1
0
mirror of https://github.com/moparisthebest/curl synced 2024-08-13 17:03:50 -04:00

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
This commit is contained in:
Daniel Stenberg 2011-01-04 10:20:28 +01:00
parent 6cf35852ad
commit c0c89cd44e

View File

@ -1865,10 +1865,10 @@ static void pubkey_show(struct SessionHandle *data,
do { \ do { \
if (pubkey->pkey._type->_name != NULL) { \ if (pubkey->pkey._type->_name != NULL) { \
int len = BN_num_bytes(pubkey->pkey._type->_name); \ int len = BN_num_bytes(pubkey->pkey._type->_name); \
if(len < (int)sizeof(buf)) { \ if(len < CERTBUFFERSIZE) { \
BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)buf); \ BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)bufp); \
buf[len] = 0; \ bufp[len] = 0; \
pubkey_show(data, _num, #_type, #_name, (unsigned char*)buf, len); \ pubkey_show(data, _num, #_type, #_name, (unsigned char*)bufp, len); \
} \ } \
} \ } \
} while (0) } while (0)
@ -1984,25 +1984,38 @@ static int init_certinfo(struct SessionHandle *data,
return 0; 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, static CURLcode get_cert_chain(struct connectdata *conn,
struct ssl_connect_data *connssl) struct ssl_connect_data *connssl)
{ {
STACK_OF(X509) *sk; STACK_OF(X509) *sk;
int i; int i;
char buf[512]; char *bufp;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
int numcerts; int numcerts;
sk = SSL_get_peer_cert_chain(connssl->handle); bufp = malloc(CERTBUFFERSIZE);
if(!bufp)
if(!sk)
return CURLE_OUT_OF_MEMORY; 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); numcerts = sk_X509_num(sk);
if(init_certinfo(data, numcerts)) {
if(init_certinfo(data, numcerts)) free(bufp);
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
}
infof(data, "--- Certificate chain\n"); infof(data, "--- Certificate chain\n");
for (i=0; i<numcerts; i++) { for (i=0; i<numcerts; i++) {
@ -2022,68 +2035,70 @@ static CURLcode get_cert_chain(struct connectdata *conn,
int j; int j;
char *ptr; char *ptr;
(void)x509_name_oneline(X509_get_subject_name(x), buf, sizeof(buf)); (void)x509_name_oneline(X509_get_subject_name(x), bufp, CERTBUFFERSIZE);
infof(data, "%2d Subject: %s\n",i,buf); infof(data, "%2d Subject: %s\n", i, bufp);
push_certinfo(data, i, "Subject", buf); push_certinfo(data, i, "Subject", bufp);
(void)x509_name_oneline(X509_get_issuer_name(x), buf, sizeof(buf)); (void)x509_name_oneline(X509_get_issuer_name(x), bufp, CERTBUFFERSIZE);
infof(data, " Issuer: %s\n",buf); infof(data, " Issuer: %s\n", bufp);
push_certinfo(data, i, "Issuer", buf); push_certinfo(data, i, "Issuer", bufp);
value = X509_get_version(x); value = X509_get_version(x);
infof(data, " Version: %lu (0x%lx)\n", value+1, value); infof(data, " Version: %lu (0x%lx)\n", value+1, value);
snprintf(buf, sizeof(buf), "%lx", value); snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
push_certinfo(data, i, "Version", buf); /* hex */ push_certinfo(data, i, "Version", bufp); /* hex */
num=X509_get_serialNumber(x); num=X509_get_serialNumber(x);
if (num->length <= 4) { if (num->length <= 4) {
value = ASN1_INTEGER_get(num); value = ASN1_INTEGER_get(num);
infof(data," Serial Number: %ld (0x%lx)\n", value, value); infof(data," Serial Number: %ld (0x%lx)\n", value, value);
snprintf(buf, sizeof(buf), "%lx", value); snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
} }
else { else {
int left = CERTBUFFERSIZE;
ptr = buf; ptr = bufp;
*ptr++ = 0; *ptr++ = 0;
if(num->type == V_ASN1_NEG_INTEGER) if(num->type == V_ASN1_NEG_INTEGER)
*ptr++='-'; *ptr++='-';
for (j=0; j<num->length; j++) { for (j=0; (j<num->length) && (left>=4); j++) {
/* TODO: length restrictions */ /* TODO: length restrictions */
snprintf(ptr, 3, "%02x%c",num->data[j], snprintf(ptr, 3, "%02x%c",num->data[j],
((j+1 == num->length)?'\n':':')); ((j+1 == num->length)?'\n':':'));
ptr += 3; ptr += 3;
left-=4;
} }
if(num->length) if(num->length)
infof(data," Serial Number: %s\n", buf); infof(data," Serial Number: %s\n", bufp);
else else
buf[0]=0; bufp[0]=0;
} }
if(buf[0]) if(bufp[0])
push_certinfo(data, i, "Serial Number", buf); /* hex */ push_certinfo(data, i, "Serial Number", bufp); /* hex */
cinf = x->cert_info; 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) { if(!j) {
infof(data, " Signature Algorithm: %s\n", buf); infof(data, " Signature Algorithm: %s\n", bufp);
push_certinfo(data, i, "Signature Algorithm", buf); push_certinfo(data, i, "Signature Algorithm", bufp);
} }
certdate = X509_get_notBefore(x); certdate = X509_get_notBefore(x);
asn1_output(certdate, buf, sizeof(buf)); asn1_output(certdate, bufp, CERTBUFFERSIZE);
infof(data, " Start date: %s\n", buf); infof(data, " Start date: %s\n", bufp);
push_certinfo(data, i, "Start date", buf); push_certinfo(data, i, "Start date", bufp);
certdate = X509_get_notAfter(x); certdate = X509_get_notAfter(x);
asn1_output(certdate, buf, sizeof(buf)); asn1_output(certdate, bufp, CERTBUFFERSIZE);
infof(data, " Expire date: %s\n", buf); infof(data, " Expire date: %s\n", bufp);
push_certinfo(data, i, "Expire date", buf); 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) { if(!j) {
infof(data, " Public Key Algorithm: %s\n", buf); infof(data, " Public Key Algorithm: %s\n", bufp);
push_certinfo(data, i, "Public Key Algorithm", buf); push_certinfo(data, i, "Public Key Algorithm", bufp);
} }
pubkey = X509_get_pubkey(x); pubkey = X509_get_pubkey(x);
@ -2094,8 +2109,8 @@ static CURLcode get_cert_chain(struct connectdata *conn,
case EVP_PKEY_RSA: case EVP_PKEY_RSA:
infof(data, " RSA Public Key (%d bits)\n", infof(data, " RSA Public Key (%d bits)\n",
BN_num_bits(pubkey->pkey.rsa->n)); BN_num_bits(pubkey->pkey.rsa->n));
snprintf(buf, sizeof(buf), "%d", BN_num_bits(pubkey->pkey.rsa->n)); snprintf(bufp, CERTBUFFERSIZE, "%d", BN_num_bits(pubkey->pkey.rsa->n));
push_certinfo(data, i, "RSA Public Key", buf); push_certinfo(data, i, "RSA Public Key", bufp);
print_pubkey_BN(rsa, n, i); print_pubkey_BN(rsa, n, i);
print_pubkey_BN(rsa, e, i); print_pubkey_BN(rsa, e, i);
@ -2135,6 +2150,8 @@ static CURLcode get_cert_chain(struct connectdata *conn,
dumpcert(data, x, i); dumpcert(data, x, i);
} }
free(bufp);
return CURLE_OK; return CURLE_OK;
} }