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.
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 ( interface{}) ( []byte,  pkix.AlgorithmIdentifier,  error) {
	switch pub := .(type) {
	case *rsa.PublicKey:
		,  = asn1.Marshal(pkcs1PublicKey{
			N: .N,
			E: .E,
		})
		if  != nil {
			return nil, pkix.AlgorithmIdentifier{}, 
		}
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
}
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.
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 ( pkix.AlgorithmIdentifier) SignatureAlgorithm {
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 }
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 ( 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 ( 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.
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}
)
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.
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.
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.
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.
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.
RFC 5280, 4.2.2.1 (Authority Information Access)
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.)
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.
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.
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 ( 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 ( 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 {
policyQualifiers omitted
}

const (
	nameTypeEmail = 1
	nameTypeDNS   = 2
	nameTypeURI   = 6
	nameTypeIP    = 7
)
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 ( PublicKeyAlgorithm,  *publicKeyInfo) (interface{}, error) {
	 := .PublicKey.RightAlign()
	switch  {
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
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
	}
}

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 ( []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 ( []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
}

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")
	}

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())
				}

				 := 
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", )
					}
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", )
				}

				 := 
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 ( *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 we didn't parse anything then we do the critical check, below.
					 = true
				}

			case 30:
				,  = parseNameConstraintsExtension(, )
				if  != nil {
					return nil, 
				}

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")
				}

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))
						}
					}
				}

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, 
				}
Unknown extensions are recorded if critical.
				 = true
			}
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")
			}

GeneralName: uniformResourceIdentifier [6] IA5String
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 ( []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 ( []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 ( []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 ( []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 ( []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 ( 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 ( []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 ( 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 (,  []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()})
	}
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 ( string) error {
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 ( *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) {
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 ( 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 ( []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 ( bool,  int,  bool) (pkix.Extension, error) {
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 ( []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 ( *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 ( *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 ( 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
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.
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.
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.
Subject Alternate Name values.
These structures reflect the ASN.1 structure of X.509 certificate signature requests (see RFC 2986):
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 ( []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 ( []asn1.RawValue) []pkix.AttributeTypeAndValueSET {
	var  []pkix.AttributeTypeAndValueSET
	for ,  := range  {
		var  pkix.AttributeTypeAndValueSET
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.
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  
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
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  {
Attributes already contained a value for this extension and it takes priority.
					continue
				}

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 ( *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.
RevocationList contains the fields used to create an X.509 v2 Certificate Revocation list with CreateRevocationList.
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.
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.
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.
ThisUpdate is used to populate the thisUpdate field in the CRL, which indicates the issuance date of the CRL.
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.
ExtraExtensions contains any additional extensions to add directly to the CRL.
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},
	})