gbarr / perl-Convert-ASN1

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

Length verification #8

Open eabalea opened 11 years ago

eabalea commented 11 years ago

In decoding "unsafe" data (submitted by an unknown user) against a valid ASN.1 description, I fell on an error. If my buffer is padded with unnecessary data, the decoding parser tries to decode past the object, and can be stuck.

An actual example below.

#! /usr/bin/perl

use Convert::ASN1;

my $hexdata = 
"30 53 30 51 30 4f 30 4d 30 4b 30 09 06 05 2b 0e\
 03 02 1a 05 00 04 14 a0 72 0e a0 6a 7c 62 02 54\
 f2 a8 f5 9d d2 7b a4 f3 b7 2f a4 04 14 b0 b0 4a\
 fd 1c 75 28 f8 1c 61 aa 13 f6 fa c1 90 3d 6b 16\
 a3 02 12 11 21 bc 57 28 6f 30 08 db 49 63 f6 ae\
 89 3a de f6 d1 ff e0";
$hexdata =~ s/ //g;
$hexdata =~ s/\n//g;

# parse ASN.1 descriptions
my $asn = Convert::ASN1->new;
$asn->prepare(<<ASN1) or die "prepare: ", $asn->error;
   OCSPRequest     ::=     SEQUENCE {
       tbsRequest                  TBSRequest,
       optionalSignature   [0]     EXPLICIT ANY OPTIONAL }

   TBSRequest      ::=     SEQUENCE {
       version             [0]     EXPLICIT INTEGER OPTIONAL,
       requestorName       [1]     EXPLICIT ANY OPTIONAL,
       requestList                 SEQUENCE OF Request,
       requestExtensions   [2]     EXPLICIT ANY OPTIONAL }

   Request         ::=     SEQUENCE {
       reqCert                     CertID,
       singleRequestExtensions     [0] EXPLICIT ANY OPTIONAL }

   CertID          ::=     SEQUENCE {
       hashAlgorithm       ANY,
       issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
       issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
       serialNumber        INTEGER }
ASN1

my $asn_ocspreq = $asn->find('OCSPRequest');

my $OCSPREQDER = pack("H*", $hexdata);
my $ocspreq = $asn_ocspreq->decode($OCSPREQDER);
if (defined $ocspreq) {
  print "I got it\n";
}

The ->decode() call doesn't finish, and I think its caused by the extraneous 'ff e0' bytes (that could be the start of a very large object).

I can't avoid this extra data to happen, the module has already decoded the first object and could ignore the rest, and it could also return an error because there's not enough data ('ff e0' lacks 96 bytes just to encode the length).

eabalea commented 11 years ago

Why did the code get modified? :o

gbarr commented 11 years ago

when you want to include something verbatim on github, use ```` to surround it