gbarr / perl-Convert-ASN1

encode/decode data using ASN.1 description
http://search.cpan.org/dist/Convert-ASN1/
13 stars 21 forks source link

Constructed ("indef") primitive values with tag not working #35

Open stbuehler opened 7 years ago

stbuehler commented 7 years ago

Hi,

given the following ASN.1 definition:

v ::= SEQUENCE { d [0] IMPLICIT OCTET STRING }

it seems the following input should be allowed:

$ printf '\x30\x80\xa0\x80\x04\x06Hello \x04\x06World!\x00\x00\x00\x00' | openssl asn1parse -inform DER -i
    0:d=0  hl=2 l=inf  cons: SEQUENCE          
    2:d=1  hl=2 l=inf  cons:  cont [ 0 ]        
    4:d=2  hl=2 l=   6 prim:   OCTET STRING      :Hello 
   12:d=2  hl=2 l=   6 prim:   OCTET STRING      :World!
   20:d=2  hl=2 l=   0 prim:   EOC               
   22:d=1  hl=2 l=   0 prim:  EOC               

(At least I see this happening in EncryptedContent in CMS messages; openssl uses ASN1_OCTET_STRING_NDEF for this special case).

Convert::ASN1 passes the $op for the outer (possibly constructed) data to the recursion for the inner handling, but doesn't replace the [0] tag with the primitive type (4), see _decode.pm:L86.

But the inner OCTET STRINGs aren't tagged with [0], they use their primitive type.

One could try to duplicate the $op and replace the tag with the type, and pass that to the recursion:

my $inner_op = [@$op];
bless $inner_op, ref $op;
$inner_op->[cTAG] = asn_encode_tag($op->[cTYPE]);

_decode(
# ...
[$inner_op],
# ...
);

If I knew I'd always get "chunked" values, I could simply write

v ::= SEQUENCE { d [0] IMPLICIT SET OF OCTET STRING }

instead... - but this is probably not the case, and I couldn't get a CHOICE working yet either.

Test case looks like this:

#!/usr/bin/env perl

use strict;

use Convert::ASN1;
use Data::Dumper;

my $p = Convert::ASN1->new;
$p->prepare("v ::= SEQUENCE { d [0] IMPLICIT OCTET STRING }");
my $d = $p->decode("\x30\x80\xa0\x80\x04\x06Hello \x04\x06World!\x00\x00\x00\x00") or die $!;
print Dumper($d);
stbuehler commented 7 years ago

I looked it up in X.690 (08/2015):