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