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