aboutsummaryrefslogtreecommitdiff
path: root/lib/nss.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nss.c')
-rw-r--r--lib/nss.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/lib/nss.c b/lib/nss.c
index 43576e6d5..2562fcfdb 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -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;
}