Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "bin/secure_socket.h" | 5 #include "bin/secure_socket.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 #include <stdio.h> | 10 #include <stdio.h> |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 } | 518 } |
| 519 | 519 |
| 520 | 520 |
| 521 void SSLFilter::RegisterBadCertificateCallback(Dart_Handle callback) { | 521 void SSLFilter::RegisterBadCertificateCallback(Dart_Handle callback) { |
| 522 ASSERT(bad_certificate_callback_ != NULL); | 522 ASSERT(bad_certificate_callback_ != NULL); |
| 523 Dart_DeletePersistentHandle(bad_certificate_callback_); | 523 Dart_DeletePersistentHandle(bad_certificate_callback_); |
| 524 bad_certificate_callback_ = Dart_NewPersistentHandle(callback); | 524 bad_certificate_callback_ = Dart_NewPersistentHandle(callback); |
| 525 ASSERT(bad_certificate_callback_ != NULL); | 525 ASSERT(bad_certificate_callback_ != NULL); |
| 526 } | 526 } |
| 527 | 527 |
| 528 | |
| 529 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { | |
| 530 if (!retry) { | |
| 531 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. | |
|
Anders Johnsen
2013/07/11 08:17:43
Why PL_strdup here but strdup below?
| |
| 532 } | |
| 533 return NULL; | |
| 534 } | |
| 535 | |
| 536 | |
| 528 static const char* builtin_roots_module = | 537 static const char* builtin_roots_module = |
| 529 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) | 538 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) |
| 530 "name=\"Root Certs\" library=\"libnssckbi.so\""; | 539 "name=\"Root Certs\" library=\"libnssckbi.so\""; |
| 531 #elif defined(TARGET_OS_MACOS) | 540 #elif defined(TARGET_OS_MACOS) |
| 532 "name=\"Root Certs\" library=\"libnssckbi.dylib\""; | 541 "name=\"Root Certs\" library=\"libnssckbi.dylib\""; |
| 533 #elif defined(TARGET_OS_WINDOWS) | 542 #elif defined(TARGET_OS_WINDOWS) |
| 534 "name=\"Root Certs\" library=\"nssckbi.dll\""; | 543 "name=\"Root Certs\" library=\"nssckbi.dll\""; |
| 535 #else | 544 #else |
| 536 #error Automatic target os detection failed. | 545 #error Automatic target os detection failed. |
| 537 #endif | 546 #endif |
| 538 | 547 |
| 539 | 548 |
| 540 | 549 |
| 541 void SSLFilter::InitializeLibrary(const char* certificate_database, | 550 void SSLFilter::InitializeLibrary(const char* certificate_database, |
| 542 const char* password, | 551 const char* password, |
| 543 bool use_builtin_root_certificates, | 552 bool use_builtin_root_certificates, |
| 544 bool report_duplicate_initialization) { | 553 bool report_duplicate_initialization) { |
| 545 MutexLocker locker(mutex_); | 554 MutexLocker locker(mutex_); |
| 546 SECStatus status; | 555 SECStatus status; |
| 547 if (!library_initialized_) { | 556 if (!library_initialized_) { |
| 548 password_ = strdup(password); // This one copy persists until Dart exits. | |
| 549 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); | 557 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); |
| 550 // TODO(whesse): Verify there are no UTF-8 issues here. | 558 // TODO(whesse): Verify there are no UTF-8 issues here. |
| 551 if (certificate_database == NULL || certificate_database[0] == '\0') { | 559 if (certificate_database == NULL || certificate_database[0] == '\0') { |
| 552 status = NSS_NoDB_Init(NULL); | 560 status = NSS_NoDB_Init(NULL); |
| 553 if (status != SECSuccess) { | 561 if (status != SECSuccess) { |
| 554 mutex_->Unlock(); // MutexLocker destructor not called when throwing. | 562 mutex_->Unlock(); // MutexLocker destructor not called when throwing. |
| 555 ThrowPRException("TlsException", | 563 ThrowPRException("TlsException", |
| 556 "Failed NSS_NoDB_Init call."); | 564 "Failed NSS_NoDB_Init call."); |
| 557 } | 565 } |
| 558 if (use_builtin_root_certificates) { | 566 if (use_builtin_root_certificates) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 572 status = NSS_Initialize(certificate_database, | 580 status = NSS_Initialize(certificate_database, |
| 573 "", | 581 "", |
| 574 "", | 582 "", |
| 575 SECMOD_DB, | 583 SECMOD_DB, |
| 576 init_flags); | 584 init_flags); |
| 577 if (status != SECSuccess) { | 585 if (status != SECSuccess) { |
| 578 mutex_->Unlock(); // MutexLocker destructor not called when throwing. | 586 mutex_->Unlock(); // MutexLocker destructor not called when throwing. |
| 579 ThrowPRException("TlsException", | 587 ThrowPRException("TlsException", |
| 580 "Failed NSS_Init call."); | 588 "Failed NSS_Init call."); |
| 581 } | 589 } |
| 590 password_ = strdup(password); // This one copy persists until Dart exits. | |
|
Anders Johnsen
2013/07/11 08:17:43
Dart exits or leaving the current Dart Scope?
Bill Hesse
2013/07/11 09:24:46
Until Dart exits (the process terminates). This i
| |
| 591 PK11_SetPasswordFunc(PasswordCallback); | |
| 582 } | 592 } |
| 583 library_initialized_ = true; | 593 library_initialized_ = true; |
| 584 | 594 |
| 585 status = NSS_SetDomesticPolicy(); | 595 status = NSS_SetDomesticPolicy(); |
| 586 if (status != SECSuccess) { | 596 if (status != SECSuccess) { |
| 587 mutex_->Unlock(); // MutexLocker destructor not called when throwing. | 597 mutex_->Unlock(); // MutexLocker destructor not called when throwing. |
| 588 ThrowPRException("TlsException", | 598 ThrowPRException("TlsException", |
| 589 "Failed NSS_SetDomesticPolicy call."); | 599 "Failed NSS_SetDomesticPolicy call."); |
| 590 } | 600 } |
| 591 // Enable TLS, as well as SSL3 and SSL2. | 601 // Enable TLS, as well as SSL3 and SSL2. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 605 } else if (report_duplicate_initialization) { | 615 } else if (report_duplicate_initialization) { |
| 606 mutex_->Unlock(); // MutexLocker destructor not called when throwing. | 616 mutex_->Unlock(); // MutexLocker destructor not called when throwing. |
| 607 // Like ThrowPRException, without adding an OSError. | 617 // Like ThrowPRException, without adding an OSError. |
| 608 Dart_ThrowException(DartUtils::NewDartIOException("TlsException", | 618 Dart_ThrowException(DartUtils::NewDartIOException("TlsException", |
| 609 "Called SecureSocket.initialize more than once", | 619 "Called SecureSocket.initialize more than once", |
| 610 Dart_Null())); | 620 Dart_Null())); |
| 611 } | 621 } |
| 612 } | 622 } |
| 613 | 623 |
| 614 | 624 |
| 615 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { | |
| 616 if (!retry) { | |
| 617 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. | |
| 618 } | |
| 619 return NULL; | |
| 620 } | |
| 621 | |
| 622 | |
| 623 SECStatus BadCertificateCallback(void* filter, PRFileDesc* fd) { | 625 SECStatus BadCertificateCallback(void* filter, PRFileDesc* fd) { |
| 624 SSLFilter* ssl_filter = static_cast<SSLFilter*>(filter); | 626 SSLFilter* ssl_filter = static_cast<SSLFilter*>(filter); |
| 625 Dart_Handle callback = ssl_filter->bad_certificate_callback(); | 627 Dart_Handle callback = ssl_filter->bad_certificate_callback(); |
| 626 if (Dart_IsNull(callback)) return SECFailure; | 628 if (Dart_IsNull(callback)) return SECFailure; |
| 627 | 629 |
| 628 Dart_EnterScope(); | 630 Dart_EnterScope(); |
| 629 Dart_Handle x509_object = ssl_filter->PeerCertificate(); | 631 Dart_Handle x509_object = ssl_filter->PeerCertificate(); |
| 630 Dart_Handle result = | 632 Dart_Handle result = |
| 631 ThrowIfError(Dart_InvokeClosure(callback, 1, &x509_object)); | 633 ThrowIfError(Dart_InvokeClosure(callback, 1, &x509_object)); |
| 632 bool c_result = Dart_IsBoolean(result) && DartUtils::GetBooleanValue(result); | 634 bool c_result = Dart_IsBoolean(result) && DartUtils::GetBooleanValue(result); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 ThrowPRException("TlsException", "Failed SSL_ImportFD call"); | 668 ThrowPRException("TlsException", "Failed SSL_ImportFD call"); |
| 667 } | 669 } |
| 668 | 670 |
| 669 SSLVersionRange vrange; | 671 SSLVersionRange vrange; |
| 670 vrange.min = SSL_LIBRARY_VERSION_3_0; | 672 vrange.min = SSL_LIBRARY_VERSION_3_0; |
| 671 vrange.max = SSL_LIBRARY_VERSION_TLS_1_1; | 673 vrange.max = SSL_LIBRARY_VERSION_TLS_1_1; |
| 672 SSL_VersionRangeSet(filter_, &vrange); | 674 SSL_VersionRangeSet(filter_, &vrange); |
| 673 | 675 |
| 674 SECStatus status; | 676 SECStatus status; |
| 675 if (is_server) { | 677 if (is_server) { |
| 676 PK11_SetPasswordFunc(PasswordCallback); | |
| 677 | |
| 678 CERTCertificate* certificate = NULL; | 678 CERTCertificate* certificate = NULL; |
| 679 if (strstr(certificate_name, "CN=") != NULL) { | 679 if (strstr(certificate_name, "CN=") != NULL) { |
| 680 // Look up certificate using the distinguished name (DN) certificate_name. | 680 // Look up certificate using the distinguished name (DN) certificate_name. |
| 681 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB(); | 681 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB(); |
| 682 if (certificate_database == NULL) { | 682 if (certificate_database == NULL) { |
| 683 ThrowPRException("CertificateException", | 683 ThrowPRException("CertificateException", |
| 684 "Certificate database cannot be loaded"); | 684 "Certificate database cannot be loaded"); |
| 685 } | 685 } |
| 686 certificate = CERT_FindCertByNameString(certificate_database, | 686 certificate = CERT_FindCertByNameString(certificate_database, |
| 687 const_cast<char*>(certificate_name)); | 687 const_cast<char*>(certificate_name)); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 748 // This disables the SSL session cache for client connections. | 748 // This disables the SSL session cache for client connections. |
| 749 // This resolves issue 7208, but degrades performance. | 749 // This resolves issue 7208, but degrades performance. |
| 750 // TODO(7230): Reenable session cache, without breaking client connections. | 750 // TODO(7230): Reenable session cache, without breaking client connections. |
| 751 status = SSL_OptionSet(filter_, SSL_NO_CACHE, PR_TRUE); | 751 status = SSL_OptionSet(filter_, SSL_NO_CACHE, PR_TRUE); |
| 752 if (status != SECSuccess) { | 752 if (status != SECSuccess) { |
| 753 ThrowPRException("TlsException", | 753 ThrowPRException("TlsException", |
| 754 "Failed SSL_OptionSet(NO_CACHE) call"); | 754 "Failed SSL_OptionSet(NO_CACHE) call"); |
| 755 } | 755 } |
| 756 | 756 |
| 757 if (send_client_certificate) { | 757 if (send_client_certificate) { |
| 758 SSL_SetPKCS11PinArg(filter_, const_cast<char*>(password_)); | |
|
Anders Johnsen
2013/07/11 08:17:43
delete password_ in destructor?
Bill Hesse
2013/07/11 09:24:46
No, password_ is a static.
| |
| 758 status = SSL_GetClientAuthDataHook( | 759 status = SSL_GetClientAuthDataHook( |
| 759 filter_, | 760 filter_, |
| 760 NSS_GetClientAuthData, | 761 NSS_GetClientAuthData, |
| 761 static_cast<void*>(client_certificate_name_)); | 762 static_cast<void*>(client_certificate_name_)); |
| 762 if (status != SECSuccess) { | 763 if (status != SECSuccess) { |
| 763 ThrowPRException("TlsException", | 764 ThrowPRException("TlsException", |
| 764 "Failed SSL_GetClientAuthDataHook call"); | 765 "Failed SSL_GetClientAuthDataHook call"); |
| 765 } | 766 } |
| 766 } | 767 } |
| 767 } | 768 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 941 // Return a send port for the service port. | 942 // Return a send port for the service port. |
| 942 Dart_Handle send_port = Dart_NewSendPort(service_port); | 943 Dart_Handle send_port = Dart_NewSendPort(service_port); |
| 943 Dart_SetReturnValue(args, send_port); | 944 Dart_SetReturnValue(args, send_port); |
| 944 } | 945 } |
| 945 Dart_ExitScope(); | 946 Dart_ExitScope(); |
| 946 } | 947 } |
| 947 | 948 |
| 948 | 949 |
| 949 } // namespace bin | 950 } // namespace bin |
| 950 } // namespace dart | 951 } // namespace dart |
| OLD | NEW |