| 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 |