| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED) | 5 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED) |
| 6 | 6 |
| 7 #include "bin/secure_socket_filter.h" | 7 #include "bin/secure_socket_filter.h" |
| 8 | 8 |
| 9 #include <openssl/bio.h> | 9 #include <openssl/bio.h> |
| 10 #include <openssl/ssl.h> | 10 #include <openssl/ssl.h> |
| 11 #include <openssl/x509.h> | 11 #include <openssl/x509.h> |
| 12 | 12 |
| 13 #include "bin/lockers.h" | 13 #include "bin/lockers.h" |
| 14 #include "bin/log.h" | 14 #include "bin/log.h" |
| 15 #include "bin/secure_socket_utils.h" | 15 #include "bin/secure_socket_utils.h" |
| 16 #include "bin/security_context.h" | 16 #include "bin/security_context.h" |
| 17 #include "platform/text_buffer.h" | 17 #include "platform/text_buffer.h" |
| 18 | 18 |
| 19 | |
| 20 // Return the error from the containing function if handle is an error handle. | 19 // Return the error from the containing function if handle is an error handle. |
| 21 #define RETURN_IF_ERROR(handle) \ | 20 #define RETURN_IF_ERROR(handle) \ |
| 22 { \ | 21 { \ |
| 23 Dart_Handle __handle = handle; \ | 22 Dart_Handle __handle = handle; \ |
| 24 if (Dart_IsError((__handle))) { \ | 23 if (Dart_IsError((__handle))) { \ |
| 25 return __handle; \ | 24 return __handle; \ |
| 26 } \ | 25 } \ |
| 27 } | 26 } |
| 28 | 27 |
| 29 namespace dart { | 28 namespace dart { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 41 static SSLFilter* GetFilter(Dart_NativeArguments args) { | 40 static SSLFilter* GetFilter(Dart_NativeArguments args) { |
| 42 SSLFilter* filter; | 41 SSLFilter* filter; |
| 43 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 42 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| 44 ASSERT(Dart_IsInstance(dart_this)); | 43 ASSERT(Dart_IsInstance(dart_this)); |
| 45 ThrowIfError(Dart_GetNativeInstanceField( | 44 ThrowIfError(Dart_GetNativeInstanceField( |
| 46 dart_this, SSLFilter::kSSLFilterNativeFieldIndex, | 45 dart_this, SSLFilter::kSSLFilterNativeFieldIndex, |
| 47 reinterpret_cast<intptr_t*>(&filter))); | 46 reinterpret_cast<intptr_t*>(&filter))); |
| 48 return filter; | 47 return filter; |
| 49 } | 48 } |
| 50 | 49 |
| 51 | |
| 52 static void DeleteFilter(void* isolate_data, | 50 static void DeleteFilter(void* isolate_data, |
| 53 Dart_WeakPersistentHandle handle, | 51 Dart_WeakPersistentHandle handle, |
| 54 void* context_pointer) { | 52 void* context_pointer) { |
| 55 SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer); | 53 SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer); |
| 56 filter->Release(); | 54 filter->Release(); |
| 57 } | 55 } |
| 58 | 56 |
| 59 | |
| 60 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { | 57 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { |
| 61 ASSERT(filter != NULL); | 58 ASSERT(filter != NULL); |
| 62 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); | 59 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); |
| 63 RETURN_IF_ERROR(dart_this); | 60 RETURN_IF_ERROR(dart_this); |
| 64 ASSERT(Dart_IsInstance(dart_this)); | 61 ASSERT(Dart_IsInstance(dart_this)); |
| 65 Dart_Handle err = Dart_SetNativeInstanceField( | 62 Dart_Handle err = Dart_SetNativeInstanceField( |
| 66 dart_this, SSLFilter::kSSLFilterNativeFieldIndex, | 63 dart_this, SSLFilter::kSSLFilterNativeFieldIndex, |
| 67 reinterpret_cast<intptr_t>(filter)); | 64 reinterpret_cast<intptr_t>(filter)); |
| 68 RETURN_IF_ERROR(err); | 65 RETURN_IF_ERROR(err); |
| 69 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(filter), | 66 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(filter), |
| 70 SSLFilter::kApproximateSize, DeleteFilter); | 67 SSLFilter::kApproximateSize, DeleteFilter); |
| 71 return Dart_Null(); | 68 return Dart_Null(); |
| 72 } | 69 } |
| 73 | 70 |
| 74 | |
| 75 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) { | 71 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) { |
| 76 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 72 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| 77 SSLFilter* filter = new SSLFilter(); | 73 SSLFilter* filter = new SSLFilter(); |
| 78 Dart_Handle err = SetFilter(args, filter); | 74 Dart_Handle err = SetFilter(args, filter); |
| 79 if (Dart_IsError(err)) { | 75 if (Dart_IsError(err)) { |
| 80 filter->Release(); | 76 filter->Release(); |
| 81 Dart_PropagateError(err); | 77 Dart_PropagateError(err); |
| 82 } | 78 } |
| 83 err = filter->Init(dart_this); | 79 err = filter->Init(dart_this); |
| 84 if (Dart_IsError(err)) { | 80 if (Dart_IsError(err)) { |
| 85 // The finalizer was set up by SetFilter. It will delete `filter` if there | 81 // The finalizer was set up by SetFilter. It will delete `filter` if there |
| 86 // is an error. | 82 // is an error. |
| 87 filter->Destroy(); | 83 filter->Destroy(); |
| 88 Dart_PropagateError(err); | 84 Dart_PropagateError(err); |
| 89 } | 85 } |
| 90 } | 86 } |
| 91 | 87 |
| 92 | |
| 93 void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) { | 88 void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) { |
| 94 Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 89 Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
| 95 Dart_Handle context_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); | 90 Dart_Handle context_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); |
| 96 bool is_server = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); | 91 bool is_server = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); |
| 97 bool request_client_certificate = | 92 bool request_client_certificate = |
| 98 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); | 93 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); |
| 99 bool require_client_certificate = | 94 bool require_client_certificate = |
| 100 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5)); | 95 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5)); |
| 101 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 6)); | 96 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 6)); |
| 102 | 97 |
| 103 const char* host_name = NULL; | 98 const char* host_name = NULL; |
| 104 // TODO(whesse): Is truncating a Dart string containing \0 what we want? | 99 // TODO(whesse): Is truncating a Dart string containing \0 what we want? |
| 105 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); | 100 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); |
| 106 | 101 |
| 107 SSLCertContext* context = NULL; | 102 SSLCertContext* context = NULL; |
| 108 if (!Dart_IsNull(context_object)) { | 103 if (!Dart_IsNull(context_object)) { |
| 109 ThrowIfError(Dart_GetNativeInstanceField( | 104 ThrowIfError(Dart_GetNativeInstanceField( |
| 110 context_object, SSLCertContext::kSecurityContextNativeFieldIndex, | 105 context_object, SSLCertContext::kSecurityContextNativeFieldIndex, |
| 111 reinterpret_cast<intptr_t*>(&context))); | 106 reinterpret_cast<intptr_t*>(&context))); |
| 112 } | 107 } |
| 113 | 108 |
| 114 // The protocols_handle is guaranteed to be a valid Uint8List. | 109 // The protocols_handle is guaranteed to be a valid Uint8List. |
| 115 // It will have the correct length encoding of the protocols array. | 110 // It will have the correct length encoding of the protocols array. |
| 116 ASSERT(!Dart_IsNull(protocols_handle)); | 111 ASSERT(!Dart_IsNull(protocols_handle)); |
| 117 GetFilter(args)->Connect(host_name, context, is_server, | 112 GetFilter(args)->Connect(host_name, context, is_server, |
| 118 request_client_certificate, | 113 request_client_certificate, |
| 119 require_client_certificate, protocols_handle); | 114 require_client_certificate, protocols_handle); |
| 120 } | 115 } |
| 121 | 116 |
| 122 | |
| 123 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { | 117 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { |
| 124 SSLFilter* filter = GetFilter(args); | 118 SSLFilter* filter = GetFilter(args); |
| 125 // There are two paths that can clean up an SSLFilter object. First, | 119 // There are two paths that can clean up an SSLFilter object. First, |
| 126 // there is this explicit call to Destroy(), called from | 120 // there is this explicit call to Destroy(), called from |
| 127 // _SecureFilter.destroy() in Dart code. After a call to destroy(), the Dart | 121 // _SecureFilter.destroy() in Dart code. After a call to destroy(), the Dart |
| 128 // code maintains the invariant that there will be no futher SSLFilter | 122 // code maintains the invariant that there will be no futher SSLFilter |
| 129 // requests sent to the IO Service. Therefore, the internals of the SSLFilter | 123 // requests sent to the IO Service. Therefore, the internals of the SSLFilter |
| 130 // are safe to deallocate, but not the SSLFilter itself, which is already | 124 // are safe to deallocate, but not the SSLFilter itself, which is already |
| 131 // set up to be cleaned up by the finalizer. | 125 // set up to be cleaned up by the finalizer. |
| 132 // | 126 // |
| 133 // The second path is through the finalizer, which we have to do in case | 127 // The second path is through the finalizer, which we have to do in case |
| 134 // some mishap prevents a call to _SecureFilter.destroy(). | 128 // some mishap prevents a call to _SecureFilter.destroy(). |
| 135 filter->Destroy(); | 129 filter->Destroy(); |
| 136 } | 130 } |
| 137 | 131 |
| 138 | |
| 139 void FUNCTION_NAME(SecureSocket_Handshake)(Dart_NativeArguments args) { | 132 void FUNCTION_NAME(SecureSocket_Handshake)(Dart_NativeArguments args) { |
| 140 GetFilter(args)->Handshake(); | 133 GetFilter(args)->Handshake(); |
| 141 } | 134 } |
| 142 | 135 |
| 143 | |
| 144 void FUNCTION_NAME(SecureSocket_GetSelectedProtocol)( | 136 void FUNCTION_NAME(SecureSocket_GetSelectedProtocol)( |
| 145 Dart_NativeArguments args) { | 137 Dart_NativeArguments args) { |
| 146 GetFilter(args)->GetSelectedProtocol(args); | 138 GetFilter(args)->GetSelectedProtocol(args); |
| 147 } | 139 } |
| 148 | 140 |
| 149 | |
| 150 void FUNCTION_NAME(SecureSocket_Renegotiate)(Dart_NativeArguments args) { | 141 void FUNCTION_NAME(SecureSocket_Renegotiate)(Dart_NativeArguments args) { |
| 151 bool use_session_cache = | 142 bool use_session_cache = |
| 152 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1)); | 143 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1)); |
| 153 bool request_client_certificate = | 144 bool request_client_certificate = |
| 154 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 2)); | 145 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 2)); |
| 155 bool require_client_certificate = | 146 bool require_client_certificate = |
| 156 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); | 147 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); |
| 157 GetFilter(args)->Renegotiate(use_session_cache, request_client_certificate, | 148 GetFilter(args)->Renegotiate(use_session_cache, request_client_certificate, |
| 158 require_client_certificate); | 149 require_client_certificate); |
| 159 } | 150 } |
| 160 | 151 |
| 161 | |
| 162 void FUNCTION_NAME(SecureSocket_RegisterHandshakeCompleteCallback)( | 152 void FUNCTION_NAME(SecureSocket_RegisterHandshakeCompleteCallback)( |
| 163 Dart_NativeArguments args) { | 153 Dart_NativeArguments args) { |
| 164 Dart_Handle handshake_complete = | 154 Dart_Handle handshake_complete = |
| 165 ThrowIfError(Dart_GetNativeArgument(args, 1)); | 155 ThrowIfError(Dart_GetNativeArgument(args, 1)); |
| 166 if (!Dart_IsClosure(handshake_complete)) { | 156 if (!Dart_IsClosure(handshake_complete)) { |
| 167 Dart_ThrowException(DartUtils::NewDartArgumentError( | 157 Dart_ThrowException(DartUtils::NewDartArgumentError( |
| 168 "Illegal argument to RegisterHandshakeCompleteCallback")); | 158 "Illegal argument to RegisterHandshakeCompleteCallback")); |
| 169 } | 159 } |
| 170 GetFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete); | 160 GetFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete); |
| 171 } | 161 } |
| 172 | 162 |
| 173 | |
| 174 void FUNCTION_NAME(SecureSocket_RegisterBadCertificateCallback)( | 163 void FUNCTION_NAME(SecureSocket_RegisterBadCertificateCallback)( |
| 175 Dart_NativeArguments args) { | 164 Dart_NativeArguments args) { |
| 176 Dart_Handle callback = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 165 Dart_Handle callback = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
| 177 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { | 166 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { |
| 178 Dart_ThrowException(DartUtils::NewDartArgumentError( | 167 Dart_ThrowException(DartUtils::NewDartArgumentError( |
| 179 "Illegal argument to RegisterBadCertificateCallback")); | 168 "Illegal argument to RegisterBadCertificateCallback")); |
| 180 } | 169 } |
| 181 GetFilter(args)->RegisterBadCertificateCallback(callback); | 170 GetFilter(args)->RegisterBadCertificateCallback(callback); |
| 182 } | 171 } |
| 183 | 172 |
| 184 | |
| 185 void FUNCTION_NAME(SecureSocket_PeerCertificate)(Dart_NativeArguments args) { | 173 void FUNCTION_NAME(SecureSocket_PeerCertificate)(Dart_NativeArguments args) { |
| 186 Dart_Handle cert = ThrowIfError(GetFilter(args)->PeerCertificate()); | 174 Dart_Handle cert = ThrowIfError(GetFilter(args)->PeerCertificate()); |
| 187 Dart_SetReturnValue(args, cert); | 175 Dart_SetReturnValue(args, cert); |
| 188 } | 176 } |
| 189 | 177 |
| 190 | |
| 191 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { | 178 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { |
| 192 SSLFilter* filter = GetFilter(args); | 179 SSLFilter* filter = GetFilter(args); |
| 193 // This filter pointer is passed to the IO Service thread. The IO Service | 180 // This filter pointer is passed to the IO Service thread. The IO Service |
| 194 // thread must Release() the pointer when it is done with it. | 181 // thread must Release() the pointer when it is done with it. |
| 195 filter->Retain(); | 182 filter->Retain(); |
| 196 intptr_t filter_pointer = reinterpret_cast<intptr_t>(filter); | 183 intptr_t filter_pointer = reinterpret_cast<intptr_t>(filter); |
| 197 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); | 184 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); |
| 198 } | 185 } |
| 199 | 186 |
| 200 | |
| 201 /** | 187 /** |
| 202 * Pushes data through the SSL filter, reading and writing from circular | 188 * Pushes data through the SSL filter, reading and writing from circular |
| 203 * buffers shared with Dart. | 189 * buffers shared with Dart. |
| 204 * | 190 * |
| 205 * The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to | 191 * The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to |
| 206 * pass encrypted and plaintext data to and from the C++ SSLFilter object. | 192 * pass encrypted and plaintext data to and from the C++ SSLFilter object. |
| 207 * | 193 * |
| 208 * ProcessFilter is called with a CObject array containing the pointer to | 194 * ProcessFilter is called with a CObject array containing the pointer to |
| 209 * the SSLFilter, encoded as an int, and the start and end positions of the | 195 * the SSLFilter, encoded as an int, and the start and end positions of the |
| 210 * valid data in the four circular buffers. The function only reads from | 196 * valid data in the four circular buffers. The function only reads from |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 int32_t error_code = static_cast<int32_t>(ERR_peek_error()); | 230 int32_t error_code = static_cast<int32_t>(ERR_peek_error()); |
| 245 TextBuffer error_string(SecureSocketUtils::SSL_ERROR_MESSAGE_BUFFER_SIZE); | 231 TextBuffer error_string(SecureSocketUtils::SSL_ERROR_MESSAGE_BUFFER_SIZE); |
| 246 SecureSocketUtils::FetchErrorString(filter->ssl_, &error_string); | 232 SecureSocketUtils::FetchErrorString(filter->ssl_, &error_string); |
| 247 CObjectArray* result = new CObjectArray(CObject::NewArray(2)); | 233 CObjectArray* result = new CObjectArray(CObject::NewArray(2)); |
| 248 result->SetAt(0, new CObjectInt32(CObject::NewInt32(error_code))); | 234 result->SetAt(0, new CObjectInt32(CObject::NewInt32(error_code))); |
| 249 result->SetAt(1, new CObjectString(CObject::NewString(error_string.buf()))); | 235 result->SetAt(1, new CObjectString(CObject::NewString(error_string.buf()))); |
| 250 return result; | 236 return result; |
| 251 } | 237 } |
| 252 } | 238 } |
| 253 | 239 |
| 254 | |
| 255 bool SSLFilter::ProcessAllBuffers(int starts[kNumBuffers], | 240 bool SSLFilter::ProcessAllBuffers(int starts[kNumBuffers], |
| 256 int ends[kNumBuffers], | 241 int ends[kNumBuffers], |
| 257 bool in_handshake) { | 242 bool in_handshake) { |
| 258 for (int i = 0; i < kNumBuffers; ++i) { | 243 for (int i = 0; i < kNumBuffers; ++i) { |
| 259 if (in_handshake && (i == kReadPlaintext || i == kWritePlaintext)) continue; | 244 if (in_handshake && (i == kReadPlaintext || i == kWritePlaintext)) continue; |
| 260 int start = starts[i]; | 245 int start = starts[i]; |
| 261 int end = ends[i]; | 246 int end = ends[i]; |
| 262 int size = IsBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; | 247 int size = IsBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; |
| 263 if (start < 0 || end < 0 || start >= size || end >= size) { | 248 if (start < 0 || end < 0 || start >= size || end >= size) { |
| 264 FATAL("Out-of-bounds internal buffer access in dart:io SecureSocket"); | 249 FATAL("Out-of-bounds internal buffer access in dart:io SecureSocket"); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 } | 302 } |
| 318 starts[i] = start; | 303 starts[i] = start; |
| 319 break; | 304 break; |
| 320 default: | 305 default: |
| 321 UNREACHABLE(); | 306 UNREACHABLE(); |
| 322 } | 307 } |
| 323 } | 308 } |
| 324 return true; | 309 return true; |
| 325 } | 310 } |
| 326 | 311 |
| 327 | |
| 328 Dart_Handle SSLFilter::Init(Dart_Handle dart_this) { | 312 Dart_Handle SSLFilter::Init(Dart_Handle dart_this) { |
| 329 if (!library_initialized_) { | 313 if (!library_initialized_) { |
| 330 InitializeLibrary(); | 314 InitializeLibrary(); |
| 331 } | 315 } |
| 332 ASSERT(string_start_ == NULL); | 316 ASSERT(string_start_ == NULL); |
| 333 string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start")); | 317 string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start")); |
| 334 ASSERT(string_start_ != NULL); | 318 ASSERT(string_start_ != NULL); |
| 335 ASSERT(string_length_ == NULL); | 319 ASSERT(string_length_ == NULL); |
| 336 string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length")); | 320 string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length")); |
| 337 ASSERT(string_length_ != NULL); | 321 ASSERT(string_length_ != NULL); |
| 338 ASSERT(bad_certificate_callback_ == NULL); | 322 ASSERT(bad_certificate_callback_ == NULL); |
| 339 bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null()); | 323 bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null()); |
| 340 ASSERT(bad_certificate_callback_ != NULL); | 324 ASSERT(bad_certificate_callback_ != NULL); |
| 341 // Caller handles cleanup on an error. | 325 // Caller handles cleanup on an error. |
| 342 return InitializeBuffers(dart_this); | 326 return InitializeBuffers(dart_this); |
| 343 } | 327 } |
| 344 | 328 |
| 345 | |
| 346 Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) { | 329 Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) { |
| 347 // Create SSLFilter buffers as ExternalUint8Array objects. | 330 // Create SSLFilter buffers as ExternalUint8Array objects. |
| 348 Dart_Handle buffers_string = DartUtils::NewString("buffers"); | 331 Dart_Handle buffers_string = DartUtils::NewString("buffers"); |
| 349 RETURN_IF_ERROR(buffers_string); | 332 RETURN_IF_ERROR(buffers_string); |
| 350 Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string); | 333 Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string); |
| 351 RETURN_IF_ERROR(dart_buffers_object); | 334 RETURN_IF_ERROR(dart_buffers_object); |
| 352 Dart_Handle secure_filter_impl_type = Dart_InstanceGetType(dart_this); | 335 Dart_Handle secure_filter_impl_type = Dart_InstanceGetType(dart_this); |
| 353 RETURN_IF_ERROR(secure_filter_impl_type); | 336 RETURN_IF_ERROR(secure_filter_impl_type); |
| 354 Dart_Handle size_string = DartUtils::NewString("SIZE"); | 337 Dart_Handle size_string = DartUtils::NewString("SIZE"); |
| 355 RETURN_IF_ERROR(size_string); | 338 RETURN_IF_ERROR(size_string); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 result = Dart_SetField(result, data_identifier, data); | 397 result = Dart_SetField(result, data_identifier, data); |
| 415 if (Dart_IsError(result)) { | 398 if (Dart_IsError(result)) { |
| 416 break; | 399 break; |
| 417 } | 400 } |
| 418 } | 401 } |
| 419 | 402 |
| 420 // Caller handles cleanup on an error. | 403 // Caller handles cleanup on an error. |
| 421 return result; | 404 return result; |
| 422 } | 405 } |
| 423 | 406 |
| 424 | |
| 425 void SSLFilter::RegisterHandshakeCompleteCallback(Dart_Handle complete) { | 407 void SSLFilter::RegisterHandshakeCompleteCallback(Dart_Handle complete) { |
| 426 ASSERT(NULL == handshake_complete_); | 408 ASSERT(NULL == handshake_complete_); |
| 427 handshake_complete_ = Dart_NewPersistentHandle(complete); | 409 handshake_complete_ = Dart_NewPersistentHandle(complete); |
| 428 | 410 |
| 429 ASSERT(handshake_complete_ != NULL); | 411 ASSERT(handshake_complete_ != NULL); |
| 430 } | 412 } |
| 431 | 413 |
| 432 | |
| 433 void SSLFilter::RegisterBadCertificateCallback(Dart_Handle callback) { | 414 void SSLFilter::RegisterBadCertificateCallback(Dart_Handle callback) { |
| 434 ASSERT(bad_certificate_callback_ != NULL); | 415 ASSERT(bad_certificate_callback_ != NULL); |
| 435 Dart_DeletePersistentHandle(bad_certificate_callback_); | 416 Dart_DeletePersistentHandle(bad_certificate_callback_); |
| 436 bad_certificate_callback_ = Dart_NewPersistentHandle(callback); | 417 bad_certificate_callback_ = Dart_NewPersistentHandle(callback); |
| 437 ASSERT(bad_certificate_callback_ != NULL); | 418 ASSERT(bad_certificate_callback_ != NULL); |
| 438 } | 419 } |
| 439 | 420 |
| 440 | |
| 441 Dart_Handle SSLFilter::PeerCertificate() { | 421 Dart_Handle SSLFilter::PeerCertificate() { |
| 442 X509* ca = SSL_get_peer_certificate(ssl_); | 422 X509* ca = SSL_get_peer_certificate(ssl_); |
| 443 if (ca == NULL) { | 423 if (ca == NULL) { |
| 444 return Dart_Null(); | 424 return Dart_Null(); |
| 445 } | 425 } |
| 446 return X509Helper::WrappedX509Certificate(ca); | 426 return X509Helper::WrappedX509Certificate(ca); |
| 447 } | 427 } |
| 448 | 428 |
| 449 | |
| 450 void SSLFilter::InitializeLibrary() { | 429 void SSLFilter::InitializeLibrary() { |
| 451 MutexLocker locker(mutex_); | 430 MutexLocker locker(mutex_); |
| 452 if (!library_initialized_) { | 431 if (!library_initialized_) { |
| 453 SSL_library_init(); | 432 SSL_library_init(); |
| 454 filter_ssl_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); | 433 filter_ssl_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); |
| 455 ASSERT(filter_ssl_index >= 0); | 434 ASSERT(filter_ssl_index >= 0); |
| 456 library_initialized_ = true; | 435 library_initialized_ = true; |
| 457 } | 436 } |
| 458 } | 437 } |
| 459 | 438 |
| 460 | |
| 461 void SSLFilter::Connect(const char* hostname, | 439 void SSLFilter::Connect(const char* hostname, |
| 462 SSLCertContext* context, | 440 SSLCertContext* context, |
| 463 bool is_server, | 441 bool is_server, |
| 464 bool request_client_certificate, | 442 bool request_client_certificate, |
| 465 bool require_client_certificate, | 443 bool require_client_certificate, |
| 466 Dart_Handle protocols_handle) { | 444 Dart_Handle protocols_handle) { |
| 467 is_server_ = is_server; | 445 is_server_ = is_server; |
| 468 if (in_handshake_) { | 446 if (in_handshake_) { |
| 469 FATAL("Connect called twice on the same _SecureFilter."); | 447 FATAL("Connect called twice on the same _SecureFilter."); |
| 470 } | 448 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 // TODO(whesse): expect a needs-data error here. Handle other errors. | 510 // TODO(whesse): expect a needs-data error here. Handle other errors. |
| 533 error = SSL_get_error(ssl_, status); | 511 error = SSL_get_error(ssl_, status); |
| 534 if (SSL_LOG_STATUS) { | 512 if (SSL_LOG_STATUS) { |
| 535 Log::Print("SSL_connect error: %d\n", error); | 513 Log::Print("SSL_connect error: %d\n", error); |
| 536 } | 514 } |
| 537 } | 515 } |
| 538 } | 516 } |
| 539 Handshake(); | 517 Handshake(); |
| 540 } | 518 } |
| 541 | 519 |
| 542 | |
| 543 void SSLFilter::Handshake() { | 520 void SSLFilter::Handshake() { |
| 544 // Try and push handshake along. | 521 // Try and push handshake along. |
| 545 int status; | 522 int status; |
| 546 status = SSL_do_handshake(ssl_); | 523 status = SSL_do_handshake(ssl_); |
| 547 if (callback_error != NULL) { | 524 if (callback_error != NULL) { |
| 548 // The SSL_do_handshake will try performing a handshake and might call | 525 // The SSL_do_handshake will try performing a handshake and might call |
| 549 // a CertificateCallback. If the certificate validation | 526 // a CertificateCallback. If the certificate validation |
| 550 // failed the 'callback_error" will be set by the certificateCallback | 527 // failed the 'callback_error" will be set by the certificateCallback |
| 551 // logic and we propagate the error" | 528 // logic and we propagate the error" |
| 552 Dart_PropagateError(callback_error); | 529 Dart_PropagateError(callback_error); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 575 X509_NAME_print_ex_fp(stdout, s_name, 4, 0); | 552 X509_NAME_print_ex_fp(stdout, s_name, 4, 0); |
| 576 printf("\n"); | 553 printf("\n"); |
| 577 } | 554 } |
| 578 } | 555 } |
| 579 ThrowIfError(Dart_InvokeClosure( | 556 ThrowIfError(Dart_InvokeClosure( |
| 580 Dart_HandleFromPersistent(handshake_complete_), 0, NULL)); | 557 Dart_HandleFromPersistent(handshake_complete_), 0, NULL)); |
| 581 in_handshake_ = false; | 558 in_handshake_ = false; |
| 582 } | 559 } |
| 583 } | 560 } |
| 584 | 561 |
| 585 | |
| 586 void SSLFilter::GetSelectedProtocol(Dart_NativeArguments args) { | 562 void SSLFilter::GetSelectedProtocol(Dart_NativeArguments args) { |
| 587 const uint8_t* protocol; | 563 const uint8_t* protocol; |
| 588 unsigned length; | 564 unsigned length; |
| 589 SSL_get0_alpn_selected(ssl_, &protocol, &length); | 565 SSL_get0_alpn_selected(ssl_, &protocol, &length); |
| 590 if (length == 0) { | 566 if (length == 0) { |
| 591 Dart_SetReturnValue(args, Dart_Null()); | 567 Dart_SetReturnValue(args, Dart_Null()); |
| 592 } else { | 568 } else { |
| 593 Dart_SetReturnValue(args, Dart_NewStringFromUTF8(protocol, length)); | 569 Dart_SetReturnValue(args, Dart_NewStringFromUTF8(protocol, length)); |
| 594 } | 570 } |
| 595 } | 571 } |
| 596 | 572 |
| 597 | |
| 598 void SSLFilter::Renegotiate(bool use_session_cache, | 573 void SSLFilter::Renegotiate(bool use_session_cache, |
| 599 bool request_client_certificate, | 574 bool request_client_certificate, |
| 600 bool require_client_certificate) { | 575 bool require_client_certificate) { |
| 601 // The SSL_REQUIRE_CERTIFICATE option only takes effect if the | 576 // The SSL_REQUIRE_CERTIFICATE option only takes effect if the |
| 602 // SSL_REQUEST_CERTIFICATE option is also set, so set it. | 577 // SSL_REQUEST_CERTIFICATE option is also set, so set it. |
| 603 request_client_certificate = | 578 request_client_certificate = |
| 604 request_client_certificate || require_client_certificate; | 579 request_client_certificate || require_client_certificate; |
| 605 // TODO(24070, 24069): Implement setting the client certificate parameters, | 580 // TODO(24070, 24069): Implement setting the client certificate parameters, |
| 606 // and triggering rehandshake. | 581 // and triggering rehandshake. |
| 607 } | 582 } |
| 608 | 583 |
| 609 | |
| 610 void SSLFilter::FreeResources() { | 584 void SSLFilter::FreeResources() { |
| 611 if (ssl_ != NULL) { | 585 if (ssl_ != NULL) { |
| 612 SSL_free(ssl_); | 586 SSL_free(ssl_); |
| 613 ssl_ = NULL; | 587 ssl_ = NULL; |
| 614 } | 588 } |
| 615 if (socket_side_ != NULL) { | 589 if (socket_side_ != NULL) { |
| 616 BIO_free(socket_side_); | 590 BIO_free(socket_side_); |
| 617 socket_side_ = NULL; | 591 socket_side_ = NULL; |
| 618 } | 592 } |
| 619 if (hostname_ != NULL) { | 593 if (hostname_ != NULL) { |
| 620 free(hostname_); | 594 free(hostname_); |
| 621 hostname_ = NULL; | 595 hostname_ = NULL; |
| 622 } | 596 } |
| 623 for (int i = 0; i < kNumBuffers; ++i) { | 597 for (int i = 0; i < kNumBuffers; ++i) { |
| 624 if (buffers_[i] != NULL) { | 598 if (buffers_[i] != NULL) { |
| 625 delete[] buffers_[i]; | 599 delete[] buffers_[i]; |
| 626 buffers_[i] = NULL; | 600 buffers_[i] = NULL; |
| 627 } | 601 } |
| 628 } | 602 } |
| 629 } | 603 } |
| 630 | 604 |
| 631 | |
| 632 SSLFilter::~SSLFilter() { | 605 SSLFilter::~SSLFilter() { |
| 633 FreeResources(); | 606 FreeResources(); |
| 634 } | 607 } |
| 635 | 608 |
| 636 | |
| 637 void SSLFilter::Destroy() { | 609 void SSLFilter::Destroy() { |
| 638 for (int i = 0; i < kNumBuffers; ++i) { | 610 for (int i = 0; i < kNumBuffers; ++i) { |
| 639 if (dart_buffer_objects_[i] != NULL) { | 611 if (dart_buffer_objects_[i] != NULL) { |
| 640 Dart_DeletePersistentHandle(dart_buffer_objects_[i]); | 612 Dart_DeletePersistentHandle(dart_buffer_objects_[i]); |
| 641 dart_buffer_objects_[i] = NULL; | 613 dart_buffer_objects_[i] = NULL; |
| 642 } | 614 } |
| 643 } | 615 } |
| 644 if (string_start_ != NULL) { | 616 if (string_start_ != NULL) { |
| 645 Dart_DeletePersistentHandle(string_start_); | 617 Dart_DeletePersistentHandle(string_start_); |
| 646 string_start_ = NULL; | 618 string_start_ = NULL; |
| 647 } | 619 } |
| 648 if (string_length_ != NULL) { | 620 if (string_length_ != NULL) { |
| 649 Dart_DeletePersistentHandle(string_length_); | 621 Dart_DeletePersistentHandle(string_length_); |
| 650 string_length_ = NULL; | 622 string_length_ = NULL; |
| 651 } | 623 } |
| 652 if (handshake_complete_ != NULL) { | 624 if (handshake_complete_ != NULL) { |
| 653 Dart_DeletePersistentHandle(handshake_complete_); | 625 Dart_DeletePersistentHandle(handshake_complete_); |
| 654 handshake_complete_ = NULL; | 626 handshake_complete_ = NULL; |
| 655 } | 627 } |
| 656 if (bad_certificate_callback_ != NULL) { | 628 if (bad_certificate_callback_ != NULL) { |
| 657 Dart_DeletePersistentHandle(bad_certificate_callback_); | 629 Dart_DeletePersistentHandle(bad_certificate_callback_); |
| 658 bad_certificate_callback_ = NULL; | 630 bad_certificate_callback_ = NULL; |
| 659 } | 631 } |
| 660 FreeResources(); | 632 FreeResources(); |
| 661 } | 633 } |
| 662 | 634 |
| 663 | |
| 664 /* Read decrypted data from the filter to the circular buffer */ | 635 /* Read decrypted data from the filter to the circular buffer */ |
| 665 int SSLFilter::ProcessReadPlaintextBuffer(int start, int end) { | 636 int SSLFilter::ProcessReadPlaintextBuffer(int start, int end) { |
| 666 int length = end - start; | 637 int length = end - start; |
| 667 int bytes_processed = 0; | 638 int bytes_processed = 0; |
| 668 if (length > 0) { | 639 if (length > 0) { |
| 669 bytes_processed = SSL_read( | 640 bytes_processed = SSL_read( |
| 670 ssl_, reinterpret_cast<char*>((buffers_[kReadPlaintext] + start)), | 641 ssl_, reinterpret_cast<char*>((buffers_[kReadPlaintext] + start)), |
| 671 length); | 642 length); |
| 672 if (bytes_processed < 0) { | 643 if (bytes_processed < 0) { |
| 673 int error = SSL_get_error(ssl_, bytes_processed); | 644 int error = SSL_get_error(ssl_, bytes_processed); |
| 674 USE(error); | 645 USE(error); |
| 675 bytes_processed = 0; | 646 bytes_processed = 0; |
| 676 } | 647 } |
| 677 } | 648 } |
| 678 return bytes_processed; | 649 return bytes_processed; |
| 679 } | 650 } |
| 680 | 651 |
| 681 | |
| 682 int SSLFilter::ProcessWritePlaintextBuffer(int start, int end) { | 652 int SSLFilter::ProcessWritePlaintextBuffer(int start, int end) { |
| 683 int length = end - start; | 653 int length = end - start; |
| 684 int bytes_processed = | 654 int bytes_processed = |
| 685 SSL_write(ssl_, buffers_[kWritePlaintext] + start, length); | 655 SSL_write(ssl_, buffers_[kWritePlaintext] + start, length); |
| 686 if (bytes_processed < 0) { | 656 if (bytes_processed < 0) { |
| 687 if (SSL_LOG_DATA) { | 657 if (SSL_LOG_DATA) { |
| 688 Log::Print("SSL_write returned error %d\n", bytes_processed); | 658 Log::Print("SSL_write returned error %d\n", bytes_processed); |
| 689 } | 659 } |
| 690 return 0; | 660 return 0; |
| 691 } | 661 } |
| 692 return bytes_processed; | 662 return bytes_processed; |
| 693 } | 663 } |
| 694 | 664 |
| 695 | |
| 696 /* Read encrypted data from the circular buffer to the filter */ | 665 /* Read encrypted data from the circular buffer to the filter */ |
| 697 int SSLFilter::ProcessReadEncryptedBuffer(int start, int end) { | 666 int SSLFilter::ProcessReadEncryptedBuffer(int start, int end) { |
| 698 int length = end - start; | 667 int length = end - start; |
| 699 if (SSL_LOG_DATA) | 668 if (SSL_LOG_DATA) |
| 700 Log::Print("Entering ProcessReadEncryptedBuffer with %d bytes\n", length); | 669 Log::Print("Entering ProcessReadEncryptedBuffer with %d bytes\n", length); |
| 701 int bytes_processed = 0; | 670 int bytes_processed = 0; |
| 702 if (length > 0) { | 671 if (length > 0) { |
| 703 bytes_processed = | 672 bytes_processed = |
| 704 BIO_write(socket_side_, buffers_[kReadEncrypted] + start, length); | 673 BIO_write(socket_side_, buffers_[kReadEncrypted] + start, length); |
| 705 if (bytes_processed <= 0) { | 674 if (bytes_processed <= 0) { |
| 706 bool retry = BIO_should_retry(socket_side_); | 675 bool retry = BIO_should_retry(socket_side_); |
| 707 if (!retry) { | 676 if (!retry) { |
| 708 if (SSL_LOG_DATA) | 677 if (SSL_LOG_DATA) |
| 709 Log::Print("BIO_write failed in ReadEncryptedBuffer\n"); | 678 Log::Print("BIO_write failed in ReadEncryptedBuffer\n"); |
| 710 } | 679 } |
| 711 bytes_processed = 0; | 680 bytes_processed = 0; |
| 712 } | 681 } |
| 713 } | 682 } |
| 714 if (SSL_LOG_DATA) | 683 if (SSL_LOG_DATA) |
| 715 Log::Print("Leaving ProcessReadEncryptedBuffer wrote %d bytes\n", | 684 Log::Print("Leaving ProcessReadEncryptedBuffer wrote %d bytes\n", |
| 716 bytes_processed); | 685 bytes_processed); |
| 717 return bytes_processed; | 686 return bytes_processed; |
| 718 } | 687 } |
| 719 | 688 |
| 720 | |
| 721 int SSLFilter::ProcessWriteEncryptedBuffer(int start, int end) { | 689 int SSLFilter::ProcessWriteEncryptedBuffer(int start, int end) { |
| 722 int length = end - start; | 690 int length = end - start; |
| 723 int bytes_processed = 0; | 691 int bytes_processed = 0; |
| 724 if (length > 0) { | 692 if (length > 0) { |
| 725 bytes_processed = | 693 bytes_processed = |
| 726 BIO_read(socket_side_, buffers_[kWriteEncrypted] + start, length); | 694 BIO_read(socket_side_, buffers_[kWriteEncrypted] + start, length); |
| 727 if (bytes_processed < 0) { | 695 if (bytes_processed < 0) { |
| 728 if (SSL_LOG_DATA) | 696 if (SSL_LOG_DATA) |
| 729 Log::Print("WriteEncrypted BIO_read returned error %d\n", | 697 Log::Print("WriteEncrypted BIO_read returned error %d\n", |
| 730 bytes_processed); | 698 bytes_processed); |
| 731 return 0; | 699 return 0; |
| 732 } else { | 700 } else { |
| 733 if (SSL_LOG_DATA) | 701 if (SSL_LOG_DATA) |
| 734 Log::Print("WriteEncrypted BIO_read wrote %d bytes\n", | 702 Log::Print("WriteEncrypted BIO_read wrote %d bytes\n", |
| 735 bytes_processed); | 703 bytes_processed); |
| 736 } | 704 } |
| 737 } | 705 } |
| 738 return bytes_processed; | 706 return bytes_processed; |
| 739 } | 707 } |
| 740 | 708 |
| 741 } // namespace bin | 709 } // namespace bin |
| 742 } // namespace dart | 710 } // namespace dart |
| 743 | 711 |
| 744 #endif // !defined(DART_IO_DISABLED) && | 712 #endif // !defined(DART_IO_DISABLED) && |
| 745 // !defined(DART_IO_SECURE_SOCKET_DISABLED) | 713 // !defined(DART_IO_SECURE_SOCKET_DISABLED) |
| OLD | NEW |