pem.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. Copyright 2014 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package cert
  14. import (
  15. "crypto/rsa"
  16. "crypto/x509"
  17. "encoding/pem"
  18. "errors"
  19. "fmt"
  20. )
  21. const (
  22. // ECPrivateKeyBlockType is a possible value for pem.Block.Type.
  23. ECPrivateKeyBlockType = "EC PRIVATE KEY"
  24. // RSAPrivateKeyBlockType is a possible value for pem.Block.Type.
  25. RSAPrivateKeyBlockType = "RSA PRIVATE KEY"
  26. // CertificateBlockType is a possible value for pem.Block.Type.
  27. CertificateBlockType = "CERTIFICATE"
  28. // CertificateRequestBlockType is a possible value for pem.Block.Type.
  29. CertificateRequestBlockType = "CERTIFICATE REQUEST"
  30. // PrivateKeyBlockType is a possible value for pem.Block.Type.
  31. PrivateKeyBlockType = "PRIVATE KEY"
  32. // PublicKeyBlockType is a possible value for pem.Block.Type.
  33. PublicKeyBlockType = "PUBLIC KEY"
  34. )
  35. // EncodePublicKeyPEM returns PEM-endcode public data
  36. func EncodePublicKeyPEM(key *rsa.PublicKey) ([]byte, error) {
  37. der, err := x509.MarshalPKIXPublicKey(key)
  38. if err != nil {
  39. return []byte{}, err
  40. }
  41. block := pem.Block{
  42. Type: PublicKeyBlockType,
  43. Bytes: der,
  44. }
  45. return pem.EncodeToMemory(&block), nil
  46. }
  47. // EncodePrivateKeyPEM returns PEM-encoded private key data
  48. func EncodePrivateKeyPEM(key *rsa.PrivateKey) []byte {
  49. block := pem.Block{
  50. Type: RSAPrivateKeyBlockType,
  51. Bytes: x509.MarshalPKCS1PrivateKey(key),
  52. }
  53. return pem.EncodeToMemory(&block)
  54. }
  55. // EncodeCertPEM returns PEM-endcoded certificate data
  56. func EncodeCertPEM(cert *x509.Certificate) []byte {
  57. block := pem.Block{
  58. Type: CertificateBlockType,
  59. Bytes: cert.Raw,
  60. }
  61. return pem.EncodeToMemory(&block)
  62. }
  63. // ParsePrivateKeyPEM returns a private key parsed from a PEM block in the supplied data.
  64. // Recognizes PEM blocks for "EC PRIVATE KEY", "RSA PRIVATE KEY", or "PRIVATE KEY"
  65. func ParsePrivateKeyPEM(keyData []byte) (interface{}, error) {
  66. var privateKeyPemBlock *pem.Block
  67. for {
  68. privateKeyPemBlock, keyData = pem.Decode(keyData)
  69. if privateKeyPemBlock == nil {
  70. break
  71. }
  72. switch privateKeyPemBlock.Type {
  73. case ECPrivateKeyBlockType:
  74. // ECDSA Private Key in ASN.1 format
  75. if key, err := x509.ParseECPrivateKey(privateKeyPemBlock.Bytes); err == nil {
  76. return key, nil
  77. }
  78. case RSAPrivateKeyBlockType:
  79. // RSA Private Key in PKCS#1 format
  80. if key, err := x509.ParsePKCS1PrivateKey(privateKeyPemBlock.Bytes); err == nil {
  81. return key, nil
  82. }
  83. case PrivateKeyBlockType:
  84. // RSA or ECDSA Private Key in unencrypted PKCS#8 format
  85. if key, err := x509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes); err == nil {
  86. return key, nil
  87. }
  88. }
  89. // tolerate non-key PEM blocks for compatibility with things like "EC PARAMETERS" blocks
  90. // originally, only the first PEM block was parsed and expected to be a key block
  91. }
  92. // we read all the PEM blocks and didn't recognize one
  93. return nil, fmt.Errorf("data does not contain a valid RSA or ECDSA private key")
  94. }
  95. // ParseCertsPEM returns the x509.Certificates contained in the given PEM-encoded byte array
  96. // Returns an error if a certificate could not be parsed, or if the data does not contain any certificates
  97. func ParseCertsPEM(pemCerts []byte) ([]*x509.Certificate, error) {
  98. ok := false
  99. certs := []*x509.Certificate{}
  100. for len(pemCerts) > 0 {
  101. var block *pem.Block
  102. block, pemCerts = pem.Decode(pemCerts)
  103. if block == nil {
  104. break
  105. }
  106. // Only use PEM "CERTIFICATE" blocks without extra headers
  107. if block.Type != CertificateBlockType || len(block.Headers) != 0 {
  108. continue
  109. }
  110. cert, err := x509.ParseCertificate(block.Bytes)
  111. if err != nil {
  112. return certs, err
  113. }
  114. certs = append(certs, cert)
  115. ok = true
  116. }
  117. if !ok {
  118. return certs, errors.New("could not read any certificates")
  119. }
  120. return certs, nil
  121. }