OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED) | 5 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED) |
6 | 6 |
7 #include "platform/globals.h" | 7 #include "platform/globals.h" |
8 #if TARGET_OS_IOS | 8 #if TARGET_OS_IOS |
9 | 9 |
10 #include "bin/secure_socket.h" | 10 #include "bin/secure_socket.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 return success ? result : NULL; | 67 return success ? result : NULL; |
68 } | 68 } |
69 | 69 |
70 | 70 |
71 // Handle an error reported from the SecureTransport library. | 71 // Handle an error reported from the SecureTransport library. |
72 static void ThrowIOException(OSStatus status, | 72 static void ThrowIOException(OSStatus status, |
73 const char* exception_type, | 73 const char* exception_type, |
74 const char* message) { | 74 const char* message) { |
75 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); | 75 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); |
76 status_message.Printf("OSStatus = %ld: https://www.osstatus.com", | 76 status_message.Printf("OSStatus = %ld: https://www.osstatus.com", |
77 static_cast<intptr_t>(status)); | 77 static_cast<intptr_t>(status)); |
78 OSError os_error_struct(status, status_message.buf(), OSError::kBoringSSL); | 78 OSError os_error_struct(status, status_message.buf(), OSError::kBoringSSL); |
79 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct); | 79 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct); |
80 Dart_Handle exception = | 80 Dart_Handle exception = |
81 DartUtils::NewDartIOException(exception_type, message, os_error); | 81 DartUtils::NewDartIOException(exception_type, message, os_error); |
82 ASSERT(!Dart_IsError(exception)); | 82 ASSERT(!Dart_IsError(exception)); |
83 Dart_ThrowException(exception); | 83 Dart_ThrowException(exception); |
84 UNREACHABLE(); | 84 UNREACHABLE(); |
85 } | 85 } |
86 | 86 |
87 | 87 |
88 static void CheckStatus(OSStatus status, | 88 static void CheckStatus(OSStatus status, |
89 const char* type, | 89 const char* type, |
90 const char* message) { | 90 const char* message) { |
91 if (status == noErr) { | 91 if (status == noErr) { |
92 return; | 92 return; |
93 } | 93 } |
94 ThrowIOException(status, type, message); | 94 ThrowIOException(status, type, message); |
95 } | 95 } |
96 | 96 |
97 | 97 |
98 static SSLFilter* GetFilter(Dart_NativeArguments args) { | 98 static SSLFilter* GetFilter(Dart_NativeArguments args) { |
99 SSLFilter* filter; | 99 SSLFilter* filter; |
100 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 100 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
101 ASSERT(Dart_IsInstance(dart_this)); | 101 ASSERT(Dart_IsInstance(dart_this)); |
102 ThrowIfError(Dart_GetNativeInstanceField( | 102 ThrowIfError( |
103 dart_this, | 103 Dart_GetNativeInstanceField(dart_this, kSSLFilterNativeFieldIndex, |
104 kSSLFilterNativeFieldIndex, | 104 reinterpret_cast<intptr_t*>(&filter))); |
105 reinterpret_cast<intptr_t*>(&filter))); | |
106 return filter; | 105 return filter; |
107 } | 106 } |
108 | 107 |
109 | 108 |
110 static void DeleteFilter(void* isolate_data, | 109 static void DeleteFilter(void* isolate_data, |
111 Dart_WeakPersistentHandle handle, | 110 Dart_WeakPersistentHandle handle, |
112 void* context_pointer) { | 111 void* context_pointer) { |
113 SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer); | 112 SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer); |
114 filter->Release(); | 113 filter->Release(); |
115 } | 114 } |
116 | 115 |
117 | 116 |
118 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { | 117 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { |
119 ASSERT(filter != NULL); | 118 ASSERT(filter != NULL); |
120 const int approximate_size_of_filter = 1500; | 119 const int approximate_size_of_filter = 1500; |
121 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); | 120 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); |
122 RETURN_IF_ERROR(dart_this); | 121 RETURN_IF_ERROR(dart_this); |
123 ASSERT(Dart_IsInstance(dart_this)); | 122 ASSERT(Dart_IsInstance(dart_this)); |
124 Dart_Handle err = Dart_SetNativeInstanceField( | 123 Dart_Handle err = |
125 dart_this, | 124 Dart_SetNativeInstanceField(dart_this, kSSLFilterNativeFieldIndex, |
126 kSSLFilterNativeFieldIndex, | 125 reinterpret_cast<intptr_t>(filter)); |
127 reinterpret_cast<intptr_t>(filter)); | |
128 RETURN_IF_ERROR(err); | 126 RETURN_IF_ERROR(err); |
129 Dart_NewWeakPersistentHandle(dart_this, | 127 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(filter), |
130 reinterpret_cast<void*>(filter), | 128 approximate_size_of_filter, DeleteFilter); |
131 approximate_size_of_filter, | |
132 DeleteFilter); | |
133 return Dart_Null(); | 129 return Dart_Null(); |
134 } | 130 } |
135 | 131 |
136 | 132 |
137 static SSLCertContext* GetSecurityContext(Dart_NativeArguments args) { | 133 static SSLCertContext* GetSecurityContext(Dart_NativeArguments args) { |
138 SSLCertContext* context; | 134 SSLCertContext* context; |
139 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 135 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
140 ASSERT(Dart_IsInstance(dart_this)); | 136 ASSERT(Dart_IsInstance(dart_this)); |
141 ThrowIfError(Dart_GetNativeInstanceField( | 137 ThrowIfError( |
142 dart_this, | 138 Dart_GetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, |
143 kSecurityContextNativeFieldIndex, | 139 reinterpret_cast<intptr_t*>(&context))); |
144 reinterpret_cast<intptr_t*>(&context))); | |
145 return context; | 140 return context; |
146 } | 141 } |
147 | 142 |
148 | 143 |
149 static void DeleteCertContext(void* isolate_data, | 144 static void DeleteCertContext(void* isolate_data, |
150 Dart_WeakPersistentHandle handle, | 145 Dart_WeakPersistentHandle handle, |
151 void* context_pointer) { | 146 void* context_pointer) { |
152 SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer); | 147 SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer); |
153 context->Release(); | 148 context->Release(); |
154 } | 149 } |
155 | 150 |
156 | 151 |
157 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, | 152 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, |
158 SSLCertContext* context) { | 153 SSLCertContext* context) { |
159 const int approximate_size_of_context = 1500; | 154 const int approximate_size_of_context = 1500; |
160 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); | 155 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); |
161 RETURN_IF_ERROR(dart_this); | 156 RETURN_IF_ERROR(dart_this); |
162 ASSERT(Dart_IsInstance(dart_this)); | 157 ASSERT(Dart_IsInstance(dart_this)); |
163 Dart_Handle err = Dart_SetNativeInstanceField( | 158 Dart_Handle err = |
164 dart_this, | 159 Dart_SetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, |
165 kSecurityContextNativeFieldIndex, | 160 reinterpret_cast<intptr_t>(context)); |
166 reinterpret_cast<intptr_t>(context)); | |
167 RETURN_IF_ERROR(err); | 161 RETURN_IF_ERROR(err); |
168 Dart_NewWeakPersistentHandle(dart_this, | 162 Dart_NewWeakPersistentHandle(dart_this, context, approximate_size_of_context, |
169 context, | |
170 approximate_size_of_context, | |
171 DeleteCertContext); | 163 DeleteCertContext); |
172 return Dart_Null(); | 164 return Dart_Null(); |
173 } | 165 } |
174 | 166 |
175 | 167 |
176 static SecCertificateRef GetX509Certificate(Dart_NativeArguments args) { | 168 static SecCertificateRef GetX509Certificate(Dart_NativeArguments args) { |
177 SecCertificateRef certificate; | 169 SecCertificateRef certificate; |
178 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 170 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
179 ASSERT(Dart_IsInstance(dart_this)); | 171 ASSERT(Dart_IsInstance(dart_this)); |
180 ThrowIfError(Dart_GetNativeInstanceField( | 172 ThrowIfError( |
181 dart_this, | 173 Dart_GetNativeInstanceField(dart_this, kX509NativeFieldIndex, |
182 kX509NativeFieldIndex, | 174 reinterpret_cast<intptr_t*>(&certificate))); |
183 reinterpret_cast<intptr_t*>(&certificate))); | |
184 return certificate; | 175 return certificate; |
185 } | 176 } |
186 | 177 |
187 | 178 |
188 static void ReleaseCertificate(void* isolate_data, | 179 static void ReleaseCertificate(void* isolate_data, |
189 Dart_WeakPersistentHandle handle, | 180 Dart_WeakPersistentHandle handle, |
190 void* context_pointer) { | 181 void* context_pointer) { |
191 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(context_pointer); | 182 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(context_pointer); |
192 CFRelease(cert); | 183 CFRelease(cert); |
193 } | 184 } |
194 | 185 |
195 | 186 |
196 static Dart_Handle WrappedX509Certificate(SecCertificateRef certificate) { | 187 static Dart_Handle WrappedX509Certificate(SecCertificateRef certificate) { |
197 const intptr_t approximate_size_of_certificate = 1500; | 188 const intptr_t approximate_size_of_certificate = 1500; |
198 if (certificate == NULL) { | 189 if (certificate == NULL) { |
199 return Dart_Null(); | 190 return Dart_Null(); |
200 } | 191 } |
201 Dart_Handle x509_type = | 192 Dart_Handle x509_type = |
202 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); | 193 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); |
203 if (Dart_IsError(x509_type)) { | 194 if (Dart_IsError(x509_type)) { |
204 return x509_type; | 195 return x509_type; |
205 } | 196 } |
206 Dart_Handle arguments[] = { NULL }; | 197 Dart_Handle arguments[] = {NULL}; |
207 | 198 |
208 Dart_Handle result = | 199 Dart_Handle result = |
209 Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments); | 200 Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments); |
210 if (Dart_IsError(result)) { | 201 if (Dart_IsError(result)) { |
211 return result; | 202 return result; |
212 } | 203 } |
213 ASSERT(Dart_IsInstance(result)); | 204 ASSERT(Dart_IsInstance(result)); |
214 | 205 |
215 // CFRetain in case the returned Dart object outlives the SecurityContext. | 206 // CFRetain in case the returned Dart object outlives the SecurityContext. |
216 // CFRelease is in the Dart object's finalizer | 207 // CFRelease is in the Dart object's finalizer |
217 CFRetain(certificate); | 208 CFRetain(certificate); |
218 Dart_NewWeakPersistentHandle(result, | 209 Dart_NewWeakPersistentHandle(result, reinterpret_cast<void*>(certificate), |
219 reinterpret_cast<void*>(certificate), | |
220 approximate_size_of_certificate, | 210 approximate_size_of_certificate, |
221 ReleaseCertificate); | 211 ReleaseCertificate); |
222 | 212 |
223 Dart_Handle status = Dart_SetNativeInstanceField( | 213 Dart_Handle status = Dart_SetNativeInstanceField( |
224 result, | 214 result, kX509NativeFieldIndex, reinterpret_cast<intptr_t>(certificate)); |
225 kX509NativeFieldIndex, | |
226 reinterpret_cast<intptr_t>(certificate)); | |
227 if (Dart_IsError(status)) { | 215 if (Dart_IsError(status)) { |
228 return status; | 216 return status; |
229 } | 217 } |
230 return result; | 218 return result; |
231 } | 219 } |
232 | 220 |
233 | 221 |
234 static const char* GetPasswordArgument(Dart_NativeArguments args, | 222 static const char* GetPasswordArgument(Dart_NativeArguments args, |
235 intptr_t index) { | 223 intptr_t index) { |
236 Dart_Handle password_object = | 224 Dart_Handle password_object = |
237 ThrowIfError(Dart_GetNativeArgument(args, index)); | 225 ThrowIfError(Dart_GetNativeArgument(args, index)); |
238 const char* password = NULL; | 226 const char* password = NULL; |
239 if (Dart_IsString(password_object)) { | 227 if (Dart_IsString(password_object)) { |
240 ThrowIfError(Dart_StringToCString(password_object, &password)); | 228 ThrowIfError(Dart_StringToCString(password_object, &password)); |
241 if (strlen(password) > PEM_BUFSIZE - 1) { | 229 if (strlen(password) > PEM_BUFSIZE - 1) { |
242 Dart_ThrowException(DartUtils::NewDartArgumentError( | 230 Dart_ThrowException(DartUtils::NewDartArgumentError( |
243 "Password length is greater than 1023 bytes.")); | 231 "Password length is greater than 1023 bytes.")); |
244 } | 232 } |
245 } else if (Dart_IsNull(password_object)) { | 233 } else if (Dart_IsNull(password_object)) { |
246 password = ""; | 234 password = ""; |
247 } else { | 235 } else { |
248 Dart_ThrowException(DartUtils::NewDartArgumentError( | 236 Dart_ThrowException( |
249 "Password is not a String or null")); | 237 DartUtils::NewDartArgumentError("Password is not a String or null")); |
250 } | 238 } |
251 return password; | 239 return password; |
252 } | 240 } |
253 | 241 |
254 | 242 |
255 static OSStatus TryPKCS12Import(CFDataRef cfdata, | 243 static OSStatus TryPKCS12Import(CFDataRef cfdata, |
256 CFStringRef password, | 244 CFStringRef password, |
257 CFArrayRef* out_certs, | 245 CFArrayRef* out_certs, |
258 SecIdentityRef* out_identity) { | 246 SecIdentityRef* out_identity) { |
259 const void* keys[] = { kSecImportExportPassphrase }; | 247 const void* keys[] = {kSecImportExportPassphrase}; |
260 const void* values[] = { password }; | 248 const void* values[] = {password}; |
261 CFDictionaryRef params = | 249 CFDictionaryRef params = |
262 CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); | 250 CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); |
263 CFArrayRef items = NULL; | 251 CFArrayRef items = NULL; |
264 OSStatus status = SecPKCS12Import(cfdata, params, &items); | 252 OSStatus status = SecPKCS12Import(cfdata, params, &items); |
265 CFRelease(params); | 253 CFRelease(params); |
266 | 254 |
267 if (status != noErr) { | 255 if (status != noErr) { |
268 if (SSL_LOG_STATUS) { | 256 if (SSL_LOG_STATUS) { |
269 Log::PrintErr("SecPKCS12Import: status = %ld", | 257 Log::PrintErr("SecPKCS12Import: status = %ld", |
270 static_cast<intptr_t>(status)); | 258 static_cast<intptr_t>(status)); |
271 return status; | 259 return status; |
272 } | 260 } |
273 } | 261 } |
274 | 262 |
275 CFIndex items_length = (items == NULL) ? 0 : CFArrayGetCount(items); | 263 CFIndex items_length = (items == NULL) ? 0 : CFArrayGetCount(items); |
276 if (SSL_LOG_CERTS) { | 264 if (SSL_LOG_CERTS) { |
277 Log::PrintErr("TryPKCS12Import succeeded, count = %ld\n", items_length); | 265 Log::PrintErr("TryPKCS12Import succeeded, count = %ld\n", items_length); |
278 } | 266 } |
279 | 267 |
280 // Empty list indicates a decoding failure of some sort. | 268 // Empty list indicates a decoding failure of some sort. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 | 309 |
322 // Certificates. | 310 // Certificates. |
323 CFTypeRef cert_items = CFDictionaryGetValue(dict, kSecImportItemCertChain); | 311 CFTypeRef cert_items = CFDictionaryGetValue(dict, kSecImportItemCertChain); |
324 if (cert_items != NULL) { | 312 if (cert_items != NULL) { |
325 ASSERT(CFGetTypeID(cert_items) == CFArrayGetTypeID()); | 313 ASSERT(CFGetTypeID(cert_items) == CFArrayGetTypeID()); |
326 CFArrayRef certs = reinterpret_cast<CFArrayRef>(cert_items); | 314 CFArrayRef certs = reinterpret_cast<CFArrayRef>(cert_items); |
327 if (SSL_LOG_CERTS) { | 315 if (SSL_LOG_CERTS) { |
328 CFIndex count = CFArrayGetCount(certs); | 316 CFIndex count = CFArrayGetCount(certs); |
329 Log::PrintErr("\titem %ld has a cert chain %ld certs long\n", i, count); | 317 Log::PrintErr("\titem %ld has a cert chain %ld certs long\n", i, count); |
330 } | 318 } |
331 CFArrayAppendArray( | 319 CFArrayAppendArray(result_certs, certs, |
332 result_certs, certs, CFRangeMake(0, CFArrayGetCount(certs))); | 320 CFRangeMake(0, CFArrayGetCount(certs))); |
333 } | 321 } |
334 } | 322 } |
335 | 323 |
336 if (out_certs == NULL) { | 324 if (out_certs == NULL) { |
337 if (result_certs != NULL) { | 325 if (result_certs != NULL) { |
338 CFRelease(result_certs); | 326 CFRelease(result_certs); |
339 } | 327 } |
340 } else { | 328 } else { |
341 *out_certs = result_certs; | 329 *out_certs = result_certs; |
342 } | 330 } |
(...skipping 15 matching lines...) Expand all Loading... |
358 | 346 |
359 static OSStatus ExtractSecItems(uint8_t* buffer, | 347 static OSStatus ExtractSecItems(uint8_t* buffer, |
360 intptr_t length, | 348 intptr_t length, |
361 const char* password, | 349 const char* password, |
362 CFArrayRef* out_certs, | 350 CFArrayRef* out_certs, |
363 SecIdentityRef* out_identity) { | 351 SecIdentityRef* out_identity) { |
364 ASSERT(buffer != NULL); | 352 ASSERT(buffer != NULL); |
365 ASSERT(password != NULL); | 353 ASSERT(password != NULL); |
366 OSStatus status = noErr; | 354 OSStatus status = noErr; |
367 | 355 |
368 CFDataRef cfdata = CFDataCreateWithBytesNoCopy( | 356 CFDataRef cfdata = |
369 NULL, buffer, length, kCFAllocatorNull); | 357 CFDataCreateWithBytesNoCopy(NULL, buffer, length, kCFAllocatorNull); |
370 CFStringRef cfpassword = CFStringCreateWithCStringNoCopy( | 358 CFStringRef cfpassword = CFStringCreateWithCStringNoCopy( |
371 NULL, password, kCFStringEncodingUTF8, kCFAllocatorNull); | 359 NULL, password, kCFStringEncodingUTF8, kCFAllocatorNull); |
372 ASSERT(cfdata != NULL); | 360 ASSERT(cfdata != NULL); |
373 ASSERT(cfpassword != NULL); | 361 ASSERT(cfpassword != NULL); |
374 | 362 |
375 status = TryPKCS12Import(cfdata, cfpassword, out_certs, out_identity); | 363 status = TryPKCS12Import(cfdata, cfpassword, out_certs, out_identity); |
376 | 364 |
377 CFRelease(cfdata); | 365 CFRelease(cfdata); |
378 CFRelease(cfpassword); | 366 CFRelease(cfpassword); |
379 return status; | 367 return status; |
(...skipping 28 matching lines...) Expand all Loading... |
408 bool require_client_certificate = | 396 bool require_client_certificate = |
409 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5)); | 397 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5)); |
410 | 398 |
411 const char* host_name = NULL; | 399 const char* host_name = NULL; |
412 // TODO(whesse): Is truncating a Dart string containing \0 what we want? | 400 // TODO(whesse): Is truncating a Dart string containing \0 what we want? |
413 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); | 401 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); |
414 | 402 |
415 SSLCertContext* context = NULL; | 403 SSLCertContext* context = NULL; |
416 if (!Dart_IsNull(context_object)) { | 404 if (!Dart_IsNull(context_object)) { |
417 ThrowIfError(Dart_GetNativeInstanceField( | 405 ThrowIfError(Dart_GetNativeInstanceField( |
418 context_object, | 406 context_object, kSecurityContextNativeFieldIndex, |
419 kSecurityContextNativeFieldIndex, | |
420 reinterpret_cast<intptr_t*>(&context))); | 407 reinterpret_cast<intptr_t*>(&context))); |
421 } | 408 } |
422 | 409 |
423 GetFilter(args)->Connect(dart_this, | 410 GetFilter(args)->Connect(dart_this, host_name, context, is_server, |
424 host_name, | |
425 context, | |
426 is_server, | |
427 request_client_certificate, | 411 request_client_certificate, |
428 require_client_certificate); | 412 require_client_certificate); |
429 } | 413 } |
430 | 414 |
431 | 415 |
432 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { | 416 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { |
433 SSLFilter* filter = GetFilter(args); | 417 SSLFilter* filter = GetFilter(args); |
434 // The SSLFilter is deleted in the finalizer for the Dart object created by | 418 // The SSLFilter is deleted in the finalizer for the Dart object created by |
435 // SetFilter. There is no need to NULL-out the native field for the SSLFilter | 419 // SetFilter. There is no need to NULL-out the native field for the SSLFilter |
436 // here because the SSLFilter won't be deleted until the finalizer for the | 420 // here because the SSLFilter won't be deleted until the finalizer for the |
(...skipping 16 matching lines...) Expand all Loading... |
453 } | 437 } |
454 | 438 |
455 | 439 |
456 void FUNCTION_NAME(SecureSocket_Renegotiate)(Dart_NativeArguments args) { | 440 void FUNCTION_NAME(SecureSocket_Renegotiate)(Dart_NativeArguments args) { |
457 bool use_session_cache = | 441 bool use_session_cache = |
458 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1)); | 442 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1)); |
459 bool request_client_certificate = | 443 bool request_client_certificate = |
460 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 2)); | 444 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 2)); |
461 bool require_client_certificate = | 445 bool require_client_certificate = |
462 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); | 446 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); |
463 GetFilter(args)->Renegotiate(use_session_cache, | 447 GetFilter(args)->Renegotiate(use_session_cache, request_client_certificate, |
464 request_client_certificate, | |
465 require_client_certificate); | 448 require_client_certificate); |
466 } | 449 } |
467 | 450 |
468 | 451 |
469 void FUNCTION_NAME(SecureSocket_RegisterHandshakeCompleteCallback)( | 452 void FUNCTION_NAME(SecureSocket_RegisterHandshakeCompleteCallback)( |
470 Dart_NativeArguments args) { | 453 Dart_NativeArguments args) { |
471 Dart_Handle handshake_complete = | 454 Dart_Handle handshake_complete = |
472 ThrowIfError(Dart_GetNativeArgument(args, 1)); | 455 ThrowIfError(Dart_GetNativeArgument(args, 1)); |
473 if (!Dart_IsClosure(handshake_complete)) { | 456 if (!Dart_IsClosure(handshake_complete)) { |
474 Dart_ThrowException(DartUtils::NewDartArgumentError( | 457 Dart_ThrowException(DartUtils::NewDartArgumentError( |
475 "Illegal argument to RegisterHandshakeCompleteCallback")); | 458 "Illegal argument to RegisterHandshakeCompleteCallback")); |
476 } | 459 } |
477 GetFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete); | 460 GetFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete); |
478 } | 461 } |
479 | 462 |
480 | 463 |
481 void FUNCTION_NAME(SecureSocket_RegisterBadCertificateCallback)( | 464 void FUNCTION_NAME(SecureSocket_RegisterBadCertificateCallback)( |
482 Dart_NativeArguments args) { | 465 Dart_NativeArguments args) { |
483 Dart_Handle callback = | 466 Dart_Handle callback = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
484 ThrowIfError(Dart_GetNativeArgument(args, 1)); | |
485 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { | 467 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { |
486 Dart_ThrowException(DartUtils::NewDartArgumentError( | 468 Dart_ThrowException(DartUtils::NewDartArgumentError( |
487 "Illegal argument to RegisterBadCertificateCallback")); | 469 "Illegal argument to RegisterBadCertificateCallback")); |
488 } | 470 } |
489 GetFilter(args)->RegisterBadCertificateCallback(callback); | 471 GetFilter(args)->RegisterBadCertificateCallback(callback); |
490 } | 472 } |
491 | 473 |
492 | 474 |
493 void FUNCTION_NAME(SecureSocket_PeerCertificate)(Dart_NativeArguments args) { | 475 void FUNCTION_NAME(SecureSocket_PeerCertificate)(Dart_NativeArguments args) { |
494 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); | 476 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); |
(...skipping 24 matching lines...) Expand all Loading... |
519 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( | 501 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( |
520 Dart_NativeArguments args) { | 502 Dart_NativeArguments args) { |
521 SSLCertContext* context = GetSecurityContext(args); | 503 SSLCertContext* context = GetSecurityContext(args); |
522 const char* password = GetPasswordArgument(args, 2); | 504 const char* password = GetPasswordArgument(args, 2); |
523 | 505 |
524 OSStatus status; | 506 OSStatus status; |
525 CFArrayRef cert_chain = NULL; | 507 CFArrayRef cert_chain = NULL; |
526 SecIdentityRef identity = NULL; | 508 SecIdentityRef identity = NULL; |
527 { | 509 { |
528 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1))); | 510 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1))); |
529 status = ExtractSecItems( | 511 status = ExtractSecItems(buffer.get(), buffer.length(), password, |
530 buffer.get(), buffer.length(), password, &cert_chain, &identity); | 512 &cert_chain, &identity); |
531 } | 513 } |
532 | 514 |
533 // Set the context fields. Repeated calls to usePrivateKeyBytes are an error. | 515 // Set the context fields. Repeated calls to usePrivateKeyBytes are an error. |
534 bool set_failure = false; | 516 bool set_failure = false; |
535 if ((identity != NULL) && !context->set_identity(identity)) { | 517 if ((identity != NULL) && !context->set_identity(identity)) { |
536 CFRelease(identity); | 518 CFRelease(identity); |
537 if (cert_chain != NULL) { | 519 if (cert_chain != NULL) { |
538 CFRelease(cert_chain); | 520 CFRelease(cert_chain); |
539 } | 521 } |
540 set_failure = true; | 522 set_failure = true; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 } | 617 } |
636 | 618 |
637 | 619 |
638 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) { | 620 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) { |
639 Dart_ThrowException(DartUtils::NewDartUnsupportedError( | 621 Dart_ThrowException(DartUtils::NewDartUnsupportedError( |
640 "X509Certificate.startValidity is not supported on this platform.")); | 622 "X509Certificate.startValidity is not supported on this platform.")); |
641 } | 623 } |
642 | 624 |
643 | 625 |
644 void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) { | 626 void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) { |
645 Dart_ThrowException(DartUtils::NewDartUnsupportedError( | 627 Dart_ThrowException(DartUtils::NewDartUnsupportedError( |
646 "X509Certificate.endValidity is not supported on this platform.")); | 628 "X509Certificate.endValidity is not supported on this platform.")); |
647 } | 629 } |
648 | 630 |
649 | 631 |
650 // Pushes data through the SSL filter, reading and writing from circular | 632 // Pushes data through the SSL filter, reading and writing from circular |
651 // buffers shared with Dart. Called from the IOService thread. | 633 // buffers shared with Dart. Called from the IOService thread. |
652 // | 634 // |
653 // The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to | 635 // The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to |
654 // pass encrypted and plaintext data to and from the C++ SSLFilter object. | 636 // pass encrypted and plaintext data to and from the C++ SSLFilter object. |
655 // | 637 // |
(...skipping 18 matching lines...) Expand all Loading... |
674 bool in_handshake = CObjectBool(request[1]).Value(); | 656 bool in_handshake = CObjectBool(request[1]).Value(); |
675 intptr_t starts[SSLFilter::kNumBuffers]; | 657 intptr_t starts[SSLFilter::kNumBuffers]; |
676 intptr_t ends[SSLFilter::kNumBuffers]; | 658 intptr_t ends[SSLFilter::kNumBuffers]; |
677 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) { | 659 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) { |
678 starts[i] = CObjectInt32(request[2 * i + 2]).Value(); | 660 starts[i] = CObjectInt32(request[2 * i + 2]).Value(); |
679 ends[i] = CObjectInt32(request[2 * i + 3]).Value(); | 661 ends[i] = CObjectInt32(request[2 * i + 3]).Value(); |
680 } | 662 } |
681 | 663 |
682 OSStatus status = filter->ProcessAllBuffers(starts, ends, in_handshake); | 664 OSStatus status = filter->ProcessAllBuffers(starts, ends, in_handshake); |
683 if (status == noErr) { | 665 if (status == noErr) { |
684 CObjectArray* result = new CObjectArray( | 666 CObjectArray* result = |
685 CObject::NewArray(SSLFilter::kNumBuffers * 2)); | 667 new CObjectArray(CObject::NewArray(SSLFilter::kNumBuffers * 2)); |
686 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) { | 668 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) { |
687 result->SetAt(2 * i, new CObjectInt32(CObject::NewInt32(starts[i]))); | 669 result->SetAt(2 * i, new CObjectInt32(CObject::NewInt32(starts[i]))); |
688 result->SetAt(2 * i + 1, new CObjectInt32(CObject::NewInt32(ends[i]))); | 670 result->SetAt(2 * i + 1, new CObjectInt32(CObject::NewInt32(ends[i]))); |
689 } | 671 } |
690 return result; | 672 return result; |
691 } else { | 673 } else { |
692 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); | 674 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); |
693 status_message.Printf("OSStatus = %ld: https://www.osstatus.com", | 675 status_message.Printf("OSStatus = %ld: https://www.osstatus.com", |
694 static_cast<intptr_t>(status)); | 676 static_cast<intptr_t>(status)); |
695 CObjectArray* result = new CObjectArray(CObject::NewArray(2)); | 677 CObjectArray* result = new CObjectArray(CObject::NewArray(2)); |
696 result->SetAt(0, new CObjectInt32(CObject::NewInt32(status))); | 678 result->SetAt(0, new CObjectInt32(CObject::NewInt32(status))); |
697 result->SetAt(1, new CObjectString(CObject::NewString( | 679 result->SetAt(1, |
698 status_message.buf()))); | 680 new CObjectString(CObject::NewString(status_message.buf()))); |
699 return result; | 681 return result; |
700 } | 682 } |
701 } | 683 } |
702 | 684 |
703 | 685 |
704 // Usually buffer_starts_ and buffer_ends_ are populated by ProcessAllBuffers, | 686 // Usually buffer_starts_ and buffer_ends_ are populated by ProcessAllBuffers, |
705 // called from ProcessFilterRequest, called from the IOService thread. | 687 // called from ProcessFilterRequest, called from the IOService thread. |
706 // However, the first call to SSLHandshake comes from the Dart thread, and so | 688 // However, the first call to SSLHandshake comes from the Dart thread, and so |
707 // doesn't go through there. This results in calls to SSLReadCallback and | 689 // doesn't go through there. This results in calls to SSLReadCallback and |
708 // SSLWriteCallback in which buffer_starts_ and buffer_ends_ haven't been set | 690 // SSLWriteCallback in which buffer_starts_ and buffer_ends_ haven't been set |
(...skipping 25 matching lines...) Expand all Loading... |
734 } | 716 } |
735 | 717 |
736 | 718 |
737 void SSLFilter::SetBufferStart(intptr_t idx, intptr_t value) { | 719 void SSLFilter::SetBufferStart(intptr_t idx, intptr_t value) { |
738 if (buffer_starts_[idx] != NULL) { | 720 if (buffer_starts_[idx] != NULL) { |
739 *buffer_starts_[idx] = value; | 721 *buffer_starts_[idx] = value; |
740 return; | 722 return; |
741 } | 723 } |
742 Dart_Handle buffer_handle = | 724 Dart_Handle buffer_handle = |
743 ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx])); | 725 ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx])); |
744 ThrowIfError(DartUtils::SetIntegerField( | 726 ThrowIfError(DartUtils::SetIntegerField(buffer_handle, "start", |
745 buffer_handle, "start", static_cast<int64_t>(value))); | 727 static_cast<int64_t>(value))); |
746 } | 728 } |
747 | 729 |
748 | 730 |
749 void SSLFilter::SetBufferEnd(intptr_t idx, intptr_t value) { | 731 void SSLFilter::SetBufferEnd(intptr_t idx, intptr_t value) { |
750 if (buffer_ends_[idx] != NULL) { | 732 if (buffer_ends_[idx] != NULL) { |
751 *buffer_ends_[idx] = value; | 733 *buffer_ends_[idx] = value; |
752 return; | 734 return; |
753 } | 735 } |
754 Dart_Handle buffer_handle = | 736 Dart_Handle buffer_handle = |
755 ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx])); | 737 ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx])); |
756 ThrowIfError(DartUtils::SetIntegerField( | 738 ThrowIfError(DartUtils::SetIntegerField(buffer_handle, "end", |
757 buffer_handle, "end", static_cast<int64_t>(value))); | 739 static_cast<int64_t>(value))); |
758 } | 740 } |
759 | 741 |
760 | 742 |
761 OSStatus SSLFilter::ProcessAllBuffers(intptr_t starts[kNumBuffers], | 743 OSStatus SSLFilter::ProcessAllBuffers(intptr_t starts[kNumBuffers], |
762 intptr_t ends[kNumBuffers], | 744 intptr_t ends[kNumBuffers], |
763 bool in_handshake) { | 745 bool in_handshake) { |
764 for (intptr_t i = 0; i < kNumBuffers; ++i) { | 746 for (intptr_t i = 0; i < kNumBuffers; ++i) { |
765 buffer_starts_[i] = &starts[i]; | 747 buffer_starts_[i] = &starts[i]; |
766 buffer_ends_[i] = &ends[i]; | 748 buffer_ends_[i] = &ends[i]; |
767 } | 749 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) { | 863 Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) { |
882 // Create SSLFilter buffers as ExternalUint8Array objects. | 864 // Create SSLFilter buffers as ExternalUint8Array objects. |
883 Dart_Handle buffers_string = DartUtils::NewString("buffers"); | 865 Dart_Handle buffers_string = DartUtils::NewString("buffers"); |
884 RETURN_IF_ERROR(buffers_string); | 866 RETURN_IF_ERROR(buffers_string); |
885 Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string); | 867 Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string); |
886 RETURN_IF_ERROR(dart_buffers_object); | 868 RETURN_IF_ERROR(dart_buffers_object); |
887 Dart_Handle secure_filter_impl_type = Dart_InstanceGetType(dart_this); | 869 Dart_Handle secure_filter_impl_type = Dart_InstanceGetType(dart_this); |
888 RETURN_IF_ERROR(secure_filter_impl_type); | 870 RETURN_IF_ERROR(secure_filter_impl_type); |
889 Dart_Handle size_string = DartUtils::NewString("SIZE"); | 871 Dart_Handle size_string = DartUtils::NewString("SIZE"); |
890 RETURN_IF_ERROR(size_string); | 872 RETURN_IF_ERROR(size_string); |
891 Dart_Handle dart_buffer_size = Dart_GetField( | 873 Dart_Handle dart_buffer_size = |
892 secure_filter_impl_type, size_string); | 874 Dart_GetField(secure_filter_impl_type, size_string); |
893 RETURN_IF_ERROR(dart_buffer_size); | 875 RETURN_IF_ERROR(dart_buffer_size); |
894 | 876 |
895 int64_t buffer_size = 0; | 877 int64_t buffer_size = 0; |
896 Dart_Handle err = Dart_IntegerToInt64(dart_buffer_size, &buffer_size); | 878 Dart_Handle err = Dart_IntegerToInt64(dart_buffer_size, &buffer_size); |
897 RETURN_IF_ERROR(err); | 879 RETURN_IF_ERROR(err); |
898 | 880 |
899 Dart_Handle encrypted_size_string = DartUtils::NewString("ENCRYPTED_SIZE"); | 881 Dart_Handle encrypted_size_string = DartUtils::NewString("ENCRYPTED_SIZE"); |
900 RETURN_IF_ERROR(encrypted_size_string); | 882 RETURN_IF_ERROR(encrypted_size_string); |
901 | 883 |
902 Dart_Handle dart_encrypted_buffer_size = Dart_GetField( | 884 Dart_Handle dart_encrypted_buffer_size = |
903 secure_filter_impl_type, encrypted_size_string); | 885 Dart_GetField(secure_filter_impl_type, encrypted_size_string); |
904 RETURN_IF_ERROR(dart_encrypted_buffer_size); | 886 RETURN_IF_ERROR(dart_encrypted_buffer_size); |
905 | 887 |
906 int64_t encrypted_buffer_size = 0; | 888 int64_t encrypted_buffer_size = 0; |
907 err = Dart_IntegerToInt64(dart_encrypted_buffer_size, &encrypted_buffer_size); | 889 err = Dart_IntegerToInt64(dart_encrypted_buffer_size, &encrypted_buffer_size); |
908 RETURN_IF_ERROR(err); | 890 RETURN_IF_ERROR(err); |
909 | 891 |
910 if (buffer_size <= 0 || buffer_size > 1 * MB) { | 892 if (buffer_size <= 0 || buffer_size > 1 * MB) { |
911 FATAL("Invalid buffer size in _ExternalBuffer"); | 893 FATAL("Invalid buffer size in _ExternalBuffer"); |
912 } | 894 } |
913 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 * MB) { | 895 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 * MB) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 FATAL("Connect called twice on the same _SecureFilter."); | 983 FATAL("Connect called twice on the same _SecureFilter."); |
1002 } | 984 } |
1003 | 985 |
1004 // Create the underlying context | 986 // Create the underlying context |
1005 SSLContextRef ssl_context = SSLCreateContext( | 987 SSLContextRef ssl_context = SSLCreateContext( |
1006 NULL, is_server ? kSSLServerSide : kSSLClientSide, kSSLStreamType); | 988 NULL, is_server ? kSSLServerSide : kSSLClientSide, kSSLStreamType); |
1007 | 989 |
1008 // Configure the context. | 990 // Configure the context. |
1009 OSStatus status; | 991 OSStatus status; |
1010 status = SSLSetPeerDomainName(ssl_context, hostname, strlen(hostname)); | 992 status = SSLSetPeerDomainName(ssl_context, hostname, strlen(hostname)); |
1011 CheckStatus(status, | 993 CheckStatus(status, "TlsException", "Failed to set peer domain name"); |
1012 "TlsException", | |
1013 "Failed to set peer domain name"); | |
1014 | 994 |
1015 status = SSLSetIOFuncs( | 995 status = SSLSetIOFuncs(ssl_context, SSLFilter::SSLReadCallback, |
1016 ssl_context, SSLFilter::SSLReadCallback, SSLFilter::SSLWriteCallback); | 996 SSLFilter::SSLWriteCallback); |
1017 CheckStatus(status, | 997 CheckStatus(status, "TlsException", "Failed to set IO Callbacks"); |
1018 "TlsException", | |
1019 "Failed to set IO Callbacks"); | |
1020 | 998 |
1021 status = SSLSetConnection( | 999 status = |
1022 ssl_context, reinterpret_cast<SSLConnectionRef>(this)); | 1000 SSLSetConnection(ssl_context, reinterpret_cast<SSLConnectionRef>(this)); |
1023 CheckStatus(status, | 1001 CheckStatus(status, "TlsException", "Failed to set connection object"); |
1024 "TlsException", | |
1025 "Failed to set connection object"); | |
1026 | 1002 |
1027 // Always evaluate the certs manually so that we can cache the peer | 1003 // Always evaluate the certs manually so that we can cache the peer |
1028 // certificates in the context for calls to peerCertificate. | 1004 // certificates in the context for calls to peerCertificate. |
1029 status = SSLSetSessionOption( | 1005 status = SSLSetSessionOption(ssl_context, kSSLSessionOptionBreakOnServerAuth, |
1030 ssl_context, kSSLSessionOptionBreakOnServerAuth, true); | 1006 true); |
1031 CheckStatus(status, | 1007 CheckStatus(status, "TlsException", "Failed to set BreakOnServerAuth option"); |
1032 "TlsException", | |
1033 "Failed to set BreakOnServerAuth option"); | |
1034 | 1008 |
1035 status = SSLSetProtocolVersionMin(ssl_context, kTLSProtocol1); | 1009 status = SSLSetProtocolVersionMin(ssl_context, kTLSProtocol1); |
1036 CheckStatus(status, | 1010 CheckStatus(status, "TlsException", |
1037 "TlsException", | 1011 "Failed to set minimum protocol version to kTLSProtocol1"); |
1038 "Failed to set minimum protocol version to kTLSProtocol1"); | |
1039 | 1012 |
1040 // If the context has an identity pass it to SSLSetCertificate(). | 1013 // If the context has an identity pass it to SSLSetCertificate(). |
1041 if (context->identity() != NULL) { | 1014 if (context->identity() != NULL) { |
1042 CFMutableArrayRef chain = | 1015 CFMutableArrayRef chain = |
1043 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); | 1016 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); |
1044 CFArrayAppendValue(chain, context->identity()); | 1017 CFArrayAppendValue(chain, context->identity()); |
1045 | 1018 |
1046 // Append the certificate chain if there is one. | 1019 // Append the certificate chain if there is one. |
1047 if (context->cert_chain() != NULL) { | 1020 if (context->cert_chain() != NULL) { |
1048 // Skip the first one, it's already included in the identity. | 1021 // Skip the first one, it's already included in the identity. |
1049 CFIndex chain_length = CFArrayGetCount(context->cert_chain()); | 1022 CFIndex chain_length = CFArrayGetCount(context->cert_chain()); |
1050 if (chain_length > 1) { | 1023 if (chain_length > 1) { |
1051 CFArrayAppendArray( | 1024 CFArrayAppendArray(chain, context->cert_chain(), |
1052 chain, context->cert_chain(), CFRangeMake(1, chain_length)); | 1025 CFRangeMake(1, chain_length)); |
1053 } | 1026 } |
1054 } | 1027 } |
1055 | 1028 |
1056 status = SSLSetCertificate(ssl_context, chain); | 1029 status = SSLSetCertificate(ssl_context, chain); |
1057 CFRelease(chain); | 1030 CFRelease(chain); |
1058 CheckStatus(status, "TlsException", "SSLSetCertificate failed"); | 1031 CheckStatus(status, "TlsException", "SSLSetCertificate failed"); |
1059 } | 1032 } |
1060 | 1033 |
1061 if (is_server) { | 1034 if (is_server) { |
1062 SSLAuthenticate auth = | 1035 SSLAuthenticate auth = |
1063 require_client_certificate | 1036 require_client_certificate |
1064 ? kAlwaysAuthenticate | 1037 ? kAlwaysAuthenticate |
1065 : (request_client_certificate ? kTryAuthenticate : kNeverAuthenticate); | 1038 : (request_client_certificate ? kTryAuthenticate |
| 1039 : kNeverAuthenticate); |
1066 status = SSLSetClientSideAuthenticate(ssl_context, auth); | 1040 status = SSLSetClientSideAuthenticate(ssl_context, auth); |
1067 CheckStatus(status, | 1041 CheckStatus(status, "TlsException", |
1068 "TlsException", | 1042 "Failed to set client authentication mode"); |
1069 "Failed to set client authentication mode"); | |
1070 | 1043 |
1071 // If we're at least trying client authentication, then break handshake | 1044 // If we're at least trying client authentication, then break handshake |
1072 // for client authentication. | 1045 // for client authentication. |
1073 if (auth != kNeverAuthenticate) { | 1046 if (auth != kNeverAuthenticate) { |
1074 status = SSLSetSessionOption( | 1047 status = SSLSetSessionOption(ssl_context, |
1075 ssl_context, kSSLSessionOptionBreakOnClientAuth, true); | 1048 kSSLSessionOptionBreakOnClientAuth, true); |
1076 CheckStatus(status, | 1049 CheckStatus(status, "TlsException", |
1077 "TlsException", | 1050 "Failed to set client authentication mode"); |
1078 "Failed to set client authentication mode"); | |
1079 } | 1051 } |
1080 } | 1052 } |
1081 | 1053 |
1082 // Add the contexts to our wrapper. | 1054 // Add the contexts to our wrapper. |
1083 cert_context_.set(context); | 1055 cert_context_.set(context); |
1084 ssl_context_ = ssl_context; | 1056 ssl_context_ = ssl_context; |
1085 is_server_ = is_server; | 1057 is_server_ = is_server; |
1086 | 1058 |
1087 // Kick-off the handshake. Expect the handshake to need more data. | 1059 // Kick-off the handshake. Expect the handshake to need more data. |
1088 // SSLHandshake calls our SSLReadCallback and SSLWriteCallback. | 1060 // SSLHandshake calls our SSLReadCallback and SSLWriteCallback. |
1089 status = SSLHandshake(ssl_context); | 1061 status = SSLHandshake(ssl_context); |
1090 ASSERT(status != noErr); | 1062 ASSERT(status != noErr); |
1091 if (status == errSSLWouldBlock) { | 1063 if (status == errSSLWouldBlock) { |
1092 status = noErr; | 1064 status = noErr; |
1093 in_handshake_ = true; | 1065 in_handshake_ = true; |
1094 } | 1066 } |
1095 CheckStatus(status, | 1067 CheckStatus(status, "HandshakeException", is_server_ |
1096 "HandshakeException", | 1068 ? "Handshake error in server" |
1097 is_server_ ? "Handshake error in server" : "Handshake error in client"); | 1069 : "Handshake error in client"); |
1098 } | 1070 } |
1099 | 1071 |
1100 | 1072 |
1101 OSStatus SSLFilter::EvaluatePeerTrust() { | 1073 OSStatus SSLFilter::EvaluatePeerTrust() { |
1102 OSStatus status = noErr; | 1074 OSStatus status = noErr; |
1103 | 1075 |
1104 if (SSL_LOG_STATUS) { | 1076 if (SSL_LOG_STATUS) { |
1105 Log::PrintErr("Handshake evaluating trust.\n"); | 1077 Log::PrintErr("Handshake evaluating trust.\n"); |
1106 } | 1078 } |
1107 SecTrustRef peer_trust = NULL; | 1079 SecTrustRef peer_trust = NULL; |
1108 status = SSLCopyPeerTrust(ssl_context_, &peer_trust); | 1080 status = SSLCopyPeerTrust(ssl_context_, &peer_trust); |
1109 if (status != noErr) { | 1081 if (status != noErr) { |
1110 if (is_server_ && (status == errSSLBadCert)) { | 1082 if (is_server_ && (status == errSSLBadCert)) { |
1111 // A client certificate was requested, but not required, and wasn't sent. | 1083 // A client certificate was requested, but not required, and wasn't sent. |
1112 return noErr; | 1084 return noErr; |
1113 } | 1085 } |
1114 if (SSL_LOG_STATUS) { | 1086 if (SSL_LOG_STATUS) { |
1115 Log::PrintErr("Handshake error from SSLCopyPeerTrust(): %ld.\n", | 1087 Log::PrintErr("Handshake error from SSLCopyPeerTrust(): %ld.\n", |
1116 static_cast<intptr_t>(status)); | 1088 static_cast<intptr_t>(status)); |
1117 } | 1089 } |
1118 return status; | 1090 return status; |
1119 } | 1091 } |
1120 | 1092 |
1121 CFArrayRef trusted_certs = NULL; | 1093 CFArrayRef trusted_certs = NULL; |
1122 if (cert_context_.get()->trusted_certs() != NULL) { | 1094 if (cert_context_.get()->trusted_certs() != NULL) { |
1123 trusted_certs = | 1095 trusted_certs = |
1124 CFArrayCreateCopy(NULL, cert_context_.get()->trusted_certs()); | 1096 CFArrayCreateCopy(NULL, cert_context_.get()->trusted_certs()); |
1125 } else { | 1097 } else { |
1126 trusted_certs = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); | 1098 trusted_certs = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); |
1127 } | 1099 } |
1128 | 1100 |
1129 status = SecTrustSetAnchorCertificates(peer_trust, trusted_certs); | 1101 status = SecTrustSetAnchorCertificates(peer_trust, trusted_certs); |
1130 if (status != noErr) { | 1102 if (status != noErr) { |
1131 if (SSL_LOG_STATUS) { | 1103 if (SSL_LOG_STATUS) { |
1132 Log::PrintErr("Handshake error from SecTrustSetAnchorCertificates: %ld\n", | 1104 Log::PrintErr("Handshake error from SecTrustSetAnchorCertificates: %ld\n", |
1133 static_cast<intptr_t>(status)); | 1105 static_cast<intptr_t>(status)); |
1134 } | 1106 } |
1135 CFRelease(trusted_certs); | 1107 CFRelease(trusted_certs); |
1136 CFRelease(peer_trust); | 1108 CFRelease(peer_trust); |
1137 return status; | 1109 return status; |
1138 } | 1110 } |
1139 | 1111 |
1140 if (SSL_LOG_STATUS) { | 1112 if (SSL_LOG_STATUS) { |
1141 Log::PrintErr("Handshake %s built in root certs\n", | 1113 Log::PrintErr( |
| 1114 "Handshake %s built in root certs\n", |
1142 cert_context_.get()->trust_builtin() ? "trusting" : "not trusting"); | 1115 cert_context_.get()->trust_builtin() ? "trusting" : "not trusting"); |
1143 } | 1116 } |
1144 | 1117 |
1145 status = SecTrustSetAnchorCertificatesOnly( | 1118 status = SecTrustSetAnchorCertificatesOnly( |
1146 peer_trust, !cert_context_.get()->trust_builtin()); | 1119 peer_trust, !cert_context_.get()->trust_builtin()); |
1147 if (status != noErr) { | 1120 if (status != noErr) { |
1148 CFRelease(trusted_certs); | 1121 CFRelease(trusted_certs); |
1149 CFRelease(peer_trust); | 1122 CFRelease(peer_trust); |
1150 return status; | 1123 return status; |
1151 } | 1124 } |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1343 handshake_complete_ = NULL; | 1316 handshake_complete_ = NULL; |
1344 } | 1317 } |
1345 if (bad_certificate_callback_ != NULL) { | 1318 if (bad_certificate_callback_ != NULL) { |
1346 Dart_DeletePersistentHandle(bad_certificate_callback_); | 1319 Dart_DeletePersistentHandle(bad_certificate_callback_); |
1347 bad_certificate_callback_ = NULL; | 1320 bad_certificate_callback_ = NULL; |
1348 } | 1321 } |
1349 } | 1322 } |
1350 | 1323 |
1351 | 1324 |
1352 OSStatus SSLFilter::SSLReadCallback(SSLConnectionRef connection, | 1325 OSStatus SSLFilter::SSLReadCallback(SSLConnectionRef connection, |
1353 void* data, size_t* data_requested) { | 1326 void* data, |
| 1327 size_t* data_requested) { |
1354 // Copy at most `data_requested` bytes from `buffers_[kReadEncrypted]` into | 1328 // Copy at most `data_requested` bytes from `buffers_[kReadEncrypted]` into |
1355 // `data` | 1329 // `data` |
1356 ASSERT(connection != NULL); | 1330 ASSERT(connection != NULL); |
1357 ASSERT(data != NULL); | 1331 ASSERT(data != NULL); |
1358 ASSERT(data_requested != NULL); | 1332 ASSERT(data_requested != NULL); |
1359 | 1333 |
1360 SSLFilter* filter = | 1334 SSLFilter* filter = |
1361 const_cast<SSLFilter*>(reinterpret_cast<const SSLFilter*>(connection)); | 1335 const_cast<SSLFilter*>(reinterpret_cast<const SSLFilter*>(connection)); |
1362 uint8_t* datap = reinterpret_cast<uint8_t*>(data); | 1336 uint8_t* datap = reinterpret_cast<uint8_t*>(data); |
1363 uint8_t* buffer = filter->buffers_[kReadEncrypted]; | 1337 uint8_t* buffer = filter->buffers_[kReadEncrypted]; |
(...skipping 25 matching lines...) Expand all Loading... |
1389 memmove(datap, &buffer[start], bytes); | 1363 memmove(datap, &buffer[start], bytes); |
1390 start += bytes; | 1364 start += bytes; |
1391 datap += bytes; | 1365 datap += bytes; |
1392 data_read += bytes; | 1366 data_read += bytes; |
1393 requested -= bytes; | 1367 requested -= bytes; |
1394 ASSERT(start <= end); | 1368 ASSERT(start <= end); |
1395 } | 1369 } |
1396 | 1370 |
1397 if (SSL_LOG_DATA) { | 1371 if (SSL_LOG_DATA) { |
1398 Log::PrintErr("SSLReadCallback: requested: %ld, read %ld bytes\n", | 1372 Log::PrintErr("SSLReadCallback: requested: %ld, read %ld bytes\n", |
1399 *data_requested, data_read); | 1373 *data_requested, data_read); |
1400 } | 1374 } |
1401 | 1375 |
1402 filter->SetBufferStart(kReadEncrypted, start); | 1376 filter->SetBufferStart(kReadEncrypted, start); |
1403 bool short_read = data_read < static_cast<intptr_t>(*data_requested); | 1377 bool short_read = data_read < static_cast<intptr_t>(*data_requested); |
1404 *data_requested = data_read; | 1378 *data_requested = data_read; |
1405 return short_read ? errSSLWouldBlock : noErr; | 1379 return short_read ? errSSLWouldBlock : noErr; |
1406 } | 1380 } |
1407 | 1381 |
1408 | 1382 |
1409 // Read decrypted data from the filter to the circular buffer. | 1383 // Read decrypted data from the filter to the circular buffer. |
1410 OSStatus SSLFilter::ProcessReadPlaintextBuffer(intptr_t start, | 1384 OSStatus SSLFilter::ProcessReadPlaintextBuffer(intptr_t start, |
1411 intptr_t end, | 1385 intptr_t end, |
1412 intptr_t* bytes_processed) { | 1386 intptr_t* bytes_processed) { |
1413 ASSERT(bytes_processed != NULL); | 1387 ASSERT(bytes_processed != NULL); |
1414 intptr_t length = end - start; | 1388 intptr_t length = end - start; |
1415 OSStatus status = noErr; | 1389 OSStatus status = noErr; |
1416 size_t bytes = 0; | 1390 size_t bytes = 0; |
1417 if (length > 0) { | 1391 if (length > 0) { |
1418 status = SSLRead( | 1392 status = |
1419 ssl_context_, | 1393 SSLRead(ssl_context_, |
1420 reinterpret_cast<void*>((buffers_[kReadPlaintext] + start)), | 1394 reinterpret_cast<void*>((buffers_[kReadPlaintext] + start)), |
1421 length, | 1395 length, &bytes); |
1422 &bytes); | |
1423 if (SSL_LOG_STATUS) { | 1396 if (SSL_LOG_STATUS) { |
1424 Log::PrintErr("SSLRead: status = %ld\n", static_cast<intptr_t>(status)); | 1397 Log::PrintErr("SSLRead: status = %ld\n", static_cast<intptr_t>(status)); |
1425 } | 1398 } |
1426 if ((status != noErr) && (status != errSSLWouldBlock)) { | 1399 if ((status != noErr) && (status != errSSLWouldBlock)) { |
1427 *bytes_processed = 0; | 1400 *bytes_processed = 0; |
1428 return status; | 1401 return status; |
1429 } | 1402 } |
1430 } | 1403 } |
1431 if (SSL_LOG_DATA) { | 1404 if (SSL_LOG_DATA) { |
1432 Log::PrintErr( | 1405 Log::PrintErr( |
1433 "ProcessReadPlaintextBuffer: requested: %ld, read %ld bytes\n", | 1406 "ProcessReadPlaintextBuffer: requested: %ld, read %ld bytes\n", length, |
1434 length, bytes); | 1407 bytes); |
1435 } | 1408 } |
1436 *bytes_processed = static_cast<intptr_t>(bytes); | 1409 *bytes_processed = static_cast<intptr_t>(bytes); |
1437 return status; | 1410 return status; |
1438 } | 1411 } |
1439 | 1412 |
1440 | 1413 |
1441 OSStatus SSLFilter::SSLWriteCallback(SSLConnectionRef connection, | 1414 OSStatus SSLFilter::SSLWriteCallback(SSLConnectionRef connection, |
1442 const void* data, size_t* data_provided) { | 1415 const void* data, |
| 1416 size_t* data_provided) { |
1443 // Copy at most `data_provided` bytes from data into | 1417 // Copy at most `data_provided` bytes from data into |
1444 // `buffers_[kWriteEncrypted]`. | 1418 // `buffers_[kWriteEncrypted]`. |
1445 ASSERT(connection != NULL); | 1419 ASSERT(connection != NULL); |
1446 ASSERT(data != NULL); | 1420 ASSERT(data != NULL); |
1447 ASSERT(data_provided != NULL); | 1421 ASSERT(data_provided != NULL); |
1448 | 1422 |
1449 SSLFilter* filter = | 1423 SSLFilter* filter = |
1450 const_cast<SSLFilter*>(reinterpret_cast<const SSLFilter*>(connection)); | 1424 const_cast<SSLFilter*>(reinterpret_cast<const SSLFilter*>(connection)); |
1451 const uint8_t* datap = reinterpret_cast<const uint8_t*>(data); | 1425 const uint8_t* datap = reinterpret_cast<const uint8_t*>(data); |
1452 uint8_t* buffer = filter->buffers_[kWriteEncrypted]; | 1426 uint8_t* buffer = filter->buffers_[kWriteEncrypted]; |
1453 intptr_t start = filter->GetBufferStart(kWriteEncrypted); | 1427 intptr_t start = filter->GetBufferStart(kWriteEncrypted); |
1454 intptr_t end = filter->GetBufferEnd(kWriteEncrypted); | 1428 intptr_t end = filter->GetBufferEnd(kWriteEncrypted); |
1455 intptr_t size = filter->encrypted_buffer_size_; | 1429 intptr_t size = filter->encrypted_buffer_size_; |
1456 intptr_t provided = static_cast<intptr_t>(*data_provided); | 1430 intptr_t provided = static_cast<intptr_t>(*data_provided); |
1457 intptr_t data_written = 0; | 1431 intptr_t data_written = 0; |
1458 | 1432 |
1459 // is full, neither if statement is executed and nothing happens. | 1433 // is full, neither if statement is executed and nothing happens. |
1460 if (start <= end) { | 1434 if (start <= end) { |
(...skipping 20 matching lines...) Expand all Loading... |
1481 memmove(&buffer[end], datap, bytes); | 1455 memmove(&buffer[end], datap, bytes); |
1482 end += bytes; | 1456 end += bytes; |
1483 datap += bytes; | 1457 datap += bytes; |
1484 data_written += bytes; | 1458 data_written += bytes; |
1485 provided -= bytes; | 1459 provided -= bytes; |
1486 ASSERT(end < start); | 1460 ASSERT(end < start); |
1487 } | 1461 } |
1488 | 1462 |
1489 if (SSL_LOG_DATA) { | 1463 if (SSL_LOG_DATA) { |
1490 Log::PrintErr("SSLWriteCallback: provided: %ld, written %ld bytes\n", | 1464 Log::PrintErr("SSLWriteCallback: provided: %ld, written %ld bytes\n", |
1491 *data_provided, data_written); | 1465 *data_provided, data_written); |
1492 } | 1466 } |
1493 | 1467 |
1494 filter->SetBufferEnd(kWriteEncrypted, end); | 1468 filter->SetBufferEnd(kWriteEncrypted, end); |
1495 *data_provided = data_written; | 1469 *data_provided = data_written; |
1496 return (data_written == 0) ? errSSLWouldBlock : noErr; | 1470 return (data_written == 0) ? errSSLWouldBlock : noErr; |
1497 } | 1471 } |
1498 | 1472 |
1499 | 1473 |
1500 OSStatus SSLFilter::ProcessWritePlaintextBuffer(intptr_t start, | 1474 OSStatus SSLFilter::ProcessWritePlaintextBuffer(intptr_t start, |
1501 intptr_t end, | 1475 intptr_t end, |
1502 intptr_t* bytes_processed) { | 1476 intptr_t* bytes_processed) { |
1503 ASSERT(bytes_processed != NULL); | 1477 ASSERT(bytes_processed != NULL); |
1504 intptr_t length = end - start; | 1478 intptr_t length = end - start; |
1505 OSStatus status = noErr; | 1479 OSStatus status = noErr; |
1506 size_t bytes = 0; | 1480 size_t bytes = 0; |
1507 if (length > 0) { | 1481 if (length > 0) { |
1508 status = SSLWrite( | 1482 status = |
1509 ssl_context_, | 1483 SSLWrite(ssl_context_, |
1510 reinterpret_cast<void*>(buffers_[kWritePlaintext] + start), | 1484 reinterpret_cast<void*>(buffers_[kWritePlaintext] + start), |
1511 length, | 1485 length, &bytes); |
1512 &bytes); | |
1513 if (SSL_LOG_STATUS) { | 1486 if (SSL_LOG_STATUS) { |
1514 Log::PrintErr("SSLWrite: status = %ld\n", static_cast<intptr_t>(status)); | 1487 Log::PrintErr("SSLWrite: status = %ld\n", static_cast<intptr_t>(status)); |
1515 } | 1488 } |
1516 if ((status != noErr) && (status != errSSLWouldBlock)) { | 1489 if ((status != noErr) && (status != errSSLWouldBlock)) { |
1517 *bytes_processed = 0; | 1490 *bytes_processed = 0; |
1518 return status; | 1491 return status; |
1519 } | 1492 } |
1520 } | 1493 } |
1521 if (SSL_LOG_DATA) { | 1494 if (SSL_LOG_DATA) { |
1522 Log::PrintErr("ProcessWritePlaintextBuffer: requested: %ld, written: %ld\n", | 1495 Log::PrintErr("ProcessWritePlaintextBuffer: requested: %ld, written: %ld\n", |
1523 length, bytes); | 1496 length, bytes); |
1524 } | 1497 } |
1525 *bytes_processed = static_cast<intptr_t>(bytes); | 1498 *bytes_processed = static_cast<intptr_t>(bytes); |
1526 return status; | 1499 return status; |
1527 } | 1500 } |
1528 | 1501 |
1529 } // namespace bin | 1502 } // namespace bin |
1530 } // namespace dart | 1503 } // namespace dart |
1531 | 1504 |
1532 #endif // TARGET_OS_IOS | 1505 #endif // TARGET_OS_IOS |
1533 | 1506 |
1534 #endif // !defined(DART_IO_SECURE_SOCKET_DISABLED) | 1507 #endif // !defined(DART_IO_SECURE_SOCKET_DISABLED) |
OLD | NEW |