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