Chromium Code Reviews| Index: runtime/bin/secure_socket_ios.h |
| diff --git a/runtime/bin/secure_socket_macos.h b/runtime/bin/secure_socket_ios.h |
| similarity index 64% |
| copy from runtime/bin/secure_socket_macos.h |
| copy to runtime/bin/secure_socket_ios.h |
| index c088d8c7e84d8730a3a2850a7069b4e9510d5379..b0cb4443848f75c82187808ce16ec99320908e2e 100644 |
| --- a/runtime/bin/secure_socket_macos.h |
| +++ b/runtime/bin/secure_socket_ios.h |
| @@ -2,8 +2,8 @@ |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| -#ifndef BIN_SECURE_SOCKET_MACOS_H_ |
| -#define BIN_SECURE_SOCKET_MACOS_H_ |
| +#ifndef BIN_SECURE_SOCKET_IOS_H_ |
| +#define BIN_SECURE_SOCKET_IOS_H_ |
| #if !defined(BIN_SECURE_SOCKET_H_) |
| #error Do not include secure_socket_macos.h directly. Use secure_socket.h. |
| @@ -20,6 +20,8 @@ |
| #include "bin/builtin.h" |
| #include "bin/dartutils.h" |
| +#include "bin/lockers.h" |
| +#include "bin/reference_counting.h" |
| #include "bin/socket.h" |
| #include "bin/thread.h" |
| #include "bin/utils.h" |
| @@ -27,15 +29,100 @@ |
| namespace dart { |
| namespace bin { |
| -// Forward declaration of SSLContext. |
| -class SSLCertContext; |
| +// SSLCertContext wraps the certificates needed for a SecureTransport |
| +// connection. Fields are protected by the mutex_ field, and may only be set |
| +// once. This is to allow access by both the Dart thread and the IOService |
| +// thread. Setters return false if the field was already set. |
| +class SSLCertContext : public ReferenceCounted<SSLCertContext> { |
| + public: |
| + SSLCertContext() : |
| + ReferenceCounted(), |
| + mutex_(new Mutex()), |
| + trusted_certs_(NULL), |
| + identity_(NULL), |
| + cert_chain_(NULL), |
| + trust_builtin_(false) {} |
| + |
| + ~SSLCertContext() { |
| + delete mutex_; |
|
siva
2016/04/12 19:03:01
Should we delete this mutex at the end of the cons
zra
2016/04/13 16:46:21
Done.
|
| + if (trusted_certs_ != NULL) { |
| + CFRelease(trusted_certs_); |
| + } |
| + if (identity_ != NULL) { |
| + CFRelease(identity_); |
| + } |
| + if (cert_chain_ != NULL) { |
| + CFRelease(cert_chain_); |
| + } |
| + } |
| + |
| + CFMutableArrayRef trusted_certs() { |
| + MutexLocker m(mutex_); |
| + return trusted_certs_; |
| + } |
| + void add_trusted_cert(SecCertificateRef trusted_cert) { |
| + // Takes ownership of trusted_cert. |
| + MutexLocker m(mutex_); |
| + if (trusted_certs_ == NULL) { |
| + trusted_certs_ = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); |
| + } |
| + CFArrayAppendValue(trusted_certs_, trusted_cert); |
| + CFRelease(trusted_cert); // trusted_cert is retained by the array. |
| + } |
| + |
| + SecIdentityRef identity() { |
| + MutexLocker m(mutex_); |
| + return identity_; |
| + } |
| + bool set_identity(SecIdentityRef identity) { |
| + MutexLocker m(mutex_); |
| + if (identity_ == NULL) { |
| + identity_ = identity; |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + CFArrayRef cert_chain() { |
| + MutexLocker m(mutex_); |
| + return cert_chain_; |
| + } |
| + bool set_cert_chain(CFArrayRef cert_chain) { |
| + MutexLocker m(mutex_); |
| + if (cert_chain_ == NULL) { |
| + cert_chain_ = cert_chain; |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + bool trust_builtin() { |
| + MutexLocker m(mutex_); |
| + return trust_builtin_; |
| + } |
| + void set_trust_builtin(bool trust_builtin) { |
| + MutexLocker m(mutex_); |
| + trust_builtin_ = trust_builtin; |
| + } |
| + |
| + private: |
| + // The context is accessed both by Dart code and the IOService. This mutex |
| + // protects all fields. |
| + Mutex* mutex_; |
| + CFMutableArrayRef trusted_certs_; |
| + SecIdentityRef identity_; |
| + CFArrayRef cert_chain_; |
| + bool trust_builtin_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(SSLCertContext); |
| +}; |
| // SSLFilter encapsulates the SecureTransport code in a filter that communicates |
| // with the containing _SecureFilterImpl Dart object through four shared |
| // ExternalByteArray buffers, for reading and writing plaintext, and |
| // reading and writing encrypted text. The filter handles handshaking |
| // and certificate verification. |
| -class SSLFilter { |
| +class SSLFilter : public ReferenceCounted<SSLFilter> { |
| public: |
| // These enums must agree with those in sdk/lib/io/secure_socket.dart. |
| enum BufferIndex { |
| @@ -48,7 +135,8 @@ class SSLFilter { |
| }; |
| SSLFilter() |
| - : cert_context_(NULL), |
| + : ReferenceCounted(), |
| + cert_context_(NULL), |
| ssl_context_(NULL), |
| peer_certs_(NULL), |
| string_start_(NULL), |
| @@ -117,7 +205,7 @@ class SSLFilter { |
| OSStatus Handshake(); |
| Dart_Handle InvokeBadCertCallback(SecCertificateRef peer_cert); |
| - SSLCertContext* cert_context_; |
| + RetainedPointer<SSLCertContext> cert_context_; |
| SSLContextRef ssl_context_; |
| CFArrayRef peer_certs_; |
| @@ -143,65 +231,7 @@ class SSLFilter { |
| DISALLOW_COPY_AND_ASSIGN(SSLFilter); |
| }; |
| -// Where the argument to the constructor is the handle for an object |
| -// implementing List<int>, this class creates a scope in which the memory |
| -// backing the list can be accessed. |
| -// |
| -// Do not make Dart_ API calls while in a ScopedMemBuffer. |
| -// Do not call Dart_PropagateError while in a ScopedMemBuffer. |
| -class ScopedMemBuffer { |
| - public: |
| - explicit ScopedMemBuffer(Dart_Handle object) { |
| - if (!Dart_IsTypedData(object) && !Dart_IsList(object)) { |
| - Dart_ThrowException(DartUtils::NewDartArgumentError( |
| - "Argument is not a List<int>")); |
| - } |
| - |
| - uint8_t* bytes = NULL; |
| - intptr_t bytes_len = 0; |
| - bool is_typed_data = false; |
| - if (Dart_IsTypedData(object)) { |
| - is_typed_data = true; |
| - Dart_TypedData_Type typ; |
| - ThrowIfError(Dart_TypedDataAcquireData( |
| - object, |
| - &typ, |
| - reinterpret_cast<void**>(&bytes), |
| - &bytes_len)); |
| - } else { |
| - ASSERT(Dart_IsList(object)); |
| - ThrowIfError(Dart_ListLength(object, &bytes_len)); |
| - bytes = Dart_ScopeAllocate(bytes_len); |
| - ASSERT(bytes != NULL); |
| - ThrowIfError(Dart_ListGetAsBytes(object, 0, bytes, bytes_len)); |
| - } |
| - |
| - object_ = object; |
| - bytes_ = bytes; |
| - bytes_len_ = bytes_len; |
| - is_typed_data_ = is_typed_data; |
| - } |
| - |
| - ~ScopedMemBuffer() { |
| - if (is_typed_data_) { |
| - ThrowIfError(Dart_TypedDataReleaseData(object_)); |
| - } |
| - } |
| - |
| - uint8_t* get() const { return bytes_; } |
| - intptr_t length() const { return bytes_len_; } |
| - |
| - private: |
| - Dart_Handle object_; |
| - uint8_t* bytes_; |
| - intptr_t bytes_len_; |
| - bool is_typed_data_; |
| - |
| - DISALLOW_ALLOCATION(); |
| - DISALLOW_COPY_AND_ASSIGN(ScopedMemBuffer); |
| -}; |
| - |
| } // namespace bin |
| } // namespace dart |
| -#endif // BIN_SECURE_SOCKET_MACOS_H_ |
| +#endif // BIN_SECURE_SOCKET_IOS_H_ |