Hi, This patch fixes a invalid read in i2c_ASN1_BIT_STRING() when a->data contains an empty NULL-terminated string and a->length is > 0. This can easily be reproduced by executing the following command with openssl 1.0.0g: openssl x509 -inform der -in invalid_cert.der -text
With the attached certificate. Running this command with valgrind shows: ==12934== Invalid read of size 1 ==12934== at 0x51B14E9: i2c_ASN1_BIT_STRING (a_bitstr.c:87) ==12934== by 0x51C1B5E: asn1_ex_i2c (tasn_enc.c:636) ==12934== by 0x51C1832: asn1_i2d_ex_primitive (tasn_enc.c:518) ==12934== by 0x51C0C89: ASN1_item_ex_i2d (tasn_enc.c:158) ==12934== by 0x51C14CB: asn1_template_ex_i2d (tasn_enc.c:413) ==12934== by 0x51C0FB2: ASN1_item_ex_i2d (tasn_enc.c:231) ==12934== by 0x51C12F2: asn1_template_ex_i2d (tasn_enc.c:358) ==12934== by 0x51C0C28: ASN1_item_ex_i2d (tasn_enc.c:152) ==12934== by 0x51BA922: i2d_name_canon (x_name.c:498) ==12934== by 0x51BA5C5: x509_name_canon (x_name.c:367) ==12934== by 0x51BA0C2: x509_name_ex_d2i (x_name.c:210) ==12934== by 0x51C20AE: ASN1_item_ex_d2i (tasn_dec.c:239) ==12934== Address 0x5d4490f is 1 bytes before a block of size 2 alloc'd ==12934== at 0x4C2993D: malloc (in /usr/lib/valgrind/vgpreload_memcheck- amd64-linux.so) ==12934== by 0x510709E: default_malloc_ex (mem.c:79) ==12934== by 0x510772B: CRYPTO_malloc (mem.c:306) ==12934== by 0x51CF227: ASN1_STRING_set (asn1_lib.c:389) ==12934== by 0x51BA6B0: asn1_string_canon (x_name.c:407) ==12934== by 0x51BA56D: x509_name_canon (x_name.c:356) ==12934== by 0x51BA0C2: x509_name_ex_d2i (x_name.c:210) ==12934== by 0x51C20AE: ASN1_item_ex_d2i (tasn_dec.c:239) ==12934== by 0x51C3164: asn1_template_noexp_d2i (tasn_dec.c:746) ==12934== by 0x51C2D38: asn1_template_ex_d2i (tasn_dec.c:607) ==12934== by 0x51C27DE: ASN1_item_ex_d2i (tasn_dec.c:448) ==12934== by 0x51C3164: asn1_template_noexp_d2i (tasn_dec.c:746) ==12934== ==12934== Invalid read of size 1 ==12934== at 0x51B14E9: i2c_ASN1_BIT_STRING (a_bitstr.c:87) ==12934== by 0x51C1B5E: asn1_ex_i2c (tasn_enc.c:636) ==12934== by 0x51C18D0: asn1_i2d_ex_primitive (tasn_enc.c:551) ==12934== by 0x51C0C89: ASN1_item_ex_i2d (tasn_enc.c:158) ==12934== by 0x51C14CB: asn1_template_ex_i2d (tasn_enc.c:413) ==12934== by 0x51C10B2: ASN1_item_ex_i2d (tasn_enc.c:249) ==12934== by 0x51C1640: asn1_set_seq_out (tasn_enc.c:467) ==12934== by 0x51C13BD: asn1_template_ex_i2d (tasn_enc.c:378) ==12934== by 0x51C0C28: ASN1_item_ex_i2d (tasn_enc.c:152) ==12934== by 0x51BA922: i2d_name_canon (x_name.c:498) ==12934== by 0x51BA612: x509_name_canon (x_name.c:376) ==12934== by 0x51BA0C2: x509_name_ex_d2i (x_name.c:210) ==12934== Address 0x5d4490f is 1 bytes before a block of size 2 alloc'd ==12934== at 0x4C2993D: malloc (in /usr/lib/valgrind/vgpreload_memcheck- amd64-linux.so) ==12934== by 0x510709E: default_malloc_ex (mem.c:79) ==12934== by 0x510772B: CRYPTO_malloc (mem.c:306) ==12934== by 0x51CF227: ASN1_STRING_set (asn1_lib.c:389) ==12934== by 0x51BA6B0: asn1_string_canon (x_name.c:407) ==12934== by 0x51BA56D: x509_name_canon (x_name.c:356) ==12934== by 0x51BA0C2: x509_name_ex_d2i (x_name.c:210) ==12934== by 0x51C20AE: ASN1_item_ex_d2i (tasn_dec.c:239) ==12934== by 0x51C3164: asn1_template_noexp_d2i (tasn_dec.c:746) ==12934== by 0x51C2D38: asn1_template_ex_d2i (tasn_dec.c:607) ==12934== by 0x51C27DE: ASN1_item_ex_d2i (tasn_dec.c:448) ==12934== by 0x51C3164: asn1_template_noexp_d2i (tasn_dec.c:746) This can also be remotely triggered by supplying this certificate over the wire to an openssl server or client. The attached patch fixes the problem for openssl 1.0.0g and 1.0.1 beta3. Regards, Remi Gacogne
|
Hi,
This patch fixes a invalid read in i2c_ASN1_BIT_STRING() when a->data contains an empty NULL-terminated string and a->length is > 0. This can easily be reproduced by executing the following command with openssl 1.0.0g: openssl x509 -inform der -in invalid_cert.der -text
With the attached certificate.
Running this command with valgrind shows:
==12934== Invalid read of size 1 ==12934== at 0x51B14E9: i2c_ASN1_BIT_STRING (a_bitstr.c:87) ==12934== by 0x51C1B5E: asn1_ex_i2c (tasn_enc.c:636) ==12934== by 0x51C1832: asn1_i2d_ex_primitive (tasn_enc.c:518) ==12934== by 0x51C0C89: ASN1_item_ex_i2d (tasn_enc.c:158) ==12934== by 0x51C14CB: asn1_template_ex_i2d (tasn_enc.c:413) ==12934== by 0x51C0FB2: ASN1_item_ex_i2d (tasn_enc.c:231) ==12934== by 0x51C12F2: asn1_template_ex_i2d (tasn_enc.c:358) ==12934== by 0x51C0C28: ASN1_item_ex_i2d (tasn_enc.c:152) ==12934== by 0x51BA922: i2d_name_canon (x_name.c:498) ==12934== by 0x51BA5C5: x509_name_canon (x_name.c:367) ==12934== by 0x51BA0C2: x509_name_ex_d2i (x_name.c:210) ==12934== by 0x51C20AE: ASN1_item_ex_d2i (tasn_dec.c:239) ==12934== Address 0x5d4490f is 1 bytes before a block of size 2 alloc'd ==12934== at 0x4C2993D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==12934== by 0x510709E: default_malloc_ex (mem.c:79) ==12934== by 0x510772B: CRYPTO_malloc (mem.c:306) ==12934== by 0x51CF227: ASN1_STRING_set (asn1_lib.c:389) ==12934== by 0x51BA6B0: asn1_string_canon (x_name.c:407) ==12934== by 0x51BA56D: x509_name_canon (x_name.c:356) ==12934== by 0x51BA0C2: x509_name_ex_d2i (x_name.c:210) ==12934== by 0x51C20AE: ASN1_item_ex_d2i (tasn_dec.c:239) ==12934== by 0x51C3164: asn1_template_noexp_d2i (tasn_dec.c:746) ==12934== by 0x51C2D38: asn1_template_ex_d2i (tasn_dec.c:607) ==12934== by 0x51C27DE: ASN1_item_ex_d2i (tasn_dec.c:448) ==12934== by 0x51C3164: asn1_template_noexp_d2i (tasn_dec.c:746) ==12934== ==12934== Invalid read of size 1 ==12934== at 0x51B14E9: i2c_ASN1_BIT_STRING (a_bitstr.c:87) ==12934== by 0x51C1B5E: asn1_ex_i2c (tasn_enc.c:636) ==12934== by 0x51C18D0: asn1_i2d_ex_primitive (tasn_enc.c:551) ==12934== by 0x51C0C89: ASN1_item_ex_i2d (tasn_enc.c:158) ==12934== by 0x51C14CB: asn1_template_ex_i2d (tasn_enc.c:413) ==12934== by 0x51C10B2: ASN1_item_ex_i2d (tasn_enc.c:249) ==12934== by 0x51C1640: asn1_set_seq_out (tasn_enc.c:467) ==12934== by 0x51C13BD: asn1_template_ex_i2d (tasn_enc.c:378) ==12934== by 0x51C0C28: ASN1_item_ex_i2d (tasn_enc.c:152) ==12934== by 0x51BA922: i2d_name_canon (x_name.c:498) ==12934== by 0x51BA612: x509_name_canon (x_name.c:376) ==12934== by 0x51BA0C2: x509_name_ex_d2i (x_name.c:210) ==12934== Address 0x5d4490f is 1 bytes before a block of size 2 alloc'd ==12934== at 0x4C2993D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==12934== by 0x510709E: default_malloc_ex (mem.c:79) ==12934== by 0x510772B: CRYPTO_malloc (mem.c:306) ==12934== by 0x51CF227: ASN1_STRING_set (asn1_lib.c:389) ==12934== by 0x51BA6B0: asn1_string_canon (x_name.c:407) ==12934== by 0x51BA56D: x509_name_canon (x_name.c:356) ==12934== by 0x51BA0C2: x509_name_ex_d2i (x_name.c:210) ==12934== by 0x51C20AE: ASN1_item_ex_d2i (tasn_dec.c:239) ==12934== by 0x51C3164: asn1_template_noexp_d2i (tasn_dec.c:746) ==12934== by 0x51C2D38: asn1_template_ex_d2i (tasn_dec.c:607) ==12934== by 0x51C27DE: ASN1_item_ex_d2i (tasn_dec.c:448) ==12934== by 0x51C3164: asn1_template_noexp_d2i (tasn_dec.c:746)
This can also be remotely triggered by supplying this certificate over the wire to an openssl server or client. The attached patch fixes the problem for openssl 1.0.0g and 1.0.1 beta3.
Regards,
Remi Gacogne
|
invalid_cert.der
Description: application/x509-ca-cert
--- openssl-1.0.0g-orig/crypto/asn1/a_bitstr.c 2008-11-12 04:57:48.000000000 +0100
+++ openssl-1.0.0g/crypto/asn1/a_bitstr.c 2012-02-26 17:30:56.706661844 +0100
@@ -84,16 +84,21 @@
{
if (a->data[len-1]) break;
}
- j=a->data[len-1];
- if (j & 0x01) bits=0;
- else if (j & 0x02) bits=1;
- else if (j & 0x04) bits=2;
- else if (j & 0x08) bits=3;
- else if (j & 0x10) bits=4;
- else if (j & 0x20) bits=5;
- else if (j & 0x40) bits=6;
- else if (j & 0x80) bits=7;
- else bits=0; /* should not happen */
+ if (len > 0)
+ {
+ j=a->data[len-1];
+ if (j & 0x01) bits=0;
+ else if (j & 0x02) bits=1;
+ else if (j & 0x04) bits=2;
+ else if (j & 0x08) bits=3;
+ else if (j & 0x10) bits=4;
+ else if (j & 0x20) bits=5;
+ else if (j & 0x40) bits=6;
+ else if (j & 0x80) bits=7;
+ else bits=0; /* should not happen */
+ }
+ else
+ bits=0;
}
}
else
