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