src/crypto/x509/parser.go GO 1,448 lines View on github.com → Search inside
1// Copyright 2021 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.45package x50967import (8	"bytes"9	"crypto/dsa"10	"crypto/ecdh"11	"crypto/ecdsa"12	"crypto/ed25519"13	"crypto/mldsa"14	"crypto/mlkem"15	"crypto/rsa"16	"crypto/x509/pkix"17	"encoding/asn1"18	"errors"19	"fmt"20	"internal/godebug"21	"math"22	"math/big"23	"net"24	"net/url"25	"strconv"26	"strings"27	"time"28	"unicode/utf16"29	"unicode/utf8"3031	"golang.org/x/crypto/cryptobyte"32	cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"33)3435// isPrintable reports whether the given b is in the ASN.1 PrintableString set.36// This is a simplified version of encoding/asn1.isPrintable.37func isPrintable(b byte) bool {38	return 'a' <= b && b <= 'z' ||39		'A' <= b && b <= 'Z' ||40		'0' <= b && b <= '9' ||41		'\'' <= b && b <= ')' ||42		'+' <= b && b <= '/' ||43		b == ' ' ||44		b == ':' ||45		b == '=' ||46		b == '?' ||47		// This is technically not allowed in a PrintableString.48		// However, x509 certificates with wildcard strings don't49		// always use the correct string type so we permit it.50		b == '*' ||51		// This is not technically allowed either. However, not52		// only is it relatively common, but there are also a53		// handful of CA certificates that contain it. At least54		// one of which will not expire until 2027.55		b == '&'56}5758// parseASN1String parses the ASN.1 string types T61String, PrintableString,59// UTF8String, BMPString, IA5String, and NumericString. This is mostly copied60// from the respective encoding/asn1.parse... methods, rather than just61// increasing the API surface of that package.62func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {63	switch tag {64	case cryptobyte_asn1.T61String:65		// T.61 is a defunct ITU 8-bit character encoding which preceded Unicode.66		// T.61 uses a code page layout that _almost_ exactly maps to the code67		// page layout of the ISO 8859-1 (Latin-1) character encoding, with the68		// exception that a number of characters in Latin-1 are not present69		// in T.61.70		//71		// Instead of mapping which characters are present in Latin-1 but not T.61,72		// we just treat these strings as being encoded using Latin-1. This matches73		// what most of the world does, including BoringSSL.74		buf := make([]byte, 0, len(value))75		for _, v := range value {76			// All the 1-byte UTF-8 runes map 1-1 with Latin-1.77			buf = utf8.AppendRune(buf, rune(v))78		}79		return string(buf), nil80	case cryptobyte_asn1.PrintableString:81		for _, b := range value {82			if !isPrintable(b) {83				return "", errors.New("invalid PrintableString")84			}85		}86		return string(value), nil87	case cryptobyte_asn1.UTF8String:88		if !utf8.Valid(value) {89			return "", errors.New("invalid UTF-8 string")90		}91		return string(value), nil92	case cryptobyte_asn1.Tag(asn1.TagBMPString):93		// BMPString uses the defunct UCS-2 16-bit character encoding, which94		// covers the Basic Multilingual Plane (BMP). UTF-16 was an extension of95		// UCS-2, containing all of the same code points, but also including96		// multi-code point characters (by using surrogate code points). We can97		// treat a UCS-2 encoded string as a UTF-16 encoded string, as long as98		// we reject out the UTF-16 specific code points. This matches the99		// BoringSSL behavior.100101		if len(value)%2 != 0 {102			return "", errors.New("invalid BMPString")103		}104105		// Strip terminator if present.106		if l := len(value); l >= 2 && value[l-1] == 0 && value[l-2] == 0 {107			value = value[:l-2]108		}109110		s := make([]uint16, 0, len(value)/2)111		for len(value) > 0 {112			point := uint16(value[0])<<8 + uint16(value[1])113			// Reject UTF-16 code points that are permanently reserved114			// noncharacters (0xfffe, 0xffff, and 0xfdd0-0xfdef) and surrogates115			// (0xd800-0xdfff).116			if point == 0xfffe || point == 0xffff ||117				(point >= 0xfdd0 && point <= 0xfdef) ||118				(point >= 0xd800 && point <= 0xdfff) {119				return "", errors.New("invalid BMPString")120			}121			s = append(s, point)122			value = value[2:]123		}124125		return string(utf16.Decode(s)), nil126	case cryptobyte_asn1.IA5String:127		s := string(value)128		if isIA5String(s) != nil {129			return "", errors.New("invalid IA5String")130		}131		return s, nil132	case cryptobyte_asn1.Tag(asn1.TagNumericString):133		for _, b := range value {134			if !('0' <= b && b <= '9' || b == ' ') {135				return "", errors.New("invalid NumericString")136			}137		}138		return string(value), nil139	}140	return "", fmt.Errorf("unsupported string type: %v", tag)141}142143// readASN1Any parses types documented at [pkix.AttributeTypeAndValue].144func readASN1Any(der *cryptobyte.String) (any, error) {145	var fullValue cryptobyte.String146	var valueTag cryptobyte_asn1.Tag147	if !der.ReadAnyASN1Element(&fullValue, &valueTag) {148		return nil, errors.New("invalid ASN.1 element")149	}150	switch valueTag {151	case cryptobyte_asn1.T61String, cryptobyte_asn1.PrintableString,152		cryptobyte_asn1.UTF8String, cryptobyte_asn1.Tag(asn1.TagBMPString),153		cryptobyte_asn1.IA5String, cryptobyte_asn1.Tag(asn1.TagNumericString):154		var rawValue []byte155		if !fullValue.ReadASN1((*cryptobyte.String)(&rawValue), valueTag) {156			return nil, errors.New("invalid ASN.1 element")157		}158		return parseASN1String(valueTag, rawValue)159	case cryptobyte_asn1.INTEGER:160		var i int64161		if !fullValue.ReadASN1Integer(&i) {162			return nil, errors.New("invalid ASN.1 integer")163		}164		return i, nil165	case cryptobyte_asn1.BIT_STRING:166		var bs asn1.BitString167		if !fullValue.ReadASN1BitString(&bs) {168			return nil, errors.New("invalid ASN.1 BIT STRING")169		}170		return bs, nil171	case cryptobyte_asn1.OCTET_STRING:172		var s []byte173		if !fullValue.ReadASN1((*cryptobyte.String)(&s), cryptobyte_asn1.OCTET_STRING) {174			return nil, errors.New("invalid ASN.1 OCTET STRING")175		}176		return s, nil177	case cryptobyte_asn1.OBJECT_IDENTIFIER:178		var oid asn1.ObjectIdentifier179		if !fullValue.ReadASN1ObjectIdentifier(&oid) {180			return nil, errors.New("invalid ASN.1 OBJECT IDENTIFIER")181		}182		return oid, nil183	case cryptobyte_asn1.UTCTime, cryptobyte_asn1.GeneralizedTime:184		out, err := readASN1Time(&fullValue)185		return out, err186	case cryptobyte_asn1.BOOLEAN:187		var b bool188		if !fullValue.ReadASN1Boolean(&b) {189			return nil, errors.New("invalid ASN.1 BOOLEAN")190		}191		return b, nil192	case cryptobyte_asn1.NULL:193		return nil, nil194	default:195		var v asn1.RawValue196		v.Class = int(valueTag >> 6)197		v.IsCompound = valueTag&0x20 == 0x20198		v.Tag = int(valueTag & 0x1f)199		v.FullBytes = fullValue200		if !fullValue.ReadAnyASN1((*cryptobyte.String)(&v.Bytes), &valueTag) {201			return nil, errors.New("invalid ASN.1 element")202		}203		return v, nil204	}205}206207// parseName parses a DER encoded Name as defined in RFC 5280. We may208// want to export this function in the future for use in crypto/tls.209func parseName(raw cryptobyte.String) (*pkix.RDNSequence, error) {210	if !raw.ReadASN1(&raw, cryptobyte_asn1.SEQUENCE) {211		return nil, errors.New("x509: invalid RDNSequence")212	}213214	var rdnSeq pkix.RDNSequence215	for !raw.Empty() {216		var rdnSet pkix.RelativeDistinguishedNameSET217		var set cryptobyte.String218		if !raw.ReadASN1(&set, cryptobyte_asn1.SET) {219			return nil, errors.New("x509: invalid RDNSequence")220		}221		for !set.Empty() {222			var atav cryptobyte.String223			if !set.ReadASN1(&atav, cryptobyte_asn1.SEQUENCE) {224				return nil, errors.New("x509: invalid RDNSequence: invalid attribute")225			}226			var attr pkix.AttributeTypeAndValue227			if !atav.ReadASN1ObjectIdentifier(&attr.Type) {228				return nil, errors.New("x509: invalid RDNSequence: invalid attribute type")229			}230			var err error231			attr.Value, err = readASN1Any(&atav)232			if err != nil {233				return nil, fmt.Errorf("x509: invalid RDNSequence: invalid attribute value: %s", err)234			}235			rdnSet = append(rdnSet, attr)236		}237238		rdnSeq = append(rdnSeq, rdnSet)239	}240241	return &rdnSeq, nil242}243244func parseAI(der cryptobyte.String) (pkix.AlgorithmIdentifier, error) {245	ai := pkix.AlgorithmIdentifier{}246	if !der.ReadASN1ObjectIdentifier(&ai.Algorithm) {247		return ai, errors.New("x509: malformed OID")248	}249	if der.Empty() {250		return ai, nil251	}252	var params cryptobyte.String253	var tag cryptobyte_asn1.Tag254	if !der.ReadAnyASN1Element(&params, &tag) {255		return ai, errors.New("x509: malformed parameters")256	}257	ai.Parameters.Tag = int(tag)258	ai.Parameters.FullBytes = params259	return ai, nil260}261262func readASN1Time(der *cryptobyte.String) (time.Time, error) {263	var t time.Time264	switch {265	case der.PeekASN1Tag(cryptobyte_asn1.UTCTime):266		if !der.ReadASN1UTCTime(&t) {267			return t, errors.New("x509: malformed UTCTime")268		}269	case der.PeekASN1Tag(cryptobyte_asn1.GeneralizedTime):270		if !der.ReadASN1GeneralizedTime(&t) {271			return t, errors.New("x509: malformed GeneralizedTime")272		}273	default:274		return t, errors.New("x509: unsupported time format")275	}276	return t, nil277}278279func parseValidity(der cryptobyte.String) (time.Time, time.Time, error) {280	notBefore, err := readASN1Time(&der)281	if err != nil {282		return time.Time{}, time.Time{}, err283	}284	notAfter, err := readASN1Time(&der)285	if err != nil {286		return time.Time{}, time.Time{}, err287	}288289	return notBefore, notAfter, nil290}291292func parseExtension(der cryptobyte.String) (pkix.Extension, error) {293	var ext pkix.Extension294	if !der.ReadASN1ObjectIdentifier(&ext.Id) {295		return ext, errors.New("x509: malformed extension OID field")296	}297	if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {298		if !der.ReadASN1Boolean(&ext.Critical) {299			return ext, errors.New("x509: malformed extension critical field")300		}301	}302	var val cryptobyte.String303	if !der.ReadASN1(&val, cryptobyte_asn1.OCTET_STRING) {304		return ext, errors.New("x509: malformed extension value field")305	}306	ext.Value = val307	return ext, nil308}309310func parsePublicKey(keyData *publicKeyInfo) (any, error) {311	oid := keyData.Algorithm.Algorithm312	params := keyData.Algorithm.Parameters313	data := keyData.PublicKey.RightAlign()314	switch {315	case oid.Equal(oidPublicKeyRSA):316		// RSA public keys must have a NULL in the parameters.317		// See RFC 3279, Section 2.3.1.318		if !bytes.Equal(params.FullBytes, asn1.NullBytes) {319			return nil, errors.New("x509: RSA key missing NULL parameters")320		}321322		der := cryptobyte.String(data)323		p := &pkcs1PublicKey{N: new(big.Int)}324		if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {325			return nil, errors.New("x509: invalid RSA public key")326		}327		if !der.ReadASN1Integer(p.N) {328			return nil, errors.New("x509: invalid RSA modulus")329		}330		if !der.ReadASN1Integer(&p.E) {331			return nil, errors.New("x509: invalid RSA public exponent")332		}333334		if p.N.Sign() <= 0 {335			return nil, errors.New("x509: RSA modulus is not a positive number")336		}337		if p.E <= 0 {338			return nil, errors.New("x509: RSA public exponent is not a positive number")339		}340341		pub := &rsa.PublicKey{342			E: p.E,343			N: p.N,344		}345		return pub, nil346	case oid.Equal(oidPublicKeyECDSA):347		paramsDer := cryptobyte.String(params.FullBytes)348		namedCurveOID := new(asn1.ObjectIdentifier)349		if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {350			return nil, errors.New("x509: invalid ECDSA parameters")351		}352		namedCurve := namedCurveFromOID(*namedCurveOID)353		if namedCurve == nil {354			return nil, errors.New("x509: unsupported elliptic curve")355		}356		return ecdsa.ParseUncompressedPublicKey(namedCurve, data)357	case oid.Equal(oidPublicKeyEd25519):358		// RFC 8410, Section 3359		// > For all of the OIDs, the parameters MUST be absent.360		if len(params.FullBytes) != 0 {361			return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")362		}363		if len(data) != ed25519.PublicKeySize {364			return nil, errors.New("x509: wrong Ed25519 public key size")365		}366		return ed25519.PublicKey(data), nil367	case oid.Equal(oidPublicKeyMLDSA44), oid.Equal(oidPublicKeyMLDSA65), oid.Equal(oidPublicKeyMLDSA87):368		if len(params.FullBytes) != 0 {369			return nil, errors.New("x509: ML-DSA key encoded with illegal parameters")370		}371		params, ok := mldsaParametersFromOID(oid)372		if !ok {373			return nil, errors.New("x509: unsupported ML-DSA parameters")374		}375		return mldsa.NewPublicKey(params, data)376	case oid.Equal(oidPublicKeyX25519):377		// RFC 8410, Section 3378		// > For all of the OIDs, the parameters MUST be absent.379		if len(params.FullBytes) != 0 {380			return nil, errors.New("x509: X25519 key encoded with illegal parameters")381		}382		return ecdh.X25519().NewPublicKey(data)383	case oid.Equal(oidPublicKeyMLKEM768):384		// RFC 9935, Section 3385		// > The parameters field of the AlgorithmIdentifier for the ML-KEM386		// > public key MUST be absent.387		if len(params.FullBytes) != 0 {388			return nil, errors.New("x509: ML-KEM-768 key encoded with illegal parameters")389		}390		return mlkem.NewEncapsulationKey768(data)391	case oid.Equal(oidPublicKeyMLKEM1024):392		if len(params.FullBytes) != 0 {393			return nil, errors.New("x509: ML-KEM-1024 key encoded with illegal parameters")394		}395		return mlkem.NewEncapsulationKey1024(data)396	case oid.Equal(oidPublicKeyDSA):397		der := cryptobyte.String(data)398		y := new(big.Int)399		if !der.ReadASN1Integer(y) {400			return nil, errors.New("x509: invalid DSA public key")401		}402		pub := &dsa.PublicKey{403			Y: y,404			Parameters: dsa.Parameters{405				P: new(big.Int),406				Q: new(big.Int),407				G: new(big.Int),408			},409		}410		paramsDer := cryptobyte.String(params.FullBytes)411		if !paramsDer.ReadASN1(&paramsDer, cryptobyte_asn1.SEQUENCE) ||412			!paramsDer.ReadASN1Integer(pub.Parameters.P) ||413			!paramsDer.ReadASN1Integer(pub.Parameters.Q) ||414			!paramsDer.ReadASN1Integer(pub.Parameters.G) {415			return nil, errors.New("x509: invalid DSA parameters")416		}417		if pub.Y.Sign() <= 0 || pub.Parameters.P.Sign() <= 0 ||418			pub.Parameters.Q.Sign() <= 0 || pub.Parameters.G.Sign() <= 0 {419			return nil, errors.New("x509: zero or negative DSA parameter")420		}421		return pub, nil422	default:423		return nil, errors.New("x509: unknown public key algorithm")424	}425}426427func parseKeyUsageExtension(der cryptobyte.String) (KeyUsage, error) {428	var usageBits asn1.BitString429	if !der.ReadASN1BitString(&usageBits) {430		return 0, errors.New("x509: invalid key usage")431	}432433	var usage int434	for i := 0; i < 9; i++ {435		if usageBits.At(i) != 0 {436			usage |= 1 << uint(i)437		}438	}439	return KeyUsage(usage), nil440}441442func parseBasicConstraintsExtension(der cryptobyte.String) (bool, int, error) {443	var isCA bool444	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {445		return false, 0, errors.New("x509: invalid basic constraints")446	}447	if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {448		if !der.ReadASN1Boolean(&isCA) {449			return false, 0, errors.New("x509: invalid basic constraints")450		}451	}452453	maxPathLen := -1454	if der.PeekASN1Tag(cryptobyte_asn1.INTEGER) {455		var mpl uint456		if !der.ReadASN1Integer(&mpl) || mpl > math.MaxInt {457			return false, 0, errors.New("x509: invalid basic constraints")458		}459		maxPathLen = int(mpl)460	}461462	return isCA, maxPathLen, nil463}464465func forEachSAN(der cryptobyte.String, callback func(tag int, data []byte) error) error {466	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {467		return errors.New("x509: invalid subject alternative names")468	}469	for !der.Empty() {470		var san cryptobyte.String471		var tag cryptobyte_asn1.Tag472		if !der.ReadAnyASN1(&san, &tag) {473			return errors.New("x509: invalid subject alternative name")474		}475		if err := callback(int(tag^0x80), san); err != nil {476			return err477		}478	}479480	return nil481}482483func parseSANExtension(der cryptobyte.String) (dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL, err error) {484	err = forEachSAN(der, func(tag int, data []byte) error {485		switch tag {486		case nameTypeEmail:487			email := string(data)488			if err := isIA5String(email); err != nil {489				return errors.New("x509: SAN rfc822Name is malformed")490			}491			emailAddresses = append(emailAddresses, email)492		case nameTypeDNS:493			name := string(data)494			if err := isIA5String(name); err != nil {495				return errors.New("x509: SAN dNSName is malformed")496			}497			dnsNames = append(dnsNames, string(name))498		case nameTypeURI:499			uriStr := string(data)500			if err := isIA5String(uriStr); err != nil {501				return errors.New("x509: SAN uniformResourceIdentifier is malformed")502			}503			uri, err := url.Parse(uriStr)504			if err != nil {505				return fmt.Errorf("x509: cannot parse URI %q: %s", uriStr, err)506			}507			if len(uri.Host) > 0 && !domainNameValid(uri.Host, false) {508				return fmt.Errorf("x509: cannot parse URI %q: invalid domain", uriStr)509			}510			uris = append(uris, uri)511		case nameTypeIP:512			switch len(data) {513			case net.IPv6len:514				if net.IP(data).To4() != nil {515					return errors.New("x509: SAN iPAddress contains IPv4-mapped IPv6 address")516				}517				ipAddresses = append(ipAddresses, data)518			case net.IPv4len:519				ipAddresses = append(ipAddresses, data)520			default:521				return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len(data)))522			}523		}524525		return nil526	})527528	return529}530531func parseAuthorityKeyIdentifier(e pkix.Extension) ([]byte, error) {532	// RFC 5280, Section 4.2.1.1533	if e.Critical {534		// Conforming CAs MUST mark this extension as non-critical535		return nil, errors.New("x509: authority key identifier incorrectly marked critical")536	}537	val := cryptobyte.String(e.Value)538	var akid cryptobyte.String539	if !val.ReadASN1(&akid, cryptobyte_asn1.SEQUENCE) {540		return nil, errors.New("x509: invalid authority key identifier")541	}542	if akid.PeekASN1Tag(cryptobyte_asn1.Tag(0).ContextSpecific()) {543		if !akid.ReadASN1(&akid, cryptobyte_asn1.Tag(0).ContextSpecific()) {544			return nil, errors.New("x509: invalid authority key identifier")545		}546		return akid, nil547	}548	return nil, nil549}550551func parseExtKeyUsageExtension(der cryptobyte.String) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) {552	var extKeyUsages []ExtKeyUsage553	var unknownUsages []asn1.ObjectIdentifier554	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {555		return nil, nil, errors.New("x509: invalid extended key usages")556	}557	for !der.Empty() {558		var eku asn1.ObjectIdentifier559		if !der.ReadASN1ObjectIdentifier(&eku) {560			return nil, nil, errors.New("x509: invalid extended key usages")561		}562		if extKeyUsage, ok := extKeyUsageFromOID(eku); ok {563			extKeyUsages = append(extKeyUsages, extKeyUsage)564		} else {565			unknownUsages = append(unknownUsages, eku)566		}567	}568	return extKeyUsages, unknownUsages, nil569}570571func parseCertificatePoliciesExtension(der cryptobyte.String) ([]OID, error) {572	var oids []OID573	seenOIDs := map[string]bool{}574	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {575		return nil, errors.New("x509: invalid certificate policies")576	}577	for !der.Empty() {578		var cp cryptobyte.String579		var OIDBytes cryptobyte.String580		if !der.ReadASN1(&cp, cryptobyte_asn1.SEQUENCE) || !cp.ReadASN1(&OIDBytes, cryptobyte_asn1.OBJECT_IDENTIFIER) {581			return nil, errors.New("x509: invalid certificate policies")582		}583		if seenOIDs[string(OIDBytes)] {584			return nil, errors.New("x509: invalid certificate policies")585		}586		seenOIDs[string(OIDBytes)] = true587		oid, ok := newOIDFromDER(OIDBytes)588		if !ok {589			return nil, errors.New("x509: invalid certificate policies")590		}591		oids = append(oids, oid)592	}593	return oids, nil594}595596// isValidIPMask reports whether mask consists of zero or more 1 bits, followed by zero bits.597func isValidIPMask(mask []byte) bool {598	seenZero := false599600	for _, b := range mask {601		if seenZero {602			if b != 0 {603				return false604			}605606			continue607		}608609		switch b {610		case 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe:611			seenZero = true612		case 0xff:613		default:614			return false615		}616	}617618	return true619}620621func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandled bool, err error) {622	// RFC 5280, 4.2.1.10623624	// NameConstraints ::= SEQUENCE {625	//      permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,626	//      excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }627	//628	// GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree629	//630	// GeneralSubtree ::= SEQUENCE {631	//      base                    GeneralName,632	//      minimum         [0]     BaseDistance DEFAULT 0,633	//      maximum         [1]     BaseDistance OPTIONAL }634	//635	// BaseDistance ::= INTEGER (0..MAX)636637	outer := cryptobyte.String(e.Value)638	var toplevel, permitted, excluded cryptobyte.String639	var havePermitted, haveExcluded bool640	if !outer.ReadASN1(&toplevel, cryptobyte_asn1.SEQUENCE) ||641		!outer.Empty() ||642		!toplevel.ReadOptionalASN1(&permitted, &havePermitted, cryptobyte_asn1.Tag(0).ContextSpecific().Constructed()) ||643		!toplevel.ReadOptionalASN1(&excluded, &haveExcluded, cryptobyte_asn1.Tag(1).ContextSpecific().Constructed()) ||644		!toplevel.Empty() {645		return false, errors.New("x509: invalid NameConstraints extension")646	}647648	if !havePermitted && !haveExcluded || len(permitted) == 0 && len(excluded) == 0 {649		// From RFC 5280, Section 4.2.1.10:650		//   “either the permittedSubtrees field651		//   or the excludedSubtrees MUST be652		//   present”653		return false, errors.New("x509: empty name constraints extension")654	}655656	getValues := func(subtrees cryptobyte.String) (dnsNames []string, ips []*net.IPNet, emails, uriDomains []string, err error) {657		for !subtrees.Empty() {658			var seq, value cryptobyte.String659			var tag cryptobyte_asn1.Tag660			if !subtrees.ReadASN1(&seq, cryptobyte_asn1.SEQUENCE) ||661				!seq.ReadAnyASN1(&value, &tag) {662				return nil, nil, nil, nil, fmt.Errorf("x509: invalid NameConstraints extension")663			}664665			var (666				dnsTag   = cryptobyte_asn1.Tag(2).ContextSpecific()667				emailTag = cryptobyte_asn1.Tag(1).ContextSpecific()668				ipTag    = cryptobyte_asn1.Tag(7).ContextSpecific()669				uriTag   = cryptobyte_asn1.Tag(6).ContextSpecific()670			)671672			switch tag {673			case dnsTag:674				domain := string(value)675				if err := isIA5String(domain); err != nil {676					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())677				}678679				if !domainNameValid(domain, true) {680					return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", domain)681				}682				dnsNames = append(dnsNames, domain)683684			case ipTag:685				l := len(value)686				var ip, mask []byte687688				switch l {689				case 8:690					ip = value[:4]691					mask = value[4:]692693				case 32:694					ip = value[:16]695					mask = value[16:]696697				default:698					return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained value of length %d", l)699				}700701				if !isValidIPMask(mask) {702					return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained invalid mask %x", mask)703				}704705				if len(ip) == net.IPv6len && net.IP(ip).To4() != nil {706					return nil, nil, nil, nil, errors.New("x509: IP constraint contained IPv4-mapped IPv6 address")707				}708709				ips = append(ips, &net.IPNet{IP: net.IP(ip), Mask: net.IPMask(mask)})710711			case emailTag:712				constraint := string(value)713				if err := isIA5String(constraint); err != nil {714					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())715				}716717				// If the constraint contains an @ then718				// it specifies an exact mailbox name.719				if strings.Contains(constraint, "@") {720					if _, ok := parseRFC2821Mailbox(constraint); !ok {721						return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)722					}723				} else {724					if !domainNameValid(constraint, true) {725						return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)726					}727				}728				emails = append(emails, constraint)729730			case uriTag:731				domain := string(value)732				if err := isIA5String(domain); err != nil {733					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())734				}735736				if net.ParseIP(domain) != nil {737					return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q: cannot be IP address", domain)738				}739740				if !domainNameValid(domain, true) {741					return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q", domain)742				}743				uriDomains = append(uriDomains, domain)744745			default:746				unhandled = true747			}748		}749750		return dnsNames, ips, emails, uriDomains, nil751	}752753	if out.PermittedDNSDomains, out.PermittedIPRanges, out.PermittedEmailAddresses, out.PermittedURIDomains, err = getValues(permitted); err != nil {754		return false, err755	}756	if out.ExcludedDNSDomains, out.ExcludedIPRanges, out.ExcludedEmailAddresses, out.ExcludedURIDomains, err = getValues(excluded); err != nil {757		return false, err758	}759	out.PermittedDNSDomainsCritical = e.Critical760761	return unhandled, nil762}763764func processExtensions(out *Certificate) error {765	var err error766	for _, e := range out.Extensions {767		unhandled := false768769		if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 {770			switch e.Id[3] {771			case 15:772				out.KeyUsage, err = parseKeyUsageExtension(e.Value)773				if err != nil {774					return err775				}776			case 19:777				out.IsCA, out.MaxPathLen, err = parseBasicConstraintsExtension(e.Value)778				if err != nil {779					return err780				}781				out.BasicConstraintsValid = true782				out.MaxPathLenZero = out.MaxPathLen == 0783			case 17:784				out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(e.Value)785				if err != nil {786					return err787				}788789				if len(out.DNSNames) == 0 && len(out.EmailAddresses) == 0 && len(out.IPAddresses) == 0 && len(out.URIs) == 0 {790					// If we didn't parse anything then we do the critical check, below.791					unhandled = true792				}793794			case 30:795				unhandled, err = parseNameConstraintsExtension(out, e)796				if err != nil {797					return err798				}799800			case 31:801				// RFC 5280, 4.2.1.13802803				// CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint804				//805				// DistributionPoint ::= SEQUENCE {806				//     distributionPoint       [0]     DistributionPointName OPTIONAL,807				//     reasons                 [1]     ReasonFlags OPTIONAL,808				//     cRLIssuer               [2]     GeneralNames OPTIONAL }809				//810				// DistributionPointName ::= CHOICE {811				//     fullName                [0]     GeneralNames,812				//     nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }813				val := cryptobyte.String(e.Value)814				if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {815					return errors.New("x509: invalid CRL distribution points")816				}817				for !val.Empty() {818					var dpDER cryptobyte.String819					if !val.ReadASN1(&dpDER, cryptobyte_asn1.SEQUENCE) {820						return errors.New("x509: invalid CRL distribution point")821					}822					var dpNameDER cryptobyte.String823					var dpNamePresent bool824					if !dpDER.ReadOptionalASN1(&dpNameDER, &dpNamePresent, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {825						return errors.New("x509: invalid CRL distribution point")826					}827					if !dpNamePresent {828						continue829					}830					if !dpNameDER.ReadASN1(&dpNameDER, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {831						return errors.New("x509: invalid CRL distribution point")832					}833					for !dpNameDER.Empty() {834						if !dpNameDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {835							break836						}837						var uri cryptobyte.String838						if !dpNameDER.ReadASN1(&uri, cryptobyte_asn1.Tag(6).ContextSpecific()) {839							return errors.New("x509: invalid CRL distribution point")840						}841						out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(uri))842					}843				}844845			case 35:846				out.AuthorityKeyId, err = parseAuthorityKeyIdentifier(e)847				if err != nil {848					return err849				}850			case 36:851				val := cryptobyte.String(e.Value)852				if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {853					return errors.New("x509: invalid policy constraints extension")854				}855				if val.PeekASN1Tag(cryptobyte_asn1.Tag(0).ContextSpecific()) {856					var v int64857					if !val.ReadASN1Int64WithTag(&v, cryptobyte_asn1.Tag(0).ContextSpecific()) {858						return errors.New("x509: invalid policy constraints extension")859					}860					out.RequireExplicitPolicy = int(v)861					// Check for overflow.862					if int64(out.RequireExplicitPolicy) != v {863						return errors.New("x509: policy constraints requireExplicitPolicy field overflows int")864					}865					out.RequireExplicitPolicyZero = out.RequireExplicitPolicy == 0866				}867				if val.PeekASN1Tag(cryptobyte_asn1.Tag(1).ContextSpecific()) {868					var v int64869					if !val.ReadASN1Int64WithTag(&v, cryptobyte_asn1.Tag(1).ContextSpecific()) {870						return errors.New("x509: invalid policy constraints extension")871					}872					out.InhibitPolicyMapping = int(v)873					// Check for overflow.874					if int64(out.InhibitPolicyMapping) != v {875						return errors.New("x509: policy constraints inhibitPolicyMapping field overflows int")876					}877					out.InhibitPolicyMappingZero = out.InhibitPolicyMapping == 0878				}879			case 37:880				out.ExtKeyUsage, out.UnknownExtKeyUsage, err = parseExtKeyUsageExtension(e.Value)881				if err != nil {882					return err883				}884			case 14: // RFC 5280, 4.2.1.2885				if e.Critical {886					// Conforming CAs MUST mark this extension as non-critical887					return errors.New("x509: subject key identifier incorrectly marked critical")888				}889				val := cryptobyte.String(e.Value)890				var skid cryptobyte.String891				if !val.ReadASN1(&skid, cryptobyte_asn1.OCTET_STRING) {892					return errors.New("x509: invalid subject key identifier")893				}894				out.SubjectKeyId = skid895			case 32:896				out.Policies, err = parseCertificatePoliciesExtension(e.Value)897				if err != nil {898					return err899				}900				out.PolicyIdentifiers = make([]asn1.ObjectIdentifier, 0, len(out.Policies))901				for _, oid := range out.Policies {902					if oid, ok := oid.toASN1OID(); ok {903						out.PolicyIdentifiers = append(out.PolicyIdentifiers, oid)904					}905				}906			case 33:907				val := cryptobyte.String(e.Value)908				if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {909					return errors.New("x509: invalid policy mappings extension")910				}911				for !val.Empty() {912					var s cryptobyte.String913					var issuer, subject cryptobyte.String914					if !val.ReadASN1(&s, cryptobyte_asn1.SEQUENCE) ||915						!s.ReadASN1(&issuer, cryptobyte_asn1.OBJECT_IDENTIFIER) ||916						!s.ReadASN1(&subject, cryptobyte_asn1.OBJECT_IDENTIFIER) {917						return errors.New("x509: invalid policy mappings extension")918					}919					out.PolicyMappings = append(out.PolicyMappings, PolicyMapping{OID{issuer}, OID{subject}})920				}921			case 54:922				val := cryptobyte.String(e.Value)923				if !val.ReadASN1Integer(&out.InhibitAnyPolicy) {924					return errors.New("x509: invalid inhibit any policy extension")925				}926				out.InhibitAnyPolicyZero = out.InhibitAnyPolicy == 0927			default:928				// Unknown extensions are recorded if critical.929				unhandled = true930			}931		} else if e.Id.Equal(oidExtensionAuthorityInfoAccess) {932			// RFC 5280 4.2.2.1: Authority Information Access933			if e.Critical {934				// Conforming CAs MUST mark this extension as non-critical935				return errors.New("x509: authority info access incorrectly marked critical")936			}937			val := cryptobyte.String(e.Value)938			if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {939				return errors.New("x509: invalid authority info access")940			}941			for !val.Empty() {942				var aiaDER cryptobyte.String943				if !val.ReadASN1(&aiaDER, cryptobyte_asn1.SEQUENCE) {944					return errors.New("x509: invalid authority info access")945				}946				var method asn1.ObjectIdentifier947				if !aiaDER.ReadASN1ObjectIdentifier(&method) {948					return errors.New("x509: invalid authority info access")949				}950				if !aiaDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {951					continue952				}953				if !aiaDER.ReadASN1(&aiaDER, cryptobyte_asn1.Tag(6).ContextSpecific()) {954					return errors.New("x509: invalid authority info access")955				}956				switch {957				case method.Equal(oidAuthorityInfoAccessOcsp):958					out.OCSPServer = append(out.OCSPServer, string(aiaDER))959				case method.Equal(oidAuthorityInfoAccessIssuers):960					out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(aiaDER))961				}962			}963		} else {964			// Unknown extensions are recorded if critical.965			unhandled = true966		}967968		if e.Critical && unhandled {969			out.UnhandledCriticalExtensions = append(out.UnhandledCriticalExtensions, e.Id)970		}971	}972973	return nil974}975976var x509negativeserial = godebug.New("x509negativeserial")977978func parseCertificate(der []byte) (*Certificate, error) {979	cert := &Certificate{}980981	input := cryptobyte.String(der)982	// we read the SEQUENCE including length and tag bytes so that983	// we can populate Certificate.Raw, before unwrapping the984	// SEQUENCE so it can be operated on985	if !input.ReadASN1Element(&input, cryptobyte_asn1.SEQUENCE) {986		return nil, errors.New("x509: malformed certificate")987	}988	cert.Raw = input989	if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) {990		return nil, errors.New("x509: malformed certificate")991	}992993	var tbs cryptobyte.String994	// do the same trick again as above to extract the raw995	// bytes for Certificate.RawTBSCertificate996	if !input.ReadASN1Element(&tbs, cryptobyte_asn1.SEQUENCE) {997		return nil, errors.New("x509: malformed tbs certificate")998	}999	cert.RawTBSCertificate = tbs1000	if !tbs.ReadASN1(&tbs, cryptobyte_asn1.SEQUENCE) {1001		return nil, errors.New("x509: malformed tbs certificate")1002	}10031004	if !tbs.ReadOptionalASN1Integer(&cert.Version, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific(), 0) {1005		return nil, errors.New("x509: malformed version")1006	}1007	if cert.Version < 0 {1008		return nil, errors.New("x509: malformed version")1009	}1010	// for backwards compat reasons Version is one-indexed,1011	// rather than zero-indexed as defined in 52801012	cert.Version++1013	if cert.Version > 3 {1014		return nil, errors.New("x509: invalid version")1015	}10161017	serial := new(big.Int)1018	if !tbs.ReadASN1Integer(serial) {1019		return nil, errors.New("x509: malformed serial number")1020	}1021	if serial.Sign() == -1 {1022		if x509negativeserial.Value() != "1" {1023			return nil, errors.New("x509: negative serial number")1024		} else {1025			x509negativeserial.IncNonDefault()1026		}1027	}1028	cert.SerialNumber = serial10291030	var sigAISeq cryptobyte.String1031	if !tbs.ReadASN1Element(&sigAISeq, cryptobyte_asn1.SEQUENCE) {1032		return nil, errors.New("x509: malformed signature algorithm identifier")1033	}1034	cert.RawSignatureAlgorithm = sigAISeq1035	if !sigAISeq.ReadASN1(&sigAISeq, cryptobyte_asn1.SEQUENCE) {1036		return nil, errors.New("x509: malformed signature algorithm identifier")1037	}1038	// Before parsing the inner algorithm identifier, extract1039	// the outer algorithm identifier and make sure that they1040	// match.1041	var outerSigAISeq cryptobyte.String1042	if !input.ReadASN1(&outerSigAISeq, cryptobyte_asn1.SEQUENCE) {1043		return nil, errors.New("x509: malformed algorithm identifier")1044	}1045	if !bytes.Equal(outerSigAISeq, sigAISeq) {1046		return nil, errors.New("x509: inner and outer signature algorithm identifiers don't match")1047	}1048	sigAI, err := parseAI(sigAISeq)1049	if err != nil {1050		return nil, err1051	}1052	cert.SignatureAlgorithm = getSignatureAlgorithmFromAI(sigAI)10531054	var issuerSeq cryptobyte.String1055	if !tbs.ReadASN1Element(&issuerSeq, cryptobyte_asn1.SEQUENCE) {1056		return nil, errors.New("x509: malformed issuer")1057	}1058	cert.RawIssuer = issuerSeq1059	issuerRDNs, err := parseName(issuerSeq)1060	if err != nil {1061		return nil, err1062	}1063	cert.Issuer.FillFromRDNSequence(issuerRDNs)10641065	var validity cryptobyte.String1066	if !tbs.ReadASN1(&validity, cryptobyte_asn1.SEQUENCE) {1067		return nil, errors.New("x509: malformed validity")1068	}1069	cert.NotBefore, cert.NotAfter, err = parseValidity(validity)1070	if err != nil {1071		return nil, err1072	}10731074	var subjectSeq cryptobyte.String1075	if !tbs.ReadASN1Element(&subjectSeq, cryptobyte_asn1.SEQUENCE) {1076		return nil, errors.New("x509: malformed issuer")1077	}1078	cert.RawSubject = subjectSeq1079	subjectRDNs, err := parseName(subjectSeq)1080	if err != nil {1081		return nil, err1082	}1083	cert.Subject.FillFromRDNSequence(subjectRDNs)10841085	var spki cryptobyte.String1086	if !tbs.ReadASN1Element(&spki, cryptobyte_asn1.SEQUENCE) {1087		return nil, errors.New("x509: malformed spki")1088	}1089	cert.RawSubjectPublicKeyInfo = spki1090	if !spki.ReadASN1(&spki, cryptobyte_asn1.SEQUENCE) {1091		return nil, errors.New("x509: malformed spki")1092	}1093	var pkAISeq cryptobyte.String1094	if !spki.ReadASN1(&pkAISeq, cryptobyte_asn1.SEQUENCE) {1095		return nil, errors.New("x509: malformed public key algorithm identifier")1096	}1097	pkAI, err := parseAI(pkAISeq)1098	if err != nil {1099		return nil, err1100	}1101	cert.PublicKeyAlgorithm = getPublicKeyAlgorithmFromOID(pkAI.Algorithm)1102	var spk asn1.BitString1103	if !spki.ReadASN1BitString(&spk) {1104		return nil, errors.New("x509: malformed subjectPublicKey")1105	}1106	if cert.PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {1107		cert.PublicKey, err = parsePublicKey(&publicKeyInfo{1108			Algorithm: pkAI,1109			PublicKey: spk,1110		})1111		if err != nil {1112			return nil, err1113		}1114	}11151116	if cert.Version > 1 {1117		if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(1).ContextSpecific()) {1118			return nil, errors.New("x509: malformed issuerUniqueID")1119		}1120		if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(2).ContextSpecific()) {1121			return nil, errors.New("x509: malformed subjectUniqueID")1122		}1123		if cert.Version == 3 {1124			var extensions cryptobyte.String1125			var present bool1126			if !tbs.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.Tag(3).Constructed().ContextSpecific()) {1127				return nil, errors.New("x509: malformed extensions")1128			}1129			if present {1130				seenExts := make(map[string]bool)1131				if !extensions.ReadASN1(&extensions, cryptobyte_asn1.SEQUENCE) {1132					return nil, errors.New("x509: malformed extensions")1133				}1134				for !extensions.Empty() {1135					var extension cryptobyte.String1136					if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {1137						return nil, errors.New("x509: malformed extension")1138					}1139					ext, err := parseExtension(extension)1140					if err != nil {1141						return nil, err1142					}1143					oidStr := ext.Id.String()1144					if seenExts[oidStr] {1145						return nil, fmt.Errorf("x509: certificate contains duplicate extension with OID %q", oidStr)1146					}1147					seenExts[oidStr] = true1148					cert.Extensions = append(cert.Extensions, ext)1149				}1150				err = processExtensions(cert)1151				if err != nil {1152					return nil, err1153				}1154			}1155		}1156	}11571158	var signature asn1.BitString1159	if !input.ReadASN1BitString(&signature) {1160		return nil, errors.New("x509: malformed signature")1161	}1162	cert.Signature = signature.RightAlign()11631164	return cert, nil1165}11661167// ParseCertificate parses a single certificate from the given ASN.1 DER data.1168//1169// Before Go 1.23, ParseCertificate accepted certificates with negative serial1170// numbers. This behavior can be restored by including "x509negativeserial=1" in1171// the GODEBUG environment variable.1172func ParseCertificate(der []byte) (*Certificate, error) {1173	cert, err := parseCertificate(der)1174	if err != nil {1175		return nil, err1176	}1177	if len(der) != len(cert.Raw) {1178		return nil, errors.New("x509: trailing data")1179	}1180	return cert, nil1181}11821183// ParseCertificates parses one or more certificates from the given ASN.1 DER1184// data. The certificates must be concatenated with no intermediate padding.1185func ParseCertificates(der []byte) ([]*Certificate, error) {1186	var certs []*Certificate1187	for len(der) > 0 {1188		cert, err := parseCertificate(der)1189		if err != nil {1190			return nil, err1191		}1192		certs = append(certs, cert)1193		der = der[len(cert.Raw):]1194	}1195	return certs, nil1196}11971198// The X.509 standards confusingly 1-indexed the version names, but 0-indexed1199// the actual encoded version, so the version for X.509v2 is 1.1200const x509v2Version = 112011202// ParseRevocationList parses a X509 v2 [Certificate] Revocation List from the given1203// ASN.1 DER data.1204func ParseRevocationList(der []byte) (*RevocationList, error) {1205	rl := &RevocationList{}12061207	input := cryptobyte.String(der)1208	// we read the SEQUENCE including length and tag bytes so that1209	// we can populate RevocationList.Raw, before unwrapping the1210	// SEQUENCE so it can be operated on1211	if !input.ReadASN1Element(&input, cryptobyte_asn1.SEQUENCE) {1212		return nil, errors.New("x509: malformed crl")1213	}1214	rl.Raw = input1215	if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) {1216		return nil, errors.New("x509: malformed crl")1217	}12181219	var tbs cryptobyte.String1220	// do the same trick again as above to extract the raw1221	// bytes for Certificate.RawTBSCertificate1222	if !input.ReadASN1Element(&tbs, cryptobyte_asn1.SEQUENCE) {1223		return nil, errors.New("x509: malformed tbs crl")1224	}1225	rl.RawTBSRevocationList = tbs1226	if !tbs.ReadASN1(&tbs, cryptobyte_asn1.SEQUENCE) {1227		return nil, errors.New("x509: malformed tbs crl")1228	}12291230	var version int1231	if !tbs.PeekASN1Tag(cryptobyte_asn1.INTEGER) {1232		return nil, errors.New("x509: unsupported crl version")1233	}1234	if !tbs.ReadASN1Integer(&version) {1235		return nil, errors.New("x509: malformed crl")1236	}1237	if version != x509v2Version {1238		return nil, fmt.Errorf("x509: unsupported crl version: %d", version)1239	}12401241	var sigAISeq cryptobyte.String1242	if !tbs.ReadASN1Element(&sigAISeq, cryptobyte_asn1.SEQUENCE) {1243		return nil, errors.New("x509: malformed signature algorithm identifier")1244	}1245	rl.RawSignatureAlgorithm = sigAISeq1246	if !sigAISeq.ReadASN1(&sigAISeq, cryptobyte_asn1.SEQUENCE) {1247		return nil, errors.New("x509: malformed signature algorithm identifier")1248	}1249	// Before parsing the inner algorithm identifier, extract1250	// the outer algorithm identifier and make sure that they1251	// match.1252	var outerSigAISeq cryptobyte.String1253	if !input.ReadASN1(&outerSigAISeq, cryptobyte_asn1.SEQUENCE) {1254		return nil, errors.New("x509: malformed algorithm identifier")1255	}1256	if !bytes.Equal(outerSigAISeq, sigAISeq) {1257		return nil, errors.New("x509: inner and outer signature algorithm identifiers don't match")1258	}1259	sigAI, err := parseAI(sigAISeq)1260	if err != nil {1261		return nil, err1262	}1263	rl.SignatureAlgorithm = getSignatureAlgorithmFromAI(sigAI)12641265	var signature asn1.BitString1266	if !input.ReadASN1BitString(&signature) {1267		return nil, errors.New("x509: malformed signature")1268	}1269	rl.Signature = signature.RightAlign()12701271	var issuerSeq cryptobyte.String1272	if !tbs.ReadASN1Element(&issuerSeq, cryptobyte_asn1.SEQUENCE) {1273		return nil, errors.New("x509: malformed issuer")1274	}1275	rl.RawIssuer = issuerSeq1276	issuerRDNs, err := parseName(issuerSeq)1277	if err != nil {1278		return nil, err1279	}1280	rl.Issuer.FillFromRDNSequence(issuerRDNs)12811282	rl.ThisUpdate, err = readASN1Time(&tbs)1283	if err != nil {1284		return nil, err1285	}1286	if tbs.PeekASN1Tag(cryptobyte_asn1.GeneralizedTime) || tbs.PeekASN1Tag(cryptobyte_asn1.UTCTime) {1287		rl.NextUpdate, err = readASN1Time(&tbs)1288		if err != nil {1289			return nil, err1290		}1291	}12921293	if tbs.PeekASN1Tag(cryptobyte_asn1.SEQUENCE) {1294		var revokedSeq cryptobyte.String1295		if !tbs.ReadASN1(&revokedSeq, cryptobyte_asn1.SEQUENCE) {1296			return nil, errors.New("x509: malformed crl")1297		}1298		for !revokedSeq.Empty() {1299			rce := RevocationListEntry{}13001301			var certSeq cryptobyte.String1302			if !revokedSeq.ReadASN1Element(&certSeq, cryptobyte_asn1.SEQUENCE) {1303				return nil, errors.New("x509: malformed crl")1304			}1305			rce.Raw = certSeq1306			if !certSeq.ReadASN1(&certSeq, cryptobyte_asn1.SEQUENCE) {1307				return nil, errors.New("x509: malformed crl")1308			}13091310			rce.SerialNumber = new(big.Int)1311			if !certSeq.ReadASN1Integer(rce.SerialNumber) {1312				return nil, errors.New("x509: malformed serial number")1313			}1314			rce.RevocationTime, err = readASN1Time(&certSeq)1315			if err != nil {1316				return nil, err1317			}1318			var extensions cryptobyte.String1319			var present bool1320			if !certSeq.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.SEQUENCE) {1321				return nil, errors.New("x509: malformed extensions")1322			}1323			if present {1324				for !extensions.Empty() {1325					var extension cryptobyte.String1326					if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {1327						return nil, errors.New("x509: malformed extension")1328					}1329					ext, err := parseExtension(extension)1330					if err != nil {1331						return nil, err1332					}1333					if ext.Id.Equal(oidExtensionReasonCode) {1334						val := cryptobyte.String(ext.Value)1335						if !val.ReadASN1Enum(&rce.ReasonCode) {1336							return nil, fmt.Errorf("x509: malformed reasonCode extension")1337						}1338					}1339					rce.Extensions = append(rce.Extensions, ext)1340				}1341			}13421343			rl.RevokedCertificateEntries = append(rl.RevokedCertificateEntries, rce)1344			rcDeprecated := pkix.RevokedCertificate{1345				SerialNumber:   rce.SerialNumber,1346				RevocationTime: rce.RevocationTime,1347				Extensions:     rce.Extensions,1348			}1349			rl.RevokedCertificates = append(rl.RevokedCertificates, rcDeprecated)1350		}1351	}13521353	var extensions cryptobyte.String1354	var present bool1355	if !tbs.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {1356		return nil, errors.New("x509: malformed extensions")1357	}1358	if present {1359		if !extensions.ReadASN1(&extensions, cryptobyte_asn1.SEQUENCE) {1360			return nil, errors.New("x509: malformed extensions")1361		}1362		for !extensions.Empty() {1363			var extension cryptobyte.String1364			if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {1365				return nil, errors.New("x509: malformed extension")1366			}1367			ext, err := parseExtension(extension)1368			if err != nil {1369				return nil, err1370			}1371			if ext.Id.Equal(oidExtensionAuthorityKeyId) {1372				rl.AuthorityKeyId, err = parseAuthorityKeyIdentifier(ext)1373				if err != nil {1374					return nil, err1375				}1376			} else if ext.Id.Equal(oidExtensionCRLNumber) {1377				value := cryptobyte.String(ext.Value)1378				rl.Number = new(big.Int)1379				if !value.ReadASN1Integer(rl.Number) {1380					return nil, errors.New("x509: malformed crl number")1381				}1382			}1383			rl.Extensions = append(rl.Extensions, ext)1384		}1385	}13861387	return rl, nil1388}13891390// domainNameValid is an alloc-less version of the checks that1391// domainToReverseLabels does.1392func domainNameValid(s string, constraint bool) bool {1393	// TODO(#75835): This function omits a number of checks which we1394	// really should be doing to enforce that domain names are valid names per1395	// RFC 1034. We previously enabled these checks, but this broke a1396	// significant number of certificates we previously considered valid, and we1397	// happily create via CreateCertificate (et al). We should enable these1398	// checks, but will need to gate them behind a GODEBUG.1399	//1400	// I have left the checks we previously enabled, noted with "TODO(#75835)" so1401	// that we can easily re-enable them once we unbreak everyone.14021403	// TODO(#75835): this should only be true for constraints.1404	if len(s) == 0 {1405		return true1406	}14071408	// Do not allow trailing period (FQDN format is not allowed in SANs or1409	// constraints).1410	if s[len(s)-1] == '.' {1411		return false1412	}14131414	// TODO(#75835): domains must have at least one label, cannot have1415	// a leading empty label, and cannot be longer than 253 characters.1416	// if len(s) == 0 || (!constraint && s[0] == '.') || len(s) > 253 {1417	// 	return false1418	// }14191420	lastDot := -11421	if constraint && s[0] == '.' {1422		s = s[1:]1423	}14241425	for i := 0; i <= len(s); i++ {1426		if i < len(s) && (s[i] < 33 || s[i] > 126) {1427			// Invalid character.1428			return false1429		}1430		if i == len(s) || s[i] == '.' {1431			labelLen := i1432			if lastDot >= 0 {1433				labelLen -= lastDot + 11434			}1435			if labelLen == 0 {1436				return false1437			}1438			// TODO(#75835): labels cannot be longer than 63 characters.1439			// if labelLen > 63 {1440			// 	return false1441			// }1442			lastDot = i1443		}1444	}14451446	return true1447}

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.