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:
parent
6cf35852ad
commit
c0c89cd44e
95
lib/ssluse.c
95
lib/ssluse.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user