| 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_IOS_H_ |
| 6 #define BIN_SECURE_SOCKET_MACOS_H_ | 6 #define BIN_SECURE_SOCKET_IOS_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 trusted_certs_(NULL), |
| 42 identity_(NULL), |
| 43 cert_chain_(NULL), |
| 44 trust_builtin_(false) {} |
| 45 |
| 46 ~SSLCertContext() { |
| 47 delete mutex_; |
| 48 if (trusted_certs_ != NULL) { |
| 49 CFRelease(trusted_certs_); |
| 50 } |
| 51 if (identity_ != NULL) { |
| 52 CFRelease(identity_); |
| 53 } |
| 54 if (cert_chain_ != NULL) { |
| 55 CFRelease(cert_chain_); |
| 56 } |
| 57 } |
| 58 |
| 59 CFMutableArrayRef trusted_certs() { |
| 60 MutexLocker m(mutex_); |
| 61 return trusted_certs_; |
| 62 } |
| 63 void add_trusted_cert(SecCertificateRef trusted_cert) { |
| 64 // Takes ownership of trusted_cert. |
| 65 MutexLocker m(mutex_); |
| 66 if (trusted_certs_ == NULL) { |
| 67 trusted_certs_ = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); |
| 68 } |
| 69 CFArrayAppendValue(trusted_certs_, trusted_cert); |
| 70 CFRelease(trusted_cert); // trusted_cert is retained by the array. |
| 71 } |
| 72 |
| 73 SecIdentityRef identity() { |
| 74 MutexLocker m(mutex_); |
| 75 return identity_; |
| 76 } |
| 77 bool set_identity(SecIdentityRef identity) { |
| 78 MutexLocker m(mutex_); |
| 79 if (identity_ == NULL) { |
| 80 identity_ = identity; |
| 81 return true; |
| 82 } |
| 83 return false; |
| 84 } |
| 85 |
| 86 CFArrayRef cert_chain() { |
| 87 MutexLocker m(mutex_); |
| 88 return cert_chain_; |
| 89 } |
| 90 bool set_cert_chain(CFArrayRef cert_chain) { |
| 91 MutexLocker m(mutex_); |
| 92 if (cert_chain_ == NULL) { |
| 93 cert_chain_ = cert_chain; |
| 94 return true; |
| 95 } |
| 96 return false; |
| 97 } |
| 98 |
| 99 bool trust_builtin() { |
| 100 MutexLocker m(mutex_); |
| 101 return trust_builtin_; |
| 102 } |
| 103 void set_trust_builtin(bool trust_builtin) { |
| 104 MutexLocker m(mutex_); |
| 105 trust_builtin_ = trust_builtin; |
| 106 } |
| 107 |
| 108 private: |
| 109 // The context is accessed both by Dart code and the IOService. This mutex |
| 110 // protects all fields. |
| 111 Mutex* mutex_; |
| 112 CFMutableArrayRef trusted_certs_; |
| 113 SecIdentityRef identity_; |
| 114 CFArrayRef cert_chain_; |
| 115 bool trust_builtin_; |
| 116 |
| 117 DISALLOW_COPY_AND_ASSIGN(SSLCertContext); |
| 118 }; |
| 32 | 119 |
| 33 // SSLFilter encapsulates the SecureTransport code in a filter that communicates | 120 // SSLFilter encapsulates the SecureTransport code in a filter that communicates |
| 34 // with the containing _SecureFilterImpl Dart object through four shared | 121 // with the containing _SecureFilterImpl Dart object through four shared |
| 35 // ExternalByteArray buffers, for reading and writing plaintext, and | 122 // ExternalByteArray buffers, for reading and writing plaintext, and |
| 36 // reading and writing encrypted text. The filter handles handshaking | 123 // reading and writing encrypted text. The filter handles handshaking |
| 37 // and certificate verification. | 124 // and certificate verification. |
| 38 class SSLFilter { | 125 class SSLFilter : public ReferenceCounted<SSLFilter> { |
| 39 public: | 126 public: |
| 40 // These enums must agree with those in sdk/lib/io/secure_socket.dart. | 127 // These enums must agree with those in sdk/lib/io/secure_socket.dart. |
| 41 enum BufferIndex { | 128 enum BufferIndex { |
| 42 kReadPlaintext, | 129 kReadPlaintext, |
| 43 kWritePlaintext, | 130 kWritePlaintext, |
| 44 kReadEncrypted, | 131 kReadEncrypted, |
| 45 kWriteEncrypted, | 132 kWriteEncrypted, |
| 46 kNumBuffers, | 133 kNumBuffers, |
| 47 kFirstEncrypted = kReadEncrypted | 134 kFirstEncrypted = kReadEncrypted |
| 48 }; | 135 }; |
| 49 | 136 |
| 50 SSLFilter() | 137 SSLFilter() |
| 51 : cert_context_(NULL), | 138 : ReferenceCounted(), |
| 139 cert_context_(NULL), |
| 52 ssl_context_(NULL), | 140 ssl_context_(NULL), |
| 53 peer_certs_(NULL), | 141 peer_certs_(NULL), |
| 54 string_start_(NULL), | 142 string_start_(NULL), |
| 55 string_length_(NULL), | 143 string_length_(NULL), |
| 56 handshake_complete_(NULL), | 144 handshake_complete_(NULL), |
| 57 bad_certificate_callback_(NULL), | 145 bad_certificate_callback_(NULL), |
| 58 in_handshake_(false), | 146 in_handshake_(false), |
| 59 connected_(false), | 147 connected_(false), |
| 60 bad_cert_(false), | 148 bad_cert_(false), |
| 61 is_server_(false), | 149 is_server_(false), |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 OSStatus ProcessWritePlaintextBuffer(intptr_t start, | 198 OSStatus ProcessWritePlaintextBuffer(intptr_t start, |
| 111 intptr_t end, | 199 intptr_t end, |
| 112 intptr_t* bytes_processed); | 200 intptr_t* bytes_processed); |
| 113 | 201 |
| 114 // These calls can block on IO, and should only be invoked from | 202 // These calls can block on IO, and should only be invoked from |
| 115 // from ProcessAllBuffers from ProcessFilterRequest. | 203 // from ProcessAllBuffers from ProcessFilterRequest. |
| 116 OSStatus EvaluatePeerTrust(); | 204 OSStatus EvaluatePeerTrust(); |
| 117 OSStatus Handshake(); | 205 OSStatus Handshake(); |
| 118 Dart_Handle InvokeBadCertCallback(SecCertificateRef peer_cert); | 206 Dart_Handle InvokeBadCertCallback(SecCertificateRef peer_cert); |
| 119 | 207 |
| 120 SSLCertContext* cert_context_; | 208 RetainedPointer<SSLCertContext> cert_context_; |
| 121 SSLContextRef ssl_context_; | 209 SSLContextRef ssl_context_; |
| 122 CFArrayRef peer_certs_; | 210 CFArrayRef peer_certs_; |
| 123 | 211 |
| 124 // starts and ends filled in at the start of ProcessAllBuffers. | 212 // starts and ends filled in at the start of ProcessAllBuffers. |
| 125 // If these are NULL, then try to get the pointers out of | 213 // If these are NULL, then try to get the pointers out of |
| 126 // dart_buffer_objects_. | 214 // dart_buffer_objects_. |
| 127 uint8_t* buffers_[kNumBuffers]; | 215 uint8_t* buffers_[kNumBuffers]; |
| 128 intptr_t* buffer_starts_[kNumBuffers]; | 216 intptr_t* buffer_starts_[kNumBuffers]; |
| 129 intptr_t* buffer_ends_[kNumBuffers]; | 217 intptr_t* buffer_ends_[kNumBuffers]; |
| 130 intptr_t buffer_size_; | 218 intptr_t buffer_size_; |
| 131 intptr_t encrypted_buffer_size_; | 219 intptr_t encrypted_buffer_size_; |
| 132 Dart_PersistentHandle string_start_; | 220 Dart_PersistentHandle string_start_; |
| 133 Dart_PersistentHandle string_length_; | 221 Dart_PersistentHandle string_length_; |
| 134 Dart_PersistentHandle dart_buffer_objects_[kNumBuffers]; | 222 Dart_PersistentHandle dart_buffer_objects_[kNumBuffers]; |
| 135 Dart_PersistentHandle handshake_complete_; | 223 Dart_PersistentHandle handshake_complete_; |
| 136 Dart_PersistentHandle bad_certificate_callback_; | 224 Dart_PersistentHandle bad_certificate_callback_; |
| 137 bool in_handshake_; | 225 bool in_handshake_; |
| 138 bool connected_; | 226 bool connected_; |
| 139 bool bad_cert_; | 227 bool bad_cert_; |
| 140 bool is_server_; | 228 bool is_server_; |
| 141 char* hostname_; | 229 char* hostname_; |
| 142 | 230 |
| 143 DISALLOW_COPY_AND_ASSIGN(SSLFilter); | 231 DISALLOW_COPY_AND_ASSIGN(SSLFilter); |
| 144 }; | 232 }; |
| 145 | 233 |
| 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 | 234 } // namespace bin |
| 205 } // namespace dart | 235 } // namespace dart |
| 206 | 236 |
| 207 #endif // BIN_SECURE_SOCKET_MACOS_H_ | 237 #endif // BIN_SECURE_SOCKET_IOS_H_ |
| OLD | NEW |