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 defined(TARGET_OS_MACOS) && !TARGET_OS_IOS | 8 #if defined(TARGET_OS_MACOS) && !TARGET_OS_IOS |
9 | 9 |
10 #include "bin/secure_socket.h" | 10 #include "bin/secure_socket.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 | 79 |
80 | 80 |
81 // Handle an error reported from the SecureTransport library. | 81 // Handle an error reported from the SecureTransport library. |
82 static void ThrowIOException(OSStatus status, | 82 static void ThrowIOException(OSStatus status, |
83 const char* exception_type, | 83 const char* exception_type, |
84 const char* message) { | 84 const char* message) { |
85 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); | 85 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); |
86 CFStringRef error_string = SecCopyErrorMessageString(status, NULL); | 86 CFStringRef error_string = SecCopyErrorMessageString(status, NULL); |
87 if (error_string == NULL) { | 87 if (error_string == NULL) { |
88 status_message.Printf("OSStatus = %ld: https://www.osstatus.com", | 88 status_message.Printf("OSStatus = %ld: https://www.osstatus.com", |
89 static_cast<intptr_t>(status)); | 89 static_cast<intptr_t>(status)); |
90 } else { | 90 } else { |
91 char* error = CFStringRefToCString(error_string); | 91 char* error = CFStringRefToCString(error_string); |
92 status_message.Printf("OSStatus = %ld: %s", | 92 status_message.Printf("OSStatus = %ld: %s", static_cast<intptr_t>(status), |
93 static_cast<intptr_t>(status), error); | 93 error); |
94 CFRelease(error_string); | 94 CFRelease(error_string); |
95 } | 95 } |
96 OSError os_error_struct(status, status_message.buf(), OSError::kBoringSSL); | 96 OSError os_error_struct(status, status_message.buf(), OSError::kBoringSSL); |
97 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct); | 97 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct); |
98 Dart_Handle exception = | 98 Dart_Handle exception = |
99 DartUtils::NewDartIOException(exception_type, message, os_error); | 99 DartUtils::NewDartIOException(exception_type, message, os_error); |
100 ASSERT(!Dart_IsError(exception)); | 100 ASSERT(!Dart_IsError(exception)); |
101 Dart_ThrowException(exception); | 101 Dart_ThrowException(exception); |
102 UNREACHABLE(); | 102 UNREACHABLE(); |
103 } | 103 } |
104 | 104 |
105 | 105 |
106 static void CheckStatus(OSStatus status, | 106 static void CheckStatus(OSStatus status, |
107 const char* type, | 107 const char* type, |
108 const char* message) { | 108 const char* message) { |
109 if (status == noErr) { | 109 if (status == noErr) { |
110 return; | 110 return; |
111 } | 111 } |
112 ThrowIOException(status, type, message); | 112 ThrowIOException(status, type, message); |
113 } | 113 } |
114 | 114 |
115 | 115 |
116 static SSLFilter* GetFilter(Dart_NativeArguments args) { | 116 static SSLFilter* GetFilter(Dart_NativeArguments args) { |
117 SSLFilter* filter; | 117 SSLFilter* filter; |
118 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 118 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
119 ASSERT(Dart_IsInstance(dart_this)); | 119 ASSERT(Dart_IsInstance(dart_this)); |
120 ThrowIfError(Dart_GetNativeInstanceField( | 120 ThrowIfError( |
121 dart_this, | 121 Dart_GetNativeInstanceField(dart_this, kSSLFilterNativeFieldIndex, |
122 kSSLFilterNativeFieldIndex, | 122 reinterpret_cast<intptr_t*>(&filter))); |
123 reinterpret_cast<intptr_t*>(&filter))); | |
124 return filter; | 123 return filter; |
125 } | 124 } |
126 | 125 |
127 | 126 |
128 static void DeleteFilter(void* isolate_data, | 127 static void DeleteFilter(void* isolate_data, |
129 Dart_WeakPersistentHandle handle, | 128 Dart_WeakPersistentHandle handle, |
130 void* context_pointer) { | 129 void* context_pointer) { |
131 SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer); | 130 SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer); |
132 filter->Release(); | 131 filter->Release(); |
133 } | 132 } |
134 | 133 |
135 | 134 |
136 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { | 135 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { |
137 ASSERT(filter != NULL); | 136 ASSERT(filter != NULL); |
138 const int approximate_size_of_filter = 1500; | 137 const int approximate_size_of_filter = 1500; |
139 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); | 138 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); |
140 RETURN_IF_ERROR(dart_this); | 139 RETURN_IF_ERROR(dart_this); |
141 ASSERT(Dart_IsInstance(dart_this)); | 140 ASSERT(Dart_IsInstance(dart_this)); |
142 Dart_Handle err = Dart_SetNativeInstanceField( | 141 Dart_Handle err = |
143 dart_this, | 142 Dart_SetNativeInstanceField(dart_this, kSSLFilterNativeFieldIndex, |
144 kSSLFilterNativeFieldIndex, | 143 reinterpret_cast<intptr_t>(filter)); |
145 reinterpret_cast<intptr_t>(filter)); | |
146 RETURN_IF_ERROR(err); | 144 RETURN_IF_ERROR(err); |
147 Dart_NewWeakPersistentHandle(dart_this, | 145 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(filter), |
148 reinterpret_cast<void*>(filter), | 146 approximate_size_of_filter, DeleteFilter); |
149 approximate_size_of_filter, | |
150 DeleteFilter); | |
151 return Dart_Null(); | 147 return Dart_Null(); |
152 } | 148 } |
153 | 149 |
154 | 150 |
155 static SSLCertContext* GetSecurityContext(Dart_NativeArguments args) { | 151 static SSLCertContext* GetSecurityContext(Dart_NativeArguments args) { |
156 SSLCertContext* context; | 152 SSLCertContext* context; |
157 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 153 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
158 ASSERT(Dart_IsInstance(dart_this)); | 154 ASSERT(Dart_IsInstance(dart_this)); |
159 ThrowIfError(Dart_GetNativeInstanceField( | 155 ThrowIfError( |
160 dart_this, | 156 Dart_GetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, |
161 kSecurityContextNativeFieldIndex, | 157 reinterpret_cast<intptr_t*>(&context))); |
162 reinterpret_cast<intptr_t*>(&context))); | |
163 return context; | 158 return context; |
164 } | 159 } |
165 | 160 |
166 | 161 |
167 static void DeleteCertContext(void* isolate_data, | 162 static void DeleteCertContext(void* isolate_data, |
168 Dart_WeakPersistentHandle handle, | 163 Dart_WeakPersistentHandle handle, |
169 void* context_pointer) { | 164 void* context_pointer) { |
170 SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer); | 165 SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer); |
171 context->Release(); | 166 context->Release(); |
172 } | 167 } |
173 | 168 |
174 | 169 |
175 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, | 170 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, |
176 SSLCertContext* context) { | 171 SSLCertContext* context) { |
177 const int approximate_size_of_context = 1500; | 172 const int approximate_size_of_context = 1500; |
178 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); | 173 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); |
179 RETURN_IF_ERROR(dart_this); | 174 RETURN_IF_ERROR(dart_this); |
180 ASSERT(Dart_IsInstance(dart_this)); | 175 ASSERT(Dart_IsInstance(dart_this)); |
181 Dart_Handle err = Dart_SetNativeInstanceField( | 176 Dart_Handle err = |
182 dart_this, | 177 Dart_SetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, |
183 kSecurityContextNativeFieldIndex, | 178 reinterpret_cast<intptr_t>(context)); |
184 reinterpret_cast<intptr_t>(context)); | |
185 RETURN_IF_ERROR(err); | 179 RETURN_IF_ERROR(err); |
186 Dart_NewWeakPersistentHandle(dart_this, | 180 Dart_NewWeakPersistentHandle(dart_this, context, approximate_size_of_context, |
187 context, | |
188 approximate_size_of_context, | |
189 DeleteCertContext); | 181 DeleteCertContext); |
190 return Dart_Null(); | 182 return Dart_Null(); |
191 } | 183 } |
192 | 184 |
193 | 185 |
194 static SecCertificateRef GetX509Certificate(Dart_NativeArguments args) { | 186 static SecCertificateRef GetX509Certificate(Dart_NativeArguments args) { |
195 SecCertificateRef certificate; | 187 SecCertificateRef certificate; |
196 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 188 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
197 ASSERT(Dart_IsInstance(dart_this)); | 189 ASSERT(Dart_IsInstance(dart_this)); |
198 ThrowIfError(Dart_GetNativeInstanceField( | 190 ThrowIfError( |
199 dart_this, | 191 Dart_GetNativeInstanceField(dart_this, kX509NativeFieldIndex, |
200 kX509NativeFieldIndex, | 192 reinterpret_cast<intptr_t*>(&certificate))); |
201 reinterpret_cast<intptr_t*>(&certificate))); | |
202 return certificate; | 193 return certificate; |
203 } | 194 } |
204 | 195 |
205 | 196 |
206 static void ReleaseCertificate(void* isolate_data, | 197 static void ReleaseCertificate(void* isolate_data, |
207 Dart_WeakPersistentHandle handle, | 198 Dart_WeakPersistentHandle handle, |
208 void* context_pointer) { | 199 void* context_pointer) { |
209 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(context_pointer); | 200 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(context_pointer); |
210 CFRelease(cert); | 201 CFRelease(cert); |
211 } | 202 } |
212 | 203 |
213 | 204 |
214 static Dart_Handle WrappedX509Certificate(SecCertificateRef certificate) { | 205 static Dart_Handle WrappedX509Certificate(SecCertificateRef certificate) { |
215 const intptr_t approximate_size_of_certificate = 1500; | 206 const intptr_t approximate_size_of_certificate = 1500; |
216 if (certificate == NULL) { | 207 if (certificate == NULL) { |
217 return Dart_Null(); | 208 return Dart_Null(); |
218 } | 209 } |
219 Dart_Handle x509_type = | 210 Dart_Handle x509_type = |
220 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); | 211 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); |
221 if (Dart_IsError(x509_type)) { | 212 if (Dart_IsError(x509_type)) { |
222 return x509_type; | 213 return x509_type; |
223 } | 214 } |
224 Dart_Handle arguments[] = { NULL }; | 215 Dart_Handle arguments[] = {NULL}; |
225 | 216 |
226 Dart_Handle result = | 217 Dart_Handle result = |
227 Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments); | 218 Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments); |
228 if (Dart_IsError(result)) { | 219 if (Dart_IsError(result)) { |
229 return result; | 220 return result; |
230 } | 221 } |
231 ASSERT(Dart_IsInstance(result)); | 222 ASSERT(Dart_IsInstance(result)); |
232 | 223 |
233 // CFRetain in case the returned Dart object outlives the SecurityContext. | 224 // CFRetain in case the returned Dart object outlives the SecurityContext. |
234 // CFRelease is in the Dart object's finalizer | 225 // CFRelease is in the Dart object's finalizer |
235 CFRetain(certificate); | 226 CFRetain(certificate); |
236 Dart_NewWeakPersistentHandle(result, | 227 Dart_NewWeakPersistentHandle(result, reinterpret_cast<void*>(certificate), |
237 reinterpret_cast<void*>(certificate), | |
238 approximate_size_of_certificate, | 228 approximate_size_of_certificate, |
239 ReleaseCertificate); | 229 ReleaseCertificate); |
240 | 230 |
241 Dart_Handle status = Dart_SetNativeInstanceField( | 231 Dart_Handle status = Dart_SetNativeInstanceField( |
242 result, | 232 result, kX509NativeFieldIndex, reinterpret_cast<intptr_t>(certificate)); |
243 kX509NativeFieldIndex, | |
244 reinterpret_cast<intptr_t>(certificate)); | |
245 if (Dart_IsError(status)) { | 233 if (Dart_IsError(status)) { |
246 return status; | 234 return status; |
247 } | 235 } |
248 return result; | 236 return result; |
249 } | 237 } |
250 | 238 |
251 | 239 |
252 static const char* GetPasswordArgument(Dart_NativeArguments args, | 240 static const char* GetPasswordArgument(Dart_NativeArguments args, |
253 intptr_t index) { | 241 intptr_t index) { |
254 Dart_Handle password_object = | 242 Dart_Handle password_object = |
255 ThrowIfError(Dart_GetNativeArgument(args, index)); | 243 ThrowIfError(Dart_GetNativeArgument(args, index)); |
256 const char* password = NULL; | 244 const char* password = NULL; |
257 if (Dart_IsString(password_object)) { | 245 if (Dart_IsString(password_object)) { |
258 ThrowIfError(Dart_StringToCString(password_object, &password)); | 246 ThrowIfError(Dart_StringToCString(password_object, &password)); |
259 if (strlen(password) > PEM_BUFSIZE - 1) { | 247 if (strlen(password) > PEM_BUFSIZE - 1) { |
260 Dart_ThrowException(DartUtils::NewDartArgumentError( | 248 Dart_ThrowException(DartUtils::NewDartArgumentError( |
261 "Password length is greater than 1023 bytes.")); | 249 "Password length is greater than 1023 bytes.")); |
262 } | 250 } |
263 } else if (Dart_IsNull(password_object)) { | 251 } else if (Dart_IsNull(password_object)) { |
264 password = ""; | 252 password = ""; |
265 } else { | 253 } else { |
266 Dart_ThrowException(DartUtils::NewDartArgumentError( | 254 Dart_ThrowException( |
267 "Password is not a String or null")); | 255 DartUtils::NewDartArgumentError("Password is not a String or null")); |
268 } | 256 } |
269 return password; | 257 return password; |
270 } | 258 } |
271 | 259 |
272 | 260 |
273 static OSStatus GetKeyAndCerts(CFArrayRef items, | 261 static OSStatus GetKeyAndCerts(CFArrayRef items, |
274 CFIndex items_length, | 262 CFIndex items_length, |
275 CFArrayRef* out_certs, | 263 CFArrayRef* out_certs, |
276 SecKeyRef* out_key) { | 264 SecKeyRef* out_key) { |
277 OSStatus status = noErr; | 265 OSStatus status = noErr; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 SecExternalFormat format = kSecFormatPEMSequence; | 339 SecExternalFormat format = kSecFormatPEMSequence; |
352 SecExternalItemType sitem_type = kSecItemTypeAggregate; | 340 SecExternalItemType sitem_type = kSecItemTypeAggregate; |
353 | 341 |
354 SecItemImportExportKeyParameters params; | 342 SecItemImportExportKeyParameters params; |
355 memset(¶ms, 0, sizeof(params)); | 343 memset(¶ms, 0, sizeof(params)); |
356 params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; | 344 params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; |
357 params.flags = kSecKeyNoAccessControl; | 345 params.flags = kSecKeyNoAccessControl; |
358 params.passphrase = password; | 346 params.passphrase = password; |
359 | 347 |
360 CFArrayRef items = NULL; | 348 CFArrayRef items = NULL; |
361 status = SecItemImport( | 349 status = SecItemImport(cfdata, NULL, &format, &sitem_type, 0, ¶ms, NULL, |
362 cfdata, NULL, &format, &sitem_type, 0, ¶ms, NULL, &items); | 350 &items); |
363 | 351 |
364 if (status != noErr) { | 352 if (status != noErr) { |
365 if (SSL_LOG_CERTS) { | 353 if (SSL_LOG_CERTS) { |
366 Log::Print("TrySecItemImport failed with: %ld, type = %d, format = %d\n", | 354 Log::Print("TrySecItemImport failed with: %ld, type = %d, format = %d\n", |
367 static_cast<intptr_t>(status), sitem_type, format); | 355 static_cast<intptr_t>(status), sitem_type, format); |
368 } | 356 } |
369 return status; | 357 return status; |
370 } | 358 } |
371 | 359 |
372 CFIndex items_length = (items == NULL) ? 0 : CFArrayGetCount(items); | 360 CFIndex items_length = (items == NULL) ? 0 : CFArrayGetCount(items); |
373 if (SSL_LOG_CERTS) { | 361 if (SSL_LOG_CERTS) { |
374 Log::Print( | 362 Log::Print( |
375 "TrySecItemImport succeeded, type = %d, format = %d, count = %ld\n", | 363 "TrySecItemImport succeeded, type = %d, format = %d, count = %ld\n", |
376 sitem_type, format, items_length); | 364 sitem_type, format, items_length); |
377 } | 365 } |
(...skipping 21 matching lines...) Expand all Loading... |
399 temp_dir = "/tmp/"; | 387 temp_dir = "/tmp/"; |
400 } | 388 } |
401 ASSERT(temp_dir != NULL); | 389 ASSERT(temp_dir != NULL); |
402 | 390 |
403 TextBuffer path(PATH_MAX); | 391 TextBuffer path(PATH_MAX); |
404 path.Printf("%s/%s", temp_dir, exes); | 392 path.Printf("%s/%s", temp_dir, exes); |
405 char* ret = mkdtemp(path.buf()); | 393 char* ret = mkdtemp(path.buf()); |
406 ASSERT(ret != NULL); | 394 ASSERT(ret != NULL); |
407 path.Printf("/%s", fname); | 395 path.Printf("/%s", fname); |
408 | 396 |
409 char* result = | 397 char* result = reinterpret_cast<char*>(Dart_ScopeAllocate(path.length() + 1)); |
410 reinterpret_cast<char*>(Dart_ScopeAllocate(path.length() + 1)); | |
411 return strncpy(result, path.buf(), path.length() + 1); | 398 return strncpy(result, path.buf(), path.length() + 1); |
412 } | 399 } |
413 | 400 |
414 | 401 |
415 static OSStatus CreateKeychain(SecKeychainRef* keychain) { | 402 static OSStatus CreateKeychain(SecKeychainRef* keychain) { |
416 ASSERT(keychain != NULL); | 403 ASSERT(keychain != NULL); |
417 OSStatus status = noErr; | 404 OSStatus status = noErr; |
418 const char* temp_keychain_pwd = "dartdart"; | 405 const char* temp_keychain_pwd = "dartdart"; |
419 char* temp_file_path = TempKeychainPath(); | 406 char* temp_file_path = TempKeychainPath(); |
420 ASSERT(temp_file_path != NULL); | 407 ASSERT(temp_file_path != NULL); |
421 if (SSL_LOG_CERTS) { | 408 if (SSL_LOG_CERTS) { |
422 Log::Print("Temporary keychain at: '%s'\n", temp_file_path); | 409 Log::Print("Temporary keychain at: '%s'\n", temp_file_path); |
423 } | 410 } |
424 status = SecKeychainCreate(temp_file_path, | 411 status = SecKeychainCreate(temp_file_path, strlen(temp_keychain_pwd) + 1, |
425 strlen(temp_keychain_pwd) + 1, | |
426 reinterpret_cast<const void*>(temp_keychain_pwd), | 412 reinterpret_cast<const void*>(temp_keychain_pwd), |
427 FALSE, // Prompt user? Definitely no. | 413 FALSE, // Prompt user? Definitely no. |
428 NULL, // Default access rights. | 414 NULL, // Default access rights. |
429 keychain); | 415 keychain); |
430 if (status != noErr) { | 416 if (status != noErr) { |
431 return status; | 417 return status; |
432 } | 418 } |
433 ASSERT(*keychain != NULL); | 419 ASSERT(*keychain != NULL); |
434 return status; | 420 return status; |
435 } | 421 } |
436 | 422 |
437 | 423 |
438 static OSStatus TryPKCS12Import(CFDataRef cfdata, | 424 static OSStatus TryPKCS12Import(CFDataRef cfdata, |
439 CFStringRef password, | 425 CFStringRef password, |
440 CFArrayRef* out_certs, | 426 CFArrayRef* out_certs, |
441 SecKeyRef* out_key, | 427 SecKeyRef* out_key, |
442 SecKeychainRef* out_keychain) { | 428 SecKeychainRef* out_keychain) { |
443 OSStatus status = noErr; | 429 OSStatus status = noErr; |
444 | 430 |
445 SecExternalFormat format = kSecFormatPKCS12; | 431 SecExternalFormat format = kSecFormatPKCS12; |
446 SecExternalItemType sitem_type = kSecItemTypeAggregate; | 432 SecExternalItemType sitem_type = kSecItemTypeAggregate; |
447 | 433 |
448 SecItemImportExportKeyParameters params; | 434 SecItemImportExportKeyParameters params; |
449 memset(¶ms, 0, sizeof(params)); | 435 memset(¶ms, 0, sizeof(params)); |
450 params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; | 436 params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; |
451 params.flags = kSecKeyNoAccessControl; | 437 params.flags = kSecKeyNoAccessControl; |
452 params.passphrase = password; | 438 params.passphrase = password; |
453 | 439 |
454 CFArrayRef items = NULL; | 440 CFArrayRef items = NULL; |
455 if (SSL_LOG_CERTS) { | 441 if (SSL_LOG_CERTS) { |
456 Log::Print("Trying PKCS12 import with: type = %d, format = %d\n", | 442 Log::Print("Trying PKCS12 import with: type = %d, format = %d\n", |
457 sitem_type, format); | 443 sitem_type, format); |
458 } | 444 } |
459 | 445 |
460 // The documentation for SecKeychainItemImport here: | 446 // The documentation for SecKeychainItemImport here: |
461 // | 447 // |
462 // https://developer.apple.com/library/mac/documentation/Security/Reference/ke
ychainservices/index.html | 448 // https://developer.apple.com/library/mac/documentation/Security/Reference/ke
ychainservices/index.html |
463 // | 449 // |
464 // states that when the SecKeychainRef argument is NULL, the CFArrayRef* | 450 // states that when the SecKeychainRef argument is NULL, the CFArrayRef* |
465 // argument will be populated by an array containing all keys, identities, | 451 // argument will be populated by an array containing all keys, identities, |
466 // and certificates from the data in the CFDataRef argument. | 452 // and certificates from the data in the CFDataRef argument. |
467 // | 453 // |
(...skipping 15 matching lines...) Expand all Loading... |
483 SecKeychainRef keychain = NULL; | 469 SecKeychainRef keychain = NULL; |
484 if (out_key != NULL) { | 470 if (out_key != NULL) { |
485 ASSERT(out_keychain != NULL); | 471 ASSERT(out_keychain != NULL); |
486 status = CreateKeychain(&keychain); | 472 status = CreateKeychain(&keychain); |
487 if (status != noErr) { | 473 if (status != noErr) { |
488 return status; | 474 return status; |
489 } | 475 } |
490 *out_keychain = keychain; | 476 *out_keychain = keychain; |
491 } | 477 } |
492 | 478 |
493 status = SecItemImport( | 479 status = SecItemImport(cfdata, NULL, &format, &sitem_type, 0, ¶ms, |
494 cfdata, NULL, &format, &sitem_type, 0, ¶ms, keychain, &items); | 480 keychain, &items); |
495 if (status != noErr) { | 481 if (status != noErr) { |
496 if (SSL_LOG_CERTS) { | 482 if (SSL_LOG_CERTS) { |
497 Log::Print("TrySecItemImport failed with: %ld, it = %d, format = %d\n", | 483 Log::Print("TrySecItemImport failed with: %ld, it = %d, format = %d\n", |
498 static_cast<intptr_t>(status), sitem_type, format); | 484 static_cast<intptr_t>(status), sitem_type, format); |
499 } | 485 } |
500 return status; | 486 return status; |
501 } | 487 } |
502 | 488 |
503 CFIndex items_length = (items == NULL) ? 0 : CFArrayGetCount(items); | 489 CFIndex items_length = (items == NULL) ? 0 : CFArrayGetCount(items); |
504 if (SSL_LOG_CERTS) { | 490 if (SSL_LOG_CERTS) { |
505 Log::Print("TrySecItemImport succeeded, count = %ld\n", items_length); | 491 Log::Print("TrySecItemImport succeeded, count = %ld\n", items_length); |
506 } | 492 } |
507 | 493 |
508 // Empty list indicates a decoding failure of some sort. | 494 // Empty list indicates a decoding failure of some sort. |
(...skipping 11 matching lines...) Expand all Loading... |
520 static OSStatus ExtractSecItems(uint8_t* buffer, | 506 static OSStatus ExtractSecItems(uint8_t* buffer, |
521 intptr_t length, | 507 intptr_t length, |
522 const char* password, | 508 const char* password, |
523 CFArrayRef* out_certs, | 509 CFArrayRef* out_certs, |
524 SecKeyRef* out_key, | 510 SecKeyRef* out_key, |
525 SecKeychainRef* out_keychain) { | 511 SecKeychainRef* out_keychain) { |
526 ASSERT(buffer != NULL); | 512 ASSERT(buffer != NULL); |
527 ASSERT(password != NULL); | 513 ASSERT(password != NULL); |
528 OSStatus status = noErr; | 514 OSStatus status = noErr; |
529 | 515 |
530 CFDataRef cfdata = CFDataCreateWithBytesNoCopy( | 516 CFDataRef cfdata = |
531 NULL, buffer, length, kCFAllocatorNull); | 517 CFDataCreateWithBytesNoCopy(NULL, buffer, length, kCFAllocatorNull); |
532 CFStringRef cfpassword = CFStringCreateWithCStringNoCopy( | 518 CFStringRef cfpassword = CFStringCreateWithCStringNoCopy( |
533 NULL, password, kCFStringEncodingUTF8, kCFAllocatorNull); | 519 NULL, password, kCFStringEncodingUTF8, kCFAllocatorNull); |
534 ASSERT(cfdata != NULL); | 520 ASSERT(cfdata != NULL); |
535 ASSERT(cfpassword != NULL); | 521 ASSERT(cfpassword != NULL); |
536 | 522 |
537 status = TryPEMImport(cfdata, cfpassword, out_certs, out_key); | 523 status = TryPEMImport(cfdata, cfpassword, out_certs, out_key); |
538 if (status != noErr) { | 524 if (status != noErr) { |
539 status = | 525 status = |
540 TryPKCS12Import(cfdata, cfpassword, out_certs, out_key, out_keychain); | 526 TryPKCS12Import(cfdata, cfpassword, out_certs, out_key, out_keychain); |
541 } | 527 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 bool require_client_certificate = | 560 bool require_client_certificate = |
575 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5)); | 561 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5)); |
576 | 562 |
577 const char* host_name = NULL; | 563 const char* host_name = NULL; |
578 // TODO(whesse): Is truncating a Dart string containing \0 what we want? | 564 // TODO(whesse): Is truncating a Dart string containing \0 what we want? |
579 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); | 565 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); |
580 | 566 |
581 SSLCertContext* context = NULL; | 567 SSLCertContext* context = NULL; |
582 if (!Dart_IsNull(context_object)) { | 568 if (!Dart_IsNull(context_object)) { |
583 ThrowIfError(Dart_GetNativeInstanceField( | 569 ThrowIfError(Dart_GetNativeInstanceField( |
584 context_object, | 570 context_object, kSecurityContextNativeFieldIndex, |
585 kSecurityContextNativeFieldIndex, | |
586 reinterpret_cast<intptr_t*>(&context))); | 571 reinterpret_cast<intptr_t*>(&context))); |
587 } | 572 } |
588 | 573 |
589 GetFilter(args)->Connect(dart_this, | 574 GetFilter(args)->Connect(dart_this, host_name, context, is_server, |
590 host_name, | |
591 context, | |
592 is_server, | |
593 request_client_certificate, | 575 request_client_certificate, |
594 require_client_certificate); | 576 require_client_certificate); |
595 } | 577 } |
596 | 578 |
597 | 579 |
598 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { | 580 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { |
599 SSLFilter* filter = GetFilter(args); | 581 SSLFilter* filter = GetFilter(args); |
600 // The SSLFilter is deleted in the finalizer for the Dart object created by | 582 // The SSLFilter is deleted in the finalizer for the Dart object created by |
601 // SetFilter. There is no need to NULL-out the native field for the SSLFilter | 583 // SetFilter. There is no need to NULL-out the native field for the SSLFilter |
602 // here because the SSLFilter won't be deleted until the finalizer for the | 584 // here because the SSLFilter won't be deleted until the finalizer for the |
(...skipping 16 matching lines...) Expand all Loading... |
619 } | 601 } |
620 | 602 |
621 | 603 |
622 void FUNCTION_NAME(SecureSocket_Renegotiate)(Dart_NativeArguments args) { | 604 void FUNCTION_NAME(SecureSocket_Renegotiate)(Dart_NativeArguments args) { |
623 bool use_session_cache = | 605 bool use_session_cache = |
624 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1)); | 606 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1)); |
625 bool request_client_certificate = | 607 bool request_client_certificate = |
626 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 2)); | 608 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 2)); |
627 bool require_client_certificate = | 609 bool require_client_certificate = |
628 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); | 610 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); |
629 GetFilter(args)->Renegotiate(use_session_cache, | 611 GetFilter(args)->Renegotiate(use_session_cache, request_client_certificate, |
630 request_client_certificate, | |
631 require_client_certificate); | 612 require_client_certificate); |
632 } | 613 } |
633 | 614 |
634 | 615 |
635 void FUNCTION_NAME(SecureSocket_RegisterHandshakeCompleteCallback)( | 616 void FUNCTION_NAME(SecureSocket_RegisterHandshakeCompleteCallback)( |
636 Dart_NativeArguments args) { | 617 Dart_NativeArguments args) { |
637 Dart_Handle handshake_complete = | 618 Dart_Handle handshake_complete = |
638 ThrowIfError(Dart_GetNativeArgument(args, 1)); | 619 ThrowIfError(Dart_GetNativeArgument(args, 1)); |
639 if (!Dart_IsClosure(handshake_complete)) { | 620 if (!Dart_IsClosure(handshake_complete)) { |
640 Dart_ThrowException(DartUtils::NewDartArgumentError( | 621 Dart_ThrowException(DartUtils::NewDartArgumentError( |
641 "Illegal argument to RegisterHandshakeCompleteCallback")); | 622 "Illegal argument to RegisterHandshakeCompleteCallback")); |
642 } | 623 } |
643 GetFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete); | 624 GetFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete); |
644 } | 625 } |
645 | 626 |
646 | 627 |
647 void FUNCTION_NAME(SecureSocket_RegisterBadCertificateCallback)( | 628 void FUNCTION_NAME(SecureSocket_RegisterBadCertificateCallback)( |
648 Dart_NativeArguments args) { | 629 Dart_NativeArguments args) { |
649 Dart_Handle callback = | 630 Dart_Handle callback = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
650 ThrowIfError(Dart_GetNativeArgument(args, 1)); | |
651 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { | 631 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { |
652 Dart_ThrowException(DartUtils::NewDartArgumentError( | 632 Dart_ThrowException(DartUtils::NewDartArgumentError( |
653 "Illegal argument to RegisterBadCertificateCallback")); | 633 "Illegal argument to RegisterBadCertificateCallback")); |
654 } | 634 } |
655 GetFilter(args)->RegisterBadCertificateCallback(callback); | 635 GetFilter(args)->RegisterBadCertificateCallback(callback); |
656 } | 636 } |
657 | 637 |
658 | 638 |
659 void FUNCTION_NAME(SecureSocket_PeerCertificate) | 639 void FUNCTION_NAME(SecureSocket_PeerCertificate)(Dart_NativeArguments args) { |
660 (Dart_NativeArguments args) { | |
661 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); | 640 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); |
662 } | 641 } |
663 | 642 |
664 | 643 |
665 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { | 644 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { |
666 SSLFilter* filter = GetFilter(args); | 645 SSLFilter* filter = GetFilter(args); |
667 // This filter pointer is passed to the IO Service thread. The IO Service | 646 // This filter pointer is passed to the IO Service thread. The IO Service |
668 // thread must Release() the pointer when it is done with it. | 647 // thread must Release() the pointer when it is done with it. |
669 filter->Retain(); | 648 filter->Retain(); |
670 intptr_t filter_pointer = reinterpret_cast<intptr_t>(filter); | 649 intptr_t filter_pointer = reinterpret_cast<intptr_t>(filter); |
(...skipping 15 matching lines...) Expand all Loading... |
686 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( | 665 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( |
687 Dart_NativeArguments args) { | 666 Dart_NativeArguments args) { |
688 SSLCertContext* context = GetSecurityContext(args); | 667 SSLCertContext* context = GetSecurityContext(args); |
689 const char* password = GetPasswordArgument(args, 2); | 668 const char* password = GetPasswordArgument(args, 2); |
690 | 669 |
691 OSStatus status; | 670 OSStatus status; |
692 SecKeyRef key = NULL; | 671 SecKeyRef key = NULL; |
693 SecKeychainRef keychain = NULL; | 672 SecKeychainRef keychain = NULL; |
694 { | 673 { |
695 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1))); | 674 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1))); |
696 status = ExtractSecItems( | 675 status = ExtractSecItems(buffer.get(), buffer.length(), password, NULL, |
697 buffer.get(), buffer.length(), password, NULL, &key, &keychain); | 676 &key, &keychain); |
698 } | 677 } |
699 | 678 |
700 // Set the context fields. If there's a failure, release the items. | 679 // Set the context fields. If there's a failure, release the items. |
701 bool set_failure = false; | 680 bool set_failure = false; |
702 if ((key != NULL) && !context->set_private_key(key)) { | 681 if ((key != NULL) && !context->set_private_key(key)) { |
703 CFRelease(key); | 682 CFRelease(key); |
704 SecKeychainDelete(keychain); | 683 SecKeychainDelete(keychain); |
705 CFRelease(keychain); | 684 CFRelease(keychain); |
706 set_failure = true; | 685 set_failure = true; |
707 } | 686 } |
(...skipping 12 matching lines...) Expand all Loading... |
720 | 699 |
721 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( | 700 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( |
722 Dart_NativeArguments args) { | 701 Dart_NativeArguments args) { |
723 SSLCertContext* context = GetSecurityContext(args); | 702 SSLCertContext* context = GetSecurityContext(args); |
724 const char* password = GetPasswordArgument(args, 2); | 703 const char* password = GetPasswordArgument(args, 2); |
725 | 704 |
726 OSStatus status; | 705 OSStatus status; |
727 CFArrayRef certs = NULL; | 706 CFArrayRef certs = NULL; |
728 { | 707 { |
729 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1))); | 708 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1))); |
730 status = ExtractSecItems( | 709 status = ExtractSecItems(buffer.get(), buffer.length(), password, &certs, |
731 buffer.get(), buffer.length(), password, &certs, NULL, NULL); | 710 NULL, NULL); |
732 } | 711 } |
733 | 712 |
734 // Set the field in the context. If there's a failure, release the certs, | 713 // Set the field in the context. If there's a failure, release the certs, |
735 // and throw an exception. | 714 // and throw an exception. |
736 if ((certs != NULL) && !context->set_trusted_certs(certs)) { | 715 if ((certs != NULL) && !context->set_trusted_certs(certs)) { |
737 CFRelease(certs); | 716 CFRelease(certs); |
738 Dart_ThrowException(DartUtils::NewDartArgumentError( | 717 Dart_ThrowException(DartUtils::NewDartArgumentError( |
739 "setTrustedCertificatesBytes has already been called " | 718 "setTrustedCertificatesBytes has already been called " |
740 "on the given context.")); | 719 "on the given context.")); |
741 } | 720 } |
(...skipping 16 matching lines...) Expand all Loading... |
758 | 737 |
759 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( | 738 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( |
760 Dart_NativeArguments args) { | 739 Dart_NativeArguments args) { |
761 SSLCertContext* context = GetSecurityContext(args); | 740 SSLCertContext* context = GetSecurityContext(args); |
762 | 741 |
763 const char* password = GetPasswordArgument(args, 2); | 742 const char* password = GetPasswordArgument(args, 2); |
764 OSStatus status; | 743 OSStatus status; |
765 CFArrayRef certs = NULL; | 744 CFArrayRef certs = NULL; |
766 { | 745 { |
767 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1))); | 746 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1))); |
768 status = ExtractSecItems( | 747 status = ExtractSecItems(buffer.get(), buffer.length(), password, &certs, |
769 buffer.get(), buffer.length(), password, &certs, NULL, NULL); | 748 NULL, NULL); |
770 } | 749 } |
771 | 750 |
772 // Set the field in the context. If there's a failure, release the certs, | 751 // Set the field in the context. If there's a failure, release the certs, |
773 // and throw an exception. | 752 // and throw an exception. |
774 if ((certs != NULL) && !context->set_cert_chain(certs)) { | 753 if ((certs != NULL) && !context->set_cert_chain(certs)) { |
775 CFRelease(certs); | 754 CFRelease(certs); |
776 Dart_ThrowException(DartUtils::NewDartArgumentError( | 755 Dart_ThrowException(DartUtils::NewDartArgumentError( |
777 "useCertificateChainBytes has already been called " | 756 "useCertificateChainBytes has already been called " |
778 "on the given context.")); | 757 "on the given context.")); |
779 } | 758 } |
780 | 759 |
781 CheckStatus(status, "TlsException", "Failure in useCertificateChainBytes"); | 760 CheckStatus(status, "TlsException", "Failure in useCertificateChainBytes"); |
782 } | 761 } |
783 | 762 |
784 | 763 |
785 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( | 764 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( |
786 Dart_NativeArguments args) { | 765 Dart_NativeArguments args) { |
787 SSLCertContext* context = GetSecurityContext(args); | 766 SSLCertContext* context = GetSecurityContext(args); |
788 const char* password = GetPasswordArgument(args, 2); | 767 const char* password = GetPasswordArgument(args, 2); |
789 | 768 |
790 OSStatus status; | 769 OSStatus status; |
791 CFArrayRef certs = NULL; | 770 CFArrayRef certs = NULL; |
792 { | 771 { |
793 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1))); | 772 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1))); |
794 status = ExtractSecItems( | 773 status = ExtractSecItems(buffer.get(), buffer.length(), password, &certs, |
795 buffer.get(), buffer.length(), password, &certs, NULL, NULL); | 774 NULL, NULL); |
796 } | 775 } |
797 | 776 |
798 // Set the field in the context. If there's a failure, release the certs, | 777 // Set the field in the context. If there's a failure, release the certs, |
799 // and throw an exception. | 778 // and throw an exception. |
800 if ((certs != NULL) && !context->set_cert_authorities(certs)) { | 779 if ((certs != NULL) && !context->set_cert_authorities(certs)) { |
801 CFRelease(certs); | 780 CFRelease(certs); |
802 Dart_ThrowException(DartUtils::NewDartArgumentError( | 781 Dart_ThrowException(DartUtils::NewDartArgumentError( |
803 "setClientAuthoritiesBytes has already been called " | 782 "setClientAuthoritiesBytes has already been called " |
804 "on the given context.")); | 783 "on the given context.")); |
805 } | 784 } |
806 | 785 |
807 CheckStatus(status, "TlsException", "Failure in setClientAuthoritiesBytes"); | 786 CheckStatus(status, "TlsException", "Failure in setClientAuthoritiesBytes"); |
808 } | 787 } |
809 | 788 |
810 | 789 |
811 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( | 790 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( |
812 Dart_NativeArguments args) { | 791 Dart_NativeArguments args) { |
813 Dart_ThrowException(DartUtils::NewDartUnsupportedError( | 792 Dart_ThrowException(DartUtils::NewDartUnsupportedError( |
814 "ALPN is not supported on this platform")); | 793 "ALPN is not supported on this platform")); |
815 } | 794 } |
816 | 795 |
817 | 796 |
818 static char* GetNameFromCert(SecCertificateRef certificate, | 797 static char* GetNameFromCert(SecCertificateRef certificate, |
819 CFTypeRef field, | 798 CFTypeRef field, |
820 CFStringRef name) { | 799 CFStringRef name) { |
821 char* issuer_name = NULL; | 800 char* issuer_name = NULL; |
822 | 801 |
823 CFTypeRef keys[] = { field }; | 802 CFTypeRef keys[] = {field}; |
824 CFArrayRef key_array = CFArrayCreate(NULL, keys, 1, &kCFTypeArrayCallBacks); | 803 CFArrayRef key_array = CFArrayCreate(NULL, keys, 1, &kCFTypeArrayCallBacks); |
825 CFErrorRef error = NULL; | 804 CFErrorRef error = NULL; |
826 CFDictionaryRef cert_dict = | 805 CFDictionaryRef cert_dict = |
827 SecCertificateCopyValues(certificate, key_array, &error); | 806 SecCertificateCopyValues(certificate, key_array, &error); |
828 if (cert_dict == NULL) { | 807 if (cert_dict == NULL) { |
829 CFRelease(key_array); | 808 CFRelease(key_array); |
830 Dart_ThrowException(DartUtils::NewDartArgumentError( | 809 Dart_ThrowException(DartUtils::NewDartArgumentError( |
831 "X509.issuer failed to copy issuer field out of certificate")); | 810 "X509.issuer failed to copy issuer field out of certificate")); |
832 } | 811 } |
833 | 812 |
(...skipping 24 matching lines...) Expand all Loading... |
858 } | 837 } |
859 | 838 |
860 CFRelease(cert_dict); | 839 CFRelease(cert_dict); |
861 CFRelease(key_array); | 840 CFRelease(key_array); |
862 return issuer_name; | 841 return issuer_name; |
863 } | 842 } |
864 | 843 |
865 | 844 |
866 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) { | 845 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) { |
867 SecCertificateRef certificate = GetX509Certificate(args); | 846 SecCertificateRef certificate = GetX509Certificate(args); |
868 char* subject_name = GetNameFromCert( | 847 char* subject_name = |
869 certificate, | 848 GetNameFromCert(certificate, kSecOIDX509V1SubjectName, |
870 kSecOIDX509V1SubjectName, | 849 reinterpret_cast<CFStringRef>(kSecOIDCommonName)); |
871 reinterpret_cast<CFStringRef>(kSecOIDCommonName)); | |
872 if (subject_name == NULL) { | 850 if (subject_name == NULL) { |
873 Dart_ThrowException(DartUtils::NewDartArgumentError( | 851 Dart_ThrowException(DartUtils::NewDartArgumentError( |
874 "X509.subject failed to find subject's common name.")); | 852 "X509.subject failed to find subject's common name.")); |
875 } else { | 853 } else { |
876 Dart_SetReturnValue(args, Dart_NewStringFromCString(subject_name)); | 854 Dart_SetReturnValue(args, Dart_NewStringFromCString(subject_name)); |
877 } | 855 } |
878 } | 856 } |
879 | 857 |
880 | 858 |
881 void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) { | 859 void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) { |
882 SecCertificateRef certificate = GetX509Certificate(args); | 860 SecCertificateRef certificate = GetX509Certificate(args); |
883 char* issuer_name = GetNameFromCert( | 861 char* issuer_name = |
884 certificate, | 862 GetNameFromCert(certificate, kSecOIDX509V1IssuerName, |
885 kSecOIDX509V1IssuerName, | 863 reinterpret_cast<CFStringRef>(kSecOIDCommonName)); |
886 reinterpret_cast<CFStringRef>(kSecOIDCommonName)); | |
887 if (issuer_name == NULL) { | 864 if (issuer_name == NULL) { |
888 Dart_ThrowException(DartUtils::NewDartArgumentError( | 865 Dart_ThrowException(DartUtils::NewDartArgumentError( |
889 "X509.issuer failed to find issuer's common name.")); | 866 "X509.issuer failed to find issuer's common name.")); |
890 } else { | 867 } else { |
891 Dart_SetReturnValue(args, Dart_NewStringFromCString(issuer_name)); | 868 Dart_SetReturnValue(args, Dart_NewStringFromCString(issuer_name)); |
892 } | 869 } |
893 } | 870 } |
894 | 871 |
895 | 872 |
896 // Returns the number of seconds since the epoch from 'field'. | 873 // Returns the number of seconds since the epoch from 'field'. |
897 static int64_t GetTimeFromCert(SecCertificateRef certificate, CFTypeRef field) { | 874 static int64_t GetTimeFromCert(SecCertificateRef certificate, CFTypeRef field) { |
898 CFTypeRef keys[] = { field }; | 875 CFTypeRef keys[] = {field}; |
899 CFArrayRef key_array = CFArrayCreate(NULL, keys, 1, &kCFTypeArrayCallBacks); | 876 CFArrayRef key_array = CFArrayCreate(NULL, keys, 1, &kCFTypeArrayCallBacks); |
900 CFErrorRef error = NULL; | 877 CFErrorRef error = NULL; |
901 CFDictionaryRef cert_dict = | 878 CFDictionaryRef cert_dict = |
902 SecCertificateCopyValues(certificate, key_array, &error); | 879 SecCertificateCopyValues(certificate, key_array, &error); |
903 if (cert_dict == NULL) { | 880 if (cert_dict == NULL) { |
904 CFRelease(key_array); | 881 CFRelease(key_array); |
905 Dart_ThrowException(DartUtils::NewDartArgumentError( | 882 Dart_ThrowException(DartUtils::NewDartArgumentError( |
906 "X509.startValidity: failed to copy issuer field out of certificate")); | 883 "X509.startValidity: failed to copy issuer field out of certificate")); |
907 } | 884 } |
908 | 885 |
909 CFTypeRef item = CFDictionaryGetValue(cert_dict, keys[0]); | 886 CFTypeRef item = CFDictionaryGetValue(cert_dict, keys[0]); |
910 ASSERT(CFGetTypeID(item) == CFDictionaryGetTypeID()); | 887 ASSERT(CFGetTypeID(item) == CFDictionaryGetTypeID()); |
911 CFDictionaryRef val_dict = reinterpret_cast<CFDictionaryRef>(item); | 888 CFDictionaryRef val_dict = reinterpret_cast<CFDictionaryRef>(item); |
912 | 889 |
913 item = CFDictionaryGetValue(val_dict, kSecPropertyKeyValue); | 890 item = CFDictionaryGetValue(val_dict, kSecPropertyKeyValue); |
914 ASSERT(CFGetTypeID(item) == CFNumberGetTypeID()); | 891 ASSERT(CFGetTypeID(item) == CFNumberGetTypeID()); |
915 CFNumberRef date_number = reinterpret_cast<CFNumberRef>(item); | 892 CFNumberRef date_number = reinterpret_cast<CFNumberRef>(item); |
916 | 893 |
917 CFAbsoluteTime date_abs_time; | 894 CFAbsoluteTime date_abs_time; |
918 CFNumberGetValue(date_number, kCFNumberDoubleType, &date_abs_time); | 895 CFNumberGetValue(date_number, kCFNumberDoubleType, &date_abs_time); |
919 CFAbsoluteTime seconds_since_epoch = | 896 CFAbsoluteTime seconds_since_epoch = |
920 date_abs_time + kCFAbsoluteTimeIntervalSince1970; | 897 date_abs_time + kCFAbsoluteTimeIntervalSince1970; |
921 return static_cast<int64_t>(seconds_since_epoch) * 1000LL; | 898 return static_cast<int64_t>(seconds_since_epoch) * 1000LL; |
922 } | 899 } |
923 | 900 |
924 | 901 |
925 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) { | 902 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) { |
926 SecCertificateRef certificate = GetX509Certificate(args); | 903 SecCertificateRef certificate = GetX509Certificate(args); |
927 int64_t seconds_since_epoch = GetTimeFromCert(certificate, | 904 int64_t seconds_since_epoch = |
928 kSecOIDX509V1ValidityNotBefore); | 905 GetTimeFromCert(certificate, kSecOIDX509V1ValidityNotBefore); |
929 Dart_SetReturnValue(args, | 906 Dart_SetReturnValue( |
| 907 args, |
930 Dart_NewInteger(static_cast<int64_t>(seconds_since_epoch) * 1000LL)); | 908 Dart_NewInteger(static_cast<int64_t>(seconds_since_epoch) * 1000LL)); |
931 } | 909 } |
932 | 910 |
933 | 911 |
934 void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) { | 912 void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) { |
935 SecCertificateRef certificate = GetX509Certificate(args); | 913 SecCertificateRef certificate = GetX509Certificate(args); |
936 int64_t seconds_since_epoch = GetTimeFromCert(certificate, | 914 int64_t seconds_since_epoch = |
937 kSecOIDX509V1ValidityNotAfter); | 915 GetTimeFromCert(certificate, kSecOIDX509V1ValidityNotAfter); |
938 Dart_SetReturnValue(args, | 916 Dart_SetReturnValue( |
| 917 args, |
939 Dart_NewInteger(static_cast<int64_t>(seconds_since_epoch) * 1000LL)); | 918 Dart_NewInteger(static_cast<int64_t>(seconds_since_epoch) * 1000LL)); |
940 } | 919 } |
941 | 920 |
942 | 921 |
943 // Pushes data through the SSL filter, reading and writing from circular | 922 // Pushes data through the SSL filter, reading and writing from circular |
944 // buffers shared with Dart. Called from the IOService thread. | 923 // buffers shared with Dart. Called from the IOService thread. |
945 // | 924 // |
946 // The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to | 925 // The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to |
947 // pass encrypted and plaintext data to and from the C++ SSLFilter object. | 926 // pass encrypted and plaintext data to and from the C++ SSLFilter object. |
948 // | 927 // |
(...skipping 18 matching lines...) Expand all Loading... |
967 bool in_handshake = CObjectBool(request[1]).Value(); | 946 bool in_handshake = CObjectBool(request[1]).Value(); |
968 intptr_t starts[SSLFilter::kNumBuffers]; | 947 intptr_t starts[SSLFilter::kNumBuffers]; |
969 intptr_t ends[SSLFilter::kNumBuffers]; | 948 intptr_t ends[SSLFilter::kNumBuffers]; |
970 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) { | 949 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) { |
971 starts[i] = CObjectInt32(request[2 * i + 2]).Value(); | 950 starts[i] = CObjectInt32(request[2 * i + 2]).Value(); |
972 ends[i] = CObjectInt32(request[2 * i + 3]).Value(); | 951 ends[i] = CObjectInt32(request[2 * i + 3]).Value(); |
973 } | 952 } |
974 | 953 |
975 OSStatus status = filter->ProcessAllBuffers(starts, ends, in_handshake); | 954 OSStatus status = filter->ProcessAllBuffers(starts, ends, in_handshake); |
976 if (status == noErr) { | 955 if (status == noErr) { |
977 CObjectArray* result = new CObjectArray( | 956 CObjectArray* result = |
978 CObject::NewArray(SSLFilter::kNumBuffers * 2)); | 957 new CObjectArray(CObject::NewArray(SSLFilter::kNumBuffers * 2)); |
979 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) { | 958 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) { |
980 result->SetAt(2 * i, new CObjectInt32(CObject::NewInt32(starts[i]))); | 959 result->SetAt(2 * i, new CObjectInt32(CObject::NewInt32(starts[i]))); |
981 result->SetAt(2 * i + 1, new CObjectInt32(CObject::NewInt32(ends[i]))); | 960 result->SetAt(2 * i + 1, new CObjectInt32(CObject::NewInt32(ends[i]))); |
982 } | 961 } |
983 return result; | 962 return result; |
984 } else { | 963 } else { |
985 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); | 964 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); |
986 CFStringRef error_string = SecCopyErrorMessageString(status, NULL); | 965 CFStringRef error_string = SecCopyErrorMessageString(status, NULL); |
987 if (error_string == NULL) { | 966 if (error_string == NULL) { |
988 status_message.Printf("OSStatus = %ld: https://www.osstatus.com", | 967 status_message.Printf("OSStatus = %ld: https://www.osstatus.com", |
989 static_cast<intptr_t>(status)); | 968 static_cast<intptr_t>(status)); |
990 } else { | 969 } else { |
991 char* error = CFStringRefToCString(error_string); | 970 char* error = CFStringRefToCString(error_string); |
992 status_message.Printf("OSStatus = %ld: %s", | 971 status_message.Printf("OSStatus = %ld: %s", static_cast<intptr_t>(status), |
993 static_cast<intptr_t>(status), error); | 972 error); |
994 CFRelease(error_string); | 973 CFRelease(error_string); |
995 } | 974 } |
996 CObjectArray* result = new CObjectArray(CObject::NewArray(2)); | 975 CObjectArray* result = new CObjectArray(CObject::NewArray(2)); |
997 result->SetAt(0, new CObjectInt32(CObject::NewInt32(status))); | 976 result->SetAt(0, new CObjectInt32(CObject::NewInt32(status))); |
998 result->SetAt(1, new CObjectString(CObject::NewString( | 977 result->SetAt(1, |
999 status_message.buf()))); | 978 new CObjectString(CObject::NewString(status_message.buf()))); |
1000 return result; | 979 return result; |
1001 } | 980 } |
1002 } | 981 } |
1003 | 982 |
1004 | 983 |
1005 // Usually buffer_starts_ and buffer_ends_ are populated by ProcessAllBuffers, | 984 // Usually buffer_starts_ and buffer_ends_ are populated by ProcessAllBuffers, |
1006 // called from ProcessFilterRequest, called from the IOService thread. | 985 // called from ProcessFilterRequest, called from the IOService thread. |
1007 // However, the first call to SSLHandshake comes from the Dart thread, and so | 986 // However, the first call to SSLHandshake comes from the Dart thread, and so |
1008 // doesn't go through there. This results in calls to SSLReadCallback and | 987 // doesn't go through there. This results in calls to SSLReadCallback and |
1009 // SSLWriteCallback in which buffer_starts_ and buffer_ends_ haven't been set | 988 // SSLWriteCallback in which buffer_starts_ and buffer_ends_ haven't been set |
(...skipping 25 matching lines...) Expand all Loading... |
1035 } | 1014 } |
1036 | 1015 |
1037 | 1016 |
1038 void SSLFilter::SetBufferStart(intptr_t idx, intptr_t value) { | 1017 void SSLFilter::SetBufferStart(intptr_t idx, intptr_t value) { |
1039 if (buffer_starts_[idx] != NULL) { | 1018 if (buffer_starts_[idx] != NULL) { |
1040 *buffer_starts_[idx] = value; | 1019 *buffer_starts_[idx] = value; |
1041 return; | 1020 return; |
1042 } | 1021 } |
1043 Dart_Handle buffer_handle = | 1022 Dart_Handle buffer_handle = |
1044 ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx])); | 1023 ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx])); |
1045 ThrowIfError(DartUtils::SetIntegerField( | 1024 ThrowIfError(DartUtils::SetIntegerField(buffer_handle, "start", |
1046 buffer_handle, "start", static_cast<int64_t>(value))); | 1025 static_cast<int64_t>(value))); |
1047 } | 1026 } |
1048 | 1027 |
1049 | 1028 |
1050 void SSLFilter::SetBufferEnd(intptr_t idx, intptr_t value) { | 1029 void SSLFilter::SetBufferEnd(intptr_t idx, intptr_t value) { |
1051 if (buffer_ends_[idx] != NULL) { | 1030 if (buffer_ends_[idx] != NULL) { |
1052 *buffer_ends_[idx] = value; | 1031 *buffer_ends_[idx] = value; |
1053 return; | 1032 return; |
1054 } | 1033 } |
1055 Dart_Handle buffer_handle = | 1034 Dart_Handle buffer_handle = |
1056 ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx])); | 1035 ThrowIfError(Dart_HandleFromPersistent(dart_buffer_objects_[idx])); |
1057 ThrowIfError(DartUtils::SetIntegerField( | 1036 ThrowIfError(DartUtils::SetIntegerField(buffer_handle, "end", |
1058 buffer_handle, "end", static_cast<int64_t>(value))); | 1037 static_cast<int64_t>(value))); |
1059 } | 1038 } |
1060 | 1039 |
1061 | 1040 |
1062 OSStatus SSLFilter::ProcessAllBuffers(intptr_t starts[kNumBuffers], | 1041 OSStatus SSLFilter::ProcessAllBuffers(intptr_t starts[kNumBuffers], |
1063 intptr_t ends[kNumBuffers], | 1042 intptr_t ends[kNumBuffers], |
1064 bool in_handshake) { | 1043 bool in_handshake) { |
1065 for (intptr_t i = 0; i < kNumBuffers; ++i) { | 1044 for (intptr_t i = 0; i < kNumBuffers; ++i) { |
1066 buffer_starts_[i] = &starts[i]; | 1045 buffer_starts_[i] = &starts[i]; |
1067 buffer_ends_[i] = &ends[i]; | 1046 buffer_ends_[i] = &ends[i]; |
1068 } | 1047 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1182 Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) { | 1161 Dart_Handle SSLFilter::InitializeBuffers(Dart_Handle dart_this) { |
1183 // Create SSLFilter buffers as ExternalUint8Array objects. | 1162 // Create SSLFilter buffers as ExternalUint8Array objects. |
1184 Dart_Handle buffers_string = DartUtils::NewString("buffers"); | 1163 Dart_Handle buffers_string = DartUtils::NewString("buffers"); |
1185 RETURN_IF_ERROR(buffers_string); | 1164 RETURN_IF_ERROR(buffers_string); |
1186 Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string); | 1165 Dart_Handle dart_buffers_object = Dart_GetField(dart_this, buffers_string); |
1187 RETURN_IF_ERROR(dart_buffers_object); | 1166 RETURN_IF_ERROR(dart_buffers_object); |
1188 Dart_Handle secure_filter_impl_type = Dart_InstanceGetType(dart_this); | 1167 Dart_Handle secure_filter_impl_type = Dart_InstanceGetType(dart_this); |
1189 RETURN_IF_ERROR(secure_filter_impl_type); | 1168 RETURN_IF_ERROR(secure_filter_impl_type); |
1190 Dart_Handle size_string = DartUtils::NewString("SIZE"); | 1169 Dart_Handle size_string = DartUtils::NewString("SIZE"); |
1191 RETURN_IF_ERROR(size_string); | 1170 RETURN_IF_ERROR(size_string); |
1192 Dart_Handle dart_buffer_size = Dart_GetField( | 1171 Dart_Handle dart_buffer_size = |
1193 secure_filter_impl_type, size_string); | 1172 Dart_GetField(secure_filter_impl_type, size_string); |
1194 RETURN_IF_ERROR(dart_buffer_size); | 1173 RETURN_IF_ERROR(dart_buffer_size); |
1195 | 1174 |
1196 int64_t buffer_size = 0; | 1175 int64_t buffer_size = 0; |
1197 Dart_Handle err = Dart_IntegerToInt64(dart_buffer_size, &buffer_size); | 1176 Dart_Handle err = Dart_IntegerToInt64(dart_buffer_size, &buffer_size); |
1198 RETURN_IF_ERROR(err); | 1177 RETURN_IF_ERROR(err); |
1199 | 1178 |
1200 Dart_Handle encrypted_size_string = DartUtils::NewString("ENCRYPTED_SIZE"); | 1179 Dart_Handle encrypted_size_string = DartUtils::NewString("ENCRYPTED_SIZE"); |
1201 RETURN_IF_ERROR(encrypted_size_string); | 1180 RETURN_IF_ERROR(encrypted_size_string); |
1202 | 1181 |
1203 Dart_Handle dart_encrypted_buffer_size = Dart_GetField( | 1182 Dart_Handle dart_encrypted_buffer_size = |
1204 secure_filter_impl_type, encrypted_size_string); | 1183 Dart_GetField(secure_filter_impl_type, encrypted_size_string); |
1205 RETURN_IF_ERROR(dart_encrypted_buffer_size); | 1184 RETURN_IF_ERROR(dart_encrypted_buffer_size); |
1206 | 1185 |
1207 int64_t encrypted_buffer_size = 0; | 1186 int64_t encrypted_buffer_size = 0; |
1208 err = Dart_IntegerToInt64(dart_encrypted_buffer_size, &encrypted_buffer_size); | 1187 err = Dart_IntegerToInt64(dart_encrypted_buffer_size, &encrypted_buffer_size); |
1209 RETURN_IF_ERROR(err); | 1188 RETURN_IF_ERROR(err); |
1210 | 1189 |
1211 if (buffer_size <= 0 || buffer_size > 1 * MB) { | 1190 if (buffer_size <= 0 || buffer_size > 1 * MB) { |
1212 FATAL("Invalid buffer size in _ExternalBuffer"); | 1191 FATAL("Invalid buffer size in _ExternalBuffer"); |
1213 } | 1192 } |
1214 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 * MB) { | 1193 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 * MB) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1302 FATAL("Connect called twice on the same _SecureFilter."); | 1281 FATAL("Connect called twice on the same _SecureFilter."); |
1303 } | 1282 } |
1304 | 1283 |
1305 // Create the underlying context | 1284 // Create the underlying context |
1306 SSLContextRef ssl_context = SSLCreateContext( | 1285 SSLContextRef ssl_context = SSLCreateContext( |
1307 NULL, is_server ? kSSLServerSide : kSSLClientSide, kSSLStreamType); | 1286 NULL, is_server ? kSSLServerSide : kSSLClientSide, kSSLStreamType); |
1308 | 1287 |
1309 // Configure the context. | 1288 // Configure the context. |
1310 OSStatus status; | 1289 OSStatus status; |
1311 status = SSLSetPeerDomainName(ssl_context, hostname, strlen(hostname)); | 1290 status = SSLSetPeerDomainName(ssl_context, hostname, strlen(hostname)); |
1312 CheckStatus(status, | 1291 CheckStatus(status, "TlsException", "Failed to set peer domain name"); |
1313 "TlsException", | |
1314 "Failed to set peer domain name"); | |
1315 | 1292 |
1316 status = SSLSetIOFuncs( | 1293 status = SSLSetIOFuncs(ssl_context, SSLFilter::SSLReadCallback, |
1317 ssl_context, SSLFilter::SSLReadCallback, SSLFilter::SSLWriteCallback); | 1294 SSLFilter::SSLWriteCallback); |
1318 CheckStatus(status, | 1295 CheckStatus(status, "TlsException", "Failed to set IO Callbacks"); |
1319 "TlsException", | |
1320 "Failed to set IO Callbacks"); | |
1321 | 1296 |
1322 status = SSLSetConnection( | 1297 status = |
1323 ssl_context, reinterpret_cast<SSLConnectionRef>(this)); | 1298 SSLSetConnection(ssl_context, reinterpret_cast<SSLConnectionRef>(this)); |
1324 CheckStatus(status, | 1299 CheckStatus(status, "TlsException", "Failed to set connection object"); |
1325 "TlsException", | |
1326 "Failed to set connection object"); | |
1327 | 1300 |
1328 // Always evaluate the certs manually so that we can cache the peer | 1301 // Always evaluate the certs manually so that we can cache the peer |
1329 // certificates in the context for calls to peerCertificate. | 1302 // certificates in the context for calls to peerCertificate. |
1330 status = SSLSetSessionOption( | 1303 status = SSLSetSessionOption(ssl_context, kSSLSessionOptionBreakOnServerAuth, |
1331 ssl_context, kSSLSessionOptionBreakOnServerAuth, true); | 1304 true); |
1332 CheckStatus(status, | 1305 CheckStatus(status, "TlsException", "Failed to set BreakOnServerAuth option"); |
1333 "TlsException", | |
1334 "Failed to set BreakOnServerAuth option"); | |
1335 | 1306 |
1336 status = SSLSetProtocolVersionMin(ssl_context, kTLSProtocol1); | 1307 status = SSLSetProtocolVersionMin(ssl_context, kTLSProtocol1); |
1337 CheckStatus(status, | 1308 CheckStatus(status, "TlsException", |
1338 "TlsException", | 1309 "Failed to set minimum protocol version to kTLSProtocol1"); |
1339 "Failed to set minimum protocol version to kTLSProtocol1"); | |
1340 | 1310 |
1341 // If the context has a private key and certificate chain, combine the | 1311 // If the context has a private key and certificate chain, combine the |
1342 // private key and first certificate into a SecIdentityRef, and place that | 1312 // private key and first certificate into a SecIdentityRef, and place that |
1343 // and the remaining certs in an array to pass to SSLSetCertificate(). | 1313 // and the remaining certs in an array to pass to SSLSetCertificate(). |
1344 if ((context->private_key() != NULL) && (context->cert_chain() != NULL)) { | 1314 if ((context->private_key() != NULL) && (context->cert_chain() != NULL)) { |
1345 CFIndex chain_length = CFArrayGetCount(context->cert_chain()); | 1315 CFIndex chain_length = CFArrayGetCount(context->cert_chain()); |
1346 CFMutableArrayRef certs = | 1316 CFMutableArrayRef certs = |
1347 CFArrayCreateMutable(NULL, chain_length, &kCFTypeArrayCallBacks); | 1317 CFArrayCreateMutable(NULL, chain_length, &kCFTypeArrayCallBacks); |
1348 CFTypeRef item = CFArrayGetValueAtIndex(context->cert_chain(), 0); | 1318 CFTypeRef item = CFArrayGetValueAtIndex(context->cert_chain(), 0); |
1349 ASSERT(CFGetTypeID(item) == SecCertificateGetTypeID()); | 1319 ASSERT(CFGetTypeID(item) == SecCertificateGetTypeID()); |
1350 SecCertificateRef first_cert = | 1320 SecCertificateRef first_cert = |
1351 reinterpret_cast<SecCertificateRef>(const_cast<void*>(item)); | 1321 reinterpret_cast<SecCertificateRef>(const_cast<void*>(item)); |
1352 SecIdentityRef identity = | 1322 SecIdentityRef identity = |
1353 SecIdentityCreate(NULL, first_cert, context->private_key()); | 1323 SecIdentityCreate(NULL, first_cert, context->private_key()); |
1354 CFArrayAppendValue(certs, identity); | 1324 CFArrayAppendValue(certs, identity); |
1355 for (CFIndex i = 0; i < chain_length; i++) { | 1325 for (CFIndex i = 0; i < chain_length; i++) { |
1356 CFArrayAppendValue(certs, | 1326 CFArrayAppendValue(certs, |
1357 CFArrayGetValueAtIndex(context->cert_chain(), i)); | 1327 CFArrayGetValueAtIndex(context->cert_chain(), i)); |
1358 } | 1328 } |
1359 CFRelease(identity); | 1329 CFRelease(identity); |
1360 status = SSLSetCertificate(ssl_context, certs); | 1330 status = SSLSetCertificate(ssl_context, certs); |
1361 CFRelease(certs); | 1331 CFRelease(certs); |
1362 CheckStatus(status, "TlsException", "SSLSetCertificate failed"); | 1332 CheckStatus(status, "TlsException", "SSLSetCertificate failed"); |
1363 } | 1333 } |
1364 | 1334 |
1365 if (context->cert_authorities() != NULL) { | 1335 if (context->cert_authorities() != NULL) { |
1366 status = SSLSetCertificateAuthorities( | 1336 status = SSLSetCertificateAuthorities(ssl_context, |
1367 ssl_context, context->cert_authorities(), true); | 1337 context->cert_authorities(), true); |
1368 CheckStatus(status, | 1338 CheckStatus(status, "TlsException", |
1369 "TlsException", | 1339 "Failed to set certificate authorities"); |
1370 "Failed to set certificate authorities"); | |
1371 } | 1340 } |
1372 | 1341 |
1373 if (is_server) { | 1342 if (is_server) { |
1374 SSLAuthenticate auth = | 1343 SSLAuthenticate auth = |
1375 require_client_certificate | 1344 require_client_certificate |
1376 ? kAlwaysAuthenticate | 1345 ? kAlwaysAuthenticate |
1377 : (request_client_certificate ? kTryAuthenticate : kNeverAuthenticate); | 1346 : (request_client_certificate ? kTryAuthenticate |
| 1347 : kNeverAuthenticate); |
1378 status = SSLSetClientSideAuthenticate(ssl_context, auth); | 1348 status = SSLSetClientSideAuthenticate(ssl_context, auth); |
1379 CheckStatus(status, | 1349 CheckStatus(status, "TlsException", |
1380 "TlsException", | 1350 "Failed to set client authentication mode"); |
1381 "Failed to set client authentication mode"); | |
1382 | 1351 |
1383 // If we're at least trying client authentication, then break handshake | 1352 // If we're at least trying client authentication, then break handshake |
1384 // for client authentication. | 1353 // for client authentication. |
1385 if (auth != kNeverAuthenticate) { | 1354 if (auth != kNeverAuthenticate) { |
1386 status = SSLSetSessionOption( | 1355 status = SSLSetSessionOption(ssl_context, |
1387 ssl_context, kSSLSessionOptionBreakOnClientAuth, true); | 1356 kSSLSessionOptionBreakOnClientAuth, true); |
1388 CheckStatus(status, | 1357 CheckStatus(status, "TlsException", |
1389 "TlsException", | 1358 "Failed to set client authentication mode"); |
1390 "Failed to set client authentication mode"); | |
1391 } | 1359 } |
1392 } | 1360 } |
1393 | 1361 |
1394 // Add the contexts to our wrapper. | 1362 // Add the contexts to our wrapper. |
1395 cert_context_.set(context); | 1363 cert_context_.set(context); |
1396 ssl_context_ = ssl_context; | 1364 ssl_context_ = ssl_context; |
1397 is_server_ = is_server; | 1365 is_server_ = is_server; |
1398 | 1366 |
1399 // Kick-off the handshake. Expect the handshake to need more data. | 1367 // Kick-off the handshake. Expect the handshake to need more data. |
1400 // SSLHandshake calls our SSLReadCallback and SSLWriteCallback. | 1368 // SSLHandshake calls our SSLReadCallback and SSLWriteCallback. |
1401 status = SSLHandshake(ssl_context); | 1369 status = SSLHandshake(ssl_context); |
1402 ASSERT(status != noErr); | 1370 ASSERT(status != noErr); |
1403 if (status == errSSLWouldBlock) { | 1371 if (status == errSSLWouldBlock) { |
1404 status = noErr; | 1372 status = noErr; |
1405 in_handshake_ = true; | 1373 in_handshake_ = true; |
1406 } | 1374 } |
1407 CheckStatus(status, | 1375 CheckStatus(status, "HandshakeException", is_server_ |
1408 "HandshakeException", | 1376 ? "Handshake error in server" |
1409 is_server_ ? "Handshake error in server" : "Handshake error in client"); | 1377 : "Handshake error in client"); |
1410 } | 1378 } |
1411 | 1379 |
1412 | 1380 |
1413 OSStatus SSLFilter::EvaluatePeerTrust() { | 1381 OSStatus SSLFilter::EvaluatePeerTrust() { |
1414 OSStatus status = noErr; | 1382 OSStatus status = noErr; |
1415 | 1383 |
1416 if (SSL_LOG_STATUS) { | 1384 if (SSL_LOG_STATUS) { |
1417 Log::Print("Handshake evaluating trust.\n"); | 1385 Log::Print("Handshake evaluating trust.\n"); |
1418 } | 1386 } |
1419 SecTrustRef peer_trust = NULL; | 1387 SecTrustRef peer_trust = NULL; |
1420 status = SSLCopyPeerTrust(ssl_context_, &peer_trust); | 1388 status = SSLCopyPeerTrust(ssl_context_, &peer_trust); |
1421 if (status != noErr) { | 1389 if (status != noErr) { |
1422 if (is_server_ && (status == errSSLBadCert)) { | 1390 if (is_server_ && (status == errSSLBadCert)) { |
1423 // A client certificate was requested, but not required, and wasn't sent. | 1391 // A client certificate was requested, but not required, and wasn't sent. |
1424 return noErr; | 1392 return noErr; |
1425 } | 1393 } |
1426 if (SSL_LOG_STATUS) { | 1394 if (SSL_LOG_STATUS) { |
1427 Log::Print("Handshake error from SSLCopyPeerTrust(): %ld.\n", | 1395 Log::Print("Handshake error from SSLCopyPeerTrust(): %ld.\n", |
1428 static_cast<intptr_t>(status)); | 1396 static_cast<intptr_t>(status)); |
1429 } | 1397 } |
1430 return status; | 1398 return status; |
1431 } | 1399 } |
1432 | 1400 |
1433 CFArrayRef trusted_certs = NULL; | 1401 CFArrayRef trusted_certs = NULL; |
1434 if (cert_context_.get()->trusted_certs() != NULL) { | 1402 if (cert_context_.get()->trusted_certs() != NULL) { |
1435 trusted_certs = | 1403 trusted_certs = |
1436 CFArrayCreateCopy(NULL, cert_context_.get()->trusted_certs()); | 1404 CFArrayCreateCopy(NULL, cert_context_.get()->trusted_certs()); |
1437 } else { | 1405 } else { |
1438 trusted_certs = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); | 1406 trusted_certs = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); |
1439 } | 1407 } |
1440 | 1408 |
1441 status = SecTrustSetAnchorCertificates(peer_trust, trusted_certs); | 1409 status = SecTrustSetAnchorCertificates(peer_trust, trusted_certs); |
1442 if (status != noErr) { | 1410 if (status != noErr) { |
1443 if (SSL_LOG_STATUS) { | 1411 if (SSL_LOG_STATUS) { |
1444 Log::Print("Handshake error from SecTrustSetAnchorCertificates: %ld\n", | 1412 Log::Print("Handshake error from SecTrustSetAnchorCertificates: %ld\n", |
1445 static_cast<intptr_t>(status)); | 1413 static_cast<intptr_t>(status)); |
1446 } | 1414 } |
1447 CFRelease(trusted_certs); | 1415 CFRelease(trusted_certs); |
1448 CFRelease(peer_trust); | 1416 CFRelease(peer_trust); |
1449 return status; | 1417 return status; |
1450 } | 1418 } |
1451 | 1419 |
1452 if (SSL_LOG_STATUS) { | 1420 if (SSL_LOG_STATUS) { |
1453 Log::Print("Handshake %s built in root certs\n", | 1421 Log::Print( |
| 1422 "Handshake %s built in root certs\n", |
1454 cert_context_.get()->trust_builtin() ? "trusting" : "not trusting"); | 1423 cert_context_.get()->trust_builtin() ? "trusting" : "not trusting"); |
1455 } | 1424 } |
1456 | 1425 |
1457 status = SecTrustSetAnchorCertificatesOnly( | 1426 status = SecTrustSetAnchorCertificatesOnly( |
1458 peer_trust, !cert_context_.get()->trust_builtin()); | 1427 peer_trust, !cert_context_.get()->trust_builtin()); |
1459 if (status != noErr) { | 1428 if (status != noErr) { |
1460 CFRelease(trusted_certs); | 1429 CFRelease(trusted_certs); |
1461 CFRelease(peer_trust); | 1430 CFRelease(peer_trust); |
1462 return status; | 1431 return status; |
1463 } | 1432 } |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1655 handshake_complete_ = NULL; | 1624 handshake_complete_ = NULL; |
1656 } | 1625 } |
1657 if (bad_certificate_callback_ != NULL) { | 1626 if (bad_certificate_callback_ != NULL) { |
1658 Dart_DeletePersistentHandle(bad_certificate_callback_); | 1627 Dart_DeletePersistentHandle(bad_certificate_callback_); |
1659 bad_certificate_callback_ = NULL; | 1628 bad_certificate_callback_ = NULL; |
1660 } | 1629 } |
1661 } | 1630 } |
1662 | 1631 |
1663 | 1632 |
1664 OSStatus SSLFilter::SSLReadCallback(SSLConnectionRef connection, | 1633 OSStatus SSLFilter::SSLReadCallback(SSLConnectionRef connection, |
1665 void* data, size_t* data_requested) { | 1634 void* data, |
| 1635 size_t* data_requested) { |
1666 // Copy at most `data_requested` bytes from `buffers_[kReadEncrypted]` into | 1636 // Copy at most `data_requested` bytes from `buffers_[kReadEncrypted]` into |
1667 // `data` | 1637 // `data` |
1668 ASSERT(connection != NULL); | 1638 ASSERT(connection != NULL); |
1669 ASSERT(data != NULL); | 1639 ASSERT(data != NULL); |
1670 ASSERT(data_requested != NULL); | 1640 ASSERT(data_requested != NULL); |
1671 | 1641 |
1672 SSLFilter* filter = | 1642 SSLFilter* filter = |
1673 const_cast<SSLFilter*>(reinterpret_cast<const SSLFilter*>(connection)); | 1643 const_cast<SSLFilter*>(reinterpret_cast<const SSLFilter*>(connection)); |
1674 uint8_t* datap = reinterpret_cast<uint8_t*>(data); | 1644 uint8_t* datap = reinterpret_cast<uint8_t*>(data); |
1675 uint8_t* buffer = filter->buffers_[kReadEncrypted]; | 1645 uint8_t* buffer = filter->buffers_[kReadEncrypted]; |
(...skipping 25 matching lines...) Expand all Loading... |
1701 memmove(datap, &buffer[start], bytes); | 1671 memmove(datap, &buffer[start], bytes); |
1702 start += bytes; | 1672 start += bytes; |
1703 datap += bytes; | 1673 datap += bytes; |
1704 data_read += bytes; | 1674 data_read += bytes; |
1705 requested -= bytes; | 1675 requested -= bytes; |
1706 ASSERT(start <= end); | 1676 ASSERT(start <= end); |
1707 } | 1677 } |
1708 | 1678 |
1709 if (SSL_LOG_DATA) { | 1679 if (SSL_LOG_DATA) { |
1710 Log::Print("SSLReadCallback: requested: %ld, read %ld bytes\n", | 1680 Log::Print("SSLReadCallback: requested: %ld, read %ld bytes\n", |
1711 *data_requested, data_read); | 1681 *data_requested, data_read); |
1712 } | 1682 } |
1713 | 1683 |
1714 filter->SetBufferStart(kReadEncrypted, start); | 1684 filter->SetBufferStart(kReadEncrypted, start); |
1715 bool short_read = data_read < static_cast<intptr_t>(*data_requested); | 1685 bool short_read = data_read < static_cast<intptr_t>(*data_requested); |
1716 *data_requested = data_read; | 1686 *data_requested = data_read; |
1717 return short_read ? errSSLWouldBlock : noErr; | 1687 return short_read ? errSSLWouldBlock : noErr; |
1718 } | 1688 } |
1719 | 1689 |
1720 | 1690 |
1721 // Read decrypted data from the filter to the circular buffer. | 1691 // Read decrypted data from the filter to the circular buffer. |
1722 OSStatus SSLFilter::ProcessReadPlaintextBuffer(intptr_t start, | 1692 OSStatus SSLFilter::ProcessReadPlaintextBuffer(intptr_t start, |
1723 intptr_t end, | 1693 intptr_t end, |
1724 intptr_t* bytes_processed) { | 1694 intptr_t* bytes_processed) { |
1725 ASSERT(bytes_processed != NULL); | 1695 ASSERT(bytes_processed != NULL); |
1726 intptr_t length = end - start; | 1696 intptr_t length = end - start; |
1727 OSStatus status = noErr; | 1697 OSStatus status = noErr; |
1728 size_t bytes = 0; | 1698 size_t bytes = 0; |
1729 if (length > 0) { | 1699 if (length > 0) { |
1730 status = SSLRead( | 1700 status = |
1731 ssl_context_, | 1701 SSLRead(ssl_context_, |
1732 reinterpret_cast<void*>((buffers_[kReadPlaintext] + start)), | 1702 reinterpret_cast<void*>((buffers_[kReadPlaintext] + start)), |
1733 length, | 1703 length, &bytes); |
1734 &bytes); | |
1735 if (SSL_LOG_STATUS) { | 1704 if (SSL_LOG_STATUS) { |
1736 Log::Print("SSLRead: status = %ld\n", static_cast<intptr_t>(status)); | 1705 Log::Print("SSLRead: status = %ld\n", static_cast<intptr_t>(status)); |
1737 } | 1706 } |
1738 if ((status != noErr) && (status != errSSLWouldBlock)) { | 1707 if ((status != noErr) && (status != errSSLWouldBlock)) { |
1739 *bytes_processed = 0; | 1708 *bytes_processed = 0; |
1740 return status; | 1709 return status; |
1741 } | 1710 } |
1742 } | 1711 } |
1743 if (SSL_LOG_DATA) { | 1712 if (SSL_LOG_DATA) { |
1744 Log::Print("ProcessReadPlaintextBuffer: requested: %ld, read %ld bytes\n", | 1713 Log::Print("ProcessReadPlaintextBuffer: requested: %ld, read %ld bytes\n", |
1745 length, bytes); | 1714 length, bytes); |
1746 } | 1715 } |
1747 *bytes_processed = static_cast<intptr_t>(bytes); | 1716 *bytes_processed = static_cast<intptr_t>(bytes); |
1748 return status; | 1717 return status; |
1749 } | 1718 } |
1750 | 1719 |
1751 | 1720 |
1752 OSStatus SSLFilter::SSLWriteCallback(SSLConnectionRef connection, | 1721 OSStatus SSLFilter::SSLWriteCallback(SSLConnectionRef connection, |
1753 const void* data, size_t* data_provided) { | 1722 const void* data, |
| 1723 size_t* data_provided) { |
1754 // Copy at most `data_provided` bytes from data into | 1724 // Copy at most `data_provided` bytes from data into |
1755 // `buffers_[kWriteEncrypted]`. | 1725 // `buffers_[kWriteEncrypted]`. |
1756 ASSERT(connection != NULL); | 1726 ASSERT(connection != NULL); |
1757 ASSERT(data != NULL); | 1727 ASSERT(data != NULL); |
1758 ASSERT(data_provided != NULL); | 1728 ASSERT(data_provided != NULL); |
1759 | 1729 |
1760 SSLFilter* filter = | 1730 SSLFilter* filter = |
1761 const_cast<SSLFilter*>(reinterpret_cast<const SSLFilter*>(connection)); | 1731 const_cast<SSLFilter*>(reinterpret_cast<const SSLFilter*>(connection)); |
1762 const uint8_t* datap = reinterpret_cast<const uint8_t*>(data); | 1732 const uint8_t* datap = reinterpret_cast<const uint8_t*>(data); |
1763 uint8_t* buffer = filter->buffers_[kWriteEncrypted]; | 1733 uint8_t* buffer = filter->buffers_[kWriteEncrypted]; |
1764 intptr_t start = filter->GetBufferStart(kWriteEncrypted); | 1734 intptr_t start = filter->GetBufferStart(kWriteEncrypted); |
1765 intptr_t end = filter->GetBufferEnd(kWriteEncrypted); | 1735 intptr_t end = filter->GetBufferEnd(kWriteEncrypted); |
1766 intptr_t size = filter->encrypted_buffer_size_; | 1736 intptr_t size = filter->encrypted_buffer_size_; |
1767 intptr_t provided = static_cast<intptr_t>(*data_provided); | 1737 intptr_t provided = static_cast<intptr_t>(*data_provided); |
1768 intptr_t data_written = 0; | 1738 intptr_t data_written = 0; |
1769 | 1739 |
1770 // is full, neither if statement is executed and nothing happens. | 1740 // is full, neither if statement is executed and nothing happens. |
1771 if (start <= end) { | 1741 if (start <= end) { |
(...skipping 20 matching lines...) Expand all Loading... |
1792 memmove(&buffer[end], datap, bytes); | 1762 memmove(&buffer[end], datap, bytes); |
1793 end += bytes; | 1763 end += bytes; |
1794 datap += bytes; | 1764 datap += bytes; |
1795 data_written += bytes; | 1765 data_written += bytes; |
1796 provided -= bytes; | 1766 provided -= bytes; |
1797 ASSERT(end < start); | 1767 ASSERT(end < start); |
1798 } | 1768 } |
1799 | 1769 |
1800 if (SSL_LOG_DATA) { | 1770 if (SSL_LOG_DATA) { |
1801 Log::Print("SSLWriteCallback: provided: %ld, written %ld bytes\n", | 1771 Log::Print("SSLWriteCallback: provided: %ld, written %ld bytes\n", |
1802 *data_provided, data_written); | 1772 *data_provided, data_written); |
1803 } | 1773 } |
1804 | 1774 |
1805 filter->SetBufferEnd(kWriteEncrypted, end); | 1775 filter->SetBufferEnd(kWriteEncrypted, end); |
1806 *data_provided = data_written; | 1776 *data_provided = data_written; |
1807 return (data_written == 0) ? errSSLWouldBlock : noErr; | 1777 return (data_written == 0) ? errSSLWouldBlock : noErr; |
1808 } | 1778 } |
1809 | 1779 |
1810 | 1780 |
1811 OSStatus SSLFilter::ProcessWritePlaintextBuffer(intptr_t start, | 1781 OSStatus SSLFilter::ProcessWritePlaintextBuffer(intptr_t start, |
1812 intptr_t end, | 1782 intptr_t end, |
1813 intptr_t* bytes_processed) { | 1783 intptr_t* bytes_processed) { |
1814 ASSERT(bytes_processed != NULL); | 1784 ASSERT(bytes_processed != NULL); |
1815 intptr_t length = end - start; | 1785 intptr_t length = end - start; |
1816 OSStatus status = noErr; | 1786 OSStatus status = noErr; |
1817 size_t bytes = 0; | 1787 size_t bytes = 0; |
1818 if (length > 0) { | 1788 if (length > 0) { |
1819 status = SSLWrite( | 1789 status = |
1820 ssl_context_, | 1790 SSLWrite(ssl_context_, |
1821 reinterpret_cast<void*>(buffers_[kWritePlaintext] + start), | 1791 reinterpret_cast<void*>(buffers_[kWritePlaintext] + start), |
1822 length, | 1792 length, &bytes); |
1823 &bytes); | |
1824 if (SSL_LOG_STATUS) { | 1793 if (SSL_LOG_STATUS) { |
1825 Log::Print("SSLWrite: status = %ld\n", static_cast<intptr_t>(status)); | 1794 Log::Print("SSLWrite: status = %ld\n", static_cast<intptr_t>(status)); |
1826 } | 1795 } |
1827 if ((status != noErr) && (status != errSSLWouldBlock)) { | 1796 if ((status != noErr) && (status != errSSLWouldBlock)) { |
1828 *bytes_processed = 0; | 1797 *bytes_processed = 0; |
1829 return status; | 1798 return status; |
1830 } | 1799 } |
1831 } | 1800 } |
1832 if (SSL_LOG_DATA) { | 1801 if (SSL_LOG_DATA) { |
1833 Log::Print("ProcessWritePlaintextBuffer: requested: %ld, written: %ld\n", | 1802 Log::Print("ProcessWritePlaintextBuffer: requested: %ld, written: %ld\n", |
1834 length, bytes); | 1803 length, bytes); |
1835 } | 1804 } |
1836 *bytes_processed = static_cast<intptr_t>(bytes); | 1805 *bytes_processed = static_cast<intptr_t>(bytes); |
1837 return status; | 1806 return status; |
1838 } | 1807 } |
1839 | 1808 |
1840 } // namespace bin | 1809 } // namespace bin |
1841 } // namespace dart | 1810 } // namespace dart |
1842 | 1811 |
1843 #endif // defined(TARGET_OS_MACOS) && !TARGET_OS_IOS | 1812 #endif // defined(TARGET_OS_MACOS) && !TARGET_OS_IOS |
1844 | 1813 |
1845 #endif // !defined(DART_IO_DISABLED) && | 1814 #endif // !defined(DART_IO_DISABLED) && |
1846 // !defined(DART_IO_SECURE_SOCKET_DISABLED) | 1815 // !defined(DART_IO_SECURE_SOCKET_DISABLED) |
OLD | NEW |