From c0c89cd44ed30385017d585df6429471f6b89617 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 4 Jan 2011 10:20:28 +0100 Subject: [PATCH] get_cert_chain: support larger data sets 512 bytes turned out too short for some data, so now we allocate a larger buffer instead Bug: http://curl.haxx.se/mail/archive-2011-01/0002.html --- lib/ssluse.c | 95 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/lib/ssluse.c b/lib/ssluse.c index 0b67f2186..bafc7460a 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -1865,10 +1865,10 @@ static void pubkey_show(struct SessionHandle *data, do { \ if (pubkey->pkey._type->_name != NULL) { \ int len = BN_num_bytes(pubkey->pkey._type->_name); \ - if(len < (int)sizeof(buf)) { \ - BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)buf); \ - buf[len] = 0; \ - pubkey_show(data, _num, #_type, #_name, (unsigned char*)buf, len); \ + if(len < CERTBUFFERSIZE) { \ + BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)bufp); \ + bufp[len] = 0; \ + pubkey_show(data, _num, #_type, #_name, (unsigned char*)bufp, len); \ } \ } \ } while (0) @@ -1984,25 +1984,38 @@ static int init_certinfo(struct SessionHandle *data, return 0; } +/* + * This size was previously 512 which has been reported "too small" without + * any specifics, so it was enlarged to allow more data to get shown uncut. + * The "perfect" size is yet to figure out. + */ +#define CERTBUFFERSIZE 8192 + static CURLcode get_cert_chain(struct connectdata *conn, struct ssl_connect_data *connssl) { STACK_OF(X509) *sk; int i; - char buf[512]; + char *bufp; struct SessionHandle *data = conn->data; int numcerts; - sk = SSL_get_peer_cert_chain(connssl->handle); - - if(!sk) + bufp = malloc(CERTBUFFERSIZE); + if(!bufp) return CURLE_OUT_OF_MEMORY; + sk = SSL_get_peer_cert_chain(connssl->handle); + if(!sk) { + free(bufp); + return CURLE_OUT_OF_MEMORY; + } + numcerts = sk_X509_num(sk); - - if(init_certinfo(data, numcerts)) + if(init_certinfo(data, numcerts)) { + free(bufp); return CURLE_OUT_OF_MEMORY; + } infof(data, "--- Certificate chain\n"); for (i=0; ilength <= 4) { value = ASN1_INTEGER_get(num); infof(data," Serial Number: %ld (0x%lx)\n", value, value); - snprintf(buf, sizeof(buf), "%lx", value); + snprintf(bufp, CERTBUFFERSIZE, "%lx", value); } else { + int left = CERTBUFFERSIZE; - ptr = buf; + ptr = bufp; *ptr++ = 0; if(num->type == V_ASN1_NEG_INTEGER) *ptr++='-'; - for (j=0; jlength; j++) { + for (j=0; (jlength) && (left>=4); j++) { /* TODO: length restrictions */ snprintf(ptr, 3, "%02x%c",num->data[j], ((j+1 == num->length)?'\n':':')); ptr += 3; + left-=4; } if(num->length) - infof(data," Serial Number: %s\n", buf); + infof(data," Serial Number: %s\n", bufp); else - buf[0]=0; + bufp[0]=0; } - if(buf[0]) - push_certinfo(data, i, "Serial Number", buf); /* hex */ + if(bufp[0]) + push_certinfo(data, i, "Serial Number", bufp); /* hex */ cinf = x->cert_info; - j = asn1_object_dump(cinf->signature->algorithm, buf, sizeof(buf)); + j = asn1_object_dump(cinf->signature->algorithm, bufp, CERTBUFFERSIZE); if(!j) { - infof(data, " Signature Algorithm: %s\n", buf); - push_certinfo(data, i, "Signature Algorithm", buf); + infof(data, " Signature Algorithm: %s\n", bufp); + push_certinfo(data, i, "Signature Algorithm", bufp); } certdate = X509_get_notBefore(x); - asn1_output(certdate, buf, sizeof(buf)); - infof(data, " Start date: %s\n", buf); - push_certinfo(data, i, "Start date", buf); + asn1_output(certdate, bufp, CERTBUFFERSIZE); + infof(data, " Start date: %s\n", bufp); + push_certinfo(data, i, "Start date", bufp); certdate = X509_get_notAfter(x); - asn1_output(certdate, buf, sizeof(buf)); - infof(data, " Expire date: %s\n", buf); - push_certinfo(data, i, "Expire date", buf); + asn1_output(certdate, bufp, CERTBUFFERSIZE); + infof(data, " Expire date: %s\n", bufp); + push_certinfo(data, i, "Expire date", bufp); - j = asn1_object_dump(cinf->key->algor->algorithm, buf, sizeof(buf)); + j = asn1_object_dump(cinf->key->algor->algorithm, bufp, CERTBUFFERSIZE); if(!j) { - infof(data, " Public Key Algorithm: %s\n", buf); - push_certinfo(data, i, "Public Key Algorithm", buf); + infof(data, " Public Key Algorithm: %s\n", bufp); + push_certinfo(data, i, "Public Key Algorithm", bufp); } pubkey = X509_get_pubkey(x); @@ -2094,8 +2109,8 @@ static CURLcode get_cert_chain(struct connectdata *conn, case EVP_PKEY_RSA: infof(data, " RSA Public Key (%d bits)\n", BN_num_bits(pubkey->pkey.rsa->n)); - snprintf(buf, sizeof(buf), "%d", BN_num_bits(pubkey->pkey.rsa->n)); - push_certinfo(data, i, "RSA Public Key", buf); + snprintf(bufp, CERTBUFFERSIZE, "%d", BN_num_bits(pubkey->pkey.rsa->n)); + push_certinfo(data, i, "RSA Public Key", bufp); print_pubkey_BN(rsa, n, i); print_pubkey_BN(rsa, e, i); @@ -2135,6 +2150,8 @@ static CURLcode get_cert_chain(struct connectdata *conn, dumpcert(data, x, i); } + free(bufp); + return CURLE_OK; }