[erlang-bugs] bug decoding AuthorityKeyIdentifier in certificate?
Warren Smith
wsmith@REDACTED
Fri Aug 3 19:05:14 CEST 2012
I've come across what may be a bug in the function dec_AuthorityKeyIdentifier(Tlv, TagIn) in OTP-PUB-Key.erl in version R15B01.
A simple test program is:
$ cat test_cert.erl
-module(test_cert).
-export([cert_file_to_db/1,cert_from_file/1]).
cert_file_to_db(File) ->
Db = ssl_certificate_db:create(),
ssl_certificate_db:add_trusted_certs(self(), File, Db).
cert_from_file(File) ->
{ok, PemBin} = file:read_file(File),
[PemEntry] = public_key:pem_decode(PemBin),
{'Certificate', Cert, not_encrypted} = PemEntry,
ErlCert = public_key:pkix_decode_cert(Cert, otp),
io:format("~p~n",[ErlCert]).
On this certificate:
$ cat 5813ea38.0
-----BEGIN CERTIFICATE-----
MIICgjCCAeugAwIBAgIBADANBgkqhkiG9w0BAQUFADA3MQ0wCwYDVQQKEwRBdXRv
MRkwFwYDVQQLExBGdXR1cmVHcmlkTmltYnVzMQswCQYDVQQDEwJDQTAeFw0xMDA5
MDcxNjM0NDJaFw0xNTA5MDcxNjM0NTJaMDcxDTALBgNVBAoTBEF1dG8xGTAXBgNV
BAsTEEZ1dHVyZUdyaWROaW1idXMxCzAJBgNVBAMTAkNBMIGfMA0GCSqGSIb3DQEB
AQUAA4GNADCBiQKBgQCyYqVUsHNqOUS+31s2zdMj7HTENnmdTxb+Ihbt50zl+L/o
VTJkRWEw3Vy3F8KSbIHEfViDPAMBcpv2KZGZIZfCfGE9wfwEp/mcuEY/WA+jKSev
lKFQXPWZQtP0OhwT7h2ZHYK/BA8gNvEpKmqvxm8Kb71v/HCXANYoZMwwgjNIcwID
AQABo4GdMIGaMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBhsOpAcfJATaaHH
EeG7ff96svu2MFsGA1UdIwRUMFKAFBhsOpAcfJATaaHHEeG7ff96svu2oTcxDTAL
BgNVBAoTBEF1dG8xGTAXBgNVBAsTEEZ1dHVyZUdyaWROaW1idXMxCzAJBgNVBAMT
AkNBggEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQCuaZaw8f8AmQg4
CiOMgR2qs1zqiXXDGJTx5mnvcDwgyWKqrsNj+8g9oh0R8fx29jUJvq82cVCk0mTR
6Yl/wlgFPFHveykA94AzMoHrVBdmusRJRN0B7GTCTnMCnSHhG0FBjagyqC92MZj4
qJRQswlft8SqfOTxezAZLRXSDJYvvw==
-----END CERTIFICATE-----
Results in:
$ erl -noshell -s test_cert cert_from_file 5813ea38.0 -s init stop
{"init terminating in do_boot",{{badmatch,{error,{asn1,{invalid_choice_tag,{17,[{16,[{6,<<3 bytes>>},{19,<<4 bytes>>}]}]}}}}},[{public_key,pkix_decode_cert,2,[{file,"public_key.erl"},{line,216}]},{test_cert,cert_from_file,1,[{file,"test_cert.erl"},{line,15}]},{init,start_it,1,[]},{init,start_em,1,[]}]}}
Crash dump was written to: erl_crash.dump
init terminating in do_boot ()
This certificate is handled ok by OpenSSL (e.g. openssl x509 -in 5813ea38.0 -text -noout) and by at least one Java X.509 implementation.
I haven't looked in to the process of how public_key/asn1/OTP-PUB-KEY.erl is generated, but this block of code in the dec_AuthorityKeyIdentifier(Tlv, TagIn) function:
%%-------------------------------------------------
%% attribute authorityCertIssuer(2) External OTP-PUB-KEY:GeneralNames OPTIONAL
%%-------------------------------------------------
{Term2, Tlv3} = case Tlv2 of
[{131073, V2} | TempTlv3] ->
{dec_GeneralNames(V2, []), TempTlv3};
_ -> {asn1_NOVALUE, Tlv2}
end,
Is where the problem start showing up. For the above certificate, it is passing this to dec_GeneralNames(Tlv, TagIn):
Tlv: [{17,[{16,[{6,<<85,4,10>>},{19,<<"Auto">>}]}]},
{17,[{16,[{6,<<85,4,11>>},{19,<<"FutureGridNimbus">>}]}]},
{17,[{16,[{6,<<85,4,3>>},{19,<<"CA">>}]}]}]
TagIn: []
This doesn't look like what dec_GeneralNames() expects. It is close to what dec_Name() expects, though.
There are perhaps 2 problems here. First, ({1310??, ???}, []) needs to be passed to dec_GeneralNames() not just (???, []). Second, 131076 should be associated with the above Tlv, not 131073.
So, a hack of:
%%-------------------------------------------------
%% attribute authorityCertIssuer(2) External OTP-PUB-KEY:GeneralNames OPTIONAL
%%-------------------------------------------------
{Term2, Tlv3} = case Tlv2 of
[{131073, V2} | TempTlv3] ->
{dec_GeneralNames([{131076, {16, V2}}], []), TempTlv3};
_ -> {asn1_NOVALUE, Tlv2}
end,
Works around the problem for this certificate.
What I haven't dug in to is why asn1rt_ber_bin_v2__decode(B, nif) is picking 131073 instead of 131076 (see below). I don't really understand what these numbers represent or where they are coming from so I'm not sure if there is a problem with the code, or with this certificate. However, from RFC 3280, it seems like it is valid to have a Name/RDN (or any other GeneralName) as the authorityCertIssuer. Maybe there is a restriction somewhere that I'm missing, though...
decode(Type, Data)
Type: 'AuthorityKeyIdentifier'
Data: <<48,82,128,20,24,108,58,144,28,124,144,19,105,161,199,17,225,187,125,
255,122,178,251,182,161,55,49,13,48,11,6,3,85,4,10,19,4,65,117,116,
111,49,25,48,23,6,3,85,4,11,19,16,70,117,116,117,114,101,71,114,105,
100,78,105,109,98,117,115,49,11,48,9,6,3,85,4,3,19,2,67,65,130,1,0>>
element: {16,
[{131072,
<<24,108,58,144,28,124,144,19,105,161,199,17,225,187,125,255,
122,178,251,182>>},
{131073,
[{17,[{16,[{6,<<85,4,10>>},{19,<<"Auto">>}]}]},
{17,[{16,[{6,<<85,4,11>>},{19,<<"FutureGridNimbus">>}]}]},
{17,[{16,[{6,<<85,4,3>>},{19,<<"CA">>}]}]}]},
{131074,<<0>>}]}
More information about the erlang-bugs
mailing list