OpenSSL people, First of all, many thanks for your excellent libraries. I apologize if this issue has already been addressed or if I am writing to the wrong mailing list.
The application I am developing makes very frequent calls to d2i_X509_bio(), on untrusted data streams can sometimes be corrupt or partly corrupt. I am seeing sudden blow-ups of the process: it suddenly grows to a very large and apparently random size (e.g., 200MB, 500MB, 800MB...) and keeps on running. This happens with both engine-0.9.6b and engine-0.9.6c. I suspect the problem is in d2i_X509()'s ASN1 parser. I managed to partly reproduce the problem by running the program tucked at the end of this message for about 20 to 30 minutes. I am saying "partly", because with this program I did not manage to have the process grow and keep on running; rather, it grows and immediately segfaults with a huge core file. Both the original application (which I am not able to debug directly) and the test program output a lot of ASN1 errors from d2i_X509() and downwards. Looking in crypto/asn1/asn1_lib.c:ASN1_get_object() I saw this: #if 0 fprintf(stderr,"p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n", (int)p,*plength,omax,(int)*pp,(int)(p+ *plength), (int)(omax+ *pp)); #endif #if 0 if ((p+ *plength) > (omax+ *pp)) { ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_TOO_LONG); /* Set this so that even if things are not long enough * the values are set correctly */ ret|=0x80; } #endif Which seemed suspicious to me. Since *plength is read from the parsed stream, corruption could make it be any number, which is, if not sanity-checked, eventually fed to OPENSSL_malloc() and memcpy() by ASN1_get_object()'s users. That could explain the blow-ups and the crashes. Removing the #if and changing the test to if (*plength < 0 || *plength > (omax - (p - *pp))) (p + *plength can wrap) got rid of the blow-ups and core files. So: - Was the test #if'd out on purpose? Is there a problem with putting it back? Do you have any recommendations? - Could this explain also a blow-up without a segfault? Could something else? - Is this a security issue? I imagine that a crafted invalid certificate could bring down a server, maybe even cause it to send sensitive information (because of the memcpy()). Thanks in advance, -- Adi Stav - developer Topaz Prism R&D Mercury Interactive +972-3-5399481 [EMAIL PROTECTED] -------------------------------------------------------------------- #include <stdlib.h> #include <stdio.h> #include <openssl/x509.h> int main(int argc, char *argv[]) { unsigned char cert[10240], buf[10240], *p = cert; unsigned len; FILE *certfile; int stat; int i; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); if (argc != 3) { fprintf(stderr, "usage: %s cert iterations\n", argv[0]); return 6; } if (!(certfile = fopen(argv[1], "r"))) { perror(argv[1]); return 3; } i = atoi(argv[2]); while ((stat = fread(p, 1, sizeof cert - (p - cert), certfile)) > 0) { p += stat; } if (stat < 0) { perror(argv[1]); return 1; } len = p - cert; while (i--) { int randlen; X509 *x509; randlen = random() % 1500; memcpy(buf, cert, randlen); RAND_pseudo_bytes(buf + randlen, len - randlen); p = buf; if ((x509 = d2i_X509(NULL, &p, len))) { X509_free(x509); } else { ERR_print_errors_fp(stderr); } } return 0; } ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]