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