Home > OS >  Proper way to decode asn1.RawValue in Golang
Proper way to decode asn1.RawValue in Golang

Time:01-28

I am implementing certificate parsing in Golang and I need to obtain parent certificate link.

If I do openssl x509 -in certificate.pem -text -noout then I am able to see the following certificate extension:

            Authority Information Access:
                OCSP - URI:http://teszt.e-szigno.hu/testca3ocsp
                CA Issuers - URI:http://teszt.e-szigno.hu/TCA3.crt

In my go project I have following code:

content := `-----BEGIN CERTIFICATE-----
MIIJxDCCCKygAwIBAgINfEbzVUOoCNMWumANCjANBgkqhkiG9w0BAQsFADBqMQsw
CQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2Vj
IEx0ZC4xFDASBgNVBAsMC2UtU3ppZ25vIENBMRowGAYDVQQDDBFlLVN6aWdubyBU
ZXN0IENBMzAeFw0yMzAxMjQxMjQxNTBaFw0yNDAxMjQxMjQxNTBaMIHQMRMwEQYL
KwYBBAGCNzwCAQMTAkVFMRgwFgYLKwYBBAGCNzwCAQEMB1RhbGxpbm4xHTAbBgNV
BA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMREwDwYDVQQFEwgxMjI2ODQ3NTELMAkG
A1UEBhMCRUUxEDAOBgNVBAcMB1RhbGxpbm4xFzAVBgNVBAoMDk1ha3Nla2Vza3Vz
IEFTMRswGQYDVQRhDBJQU0RFRS1GU0EtMTIyNjg0NzUxGDAWBgNVBAMMD21ha2Vj
b21tZXJjZS5sdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJFyj3sS
xev2yHbGXNmqw8e ZqFvrb1 UHlsm7c65HSjwAVjheHNV1cufilRf5X1PuBDmXtC
XpwD7FmOc7h  BAEdapv/XcWkMqUgbkfwhaZPkjbXIQBH7jbe4D 3pxn ZDlq/1b
Wi6dJhGHN Ydgw6x qGBOVzaFlprFdOYQXDw8yMc/iQMBahzzQApe2EwW1XRgyaT
DNE5t2T7uWC05qDYgi1HI50WGoezx7A7CDSjwG kFvczleY 4H73aPiGH1f0q EC
POZsoot12CWspBwZB9G03S5IoIipJPoQmIvnKGgeGbbY16P3VQ/78w9XjPy0dwid
x2CfPlPLTa8eJF0CAwEAAaOCBgAwggX8MA4GA1UdDwEB/wQEAwIFoDCBiQYKKwYB
BAHWeQIEAgR7BHkAdwB1AKoeeAQ/gGSCK VMtcHKwuMu5FDmczAqSLwmlwubLAgd
AAABhePMiCsAAAQDAEYwRAIgMbv IXdcxOgT9VPPUIuuHajA08AiGnQMKnSsYHPl
4egCICQN64jfx fitpnfxb6u531tA3VkjmMmLOkvN5b2vj4wMB0GA1UdJQQWMBQG
CCsGAQUFBwMBBggrBgEFBQcDAjCCAyQGA1UdIASCAxswggMXMIIDEwYMKwYBBAGB
qBgCAQFkMIIDATAmBggrBgEFBQcCARYaaHR0cDovL2NwLmUtc3ppZ25vLmh1L3Fj
cHMwgb8GCCsGAQUFBwICMIGyDIGvVGVzdCBxdWFsaWZpZWQgY2VydGlmaWNhdGUg
Zm9yIHdlYnNpdGUgYXV0aGVudGljYXRpb24gYW5kIGNsaWVudCBhdXRoZW50aWNh
dGlvbi4gVGhlIHByb3ZpZGVyIHByZXNlcnZlcyByZWdpc3RyYXRpb24gZGF0YSBm
b3IgMTAgeWVhcnMgYWZ0ZXIgdGhlIGV4cGlyYXRpb24gb2YgdGhlIGNlcnRpZmlj
YXRlLjCBlQYIKwYBBQUHAgIwgYgMgYVURVNUIGNlcnRpZmljYXRlIGlzc3VlZCBv
bmx5IGZvciB0ZXN0aW5nIHB1cnBvc2VzLiBUaGUgaXNzdWVyIGlzIG5vdCBsaWFi
bGUgZm9yIGFueSBkYW1hZ2VzIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMg
Y2VydGlmaWNhdGUhMIHMBggrBgEFBQcCAjCBvwyBvFRlc3p0IG1pbsWRc8OtdGV0
dCB3ZWJvbGRhbC1oaXRlbGVzw610xZEgw6lzIMO8Z3lmw6lsLWhpdGVsZXPDrXTF
kSB0YW7DunPDrXR2w6FueS4gQSByZWdpc3p0csOhY2nDs3MgYWRhdG9rYXQgYSBz
em9sZ8OhbHRhdMOzIGEgdGFuw7pzw610dsOhbnkgbGVqw6FydMOhdMOzbCBzesOh
bcOtdG90dCAxMCDDqXZpZyDFkXJ6aSBtZWcuMIGtBggrBgEFBQcCAjCBoAyBnVRl
c3p0ZWzDqXNpIGPDqWxyYSBraWFkb3R0IFRFU1pUIHRhbsO6c8OtdHbDoW55LiBB
IGhhc3puw6FsYXTDoXZhbCBrYXBjc29sYXRvc2FuIGZlbG1lcsO8bMWRIGvDoXJv
a8OpcnQgYSBTem9sZ8OhbHRhdMOzIHNlbW1pbHllbiBmZWxlbMWRc3PDqWdldCBu
ZW0gdsOhbGxhbCEwHQYDVR0OBBYEFFpdJ86Z7qiDATzBzLvlL 6RLl12MB8GA1Ud
IwQYMBaAFNzmAijvNzCPiT6grSBV8 826PDNMBoGA1UdEQQTMBGCD21ha2Vjb21t
ZXJjZS5sdDAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vdGVzenQuZS1zemlnbm8u
aHUvVENBMy5jcmwwbwYIKwYBBQUHAQEEYzBhMDAGCCsGAQUFBzABhiRodHRwOi8v
dGVzenQuZS1zemlnbm8uaHUvdGVzdGNhM29jc3AwLQYIKwYBBQUHMAKGIWh0dHA6
Ly90ZXN6dC5lLXN6aWduby5odS9UQ0EzLmNydDCCARQGCCsGAQUFBwEDBIIBBjCC
AQIwCAYGBACORgEBMAsGBgQAjkYBAwIBCjBTBgYEAI5GAQUwSTAkFh5odHRwczov
L2NwLmUtc3ppZ25vLmh1L3FjcHNfZW4TAkVOMCEWG2h0dHBzOi8vY3AuZS1zemln
bm8uaHUvcWNwcxMCSFUwEwYGBACORgEGMAkGBwQAjkYBBgMwfwYGBACBmCcCMHUw
JjARBgcEAIGYJwECDAZQU1BfUEkwEQYHBACBmCcBAwwGUFNQX0FJDENFRSAtIEVz
dG9uaWFuIEZpbmFuY2lhbCBTdXBlcnZpc2lvbiBBdXRob3JpdHkgLyBGaW5hbnRz
aW5zcGVrdHNpb29uDAZFRS1GU0EwDQYJKoZIhvcNAQELBQADggEBAHZXm9440SvU
cpZLshQ3oKOOeU4fTrP0KQkvzmBkmf yct80vartjnIaDk5rk6HQRJRjcuDI9 Hj
ep9nzwkN BUVwc2EV M7i35pCK dvNMTcgXTo2qGVznoSVjFuzshoC4mFIfxNczo
2NE2uTfU2wyWzQPYNcwFMZ7AoUXylGofEfS13mdH5dET  nWoAOD8ABZZqAeYsk9
R1fCxRThpldxjiJdDUZpzcVw obyjRhKIm6zAHd6R0E6KB9I feevF8IwgnTSozE
Zflb6EvyjuizsyqGteLrjim4ALu1 pA/2zhLZm55PWj1kM8PiWYqIGla0dKOzF4 
OTNNT6RR7bU=
-----END CERTIFICATE-----`
certDERBlock, _ := pem.Decode([]byte(content))
x509Cert, err := x509.ParseCertificate(certDERBlock.Bytes)
for _, extension := range x509Cert.Extensions {
    if extension.Id.Equal(asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 1}) {
        var collExts []asn1.RawValue
        asn1.Unmarshal(extension.Value, &collExts)
        for _, collExt := range collExts {
            fmt.Println(string(collExt.Bytes))
        }
    }
}

And it gives the following output:

 0�#http://teszt.e-szigno.hu/testca3ocsp
 0�0http://teszt.e-szigno.hu/TCA3.crt

Even though I am already able to parse such output and get the parent certificate link, I would like to understand how to get a human-readable text there. I've looked through the asn1 package and did not find any function to decode either asn1.RawValue object or asn1.RawValue.Bytes.

CodePudding user response:

You don't need to look at the x509Cert.Extensions for the AIA info, you can look it up directly from the x509.Certificate:

// RFC 5280, 4.2.2.1 (Authority Information Access)
OCSPServer            []string
IssuingCertificateURL []string

So just simply:

certDERBlock, _ := pem.Decode([]byte(certBody))
x509Cert, err = x509.ParseCertificate(certDERBlock.Bytes)

fmt.Printf("OCSPServer:            %v\n", x509Cert.OCSPServer)
fmt.Printf("IssuingCertificateURL: %v\n", x509Cert.IssuingCertificateURL)

https://go.dev/play/p/rUJOzYC_NmW

OCSPServer:            [http://teszt.e-szigno.hu/testca3ocsp]
IssuingCertificateURL: [http://teszt.e-szigno.hu/TCA3.crt]
  • Related