X509KeyPair parses a public/private key pair from a pair of PEM encoded data. On successful return, Certificate.Leaf will be nil because the parsed form of the certificate is not retained.
(certPEMBlock, keyPEMBlock []byte)
| 243 | // PEM encoded data. On successful return, Certificate.Leaf will be nil because |
| 244 | // the parsed form of the certificate is not retained. |
| 245 | func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) { |
| 246 | fail := func(err error) (Certificate, error) { return Certificate{}, err } |
| 247 | |
| 248 | var cert Certificate |
| 249 | var skippedBlockTypes []string |
| 250 | for { |
| 251 | var certDERBlock *pem.Block |
| 252 | certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) |
| 253 | if certDERBlock == nil { |
| 254 | break |
| 255 | } |
| 256 | if certDERBlock.Type == "CERTIFICATE" { |
| 257 | cert.Certificate = append(cert.Certificate, certDERBlock.Bytes) |
| 258 | } else { |
| 259 | skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type) |
| 260 | } |
| 261 | } |
| 262 | |
| 263 | if len(cert.Certificate) == 0 { |
| 264 | if len(skippedBlockTypes) == 0 { |
| 265 | return fail(errors.New("tls: failed to find any PEM data in certificate input")) |
| 266 | } |
| 267 | if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") { |
| 268 | return fail(errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched")) |
| 269 | } |
| 270 | return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) |
| 271 | } |
| 272 | |
| 273 | skippedBlockTypes = skippedBlockTypes[:0] |
| 274 | var keyDERBlock *pem.Block |
| 275 | for { |
| 276 | keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock) |
| 277 | if keyDERBlock == nil { |
| 278 | if len(skippedBlockTypes) == 0 { |
| 279 | return fail(errors.New("tls: failed to find any PEM data in key input")) |
| 280 | } |
| 281 | if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" { |
| 282 | return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key")) |
| 283 | } |
| 284 | return fail(fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) |
| 285 | } |
| 286 | if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") { |
| 287 | break |
| 288 | } |
| 289 | skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type) |
| 290 | } |
| 291 | |
| 292 | // We don't need to parse the public key for TLS, but we so do anyway |
| 293 | // to check that it looks sane and matches the private key. |
| 294 | x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) |
| 295 | if err != nil { |
| 296 | return fail(err) |
| 297 | } |
| 298 | |
| 299 | cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes) |
| 300 | if err != nil { |
| 301 | return fail(err) |
| 302 | } |
no test coverage detected
searching dependent graphs…