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(¶ms, &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(¶msDer, 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.