I can access get subjectAltName
using following code:
for _, ext := range certificate.Extensions {
if ext.Id.Equal(subjectAltNameOID) {
var extensionData asn1.RawValue
_, err := asn1.Unmarshal(ext.Value, &extensionData)
if err != nil {
log.Fatal(err)
}
// get value for OID "2.23.33.5.1.6"
return
}
}
var subjectAltNameOID = []int{2, 5, 29, 17}
but how can I now retrieve the data from extensionData?
Extension SEQUENCE (2 elem)
extnID OBJECT IDENTIFIER 2.5.29.17 subjectAltName (X.509 extension)
extnValue OCTET STRING (79 byte) 304D06066781050501010C09585886868768686806F7765…
SEQUENCE (8 elem)
OBJECT IDENTIFIER 2.23.33.5.1.1
UTF8String hello
OBJECT IDENTIFIER 2.23.33.5.1.4
UTF8String power
OBJECT IDENTIFIER 2.23.33.5.1.5
UTF8String Unknown
OBJECT IDENTIFIER 2.23.33.5.1.6
UTF8String 1234
The Golang standard library contains an unexported function, parseSANExtension, that parses an SAN extension:
func parseSANExtension(der cryptobyte.String) (dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL, err error)
It also contains a function, marshalSANs, that marshals an SAN extension:
// marshalSANs marshals a list of addresses into a the contents of an X.509
// SubjectAlternativeName extension.
func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL) (derBytes []byte, err error)
You can copy the source code from the standard library. And then call parseSANExtension(ext.Value)
to get the values stored in the extension.
Try this demo: https://go.dev/play/p/ZkaVBIVp3GB.