bump product version to 4.2.0.1
[LibreOffice.git] / external / curl / NSS-support-for-CERTINFO-feature.patch
blob7976a08685e418a26c721628e6c42661d9722288
1 From f6c335d63f2da025a0a3efde1fe59e3bb7189b70 Mon Sep 17 00:00:00 2001
2 From: Patrick Monnerat <pm@datasphere.ch>
3 Date: Wed, 30 Oct 2013 11:12:06 +0100
4 Subject: [PATCH] NSS: support for CERTINFO feature
6 ---
7 docs/libcurl/curl_easy_getinfo.3 | 6 +--
8 docs/libcurl/curl_easy_setopt.3 | 5 +-
9 lib/hostcheck.c | 4 +-
10 lib/nss.c | 46 ++++++++++++++++--
11 lib/url.c | 3 +-
12 lib/x509asn1.c | 100 +++++++++++++++++++++++++--------------
13 lib/x509asn1.h | 4 +-
14 7 files changed, 119 insertions(+), 49 deletions(-)
16 diff --git a/docs/libcurl/curl_easy_getinfo.3 b/docs/libcurl/curl_easy_getinfo.3
17 index 62d8ae4..db0f4d6 100644
18 --- a/docs/libcurl/curl_easy_getinfo.3
19 +++ b/docs/libcurl/curl_easy_getinfo.3
20 @@ -5,7 +5,7 @@
21 .\" * | (__| |_| | _ <| |___
22 .\" * \___|\___/|_| \_\_____|
23 .\" *
24 -.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
25 +.\" * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
26 .\" *
27 .\" * This software is licensed as described in the file COPYING, which
28 .\" * you should have received as part of this distribution. The terms
29 @@ -219,8 +219,8 @@ done. The struct reports how many certs it found and then you can extract info
30 for each of those certs by following the linked lists. The info chain is
31 provided in a series of data in the format "name:content" where the content is
32 for the specific named data. See also the certinfo.c example. NOTE: this
33 -option is only available in libcurl built with OpenSSL support. (Added in
34 -7.19.1)
35 +option is only available in libcurl built with OpenSSL, NSS, GSKit or QsoSSL
36 +support. (Added in 7.19.1)
37 .IP CURLINFO_CONDITION_UNMET
38 Pass a pointer to a long to receive the number 1 if the condition provided in
39 the previous request didn't match (see \fICURLOPT_TIMECONDITION\fP). Alas, if
40 diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
41 index f58c8fb..2887483 100644
42 --- a/docs/libcurl/curl_easy_setopt.3
43 +++ b/docs/libcurl/curl_easy_setopt.3
44 @@ -2549,9 +2549,10 @@ is ignored.
46 .IP CURLOPT_CERTINFO
47 Pass a long set to 1 to enable libcurl's certificate chain info gatherer. With
48 -this enabled, libcurl (if built with OpenSSL) will extract lots of information
49 +this enabled, libcurl (if built with OpenSSL, NSS, GSKit or QsoSSL) will
50 +extract lots of information
51 and data about the certificates in the certificate chain used in the SSL
52 -connection. This data is then possible to extract after a transfer using
53 +connection. This data may then be retrieved after a transfer using
54 \fIcurl_easy_getinfo(3)\fP and its option \fICURLINFO_CERTINFO\fP. (Added in
55 7.19.1)
56 .IP CURLOPT_RANDOM_FILE
57 diff --git a/lib/hostcheck.c b/lib/hostcheck.c
58 index abd1fa0..4be5baa 100644
59 --- a/lib/hostcheck.c
60 +++ b/lib/hostcheck.c
61 @@ -23,7 +23,7 @@
62 #include "curl_setup.h"
64 #if defined(USE_SSLEAY) || defined(USE_AXTLS) || defined(USE_QSOSSL) || \
65 - defined(USE_GSKIT)
66 + defined(USE_GSKIT) || defined(USE_NSS)
67 /* these backends use functions from this file */
69 #include "hostcheck.h"
70 @@ -94,4 +94,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
71 return 0;
74 -#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT */
75 +#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT or NSS */
76 diff --git a/lib/nss.c b/lib/nss.c
77 index 43576e6..2562fcf 100644
78 --- a/lib/nss.c
79 +++ b/lib/nss.c
80 @@ -653,6 +653,10 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
81 SSLChannelInfo channel;
82 SSLCipherSuiteInfo suite;
83 CERTCertificate *cert;
84 + CERTCertificate *cert2;
85 + CERTCertificate *cert3;
86 + PRTime now;
87 + int i;
89 if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==
90 SECSuccess && channel.length == sizeof channel &&
91 @@ -663,11 +667,45 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
95 - infof(conn->data, "Server certificate:\n");
97 cert = SSL_PeerCertificate(sock);
98 - display_cert_info(conn->data, cert);
99 - CERT_DestroyCertificate(cert);
101 + if(cert) {
102 + infof(conn->data, "Server certificate:\n");
104 + if(!conn->data->set.ssl.certinfo) {
105 + display_cert_info(conn->data, cert);
106 + CERT_DestroyCertificate(cert);
108 + else {
109 + /* Count certificates in chain. */
110 + now = PR_Now();
111 + i = 1;
112 + if(!cert->isRoot) {
113 + cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
114 + while(cert2) {
115 + i++;
116 + if(cert2->isRoot) {
117 + CERT_DestroyCertificate(cert2);
118 + break;
120 + cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA);
121 + CERT_DestroyCertificate(cert2);
122 + cert2 = cert3;
125 + Curl_ssl_init_certinfo(conn->data, i);
126 + for(i = 0; cert; cert = cert2) {
127 + Curl_extract_certinfo(conn, i++, cert->derCert.data,
128 + cert->derCert.data + cert->derCert.len);
129 + if(cert->isRoot) {
130 + CERT_DestroyCertificate(cert);
131 + break;
133 + cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
134 + CERT_DestroyCertificate(cert);
139 return;
141 diff --git a/lib/url.c b/lib/url.c
142 index e86fbc2..03c7607 100644
143 --- a/lib/url.c
144 +++ b/lib/url.c
145 @@ -1926,7 +1926,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
146 data->set.ssl.fsslctxp = va_arg(param, void *);
147 break;
148 #endif
149 -#if defined(USE_SSLEAY) || defined(USE_QSOSSL) || defined(USE_GSKIT)
150 +#if defined(USE_SSLEAY) || defined(USE_QSOSSL) || defined(USE_GSKIT) || \
151 + defined(USE_NSS)
152 case CURLOPT_CERTINFO:
153 data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
154 break;
155 diff --git a/lib/x509asn1.c b/lib/x509asn1.c
156 index 94b89b2..d6aa045 100644
157 --- a/lib/x509asn1.c
158 +++ b/lib/x509asn1.c
159 @@ -22,7 +22,7 @@
161 #include "curl_setup.h"
163 -#if defined(USE_QSOSSL) || defined(USE_GSKIT)
164 +#if defined(USE_QSOSSL) || defined(USE_GSKIT) || defined(USE_NSS)
166 #include <curl/curl.h>
167 #include "urldata.h"
168 @@ -803,7 +803,7 @@ static const char * dumpAlgo(curl_asn1Element * param,
169 return OID2str(oid.beg, oid.end, TRUE);
172 -static void do_pubkey_field(struct SessionHandle *data, int certnum,
173 +static void do_pubkey_field(struct SessionHandle * data, int certnum,
174 const char * label, curl_asn1Element * elem)
176 const char * output;
177 @@ -812,8 +812,10 @@ static void do_pubkey_field(struct SessionHandle *data, int certnum,
179 output = Curl_ASN1tostr(elem, 0);
180 if(output) {
181 - Curl_ssl_push_certinfo(data, certnum, label, output);
182 - infof(data, " %s: %s\n", label, output);
183 + if(data->set.ssl.certinfo)
184 + Curl_ssl_push_certinfo(data, certnum, label, output);
185 + if(!certnum)
186 + infof(data, " %s: %s\n", label, output);
187 free((char *) output);
190 @@ -845,11 +847,14 @@ static void do_pubkey(struct SessionHandle * data, int certnum,
191 len--;
192 if(len > 32)
193 elem.beg = q; /* Strip leading zero bytes. */
194 - infof(data, " RSA Public Key (%lu bits)\n", len);
195 - q = curl_maprintf("%lu", len);
196 - if(q) {
197 - Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
198 - free((char *) q);
199 + if(!certnum)
200 + infof(data, " RSA Public Key (%lu bits)\n", len);
201 + if(data->set.ssl.certinfo) {
202 + q = curl_maprintf("%lu", len);
203 + if(q) {
204 + Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
205 + free((char *) q);
208 /* Generate coefficients. */
209 do_pubkey_field(data, certnum, "rsa(n)", &elem);
210 @@ -896,6 +901,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
211 size_t i;
212 size_t j;
214 + if(!data->set.ssl.certinfo)
215 + if(certnum)
216 + return CURLE_OK;
218 /* Prepare the certificate information for curl_easy_getinfo(). */
220 /* Extract the certificate ASN.1 elements. */
221 @@ -905,35 +914,44 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
222 ccp = Curl_DNtostr(&cert.subject);
223 if(!ccp)
224 return CURLE_OUT_OF_MEMORY;
225 - Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
226 - infof(data, "%2d Subject: %s\n", certnum, ccp);
227 + if(data->set.ssl.certinfo)
228 + Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
229 + if(!certnum)
230 + infof(data, "%2d Subject: %s\n", certnum, ccp);
231 free((char *) ccp);
233 /* Issuer. */
234 ccp = Curl_DNtostr(&cert.issuer);
235 if(!ccp)
236 return CURLE_OUT_OF_MEMORY;
237 - Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
238 - infof(data, " Issuer: %s\n", ccp);
239 + if(data->set.ssl.certinfo)
240 + Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
241 + if(!certnum)
242 + infof(data, " Issuer: %s\n", ccp);
243 free((char *) ccp);
245 /* Version (always fits in less than 32 bits). */
246 version = 0;
247 for(ccp = cert.version.beg; ccp < cert.version.end; ccp++)
248 version = (version << 8) | *(const unsigned char *) ccp;
249 - ccp = curl_maprintf("%lx", version);
250 - if(!ccp)
251 - return CURLE_OUT_OF_MEMORY;
252 - Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
253 - free((char *) ccp);
254 - infof(data, " Version: %lu (0x%lx)\n", version + 1, version);
255 + if(data->set.ssl.certinfo) {
256 + ccp = curl_maprintf("%lx", version);
257 + if(!ccp)
258 + return CURLE_OUT_OF_MEMORY;
259 + Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
260 + free((char *) ccp);
262 + if(!certnum)
263 + infof(data, " Version: %lu (0x%lx)\n", version + 1, version);
265 /* Serial number. */
266 ccp = Curl_ASN1tostr(&cert.serialNumber, 0);
267 if(!ccp)
268 return CURLE_OUT_OF_MEMORY;
269 - Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
270 - infof(data, " Serial Number: %s\n", ccp);
271 + if(data->set.ssl.certinfo)
272 + Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
273 + if(!certnum)
274 + infof(data, " Serial Number: %s\n", ccp);
275 free((char *) ccp);
277 /* Signature algorithm .*/
278 @@ -941,24 +959,30 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
279 cert.signatureAlgorithm.end);
280 if(!ccp)
281 return CURLE_OUT_OF_MEMORY;
282 - Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
283 - infof(data, " Signature Algorithm: %s\n", ccp);
284 + if(data->set.ssl.certinfo)
285 + Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
286 + if(!certnum)
287 + infof(data, " Signature Algorithm: %s\n", ccp);
288 free((char *) ccp);
290 /* Start Date. */
291 ccp = Curl_ASN1tostr(&cert.notBefore, 0);
292 if(!ccp)
293 return CURLE_OUT_OF_MEMORY;
294 - Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
295 - infof(data, " Start Date: %s\n", ccp);
296 + if(data->set.ssl.certinfo)
297 + Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
298 + if(!certnum)
299 + infof(data, " Start Date: %s\n", ccp);
300 free((char *) ccp);
302 /* Expire Date. */
303 ccp = Curl_ASN1tostr(&cert.notAfter, 0);
304 if(!ccp)
305 return CURLE_OUT_OF_MEMORY;
306 - Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
307 - infof(data, " Expire Date: %s\n", ccp);
308 + if(data->set.ssl.certinfo)
309 + Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
310 + if(!certnum)
311 + infof(data, " Expire Date: %s\n", ccp);
312 free((char *) ccp);
314 /* Public Key Algorithm. */
315 @@ -966,8 +990,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
316 cert.subjectPublicKeyAlgorithm.end);
317 if(!ccp)
318 return CURLE_OUT_OF_MEMORY;
319 - Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp);
320 - infof(data, " Public Key Algorithm: %s\n", ccp);
321 + if(data->set.ssl.certinfo)
322 + Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp);
323 + if(!certnum)
324 + infof(data, " Public Key Algorithm: %s\n", ccp);
325 do_pubkey(data, certnum, ccp, &param, &cert.subjectPublicKey);
326 free((char *) ccp);
328 @@ -977,8 +1003,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
329 ccp = Curl_ASN1tostr(&cert.signature, 0);
330 if(!ccp)
331 return CURLE_OUT_OF_MEMORY;
332 - Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
333 - infof(data, " Signature: %s\n", ccp);
334 + if(data->set.ssl.certinfo)
335 + Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
336 + if(!certnum)
337 + infof(data, " Signature: %s\n", ccp);
338 free((char *) ccp);
340 /* Generate PEM certificate. */
341 @@ -987,7 +1015,7 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
342 &cp1, &cl1);
343 if(cc != CURLE_OK)
344 return cc;
345 - /* Compute the number of charaters in final certificate string. Format is:
346 + /* Compute the number of characters in final certificate string. Format is:
347 -----BEGIN CERTIFICATE-----\n
348 <max 64 base64 characters>\n
350 @@ -1008,8 +1036,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
351 i += copySubstring(cp2 + i, "-----END CERTIFICATE-----");
352 cp2[i] = '\0';
353 free(cp1);
354 - Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
355 - infof(data, "%s\n", cp2);
356 + if(data->set.ssl.certinfo)
357 + Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
358 + if(!certnum)
359 + infof(data, "%s\n", cp2);
360 free(cp2);
361 return CURLE_OK;
363 @@ -1148,4 +1178,4 @@ CURLcode Curl_verifyhost(struct connectdata * conn,
364 return CURLE_PEER_FAILED_VERIFICATION;
367 -#endif /* USE_QSOSSL or USE_GSKIT */
368 +#endif /* USE_QSOSSL or USE_GSKIT or USE_NSS */
369 diff --git a/lib/x509asn1.h b/lib/x509asn1.h
370 index 2276b5b..1741d6d 100644
371 --- a/lib/x509asn1.h
372 +++ b/lib/x509asn1.h
373 @@ -25,7 +25,7 @@
375 #include "curl_setup.h"
377 -#if defined(USE_QSOSSL) || defined(USE_GSKIT)
378 +#if defined(USE_QSOSSL) || defined(USE_GSKIT) || defined(USE_NSS)
380 #include "urldata.h"
382 @@ -125,5 +125,5 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum,
383 CURLcode Curl_verifyhost(struct connectdata * conn,
384 const char * beg, const char * end);
386 -#endif /* USE_QSOSSL or USE_GSKIT */
387 +#endif /* USE_QSOSSL or USE_GSKIT or USE_NSS */
388 #endif /* HEADER_CURL_X509ASN1_H */
390 1.8.4.2