| 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 25 matching lines...) Expand all Loading... |
| 36 | 36 |
| 37 // Return the error from the containing function if handle is an error handle. | 37 // Return the error from the containing function if handle is an error handle. |
| 38 #define RETURN_IF_ERROR(handle) \ | 38 #define RETURN_IF_ERROR(handle) \ |
| 39 { \ | 39 { \ |
| 40 Dart_Handle __handle = handle; \ | 40 Dart_Handle __handle = handle; \ |
| 41 if (Dart_IsError((__handle))) { \ | 41 if (Dart_IsError((__handle))) { \ |
| 42 return __handle; \ | 42 return __handle; \ |
| 43 } \ | 43 } \ |
| 44 } | 44 } |
| 45 | 45 |
| 46 // We need to access this private API function to create a SecIdentityRef | |
| 47 // without writing a custom keychain to the filesystem. This is the approach | |
| 48 // taken in WebKit: | |
| 49 // https://webkit.googlesource.com/WebKit/+/master/Source/WebKit2/Shared/cf/Argu
mentCodersCF.cpp | |
| 50 extern "C" { | |
| 51 SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator, | |
| 52 SecCertificateRef certificate, | |
| 53 SecKeyRef private_key); | |
| 54 } | |
| 55 | |
| 56 namespace dart { | 46 namespace dart { |
| 57 namespace bin { | 47 namespace bin { |
| 58 | 48 |
| 59 static const int kSSLFilterNativeFieldIndex = 0; | 49 static const int kSSLFilterNativeFieldIndex = 0; |
| 60 static const int kSecurityContextNativeFieldIndex = 0; | 50 static const int kSecurityContextNativeFieldIndex = 0; |
| 61 static const int kX509NativeFieldIndex = 0; | 51 static const int kX509NativeFieldIndex = 0; |
| 62 | 52 |
| 63 static const bool SSL_LOG_STATUS = false; | 53 static const bool SSL_LOG_STATUS = false; |
| 64 static const bool SSL_LOG_DATA = false; | 54 static const bool SSL_LOG_DATA = false; |
| 65 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000; | 55 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000; |
| 66 | 56 |
| 67 // SSLCertContext wraps the certificates needed for a SecureTransport | 57 // SSLCertContext wraps the certificates needed for a SecureTransport |
| 68 // connection. Fields are protected by the mutex_ field, and may only be set | 58 // connection. Fields are protected by the mutex_ field, and may only be set |
| 69 // once. This is to allow access by both the Dart thread and the IOService | 59 // once. This is to allow access by both the Dart thread and the IOService |
| 70 // thread. Setters return false if the field was already set. | 60 // thread. Setters return false if the field was already set. |
| 71 class SSLCertContext { | 61 class SSLCertContext { |
| 72 public: | 62 public: |
| 73 SSLCertContext() : | 63 SSLCertContext() : |
| 74 mutex_(new Mutex()), | 64 mutex_(new Mutex()), |
| 65 trusted_certs_(NULL), |
| 75 trust_builtin_(false) {} | 66 trust_builtin_(false) {} |
| 76 | 67 |
| 77 ~SSLCertContext() { | 68 ~SSLCertContext() { |
| 78 delete mutex_; | 69 delete mutex_; |
| 70 if (trusted_certs_ != NULL) { |
| 71 CFRelease(trusted_certs_); |
| 72 } |
| 73 } |
| 74 |
| 75 CFMutableArrayRef trusted_certs() { |
| 76 MutexLocker m(mutex_); |
| 77 return trusted_certs_; |
| 78 } |
| 79 void add_trusted_cert(SecCertificateRef trusted_cert) { |
| 80 // Takes ownership of trusted_cert. |
| 81 MutexLocker m(mutex_); |
| 82 if (trusted_certs_ == NULL) { |
| 83 trusted_certs_ = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); |
| 84 } |
| 85 CFArrayAppendValue(trusted_certs_, trusted_cert); |
| 86 CFRelease(trusted_cert); // trusted_cert is retained by the array. |
| 79 } | 87 } |
| 80 | 88 |
| 81 bool trust_builtin() { | 89 bool trust_builtin() { |
| 82 MutexLocker m(mutex_); | 90 MutexLocker m(mutex_); |
| 83 return trust_builtin_; | 91 return trust_builtin_; |
| 84 } | 92 } |
| 85 void set_trust_builtin(bool trust_builtin) { | 93 void set_trust_builtin(bool trust_builtin) { |
| 86 MutexLocker m(mutex_); | 94 MutexLocker m(mutex_); |
| 87 trust_builtin_ = trust_builtin; | 95 trust_builtin_ = trust_builtin; |
| 88 } | 96 } |
| 89 | 97 |
| 90 private: | 98 private: |
| 91 // The context is accessed both by Dart code and the IOService. This mutex | 99 // The context is accessed both by Dart code and the IOService. This mutex |
| 92 // protects all fields. | 100 // protects all fields. |
| 93 Mutex* mutex_; | 101 Mutex* mutex_; |
| 102 CFMutableArrayRef trusted_certs_; |
| 94 bool trust_builtin_; | 103 bool trust_builtin_; |
| 95 | 104 |
| 96 DISALLOW_COPY_AND_ASSIGN(SSLCertContext); | 105 DISALLOW_COPY_AND_ASSIGN(SSLCertContext); |
| 97 }; | 106 }; |
| 98 | 107 |
| 99 // Handle an error reported from the SecureTransport library. | 108 // Handle an error reported from the SecureTransport library. |
| 100 static void ThrowIOException(OSStatus status, | 109 static void ThrowIOException(OSStatus status, |
| 101 const char* exception_type, | 110 const char* exception_type, |
| 102 const char* message) { | 111 const char* message) { |
| 103 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); | 112 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 | 390 |
| 382 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( | 391 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( |
| 383 Dart_NativeArguments args) { | 392 Dart_NativeArguments args) { |
| 384 Dart_ThrowException(DartUtils::NewDartUnsupportedError( | 393 Dart_ThrowException(DartUtils::NewDartUnsupportedError( |
| 385 "SecurityContext.usePrivateKeyBytes is not yet implemented.")); | 394 "SecurityContext.usePrivateKeyBytes is not yet implemented.")); |
| 386 } | 395 } |
| 387 | 396 |
| 388 | 397 |
| 389 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( | 398 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( |
| 390 Dart_NativeArguments args) { | 399 Dart_NativeArguments args) { |
| 391 Dart_ThrowException(DartUtils::NewDartUnsupportedError( | 400 SSLCertContext* context = GetSecurityContext(args); |
| 392 "SecurityContext.setTrustedCertificatesBytes is not yet implemented.")); | 401 |
| 402 OSStatus status = noErr; |
| 403 SecCertificateRef cert = NULL; |
| 404 { |
| 405 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1))); |
| 406 CFDataRef cfdata = CFDataCreateWithBytesNoCopy( |
| 407 NULL, buffer.get(), buffer.length(), kCFAllocatorNull); |
| 408 cert = SecCertificateCreateWithData(NULL, cfdata); |
| 409 CFRelease(cfdata); |
| 410 } |
| 411 |
| 412 // Add the certs to the context. |
| 413 if (cert != NULL) { |
| 414 context->add_trusted_cert(cert); |
| 415 } else { |
| 416 status = errSSLBadCert; |
| 417 } |
| 418 CheckStatus(status, "TlsException", "Failure in setTrustedCertificatesBytes"); |
| 393 } | 419 } |
| 394 | 420 |
| 395 | 421 |
| 396 void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) { | 422 void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) { |
| 397 Dart_SetReturnValue(args, Dart_NewBoolean(false)); | 423 Dart_SetReturnValue(args, Dart_NewBoolean(false)); |
| 398 } | 424 } |
| 399 | 425 |
| 400 | 426 |
| 401 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( | 427 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( |
| 402 Dart_NativeArguments args) { | 428 Dart_NativeArguments args) { |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 // A client certificate was requested, but not required, and wasn't sent. | 917 // A client certificate was requested, but not required, and wasn't sent. |
| 892 return noErr; | 918 return noErr; |
| 893 } | 919 } |
| 894 if (SSL_LOG_STATUS) { | 920 if (SSL_LOG_STATUS) { |
| 895 Log::Print("Handshake error from SSLCopyPeerTrust(): %ld.\n", | 921 Log::Print("Handshake error from SSLCopyPeerTrust(): %ld.\n", |
| 896 static_cast<intptr_t>(status)); | 922 static_cast<intptr_t>(status)); |
| 897 } | 923 } |
| 898 return status; | 924 return status; |
| 899 } | 925 } |
| 900 | 926 |
| 901 CFArrayRef trusted_certs = | 927 CFArrayRef trusted_certs = NULL; |
| 902 CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); | 928 if (cert_context_->trusted_certs() != NULL) { |
| 929 trusted_certs = CFArrayCreateCopy(NULL, cert_context_->trusted_certs()); |
| 930 } else { |
| 931 trusted_certs = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); |
| 932 } |
| 903 | 933 |
| 904 status = SecTrustSetAnchorCertificates(peer_trust, trusted_certs); | 934 status = SecTrustSetAnchorCertificates(peer_trust, trusted_certs); |
| 905 if (status != noErr) { | 935 if (status != noErr) { |
| 906 if (SSL_LOG_STATUS) { | 936 if (SSL_LOG_STATUS) { |
| 907 Log::Print("Handshake error from SecTrustSetAnchorCertificates: %ld\n", | 937 Log::Print("Handshake error from SecTrustSetAnchorCertificates: %ld\n", |
| 908 static_cast<intptr_t>(status)); | 938 static_cast<intptr_t>(status)); |
| 909 } | 939 } |
| 910 CFRelease(trusted_certs); | 940 CFRelease(trusted_certs); |
| 911 CFRelease(peer_trust); | 941 CFRelease(peer_trust); |
| 912 return status; | 942 return status; |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1301 *bytes_processed = static_cast<intptr_t>(bytes); | 1331 *bytes_processed = static_cast<intptr_t>(bytes); |
| 1302 return status; | 1332 return status; |
| 1303 } | 1333 } |
| 1304 | 1334 |
| 1305 } // namespace bin | 1335 } // namespace bin |
| 1306 } // namespace dart | 1336 } // namespace dart |
| 1307 | 1337 |
| 1308 #endif // TARGET_OS_IOS | 1338 #endif // TARGET_OS_IOS |
| 1309 | 1339 |
| 1310 #endif // !defined(DART_IO_SECURE_SOCKET_DISABLED) | 1340 #endif // !defined(DART_IO_SECURE_SOCKET_DISABLED) |
| OLD | NEW |