X509KeyPair parses a public/private key pair from a pair of PEM encoded data. On successful return, Certificate.Leaf will be populated. Before Go 1.23 Certificate.Leaf was left nil, and the parsed certificate was discarded. This behavior can be re-enabled by setting "x509keypairleaf=0" in the GODEB
(certPEMBlock, keyPEMBlock []byte)
| 723 | // discarded. This behavior can be re-enabled by setting "x509keypairleaf=0" |
| 724 | // in the GODEBUG environment variable. |
| 725 | func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) { |
| 726 | fail := func(err error) (Certificate, error) { return Certificate{}, err } |
| 727 | |
| 728 | var cert Certificate |
| 729 | var skippedBlockTypes []string |
| 730 | for { |
| 731 | var certDERBlock *pem.Block |
| 732 | certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) |
| 733 | if certDERBlock == nil { |
| 734 | break |
| 735 | } |
| 736 | if certDERBlock.Type == "CERTIFICATE" { |
| 737 | cert.Certificate = append(cert.Certificate, certDERBlock.Bytes) |
| 738 | } else { |
| 739 | skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type) |
| 740 | } |
| 741 | } |
| 742 | |
| 743 | if len(cert.Certificate) == 0 { |
| 744 | if len(skippedBlockTypes) == 0 { |
| 745 | return fail(errors.New("tls: failed to find any PEM data in certificate input")) |
| 746 | } |
| 747 | if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") { |
| 748 | 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")) |
| 749 | } |
| 750 | return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) |
| 751 | } |
| 752 | |
| 753 | skippedBlockTypes = skippedBlockTypes[:0] |
| 754 | var keyDERBlock *pem.Block |
| 755 | for { |
| 756 | keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock) |
| 757 | if keyDERBlock == nil { |
| 758 | if len(skippedBlockTypes) == 0 { |
| 759 | return fail(errors.New("tls: failed to find any PEM data in key input")) |
| 760 | } |
| 761 | if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" { |
| 762 | return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key")) |
| 763 | } |
| 764 | 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)) |
| 765 | } |
| 766 | if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") { |
| 767 | break |
| 768 | } |
| 769 | skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type) |
| 770 | } |
| 771 | |
| 772 | // We don't need to parse the public key for TLS, but we so do anyway |
| 773 | // to check that it looks sane and matches the private key. |
| 774 | x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) |
| 775 | if err != nil { |
| 776 | return fail(err) |
| 777 | } |
| 778 | |
| 779 | cert.Leaf = x509Cert |
| 780 | |
| 781 | cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes) |
| 782 | if err != nil { |
no test coverage detected
searching dependent graphs…