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