[erlang-bugs] bug decoding domain components in certificate?
Warren Smith
wsmith@REDACTED
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