| 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 #ifndef BIN_SECURE_SOCKET_MACOS_H_ | 5 #ifndef BIN_SECURE_SOCKET_MACOS_H_ |
| 6 #define BIN_SECURE_SOCKET_MACOS_H_ | 6 #define BIN_SECURE_SOCKET_MACOS_H_ |
| 7 | 7 |
| 8 #if !defined(BIN_SECURE_SOCKET_H_) | 8 #if !defined(BIN_SECURE_SOCKET_H_) |
| 9 #error Do not include secure_socket_macos.h directly. Use secure_socket.h. | 9 #error Do not include secure_socket_macos.h directly. Use secure_socket.h. |
| 10 #endif | 10 #endif |
| 11 | 11 |
| 12 #include <stdlib.h> | 12 #include <stdlib.h> |
| 13 #include <string.h> | 13 #include <string.h> |
| 14 #include <stdio.h> | 14 #include <stdio.h> |
| 15 #include <sys/types.h> | 15 #include <sys/types.h> |
| 16 | 16 |
| 17 #include <CoreFoundation/CoreFoundation.h> | 17 #include <CoreFoundation/CoreFoundation.h> |
| 18 #include <Security/SecureTransport.h> | 18 #include <Security/SecureTransport.h> |
| 19 #include <Security/Security.h> | 19 #include <Security/Security.h> |
| 20 | 20 |
| 21 #include "bin/builtin.h" | 21 #include "bin/builtin.h" |
| 22 #include "bin/dartutils.h" | 22 #include "bin/dartutils.h" |
| 23 #include "bin/lockers.h" |
| 24 #include "bin/reference_counting.h" |
| 23 #include "bin/socket.h" | 25 #include "bin/socket.h" |
| 24 #include "bin/thread.h" | 26 #include "bin/thread.h" |
| 25 #include "bin/utils.h" | 27 #include "bin/utils.h" |
| 26 | 28 |
| 27 namespace dart { | 29 namespace dart { |
| 28 namespace bin { | 30 namespace bin { |
| 29 | 31 |
| 30 // Forward declaration of SSLContext. | 32 // SSLCertContext wraps the certificates needed for a SecureTransport |
| 31 class SSLCertContext; | 33 // connection. Fields are protected by the mutex_ field, and may only be set |
| 34 // once. This is to allow access by both the Dart thread and the IOService |
| 35 // thread. Setters return false if the field was already set. |
| 36 class SSLCertContext : public ReferenceCounted<SSLCertContext> { |
| 37 public: |
| 38 SSLCertContext() : |
| 39 ReferenceCounted(), |
| 40 mutex_(new Mutex()), |
| 41 private_key_(NULL), |
| 42 keychain_(NULL), |
| 43 cert_chain_(NULL), |
| 44 trusted_certs_(NULL), |
| 45 cert_authorities_(NULL), |
| 46 trust_builtin_(false) { |
| 47 } |
| 48 |
| 49 ~SSLCertContext() { |
| 50 { |
| 51 MutexLocker m(mutex_); |
| 52 if (private_key_ != NULL) { |
| 53 CFRelease(private_key_); |
| 54 } |
| 55 if (keychain_ != NULL) { |
| 56 SecKeychainDelete(keychain_); |
| 57 CFRelease(keychain_); |
| 58 } |
| 59 if (cert_chain_ != NULL) { |
| 60 CFRelease(cert_chain_); |
| 61 } |
| 62 if (trusted_certs_ != NULL) { |
| 63 CFRelease(trusted_certs_); |
| 64 } |
| 65 if (cert_authorities_ != NULL) { |
| 66 CFRelease(cert_authorities_); |
| 67 } |
| 68 } |
| 69 delete mutex_; |
| 70 } |
| 71 |
| 72 SecKeyRef private_key() { |
| 73 MutexLocker m(mutex_); |
| 74 return private_key_; |
| 75 } |
| 76 bool set_private_key(SecKeyRef private_key) { |
| 77 MutexLocker m(mutex_); |
| 78 if (private_key_ != NULL) { |
| 79 return false; |
| 80 } |
| 81 private_key_ = private_key; |
| 82 return true; |
| 83 } |
| 84 |
| 85 SecKeychainRef keychain() { |
| 86 MutexLocker m(mutex_); |
| 87 return keychain_; |
| 88 } |
| 89 bool set_keychain(SecKeychainRef keychain) { |
| 90 MutexLocker m(mutex_); |
| 91 if (keychain_ != NULL) { |
| 92 return false; |
| 93 } |
| 94 keychain_ = keychain; |
| 95 return true; |
| 96 } |
| 97 |
| 98 CFArrayRef cert_chain() { |
| 99 MutexLocker m(mutex_); |
| 100 return cert_chain_; |
| 101 } |
| 102 bool set_cert_chain(CFArrayRef cert_chain) { |
| 103 MutexLocker m(mutex_); |
| 104 if (cert_chain_ != NULL) { |
| 105 return false; |
| 106 } |
| 107 cert_chain_ = cert_chain; |
| 108 return true; |
| 109 } |
| 110 |
| 111 CFArrayRef trusted_certs() { |
| 112 MutexLocker m(mutex_); |
| 113 return trusted_certs_; |
| 114 } |
| 115 bool set_trusted_certs(CFArrayRef trusted_certs) { |
| 116 MutexLocker m(mutex_); |
| 117 if (trusted_certs_ != NULL) { |
| 118 return false; |
| 119 } |
| 120 trusted_certs_ = trusted_certs; |
| 121 return true; |
| 122 } |
| 123 |
| 124 CFArrayRef cert_authorities() { |
| 125 MutexLocker m(mutex_); |
| 126 return cert_authorities_; |
| 127 } |
| 128 bool set_cert_authorities(CFArrayRef cert_authorities) { |
| 129 MutexLocker m(mutex_); |
| 130 if (cert_authorities_ != NULL) { |
| 131 return false; |
| 132 } |
| 133 cert_authorities_ = cert_authorities; |
| 134 return true; |
| 135 } |
| 136 |
| 137 bool trust_builtin() { |
| 138 MutexLocker m(mutex_); |
| 139 return trust_builtin_; |
| 140 } |
| 141 void set_trust_builtin(bool trust_builtin) { |
| 142 MutexLocker m(mutex_); |
| 143 trust_builtin_ = trust_builtin; |
| 144 } |
| 145 |
| 146 private: |
| 147 // The context is accessed both by Dart code and the IOService. This mutex |
| 148 // protects all fields. |
| 149 Mutex* mutex_; |
| 150 |
| 151 SecKeyRef private_key_; |
| 152 SecKeychainRef keychain_; |
| 153 |
| 154 // CFArrays of SecCertificateRef. |
| 155 CFArrayRef cert_chain_; |
| 156 CFArrayRef trusted_certs_; |
| 157 CFArrayRef cert_authorities_; |
| 158 |
| 159 bool trust_builtin_; |
| 160 |
| 161 DISALLOW_COPY_AND_ASSIGN(SSLCertContext); |
| 162 }; |
| 32 | 163 |
| 33 // SSLFilter encapsulates the SecureTransport code in a filter that communicates | 164 // SSLFilter encapsulates the SecureTransport code in a filter that communicates |
| 34 // with the containing _SecureFilterImpl Dart object through four shared | 165 // with the containing _SecureFilterImpl Dart object through four shared |
| 35 // ExternalByteArray buffers, for reading and writing plaintext, and | 166 // ExternalByteArray buffers, for reading and writing plaintext, and |
| 36 // reading and writing encrypted text. The filter handles handshaking | 167 // reading and writing encrypted text. The filter handles handshaking |
| 37 // and certificate verification. | 168 // and certificate verification. |
| 38 class SSLFilter { | 169 class SSLFilter : public ReferenceCounted<SSLFilter> { |
| 39 public: | 170 public: |
| 40 // These enums must agree with those in sdk/lib/io/secure_socket.dart. | 171 // These enums must agree with those in sdk/lib/io/secure_socket.dart. |
| 41 enum BufferIndex { | 172 enum BufferIndex { |
| 42 kReadPlaintext, | 173 kReadPlaintext, |
| 43 kWritePlaintext, | 174 kWritePlaintext, |
| 44 kReadEncrypted, | 175 kReadEncrypted, |
| 45 kWriteEncrypted, | 176 kWriteEncrypted, |
| 46 kNumBuffers, | 177 kNumBuffers, |
| 47 kFirstEncrypted = kReadEncrypted | 178 kFirstEncrypted = kReadEncrypted |
| 48 }; | 179 }; |
| 49 | 180 |
| 50 SSLFilter() | 181 SSLFilter() |
| 51 : cert_context_(NULL), | 182 : ReferenceCounted(), |
| 183 cert_context_(NULL), |
| 52 ssl_context_(NULL), | 184 ssl_context_(NULL), |
| 53 peer_certs_(NULL), | 185 peer_certs_(NULL), |
| 54 string_start_(NULL), | 186 string_start_(NULL), |
| 55 string_length_(NULL), | 187 string_length_(NULL), |
| 56 handshake_complete_(NULL), | 188 handshake_complete_(NULL), |
| 57 bad_certificate_callback_(NULL), | 189 bad_certificate_callback_(NULL), |
| 58 in_handshake_(false), | 190 in_handshake_(false), |
| 59 connected_(false), | 191 connected_(false), |
| 60 bad_cert_(false), | 192 bad_cert_(false), |
| 61 is_server_(false), | 193 is_server_(false), |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 OSStatus ProcessWritePlaintextBuffer(intptr_t start, | 242 OSStatus ProcessWritePlaintextBuffer(intptr_t start, |
| 111 intptr_t end, | 243 intptr_t end, |
| 112 intptr_t* bytes_processed); | 244 intptr_t* bytes_processed); |
| 113 | 245 |
| 114 // These calls can block on IO, and should only be invoked from | 246 // These calls can block on IO, and should only be invoked from |
| 115 // from ProcessAllBuffers from ProcessFilterRequest. | 247 // from ProcessAllBuffers from ProcessFilterRequest. |
| 116 OSStatus EvaluatePeerTrust(); | 248 OSStatus EvaluatePeerTrust(); |
| 117 OSStatus Handshake(); | 249 OSStatus Handshake(); |
| 118 Dart_Handle InvokeBadCertCallback(SecCertificateRef peer_cert); | 250 Dart_Handle InvokeBadCertCallback(SecCertificateRef peer_cert); |
| 119 | 251 |
| 120 SSLCertContext* cert_context_; | 252 RetainedPointer<SSLCertContext> cert_context_; |
| 121 SSLContextRef ssl_context_; | 253 SSLContextRef ssl_context_; |
| 122 CFArrayRef peer_certs_; | 254 CFArrayRef peer_certs_; |
| 123 | 255 |
| 124 // starts and ends filled in at the start of ProcessAllBuffers. | 256 // starts and ends filled in at the start of ProcessAllBuffers. |
| 125 // If these are NULL, then try to get the pointers out of | 257 // If these are NULL, then try to get the pointers out of |
| 126 // dart_buffer_objects_. | 258 // dart_buffer_objects_. |
| 127 uint8_t* buffers_[kNumBuffers]; | 259 uint8_t* buffers_[kNumBuffers]; |
| 128 intptr_t* buffer_starts_[kNumBuffers]; | 260 intptr_t* buffer_starts_[kNumBuffers]; |
| 129 intptr_t* buffer_ends_[kNumBuffers]; | 261 intptr_t* buffer_ends_[kNumBuffers]; |
| 130 intptr_t buffer_size_; | 262 intptr_t buffer_size_; |
| 131 intptr_t encrypted_buffer_size_; | 263 intptr_t encrypted_buffer_size_; |
| 132 Dart_PersistentHandle string_start_; | 264 Dart_PersistentHandle string_start_; |
| 133 Dart_PersistentHandle string_length_; | 265 Dart_PersistentHandle string_length_; |
| 134 Dart_PersistentHandle dart_buffer_objects_[kNumBuffers]; | 266 Dart_PersistentHandle dart_buffer_objects_[kNumBuffers]; |
| 135 Dart_PersistentHandle handshake_complete_; | 267 Dart_PersistentHandle handshake_complete_; |
| 136 Dart_PersistentHandle bad_certificate_callback_; | 268 Dart_PersistentHandle bad_certificate_callback_; |
| 137 bool in_handshake_; | 269 bool in_handshake_; |
| 138 bool connected_; | 270 bool connected_; |
| 139 bool bad_cert_; | 271 bool bad_cert_; |
| 140 bool is_server_; | 272 bool is_server_; |
| 141 char* hostname_; | 273 char* hostname_; |
| 142 | 274 |
| 143 DISALLOW_COPY_AND_ASSIGN(SSLFilter); | 275 DISALLOW_COPY_AND_ASSIGN(SSLFilter); |
| 144 }; | 276 }; |
| 145 | 277 |
| 146 // Where the argument to the constructor is the handle for an object | |
| 147 // implementing List<int>, this class creates a scope in which the memory | |
| 148 // backing the list can be accessed. | |
| 149 // | |
| 150 // Do not make Dart_ API calls while in a ScopedMemBuffer. | |
| 151 // Do not call Dart_PropagateError while in a ScopedMemBuffer. | |
| 152 class ScopedMemBuffer { | |
| 153 public: | |
| 154 explicit ScopedMemBuffer(Dart_Handle object) { | |
| 155 if (!Dart_IsTypedData(object) && !Dart_IsList(object)) { | |
| 156 Dart_ThrowException(DartUtils::NewDartArgumentError( | |
| 157 "Argument is not a List<int>")); | |
| 158 } | |
| 159 | |
| 160 uint8_t* bytes = NULL; | |
| 161 intptr_t bytes_len = 0; | |
| 162 bool is_typed_data = false; | |
| 163 if (Dart_IsTypedData(object)) { | |
| 164 is_typed_data = true; | |
| 165 Dart_TypedData_Type typ; | |
| 166 ThrowIfError(Dart_TypedDataAcquireData( | |
| 167 object, | |
| 168 &typ, | |
| 169 reinterpret_cast<void**>(&bytes), | |
| 170 &bytes_len)); | |
| 171 } else { | |
| 172 ASSERT(Dart_IsList(object)); | |
| 173 ThrowIfError(Dart_ListLength(object, &bytes_len)); | |
| 174 bytes = Dart_ScopeAllocate(bytes_len); | |
| 175 ASSERT(bytes != NULL); | |
| 176 ThrowIfError(Dart_ListGetAsBytes(object, 0, bytes, bytes_len)); | |
| 177 } | |
| 178 | |
| 179 object_ = object; | |
| 180 bytes_ = bytes; | |
| 181 bytes_len_ = bytes_len; | |
| 182 is_typed_data_ = is_typed_data; | |
| 183 } | |
| 184 | |
| 185 ~ScopedMemBuffer() { | |
| 186 if (is_typed_data_) { | |
| 187 ThrowIfError(Dart_TypedDataReleaseData(object_)); | |
| 188 } | |
| 189 } | |
| 190 | |
| 191 uint8_t* get() const { return bytes_; } | |
| 192 intptr_t length() const { return bytes_len_; } | |
| 193 | |
| 194 private: | |
| 195 Dart_Handle object_; | |
| 196 uint8_t* bytes_; | |
| 197 intptr_t bytes_len_; | |
| 198 bool is_typed_data_; | |
| 199 | |
| 200 DISALLOW_ALLOCATION(); | |
| 201 DISALLOW_COPY_AND_ASSIGN(ScopedMemBuffer); | |
| 202 }; | |
| 203 | |
| 204 } // namespace bin | 278 } // namespace bin |
| 205 } // namespace dart | 279 } // namespace dart |
| 206 | 280 |
| 207 #endif // BIN_SECURE_SOCKET_MACOS_H_ | 281 #endif // BIN_SECURE_SOCKET_MACOS_H_ |
| OLD | NEW |