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