| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // 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. |
| |
| patch class SecureSocket { |
| /* patch */ factory SecureSocket._(RawSecureSocket rawSocket) => |
| new _SecureSocket(rawSocket); |
| } |
| |
| |
| patch class _SecureFilter { |
| /* patch */ factory _SecureFilter() => new _SecureFilterImpl(); |
| } |
| |
| patch class X509Certificate { |
| /* patch */ factory X509Certificate._() => new _X509CertificateImpl(); |
| } |
| |
| class _SecureSocket extends _Socket implements SecureSocket { |
| _SecureSocket(RawSecureSocket raw) : super(raw); |
| |
| void set onBadCertificate(bool callback(X509Certificate certificate)) { |
| if (_raw == null) { |
| throw new StateError("onBadCertificate called on destroyed SecureSocket"); |
| } |
| _raw.onBadCertificate = callback; |
| } |
| |
| void renegotiate({bool useSessionCache: true, |
| bool requestClientCertificate: false, |
| bool requireClientCertificate: false}) { |
| _raw.renegotiate(useSessionCache: useSessionCache, |
| requestClientCertificate: requestClientCertificate, |
| requireClientCertificate: requireClientCertificate); |
| } |
| |
| X509Certificate get peerCertificate { |
| if (_raw == null) { |
| throw new StateError("peerCertificate called on destroyed SecureSocket"); |
| } |
| return _raw.peerCertificate; |
| } |
| |
| String get selectedProtocol { |
| if (_raw == null) { |
| throw new StateError("selectedProtocol called on destroyed SecureSocket"); |
| } |
| return _raw.selectedProtocol; |
| } |
| } |
| |
| |
| /** |
| * _SecureFilterImpl wraps a filter that encrypts and decrypts data travelling |
| * over an encrypted socket. The filter also handles the handshaking |
| * and certificate verification. |
| * |
| * The filter exposes its input and output buffers as Dart objects that |
| * are backed by an external C array of bytes, so that both Dart code and |
| * native code can access the same data. |
| */ |
| class _SecureFilterImpl |
| extends NativeFieldWrapperClass1 |
| implements _SecureFilter { |
| // Performance is improved if a full buffer of plaintext fits |
| // in the encrypted buffer, when encrypted. |
| static final int SIZE = 8 * 1024; |
| static final int ENCRYPTED_SIZE = 10 * 1024; |
| |
| _SecureFilterImpl() { |
| buffers = new List<_ExternalBuffer>(_RawSecureSocket.NUM_BUFFERS); |
| for (int i = 0; i < _RawSecureSocket.NUM_BUFFERS; ++i) { |
| buffers[i] = new _ExternalBuffer(_RawSecureSocket._isBufferEncrypted(i) ? |
| ENCRYPTED_SIZE : |
| SIZE); |
| } |
| } |
| |
| void connect(String hostName, |
| SecurityContext context, |
| bool is_server, |
| bool requestClientCertificate, |
| bool requireClientCertificate, |
| Uint8List protocols) native "SecureSocket_Connect"; |
| |
| void destroy() { |
| buffers = null; |
| _destroy(); |
| } |
| |
| void _destroy() native "SecureSocket_Destroy"; |
| |
| void handshake() native "SecureSocket_Handshake"; |
| |
| String selectedProtocol() native "SecureSocket_GetSelectedProtocol"; |
| |
| void renegotiate(bool useSessionCache, |
| bool requestClientCertificate, |
| bool requireClientCertificate) |
| native "SecureSocket_Renegotiate"; |
| |
| void init() native "SecureSocket_Init"; |
| |
| X509Certificate get peerCertificate native "SecureSocket_PeerCertificate"; |
| |
| void registerBadCertificateCallback(Function callback) |
| native "SecureSocket_RegisterBadCertificateCallback"; |
| |
| void registerHandshakeCompleteCallback(Function handshakeCompleteHandler) |
| native "SecureSocket_RegisterHandshakeCompleteCallback"; |
| |
| // This is a security issue, as it exposes a raw pointer to Dart code. |
| int _pointer() native "SecureSocket_FilterPointer"; |
| |
| List<_ExternalBuffer> buffers; |
| } |
| |
| patch class SecurityContext { |
| /* patch */ factory SecurityContext() { |
| return new _SecurityContext(); |
| } |
| |
| /* patch */ static SecurityContext get defaultContext { |
| return _SecurityContext.defaultContext; |
| } |
| } |
| |
| class _SecurityContext |
| extends NativeFieldWrapperClass1 |
| implements SecurityContext { |
| _SecurityContext() { |
| _createNativeContext(); |
| } |
| |
| void _createNativeContext() native "SecurityContext_Allocate"; |
| |
| static final SecurityContext defaultContext = |
| new _SecurityContext().._trustBuiltinRoots(); |
| |
| void usePrivateKey(String keyFile, {String password}) |
| native "SecurityContext_UsePrivateKey"; |
| void setTrustedCertificates({String file, String directory}) |
| native "SecurityContext_SetTrustedCertificates"; |
| void useCertificateChain(String file) |
| native "SecurityContext_UseCertificateChain"; |
| void setClientAuthorities(String file) |
| native "SecurityContext_SetClientAuthorities"; |
| void setAlpnProtocols(List<String> protocols, bool isServer) { |
| Uint8List encodedProtocols = |
| SecurityContext._protocolsToLengthEncoding(protocols); |
| _setAlpnProtocols(encodedProtocols, isServer); |
| } |
| void _setAlpnProtocols(Uint8List protocols, bool isServer) |
| native "SecurityContext_SetAlpnProtocols"; |
| void _trustBuiltinRoots() |
| native "SecurityContext_TrustBuiltinRoots"; |
| } |
| |
| /** |
| * _X509CertificateImpl wraps an X509 certificate object held by the BoringSSL |
| * library. It exposes the fields of the certificate object. |
| */ |
| class _X509CertificateImpl extends NativeFieldWrapperClass1 |
| implements X509Certificate { |
| // The native field must be set manually on a new object, in native code. |
| // This is done by WrappedX509 in secure_socket.cc. |
| _X509CertificateImpl(); |
| |
| String get subject native "X509_Subject"; |
| String get issuer native "X509_Issuer"; |
| DateTime get startValidity { |
| return new DateTime.fromMillisecondsSinceEpoch(_startValidity(), |
| isUtc: true); |
| } |
| DateTime get endValidity { |
| return new DateTime.fromMillisecondsSinceEpoch(_endValidity(), |
| isUtc: true); |
| } |
| int _startValidity() native "X509_StartValidity"; |
| int _endValidity() native "X509_EndValidity"; |
| } |