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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 | 43 |
| 44 // Forward declaration. | 44 // Forward declaration. |
| 45 static void ProcessFilter(Dart_Port dest_port_id, | 45 static void ProcessFilter(Dart_Port dest_port_id, |
| 46 Dart_Port reply_port_id, | 46 Dart_Port reply_port_id, |
| 47 Dart_CObject* message); | 47 Dart_CObject* message); |
| 48 | 48 |
| 49 NativeService SSLFilter::filter_service_("FilterService", ProcessFilter, 16); | 49 NativeService SSLFilter::filter_service_("FilterService", ProcessFilter, 16); |
| 50 | 50 |
| 51 static const int kSSLFilterNativeFieldIndex = 0; | 51 static const int kSSLFilterNativeFieldIndex = 0; |
| 52 | 52 |
| 53 | |
| 54 /* Handle an error reported from the NSS library. */ | |
| 55 static void ThrowPRException(const char* exception_type, | |
| 56 const char* message, | |
| 57 bool free_message = false) { | |
| 58 PRErrorCode error_code = PR_GetError(); | |
| 59 const char* error_message = PR_ErrorToString(error_code, PR_LANGUAGE_EN); | |
| 60 OSError os_error_struct(error_code, error_message, OSError::kNSS); | |
| 61 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct); | |
| 62 Dart_Handle exception = | |
| 63 DartUtils::NewDartIOException(exception_type, message, os_error); | |
| 64 if (free_message) { | |
| 65 free(const_cast<char*>(message)); | |
| 66 } | |
| 67 Dart_ThrowException(exception); | |
| 68 } | |
| 69 | |
| 70 | |
| 71 static void ThrowCertificateException(const char* format, | |
|
Søren Gjesse
2013/06/25 13:17:38
When passing a format string you should consider a
| |
| 72 const char* certificate_name) { | |
| 73 int length = strlen(certificate_name); | |
| 74 length += strlen(format); | |
| 75 char* message = reinterpret_cast<char*>(malloc(length + 1)); | |
| 76 if (message == NULL) { | |
| 77 FATAL("Out of memory formatting CertificateException for throwing"); | |
| 78 } | |
| 79 snprintf(message, length + 1, format, certificate_name); | |
| 80 message[length] = '\0'; | |
| 81 ThrowPRException("CertificateException", message, true); | |
| 82 } | |
| 83 | |
| 84 | |
| 53 static SSLFilter* GetFilter(Dart_NativeArguments args) { | 85 static SSLFilter* GetFilter(Dart_NativeArguments args) { |
| 54 SSLFilter* filter; | 86 SSLFilter* filter; |
| 55 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 87 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| 56 ASSERT(Dart_IsInstance(dart_this)); | 88 ASSERT(Dart_IsInstance(dart_this)); |
| 57 ThrowIfError(Dart_GetNativeInstanceField( | 89 ThrowIfError(Dart_GetNativeInstanceField( |
| 58 dart_this, | 90 dart_this, |
| 59 kSSLFilterNativeFieldIndex, | 91 kSSLFilterNativeFieldIndex, |
| 60 reinterpret_cast<intptr_t*>(&filter))); | 92 reinterpret_cast<intptr_t*>(&filter))); |
| 61 return filter; | 93 return filter; |
| 62 } | 94 } |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 | 324 |
| 293 | 325 |
| 294 void SSLFilter::ProcessAllBuffers(int starts[kNumBuffers], | 326 void SSLFilter::ProcessAllBuffers(int starts[kNumBuffers], |
| 295 int ends[kNumBuffers], | 327 int ends[kNumBuffers], |
| 296 bool in_handshake) { | 328 bool in_handshake) { |
| 297 for (int i = 0; i < kNumBuffers; ++i) { | 329 for (int i = 0; i < kNumBuffers; ++i) { |
| 298 if (in_handshake && (i == kReadPlaintext || i == kWritePlaintext)) continue; | 330 if (in_handshake && (i == kReadPlaintext || i == kWritePlaintext)) continue; |
| 299 int start = starts[i]; | 331 int start = starts[i]; |
| 300 int end = ends[i]; | 332 int end = ends[i]; |
| 301 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; | 333 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; |
| 334 if (start < 0 || end < 0 || start >= size || end >= size) { | |
| 335 FATAL("Out-of-bounds internal buffer access in dart:io SecureSocket"); | |
| 336 } | |
| 302 switch (i) { | 337 switch (i) { |
| 303 case kReadPlaintext: | 338 case kReadPlaintext: |
| 304 case kWriteEncrypted: | 339 case kWriteEncrypted: |
| 305 // Write data to the circular buffer's free space. If the buffer | 340 // Write data to the circular buffer's free space. If the buffer |
| 306 // is full, neither if statement is executed and nothing happens. | 341 // is full, neither if statement is executed and nothing happens. |
| 307 if (start <= end) { | 342 if (start <= end) { |
| 308 // If the free space may be split into two segments, | 343 // If the free space may be split into two segments, |
| 309 // then the first is [end, size), unless start == 0. | 344 // then the first is [end, size), unless start == 0. |
| 310 // Then, since the last free byte is at position start - 2, | 345 // Then, since the last free byte is at position start - 2, |
| 311 // the interval is [end, size - 1). | 346 // the interval is [end, size - 1). |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 } | 397 } |
| 363 } | 398 } |
| 364 | 399 |
| 365 | 400 |
| 366 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) { | 401 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) { |
| 367 PRTime start_validity; | 402 PRTime start_validity; |
| 368 PRTime end_validity; | 403 PRTime end_validity; |
| 369 SECStatus status = | 404 SECStatus status = |
| 370 CERT_GetCertTimes(certificate, &start_validity, &end_validity); | 405 CERT_GetCertTimes(certificate, &start_validity, &end_validity); |
| 371 if (status != SECSuccess) { | 406 if (status != SECSuccess) { |
| 372 ThrowPRException("Cannot get validity times from certificate"); | 407 ThrowPRException("CertificateException", |
| 408 "Cannot get validity times from certificate"); | |
| 373 } | 409 } |
| 374 int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC; | 410 int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC; |
| 375 int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC; | 411 int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC; |
| 376 Dart_Handle subject_name_object = | 412 Dart_Handle subject_name_object = |
| 377 DartUtils::NewString(certificate->subjectName); | 413 DartUtils::NewString(certificate->subjectName); |
| 378 Dart_Handle issuer_name_object = | 414 Dart_Handle issuer_name_object = |
| 379 DartUtils::NewString(certificate->issuerName); | 415 DartUtils::NewString(certificate->issuerName); |
| 380 Dart_Handle start_epoch_ms_int = Dart_NewInteger(start_epoch_ms); | 416 Dart_Handle start_epoch_ms_int = Dart_NewInteger(start_epoch_ms); |
| 381 Dart_Handle end_epoch_ms_int = Dart_NewInteger(end_epoch_ms); | 417 Dart_Handle end_epoch_ms_int = Dart_NewInteger(end_epoch_ms); |
| 382 | 418 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 Dart_Handle secure_filter_impl_type = | 462 Dart_Handle secure_filter_impl_type = |
| 427 Dart_InstanceGetType(dart_this); | 463 Dart_InstanceGetType(dart_this); |
| 428 Dart_Handle dart_buffer_size = ThrowIfError( | 464 Dart_Handle dart_buffer_size = ThrowIfError( |
| 429 Dart_GetField(secure_filter_impl_type, DartUtils::NewString("SIZE"))); | 465 Dart_GetField(secure_filter_impl_type, DartUtils::NewString("SIZE"))); |
| 430 int64_t buffer_size = DartUtils::GetIntegerValue(dart_buffer_size); | 466 int64_t buffer_size = DartUtils::GetIntegerValue(dart_buffer_size); |
| 431 Dart_Handle dart_encrypted_buffer_size = ThrowIfError( | 467 Dart_Handle dart_encrypted_buffer_size = ThrowIfError( |
| 432 Dart_GetField(secure_filter_impl_type, | 468 Dart_GetField(secure_filter_impl_type, |
| 433 DartUtils::NewString("ENCRYPTED_SIZE"))); | 469 DartUtils::NewString("ENCRYPTED_SIZE"))); |
| 434 int64_t encrypted_buffer_size = | 470 int64_t encrypted_buffer_size = |
| 435 DartUtils::GetIntegerValue(dart_encrypted_buffer_size); | 471 DartUtils::GetIntegerValue(dart_encrypted_buffer_size); |
| 436 if (buffer_size <= 0 || buffer_size > 1024 * 1024) { | 472 if (buffer_size <= 0 || buffer_size > 1 * MB) { |
| 437 Dart_ThrowException( | 473 FATAL("Invalid buffer size in _ExternalBuffer"); |
| 438 DartUtils::NewString("Invalid buffer size in _ExternalBuffer")); | |
| 439 } | 474 } |
| 440 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1024 * 1024) { | 475 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 * MB) { |
| 441 Dart_ThrowException(DartUtils::NewString( | 476 FATAL("Invalid encrypted buffer size in _ExternalBuffer"); |
| 442 "Invalid encrypted buffer size in _ExternalBuffer")); | |
| 443 } | 477 } |
| 444 buffer_size_ = static_cast<int>(buffer_size); | 478 buffer_size_ = static_cast<int>(buffer_size); |
| 445 encrypted_buffer_size_ = static_cast<int>(encrypted_buffer_size); | 479 encrypted_buffer_size_ = static_cast<int>(encrypted_buffer_size); |
| 446 | 480 |
| 447 | 481 |
| 448 Dart_Handle data_identifier = DartUtils::NewString("data"); | 482 Dart_Handle data_identifier = DartUtils::NewString("data"); |
| 449 for (int i = 0; i < kNumBuffers; ++i) { | 483 for (int i = 0; i < kNumBuffers; ++i) { |
| 450 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; | 484 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; |
| 451 dart_buffer_objects_[i] = | 485 dart_buffer_objects_[i] = |
| 452 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i)); | 486 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i)); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 MutexLocker locker(&mutex_); | 530 MutexLocker locker(&mutex_); |
| 497 SECStatus status; | 531 SECStatus status; |
| 498 if (!library_initialized_) { | 532 if (!library_initialized_) { |
| 499 password_ = strdup(password); // This one copy persists until Dart exits. | 533 password_ = strdup(password); // This one copy persists until Dart exits. |
| 500 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); | 534 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); |
| 501 // TODO(whesse): Verify there are no UTF-8 issues here. | 535 // TODO(whesse): Verify there are no UTF-8 issues here. |
| 502 if (certificate_database == NULL || certificate_database[0] == '\0') { | 536 if (certificate_database == NULL || certificate_database[0] == '\0') { |
| 503 status = NSS_NoDB_Init(NULL); | 537 status = NSS_NoDB_Init(NULL); |
| 504 if (status != SECSuccess) { | 538 if (status != SECSuccess) { |
| 505 mutex_.Unlock(); // MutexLocker destructor not called when throwing. | 539 mutex_.Unlock(); // MutexLocker destructor not called when throwing. |
| 506 ThrowPRException("Failed NSS_NoDB_Init call."); | 540 ThrowPRException("TlsException", |
| 541 "Failed NSS_NoDB_Init call."); | |
| 507 } | 542 } |
| 508 if (use_builtin_root_certificates) { | 543 if (use_builtin_root_certificates) { |
| 509 SECMODModule* module = SECMOD_LoadUserModule( | 544 SECMODModule* module = SECMOD_LoadUserModule( |
| 510 const_cast<char*>(builtin_roots_module), NULL, PR_FALSE); | 545 const_cast<char*>(builtin_roots_module), NULL, PR_FALSE); |
| 511 if (!module) { | 546 if (!module) { |
| 512 mutex_.Unlock(); // MutexLocker destructor not called when throwing. | 547 mutex_.Unlock(); // MutexLocker destructor not called when throwing. |
| 513 ThrowPRException("Failed to load builtin root certificates."); | 548 ThrowPRException("TlsException", |
| 549 "Failed to load builtin root certificates."); | |
| 514 } | 550 } |
| 515 } | 551 } |
| 516 } else { | 552 } else { |
| 517 PRUint32 init_flags = NSS_INIT_READONLY; | 553 PRUint32 init_flags = NSS_INIT_READONLY; |
| 518 if (!use_builtin_root_certificates) { | 554 if (!use_builtin_root_certificates) { |
| 519 init_flags |= NSS_INIT_NOMODDB; | 555 init_flags |= NSS_INIT_NOMODDB; |
| 520 } | 556 } |
| 521 status = NSS_Initialize(certificate_database, | 557 status = NSS_Initialize(certificate_database, |
| 522 "", | 558 "", |
| 523 "", | 559 "", |
| 524 SECMOD_DB, | 560 SECMOD_DB, |
| 525 init_flags); | 561 init_flags); |
| 526 if (status != SECSuccess) { | 562 if (status != SECSuccess) { |
| 527 mutex_.Unlock(); // MutexLocker destructor not called when throwing. | 563 mutex_.Unlock(); // MutexLocker destructor not called when throwing. |
| 528 ThrowPRException("Failed NSS_Init call."); | 564 ThrowPRException("TlsException", |
| 565 "Failed NSS_Init call."); | |
| 529 } | 566 } |
| 530 } | 567 } |
| 531 library_initialized_ = true; | 568 library_initialized_ = true; |
| 532 | 569 |
| 533 status = NSS_SetDomesticPolicy(); | 570 status = NSS_SetDomesticPolicy(); |
| 534 if (status != SECSuccess) { | 571 if (status != SECSuccess) { |
| 535 mutex_.Unlock(); // MutexLocker destructor not called when throwing. | 572 mutex_.Unlock(); // MutexLocker destructor not called when throwing. |
| 536 ThrowPRException("Failed NSS_SetDomesticPolicy call."); | 573 ThrowPRException("TlsException", |
| 574 "Failed NSS_SetDomesticPolicy call."); | |
| 537 } | 575 } |
| 538 // Enable TLS, as well as SSL3 and SSL2. | 576 // Enable TLS, as well as SSL3 and SSL2. |
| 539 status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE); | 577 status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE); |
| 540 if (status != SECSuccess) { | 578 if (status != SECSuccess) { |
| 541 mutex_.Unlock(); // MutexLocker destructor not called when throwing. | 579 mutex_.Unlock(); // MutexLocker destructor not called when throwing. |
| 542 ThrowPRException("Failed SSL_OptionSetDefault enable TLS call."); | 580 ThrowPRException("TlsException", |
| 581 "Failed SSL_OptionSetDefault enable TLS call."); | |
| 543 } | 582 } |
| 544 status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL); | 583 status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL); |
| 545 if (status != SECSuccess) { | 584 if (status != SECSuccess) { |
| 546 mutex_.Unlock(); // MutexLocker destructor not called when throwing. | 585 mutex_.Unlock(); // MutexLocker destructor not called when throwing. |
| 547 ThrowPRException("Failed SSL_ConfigServerSessionIDCache call."); | 586 ThrowPRException("TlsException", |
| 587 "Failed SSL_ConfigServerSessionIDCache call."); | |
| 548 } | 588 } |
| 549 | 589 |
| 550 } else if (report_duplicate_initialization) { | 590 } else if (report_duplicate_initialization) { |
| 551 mutex_.Unlock(); // MutexLocker destructor not called when throwing. | 591 mutex_.Unlock(); // MutexLocker destructor not called when throwing. |
| 552 ThrowException("Called SSLFilter::InitializeLibrary more than once"); | 592 // Like ThrowPRException, without adding an OSError. |
| 593 Dart_ThrowException(DartUtils::NewDartIOException("TlsException", | |
| 594 "Called SecureSocket.initialize more than once", | |
| 595 Dart_Null())); | |
| 553 } | 596 } |
| 554 } | 597 } |
| 555 | 598 |
| 556 | 599 |
| 557 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { | 600 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { |
| 558 if (!retry) { | 601 if (!retry) { |
| 559 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. | 602 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. |
| 560 } | 603 } |
| 561 return NULL; | 604 return NULL; |
| 562 } | 605 } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 589 void SSLFilter::Connect(const char* host_name, | 632 void SSLFilter::Connect(const char* host_name, |
| 590 RawAddr* raw_addr, | 633 RawAddr* raw_addr, |
| 591 int port, | 634 int port, |
| 592 bool is_server, | 635 bool is_server, |
| 593 const char* certificate_name, | 636 const char* certificate_name, |
| 594 bool request_client_certificate, | 637 bool request_client_certificate, |
| 595 bool require_client_certificate, | 638 bool require_client_certificate, |
| 596 bool send_client_certificate) { | 639 bool send_client_certificate) { |
| 597 is_server_ = is_server; | 640 is_server_ = is_server; |
| 598 if (in_handshake_) { | 641 if (in_handshake_) { |
| 599 ThrowException("Connect called while already in handshake state."); | 642 FATAL("Connect called twice on the same _SecureFilter."); |
| 600 } | 643 } |
| 601 | 644 |
| 602 if (!is_server && certificate_name != NULL) { | 645 if (!is_server && certificate_name != NULL) { |
| 603 client_certificate_name_ = strdup(certificate_name); | 646 client_certificate_name_ = strdup(certificate_name); |
| 604 } | 647 } |
| 605 | 648 |
| 606 filter_ = SSL_ImportFD(NULL, filter_); | 649 filter_ = SSL_ImportFD(NULL, filter_); |
| 607 if (filter_ == NULL) { | 650 if (filter_ == NULL) { |
| 608 ThrowPRException("Failed SSL_ImportFD call"); | 651 ThrowPRException("TlsException", "Failed SSL_ImportFD call"); |
| 609 } | 652 } |
| 610 | 653 |
| 611 SSLVersionRange vrange; | 654 SSLVersionRange vrange; |
| 612 vrange.min = SSL_LIBRARY_VERSION_3_0; | 655 vrange.min = SSL_LIBRARY_VERSION_3_0; |
| 613 vrange.max = SSL_LIBRARY_VERSION_TLS_1_1; | 656 vrange.max = SSL_LIBRARY_VERSION_TLS_1_1; |
| 614 SSL_VersionRangeSet(filter_, &vrange); | 657 SSL_VersionRangeSet(filter_, &vrange); |
| 615 | 658 |
| 616 SECStatus status; | 659 SECStatus status; |
| 617 if (is_server) { | 660 if (is_server) { |
| 618 PK11_SetPasswordFunc(PasswordCallback); | 661 PK11_SetPasswordFunc(PasswordCallback); |
| 619 | 662 |
| 620 CERTCertificate* certificate = NULL; | 663 CERTCertificate* certificate = NULL; |
| 621 if (strstr(certificate_name, "CN=") != NULL) { | 664 if (strstr(certificate_name, "CN=") != NULL) { |
| 622 // Look up certificate using the distinguished name (DN) certificate_name. | 665 // Look up certificate using the distinguished name (DN) certificate_name. |
| 623 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB(); | 666 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB(); |
| 624 if (certificate_database == NULL) { | 667 if (certificate_database == NULL) { |
| 625 ThrowPRException("Certificate database cannot be loaded"); | 668 ThrowPRException("CertificateException", |
| 669 "Certificate database cannot be loaded"); | |
| 626 } | 670 } |
| 627 certificate = CERT_FindCertByNameString(certificate_database, | 671 certificate = CERT_FindCertByNameString(certificate_database, |
| 628 const_cast<char*>(certificate_name)); | 672 const_cast<char*>(certificate_name)); |
| 629 if (certificate == NULL) { | 673 if (certificate == NULL) { |
| 630 ThrowPRException( | 674 ThrowCertificateException( |
| 631 "Cannot find server certificate by distinguished name"); | 675 "Cannot find server certificate by distinguished name: %s", |
| 676 certificate_name); | |
| 632 } | 677 } |
| 633 } else { | 678 } else { |
| 634 // Look up certificate using the nickname certificate_name. | 679 // Look up certificate using the nickname certificate_name. |
| 635 certificate = PK11_FindCertFromNickname( | 680 certificate = PK11_FindCertFromNickname( |
| 636 const_cast<char*>(certificate_name), | 681 const_cast<char*>(certificate_name), |
| 637 static_cast<void*>(const_cast<char*>(password_))); | 682 static_cast<void*>(const_cast<char*>(password_))); |
| 638 if (certificate == NULL) { | 683 if (certificate == NULL) { |
| 639 ThrowPRException("Cannot find server certificate by nickname"); | 684 ThrowCertificateException( |
| 685 "Cannot find server certificate by nickname: %s", | |
| 686 certificate_name); | |
| 640 } | 687 } |
| 641 } | 688 } |
| 642 SECKEYPrivateKey* key = PK11_FindKeyByAnyCert( | 689 SECKEYPrivateKey* key = PK11_FindKeyByAnyCert( |
| 643 certificate, | 690 certificate, |
| 644 static_cast<void*>(const_cast<char*>(password_))); | 691 static_cast<void*>(const_cast<char*>(password_))); |
| 645 if (key == NULL) { | 692 if (key == NULL) { |
| 646 CERT_DestroyCertificate(certificate); | 693 CERT_DestroyCertificate(certificate); |
| 647 if (PR_GetError() == -8177) { | 694 if (PR_GetError() == -8177) { |
| 648 ThrowPRException("Certificate database password incorrect"); | 695 ThrowPRException("CertificateException", |
| 696 "Certificate database password incorrect"); | |
| 649 } else { | 697 } else { |
| 650 ThrowPRException("Failed PK11_FindKeyByAnyCert call." | 698 ThrowCertificateException( |
| 651 " Cannot find private key for certificate"); | 699 "Cannot find private key for certificate %s", |
| 700 certificate_name); | |
| 652 } | 701 } |
| 653 } | 702 } |
| 654 // kt_rsa (key type RSA) is an enum constant from the NSS libraries. | 703 // kt_rsa (key type RSA) is an enum constant from the NSS libraries. |
| 655 // TODO(whesse): Allow different key types. | 704 // TODO(whesse): Allow different key types. |
| 656 status = SSL_ConfigSecureServer(filter_, certificate, key, kt_rsa); | 705 status = SSL_ConfigSecureServer(filter_, certificate, key, kt_rsa); |
| 657 CERT_DestroyCertificate(certificate); | 706 CERT_DestroyCertificate(certificate); |
| 658 SECKEY_DestroyPrivateKey(key); | 707 SECKEY_DestroyPrivateKey(key); |
| 659 if (status != SECSuccess) { | 708 if (status != SECSuccess) { |
| 660 ThrowPRException("Failed SSL_ConfigSecureServer call"); | 709 ThrowCertificateException( |
| 710 "Failed SSL_ConfigSecureServer call with certificate %s", | |
| 711 certificate_name); | |
| 661 } | 712 } |
| 662 | 713 |
| 663 if (request_client_certificate) { | 714 if (request_client_certificate) { |
| 664 status = SSL_OptionSet(filter_, SSL_REQUEST_CERTIFICATE, PR_TRUE); | 715 status = SSL_OptionSet(filter_, SSL_REQUEST_CERTIFICATE, PR_TRUE); |
| 665 if (status != SECSuccess) { | 716 if (status != SECSuccess) { |
| 666 ThrowPRException("Failed SSL_OptionSet(REQUEST_CERTIFICATE) call"); | 717 ThrowPRException("TlsException", |
| 718 "Failed SSL_OptionSet(REQUEST_CERTIFICATE) call"); | |
| 667 } | 719 } |
| 668 PRBool require_cert = require_client_certificate ? PR_TRUE : PR_FALSE; | 720 PRBool require_cert = require_client_certificate ? PR_TRUE : PR_FALSE; |
| 669 status = SSL_OptionSet(filter_, SSL_REQUIRE_CERTIFICATE, require_cert); | 721 status = SSL_OptionSet(filter_, SSL_REQUIRE_CERTIFICATE, require_cert); |
| 670 if (status != SECSuccess) { | 722 if (status != SECSuccess) { |
| 671 ThrowPRException("Failed SSL_OptionSet(REQUIRE_CERTIFICATE) call"); | 723 ThrowPRException("TlsException", |
| 724 "Failed SSL_OptionSet(REQUIRE_CERTIFICATE) call"); | |
| 672 } | 725 } |
| 673 } | 726 } |
| 674 } else { // Client. | 727 } else { // Client. |
| 675 if (SSL_SetURL(filter_, host_name) == -1) { | 728 if (SSL_SetURL(filter_, host_name) == -1) { |
| 676 ThrowPRException("Failed SetURL call"); | 729 ThrowPRException("TlsException", |
| 730 "Failed SetURL call"); | |
| 677 } | 731 } |
| 678 | 732 |
| 679 // This disables the SSL session cache for client connections. | 733 // This disables the SSL session cache for client connections. |
| 680 // This resolves issue 7208, but degrades performance. | 734 // This resolves issue 7208, but degrades performance. |
| 681 // TODO(7230): Reenable session cache, without breaking client connections. | 735 // TODO(7230): Reenable session cache, without breaking client connections. |
| 682 status = SSL_OptionSet(filter_, SSL_NO_CACHE, PR_TRUE); | 736 status = SSL_OptionSet(filter_, SSL_NO_CACHE, PR_TRUE); |
| 683 if (status != SECSuccess) { | 737 if (status != SECSuccess) { |
| 684 ThrowPRException("Failed SSL_OptionSet(NO_CACHE) call"); | 738 ThrowPRException("TlsException", |
| 739 "Failed SSL_OptionSet(NO_CACHE) call"); | |
| 685 } | 740 } |
| 686 | 741 |
| 687 if (send_client_certificate) { | 742 if (send_client_certificate) { |
| 688 status = SSL_GetClientAuthDataHook( | 743 status = SSL_GetClientAuthDataHook( |
| 689 filter_, | 744 filter_, |
| 690 NSS_GetClientAuthData, | 745 NSS_GetClientAuthData, |
| 691 static_cast<void*>(client_certificate_name_)); | 746 static_cast<void*>(client_certificate_name_)); |
| 692 if (status != SECSuccess) { | 747 if (status != SECSuccess) { |
| 693 ThrowPRException("Failed SSL_GetClientAuthDataHook call"); | 748 ThrowPRException("TlsException", |
| 749 "Failed SSL_GetClientAuthDataHook call"); | |
| 694 } | 750 } |
| 695 } | 751 } |
| 696 } | 752 } |
| 697 | 753 |
| 698 // Install bad certificate callback, and pass 'this' to it if it is called. | 754 // Install bad certificate callback, and pass 'this' to it if it is called. |
| 699 status = SSL_BadCertHook(filter_, | 755 status = SSL_BadCertHook(filter_, |
| 700 BadCertificateCallback, | 756 BadCertificateCallback, |
| 701 static_cast<void*>(this)); | 757 static_cast<void*>(this)); |
| 702 | 758 |
| 703 PRBool as_server = is_server ? PR_TRUE : PR_FALSE; | 759 PRBool as_server = is_server ? PR_TRUE : PR_FALSE; |
| 704 status = SSL_ResetHandshake(filter_, as_server); | 760 status = SSL_ResetHandshake(filter_, as_server); |
| 705 if (status != SECSuccess) { | 761 if (status != SECSuccess) { |
| 706 ThrowPRException("Failed SSL_ResetHandshake call"); | 762 ThrowPRException("TlsException", |
| 763 "Failed SSL_ResetHandshake call"); | |
| 707 } | 764 } |
| 708 | 765 |
| 709 // Set the peer address from the address passed. The DNS has already | 766 // Set the peer address from the address passed. The DNS has already |
| 710 // been done in Dart code, so just use that address. This relies on | 767 // been done in Dart code, so just use that address. This relies on |
| 711 // following about PRNetAddr: "The raw member of the union is | 768 // following about PRNetAddr: "The raw member of the union is |
| 712 // equivalent to struct sockaddr", which is stated in the NSS | 769 // equivalent to struct sockaddr", which is stated in the NSS |
| 713 // documentation. | 770 // documentation. |
| 714 PRNetAddr peername; | 771 PRNetAddr peername; |
| 715 memset(&peername, 0, sizeof(peername)); | 772 memset(&peername, 0, sizeof(peername)); |
| 716 intptr_t len = SocketAddress::GetAddrLength(raw_addr); | 773 intptr_t len = SocketAddress::GetAddrLength(raw_addr); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 736 in_handshake_ = false; | 793 in_handshake_ = false; |
| 737 } | 794 } |
| 738 } else { | 795 } else { |
| 739 PRErrorCode error = PR_GetError(); | 796 PRErrorCode error = PR_GetError(); |
| 740 if (error == PR_WOULD_BLOCK_ERROR) { | 797 if (error == PR_WOULD_BLOCK_ERROR) { |
| 741 if (!in_handshake_) { | 798 if (!in_handshake_) { |
| 742 in_handshake_ = true; | 799 in_handshake_ = true; |
| 743 } | 800 } |
| 744 } else { | 801 } else { |
| 745 if (is_server_) { | 802 if (is_server_) { |
| 746 ThrowPRException("Unexpected handshake error in server"); | 803 ThrowPRException("HandshakeException", |
| 804 "Handshake error in server"); | |
| 747 } else { | 805 } else { |
| 748 ThrowPRException("Unexpected handshake error in client"); | 806 ThrowPRException("HandshakeException", |
| 807 "Handshake error in client"); | |
| 749 } | 808 } |
| 750 } | 809 } |
| 751 } | 810 } |
| 752 } | 811 } |
| 753 | 812 |
| 754 | 813 |
| 755 void SSLFilter::Destroy() { | 814 void SSLFilter::Destroy() { |
| 756 for (int i = 0; i < kNumBuffers; ++i) { | 815 for (int i = 0; i < kNumBuffers; ++i) { |
| 757 Dart_DeletePersistentHandle(dart_buffer_objects_[i]); | 816 Dart_DeletePersistentHandle(dart_buffer_objects_[i]); |
| 758 delete[] buffers_[i]; | 817 delete[] buffers_[i]; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 869 // Return a send port for the service port. | 928 // Return a send port for the service port. |
| 870 Dart_Handle send_port = Dart_NewSendPort(service_port); | 929 Dart_Handle send_port = Dart_NewSendPort(service_port); |
| 871 Dart_SetReturnValue(args, send_port); | 930 Dart_SetReturnValue(args, send_port); |
| 872 } | 931 } |
| 873 Dart_ExitScope(); | 932 Dart_ExitScope(); |
| 874 } | 933 } |
| 875 | 934 |
| 876 | 935 |
| 877 } // namespace bin | 936 } // namespace bin |
| 878 } // namespace dart | 937 } // namespace dart |
| OLD | NEW |