get_cert_chain: support larger data sets
authorDaniel Stenberg <daniel@haxx.se>
Tue, 4 Jan 2011 09:20:28 +0000 (10:20 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 4 Jan 2011 09:20:28 +0000 (10:20 +0100)
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

index 0b67f21..bafc746 100644 (file)
@@ -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);
+  bufp = malloc(CERTBUFFERSIZE);
+  if(!bufp)
+    return CURLE_OUT_OF_MEMORY;
 
-  if(!sk)
+  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; i<numcerts; i++) {
@@ -2022,68 +2035,70 @@ static CURLcode get_cert_chain(struct connectdata *conn,
     int j;
     char *ptr;
 
-    (void)x509_name_oneline(X509_get_subject_name(x), buf, sizeof(buf));
-    infof(data, "%2d Subject: %s\n",i,buf);
-    push_certinfo(data, i, "Subject", buf);
+    (void)x509_name_oneline(X509_get_subject_name(x), bufp, CERTBUFFERSIZE);
+    infof(data, "%2d Subject: %s\n", i, bufp);
+    push_certinfo(data, i, "Subject", bufp);
 
-    (void)x509_name_oneline(X509_get_issuer_name(x), buf, sizeof(buf));
-    infof(data, "   Issuer: %s\n",buf);
-    push_certinfo(data, i, "Issuer", buf);
+    (void)x509_name_oneline(X509_get_issuer_name(x), bufp, CERTBUFFERSIZE);
+    infof(data, "   Issuer: %s\n", bufp);
+    push_certinfo(data, i, "Issuer", bufp);
 
     value = X509_get_version(x);
     infof(data, "   Version: %lu (0x%lx)\n", value+1, value);
-    snprintf(buf, sizeof(buf), "%lx", value);
-    push_certinfo(data, i, "Version", buf); /* hex */
+    snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
+    push_certinfo(data, i, "Version", bufp); /* hex */
 
     num=X509_get_serialNumber(x);
     if (num->length <= 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; j<num->length; j++) {
+      for (j=0; (j<num->length) && (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;
 }