// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package x509 parses X.509-encoded keys and certificates.
package x509 import ( // Explicitly import these for their crypto.RegisterHash init side-effects. // Keep these as blank imports, even if they're imported above. _ _ _ cryptobyte_asn1 ) // pkixPublicKey reflects a PKIX public key structure. See SubjectPublicKeyInfo // in RFC 3280. type pkixPublicKey struct { Algo pkix.AlgorithmIdentifier BitString asn1.BitString } // ParsePKIXPublicKey parses a public key in PKIX, ASN.1 DER form. // The encoded public key is a SubjectPublicKeyInfo structure // (see RFC 5280, Section 4.1). // // It returns a *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey, or // ed25519.PublicKey. More types might be supported in the future. // // This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY". func ( []byte) ( interface{}, error) { var publicKeyInfo if , := asn1.Unmarshal(, &); != nil { if , := asn1.Unmarshal(, &pkcs1PublicKey{}); == nil { return nil, errors.New("x509: failed to parse public key (use ParsePKCS1PublicKey instead for this key format)") } return nil, } else if len() != 0 { return nil, errors.New("x509: trailing data after ASN.1 of public-key") } := getPublicKeyAlgorithmFromOID(.Algorithm.Algorithm) if == UnknownPublicKeyAlgorithm { return nil, errors.New("x509: unknown public key algorithm") } return parsePublicKey(, &) } func marshalPublicKey( interface{}) ( []byte, pkix.AlgorithmIdentifier, error) { switch pub := .(type) { case *rsa.PublicKey: , = asn1.Marshal(pkcs1PublicKey{ N: .N, E: .E, }) if != nil { return nil, pkix.AlgorithmIdentifier{}, } .Algorithm = oidPublicKeyRSA // This is a NULL parameters value which is required by // RFC 3279, Section 2.3.1. .Parameters = asn1.NullRawValue case *ecdsa.PublicKey: = elliptic.Marshal(.Curve, .X, .Y) , := oidFromNamedCurve(.Curve) if ! { return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve") } .Algorithm = oidPublicKeyECDSA var []byte , = asn1.Marshal() if != nil { return } .Parameters.FullBytes = case ed25519.PublicKey: = .Algorithm = oidPublicKeyEd25519 default: return nil, pkix.AlgorithmIdentifier{}, fmt.Errorf("x509: unsupported public key type: %T", ) } return , , nil } // MarshalPKIXPublicKey converts a public key to PKIX, ASN.1 DER form. // The encoded public key is a SubjectPublicKeyInfo structure // (see RFC 5280, Section 4.1). // // The following key types are currently supported: *rsa.PublicKey, *ecdsa.PublicKey // and ed25519.PublicKey. Unsupported key types result in an error. // // This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY". func ( interface{}) ([]byte, error) { var []byte var pkix.AlgorithmIdentifier var error if , , = marshalPublicKey(); != nil { return nil, } := pkixPublicKey{ Algo: , BitString: asn1.BitString{ Bytes: , BitLength: 8 * len(), }, } , := asn1.Marshal() return , nil } // These structures reflect the ASN.1 structure of X.509 certificates.: type certificate struct { Raw asn1.RawContent TBSCertificate tbsCertificate SignatureAlgorithm pkix.AlgorithmIdentifier SignatureValue asn1.BitString } type tbsCertificate struct { Raw asn1.RawContent Version int `asn1:"optional,explicit,default:0,tag:0"` SerialNumber *big.Int SignatureAlgorithm pkix.AlgorithmIdentifier Issuer asn1.RawValue Validity validity Subject asn1.RawValue PublicKey publicKeyInfo UniqueId asn1.BitString `asn1:"optional,tag:1"` SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"` Extensions []pkix.Extension `asn1:"optional,explicit,tag:3"` } type dsaAlgorithmParameters struct { P, Q, G *big.Int } type validity struct { NotBefore, NotAfter time.Time } type publicKeyInfo struct { Raw asn1.RawContent Algorithm pkix.AlgorithmIdentifier PublicKey asn1.BitString } // RFC 5280, 4.2.1.1 type authKeyId struct { Id []byte `asn1:"optional,tag:0"` } type SignatureAlgorithm int const ( UnknownSignatureAlgorithm SignatureAlgorithm = iota MD2WithRSA // Unsupported. MD5WithRSA // Only supported for signing, not verification. SHA1WithRSA SHA256WithRSA SHA384WithRSA SHA512WithRSA DSAWithSHA1 // Unsupported. DSAWithSHA256 // Unsupported. ECDSAWithSHA1 ECDSAWithSHA256 ECDSAWithSHA384 ECDSAWithSHA512 SHA256WithRSAPSS SHA384WithRSAPSS SHA512WithRSAPSS PureEd25519 ) func ( SignatureAlgorithm) () bool { switch { case SHA256WithRSAPSS, SHA384WithRSAPSS, SHA512WithRSAPSS: return true default: return false } } func ( SignatureAlgorithm) () string { for , := range signatureAlgorithmDetails { if .algo == { return .name } } return strconv.Itoa(int()) } type PublicKeyAlgorithm int const ( UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota RSA DSA // Unsupported. ECDSA Ed25519 ) var publicKeyAlgoName = [...]string{ RSA: "RSA", DSA: "DSA", ECDSA: "ECDSA", Ed25519: "Ed25519", } func ( PublicKeyAlgorithm) () string { if 0 < && int() < len(publicKeyAlgoName) { return publicKeyAlgoName[] } return strconv.Itoa(int()) } // OIDs for signature algorithms // // pkcs-1 OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } // // // RFC 3279 2.2.1 RSA Signature Algorithms // // md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } // // md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } // // sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } // // dsaWithSha1 OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 } // // RFC 3279 2.2.3 ECDSA Signature Algorithm // // ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) ansi-x962(10045) // signatures(4) ecdsa-with-SHA1(1)} // // // RFC 4055 5 PKCS #1 Version 1.5 // // sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 } // // sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 } // // sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } // // // RFC 5758 3.1 DSA Signature Algorithms // // dsaWithSha256 OBJECT IDENTIFIER ::= { // joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101) // csor(3) algorithms(4) id-dsa-with-sha2(3) 2} // // RFC 5758 3.2 ECDSA Signature Algorithm // // ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 } // // ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 } // // ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 } // // // RFC 8410 3 Curve25519 and Curve448 Algorithm Identifiers // // id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 } var ( oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2} oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4} oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10} oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3} oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2} oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1} oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2} oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3} oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4} oidSignatureEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112} oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1} oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2} oidSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3} oidMGF1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 8} // oidISOSignatureSHA1WithRSA means the same as oidSignatureSHA1WithRSA // but it's specified by ISO. Microsoft's makecert.exe has been known // to produce certificates with this OID. oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29} ) var signatureAlgorithmDetails = []struct { algo SignatureAlgorithm name string oid asn1.ObjectIdentifier pubKeyAlgo PublicKeyAlgorithm hash crypto.Hash }{ {MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, RSA, crypto.Hash(0) /* no value for MD2 */}, {MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, RSA, crypto.MD5}, {SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, RSA, crypto.SHA1}, {SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, RSA, crypto.SHA1}, {SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, RSA, crypto.SHA256}, {SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, RSA, crypto.SHA384}, {SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, RSA, crypto.SHA512}, {SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA256}, {SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA384}, {SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA512}, {DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, DSA, crypto.SHA1}, {DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, DSA, crypto.SHA256}, {ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, ECDSA, crypto.SHA1}, {ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, ECDSA, crypto.SHA256}, {ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, ECDSA, crypto.SHA384}, {ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, ECDSA, crypto.SHA512}, {PureEd25519, "Ed25519", oidSignatureEd25519, Ed25519, crypto.Hash(0) /* no pre-hashing */}, } // hashToPSSParameters contains the DER encoded RSA PSS parameters for the // SHA256, SHA384, and SHA512 hashes as defined in RFC 3447, Appendix A.2.3. // The parameters contain the following values: // * hashAlgorithm contains the associated hash identifier with NULL parameters // * maskGenAlgorithm always contains the default mgf1SHA1 identifier // * saltLength contains the length of the associated hash // * trailerField always contains the default trailerFieldBC value var hashToPSSParameters = map[crypto.Hash]asn1.RawValue{ crypto.SHA256: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 162, 3, 2, 1, 32}}, crypto.SHA384: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 162, 3, 2, 1, 48}}, crypto.SHA512: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 162, 3, 2, 1, 64}}, } // pssParameters reflects the parameters in an AlgorithmIdentifier that // specifies RSA PSS. See RFC 3447, Appendix A.2.3. type pssParameters struct { // The following three fields are not marked as // optional because the default values specify SHA-1, // which is no longer suitable for use in signatures. Hash pkix.AlgorithmIdentifier `asn1:"explicit,tag:0"` MGF pkix.AlgorithmIdentifier `asn1:"explicit,tag:1"` SaltLength int `asn1:"explicit,tag:2"` TrailerField int `asn1:"optional,explicit,tag:3,default:1"` } func getSignatureAlgorithmFromAI( pkix.AlgorithmIdentifier) SignatureAlgorithm { if .Algorithm.Equal(oidSignatureEd25519) { // RFC 8410, Section 3 // > For all of the OIDs, the parameters MUST be absent. if len(.Parameters.FullBytes) != 0 { return UnknownSignatureAlgorithm } } if !.Algorithm.Equal(oidSignatureRSAPSS) { for , := range signatureAlgorithmDetails { if .Algorithm.Equal(.oid) { return .algo } } return UnknownSignatureAlgorithm } // RSA PSS is special because it encodes important parameters // in the Parameters. var pssParameters if , := asn1.Unmarshal(.Parameters.FullBytes, &); != nil { return UnknownSignatureAlgorithm } var pkix.AlgorithmIdentifier if , := asn1.Unmarshal(.MGF.Parameters.FullBytes, &); != nil { return UnknownSignatureAlgorithm } // PSS is greatly overburdened with options. This code forces them into // three buckets by requiring that the MGF1 hash function always match the // message hash function (as recommended in RFC 3447, Section 8.1), that the // salt length matches the hash length, and that the trailer field has the // default value. if (len(.Hash.Parameters.FullBytes) != 0 && !bytes.Equal(.Hash.Parameters.FullBytes, asn1.NullBytes)) || !.MGF.Algorithm.Equal(oidMGF1) || !.Algorithm.Equal(.Hash.Algorithm) || (len(.Parameters.FullBytes) != 0 && !bytes.Equal(.Parameters.FullBytes, asn1.NullBytes)) || .TrailerField != 1 { return UnknownSignatureAlgorithm } switch { case .Hash.Algorithm.Equal(oidSHA256) && .SaltLength == 32: return SHA256WithRSAPSS case .Hash.Algorithm.Equal(oidSHA384) && .SaltLength == 48: return SHA384WithRSAPSS case .Hash.Algorithm.Equal(oidSHA512) && .SaltLength == 64: return SHA512WithRSAPSS } return UnknownSignatureAlgorithm } // RFC 3279, 2.3 Public Key Algorithms // // pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840) // rsadsi(113549) pkcs(1) 1 } // // rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 } // // id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840) // x9-57(10040) x9cm(4) 1 } // // RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters // // id-ecPublicKey OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } var ( oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1} oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} oidPublicKeyEd25519 = oidSignatureEd25519 ) func getPublicKeyAlgorithmFromOID( asn1.ObjectIdentifier) PublicKeyAlgorithm { switch { case .Equal(oidPublicKeyRSA): return RSA case .Equal(oidPublicKeyDSA): return DSA case .Equal(oidPublicKeyECDSA): return ECDSA case .Equal(oidPublicKeyEd25519): return Ed25519 } return UnknownPublicKeyAlgorithm } // RFC 5480, 2.1.1.1. Named Curve // // secp224r1 OBJECT IDENTIFIER ::= { // iso(1) identified-organization(3) certicom(132) curve(0) 33 } // // secp256r1 OBJECT IDENTIFIER ::= { // iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) // prime(1) 7 } // // secp384r1 OBJECT IDENTIFIER ::= { // iso(1) identified-organization(3) certicom(132) curve(0) 34 } // // secp521r1 OBJECT IDENTIFIER ::= { // iso(1) identified-organization(3) certicom(132) curve(0) 35 } // // NB: secp256r1 is equivalent to prime256v1 var ( oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33} oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7} oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34} oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35} ) func namedCurveFromOID( asn1.ObjectIdentifier) elliptic.Curve { switch { case .Equal(oidNamedCurveP224): return elliptic.P224() case .Equal(oidNamedCurveP256): return elliptic.P256() case .Equal(oidNamedCurveP384): return elliptic.P384() case .Equal(oidNamedCurveP521): return elliptic.P521() } return nil } func oidFromNamedCurve( elliptic.Curve) (asn1.ObjectIdentifier, bool) { switch { case elliptic.P224(): return oidNamedCurveP224, true case elliptic.P256(): return oidNamedCurveP256, true case elliptic.P384(): return oidNamedCurveP384, true case elliptic.P521(): return oidNamedCurveP521, true } return nil, false } // KeyUsage represents the set of actions that are valid for a given key. It's // a bitmap of the KeyUsage* constants. type KeyUsage int const ( KeyUsageDigitalSignature KeyUsage = 1 << iota KeyUsageContentCommitment KeyUsageKeyEncipherment KeyUsageDataEncipherment KeyUsageKeyAgreement KeyUsageCertSign KeyUsageCRLSign KeyUsageEncipherOnly KeyUsageDecipherOnly ) // RFC 5280, 4.2.1.12 Extended Key Usage // // anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } // // id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } // // id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } // id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } // id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } // id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } // id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } // id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } var ( oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0} oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1} oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2} oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3} oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4} oidExtKeyUsageIPSECEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5} oidExtKeyUsageIPSECTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6} oidExtKeyUsageIPSECUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7} oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8} oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9} oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3} oidExtKeyUsageNetscapeServerGatedCrypto = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1} oidExtKeyUsageMicrosoftCommercialCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 22} oidExtKeyUsageMicrosoftKernelCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1} ) // ExtKeyUsage represents an extended set of actions that are valid for a given key. // Each of the ExtKeyUsage* constants define a unique action. type ExtKeyUsage int const ( ExtKeyUsageAny ExtKeyUsage = iota ExtKeyUsageServerAuth ExtKeyUsageClientAuth ExtKeyUsageCodeSigning ExtKeyUsageEmailProtection ExtKeyUsageIPSECEndSystem ExtKeyUsageIPSECTunnel ExtKeyUsageIPSECUser ExtKeyUsageTimeStamping ExtKeyUsageOCSPSigning ExtKeyUsageMicrosoftServerGatedCrypto ExtKeyUsageNetscapeServerGatedCrypto ExtKeyUsageMicrosoftCommercialCodeSigning ExtKeyUsageMicrosoftKernelCodeSigning ) // extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID. var extKeyUsageOIDs = []struct { extKeyUsage ExtKeyUsage oid asn1.ObjectIdentifier }{ {ExtKeyUsageAny, oidExtKeyUsageAny}, {ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth}, {ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth}, {ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning}, {ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection}, {ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem}, {ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel}, {ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser}, {ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping}, {ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning}, {ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto}, {ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto}, {ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning}, {ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning}, } func extKeyUsageFromOID( asn1.ObjectIdentifier) ( ExtKeyUsage, bool) { for , := range extKeyUsageOIDs { if .Equal(.oid) { return .extKeyUsage, true } } return } func oidFromExtKeyUsage( ExtKeyUsage) ( asn1.ObjectIdentifier, bool) { for , := range extKeyUsageOIDs { if == .extKeyUsage { return .oid, true } } return } // A Certificate represents an X.509 certificate. type Certificate struct { Raw []byte // Complete ASN.1 DER content (certificate, signature algorithm and signature). RawTBSCertificate []byte // Certificate part of raw ASN.1 DER content. RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo. RawSubject []byte // DER encoded Subject RawIssuer []byte // DER encoded Issuer Signature []byte SignatureAlgorithm SignatureAlgorithm PublicKeyAlgorithm PublicKeyAlgorithm PublicKey interface{} Version int SerialNumber *big.Int Issuer pkix.Name Subject pkix.Name NotBefore, NotAfter time.Time // Validity bounds. KeyUsage KeyUsage // Extensions contains raw X.509 extensions. When parsing certificates, // this can be used to extract non-critical extensions that are not // parsed by this package. When marshaling certificates, the Extensions // field is ignored, see ExtraExtensions. Extensions []pkix.Extension // ExtraExtensions contains extensions to be copied, raw, into any // marshaled certificates. Values override any extensions that would // otherwise be produced based on the other fields. The ExtraExtensions // field is not populated when parsing certificates, see Extensions. ExtraExtensions []pkix.Extension // UnhandledCriticalExtensions contains a list of extension IDs that // were not (fully) processed when parsing. Verify will fail if this // slice is non-empty, unless verification is delegated to an OS // library which understands all the critical extensions. // // Users can access these extensions using Extensions and can remove // elements from this slice if they believe that they have been // handled. UnhandledCriticalExtensions []asn1.ObjectIdentifier ExtKeyUsage []ExtKeyUsage // Sequence of extended key usages. UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package. // BasicConstraintsValid indicates whether IsCA, MaxPathLen, // and MaxPathLenZero are valid. BasicConstraintsValid bool IsCA bool // MaxPathLen and MaxPathLenZero indicate the presence and // value of the BasicConstraints' "pathLenConstraint". // // When parsing a certificate, a positive non-zero MaxPathLen // means that the field was specified, -1 means it was unset, // and MaxPathLenZero being true mean that the field was // explicitly set to zero. The case of MaxPathLen==0 with MaxPathLenZero==false // should be treated equivalent to -1 (unset). // // When generating a certificate, an unset pathLenConstraint // can be requested with either MaxPathLen == -1 or using the // zero value for both MaxPathLen and MaxPathLenZero. MaxPathLen int // MaxPathLenZero indicates that BasicConstraintsValid==true // and MaxPathLen==0 should be interpreted as an actual // maximum path length of zero. Otherwise, that combination is // interpreted as MaxPathLen not being set. MaxPathLenZero bool SubjectKeyId []byte AuthorityKeyId []byte // RFC 5280, 4.2.2.1 (Authority Information Access) OCSPServer []string IssuingCertificateURL []string // Subject Alternate Name values. (Note that these values may not be valid // if invalid values were contained within a parsed certificate. For // example, an element of DNSNames may not be a valid DNS domain name.) DNSNames []string EmailAddresses []string IPAddresses []net.IP URIs []*url.URL // Name constraints PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical. PermittedDNSDomains []string ExcludedDNSDomains []string PermittedIPRanges []*net.IPNet ExcludedIPRanges []*net.IPNet PermittedEmailAddresses []string ExcludedEmailAddresses []string PermittedURIDomains []string ExcludedURIDomains []string // CRL Distribution Points CRLDistributionPoints []string PolicyIdentifiers []asn1.ObjectIdentifier } // ErrUnsupportedAlgorithm results from attempting to perform an operation that // involves algorithms that are not currently implemented. var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented") // An InsecureAlgorithmError type InsecureAlgorithmError SignatureAlgorithm func ( InsecureAlgorithmError) () string { return fmt.Sprintf("x509: cannot verify signature: insecure algorithm %v", SignatureAlgorithm()) } // ConstraintViolationError results when a requested usage is not permitted by // a certificate. For example: checking a signature when the public key isn't a // certificate signing key. type ConstraintViolationError struct{} func (ConstraintViolationError) () string { return "x509: invalid signature: parent certificate cannot sign this kind of certificate" } func ( *Certificate) ( *Certificate) bool { if == nil || == nil { return == } return bytes.Equal(.Raw, .Raw) } func ( *Certificate) () bool { return oidInExtensions(oidExtensionSubjectAltName, .Extensions) } // CheckSignatureFrom verifies that the signature on c is a valid signature // from parent. func ( *Certificate) ( *Certificate) error { // RFC 5280, 4.2.1.9: // "If the basic constraints extension is not present in a version 3 // certificate, or the extension is present but the cA boolean is not // asserted, then the certified public key MUST NOT be used to verify // certificate signatures." if .Version == 3 && !.BasicConstraintsValid || .BasicConstraintsValid && !.IsCA { return ConstraintViolationError{} } if .KeyUsage != 0 && .KeyUsage&KeyUsageCertSign == 0 { return ConstraintViolationError{} } if .PublicKeyAlgorithm == UnknownPublicKeyAlgorithm { return ErrUnsupportedAlgorithm } // TODO(agl): don't ignore the path length constraint. return .CheckSignature(.SignatureAlgorithm, .RawTBSCertificate, .Signature) } // CheckSignature verifies that signature is a valid signature over signed from // c's public key. func ( *Certificate) ( SignatureAlgorithm, , []byte) error { return checkSignature(, , , .PublicKey) } func ( *Certificate) () bool { return oidInExtensions(oidExtensionNameConstraints, .Extensions) } func ( *Certificate) () []byte { for , := range .Extensions { if .Id.Equal(oidExtensionSubjectAltName) { return .Value } } return nil } func signaturePublicKeyAlgoMismatchError( PublicKeyAlgorithm, interface{}) error { return fmt.Errorf("x509: signature algorithm specifies an %s public key, but have public key of type %T", .String(), ) } // CheckSignature verifies that signature is a valid signature over signed from // a crypto.PublicKey. func checkSignature( SignatureAlgorithm, , []byte, crypto.PublicKey) ( error) { var crypto.Hash var PublicKeyAlgorithm for , := range signatureAlgorithmDetails { if .algo == { = .hash = .pubKeyAlgo } } switch { case crypto.Hash(0): if != Ed25519 { return ErrUnsupportedAlgorithm } case crypto.MD5: return InsecureAlgorithmError() default: if !.Available() { return ErrUnsupportedAlgorithm } := .New() .Write() = .Sum(nil) } switch pub := .(type) { case *rsa.PublicKey: if != RSA { return signaturePublicKeyAlgoMismatchError(, ) } if .isRSAPSS() { return rsa.VerifyPSS(, , , , &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}) } else { return rsa.VerifyPKCS1v15(, , , ) } case *ecdsa.PublicKey: if != ECDSA { return signaturePublicKeyAlgoMismatchError(, ) } if !ecdsa.VerifyASN1(, , ) { return errors.New("x509: ECDSA verification failure") } return case ed25519.PublicKey: if != Ed25519 { return signaturePublicKeyAlgoMismatchError(, ) } if !ed25519.Verify(, , ) { return errors.New("x509: Ed25519 verification failure") } return } return ErrUnsupportedAlgorithm } // CheckCRLSignature checks that the signature in crl is from c. func ( *Certificate) ( *pkix.CertificateList) error { := getSignatureAlgorithmFromAI(.SignatureAlgorithm) return .CheckSignature(, .TBSCertList.Raw, .SignatureValue.RightAlign()) } type UnhandledCriticalExtension struct{} func ( UnhandledCriticalExtension) () string { return "x509: unhandled critical extension" } type basicConstraints struct { IsCA bool `asn1:"optional"` MaxPathLen int `asn1:"optional,default:-1"` } // RFC 5280 4.2.1.4 type policyInformation struct { Policy asn1.ObjectIdentifier // policyQualifiers omitted } const ( nameTypeEmail = 1 nameTypeDNS = 2 nameTypeURI = 6 nameTypeIP = 7 ) // RFC 5280, 4.2.2.1 type authorityInfoAccess struct { Method asn1.ObjectIdentifier Location asn1.RawValue } // RFC 5280, 4.2.1.14 type distributionPoint struct { DistributionPoint distributionPointName `asn1:"optional,tag:0"` Reason asn1.BitString `asn1:"optional,tag:1"` CRLIssuer asn1.RawValue `asn1:"optional,tag:2"` } type distributionPointName struct { FullName []asn1.RawValue `asn1:"optional,tag:0"` RelativeName pkix.RDNSequence `asn1:"optional,tag:1"` } func parsePublicKey( PublicKeyAlgorithm, *publicKeyInfo) (interface{}, error) { := .PublicKey.RightAlign() switch { case RSA: // RSA public keys must have a NULL in the parameters. // See RFC 3279, Section 2.3.1. if !bytes.Equal(.Algorithm.Parameters.FullBytes, asn1.NullBytes) { return nil, errors.New("x509: RSA key missing NULL parameters") } := new(pkcs1PublicKey) , := asn1.Unmarshal(, ) if != nil { return nil, } if len() != 0 { return nil, errors.New("x509: trailing data after RSA public key") } if .N.Sign() <= 0 { return nil, errors.New("x509: RSA modulus is not a positive number") } if .E <= 0 { return nil, errors.New("x509: RSA public exponent is not a positive number") } := &rsa.PublicKey{ E: .E, N: .N, } return , nil case DSA: var *big.Int , := asn1.Unmarshal(, &) if != nil { return nil, } if len() != 0 { return nil, errors.New("x509: trailing data after DSA public key") } := .Algorithm.Parameters.FullBytes := new(dsaAlgorithmParameters) , = asn1.Unmarshal(, ) if != nil { return nil, } if len() != 0 { return nil, errors.New("x509: trailing data after DSA parameters") } if .Sign() <= 0 || .P.Sign() <= 0 || .Q.Sign() <= 0 || .G.Sign() <= 0 { return nil, errors.New("x509: zero or negative DSA parameter") } := &dsa.PublicKey{ Parameters: dsa.Parameters{ P: .P, Q: .Q, G: .G, }, Y: , } return , nil case ECDSA: := .Algorithm.Parameters.FullBytes := new(asn1.ObjectIdentifier) , := asn1.Unmarshal(, ) if != nil { return nil, errors.New("x509: failed to parse ECDSA parameters as named curve") } if len() != 0 { return nil, errors.New("x509: trailing data after ECDSA parameters") } := namedCurveFromOID(*) if == nil { return nil, errors.New("x509: unsupported elliptic curve") } , := elliptic.Unmarshal(, ) if == nil { return nil, errors.New("x509: failed to unmarshal elliptic curve point") } := &ecdsa.PublicKey{ Curve: , X: , Y: , } return , nil case Ed25519: // RFC 8410, Section 3 // > For all of the OIDs, the parameters MUST be absent. if len(.Algorithm.Parameters.FullBytes) != 0 { return nil, errors.New("x509: Ed25519 key encoded with illegal parameters") } if len() != ed25519.PublicKeySize { return nil, errors.New("x509: wrong Ed25519 public key size") } := make([]byte, ed25519.PublicKeySize) copy(, ) return ed25519.PublicKey(), nil default: return nil, nil } } func forEachSAN( []byte, func( int, []byte) error) error { // RFC 5280, 4.2.1.6 // SubjectAltName ::= GeneralNames // // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName // // GeneralName ::= CHOICE { // otherName [0] OtherName, // rfc822Name [1] IA5String, // dNSName [2] IA5String, // x400Address [3] ORAddress, // directoryName [4] Name, // ediPartyName [5] EDIPartyName, // uniformResourceIdentifier [6] IA5String, // iPAddress [7] OCTET STRING, // registeredID [8] OBJECT IDENTIFIER } var asn1.RawValue , := asn1.Unmarshal(, &) if != nil { return } else if len() != 0 { return errors.New("x509: trailing data after X.509 extension") } if !.IsCompound || .Tag != 16 || .Class != 0 { return asn1.StructuralError{Msg: "bad SAN sequence"} } = .Bytes for len() > 0 { var asn1.RawValue , = asn1.Unmarshal(, &) if != nil { return } if := (.Tag, .Bytes); != nil { return } } return nil } func parseSANExtension( []byte) (, []string, []net.IP, []*url.URL, error) { = forEachSAN(, func( int, []byte) error { switch { case nameTypeEmail: := string() if := isIA5String(); != nil { return errors.New("x509: SAN rfc822Name is malformed") } = append(, ) case nameTypeDNS: := string() if := isIA5String(); != nil { return errors.New("x509: SAN dNSName is malformed") } = append(, string()) case nameTypeURI: := string() if := isIA5String(); != nil { return errors.New("x509: SAN uniformResourceIdentifier is malformed") } , := url.Parse() if != nil { return fmt.Errorf("x509: cannot parse URI %q: %s", , ) } if len(.Host) > 0 { if , := domainToReverseLabels(.Host); ! { return fmt.Errorf("x509: cannot parse URI %q: invalid domain", ) } } = append(, ) case nameTypeIP: switch len() { case net.IPv4len, net.IPv6len: = append(, ) default: return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len())) } } return nil }) return } // isValidIPMask reports whether mask consists of zero or more 1 bits, followed by zero bits. func isValidIPMask( []byte) bool { := false for , := range { if { if != 0 { return false } continue } switch { case 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe: = true case 0xff: default: return false } } return true } func parseNameConstraintsExtension( *Certificate, pkix.Extension) ( bool, error) { // RFC 5280, 4.2.1.10 // NameConstraints ::= SEQUENCE { // permittedSubtrees [0] GeneralSubtrees OPTIONAL, // excludedSubtrees [1] GeneralSubtrees OPTIONAL } // // GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree // // GeneralSubtree ::= SEQUENCE { // base GeneralName, // minimum [0] BaseDistance DEFAULT 0, // maximum [1] BaseDistance OPTIONAL } // // BaseDistance ::= INTEGER (0..MAX) := cryptobyte.String(.Value) var , , cryptobyte.String var , bool if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) || !.Empty() || !.ReadOptionalASN1(&, &, cryptobyte_asn1.Tag(0).ContextSpecific().Constructed()) || !.ReadOptionalASN1(&, &, cryptobyte_asn1.Tag(1).ContextSpecific().Constructed()) || !.Empty() { return false, errors.New("x509: invalid NameConstraints extension") } if ! && ! || len() == 0 && len() == 0 { // From RFC 5280, Section 4.2.1.10: // “either the permittedSubtrees field // or the excludedSubtrees MUST be // present” return false, errors.New("x509: empty name constraints extension") } := func( cryptobyte.String) ( []string, []*net.IPNet, , []string, error) { for !.Empty() { var , cryptobyte.String var cryptobyte_asn1.Tag if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) || !.ReadAnyASN1(&, &) { return nil, nil, nil, nil, fmt.Errorf("x509: invalid NameConstraints extension") } var ( = cryptobyte_asn1.Tag(2).ContextSpecific() = cryptobyte_asn1.Tag(1).ContextSpecific() = cryptobyte_asn1.Tag(7).ContextSpecific() = cryptobyte_asn1.Tag(6).ContextSpecific() ) switch { case : := string() if := isIA5String(); != nil { return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + .Error()) } := if len() > 0 && [0] == '.' { // constraints can have a leading // period to exclude the domain // itself, but that's not valid in a // normal domain name. = [1:] } if , := domainToReverseLabels(); ! { return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", ) } = append(, ) case : := len() var , []byte switch { case 8: = [:4] = [4:] case 32: = [:16] = [16:] default: return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained value of length %d", ) } if !isValidIPMask() { return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained invalid mask %x", ) } = append(, &net.IPNet{IP: net.IP(), Mask: net.IPMask()}) case : := string() if := isIA5String(); != nil { return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + .Error()) } // If the constraint contains an @ then // it specifies an exact mailbox name. if strings.Contains(, "@") { if , := parseRFC2821Mailbox(); ! { return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", ) } } else { // Otherwise it's a domain name. := if len() > 0 && [0] == '.' { = [1:] } if , := domainToReverseLabels(); ! { return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", ) } } = append(, ) case : := string() if := isIA5String(); != nil { return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + .Error()) } if net.ParseIP() != nil { return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q: cannot be IP address", ) } := if len() > 0 && [0] == '.' { // constraints can have a leading // period to exclude the domain itself, // but that's not valid in a normal // domain name. = [1:] } if , := domainToReverseLabels(); ! { return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q", ) } = append(, ) default: = true } } return , , , , nil } if .PermittedDNSDomains, .PermittedIPRanges, .PermittedEmailAddresses, .PermittedURIDomains, = (); != nil { return false, } if .ExcludedDNSDomains, .ExcludedIPRanges, .ExcludedEmailAddresses, .ExcludedURIDomains, = (); != nil { return false, } .PermittedDNSDomainsCritical = .Critical return , nil } func parseCertificate( *certificate) (*Certificate, error) { := new(Certificate) .Raw = .Raw .RawTBSCertificate = .TBSCertificate.Raw .RawSubjectPublicKeyInfo = .TBSCertificate.PublicKey.Raw .RawSubject = .TBSCertificate.Subject.FullBytes .RawIssuer = .TBSCertificate.Issuer.FullBytes .Signature = .SignatureValue.RightAlign() .SignatureAlgorithm = getSignatureAlgorithmFromAI(.TBSCertificate.SignatureAlgorithm) .PublicKeyAlgorithm = getPublicKeyAlgorithmFromOID(.TBSCertificate.PublicKey.Algorithm.Algorithm) var error .PublicKey, = parsePublicKey(.PublicKeyAlgorithm, &.TBSCertificate.PublicKey) if != nil { return nil, } .Version = .TBSCertificate.Version + 1 .SerialNumber = .TBSCertificate.SerialNumber var , pkix.RDNSequence if , := asn1.Unmarshal(.TBSCertificate.Subject.FullBytes, &); != nil { return nil, } else if len() != 0 { return nil, errors.New("x509: trailing data after X.509 subject") } if , := asn1.Unmarshal(.TBSCertificate.Issuer.FullBytes, &); != nil { return nil, } else if len() != 0 { return nil, errors.New("x509: trailing data after X.509 issuer") } .Issuer.FillFromRDNSequence(&) .Subject.FillFromRDNSequence(&) .NotBefore = .TBSCertificate.Validity.NotBefore .NotAfter = .TBSCertificate.Validity.NotAfter for , := range .TBSCertificate.Extensions { .Extensions = append(.Extensions, ) := false if len(.Id) == 4 && .Id[0] == 2 && .Id[1] == 5 && .Id[2] == 29 { switch .Id[3] { case 15: .KeyUsage, = parseKeyUsageExtension(.Value) if != nil { return nil, } case 19: .IsCA, .MaxPathLen, = parseBasicConstraintsExtension(.Value) if != nil { return nil, } .BasicConstraintsValid = true .MaxPathLenZero = .MaxPathLen == 0 case 17: .DNSNames, .EmailAddresses, .IPAddresses, .URIs, = parseSANExtension(.Value) if != nil { return nil, } if len(.DNSNames) == 0 && len(.EmailAddresses) == 0 && len(.IPAddresses) == 0 && len(.URIs) == 0 { // If we didn't parse anything then we do the critical check, below. = true } case 30: , = parseNameConstraintsExtension(, ) if != nil { return nil, } case 31: // RFC 5280, 4.2.1.13 // CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint // // DistributionPoint ::= SEQUENCE { // distributionPoint [0] DistributionPointName OPTIONAL, // reasons [1] ReasonFlags OPTIONAL, // cRLIssuer [2] GeneralNames OPTIONAL } // // DistributionPointName ::= CHOICE { // fullName [0] GeneralNames, // nameRelativeToCRLIssuer [1] RelativeDistinguishedName } var []distributionPoint if , := asn1.Unmarshal(.Value, &); != nil { return nil, } else if len() != 0 { return nil, errors.New("x509: trailing data after X.509 CRL distribution point") } for , := range { // Per RFC 5280, 4.2.1.13, one of distributionPoint or cRLIssuer may be empty. if len(.DistributionPoint.FullName) == 0 { continue } for , := range .DistributionPoint.FullName { if .Tag == 6 { .CRLDistributionPoints = append(.CRLDistributionPoints, string(.Bytes)) } } } case 35: // RFC 5280, 4.2.1.1 var authKeyId if , := asn1.Unmarshal(.Value, &); != nil { return nil, } else if len() != 0 { return nil, errors.New("x509: trailing data after X.509 authority key-id") } .AuthorityKeyId = .Id case 37: .ExtKeyUsage, .UnknownExtKeyUsage, = parseExtKeyUsageExtension(.Value) if != nil { return nil, } case 14: .SubjectKeyId, = parseSubjectKeyIdExtension(.Value) if != nil { return nil, } case 32: .PolicyIdentifiers, = parseCertificatePoliciesExtension(.Value) if != nil { return nil, } default: // Unknown extensions are recorded if critical. = true } } else if .Id.Equal(oidExtensionAuthorityInfoAccess) { // RFC 5280 4.2.2.1: Authority Information Access var []authorityInfoAccess if , := asn1.Unmarshal(.Value, &); != nil { return nil, } else if len() != 0 { return nil, errors.New("x509: trailing data after X.509 authority information") } for , := range { // GeneralName: uniformResourceIdentifier [6] IA5String if .Location.Tag != 6 { continue } if .Method.Equal(oidAuthorityInfoAccessOcsp) { .OCSPServer = append(.OCSPServer, string(.Location.Bytes)) } else if .Method.Equal(oidAuthorityInfoAccessIssuers) { .IssuingCertificateURL = append(.IssuingCertificateURL, string(.Location.Bytes)) } } } else { // Unknown extensions are recorded if critical. = true } if .Critical && { .UnhandledCriticalExtensions = append(.UnhandledCriticalExtensions, .Id) } } return , nil } // parseKeyUsageExtension parses id-ce-keyUsage (2.5.29.15) from RFC 5280 // Section 4.2.1.3 func parseKeyUsageExtension( []byte) (KeyUsage, error) { var asn1.BitString if , := asn1.Unmarshal(, &); != nil { return 0, } else if len() != 0 { return 0, errors.New("x509: trailing data after X.509 KeyUsage") } var int for := 0; < 9; ++ { if .At() != 0 { |= 1 << uint() } } return KeyUsage(), nil } // parseBasicConstraintsExtension parses id-ce-basicConstraints (2.5.29.19) // from RFC 5280 Section 4.2.1.9 func parseBasicConstraintsExtension( []byte) ( bool, int, error) { var basicConstraints if , := asn1.Unmarshal(, &); != nil { return false, 0, } else if len() != 0 { return false, 0, errors.New("x509: trailing data after X.509 BasicConstraints") } // TODO: map out.MaxPathLen to 0 if it has the -1 default value? (Issue 19285) return .IsCA, .MaxPathLen, nil } // parseExtKeyUsageExtension parses id-ce-extKeyUsage (2.5.29.37) from // RFC 5280 Section 4.2.1.12 func parseExtKeyUsageExtension( []byte) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) { var []asn1.ObjectIdentifier if , := asn1.Unmarshal(, &); != nil { return nil, nil, } else if len() != 0 { return nil, nil, errors.New("x509: trailing data after X.509 ExtendedKeyUsage") } var []ExtKeyUsage var []asn1.ObjectIdentifier for , := range { if , := extKeyUsageFromOID(); { = append(, ) } else { = append(, ) } } return , , nil } // parseSubjectKeyIdExtension parses id-ce-subjectKeyIdentifier (2.5.29.14) // from RFC 5280 Section 4.2.1.2 func parseSubjectKeyIdExtension( []byte) ([]byte, error) { var []byte if , := asn1.Unmarshal(, &); != nil { return nil, } else if len() != 0 { return nil, errors.New("x509: trailing data after X.509 key-id") } return , nil } func parseCertificatePoliciesExtension( []byte) ([]asn1.ObjectIdentifier, error) { var []policyInformation if , := asn1.Unmarshal(, &); != nil { return nil, } else if len() != 0 { return nil, errors.New("x509: trailing data after X.509 certificate policies") } := make([]asn1.ObjectIdentifier, len()) for , := range { [] = .Policy } return , nil } // ParseCertificate parses a single certificate from the given ASN.1 DER data. func ( []byte) (*Certificate, error) { var certificate , := asn1.Unmarshal(, &) if != nil { return nil, } if len() > 0 { return nil, asn1.SyntaxError{Msg: "trailing data"} } return parseCertificate(&) } // ParseCertificates parses one or more certificates from the given ASN.1 DER // data. The certificates must be concatenated with no intermediate padding. func ( []byte) ([]*Certificate, error) { var []*certificate for len() > 0 { := new(certificate) var error , = asn1.Unmarshal(, ) if != nil { return nil, } = append(, ) } := make([]*Certificate, len()) for , := range { , := parseCertificate() if != nil { return nil, } [] = } return , nil } func reverseBitsInAByte( byte) byte { := >>4 | <<4 := >>2&0x33 | <<2&0xcc := >>1&0x55 | <<1&0xaa return } // asn1BitLength returns the bit-length of bitString by considering the // most-significant bit in a byte to be the "first" bit. This convention // matches ASN.1, but differs from almost everything else. func asn1BitLength( []byte) int { := len() * 8 for := range { := [len()--1] for := uint(0); < 8; ++ { if (>>)&1 == 1 { return } -- } } return 0 } var ( oidExtensionSubjectKeyId = []int{2, 5, 29, 14} oidExtensionKeyUsage = []int{2, 5, 29, 15} oidExtensionExtendedKeyUsage = []int{2, 5, 29, 37} oidExtensionAuthorityKeyId = []int{2, 5, 29, 35} oidExtensionBasicConstraints = []int{2, 5, 29, 19} oidExtensionSubjectAltName = []int{2, 5, 29, 17} oidExtensionCertificatePolicies = []int{2, 5, 29, 32} oidExtensionNameConstraints = []int{2, 5, 29, 30} oidExtensionCRLDistributionPoints = []int{2, 5, 29, 31} oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1} oidExtensionCRLNumber = []int{2, 5, 29, 20} ) var ( oidAuthorityInfoAccessOcsp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1} oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2} ) // oidNotInExtensions reports whether an extension with the given oid exists in // extensions. func oidInExtensions( asn1.ObjectIdentifier, []pkix.Extension) bool { for , := range { if .Id.Equal() { return true } } return false } // marshalSANs marshals a list of addresses into a the contents of an X.509 // SubjectAlternativeName extension. func marshalSANs(, []string, []net.IP, []*url.URL) ( []byte, error) { var []asn1.RawValue for , := range { if := isIA5String(); != nil { return nil, } = append(, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte()}) } for , := range { if := isIA5String(); != nil { return nil, } = append(, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte()}) } for , := range { // If possible, we always want to encode IPv4 addresses in 4 bytes. := .To4() if == nil { = } = append(, asn1.RawValue{Tag: nameTypeIP, Class: 2, Bytes: }) } for , := range { := .String() if := isIA5String(); != nil { return nil, } = append(, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte()}) } return asn1.Marshal() } func isIA5String( string) error { for , := range { // Per RFC5280 "IA5String is limited to the set of ASCII characters" if > unicode.MaxASCII { return fmt.Errorf("x509: %q cannot be encoded as an IA5String", ) } } return nil } func buildCertExtensions( *Certificate, bool, []byte, []byte) ( []pkix.Extension, error) { = make([]pkix.Extension, 10 /* maximum number of elements. */) := 0 if .KeyUsage != 0 && !oidInExtensions(oidExtensionKeyUsage, .ExtraExtensions) { [], = marshalKeyUsage(.KeyUsage) if != nil { return nil, } ++ } if (len(.ExtKeyUsage) > 0 || len(.UnknownExtKeyUsage) > 0) && !oidInExtensions(oidExtensionExtendedKeyUsage, .ExtraExtensions) { [], = marshalExtKeyUsage(.ExtKeyUsage, .UnknownExtKeyUsage) if != nil { return nil, } ++ } if .BasicConstraintsValid && !oidInExtensions(oidExtensionBasicConstraints, .ExtraExtensions) { [], = marshalBasicConstraints(.IsCA, .MaxPathLen, .MaxPathLenZero) if != nil { return nil, } ++ } if len() > 0 && !oidInExtensions(oidExtensionSubjectKeyId, .ExtraExtensions) { [].Id = oidExtensionSubjectKeyId [].Value, = asn1.Marshal() if != nil { return } ++ } if len() > 0 && !oidInExtensions(oidExtensionAuthorityKeyId, .ExtraExtensions) { [].Id = oidExtensionAuthorityKeyId [].Value, = asn1.Marshal(authKeyId{}) if != nil { return } ++ } if (len(.OCSPServer) > 0 || len(.IssuingCertificateURL) > 0) && !oidInExtensions(oidExtensionAuthorityInfoAccess, .ExtraExtensions) { [].Id = oidExtensionAuthorityInfoAccess var []authorityInfoAccess for , := range .OCSPServer { = append(, authorityInfoAccess{ Method: oidAuthorityInfoAccessOcsp, Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte()}, }) } for , := range .IssuingCertificateURL { = append(, authorityInfoAccess{ Method: oidAuthorityInfoAccessIssuers, Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte()}, }) } [].Value, = asn1.Marshal() if != nil { return } ++ } if (len(.DNSNames) > 0 || len(.EmailAddresses) > 0 || len(.IPAddresses) > 0 || len(.URIs) > 0) && !oidInExtensions(oidExtensionSubjectAltName, .ExtraExtensions) { [].Id = oidExtensionSubjectAltName // From RFC 5280, Section 4.2.1.6: // “If the subject field contains an empty sequence ... then // subjectAltName extension ... is marked as critical” [].Critical = [].Value, = marshalSANs(.DNSNames, .EmailAddresses, .IPAddresses, .URIs) if != nil { return } ++ } if len(.PolicyIdentifiers) > 0 && !oidInExtensions(oidExtensionCertificatePolicies, .ExtraExtensions) { [], = marshalCertificatePolicies(.PolicyIdentifiers) if != nil { return nil, } ++ } if (len(.PermittedDNSDomains) > 0 || len(.ExcludedDNSDomains) > 0 || len(.PermittedIPRanges) > 0 || len(.ExcludedIPRanges) > 0 || len(.PermittedEmailAddresses) > 0 || len(.ExcludedEmailAddresses) > 0 || len(.PermittedURIDomains) > 0 || len(.ExcludedURIDomains) > 0) && !oidInExtensions(oidExtensionNameConstraints, .ExtraExtensions) { [].Id = oidExtensionNameConstraints [].Critical = .PermittedDNSDomainsCritical := func( *net.IPNet) []byte { := .IP.Mask(.Mask) := make([]byte, 0, len()+len(.Mask)) = append(, ...) = append(, .Mask...) return } := func( []string, []*net.IPNet, []string, []string) ( []byte, error) { var cryptobyte.Builder for , := range { if = isIA5String(); != nil { return nil, } .AddASN1(cryptobyte_asn1.SEQUENCE, func( *cryptobyte.Builder) { .AddASN1(cryptobyte_asn1.Tag(2).ContextSpecific(), func( *cryptobyte.Builder) { .AddBytes([]byte()) }) }) } for , := range { .AddASN1(cryptobyte_asn1.SEQUENCE, func( *cryptobyte.Builder) { .AddASN1(cryptobyte_asn1.Tag(7).ContextSpecific(), func( *cryptobyte.Builder) { .AddBytes(()) }) }) } for , := range { if = isIA5String(); != nil { return nil, } .AddASN1(cryptobyte_asn1.SEQUENCE, func( *cryptobyte.Builder) { .AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific(), func( *cryptobyte.Builder) { .AddBytes([]byte()) }) }) } for , := range { if = isIA5String(); != nil { return nil, } .AddASN1(cryptobyte_asn1.SEQUENCE, func( *cryptobyte.Builder) { .AddASN1(cryptobyte_asn1.Tag(6).ContextSpecific(), func( *cryptobyte.Builder) { .AddBytes([]byte()) }) }) } return .Bytes() } , := (.PermittedDNSDomains, .PermittedIPRanges, .PermittedEmailAddresses, .PermittedURIDomains) if != nil { return nil, } , := (.ExcludedDNSDomains, .ExcludedIPRanges, .ExcludedEmailAddresses, .ExcludedURIDomains) if != nil { return nil, } var cryptobyte.Builder .AddASN1(cryptobyte_asn1.SEQUENCE, func( *cryptobyte.Builder) { if len() > 0 { .AddASN1(cryptobyte_asn1.Tag(0).ContextSpecific().Constructed(), func( *cryptobyte.Builder) { .AddBytes() }) } if len() > 0 { .AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific().Constructed(), func( *cryptobyte.Builder) { .AddBytes() }) } }) [].Value, = .Bytes() if != nil { return nil, } ++ } if len(.CRLDistributionPoints) > 0 && !oidInExtensions(oidExtensionCRLDistributionPoints, .ExtraExtensions) { [].Id = oidExtensionCRLDistributionPoints var []distributionPoint for , := range .CRLDistributionPoints { := distributionPoint{ DistributionPoint: distributionPointName{ FullName: []asn1.RawValue{ {Tag: 6, Class: 2, Bytes: []byte()}, }, }, } = append(, ) } [].Value, = asn1.Marshal() if != nil { return } ++ } // Adding another extension here? Remember to update the maximum number // of elements in the make() at the top of the function and the list of // template fields used in CreateCertificate documentation. return append([:], .ExtraExtensions...), nil } func marshalKeyUsage( KeyUsage) (pkix.Extension, error) { := pkix.Extension{Id: oidExtensionKeyUsage, Critical: true} var [2]byte [0] = reverseBitsInAByte(byte()) [1] = reverseBitsInAByte(byte( >> 8)) := 1 if [1] != 0 { = 2 } := [:] var error .Value, = asn1.Marshal(asn1.BitString{Bytes: , BitLength: asn1BitLength()}) if != nil { return , } return , nil } func marshalExtKeyUsage( []ExtKeyUsage, []asn1.ObjectIdentifier) (pkix.Extension, error) { := pkix.Extension{Id: oidExtensionExtendedKeyUsage} := make([]asn1.ObjectIdentifier, len()+len()) for , := range { if , := oidFromExtKeyUsage(); { [] = } else { return , errors.New("x509: unknown extended key usage") } } copy([len():], ) var error .Value, = asn1.Marshal() if != nil { return , } return , nil } func marshalBasicConstraints( bool, int, bool) (pkix.Extension, error) { := pkix.Extension{Id: oidExtensionBasicConstraints, Critical: true} // Leaving MaxPathLen as zero indicates that no maximum path // length is desired, unless MaxPathLenZero is set. A value of // -1 causes encoding/asn1 to omit the value as desired. if == 0 && ! { = -1 } var error .Value, = asn1.Marshal(basicConstraints{, }) if != nil { return , nil } return , nil } func marshalCertificatePolicies( []asn1.ObjectIdentifier) (pkix.Extension, error) { := pkix.Extension{Id: oidExtensionCertificatePolicies} := make([]policyInformation, len()) for , := range { [].Policy = } var error .Value, = asn1.Marshal() if != nil { return , } return , nil } func buildCSRExtensions( *CertificateRequest) ([]pkix.Extension, error) { var []pkix.Extension if (len(.DNSNames) > 0 || len(.EmailAddresses) > 0 || len(.IPAddresses) > 0 || len(.URIs) > 0) && !oidInExtensions(oidExtensionSubjectAltName, .ExtraExtensions) { , := marshalSANs(.DNSNames, .EmailAddresses, .IPAddresses, .URIs) if != nil { return nil, } = append(, pkix.Extension{ Id: oidExtensionSubjectAltName, Value: , }) } return append(, .ExtraExtensions...), nil } func subjectBytes( *Certificate) ([]byte, error) { if len(.RawSubject) > 0 { return .RawSubject, nil } return asn1.Marshal(.Subject.ToRDNSequence()) } // signingParamsForPublicKey returns the parameters to use for signing with // priv. If requestedSigAlgo is not zero then it overrides the default // signature algorithm. func signingParamsForPublicKey( interface{}, SignatureAlgorithm) ( crypto.Hash, pkix.AlgorithmIdentifier, error) { var PublicKeyAlgorithm switch pub := .(type) { case *rsa.PublicKey: = RSA = crypto.SHA256 .Algorithm = oidSignatureSHA256WithRSA .Parameters = asn1.NullRawValue case *ecdsa.PublicKey: = ECDSA switch .Curve { case elliptic.P224(), elliptic.P256(): = crypto.SHA256 .Algorithm = oidSignatureECDSAWithSHA256 case elliptic.P384(): = crypto.SHA384 .Algorithm = oidSignatureECDSAWithSHA384 case elliptic.P521(): = crypto.SHA512 .Algorithm = oidSignatureECDSAWithSHA512 default: = errors.New("x509: unknown elliptic curve") } case ed25519.PublicKey: = Ed25519 .Algorithm = oidSignatureEd25519 default: = errors.New("x509: only RSA, ECDSA and Ed25519 keys supported") } if != nil { return } if == 0 { return } := false for , := range signatureAlgorithmDetails { if .algo == { if .pubKeyAlgo != { = errors.New("x509: requested SignatureAlgorithm does not match private key type") return } .Algorithm, = .oid, .hash if == 0 && != Ed25519 { = errors.New("x509: cannot sign with hash function requested") return } if .isRSAPSS() { .Parameters = hashToPSSParameters[] } = true break } } if ! { = errors.New("x509: unknown SignatureAlgorithm") } return } // emptyASN1Subject is the ASN.1 DER encoding of an empty Subject, which is // just an empty SEQUENCE. var emptyASN1Subject = []byte{0x30, 0} // CreateCertificate creates a new X.509v3 certificate based on a template. // The following members of template are used: // // - AuthorityKeyId // - BasicConstraintsValid // - CRLDistributionPoints // - DNSNames // - EmailAddresses // - ExcludedDNSDomains // - ExcludedEmailAddresses // - ExcludedIPRanges // - ExcludedURIDomains // - ExtKeyUsage // - ExtraExtensions // - IPAddresses // - IsCA // - IssuingCertificateURL // - KeyUsage // - MaxPathLen // - MaxPathLenZero // - NotAfter // - NotBefore // - OCSPServer // - PermittedDNSDomains // - PermittedDNSDomainsCritical // - PermittedEmailAddresses // - PermittedIPRanges // - PermittedURIDomains // - PolicyIdentifiers // - SerialNumber // - SignatureAlgorithm // - Subject // - SubjectKeyId // - URIs // - UnknownExtKeyUsage // // The certificate is signed by parent. If parent is equal to template then the // certificate is self-signed. The parameter pub is the public key of the // signee and priv is the private key of the signer. // // The returned slice is the certificate in DER encoding. // // The currently supported key types are *rsa.PublicKey, *ecdsa.PublicKey and // ed25519.PublicKey. pub must be a supported key type, and priv must be a // crypto.Signer with a supported public key. // // The AuthorityKeyId will be taken from the SubjectKeyId of parent, if any, // unless the resulting certificate is self-signed. Otherwise the value from // template will be used. // // If SubjectKeyId from template is empty and the template is a CA, SubjectKeyId // will be generated from the hash of the public key. func ( io.Reader, , *Certificate, , interface{}) ( []byte, error) { , := .(crypto.Signer) if ! { return nil, errors.New("x509: certificate private key does not implement crypto.Signer") } if .SerialNumber == nil { return nil, errors.New("x509: no SerialNumber given") } if .BasicConstraintsValid && !.IsCA && .MaxPathLen != -1 && (.MaxPathLen != 0 || .MaxPathLenZero) { return nil, errors.New("x509: only CAs are allowed to specify MaxPathLen") } , , := signingParamsForPublicKey(.Public(), .SignatureAlgorithm) if != nil { return nil, } , , := marshalPublicKey() if != nil { return nil, } , := subjectBytes() if != nil { return } , := subjectBytes() if != nil { return } := .AuthorityKeyId if !bytes.Equal(, ) && len(.SubjectKeyId) > 0 { = .SubjectKeyId } := .SubjectKeyId if len() == 0 && .IsCA { // SubjectKeyId generated using method 1 in RFC 5280, Section 4.2.1.2: // (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the // value of the BIT STRING subjectPublicKey (excluding the tag, // length, and number of unused bits). := sha1.Sum() = [:] } , := buildCertExtensions(, bytes.Equal(, emptyASN1Subject), , ) if != nil { return } := asn1.BitString{BitLength: len() * 8, Bytes: } := tbsCertificate{ Version: 2, SerialNumber: .SerialNumber, SignatureAlgorithm: , Issuer: asn1.RawValue{FullBytes: }, Validity: validity{.NotBefore.UTC(), .NotAfter.UTC()}, Subject: asn1.RawValue{FullBytes: }, PublicKey: publicKeyInfo{nil, , }, Extensions: , } , := asn1.Marshal() if != nil { return } .Raw = := if != 0 { := .New() .Write() = .Sum(nil) } var crypto.SignerOpts = if .SignatureAlgorithm != 0 && .SignatureAlgorithm.isRSAPSS() { = &rsa.PSSOptions{ SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: , } } var []byte , = .Sign(, , ) if != nil { return } , := asn1.Marshal(certificate{ nil, , , asn1.BitString{Bytes: , BitLength: len() * 8}, }) if != nil { return nil, } // Check the signature to ensure the crypto.Signer behaved correctly. // We skip this check if the signature algorithm is MD5WithRSA as we // only support this algorithm for signing, and not verification. if := getSignatureAlgorithmFromAI(); != MD5WithRSA { if := checkSignature(, .Raw, , .Public()); != nil { return nil, fmt.Errorf("x509: signature over certificate returned by signer is invalid: %w", ) } } return , nil } // pemCRLPrefix is the magic string that indicates that we have a PEM encoded // CRL. var pemCRLPrefix = []byte("-----BEGIN X509 CRL") // pemType is the type of a PEM encoded CRL. var pemType = "X509 CRL" // ParseCRL parses a CRL from the given bytes. It's often the case that PEM // encoded CRLs will appear where they should be DER encoded, so this function // will transparently handle PEM encoding as long as there isn't any leading // garbage. func ( []byte) (*pkix.CertificateList, error) { if bytes.HasPrefix(, pemCRLPrefix) { , := pem.Decode() if != nil && .Type == pemType { = .Bytes } } return ParseDERCRL() } // ParseDERCRL parses a DER encoded CRL from the given bytes. func ( []byte) (*pkix.CertificateList, error) { := new(pkix.CertificateList) if , := asn1.Unmarshal(, ); != nil { return nil, } else if len() != 0 { return nil, errors.New("x509: trailing data after CRL") } return , nil } // CreateCRL returns a DER encoded CRL, signed by this Certificate, that // contains the given list of revoked certificates. // // Note: this method does not generate an RFC 5280 conformant X.509 v2 CRL. // To generate a standards compliant CRL, use CreateRevocationList instead. func ( *Certificate) ( io.Reader, interface{}, []pkix.RevokedCertificate, , time.Time) ( []byte, error) { , := .(crypto.Signer) if ! { return nil, errors.New("x509: certificate private key does not implement crypto.Signer") } , , := signingParamsForPublicKey(.Public(), 0) if != nil { return nil, } // Force revocation times to UTC per RFC 5280. := make([]pkix.RevokedCertificate, len()) for , := range { .RevocationTime = .RevocationTime.UTC() [] = } := pkix.TBSCertificateList{ Version: 1, Signature: , Issuer: .Subject.ToRDNSequence(), ThisUpdate: .UTC(), NextUpdate: .UTC(), RevokedCertificates: , } // Authority Key Id if len(.SubjectKeyId) > 0 { var pkix.Extension .Id = oidExtensionAuthorityKeyId .Value, = asn1.Marshal(authKeyId{Id: .SubjectKeyId}) if != nil { return } .Extensions = append(.Extensions, ) } , := asn1.Marshal() if != nil { return } := if != 0 { := .New() .Write() = .Sum(nil) } var []byte , = .Sign(, , ) if != nil { return } return asn1.Marshal(pkix.CertificateList{ TBSCertList: , SignatureAlgorithm: , SignatureValue: asn1.BitString{Bytes: , BitLength: len() * 8}, }) } // CertificateRequest represents a PKCS #10, certificate signature request. type CertificateRequest struct { Raw []byte // Complete ASN.1 DER content (CSR, signature algorithm and signature). RawTBSCertificateRequest []byte // Certificate request info part of raw ASN.1 DER content. RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo. RawSubject []byte // DER encoded Subject. Version int Signature []byte SignatureAlgorithm SignatureAlgorithm PublicKeyAlgorithm PublicKeyAlgorithm PublicKey interface{} Subject pkix.Name // Attributes contains the CSR attributes that can parse as // pkix.AttributeTypeAndValueSET. // // Deprecated: Use Extensions and ExtraExtensions instead for parsing and // generating the requestedExtensions attribute. Attributes []pkix.AttributeTypeAndValueSET // Extensions contains all requested extensions, in raw form. When parsing // CSRs, this can be used to extract extensions that are not parsed by this // package. Extensions []pkix.Extension // ExtraExtensions contains extensions to be copied, raw, into any CSR // marshaled by CreateCertificateRequest. Values override any extensions // that would otherwise be produced based on the other fields but are // overridden by any extensions specified in Attributes. // // The ExtraExtensions field is not populated by ParseCertificateRequest, // see Extensions instead. ExtraExtensions []pkix.Extension // Subject Alternate Name values. DNSNames []string EmailAddresses []string IPAddresses []net.IP URIs []*url.URL } // These structures reflect the ASN.1 structure of X.509 certificate // signature requests (see RFC 2986): type tbsCertificateRequest struct { Raw asn1.RawContent Version int Subject asn1.RawValue PublicKey publicKeyInfo RawAttributes []asn1.RawValue `asn1:"tag:0"` } type certificateRequest struct { Raw asn1.RawContent TBSCSR tbsCertificateRequest SignatureAlgorithm pkix.AlgorithmIdentifier SignatureValue asn1.BitString } // oidExtensionRequest is a PKCS #9 OBJECT IDENTIFIER that indicates requested // extensions in a CSR. var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14} // newRawAttributes converts AttributeTypeAndValueSETs from a template // CertificateRequest's Attributes into tbsCertificateRequest RawAttributes. func newRawAttributes( []pkix.AttributeTypeAndValueSET) ([]asn1.RawValue, error) { var []asn1.RawValue , := asn1.Marshal() if != nil { return nil, } , := asn1.Unmarshal(, &) if != nil { return nil, } if len() != 0 { return nil, errors.New("x509: failed to unmarshal raw CSR Attributes") } return , nil } // parseRawAttributes Unmarshals RawAttributes into AttributeTypeAndValueSETs. func parseRawAttributes( []asn1.RawValue) []pkix.AttributeTypeAndValueSET { var []pkix.AttributeTypeAndValueSET for , := range { var pkix.AttributeTypeAndValueSET , := asn1.Unmarshal(.FullBytes, &) // Ignore attributes that don't parse into pkix.AttributeTypeAndValueSET // (i.e.: challengePassword or unstructuredName). if == nil && len() == 0 { = append(, ) } } return } // parseCSRExtensions parses the attributes from a CSR and extracts any // requested extensions. func parseCSRExtensions( []asn1.RawValue) ([]pkix.Extension, error) { // pkcs10Attribute reflects the Attribute structure from RFC 2986, Section 4.1. type struct { asn1.ObjectIdentifier []asn1.RawValue `asn1:"set"` } var []pkix.Extension for , := range { var if , := asn1.Unmarshal(.FullBytes, &); != nil || len() != 0 || len(.) == 0 { // Ignore attributes that don't parse. continue } if !..Equal(oidExtensionRequest) { continue } var []pkix.Extension if , := asn1.Unmarshal(.[0].FullBytes, &); != nil { return nil, } = append(, ...) } return , nil } // CreateCertificateRequest creates a new certificate request based on a // template. The following members of template are used: // // - SignatureAlgorithm // - Subject // - DNSNames // - EmailAddresses // - IPAddresses // - URIs // - ExtraExtensions // - Attributes (deprecated) // // priv is the private key to sign the CSR with, and the corresponding public // key will be included in the CSR. It must implement crypto.Signer and its // Public() method must return a *rsa.PublicKey or a *ecdsa.PublicKey or a // ed25519.PublicKey. (A *rsa.PrivateKey, *ecdsa.PrivateKey or // ed25519.PrivateKey satisfies this.) // // The returned slice is the certificate request in DER encoding. func ( io.Reader, *CertificateRequest, interface{}) ( []byte, error) { , := .(crypto.Signer) if ! { return nil, errors.New("x509: certificate private key does not implement crypto.Signer") } var crypto.Hash var pkix.AlgorithmIdentifier , , = signingParamsForPublicKey(.Public(), .SignatureAlgorithm) if != nil { return nil, } var []byte var pkix.AlgorithmIdentifier , , = marshalPublicKey(.Public()) if != nil { return nil, } , := buildCSRExtensions() if != nil { return nil, } // Make a copy of template.Attributes because we may alter it below. := make([]pkix.AttributeTypeAndValueSET, 0, len(.Attributes)) for , := range .Attributes { := make([][]pkix.AttributeTypeAndValue, len(.Value)) copy(, .Value) = append(, pkix.AttributeTypeAndValueSET{ Type: .Type, Value: , }) } := false if len() > 0 { // Append the extensions to an existing attribute if possible. for , := range { if !.Type.Equal(oidExtensionRequest) || len(.Value) == 0 { continue } // specifiedExtensions contains all the extensions that we // found specified via template.Attributes. := make(map[string]bool) for , := range .Value { for , := range { [.Type.String()] = true } } := make([]pkix.AttributeTypeAndValue, 0, len(.Value[0])+len()) = append(, .Value[0]...) for , := range { if [.Id.String()] { // Attributes already contained a value for // this extension and it takes priority. continue } = append(, pkix.AttributeTypeAndValue{ // There is no place for the critical // flag in an AttributeTypeAndValue. Type: .Id, Value: .Value, }) } .Value[0] = = true break } } , := newRawAttributes() if != nil { return } // If not included in attributes, add a new attribute for the // extensions. if len() > 0 && ! { := struct { asn1.ObjectIdentifier [][]pkix.Extension `asn1:"set"` }{ : oidExtensionRequest, : [][]pkix.Extension{}, } , := asn1.Marshal() if != nil { return nil, errors.New("x509: failed to serialise extensions attribute: " + .Error()) } var asn1.RawValue if , := asn1.Unmarshal(, &); != nil { return nil, } = append(, ) } := .RawSubject if len() == 0 { , = asn1.Marshal(.Subject.ToRDNSequence()) if != nil { return nil, } } := tbsCertificateRequest{ Version: 0, // PKCS #10, RFC 2986 Subject: asn1.RawValue{FullBytes: }, PublicKey: publicKeyInfo{ Algorithm: , PublicKey: asn1.BitString{ Bytes: , BitLength: len() * 8, }, }, RawAttributes: , } , := asn1.Marshal() if != nil { return } .Raw = := if != 0 { := .New() .Write() = .Sum(nil) } var []byte , = .Sign(, , ) if != nil { return } return asn1.Marshal(certificateRequest{ TBSCSR: , SignatureAlgorithm: , SignatureValue: asn1.BitString{ Bytes: , BitLength: len() * 8, }, }) } // ParseCertificateRequest parses a single certificate request from the // given ASN.1 DER data. func ( []byte) (*CertificateRequest, error) { var certificateRequest , := asn1.Unmarshal(, &) if != nil { return nil, } else if len() != 0 { return nil, asn1.SyntaxError{Msg: "trailing data"} } return parseCertificateRequest(&) } func parseCertificateRequest( *certificateRequest) (*CertificateRequest, error) { := &CertificateRequest{ Raw: .Raw, RawTBSCertificateRequest: .TBSCSR.Raw, RawSubjectPublicKeyInfo: .TBSCSR.PublicKey.Raw, RawSubject: .TBSCSR.Subject.FullBytes, Signature: .SignatureValue.RightAlign(), SignatureAlgorithm: getSignatureAlgorithmFromAI(.SignatureAlgorithm), PublicKeyAlgorithm: getPublicKeyAlgorithmFromOID(.TBSCSR.PublicKey.Algorithm.Algorithm), Version: .TBSCSR.Version, Attributes: parseRawAttributes(.TBSCSR.RawAttributes), } var error .PublicKey, = parsePublicKey(.PublicKeyAlgorithm, &.TBSCSR.PublicKey) if != nil { return nil, } var pkix.RDNSequence if , := asn1.Unmarshal(.TBSCSR.Subject.FullBytes, &); != nil { return nil, } else if len() != 0 { return nil, errors.New("x509: trailing data after X.509 Subject") } .Subject.FillFromRDNSequence(&) if .Extensions, = parseCSRExtensions(.TBSCSR.RawAttributes); != nil { return nil, } for , := range .Extensions { switch { case .Id.Equal(oidExtensionSubjectAltName): .DNSNames, .EmailAddresses, .IPAddresses, .URIs, = parseSANExtension(.Value) if != nil { return nil, } } } return , nil } // CheckSignature reports whether the signature on c is valid. func ( *CertificateRequest) () error { return checkSignature(.SignatureAlgorithm, .RawTBSCertificateRequest, .Signature, .PublicKey) } // RevocationList contains the fields used to create an X.509 v2 Certificate // Revocation list with CreateRevocationList. type RevocationList struct { // SignatureAlgorithm is used to determine the signature algorithm to be // used when signing the CRL. If 0 the default algorithm for the signing // key will be used. SignatureAlgorithm SignatureAlgorithm // RevokedCertificates is used to populate the revokedCertificates // sequence in the CRL, it may be empty. RevokedCertificates may be nil, // in which case an empty CRL will be created. RevokedCertificates []pkix.RevokedCertificate // Number is used to populate the X.509 v2 cRLNumber extension in the CRL, // which should be a monotonically increasing sequence number for a given // CRL scope and CRL issuer. Number *big.Int // ThisUpdate is used to populate the thisUpdate field in the CRL, which // indicates the issuance date of the CRL. ThisUpdate time.Time // NextUpdate is used to populate the nextUpdate field in the CRL, which // indicates the date by which the next CRL will be issued. NextUpdate // must be greater than ThisUpdate. NextUpdate time.Time // ExtraExtensions contains any additional extensions to add directly to // the CRL. ExtraExtensions []pkix.Extension } // CreateRevocationList creates a new X.509 v2 Certificate Revocation List, // according to RFC 5280, based on template. // // The CRL is signed by priv which should be the private key associated with // the public key in the issuer certificate. // // The issuer may not be nil, and the crlSign bit must be set in KeyUsage in // order to use it as a CRL issuer. // // The issuer distinguished name CRL field and authority key identifier // extension are populated using the issuer certificate. issuer must have // SubjectKeyId set. func ( io.Reader, *RevocationList, *Certificate, crypto.Signer) ([]byte, error) { if == nil { return nil, errors.New("x509: template can not be nil") } if == nil { return nil, errors.New("x509: issuer can not be nil") } if (.KeyUsage & KeyUsageCRLSign) == 0 { return nil, errors.New("x509: issuer must have the crlSign key usage bit set") } if len(.SubjectKeyId) == 0 { return nil, errors.New("x509: issuer certificate doesn't contain a subject key identifier") } if .NextUpdate.Before(.ThisUpdate) { return nil, errors.New("x509: template.ThisUpdate is after template.NextUpdate") } if .Number == nil { return nil, errors.New("x509: template contains nil Number field") } , , := signingParamsForPublicKey(.Public(), .SignatureAlgorithm) if != nil { return nil, } // Force revocation times to UTC per RFC 5280. := make([]pkix.RevokedCertificate, len(.RevokedCertificates)) for , := range .RevokedCertificates { .RevocationTime = .RevocationTime.UTC() [] = } , := asn1.Marshal(authKeyId{Id: .SubjectKeyId}) if != nil { return nil, } , := asn1.Marshal(.Number) if != nil { return nil, } := pkix.TBSCertificateList{ Version: 1, // v2 Signature: , Issuer: .Subject.ToRDNSequence(), ThisUpdate: .ThisUpdate.UTC(), NextUpdate: .NextUpdate.UTC(), Extensions: []pkix.Extension{ { Id: oidExtensionAuthorityKeyId, Value: , }, { Id: oidExtensionCRLNumber, Value: , }, }, } if len() > 0 { .RevokedCertificates = } if len(.ExtraExtensions) > 0 { .Extensions = append(.Extensions, .ExtraExtensions...) } , := asn1.Marshal() if != nil { return nil, } := if != 0 { := .New() .Write() = .Sum(nil) } var crypto.SignerOpts = if .SignatureAlgorithm.isRSAPSS() { = &rsa.PSSOptions{ SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: , } } , := .Sign(, , ) if != nil { return nil, } return asn1.Marshal(pkix.CertificateList{ TBSCertList: , SignatureAlgorithm: , SignatureValue: asn1.BitString{Bytes: , BitLength: len() * 8}, }) }