Black Lives Matter. Support the Equal Justice Initiative.

Source file src/crypto/x509/parser.go

Documentation: crypto/x509

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  package x509
     5  
     6  import (
     7  	"bytes"
     8  	"crypto/dsa"
     9  	"crypto/ecdsa"
    10  	"crypto/ed25519"
    11  	"crypto/elliptic"
    12  	"crypto/rsa"
    13  	"crypto/x509/pkix"
    14  	"encoding/asn1"
    15  	"errors"
    16  	"fmt"
    17  	"math/big"
    18  	"net"
    19  	"net/url"
    20  	"strconv"
    21  	"strings"
    22  	"time"
    23  	"unicode/utf16"
    24  	"unicode/utf8"
    25  
    26  	"golang.org/x/crypto/cryptobyte"
    27  	cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
    28  )
    29  
    30  // isPrintable reports whether the given b is in the ASN.1 PrintableString set.
    31  // This is a simplified version of encoding/asn1.isPrintable.
    32  func isPrintable(b byte) bool {
    33  	return 'a' <= b && b <= 'z' ||
    34  		'A' <= b && b <= 'Z' ||
    35  		'0' <= b && b <= '9' ||
    36  		'\'' <= b && b <= ')' ||
    37  		'+' <= b && b <= '/' ||
    38  		b == ' ' ||
    39  		b == ':' ||
    40  		b == '=' ||
    41  		b == '?' ||
    42  		// This is technically not allowed in a PrintableString.
    43  		// However, x509 certificates with wildcard strings don't
    44  		// always use the correct string type so we permit it.
    45  		b == '*' ||
    46  		// This is not technically allowed either. However, not
    47  		// only is it relatively common, but there are also a
    48  		// handful of CA certificates that contain it. At least
    49  		// one of which will not expire until 2027.
    50  		b == '&'
    51  }
    52  
    53  // parseASN1String parses the ASN.1 string types T61String, PrintableString,
    54  // UTF8String, BMPString, and IA5String. This is mostly copied from the
    55  // respective encoding/asn1.parse... methods, rather than just increasing
    56  // the API surface of that package.
    57  func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {
    58  	switch tag {
    59  	case cryptobyte_asn1.T61String:
    60  		return string(value), nil
    61  	case cryptobyte_asn1.PrintableString:
    62  		for _, b := range value {
    63  			if !isPrintable(b) {
    64  				return "", errors.New("invalid PrintableString")
    65  			}
    66  		}
    67  		return string(value), nil
    68  	case cryptobyte_asn1.UTF8String:
    69  		if !utf8.Valid(value) {
    70  			return "", errors.New("invalid UTF-8 string")
    71  		}
    72  		return string(value), nil
    73  	case cryptobyte_asn1.Tag(asn1.TagBMPString):
    74  		if len(value)%2 != 0 {
    75  			return "", errors.New("invalid BMPString")
    76  		}
    77  
    78  		// Strip terminator if present.
    79  		if l := len(value); l >= 2 && value[l-1] == 0 && value[l-2] == 0 {
    80  			value = value[:l-2]
    81  		}
    82  
    83  		s := make([]uint16, 0, len(value)/2)
    84  		for len(value) > 0 {
    85  			s = append(s, uint16(value[0])<<8+uint16(value[1]))
    86  			value = value[2:]
    87  		}
    88  
    89  		return string(utf16.Decode(s)), nil
    90  	case cryptobyte_asn1.IA5String:
    91  		s := string(value)
    92  		if isIA5String(s) != nil {
    93  			return "", errors.New("invalid IA5String")
    94  		}
    95  		return s, nil
    96  	}
    97  	return "", fmt.Errorf("unsupported string type: %v", tag)
    98  }
    99  
   100  // parseName parses a DER encoded Name as defined in RFC 5280. We may
   101  // want to export this function in the future for use in crypto/tls.
   102  func parseName(raw cryptobyte.String) (*pkix.RDNSequence, error) {
   103  	if !raw.ReadASN1(&raw, cryptobyte_asn1.SEQUENCE) {
   104  		return nil, errors.New("x509: invalid RDNSequence")
   105  	}
   106  
   107  	var rdnSeq pkix.RDNSequence
   108  	for !raw.Empty() {
   109  		var rdnSet pkix.RelativeDistinguishedNameSET
   110  		var set cryptobyte.String
   111  		if !raw.ReadASN1(&set, cryptobyte_asn1.SET) {
   112  			return nil, errors.New("x509: invalid RDNSequence")
   113  		}
   114  		for !set.Empty() {
   115  			var atav cryptobyte.String
   116  			if !set.ReadASN1(&atav, cryptobyte_asn1.SEQUENCE) {
   117  				return nil, errors.New("x509: invalid RDNSequence: invalid attribute")
   118  			}
   119  			var attr pkix.AttributeTypeAndValue
   120  			if !atav.ReadASN1ObjectIdentifier(&attr.Type) {
   121  				return nil, errors.New("x509: invalid RDNSequence: invalid attribute type")
   122  			}
   123  			var rawValue cryptobyte.String
   124  			var valueTag cryptobyte_asn1.Tag
   125  			if !atav.ReadAnyASN1(&rawValue, &valueTag) {
   126  				return nil, errors.New("x509: invalid RDNSequence: invalid attribute value")
   127  			}
   128  			var err error
   129  			attr.Value, err = parseASN1String(valueTag, rawValue)
   130  			if err != nil {
   131  				return nil, fmt.Errorf("x509: invalid RDNSequence: invalid attribute value: %s", err)
   132  			}
   133  			rdnSet = append(rdnSet, attr)
   134  		}
   135  
   136  		rdnSeq = append(rdnSeq, rdnSet)
   137  	}
   138  
   139  	return &rdnSeq, nil
   140  }
   141  
   142  func parseAI(der cryptobyte.String) (pkix.AlgorithmIdentifier, error) {
   143  	ai := pkix.AlgorithmIdentifier{}
   144  	if !der.ReadASN1ObjectIdentifier(&ai.Algorithm) {
   145  		return ai, errors.New("x509: malformed OID")
   146  	}
   147  	if der.Empty() {
   148  		return ai, nil
   149  	}
   150  	var params cryptobyte.String
   151  	var tag cryptobyte_asn1.Tag
   152  	if !der.ReadAnyASN1Element(&params, &tag) {
   153  		return ai, errors.New("x509: malformed parameters")
   154  	}
   155  	ai.Parameters.Tag = int(tag)
   156  	ai.Parameters.FullBytes = params
   157  	return ai, nil
   158  }
   159  
   160  func parseValidity(der cryptobyte.String) (time.Time, time.Time, error) {
   161  	extract := func() (time.Time, error) {
   162  		var t time.Time
   163  		switch {
   164  		case der.PeekASN1Tag(cryptobyte_asn1.UTCTime):
   165  			// TODO(rolandshoemaker): once #45411 is fixed, the following code
   166  			// should be replaced with a call to der.ReadASN1UTCTime.
   167  			var utc cryptobyte.String
   168  			if !der.ReadASN1(&utc, cryptobyte_asn1.UTCTime) {
   169  				return t, errors.New("x509: malformed UTCTime")
   170  			}
   171  			s := string(utc)
   172  
   173  			formatStr := "0601021504Z0700"
   174  			var err error
   175  			t, err = time.Parse(formatStr, s)
   176  			if err != nil {
   177  				formatStr = "060102150405Z0700"
   178  				t, err = time.Parse(formatStr, s)
   179  			}
   180  			if err != nil {
   181  				return t, err
   182  			}
   183  
   184  			if serialized := t.Format(formatStr); serialized != s {
   185  				return t, errors.New("x509: malformed UTCTime")
   186  			}
   187  
   188  			if t.Year() >= 2050 {
   189  				// UTCTime only encodes times prior to 2050. See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
   190  				t = t.AddDate(-100, 0, 0)
   191  			}
   192  		case der.PeekASN1Tag(cryptobyte_asn1.GeneralizedTime):
   193  			if !der.ReadASN1GeneralizedTime(&t) {
   194  				return t, errors.New("x509: malformed GeneralizedTime")
   195  			}
   196  		default:
   197  			return t, errors.New("x509: unsupported time format")
   198  		}
   199  		return t, nil
   200  	}
   201  
   202  	notBefore, err := extract()
   203  	if err != nil {
   204  		return time.Time{}, time.Time{}, err
   205  	}
   206  	notAfter, err := extract()
   207  	if err != nil {
   208  		return time.Time{}, time.Time{}, err
   209  	}
   210  
   211  	return notBefore, notAfter, nil
   212  }
   213  
   214  func parseExtension(der cryptobyte.String) (pkix.Extension, error) {
   215  	var ext pkix.Extension
   216  	if !der.ReadASN1ObjectIdentifier(&ext.Id) {
   217  		return ext, errors.New("x509: malformed extention OID field")
   218  	}
   219  	if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
   220  		if !der.ReadASN1Boolean(&ext.Critical) {
   221  			return ext, errors.New("x509: malformed extention critical field")
   222  		}
   223  	}
   224  	var val cryptobyte.String
   225  	if !der.ReadASN1(&val, cryptobyte_asn1.OCTET_STRING) {
   226  		return ext, errors.New("x509: malformed extention value field")
   227  	}
   228  	ext.Value = val
   229  	return ext, nil
   230  }
   231  
   232  func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) {
   233  	der := cryptobyte.String(keyData.PublicKey.RightAlign())
   234  	switch algo {
   235  	case RSA:
   236  		// RSA public keys must have a NULL in the parameters.
   237  		// See RFC 3279, Section 2.3.1.
   238  		if !bytes.Equal(keyData.Algorithm.Parameters.FullBytes, asn1.NullBytes) {
   239  			return nil, errors.New("x509: RSA key missing NULL parameters")
   240  		}
   241  
   242  		p := &pkcs1PublicKey{N: new(big.Int)}
   243  		if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
   244  			return nil, errors.New("x509: invalid RSA public key")
   245  		}
   246  		if !der.ReadASN1Integer(p.N) {
   247  			return nil, errors.New("x509: invalid RSA modulus")
   248  		}
   249  		if !der.ReadASN1Integer(&p.E) {
   250  			return nil, errors.New("x509: invalid RSA public exponent")
   251  		}
   252  
   253  		if p.N.Sign() <= 0 {
   254  			return nil, errors.New("x509: RSA modulus is not a positive number")
   255  		}
   256  		if p.E <= 0 {
   257  			return nil, errors.New("x509: RSA public exponent is not a positive number")
   258  		}
   259  
   260  		pub := &rsa.PublicKey{
   261  			E: p.E,
   262  			N: p.N,
   263  		}
   264  		return pub, nil
   265  	case ECDSA:
   266  		paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes)
   267  		namedCurveOID := new(asn1.ObjectIdentifier)
   268  		if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
   269  			return nil, errors.New("x509: invalid ECDSA parameters")
   270  		}
   271  		namedCurve := namedCurveFromOID(*namedCurveOID)
   272  		if namedCurve == nil {
   273  			return nil, errors.New("x509: unsupported elliptic curve")
   274  		}
   275  		x, y := elliptic.Unmarshal(namedCurve, der)
   276  		if x == nil {
   277  			return nil, errors.New("x509: failed to unmarshal elliptic curve point")
   278  		}
   279  		pub := &ecdsa.PublicKey{
   280  			Curve: namedCurve,
   281  			X:     x,
   282  			Y:     y,
   283  		}
   284  		return pub, nil
   285  	case Ed25519:
   286  		// RFC 8410, Section 3
   287  		// > For all of the OIDs, the parameters MUST be absent.
   288  		if len(keyData.Algorithm.Parameters.FullBytes) != 0 {
   289  			return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
   290  		}
   291  		if len(der) != ed25519.PublicKeySize {
   292  			return nil, errors.New("x509: wrong Ed25519 public key size")
   293  		}
   294  		return ed25519.PublicKey(der), nil
   295  	case DSA:
   296  		y := new(big.Int)
   297  		if !der.ReadASN1Integer(y) {
   298  			return nil, errors.New("x509: invalid DSA public key")
   299  		}
   300  		pub := &dsa.PublicKey{
   301  			Y: y,
   302  			Parameters: dsa.Parameters{
   303  				P: new(big.Int),
   304  				Q: new(big.Int),
   305  				G: new(big.Int),
   306  			},
   307  		}
   308  		paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes)
   309  		if !paramsDer.ReadASN1(&paramsDer, cryptobyte_asn1.SEQUENCE) ||
   310  			!paramsDer.ReadASN1Integer(pub.Parameters.P) ||
   311  			!paramsDer.ReadASN1Integer(pub.Parameters.Q) ||
   312  			!paramsDer.ReadASN1Integer(pub.Parameters.G) {
   313  			return nil, errors.New("x509: invalid DSA parameters")
   314  		}
   315  		if pub.Y.Sign() <= 0 || pub.Parameters.P.Sign() <= 0 ||
   316  			pub.Parameters.Q.Sign() <= 0 || pub.Parameters.G.Sign() <= 0 {
   317  			return nil, errors.New("x509: zero or negative DSA parameter")
   318  		}
   319  		return pub, nil
   320  	default:
   321  		return nil, nil
   322  	}
   323  }
   324  
   325  func parseKeyUsageExtension(der cryptobyte.String) (KeyUsage, error) {
   326  	var usageBits asn1.BitString
   327  	if !der.ReadASN1BitString(&usageBits) {
   328  		return 0, errors.New("x509: invalid key usage")
   329  	}
   330  
   331  	var usage int
   332  	for i := 0; i < 9; i++ {
   333  		if usageBits.At(i) != 0 {
   334  			usage |= 1 << uint(i)
   335  		}
   336  	}
   337  	return KeyUsage(usage), nil
   338  }
   339  
   340  func parseBasicConstraintsExtension(der cryptobyte.String) (bool, int, error) {
   341  	var isCA bool
   342  	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
   343  		return false, 0, errors.New("x509: invalid basic constraints a")
   344  	}
   345  	if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
   346  		if !der.ReadASN1Boolean(&isCA) {
   347  			return false, 0, errors.New("x509: invalid basic constraints b")
   348  		}
   349  	}
   350  	maxPathLen := -1
   351  	if !der.Empty() && der.PeekASN1Tag(cryptobyte_asn1.INTEGER) {
   352  		if !der.ReadASN1Integer(&maxPathLen) {
   353  			return false, 0, errors.New("x509: invalid basic constraints c")
   354  		}
   355  	}
   356  
   357  	// TODO: map out.MaxPathLen to 0 if it has the -1 default value? (Issue 19285)
   358  	return isCA, maxPathLen, nil
   359  }
   360  
   361  func forEachSAN(der cryptobyte.String, callback func(tag int, data []byte) error) error {
   362  	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
   363  		return errors.New("x509: invalid subject alternative names")
   364  	}
   365  	for !der.Empty() {
   366  		var san cryptobyte.String
   367  		var tag cryptobyte_asn1.Tag
   368  		if !der.ReadAnyASN1(&san, &tag) {
   369  			return errors.New("x509: invalid subject alternative name")
   370  		}
   371  		if err := callback(int(tag^0x80), san); err != nil {
   372  			return err
   373  		}
   374  	}
   375  
   376  	return nil
   377  }
   378  
   379  func parseSANExtension(der cryptobyte.String) (dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL, err error) {
   380  	err = forEachSAN(der, func(tag int, data []byte) error {
   381  		switch tag {
   382  		case nameTypeEmail:
   383  			email := string(data)
   384  			if err := isIA5String(email); err != nil {
   385  				return errors.New("x509: SAN rfc822Name is malformed")
   386  			}
   387  			emailAddresses = append(emailAddresses, email)
   388  		case nameTypeDNS:
   389  			name := string(data)
   390  			if err := isIA5String(name); err != nil {
   391  				return errors.New("x509: SAN dNSName is malformed")
   392  			}
   393  			dnsNames = append(dnsNames, string(name))
   394  		case nameTypeURI:
   395  			uriStr := string(data)
   396  			if err := isIA5String(uriStr); err != nil {
   397  				return errors.New("x509: SAN uniformResourceIdentifier is malformed")
   398  			}
   399  			uri, err := url.Parse(uriStr)
   400  			if err != nil {
   401  				return fmt.Errorf("x509: cannot parse URI %q: %s", uriStr, err)
   402  			}
   403  			if len(uri.Host) > 0 {
   404  				if _, ok := domainToReverseLabels(uri.Host); !ok {
   405  					return fmt.Errorf("x509: cannot parse URI %q: invalid domain", uriStr)
   406  				}
   407  			}
   408  			uris = append(uris, uri)
   409  		case nameTypeIP:
   410  			switch len(data) {
   411  			case net.IPv4len, net.IPv6len:
   412  				ipAddresses = append(ipAddresses, data)
   413  			default:
   414  				return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len(data)))
   415  			}
   416  		}
   417  
   418  		return nil
   419  	})
   420  
   421  	return
   422  }
   423  
   424  func parseExtKeyUsageExtension(der cryptobyte.String) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) {
   425  	var extKeyUsages []ExtKeyUsage
   426  	var unknownUsages []asn1.ObjectIdentifier
   427  	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
   428  		return nil, nil, errors.New("x509: invalid extended key usages")
   429  	}
   430  	for !der.Empty() {
   431  		var eku asn1.ObjectIdentifier
   432  		if !der.ReadASN1ObjectIdentifier(&eku) {
   433  			return nil, nil, errors.New("x509: invalid extended key usages")
   434  		}
   435  		if extKeyUsage, ok := extKeyUsageFromOID(eku); ok {
   436  			extKeyUsages = append(extKeyUsages, extKeyUsage)
   437  		} else {
   438  			unknownUsages = append(unknownUsages, eku)
   439  		}
   440  	}
   441  	return extKeyUsages, unknownUsages, nil
   442  }
   443  
   444  func parseCertificatePoliciesExtension(der cryptobyte.String) ([]asn1.ObjectIdentifier, error) {
   445  	var oids []asn1.ObjectIdentifier
   446  	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
   447  		return nil, errors.New("x509: invalid certificate policies")
   448  	}
   449  	for !der.Empty() {
   450  		var cp cryptobyte.String
   451  		if !der.ReadASN1(&cp, cryptobyte_asn1.SEQUENCE) {
   452  			return nil, errors.New("x509: invalid certificate policies")
   453  		}
   454  		var oid asn1.ObjectIdentifier
   455  		if !cp.ReadASN1ObjectIdentifier(&oid) {
   456  			return nil, errors.New("x509: invalid certificate policies")
   457  		}
   458  		oids = append(oids, oid)
   459  	}
   460  
   461  	return oids, nil
   462  }
   463  
   464  // isValidIPMask reports whether mask consists of zero or more 1 bits, followed by zero bits.
   465  func isValidIPMask(mask []byte) bool {
   466  	seenZero := false
   467  
   468  	for _, b := range mask {
   469  		if seenZero {
   470  			if b != 0 {
   471  				return false
   472  			}
   473  
   474  			continue
   475  		}
   476  
   477  		switch b {
   478  		case 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe:
   479  			seenZero = true
   480  		case 0xff:
   481  		default:
   482  			return false
   483  		}
   484  	}
   485  
   486  	return true
   487  }
   488  
   489  func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandled bool, err error) {
   490  	// RFC 5280, 4.2.1.10
   491  
   492  	// NameConstraints ::= SEQUENCE {
   493  	//      permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
   494  	//      excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
   495  	//
   496  	// GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
   497  	//
   498  	// GeneralSubtree ::= SEQUENCE {
   499  	//      base                    GeneralName,
   500  	//      minimum         [0]     BaseDistance DEFAULT 0,
   501  	//      maximum         [1]     BaseDistance OPTIONAL }
   502  	//
   503  	// BaseDistance ::= INTEGER (0..MAX)
   504  
   505  	outer := cryptobyte.String(e.Value)
   506  	var toplevel, permitted, excluded cryptobyte.String
   507  	var havePermitted, haveExcluded bool
   508  	if !outer.ReadASN1(&toplevel, cryptobyte_asn1.SEQUENCE) ||
   509  		!outer.Empty() ||
   510  		!toplevel.ReadOptionalASN1(&permitted, &havePermitted, cryptobyte_asn1.Tag(0).ContextSpecific().Constructed()) ||
   511  		!toplevel.ReadOptionalASN1(&excluded, &haveExcluded, cryptobyte_asn1.Tag(1).ContextSpecific().Constructed()) ||
   512  		!toplevel.Empty() {
   513  		return false, errors.New("x509: invalid NameConstraints extension")
   514  	}
   515  
   516  	if !havePermitted && !haveExcluded || len(permitted) == 0 && len(excluded) == 0 {
   517  		// From RFC 5280, Section 4.2.1.10:
   518  		//   “either the permittedSubtrees field
   519  		//   or the excludedSubtrees MUST be
   520  		//   present”
   521  		return false, errors.New("x509: empty name constraints extension")
   522  	}
   523  
   524  	getValues := func(subtrees cryptobyte.String) (dnsNames []string, ips []*net.IPNet, emails, uriDomains []string, err error) {
   525  		for !subtrees.Empty() {
   526  			var seq, value cryptobyte.String
   527  			var tag cryptobyte_asn1.Tag
   528  			if !subtrees.ReadASN1(&seq, cryptobyte_asn1.SEQUENCE) ||
   529  				!seq.ReadAnyASN1(&value, &tag) {
   530  				return nil, nil, nil, nil, fmt.Errorf("x509: invalid NameConstraints extension")
   531  			}
   532  
   533  			var (
   534  				dnsTag   = cryptobyte_asn1.Tag(2).ContextSpecific()
   535  				emailTag = cryptobyte_asn1.Tag(1).ContextSpecific()
   536  				ipTag    = cryptobyte_asn1.Tag(7).ContextSpecific()
   537  				uriTag   = cryptobyte_asn1.Tag(6).ContextSpecific()
   538  			)
   539  
   540  			switch tag {
   541  			case dnsTag:
   542  				domain := string(value)
   543  				if err := isIA5String(domain); err != nil {
   544  					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
   545  				}
   546  
   547  				trimmedDomain := domain
   548  				if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
   549  					// constraints can have a leading
   550  					// period to exclude the domain
   551  					// itself, but that's not valid in a
   552  					// normal domain name.
   553  					trimmedDomain = trimmedDomain[1:]
   554  				}
   555  				if _, ok := domainToReverseLabels(trimmedDomain); !ok {
   556  					return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", domain)
   557  				}
   558  				dnsNames = append(dnsNames, domain)
   559  
   560  			case ipTag:
   561  				l := len(value)
   562  				var ip, mask []byte
   563  
   564  				switch l {
   565  				case 8:
   566  					ip = value[:4]
   567  					mask = value[4:]
   568  
   569  				case 32:
   570  					ip = value[:16]
   571  					mask = value[16:]
   572  
   573  				default:
   574  					return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained value of length %d", l)
   575  				}
   576  
   577  				if !isValidIPMask(mask) {
   578  					return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained invalid mask %x", mask)
   579  				}
   580  
   581  				ips = append(ips, &net.IPNet{IP: net.IP(ip), Mask: net.IPMask(mask)})
   582  
   583  			case emailTag:
   584  				constraint := string(value)
   585  				if err := isIA5String(constraint); err != nil {
   586  					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
   587  				}
   588  
   589  				// If the constraint contains an @ then
   590  				// it specifies an exact mailbox name.
   591  				if strings.Contains(constraint, "@") {
   592  					if _, ok := parseRFC2821Mailbox(constraint); !ok {
   593  						return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
   594  					}
   595  				} else {
   596  					// Otherwise it's a domain name.
   597  					domain := constraint
   598  					if len(domain) > 0 && domain[0] == '.' {
   599  						domain = domain[1:]
   600  					}
   601  					if _, ok := domainToReverseLabels(domain); !ok {
   602  						return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
   603  					}
   604  				}
   605  				emails = append(emails, constraint)
   606  
   607  			case uriTag:
   608  				domain := string(value)
   609  				if err := isIA5String(domain); err != nil {
   610  					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
   611  				}
   612  
   613  				if net.ParseIP(domain) != nil {
   614  					return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q: cannot be IP address", domain)
   615  				}
   616  
   617  				trimmedDomain := domain
   618  				if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
   619  					// constraints can have a leading
   620  					// period to exclude the domain itself,
   621  					// but that's not valid in a normal
   622  					// domain name.
   623  					trimmedDomain = trimmedDomain[1:]
   624  				}
   625  				if _, ok := domainToReverseLabels(trimmedDomain); !ok {