Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: runtime/bin/secure_socket.cc

Issue 2903743002: Porting SecureSocket to use BoringSSL on OSX (Closed)
Patch Set: General cleanup Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
8 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) || \
9 defined(HOST_OS_WINDOWS) || defined(HOST_OS_FUCHSIA)
10
11 #include "bin/secure_socket.h" 7 #include "bin/secure_socket.h"
12 #include "bin/secure_socket_boringssl.h"
13 8
14 #include <errno.h> 9 #include <errno.h>
15 #include <fcntl.h> 10 #include <fcntl.h>
16 #include <stdarg.h> 11 #include <stdarg.h>
17 #include <stdio.h> 12 #include <stdio.h>
18 #include <string.h> 13 #include <string.h>
19 #include <sys/stat.h> 14 #include <sys/stat.h>
20 15
21 #include <openssl/bio.h> 16 #include <openssl/bio.h>
22 #include <openssl/err.h> 17 #include <openssl/err.h>
23 #include <openssl/pkcs12.h> 18 #include <openssl/pkcs12.h>
24 #include <openssl/safestack.h> 19 #include <openssl/safestack.h>
25 #include <openssl/ssl.h> 20 #include <openssl/ssl.h>
26 #include <openssl/tls1.h> 21 #include <openssl/tls1.h>
27 #include <openssl/x509.h> 22 #include <openssl/x509.h>
28 23
24 #include "platform/globals.h"
25
29 #include "bin/builtin.h" 26 #include "bin/builtin.h"
30 #include "bin/dartutils.h" 27 #include "bin/dartutils.h"
31 #include "bin/directory.h" 28 #include "bin/directory.h"
32 #include "bin/file.h" 29 #include "bin/file.h"
33 #include "bin/lockers.h" 30 #include "bin/lockers.h"
34 #include "bin/log.h" 31 #include "bin/log.h"
35 #include "bin/socket.h" 32 #include "bin/socket.h"
36 #include "bin/thread.h" 33 #include "bin/thread.h"
37 #include "bin/utils.h" 34 #include "bin/utils.h"
38 #include "platform/text_buffer.h" 35 #include "platform/text_buffer.h"
39 #include "platform/utils.h" 36 #include "platform/utils.h"
40
41 #include "include/dart_api.h"
42
43 // Return the error from the containing function if handle is an error handle. 37 // Return the error from the containing function if handle is an error handle.
44 #define RETURN_IF_ERROR(handle) \ 38 #define RETURN_IF_ERROR(handle) \
45 { \ 39 { \
46 Dart_Handle __handle = handle; \ 40 Dart_Handle __handle = handle; \
47 if (Dart_IsError((__handle))) { \ 41 if (Dart_IsError((__handle))) { \
48 return __handle; \ 42 return __handle; \
49 } \ 43 } \
50 } 44 }
51 45
52 namespace dart { 46 namespace dart {
53 namespace bin { 47 namespace bin {
54 48
55 bool SSLFilter::library_initialized_ = false; 49 bool SSLFilter::library_initialized_ = false;
56 // To protect library initialization. 50 // To protect library initialization.
57 Mutex* SSLFilter::mutex_ = new Mutex(); 51 Mutex* SSLFilter::mutex_ = new Mutex();
58 int SSLFilter::filter_ssl_index; 52 int SSLFilter::filter_ssl_index;
59 53
60 const intptr_t SSLFilter::kInternalBIOSize = 10 * KB; 54 const intptr_t SSLFilter::kInternalBIOSize = 10 * KB;
61 const intptr_t SSLFilter::kApproximateSize = 55 const intptr_t SSLFilter::kApproximateSize =
62 sizeof(SSLFilter) + (2 * SSLFilter::kInternalBIOSize); 56 sizeof(SSLFilter) + (2 * SSLFilter::kInternalBIOSize);
63 57
64 // The security context won't necessarily use the compiled-in root certificates, 58 const int kSSLFilterNativeFieldIndex = 0;
65 // but since there is no way to update the size of the allocation after creating 59 const int kSecurityContextNativeFieldIndex = 0;
66 // the weak persistent handle, we assume that it will. Note that when the
67 // root certs aren't compiled in, |root_certificates_pem_length| is 0.
68 const intptr_t SSLContext::kApproximateSize =
69 sizeof(SSLContext) + root_certificates_pem_length;
70
71 static const int kSSLFilterNativeFieldIndex = 0;
72 static const int kSecurityContextNativeFieldIndex = 0;
73 static const int kX509NativeFieldIndex = 0;
74
75 static const bool SSL_LOG_STATUS = false;
76 static const bool SSL_LOG_DATA = false;
77 60
78 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000; 61 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000;
79 62
80 const char* commandline_root_certs_file = NULL; 63 extern int CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx);
bkonyi 2017/05/25 22:49:20 I'm not sure if this is what we should do, or if w
zra 2017/05/26 18:11:12 Yes, try to put the declaration in a header.
bkonyi 2017/05/26 23:35:30 Done.
81 const char* commandline_root_certs_cache = NULL;
82 64
83 // Get the error messages from BoringSSL, and put them in buffer as a 65 // Get the error messages from BoringSSL, and put them in buffer as a
84 // null-terminated string. 66 // null-terminated string.
85 static void FetchErrorString(const SSL* ssl, TextBuffer* text_buffer) { 67 static void FetchErrorString(const SSL* ssl, TextBuffer* text_buffer) {
86 const char* sep = File::PathSeparator(); 68 const char* sep = File::PathSeparator();
87 while (true) { 69 while (true) {
88 const char* path = NULL; 70 const char* path = NULL;
89 int line = -1; 71 int line = -1;
90 uint32_t error = ERR_get_error_line(&path, &line); 72 uint32_t error = ERR_get_error_line(&path, &line);
91 if (error == 0) { 73 if (error == 0) {
92 break; 74 break;
93 } 75 }
94 text_buffer->Printf("\n\t%s", ERR_reason_error_string(error)); 76 text_buffer->Printf("\n\t%s", ERR_reason_error_string(error));
95 if ((ssl != NULL) && (ERR_GET_LIB(error) == ERR_LIB_SSL) && 77 if ((ssl != NULL) && (ERR_GET_LIB(error) == ERR_LIB_SSL) &&
96 (ERR_GET_REASON(error) == SSL_R_CERTIFICATE_VERIFY_FAILED)) { 78 (ERR_GET_REASON(error) == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
97 intptr_t result = SSL_get_verify_result(ssl); 79 intptr_t result = SSL_get_verify_result(ssl);
98 text_buffer->Printf(": %s", X509_verify_cert_error_string(result)); 80 text_buffer->Printf(": %s", X509_verify_cert_error_string(result));
99 } 81 }
100 if ((path != NULL) && (line >= 0)) { 82 if ((path != NULL) && (line >= 0)) {
101 const char* file = strrchr(path, sep[0]); 83 const char* file = strrchr(path, sep[0]);
102 path = file ? file + 1 : path; 84 path = file ? file + 1 : path;
103 text_buffer->Printf("(%s:%d)", path, line); 85 text_buffer->Printf("(%s:%d)", path, line);
104 } 86 }
105 } 87 }
106 } 88 }
107 89
108 90
109 // Handle an error reported from the BoringSSL library. 91 // Handle an error reported from the BoringSSL library.
110 static void ThrowIOException(int status, 92 void ThrowIOException(int status,
111 const char* exception_type, 93 const char* exception_type,
112 const char* message, 94 const char* message,
113 const SSL* ssl) { 95 const SSL* ssl) {
114 Dart_Handle exception; 96 Dart_Handle exception;
115 { 97 {
116 TextBuffer error_string(SSL_ERROR_MESSAGE_BUFFER_SIZE); 98 TextBuffer error_string(SSL_ERROR_MESSAGE_BUFFER_SIZE);
117 FetchErrorString(ssl, &error_string); 99 FetchErrorString(ssl, &error_string);
118 OSError os_error_struct(status, error_string.buf(), OSError::kBoringSSL); 100 OSError os_error_struct(status, error_string.buf(), OSError::kBoringSSL);
119 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct); 101 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
120 exception = 102 exception =
121 DartUtils::NewDartIOException(exception_type, message, os_error); 103 DartUtils::NewDartIOException(exception_type, message, os_error);
122 ASSERT(!Dart_IsError(exception)); 104 ASSERT(!Dart_IsError(exception));
123 } 105 }
(...skipping 29 matching lines...) Expand all
153 Dart_Handle err = 135 Dart_Handle err =
154 Dart_SetNativeInstanceField(dart_this, kSSLFilterNativeFieldIndex, 136 Dart_SetNativeInstanceField(dart_this, kSSLFilterNativeFieldIndex,
155 reinterpret_cast<intptr_t>(filter)); 137 reinterpret_cast<intptr_t>(filter));
156 RETURN_IF_ERROR(err); 138 RETURN_IF_ERROR(err);
157 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(filter), 139 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(filter),
158 SSLFilter::kApproximateSize, DeleteFilter); 140 SSLFilter::kApproximateSize, DeleteFilter);
159 return Dart_Null(); 141 return Dart_Null();
160 } 142 }
161 143
162 144
163 static SSLContext* GetSecurityContext(Dart_NativeArguments args) { 145 SSLCertContext* SSLCertContext::GetSecurityContext(Dart_NativeArguments args) {
164 SSLContext* context; 146 SSLCertContext* context;
165 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); 147 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
166 ASSERT(Dart_IsInstance(dart_this)); 148 ASSERT(Dart_IsInstance(dart_this));
167 ThrowIfError( 149 ThrowIfError(
168 Dart_GetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, 150 Dart_GetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex,
169 reinterpret_cast<intptr_t*>(&context))); 151 reinterpret_cast<intptr_t*>(&context)));
170 return context; 152 return context;
171 } 153 }
172 154
173 155
174 static void DeleteSecurityContext(void* isolate_data, 156 static void DeleteSecurityContext(void* isolate_data,
175 Dart_WeakPersistentHandle handle, 157 Dart_WeakPersistentHandle handle,
176 void* context_pointer) { 158 void* context_pointer) {
177 SSLContext* context = static_cast<SSLContext*>(context_pointer); 159 SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer);
160 #if !defined(HOST_OS_MACOS)
zra 2017/05/26 18:11:12 Let's not have platform #ifdefs in the non-platfor
bkonyi 2017/05/26 23:35:30 Done.
178 delete context; 161 delete context;
162 #else
163 context->Release();
164 #endif
179 } 165 }
180 166
181 167
182 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, 168 static Dart_Handle SetSecurityContext(Dart_NativeArguments args,
183 SSLContext* context) { 169 SSLCertContext* context) {
184 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); 170 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
185 RETURN_IF_ERROR(dart_this); 171 RETURN_IF_ERROR(dart_this);
186 ASSERT(Dart_IsInstance(dart_this)); 172 ASSERT(Dart_IsInstance(dart_this));
187 Dart_Handle err = 173 Dart_Handle err =
188 Dart_SetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, 174 Dart_SetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex,
189 reinterpret_cast<intptr_t>(context)); 175 reinterpret_cast<intptr_t>(context));
190 RETURN_IF_ERROR(err); 176 RETURN_IF_ERROR(err);
191 Dart_NewWeakPersistentHandle(dart_this, context, SSLContext::kApproximateSize, 177 Dart_NewWeakPersistentHandle(dart_this, context,
178 SSLCertContext::kApproximateSize,
192 DeleteSecurityContext); 179 DeleteSecurityContext);
193 return Dart_Null(); 180 return Dart_Null();
194 } 181 }
195 182
196 183
197 static X509* GetX509Certificate(Dart_NativeArguments args) {
198 X509* certificate;
199 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
200 ASSERT(Dart_IsInstance(dart_this));
201 ThrowIfError(
202 Dart_GetNativeInstanceField(dart_this, kX509NativeFieldIndex,
203 reinterpret_cast<intptr_t*>(&certificate)));
204 return certificate;
205 }
206
207
208 // Forward declaration. 184 // Forward declaration.
209 static void SetAlpnProtocolList(Dart_Handle protocols_handle, 185 static void SetAlpnProtocolList(Dart_Handle protocols_handle,
210 SSL* ssl, 186 SSL* ssl,
211 SSLContext* context, 187 SSLCertContext* context,
212 bool is_server); 188 bool is_server);
213 189
214 190
215 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) { 191 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) {
216 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); 192 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
217 SSLFilter* filter = new SSLFilter(); 193 SSLFilter* filter = new SSLFilter();
218 Dart_Handle err = SetFilter(args, filter); 194 Dart_Handle err = SetFilter(args, filter);
219 if (Dart_IsError(err)) { 195 if (Dart_IsError(err)) {
220 filter->Release(); 196 filter->Release();
221 Dart_PropagateError(err); 197 Dart_PropagateError(err);
(...skipping 15 matching lines...) Expand all
237 bool request_client_certificate = 213 bool request_client_certificate =
238 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); 214 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
239 bool require_client_certificate = 215 bool require_client_certificate =
240 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5)); 216 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5));
241 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 6)); 217 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 6));
242 218
243 const char* host_name = NULL; 219 const char* host_name = NULL;
244 // TODO(whesse): Is truncating a Dart string containing \0 what we want? 220 // TODO(whesse): Is truncating a Dart string containing \0 what we want?
245 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); 221 ThrowIfError(Dart_StringToCString(host_name_object, &host_name));
246 222
247 SSLContext* context = NULL; 223 SSLCertContext* context = NULL;
248 if (!Dart_IsNull(context_object)) { 224 if (!Dart_IsNull(context_object)) {
249 ThrowIfError(Dart_GetNativeInstanceField( 225 ThrowIfError(Dart_GetNativeInstanceField(
250 context_object, kSecurityContextNativeFieldIndex, 226 context_object, kSecurityContextNativeFieldIndex,
251 reinterpret_cast<intptr_t*>(&context))); 227 reinterpret_cast<intptr_t*>(&context)));
252 } 228 }
253 229
254 // The protocols_handle is guaranteed to be a valid Uint8List. 230 // The protocols_handle is guaranteed to be a valid Uint8List.
255 // It will have the correct length encoding of the protocols array. 231 // It will have the correct length encoding of the protocols array.
256 ASSERT(!Dart_IsNull(protocols_handle)); 232 ASSERT(!Dart_IsNull(protocols_handle));
257 233
258 GetFilter(args)->Connect(host_name, context->context(), is_server, 234 GetFilter(args)->Connect(host_name, context, is_server,
259 request_client_certificate, 235 request_client_certificate,
260 require_client_certificate, protocols_handle); 236 require_client_certificate, protocols_handle);
261 } 237 }
262 238
263 239
264 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { 240 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) {
265 SSLFilter* filter = GetFilter(args); 241 SSLFilter* filter = GetFilter(args);
266 // There are two paths that can clean up an SSLFilter object. First, 242 // There are two paths that can clean up an SSLFilter object. First,
267 // there is this explicit call to Destroy(), called from 243 // there is this explicit call to Destroy(), called from
268 // _SecureFilter.destroy() in Dart code. After a call to destroy(), the Dart 244 // _SecureFilter.destroy() in Dart code. After a call to destroy(), the Dart
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { 308 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) {
333 SSLFilter* filter = GetFilter(args); 309 SSLFilter* filter = GetFilter(args);
334 // This filter pointer is passed to the IO Service thread. The IO Service 310 // This filter pointer is passed to the IO Service thread. The IO Service
335 // thread must Release() the pointer when it is done with it. 311 // thread must Release() the pointer when it is done with it.
336 filter->Retain(); 312 filter->Retain();
337 intptr_t filter_pointer = reinterpret_cast<intptr_t>(filter); 313 intptr_t filter_pointer = reinterpret_cast<intptr_t>(filter);
338 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); 314 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer));
339 } 315 }
340 316
341 317
342 static void ReleaseCertificate(void* isolate_data,
343 Dart_WeakPersistentHandle handle,
344 void* context_pointer) {
345 X509* cert = reinterpret_cast<X509*>(context_pointer);
346 X509_free(cert);
347 }
348
349
350 static intptr_t EstimateX509Size(X509* certificate) {
351 intptr_t length = i2d_X509(certificate, NULL);
352 return length > 0 ? length : 0;
353 }
354
355
356 // Returns the handle for a Dart object wrapping the X509 certificate object.
357 // The caller should own a reference to the X509 object whose reference count
358 // won't drop to zero before the ReleaseCertificate finalizer runs.
359 static Dart_Handle WrappedX509Certificate(X509* certificate) {
360 if (certificate == NULL) {
361 return Dart_Null();
362 }
363 Dart_Handle x509_type =
364 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate");
365 if (Dart_IsError(x509_type)) {
366 X509_free(certificate);
367 return x509_type;
368 }
369 Dart_Handle arguments[] = {NULL};
370 Dart_Handle result =
371 Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments);
372 if (Dart_IsError(result)) {
373 X509_free(certificate);
374 return result;
375 }
376 ASSERT(Dart_IsInstance(result));
377 Dart_Handle status = Dart_SetNativeInstanceField(
378 result, kX509NativeFieldIndex, reinterpret_cast<intptr_t>(certificate));
379 if (Dart_IsError(status)) {
380 X509_free(certificate);
381 return status;
382 }
383 const intptr_t approximate_size_of_certificate =
384 sizeof(*certificate) + EstimateX509Size(certificate);
385 ASSERT(approximate_size_of_certificate > 0);
386 Dart_NewWeakPersistentHandle(result, reinterpret_cast<void*>(certificate),
387 approximate_size_of_certificate,
388 ReleaseCertificate);
389 return result;
390 }
391
392
393 int CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx) {
394 if (preverify_ok == 1) {
395 return 1;
396 }
397 Dart_Isolate isolate = Dart_CurrentIsolate();
398 if (isolate == NULL) {
399 FATAL("CertificateCallback called with no current isolate\n");
400 }
401 X509* certificate = X509_STORE_CTX_get_current_cert(store_ctx);
402 int ssl_index = SSL_get_ex_data_X509_STORE_CTX_idx();
403 SSL* ssl =
404 static_cast<SSL*>(X509_STORE_CTX_get_ex_data(store_ctx, ssl_index));
405 SSLFilter* filter = static_cast<SSLFilter*>(
406 SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index));
407 Dart_Handle callback = filter->bad_certificate_callback();
408 if (Dart_IsNull(callback)) {
409 return 0;
410 }
411
412 // Upref since the Dart X509 object may outlive the SecurityContext.
413 if (certificate != NULL) {
414 X509_up_ref(certificate);
415 }
416 Dart_Handle args[1];
417 args[0] = WrappedX509Certificate(certificate);
418 if (Dart_IsError(args[0])) {
419 filter->callback_error = args[0];
420 return 0;
421 }
422 Dart_Handle result = Dart_InvokeClosure(callback, 1, args);
423 if (!Dart_IsError(result) && !Dart_IsBoolean(result)) {
424 result = Dart_NewUnhandledExceptionError(DartUtils::NewDartIOException(
425 "HandshakeException",
426 "BadCertificateCallback returned a value that was not a boolean",
427 Dart_Null()));
428 }
429 if (Dart_IsError(result)) {
430 filter->callback_error = result;
431 return 0;
432 }
433 return DartUtils::GetBooleanValue(result);
434 }
435
436
437 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) { 318 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) {
438 SSLFilter::InitializeLibrary(); 319 SSLFilter::InitializeLibrary();
439 SSL_CTX* ctx = SSL_CTX_new(TLS_method()); 320 SSL_CTX* ctx = SSL_CTX_new(TLS_method());
440 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, CertificateCallback); 321 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, CertificateCallback);
441 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION); 322 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
442 SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM"); 323 SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM");
443 SSLContext* context = new SSLContext(ctx); 324 SSLCertContext* context = new SSLCertContext(ctx);
444 Dart_Handle err = SetSecurityContext(args, context); 325 Dart_Handle err = SetSecurityContext(args, context);
445 if (Dart_IsError(err)) { 326 if (Dart_IsError(err)) {
446 delete context; 327 delete context;
447 Dart_PropagateError(err); 328 Dart_PropagateError(err);
448 } 329 }
449 } 330 }
450 331
451 332
452 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) { 333 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) {
453 char* password = static_cast<char*>(userdata); 334 char* password = static_cast<char*>(userdata);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 BIO_reset(bio); 529 BIO_reset(bio);
649 530
650 // Try to decode as PKCS12. 531 // Try to decode as PKCS12.
651 key = GetPrivateKeyPKCS12(bio, password); 532 key = GetPrivateKeyPKCS12(bio, password);
652 } 533 }
653 } 534 }
654 return key; 535 return key;
655 } 536 }
656 537
657 538
658 static const char* GetPasswordArgument(Dart_NativeArguments args, 539 const char* SSLCertContext::GetPasswordArgument(Dart_NativeArguments args,
659 intptr_t index) { 540 intptr_t index) {
660 Dart_Handle password_object = 541 Dart_Handle password_object =
661 ThrowIfError(Dart_GetNativeArgument(args, index)); 542 ThrowIfError(Dart_GetNativeArgument(args, index));
662 const char* password = NULL; 543 const char* password = NULL;
663 if (Dart_IsString(password_object)) { 544 if (Dart_IsString(password_object)) {
664 ThrowIfError(Dart_StringToCString(password_object, &password)); 545 ThrowIfError(Dart_StringToCString(password_object, &password));
665 if (strlen(password) > PEM_BUFSIZE - 1) { 546 if (strlen(password) > PEM_BUFSIZE - 1) {
666 Dart_ThrowException(DartUtils::NewDartArgumentError( 547 Dart_ThrowException(DartUtils::NewDartArgumentError(
667 "Password length is greater than 1023 (PEM_BUFSIZE)")); 548 "Password length is greater than 1023 (PEM_BUFSIZE)"));
668 } 549 }
669 } else if (Dart_IsNull(password_object)) { 550 } else if (Dart_IsNull(password_object)) {
670 password = ""; 551 password = "";
671 } else { 552 } else {
672 Dart_ThrowException( 553 Dart_ThrowException(
673 DartUtils::NewDartArgumentError("Password is not a String or null")); 554 DartUtils::NewDartArgumentError("Password is not a String or null"));
674 } 555 }
675 return password; 556 return password;
676 } 557 }
677 558
678 559
679 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( 560 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
680 Dart_NativeArguments args) { 561 Dart_NativeArguments args) {
681 SSLContext* context = GetSecurityContext(args); 562 SSLCertContext* context = SSLCertContext::GetSecurityContext(args);
682 const char* password = GetPasswordArgument(args, 2); 563 const char* password = SSLCertContext::GetPasswordArgument(args, 2);
683 564
684 int status; 565 int status;
685 { 566 {
686 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 567 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
687 EVP_PKEY* key = GetPrivateKey(bio.bio(), password); 568 EVP_PKEY* key = GetPrivateKey(bio.bio(), password);
688 status = SSL_CTX_use_PrivateKey(context->context(), key); 569 status = SSL_CTX_use_PrivateKey(context->context(), key);
689 // SSL_CTX_use_PrivateKey increments the reference count of key on success, 570 // SSL_CTX_use_PrivateKey increments the reference count of key on success,
690 // so we have to call EVP_PKEY_free on both success and failure. 571 // so we have to call EVP_PKEY_free on both success and failure.
691 EVP_PKEY_free(key); 572 EVP_PKEY_free(key);
692 } 573 }
693 574
694 // TODO(24184): Handle different expected errors here - file missing, 575 // TODO(24184): Handle different expected errors here - file missing,
695 // incorrect password, file not a PEM, and throw exceptions. 576 // incorrect password, file not a PEM, and throw exceptions.
696 // CheckStatus should also throw an exception in uncaught cases. 577 // CheckStatus should also throw an exception in uncaught cases.
697 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes"); 578 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes");
698 } 579 }
699 580
700 581
701 static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context,
702 BIO* bio,
703 const char* password) {
704 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
705 if (p12.get() == NULL) {
706 return 0;
707 }
708
709 EVP_PKEY* key = NULL;
710 X509* cert = NULL;
711 STACK_OF(X509)* ca_certs = NULL;
712 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
713 if (status == 0) {
714 return status;
715 }
716
717 ScopedX509Stack cert_stack(ca_certs);
718 X509_STORE* store = SSL_CTX_get_cert_store(context);
719 status = X509_STORE_add_cert(store, cert);
720 // X509_STORE_add_cert increments the reference count of cert on success.
721 X509_free(cert);
722 if (status == 0) {
723 return status;
724 }
725
726 X509* ca;
727 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
728 status = X509_STORE_add_cert(store, ca);
729 // X509_STORE_add_cert increments the reference count of cert on success.
730 X509_free(ca);
731 if (status == 0) {
732 return status;
733 }
734 }
735
736 return status;
737 }
738
739
740 static int SetTrustedCertificatesBytesPEM(SSL_CTX* context, BIO* bio) {
741 X509_STORE* store = SSL_CTX_get_cert_store(context);
742
743 int status = 0;
744 X509* cert = NULL;
745 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
746 status = X509_STORE_add_cert(store, cert);
747 // X509_STORE_add_cert increments the reference count of cert on success.
748 X509_free(cert);
749 if (status == 0) {
750 return status;
751 }
752 }
753
754 // If no PEM start line is found, it means that we read to the end of the
755 // file, or that the file isn't PEM. In the first case, status will be
756 // non-zero indicating success. In the second case, status will be 0,
757 // indicating that we should try to read as PKCS12. If there is some other
758 // error, we return it up to the caller.
759 return NoPEMStartLine() ? status : 0;
760 }
761
762
763 static int SetTrustedCertificatesBytes(SSL_CTX* context,
764 BIO* bio,
765 const char* password) {
766 int status = SetTrustedCertificatesBytesPEM(context, bio);
767 if (status == 0) {
768 if (NoPEMStartLine()) {
769 ERR_clear_error();
770 BIO_reset(bio);
771 status = SetTrustedCertificatesBytesPKCS12(context, bio, password);
772 }
773 } else {
774 // The PEM file was successfully parsed.
775 ERR_clear_error();
776 }
777 return status;
778 }
779
780
781 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)(
782 Dart_NativeArguments args) {
783 SSLContext* context = GetSecurityContext(args);
784 const char* password = GetPasswordArgument(args, 2);
785 int status;
786 {
787 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
788 status =
789 SetTrustedCertificatesBytes(context->context(), bio.bio(), password);
790 }
791 CheckStatus(status, "TlsException", "Failure in setTrustedCertificatesBytes");
792 }
793
794
795 void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) {
796 Dart_SetReturnValue(args, Dart_NewBoolean(true));
797 }
798
799
800 static void AddCompiledInCerts(SSLContext* context) {
801 if (root_certificates_pem == NULL) {
802 if (SSL_LOG_STATUS) {
803 Log::Print("Missing compiled-in roots\n");
804 }
805 return;
806 }
807 X509_STORE* store = SSL_CTX_get_cert_store(context->context());
808 BIO* roots_bio =
809 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem),
810 root_certificates_pem_length);
811 X509* root_cert;
812 // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case,
813 // backed by a memory buffer), and returns X509 objects, one by one.
814 // When the end of the bio is reached, it returns null.
815 while ((root_cert = PEM_read_bio_X509(roots_bio, NULL, NULL, NULL)) != NULL) {
816 int status = X509_STORE_add_cert(store, root_cert);
817 // X509_STORE_add_cert increments the reference count of cert on success.
818 X509_free(root_cert);
819 if (status == 0) {
820 break;
821 }
822 }
823 BIO_free(roots_bio);
824 // If there is an error here, it must be the error indicating that we are done
825 // reading PEM certificates.
826 ASSERT((ERR_peek_error() == 0) || NoPEMStartLine());
827 ERR_clear_error();
828 }
829
830
831 static void LoadRootCertFile(SSLContext* context, const char* file) {
832 if (SSL_LOG_STATUS) {
833 Log::Print("Looking for trusted roots in %s\n", file);
834 }
835 if (!File::Exists(file)) {
836 ThrowIOException(-1, "TlsException", "Failed to find root cert file", NULL);
837 }
838 int status = SSL_CTX_load_verify_locations(context->context(), file, NULL);
839 CheckStatus(status, "TlsException", "Failure trusting builtin roots");
840 if (SSL_LOG_STATUS) {
841 Log::Print("Trusting roots from: %s\n", file);
842 }
843 }
844
845
846 static void LoadRootCertCache(SSLContext* context, const char* cache) {
847 if (SSL_LOG_STATUS) {
848 Log::Print("Looking for trusted roots in %s\n", cache);
849 }
850 if (Directory::Exists(cache) != Directory::EXISTS) {
851 ThrowIOException(-1, "TlsException", "Failed to find root cert cache",
852 NULL);
853 }
854 int status = SSL_CTX_load_verify_locations(context->context(), NULL, cache);
855 CheckStatus(status, "TlsException", "Failure trusting builtin roots");
856 if (SSL_LOG_STATUS) {
857 Log::Print("Trusting roots from: %s\n", cache);
858 }
859 }
860
861
862 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
863 Dart_NativeArguments args) {
864 SSLContext* context = GetSecurityContext(args);
865
866 // First, try to use locations specified on the command line.
867 if (commandline_root_certs_file != NULL) {
868 LoadRootCertFile(context, commandline_root_certs_file);
869 return;
870 }
871
872 if (commandline_root_certs_cache != NULL) {
873 LoadRootCertCache(context, commandline_root_certs_cache);
874 return;
875 }
876
877 #if defined(HOST_OS_ANDROID)
878 // On Android, we don't compile in the trusted root certificates. Insead,
879 // we use the directory of trusted certificates already present on the device.
880 // This saves ~240KB from the size of the binary. This has the drawback that
881 // SSL_do_handshake will synchronously hit the filesystem looking for root
882 // certs during its trust evaluation. We call SSL_do_handshake directly from
883 // the Dart thread so that Dart code can be invoked from the "bad certificate"
884 // callback called by SSL_do_handshake.
885 const char* android_cacerts = "/system/etc/security/cacerts";
886 LoadRootCertCache(context, android_cacerts);
887 return;
888 #elif defined(HOST_OS_LINUX)
889 // On Linux, we use the compiled-in trusted certs as a last resort. First,
890 // we try to find the trusted certs in various standard locations. A good
891 // discussion of the complexities of this endeavor can be found here:
892 //
893 // https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certif icate-stores-and-platforms/
894 const char* bundle = "/etc/pki/tls/certs/ca-bundle.crt";
895 const char* cachedir = "/etc/ssl/certs";
896 if (File::Exists(bundle)) {
897 LoadRootCertFile(context, bundle);
898 return;
899 }
900
901 if (Directory::Exists(cachedir) == Directory::EXISTS) {
902 LoadRootCertCache(context, cachedir);
903 return;
904 }
905 #endif // defined(HOST_OS_ANDROID)
906
907 // Fall back on the compiled-in certs if the standard locations don't exist,
908 // or we aren't on Linux.
909 if (SSL_LOG_STATUS) {
910 Log::Print("Trusting compiled-in roots\n");
911 }
912 AddCompiledInCerts(context);
913 }
914
915
916 static int UseChainBytesPKCS12(SSL_CTX* context,
917 BIO* bio,
918 const char* password) {
919 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
920 if (p12.get() == NULL) {
921 return 0;
922 }
923
924 EVP_PKEY* key = NULL;
925 X509* cert = NULL;
926 STACK_OF(X509)* ca_certs = NULL;
927 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
928 if (status == 0) {
929 return status;
930 }
931
932 ScopedX509 x509(cert);
933 ScopedX509Stack certs(ca_certs);
934 status = SSL_CTX_use_certificate(context, x509.get());
935 if (ERR_peek_error() != 0) {
936 // Key/certificate mismatch doesn't imply status is 0.
937 status = 0;
938 }
939 if (status == 0) {
940 return status;
941 }
942
943 SSL_CTX_clear_chain_certs(context);
944
945 X509* ca;
946 while ((ca = sk_X509_shift(certs.get())) != NULL) {
947 status = SSL_CTX_add0_chain_cert(context, ca);
948 // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the
949 // call fails.
950 if (status == 0) {
951 X509_free(ca);
952 return status;
953 }
954 }
955
956 return status;
957 }
958
959
960 static int UseChainBytesPEM(SSL_CTX* context, BIO* bio) {
961 int status = 0;
962 ScopedX509 x509(PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL));
963 if (x509.get() == NULL) {
964 return 0;
965 }
966
967 status = SSL_CTX_use_certificate(context, x509.get());
968 if (ERR_peek_error() != 0) {
969 // Key/certificate mismatch doesn't imply status is 0.
970 status = 0;
971 }
972 if (status == 0) {
973 return status;
974 }
975
976 SSL_CTX_clear_chain_certs(context);
977
978 X509* ca;
979 while ((ca = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
980 status = SSL_CTX_add0_chain_cert(context, ca);
981 // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the
982 // call fails.
983 if (status == 0) {
984 X509_free(ca);
985 return status;
986 }
987 // Note that we must not free `ca` if it was successfully added to the
988 // chain. We must free the main certificate x509, though since its reference
989 // count is increased by SSL_CTX_use_certificate.
990 }
991
992 return NoPEMStartLine() ? status : 0;
993 }
994
995
996 static int UseChainBytes(SSL_CTX* context, BIO* bio, const char* password) {
997 int status = UseChainBytesPEM(context, bio);
998 if (status == 0) {
999 if (NoPEMStartLine()) {
1000 ERR_clear_error();
1001 BIO_reset(bio);
1002 status = UseChainBytesPKCS12(context, bio, password);
1003 }
1004 } else {
1005 // The PEM file was successfully read.
1006 ERR_clear_error();
1007 }
1008 return status;
1009 }
1010
1011
1012 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
1013 Dart_NativeArguments args) {
1014 SSLContext* context = GetSecurityContext(args);
1015 const char* password = GetPasswordArgument(args, 2);
1016 int status;
1017 {
1018 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
1019 status = UseChainBytes(context->context(), bio.bio(), password);
1020 }
1021 CheckStatus(status, "TlsException", "Failure in useCertificateChainBytes");
1022 }
1023
1024
1025 static int SetClientAuthoritiesPKCS12(SSL_CTX* context,
1026 BIO* bio,
1027 const char* password) {
1028 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
1029 if (p12.get() == NULL) {
1030 return 0;
1031 }
1032
1033 EVP_PKEY* key = NULL;
1034 X509* cert = NULL;
1035 STACK_OF(X509)* ca_certs = NULL;
1036 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
1037 if (status == 0) {
1038 return status;
1039 }
1040
1041 ScopedX509Stack cert_stack(ca_certs);
1042 status = SSL_CTX_add_client_CA(context, cert);
1043 // SSL_CTX_add_client_CA increments the reference count of cert on success.
1044 X509_free(cert);
1045 if (status == 0) {
1046 return status;
1047 }
1048
1049 X509* ca;
1050 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
1051 status = SSL_CTX_add_client_CA(context, ca);
1052 // SSL_CTX_add_client_CA increments the reference count of ca on success.
1053 X509_free(ca); // The name has been extracted.
1054 if (status == 0) {
1055 return status;
1056 }
1057 }
1058
1059 return status;
1060 }
1061
1062
1063 static int SetClientAuthoritiesPEM(SSL_CTX* context, BIO* bio) {
1064 int status = 0;
1065 X509* cert = NULL;
1066 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
1067 status = SSL_CTX_add_client_CA(context, cert);
1068 X509_free(cert); // The name has been extracted.
1069 if (status == 0) {
1070 return status;
1071 }
1072 }
1073 return NoPEMStartLine() ? status : 0;
1074 }
1075
1076
1077 static int SetClientAuthorities(SSL_CTX* context,
1078 BIO* bio,
1079 const char* password) {
1080 int status = SetClientAuthoritiesPEM(context, bio);
1081 if (status == 0) {
1082 if (NoPEMStartLine()) {
1083 ERR_clear_error();
1084 BIO_reset(bio);
1085 status = SetClientAuthoritiesPKCS12(context, bio, password);
1086 }
1087 } else {
1088 // The PEM file was successfully parsed.
1089 ERR_clear_error();
1090 }
1091 return status;
1092 }
1093
1094
1095 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
1096 Dart_NativeArguments args) {
1097 SSLContext* context = GetSecurityContext(args);
1098 const char* password = GetPasswordArgument(args, 2);
1099
1100 int status;
1101 {
1102 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
1103 status = SetClientAuthorities(context->context(), bio.bio(), password);
1104 }
1105
1106 CheckStatus(status, "TlsException", "Failure in setClientAuthoritiesBytes");
1107 }
1108
1109
1110 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( 582 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)(
1111 Dart_NativeArguments args) { 583 Dart_NativeArguments args) {
1112 SSLContext* context = GetSecurityContext(args); 584 SSLCertContext* context = SSLCertContext::GetSecurityContext(args);
1113 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 1)); 585 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 1));
1114 Dart_Handle is_server_handle = ThrowIfError(Dart_GetNativeArgument(args, 2)); 586 Dart_Handle is_server_handle = ThrowIfError(Dart_GetNativeArgument(args, 2));
1115 if (Dart_IsBoolean(is_server_handle)) { 587 if (Dart_IsBoolean(is_server_handle)) {
1116 bool is_server = DartUtils::GetBooleanValue(is_server_handle); 588 bool is_server = DartUtils::GetBooleanValue(is_server_handle);
1117 SetAlpnProtocolList(protocols_handle, NULL, context, is_server); 589 SetAlpnProtocolList(protocols_handle, NULL, context, is_server);
1118 } else { 590 } else {
1119 Dart_ThrowException(DartUtils::NewDartArgumentError( 591 Dart_ThrowException(DartUtils::NewDartArgumentError(
1120 "Non-boolean is_server argument passed to SetAlpnProtocols")); 592 "Non-boolean is_server argument passed to SetAlpnProtocols"));
1121 } 593 }
1122 } 594 }
1123 595
1124 596
1125 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) {
1126 X509* certificate = GetX509Certificate(args);
1127 X509_NAME* subject = X509_get_subject_name(certificate);
1128 char* subject_string = X509_NAME_oneline(subject, NULL, 0);
1129 Dart_SetReturnValue(args, Dart_NewStringFromCString(subject_string));
1130 OPENSSL_free(subject_string);
1131 }
1132
1133
1134 void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) {
1135 X509* certificate = GetX509Certificate(args);
1136 X509_NAME* issuer = X509_get_issuer_name(certificate);
1137 char* issuer_string = X509_NAME_oneline(issuer, NULL, 0);
1138 Dart_SetReturnValue(args, Dart_NewStringFromCString(issuer_string));
1139 OPENSSL_free(issuer_string);
1140 }
1141
1142 static Dart_Handle ASN1TimeToMilliseconds(ASN1_TIME* aTime) {
1143 ASN1_UTCTIME* epoch_start = M_ASN1_UTCTIME_new();
1144 ASN1_UTCTIME_set_string(epoch_start, "700101000000Z");
1145 int days;
1146 int seconds;
1147 int result = ASN1_TIME_diff(&days, &seconds, epoch_start, aTime);
1148 M_ASN1_UTCTIME_free(epoch_start);
1149 if (result != 1) {
1150 // TODO(whesse): Propagate an error to Dart.
1151 Log::PrintErr("ASN1Time error %d\n", result);
1152 }
1153 return Dart_NewInteger((86400LL * days + seconds) * 1000LL);
1154 }
1155
1156 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) {
1157 X509* certificate = GetX509Certificate(args);
1158 ASN1_TIME* not_before = X509_get_notBefore(certificate);
1159 Dart_SetReturnValue(args, ASN1TimeToMilliseconds(not_before));
1160 }
1161
1162
1163 void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) {
1164 X509* certificate = GetX509Certificate(args);
1165 ASN1_TIME* not_after = X509_get_notAfter(certificate);
1166 Dart_SetReturnValue(args, ASN1TimeToMilliseconds(not_after));
1167 }
1168
1169
1170 /** 597 /**
1171 * Pushes data through the SSL filter, reading and writing from circular 598 * Pushes data through the SSL filter, reading and writing from circular
1172 * buffers shared with Dart. 599 * buffers shared with Dart.
1173 * 600 *
1174 * The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to 601 * The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to
1175 * pass encrypted and plaintext data to and from the C++ SSLFilter object. 602 * pass encrypted and plaintext data to and from the C++ SSLFilter object.
1176 * 603 *
1177 * ProcessFilter is called with a CObject array containing the pointer to 604 * ProcessFilter is called with a CObject array containing the pointer to
1178 * the SSLFilter, encoded as an int, and the start and end positions of the 605 * the SSLFilter, encoded as an int, and the start and end positions of the
1179 * valid data in the four circular buffers. The function only reads from 606 * valid data in the four circular buffers. The function only reads from
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 Dart_Handle SSLFilter::Init(Dart_Handle dart_this) { 724 Dart_Handle SSLFilter::Init(Dart_Handle dart_this) {
1298 if (!library_initialized_) { 725 if (!library_initialized_) {
1299 InitializeLibrary(); 726 InitializeLibrary();
1300 } 727 }
1301 ASSERT(string_start_ == NULL); 728 ASSERT(string_start_ == NULL);
1302 string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start")); 729 string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start"));
1303 ASSERT(string_start_ != NULL); 730 ASSERT(string_start_ != NULL);
1304 ASSERT(string_length_ == NULL); 731 ASSERT(string_length_ == NULL);
1305 string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length")); 732 string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length"));
1306 ASSERT(string_length_ != NULL); 733 ASSERT(string_length_ != NULL);
1307 ASSERT(bad_certificate_callback_ == NULL);
zra 2017/05/26 18:11:12 Why remove this assert?
bkonyi 2017/05/26 23:35:29 Probably did it during all the refactoring and did
1308 bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null()); 734 bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null());
1309 ASSERT(bad_certificate_callback_ != NULL); 735 ASSERT(bad_certificate_callback_ != NULL);
1310
1311 // Caller handles cleanup on an error. 736 // Caller handles cleanup on an error.
1312 return InitializeBuffers(dart_this); 737 return InitializeBuffers(dart_this);
1313 } 738 }
1314 739
1315 740
1316 Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) { 741 Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) {
1317 // Create SSLFilter buffers as ExternalUint8Array objects. 742 // Create SSLFilter buffers as ExternalUint8Array objects.
1318 Dart_Handle buffers_string = DartUtils::NewString("buffers"); 743 Dart_Handle buffers_string = DartUtils::NewString("buffers");
1319 RETURN_IF_ERROR(buffers_string); 744 RETURN_IF_ERROR(buffers_string);
1320 Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string); 745 Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 MutexLocker locker(mutex_); 837 MutexLocker locker(mutex_);
1413 if (!library_initialized_) { 838 if (!library_initialized_) {
1414 SSL_library_init(); 839 SSL_library_init();
1415 filter_ssl_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); 840 filter_ssl_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
1416 ASSERT(filter_ssl_index >= 0); 841 ASSERT(filter_ssl_index >= 0);
1417 library_initialized_ = true; 842 library_initialized_ = true;
1418 } 843 }
1419 } 844 }
1420 845
1421 846
1422 Dart_Handle SSLFilter::PeerCertificate() {
1423 // SSL_get_peer_certificate incs the refcount of certificate. X509_free is
1424 // called by the finalizer set up by WrappedX509Certificate.
1425 X509* certificate = SSL_get_peer_certificate(ssl_);
1426 return WrappedX509Certificate(certificate);
1427 }
1428
1429
1430 int AlpnCallback(SSL* ssl, 847 int AlpnCallback(SSL* ssl,
1431 const uint8_t** out, 848 const uint8_t** out,
1432 uint8_t* outlen, 849 uint8_t* outlen,
1433 const uint8_t* in, 850 const uint8_t* in,
1434 unsigned int inlen, 851 unsigned int inlen,
1435 void* arg) { 852 void* arg) {
1436 // 'in' and 'arg' are sequences of (length, data) strings with 1-byte lengths. 853 // 'in' and 'arg' are sequences of (length, data) strings with 1-byte lengths.
1437 // 'arg' is 0-terminated. Finds the first string in 'arg' that is in 'in'. 854 // 'arg' is 0-terminated. Finds the first string in 'arg' that is in 'in'.
1438 uint8_t* server_list = static_cast<uint8_t*>(arg); 855 uint8_t* server_list = static_cast<uint8_t*>(arg);
1439 while (*server_list != 0) { 856 while (*server_list != 0) {
(...skipping 13 matching lines...) Expand all
1453 server_list += protocol_length; 870 server_list += protocol_length;
1454 } 871 }
1455 // TODO(23580): Make failure send a fatal alert instead of ignoring ALPN. 872 // TODO(23580): Make failure send a fatal alert instead of ignoring ALPN.
1456 return SSL_TLSEXT_ERR_NOACK; 873 return SSL_TLSEXT_ERR_NOACK;
1457 } 874 }
1458 875
1459 876
1460 // Sets the protocol list for ALPN on a SSL object or a context. 877 // Sets the protocol list for ALPN on a SSL object or a context.
1461 static void SetAlpnProtocolList(Dart_Handle protocols_handle, 878 static void SetAlpnProtocolList(Dart_Handle protocols_handle,
1462 SSL* ssl, 879 SSL* ssl,
1463 SSLContext* context, 880 SSLCertContext* context,
1464 bool is_server) { 881 bool is_server) {
1465 // Enable ALPN (application layer protocol negotiation) if the caller provides 882 // Enable ALPN (application layer protocol negotiation) if the caller provides
1466 // a valid list of supported protocols. 883 // a valid list of supported protocols.
1467 Dart_TypedData_Type protocols_type; 884 Dart_TypedData_Type protocols_type;
1468 uint8_t* protocol_string = NULL; 885 uint8_t* protocol_string = NULL;
1469 uint8_t* protocol_string_copy = NULL; 886 uint8_t* protocol_string_copy = NULL;
1470 intptr_t protocol_string_len = 0; 887 intptr_t protocol_string_len = 0;
1471 int status; 888 int status;
1472 889
1473 Dart_Handle result = Dart_TypedDataAcquireData( 890 Dart_Handle result = Dart_TypedDataAcquireData(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 protocol_string_len); 927 protocol_string_len);
1511 } 928 }
1512 ASSERT(status == 0); // The function returns a non-standard status. 929 ASSERT(status == 0); // The function returns a non-standard status.
1513 } 930 }
1514 } 931 }
1515 Dart_TypedDataReleaseData(protocols_handle); 932 Dart_TypedDataReleaseData(protocols_handle);
1516 } 933 }
1517 934
1518 935
1519 void SSLFilter::Connect(const char* hostname, 936 void SSLFilter::Connect(const char* hostname,
1520 SSL_CTX* context, 937 SSLCertContext* context,
1521 bool is_server, 938 bool is_server,
1522 bool request_client_certificate, 939 bool request_client_certificate,
1523 bool require_client_certificate, 940 bool require_client_certificate,
1524 Dart_Handle protocols_handle) { 941 Dart_Handle protocols_handle) {
1525 is_server_ = is_server; 942 is_server_ = is_server;
1526 if (in_handshake_) { 943 if (in_handshake_) {
1527 FATAL("Connect called twice on the same _SecureFilter."); 944 FATAL("Connect called twice on the same _SecureFilter.");
1528 } 945 }
1529 946
1530 int status; 947 int status;
1531 int error; 948 int error;
1532 BIO* ssl_side; 949 BIO* ssl_side;
1533 status = BIO_new_bio_pair(&ssl_side, kInternalBIOSize, &socket_side_, 950 status = BIO_new_bio_pair(&ssl_side, kInternalBIOSize, &socket_side_,
1534 kInternalBIOSize); 951 kInternalBIOSize);
1535 CheckStatusSSL(status, "TlsException", "BIO_new_bio_pair", ssl_); 952 CheckStatusSSL(status, "TlsException", "BIO_new_bio_pair", ssl_);
1536 953
1537 assert(context != NULL); 954 ASSERT(context != NULL);
1538 ssl_ = SSL_new(context); 955 ASSERT(context->context() != NULL);
956 ssl_ = SSL_new(context->context());
1539 SSL_set_bio(ssl_, ssl_side, ssl_side); 957 SSL_set_bio(ssl_, ssl_side, ssl_side);
1540 SSL_set_mode(ssl_, SSL_MODE_AUTO_RETRY); // TODO(whesse): Is this right? 958 SSL_set_mode(ssl_, SSL_MODE_AUTO_RETRY); // TODO(whesse): Is this right?
1541 SSL_set_ex_data(ssl_, filter_ssl_index, this); 959 SSL_set_ex_data(ssl_, filter_ssl_index, this);
960 RegisterCallbacks(context);
1542 961
1543 if (is_server_) { 962 if (is_server_) {
1544 int certificate_mode = 963 int certificate_mode =
1545 request_client_certificate ? SSL_VERIFY_PEER : SSL_VERIFY_NONE; 964 request_client_certificate ? SSL_VERIFY_PEER : SSL_VERIFY_NONE;
1546 if (require_client_certificate) { 965 if (require_client_certificate) {
1547 certificate_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; 966 certificate_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1548 } 967 }
1549 SSL_set_verify(ssl_, certificate_mode, NULL); 968 SSL_set_verify(ssl_, certificate_mode, NULL);
1550 } else { 969 } else {
1551 SetAlpnProtocolList(protocols_handle, ssl_, NULL, false); 970 SetAlpnProtocolList(protocols_handle, ssl_, NULL, false);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 Log::Print("WriteEncrypted BIO_read wrote %d bytes\n", 1213 Log::Print("WriteEncrypted BIO_read wrote %d bytes\n",
1795 bytes_processed); 1214 bytes_processed);
1796 } 1215 }
1797 } 1216 }
1798 return bytes_processed; 1217 return bytes_processed;
1799 } 1218 }
1800 1219
1801 } // namespace bin 1220 } // namespace bin
1802 } // namespace dart 1221 } // namespace dart
1803 1222
1804 #endif // defined(HOST_OS_LINUX)
1805
1806 #endif // !defined(DART_IO_DISABLED) && 1223 #endif // !defined(DART_IO_DISABLED) &&
1807 // !defined(DART_IO_SECURE_SOCKET_DISABLED) 1224 // !defined(DART_IO_SECURE_SOCKET_DISABLED)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698