Page MenuHome GnuPG

out of bounds read in ksba_cert_get_ext_key_usages called from libksba/cert-basic
Closed, ResolvedPublic

Description

The attached file oid_oob_small.crt causes a reproducible crash on my computer (x86_64,Linux,Glibc 2.21):

~/libksba-1.3.3$ ./tests/cert-basic oid_oob_small.crt
...
AuthorityKeyIdentifier: 1.2.840.113549.1.9.1=#696E73656375726540746573742E696E736563757265,CN=For Tests
Only,O=InsecureTestCertificate,C=de

       serial: (#00#)
keyIdentifier: (#BF53438278D09EC380E51B67CA0500DFB94883A5#)

KeyUsage: digitalSignature keyEncipherment keyAgreement
this is not going to end well: length=2819585
Segmentation fault

The program has been instrumented with the following change at the entry of the function ksba_oid_to_str():

diff -ru orig/libksba-1.3.3/src/oid.c libksba-1.3.3/src/oid.c

  • orig/libksba-1.3.3/src/oid.c 2014-11-25 12:42:56.000000000 +0100

+++ libksba-1.3.3/src/oid.c 2016-05-01 12:41:55.565772704 +0200
@@ -66,7 +66,7 @@

char *string, *p;
int n = 0;
unsigned long val, valmask;

+ if (length>1000000) printf("this is not going to end well: length=%zu\n", length);

   valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1));
 
   /* To calculate the length of the string we can safely assume an

After submitting this entry, I hope to be able to attach another file showing that the value of “length” can be even
larger than 2819585. The bug submission form only allows one file to be attached.

The call stack at the point of the ouf-of-bounds read is:

src/oid.c:105:[kernel] warning: out of bounds read. assert \valid_read(buf+n);

                  stack: _ksba_oid_to_str :: src/cert.c:1462 <-
                         _ksba_cert_get_ext_key_usages :: src/visibility.c:259 <-
                         ksba_cert_get_ext_key_usages :: tests/cert-basic.c:265 <-
                         list_extensions :: tests/cert-basic.c:545 <-
                         one_file :: tests/cert-basic.c:592 <-
                         main

The title refers to ksba_cert_get_ext_key_usages() as culprit because as the additional printf() call shows,
ksba_oid_to_str() is passed incoherent arguments and is not at fault.

Details

Version
1.3.3

Event Timeline

pascal_cuoq set Version to 1.3.3.
pascal_cuoq added a subscriber: pascal_cuoq.

The file oid_oob_big.crt would cause the function ksba_oid_to_str() to be called with a “length” argument of

  1. This is what execution in tis-interpreter (in which allocations always succeed) shows:


48

83

A5

this is not going to end well: length=3100166514561975041

src/oid.c:105:[kernel] warning: out of bounds read. assert \valid_read(buf_0+n);

                  stack: _ksba_oid_to_str :: src/cert.c:1462 <-
                         _ksba_cert_get_ext_key_usages :: src/visibility.c:259 <-
                         ksba_cert_get_ext_key_usages :: tests/cert-basic.c:265 <-
                         list_extensions :: tests/cert-basic.c:545 <-
                         one_file :: tests/cert-basic.c:592 <-
                         main

“Fortunately”, for the file oid_oob_big.crt, execution of the program tests/cert-basic differs in that a memory
allocation fails:

$ ./tests/cert-basic ../../libksba-1.3.3/oid_oob_big.crt
Certificate in `../../libksba-1.3.3/oid_oob_big.crt':

serial....: (#04#)
issuer....: `1.2.840.113549.1.9.1=#696E73656375726540746573742E696E736563757265,CN=For Tests

Only,O=InsecureTestCertificate,C=de'

       aka: `<insecure@test.insecure>'
subject...: `1.2.840.113549.1.9.1=#696E73656375726540746573742E696E736563757265,CN=Insecure Server

Cert,O=InsecureTestCertificate,C=de'

       aka: `<insecure@test.insecure>'
notBefore.: 2001-08-17 08:46:24
notAfter..: 2006-08-16 08:46:24
hash algo.: 1.2.840.113549.1.1.4

Extn: 2.5.29.15 at 474 with length 4
Extn: 2.5.29.37 at 487 with length 12
Extn: 2.5.29.14 at 508 with length 22
Extn: 2.5.29.35 at 541 with length 145
Extn: 2.5.29.17 at 695 with length 26
Extn: 2.5.29.18 at 730 with length 26
Extn: 2.16.840.1.113730.1.1 at 771 with length 4
Extn: 2.16.840.1.113730.1.13 at 790 with length 47
SubjectKeyIdentifier: (#0234E2C906F6E0B44253BE04C0CBA7823A6DB509#)
AuthorityKeyIdentifier: 1.2.840.113549.1.9.1=#696E73656375726540746573742E696E736563757265,CN=For Tests
Only,O=InsecureTestCertificate,C=de

       serial: (#00#)
keyIdentifier: (#BF53438278D09EC380E51B67CA0500DFB94883A5#)

KeyUsage: digitalSignature keyEncipherment keyAgreement
cert-basic.c:271: ksba_cert_ext_key_usages failed: Cannot allocate memory
CertificatePolicies: none

Regardless, between themselves, the two files oid_oob_big.crt and oid_oob_small.crt shows that an attacker seems to have
many possibilities for crafting a malicious certificate that crashes in ksba_oid_to_str() called from
ksba_cert_get_ext_key_usages().

Fixed with commit a7eed17 . Thanks.

I also checked all other places to ensure that the tag length returned from
_ksba_ber_parse_tl is within the bounds.

I just released 1.3.4 and thus closing this bug and 2342 and 2343. Thanks again
for you help.

werner removed a project: Restricted Project.