pem.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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/ecdsa"
  16. "crypto/rsa"
  17. "crypto/x509"
  18. "encoding/pem"
  19. "errors"
  20. "fmt"
  21. )
  22. const (
  23. // ECPrivateKeyBlockType is a possible value for pem.Block.Type.
  24. ECPrivateKeyBlockType = "EC PRIVATE KEY"
  25. // RSAPrivateKeyBlockType is a possible value for pem.Block.Type.
  26. RSAPrivateKeyBlockType = "RSA PRIVATE KEY"
  27. // PrivateKeyBlockType is a possible value for pem.Block.Type.
  28. PrivateKeyBlockType = "PRIVATE KEY"
  29. // PublicKeyBlockType is a possible value for pem.Block.Type.
  30. PublicKeyBlockType = "PUBLIC KEY"
  31. // CertificateBlockType is a possible value for pem.Block.Type.
  32. CertificateBlockType = "CERTIFICATE"
  33. // CertificateRequestBlockType is a possible value for pem.Block.Type.
  34. CertificateRequestBlockType = "CERTIFICATE REQUEST"
  35. )
  36. // EncodePublicKeyPEM returns PEM-encoded public data
  37. func EncodePublicKeyPEM(key *rsa.PublicKey) ([]byte, error) {
  38. der, err := x509.MarshalPKIXPublicKey(key)
  39. if err != nil {
  40. return []byte{}, err
  41. }
  42. block := pem.Block{
  43. Type: PublicKeyBlockType,
  44. Bytes: der,
  45. }
  46. return pem.EncodeToMemory(&block), nil
  47. }
  48. // EncodePrivateKeyPEM returns PEM-encoded private key data
  49. func EncodePrivateKeyPEM(key *rsa.PrivateKey) []byte {
  50. block := pem.Block{
  51. Type: RSAPrivateKeyBlockType,
  52. Bytes: x509.MarshalPKCS1PrivateKey(key),
  53. }
  54. return pem.EncodeToMemory(&block)
  55. }
  56. // EncodeCertPEM returns PEM-endcoded certificate data
  57. func EncodeCertPEM(cert *x509.Certificate) []byte {
  58. block := pem.Block{
  59. Type: CertificateBlockType,
  60. Bytes: cert.Raw,
  61. }
  62. return pem.EncodeToMemory(&block)
  63. }
  64. // ParsePrivateKeyPEM returns a private key parsed from a PEM block in the supplied data.
  65. // Recognizes PEM blocks for "EC PRIVATE KEY", "RSA PRIVATE KEY", or "PRIVATE KEY"
  66. func ParsePrivateKeyPEM(keyData []byte) (interface{}, error) {
  67. var privateKeyPemBlock *pem.Block
  68. for {
  69. privateKeyPemBlock, keyData = pem.Decode(keyData)
  70. if privateKeyPemBlock == nil {
  71. break
  72. }
  73. switch privateKeyPemBlock.Type {
  74. case ECPrivateKeyBlockType:
  75. // ECDSA Private Key in ASN.1 format
  76. if key, err := x509.ParseECPrivateKey(privateKeyPemBlock.Bytes); err == nil {
  77. return key, nil
  78. }
  79. case RSAPrivateKeyBlockType:
  80. // RSA Private Key in PKCS#1 format
  81. if key, err := x509.ParsePKCS1PrivateKey(privateKeyPemBlock.Bytes); err == nil {
  82. return key, nil
  83. }
  84. case PrivateKeyBlockType:
  85. // RSA or ECDSA Private Key in unencrypted PKCS#8 format
  86. if key, err := x509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes); err == nil {
  87. return key, nil
  88. }
  89. }
  90. // tolerate non-key PEM blocks for compatibility with things like "EC PARAMETERS" blocks
  91. // originally, only the first PEM block was parsed and expected to be a key block
  92. }
  93. // we read all the PEM blocks and didn't recognize one
  94. return nil, fmt.Errorf("data does not contain a valid RSA or ECDSA private key")
  95. }
  96. // ParsePublicKeysPEM is a helper function for reading an array of rsa.PublicKey or ecdsa.PublicKey from a PEM-encoded byte array.
  97. // Reads public keys from both public and private key files.
  98. func ParsePublicKeysPEM(keyData []byte) ([]interface{}, error) {
  99. var block *pem.Block
  100. keys := []interface{}{}
  101. for {
  102. // read the next block
  103. block, keyData = pem.Decode(keyData)
  104. if block == nil {
  105. break
  106. }
  107. // test block against parsing functions
  108. if privateKey, err := parseRSAPrivateKey(block.Bytes); err == nil {
  109. keys = append(keys, &privateKey.PublicKey)
  110. continue
  111. }
  112. if publicKey, err := parseRSAPublicKey(block.Bytes); err == nil {
  113. keys = append(keys, publicKey)
  114. continue
  115. }
  116. if privateKey, err := parseECPrivateKey(block.Bytes); err == nil {
  117. keys = append(keys, &privateKey.PublicKey)
  118. continue
  119. }
  120. if publicKey, err := parseECPublicKey(block.Bytes); err == nil {
  121. keys = append(keys, publicKey)
  122. continue
  123. }
  124. // tolerate non-key PEM blocks for backwards compatibility
  125. // originally, only the first PEM block was parsed and expected to be a key block
  126. }
  127. if len(keys) == 0 {
  128. return nil, fmt.Errorf("data does not contain any valid RSA or ECDSA public keys")
  129. }
  130. return keys, nil
  131. }
  132. // ParseCertsPEM returns the x509.Certificates contained in the given PEM-encoded byte array
  133. // Returns an error if a certificate could not be parsed, or if the data does not contain any certificates
  134. func ParseCertsPEM(pemCerts []byte) ([]*x509.Certificate, error) {
  135. ok := false
  136. certs := []*x509.Certificate{}
  137. for len(pemCerts) > 0 {
  138. var block *pem.Block
  139. block, pemCerts = pem.Decode(pemCerts)
  140. if block == nil {
  141. break
  142. }
  143. // Only use PEM "CERTIFICATE" blocks without extra headers
  144. if block.Type != CertificateBlockType || len(block.Headers) != 0 {
  145. continue
  146. }
  147. cert, err := x509.ParseCertificate(block.Bytes)
  148. if err != nil {
  149. return certs, err
  150. }
  151. certs = append(certs, cert)
  152. ok = true
  153. }
  154. if !ok {
  155. return certs, errors.New("data does not contain any valid RSA or ECDSA certificates")
  156. }
  157. return certs, nil
  158. }
  159. // parseRSAPublicKey parses a single RSA public key from the provided data
  160. func parseRSAPublicKey(data []byte) (*rsa.PublicKey, error) {
  161. var err error
  162. // Parse the key
  163. var parsedKey interface{}
  164. if parsedKey, err = x509.ParsePKIXPublicKey(data); err != nil {
  165. if cert, err := x509.ParseCertificate(data); err == nil {
  166. parsedKey = cert.PublicKey
  167. } else {
  168. return nil, err
  169. }
  170. }
  171. // Test if parsed key is an RSA Public Key
  172. var pubKey *rsa.PublicKey
  173. var ok bool
  174. if pubKey, ok = parsedKey.(*rsa.PublicKey); !ok {
  175. return nil, fmt.Errorf("data doesn't contain valid RSA Public Key")
  176. }
  177. return pubKey, nil
  178. }
  179. // parseRSAPrivateKey parses a single RSA private key from the provided data
  180. func parseRSAPrivateKey(data []byte) (*rsa.PrivateKey, error) {
  181. var err error
  182. // Parse the key
  183. var parsedKey interface{}
  184. if parsedKey, err = x509.ParsePKCS1PrivateKey(data); err != nil {
  185. if parsedKey, err = x509.ParsePKCS8PrivateKey(data); err != nil {
  186. return nil, err
  187. }
  188. }
  189. // Test if parsed key is an RSA Private Key
  190. var privKey *rsa.PrivateKey
  191. var ok bool
  192. if privKey, ok = parsedKey.(*rsa.PrivateKey); !ok {
  193. return nil, fmt.Errorf("data doesn't contain valid RSA Private Key")
  194. }
  195. return privKey, nil
  196. }
  197. // parseECPublicKey parses a single ECDSA public key from the provided data
  198. func parseECPublicKey(data []byte) (*ecdsa.PublicKey, error) {
  199. var err error
  200. // Parse the key
  201. var parsedKey interface{}
  202. if parsedKey, err = x509.ParsePKIXPublicKey(data); err != nil {
  203. if cert, err := x509.ParseCertificate(data); err == nil {
  204. parsedKey = cert.PublicKey
  205. } else {
  206. return nil, err
  207. }
  208. }
  209. // Test if parsed key is an ECDSA Public Key
  210. var pubKey *ecdsa.PublicKey
  211. var ok bool
  212. if pubKey, ok = parsedKey.(*ecdsa.PublicKey); !ok {
  213. return nil, fmt.Errorf("data doesn't contain valid ECDSA Public Key")
  214. }
  215. return pubKey, nil
  216. }
  217. // parseECPrivateKey parses a single ECDSA private key from the provided data
  218. func parseECPrivateKey(data []byte) (*ecdsa.PrivateKey, error) {
  219. var err error
  220. // Parse the key
  221. var parsedKey interface{}
  222. if parsedKey, err = x509.ParseECPrivateKey(data); err != nil {
  223. return nil, err
  224. }
  225. // Test if parsed key is an ECDSA Private Key
  226. var privKey *ecdsa.PrivateKey
  227. var ok bool
  228. if privKey, ok = parsedKey.(*ecdsa.PrivateKey); !ok {
  229. return nil, fmt.Errorf("data doesn't contain valid ECDSA Private Key")
  230. }
  231. return privKey, nil
  232. }