diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/hostcheck.c | 4 | ||||
| -rw-r--r-- | lib/nss.c | 46 | ||||
| -rw-r--r-- | lib/url.c | 3 | ||||
| -rw-r--r-- | lib/x509asn1.c | 100 | ||||
| -rw-r--r-- | lib/x509asn1.h | 4 | 
5 files changed, 113 insertions, 44 deletions
| diff --git a/lib/hostcheck.c b/lib/hostcheck.c index abd1fa0c3..4be5baa92 100644 --- a/lib/hostcheck.c +++ b/lib/hostcheck.c @@ -23,7 +23,7 @@  #include "curl_setup.h"  #if defined(USE_SSLEAY) || defined(USE_AXTLS) || defined(USE_QSOSSL) || \ -    defined(USE_GSKIT) +    defined(USE_GSKIT) || defined(USE_NSS)  /* these backends use functions from this file */  #include "hostcheck.h" @@ -94,4 +94,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)    return 0;  } -#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT */ +#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT or NSS */ @@ -653,6 +653,10 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)    SSLChannelInfo channel;    SSLCipherSuiteInfo suite;    CERTCertificate *cert; +  CERTCertificate *cert2; +  CERTCertificate *cert3; +  PRTime now; +  int i;    if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==       SECSuccess && channel.length == sizeof channel && @@ -663,11 +667,45 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)      }    } -  infof(conn->data, "Server certificate:\n"); -    cert = SSL_PeerCertificate(sock); -  display_cert_info(conn->data, cert); -  CERT_DestroyCertificate(cert); + +  if(cert) { +    infof(conn->data, "Server certificate:\n"); + +    if(!conn->data->set.ssl.certinfo) { +      display_cert_info(conn->data, cert); +      CERT_DestroyCertificate(cert); +    } +    else { +      /* Count certificates in chain. */ +      now = PR_Now(); +      i = 1; +      if(!cert->isRoot) { +        cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA); +        while(cert2) { +          i++; +          if(cert2->isRoot) { +            CERT_DestroyCertificate(cert2); +            break; +          } +          cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA); +          CERT_DestroyCertificate(cert2); +          cert2 = cert3; +        } +      } +      Curl_ssl_init_certinfo(conn->data, i); +      for(i = 0; cert; cert = cert2) { +        Curl_extract_certinfo(conn, i++, cert->derCert.data, +                              cert->derCert.data + cert->derCert.len); +        if(cert->isRoot) { +          CERT_DestroyCertificate(cert); +          break; +        } +        cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA); +        CERT_DestroyCertificate(cert); +      } +    } +  }    return;  } @@ -1926,7 +1926,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,      data->set.ssl.fsslctxp = va_arg(param, void *);      break;  #endif -#if defined(USE_SSLEAY) || defined(USE_QSOSSL) || defined(USE_GSKIT) +#if defined(USE_SSLEAY) || defined(USE_QSOSSL) || defined(USE_GSKIT) || \ +    defined(USE_NSS)    case CURLOPT_CERTINFO:      data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;      break; diff --git a/lib/x509asn1.c b/lib/x509asn1.c index 94b89b2be..d6aa04596 100644 --- a/lib/x509asn1.c +++ b/lib/x509asn1.c @@ -22,7 +22,7 @@  #include "curl_setup.h" -#if defined(USE_QSOSSL) || defined(USE_GSKIT) +#if defined(USE_QSOSSL) || defined(USE_GSKIT) || defined(USE_NSS)  #include <curl/curl.h>  #include "urldata.h" @@ -803,7 +803,7 @@ static const char * dumpAlgo(curl_asn1Element * param,    return OID2str(oid.beg, oid.end, TRUE);  } -static void do_pubkey_field(struct SessionHandle *data, int certnum, +static void do_pubkey_field(struct SessionHandle * data, int certnum,                              const char * label, curl_asn1Element * elem)  {    const char * output; @@ -812,8 +812,10 @@ static void do_pubkey_field(struct SessionHandle *data, int certnum,    output = Curl_ASN1tostr(elem, 0);    if(output) { -    Curl_ssl_push_certinfo(data, certnum, label, output); -    infof(data, "   %s: %s\n", label, output); +    if(data->set.ssl.certinfo) +      Curl_ssl_push_certinfo(data, certnum, label, output); +    if(!certnum) +      infof(data, "   %s: %s\n", label, output);      free((char *) output);    }  } @@ -845,11 +847,14 @@ static void do_pubkey(struct SessionHandle * data, int certnum,          len--;      if(len > 32)        elem.beg = q;     /* Strip leading zero bytes. */ -    infof(data, "   RSA Public Key (%lu bits)\n", len); -    q = curl_maprintf("%lu", len); -    if(q) { -      Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q); -      free((char *) q); +    if(!certnum) +      infof(data, "   RSA Public Key (%lu bits)\n", len); +    if(data->set.ssl.certinfo) { +      q = curl_maprintf("%lu", len); +      if(q) { +        Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q); +        free((char *) q); +      }      }      /* Generate coefficients. */      do_pubkey_field(data, certnum, "rsa(n)", &elem); @@ -896,6 +901,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,    size_t i;    size_t j; +  if(!data->set.ssl.certinfo) +    if(certnum) +      return CURLE_OK; +    /* Prepare the certificate information for curl_easy_getinfo(). */    /* Extract the certificate ASN.1 elements. */ @@ -905,35 +914,44 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,    ccp = Curl_DNtostr(&cert.subject);    if(!ccp)      return CURLE_OUT_OF_MEMORY; -  Curl_ssl_push_certinfo(data, certnum, "Subject", ccp); -  infof(data, "%2d Subject: %s\n", certnum, ccp); +  if(data->set.ssl.certinfo) +    Curl_ssl_push_certinfo(data, certnum, "Subject", ccp); +  if(!certnum) +    infof(data, "%2d Subject: %s\n", certnum, ccp);    free((char *) ccp);    /* Issuer. */    ccp = Curl_DNtostr(&cert.issuer);    if(!ccp)      return CURLE_OUT_OF_MEMORY; -  Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp); -  infof(data, "   Issuer: %s\n", ccp); +  if(data->set.ssl.certinfo) +    Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp); +  if(!certnum) +    infof(data, "   Issuer: %s\n", ccp);    free((char *) ccp);    /* Version (always fits in less than 32 bits). */    version = 0;    for(ccp = cert.version.beg; ccp < cert.version.end; ccp++)      version = (version << 8) | *(const unsigned char *) ccp; -  ccp = curl_maprintf("%lx", version); -  if(!ccp) -    return CURLE_OUT_OF_MEMORY; -  Curl_ssl_push_certinfo(data, certnum, "Version", ccp); -  free((char *) ccp); -  infof(data, "   Version: %lu (0x%lx)\n", version + 1, version); +  if(data->set.ssl.certinfo) { +    ccp = curl_maprintf("%lx", version); +    if(!ccp) +      return CURLE_OUT_OF_MEMORY; +    Curl_ssl_push_certinfo(data, certnum, "Version", ccp); +    free((char *) ccp); +  } +  if(!certnum) +    infof(data, "   Version: %lu (0x%lx)\n", version + 1, version);    /* Serial number. */    ccp = Curl_ASN1tostr(&cert.serialNumber, 0);    if(!ccp)      return CURLE_OUT_OF_MEMORY; -  Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp); -  infof(data, "   Serial Number: %s\n", ccp); +  if(data->set.ssl.certinfo) +    Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp); +  if(!certnum) +    infof(data, "   Serial Number: %s\n", ccp);    free((char *) ccp);    /* Signature algorithm .*/ @@ -941,24 +959,30 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,                   cert.signatureAlgorithm.end);    if(!ccp)      return CURLE_OUT_OF_MEMORY; -  Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp); -  infof(data, "   Signature Algorithm: %s\n", ccp); +  if(data->set.ssl.certinfo) +    Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp); +  if(!certnum) +    infof(data, "   Signature Algorithm: %s\n", ccp);    free((char *) ccp);    /* Start Date. */    ccp = Curl_ASN1tostr(&cert.notBefore, 0);    if(!ccp)      return CURLE_OUT_OF_MEMORY; -  Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp); -  infof(data, "   Start Date: %s\n", ccp); +  if(data->set.ssl.certinfo) +    Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp); +  if(!certnum) +    infof(data, "   Start Date: %s\n", ccp);    free((char *) ccp);    /* Expire Date. */    ccp = Curl_ASN1tostr(&cert.notAfter, 0);    if(!ccp)      return CURLE_OUT_OF_MEMORY; -  Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp); -  infof(data, "   Expire Date: %s\n", ccp); +  if(data->set.ssl.certinfo) +    Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp); +  if(!certnum) +    infof(data, "   Expire Date: %s\n", ccp);    free((char *) ccp);    /* Public Key Algorithm. */ @@ -966,8 +990,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,                   cert.subjectPublicKeyAlgorithm.end);    if(!ccp)      return CURLE_OUT_OF_MEMORY; -  Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp); -  infof(data, "   Public Key Algorithm: %s\n", ccp); +  if(data->set.ssl.certinfo) +    Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp); +  if(!certnum) +    infof(data, "   Public Key Algorithm: %s\n", ccp);    do_pubkey(data, certnum, ccp, ¶m, &cert.subjectPublicKey);    free((char *) ccp); @@ -977,8 +1003,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,    ccp = Curl_ASN1tostr(&cert.signature, 0);    if(!ccp)      return CURLE_OUT_OF_MEMORY; -  Curl_ssl_push_certinfo(data, certnum, "Signature", ccp); -  infof(data, "   Signature: %s\n", ccp); +  if(data->set.ssl.certinfo) +    Curl_ssl_push_certinfo(data, certnum, "Signature", ccp); +  if(!certnum) +    infof(data, "   Signature: %s\n", ccp);    free((char *) ccp);    /* Generate PEM certificate. */ @@ -987,7 +1015,7 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,                            &cp1, &cl1);    if(cc != CURLE_OK)      return cc; -  /* Compute the number of charaters in final certificate string. Format is: +  /* Compute the number of characters in final certificate string. Format is:       -----BEGIN CERTIFICATE-----\n       <max 64 base64 characters>\n       . @@ -1008,8 +1036,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,    i += copySubstring(cp2 + i, "-----END CERTIFICATE-----");    cp2[i] = '\0';    free(cp1); -  Curl_ssl_push_certinfo(data, certnum, "Cert", cp2); -  infof(data, "%s\n", cp2); +  if(data->set.ssl.certinfo) +    Curl_ssl_push_certinfo(data, certnum, "Cert", cp2); +  if(!certnum) +    infof(data, "%s\n", cp2);    free(cp2);    return CURLE_OK;  } @@ -1148,4 +1178,4 @@ CURLcode Curl_verifyhost(struct connectdata * conn,    return CURLE_PEER_FAILED_VERIFICATION;  } -#endif /* USE_QSOSSL or USE_GSKIT */ +#endif /* USE_QSOSSL or USE_GSKIT or USE_NSS */ diff --git a/lib/x509asn1.h b/lib/x509asn1.h index 2276b5b64..1741d6dca 100644 --- a/lib/x509asn1.h +++ b/lib/x509asn1.h @@ -25,7 +25,7 @@  #include "curl_setup.h" -#if defined(USE_QSOSSL) || defined(USE_GSKIT) +#if defined(USE_QSOSSL) || defined(USE_GSKIT) || defined(USE_NSS)  #include "urldata.h" @@ -125,5 +125,5 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum,  CURLcode Curl_verifyhost(struct connectdata * conn,                           const char * beg, const char * end); -#endif /* USE_QSOSSL or USE_GSKIT */ +#endif /* USE_QSOSSL or USE_GSKIT or USE_NSS */  #endif /* HEADER_CURL_X509ASN1_H */ | 
