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

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

Issue 2903743002: Porting SecureSocket to use BoringSSL on OSX (Closed)
Patch Set: Fixed issues on non-Macos platforms Created 3 years, 6 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
« no previous file with comments | « runtime/bin/secure_socket.h ('k') | runtime/bin/secure_socket_boringssl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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" 8 #include "bin/secure_socket_utils.h"
13 9
14 #include <errno.h> 10 #include <errno.h>
15 #include <fcntl.h> 11 #include <fcntl.h>
16 #include <stdarg.h> 12 #include <stdarg.h>
17 #include <stdio.h> 13 #include <stdio.h>
18 #include <string.h> 14 #include <string.h>
19 #include <sys/stat.h> 15 #include <sys/stat.h>
20 16
21 #include <openssl/bio.h> 17 #include <openssl/bio.h>
22 #include <openssl/err.h> 18 #include <openssl/err.h>
23 #include <openssl/pkcs12.h> 19 #include <openssl/pkcs12.h>
24 #include <openssl/safestack.h> 20 #include <openssl/safestack.h>
25 #include <openssl/ssl.h> 21 #include <openssl/ssl.h>
26 #include <openssl/tls1.h> 22 #include <openssl/tls1.h>
27 #include <openssl/x509.h> 23 #include <openssl/x509.h>
28 24
25 #include "platform/globals.h"
26
29 #include "bin/builtin.h" 27 #include "bin/builtin.h"
30 #include "bin/dartutils.h" 28 #include "bin/dartutils.h"
31 #include "bin/directory.h" 29 #include "bin/directory.h"
32 #include "bin/file.h" 30 #include "bin/file.h"
33 #include "bin/lockers.h" 31 #include "bin/lockers.h"
34 #include "bin/log.h" 32 #include "bin/log.h"
35 #include "bin/socket.h" 33 #include "bin/socket.h"
36 #include "bin/thread.h" 34 #include "bin/thread.h"
37 #include "bin/utils.h" 35 #include "bin/utils.h"
38 #include "platform/text_buffer.h" 36 #include "platform/text_buffer.h"
39 #include "platform/utils.h" 37 #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. 38 // Return the error from the containing function if handle is an error handle.
44 #define RETURN_IF_ERROR(handle) \ 39 #define RETURN_IF_ERROR(handle) \
45 { \ 40 { \
46 Dart_Handle __handle = handle; \ 41 Dart_Handle __handle = handle; \
47 if (Dart_IsError((__handle))) { \ 42 if (Dart_IsError((__handle))) { \
48 return __handle; \ 43 return __handle; \
49 } \ 44 } \
50 } 45 }
51 46
52 namespace dart { 47 namespace dart {
53 namespace bin { 48 namespace bin {
54 49
55 bool SSLFilter::library_initialized_ = false; 50 bool SSLFilter::library_initialized_ = false;
56 // To protect library initialization. 51 // To protect library initialization.
57 Mutex* SSLFilter::mutex_ = new Mutex(); 52 Mutex* SSLFilter::mutex_ = new Mutex();
58 int SSLFilter::filter_ssl_index; 53 int SSLFilter::filter_ssl_index;
59 54
60 const intptr_t SSLFilter::kInternalBIOSize = 10 * KB; 55 const intptr_t SSLFilter::kInternalBIOSize = 10 * KB;
61 const intptr_t SSLFilter::kApproximateSize = 56 const intptr_t SSLFilter::kApproximateSize =
62 sizeof(SSLFilter) + (2 * SSLFilter::kInternalBIOSize); 57 sizeof(SSLFilter) + (2 * SSLFilter::kInternalBIOSize);
63 58
64 // The security context won't necessarily use the compiled-in root certificates,
65 // but since there is no way to update the size of the allocation after creating
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
78 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000; 59 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000;
79 60
80 const char* commandline_root_certs_file = NULL;
81 const char* commandline_root_certs_cache = NULL;
82
83 // Get the error messages from BoringSSL, and put them in buffer as a 61 // Get the error messages from BoringSSL, and put them in buffer as a
84 // null-terminated string. 62 // null-terminated string.
85 static void FetchErrorString(const SSL* ssl, TextBuffer* text_buffer) { 63 static void FetchErrorString(const SSL* ssl, TextBuffer* text_buffer) {
86 const char* sep = File::PathSeparator(); 64 const char* sep = File::PathSeparator();
87 while (true) { 65 while (true) {
88 const char* path = NULL; 66 const char* path = NULL;
89 int line = -1; 67 int line = -1;
90 uint32_t error = ERR_get_error_line(&path, &line); 68 uint32_t error = ERR_get_error_line(&path, &line);
91 if (error == 0) { 69 if (error == 0) {
92 break; 70 break;
93 } 71 }
94 text_buffer->Printf("\n\t%s", ERR_reason_error_string(error)); 72 text_buffer->Printf("\n\t%s", ERR_reason_error_string(error));
95 if ((ssl != NULL) && (ERR_GET_LIB(error) == ERR_LIB_SSL) && 73 if ((ssl != NULL) && (ERR_GET_LIB(error) == ERR_LIB_SSL) &&
96 (ERR_GET_REASON(error) == SSL_R_CERTIFICATE_VERIFY_FAILED)) { 74 (ERR_GET_REASON(error) == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
97 intptr_t result = SSL_get_verify_result(ssl); 75 intptr_t result = SSL_get_verify_result(ssl);
98 text_buffer->Printf(": %s", X509_verify_cert_error_string(result)); 76 text_buffer->Printf(": %s", X509_verify_cert_error_string(result));
99 } 77 }
100 if ((path != NULL) && (line >= 0)) { 78 if ((path != NULL) && (line >= 0)) {
101 const char* file = strrchr(path, sep[0]); 79 const char* file = strrchr(path, sep[0]);
102 path = file ? file + 1 : path; 80 path = file ? file + 1 : path;
103 text_buffer->Printf("(%s:%d)", path, line); 81 text_buffer->Printf("(%s:%d)", path, line);
104 } 82 }
105 } 83 }
106 } 84 }
107 85
108 86
109 // Handle an error reported from the BoringSSL library. 87 // Handle an error reported from the BoringSSL library.
110 static void ThrowIOException(int status, 88 void SecureSocketUtils::ThrowIOException(int status,
zra 2017/05/30 16:15:36 Please keep the SecureSocketUtils methods all toge
111 const char* exception_type, 89 const char* exception_type,
112 const char* message, 90 const char* message,
113 const SSL* ssl) { 91 const SSL* ssl) {
114 Dart_Handle exception; 92 Dart_Handle exception;
115 { 93 {
116 TextBuffer error_string(SSL_ERROR_MESSAGE_BUFFER_SIZE); 94 TextBuffer error_string(SSL_ERROR_MESSAGE_BUFFER_SIZE);
117 FetchErrorString(ssl, &error_string); 95 FetchErrorString(ssl, &error_string);
118 OSError os_error_struct(status, error_string.buf(), OSError::kBoringSSL); 96 OSError os_error_struct(status, error_string.buf(), OSError::kBoringSSL);
119 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct); 97 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
120 exception = 98 exception =
121 DartUtils::NewDartIOException(exception_type, message, os_error); 99 DartUtils::NewDartIOException(exception_type, message, os_error);
122 ASSERT(!Dart_IsError(exception)); 100 ASSERT(!Dart_IsError(exception));
123 } 101 }
124 Dart_ThrowException(exception); 102 Dart_ThrowException(exception);
125 UNREACHABLE(); 103 UNREACHABLE();
126 } 104 }
127 105
128 106
129 static SSLFilter* GetFilter(Dart_NativeArguments args) { 107 static SSLFilter* GetFilter(Dart_NativeArguments args) {
130 SSLFilter* filter; 108 SSLFilter* filter;
131 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); 109 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
132 ASSERT(Dart_IsInstance(dart_this)); 110 ASSERT(Dart_IsInstance(dart_this));
133 ThrowIfError( 111 ThrowIfError(Dart_GetNativeInstanceField(
134 Dart_GetNativeInstanceField(dart_this, kSSLFilterNativeFieldIndex, 112 dart_this, SSLFilter::kSSLFilterNativeFieldIndex,
135 reinterpret_cast<intptr_t*>(&filter))); 113 reinterpret_cast<intptr_t*>(&filter)));
136 return filter; 114 return filter;
137 } 115 }
138 116
139 117
140 static void DeleteFilter(void* isolate_data, 118 static void DeleteFilter(void* isolate_data,
141 Dart_WeakPersistentHandle handle, 119 Dart_WeakPersistentHandle handle,
142 void* context_pointer) { 120 void* context_pointer) {
143 SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer); 121 SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer);
144 filter->Release(); 122 filter->Release();
145 } 123 }
146 124
147 125
148 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { 126 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) {
149 ASSERT(filter != NULL); 127 ASSERT(filter != NULL);
150 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); 128 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
151 RETURN_IF_ERROR(dart_this); 129 RETURN_IF_ERROR(dart_this);
152 ASSERT(Dart_IsInstance(dart_this)); 130 ASSERT(Dart_IsInstance(dart_this));
153 Dart_Handle err = 131 Dart_Handle err = Dart_SetNativeInstanceField(
154 Dart_SetNativeInstanceField(dart_this, kSSLFilterNativeFieldIndex, 132 dart_this, SSLFilter::kSSLFilterNativeFieldIndex,
155 reinterpret_cast<intptr_t>(filter)); 133 reinterpret_cast<intptr_t>(filter));
156 RETURN_IF_ERROR(err); 134 RETURN_IF_ERROR(err);
157 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(filter), 135 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(filter),
158 SSLFilter::kApproximateSize, DeleteFilter); 136 SSLFilter::kApproximateSize, DeleteFilter);
159 return Dart_Null(); 137 return Dart_Null();
160 } 138 }
161 139
162 140
163 static SSLContext* GetSecurityContext(Dart_NativeArguments args) { 141 SSLCertContext* SSLCertContext::GetSecurityContext(Dart_NativeArguments args) {
164 SSLContext* context; 142 SSLCertContext* context;
165 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); 143 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
166 ASSERT(Dart_IsInstance(dart_this)); 144 ASSERT(Dart_IsInstance(dart_this));
167 ThrowIfError( 145 ThrowIfError(Dart_GetNativeInstanceField(
168 Dart_GetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, 146 dart_this, SSLCertContext::kSecurityContextNativeFieldIndex,
169 reinterpret_cast<intptr_t*>(&context))); 147 reinterpret_cast<intptr_t*>(&context)));
170 return context; 148 return context;
171 } 149 }
172 150
173 151
174 static void DeleteSecurityContext(void* isolate_data, 152 static void DeleteSecurityContext(void* isolate_data,
175 Dart_WeakPersistentHandle handle, 153 Dart_WeakPersistentHandle handle,
176 void* context_pointer) { 154 void* context_pointer) {
177 SSLContext* context = static_cast<SSLContext*>(context_pointer); 155 SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer);
178 delete context; 156 context->Release();
179 } 157 }
180 158
181 159
182 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, 160 static Dart_Handle SetSecurityContext(Dart_NativeArguments args,
183 SSLContext* context) { 161 SSLCertContext* context) {
184 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); 162 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
185 RETURN_IF_ERROR(dart_this); 163 RETURN_IF_ERROR(dart_this);
186 ASSERT(Dart_IsInstance(dart_this)); 164 ASSERT(Dart_IsInstance(dart_this));
187 Dart_Handle err = 165 Dart_Handle err = Dart_SetNativeInstanceField(
188 Dart_SetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, 166 dart_this, SSLCertContext::kSecurityContextNativeFieldIndex,
189 reinterpret_cast<intptr_t>(context)); 167 reinterpret_cast<intptr_t>(context));
190 RETURN_IF_ERROR(err); 168 RETURN_IF_ERROR(err);
191 Dart_NewWeakPersistentHandle(dart_this, context, SSLContext::kApproximateSize, 169 Dart_NewWeakPersistentHandle(dart_this, context,
170 SSLCertContext::kApproximateSize,
192 DeleteSecurityContext); 171 DeleteSecurityContext);
193 return Dart_Null(); 172 return Dart_Null();
194 } 173 }
195 174
196 175
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. 176 // Forward declaration.
209 static void SetAlpnProtocolList(Dart_Handle protocols_handle, 177 static void SetAlpnProtocolList(Dart_Handle protocols_handle,
210 SSL* ssl, 178 SSL* ssl,
211 SSLContext* context, 179 SSLCertContext* context,
212 bool is_server); 180 bool is_server);
213 181
214 182
215 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) { 183 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) {
216 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); 184 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
217 SSLFilter* filter = new SSLFilter(); 185 SSLFilter* filter = new SSLFilter();
218 Dart_Handle err = SetFilter(args, filter); 186 Dart_Handle err = SetFilter(args, filter);
219 if (Dart_IsError(err)) { 187 if (Dart_IsError(err)) {
220 filter->Release(); 188 filter->Release();
221 Dart_PropagateError(err); 189 Dart_PropagateError(err);
(...skipping 15 matching lines...) Expand all
237 bool request_client_certificate = 205 bool request_client_certificate =
238 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); 206 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
239 bool require_client_certificate = 207 bool require_client_certificate =
240 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5)); 208 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5));
241 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 6)); 209 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 6));
242 210
243 const char* host_name = NULL; 211 const char* host_name = NULL;
244 // TODO(whesse): Is truncating a Dart string containing \0 what we want? 212 // TODO(whesse): Is truncating a Dart string containing \0 what we want?
245 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); 213 ThrowIfError(Dart_StringToCString(host_name_object, &host_name));
246 214
247 SSLContext* context = NULL; 215 SSLCertContext* context = NULL;
248 if (!Dart_IsNull(context_object)) { 216 if (!Dart_IsNull(context_object)) {
249 ThrowIfError(Dart_GetNativeInstanceField( 217 ThrowIfError(Dart_GetNativeInstanceField(
250 context_object, kSecurityContextNativeFieldIndex, 218 context_object, SSLCertContext::kSecurityContextNativeFieldIndex,
251 reinterpret_cast<intptr_t*>(&context))); 219 reinterpret_cast<intptr_t*>(&context)));
252 } 220 }
253 221
254 // The protocols_handle is guaranteed to be a valid Uint8List. 222 // The protocols_handle is guaranteed to be a valid Uint8List.
255 // It will have the correct length encoding of the protocols array. 223 // It will have the correct length encoding of the protocols array.
256 ASSERT(!Dart_IsNull(protocols_handle)); 224 ASSERT(!Dart_IsNull(protocols_handle));
257 225
258 GetFilter(args)->Connect(host_name, context->context(), is_server, 226 GetFilter(args)->Connect(host_name, context, is_server,
259 request_client_certificate, 227 request_client_certificate,
260 require_client_certificate, protocols_handle); 228 require_client_certificate, protocols_handle);
261 } 229 }
262 230
263 231
264 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { 232 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) {
265 SSLFilter* filter = GetFilter(args); 233 SSLFilter* filter = GetFilter(args);
266 // There are two paths that can clean up an SSLFilter object. First, 234 // There are two paths that can clean up an SSLFilter object. First,
267 // there is this explicit call to Destroy(), called from 235 // there is this explicit call to Destroy(), called from
268 // _SecureFilter.destroy() in Dart code. After a call to destroy(), the Dart 236 // _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) { 300 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) {
333 SSLFilter* filter = GetFilter(args); 301 SSLFilter* filter = GetFilter(args);
334 // This filter pointer is passed to the IO Service thread. The IO Service 302 // 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. 303 // thread must Release() the pointer when it is done with it.
336 filter->Retain(); 304 filter->Retain();
337 intptr_t filter_pointer = reinterpret_cast<intptr_t>(filter); 305 intptr_t filter_pointer = reinterpret_cast<intptr_t>(filter);
338 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); 306 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer));
339 } 307 }
340 308
341 309
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) { 310 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) {
438 SSLFilter::InitializeLibrary(); 311 SSLFilter::InitializeLibrary();
439 SSL_CTX* ctx = SSL_CTX_new(TLS_method()); 312 SSL_CTX* ctx = SSL_CTX_new(TLS_method());
440 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, CertificateCallback); 313 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, CertificateCallback);
441 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION); 314 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
442 SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM"); 315 SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM");
443 SSLContext* context = new SSLContext(ctx); 316 SSLCertContext* context = new SSLCertContext(ctx);
444 Dart_Handle err = SetSecurityContext(args, context); 317 Dart_Handle err = SetSecurityContext(args, context);
445 if (Dart_IsError(err)) { 318 if (Dart_IsError(err)) {
446 delete context; 319 delete context;
447 Dart_PropagateError(err); 320 Dart_PropagateError(err);
448 } 321 }
449 } 322 }
450 323
451 324
452 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) { 325 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) {
453 char* password = static_cast<char*>(userdata); 326 char* password = static_cast<char*>(userdata);
454 ASSERT(size == PEM_BUFSIZE); 327 ASSERT(size == PEM_BUFSIZE);
455 strncpy(buf, password, size); 328 strncpy(buf, password, size);
456 return strlen(password); 329 return strlen(password);
457 } 330 }
458 331
459 332
460 void CheckStatusSSL(int status, 333 void SecureSocketUtils::CheckStatusSSL(int status,
461 const char* type, 334 const char* type,
462 const char* message, 335 const char* message,
463 const SSL* ssl) { 336 const SSL* ssl) {
464 // TODO(24183): Take appropriate action on failed calls, 337 // TODO(24183): Take appropriate action on failed calls,
465 // throw exception that includes all messages from the error stack. 338 // throw exception that includes all messages from the error stack.
466 if (status == 1) { 339 if (status == 1) {
467 return; 340 return;
468 } 341 }
469 if (SSL_LOG_STATUS) { 342 if (SSL_LOG_STATUS) {
470 int error = ERR_get_error(); 343 int error = ERR_get_error();
471 Log::PrintErr("Failed: %s status %d", message, status); 344 Log::PrintErr("Failed: %s status %d", message, status);
472 char error_string[SSL_ERROR_MESSAGE_BUFFER_SIZE]; 345 char error_string[SSL_ERROR_MESSAGE_BUFFER_SIZE];
473 ERR_error_string_n(error, error_string, SSL_ERROR_MESSAGE_BUFFER_SIZE); 346 ERR_error_string_n(error, error_string, SSL_ERROR_MESSAGE_BUFFER_SIZE);
474 Log::PrintErr("ERROR: %d %s\n", error, error_string); 347 Log::PrintErr("ERROR: %d %s\n", error, error_string);
475 } 348 }
476 ThrowIOException(status, type, message, ssl); 349 SecureSocketUtils::ThrowIOException(status, type, message, ssl);
477 } 350 }
478 351
479 352
480 void CheckStatus(int status, const char* type, const char* message) { 353 void SecureSocketUtils::CheckStatus(int status,
481 CheckStatusSSL(status, type, message, NULL); 354 const char* type,
355 const char* message) {
356 SecureSocketUtils::CheckStatusSSL(status, type, message, NULL);
482 } 357 }
483 358
484 359
485 // Where the argument to the constructor is the handle for an object
486 // implementing List<int>, this class creates a scope in which a memory-backed
487 // BIO is allocated. Leaving the scope cleans up the BIO and the buffer that
488 // was used to create it.
489 //
490 // Do not make Dart_ API calls while in a ScopedMemBIO.
491 // Do not call Dart_PropagateError while in a ScopedMemBIO.
492 class ScopedMemBIO {
493 public:
494 explicit ScopedMemBIO(Dart_Handle object) {
495 if (!Dart_IsTypedData(object) && !Dart_IsList(object)) {
496 Dart_ThrowException(
497 DartUtils::NewDartArgumentError("Argument is not a List<int>"));
498 }
499
500 uint8_t* bytes = NULL;
501 intptr_t bytes_len = 0;
502 bool is_typed_data = false;
503 if (Dart_IsTypedData(object)) {
504 is_typed_data = true;
505 Dart_TypedData_Type typ;
506 ThrowIfError(Dart_TypedDataAcquireData(
507 object, &typ, reinterpret_cast<void**>(&bytes), &bytes_len));
508 } else {
509 ASSERT(Dart_IsList(object));
510 ThrowIfError(Dart_ListLength(object, &bytes_len));
511 bytes = Dart_ScopeAllocate(bytes_len);
512 ASSERT(bytes != NULL);
513 ThrowIfError(Dart_ListGetAsBytes(object, 0, bytes, bytes_len));
514 }
515
516 object_ = object;
517 bytes_ = bytes;
518 bytes_len_ = bytes_len;
519 bio_ = BIO_new_mem_buf(bytes, bytes_len);
520 ASSERT(bio_ != NULL);
521 is_typed_data_ = is_typed_data;
522 }
523
524 ~ScopedMemBIO() {
525 ASSERT(bio_ != NULL);
526 if (is_typed_data_) {
527 BIO_free(bio_);
528 ThrowIfError(Dart_TypedDataReleaseData(object_));
529 } else {
530 BIO_free(bio_);
531 }
532 }
533
534 BIO* bio() {
535 ASSERT(bio_ != NULL);
536 return bio_;
537 }
538
539 private:
540 Dart_Handle object_;
541 uint8_t* bytes_;
542 intptr_t bytes_len_;
543 BIO* bio_;
544 bool is_typed_data_;
545
546 DISALLOW_ALLOCATION();
547 DISALLOW_COPY_AND_ASSIGN(ScopedMemBIO);
548 };
549
550 template <typename T, void (*free_func)(T*)>
551 class ScopedSSLType {
552 public:
553 explicit ScopedSSLType(T* obj) : obj_(obj) {}
554
555 ~ScopedSSLType() {
556 if (obj_ != NULL) {
557 free_func(obj_);
558 }
559 }
560
561 T* get() { return obj_; }
562 const T* get() const { return obj_; }
563
564 T* release() {
565 T* result = obj_;
566 obj_ = NULL;
567 return result;
568 }
569
570 private:
571 T* obj_;
572
573 DISALLOW_ALLOCATION();
574 DISALLOW_COPY_AND_ASSIGN(ScopedSSLType);
575 };
576
577 template <typename T, typename E, void (*func)(E*)>
578 class ScopedSSLStackType {
579 public:
580 explicit ScopedSSLStackType(T* obj) : obj_(obj) {}
581
582 ~ScopedSSLStackType() {
583 if (obj_ != NULL) {
584 sk_pop_free(reinterpret_cast<_STACK*>(obj_),
585 reinterpret_cast<void (*)(void*)>(func));
586 }
587 }
588
589 T* get() { return obj_; }
590 const T* get() const { return obj_; }
591
592 T* release() {
593 T* result = obj_;
594 obj_ = NULL;
595 return result;
596 }
597
598 private:
599 T* obj_;
600
601 DISALLOW_ALLOCATION();
602 DISALLOW_COPY_AND_ASSIGN(ScopedSSLStackType);
603 };
604
605 typedef ScopedSSLType<PKCS12, PKCS12_free> ScopedPKCS12;
606 typedef ScopedSSLType<X509, X509_free> ScopedX509;
607 typedef ScopedSSLStackType<STACK_OF(X509), X509, X509_free> ScopedX509Stack;
608
609 static bool NoPEMStartLine() {
610 uint32_t last_error = ERR_peek_last_error();
611 return (ERR_GET_LIB(last_error) == ERR_LIB_PEM) &&
612 (ERR_GET_REASON(last_error) == PEM_R_NO_START_LINE);
613 }
614
615
616 static EVP_PKEY* GetPrivateKeyPKCS12(BIO* bio, const char* password) { 360 static EVP_PKEY* GetPrivateKeyPKCS12(BIO* bio, const char* password) {
617 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); 361 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
618 if (p12.get() == NULL) { 362 if (p12.get() == NULL) {
619 return NULL; 363 return NULL;
620 } 364 }
621 365
622 EVP_PKEY* key = NULL; 366 EVP_PKEY* key = NULL;
623 X509* cert = NULL; 367 X509* cert = NULL;
624 STACK_OF(X509)* ca_certs = NULL; 368 STACK_OF(X509)* ca_certs = NULL;
625 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs); 369 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
626 if (status == 0) { 370 if (status == 0) {
627 return NULL; 371 return NULL;
628 } 372 }
629 373
630 // We only care about the private key. 374 // We only care about the private key.
631 ScopedX509 delete_cert(cert); 375 ScopedX509 delete_cert(cert);
632 ScopedX509Stack delete_ca_certs(ca_certs); 376 ScopedX509Stack delete_ca_certs(ca_certs);
633 return key; 377 return key;
634 } 378 }
635 379
636 380
637 static EVP_PKEY* GetPrivateKey(BIO* bio, const char* password) { 381 static EVP_PKEY* GetPrivateKey(BIO* bio, const char* password) {
638 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, PasswordCallback, 382 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, PasswordCallback,
639 const_cast<char*>(password)); 383 const_cast<char*>(password));
640 if (key == NULL) { 384 if (key == NULL) {
641 // We try reading data as PKCS12 only if reading as PEM was unsuccessful and 385 // We try reading data as PKCS12 only if reading as PEM was unsuccessful and
642 // if there is no indication that the data is malformed PEM. We assume the 386 // if there is no indication that the data is malformed PEM. We assume the
643 // data is malformed PEM if it contains the start line, i.e. a line 387 // data is malformed PEM if it contains the start line, i.e. a line
644 // with ----- BEGIN. 388 // with ----- BEGIN.
645 if (NoPEMStartLine()) { 389 if (SecureSocketUtils::NoPEMStartLine()) {
646 // Reset the bio, and clear the error from trying to read as PEM. 390 // Reset the bio, and clear the error from trying to read as PEM.
647 ERR_clear_error(); 391 ERR_clear_error();
648 BIO_reset(bio); 392 BIO_reset(bio);
649 393
650 // Try to decode as PKCS12. 394 // Try to decode as PKCS12.
651 key = GetPrivateKeyPKCS12(bio, password); 395 key = GetPrivateKeyPKCS12(bio, password);
652 } 396 }
653 } 397 }
654 return key; 398 return key;
655 } 399 }
656 400
657 401
658 static const char* GetPasswordArgument(Dart_NativeArguments args, 402 const char* SSLCertContext::GetPasswordArgument(Dart_NativeArguments args,
659 intptr_t index) { 403 intptr_t index) {
660 Dart_Handle password_object = 404 Dart_Handle password_object =
661 ThrowIfError(Dart_GetNativeArgument(args, index)); 405 ThrowIfError(Dart_GetNativeArgument(args, index));
662 const char* password = NULL; 406 const char* password = NULL;
663 if (Dart_IsString(password_object)) { 407 if (Dart_IsString(password_object)) {
664 ThrowIfError(Dart_StringToCString(password_object, &password)); 408 ThrowIfError(Dart_StringToCString(password_object, &password));
665 if (strlen(password) > PEM_BUFSIZE - 1) { 409 if (strlen(password) > PEM_BUFSIZE - 1) {
666 Dart_ThrowException(DartUtils::NewDartArgumentError( 410 Dart_ThrowException(DartUtils::NewDartArgumentError(
667 "Password length is greater than 1023 (PEM_BUFSIZE)")); 411 "Password length is greater than 1023 (PEM_BUFSIZE)"));
668 } 412 }
669 } else if (Dart_IsNull(password_object)) { 413 } else if (Dart_IsNull(password_object)) {
670 password = ""; 414 password = "";
671 } else { 415 } else {
672 Dart_ThrowException( 416 Dart_ThrowException(
673 DartUtils::NewDartArgumentError("Password is not a String or null")); 417 DartUtils::NewDartArgumentError("Password is not a String or null"));
674 } 418 }
675 return password; 419 return password;
676 } 420 }
677 421
678 422
679 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( 423 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
680 Dart_NativeArguments args) { 424 Dart_NativeArguments args) {
681 SSLContext* context = GetSecurityContext(args); 425 SSLCertContext* context = SSLCertContext::GetSecurityContext(args);
682 const char* password = GetPasswordArgument(args, 2); 426 const char* password = SSLCertContext::GetPasswordArgument(args, 2);
683 427
684 int status; 428 int status;
685 { 429 {
686 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 430 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
687 EVP_PKEY* key = GetPrivateKey(bio.bio(), password); 431 EVP_PKEY* key = GetPrivateKey(bio.bio(), password);
688 status = SSL_CTX_use_PrivateKey(context->context(), key); 432 status = SSL_CTX_use_PrivateKey(context->context(), key);
689 // SSL_CTX_use_PrivateKey increments the reference count of key on success, 433 // 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. 434 // so we have to call EVP_PKEY_free on both success and failure.
691 EVP_PKEY_free(key); 435 EVP_PKEY_free(key);
692 } 436 }
693 437
694 // TODO(24184): Handle different expected errors here - file missing, 438 // TODO(24184): Handle different expected errors here - file missing,
695 // incorrect password, file not a PEM, and throw exceptions. 439 // incorrect password, file not a PEM, and throw exceptions.
696 // CheckStatus should also throw an exception in uncaught cases. 440 // SecureSocketUtils::CheckStatus should also throw an exception in uncaught
697 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes"); 441 // cases.
698 } 442 SecureSocketUtils::CheckStatus(status, "TlsException",
699 443 "Failure in usePrivateKeyBytes");
700
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)(
zra 2017/05/30 16:15:36 To be consistent with other parts of the dart:io i
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 } 444 }
1108 445
1109 446
1110 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( 447 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)(
1111 Dart_NativeArguments args) { 448 Dart_NativeArguments args) {
1112 SSLContext* context = GetSecurityContext(args); 449 SSLCertContext* context = SSLCertContext::GetSecurityContext(args);
1113 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 1)); 450 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 1));
1114 Dart_Handle is_server_handle = ThrowIfError(Dart_GetNativeArgument(args, 2)); 451 Dart_Handle is_server_handle = ThrowIfError(Dart_GetNativeArgument(args, 2));
1115 if (Dart_IsBoolean(is_server_handle)) { 452 if (Dart_IsBoolean(is_server_handle)) {
1116 bool is_server = DartUtils::GetBooleanValue(is_server_handle); 453 bool is_server = DartUtils::GetBooleanValue(is_server_handle);
1117 SetAlpnProtocolList(protocols_handle, NULL, context, is_server); 454 SetAlpnProtocolList(protocols_handle, NULL, context, is_server);
1118 } else { 455 } else {
1119 Dart_ThrowException(DartUtils::NewDartArgumentError( 456 Dart_ThrowException(DartUtils::NewDartArgumentError(
1120 "Non-boolean is_server argument passed to SetAlpnProtocols")); 457 "Non-boolean is_server argument passed to SetAlpnProtocols"));
1121 } 458 }
1122 } 459 }
1123 460
1124 461
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 /** 462 /**
1171 * Pushes data through the SSL filter, reading and writing from circular 463 * Pushes data through the SSL filter, reading and writing from circular
1172 * buffers shared with Dart. 464 * buffers shared with Dart.
1173 * 465 *
1174 * The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to 466 * The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to
1175 * pass encrypted and plaintext data to and from the C++ SSLFilter object. 467 * pass encrypted and plaintext data to and from the C++ SSLFilter object.
1176 * 468 *
1177 * ProcessFilter is called with a CObject array containing the pointer to 469 * 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 470 * 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 471 * valid data in the four circular buffers. The function only reads from
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 } 513 }
1222 514
1223 515
1224 bool SSLFilter::ProcessAllBuffers(int starts[kNumBuffers], 516 bool SSLFilter::ProcessAllBuffers(int starts[kNumBuffers],
1225 int ends[kNumBuffers], 517 int ends[kNumBuffers],
1226 bool in_handshake) { 518 bool in_handshake) {
1227 for (int i = 0; i < kNumBuffers; ++i) { 519 for (int i = 0; i < kNumBuffers; ++i) {
1228 if (in_handshake && (i == kReadPlaintext || i == kWritePlaintext)) continue; 520 if (in_handshake && (i == kReadPlaintext || i == kWritePlaintext)) continue;
1229 int start = starts[i]; 521 int start = starts[i];
1230 int end = ends[i]; 522 int end = ends[i];
1231 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; 523 int size = IsBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_;
1232 if (start < 0 || end < 0 || start >= size || end >= size) { 524 if (start < 0 || end < 0 || start >= size || end >= size) {
1233 FATAL("Out-of-bounds internal buffer access in dart:io SecureSocket"); 525 FATAL("Out-of-bounds internal buffer access in dart:io SecureSocket");
1234 } 526 }
1235 switch (i) { 527 switch (i) {
1236 case kReadPlaintext: 528 case kReadPlaintext:
1237 case kWriteEncrypted: 529 case kWriteEncrypted:
1238 // Write data to the circular buffer's free space. If the buffer 530 // Write data to the circular buffer's free space. If the buffer
1239 // is full, neither if statement is executed and nothing happens. 531 // is full, neither if statement is executed and nothing happens.
1240 if (start <= end) { 532 if (start <= end) {
1241 // If the free space may be split into two segments, 533 // If the free space may be split into two segments,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 } 592 }
1301 ASSERT(string_start_ == NULL); 593 ASSERT(string_start_ == NULL);
1302 string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start")); 594 string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start"));
1303 ASSERT(string_start_ != NULL); 595 ASSERT(string_start_ != NULL);
1304 ASSERT(string_length_ == NULL); 596 ASSERT(string_length_ == NULL);
1305 string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length")); 597 string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length"));
1306 ASSERT(string_length_ != NULL); 598 ASSERT(string_length_ != NULL);
1307 ASSERT(bad_certificate_callback_ == NULL); 599 ASSERT(bad_certificate_callback_ == NULL);
1308 bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null()); 600 bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null());
1309 ASSERT(bad_certificate_callback_ != NULL); 601 ASSERT(bad_certificate_callback_ != NULL);
1310
1311 // Caller handles cleanup on an error. 602 // Caller handles cleanup on an error.
1312 return InitializeBuffers(dart_this); 603 return InitializeBuffers(dart_this);
1313 } 604 }
1314 605
1315 606
1316 Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) { 607 Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) {
1317 // Create SSLFilter buffers as ExternalUint8Array objects. 608 // Create SSLFilter buffers as ExternalUint8Array objects.
1318 Dart_Handle buffers_string = DartUtils::NewString("buffers"); 609 Dart_Handle buffers_string = DartUtils::NewString("buffers");
1319 RETURN_IF_ERROR(buffers_string); 610 RETURN_IF_ERROR(buffers_string);
1320 Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string); 611 Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string);
(...skipping 27 matching lines...) Expand all
1348 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 * MB) { 639 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 * MB) {
1349 FATAL("Invalid encrypted buffer size in _ExternalBuffer"); 640 FATAL("Invalid encrypted buffer size in _ExternalBuffer");
1350 } 641 }
1351 buffer_size_ = static_cast<int>(buffer_size); 642 buffer_size_ = static_cast<int>(buffer_size);
1352 encrypted_buffer_size_ = static_cast<int>(encrypted_buffer_size); 643 encrypted_buffer_size_ = static_cast<int>(encrypted_buffer_size);
1353 644
1354 Dart_Handle data_identifier = DartUtils::NewString("data"); 645 Dart_Handle data_identifier = DartUtils::NewString("data");
1355 RETURN_IF_ERROR(data_identifier); 646 RETURN_IF_ERROR(data_identifier);
1356 647
1357 for (int i = 0; i < kNumBuffers; i++) { 648 for (int i = 0; i < kNumBuffers; i++) {
1358 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; 649 int size = IsBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_;
1359 buffers_[i] = new uint8_t[size]; 650 buffers_[i] = new uint8_t[size];
1360 ASSERT(buffers_[i] != NULL); 651 ASSERT(buffers_[i] != NULL);
1361 dart_buffer_objects_[i] = NULL; 652 dart_buffer_objects_[i] = NULL;
1362 } 653 }
1363 654
1364 Dart_Handle result = Dart_Null(); 655 Dart_Handle result = Dart_Null();
1365 for (int i = 0; i < kNumBuffers; ++i) { 656 for (int i = 0; i < kNumBuffers; ++i) {
1366 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; 657 int size = IsBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_;
1367 result = Dart_ListGetAt(dart_buffers_object, i); 658 result = Dart_ListGetAt(dart_buffers_object, i);
1368 if (Dart_IsError(result)) { 659 if (Dart_IsError(result)) {
1369 break; 660 break;
1370 } 661 }
1371 662
1372 dart_buffer_objects_[i] = Dart_NewPersistentHandle(result); 663 dart_buffer_objects_[i] = Dart_NewPersistentHandle(result);
1373 ASSERT(dart_buffer_objects_[i] != NULL); 664 ASSERT(dart_buffer_objects_[i] != NULL);
1374 Dart_Handle data = 665 Dart_Handle data =
1375 Dart_NewExternalTypedData(Dart_TypedData_kUint8, buffers_[i], size); 666 Dart_NewExternalTypedData(Dart_TypedData_kUint8, buffers_[i], size);
1376 if (Dart_IsError(data)) { 667 if (Dart_IsError(data)) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 MutexLocker locker(mutex_); 703 MutexLocker locker(mutex_);
1413 if (!library_initialized_) { 704 if (!library_initialized_) {
1414 SSL_library_init(); 705 SSL_library_init();
1415 filter_ssl_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); 706 filter_ssl_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
1416 ASSERT(filter_ssl_index >= 0); 707 ASSERT(filter_ssl_index >= 0);
1417 library_initialized_ = true; 708 library_initialized_ = true;
1418 } 709 }
1419 } 710 }
1420 711
1421 712
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, 713 int AlpnCallback(SSL* ssl,
1431 const uint8_t** out, 714 const uint8_t** out,
1432 uint8_t* outlen, 715 uint8_t* outlen,
1433 const uint8_t* in, 716 const uint8_t* in,
1434 unsigned int inlen, 717 unsigned int inlen,
1435 void* arg) { 718 void* arg) {
1436 // 'in' and 'arg' are sequences of (length, data) strings with 1-byte lengths. 719 // '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'. 720 // 'arg' is 0-terminated. Finds the first string in 'arg' that is in 'in'.
1438 uint8_t* server_list = static_cast<uint8_t*>(arg); 721 uint8_t* server_list = static_cast<uint8_t*>(arg);
1439 while (*server_list != 0) { 722 while (*server_list != 0) {
(...skipping 13 matching lines...) Expand all
1453 server_list += protocol_length; 736 server_list += protocol_length;
1454 } 737 }
1455 // TODO(23580): Make failure send a fatal alert instead of ignoring ALPN. 738 // TODO(23580): Make failure send a fatal alert instead of ignoring ALPN.
1456 return SSL_TLSEXT_ERR_NOACK; 739 return SSL_TLSEXT_ERR_NOACK;
1457 } 740 }
1458 741
1459 742
1460 // Sets the protocol list for ALPN on a SSL object or a context. 743 // Sets the protocol list for ALPN on a SSL object or a context.
1461 static void SetAlpnProtocolList(Dart_Handle protocols_handle, 744 static void SetAlpnProtocolList(Dart_Handle protocols_handle,
1462 SSL* ssl, 745 SSL* ssl,
1463 SSLContext* context, 746 SSLCertContext* context,
1464 bool is_server) { 747 bool is_server) {
1465 // Enable ALPN (application layer protocol negotiation) if the caller provides 748 // Enable ALPN (application layer protocol negotiation) if the caller provides
1466 // a valid list of supported protocols. 749 // a valid list of supported protocols.
1467 Dart_TypedData_Type protocols_type; 750 Dart_TypedData_Type protocols_type;
1468 uint8_t* protocol_string = NULL; 751 uint8_t* protocol_string = NULL;
1469 uint8_t* protocol_string_copy = NULL; 752 uint8_t* protocol_string_copy = NULL;
1470 intptr_t protocol_string_len = 0; 753 intptr_t protocol_string_len = 0;
1471 int status; 754 int status;
1472 755
1473 Dart_Handle result = Dart_TypedDataAcquireData( 756 Dart_Handle result = Dart_TypedDataAcquireData(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 protocol_string_len); 793 protocol_string_len);
1511 } 794 }
1512 ASSERT(status == 0); // The function returns a non-standard status. 795 ASSERT(status == 0); // The function returns a non-standard status.
1513 } 796 }
1514 } 797 }
1515 Dart_TypedDataReleaseData(protocols_handle); 798 Dart_TypedDataReleaseData(protocols_handle);
1516 } 799 }
1517 800
1518 801
1519 void SSLFilter::Connect(const char* hostname, 802 void SSLFilter::Connect(const char* hostname,
1520 SSL_CTX* context, 803 SSLCertContext* context,
1521 bool is_server, 804 bool is_server,
1522 bool request_client_certificate, 805 bool request_client_certificate,
1523 bool require_client_certificate, 806 bool require_client_certificate,
1524 Dart_Handle protocols_handle) { 807 Dart_Handle protocols_handle) {
1525 is_server_ = is_server; 808 is_server_ = is_server;
1526 if (in_handshake_) { 809 if (in_handshake_) {
1527 FATAL("Connect called twice on the same _SecureFilter."); 810 FATAL("Connect called twice on the same _SecureFilter.");
1528 } 811 }
1529 812
1530 int status; 813 int status;
1531 int error; 814 int error;
1532 BIO* ssl_side; 815 BIO* ssl_side;
1533 status = BIO_new_bio_pair(&ssl_side, kInternalBIOSize, &socket_side_, 816 status = BIO_new_bio_pair(&ssl_side, kInternalBIOSize, &socket_side_,
1534 kInternalBIOSize); 817 kInternalBIOSize);
1535 CheckStatusSSL(status, "TlsException", "BIO_new_bio_pair", ssl_); 818 SecureSocketUtils::CheckStatusSSL(status, "TlsException", "BIO_new_bio_pair",
819 ssl_);
1536 820
1537 assert(context != NULL); 821 ASSERT(context != NULL);
1538 ssl_ = SSL_new(context); 822 ASSERT(context->context() != NULL);
823 ssl_ = SSL_new(context->context());
1539 SSL_set_bio(ssl_, ssl_side, ssl_side); 824 SSL_set_bio(ssl_, ssl_side, ssl_side);
1540 SSL_set_mode(ssl_, SSL_MODE_AUTO_RETRY); // TODO(whesse): Is this right? 825 SSL_set_mode(ssl_, SSL_MODE_AUTO_RETRY); // TODO(whesse): Is this right?
1541 SSL_set_ex_data(ssl_, filter_ssl_index, this); 826 SSL_set_ex_data(ssl_, filter_ssl_index, this);
827 RegisterCallbacks(context);
1542 828
1543 if (is_server_) { 829 if (is_server_) {
1544 int certificate_mode = 830 int certificate_mode =
1545 request_client_certificate ? SSL_VERIFY_PEER : SSL_VERIFY_NONE; 831 request_client_certificate ? SSL_VERIFY_PEER : SSL_VERIFY_NONE;
1546 if (require_client_certificate) { 832 if (require_client_certificate) {
1547 certificate_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; 833 certificate_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1548 } 834 }
1549 SSL_set_verify(ssl_, certificate_mode, NULL); 835 SSL_set_verify(ssl_, certificate_mode, NULL);
1550 } else { 836 } else {
1551 SetAlpnProtocolList(protocols_handle, ssl_, NULL, false); 837 SetAlpnProtocolList(protocols_handle, ssl_, NULL, false);
1552 status = SSL_set_tlsext_host_name(ssl_, hostname); 838 status = SSL_set_tlsext_host_name(ssl_, hostname);
1553 CheckStatusSSL(status, "TlsException", "Set SNI host name", ssl_); 839 SecureSocketUtils::CheckStatusSSL(status, "TlsException",
840 "Set SNI host name", ssl_);
1554 // Sets the hostname in the certificate-checking object, so it is checked 841 // Sets the hostname in the certificate-checking object, so it is checked
1555 // against the certificate presented by the server. 842 // against the certificate presented by the server.
1556 X509_VERIFY_PARAM* certificate_checking_parameters = SSL_get0_param(ssl_); 843 X509_VERIFY_PARAM* certificate_checking_parameters = SSL_get0_param(ssl_);
1557 hostname_ = strdup(hostname); 844 hostname_ = strdup(hostname);
1558 X509_VERIFY_PARAM_set_flags( 845 X509_VERIFY_PARAM_set_flags(
1559 certificate_checking_parameters, 846 certificate_checking_parameters,
1560 X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_TRUSTED_FIRST); 847 X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_TRUSTED_FIRST);
1561 X509_VERIFY_PARAM_set_hostflags(certificate_checking_parameters, 0); 848 X509_VERIFY_PARAM_set_hostflags(certificate_checking_parameters, 0);
1562 status = X509_VERIFY_PARAM_set1_host(certificate_checking_parameters, 849 status = X509_VERIFY_PARAM_set1_host(certificate_checking_parameters,
1563 hostname_, strlen(hostname_)); 850 hostname_, strlen(hostname_));
1564 CheckStatusSSL(status, "TlsException", 851 SecureSocketUtils::CheckStatusSSL(
1565 "Set hostname for certificate checking", ssl_); 852 status, "TlsException", "Set hostname for certificate checking", ssl_);
1566 } 853 }
1567 // Make the connection: 854 // Make the connection:
1568 if (is_server_) { 855 if (is_server_) {
1569 status = SSL_accept(ssl_); 856 status = SSL_accept(ssl_);
1570 if (SSL_LOG_STATUS) { 857 if (SSL_LOG_STATUS) {
1571 Log::Print("SSL_accept status: %d\n", status); 858 Log::Print("SSL_accept status: %d\n", status);
1572 } 859 }
1573 if (status != 1) { 860 if (status != 1) {
1574 // TODO(whesse): expect a needs-data error here. Handle other errors. 861 // TODO(whesse): expect a needs-data error here. Handle other errors.
1575 error = SSL_get_error(ssl_, status); 862 error = SSL_get_error(ssl_, status);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 // The SSL_do_handshake will try performing a handshake and might call 895 // The SSL_do_handshake will try performing a handshake and might call
1609 // a CertificateCallback. If the certificate validation 896 // a CertificateCallback. If the certificate validation
1610 // failed the 'callback_error" will be set by the certificateCallback 897 // failed the 'callback_error" will be set by the certificateCallback
1611 // logic and we propagate the error" 898 // logic and we propagate the error"
1612 Dart_PropagateError(callback_error); 899 Dart_PropagateError(callback_error);
1613 } 900 }
1614 if (SSL_want_write(ssl_) || SSL_want_read(ssl_)) { 901 if (SSL_want_write(ssl_) || SSL_want_read(ssl_)) {
1615 in_handshake_ = true; 902 in_handshake_ = true;
1616 return; 903 return;
1617 } 904 }
1618 CheckStatusSSL( 905 SecureSocketUtils::CheckStatusSSL(
1619 status, "HandshakeException", 906 status, "HandshakeException",
1620 is_server_ ? "Handshake error in server" : "Handshake error in client", 907 is_server_ ? "Handshake error in server" : "Handshake error in client",
1621 ssl_); 908 ssl_);
1622 // Handshake succeeded. 909 // Handshake succeeded.
1623 if (in_handshake_) { 910 if (in_handshake_) {
1624 // TODO(24071): Check return value of SSL_get_verify_result, this 911 // TODO(24071): Check return value of SSL_get_verify_result, this
1625 // should give us the hostname check. 912 // should give us the hostname check.
1626 int result = SSL_get_verify_result(ssl_); 913 int result = SSL_get_verify_result(ssl_);
1627 if (SSL_LOG_STATUS) { 914 if (SSL_LOG_STATUS) {
1628 Log::Print("Handshake verification status: %d\n", result); 915 Log::Print("Handshake verification status: %d\n", result);
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 Log::Print("WriteEncrypted BIO_read wrote %d bytes\n", 1081 Log::Print("WriteEncrypted BIO_read wrote %d bytes\n",
1795 bytes_processed); 1082 bytes_processed);
1796 } 1083 }
1797 } 1084 }
1798 return bytes_processed; 1085 return bytes_processed;
1799 } 1086 }
1800 1087
1801 } // namespace bin 1088 } // namespace bin
1802 } // namespace dart 1089 } // namespace dart
1803 1090
1804 #endif // defined(HOST_OS_LINUX)
1805
1806 #endif // !defined(DART_IO_DISABLED) && 1091 #endif // !defined(DART_IO_DISABLED) &&
1807 // !defined(DART_IO_SECURE_SOCKET_DISABLED) 1092 // !defined(DART_IO_SECURE_SOCKET_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/secure_socket.h ('k') | runtime/bin/secure_socket_boringssl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698