Commit c4d63a0d authored by Adam Langley's avatar Adam Langley

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: default avatarDavid Crawshaw <crawshaw@golang.org>
parent 3079b0ad
...@@ -1042,7 +1042,7 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{ ...@@ -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 // RFC 5280, 4.2.1.6
// SubjectAltName ::= GeneralNames // SubjectAltName ::= GeneralNames
...@@ -1060,16 +1060,14 @@ func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddre ...@@ -1060,16 +1060,14 @@ func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddre
// iPAddress [7] OCTET STRING, // iPAddress [7] OCTET STRING,
// registeredID [8] OBJECT IDENTIFIER } // registeredID [8] OBJECT IDENTIFIER }
var seq asn1.RawValue var seq asn1.RawValue
var rest []byte rest, err := asn1.Unmarshal(extension, &seq)
if rest, err = asn1.Unmarshal(value, &seq); err != nil { if err != nil {
return return err
} else if len(rest) != 0 { } else if len(rest) != 0 {
err = errors.New("x509: trailing data after X.509 extension") return errors.New("x509: trailing data after X.509 extension")
return
} }
if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 { if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 {
err = asn1.StructuralError{Msg: "bad SAN sequence"} return asn1.StructuralError{Msg: "bad SAN sequence"}
return
} }
rest = seq.Bytes rest = seq.Bytes
...@@ -1077,24 +1075,36 @@ func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddre ...@@ -1077,24 +1075,36 @@ func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddre
var v asn1.RawValue var v asn1.RawValue
rest, err = asn1.Unmarshal(rest, &v) rest, err = asn1.Unmarshal(rest, &v)
if err != nil { if err != nil {
return return err
}
if err := callback(v.Tag, v.Bytes); err != nil {
return err
} }
switch v.Tag { }
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: case 1:
emailAddresses = append(emailAddresses, string(v.Bytes)) emailAddresses = append(emailAddresses, string(data))
case 2: case 2:
dnsNames = append(dnsNames, string(v.Bytes)) dnsNames = append(dnsNames, string(data))
case 7: case 7:
switch len(v.Bytes) { switch len(data) {
case net.IPv4len, net.IPv6len: case net.IPv4len, net.IPv6len:
ipAddresses = append(ipAddresses, v.Bytes) ipAddresses = append(ipAddresses, data)
default: default:
err = errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(v.Bytes))) return errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(data)))
return
}
} }
} }
return nil
})
return return
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment