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 |