[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