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