| 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/tls_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> |
| 11 #include <string.h> | 11 #include <string.h> |
| 12 | 12 |
| 13 #include <nss.h> | 13 #include <nss.h> |
| 14 #include <pk11pub.h> | 14 #include <pk11pub.h> |
| 15 #include <prerror.h> | 15 #include <prerror.h> |
| 16 #include <prinit.h> | 16 #include <prinit.h> |
| 17 #include <prnetdb.h> | 17 #include <prnetdb.h> |
| 18 #include <ssl.h> | 18 #include <ssl.h> |
| 19 #include <sslproto.h> | 19 #include <sslproto.h> |
| 20 | 20 |
| 21 #include "bin/builtin.h" | 21 #include "bin/builtin.h" |
| 22 #include "bin/dartutils.h" | 22 #include "bin/dartutils.h" |
| 23 #include "bin/net/nss_memio.h" | 23 #include "bin/net/nss_memio.h" |
| 24 #include "bin/thread.h" | 24 #include "bin/thread.h" |
| 25 #include "bin/utils.h" | 25 #include "bin/utils.h" |
| 26 #include "platform/utils.h" | 26 #include "platform/utils.h" |
| 27 | 27 |
| 28 #include "include/dart_api.h" | 28 #include "include/dart_api.h" |
| 29 | 29 |
| 30 bool TlsFilter::library_initialized_ = false; | 30 bool SSLFilter::library_initialized_ = false; |
| 31 dart::Mutex TlsFilter::mutex_; // To protect library initialization. | 31 dart::Mutex SSLFilter::mutex_; // To protect library initialization. |
| 32 // The password is needed when creating secure server sockets. It can | 32 // The password is needed when creating secure server sockets. It can |
| 33 // be null if only secure client sockets are used. | 33 // be null if only secure client sockets are used. |
| 34 const char* TlsFilter::password_ = NULL; | 34 const char* SSLFilter::password_ = NULL; |
| 35 | 35 |
| 36 static const int kTlsFilterNativeFieldIndex = 0; | 36 static const int kSSLFilterNativeFieldIndex = 0; |
| 37 | 37 |
| 38 static TlsFilter* GetTlsFilter(Dart_NativeArguments args) { | 38 static SSLFilter* GetFilter(Dart_NativeArguments args) { |
| 39 TlsFilter* filter; | 39 SSLFilter* filter; |
| 40 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 40 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| 41 ASSERT(Dart_IsInstance(dart_this)); | 41 ASSERT(Dart_IsInstance(dart_this)); |
| 42 ThrowIfError(Dart_GetNativeInstanceField( | 42 ThrowIfError(Dart_GetNativeInstanceField( |
| 43 dart_this, | 43 dart_this, |
| 44 kTlsFilterNativeFieldIndex, | 44 kSSLFilterNativeFieldIndex, |
| 45 reinterpret_cast<intptr_t*>(&filter))); | 45 reinterpret_cast<intptr_t*>(&filter))); |
| 46 return filter; | 46 return filter; |
| 47 } | 47 } |
| 48 | 48 |
| 49 | 49 |
| 50 static void SetTlsFilter(Dart_NativeArguments args, TlsFilter* filter) { | 50 static void SetFilter(Dart_NativeArguments args, SSLFilter* filter) { |
| 51 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 51 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| 52 ASSERT(Dart_IsInstance(dart_this)); | 52 ASSERT(Dart_IsInstance(dart_this)); |
| 53 ThrowIfError(Dart_SetNativeInstanceField( | 53 ThrowIfError(Dart_SetNativeInstanceField( |
| 54 dart_this, | 54 dart_this, |
| 55 kTlsFilterNativeFieldIndex, | 55 kSSLFilterNativeFieldIndex, |
| 56 reinterpret_cast<intptr_t>(filter))); | 56 reinterpret_cast<intptr_t>(filter))); |
| 57 } | 57 } |
| 58 | 58 |
| 59 | 59 |
| 60 void FUNCTION_NAME(TlsSocket_Init)(Dart_NativeArguments args) { | 60 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) { |
| 61 Dart_EnterScope(); | 61 Dart_EnterScope(); |
| 62 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 62 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| 63 TlsFilter* filter = new TlsFilter; | 63 SSLFilter* filter = new SSLFilter; |
| 64 SetTlsFilter(args, filter); | 64 SetFilter(args, filter); |
| 65 filter->Init(dart_this); | 65 filter->Init(dart_this); |
| 66 Dart_ExitScope(); | 66 Dart_ExitScope(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 | 69 |
| 70 void FUNCTION_NAME(TlsSocket_Connect)(Dart_NativeArguments args) { | 70 void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) { |
| 71 Dart_EnterScope(); | 71 Dart_EnterScope(); |
| 72 Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 72 Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
| 73 Dart_Handle port_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); | 73 Dart_Handle port_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); |
| 74 Dart_Handle is_server_object = ThrowIfError(Dart_GetNativeArgument(args, 3)); | 74 Dart_Handle is_server_object = ThrowIfError(Dart_GetNativeArgument(args, 3)); |
| 75 Dart_Handle certificate_name_object = | 75 Dart_Handle certificate_name_object = |
| 76 ThrowIfError(Dart_GetNativeArgument(args, 4)); | 76 ThrowIfError(Dart_GetNativeArgument(args, 4)); |
| 77 | 77 |
| 78 const char* host_name = NULL; | 78 const char* host_name = NULL; |
| 79 // TODO(whesse): Is truncating a Dart string containing \0 what we want? | 79 // TODO(whesse): Is truncating a Dart string containing \0 what we want? |
| 80 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); | 80 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); |
| 81 | 81 |
| 82 int64_t port; | 82 int64_t port; |
| 83 if (!DartUtils::GetInt64Value(port_object, &port) || | 83 if (!DartUtils::GetInt64Value(port_object, &port) || |
| 84 port < 0 || port > 65535) { | 84 port < 0 || port > 65535) { |
| 85 Dart_ThrowException(DartUtils::NewDartArgumentError( | 85 Dart_ThrowException(DartUtils::NewDartArgumentError( |
| 86 "Illegal port parameter in _TlsFilter.connect")); | 86 "Illegal port parameter in _SSLFilter.connect")); |
| 87 } | 87 } |
| 88 | 88 |
| 89 if (!Dart_IsBoolean(is_server_object)) { | 89 if (!Dart_IsBoolean(is_server_object)) { |
| 90 Dart_ThrowException(DartUtils::NewDartArgumentError( | 90 Dart_ThrowException(DartUtils::NewDartArgumentError( |
| 91 "Illegal is_server parameter in _TlsFilter.connect")); | 91 "Illegal is_server parameter in _SSLFilter.connect")); |
| 92 } | 92 } |
| 93 bool is_server = DartUtils::GetBooleanValue(is_server_object); | 93 bool is_server = DartUtils::GetBooleanValue(is_server_object); |
| 94 | 94 |
| 95 const char* certificate_name = NULL; | 95 const char* certificate_name = NULL; |
| 96 // If this is a server connection, get the certificate to connect with. | 96 // If this is a server connection, get the certificate to connect with. |
| 97 // TODO(whesse): Use this parameter for a client certificate as well. | 97 // TODO(whesse): Use this parameter for a client certificate as well. |
| 98 if (is_server) { | 98 if (is_server) { |
| 99 if (!Dart_IsString(certificate_name_object)) { | 99 if (!Dart_IsString(certificate_name_object)) { |
| 100 Dart_ThrowException(DartUtils::NewDartArgumentError( | 100 Dart_ThrowException(DartUtils::NewDartArgumentError( |
| 101 "Non-String certificate parameter in _TlsFilter.connect")); | 101 "Non-String certificate parameter in _SSLFilter.connect")); |
| 102 } | 102 } |
| 103 ThrowIfError(Dart_StringToCString(certificate_name_object, | 103 ThrowIfError(Dart_StringToCString(certificate_name_object, |
| 104 &certificate_name)); | 104 &certificate_name)); |
| 105 } | 105 } |
| 106 | 106 |
| 107 GetTlsFilter(args)->Connect(host_name, | 107 GetFilter(args)->Connect(host_name, |
| 108 static_cast<int>(port), | 108 static_cast<int>(port), |
| 109 is_server, | 109 is_server, |
| 110 certificate_name); | 110 certificate_name); |
| 111 Dart_ExitScope(); | 111 Dart_ExitScope(); |
| 112 } | 112 } |
| 113 | 113 |
| 114 | 114 |
| 115 void FUNCTION_NAME(TlsSocket_Destroy)(Dart_NativeArguments args) { | 115 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { |
| 116 Dart_EnterScope(); | 116 Dart_EnterScope(); |
| 117 TlsFilter* filter = GetTlsFilter(args); | 117 SSLFilter* filter = GetFilter(args); |
| 118 SetTlsFilter(args, NULL); | 118 SetFilter(args, NULL); |
| 119 filter->Destroy(); | 119 filter->Destroy(); |
| 120 delete filter; | 120 delete filter; |
| 121 Dart_ExitScope(); | 121 Dart_ExitScope(); |
| 122 } | 122 } |
| 123 | 123 |
| 124 | 124 |
| 125 void FUNCTION_NAME(TlsSocket_Handshake)(Dart_NativeArguments args) { | 125 void FUNCTION_NAME(SecureSocket_Handshake)(Dart_NativeArguments args) { |
| 126 Dart_EnterScope(); | 126 Dart_EnterScope(); |
| 127 GetTlsFilter(args)->Handshake(); | 127 GetFilter(args)->Handshake(); |
| 128 Dart_ExitScope(); | 128 Dart_ExitScope(); |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 void FUNCTION_NAME(TlsSocket_RegisterHandshakeCompleteCallback)( | 132 void FUNCTION_NAME(SecureSocket_RegisterHandshakeCompleteCallback)( |
| 133 Dart_NativeArguments args) { | 133 Dart_NativeArguments args) { |
| 134 Dart_EnterScope(); | 134 Dart_EnterScope(); |
| 135 Dart_Handle handshake_complete = | 135 Dart_Handle handshake_complete = |
| 136 ThrowIfError(Dart_GetNativeArgument(args, 1)); | 136 ThrowIfError(Dart_GetNativeArgument(args, 1)); |
| 137 if (!Dart_IsClosure(handshake_complete)) { | 137 if (!Dart_IsClosure(handshake_complete)) { |
| 138 Dart_ThrowException(DartUtils::NewDartArgumentError( | 138 Dart_ThrowException(DartUtils::NewDartArgumentError( |
| 139 "Illegal argument to RegisterHandshakeCompleteCallback")); | 139 "Illegal argument to RegisterHandshakeCompleteCallback")); |
| 140 } | 140 } |
| 141 GetTlsFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete); | 141 GetFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete); |
| 142 Dart_ExitScope(); | 142 Dart_ExitScope(); |
| 143 } | 143 } |
| 144 | 144 |
| 145 | 145 |
| 146 void FUNCTION_NAME(TlsSocket_ProcessBuffer)(Dart_NativeArguments args) { | 146 void FUNCTION_NAME(SecureSocket_ProcessBuffer)(Dart_NativeArguments args) { |
| 147 Dart_EnterScope(); | 147 Dart_EnterScope(); |
| 148 Dart_Handle buffer_id_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 148 Dart_Handle buffer_id_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
| 149 int64_t buffer_id = DartUtils::GetIntegerValue(buffer_id_object); | 149 int64_t buffer_id = DartUtils::GetIntegerValue(buffer_id_object); |
| 150 if (buffer_id < 0 || buffer_id >= TlsFilter::kNumBuffers) { | 150 if (buffer_id < 0 || buffer_id >= SSLFilter::kNumBuffers) { |
| 151 Dart_ThrowException(DartUtils::NewDartArgumentError( | 151 Dart_ThrowException(DartUtils::NewDartArgumentError( |
| 152 "Illegal argument to ProcessBuffer")); | 152 "Illegal argument to ProcessBuffer")); |
| 153 } | 153 } |
| 154 | 154 |
| 155 intptr_t bytes_read = | 155 intptr_t bytes_read = |
| 156 GetTlsFilter(args)->ProcessBuffer(static_cast<int>(buffer_id)); | 156 GetFilter(args)->ProcessBuffer(static_cast<int>(buffer_id)); |
| 157 Dart_SetReturnValue(args, Dart_NewInteger(bytes_read)); | 157 Dart_SetReturnValue(args, Dart_NewInteger(bytes_read)); |
| 158 Dart_ExitScope(); | 158 Dart_ExitScope(); |
| 159 } | 159 } |
| 160 | 160 |
| 161 | 161 |
| 162 void FUNCTION_NAME(TlsSocket_SetCertificateDatabase) | 162 void FUNCTION_NAME(SecureSocket_SetCertificateDatabase) |
| 163 (Dart_NativeArguments args) { | 163 (Dart_NativeArguments args) { |
| 164 Dart_EnterScope(); | 164 Dart_EnterScope(); |
| 165 Dart_Handle certificate_database_object = | 165 Dart_Handle certificate_database_object = |
| 166 ThrowIfError(Dart_GetNativeArgument(args, 0)); | 166 ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| 167 // Check that the type is string, and get the UTF-8 C string value from it. | 167 // Check that the type is string, and get the UTF-8 C string value from it. |
| 168 const char* certificate_database = NULL; | 168 const char* certificate_database = NULL; |
| 169 if (Dart_IsString(certificate_database_object)) { | 169 if (Dart_IsString(certificate_database_object)) { |
| 170 ThrowIfError(Dart_StringToCString(certificate_database_object, | 170 ThrowIfError(Dart_StringToCString(certificate_database_object, |
| 171 &certificate_database)); | 171 &certificate_database)); |
| 172 } else { | 172 } else { |
| 173 Dart_ThrowException(DartUtils::NewDartArgumentError( | 173 Dart_ThrowException(DartUtils::NewDartArgumentError( |
| 174 "Non-String certificate directory argument to SetCertificateDatabase")); | 174 "Non-String certificate directory argument to SetCertificateDatabase")); |
| 175 } | 175 } |
| 176 | 176 |
| 177 Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 177 Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
| 178 // Check that the type is string or null, | 178 // Check that the type is string or null, |
| 179 // and get the UTF-8 C string value from it. | 179 // and get the UTF-8 C string value from it. |
| 180 const char* password = NULL; | 180 const char* password = NULL; |
| 181 if (Dart_IsString(password_object)) { | 181 if (Dart_IsString(password_object)) { |
| 182 ThrowIfError(Dart_StringToCString(password_object, &password)); | 182 ThrowIfError(Dart_StringToCString(password_object, &password)); |
| 183 } else if (Dart_IsNull(password_object)) { | 183 } else if (Dart_IsNull(password_object)) { |
| 184 // Pass the empty string as the password. | 184 // Pass the empty string as the password. |
| 185 password = ""; | 185 password = ""; |
| 186 } else { | 186 } else { |
| 187 Dart_ThrowException(DartUtils::NewDartArgumentError( | 187 Dart_ThrowException(DartUtils::NewDartArgumentError( |
| 188 "Password argument to SetCertificateDatabase is not a String or null")); | 188 "Password argument to SetCertificateDatabase is not a String or null")); |
| 189 } | 189 } |
| 190 | 190 |
| 191 TlsFilter::InitializeLibrary(certificate_database, password); | 191 SSLFilter::InitializeLibrary(certificate_database, password); |
| 192 Dart_ExitScope(); | 192 Dart_ExitScope(); |
| 193 } | 193 } |
| 194 | 194 |
| 195 | 195 |
| 196 void TlsFilter::Init(Dart_Handle dart_this) { | 196 void SSLFilter::Init(Dart_Handle dart_this) { |
| 197 string_start_ = ThrowIfError( | 197 string_start_ = ThrowIfError( |
| 198 Dart_NewPersistentHandle(DartUtils::NewString("start"))); | 198 Dart_NewPersistentHandle(DartUtils::NewString("start"))); |
| 199 string_length_ = ThrowIfError( | 199 string_length_ = ThrowIfError( |
| 200 Dart_NewPersistentHandle(DartUtils::NewString("length"))); | 200 Dart_NewPersistentHandle(DartUtils::NewString("length"))); |
| 201 | 201 |
| 202 InitializeBuffers(dart_this); | 202 InitializeBuffers(dart_this); |
| 203 filter_ = memio_CreateIOLayer(kMemioBufferSize); | 203 filter_ = memio_CreateIOLayer(kMemioBufferSize); |
| 204 } | 204 } |
| 205 | 205 |
| 206 | 206 |
| 207 void TlsFilter::InitializeBuffers(Dart_Handle dart_this) { | 207 void SSLFilter::InitializeBuffers(Dart_Handle dart_this) { |
| 208 // Create TlsFilter buffers as ExternalUint8Array objects. | 208 // Create SSLFilter buffers as ExternalUint8Array objects. |
| 209 Dart_Handle dart_buffers_object = ThrowIfError( | 209 Dart_Handle dart_buffers_object = ThrowIfError( |
| 210 Dart_GetField(dart_this, DartUtils::NewString("buffers"))); | 210 Dart_GetField(dart_this, DartUtils::NewString("buffers"))); |
| 211 Dart_Handle dart_buffer_object = | 211 Dart_Handle dart_buffer_object = |
| 212 Dart_ListGetAt(dart_buffers_object, kReadPlaintext); | 212 Dart_ListGetAt(dart_buffers_object, kReadPlaintext); |
| 213 Dart_Handle tls_external_buffer_class = | 213 Dart_Handle external_buffer_class = |
| 214 Dart_InstanceGetClass(dart_buffer_object); | 214 Dart_InstanceGetClass(dart_buffer_object); |
| 215 Dart_Handle dart_buffer_size = ThrowIfError( | 215 Dart_Handle dart_buffer_size = ThrowIfError( |
| 216 Dart_GetField(tls_external_buffer_class, DartUtils::NewString("SIZE"))); | 216 Dart_GetField(external_buffer_class, DartUtils::NewString("SIZE"))); |
| 217 buffer_size_ = DartUtils::GetIntegerValue(dart_buffer_size); | 217 buffer_size_ = DartUtils::GetIntegerValue(dart_buffer_size); |
| 218 if (buffer_size_ <= 0 || buffer_size_ > 1024 * 1024) { | 218 if (buffer_size_ <= 0 || buffer_size_ > 1024 * 1024) { |
| 219 Dart_ThrowException( | 219 Dart_ThrowException( |
| 220 DartUtils::NewString("Invalid buffer size in _TlsExternalBuffer")); | 220 DartUtils::NewString("Invalid buffer size in _ExternalBuffer")); |
| 221 } | 221 } |
| 222 | 222 |
| 223 Dart_Handle data_identifier = DartUtils::NewString("data"); | 223 Dart_Handle data_identifier = DartUtils::NewString("data"); |
| 224 for (int i = 0; i < kNumBuffers; ++i) { | 224 for (int i = 0; i < kNumBuffers; ++i) { |
| 225 dart_buffer_objects_[i] = ThrowIfError( | 225 dart_buffer_objects_[i] = ThrowIfError( |
| 226 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i))); | 226 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i))); |
| 227 buffers_[i] = new uint8_t[buffer_size_]; | 227 buffers_[i] = new uint8_t[buffer_size_]; |
| 228 Dart_Handle data = ThrowIfError( | 228 Dart_Handle data = ThrowIfError( |
| 229 Dart_NewExternalByteArray(buffers_[i], buffer_size_, NULL, NULL)); | 229 Dart_NewExternalByteArray(buffers_[i], buffer_size_, NULL, NULL)); |
| 230 ThrowIfError(Dart_SetField(dart_buffer_objects_[i], | 230 ThrowIfError(Dart_SetField(dart_buffer_objects_[i], |
| 231 data_identifier, | 231 data_identifier, |
| 232 data)); | 232 data)); |
| 233 } | 233 } |
| 234 } | 234 } |
| 235 | 235 |
| 236 | 236 |
| 237 void TlsFilter::RegisterHandshakeCompleteCallback(Dart_Handle complete) { | 237 void SSLFilter::RegisterHandshakeCompleteCallback(Dart_Handle complete) { |
| 238 ASSERT(NULL == handshake_complete_); | 238 ASSERT(NULL == handshake_complete_); |
| 239 handshake_complete_ = ThrowIfError(Dart_NewPersistentHandle(complete)); | 239 handshake_complete_ = ThrowIfError(Dart_NewPersistentHandle(complete)); |
| 240 } | 240 } |
| 241 | 241 |
| 242 | 242 |
| 243 void TlsFilter::InitializeLibrary(const char* certificate_database, | 243 void SSLFilter::InitializeLibrary(const char* certificate_database, |
| 244 const char* password) { | 244 const char* password) { |
| 245 MutexLocker locker(&mutex_); | 245 MutexLocker locker(&mutex_); |
| 246 if (!library_initialized_) { | 246 if (!library_initialized_) { |
| 247 library_initialized_ = true; | 247 library_initialized_ = true; |
| 248 password_ = strdup(password); // This one copy persists until Dart exits. | 248 password_ = strdup(password); // This one copy persists until Dart exits. |
| 249 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); | 249 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); |
| 250 // TODO(whesse): Verify there are no UTF-8 issues here. | 250 // TODO(whesse): Verify there are no UTF-8 issues here. |
| 251 SECStatus status = NSS_Init(certificate_database); | 251 SECStatus status = NSS_Init(certificate_database); |
| 252 if (status != SECSuccess) { | 252 if (status != SECSuccess) { |
| 253 ThrowPRException("Unsuccessful NSS_Init call."); | 253 ThrowPRException("Unsuccessful NSS_Init call."); |
| 254 } | 254 } |
| 255 | 255 |
| 256 status = NSS_SetDomesticPolicy(); | 256 status = NSS_SetDomesticPolicy(); |
| 257 if (status != SECSuccess) { | 257 if (status != SECSuccess) { |
| 258 ThrowPRException("Unsuccessful NSS_SetDomesticPolicy call."); | 258 ThrowPRException("Unsuccessful NSS_SetDomesticPolicy call."); |
| 259 } | 259 } |
| 260 // Enable TLS, as well as SSL3 and SSL2. | 260 // Enable TLS, as well as SSL3 and SSL2. |
| 261 status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE); | 261 status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE); |
| 262 if (status != SECSuccess) { | 262 if (status != SECSuccess) { |
| 263 ThrowPRException("Unsuccessful SSL_OptionSetDefault enable TLS call."); | 263 ThrowPRException("Unsuccessful SSL_OptionSetDefault enable TLS call."); |
| 264 } | 264 } |
| 265 } else { | 265 } else { |
| 266 ThrowException("Called TlsFilter::InitializeLibrary more than once"); | 266 ThrowException("Called SSLFilter::InitializeLibrary more than once"); |
| 267 } | 267 } |
| 268 } | 268 } |
| 269 | 269 |
| 270 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { | 270 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { |
| 271 if (!retry) { | 271 if (!retry) { |
| 272 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. | 272 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. |
| 273 } | 273 } |
| 274 return NULL; | 274 return NULL; |
| 275 } | 275 } |
| 276 | 276 |
| 277 void TlsFilter::Connect(const char* host_name, | 277 void SSLFilter::Connect(const char* host_name, |
| 278 int port, | 278 int port, |
| 279 bool is_server, | 279 bool is_server, |
| 280 const char* certificate_name) { | 280 const char* certificate_name) { |
| 281 is_server_ = is_server; | 281 is_server_ = is_server; |
| 282 if (in_handshake_) { | 282 if (in_handshake_) { |
| 283 ThrowException("Connect called while already in handshake state."); | 283 ThrowException("Connect called while already in handshake state."); |
| 284 } | 284 } |
| 285 | 285 |
| 286 filter_ = SSL_ImportFD(NULL, filter_); | 286 filter_ = SSL_ImportFD(NULL, filter_); |
| 287 if (filter_ == NULL) { | 287 if (filter_ == NULL) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 } | 341 } |
| 342 | 342 |
| 343 int index = PR_EnumerateHostEnt(0, &host_entry, port, &host_address); | 343 int index = PR_EnumerateHostEnt(0, &host_entry, port, &host_address); |
| 344 if (index == -1 || index == 0) { | 344 if (index == -1 || index == 0) { |
| 345 ThrowPRException("Unsuccessful PR_EnumerateHostEnt call"); | 345 ThrowPRException("Unsuccessful PR_EnumerateHostEnt call"); |
| 346 } | 346 } |
| 347 memio_SetPeerName(filter_, &host_address); | 347 memio_SetPeerName(filter_, &host_address); |
| 348 } | 348 } |
| 349 | 349 |
| 350 | 350 |
| 351 void TlsFilter::Handshake() { | 351 void SSLFilter::Handshake() { |
| 352 SECStatus status = SSL_ForceHandshake(filter_); | 352 SECStatus status = SSL_ForceHandshake(filter_); |
| 353 if (status == SECSuccess) { | 353 if (status == SECSuccess) { |
| 354 if (in_handshake_) { | 354 if (in_handshake_) { |
| 355 ThrowIfError(Dart_InvokeClosure(handshake_complete_, 0, NULL)); | 355 ThrowIfError(Dart_InvokeClosure(handshake_complete_, 0, NULL)); |
| 356 in_handshake_ = false; | 356 in_handshake_ = false; |
| 357 } | 357 } |
| 358 } else { | 358 } else { |
| 359 PRErrorCode error = PR_GetError(); | 359 PRErrorCode error = PR_GetError(); |
| 360 if (error == PR_WOULD_BLOCK_ERROR) { | 360 if (error == PR_WOULD_BLOCK_ERROR) { |
| 361 if (!in_handshake_) { | 361 if (!in_handshake_) { |
| 362 in_handshake_ = true; | 362 in_handshake_ = true; |
| 363 } | 363 } |
| 364 } else { | 364 } else { |
| 365 if (is_server_) { | 365 if (is_server_) { |
| 366 ThrowPRException("Unexpected handshake error in server"); | 366 ThrowPRException("Unexpected handshake error in server"); |
| 367 } else { | 367 } else { |
| 368 ThrowPRException("Unexpected handshake error in client"); | 368 ThrowPRException("Unexpected handshake error in client"); |
| 369 } | 369 } |
| 370 } | 370 } |
| 371 } | 371 } |
| 372 } | 372 } |
| 373 | 373 |
| 374 | 374 |
| 375 void TlsFilter::Destroy() { | 375 void SSLFilter::Destroy() { |
| 376 for (int i = 0; i < kNumBuffers; ++i) { | 376 for (int i = 0; i < kNumBuffers; ++i) { |
| 377 Dart_DeletePersistentHandle(dart_buffer_objects_[i]); | 377 Dart_DeletePersistentHandle(dart_buffer_objects_[i]); |
| 378 delete[] buffers_[i]; | 378 delete[] buffers_[i]; |
| 379 } | 379 } |
| 380 Dart_DeletePersistentHandle(string_start_); | 380 Dart_DeletePersistentHandle(string_start_); |
| 381 Dart_DeletePersistentHandle(string_length_); | 381 Dart_DeletePersistentHandle(string_length_); |
| 382 Dart_DeletePersistentHandle(handshake_complete_); | 382 Dart_DeletePersistentHandle(handshake_complete_); |
| 383 // TODO(whesse): Free NSS objects here. | 383 // TODO(whesse): Free NSS objects here. |
| 384 } | 384 } |
| 385 | 385 |
| 386 | 386 |
| 387 intptr_t TlsFilter::ProcessBuffer(int buffer_index) { | 387 intptr_t SSLFilter::ProcessBuffer(int buffer_index) { |
| 388 Dart_Handle buffer_object = dart_buffer_objects_[buffer_index]; | 388 Dart_Handle buffer_object = dart_buffer_objects_[buffer_index]; |
| 389 Dart_Handle start_object = ThrowIfError( | 389 Dart_Handle start_object = ThrowIfError( |
| 390 Dart_GetField(buffer_object, string_start_)); | 390 Dart_GetField(buffer_object, string_start_)); |
| 391 Dart_Handle length_object = ThrowIfError( | 391 Dart_Handle length_object = ThrowIfError( |
| 392 Dart_GetField(buffer_object, string_length_)); | 392 Dart_GetField(buffer_object, string_length_)); |
| 393 int64_t unsafe_start = DartUtils::GetIntegerValue(start_object); | 393 int64_t unsafe_start = DartUtils::GetIntegerValue(start_object); |
| 394 int64_t unsafe_length = DartUtils::GetIntegerValue(length_object); | 394 int64_t unsafe_length = DartUtils::GetIntegerValue(length_object); |
| 395 ASSERT(unsafe_start >= 0); | 395 ASSERT(unsafe_start >= 0); |
| 396 ASSERT(unsafe_start < buffer_size_); | 396 ASSERT(unsafe_start < buffer_size_); |
| 397 ASSERT(unsafe_length >= 0); | 397 ASSERT(unsafe_length >= 0); |
| 398 ASSERT(unsafe_length <= buffer_size_); | 398 ASSERT(unsafe_length <= buffer_size_); |
| 399 intptr_t start = static_cast<intptr_t>(unsafe_start); | 399 intptr_t start = static_cast<intptr_t>(unsafe_start); |
| 400 intptr_t length = static_cast<intptr_t>(unsafe_length); | 400 intptr_t length = static_cast<intptr_t>(unsafe_length); |
| 401 uint8_t* buffer = buffers_[buffer_index]; | 401 uint8_t* buffer = buffers_[buffer_index]; |
| 402 | 402 |
| 403 int bytes_processed = 0; | 403 int bytes_processed = 0; |
| 404 switch (buffer_index) { | 404 switch (buffer_index) { |
| 405 case kReadPlaintext: { | 405 case kReadPlaintext: { |
| 406 int bytes_free = buffer_size_ - start - length; | 406 int bytes_free = buffer_size_ - start - length; |
| 407 bytes_processed = PR_Read(filter_, | 407 bytes_processed = PR_Read(filter_, |
| 408 buffer + start + length, | 408 buffer + start + length, |
| 409 bytes_free); | 409 bytes_free); |
| 410 if (bytes_processed < 0) { | 410 if (bytes_processed < 0) { |
| 411 ASSERT(bytes_processed == -1); | 411 ASSERT(bytes_processed == -1); |
| 412 // TODO(whesse): Handle unexpected errors here. | 412 // TODO(whesse): Handle unexpected errors here. |
| 413 PRErrorCode pr_error = PR_GetError(); | 413 PRErrorCode pr_error = PR_GetError(); |
| 414 if (PR_WOULD_BLOCK_ERROR != pr_error) { | 414 if (PR_WOULD_BLOCK_ERROR != pr_error) { |
| 415 ThrowPRException("Error reading plaintext from TlsFilter"); | 415 ThrowPRException("Error reading plaintext from SSLFilter"); |
| 416 } | 416 } |
| 417 bytes_processed = 0; | 417 bytes_processed = 0; |
| 418 } | 418 } |
| 419 break; | 419 break; |
| 420 } | 420 } |
| 421 | 421 |
| 422 case kWriteEncrypted: { | 422 case kWriteEncrypted: { |
| 423 const uint8_t* buf1; | 423 const uint8_t* buf1; |
| 424 const uint8_t* buf2; | 424 const uint8_t* buf2; |
| 425 unsigned int len1; | 425 unsigned int len1; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 bytes_processed = PR_Write(filter_, | 466 bytes_processed = PR_Write(filter_, |
| 467 buffer + start, | 467 buffer + start, |
| 468 length); | 468 length); |
| 469 } | 469 } |
| 470 | 470 |
| 471 if (bytes_processed < 0) { | 471 if (bytes_processed < 0) { |
| 472 ASSERT(bytes_processed == -1); | 472 ASSERT(bytes_processed == -1); |
| 473 // TODO(whesse): Handle unexpected errors here. | 473 // TODO(whesse): Handle unexpected errors here. |
| 474 PRErrorCode pr_error = PR_GetError(); | 474 PRErrorCode pr_error = PR_GetError(); |
| 475 if (PR_WOULD_BLOCK_ERROR != pr_error) { | 475 if (PR_WOULD_BLOCK_ERROR != pr_error) { |
| 476 ThrowPRException("Error reading plaintext from TlsFilter"); | 476 ThrowPRException("Error reading plaintext from SSLFilter"); |
| 477 } | 477 } |
| 478 bytes_processed = 0; | 478 bytes_processed = 0; |
| 479 } | 479 } |
| 480 break; | 480 break; |
| 481 } | 481 } |
| 482 } | 482 } |
| 483 return bytes_processed; | 483 return bytes_processed; |
| 484 } | 484 } |
| OLD | NEW |