1
0
mirror of https://github.com/golang/go synced 2024-09-29 20:14:29 -06:00

crypto/x509: abstract SAN parsing function

We'll need this for handling name constraints during verification.

Change-Id: I4ef19d9489fb2a9ae9a62699d81cef92a21fda28
Reviewed-on: https://go-review.googlesource.com/62692
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Adam Langley 2017-09-09 16:52:58 -07:00
parent 3079b0ad89
commit c4d63a0d34

View File

@ -1042,7 +1042,7 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
}
}
func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddresses []net.IP, err error) {
func forEachSAN(extension []byte, callback func(tag int, data []byte) error) error {
// RFC 5280, 4.2.1.6
// SubjectAltName ::= GeneralNames
@ -1060,16 +1060,14 @@ func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddre
// iPAddress [7] OCTET STRING,
// registeredID [8] OBJECT IDENTIFIER }
var seq asn1.RawValue
var rest []byte
if rest, err = asn1.Unmarshal(value, &seq); err != nil {
return
rest, err := asn1.Unmarshal(extension, &seq)
if err != nil {
return err
} else if len(rest) != 0 {
err = errors.New("x509: trailing data after X.509 extension")
return
return errors.New("x509: trailing data after X.509 extension")
}
if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 {
err = asn1.StructuralError{Msg: "bad SAN sequence"}
return
return asn1.StructuralError{Msg: "bad SAN sequence"}
}
rest = seq.Bytes
@ -1077,24 +1075,36 @@ func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddre
var v asn1.RawValue
rest, err = asn1.Unmarshal(rest, &v)
if err != nil {
return
return err
}
switch v.Tag {
case 1:
emailAddresses = append(emailAddresses, string(v.Bytes))
case 2:
dnsNames = append(dnsNames, string(v.Bytes))
case 7:
switch len(v.Bytes) {
case net.IPv4len, net.IPv6len:
ipAddresses = append(ipAddresses, v.Bytes)
default:
err = errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(v.Bytes)))
return
}
if err := callback(v.Tag, v.Bytes); err != nil {
return err
}
}
return nil
}
func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddresses []net.IP, err error) {
err = forEachSAN(value, func(tag int, data []byte) error {
switch tag {
case 1:
emailAddresses = append(emailAddresses, string(data))
case 2:
dnsNames = append(dnsNames, string(data))
case 7:
switch len(data) {
case net.IPv4len, net.IPv6len:
ipAddresses = append(ipAddresses, data)
default:
return errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(data)))
}
}
return nil
})
return
}