| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 @patch | 5 @patch class SecureSocket { |
| 6 class SecureSocket { | 6 @patch factory SecureSocket._(RawSecureSocket rawSocket) => |
| 7 @patch | |
| 8 factory SecureSocket._(RawSecureSocket rawSocket) => | |
| 9 new _SecureSocket(rawSocket); | 7 new _SecureSocket(rawSocket); |
| 10 } | 8 } |
| 11 | 9 |
| 12 @patch | 10 |
| 13 class _SecureFilter { | 11 @patch class _SecureFilter { |
| 14 @patch | 12 @patch factory _SecureFilter() => new _SecureFilterImpl(); |
| 15 factory _SecureFilter() => new _SecureFilterImpl(); | |
| 16 } | 13 } |
| 17 | 14 |
| 18 @patch | 15 @patch class X509Certificate { |
| 19 class X509Certificate { | 16 @patch factory X509Certificate._() => new _X509CertificateImpl(); |
| 20 @patch | |
| 21 factory X509Certificate._() => new _X509CertificateImpl(); | |
| 22 } | 17 } |
| 23 | 18 |
| 24 class _SecureSocket extends _Socket implements SecureSocket { | 19 class _SecureSocket extends _Socket implements SecureSocket { |
| 25 _SecureSocket(RawSecureSocket raw) : super(raw); | 20 _SecureSocket(RawSecureSocket raw) : super(raw); |
| 26 | 21 |
| 27 void set onBadCertificate(bool callback(X509Certificate certificate)) { | 22 void set onBadCertificate(bool callback(X509Certificate certificate)) { |
| 28 if (_raw == null) { | 23 if (_raw == null) { |
| 29 throw new StateError("onBadCertificate called on destroyed SecureSocket"); | 24 throw new StateError("onBadCertificate called on destroyed SecureSocket"); |
| 30 } | 25 } |
| 31 _raw.onBadCertificate = callback; | 26 _raw.onBadCertificate = callback; |
| 32 } | 27 } |
| 33 | 28 |
| 34 void renegotiate( | 29 void renegotiate({bool useSessionCache: true, |
| 35 {bool useSessionCache: true, | 30 bool requestClientCertificate: false, |
| 36 bool requestClientCertificate: false, | 31 bool requireClientCertificate: false}) { |
| 37 bool requireClientCertificate: false}) { | 32 _raw.renegotiate(useSessionCache: useSessionCache, |
| 38 _raw.renegotiate( | 33 requestClientCertificate: requestClientCertificate, |
| 39 useSessionCache: useSessionCache, | 34 requireClientCertificate: requireClientCertificate); |
| 40 requestClientCertificate: requestClientCertificate, | |
| 41 requireClientCertificate: requireClientCertificate); | |
| 42 } | 35 } |
| 43 | 36 |
| 44 X509Certificate get peerCertificate { | 37 X509Certificate get peerCertificate { |
| 45 if (_raw == null) { | 38 if (_raw == null) { |
| 46 throw new StateError("peerCertificate called on destroyed SecureSocket"); | 39 throw new StateError("peerCertificate called on destroyed SecureSocket"); |
| 47 } | 40 } |
| 48 return _raw.peerCertificate; | 41 return _raw.peerCertificate; |
| 49 } | 42 } |
| 50 | 43 |
| 51 String get selectedProtocol { | 44 String get selectedProtocol { |
| 52 if (_raw == null) { | 45 if (_raw == null) { |
| 53 throw new StateError("selectedProtocol called on destroyed SecureSocket"); | 46 throw new StateError("selectedProtocol called on destroyed SecureSocket"); |
| 54 } | 47 } |
| 55 return _raw.selectedProtocol; | 48 return _raw.selectedProtocol; |
| 56 } | 49 } |
| 57 } | 50 } |
| 58 | 51 |
| 52 |
| 59 /** | 53 /** |
| 60 * _SecureFilterImpl wraps a filter that encrypts and decrypts data travelling | 54 * _SecureFilterImpl wraps a filter that encrypts and decrypts data travelling |
| 61 * over an encrypted socket. The filter also handles the handshaking | 55 * over an encrypted socket. The filter also handles the handshaking |
| 62 * and certificate verification. | 56 * and certificate verification. |
| 63 * | 57 * |
| 64 * The filter exposes its input and output buffers as Dart objects that | 58 * The filter exposes its input and output buffers as Dart objects that |
| 65 * are backed by an external C array of bytes, so that both Dart code and | 59 * are backed by an external C array of bytes, so that both Dart code and |
| 66 * native code can access the same data. | 60 * native code can access the same data. |
| 67 */ | 61 */ |
| 68 class _SecureFilterImpl extends NativeFieldWrapperClass1 | 62 class _SecureFilterImpl |
| 63 extends NativeFieldWrapperClass1 |
| 69 implements _SecureFilter { | 64 implements _SecureFilter { |
| 70 // Performance is improved if a full buffer of plaintext fits | 65 // Performance is improved if a full buffer of plaintext fits |
| 71 // in the encrypted buffer, when encrypted. | 66 // in the encrypted buffer, when encrypted. |
| 72 static final int SIZE = 8 * 1024; | 67 static final int SIZE = 8 * 1024; |
| 73 static final int ENCRYPTED_SIZE = 10 * 1024; | 68 static final int ENCRYPTED_SIZE = 10 * 1024; |
| 74 | 69 |
| 75 _SecureFilterImpl() { | 70 _SecureFilterImpl() { |
| 76 buffers = new List<_ExternalBuffer>(_RawSecureSocket.NUM_BUFFERS); | 71 buffers = new List<_ExternalBuffer>(_RawSecureSocket.NUM_BUFFERS); |
| 77 for (int i = 0; i < _RawSecureSocket.NUM_BUFFERS; ++i) { | 72 for (int i = 0; i < _RawSecureSocket.NUM_BUFFERS; ++i) { |
| 78 buffers[i] = new _ExternalBuffer( | 73 buffers[i] = new _ExternalBuffer(_RawSecureSocket._isBufferEncrypted(i) ? |
| 79 _RawSecureSocket._isBufferEncrypted(i) ? ENCRYPTED_SIZE : SIZE); | 74 ENCRYPTED_SIZE : |
| 75 SIZE); |
| 80 } | 76 } |
| 81 } | 77 } |
| 82 | 78 |
| 83 void connect( | 79 void connect(String hostName, |
| 84 String hostName, | 80 SecurityContext context, |
| 85 SecurityContext context, | 81 bool is_server, |
| 86 bool is_server, | 82 bool requestClientCertificate, |
| 87 bool requestClientCertificate, | 83 bool requireClientCertificate, |
| 88 bool requireClientCertificate, | 84 Uint8List protocols) native "SecureSocket_Connect"; |
| 89 Uint8List protocols) native "SecureSocket_Connect"; | |
| 90 | 85 |
| 91 void destroy() { | 86 void destroy() { |
| 92 buffers = null; | 87 buffers = null; |
| 93 _destroy(); | 88 _destroy(); |
| 94 } | 89 } |
| 95 | 90 |
| 96 void _destroy() native "SecureSocket_Destroy"; | 91 void _destroy() native "SecureSocket_Destroy"; |
| 97 | 92 |
| 98 void handshake() native "SecureSocket_Handshake"; | 93 void handshake() native "SecureSocket_Handshake"; |
| 99 | 94 |
| 100 String selectedProtocol() native "SecureSocket_GetSelectedProtocol"; | 95 String selectedProtocol() native "SecureSocket_GetSelectedProtocol"; |
| 101 | 96 |
| 102 void renegotiate(bool useSessionCache, bool requestClientCertificate, | 97 void renegotiate(bool useSessionCache, |
| 103 bool requireClientCertificate) native "SecureSocket_Renegotiate"; | 98 bool requestClientCertificate, |
| 99 bool requireClientCertificate) |
| 100 native "SecureSocket_Renegotiate"; |
| 104 | 101 |
| 105 void init() native "SecureSocket_Init"; | 102 void init() native "SecureSocket_Init"; |
| 106 | 103 |
| 107 X509Certificate get peerCertificate native "SecureSocket_PeerCertificate"; | 104 X509Certificate get peerCertificate native "SecureSocket_PeerCertificate"; |
| 108 | 105 |
| 109 void registerBadCertificateCallback(Function callback) | 106 void registerBadCertificateCallback(Function callback) |
| 110 native "SecureSocket_RegisterBadCertificateCallback"; | 107 native "SecureSocket_RegisterBadCertificateCallback"; |
| 111 | 108 |
| 112 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler) | 109 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler) |
| 113 native "SecureSocket_RegisterHandshakeCompleteCallback"; | 110 native "SecureSocket_RegisterHandshakeCompleteCallback"; |
| 114 | 111 |
| 115 // This is a security issue, as it exposes a raw pointer to Dart code. | 112 // This is a security issue, as it exposes a raw pointer to Dart code. |
| 116 int _pointer() native "SecureSocket_FilterPointer"; | 113 int _pointer() native "SecureSocket_FilterPointer"; |
| 117 | 114 |
| 118 List<_ExternalBuffer> buffers; | 115 List<_ExternalBuffer> buffers; |
| 119 } | 116 } |
| 120 | 117 |
| 121 @patch | 118 @patch class SecurityContext { |
| 122 class SecurityContext { | 119 @patch factory SecurityContext() { |
| 123 @patch | |
| 124 factory SecurityContext() { | |
| 125 return new _SecurityContext(); | 120 return new _SecurityContext(); |
| 126 } | 121 } |
| 127 | 122 |
| 128 @patch | 123 @patch static SecurityContext get defaultContext { |
| 129 static SecurityContext get defaultContext { | |
| 130 return _SecurityContext.defaultContext; | 124 return _SecurityContext.defaultContext; |
| 131 } | 125 } |
| 132 | 126 |
| 133 @patch | 127 @patch static bool get alpnSupported { |
| 134 static bool get alpnSupported { | |
| 135 return _SecurityContext.alpnSupported; | 128 return _SecurityContext.alpnSupported; |
| 136 } | 129 } |
| 137 } | 130 } |
| 138 | 131 |
| 139 class _SecurityContext extends NativeFieldWrapperClass1 | 132 class _SecurityContext |
| 133 extends NativeFieldWrapperClass1 |
| 140 implements SecurityContext { | 134 implements SecurityContext { |
| 141 _SecurityContext() { | 135 _SecurityContext() { |
| 142 _createNativeContext(); | 136 _createNativeContext(); |
| 143 } | 137 } |
| 144 | 138 |
| 145 void _createNativeContext() native "SecurityContext_Allocate"; | 139 void _createNativeContext() native "SecurityContext_Allocate"; |
| 146 | 140 |
| 147 static final SecurityContext defaultContext = new _SecurityContext() | 141 static final SecurityContext defaultContext = |
| 148 .._trustBuiltinRoots(); | 142 new _SecurityContext().._trustBuiltinRoots(); |
| 149 | 143 |
| 150 void usePrivateKey(String file, {String password}) { | 144 void usePrivateKey(String file, {String password}) { |
| 151 List<int> bytes = (new File(file)).readAsBytesSync(); | 145 List<int> bytes = (new File(file)).readAsBytesSync(); |
| 152 usePrivateKeyBytes(bytes, password: password); | 146 usePrivateKeyBytes(bytes, password: password); |
| 153 } | 147 } |
| 154 | |
| 155 void usePrivateKeyBytes(List<int> keyBytes, {String password}) | 148 void usePrivateKeyBytes(List<int> keyBytes, {String password}) |
| 156 native "SecurityContext_UsePrivateKeyBytes"; | 149 native "SecurityContext_UsePrivateKeyBytes"; |
| 157 | 150 |
| 158 void setTrustedCertificates(String file, {String password}) { | 151 void setTrustedCertificates(String file, {String password}) { |
| 159 List<int> bytes = (new File(file)).readAsBytesSync(); | 152 List<int> bytes = (new File(file)).readAsBytesSync(); |
| 160 setTrustedCertificatesBytes(bytes, password: password); | 153 setTrustedCertificatesBytes(bytes, password: password); |
| 161 } | 154 } |
| 162 | |
| 163 void setTrustedCertificatesBytes(List<int> certBytes, {String password}) | 155 void setTrustedCertificatesBytes(List<int> certBytes, {String password}) |
| 164 native "SecurityContext_SetTrustedCertificatesBytes"; | 156 native "SecurityContext_SetTrustedCertificatesBytes"; |
| 165 | 157 |
| 166 void useCertificateChain(String file, {String password}) { | 158 void useCertificateChain(String file, {String password}) { |
| 167 List<int> bytes = (new File(file)).readAsBytesSync(); | 159 List<int> bytes = (new File(file)).readAsBytesSync(); |
| 168 useCertificateChainBytes(bytes, password: password); | 160 useCertificateChainBytes(bytes, password: password); |
| 169 } | 161 } |
| 170 | |
| 171 void useCertificateChainBytes(List<int> chainBytes, {String password}) | 162 void useCertificateChainBytes(List<int> chainBytes, {String password}) |
| 172 native "SecurityContext_UseCertificateChainBytes"; | 163 native "SecurityContext_UseCertificateChainBytes"; |
| 173 | 164 |
| 174 void setClientAuthorities(String file, {String password}) { | 165 void setClientAuthorities(String file, {String password}) { |
| 175 List<int> bytes = (new File(file)).readAsBytesSync(); | 166 List<int> bytes = (new File(file)).readAsBytesSync(); |
| 176 setClientAuthoritiesBytes(bytes, password: password); | 167 setClientAuthoritiesBytes(bytes, password: password); |
| 177 } | 168 } |
| 178 | |
| 179 void setClientAuthoritiesBytes(List<int> authCertBytes, {String password}) | 169 void setClientAuthoritiesBytes(List<int> authCertBytes, {String password}) |
| 180 native "SecurityContext_SetClientAuthoritiesBytes"; | 170 native "SecurityContext_SetClientAuthoritiesBytes"; |
| 181 | 171 |
| 182 static bool get alpnSupported => _alpnSupported(); | 172 static bool get alpnSupported => _alpnSupported(); |
| 183 static bool _alpnSupported() native "SecurityContext_AlpnSupported"; | 173 static bool _alpnSupported() native "SecurityContext_AlpnSupported"; |
| 184 void setAlpnProtocols(List<String> protocols, bool isServer) { | 174 void setAlpnProtocols(List<String> protocols, bool isServer) { |
| 185 Uint8List encodedProtocols = | 175 Uint8List encodedProtocols = |
| 186 SecurityContext._protocolsToLengthEncoding(protocols); | 176 SecurityContext._protocolsToLengthEncoding(protocols); |
| 187 _setAlpnProtocols(encodedProtocols, isServer); | 177 _setAlpnProtocols(encodedProtocols, isServer); |
| 188 } | 178 } |
| 189 | |
| 190 void _setAlpnProtocols(Uint8List protocols, bool isServer) | 179 void _setAlpnProtocols(Uint8List protocols, bool isServer) |
| 191 native "SecurityContext_SetAlpnProtocols"; | 180 native "SecurityContext_SetAlpnProtocols"; |
| 192 void _trustBuiltinRoots() native "SecurityContext_TrustBuiltinRoots"; | 181 void _trustBuiltinRoots() |
| 182 native "SecurityContext_TrustBuiltinRoots"; |
| 193 } | 183 } |
| 194 | 184 |
| 195 /** | 185 /** |
| 196 * _X509CertificateImpl wraps an X509 certificate object held by the BoringSSL | 186 * _X509CertificateImpl wraps an X509 certificate object held by the BoringSSL |
| 197 * library. It exposes the fields of the certificate object. | 187 * library. It exposes the fields of the certificate object. |
| 198 */ | 188 */ |
| 199 class _X509CertificateImpl extends NativeFieldWrapperClass1 | 189 class _X509CertificateImpl extends NativeFieldWrapperClass1 |
| 200 implements X509Certificate { | 190 implements X509Certificate { |
| 201 // The native field must be set manually on a new object, in native code. | 191 // The native field must be set manually on a new object, in native code. |
| 202 // This is done by WrappedX509 in secure_socket.cc. | 192 // This is done by WrappedX509 in secure_socket.cc. |
| 203 _X509CertificateImpl(); | 193 _X509CertificateImpl(); |
| 204 | 194 |
| 205 String get subject native "X509_Subject"; | 195 String get subject native "X509_Subject"; |
| 206 String get issuer native "X509_Issuer"; | 196 String get issuer native "X509_Issuer"; |
| 207 DateTime get startValidity { | 197 DateTime get startValidity { |
| 208 return new DateTime.fromMillisecondsSinceEpoch(_startValidity(), | 198 return new DateTime.fromMillisecondsSinceEpoch(_startValidity(), |
| 209 isUtc: true); | 199 isUtc: true); |
| 210 } | 200 } |
| 211 | |
| 212 DateTime get endValidity { | 201 DateTime get endValidity { |
| 213 return new DateTime.fromMillisecondsSinceEpoch(_endValidity(), isUtc: true); | 202 return new DateTime.fromMillisecondsSinceEpoch(_endValidity(), |
| 203 isUtc: true); |
| 214 } | 204 } |
| 215 | |
| 216 int _startValidity() native "X509_StartValidity"; | 205 int _startValidity() native "X509_StartValidity"; |
| 217 int _endValidity() native "X509_EndValidity"; | 206 int _endValidity() native "X509_EndValidity"; |
| 218 } | 207 } |
| OLD | NEW |