func permittedDirNames()

in certificate/constraints_v29.go [161:206]


func permittedDirNames(cert *x509.Certificate) []pkix.RDNSequence {
	var dirNames []pkix.RDNSequence
	var oidNameConstraints = asn1.ObjectIdentifier{2, 5, 29, 30}
	for _, ext := range cert.Extensions {
		if ext.Id.Equal(oidNameConstraints) {
			outer := cryptobyte.String(ext.Value)
			var toplevel, permitted, excluded cryptobyte.String
			var havePermitted, haveExcluded bool
			if !outer.ReadASN1(&toplevel, cryptobyte_asn1.SEQUENCE) ||
				!outer.Empty() ||
				!toplevel.ReadOptionalASN1(&permitted, &havePermitted, cryptobyte_asn1.Tag(0).ContextSpecific().Constructed()) ||
				!toplevel.ReadOptionalASN1(&excluded, &haveExcluded, cryptobyte_asn1.Tag(1).ContextSpecific().Constructed()) ||
				!toplevel.Empty() {
				return nil // Invalid NameConstraints extension.
			}
			if !havePermitted || len(permitted) == 0 {
				return nil // No permittedSubtrees.
			}

			for !permitted.Empty() {
				var seq, value cryptobyte.String
				var tag cryptobyte_asn1.Tag
				if !permitted.ReadASN1(&seq, cryptobyte_asn1.SEQUENCE) ||
					!seq.ReadAnyASN1(&value, &tag) {
					return nil // Invalid NameConstraints extension.
				}

				var dirNameTag = cryptobyte_asn1.Tag(4).ContextSpecific().Constructed()
				switch tag {
				case dirNameTag:
					var dirName pkix.RDNSequence

					if rest, err := asn1.Unmarshal(value, &dirName); err != nil {
						return nil // ASN.1 decode error.
					} else if len(rest) != 0 {
						return nil // Trailing data after dirname constraint.
					}

					dirNames = append(dirNames, dirName)
				}
			}
		}
	}

	return dirNames
}