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 #include "bin/tls_socket.h" | 5 #include "bin/secure_socket.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
11 #include <string.h> | 11 #include <string.h> |
12 | 12 |
13 #include <nss.h> | 13 #include <nss.h> |
14 #include <pk11pub.h> | 14 #include <pk11pub.h> |
15 #include <prerror.h> | 15 #include <prerror.h> |
16 #include <prinit.h> | 16 #include <prinit.h> |
17 #include <prnetdb.h> | 17 #include <prnetdb.h> |
18 #include <ssl.h> | 18 #include <ssl.h> |
19 #include <sslproto.h> | 19 #include <sslproto.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/net/nss_memio.h" | 23 #include "bin/net/nss_memio.h" |
24 #include "bin/thread.h" | 24 #include "bin/thread.h" |
25 #include "bin/utils.h" | 25 #include "bin/utils.h" |
26 #include "platform/utils.h" | 26 #include "platform/utils.h" |
27 | 27 |
28 #include "include/dart_api.h" | 28 #include "include/dart_api.h" |
29 | 29 |
30 bool TlsFilter::library_initialized_ = false; | 30 bool SSLFilter::library_initialized_ = false; |
31 dart::Mutex TlsFilter::mutex_; // To protect library initialization. | 31 dart::Mutex SSLFilter::mutex_; // To protect library initialization. |
32 // The password is needed when creating secure server sockets. It can | 32 // The password is needed when creating secure server sockets. It can |
33 // be null if only secure client sockets are used. | 33 // be null if only secure client sockets are used. |
34 const char* TlsFilter::password_ = NULL; | 34 const char* SSLFilter::password_ = NULL; |
35 | 35 |
36 static const int kTlsFilterNativeFieldIndex = 0; | 36 static const int kSSLFilterNativeFieldIndex = 0; |
37 | 37 |
38 static TlsFilter* GetTlsFilter(Dart_NativeArguments args) { | 38 static SSLFilter* GetFilter(Dart_NativeArguments args) { |
39 TlsFilter* filter; | 39 SSLFilter* filter; |
40 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 40 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
41 ASSERT(Dart_IsInstance(dart_this)); | 41 ASSERT(Dart_IsInstance(dart_this)); |
42 ThrowIfError(Dart_GetNativeInstanceField( | 42 ThrowIfError(Dart_GetNativeInstanceField( |
43 dart_this, | 43 dart_this, |
44 kTlsFilterNativeFieldIndex, | 44 kSSLFilterNativeFieldIndex, |
45 reinterpret_cast<intptr_t*>(&filter))); | 45 reinterpret_cast<intptr_t*>(&filter))); |
46 return filter; | 46 return filter; |
47 } | 47 } |
48 | 48 |
49 | 49 |
50 static void SetTlsFilter(Dart_NativeArguments args, TlsFilter* filter) { | 50 static void SetFilter(Dart_NativeArguments args, SSLFilter* filter) { |
51 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 51 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
52 ASSERT(Dart_IsInstance(dart_this)); | 52 ASSERT(Dart_IsInstance(dart_this)); |
53 ThrowIfError(Dart_SetNativeInstanceField( | 53 ThrowIfError(Dart_SetNativeInstanceField( |
54 dart_this, | 54 dart_this, |
55 kTlsFilterNativeFieldIndex, | 55 kSSLFilterNativeFieldIndex, |
56 reinterpret_cast<intptr_t>(filter))); | 56 reinterpret_cast<intptr_t>(filter))); |
57 } | 57 } |
58 | 58 |
59 | 59 |
60 void FUNCTION_NAME(TlsSocket_Init)(Dart_NativeArguments args) { | 60 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) { |
61 Dart_EnterScope(); | 61 Dart_EnterScope(); |
62 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 62 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
63 TlsFilter* filter = new TlsFilter; | 63 SSLFilter* filter = new SSLFilter; |
64 SetTlsFilter(args, filter); | 64 SetFilter(args, filter); |
65 filter->Init(dart_this); | 65 filter->Init(dart_this); |
66 Dart_ExitScope(); | 66 Dart_ExitScope(); |
67 } | 67 } |
68 | 68 |
69 | 69 |
70 void FUNCTION_NAME(TlsSocket_Connect)(Dart_NativeArguments args) { | 70 void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) { |
71 Dart_EnterScope(); | 71 Dart_EnterScope(); |
72 Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 72 Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
73 Dart_Handle port_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); | 73 Dart_Handle port_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); |
74 Dart_Handle is_server_object = ThrowIfError(Dart_GetNativeArgument(args, 3)); | 74 Dart_Handle is_server_object = ThrowIfError(Dart_GetNativeArgument(args, 3)); |
75 Dart_Handle certificate_name_object = | 75 Dart_Handle certificate_name_object = |
76 ThrowIfError(Dart_GetNativeArgument(args, 4)); | 76 ThrowIfError(Dart_GetNativeArgument(args, 4)); |
77 | 77 |
78 const char* host_name = NULL; | 78 const char* host_name = NULL; |
79 // TODO(whesse): Is truncating a Dart string containing \0 what we want? | 79 // TODO(whesse): Is truncating a Dart string containing \0 what we want? |
80 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); | 80 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); |
81 | 81 |
82 int64_t port; | 82 int64_t port; |
83 if (!DartUtils::GetInt64Value(port_object, &port) || | 83 if (!DartUtils::GetInt64Value(port_object, &port) || |
84 port < 0 || port > 65535) { | 84 port < 0 || port > 65535) { |
85 Dart_ThrowException(DartUtils::NewDartArgumentError( | 85 Dart_ThrowException(DartUtils::NewDartArgumentError( |
86 "Illegal port parameter in _TlsFilter.connect")); | 86 "Illegal port parameter in _SSLFilter.connect")); |
87 } | 87 } |
88 | 88 |
89 if (!Dart_IsBoolean(is_server_object)) { | 89 if (!Dart_IsBoolean(is_server_object)) { |
90 Dart_ThrowException(DartUtils::NewDartArgumentError( | 90 Dart_ThrowException(DartUtils::NewDartArgumentError( |
91 "Illegal is_server parameter in _TlsFilter.connect")); | 91 "Illegal is_server parameter in _SSLFilter.connect")); |
92 } | 92 } |
93 bool is_server = DartUtils::GetBooleanValue(is_server_object); | 93 bool is_server = DartUtils::GetBooleanValue(is_server_object); |
94 | 94 |
95 const char* certificate_name = NULL; | 95 const char* certificate_name = NULL; |
96 // If this is a server connection, get the certificate to connect with. | 96 // If this is a server connection, get the certificate to connect with. |
97 // TODO(whesse): Use this parameter for a client certificate as well. | 97 // TODO(whesse): Use this parameter for a client certificate as well. |
98 if (is_server) { | 98 if (is_server) { |
99 if (!Dart_IsString(certificate_name_object)) { | 99 if (!Dart_IsString(certificate_name_object)) { |
100 Dart_ThrowException(DartUtils::NewDartArgumentError( | 100 Dart_ThrowException(DartUtils::NewDartArgumentError( |
101 "Non-String certificate parameter in _TlsFilter.connect")); | 101 "Non-String certificate parameter in _SSLFilter.connect")); |
102 } | 102 } |
103 ThrowIfError(Dart_StringToCString(certificate_name_object, | 103 ThrowIfError(Dart_StringToCString(certificate_name_object, |
104 &certificate_name)); | 104 &certificate_name)); |
105 } | 105 } |
106 | 106 |
107 GetTlsFilter(args)->Connect(host_name, | 107 GetFilter(args)->Connect(host_name, |
108 static_cast<int>(port), | 108 static_cast<int>(port), |
109 is_server, | 109 is_server, |
110 certificate_name); | 110 certificate_name); |
111 Dart_ExitScope(); | 111 Dart_ExitScope(); |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 void FUNCTION_NAME(TlsSocket_Destroy)(Dart_NativeArguments args) { | 115 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { |
116 Dart_EnterScope(); | 116 Dart_EnterScope(); |
117 TlsFilter* filter = GetTlsFilter(args); | 117 SSLFilter* filter = GetFilter(args); |
118 SetTlsFilter(args, NULL); | 118 SetFilter(args, NULL); |
119 filter->Destroy(); | 119 filter->Destroy(); |
120 delete filter; | 120 delete filter; |
121 Dart_ExitScope(); | 121 Dart_ExitScope(); |
122 } | 122 } |
123 | 123 |
124 | 124 |
125 void FUNCTION_NAME(TlsSocket_Handshake)(Dart_NativeArguments args) { | 125 void FUNCTION_NAME(SecureSocket_Handshake)(Dart_NativeArguments args) { |
126 Dart_EnterScope(); | 126 Dart_EnterScope(); |
127 GetTlsFilter(args)->Handshake(); | 127 GetFilter(args)->Handshake(); |
128 Dart_ExitScope(); | 128 Dart_ExitScope(); |
129 } | 129 } |
130 | 130 |
131 | 131 |
132 void FUNCTION_NAME(TlsSocket_RegisterHandshakeCompleteCallback)( | 132 void FUNCTION_NAME(SecureSocket_RegisterHandshakeCompleteCallback)( |
133 Dart_NativeArguments args) { | 133 Dart_NativeArguments args) { |
134 Dart_EnterScope(); | 134 Dart_EnterScope(); |
135 Dart_Handle handshake_complete = | 135 Dart_Handle handshake_complete = |
136 ThrowIfError(Dart_GetNativeArgument(args, 1)); | 136 ThrowIfError(Dart_GetNativeArgument(args, 1)); |
137 if (!Dart_IsClosure(handshake_complete)) { | 137 if (!Dart_IsClosure(handshake_complete)) { |
138 Dart_ThrowException(DartUtils::NewDartArgumentError( | 138 Dart_ThrowException(DartUtils::NewDartArgumentError( |
139 "Illegal argument to RegisterHandshakeCompleteCallback")); | 139 "Illegal argument to RegisterHandshakeCompleteCallback")); |
140 } | 140 } |
141 GetTlsFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete); | 141 GetFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete); |
142 Dart_ExitScope(); | 142 Dart_ExitScope(); |
143 } | 143 } |
144 | 144 |
145 | 145 |
146 void FUNCTION_NAME(TlsSocket_ProcessBuffer)(Dart_NativeArguments args) { | 146 void FUNCTION_NAME(SecureSocket_ProcessBuffer)(Dart_NativeArguments args) { |
147 Dart_EnterScope(); | 147 Dart_EnterScope(); |
148 Dart_Handle buffer_id_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 148 Dart_Handle buffer_id_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
149 int64_t buffer_id = DartUtils::GetIntegerValue(buffer_id_object); | 149 int64_t buffer_id = DartUtils::GetIntegerValue(buffer_id_object); |
150 if (buffer_id < 0 || buffer_id >= TlsFilter::kNumBuffers) { | 150 if (buffer_id < 0 || buffer_id >= SSLFilter::kNumBuffers) { |
151 Dart_ThrowException(DartUtils::NewDartArgumentError( | 151 Dart_ThrowException(DartUtils::NewDartArgumentError( |
152 "Illegal argument to ProcessBuffer")); | 152 "Illegal argument to ProcessBuffer")); |
153 } | 153 } |
154 | 154 |
155 intptr_t bytes_read = | 155 intptr_t bytes_read = |
156 GetTlsFilter(args)->ProcessBuffer(static_cast<int>(buffer_id)); | 156 GetFilter(args)->ProcessBuffer(static_cast<int>(buffer_id)); |
157 Dart_SetReturnValue(args, Dart_NewInteger(bytes_read)); | 157 Dart_SetReturnValue(args, Dart_NewInteger(bytes_read)); |
158 Dart_ExitScope(); | 158 Dart_ExitScope(); |
159 } | 159 } |
160 | 160 |
161 | 161 |
162 void FUNCTION_NAME(TlsSocket_SetCertificateDatabase) | 162 void FUNCTION_NAME(SecureSocket_SetCertificateDatabase) |
163 (Dart_NativeArguments args) { | 163 (Dart_NativeArguments args) { |
164 Dart_EnterScope(); | 164 Dart_EnterScope(); |
165 Dart_Handle certificate_database_object = | 165 Dart_Handle certificate_database_object = |
166 ThrowIfError(Dart_GetNativeArgument(args, 0)); | 166 ThrowIfError(Dart_GetNativeArgument(args, 0)); |
167 // Check that the type is string, and get the UTF-8 C string value from it. | 167 // Check that the type is string, and get the UTF-8 C string value from it. |
168 const char* certificate_database = NULL; | 168 const char* certificate_database = NULL; |
169 if (Dart_IsString(certificate_database_object)) { | 169 if (Dart_IsString(certificate_database_object)) { |
170 ThrowIfError(Dart_StringToCString(certificate_database_object, | 170 ThrowIfError(Dart_StringToCString(certificate_database_object, |
171 &certificate_database)); | 171 &certificate_database)); |
172 } else { | 172 } else { |
173 Dart_ThrowException(DartUtils::NewDartArgumentError( | 173 Dart_ThrowException(DartUtils::NewDartArgumentError( |
174 "Non-String certificate directory argument to SetCertificateDatabase")); | 174 "Non-String certificate directory argument to SetCertificateDatabase")); |
175 } | 175 } |
176 | 176 |
177 Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 177 Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
178 // Check that the type is string or null, | 178 // Check that the type is string or null, |
179 // and get the UTF-8 C string value from it. | 179 // and get the UTF-8 C string value from it. |
180 const char* password = NULL; | 180 const char* password = NULL; |
181 if (Dart_IsString(password_object)) { | 181 if (Dart_IsString(password_object)) { |
182 ThrowIfError(Dart_StringToCString(password_object, &password)); | 182 ThrowIfError(Dart_StringToCString(password_object, &password)); |
183 } else if (Dart_IsNull(password_object)) { | 183 } else if (Dart_IsNull(password_object)) { |
184 // Pass the empty string as the password. | 184 // Pass the empty string as the password. |
185 password = ""; | 185 password = ""; |
186 } else { | 186 } else { |
187 Dart_ThrowException(DartUtils::NewDartArgumentError( | 187 Dart_ThrowException(DartUtils::NewDartArgumentError( |
188 "Password argument to SetCertificateDatabase is not a String or null")); | 188 "Password argument to SetCertificateDatabase is not a String or null")); |
189 } | 189 } |
190 | 190 |
191 TlsFilter::InitializeLibrary(certificate_database, password); | 191 SSLFilter::InitializeLibrary(certificate_database, password); |
192 Dart_ExitScope(); | 192 Dart_ExitScope(); |
193 } | 193 } |
194 | 194 |
195 | 195 |
196 void TlsFilter::Init(Dart_Handle dart_this) { | 196 void SSLFilter::Init(Dart_Handle dart_this) { |
197 string_start_ = ThrowIfError( | 197 string_start_ = ThrowIfError( |
198 Dart_NewPersistentHandle(DartUtils::NewString("start"))); | 198 Dart_NewPersistentHandle(DartUtils::NewString("start"))); |
199 string_length_ = ThrowIfError( | 199 string_length_ = ThrowIfError( |
200 Dart_NewPersistentHandle(DartUtils::NewString("length"))); | 200 Dart_NewPersistentHandle(DartUtils::NewString("length"))); |
201 | 201 |
202 InitializeBuffers(dart_this); | 202 InitializeBuffers(dart_this); |
203 filter_ = memio_CreateIOLayer(kMemioBufferSize); | 203 filter_ = memio_CreateIOLayer(kMemioBufferSize); |
204 } | 204 } |
205 | 205 |
206 | 206 |
207 void TlsFilter::InitializeBuffers(Dart_Handle dart_this) { | 207 void SSLFilter::InitializeBuffers(Dart_Handle dart_this) { |
208 // Create TlsFilter buffers as ExternalUint8Array objects. | 208 // Create SSLFilter buffers as ExternalUint8Array objects. |
209 Dart_Handle dart_buffers_object = ThrowIfError( | 209 Dart_Handle dart_buffers_object = ThrowIfError( |
210 Dart_GetField(dart_this, DartUtils::NewString("buffers"))); | 210 Dart_GetField(dart_this, DartUtils::NewString("buffers"))); |
211 Dart_Handle dart_buffer_object = | 211 Dart_Handle dart_buffer_object = |
212 Dart_ListGetAt(dart_buffers_object, kReadPlaintext); | 212 Dart_ListGetAt(dart_buffers_object, kReadPlaintext); |
213 Dart_Handle tls_external_buffer_class = | 213 Dart_Handle external_buffer_class = |
214 Dart_InstanceGetClass(dart_buffer_object); | 214 Dart_InstanceGetClass(dart_buffer_object); |
215 Dart_Handle dart_buffer_size = ThrowIfError( | 215 Dart_Handle dart_buffer_size = ThrowIfError( |
216 Dart_GetField(tls_external_buffer_class, DartUtils::NewString("SIZE"))); | 216 Dart_GetField(external_buffer_class, DartUtils::NewString("SIZE"))); |
217 buffer_size_ = DartUtils::GetIntegerValue(dart_buffer_size); | 217 buffer_size_ = DartUtils::GetIntegerValue(dart_buffer_size); |
218 if (buffer_size_ <= 0 || buffer_size_ > 1024 * 1024) { | 218 if (buffer_size_ <= 0 || buffer_size_ > 1024 * 1024) { |
219 Dart_ThrowException( | 219 Dart_ThrowException( |
220 DartUtils::NewString("Invalid buffer size in _TlsExternalBuffer")); | 220 DartUtils::NewString("Invalid buffer size in _ExternalBuffer")); |
221 } | 221 } |
222 | 222 |
223 Dart_Handle data_identifier = DartUtils::NewString("data"); | 223 Dart_Handle data_identifier = DartUtils::NewString("data"); |
224 for (int i = 0; i < kNumBuffers; ++i) { | 224 for (int i = 0; i < kNumBuffers; ++i) { |
225 dart_buffer_objects_[i] = ThrowIfError( | 225 dart_buffer_objects_[i] = ThrowIfError( |
226 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i))); | 226 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i))); |
227 buffers_[i] = new uint8_t[buffer_size_]; | 227 buffers_[i] = new uint8_t[buffer_size_]; |
228 Dart_Handle data = ThrowIfError( | 228 Dart_Handle data = ThrowIfError( |
229 Dart_NewExternalByteArray(buffers_[i], buffer_size_, NULL, NULL)); | 229 Dart_NewExternalByteArray(buffers_[i], buffer_size_, NULL, NULL)); |
230 ThrowIfError(Dart_SetField(dart_buffer_objects_[i], | 230 ThrowIfError(Dart_SetField(dart_buffer_objects_[i], |
231 data_identifier, | 231 data_identifier, |
232 data)); | 232 data)); |
233 } | 233 } |
234 } | 234 } |
235 | 235 |
236 | 236 |
237 void TlsFilter::RegisterHandshakeCompleteCallback(Dart_Handle complete) { | 237 void SSLFilter::RegisterHandshakeCompleteCallback(Dart_Handle complete) { |
238 ASSERT(NULL == handshake_complete_); | 238 ASSERT(NULL == handshake_complete_); |
239 handshake_complete_ = ThrowIfError(Dart_NewPersistentHandle(complete)); | 239 handshake_complete_ = ThrowIfError(Dart_NewPersistentHandle(complete)); |
240 } | 240 } |
241 | 241 |
242 | 242 |
243 void TlsFilter::InitializeLibrary(const char* certificate_database, | 243 void SSLFilter::InitializeLibrary(const char* certificate_database, |
244 const char* password) { | 244 const char* password) { |
245 MutexLocker locker(&mutex_); | 245 MutexLocker locker(&mutex_); |
246 if (!library_initialized_) { | 246 if (!library_initialized_) { |
247 library_initialized_ = true; | 247 library_initialized_ = true; |
248 password_ = strdup(password); // This one copy persists until Dart exits. | 248 password_ = strdup(password); // This one copy persists until Dart exits. |
249 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); | 249 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); |
250 // TODO(whesse): Verify there are no UTF-8 issues here. | 250 // TODO(whesse): Verify there are no UTF-8 issues here. |
251 SECStatus status = NSS_Init(certificate_database); | 251 SECStatus status = NSS_Init(certificate_database); |
252 if (status != SECSuccess) { | 252 if (status != SECSuccess) { |
253 ThrowPRException("Unsuccessful NSS_Init call."); | 253 ThrowPRException("Unsuccessful NSS_Init call."); |
254 } | 254 } |
255 | 255 |
256 status = NSS_SetDomesticPolicy(); | 256 status = NSS_SetDomesticPolicy(); |
257 if (status != SECSuccess) { | 257 if (status != SECSuccess) { |
258 ThrowPRException("Unsuccessful NSS_SetDomesticPolicy call."); | 258 ThrowPRException("Unsuccessful NSS_SetDomesticPolicy call."); |
259 } | 259 } |
260 // Enable TLS, as well as SSL3 and SSL2. | 260 // Enable TLS, as well as SSL3 and SSL2. |
261 status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE); | 261 status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE); |
262 if (status != SECSuccess) { | 262 if (status != SECSuccess) { |
263 ThrowPRException("Unsuccessful SSL_OptionSetDefault enable TLS call."); | 263 ThrowPRException("Unsuccessful SSL_OptionSetDefault enable TLS call."); |
264 } | 264 } |
265 } else { | 265 } else { |
266 ThrowException("Called TlsFilter::InitializeLibrary more than once"); | 266 ThrowException("Called SSLFilter::InitializeLibrary more than once"); |
267 } | 267 } |
268 } | 268 } |
269 | 269 |
270 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { | 270 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { |
271 if (!retry) { | 271 if (!retry) { |
272 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. | 272 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. |
273 } | 273 } |
274 return NULL; | 274 return NULL; |
275 } | 275 } |
276 | 276 |
277 void TlsFilter::Connect(const char* host_name, | 277 void SSLFilter::Connect(const char* host_name, |
278 int port, | 278 int port, |
279 bool is_server, | 279 bool is_server, |
280 const char* certificate_name) { | 280 const char* certificate_name) { |
281 is_server_ = is_server; | 281 is_server_ = is_server; |
282 if (in_handshake_) { | 282 if (in_handshake_) { |
283 ThrowException("Connect called while already in handshake state."); | 283 ThrowException("Connect called while already in handshake state."); |
284 } | 284 } |
285 | 285 |
286 filter_ = SSL_ImportFD(NULL, filter_); | 286 filter_ = SSL_ImportFD(NULL, filter_); |
287 if (filter_ == NULL) { | 287 if (filter_ == NULL) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 } | 341 } |
342 | 342 |
343 int index = PR_EnumerateHostEnt(0, &host_entry, port, &host_address); | 343 int index = PR_EnumerateHostEnt(0, &host_entry, port, &host_address); |
344 if (index == -1 || index == 0) { | 344 if (index == -1 || index == 0) { |
345 ThrowPRException("Unsuccessful PR_EnumerateHostEnt call"); | 345 ThrowPRException("Unsuccessful PR_EnumerateHostEnt call"); |
346 } | 346 } |
347 memio_SetPeerName(filter_, &host_address); | 347 memio_SetPeerName(filter_, &host_address); |
348 } | 348 } |
349 | 349 |
350 | 350 |
351 void TlsFilter::Handshake() { | 351 void SSLFilter::Handshake() { |
352 SECStatus status = SSL_ForceHandshake(filter_); | 352 SECStatus status = SSL_ForceHandshake(filter_); |
353 if (status == SECSuccess) { | 353 if (status == SECSuccess) { |
354 if (in_handshake_) { | 354 if (in_handshake_) { |
355 ThrowIfError(Dart_InvokeClosure(handshake_complete_, 0, NULL)); | 355 ThrowIfError(Dart_InvokeClosure(handshake_complete_, 0, NULL)); |
356 in_handshake_ = false; | 356 in_handshake_ = false; |
357 } | 357 } |
358 } else { | 358 } else { |
359 PRErrorCode error = PR_GetError(); | 359 PRErrorCode error = PR_GetError(); |
360 if (error == PR_WOULD_BLOCK_ERROR) { | 360 if (error == PR_WOULD_BLOCK_ERROR) { |
361 if (!in_handshake_) { | 361 if (!in_handshake_) { |
362 in_handshake_ = true; | 362 in_handshake_ = true; |
363 } | 363 } |
364 } else { | 364 } else { |
365 if (is_server_) { | 365 if (is_server_) { |
366 ThrowPRException("Unexpected handshake error in server"); | 366 ThrowPRException("Unexpected handshake error in server"); |
367 } else { | 367 } else { |
368 ThrowPRException("Unexpected handshake error in client"); | 368 ThrowPRException("Unexpected handshake error in client"); |
369 } | 369 } |
370 } | 370 } |
371 } | 371 } |
372 } | 372 } |
373 | 373 |
374 | 374 |
375 void TlsFilter::Destroy() { | 375 void SSLFilter::Destroy() { |
376 for (int i = 0; i < kNumBuffers; ++i) { | 376 for (int i = 0; i < kNumBuffers; ++i) { |
377 Dart_DeletePersistentHandle(dart_buffer_objects_[i]); | 377 Dart_DeletePersistentHandle(dart_buffer_objects_[i]); |
378 delete[] buffers_[i]; | 378 delete[] buffers_[i]; |
379 } | 379 } |
380 Dart_DeletePersistentHandle(string_start_); | 380 Dart_DeletePersistentHandle(string_start_); |
381 Dart_DeletePersistentHandle(string_length_); | 381 Dart_DeletePersistentHandle(string_length_); |
382 Dart_DeletePersistentHandle(handshake_complete_); | 382 Dart_DeletePersistentHandle(handshake_complete_); |
383 // TODO(whesse): Free NSS objects here. | 383 // TODO(whesse): Free NSS objects here. |
384 } | 384 } |
385 | 385 |
386 | 386 |
387 intptr_t TlsFilter::ProcessBuffer(int buffer_index) { | 387 intptr_t SSLFilter::ProcessBuffer(int buffer_index) { |
388 Dart_Handle buffer_object = dart_buffer_objects_[buffer_index]; | 388 Dart_Handle buffer_object = dart_buffer_objects_[buffer_index]; |
389 Dart_Handle start_object = ThrowIfError( | 389 Dart_Handle start_object = ThrowIfError( |
390 Dart_GetField(buffer_object, string_start_)); | 390 Dart_GetField(buffer_object, string_start_)); |
391 Dart_Handle length_object = ThrowIfError( | 391 Dart_Handle length_object = ThrowIfError( |
392 Dart_GetField(buffer_object, string_length_)); | 392 Dart_GetField(buffer_object, string_length_)); |
393 int64_t unsafe_start = DartUtils::GetIntegerValue(start_object); | 393 int64_t unsafe_start = DartUtils::GetIntegerValue(start_object); |
394 int64_t unsafe_length = DartUtils::GetIntegerValue(length_object); | 394 int64_t unsafe_length = DartUtils::GetIntegerValue(length_object); |
395 ASSERT(unsafe_start >= 0); | 395 ASSERT(unsafe_start >= 0); |
396 ASSERT(unsafe_start < buffer_size_); | 396 ASSERT(unsafe_start < buffer_size_); |
397 ASSERT(unsafe_length >= 0); | 397 ASSERT(unsafe_length >= 0); |
398 ASSERT(unsafe_length <= buffer_size_); | 398 ASSERT(unsafe_length <= buffer_size_); |
399 intptr_t start = static_cast<intptr_t>(unsafe_start); | 399 intptr_t start = static_cast<intptr_t>(unsafe_start); |
400 intptr_t length = static_cast<intptr_t>(unsafe_length); | 400 intptr_t length = static_cast<intptr_t>(unsafe_length); |
401 uint8_t* buffer = buffers_[buffer_index]; | 401 uint8_t* buffer = buffers_[buffer_index]; |
402 | 402 |
403 int bytes_processed = 0; | 403 int bytes_processed = 0; |
404 switch (buffer_index) { | 404 switch (buffer_index) { |
405 case kReadPlaintext: { | 405 case kReadPlaintext: { |
406 int bytes_free = buffer_size_ - start - length; | 406 int bytes_free = buffer_size_ - start - length; |
407 bytes_processed = PR_Read(filter_, | 407 bytes_processed = PR_Read(filter_, |
408 buffer + start + length, | 408 buffer + start + length, |
409 bytes_free); | 409 bytes_free); |
410 if (bytes_processed < 0) { | 410 if (bytes_processed < 0) { |
411 ASSERT(bytes_processed == -1); | 411 ASSERT(bytes_processed == -1); |
412 // TODO(whesse): Handle unexpected errors here. | 412 // TODO(whesse): Handle unexpected errors here. |
413 PRErrorCode pr_error = PR_GetError(); | 413 PRErrorCode pr_error = PR_GetError(); |
414 if (PR_WOULD_BLOCK_ERROR != pr_error) { | 414 if (PR_WOULD_BLOCK_ERROR != pr_error) { |
415 ThrowPRException("Error reading plaintext from TlsFilter"); | 415 ThrowPRException("Error reading plaintext from SSLFilter"); |
416 } | 416 } |
417 bytes_processed = 0; | 417 bytes_processed = 0; |
418 } | 418 } |
419 break; | 419 break; |
420 } | 420 } |
421 | 421 |
422 case kWriteEncrypted: { | 422 case kWriteEncrypted: { |
423 const uint8_t* buf1; | 423 const uint8_t* buf1; |
424 const uint8_t* buf2; | 424 const uint8_t* buf2; |
425 unsigned int len1; | 425 unsigned int len1; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 bytes_processed = PR_Write(filter_, | 466 bytes_processed = PR_Write(filter_, |
467 buffer + start, | 467 buffer + start, |
468 length); | 468 length); |
469 } | 469 } |
470 | 470 |
471 if (bytes_processed < 0) { | 471 if (bytes_processed < 0) { |
472 ASSERT(bytes_processed == -1); | 472 ASSERT(bytes_processed == -1); |
473 // TODO(whesse): Handle unexpected errors here. | 473 // TODO(whesse): Handle unexpected errors here. |
474 PRErrorCode pr_error = PR_GetError(); | 474 PRErrorCode pr_error = PR_GetError(); |
475 if (PR_WOULD_BLOCK_ERROR != pr_error) { | 475 if (PR_WOULD_BLOCK_ERROR != pr_error) { |
476 ThrowPRException("Error reading plaintext from TlsFilter"); | 476 ThrowPRException("Error reading plaintext from SSLFilter"); |
477 } | 477 } |
478 bytes_processed = 0; | 478 bytes_processed = 0; |
479 } | 479 } |
480 break; | 480 break; |
481 } | 481 } |
482 } | 482 } |
483 return bytes_processed; | 483 return bytes_processed; |
484 } | 484 } |
OLD | NEW |