[erlang-bugs] bug decoding domain components in certificate?

Warren Smith <>
Fri Aug 3 21:10:31 CEST 2012


I've come across another problem with decoding some certificates in R15B01. An example certificate where the problem occurs is:

$ cat 684261aa.0
-----BEGIN CERTIFICATE-----
MIIEHTCCAwWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBuMRMwEQYKCZImiZPyLGQB
GRMDRURVMRYwFAYKCZImiZPyLGQBGRMGVVRFWEFTMRQwEgYKCZImiZPyLGQBGRME
VEFDQzESMBAGA1UEChMJVVQtQVVTVElOMRUwEwYDVQQDEwxUQUNDIFJvb3QgQ0Ew
HhcNMDgxMDAyMDM1NjAyWhcNMTgwOTMwMDM1NjAyWjBuMRMwEQYKCZImiZPyLGQB
GRMDRURVMRYwFAYKCZImiZPyLGQBGRMGVVRFWEFTMRQwEgYKCZImiZPyLGQBGRME
VEFDQzESMBAGA1UEChMJVVQtQVVTVElOMRUwEwYDVQQDEwxUQUNDIFJvb3QgQ0Ew
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwlD+7dc8Am/rnd1bvvyW+
UGlkXb3KxlObgmlx0RdznJvWrxCPz4/nfvk87toUX2L4fxv3/mO3Q6n0UVFc83og
oJlNh8oqNJuVotH6jg+e65XD0z4QSNSgLVAWGV/9TU93PGUALgfXJFng3VbJ/Ljb
o01RbOQjOD7e5VJIx52wlOiyaMQlaV0yZ4C5OxgpKR/X2xMtqbuCGVIieeOBJtzg
cvatyuEIZBSHA/qhX51Rqrfc8MtKeZ/Zu7K4v0RC77bolptsAg36LCRR1T9BcyJx
Gv+yj52m5bPBuJj6ALEx/CkI6fAmkDGLvtIwZJRByrN8BdXYrBme6q0NChJg1pPR
AgMAyfujgcUwgcIwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjXUjaNFVmWzD
ph6G/N/EU+jlU8cwHwYDVR0jBBgwFoAUjXUjaNFVmWzDph6G/N/EU+jlU8cwDgYD
VR0PAQH/BAQDAgEGMB0GA1UdEQQWMBSBEmNhQHRhY2MudXRleGFzLmVkdTBABgNV
HR8EOTA3MDWgM6Axhi9odHRwOi8vd3d3LnRhY2MudXRleGFzLmVkdS9DQS9UQUND
X1Jvb3RfQ1JMLmRlcjANBgkqhkiG9w0BAQUFAAOCAQEAm7B3gK4RiE50ct2cAbhT
dD1BOHXVIIb312ZlqB6IqwM+EFfo4HW82/bDbfPfF8QZMvESuRkFl0mVK5hYPT12
VWsQC5sX6wz1ps5dgoaJ+lLZbgb3pStnN0lZEAfufMog98GM+DW6YnJaWIYpv2Mv
QbRYInGZAYWHR2GJbUjyKh2u0sJZOHJjffDL4NCUsA2thaKDcE0CG8bjwikYEVHX
j6GTY5rLsKW2NfJ8VU40dPEGjtWMOsC0HFoy27Nj5Gi2j6WpRD49EKN7+pg6Dy2I
Em9R60Sl6WhKgo//3+mg8/mZqsqCQSq5BNa7M5ltyx1RgFPoRhKlTDXLDzxVEFNk
Cg==
-----END CERTIFICATE-----

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]).

And the error I see is:

$ erl -noshell -s test_cert cert_from_file 684261aa.0 -s init stop
{"init terminating in do_boot",{{badmatch,{error,{asn1,{{case_clause,22},[{'OTP-PUB-KEY',check_and_convert_restricted_string,5,[{file,"OTP-PUB-KEY.erl"},{line,14128}]},{'OTP-PUB-KEY',decode,2,[{file,"OTP-PUB-KEY.erl"},{line,499}]},{pubkey_cert_records,transform,2,[{file,"pubkey_cert_records.erl"},{line,60}]},{lists,map,2,[{file,"lists.erl"},{line,1173}]},{pubkey_cert_records,transform,2,[{file,"pubkey_cert_records.erl"},{line,72}]},{pubkey_cert_records,decode_tbs,1,[{file,"pubkey_cert_records.erl"},{line,189}]},{pubkey_cert_records,decode_cert,1,[{file,"pubkey_cert_records.erl"},{line,40}]},{public_key,pkix_decode_cert,2,[{file,"public_key.erl"},{line,211}]}]}}}},[{public_key,pkix_decode_cert,2,[{file,"public_key.erl"},{line,215}]},{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 ()

I see that dec_DomainComponent(Tlv, TagIn) gets arguments:

  Tlv: {19,<<"EDU">>}
  TagIn: [22]

And this results (after a couple levels of function calls) in match_tags() returning:

{error,{asn1,{wrong_tag,{19,22}}}}

It looks like this certificate has domain components that use the type poste-restante-address (19) while the erlang code expects extended-network-address (22). I'm not entirely sure what the correct behavior should be. I spent some time looking around the X.509-related RFCs and didn't manage to find constraints on what types can be used in domain components. 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, though.

I just did a work around by changing dec_DomainComponent() from:

dec_DomainComponent(Tlv) ->
    dec_DomainComponent(Tlv, [22]).

To:

dec_DomainComponent(Tlv) ->
    {Tag, Data} = Tlv,
    case Tag of
        19 -> decode_restricted_string(Tlv, [], Tag, [Tag]);
        22 -> decode_restricted_string(Tlv, [], Tag, [Tag])
    end.





More information about the erlang-bugs mailing list