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/secure_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> |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 namespace dart { | 35 namespace dart { |
36 namespace bin { | 36 namespace bin { |
37 | 37 |
38 bool SSLFilter::library_initialized_ = false; | 38 bool SSLFilter::library_initialized_ = false; |
39 dart::Mutex SSLFilter::mutex_; // To protect library initialization. | 39 dart::Mutex SSLFilter::mutex_; // To protect library initialization. |
40 // The password is needed when creating secure server sockets. It can | 40 // The password is needed when creating secure server sockets. It can |
41 // be null if only secure client sockets are used. | 41 // be null if only secure client sockets are used. |
42 const char* SSLFilter::password_ = NULL; | 42 const char* SSLFilter::password_ = NULL; |
43 | 43 |
| 44 // Forward declaration. |
| 45 static void ProcessFilter(Dart_Port dest_port_id, |
| 46 Dart_Port reply_port_id, |
| 47 Dart_CObject* message); |
| 48 |
| 49 NativeService SSLFilter::filter_service_("FilterService", ProcessFilter, 16); |
| 50 |
44 static const int kSSLFilterNativeFieldIndex = 0; | 51 static const int kSSLFilterNativeFieldIndex = 0; |
45 | 52 |
46 static SSLFilter* GetFilter(Dart_NativeArguments args) { | 53 static SSLFilter* GetFilter(Dart_NativeArguments args) { |
47 SSLFilter* filter; | 54 SSLFilter* filter; |
48 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 55 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
49 ASSERT(Dart_IsInstance(dart_this)); | 56 ASSERT(Dart_IsInstance(dart_this)); |
50 ThrowIfError(Dart_GetNativeInstanceField( | 57 ThrowIfError(Dart_GetNativeInstanceField( |
51 dart_this, | 58 dart_this, |
52 kSSLFilterNativeFieldIndex, | 59 kSSLFilterNativeFieldIndex, |
53 reinterpret_cast<intptr_t*>(&filter))); | 60 reinterpret_cast<intptr_t*>(&filter))); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 ThrowIfError(Dart_GetNativeArgument(args, 1)); | 177 ThrowIfError(Dart_GetNativeArgument(args, 1)); |
171 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { | 178 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { |
172 Dart_ThrowException(DartUtils::NewDartArgumentError( | 179 Dart_ThrowException(DartUtils::NewDartArgumentError( |
173 "Illegal argument to RegisterBadCertificateCallback")); | 180 "Illegal argument to RegisterBadCertificateCallback")); |
174 } | 181 } |
175 GetFilter(args)->RegisterBadCertificateCallback(callback); | 182 GetFilter(args)->RegisterBadCertificateCallback(callback); |
176 Dart_ExitScope(); | 183 Dart_ExitScope(); |
177 } | 184 } |
178 | 185 |
179 | 186 |
180 void FUNCTION_NAME(SecureSocket_ProcessBuffer)(Dart_NativeArguments args) { | |
181 Dart_EnterScope(); | |
182 Dart_Handle buffer_id_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | |
183 int64_t buffer_id = DartUtils::GetIntegerValue(buffer_id_object); | |
184 if (buffer_id < 0 || buffer_id >= SSLFilter::kNumBuffers) { | |
185 Dart_ThrowException(DartUtils::NewDartArgumentError( | |
186 "Illegal argument to ProcessBuffer")); | |
187 } | |
188 | |
189 intptr_t bytes_read = | |
190 GetFilter(args)->ProcessBuffer(static_cast<int>(buffer_id)); | |
191 Dart_SetReturnValue(args, Dart_NewInteger(bytes_read)); | |
192 Dart_ExitScope(); | |
193 } | |
194 | |
195 | |
196 void FUNCTION_NAME(SecureSocket_InitializeLibrary) | 187 void FUNCTION_NAME(SecureSocket_InitializeLibrary) |
197 (Dart_NativeArguments args) { | 188 (Dart_NativeArguments args) { |
198 Dart_EnterScope(); | 189 Dart_EnterScope(); |
199 Dart_Handle certificate_database_object = | 190 Dart_Handle certificate_database_object = |
200 ThrowIfError(Dart_GetNativeArgument(args, 0)); | 191 ThrowIfError(Dart_GetNativeArgument(args, 0)); |
201 // Check that the type is string, and get the UTF-8 C string value from it. | 192 // Check that the type is string, and get the UTF-8 C string value from it. |
202 const char* certificate_database = NULL; | 193 const char* certificate_database = NULL; |
203 if (Dart_IsString(certificate_database_object)) { | 194 if (Dart_IsString(certificate_database_object)) { |
204 ThrowIfError(Dart_StringToCString(certificate_database_object, | 195 ThrowIfError(Dart_StringToCString(certificate_database_object, |
205 &certificate_database)); | 196 &certificate_database)); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 | 231 |
241 | 232 |
242 void FUNCTION_NAME(SecureSocket_PeerCertificate) | 233 void FUNCTION_NAME(SecureSocket_PeerCertificate) |
243 (Dart_NativeArguments args) { | 234 (Dart_NativeArguments args) { |
244 Dart_EnterScope(); | 235 Dart_EnterScope(); |
245 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); | 236 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); |
246 Dart_ExitScope(); | 237 Dart_ExitScope(); |
247 } | 238 } |
248 | 239 |
249 | 240 |
| 241 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { |
| 242 Dart_EnterScope(); |
| 243 intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args)); |
| 244 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); |
| 245 Dart_ExitScope(); |
| 246 } |
| 247 |
| 248 |
| 249 /** |
| 250 * Pushes data through the SSL filter, reading and writing from circular |
| 251 * buffers shared with Dart. |
| 252 * |
| 253 * The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to |
| 254 * pass encrypted and plaintext data to and from the C++ SSLFilter object. |
| 255 * |
| 256 * ProcessFilter is called with a CObject array containing the pointer to |
| 257 * the SSLFilter, encoded as an int, and the start and end positions of the |
| 258 * valid data in the four circular buffers. The function only reads from |
| 259 * the valid data area of the input buffers, and only writes to the free |
| 260 * area of the output buffers. The function returns the new start and end |
| 261 * positions in the buffers, but it only updates start for input buffers, and |
| 262 * end for output buffers. Therefore, the Dart thread can simultaneously |
| 263 * write to the free space and end pointer of input buffers, and read from |
| 264 * the data space of output buffers, and modify the start pointer. |
| 265 * |
| 266 * When ProcessFilter returns, the Dart thread is responsible for combining |
| 267 * the updated pointers from Dart and C++, to make the new valid state of |
| 268 * the circular buffer. |
| 269 */ |
| 270 static void ProcessFilter(Dart_Port dest_port_id, |
| 271 Dart_Port reply_port_id, |
| 272 Dart_CObject* message) { |
| 273 CObjectArray args(message); |
| 274 CObjectIntptr filter_object(args[0]); |
| 275 SSLFilter* filter = reinterpret_cast<SSLFilter*>(filter_object.Value()); |
| 276 bool in_handshake = CObjectBool(args[1]).Value(); |
| 277 int starts[SSLFilter::kNumBuffers]; |
| 278 int ends[SSLFilter::kNumBuffers]; |
| 279 for (int i = 0; i < SSLFilter::kNumBuffers; ++i) { |
| 280 starts[i] = CObjectInt32(args[2 * i + 2]).Value(); |
| 281 ends[i] = CObjectInt32(args[2 * i + 3]).Value(); |
| 282 } |
| 283 |
| 284 filter->ProcessAllBuffers(starts, ends, in_handshake); |
| 285 |
| 286 for (int i = 0; i < SSLFilter::kNumBuffers; ++i) { |
| 287 args[2 * i + 2]->AsApiCObject()->value.as_int32 = starts[i]; |
| 288 args[2 * i + 3]->AsApiCObject()->value.as_int32 = ends[i]; |
| 289 } |
| 290 Dart_PostCObject(reply_port_id, args.AsApiCObject()); |
| 291 } |
| 292 |
| 293 |
| 294 void SSLFilter::ProcessAllBuffers(int starts[kNumBuffers], |
| 295 int ends[kNumBuffers], |
| 296 bool in_handshake) { |
| 297 for (int i = 0; i < kNumBuffers; ++i) { |
| 298 if (in_handshake && (i == kReadPlaintext || i == kWritePlaintext)) continue; |
| 299 int start = starts[i]; |
| 300 int end = ends[i]; |
| 301 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; |
| 302 switch (i) { |
| 303 case kReadPlaintext: |
| 304 case kWriteEncrypted: |
| 305 // Write data to the circular buffer's free space. If the buffer |
| 306 // is full, neither if statement is executed and nothing happens. |
| 307 if (start <= end) { |
| 308 // If the free space may be split into two segments, |
| 309 // then the first is [end, size), unless start == 0. |
| 310 // Then, since the last free byte is at position start - 2, |
| 311 // the interval is [end, size - 1). |
| 312 int buffer_end = (start == 0) ? size - 1 : size; |
| 313 int bytes = (i == kReadPlaintext) ? |
| 314 ProcessReadPlaintextBuffer(end, buffer_end) : |
| 315 ProcessWriteEncryptedBuffer(end, buffer_end); |
| 316 end += bytes; |
| 317 ASSERT(end <= size); |
| 318 if (end == size) end = 0; |
| 319 } |
| 320 if (start > end + 1) { |
| 321 int bytes = (i == kReadPlaintext) ? |
| 322 ProcessReadPlaintextBuffer(end, start - 1) : |
| 323 ProcessWriteEncryptedBuffer(end, start - 1); |
| 324 end += bytes; |
| 325 ASSERT(end < start); |
| 326 } |
| 327 ends[i] = end; |
| 328 break; |
| 329 case kReadEncrypted: |
| 330 // Read data from circular buffer. |
| 331 if (end < start) { |
| 332 // Data may be split into two segments. In this case, |
| 333 // the first is [start, size). |
| 334 int bytes = ProcessReadEncryptedBuffer(start, size); |
| 335 start += bytes; |
| 336 ASSERT(start <= size); |
| 337 if (start == size) start = 0; |
| 338 } |
| 339 if (start < end) { |
| 340 int bytes = ProcessReadEncryptedBuffer(start, end); |
| 341 start += bytes; |
| 342 ASSERT(start <= end); |
| 343 } |
| 344 starts[i] = start; |
| 345 break; |
| 346 case kWritePlaintext: |
| 347 if (end < start) { |
| 348 // Data is split into two segments, [start, size) and [0, end). |
| 349 int bytes = ProcessWritePlaintextBuffer(start, size, 0, end); |
| 350 start += bytes; |
| 351 if (start >= size) start -= size; |
| 352 } else { |
| 353 int bytes = ProcessWritePlaintextBuffer(start, end, 0, 0); |
| 354 start += bytes; |
| 355 ASSERT(start <= end); |
| 356 } |
| 357 starts[i] = start; |
| 358 break; |
| 359 default: |
| 360 UNREACHABLE(); |
| 361 } |
| 362 } |
| 363 } |
| 364 |
| 365 |
250 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) { | 366 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) { |
251 PRTime start_validity; | 367 PRTime start_validity; |
252 PRTime end_validity; | 368 PRTime end_validity; |
253 SECStatus status = | 369 SECStatus status = |
254 CERT_GetCertTimes(certificate, &start_validity, &end_validity); | 370 CERT_GetCertTimes(certificate, &start_validity, &end_validity); |
255 if (status != SECSuccess) { | 371 if (status != SECSuccess) { |
256 ThrowPRException("Cannot get validity times from certificate"); | 372 ThrowPRException("Cannot get validity times from certificate"); |
257 } | 373 } |
258 int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC; | 374 int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC; |
259 int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC; | 375 int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 | 416 |
301 InitializeBuffers(dart_this); | 417 InitializeBuffers(dart_this); |
302 filter_ = memio_CreateIOLayer(kMemioBufferSize); | 418 filter_ = memio_CreateIOLayer(kMemioBufferSize); |
303 } | 419 } |
304 | 420 |
305 | 421 |
306 void SSLFilter::InitializeBuffers(Dart_Handle dart_this) { | 422 void SSLFilter::InitializeBuffers(Dart_Handle dart_this) { |
307 // Create SSLFilter buffers as ExternalUint8Array objects. | 423 // Create SSLFilter buffers as ExternalUint8Array objects. |
308 Dart_Handle dart_buffers_object = ThrowIfError( | 424 Dart_Handle dart_buffers_object = ThrowIfError( |
309 Dart_GetField(dart_this, DartUtils::NewString("buffers"))); | 425 Dart_GetField(dart_this, DartUtils::NewString("buffers"))); |
310 Dart_Handle dart_buffer_object = | 426 Dart_Handle secure_filter_impl_class = |
311 Dart_ListGetAt(dart_buffers_object, kReadPlaintext); | 427 Dart_InstanceGetClass(dart_this); |
312 Dart_Handle external_buffer_class = | |
313 Dart_InstanceGetClass(dart_buffer_object); | |
314 Dart_Handle dart_buffer_size = ThrowIfError( | 428 Dart_Handle dart_buffer_size = ThrowIfError( |
315 Dart_GetField(external_buffer_class, DartUtils::NewString("SIZE"))); | 429 Dart_GetField(secure_filter_impl_class, DartUtils::NewString("SIZE"))); |
316 int64_t buffer_size = DartUtils::GetIntegerValue(dart_buffer_size); | 430 int64_t buffer_size = DartUtils::GetIntegerValue(dart_buffer_size); |
317 Dart_Handle dart_encrypted_buffer_size = ThrowIfError( | 431 Dart_Handle dart_encrypted_buffer_size = ThrowIfError( |
318 Dart_GetField(external_buffer_class, | 432 Dart_GetField(secure_filter_impl_class, |
319 DartUtils::NewString("ENCRYPTED_SIZE"))); | 433 DartUtils::NewString("ENCRYPTED_SIZE"))); |
320 int64_t encrypted_buffer_size = | 434 int64_t encrypted_buffer_size = |
321 DartUtils::GetIntegerValue(dart_encrypted_buffer_size); | 435 DartUtils::GetIntegerValue(dart_encrypted_buffer_size); |
322 if (buffer_size <= 0 || buffer_size > 1024 * 1024) { | 436 if (buffer_size <= 0 || buffer_size > 1024 * 1024) { |
323 Dart_ThrowException( | 437 Dart_ThrowException( |
324 DartUtils::NewString("Invalid buffer size in _ExternalBuffer")); | 438 DartUtils::NewString("Invalid buffer size in _ExternalBuffer")); |
325 } | 439 } |
326 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1024 * 1024) { | 440 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1024 * 1024) { |
327 Dart_ThrowException(DartUtils::NewString( | 441 Dart_ThrowException(DartUtils::NewString( |
328 "Invalid encrypted buffer size in _ExternalBuffer")); | 442 "Invalid encrypted buffer size in _ExternalBuffer")); |
329 } | 443 } |
330 buffer_size_ = static_cast<int>(buffer_size); | 444 buffer_size_ = static_cast<int>(buffer_size); |
331 encrypted_buffer_size_ = static_cast<int>(encrypted_buffer_size); | 445 encrypted_buffer_size_ = static_cast<int>(encrypted_buffer_size); |
332 | 446 |
333 | 447 |
334 Dart_Handle data_identifier = DartUtils::NewString("data"); | 448 Dart_Handle data_identifier = DartUtils::NewString("data"); |
335 for (int i = 0; i < kNumBuffers; ++i) { | 449 for (int i = 0; i < kNumBuffers; ++i) { |
336 int size = isEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; | 450 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; |
337 dart_buffer_objects_[i] = | 451 dart_buffer_objects_[i] = |
338 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i)); | 452 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i)); |
339 ASSERT(dart_buffer_objects_[i] != NULL); | 453 ASSERT(dart_buffer_objects_[i] != NULL); |
340 buffers_[i] = new uint8_t[size]; | 454 buffers_[i] = new uint8_t[size]; |
341 Dart_Handle data = ThrowIfError( | 455 Dart_Handle data = ThrowIfError( |
342 Dart_NewExternalTypedData(Dart_TypedData_kUint8, buffers_[i], size)); | 456 Dart_NewExternalTypedData(Dart_TypedData_kUint8, buffers_[i], size)); |
343 ThrowIfError( | 457 ThrowIfError( |
344 Dart_SetField(Dart_HandleFromPersistent(dart_buffer_objects_[i]), | 458 Dart_SetField(Dart_HandleFromPersistent(dart_buffer_objects_[i]), |
345 data_identifier, | 459 data_identifier, |
346 data)); | 460 data)); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 | 601 |
488 if (!is_server && certificate_name != NULL) { | 602 if (!is_server && certificate_name != NULL) { |
489 client_certificate_name_ = strdup(certificate_name); | 603 client_certificate_name_ = strdup(certificate_name); |
490 } | 604 } |
491 | 605 |
492 filter_ = SSL_ImportFD(NULL, filter_); | 606 filter_ = SSL_ImportFD(NULL, filter_); |
493 if (filter_ == NULL) { | 607 if (filter_ == NULL) { |
494 ThrowPRException("Failed SSL_ImportFD call"); | 608 ThrowPRException("Failed SSL_ImportFD call"); |
495 } | 609 } |
496 | 610 |
| 611 SSLVersionRange vrange; |
| 612 vrange.min = SSL_LIBRARY_VERSION_3_0; |
| 613 vrange.max = SSL_LIBRARY_VERSION_TLS_1_1; |
| 614 SSL_VersionRangeSet(filter_, &vrange); |
| 615 |
497 SECStatus status; | 616 SECStatus status; |
498 if (is_server) { | 617 if (is_server) { |
499 PK11_SetPasswordFunc(PasswordCallback); | 618 PK11_SetPasswordFunc(PasswordCallback); |
500 | 619 |
501 CERTCertificate* certificate = NULL; | 620 CERTCertificate* certificate = NULL; |
502 if (strstr(certificate_name, "CN=") != NULL) { | 621 if (strstr(certificate_name, "CN=") != NULL) { |
503 // Look up certificate using the distinguished name (DN) certificate_name. | 622 // Look up certificate using the distinguished name (DN) certificate_name. |
504 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB(); | 623 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB(); |
505 if (certificate_database == NULL) { | 624 if (certificate_database == NULL) { |
506 ThrowPRException("Certificate database cannot be loaded"); | 625 ThrowPRException("Certificate database cannot be loaded"); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 Dart_DeletePersistentHandle(string_start_); | 760 Dart_DeletePersistentHandle(string_start_); |
642 Dart_DeletePersistentHandle(string_length_); | 761 Dart_DeletePersistentHandle(string_length_); |
643 Dart_DeletePersistentHandle(handshake_complete_); | 762 Dart_DeletePersistentHandle(handshake_complete_); |
644 Dart_DeletePersistentHandle(bad_certificate_callback_); | 763 Dart_DeletePersistentHandle(bad_certificate_callback_); |
645 free(client_certificate_name_); | 764 free(client_certificate_name_); |
646 | 765 |
647 PR_Close(filter_); | 766 PR_Close(filter_); |
648 } | 767 } |
649 | 768 |
650 | 769 |
651 intptr_t SSLFilter::ProcessBuffer(int buffer_index) { | 770 intptr_t SSLFilter::ProcessReadPlaintextBuffer(int start, int end) { |
652 int size = isEncrypted(buffer_index) ? encrypted_buffer_size_ : buffer_size_; | 771 int length = end - start; |
653 Dart_Handle buffer_object = | |
654 Dart_HandleFromPersistent(dart_buffer_objects_[buffer_index]); | |
655 Dart_Handle start_object = ThrowIfError( | |
656 Dart_GetField(buffer_object, Dart_HandleFromPersistent(string_start_))); | |
657 Dart_Handle length_object = ThrowIfError( | |
658 Dart_GetField(buffer_object, Dart_HandleFromPersistent(string_length_))); | |
659 int64_t unsafe_start = DartUtils::GetIntegerValue(start_object); | |
660 int64_t unsafe_length = DartUtils::GetIntegerValue(length_object); | |
661 ASSERT(unsafe_start >= 0); | |
662 ASSERT(unsafe_start < size); | |
663 ASSERT(unsafe_length >= 0); | |
664 ASSERT(unsafe_length <= size); | |
665 int start = static_cast<int>(unsafe_start); | |
666 int length = static_cast<int>(unsafe_length); | |
667 uint8_t* buffer = buffers_[buffer_index]; | |
668 | |
669 int bytes_processed = 0; | 772 int bytes_processed = 0; |
670 switch (buffer_index) { | 773 if (length > 0) { |
671 case kReadPlaintext: { | 774 bytes_processed = PR_Read(filter_, |
672 int bytes_free = size - start - length; | 775 buffers_[kReadPlaintext] + start, |
673 bytes_processed = PR_Read(filter_, | 776 length); |
674 buffer + start + length, | 777 if (bytes_processed < 0) { |
675 bytes_free); | 778 ASSERT(bytes_processed == -1); |
676 if (bytes_processed < 0) { | 779 PRErrorCode pr_error = PR_GetError(); |
677 ASSERT(bytes_processed == -1); | 780 if (PR_WOULD_BLOCK_ERROR != pr_error) { |
678 // TODO(whesse): Handle unexpected errors here. | 781 // TODO(11383): Handle unexpected errors here. |
679 PRErrorCode pr_error = PR_GetError(); | 782 FATAL("Error reading plaintext from SSLFilter"); |
680 if (PR_WOULD_BLOCK_ERROR != pr_error) { | |
681 ThrowPRException("Error reading plaintext from SSLFilter"); | |
682 } | |
683 bytes_processed = 0; | |
684 } | 783 } |
685 break; | 784 bytes_processed = 0; |
686 } | |
687 | |
688 case kWriteEncrypted: { | |
689 const uint8_t* buf1; | |
690 const uint8_t* buf2; | |
691 unsigned int len1; | |
692 unsigned int len2; | |
693 int bytes_free = size - start - length; | |
694 memio_Private* secret = memio_GetSecret(filter_); | |
695 memio_GetWriteParams(secret, &buf1, &len1, &buf2, &len2); | |
696 int bytes_to_send = | |
697 dart::Utils::Minimum(len1, static_cast<unsigned>(bytes_free)); | |
698 if (bytes_to_send > 0) { | |
699 memmove(buffer + start + length, buf1, bytes_to_send); | |
700 bytes_processed = bytes_to_send; | |
701 } | |
702 bytes_to_send = dart::Utils::Minimum(len2, | |
703 static_cast<unsigned>(bytes_free - bytes_processed)); | |
704 if (bytes_to_send > 0) { | |
705 memmove(buffer + start + length + bytes_processed, buf2, | |
706 bytes_to_send); | |
707 bytes_processed += bytes_to_send; | |
708 } | |
709 if (bytes_processed > 0) { | |
710 memio_PutWriteResult(secret, bytes_processed); | |
711 } | |
712 break; | |
713 } | |
714 | |
715 case kReadEncrypted: { | |
716 if (length > 0) { | |
717 bytes_processed = length; | |
718 memio_Private* secret = memio_GetSecret(filter_); | |
719 uint8_t* filter_buf; | |
720 int free_bytes = memio_GetReadParams(secret, &filter_buf); | |
721 if (free_bytes < bytes_processed) bytes_processed = free_bytes; | |
722 memmove(filter_buf, | |
723 buffer + start, | |
724 bytes_processed); | |
725 memio_PutReadResult(secret, bytes_processed); | |
726 } | |
727 break; | |
728 } | |
729 | |
730 case kWritePlaintext: { | |
731 if (length > 0) { | |
732 bytes_processed = PR_Write(filter_, | |
733 buffer + start, | |
734 length); | |
735 } | |
736 | |
737 if (bytes_processed < 0) { | |
738 ASSERT(bytes_processed == -1); | |
739 // TODO(whesse): Handle unexpected errors here. | |
740 PRErrorCode pr_error = PR_GetError(); | |
741 if (PR_WOULD_BLOCK_ERROR != pr_error) { | |
742 ThrowPRException("Error reading plaintext from SSLFilter"); | |
743 } | |
744 bytes_processed = 0; | |
745 } | |
746 break; | |
747 } | 785 } |
748 } | 786 } |
749 return bytes_processed; | 787 return bytes_processed; |
750 } | 788 } |
751 | 789 |
| 790 |
| 791 intptr_t SSLFilter::ProcessWritePlaintextBuffer(int start1, int end1, |
| 792 int start2, int end2) { |
| 793 PRIOVec ranges[2]; |
| 794 uint8_t* buffer = buffers_[kWritePlaintext]; |
| 795 ranges[0].iov_base = reinterpret_cast<char*>(buffer + start1); |
| 796 ranges[0].iov_len = end1 - start1; |
| 797 ranges[1].iov_base = reinterpret_cast<char*>(buffer + start2); |
| 798 ranges[1].iov_len = end2 - start2; |
| 799 int bytes_processed = PR_Writev(filter_, ranges, 2, PR_INTERVAL_NO_TIMEOUT); |
| 800 if (bytes_processed < 0) { |
| 801 ASSERT(bytes_processed == -1); |
| 802 PRErrorCode pr_error = PR_GetError(); |
| 803 if (PR_WOULD_BLOCK_ERROR != pr_error) { |
| 804 // TODO(11383): Handle unexpected errors here. |
| 805 FATAL("Error reading plaintext from SSLFilter"); |
| 806 } |
| 807 bytes_processed = 0; |
| 808 } |
| 809 return bytes_processed; |
| 810 } |
| 811 |
| 812 |
| 813 intptr_t SSLFilter::ProcessReadEncryptedBuffer(int start, int end) { |
| 814 int length = end - start; |
| 815 int bytes_processed = 0; |
| 816 if (length > 0) { |
| 817 memio_Private* secret = memio_GetSecret(filter_); |
| 818 uint8_t* filter_buf; |
| 819 int free_bytes = memio_GetReadParams(secret, &filter_buf); |
| 820 bytes_processed = dart::Utils::Minimum(length, free_bytes); |
| 821 memmove(filter_buf, buffers_[kReadEncrypted] + start, bytes_processed); |
| 822 memio_PutReadResult(secret, bytes_processed); |
| 823 } |
| 824 return bytes_processed; |
| 825 } |
| 826 |
| 827 |
| 828 intptr_t SSLFilter::ProcessWriteEncryptedBuffer(int start, int end) { |
| 829 int length = end - start; |
| 830 int bytes_processed = 0; |
| 831 if (length > 0) { |
| 832 uint8_t* buffer = buffers_[kWriteEncrypted]; |
| 833 const uint8_t* buf1; |
| 834 const uint8_t* buf2; |
| 835 unsigned int len1; |
| 836 unsigned int len2; |
| 837 memio_Private* secret = memio_GetSecret(filter_); |
| 838 memio_GetWriteParams(secret, &buf1, &len1, &buf2, &len2); |
| 839 int bytes_to_send = |
| 840 dart::Utils::Minimum(len1, static_cast<unsigned>(length)); |
| 841 if (bytes_to_send > 0) { |
| 842 memmove(buffer + start, buf1, bytes_to_send); |
| 843 bytes_processed = bytes_to_send; |
| 844 } |
| 845 bytes_to_send = dart::Utils::Minimum(len2, |
| 846 static_cast<unsigned>(length - bytes_processed)); |
| 847 if (bytes_to_send > 0) { |
| 848 memmove(buffer + start + bytes_processed, buf2, bytes_to_send); |
| 849 bytes_processed += bytes_to_send; |
| 850 } |
| 851 if (bytes_processed > 0) { |
| 852 memio_PutWriteResult(secret, bytes_processed); |
| 853 } |
| 854 } |
| 855 return bytes_processed; |
| 856 } |
| 857 |
| 858 |
| 859 Dart_Port SSLFilter::GetServicePort() { |
| 860 return filter_service_.GetServicePort(); |
| 861 } |
| 862 |
| 863 |
| 864 void FUNCTION_NAME(SecureSocket_NewServicePort)(Dart_NativeArguments args) { |
| 865 Dart_EnterScope(); |
| 866 Dart_SetReturnValue(args, Dart_Null()); |
| 867 Dart_Port service_port = SSLFilter::GetServicePort(); |
| 868 if (service_port != ILLEGAL_PORT) { |
| 869 // Return a send port for the service port. |
| 870 Dart_Handle send_port = Dart_NewSendPort(service_port); |
| 871 Dart_SetReturnValue(args, send_port); |
| 872 } |
| 873 Dart_ExitScope(); |
| 874 } |
| 875 |
| 876 |
752 } // namespace bin | 877 } // namespace bin |
753 } // namespace dart | 878 } // namespace dart |
OLD | NEW |