Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: runtime/bin/secure_socket.cc

Issue 16858011: dart:io | Enable multithreaded secure networking encryption. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address all comments Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/secure_socket.h ('k') | runtime/bin/secure_socket_patch.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/bin/secure_socket.h ('k') | runtime/bin/secure_socket_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698