erlang / otp

Erlang/OTP
http://erlang.org
Apache License 2.0
11.36k stars 2.95k forks source link

ASN-1 compiler fails to decode a 'UserNotice' from PKIX standard test suite #7727

Closed IngelaAndin closed 1 year ago

IngelaAndin commented 1 year ago

Describe the bug When implementing support for certificate policies in our public_key application I enabled more tests from http://csrc.nist.gov/groups/ST/crypto_apps_infra/pki/pkitesting.html and one of them includes a entity of ASN-1 type 'UserNotice' which fails to decode.

To Reproduce

 DER =   <<48,130,1,58,26,130,1,54,113,54,58,
                                          32,32,83,101,99,116,105,111,110,32,
                                          52,46,50,46,49,46,53,32,111,102,32,
                                          82,70,67,32,51,50,56,48,32,115,116,
                                          97,116,101,115,32,116,104,101,32,
                                          109,97,120,105,109,117,109,32,115,
                                          105,122,101,32,111,102,32,101,120,
                                          112,108,105,99,105,116,84,101,120,
                                          116,32,105,115,32,50,48,48,32,99,
                                          104,97,114,97,99,116,101,114,115,
                                          44,32,98,117,116,32,119,97,114,110,
                                          115,32,116,104,97,116,32,115,111,
                                          109,101,32,110,111,110,45,99,111,
                                          110,102,111,114,109,105,110,103,32,
                                          67,65,115,32,101,120,99,101,101,
                                          100,32,116,104,105,115,32,108,105,
                                          109,105,116,46,32,32,84,104,117,
                                          115,32,82,70,67,32,51,50,56,48,32,
                                          115,116,97,116,101,115,32,116,104,
                                          97,116,32,99,101,114,116,105,102,
                                          105,99,97,116,101,32,117,115,101,
                                          114,115,32,83,72,79,85,76,68,32,
                                          103,114,97,99,101,102,117,108,108,
                                          121,32,104,97,110,100,108,101,32,
                                          101,120,112,108,105,99,105,116,84,
                                          101,120,116,32,119,105,116,104,32,
                                          109,111,114,101,32,116,104,97,110,
                                          32,50,48,48,32,99,104,97,114,97,99,
                                          116,101,114,115,46,32,32,84,104,
                                          105,115,32,101,120,112,108,105,99,
                                          105,116,84,101,120,116,32,105,115,
                                          32,111,118,101,114,32,50,48,48,32,
                                          99,104,97,114,97,99,116,101,114,
                                          115,32,108,111,110,103>>.

 public_key:der_decode('UserNotice', DER).
** exception error: no match of right hand side value
                    {error,
                        {asn1,
                            {bad_range,
                                [{'OTP-PUB-KEY',dec_DisplayText,2,
                                     [{file,"../src/OTP-PUB-KEY.erl"},{line,7218}]},
                                 {'OTP-PUB-KEY',dec_UserNotice,2,
                                     [{file,"../src/OTP-PUB-KEY.erl"},{line,7381}]},
                                 {'OTP-PUB-KEY',decode,2,
                                     [{file,"../src/OTP-PUB-KEY.erl"},{line,1233}]},
                                 {public_key,der_decode,2,
                                     [{file,"public_key.erl"},{line,348}]},
                                 {erl_eval,do_apply,7,[{file,"erl_eval.erl"},{line,750}]},
                                 {shell,exprs,7,[{file,"shell.erl"},{line,780}]},
                                 {shell,eval_exprs,7,[{file,"shell.erl"},{line,736}]},
                                 {shell,eval_loop,4,[{file,"shell.erl"},{line,721}]}]}}}
     in function  public_key:der_decode/2 (public_key.erl, line 352)
    ;

Expected behavior I expect to get something like this: (this is another UserNotice from the same test suite)

{'UserNotice',asn1_NOVALUE, {visibleString,"q8: This is the user notice from qualifier 8 associated with anyPolicy. This user notice should be displayed when NIST-test-policy-2 is in the user-constrained-policy-set"}

Affected versions

I am running this on the maint branch.

Additional context

For OTP team members: This is related to #7579, but as it is under development the latest version is not yet pushed to github
if you want the failing test case please use my internal branch with same name, however the interesting part for you should be the code showed above.

IngelaAndin commented 1 year ago

@bjorng now the PR fails too, as I finished up the other things I was doing with the implementation.

bjorng commented 1 year ago

@IngelaAndin This is not a bug in the ASN.1 compiler. Decoding fails because the actual size of the string exceeds the max number of characters allowed by the constraint in the ASN.1 spec. If I remove the upper limit for the number of characters:

diff --git a/lib/public_key/asn1/PKIX1Implicit88.asn1 b/lib/public_key/asn1/PKIX1Implicit88.asn1
index ced270baf6..6570ecdc8b 100644
--- a/lib/public_key/asn1/PKIX1Implicit88.asn1
+++ b/lib/public_key/asn1/PKIX1Implicit88.asn1
@@ -107,7 +107,7 @@ NoticeReference ::= SEQUENCE {

 DisplayText ::= CHOICE {
      ia5String        IA5String      (SIZE (1..200)),
-     visibleString    VisibleString  (SIZE (1..200)),
+     visibleString    VisibleString  (SIZE (1..MAX)),
      bmpString        BMPString      (SIZE (1..200)),
      utf8String       UTF8String     (SIZE (1..200)) }

decoding succeeds, returning the following term:

{'UserNotice',asn1_NOVALUE,
              {visibleString,"q6:  Section 4.2.1.5 of RFC 3280 states the maximum size of explicitText is 200 characters, but warns that some non-conforming CAs exceed this limit.  Thus RFC 3280 states that certificate users SHOULD gracefully handle explicitText with more than 200 characters.  This explicitText is over 200 characters long"}}
IngelaAndin commented 1 year ago

Oh, thanks for finding this out. I really hate all these pragmatic workarounds. I guess I have to make some kind of workaround for this with an alternative spec that allows a little more and if it still fails return some kind default notice saying it was too long.