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]