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 #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 "platform/globals.h" | 7 #include "platform/globals.h" |
8 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) || \ | 8 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) || \ |
9 defined(TARGET_OS_WINDOWS) || defined(TARGET_OS_FUCHSIA) | 9 defined(TARGET_OS_WINDOWS) || defined(TARGET_OS_FUCHSIA) |
10 | 10 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 } | 48 } |
49 | 49 |
50 namespace dart { | 50 namespace dart { |
51 namespace bin { | 51 namespace bin { |
52 | 52 |
53 bool SSLFilter::library_initialized_ = false; | 53 bool SSLFilter::library_initialized_ = false; |
54 // To protect library initialization. | 54 // To protect library initialization. |
55 Mutex* SSLFilter::mutex_ = new Mutex(); | 55 Mutex* SSLFilter::mutex_ = new Mutex(); |
56 int SSLFilter::filter_ssl_index; | 56 int SSLFilter::filter_ssl_index; |
57 | 57 |
| 58 const intptr_t SSLFilter::kInternalBIOSize = 10 * KB; |
| 59 const intptr_t SSLFilter::kApproximateSize = |
| 60 sizeof(SSLFilter) + (2 * SSLFilter::kInternalBIOSize); |
| 61 |
| 62 // The security context won't necessarily use the compiled-in root certificates, |
| 63 // but since there is no way to update the size of the allocation after creating |
| 64 // the weak persistent handle, we assume that it will. Note that when the |
| 65 // root certs aren't compiled in, |root_certificates_pem_length| is 0. |
| 66 const intptr_t SSLContext::kApproximateSize = |
| 67 sizeof(SSLContext) + root_certificates_pem_length; |
| 68 |
58 static const int kSSLFilterNativeFieldIndex = 0; | 69 static const int kSSLFilterNativeFieldIndex = 0; |
59 static const int kSecurityContextNativeFieldIndex = 0; | 70 static const int kSecurityContextNativeFieldIndex = 0; |
60 static const int kX509NativeFieldIndex = 0; | 71 static const int kX509NativeFieldIndex = 0; |
61 | 72 |
62 static const bool SSL_LOG_STATUS = false; | 73 static const bool SSL_LOG_STATUS = false; |
63 static const bool SSL_LOG_DATA = false; | 74 static const bool SSL_LOG_DATA = false; |
64 | 75 |
65 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000; | 76 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000; |
66 | 77 |
67 | |
68 const char* commandline_root_certs_file = NULL; | 78 const char* commandline_root_certs_file = NULL; |
69 const char* commandline_root_certs_cache = NULL; | 79 const char* commandline_root_certs_cache = NULL; |
70 | 80 |
71 | |
72 /* Get the error messages from BoringSSL, and put them in buffer as a | 81 /* Get the error messages from BoringSSL, and put them in buffer as a |
73 * null-terminated string. */ | 82 * null-terminated string. */ |
74 static void FetchErrorString(char* buffer, int length) { | 83 static void FetchErrorString(char* buffer, int length) { |
75 buffer[0] = '\0'; | 84 buffer[0] = '\0'; |
76 int error = ERR_get_error(); | 85 int error = ERR_get_error(); |
77 while (error != 0) { | 86 while (error != 0) { |
78 int used = strlen(buffer); | 87 int used = strlen(buffer); |
79 int free_length = length - used; | 88 int free_length = length - used; |
80 if (free_length > 16) { | 89 if (free_length > 16) { |
81 // Enough room for error code at least. | 90 // Enough room for error code at least. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { | 143 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { |
135 ASSERT(filter != NULL); | 144 ASSERT(filter != NULL); |
136 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); | 145 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); |
137 RETURN_IF_ERROR(dart_this); | 146 RETURN_IF_ERROR(dart_this); |
138 ASSERT(Dart_IsInstance(dart_this)); | 147 ASSERT(Dart_IsInstance(dart_this)); |
139 Dart_Handle err = | 148 Dart_Handle err = |
140 Dart_SetNativeInstanceField(dart_this, kSSLFilterNativeFieldIndex, | 149 Dart_SetNativeInstanceField(dart_this, kSSLFilterNativeFieldIndex, |
141 reinterpret_cast<intptr_t>(filter)); | 150 reinterpret_cast<intptr_t>(filter)); |
142 RETURN_IF_ERROR(err); | 151 RETURN_IF_ERROR(err); |
143 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(filter), | 152 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(filter), |
144 sizeof(*filter), DeleteFilter); | 153 SSLFilter::kApproximateSize, DeleteFilter); |
145 return Dart_Null(); | 154 return Dart_Null(); |
146 } | 155 } |
147 | 156 |
148 | 157 |
149 static SSLContext* GetSecurityContext(Dart_NativeArguments args) { | 158 static SSLContext* GetSecurityContext(Dart_NativeArguments args) { |
150 SSLContext* context; | 159 SSLContext* context; |
151 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 160 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
152 ASSERT(Dart_IsInstance(dart_this)); | 161 ASSERT(Dart_IsInstance(dart_this)); |
153 ThrowIfError( | 162 ThrowIfError( |
154 Dart_GetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, | 163 Dart_GetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, |
155 reinterpret_cast<intptr_t*>(&context))); | 164 reinterpret_cast<intptr_t*>(&context))); |
156 return context; | 165 return context; |
157 } | 166 } |
158 | 167 |
159 | 168 |
160 static void DeleteSecurityContext(void* isolate_data, | 169 static void DeleteSecurityContext(void* isolate_data, |
161 Dart_WeakPersistentHandle handle, | 170 Dart_WeakPersistentHandle handle, |
162 void* context_pointer) { | 171 void* context_pointer) { |
163 SSLContext* context = static_cast<SSLContext*>(context_pointer); | 172 SSLContext* context = static_cast<SSLContext*>(context_pointer); |
164 delete context; | 173 delete context; |
165 } | 174 } |
166 | 175 |
167 | 176 |
168 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, | 177 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, |
169 SSLContext* context) { | 178 SSLContext* context) { |
170 const int approximate_size_of_context = 1500; | |
171 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); | 179 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); |
172 RETURN_IF_ERROR(dart_this); | 180 RETURN_IF_ERROR(dart_this); |
173 ASSERT(Dart_IsInstance(dart_this)); | 181 ASSERT(Dart_IsInstance(dart_this)); |
174 Dart_Handle err = | 182 Dart_Handle err = |
175 Dart_SetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, | 183 Dart_SetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, |
176 reinterpret_cast<intptr_t>(context)); | 184 reinterpret_cast<intptr_t>(context)); |
177 RETURN_IF_ERROR(err); | 185 RETURN_IF_ERROR(err); |
178 Dart_NewWeakPersistentHandle(dart_this, context, approximate_size_of_context, | 186 Dart_NewWeakPersistentHandle(dart_this, context, SSLContext::kApproximateSize, |
179 DeleteSecurityContext); | 187 DeleteSecurityContext); |
180 return Dart_Null(); | 188 return Dart_Null(); |
181 } | 189 } |
182 | 190 |
183 | 191 |
184 static X509* GetX509Certificate(Dart_NativeArguments args) { | 192 static X509* GetX509Certificate(Dart_NativeArguments args) { |
185 X509* certificate; | 193 X509* certificate; |
186 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 194 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
187 ASSERT(Dart_IsInstance(dart_this)); | 195 ASSERT(Dart_IsInstance(dart_this)); |
188 ThrowIfError( | 196 ThrowIfError( |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 | 331 |
324 | 332 |
325 static void ReleaseCertificate(void* isolate_data, | 333 static void ReleaseCertificate(void* isolate_data, |
326 Dart_WeakPersistentHandle handle, | 334 Dart_WeakPersistentHandle handle, |
327 void* context_pointer) { | 335 void* context_pointer) { |
328 X509* cert = reinterpret_cast<X509*>(context_pointer); | 336 X509* cert = reinterpret_cast<X509*>(context_pointer); |
329 X509_free(cert); | 337 X509_free(cert); |
330 } | 338 } |
331 | 339 |
332 | 340 |
| 341 static intptr_t EstimateX509Size(X509* certificate) { |
| 342 intptr_t length = i2d_X509(certificate, NULL); |
| 343 return length > 0 ? length : 0; |
| 344 } |
| 345 |
| 346 |
333 // Returns the handle for a Dart object wrapping the X509 certificate object. | 347 // Returns the handle for a Dart object wrapping the X509 certificate object. |
334 // The caller should own a reference to the X509 object whose reference count | 348 // The caller should own a reference to the X509 object whose reference count |
335 // won't drop to zero before the ReleaseCertificate finalizer runs. | 349 // won't drop to zero before the ReleaseCertificate finalizer runs. |
336 static Dart_Handle WrappedX509Certificate(X509* certificate) { | 350 static Dart_Handle WrappedX509Certificate(X509* certificate) { |
337 const intptr_t approximate_size_of_certificate = 1500; | |
338 if (certificate == NULL) { | 351 if (certificate == NULL) { |
339 return Dart_Null(); | 352 return Dart_Null(); |
340 } | 353 } |
341 Dart_Handle x509_type = | 354 Dart_Handle x509_type = |
342 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); | 355 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); |
343 if (Dart_IsError(x509_type)) { | 356 if (Dart_IsError(x509_type)) { |
344 X509_free(certificate); | 357 X509_free(certificate); |
345 return x509_type; | 358 return x509_type; |
346 } | 359 } |
347 Dart_Handle arguments[] = {NULL}; | 360 Dart_Handle arguments[] = {NULL}; |
348 Dart_Handle result = | 361 Dart_Handle result = |
349 Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments); | 362 Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments); |
350 if (Dart_IsError(result)) { | 363 if (Dart_IsError(result)) { |
351 X509_free(certificate); | 364 X509_free(certificate); |
352 return result; | 365 return result; |
353 } | 366 } |
354 ASSERT(Dart_IsInstance(result)); | 367 ASSERT(Dart_IsInstance(result)); |
355 Dart_Handle status = Dart_SetNativeInstanceField( | 368 Dart_Handle status = Dart_SetNativeInstanceField( |
356 result, kX509NativeFieldIndex, reinterpret_cast<intptr_t>(certificate)); | 369 result, kX509NativeFieldIndex, reinterpret_cast<intptr_t>(certificate)); |
357 if (Dart_IsError(status)) { | 370 if (Dart_IsError(status)) { |
358 X509_free(certificate); | 371 X509_free(certificate); |
359 return status; | 372 return status; |
360 } | 373 } |
| 374 const intptr_t approximate_size_of_certificate = |
| 375 sizeof(*certificate) + EstimateX509Size(certificate); |
| 376 ASSERT(approximate_size_of_certificate > 0); |
361 Dart_NewWeakPersistentHandle(result, reinterpret_cast<void*>(certificate), | 377 Dart_NewWeakPersistentHandle(result, reinterpret_cast<void*>(certificate), |
362 approximate_size_of_certificate, | 378 approximate_size_of_certificate, |
363 ReleaseCertificate); | 379 ReleaseCertificate); |
364 return result; | 380 return result; |
365 } | 381 } |
366 | 382 |
367 | 383 |
368 int CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx) { | 384 int CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx) { |
369 if (preverify_ok == 1) { | 385 if (preverify_ok == 1) { |
370 return 1; | 386 return 1; |
(...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1489 bool require_client_certificate, | 1505 bool require_client_certificate, |
1490 Dart_Handle protocols_handle) { | 1506 Dart_Handle protocols_handle) { |
1491 is_server_ = is_server; | 1507 is_server_ = is_server; |
1492 if (in_handshake_) { | 1508 if (in_handshake_) { |
1493 FATAL("Connect called twice on the same _SecureFilter."); | 1509 FATAL("Connect called twice on the same _SecureFilter."); |
1494 } | 1510 } |
1495 | 1511 |
1496 int status; | 1512 int status; |
1497 int error; | 1513 int error; |
1498 BIO* ssl_side; | 1514 BIO* ssl_side; |
1499 status = BIO_new_bio_pair(&ssl_side, 10000, &socket_side_, 10000); | 1515 status = BIO_new_bio_pair(&ssl_side, kInternalBIOSize, &socket_side_, |
| 1516 kInternalBIOSize); |
1500 CheckStatus(status, "TlsException", "BIO_new_bio_pair"); | 1517 CheckStatus(status, "TlsException", "BIO_new_bio_pair"); |
1501 | 1518 |
1502 assert(context != NULL); | 1519 assert(context != NULL); |
1503 ssl_ = SSL_new(context); | 1520 ssl_ = SSL_new(context); |
1504 SSL_set_bio(ssl_, ssl_side, ssl_side); | 1521 SSL_set_bio(ssl_, ssl_side, ssl_side); |
1505 SSL_set_mode(ssl_, SSL_MODE_AUTO_RETRY); // TODO(whesse): Is this right? | 1522 SSL_set_mode(ssl_, SSL_MODE_AUTO_RETRY); // TODO(whesse): Is this right? |
1506 SSL_set_ex_data(ssl_, filter_ssl_index, this); | 1523 SSL_set_ex_data(ssl_, filter_ssl_index, this); |
1507 | 1524 |
1508 #if defined(TARGET_OS_FUCHSIA) | 1525 #if defined(TARGET_OS_FUCHSIA) |
1509 // Temporary workaround until we isolate the memory leak issue. | 1526 // Temporary workaround until we isolate the memory leak issue. |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1761 return bytes_processed; | 1778 return bytes_processed; |
1762 } | 1779 } |
1763 | 1780 |
1764 } // namespace bin | 1781 } // namespace bin |
1765 } // namespace dart | 1782 } // namespace dart |
1766 | 1783 |
1767 #endif // defined(TARGET_OS_LINUX) | 1784 #endif // defined(TARGET_OS_LINUX) |
1768 | 1785 |
1769 #endif // !defined(DART_IO_DISABLED) && | 1786 #endif // !defined(DART_IO_DISABLED) && |
1770 // !defined(DART_IO_SECURE_SOCKET_DISABLED) | 1787 // !defined(DART_IO_SECURE_SOCKET_DISABLED) |
OLD | NEW |