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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 Dart_Handle port_object = ThrowIfError(Dart_GetNativeArgument(args, 3)); | 114 Dart_Handle port_object = ThrowIfError(Dart_GetNativeArgument(args, 3)); |
| 115 bool is_server = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); | 115 bool is_server = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); |
| 116 Dart_Handle certificate_name_object = | 116 Dart_Handle certificate_name_object = |
| 117 ThrowIfError(Dart_GetNativeArgument(args, 5)); | 117 ThrowIfError(Dart_GetNativeArgument(args, 5)); |
| 118 bool request_client_certificate = | 118 bool request_client_certificate = |
| 119 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 6)); | 119 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 6)); |
| 120 bool require_client_certificate = | 120 bool require_client_certificate = |
| 121 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 7)); | 121 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 7)); |
| 122 bool send_client_certificate = | 122 bool send_client_certificate = |
| 123 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 8)); | 123 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 8)); |
| 124 Dart_Handle client_protocols_handle = | |
| 125 ThrowIfError(Dart_GetNativeArgument(args, 9)); | |
| 124 | 126 |
| 125 const char* host_name = NULL; | 127 const char* host_name = NULL; |
| 126 // TODO(whesse): Is truncating a Dart string containing \0 what we want? | 128 // TODO(whesse): Is truncating a Dart string containing \0 what we want? |
| 127 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); | 129 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); |
| 128 | 130 |
| 129 RawAddr raw_addr; | 131 RawAddr raw_addr; |
| 130 SocketAddress::GetSockAddr(host_sockaddr_storage_object, &raw_addr); | 132 SocketAddress::GetSockAddr(host_sockaddr_storage_object, &raw_addr); |
| 131 | 133 |
| 132 int64_t port; | 134 int64_t port; |
| 133 if (!DartUtils::GetInt64Value(port_object, &port)) { | 135 if (!DartUtils::GetInt64Value(port_object, &port)) { |
| 134 FATAL("The range of port_object was checked in Dart - it cannot fail here"); | 136 FATAL("The range of port_object was checked in Dart - it cannot fail here"); |
| 135 } | 137 } |
| 136 | 138 |
| 137 const char* certificate_name = NULL; | 139 const char* certificate_name = NULL; |
| 138 if (Dart_IsString(certificate_name_object)) { | 140 if (Dart_IsString(certificate_name_object)) { |
| 139 ThrowIfError(Dart_StringToCString(certificate_name_object, | 141 ThrowIfError(Dart_StringToCString(certificate_name_object, |
| 140 &certificate_name)); | 142 &certificate_name)); |
| 141 } | 143 } |
| 142 // If this is a server connection, it must have a certificate to connect with. | 144 // If this is a server connection, it must have a certificate to connect with. |
| 143 ASSERT(!is_server || certificate_name != NULL); | 145 ASSERT(!is_server || certificate_name != NULL); |
| 144 | 146 |
| 147 | |
| 148 | |
| 149 Dart_TypedData_Type protocols_type; | |
| 150 uint8_t* protocol_string = NULL; | |
| 151 intptr_t protocol_string_len = 0; | |
| 152 | |
| 153 ASSERT(!Dart_IsNull(client_protocols_handle)); | |
| 154 Dart_Handle result = Dart_TypedDataAcquireData( | |
| 155 client_protocols_handle, | |
| 156 &protocols_type, | |
| 157 reinterpret_cast<void**>(&protocol_string), | |
| 158 &protocol_string_len); | |
| 159 if (Dart_IsError(result)) { | |
| 160 Dart_PropagateError(result); | |
| 161 } | |
| 162 | |
| 163 if (protocols_type != Dart_TypedData_kUint8) { | |
| 164 Dart_TypedDataReleaseData(client_protocols_handle); | |
| 165 Dart_PropagateError( | |
| 166 Dart_NewApiError("Unexpected type for protocols")); | |
| 167 } | |
| 168 | |
| 145 GetFilter(args)->Connect(host_name, | 169 GetFilter(args)->Connect(host_name, |
| 146 &raw_addr, | 170 &raw_addr, |
| 147 static_cast<int>(port), | 171 static_cast<int>(port), |
| 148 is_server, | 172 is_server, |
| 149 certificate_name, | 173 certificate_name, |
| 150 request_client_certificate, | 174 request_client_certificate, |
| 151 require_client_certificate, | 175 require_client_certificate, |
| 152 send_client_certificate); | 176 send_client_certificate, |
| 177 protocol_string, | |
| 178 protocol_string_len); | |
|
kustermann
2014/10/03 13:25:26
If GetFilter(args)->Connect() fails, can it unwind
Søren Gjesse
2014/10/03 15:47:04
As discussed off-line you need to release it befor
kustermann
2014/11/07 16:20:03
Instead of making more calls into the VM & copying
| |
| 179 Dart_TypedDataReleaseData(client_protocols_handle); | |
| 153 } | 180 } |
| 154 | 181 |
| 155 | 182 |
| 156 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { | 183 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { |
| 157 SSLFilter* filter = GetFilter(args); | 184 SSLFilter* filter = GetFilter(args); |
| 158 SetFilter(args, NULL); | 185 SetFilter(args, NULL); |
| 159 filter->Destroy(); | 186 filter->Destroy(); |
| 160 delete filter; | 187 delete filter; |
| 161 } | 188 } |
| 162 | 189 |
| 163 | 190 |
| 164 void FUNCTION_NAME(SecureSocket_Handshake)(Dart_NativeArguments args) { | 191 void FUNCTION_NAME(SecureSocket_Handshake)(Dart_NativeArguments args) { |
| 165 GetFilter(args)->Handshake(); | 192 GetFilter(args)->Handshake(); |
| 166 } | 193 } |
| 167 | 194 |
| 168 | 195 |
| 196 void FUNCTION_NAME(SecureSocket_GetSelectedProtocol)( | |
| 197 Dart_NativeArguments args) { | |
| 198 GetFilter(args)->GetSelectedProtocol(args); | |
| 199 } | |
| 200 | |
| 201 | |
| 169 void FUNCTION_NAME(SecureSocket_Renegotiate)(Dart_NativeArguments args) { | 202 void FUNCTION_NAME(SecureSocket_Renegotiate)(Dart_NativeArguments args) { |
| 170 bool use_session_cache = | 203 bool use_session_cache = |
| 171 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1)); | 204 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1)); |
| 172 bool request_client_certificate = | 205 bool request_client_certificate = |
| 173 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 2)); | 206 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 2)); |
| 174 bool require_client_certificate = | 207 bool require_client_certificate = |
| 175 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); | 208 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); |
| 176 GetFilter(args)->Renegotiate(use_session_cache, | 209 GetFilter(args)->Renegotiate(use_session_cache, |
| 177 request_client_certificate, | 210 request_client_certificate, |
| 178 require_client_certificate); | 211 require_client_certificate); |
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 651 } | 684 } |
| 652 | 685 |
| 653 | 686 |
| 654 void SSLFilter::Connect(const char* host_name, | 687 void SSLFilter::Connect(const char* host_name, |
| 655 RawAddr* raw_addr, | 688 RawAddr* raw_addr, |
| 656 int port, | 689 int port, |
| 657 bool is_server, | 690 bool is_server, |
| 658 const char* certificate_name, | 691 const char* certificate_name, |
| 659 bool request_client_certificate, | 692 bool request_client_certificate, |
| 660 bool require_client_certificate, | 693 bool require_client_certificate, |
| 661 bool send_client_certificate) { | 694 bool send_client_certificate, |
| 695 uint8_t *protocols, | |
| 696 intptr_t protocols_len) { | |
| 662 is_server_ = is_server; | 697 is_server_ = is_server; |
| 663 if (in_handshake_) { | 698 if (in_handshake_) { |
| 664 FATAL("Connect called twice on the same _SecureFilter."); | 699 FATAL("Connect called twice on the same _SecureFilter."); |
| 665 } | 700 } |
| 666 | 701 |
| 667 if (!is_server && certificate_name != NULL) { | 702 if (!is_server && certificate_name != NULL) { |
| 668 client_certificate_name_ = strdup(certificate_name); | 703 client_certificate_name_ = strdup(certificate_name); |
| 669 } | 704 } |
| 670 | 705 |
| 671 filter_ = SSL_ImportFD(NULL, filter_); | 706 filter_ = SSL_ImportFD(NULL, filter_); |
| 672 if (filter_ == NULL) { | 707 if (filter_ == NULL) { |
| 673 ThrowPRException("TlsException", "Failed SSL_ImportFD call"); | 708 ThrowPRException("TlsException", "Failed SSL_ImportFD call"); |
| 674 } | 709 } |
| 675 | 710 |
| 711 | |
| 712 SECStatus status; | |
| 713 | |
| 714 if (protocols_len > 0) { | |
| 715 status = SSL_OptionSet(filter_, SSL_ENABLE_ALPN, PR_TRUE); | |
| 716 ASSERT(status == SECSuccess); | |
| 717 | |
| 718 status = SSL_SetNextProtoNego(filter_, protocols, protocols_len); | |
| 719 ASSERT(status == SECSuccess); | |
| 720 } | |
| 721 | |
| 676 SSLVersionRange vrange; | 722 SSLVersionRange vrange; |
| 677 vrange.min = SSL_LIBRARY_VERSION_3_0; | 723 vrange.min = SSL_LIBRARY_VERSION_3_0; |
| 678 vrange.max = SSL_LIBRARY_VERSION_TLS_1_2; | 724 vrange.max = SSL_LIBRARY_VERSION_TLS_1_2; |
| 679 SSL_VersionRangeSet(filter_, &vrange); | 725 SSL_VersionRangeSet(filter_, &vrange); |
| 680 | 726 |
| 681 SECStatus status; | |
| 682 if (is_server) { | 727 if (is_server) { |
| 683 CERTCertificate* certificate = NULL; | 728 CERTCertificate* certificate = NULL; |
| 684 if (strstr(certificate_name, "CN=") != NULL) { | 729 if (strstr(certificate_name, "CN=") != NULL) { |
| 685 // Look up certificate using the distinguished name (DN) certificate_name. | 730 // Look up certificate using the distinguished name (DN) certificate_name. |
| 686 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB(); | 731 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB(); |
| 687 if (certificate_database == NULL) { | 732 if (certificate_database == NULL) { |
| 688 ThrowPRException("CertificateException", | 733 ThrowPRException("CertificateException", |
| 689 "Certificate database cannot be loaded"); | 734 "Certificate database cannot be loaded"); |
| 690 } | 735 } |
| 691 certificate = CERT_FindCertByNameString(certificate_database, | 736 certificate = CERT_FindCertByNameString(certificate_database, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 816 ThrowPRException("HandshakeException", | 861 ThrowPRException("HandshakeException", |
| 817 "Handshake error in server"); | 862 "Handshake error in server"); |
| 818 } else { | 863 } else { |
| 819 ThrowPRException("HandshakeException", | 864 ThrowPRException("HandshakeException", |
| 820 "Handshake error in client"); | 865 "Handshake error in client"); |
| 821 } | 866 } |
| 822 } | 867 } |
| 823 } | 868 } |
| 824 } | 869 } |
| 825 | 870 |
| 871 void SSLFilter::GetSelectedProtocol(Dart_NativeArguments args) { | |
| 872 // Space for the selected protocol. | |
| 873 const intptr_t kBufferSize = 256; | |
| 874 unsigned char buffer[kBufferSize + 1]; | |
| 875 | |
| 876 unsigned int outLength = 0; | |
| 877 SSLNextProtoState outState; | |
| 878 | |
| 879 SECStatus status = SSL_GetNextProto( | |
| 880 filter_, &outState, buffer, &outLength, kBufferSize); | |
| 881 if (status == SECSuccess) { | |
| 882 if (outState == SSL_NEXT_PROTO_SELECTED || | |
| 883 outState == SSL_NEXT_PROTO_NEGOTIATED) { | |
| 884 ASSERT(outLength <= kBufferSize); | |
| 885 buffer[outLength] = '\0'; | |
| 886 Dart_Handle protocol_string = DartUtils::NewString( | |
| 887 reinterpret_cast<const char *>(&buffer[0])); | |
| 888 if (Dart_IsError(protocol_string)) { | |
| 889 ThrowPRException("HandshakeException", | |
| 890 "Protocol selected via ALPN was non-UTF8"); | |
|
Søren Gjesse
2014/10/03 15:47:04
In principle this could also be an OOM i think, or
kustermann
2014/11/07 16:20:02
Rephrased message.
| |
| 891 } else { | |
| 892 Dart_SetReturnValue(args, protocol_string); | |
| 893 } | |
| 894 } else if (outState == SSL_NEXT_PROTO_NO_OVERLAP) { | |
| 895 ThrowPRException("HandshakeException", | |
| 896 "Client and Server could not agree upon a protocol"); | |
| 897 } else if (outState == SSL_NEXT_PROTO_NO_SUPPORT) { | |
| 898 // A value of `null` denotes that the client did not support protocol | |
| 899 // negogiation. | |
| 900 Dart_SetReturnValue(args, Dart_Null()); | |
| 901 } else { | |
| 902 UNREACHABLE(); | |
| 903 } | |
| 904 } else { | |
| 905 ThrowPRException("HandshakeException", | |
| 906 "Could not retrieve selected protocol via ALPN"); | |
| 907 } | |
| 908 } | |
| 909 | |
| 826 | 910 |
| 827 void SSLFilter::Renegotiate(bool use_session_cache, | 911 void SSLFilter::Renegotiate(bool use_session_cache, |
| 828 bool request_client_certificate, | 912 bool request_client_certificate, |
| 829 bool require_client_certificate) { | 913 bool require_client_certificate) { |
| 830 SECStatus status; | 914 SECStatus status; |
| 831 // The SSL_REQUIRE_CERTIFICATE option only takes effect if the | 915 // The SSL_REQUIRE_CERTIFICATE option only takes effect if the |
| 832 // SSL_REQUEST_CERTIFICATE option is also set, so set it. | 916 // SSL_REQUEST_CERTIFICATE option is also set, so set it. |
| 833 request_client_certificate = | 917 request_client_certificate = |
| 834 request_client_certificate || require_client_certificate; | 918 request_client_certificate || require_client_certificate; |
| 835 | 919 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 960 } | 1044 } |
| 961 if (bytes_processed > 0) { | 1045 if (bytes_processed > 0) { |
| 962 memio_PutWriteResult(secret, bytes_processed); | 1046 memio_PutWriteResult(secret, bytes_processed); |
| 963 } | 1047 } |
| 964 } | 1048 } |
| 965 return bytes_processed; | 1049 return bytes_processed; |
| 966 } | 1050 } |
| 967 | 1051 |
| 968 } // namespace bin | 1052 } // namespace bin |
| 969 } // namespace dart | 1053 } // namespace dart |
| OLD | NEW |