Revert "Imported Upstream version 7.53.1"
[platform/upstream/curl.git] / lib / vtls / nss.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22
23 /*
24  * Source file for all NSS-specific code for the TLS/SSL layer. No code
25  * but vtls.c should ever call or use these functions.
26  */
27
28 #include "curl_setup.h"
29
30 #ifdef USE_NSS
31
32 #include "urldata.h"
33 #include "sendf.h"
34 #include "formdata.h" /* for the boundary function */
35 #include "url.h" /* for the ssl config check function */
36 #include "connect.h"
37 #include "strequal.h"
38 #include "select.h"
39 #include "vtls.h"
40 #include "llist.h"
41 #include "curl_printf.h"
42 #include "nssg.h"
43 #include <nspr.h>
44 #include <nss.h>
45 #include <ssl.h>
46 #include <sslerr.h>
47 #include <secerr.h>
48 #include <secmod.h>
49 #include <sslproto.h>
50 #include <prtypes.h>
51 #include <pk11pub.h>
52 #include <prio.h>
53 #include <secitem.h>
54 #include <secport.h>
55 #include <certdb.h>
56 #include <base64.h>
57 #include <cert.h>
58 #include <prerror.h>
59 #include <keyhi.h>        /* for SECKEY_DestroyPublicKey() */
60
61 #define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH)
62
63 #if NSSVERNUM >= 0x030f00 /* 3.15.0 */
64 #include <ocsp.h>
65 #endif
66
67 #include "rawstr.h"
68 #include "warnless.h"
69 #include "x509asn1.h"
70
71 /* The last #include files should be: */
72 #include "curl_memory.h"
73 #include "memdebug.h"
74
75 #define SSL_DIR "/etc/pki/nssdb"
76
77 /* enough to fit the string "PEM Token #[0|1]" */
78 #define SLOTSIZE 13
79
80 PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
81 static PRLock *nss_initlock = NULL;
82 static PRLock *nss_crllock = NULL;
83 static PRLock *nss_findslot_lock = NULL;
84 static struct curl_llist *nss_crl_list = NULL;
85 static NSSInitContext *nss_context = NULL;
86 static volatile int initialized = 0;
87
88 typedef struct {
89   const char *name;
90   int num;
91 } cipher_s;
92
93 #define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do {  \
94   CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++);                 \
95   ptr->type = (_type);                                      \
96   ptr->pValue = (_val);                                     \
97   ptr->ulValueLen = (_len);                                 \
98 } WHILE_FALSE
99
100 #define CERT_NewTempCertificate __CERT_NewTempCertificate
101
102 #define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0])
103 static const cipher_s cipherlist[] = {
104   /* SSL2 cipher suites */
105   {"rc4",                        SSL_EN_RC4_128_WITH_MD5},
106   {"rc4-md5",                    SSL_EN_RC4_128_WITH_MD5},
107   {"rc4export",                  SSL_EN_RC4_128_EXPORT40_WITH_MD5},
108   {"rc2",                        SSL_EN_RC2_128_CBC_WITH_MD5},
109   {"rc2export",                  SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5},
110   {"des",                        SSL_EN_DES_64_CBC_WITH_MD5},
111   {"desede3",                    SSL_EN_DES_192_EDE3_CBC_WITH_MD5},
112   /* SSL3/TLS cipher suites */
113   {"rsa_rc4_128_md5",            SSL_RSA_WITH_RC4_128_MD5},
114   {"rsa_rc4_128_sha",            SSL_RSA_WITH_RC4_128_SHA},
115   {"rsa_3des_sha",               SSL_RSA_WITH_3DES_EDE_CBC_SHA},
116   {"rsa_des_sha",                SSL_RSA_WITH_DES_CBC_SHA},
117   {"rsa_rc4_40_md5",             SSL_RSA_EXPORT_WITH_RC4_40_MD5},
118   {"rsa_rc2_40_md5",             SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5},
119   {"rsa_null_md5",               SSL_RSA_WITH_NULL_MD5},
120   {"rsa_null_sha",               SSL_RSA_WITH_NULL_SHA},
121   {"fips_3des_sha",              SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA},
122   {"fips_des_sha",               SSL_RSA_FIPS_WITH_DES_CBC_SHA},
123   {"fortezza",                   SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA},
124   {"fortezza_rc4_128_sha",       SSL_FORTEZZA_DMS_WITH_RC4_128_SHA},
125   {"fortezza_null",              SSL_FORTEZZA_DMS_WITH_NULL_SHA},
126   /* TLS 1.0: Exportable 56-bit Cipher Suites. */
127   {"rsa_des_56_sha",             TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
128   {"rsa_rc4_56_sha",             TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
129   /* AES ciphers. */
130   {"dhe_dss_aes_128_cbc_sha",    TLS_DHE_DSS_WITH_AES_128_CBC_SHA},
131   {"dhe_dss_aes_256_cbc_sha",    TLS_DHE_DSS_WITH_AES_256_CBC_SHA},
132   {"dhe_rsa_aes_128_cbc_sha",    TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
133   {"dhe_rsa_aes_256_cbc_sha",    TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
134   {"rsa_aes_128_sha",            TLS_RSA_WITH_AES_128_CBC_SHA},
135   {"rsa_aes_256_sha",            TLS_RSA_WITH_AES_256_CBC_SHA},
136   /* ECC ciphers. */
137   {"ecdh_ecdsa_null_sha",        TLS_ECDH_ECDSA_WITH_NULL_SHA},
138   {"ecdh_ecdsa_rc4_128_sha",     TLS_ECDH_ECDSA_WITH_RC4_128_SHA},
139   {"ecdh_ecdsa_3des_sha",        TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA},
140   {"ecdh_ecdsa_aes_128_sha",     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA},
141   {"ecdh_ecdsa_aes_256_sha",     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA},
142   {"ecdhe_ecdsa_null_sha",       TLS_ECDHE_ECDSA_WITH_NULL_SHA},
143   {"ecdhe_ecdsa_rc4_128_sha",    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
144   {"ecdhe_ecdsa_3des_sha",       TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA},
145   {"ecdhe_ecdsa_aes_128_sha",    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
146   {"ecdhe_ecdsa_aes_256_sha",    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
147   {"ecdh_rsa_null_sha",          TLS_ECDH_RSA_WITH_NULL_SHA},
148   {"ecdh_rsa_128_sha",           TLS_ECDH_RSA_WITH_RC4_128_SHA},
149   {"ecdh_rsa_3des_sha",          TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA},
150   {"ecdh_rsa_aes_128_sha",       TLS_ECDH_RSA_WITH_AES_128_CBC_SHA},
151   {"ecdh_rsa_aes_256_sha",       TLS_ECDH_RSA_WITH_AES_256_CBC_SHA},
152   {"echde_rsa_null",             TLS_ECDHE_RSA_WITH_NULL_SHA},
153   {"ecdhe_rsa_rc4_128_sha",      TLS_ECDHE_RSA_WITH_RC4_128_SHA},
154   {"ecdhe_rsa_3des_sha",         TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
155   {"ecdhe_rsa_aes_128_sha",      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
156   {"ecdhe_rsa_aes_256_sha",      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
157   {"ecdh_anon_null_sha",         TLS_ECDH_anon_WITH_NULL_SHA},
158   {"ecdh_anon_rc4_128sha",       TLS_ECDH_anon_WITH_RC4_128_SHA},
159   {"ecdh_anon_3des_sha",         TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA},
160   {"ecdh_anon_aes_128_sha",      TLS_ECDH_anon_WITH_AES_128_CBC_SHA},
161   {"ecdh_anon_aes_256_sha",      TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
162 #ifdef TLS_RSA_WITH_NULL_SHA256
163   /* new HMAC-SHA256 cipher suites specified in RFC */
164   {"rsa_null_sha_256",                TLS_RSA_WITH_NULL_SHA256},
165   {"rsa_aes_128_cbc_sha_256",         TLS_RSA_WITH_AES_128_CBC_SHA256},
166   {"rsa_aes_256_cbc_sha_256",         TLS_RSA_WITH_AES_256_CBC_SHA256},
167   {"dhe_rsa_aes_128_cbc_sha_256",     TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
168   {"dhe_rsa_aes_256_cbc_sha_256",     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
169   {"ecdhe_ecdsa_aes_128_cbc_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
170   {"ecdhe_rsa_aes_128_cbc_sha_256",   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
171 #endif
172 #ifdef TLS_RSA_WITH_AES_128_GCM_SHA256
173   /* AES GCM cipher suites in RFC 5288 and RFC 5289 */
174   {"rsa_aes_128_gcm_sha_256",         TLS_RSA_WITH_AES_128_GCM_SHA256},
175   {"dhe_rsa_aes_128_gcm_sha_256",     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
176   {"dhe_dss_aes_128_gcm_sha_256",     TLS_DHE_DSS_WITH_AES_128_GCM_SHA256},
177   {"ecdhe_ecdsa_aes_128_gcm_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
178   {"ecdh_ecdsa_aes_128_gcm_sha_256",  TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256},
179   {"ecdhe_rsa_aes_128_gcm_sha_256",   TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
180   {"ecdh_rsa_aes_128_gcm_sha_256",    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256},
181 #endif
182 };
183
184 static const char* pem_library = "libnsspem.so";
185 static SECMODModule* mod = NULL;
186
187 /* NSPR I/O layer we use to detect blocking direction during SSL handshake */
188 static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER;
189 static PRIOMethods nspr_io_methods;
190
191 static const char* nss_error_to_name(PRErrorCode code)
192 {
193   const char *name = PR_ErrorToName(code);
194   if(name)
195     return name;
196
197   return "unknown error";
198 }
199
200 static void nss_print_error_message(struct Curl_easy *data, PRUint32 err)
201 {
202   failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
203 }
204
205 static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
206                              char *cipher_list)
207 {
208   unsigned int i;
209   PRBool cipher_state[NUM_OF_CIPHERS];
210   PRBool found;
211   char *cipher;
212
213   /* use accessors to avoid dynamic linking issues after an update of NSS */
214   const PRUint16 num_implemented_ciphers = SSL_GetNumImplementedCiphers();
215   const PRUint16 *implemented_ciphers = SSL_GetImplementedCiphers();
216   if(!implemented_ciphers)
217     return SECFailure;
218
219   /* First disable all ciphers. This uses a different max value in case
220    * NSS adds more ciphers later we don't want them available by
221    * accident
222    */
223   for(i = 0; i < num_implemented_ciphers; i++) {
224     SSL_CipherPrefSet(model, implemented_ciphers[i], PR_FALSE);
225   }
226
227   /* Set every entry in our list to false */
228   for(i = 0; i < NUM_OF_CIPHERS; i++) {
229     cipher_state[i] = PR_FALSE;
230   }
231
232   cipher = cipher_list;
233
234   while(cipher_list && (cipher_list[0])) {
235     while((*cipher) && (ISSPACE(*cipher)))
236       ++cipher;
237
238     if((cipher_list = strchr(cipher, ','))) {
239       *cipher_list++ = '\0';
240     }
241
242     found = PR_FALSE;
243
244     for(i=0; i<NUM_OF_CIPHERS; i++) {
245       if(Curl_raw_equal(cipher, cipherlist[i].name)) {
246         cipher_state[i] = PR_TRUE;
247         found = PR_TRUE;
248         break;
249       }
250     }
251
252     if(found == PR_FALSE) {
253       failf(data, "Unknown cipher in list: %s", cipher);
254       return SECFailure;
255     }
256
257     if(cipher_list) {
258       cipher = cipher_list;
259     }
260   }
261
262   /* Finally actually enable the selected ciphers */
263   for(i=0; i<NUM_OF_CIPHERS; i++) {
264     if(!cipher_state[i])
265       continue;
266
267     if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) != SECSuccess) {
268       failf(data, "cipher-suite not supported by NSS: %s", cipherlist[i].name);
269       return SECFailure;
270     }
271   }
272
273   return SECSuccess;
274 }
275
276 /*
277  * Return true if at least one cipher-suite is enabled. Used to determine
278  * if we need to call NSS_SetDomesticPolicy() to enable the default ciphers.
279  */
280 static bool any_cipher_enabled(void)
281 {
282   unsigned int i;
283
284   for(i=0; i<NUM_OF_CIPHERS; i++) {
285     PRInt32 policy = 0;
286     SSL_CipherPolicyGet(cipherlist[i].num, &policy);
287     if(policy)
288       return TRUE;
289   }
290
291   return FALSE;
292 }
293
294 /*
295  * Determine whether the nickname passed in is a filename that needs to
296  * be loaded as a PEM or a regular NSS nickname.
297  *
298  * returns 1 for a file
299  * returns 0 for not a file (NSS nickname)
300  */
301 static int is_file(const char *filename)
302 {
303   struct_stat st;
304
305   if(filename == NULL)
306     return 0;
307
308   if(stat(filename, &st) == 0)
309     if(S_ISREG(st.st_mode))
310       return 1;
311
312   return 0;
313 }
314
315 /* Check if the given string is filename or nickname of a certificate.  If the
316  * given string is recognized as filename, return NULL.  If the given string is
317  * recognized as nickname, return a duplicated string.  The returned string
318  * should be later deallocated using free().  If the OOM failure occurs, we
319  * return NULL, too.
320  */
321 static char* dup_nickname(struct Curl_easy *data, enum dupstring cert_kind)
322 {
323   const char *str = data->set.str[cert_kind];
324   const char *n;
325
326   if(!is_file(str))
327     /* no such file exists, use the string as nickname */
328     return strdup(str);
329
330   /* search the first slash; we require at least one slash in a file name */
331   n = strchr(str, '/');
332   if(!n) {
333     infof(data, "warning: certificate file name \"%s\" handled as nickname; "
334           "please use \"./%s\" to force file name\n", str, str);
335     return strdup(str);
336   }
337
338   /* we'll use the PEM reader to read the certificate from file */
339   return NULL;
340 }
341
342 /* Lock/unlock wrapper for PK11_FindSlotByName() to work around race condition
343  * in nssSlot_IsTokenPresent() causing spurious SEC_ERROR_NO_TOKEN.  For more
344  * details, go to <https://bugzilla.mozilla.org/1297397>.
345  */
346 static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name)
347 {
348   PK11SlotInfo *slot;
349   PR_Lock(nss_initlock);
350   slot = PK11_FindSlotByName(slot_name);
351   PR_Unlock(nss_initlock);
352   return slot;
353 }
354
355 /* Call PK11_CreateGenericObject() with the given obj_class and filename.  If
356  * the call succeeds, append the object handle to the list of objects so that
357  * the object can be destroyed in Curl_nss_close(). */
358 static CURLcode nss_create_object(struct ssl_connect_data *ssl,
359                                   CK_OBJECT_CLASS obj_class,
360                                   const char *filename, bool cacert)
361 {
362   PK11SlotInfo *slot;
363   PK11GenericObject *obj;
364   CK_BBOOL cktrue = CK_TRUE;
365   CK_BBOOL ckfalse = CK_FALSE;
366   CK_ATTRIBUTE attrs[/* max count of attributes */ 4];
367   int attr_cnt = 0;
368   CURLcode result = (cacert)
369     ? CURLE_SSL_CACERT_BADFILE
370     : CURLE_SSL_CERTPROBLEM;
371
372   const int slot_id = (cacert) ? 0 : 1;
373   char *slot_name = aprintf("PEM Token #%d", slot_id);
374   if(!slot_name)
375     return CURLE_OUT_OF_MEMORY;
376
377   slot = nss_find_slot_by_name(slot_name);
378   free(slot_name);
379   if(!slot)
380     return result;
381
382   PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class));
383   PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
384   PK11_SETATTRS(attrs, attr_cnt, CKA_LABEL, (unsigned char *)filename,
385                 strlen(filename) + 1);
386
387   if(CKO_CERTIFICATE == obj_class) {
388     CK_BBOOL *pval = (cacert) ? (&cktrue) : (&ckfalse);
389     PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval, sizeof(*pval));
390   }
391
392   obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE);
393   PK11_FreeSlot(slot);
394   if(!obj)
395     return result;
396
397   if(!Curl_llist_insert_next(ssl->obj_list, ssl->obj_list->tail, obj)) {
398     PK11_DestroyGenericObject(obj);
399     return CURLE_OUT_OF_MEMORY;
400   }
401
402   if(!cacert && CKO_CERTIFICATE == obj_class)
403     /* store reference to a client certificate */
404     ssl->obj_clicert = obj;
405
406   return CURLE_OK;
407 }
408
409 /* Destroy the NSS object whose handle is given by ptr.  This function is
410  * a callback of Curl_llist_alloc() used by Curl_llist_destroy() to destroy
411  * NSS objects in Curl_nss_close() */
412 static void nss_destroy_object(void *user, void *ptr)
413 {
414   PK11GenericObject *obj = (PK11GenericObject *)ptr;
415   (void) user;
416   PK11_DestroyGenericObject(obj);
417 }
418
419 /* same as nss_destroy_object() but for CRL items */
420 static void nss_destroy_crl_item(void *user, void *ptr)
421 {
422   SECItem *crl_der = (SECItem *)ptr;
423   (void) user;
424   SECITEM_FreeItem(crl_der, PR_TRUE);
425 }
426
427 static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
428                               const char *filename, PRBool cacert)
429 {
430   CURLcode result = (cacert)
431     ? CURLE_SSL_CACERT_BADFILE
432     : CURLE_SSL_CERTPROBLEM;
433
434   /* libnsspem.so leaks memory if the requested file does not exist.  For more
435    * details, go to <https://bugzilla.redhat.com/734760>. */
436   if(is_file(filename))
437     result = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert);
438
439   if(!result && !cacert) {
440     /* we have successfully loaded a client certificate */
441     CERTCertificate *cert;
442     char *nickname = NULL;
443     char *n = strrchr(filename, '/');
444     if(n)
445       n++;
446
447     /* The following undocumented magic helps to avoid a SIGSEGV on call
448      * of PK11_ReadRawAttribute() from SelectClientCert() when using an
449      * immature version of libnsspem.so.  For more details, go to
450      * <https://bugzilla.redhat.com/733685>. */
451     nickname = aprintf("PEM Token #1:%s", n);
452     if(nickname) {
453       cert = PK11_FindCertFromNickname(nickname, NULL);
454       if(cert)
455         CERT_DestroyCertificate(cert);
456
457       free(nickname);
458     }
459   }
460
461   return result;
462 }
463
464 /* add given CRL to cache if it is not already there */
465 static CURLcode nss_cache_crl(SECItem *crl_der)
466 {
467   CERTCertDBHandle *db = CERT_GetDefaultCertDB();
468   CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0);
469   if(crl) {
470     /* CRL already cached */
471     SEC_DestroyCrl(crl);
472     SECITEM_FreeItem(crl_der, PR_TRUE);
473     return CURLE_OK;
474   }
475
476   /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */
477   PR_Lock(nss_crllock);
478
479   /* store the CRL item so that we can free it in Curl_nss_cleanup() */
480   if(!Curl_llist_insert_next(nss_crl_list, nss_crl_list->tail, crl_der)) {
481     SECITEM_FreeItem(crl_der, PR_TRUE);
482     PR_Unlock(nss_crllock);
483     return CURLE_OUT_OF_MEMORY;
484   }
485
486   if(SECSuccess != CERT_CacheCRL(db, crl_der)) {
487     /* unable to cache CRL */
488     PR_Unlock(nss_crllock);
489     return CURLE_SSL_CRL_BADFILE;
490   }
491
492   /* we need to clear session cache, so that the CRL could take effect */
493   SSL_ClearSessionCache();
494   PR_Unlock(nss_crllock);
495   return CURLE_OK;
496 }
497
498 static CURLcode nss_load_crl(const char* crlfilename)
499 {
500   PRFileDesc *infile;
501   PRFileInfo  info;
502   SECItem filedata = { 0, NULL, 0 };
503   SECItem *crl_der = NULL;
504   char *body;
505
506   infile = PR_Open(crlfilename, PR_RDONLY, 0);
507   if(!infile)
508     return CURLE_SSL_CRL_BADFILE;
509
510   if(PR_SUCCESS != PR_GetOpenFileInfo(infile, &info))
511     goto fail;
512
513   if(!SECITEM_AllocItem(NULL, &filedata, info.size + /* zero ended */ 1))
514     goto fail;
515
516   if(info.size != PR_Read(infile, filedata.data, info.size))
517     goto fail;
518
519   crl_der = SECITEM_AllocItem(NULL, NULL, 0U);
520   if(!crl_der)
521     goto fail;
522
523   /* place a trailing zero right after the visible data */
524   body = (char*)filedata.data;
525   body[--filedata.len] = '\0';
526
527   body = strstr(body, "-----BEGIN");
528   if(body) {
529     /* assume ASCII */
530     char *trailer;
531     char *begin = PORT_Strchr(body, '\n');
532     if(!begin)
533       begin = PORT_Strchr(body, '\r');
534     if(!begin)
535       goto fail;
536
537     trailer = strstr(++begin, "-----END");
538     if(!trailer)
539       goto fail;
540
541     /* retrieve DER from ASCII */
542     *trailer = '\0';
543     if(ATOB_ConvertAsciiToItem(crl_der, begin))
544       goto fail;
545
546     SECITEM_FreeItem(&filedata, PR_FALSE);
547   }
548   else
549     /* assume DER */
550     *crl_der = filedata;
551
552   PR_Close(infile);
553   return nss_cache_crl(crl_der);
554
555 fail:
556   PR_Close(infile);
557   SECITEM_FreeItem(crl_der, PR_TRUE);
558   SECITEM_FreeItem(&filedata, PR_FALSE);
559   return CURLE_SSL_CRL_BADFILE;
560 }
561
562 static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
563                              char *key_file)
564 {
565   PK11SlotInfo *slot;
566   SECStatus status;
567   CURLcode result;
568   struct ssl_connect_data *ssl = conn->ssl;
569
570   (void)sockindex; /* unused */
571
572   result = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE);
573   if(result) {
574     PR_SetError(SEC_ERROR_BAD_KEY, 0);
575     return result;
576   }
577
578   slot = nss_find_slot_by_name("PEM Token #1");
579   if(!slot)
580     return CURLE_SSL_CERTPROBLEM;
581
582   /* This will force the token to be seen as re-inserted */
583   SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
584   PK11_IsPresent(slot);
585
586   status = PK11_Authenticate(slot, PR_TRUE,
587                              conn->data->set.str[STRING_KEY_PASSWD]);
588   PK11_FreeSlot(slot);
589
590   return (SECSuccess == status) ? CURLE_OK : CURLE_SSL_CERTPROBLEM;
591 }
592
593 static int display_error(struct connectdata *conn, PRInt32 err,
594                          const char *filename)
595 {
596   switch(err) {
597   case SEC_ERROR_BAD_PASSWORD:
598     failf(conn->data, "Unable to load client key: Incorrect password");
599     return 1;
600   case SEC_ERROR_UNKNOWN_CERT:
601     failf(conn->data, "Unable to load certificate %s", filename);
602     return 1;
603   default:
604     break;
605   }
606   return 0; /* The caller will print a generic error */
607 }
608
609 static CURLcode cert_stuff(struct connectdata *conn, int sockindex,
610                            char *cert_file, char *key_file)
611 {
612   struct Curl_easy *data = conn->data;
613   CURLcode result;
614
615   if(cert_file) {
616     result = nss_load_cert(&conn->ssl[sockindex], cert_file, PR_FALSE);
617     if(result) {
618       const PRErrorCode err = PR_GetError();
619       if(!display_error(conn, err, cert_file)) {
620         const char *err_name = nss_error_to_name(err);
621         failf(data, "unable to load client cert: %d (%s)", err, err_name);
622       }
623
624       return result;
625     }
626   }
627
628   if(key_file || (is_file(cert_file))) {
629     if(key_file)
630       result = nss_load_key(conn, sockindex, key_file);
631     else
632       /* In case the cert file also has the key */
633       result = nss_load_key(conn, sockindex, cert_file);
634     if(result) {
635       const PRErrorCode err = PR_GetError();
636       if(!display_error(conn, err, key_file)) {
637         const char *err_name = nss_error_to_name(err);
638         failf(data, "unable to load client key: %d (%s)", err, err_name);
639       }
640
641       return result;
642     }
643   }
644
645   return CURLE_OK;
646 }
647
648 static char * nss_get_password(PK11SlotInfo * slot, PRBool retry, void *arg)
649 {
650   (void)slot; /* unused */
651
652   if(retry || NULL == arg)
653     return NULL;
654   else
655     return (char *)PORT_Strdup((char *)arg);
656 }
657
658 /* bypass the default SSL_AuthCertificate() hook in case we do not want to
659  * verify peer */
660 static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
661                                     PRBool isServer)
662 {
663   struct connectdata *conn = (struct connectdata *)arg;
664
665 #ifdef SSL_ENABLE_OCSP_STAPLING
666   if(conn->data->set.ssl.verifystatus) {
667     SECStatus cacheResult;
668
669     const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
670     if(!csa) {
671       failf(conn->data, "Invalid OCSP response");
672       return SECFailure;
673     }
674
675     if(csa->len == 0) {
676       failf(conn->data, "No OCSP response received");
677       return SECFailure;
678     }
679
680     cacheResult = CERT_CacheOCSPResponseFromSideChannel(
681       CERT_GetDefaultCertDB(), SSL_PeerCertificate(fd),
682       PR_Now(), &csa->items[0], arg
683     );
684
685     if(cacheResult != SECSuccess) {
686       failf(conn->data, "Invalid OCSP response");
687       return cacheResult;
688     }
689   }
690 #endif
691
692   if(!conn->data->set.ssl.verifypeer) {
693     infof(conn->data, "skipping SSL peer certificate verification\n");
694     return SECSuccess;
695   }
696
697   return SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer);
698 }
699
700 /**
701  * Inform the application that the handshake is complete.
702  */
703 static void HandshakeCallback(PRFileDesc *sock, void *arg)
704 {
705   struct connectdata *conn = (struct connectdata*) arg;
706   unsigned int buflenmax = 50;
707   unsigned char buf[50];
708   unsigned int buflen;
709   SSLNextProtoState state;
710
711   if(!conn->bits.tls_enable_npn && !conn->bits.tls_enable_alpn) {
712     return;
713   }
714
715   if(SSL_GetNextProto(sock, &state, buf, &buflen, buflenmax) == SECSuccess) {
716
717     switch(state) {
718     case SSL_NEXT_PROTO_NO_SUPPORT:
719     case SSL_NEXT_PROTO_NO_OVERLAP:
720       infof(conn->data, "ALPN/NPN, server did not agree to a protocol\n");
721       return;
722 #ifdef SSL_ENABLE_ALPN
723     case SSL_NEXT_PROTO_SELECTED:
724       infof(conn->data, "ALPN, server accepted to use %.*s\n", buflen, buf);
725       break;
726 #endif
727     case SSL_NEXT_PROTO_NEGOTIATED:
728       infof(conn->data, "NPN, server accepted to use %.*s\n", buflen, buf);
729       break;
730     }
731
732 #ifdef USE_NGHTTP2
733     if(buflen == NGHTTP2_PROTO_VERSION_ID_LEN &&
734        !memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)) {
735       conn->negnpn = CURL_HTTP_VERSION_2;
736     }
737     else
738 #endif
739     if(buflen == ALPN_HTTP_1_1_LENGTH &&
740        !memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) {
741       conn->negnpn = CURL_HTTP_VERSION_1_1;
742     }
743   }
744 }
745
746 #if NSSVERNUM >= 0x030f04 /* 3.15.4 */
747 static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data,
748                                        PRBool *canFalseStart)
749 {
750   struct connectdata *conn = client_data;
751   struct Curl_easy *data = conn->data;
752
753   SSLChannelInfo channelInfo;
754   SSLCipherSuiteInfo cipherInfo;
755
756   SECStatus rv;
757   PRBool negotiatedExtension;
758
759   *canFalseStart = PR_FALSE;
760
761   if(SSL_GetChannelInfo(sock, &channelInfo, sizeof(channelInfo)) != SECSuccess)
762     return SECFailure;
763
764   if(SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
765                             sizeof(cipherInfo)) != SECSuccess)
766     return SECFailure;
767
768   /* Prevent version downgrade attacks from TLS 1.2, and avoid False Start for
769    * TLS 1.3 and later. See https://bugzilla.mozilla.org/show_bug.cgi?id=861310
770    */
771   if(channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2)
772     goto end;
773
774   /* Only allow ECDHE key exchange algorithm.
775    * See https://bugzilla.mozilla.org/show_bug.cgi?id=952863 */
776   if(cipherInfo.keaType != ssl_kea_ecdh)
777     goto end;
778
779   /* Prevent downgrade attacks on the symmetric cipher. We do not allow CBC
780    * mode due to BEAST, POODLE, and other attacks on the MAC-then-Encrypt
781    * design. See https://bugzilla.mozilla.org/show_bug.cgi?id=1109766 */
782   if(cipherInfo.symCipher != ssl_calg_aes_gcm)
783     goto end;
784
785   /* Enforce ALPN or NPN to do False Start, as an indicator of server
786    * compatibility. */
787   rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn,
788                                         &negotiatedExtension);
789   if(rv != SECSuccess || !negotiatedExtension) {
790     rv = SSL_HandshakeNegotiatedExtension(sock, ssl_next_proto_nego_xtn,
791                                           &negotiatedExtension);
792   }
793
794   if(rv != SECSuccess || !negotiatedExtension)
795     goto end;
796
797   *canFalseStart = PR_TRUE;
798
799   infof(data, "Trying TLS False Start\n");
800
801 end:
802   return SECSuccess;
803 }
804 #endif
805
806 static void display_cert_info(struct Curl_easy *data,
807                               CERTCertificate *cert)
808 {
809   char *subject, *issuer, *common_name;
810   PRExplodedTime printableTime;
811   char timeString[256];
812   PRTime notBefore, notAfter;
813
814   subject = CERT_NameToAscii(&cert->subject);
815   issuer = CERT_NameToAscii(&cert->issuer);
816   common_name = CERT_GetCommonName(&cert->subject);
817   infof(data, "\tsubject: %s\n", subject);
818
819   CERT_GetCertTimes(cert, &notBefore, &notAfter);
820   PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime);
821   PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
822   infof(data, "\tstart date: %s\n", timeString);
823   PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime);
824   PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
825   infof(data, "\texpire date: %s\n", timeString);
826   infof(data, "\tcommon name: %s\n", common_name);
827   infof(data, "\tissuer: %s\n", issuer);
828
829   PR_Free(subject);
830   PR_Free(issuer);
831   PR_Free(common_name);
832 }
833
834 static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock)
835 {
836   CURLcode result = CURLE_OK;
837   SSLChannelInfo channel;
838   SSLCipherSuiteInfo suite;
839   CERTCertificate *cert;
840   CERTCertificate *cert2;
841   CERTCertificate *cert3;
842   PRTime now;
843   int i;
844
845   if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==
846      SECSuccess && channel.length == sizeof channel &&
847      channel.cipherSuite) {
848     if(SSL_GetCipherSuiteInfo(channel.cipherSuite,
849                               &suite, sizeof suite) == SECSuccess) {
850       infof(conn->data, "SSL connection using %s\n", suite.cipherSuiteName);
851     }
852   }
853
854   cert = SSL_PeerCertificate(sock);
855   if(cert) {
856     infof(conn->data, "Server certificate:\n");
857
858     if(!conn->data->set.ssl.certinfo) {
859       display_cert_info(conn->data, cert);
860       CERT_DestroyCertificate(cert);
861     }
862     else {
863       /* Count certificates in chain. */
864       now = PR_Now();
865       i = 1;
866       if(!cert->isRoot) {
867         cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
868         while(cert2) {
869           i++;
870           if(cert2->isRoot) {
871             CERT_DestroyCertificate(cert2);
872             break;
873           }
874           cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA);
875           CERT_DestroyCertificate(cert2);
876           cert2 = cert3;
877         }
878       }
879
880       result = Curl_ssl_init_certinfo(conn->data, i);
881       if(!result) {
882         for(i = 0; cert; cert = cert2) {
883           result = Curl_extract_certinfo(conn, i++, (char *)cert->derCert.data,
884                                          (char *)cert->derCert.data +
885                                                  cert->derCert.len);
886           if(result)
887             break;
888
889           if(cert->isRoot) {
890             CERT_DestroyCertificate(cert);
891             break;
892           }
893
894           cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
895           CERT_DestroyCertificate(cert);
896         }
897       }
898     }
899   }
900
901   return result;
902 }
903
904 static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
905 {
906   struct connectdata *conn = (struct connectdata *)arg;
907   struct Curl_easy *data = conn->data;
908   PRErrorCode err = PR_GetError();
909   CERTCertificate *cert;
910
911   /* remember the cert verification result */
912   data->set.ssl.certverifyresult = err;
913
914   if(err == SSL_ERROR_BAD_CERT_DOMAIN && !data->set.ssl.verifyhost)
915     /* we are asked not to verify the host name */
916     return SECSuccess;
917
918   /* print only info about the cert, the error is printed off the callback */
919   cert = SSL_PeerCertificate(sock);
920   if(cert) {
921     infof(data, "Server certificate:\n");
922     display_cert_info(data, cert);
923     CERT_DestroyCertificate(cert);
924   }
925
926   return SECFailure;
927 }
928
929 /**
930  *
931  * Check that the Peer certificate's issuer certificate matches the one found
932  * by issuer_nickname.  This is not exactly the way OpenSSL and GNU TLS do the
933  * issuer check, so we provide comments that mimic the OpenSSL
934  * X509_check_issued function (in x509v3/v3_purp.c)
935  */
936 static SECStatus check_issuer_cert(PRFileDesc *sock,
937                                    char *issuer_nickname)
938 {
939   CERTCertificate *cert, *cert_issuer, *issuer;
940   SECStatus res=SECSuccess;
941   void *proto_win = NULL;
942
943   cert = SSL_PeerCertificate(sock);
944   cert_issuer = CERT_FindCertIssuer(cert, PR_Now(), certUsageObjectSigner);
945
946   proto_win = SSL_RevealPinArg(sock);
947   issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win);
948
949   if((!cert_issuer) || (!issuer))
950     res = SECFailure;
951   else if(SECITEM_CompareItem(&cert_issuer->derCert,
952                               &issuer->derCert)!=SECEqual)
953     res = SECFailure;
954
955   CERT_DestroyCertificate(cert);
956   CERT_DestroyCertificate(issuer);
957   CERT_DestroyCertificate(cert_issuer);
958   return res;
959 }
960
961 static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
962                                 const char *pinnedpubkey)
963 {
964   CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
965   struct Curl_easy *data = connssl->data;
966   CERTCertificate *cert;
967
968   if(!pinnedpubkey)
969     /* no pinned public key specified */
970     return CURLE_OK;
971
972   /* get peer certificate */
973   cert = SSL_PeerCertificate(connssl->handle);
974   if(cert) {
975     /* extract public key from peer certificate */
976     SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
977     if(pubkey) {
978       /* encode the public key as DER */
979       SECItem *cert_der = PK11_DEREncodePublicKey(pubkey);
980       if(cert_der) {
981         /* compare the public key with the pinned public key */
982         result = Curl_pin_peer_pubkey(data, pinnedpubkey, cert_der->data,
983                                       cert_der->len);
984         SECITEM_FreeItem(cert_der, PR_TRUE);
985       }
986       SECKEY_DestroyPublicKey(pubkey);
987     }
988     CERT_DestroyCertificate(cert);
989   }
990
991   /* report the resulting status */
992   switch(result) {
993   case CURLE_OK:
994     infof(data, "pinned public key verified successfully!\n");
995     break;
996   case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
997     failf(data, "failed to verify pinned public key");
998     break;
999   default:
1000     /* OOM, etc. */
1001     break;
1002   }
1003
1004   return result;
1005 }
1006
1007 /**
1008  *
1009  * Callback to pick the SSL client certificate.
1010  */
1011 static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
1012                                   struct CERTDistNamesStr *caNames,
1013                                   struct CERTCertificateStr **pRetCert,
1014                                   struct SECKEYPrivateKeyStr **pRetKey)
1015 {
1016   struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
1017   struct Curl_easy *data = connssl->data;
1018   const char *nickname = connssl->client_nickname;
1019   static const char pem_slotname[] = "PEM Token #1";
1020
1021   if(connssl->obj_clicert) {
1022     /* use the cert/key provided by PEM reader */
1023     SECItem cert_der = { 0, NULL, 0 };
1024     void *proto_win = SSL_RevealPinArg(sock);
1025     struct CERTCertificateStr *cert;
1026     struct SECKEYPrivateKeyStr *key;
1027
1028     PK11SlotInfo *slot = nss_find_slot_by_name(pem_slotname);
1029     if(NULL == slot) {
1030       failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
1031       return SECFailure;
1032     }
1033
1034     if(PK11_ReadRawAttribute(PK11_TypeGeneric, connssl->obj_clicert, CKA_VALUE,
1035                              &cert_der) != SECSuccess) {
1036       failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
1037       PK11_FreeSlot(slot);
1038       return SECFailure;
1039     }
1040
1041     cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
1042     SECITEM_FreeItem(&cert_der, PR_FALSE);
1043     if(NULL == cert) {
1044       failf(data, "NSS: client certificate from file not found");
1045       PK11_FreeSlot(slot);
1046       return SECFailure;
1047     }
1048
1049     key = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
1050     PK11_FreeSlot(slot);
1051     if(NULL == key) {
1052       failf(data, "NSS: private key from file not found");
1053       CERT_DestroyCertificate(cert);
1054       return SECFailure;
1055     }
1056
1057     infof(data, "NSS: client certificate from file\n");
1058     display_cert_info(data, cert);
1059
1060     *pRetCert = cert;
1061     *pRetKey = key;
1062     return SECSuccess;
1063   }
1064
1065   /* use the default NSS hook */
1066   if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
1067                                           pRetCert, pRetKey)
1068       || NULL == *pRetCert) {
1069
1070     if(NULL == nickname)
1071       failf(data, "NSS: client certificate not found (nickname not "
1072             "specified)");
1073     else
1074       failf(data, "NSS: client certificate not found: %s", nickname);
1075
1076     return SECFailure;
1077   }
1078
1079   /* get certificate nickname if any */
1080   nickname = (*pRetCert)->nickname;
1081   if(NULL == nickname)
1082     nickname = "[unknown]";
1083
1084   if(!strncmp(nickname, pem_slotname, sizeof(pem_slotname) - 1U)) {
1085     failf(data, "NSS: refusing previously loaded certificate from file: %s",
1086           nickname);
1087     return SECFailure;
1088   }
1089
1090   if(NULL == *pRetKey) {
1091     failf(data, "NSS: private key not found for certificate: %s", nickname);
1092     return SECFailure;
1093   }
1094
1095   infof(data, "NSS: using client certificate: %s\n", nickname);
1096   display_cert_info(data, *pRetCert);
1097   return SECSuccess;
1098 }
1099
1100 /* update blocking direction in case of PR_WOULD_BLOCK_ERROR */
1101 static void nss_update_connecting_state(ssl_connect_state state, void *secret)
1102 {
1103   struct ssl_connect_data *connssl = (struct ssl_connect_data *)secret;
1104   if(PR_GetError() != PR_WOULD_BLOCK_ERROR)
1105     /* an unrelated error is passing by */
1106     return;
1107
1108   switch(connssl->connecting_state) {
1109   case ssl_connect_2:
1110   case ssl_connect_2_reading:
1111   case ssl_connect_2_writing:
1112     break;
1113   default:
1114     /* we are not called from an SSL handshake */
1115     return;
1116   }
1117
1118   /* update the state accordingly */
1119   connssl->connecting_state = state;
1120 }
1121
1122 /* recv() wrapper we use to detect blocking direction during SSL handshake */
1123 static PRInt32 nspr_io_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
1124                             PRIntn flags, PRIntervalTime timeout)
1125 {
1126   const PRRecvFN recv_fn = fd->lower->methods->recv;
1127   const PRInt32 rv = recv_fn(fd->lower, buf, amount, flags, timeout);
1128   if(rv < 0)
1129     /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
1130     nss_update_connecting_state(ssl_connect_2_reading, fd->secret);
1131   return rv;
1132 }
1133
1134 /* send() wrapper we use to detect blocking direction during SSL handshake */
1135 static PRInt32 nspr_io_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
1136                             PRIntn flags, PRIntervalTime timeout)
1137 {
1138   const PRSendFN send_fn = fd->lower->methods->send;
1139   const PRInt32 rv = send_fn(fd->lower, buf, amount, flags, timeout);
1140   if(rv < 0)
1141     /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
1142     nss_update_connecting_state(ssl_connect_2_writing, fd->secret);
1143   return rv;
1144 }
1145
1146 /* close() wrapper to avoid assertion failure due to fd->secret != NULL */
1147 static PRStatus nspr_io_close(PRFileDesc *fd)
1148 {
1149   const PRCloseFN close_fn = PR_GetDefaultIOMethods()->close;
1150   fd->secret = NULL;
1151   return close_fn(fd);
1152 }
1153
1154 /* data might be NULL */
1155 static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
1156 {
1157   NSSInitParameters initparams;
1158
1159   if(nss_context != NULL)
1160     return CURLE_OK;
1161
1162   memset((void *) &initparams, '\0', sizeof(initparams));
1163   initparams.length = sizeof(initparams);
1164
1165   if(cert_dir) {
1166     char *certpath = aprintf("sql:%s", cert_dir);
1167     if(!certpath)
1168       return CURLE_OUT_OF_MEMORY;
1169
1170     infof(data, "Initializing NSS with certpath: %s\n", certpath);
1171     nss_context = NSS_InitContext(certpath, "", "", "", &initparams,
1172             NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
1173     free(certpath);
1174
1175     if(nss_context != NULL)
1176       return CURLE_OK;
1177
1178     infof(data, "Unable to initialize NSS database\n");
1179   }
1180
1181   infof(data, "Initializing NSS with certpath: none\n");
1182   nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
1183          | NSS_INIT_NOCERTDB   | NSS_INIT_NOMODDB       | NSS_INIT_FORCEOPEN
1184          | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
1185   if(nss_context != NULL)
1186     return CURLE_OK;
1187
1188   infof(data, "Unable to initialize NSS\n");
1189   return CURLE_SSL_CACERT_BADFILE;
1190 }
1191
1192 /* data might be NULL */
1193 static CURLcode nss_init(struct Curl_easy *data)
1194 {
1195   char *cert_dir;
1196   struct_stat st;
1197   CURLcode result;
1198
1199   if(initialized)
1200     return CURLE_OK;
1201
1202   /* list of all CRL items we need to destroy in Curl_nss_cleanup() */
1203   nss_crl_list = Curl_llist_alloc(nss_destroy_crl_item);
1204   if(!nss_crl_list)
1205     return CURLE_OUT_OF_MEMORY;
1206
1207   /* First we check if $SSL_DIR points to a valid dir */
1208   cert_dir = getenv("SSL_DIR");
1209   if(cert_dir) {
1210     if((stat(cert_dir, &st) != 0) ||
1211         (!S_ISDIR(st.st_mode))) {
1212       cert_dir = NULL;
1213     }
1214   }
1215
1216   /* Now we check if the default location is a valid dir */
1217   if(!cert_dir) {
1218     if((stat(SSL_DIR, &st) == 0) &&
1219         (S_ISDIR(st.st_mode))) {
1220       cert_dir = (char *)SSL_DIR;
1221     }
1222   }
1223
1224   if(nspr_io_identity == PR_INVALID_IO_LAYER) {
1225     /* allocate an identity for our own NSPR I/O layer */
1226     nspr_io_identity = PR_GetUniqueIdentity("libcurl");
1227     if(nspr_io_identity == PR_INVALID_IO_LAYER)
1228       return CURLE_OUT_OF_MEMORY;
1229
1230     /* the default methods just call down to the lower I/O layer */
1231     memcpy(&nspr_io_methods, PR_GetDefaultIOMethods(), sizeof nspr_io_methods);
1232
1233     /* override certain methods in the table by our wrappers */
1234     nspr_io_methods.recv  = nspr_io_recv;
1235     nspr_io_methods.send  = nspr_io_send;
1236     nspr_io_methods.close = nspr_io_close;
1237   }
1238
1239   result = nss_init_core(data, cert_dir);
1240   if(result)
1241     return result;
1242
1243   if(!any_cipher_enabled())
1244     NSS_SetDomesticPolicy();
1245
1246   initialized = 1;
1247
1248   return CURLE_OK;
1249 }
1250
1251 /**
1252  * Global SSL init
1253  *
1254  * @retval 0 error initializing SSL
1255  * @retval 1 SSL initialized successfully
1256  */
1257 int Curl_nss_init(void)
1258 {
1259   /* curl_global_init() is not thread-safe so this test is ok */
1260   if(nss_initlock == NULL) {
1261     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
1262     nss_initlock = PR_NewLock();
1263     nss_crllock = PR_NewLock();
1264     nss_findslot_lock = PR_NewLock();
1265   }
1266
1267   /* We will actually initialize NSS later */
1268
1269   return 1;
1270 }
1271
1272 /* data might be NULL */
1273 CURLcode Curl_nss_force_init(struct Curl_easy *data)
1274 {
1275   CURLcode result;
1276   if(!nss_initlock) {
1277     if(data)
1278       failf(data, "unable to initialize NSS, curl_global_init() should have "
1279                   "been called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL");
1280     return CURLE_FAILED_INIT;
1281   }
1282
1283   PR_Lock(nss_initlock);
1284   result = nss_init(data);
1285   PR_Unlock(nss_initlock);
1286
1287   return result;
1288 }
1289
1290 /* Global cleanup */
1291 void Curl_nss_cleanup(void)
1292 {
1293   /* This function isn't required to be threadsafe and this is only done
1294    * as a safety feature.
1295    */
1296   PR_Lock(nss_initlock);
1297   if(initialized) {
1298     /* Free references to client certificates held in the SSL session cache.
1299      * Omitting this hampers destruction of the security module owning
1300      * the certificates. */
1301     SSL_ClearSessionCache();
1302
1303     if(mod && SECSuccess == SECMOD_UnloadUserModule(mod)) {
1304       SECMOD_DestroyModule(mod);
1305       mod = NULL;
1306     }
1307     NSS_ShutdownContext(nss_context);
1308     nss_context = NULL;
1309   }
1310
1311   /* destroy all CRL items */
1312   Curl_llist_destroy(nss_crl_list, NULL);
1313   nss_crl_list = NULL;
1314
1315   PR_Unlock(nss_initlock);
1316
1317   PR_DestroyLock(nss_initlock);
1318   PR_DestroyLock(nss_crllock);
1319   PR_DestroyLock(nss_findslot_lock);
1320   nss_initlock = NULL;
1321
1322   initialized = 0;
1323 }
1324
1325 /*
1326  * This function uses SSL_peek to determine connection status.
1327  *
1328  * Return codes:
1329  *     1 means the connection is still in place
1330  *     0 means the connection has been closed
1331  *    -1 means the connection status is unknown
1332  */
1333 int
1334 Curl_nss_check_cxn(struct connectdata *conn)
1335 {
1336   int rc;
1337   char buf;
1338
1339   rc =
1340     PR_Recv(conn->ssl[FIRSTSOCKET].handle, (void *)&buf, 1, PR_MSG_PEEK,
1341             PR_SecondsToInterval(1));
1342   if(rc > 0)
1343     return 1; /* connection still in place */
1344
1345   if(rc == 0)
1346     return 0; /* connection has been closed */
1347
1348   return -1;  /* connection status unknown */
1349 }
1350
1351 /*
1352  * This function is called when an SSL connection is closed.
1353  */
1354 void Curl_nss_close(struct connectdata *conn, int sockindex)
1355 {
1356   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1357
1358   if(connssl->handle) {
1359     /* NSS closes the socket we previously handed to it, so we must mark it
1360        as closed to avoid double close */
1361     fake_sclose(conn->sock[sockindex]);
1362     conn->sock[sockindex] = CURL_SOCKET_BAD;
1363
1364     if((connssl->client_nickname != NULL) || (connssl->obj_clicert != NULL))
1365       /* A server might require different authentication based on the
1366        * particular path being requested by the client.  To support this
1367        * scenario, we must ensure that a connection will never reuse the
1368        * authentication data from a previous connection. */
1369       SSL_InvalidateSession(connssl->handle);
1370
1371     free(connssl->client_nickname);
1372     connssl->client_nickname = NULL;
1373     /* destroy all NSS objects in order to avoid failure of NSS shutdown */
1374     Curl_llist_destroy(connssl->obj_list, NULL);
1375     connssl->obj_list = NULL;
1376     connssl->obj_clicert = NULL;
1377
1378     PR_Close(connssl->handle);
1379     connssl->handle = NULL;
1380   }
1381 }
1382
1383 /* return true if NSS can provide error code (and possibly msg) for the
1384    error */
1385 static bool is_nss_error(CURLcode err)
1386 {
1387   switch(err) {
1388   case CURLE_PEER_FAILED_VERIFICATION:
1389   case CURLE_SSL_CACERT:
1390   case CURLE_SSL_CERTPROBLEM:
1391   case CURLE_SSL_CONNECT_ERROR:
1392   case CURLE_SSL_ISSUER_ERROR:
1393     return true;
1394
1395   default:
1396     return false;
1397   }
1398 }
1399
1400 /* return true if the given error code is related to a client certificate */
1401 static bool is_cc_error(PRInt32 err)
1402 {
1403   switch(err) {
1404   case SSL_ERROR_BAD_CERT_ALERT:
1405   case SSL_ERROR_EXPIRED_CERT_ALERT:
1406   case SSL_ERROR_REVOKED_CERT_ALERT:
1407     return true;
1408
1409   default:
1410     return false;
1411   }
1412 }
1413
1414 static Curl_recv nss_recv;
1415 static Curl_send nss_send;
1416
1417 static CURLcode nss_load_ca_certificates(struct connectdata *conn,
1418                                          int sockindex)
1419 {
1420   struct Curl_easy *data = conn->data;
1421   const char *cafile = data->set.ssl.CAfile;
1422   const char *capath = data->set.ssl.CApath;
1423
1424   if(cafile) {
1425     CURLcode result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
1426     if(result)
1427       return result;
1428   }
1429
1430   if(capath) {
1431     struct_stat st;
1432     if(stat(capath, &st) == -1)
1433       return CURLE_SSL_CACERT_BADFILE;
1434
1435     if(S_ISDIR(st.st_mode)) {
1436       PRDirEntry *entry;
1437       PRDir *dir = PR_OpenDir(capath);
1438       if(!dir)
1439         return CURLE_SSL_CACERT_BADFILE;
1440
1441       while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) {
1442         char *fullpath = aprintf("%s/%s", capath, entry->name);
1443         if(!fullpath) {
1444           PR_CloseDir(dir);
1445           return CURLE_OUT_OF_MEMORY;
1446         }
1447
1448         if(CURLE_OK != nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE))
1449           /* This is purposefully tolerant of errors so non-PEM files can
1450            * be in the same directory */
1451           infof(data, "failed to load '%s' from CURLOPT_CAPATH\n", fullpath);
1452
1453         free(fullpath);
1454       }
1455
1456       PR_CloseDir(dir);
1457     }
1458     else
1459       infof(data, "warning: CURLOPT_CAPATH not a directory (%s)\n", capath);
1460   }
1461
1462   infof(data, "  CAfile: %s\n  CApath: %s\n",
1463       cafile ? cafile : "none",
1464       capath ? capath : "none");
1465
1466   return CURLE_OK;
1467 }
1468
1469 static CURLcode nss_init_sslver(SSLVersionRange *sslver,
1470                                 struct Curl_easy *data)
1471 {
1472   switch(data->set.ssl.version) {
1473   default:
1474   case CURL_SSLVERSION_DEFAULT:
1475   case CURL_SSLVERSION_TLSv1:
1476     sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
1477 #ifdef SSL_LIBRARY_VERSION_TLS_1_2
1478     sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
1479 #elif defined SSL_LIBRARY_VERSION_TLS_1_1
1480     sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
1481 #else
1482     sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
1483 #endif
1484     return CURLE_OK;
1485
1486   case CURL_SSLVERSION_SSLv2:
1487     sslver->min = SSL_LIBRARY_VERSION_2;
1488     sslver->max = SSL_LIBRARY_VERSION_2;
1489     return CURLE_OK;
1490
1491   case CURL_SSLVERSION_SSLv3:
1492     sslver->min = SSL_LIBRARY_VERSION_3_0;
1493     sslver->max = SSL_LIBRARY_VERSION_3_0;
1494     return CURLE_OK;
1495
1496   case CURL_SSLVERSION_TLSv1_0:
1497     sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
1498     sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
1499     return CURLE_OK;
1500
1501   case CURL_SSLVERSION_TLSv1_1:
1502 #ifdef SSL_LIBRARY_VERSION_TLS_1_1
1503     sslver->min = SSL_LIBRARY_VERSION_TLS_1_1;
1504     sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
1505     return CURLE_OK;
1506 #endif
1507     break;
1508
1509   case CURL_SSLVERSION_TLSv1_2:
1510 #ifdef SSL_LIBRARY_VERSION_TLS_1_2
1511     sslver->min = SSL_LIBRARY_VERSION_TLS_1_2;
1512     sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
1513     return CURLE_OK;
1514 #endif
1515     break;
1516   }
1517
1518   failf(data, "TLS minor version cannot be set");
1519   return CURLE_SSL_CONNECT_ERROR;
1520 }
1521
1522 static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
1523                                  struct Curl_easy *data,
1524                                  CURLcode curlerr)
1525 {
1526   PRErrorCode err = 0;
1527
1528   if(is_nss_error(curlerr)) {
1529     /* read NSPR error code */
1530     err = PR_GetError();
1531     if(is_cc_error(err))
1532       curlerr = CURLE_SSL_CERTPROBLEM;
1533
1534     /* print the error number and error string */
1535     infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err));
1536
1537     /* print a human-readable message describing the error if available */
1538     nss_print_error_message(data, err);
1539   }
1540
1541   /* cleanup on connection failure */
1542   Curl_llist_destroy(connssl->obj_list, NULL);
1543   connssl->obj_list = NULL;
1544
1545   return curlerr;
1546 }
1547
1548 /* Switch the SSL socket into non-blocking mode. */
1549 static CURLcode nss_set_nonblock(struct ssl_connect_data *connssl,
1550                                  struct Curl_easy *data)
1551 {
1552   static PRSocketOptionData sock_opt;
1553   sock_opt.option = PR_SockOpt_Nonblocking;
1554   sock_opt.value.non_blocking = PR_TRUE;
1555
1556   if(PR_SetSocketOption(connssl->handle, &sock_opt) != PR_SUCCESS)
1557     return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
1558
1559   return CURLE_OK;
1560 }
1561
1562 static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
1563 {
1564   PRFileDesc *model = NULL;
1565   PRFileDesc *nspr_io = NULL;
1566   PRFileDesc *nspr_io_stub = NULL;
1567   PRBool ssl_no_cache;
1568   PRBool ssl_cbc_random_iv;
1569   struct Curl_easy *data = conn->data;
1570   curl_socket_t sockfd = conn->sock[sockindex];
1571   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1572   CURLcode result;
1573
1574   SSLVersionRange sslver = {
1575     SSL_LIBRARY_VERSION_TLS_1_0,  /* min */
1576     SSL_LIBRARY_VERSION_TLS_1_0   /* max */
1577   };
1578
1579   connssl->data = data;
1580
1581   /* list of all NSS objects we need to destroy in Curl_nss_close() */
1582   connssl->obj_list = Curl_llist_alloc(nss_destroy_object);
1583   if(!connssl->obj_list)
1584     return CURLE_OUT_OF_MEMORY;
1585
1586   /* FIXME. NSS doesn't support multiple databases open at the same time. */
1587   PR_Lock(nss_initlock);
1588   result = nss_init(conn->data);
1589   if(result) {
1590     PR_Unlock(nss_initlock);
1591     goto error;
1592   }
1593
1594   result = CURLE_SSL_CONNECT_ERROR;
1595
1596   if(!mod) {
1597     char *configstring = aprintf("library=%s name=PEM", pem_library);
1598     if(!configstring) {
1599       PR_Unlock(nss_initlock);
1600       goto error;
1601     }
1602     mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
1603     free(configstring);
1604
1605     if(!mod || !mod->loaded) {
1606       if(mod) {
1607         SECMOD_DestroyModule(mod);
1608         mod = NULL;
1609       }
1610       infof(data, "WARNING: failed to load NSS PEM library %s. Using "
1611                   "OpenSSL PEM certificates will not work.\n", pem_library);
1612     }
1613   }
1614
1615   PK11_SetPasswordFunc(nss_get_password);
1616   PR_Unlock(nss_initlock);
1617
1618   model = PR_NewTCPSocket();
1619   if(!model)
1620     goto error;
1621   model = SSL_ImportFD(NULL, model);
1622
1623   if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess)
1624     goto error;
1625   if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess)
1626     goto error;
1627   if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
1628     goto error;
1629
1630   /* do not use SSL cache if disabled or we are not going to verify peer */
1631   ssl_no_cache = (conn->ssl_config.sessionid && data->set.ssl.verifypeer) ?
1632     PR_FALSE : PR_TRUE;
1633   if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
1634     goto error;
1635
1636   /* enable/disable the requested SSL version(s) */
1637   if(nss_init_sslver(&sslver, data) != CURLE_OK)
1638     goto error;
1639   if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
1640     goto error;
1641
1642   ssl_cbc_random_iv = !data->set.ssl_enable_beast;
1643 #ifdef SSL_CBC_RANDOM_IV
1644   /* unless the user explicitly asks to allow the protocol vulnerability, we
1645      use the work-around */
1646   if(SSL_OptionSet(model, SSL_CBC_RANDOM_IV, ssl_cbc_random_iv) != SECSuccess)
1647     infof(data, "warning: failed to set SSL_CBC_RANDOM_IV = %d\n",
1648           ssl_cbc_random_iv);
1649 #else
1650   if(ssl_cbc_random_iv)
1651     infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n");
1652 #endif
1653
1654   if(data->set.ssl.cipher_list) {
1655     if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
1656       result = CURLE_SSL_CIPHER;
1657       goto error;
1658     }
1659   }
1660
1661   if(!data->set.ssl.verifypeer && data->set.ssl.verifyhost)
1662     infof(data, "warning: ignoring value of ssl.verifyhost\n");
1663
1664   /* bypass the default SSL_AuthCertificate() hook in case we do not want to
1665    * verify peer */
1666   if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, conn) != SECSuccess)
1667     goto error;
1668
1669   data->set.ssl.certverifyresult=0; /* not checked yet */
1670   if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess)
1671     goto error;
1672
1673   if(SSL_HandshakeCallback(model, HandshakeCallback, conn) != SECSuccess)
1674     goto error;
1675
1676   if(data->set.ssl.verifypeer) {
1677     const CURLcode rv = nss_load_ca_certificates(conn, sockindex);
1678     if(rv) {
1679       result = rv;
1680       goto error;
1681     }
1682   }
1683
1684   if(data->set.ssl.CRLfile) {
1685     const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile);
1686     if(rv) {
1687       result = rv;
1688       goto error;
1689     }
1690     infof(data, "  CRLfile: %s\n", data->set.ssl.CRLfile);
1691   }
1692
1693   if(data->set.str[STRING_CERT]) {
1694     char *nickname = dup_nickname(data, STRING_CERT);
1695     if(nickname) {
1696       /* we are not going to use libnsspem.so to read the client cert */
1697       connssl->obj_clicert = NULL;
1698     }
1699     else {
1700       CURLcode rv = cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
1701                                data->set.str[STRING_KEY]);
1702       if(rv) {
1703         /* failf() is already done in cert_stuff() */
1704         result = rv;
1705         goto error;
1706       }
1707     }
1708
1709     /* store the nickname for SelectClientCert() called during handshake */
1710     connssl->client_nickname = nickname;
1711   }
1712   else
1713     connssl->client_nickname = NULL;
1714
1715   if(SSL_GetClientAuthDataHook(model, SelectClientCert,
1716                                (void *)connssl) != SECSuccess) {
1717     result = CURLE_SSL_CERTPROBLEM;
1718     goto error;
1719   }
1720
1721   /* wrap OS file descriptor by NSPR's file descriptor abstraction */
1722   nspr_io = PR_ImportTCPSocket(sockfd);
1723   if(!nspr_io)
1724     goto error;
1725
1726   /* create our own NSPR I/O layer */
1727   nspr_io_stub = PR_CreateIOLayerStub(nspr_io_identity, &nspr_io_methods);
1728   if(!nspr_io_stub) {
1729     PR_Close(nspr_io);
1730     goto error;
1731   }
1732
1733   /* make the per-connection data accessible from NSPR I/O callbacks */
1734   nspr_io_stub->secret = (void *)connssl;
1735
1736   /* push our new layer to the NSPR I/O stack */
1737   if(PR_PushIOLayer(nspr_io, PR_TOP_IO_LAYER, nspr_io_stub) != PR_SUCCESS) {
1738     PR_Close(nspr_io);
1739     PR_Close(nspr_io_stub);
1740     goto error;
1741   }
1742
1743   /* import our model socket onto the current I/O stack */
1744   connssl->handle = SSL_ImportFD(model, nspr_io);
1745   if(!connssl->handle) {
1746     PR_Close(nspr_io);
1747     goto error;
1748   }
1749
1750   PR_Close(model); /* We don't need this any more */
1751   model = NULL;
1752
1753   /* This is the password associated with the cert that we're using */
1754   if(data->set.str[STRING_KEY_PASSWD]) {
1755     SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
1756   }
1757
1758 #ifdef SSL_ENABLE_OCSP_STAPLING
1759   if(data->set.ssl.verifystatus) {
1760     if(SSL_OptionSet(connssl->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
1761         != SECSuccess)
1762       goto error;
1763   }
1764 #endif
1765
1766 #ifdef SSL_ENABLE_NPN
1767   if(SSL_OptionSet(connssl->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
1768                    ? PR_TRUE : PR_FALSE) != SECSuccess)
1769     goto error;
1770 #endif
1771
1772 #ifdef SSL_ENABLE_ALPN
1773   if(SSL_OptionSet(connssl->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
1774                    ? PR_TRUE : PR_FALSE) != SECSuccess)
1775     goto error;
1776 #endif
1777
1778 #if NSSVERNUM >= 0x030f04 /* 3.15.4 */
1779   if(data->set.ssl.falsestart) {
1780     if(SSL_OptionSet(connssl->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
1781         != SECSuccess)
1782       goto error;
1783
1784     if(SSL_SetCanFalseStartCallback(connssl->handle, CanFalseStartCallback,
1785         conn) != SECSuccess)
1786       goto error;
1787   }
1788 #endif
1789
1790 #if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN)
1791   if(conn->bits.tls_enable_npn || conn->bits.tls_enable_alpn) {
1792     int cur = 0;
1793     unsigned char protocols[128];
1794
1795 #ifdef USE_NGHTTP2
1796     if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
1797       protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
1798       memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
1799           NGHTTP2_PROTO_VERSION_ID_LEN);
1800       cur += NGHTTP2_PROTO_VERSION_ID_LEN;
1801     }
1802 #endif
1803     protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
1804     memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
1805     cur += ALPN_HTTP_1_1_LENGTH;
1806
1807     if(SSL_SetNextProtoNego(connssl->handle, protocols, cur) != SECSuccess)
1808       goto error;
1809   }
1810 #endif
1811
1812
1813   /* Force handshake on next I/O */
1814   if(SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE)
1815       != SECSuccess)
1816     goto error;
1817
1818   /* propagate hostname to the TLS layer */
1819   if(SSL_SetURL(connssl->handle, conn->host.name) != SECSuccess)
1820     goto error;
1821
1822   /* prevent NSS from re-using the session for a different hostname */
1823   if(SSL_SetSockPeerID(connssl->handle, conn->host.name) != SECSuccess)
1824     goto error;
1825
1826   return CURLE_OK;
1827
1828 error:
1829   if(model)
1830     PR_Close(model);
1831
1832   return nss_fail_connect(connssl, data, result);
1833 }
1834
1835 static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
1836 {
1837   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1838   struct Curl_easy *data = conn->data;
1839   CURLcode result = CURLE_SSL_CONNECT_ERROR;
1840   PRUint32 timeout;
1841
1842   /* check timeout situation */
1843   const long time_left = Curl_timeleft(data, NULL, TRUE);
1844   if(time_left < 0L) {
1845     failf(data, "timed out before SSL handshake");
1846     result = CURLE_OPERATION_TIMEDOUT;
1847     goto error;
1848   }
1849
1850   /* Force the handshake now */
1851   timeout = PR_MillisecondsToInterval((PRUint32) time_left);
1852   if(SSL_ForceHandshakeWithTimeout(connssl->handle, timeout) != SECSuccess) {
1853     if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
1854       /* blocking direction is updated by nss_update_connecting_state() */
1855       return CURLE_AGAIN;
1856     else if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
1857       result = CURLE_PEER_FAILED_VERIFICATION;
1858     else if(conn->data->set.ssl.certverifyresult!=0)
1859       result = CURLE_SSL_CACERT;
1860     goto error;
1861   }
1862
1863   result = display_conn_info(conn, connssl->handle);
1864   if(result)
1865     goto error;
1866
1867   if(data->set.str[STRING_SSL_ISSUERCERT]) {
1868     SECStatus ret = SECFailure;
1869     char *nickname = dup_nickname(data, STRING_SSL_ISSUERCERT);
1870     if(nickname) {
1871       /* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */
1872       ret = check_issuer_cert(connssl->handle, nickname);
1873       free(nickname);
1874     }
1875
1876     if(SECFailure == ret) {
1877       infof(data, "SSL certificate issuer check failed\n");
1878       result = CURLE_SSL_ISSUER_ERROR;
1879       goto error;
1880     }
1881     else {
1882       infof(data, "SSL certificate issuer check ok\n");
1883     }
1884   }
1885
1886   result = cmp_peer_pubkey(connssl, data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
1887   if(result)
1888     /* status already printed */
1889     goto error;
1890
1891   return CURLE_OK;
1892
1893 error:
1894   return nss_fail_connect(connssl, data, result);
1895 }
1896
1897 static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
1898                                    bool *done)
1899 {
1900   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1901   struct Curl_easy *data = conn->data;
1902   const bool blocking = (done == NULL);
1903   CURLcode result;
1904
1905   if(connssl->state == ssl_connection_complete)
1906     return CURLE_OK;
1907
1908   if(connssl->connecting_state == ssl_connect_1) {
1909     result = nss_setup_connect(conn, sockindex);
1910     if(result)
1911       /* we do not expect CURLE_AGAIN from nss_setup_connect() */
1912       return result;
1913
1914     if(!blocking) {
1915       /* in non-blocking mode, set NSS non-blocking mode before handshake */
1916       result = nss_set_nonblock(connssl, data);
1917       if(result)
1918         return result;
1919     }
1920
1921     connssl->connecting_state = ssl_connect_2;
1922   }
1923
1924   result = nss_do_connect(conn, sockindex);
1925   switch(result) {
1926   case CURLE_OK:
1927     break;
1928   case CURLE_AGAIN:
1929     if(!blocking)
1930       /* CURLE_AGAIN in non-blocking mode is not an error */
1931       return CURLE_OK;
1932     /* fall through */
1933   default:
1934     return result;
1935   }
1936
1937   if(blocking) {
1938     /* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */
1939     result = nss_set_nonblock(connssl, data);
1940     if(result)
1941       return result;
1942   }
1943   else
1944     /* signal completed SSL handshake */
1945     *done = TRUE;
1946
1947   connssl->state = ssl_connection_complete;
1948   conn->recv[sockindex] = nss_recv;
1949   conn->send[sockindex] = nss_send;
1950
1951   /* ssl_connect_done is never used outside, go back to the initial state */
1952   connssl->connecting_state = ssl_connect_1;
1953
1954   return CURLE_OK;
1955 }
1956
1957 CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
1958 {
1959   return nss_connect_common(conn, sockindex, /* blocking */ NULL);
1960 }
1961
1962 CURLcode Curl_nss_connect_nonblocking(struct connectdata *conn,
1963                                       int sockindex, bool *done)
1964 {
1965   return nss_connect_common(conn, sockindex, done);
1966 }
1967
1968 static ssize_t nss_send(struct connectdata *conn,  /* connection data */
1969                         int sockindex,             /* socketindex */
1970                         const void *mem,           /* send this data */
1971                         size_t len,                /* amount to write */
1972                         CURLcode *curlcode)
1973 {
1974   ssize_t rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0,
1975                        PR_INTERVAL_NO_WAIT);
1976   if(rc < 0) {
1977     PRInt32 err = PR_GetError();
1978     if(err == PR_WOULD_BLOCK_ERROR)
1979       *curlcode = CURLE_AGAIN;
1980     else {
1981       /* print the error number and error string */
1982       const char *err_name = nss_error_to_name(err);
1983       infof(conn->data, "SSL write: error %d (%s)\n", err, err_name);
1984
1985       /* print a human-readable message describing the error if available */
1986       nss_print_error_message(conn->data, err);
1987
1988       *curlcode = (is_cc_error(err))
1989         ? CURLE_SSL_CERTPROBLEM
1990         : CURLE_SEND_ERROR;
1991     }
1992
1993     return -1;
1994   }
1995
1996   return rc; /* number of bytes */
1997 }
1998
1999 static ssize_t nss_recv(struct connectdata * conn, /* connection data */
2000                         int num,                   /* socketindex */
2001                         char *buf,                 /* store read data here */
2002                         size_t buffersize,         /* max amount to read */
2003                         CURLcode *curlcode)
2004 {
2005   ssize_t nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0,
2006                           PR_INTERVAL_NO_WAIT);
2007   if(nread < 0) {
2008     /* failed SSL read */
2009     PRInt32 err = PR_GetError();
2010
2011     if(err == PR_WOULD_BLOCK_ERROR)
2012       *curlcode = CURLE_AGAIN;
2013     else {
2014       /* print the error number and error string */
2015       const char *err_name = nss_error_to_name(err);
2016       infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name);
2017
2018       /* print a human-readable message describing the error if available */
2019       nss_print_error_message(conn->data, err);
2020
2021       *curlcode = (is_cc_error(err))
2022         ? CURLE_SSL_CERTPROBLEM
2023         : CURLE_RECV_ERROR;
2024     }
2025
2026     return -1;
2027   }
2028
2029   return nread;
2030 }
2031
2032 size_t Curl_nss_version(char *buffer, size_t size)
2033 {
2034   return snprintf(buffer, size, "NSS/%s", NSS_VERSION);
2035 }
2036
2037 /* data might be NULL */
2038 int Curl_nss_seed(struct Curl_easy *data)
2039 {
2040   /* make sure that NSS is initialized */
2041   return !!Curl_nss_force_init(data);
2042 }
2043
2044 /* data might be NULL */
2045 int Curl_nss_random(struct Curl_easy *data,
2046                     unsigned char *entropy,
2047                     size_t length)
2048 {
2049   Curl_nss_seed(data);  /* Initiate the seed if not already done */
2050
2051   if(SECSuccess != PK11_GenerateRandom(entropy, curlx_uztosi(length)))
2052     /* signal a failure */
2053     return -1;
2054
2055   return 0;
2056 }
2057
2058 void Curl_nss_md5sum(unsigned char *tmp, /* input */
2059                      size_t tmplen,
2060                      unsigned char *md5sum, /* output */
2061                      size_t md5len)
2062 {
2063   PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
2064   unsigned int MD5out;
2065
2066   PK11_DigestOp(MD5pw, tmp, curlx_uztoui(tmplen));
2067   PK11_DigestFinal(MD5pw, md5sum, &MD5out, curlx_uztoui(md5len));
2068   PK11_DestroyContext(MD5pw, PR_TRUE);
2069 }
2070
2071 void Curl_nss_sha256sum(const unsigned char *tmp, /* input */
2072                      size_t tmplen,
2073                      unsigned char *sha256sum, /* output */
2074                      size_t sha256len)
2075 {
2076   PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256);
2077   unsigned int SHA256out;
2078
2079   PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen));
2080   PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len));
2081   PK11_DestroyContext(SHA256pw, PR_TRUE);
2082 }
2083
2084 bool Curl_nss_cert_status_request(void)
2085 {
2086 #ifdef SSL_ENABLE_OCSP_STAPLING
2087   return TRUE;
2088 #else
2089   return FALSE;
2090 #endif
2091 }
2092
2093 bool Curl_nss_false_start(void) {
2094 #if NSSVERNUM >= 0x030f04 /* 3.15.4 */
2095   return TRUE;
2096 #else
2097   return FALSE;
2098 #endif
2099 }
2100
2101 #endif /* USE_NSS */