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 11 matching lines...) Expand all Loading... | |
22 #include "bin/dartutils.h" | 22 #include "bin/dartutils.h" |
23 #include "bin/lockers.h" | 23 #include "bin/lockers.h" |
24 #include "bin/log.h" | 24 #include "bin/log.h" |
25 #include "bin/socket.h" | 25 #include "bin/socket.h" |
26 #include "bin/thread.h" | 26 #include "bin/thread.h" |
27 #include "bin/utils.h" | 27 #include "bin/utils.h" |
28 #include "platform/utils.h" | 28 #include "platform/utils.h" |
29 | 29 |
30 #include "include/dart_api.h" | 30 #include "include/dart_api.h" |
31 | 31 |
32 // Return the error from the containing function if handle is an error handle. | |
33 #define RETURN_IF_ERROR(handle) \ | |
34 { \ | |
35 Dart_Handle __handle = handle; \ | |
36 if (Dart_IsError((__handle))) { \ | |
37 return __handle; \ | |
38 } \ | |
39 } | |
40 | |
32 namespace dart { | 41 namespace dart { |
33 namespace bin { | 42 namespace bin { |
34 | 43 |
35 bool SSLFilter::library_initialized_ = false; | 44 bool SSLFilter::library_initialized_ = false; |
36 // To protect library initialization. | 45 // To protect library initialization. |
37 Mutex* SSLFilter::mutex_ = new Mutex(); | 46 Mutex* SSLFilter::mutex_ = new Mutex(); |
38 int SSLFilter::filter_ssl_index; | 47 int SSLFilter::filter_ssl_index; |
39 | 48 |
40 static const int kSSLFilterNativeFieldIndex = 0; | 49 static const int kSSLFilterNativeFieldIndex = 0; |
41 static const int kSecurityContextNativeFieldIndex = 0; | 50 static const int kSecurityContextNativeFieldIndex = 0; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 105 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
97 ASSERT(Dart_IsInstance(dart_this)); | 106 ASSERT(Dart_IsInstance(dart_this)); |
98 ThrowIfError(Dart_GetNativeInstanceField( | 107 ThrowIfError(Dart_GetNativeInstanceField( |
99 dart_this, | 108 dart_this, |
100 kSSLFilterNativeFieldIndex, | 109 kSSLFilterNativeFieldIndex, |
101 reinterpret_cast<intptr_t*>(&filter))); | 110 reinterpret_cast<intptr_t*>(&filter))); |
102 return filter; | 111 return filter; |
103 } | 112 } |
104 | 113 |
105 | 114 |
106 static void SetFilter(Dart_NativeArguments args, SSLFilter* filter) { | 115 static void DeleteFilter( |
107 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 116 void* isolate_data, |
108 ASSERT(Dart_IsInstance(dart_this)); | 117 Dart_WeakPersistentHandle handle, |
109 ThrowIfError(Dart_SetNativeInstanceField( | 118 void* context_pointer) { |
110 dart_this, | 119 SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer); |
111 kSSLFilterNativeFieldIndex, | 120 delete filter; |
112 reinterpret_cast<intptr_t>(filter))); | |
113 } | 121 } |
114 | 122 |
115 | 123 |
124 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { | |
125 ASSERT(filter != NULL); | |
126 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); | |
127 RETURN_IF_ERROR(dart_this); | |
128 ASSERT(Dart_IsInstance(dart_this)); | |
129 Dart_Handle err = Dart_SetNativeInstanceField( | |
130 dart_this, | |
131 kSSLFilterNativeFieldIndex, | |
132 reinterpret_cast<intptr_t>(filter)); | |
133 RETURN_IF_ERROR(err); | |
134 Dart_NewWeakPersistentHandle(dart_this, | |
135 reinterpret_cast<void*>(filter), | |
136 sizeof(*filter), | |
137 DeleteFilter); | |
138 return Dart_Null(); | |
139 } | |
140 | |
141 | |
116 static SSL_CTX* GetSecurityContext(Dart_NativeArguments args) { | 142 static SSL_CTX* GetSecurityContext(Dart_NativeArguments args) { |
117 SSL_CTX* context; | 143 SSL_CTX* context; |
118 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 144 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
119 ASSERT(Dart_IsInstance(dart_this)); | 145 ASSERT(Dart_IsInstance(dart_this)); |
120 ThrowIfError(Dart_GetNativeInstanceField( | 146 ThrowIfError(Dart_GetNativeInstanceField( |
121 dart_this, | 147 dart_this, |
122 kSecurityContextNativeFieldIndex, | 148 kSecurityContextNativeFieldIndex, |
123 reinterpret_cast<intptr_t*>(&context))); | 149 reinterpret_cast<intptr_t*>(&context))); |
124 return context; | 150 return context; |
125 } | 151 } |
126 | 152 |
127 | 153 |
128 static void FreeSecurityContext( | 154 static void FreeSecurityContext( |
129 void* isolate_data, | 155 void* isolate_data, |
130 Dart_WeakPersistentHandle handle, | 156 Dart_WeakPersistentHandle handle, |
131 void* context_pointer) { | 157 void* context_pointer) { |
132 SSL_CTX* context = static_cast<SSL_CTX*>(context_pointer); | 158 SSL_CTX* context = static_cast<SSL_CTX*>(context_pointer); |
133 SSL_CTX_free(context); | 159 SSL_CTX_free(context); |
134 } | 160 } |
135 | 161 |
136 | 162 |
137 static void SetSecurityContext(Dart_NativeArguments args, | 163 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, |
138 SSL_CTX* context) { | 164 SSL_CTX* context) { |
139 const int approximate_size_of_context = 1500; | 165 const int approximate_size_of_context = 1500; |
140 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 166 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); |
167 RETURN_IF_ERROR(dart_this); | |
141 ASSERT(Dart_IsInstance(dart_this)); | 168 ASSERT(Dart_IsInstance(dart_this)); |
142 ThrowIfError(Dart_SetNativeInstanceField( | 169 Dart_Handle err = Dart_SetNativeInstanceField( |
143 dart_this, | 170 dart_this, |
144 kSecurityContextNativeFieldIndex, | 171 kSecurityContextNativeFieldIndex, |
145 reinterpret_cast<intptr_t>(context))); | 172 reinterpret_cast<intptr_t>(context)); |
173 RETURN_IF_ERROR(err); | |
146 Dart_NewWeakPersistentHandle(dart_this, | 174 Dart_NewWeakPersistentHandle(dart_this, |
147 context, | 175 context, |
148 approximate_size_of_context, | 176 approximate_size_of_context, |
149 FreeSecurityContext); | 177 FreeSecurityContext); |
178 return Dart_Null(); | |
150 } | 179 } |
151 | 180 |
152 | 181 |
153 static X509* GetX509Certificate(Dart_NativeArguments args) { | 182 static X509* GetX509Certificate(Dart_NativeArguments args) { |
154 X509* certificate; | 183 X509* certificate; |
155 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 184 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
156 ASSERT(Dart_IsInstance(dart_this)); | 185 ASSERT(Dart_IsInstance(dart_this)); |
157 ThrowIfError(Dart_GetNativeInstanceField( | 186 ThrowIfError(Dart_GetNativeInstanceField( |
158 dart_this, | 187 dart_this, |
159 kX509NativeFieldIndex, | 188 kX509NativeFieldIndex, |
160 reinterpret_cast<intptr_t*>(&certificate))); | 189 reinterpret_cast<intptr_t*>(&certificate))); |
161 return certificate; | 190 return certificate; |
162 } | 191 } |
163 | 192 |
164 | 193 |
165 // Forward declaration. | 194 // Forward declaration. |
166 static void SetAlpnProtocolList(Dart_Handle protocols_handle, | 195 static void SetAlpnProtocolList(Dart_Handle protocols_handle, |
167 SSL* ssl, | 196 SSL* ssl, |
168 SSL_CTX* context, | 197 SSL_CTX* context, |
169 bool is_server); | 198 bool is_server); |
170 | 199 |
171 | 200 |
172 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) { | 201 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) { |
173 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 202 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
174 SSLFilter* filter = new SSLFilter; | 203 SSLFilter* filter = new SSLFilter(); |
175 SetFilter(args, filter); | 204 Dart_Handle err = SetFilter(args, filter); |
176 filter->Init(dart_this); | 205 if (Dart_IsError(err)) { |
206 delete filter; | |
207 Dart_PropagateError(err); | |
208 } | |
209 err = filter->Init(dart_this); | |
210 if (Dart_IsError(err)) { | |
211 // The finalizer was set up by SetFilter. It will delete `filter` if there | |
212 // is an error. | |
213 filter->Destroy(); | |
214 Dart_PropagateError(err); | |
215 } | |
177 } | 216 } |
178 | 217 |
179 | 218 |
180 void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) { | 219 void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) { |
181 Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 220 Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
182 Dart_Handle context_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); | 221 Dart_Handle context_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); |
183 bool is_server = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); | 222 bool is_server = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); |
184 bool request_client_certificate = | 223 bool request_client_certificate = |
185 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); | 224 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); |
186 bool require_client_certificate = | 225 bool require_client_certificate = |
(...skipping 21 matching lines...) Expand all Loading... | |
208 context, | 247 context, |
209 is_server, | 248 is_server, |
210 request_client_certificate, | 249 request_client_certificate, |
211 require_client_certificate, | 250 require_client_certificate, |
212 protocols_handle); | 251 protocols_handle); |
213 } | 252 } |
214 | 253 |
215 | 254 |
216 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { | 255 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { |
217 SSLFilter* filter = GetFilter(args); | 256 SSLFilter* filter = GetFilter(args); |
218 SetFilter(args, NULL); | 257 // The SSLFilter is deleted in the finalizer for the Dart object created by |
258 // SetFilter. There is no need to NULL-out the native field for the SSLFilter | |
259 // here because the SSLFilter won't be deleted until the finalizer for the | |
260 // Dart object runs while the Dart object is being GCd. This approach avoids a | |
261 // leak if Destroy isn't called, and avoids a NULL-dereference if Destroy is | |
262 // called more than once. | |
Ivan Posva
2016/03/02 06:17:21
Thanks!
| |
219 filter->Destroy(); | 263 filter->Destroy(); |
220 delete filter; | |
221 } | 264 } |
222 | 265 |
223 | 266 |
224 void FUNCTION_NAME(SecureSocket_Handshake)(Dart_NativeArguments args) { | 267 void FUNCTION_NAME(SecureSocket_Handshake)(Dart_NativeArguments args) { |
225 GetFilter(args)->Handshake(); | 268 GetFilter(args)->Handshake(); |
226 } | 269 } |
227 | 270 |
228 | 271 |
229 void FUNCTION_NAME(SecureSocket_GetSelectedProtocol)( | 272 void FUNCTION_NAME(SecureSocket_GetSelectedProtocol)( |
230 Dart_NativeArguments args) { | 273 Dart_NativeArguments args) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { | 307 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { |
265 Dart_ThrowException(DartUtils::NewDartArgumentError( | 308 Dart_ThrowException(DartUtils::NewDartArgumentError( |
266 "Illegal argument to RegisterBadCertificateCallback")); | 309 "Illegal argument to RegisterBadCertificateCallback")); |
267 } | 310 } |
268 GetFilter(args)->RegisterBadCertificateCallback(callback); | 311 GetFilter(args)->RegisterBadCertificateCallback(callback); |
269 } | 312 } |
270 | 313 |
271 | 314 |
272 void FUNCTION_NAME(SecureSocket_PeerCertificate) | 315 void FUNCTION_NAME(SecureSocket_PeerCertificate) |
273 (Dart_NativeArguments args) { | 316 (Dart_NativeArguments args) { |
274 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); | 317 Dart_Handle cert = ThrowIfError(GetFilter(args)->PeerCertificate()); |
318 Dart_SetReturnValue(args, cert); | |
275 } | 319 } |
276 | 320 |
277 | 321 |
278 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { | 322 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { |
279 intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args)); | 323 intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args)); |
280 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); | 324 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); |
281 } | 325 } |
282 | 326 |
283 | 327 |
328 static void ReleaseCertificate( | |
329 void* isolate_data, | |
330 Dart_WeakPersistentHandle handle, | |
331 void* context_pointer) { | |
332 X509* cert = reinterpret_cast<X509*>(context_pointer); | |
333 X509_free(cert); | |
334 } | |
335 | |
336 | |
337 // Returns the handle for a Dart object wrapping the X509 certificate object. | |
338 // The caller should own a reference to the X509 object whose reference count | |
339 // won't drop to zero before the ReleaseCertificate finalizer runs. | |
284 static Dart_Handle WrappedX509Certificate(X509* certificate) { | 340 static Dart_Handle WrappedX509Certificate(X509* certificate) { |
341 const intptr_t approximate_size_of_certificate = 1500; | |
285 if (certificate == NULL) { | 342 if (certificate == NULL) { |
286 return Dart_Null(); | 343 return Dart_Null(); |
287 } | 344 } |
288 Dart_Handle x509_type = | 345 Dart_Handle x509_type = |
289 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); | 346 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); |
290 if (Dart_IsError(x509_type)) { | 347 if (Dart_IsError(x509_type)) { |
348 X509_free(certificate); | |
291 return x509_type; | 349 return x509_type; |
292 } | 350 } |
293 Dart_Handle arguments[] = { NULL }; | 351 Dart_Handle arguments[] = { NULL }; |
294 Dart_Handle result = | 352 Dart_Handle result = |
295 Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments); | 353 Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments); |
296 if (Dart_IsError(result)) { | 354 if (Dart_IsError(result)) { |
355 X509_free(certificate); | |
297 return result; | 356 return result; |
298 } | 357 } |
299 ASSERT(Dart_IsInstance(result)); | 358 ASSERT(Dart_IsInstance(result)); |
300 Dart_Handle status = Dart_SetNativeInstanceField( | 359 Dart_Handle status = Dart_SetNativeInstanceField( |
301 result, | 360 result, |
302 kX509NativeFieldIndex, | 361 kX509NativeFieldIndex, |
303 reinterpret_cast<intptr_t>(certificate)); | 362 reinterpret_cast<intptr_t>(certificate)); |
304 if (Dart_IsError(status)) { | 363 if (Dart_IsError(status)) { |
364 X509_free(certificate); | |
305 return status; | 365 return status; |
306 } | 366 } |
367 Dart_NewWeakPersistentHandle(result, | |
368 reinterpret_cast<void*>(certificate), | |
369 approximate_size_of_certificate, | |
370 ReleaseCertificate); | |
307 return result; | 371 return result; |
308 } | 372 } |
309 | 373 |
310 | 374 |
311 int CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx) { | 375 int CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx) { |
312 if (preverify_ok == 1) { | 376 if (preverify_ok == 1) { |
313 return 1; | 377 return 1; |
314 } | 378 } |
315 Dart_Isolate isolate = Dart_CurrentIsolate(); | 379 Dart_Isolate isolate = Dart_CurrentIsolate(); |
316 if (isolate == NULL) { | 380 if (isolate == NULL) { |
317 FATAL("CertificateCallback called with no current isolate\n"); | 381 FATAL("CertificateCallback called with no current isolate\n"); |
318 } | 382 } |
319 X509* certificate = X509_STORE_CTX_get_current_cert(store_ctx); | 383 X509* certificate = X509_STORE_CTX_get_current_cert(store_ctx); |
320 int ssl_index = SSL_get_ex_data_X509_STORE_CTX_idx(); | 384 int ssl_index = SSL_get_ex_data_X509_STORE_CTX_idx(); |
321 SSL* ssl = static_cast<SSL*>( | 385 SSL* ssl = static_cast<SSL*>( |
322 X509_STORE_CTX_get_ex_data(store_ctx, ssl_index)); | 386 X509_STORE_CTX_get_ex_data(store_ctx, ssl_index)); |
323 SSLFilter* filter = static_cast<SSLFilter*>( | 387 SSLFilter* filter = static_cast<SSLFilter*>( |
324 SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index)); | 388 SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index)); |
325 Dart_Handle callback = filter->bad_certificate_callback(); | 389 Dart_Handle callback = filter->bad_certificate_callback(); |
326 if (Dart_IsNull(callback)) { | 390 if (Dart_IsNull(callback)) { |
327 return 0; | 391 return 0; |
328 } | 392 } |
393 | |
394 // Upref since the Dart X509 object may outlive the SecurityContext. | |
395 if (certificate != NULL) { | |
396 X509_up_ref(certificate); | |
397 } | |
329 Dart_Handle args[1]; | 398 Dart_Handle args[1]; |
330 args[0] = WrappedX509Certificate(certificate); | 399 args[0] = WrappedX509Certificate(certificate); |
331 if (Dart_IsError(args[0])) { | 400 if (Dart_IsError(args[0])) { |
332 filter->callback_error = args[0]; | 401 filter->callback_error = args[0]; |
333 return 0; | 402 return 0; |
334 } | 403 } |
335 Dart_Handle result = Dart_InvokeClosure(callback, 1, args); | 404 Dart_Handle result = Dart_InvokeClosure(callback, 1, args); |
336 if (!Dart_IsError(result) && !Dart_IsBoolean(result)) { | 405 if (!Dart_IsError(result) && !Dart_IsBoolean(result)) { |
337 result = Dart_NewUnhandledExceptionError(DartUtils::NewDartIOException( | 406 result = Dart_NewUnhandledExceptionError(DartUtils::NewDartIOException( |
338 "HandshakeException", | 407 "HandshakeException", |
339 "BadCertificateCallback returned a value that was not a boolean", | 408 "BadCertificateCallback returned a value that was not a boolean", |
340 Dart_Null())); | 409 Dart_Null())); |
341 } | 410 } |
342 if (Dart_IsError(result)) { | 411 if (Dart_IsError(result)) { |
343 filter->callback_error = result; | 412 filter->callback_error = result; |
344 return 0; | 413 return 0; |
345 } | 414 } |
346 return DartUtils::GetBooleanValue(result); | 415 return DartUtils::GetBooleanValue(result); |
347 } | 416 } |
348 | 417 |
349 | 418 |
350 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) { | 419 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) { |
351 SSLFilter::InitializeLibrary(); | 420 SSLFilter::InitializeLibrary(); |
352 SSL_CTX* context = SSL_CTX_new(TLS_method()); | 421 SSL_CTX* context = SSL_CTX_new(TLS_method()); |
353 SSL_CTX_set_verify(context, SSL_VERIFY_PEER, CertificateCallback); | 422 SSL_CTX_set_verify(context, SSL_VERIFY_PEER, CertificateCallback); |
354 SSL_CTX_set_min_version(context, TLS1_VERSION); | 423 SSL_CTX_set_min_version(context, TLS1_VERSION); |
355 SSL_CTX_set_cipher_list(context, "HIGH:MEDIUM"); | 424 SSL_CTX_set_cipher_list(context, "HIGH:MEDIUM"); |
356 SSL_CTX_set_cipher_list_tls11(context, "HIGH:MEDIUM"); | 425 SSL_CTX_set_cipher_list_tls11(context, "HIGH:MEDIUM"); |
357 SetSecurityContext(args, context); | 426 Dart_Handle err = SetSecurityContext(args, context); |
427 if (Dart_IsError(err)) { | |
428 SSL_CTX_free(context); | |
429 Dart_PropagateError(err); | |
430 } | |
358 } | 431 } |
359 | 432 |
360 | 433 |
361 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) { | 434 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) { |
362 char* password = static_cast<char*>(userdata); | 435 char* password = static_cast<char*>(userdata); |
363 ASSERT(size == PEM_BUFSIZE); | 436 ASSERT(size == PEM_BUFSIZE); |
364 strncpy(buf, password, size); | 437 strncpy(buf, password, size); |
365 return strlen(password); | 438 return strlen(password); |
366 } | 439 } |
367 | 440 |
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1147 starts[i] = start; | 1220 starts[i] = start; |
1148 break; | 1221 break; |
1149 default: | 1222 default: |
1150 UNREACHABLE(); | 1223 UNREACHABLE(); |
1151 } | 1224 } |
1152 } | 1225 } |
1153 return true; | 1226 return true; |
1154 } | 1227 } |
1155 | 1228 |
1156 | 1229 |
1157 void SSLFilter::Init(Dart_Handle dart_this) { | 1230 Dart_Handle SSLFilter::Init(Dart_Handle dart_this) { |
1158 if (!library_initialized_) { | 1231 if (!library_initialized_) { |
1159 InitializeLibrary(); | 1232 InitializeLibrary(); |
1160 } | 1233 } |
1161 ASSERT(string_start_ == NULL); | 1234 ASSERT(string_start_ == NULL); |
1162 string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start")); | 1235 string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start")); |
1163 ASSERT(string_start_ != NULL); | 1236 ASSERT(string_start_ != NULL); |
1164 ASSERT(string_length_ == NULL); | 1237 ASSERT(string_length_ == NULL); |
1165 string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length")); | 1238 string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length")); |
1166 ASSERT(string_length_ != NULL); | 1239 ASSERT(string_length_ != NULL); |
1167 ASSERT(bad_certificate_callback_ == NULL); | 1240 ASSERT(bad_certificate_callback_ == NULL); |
1168 bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null()); | 1241 bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null()); |
1169 ASSERT(bad_certificate_callback_ != NULL); | 1242 ASSERT(bad_certificate_callback_ != NULL); |
1170 | 1243 |
1171 InitializeBuffers(dart_this); | 1244 // Caller handles cleanup on an error. |
1245 return InitializeBuffers(dart_this); | |
1172 } | 1246 } |
1173 | 1247 |
1174 | 1248 |
1175 void SSLFilter::InitializeBuffers(Dart_Handle dart_this) { | 1249 Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) { |
1176 // Create SSLFilter buffers as ExternalUint8Array objects. | 1250 // Create SSLFilter buffers as ExternalUint8Array objects. |
1177 Dart_Handle dart_buffers_object = ThrowIfError( | 1251 Dart_Handle buffers_string = DartUtils::NewString("buffers"); |
1178 Dart_GetField(dart_this, DartUtils::NewString("buffers"))); | 1252 RETURN_IF_ERROR(buffers_string); |
1179 Dart_Handle secure_filter_impl_type = | 1253 Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string); |
1180 Dart_InstanceGetType(dart_this); | 1254 RETURN_IF_ERROR(dart_buffers_object); |
1181 Dart_Handle dart_buffer_size = ThrowIfError( | 1255 Dart_Handle secure_filter_impl_type = Dart_InstanceGetType(dart_this); |
1182 Dart_GetField(secure_filter_impl_type, DartUtils::NewString("SIZE"))); | 1256 RETURN_IF_ERROR(secure_filter_impl_type); |
1183 int64_t buffer_size = DartUtils::GetIntegerValue(dart_buffer_size); | 1257 Dart_Handle size_string = DartUtils::NewString("SIZE"); |
1184 Dart_Handle dart_encrypted_buffer_size = ThrowIfError( | 1258 RETURN_IF_ERROR(size_string); |
1185 Dart_GetField(secure_filter_impl_type, | 1259 Dart_Handle dart_buffer_size = Dart_GetField( |
1186 DartUtils::NewString("ENCRYPTED_SIZE"))); | 1260 secure_filter_impl_type, size_string); |
1187 int64_t encrypted_buffer_size = | 1261 RETURN_IF_ERROR(dart_buffer_size); |
1188 DartUtils::GetIntegerValue(dart_encrypted_buffer_size); | 1262 |
1263 int64_t buffer_size = 0; | |
1264 Dart_Handle err = Dart_IntegerToInt64(dart_buffer_size, &buffer_size); | |
1265 RETURN_IF_ERROR(err); | |
1266 | |
1267 Dart_Handle encrypted_size_string = DartUtils::NewString("ENCRYPTED_SIZE"); | |
1268 RETURN_IF_ERROR(encrypted_size_string); | |
1269 | |
1270 Dart_Handle dart_encrypted_buffer_size = Dart_GetField( | |
1271 secure_filter_impl_type, encrypted_size_string); | |
1272 RETURN_IF_ERROR(dart_encrypted_buffer_size); | |
1273 | |
1274 int64_t encrypted_buffer_size = 0; | |
1275 err = Dart_IntegerToInt64(dart_encrypted_buffer_size, &encrypted_buffer_size); | |
1276 RETURN_IF_ERROR(err); | |
1277 | |
1189 if (buffer_size <= 0 || buffer_size > 1 * MB) { | 1278 if (buffer_size <= 0 || buffer_size > 1 * MB) { |
1190 FATAL("Invalid buffer size in _ExternalBuffer"); | 1279 FATAL("Invalid buffer size in _ExternalBuffer"); |
1191 } | 1280 } |
1192 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 * MB) { | 1281 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 * MB) { |
1193 FATAL("Invalid encrypted buffer size in _ExternalBuffer"); | 1282 FATAL("Invalid encrypted buffer size in _ExternalBuffer"); |
1194 } | 1283 } |
1195 buffer_size_ = static_cast<int>(buffer_size); | 1284 buffer_size_ = static_cast<int>(buffer_size); |
1196 encrypted_buffer_size_ = static_cast<int>(encrypted_buffer_size); | 1285 encrypted_buffer_size_ = static_cast<int>(encrypted_buffer_size); |
1197 | 1286 |
1287 Dart_Handle data_identifier = DartUtils::NewString("data"); | |
1288 RETURN_IF_ERROR(data_identifier); | |
1198 | 1289 |
1199 Dart_Handle data_identifier = DartUtils::NewString("data"); | 1290 for (int i = 0; i < kNumBuffers; i++) { |
1291 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; | |
1292 buffers_[i] = new uint8_t[size]; | |
1293 ASSERT(buffers_[i] != NULL); | |
1294 dart_buffer_objects_[i] = NULL; | |
1295 } | |
1296 | |
1297 Dart_Handle result = Dart_Null(); | |
1200 for (int i = 0; i < kNumBuffers; ++i) { | 1298 for (int i = 0; i < kNumBuffers; ++i) { |
1201 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; | 1299 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; |
1202 dart_buffer_objects_[i] = | 1300 result = Dart_ListGetAt(dart_buffers_object, i); |
1203 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i)); | 1301 if (Dart_IsError(result)) { |
1302 break; | |
1303 } | |
1304 | |
1305 dart_buffer_objects_[i] = Dart_NewPersistentHandle(result); | |
1204 ASSERT(dart_buffer_objects_[i] != NULL); | 1306 ASSERT(dart_buffer_objects_[i] != NULL); |
1205 buffers_[i] = new uint8_t[size]; | 1307 Dart_Handle data = |
1206 Dart_Handle data = ThrowIfError( | 1308 Dart_NewExternalTypedData(Dart_TypedData_kUint8, buffers_[i], size); |
1207 Dart_NewExternalTypedData(Dart_TypedData_kUint8, buffers_[i], size)); | 1309 if (Dart_IsError(data)) { |
1208 ThrowIfError( | 1310 result = data; |
1209 Dart_SetField(Dart_HandleFromPersistent(dart_buffer_objects_[i]), | 1311 break; |
1210 data_identifier, | 1312 } |
1211 data)); | 1313 result = Dart_HandleFromPersistent(dart_buffer_objects_[i]); |
1314 if (Dart_IsError(result)) { | |
1315 break; | |
1316 } | |
1317 result = Dart_SetField(result, data_identifier, data); | |
1318 if (Dart_IsError(result)) { | |
1319 break; | |
1320 } | |
1212 } | 1321 } |
1322 | |
1323 // Caller handles cleanup on an error. | |
1324 return result; | |
1213 } | 1325 } |
1214 | 1326 |
1215 | 1327 |
1216 void SSLFilter::RegisterHandshakeCompleteCallback(Dart_Handle complete) { | 1328 void SSLFilter::RegisterHandshakeCompleteCallback(Dart_Handle complete) { |
1217 ASSERT(NULL == handshake_complete_); | 1329 ASSERT(NULL == handshake_complete_); |
1218 handshake_complete_ = Dart_NewPersistentHandle(complete); | 1330 handshake_complete_ = Dart_NewPersistentHandle(complete); |
1219 | 1331 |
1220 ASSERT(handshake_complete_ != NULL); | 1332 ASSERT(handshake_complete_ != NULL); |
1221 } | 1333 } |
1222 | 1334 |
(...skipping 11 matching lines...) Expand all Loading... | |
1234 if (!library_initialized_) { | 1346 if (!library_initialized_) { |
1235 SSL_library_init(); | 1347 SSL_library_init(); |
1236 filter_ssl_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); | 1348 filter_ssl_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); |
1237 ASSERT(filter_ssl_index >= 0); | 1349 ASSERT(filter_ssl_index >= 0); |
1238 library_initialized_ = true; | 1350 library_initialized_ = true; |
1239 } | 1351 } |
1240 } | 1352 } |
1241 | 1353 |
1242 | 1354 |
1243 Dart_Handle SSLFilter::PeerCertificate() { | 1355 Dart_Handle SSLFilter::PeerCertificate() { |
1356 // SSL_get_peer_certificate incs the refcount of certificate. X509_free is | |
1357 // called by the finalizer set up by WrappedX509Certificate. | |
1244 X509* certificate = SSL_get_peer_certificate(ssl_); | 1358 X509* certificate = SSL_get_peer_certificate(ssl_); |
1245 Dart_Handle x509_object = WrappedX509Certificate(certificate); | 1359 return WrappedX509Certificate(certificate); |
1246 if (Dart_IsError(x509_object)) { | |
1247 Dart_PropagateError(x509_object); | |
1248 } | |
1249 return x509_object; | |
1250 } | 1360 } |
1251 | 1361 |
1252 | 1362 |
1253 int AlpnCallback(SSL *ssl, | 1363 int AlpnCallback(SSL *ssl, |
1254 const uint8_t **out, | 1364 const uint8_t **out, |
1255 uint8_t *outlen, | 1365 uint8_t *outlen, |
1256 const uint8_t *in, | 1366 const uint8_t *in, |
1257 unsigned int inlen, | 1367 unsigned int inlen, |
1258 void *arg) { | 1368 void *arg) { |
1259 // 'in' and 'arg' are sequences of (length, data) strings with 1-byte lengths. | 1369 // 'in' and 'arg' are sequences of (length, data) strings with 1-byte lengths. |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1477 bool require_client_certificate) { | 1587 bool require_client_certificate) { |
1478 // The SSL_REQUIRE_CERTIFICATE option only takes effect if the | 1588 // The SSL_REQUIRE_CERTIFICATE option only takes effect if the |
1479 // SSL_REQUEST_CERTIFICATE option is also set, so set it. | 1589 // SSL_REQUEST_CERTIFICATE option is also set, so set it. |
1480 request_client_certificate = | 1590 request_client_certificate = |
1481 request_client_certificate || require_client_certificate; | 1591 request_client_certificate || require_client_certificate; |
1482 // TODO(24070, 24069): Implement setting the client certificate parameters, | 1592 // TODO(24070, 24069): Implement setting the client certificate parameters, |
1483 // and triggering rehandshake. | 1593 // and triggering rehandshake. |
1484 } | 1594 } |
1485 | 1595 |
1486 | 1596 |
1487 void SSLFilter::Destroy() { | 1597 SSLFilter::~SSLFilter() { |
1488 if (ssl_ != NULL) { | 1598 if (ssl_ != NULL) { |
1489 SSL_free(ssl_); | 1599 SSL_free(ssl_); |
1490 ssl_ = NULL; | 1600 ssl_ = NULL; |
1491 } | 1601 } |
1492 if (socket_side_ != NULL) { | 1602 if (socket_side_ != NULL) { |
1493 BIO_free(socket_side_); | 1603 BIO_free(socket_side_); |
1494 socket_side_ = NULL; | 1604 socket_side_ = NULL; |
1495 } | 1605 } |
1496 if (hostname_ != NULL) { | 1606 if (hostname_ != NULL) { |
1497 free(hostname_); | 1607 free(hostname_); |
1498 hostname_ = NULL; | 1608 hostname_ = NULL; |
1499 } | 1609 } |
1500 for (int i = 0; i < kNumBuffers; ++i) { | 1610 for (int i = 0; i < kNumBuffers; ++i) { |
1501 Dart_DeletePersistentHandle(dart_buffer_objects_[i]); | 1611 if (buffers_[i] != NULL) { |
1502 delete[] buffers_[i]; | 1612 delete[] buffers_[i]; |
1613 buffers_[i] = NULL; | |
1614 } | |
1503 } | 1615 } |
1504 Dart_DeletePersistentHandle(string_start_); | |
1505 Dart_DeletePersistentHandle(string_length_); | |
1506 Dart_DeletePersistentHandle(handshake_complete_); | |
1507 Dart_DeletePersistentHandle(bad_certificate_callback_); | |
1508 } | 1616 } |
1509 | 1617 |
1510 | 1618 |
1619 void SSLFilter::Destroy() { | |
1620 for (int i = 0; i < kNumBuffers; ++i) { | |
1621 if (dart_buffer_objects_[i] != NULL) { | |
1622 Dart_DeletePersistentHandle(dart_buffer_objects_[i]); | |
1623 dart_buffer_objects_[i] = NULL; | |
1624 } | |
1625 } | |
1626 if (string_start_ != NULL) { | |
1627 Dart_DeletePersistentHandle(string_start_); | |
1628 string_start_ = NULL; | |
1629 } | |
1630 if (string_length_ != NULL) { | |
1631 Dart_DeletePersistentHandle(string_length_); | |
1632 string_length_ = NULL; | |
1633 } | |
1634 if (handshake_complete_ != NULL) { | |
1635 Dart_DeletePersistentHandle(handshake_complete_); | |
1636 handshake_complete_ = NULL; | |
1637 } | |
1638 if (bad_certificate_callback_ != NULL) { | |
1639 Dart_DeletePersistentHandle(bad_certificate_callback_); | |
1640 bad_certificate_callback_ = NULL; | |
1641 } | |
1642 } | |
1643 | |
1644 | |
1511 /* Read decrypted data from the filter to the circular buffer */ | 1645 /* Read decrypted data from the filter to the circular buffer */ |
1512 int SSLFilter::ProcessReadPlaintextBuffer(int start, int end) { | 1646 int SSLFilter::ProcessReadPlaintextBuffer(int start, int end) { |
1513 int length = end - start; | 1647 int length = end - start; |
1514 int bytes_processed = 0; | 1648 int bytes_processed = 0; |
1515 if (length > 0) { | 1649 if (length > 0) { |
1516 bytes_processed = SSL_read( | 1650 bytes_processed = SSL_read( |
1517 ssl_, | 1651 ssl_, |
1518 reinterpret_cast<char*>((buffers_[kReadPlaintext] + start)), | 1652 reinterpret_cast<char*>((buffers_[kReadPlaintext] + start)), |
1519 length); | 1653 length); |
1520 if (bytes_processed < 0) { | 1654 if (bytes_processed < 0) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1579 } else { | 1713 } else { |
1580 if (SSL_LOG_DATA) Log::Print( | 1714 if (SSL_LOG_DATA) Log::Print( |
1581 "WriteEncrypted BIO_read wrote %d bytes\n", bytes_processed); | 1715 "WriteEncrypted BIO_read wrote %d bytes\n", bytes_processed); |
1582 } | 1716 } |
1583 } | 1717 } |
1584 return bytes_processed; | 1718 return bytes_processed; |
1585 } | 1719 } |
1586 | 1720 |
1587 } // namespace bin | 1721 } // namespace bin |
1588 } // namespace dart | 1722 } // namespace dart |
OLD | NEW |