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 22 matching lines...) Expand all Loading... | |
33 | 33 |
34 namespace dart { | 34 namespace dart { |
35 namespace bin { | 35 namespace bin { |
36 | 36 |
37 bool SSLFilter::library_initialized_ = false; | 37 bool SSLFilter::library_initialized_ = false; |
38 dart::Mutex SSLFilter::mutex_; // To protect library initialization. | 38 dart::Mutex SSLFilter::mutex_; // To protect library initialization. |
39 // The password is needed when creating secure server sockets. It can | 39 // The password is needed when creating secure server sockets. It can |
40 // be null if only secure client sockets are used. | 40 // be null if only secure client sockets are used. |
41 const char* SSLFilter::password_ = NULL; | 41 const char* SSLFilter::password_ = NULL; |
42 | 42 |
43 // Forward declaration. | |
44 static void ProcessFilter(Dart_Port dest_port_id, | |
45 Dart_Port reply_port_id, | |
46 Dart_CObject* message); | |
47 | |
48 NativeService SSLFilter::filter_service_("FilterService", ProcessFilter, 16); | |
49 | |
43 static const int kSSLFilterNativeFieldIndex = 0; | 50 static const int kSSLFilterNativeFieldIndex = 0; |
44 | 51 |
45 static SSLFilter* GetFilter(Dart_NativeArguments args) { | 52 static SSLFilter* GetFilter(Dart_NativeArguments args) { |
46 SSLFilter* filter; | 53 SSLFilter* filter; |
47 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 54 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
48 ASSERT(Dart_IsInstance(dart_this)); | 55 ASSERT(Dart_IsInstance(dart_this)); |
49 ThrowIfError(Dart_GetNativeInstanceField( | 56 ThrowIfError(Dart_GetNativeInstanceField( |
50 dart_this, | 57 dart_this, |
51 kSSLFilterNativeFieldIndex, | 58 kSSLFilterNativeFieldIndex, |
52 reinterpret_cast<intptr_t*>(&filter))); | 59 reinterpret_cast<intptr_t*>(&filter))); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 ThrowIfError(Dart_GetNativeArgument(args, 1)); | 161 ThrowIfError(Dart_GetNativeArgument(args, 1)); |
155 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { | 162 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { |
156 Dart_ThrowException(DartUtils::NewDartArgumentError( | 163 Dart_ThrowException(DartUtils::NewDartArgumentError( |
157 "Illegal argument to RegisterBadCertificateCallback")); | 164 "Illegal argument to RegisterBadCertificateCallback")); |
158 } | 165 } |
159 GetFilter(args)->RegisterBadCertificateCallback(callback); | 166 GetFilter(args)->RegisterBadCertificateCallback(callback); |
160 Dart_ExitScope(); | 167 Dart_ExitScope(); |
161 } | 168 } |
162 | 169 |
163 | 170 |
164 void FUNCTION_NAME(SecureSocket_ProcessBuffer)(Dart_NativeArguments args) { | |
165 Dart_EnterScope(); | |
166 Dart_Handle buffer_id_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | |
167 int64_t buffer_id = DartUtils::GetIntegerValue(buffer_id_object); | |
168 if (buffer_id < 0 || buffer_id >= SSLFilter::kNumBuffers) { | |
169 Dart_ThrowException(DartUtils::NewDartArgumentError( | |
170 "Illegal argument to ProcessBuffer")); | |
171 } | |
172 | |
173 intptr_t bytes_read = | |
174 GetFilter(args)->ProcessBuffer(static_cast<int>(buffer_id)); | |
175 Dart_SetReturnValue(args, Dart_NewInteger(bytes_read)); | |
176 Dart_ExitScope(); | |
177 } | |
178 | |
179 | |
180 void FUNCTION_NAME(SecureSocket_InitializeLibrary) | 171 void FUNCTION_NAME(SecureSocket_InitializeLibrary) |
181 (Dart_NativeArguments args) { | 172 (Dart_NativeArguments args) { |
182 Dart_EnterScope(); | 173 Dart_EnterScope(); |
183 Dart_Handle certificate_database_object = | 174 Dart_Handle certificate_database_object = |
184 ThrowIfError(Dart_GetNativeArgument(args, 0)); | 175 ThrowIfError(Dart_GetNativeArgument(args, 0)); |
185 // Check that the type is string, and get the UTF-8 C string value from it. | 176 // Check that the type is string, and get the UTF-8 C string value from it. |
186 const char* certificate_database = NULL; | 177 const char* certificate_database = NULL; |
187 if (Dart_IsString(certificate_database_object)) { | 178 if (Dart_IsString(certificate_database_object)) { |
188 ThrowIfError(Dart_StringToCString(certificate_database_object, | 179 ThrowIfError(Dart_StringToCString(certificate_database_object, |
189 &certificate_database)); | 180 &certificate_database)); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 | 215 |
225 | 216 |
226 void FUNCTION_NAME(SecureSocket_PeerCertificate) | 217 void FUNCTION_NAME(SecureSocket_PeerCertificate) |
227 (Dart_NativeArguments args) { | 218 (Dart_NativeArguments args) { |
228 Dart_EnterScope(); | 219 Dart_EnterScope(); |
229 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); | 220 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); |
230 Dart_ExitScope(); | 221 Dart_ExitScope(); |
231 } | 222 } |
232 | 223 |
233 | 224 |
225 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { | |
226 Dart_EnterScope(); | |
227 intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args)); | |
228 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); | |
229 Dart_ExitScope(); | |
230 } | |
231 | |
232 | |
233 /** | |
Søren Gjesse
2013/06/17 07:31:07
Nice comment
Bill Hesse
2013/06/20 14:56:26
Thanks a lot
| |
234 * Pushes data through the SSL filter, reading and writing from circular | |
235 * buffers shared with Dart. | |
236 * | |
237 * The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to | |
238 * pass encrypted and plaintext data to and from the C++ SSLFilter object. | |
239 * | |
240 * ProcessFilter is called with a CObject array containing the pointer to | |
241 * the SSLFilter, encoded as an int, and the start and end positions of the | |
242 * valid data in the four circular buffers. The function only reads from | |
243 * the valid data area of the input buffers, and only writes to the free | |
244 * area of the output buffers. The function returns the new start and end | |
245 * positions in the buffers, but it only updates start for input buffers, and | |
246 * end for output buffers. Therefore, the Dart thread can simultaneously | |
247 * write to the free space and end pointer of input buffers, and read from | |
248 * the data space of output buffers, and modify the start pointer. | |
249 * | |
250 * When ProcessFilter returns, the Dart thread is responsible for combining | |
251 * the updated pointers from Dart and C++, to make the new valid state of | |
252 * the circular buffer. | |
253 */ | |
254 static void ProcessFilter(Dart_Port dest_port_id, | |
255 Dart_Port reply_port_id, | |
256 Dart_CObject* message) { | |
257 CObjectArray args(message); | |
258 CObjectIntptr filter_object(args[0]); | |
259 SSLFilter* filter = reinterpret_cast<SSLFilter*>(filter_object.Value()); | |
260 bool in_handshake = CObjectBool(args[1]).Value(); | |
261 int starts[SSLFilter::kNumBuffers]; | |
262 int ends[SSLFilter::kNumBuffers]; | |
263 for (int i = 0; i < SSLFilter::kNumBuffers; ++i) { | |
264 starts[i] = CObjectInt32(args[2*i + 2]).Value(); | |
Søren Gjesse
2013/06/17 07:31:07
We normally have space around all binary operators
Bill Hesse
2013/06/20 14:56:26
Done.
| |
265 ends[i] = CObjectInt32(args[2*i + 3]).Value(); | |
266 } | |
267 | |
268 filter->ProcessAllBuffers(starts, ends, in_handshake); | |
269 | |
270 for (int i = 0; i < SSLFilter::kNumBuffers; ++i) { | |
Søren Gjesse
2013/06/17 07:31:07
You could "cheat" here and just update the int val
Bill Hesse
2013/06/20 14:56:26
Done.
| |
271 args.SetAt(2*i + 2, new CObjectInt32(CObject::NewInt32(starts[i]))); | |
272 args.SetAt(2*i + 3, new CObjectInt32(CObject::NewInt32(ends[i]))); | |
273 } | |
274 Dart_PostCObject(reply_port_id, args.AsApiCObject()); | |
275 } | |
276 | |
277 | |
278 void SSLFilter::ProcessAllBuffers(int starts[kNumBuffers], | |
279 int ends[kNumBuffers], | |
280 bool in_handshake) { | |
281 for (int i = 0; i < kNumBuffers; ++i) { | |
282 if (in_handshake && (i == kReadPlaintext || i == kWritePlaintext)) continue; | |
283 int start = starts[i]; | |
284 int end = ends[i]; | |
285 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; | |
286 switch (i) { | |
287 case kReadPlaintext: | |
288 case kWriteEncrypted: | |
Søren Gjesse
2013/06/17 07:31:07
Maybe add an overall comment here: "Write data to
Bill Hesse
2013/06/20 14:56:26
Done.
| |
289 if (start <= end) { | |
Søren Gjesse
2013/06/17 07:31:07
If start == 0 this is not two segments after all.
Bill Hesse
2013/06/20 14:56:26
Or if it equals 1. I think the comments are enoug
| |
290 // Free space is split into two segments. | |
Søren Gjesse
2013/06/17 07:31:07
Please explain the "or" (when is the last element
Bill Hesse
2013/06/20 14:56:26
Done.
| |
291 // The first is [end, size - 1) or [end, size). | |
292 int buffer_end = (start == 0) ? size - 1 : size; | |
293 int bytes = ProcessBuffer(i, end, buffer_end); | |
294 end += bytes; | |
295 ASSERT(end <= size); | |
296 if (end == size) end = 0; | |
297 } | |
298 if (start > end + 1) { | |
299 int bytes = ProcessBuffer(i, end, start - 1); | |
300 end += bytes; | |
301 ASSERT(end < start); | |
302 } | |
303 ends[i] = end; | |
304 break; | |
305 case kReadEncrypted: | |
306 case kWritePlaintext: | |
Søren Gjesse
2013/06/17 07:31:07
Overall comment here: "Read data from buffer"
Bill Hesse
2013/06/20 14:56:26
Done.
| |
307 if (end < start) { | |
308 // Data is split into two segments. | |
309 // The first is [start, size). | |
310 int bytes = ProcessBuffer(i, start, size); | |
311 start += bytes; | |
312 ASSERT(start <= size); | |
313 if (start == size) start = 0; | |
314 } | |
315 if (start < end) { | |
316 int bytes = ProcessBuffer(i, start, end); | |
317 start += bytes; | |
318 ASSERT(start <= end); | |
319 } | |
320 starts[i] = start; | |
321 break; | |
322 default: | |
323 UNREACHABLE(); | |
324 } | |
325 } | |
326 } | |
327 | |
328 | |
234 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) { | 329 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) { |
235 PRTime start_validity; | 330 PRTime start_validity; |
236 PRTime end_validity; | 331 PRTime end_validity; |
237 SECStatus status = | 332 SECStatus status = |
238 CERT_GetCertTimes(certificate, &start_validity, &end_validity); | 333 CERT_GetCertTimes(certificate, &start_validity, &end_validity); |
239 if (status != SECSuccess) { | 334 if (status != SECSuccess) { |
240 ThrowPRException("Cannot get validity times from certificate"); | 335 ThrowPRException("Cannot get validity times from certificate"); |
241 } | 336 } |
242 int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC; | 337 int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC; |
243 int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC; | 338 int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 | 379 |
285 InitializeBuffers(dart_this); | 380 InitializeBuffers(dart_this); |
286 filter_ = memio_CreateIOLayer(kMemioBufferSize); | 381 filter_ = memio_CreateIOLayer(kMemioBufferSize); |
287 } | 382 } |
288 | 383 |
289 | 384 |
290 void SSLFilter::InitializeBuffers(Dart_Handle dart_this) { | 385 void SSLFilter::InitializeBuffers(Dart_Handle dart_this) { |
291 // Create SSLFilter buffers as ExternalUint8Array objects. | 386 // Create SSLFilter buffers as ExternalUint8Array objects. |
292 Dart_Handle dart_buffers_object = ThrowIfError( | 387 Dart_Handle dart_buffers_object = ThrowIfError( |
293 Dart_GetField(dart_this, DartUtils::NewString("buffers"))); | 388 Dart_GetField(dart_this, DartUtils::NewString("buffers"))); |
294 Dart_Handle dart_buffer_object = | 389 Dart_Handle secure_filter_impl_class = |
295 Dart_ListGetAt(dart_buffers_object, kReadPlaintext); | 390 Dart_InstanceGetClass(dart_this); |
296 Dart_Handle external_buffer_class = | |
297 Dart_InstanceGetClass(dart_buffer_object); | |
298 Dart_Handle dart_buffer_size = ThrowIfError( | 391 Dart_Handle dart_buffer_size = ThrowIfError( |
299 Dart_GetField(external_buffer_class, DartUtils::NewString("SIZE"))); | 392 Dart_GetField(secure_filter_impl_class, DartUtils::NewString("SIZE"))); |
300 int64_t buffer_size = DartUtils::GetIntegerValue(dart_buffer_size); | 393 int64_t buffer_size = DartUtils::GetIntegerValue(dart_buffer_size); |
301 Dart_Handle dart_encrypted_buffer_size = ThrowIfError( | 394 Dart_Handle dart_encrypted_buffer_size = ThrowIfError( |
302 Dart_GetField(external_buffer_class, | 395 Dart_GetField(secure_filter_impl_class, |
303 DartUtils::NewString("ENCRYPTED_SIZE"))); | 396 DartUtils::NewString("ENCRYPTED_SIZE"))); |
304 int64_t encrypted_buffer_size = | 397 int64_t encrypted_buffer_size = |
305 DartUtils::GetIntegerValue(dart_encrypted_buffer_size); | 398 DartUtils::GetIntegerValue(dart_encrypted_buffer_size); |
306 if (buffer_size <= 0 || buffer_size > 1024 * 1024) { | 399 if (buffer_size <= 0 || buffer_size > 1024 * 1024) { |
307 Dart_ThrowException( | 400 Dart_ThrowException( |
308 DartUtils::NewString("Invalid buffer size in _ExternalBuffer")); | 401 DartUtils::NewString("Invalid buffer size in _ExternalBuffer")); |
309 } | 402 } |
310 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1024 * 1024) { | 403 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1024 * 1024) { |
311 Dart_ThrowException(DartUtils::NewString( | 404 Dart_ThrowException(DartUtils::NewString( |
312 "Invalid encrypted buffer size in _ExternalBuffer")); | 405 "Invalid encrypted buffer size in _ExternalBuffer")); |
313 } | 406 } |
314 buffer_size_ = static_cast<int>(buffer_size); | 407 buffer_size_ = static_cast<int>(buffer_size); |
315 encrypted_buffer_size_ = static_cast<int>(encrypted_buffer_size); | 408 encrypted_buffer_size_ = static_cast<int>(encrypted_buffer_size); |
316 | 409 |
317 | 410 |
318 Dart_Handle data_identifier = DartUtils::NewString("data"); | 411 Dart_Handle data_identifier = DartUtils::NewString("data"); |
319 for (int i = 0; i < kNumBuffers; ++i) { | 412 for (int i = 0; i < kNumBuffers; ++i) { |
320 int size = isEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; | 413 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; |
321 dart_buffer_objects_[i] = | 414 dart_buffer_objects_[i] = |
322 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i)); | 415 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i)); |
323 ASSERT(dart_buffer_objects_[i] != NULL); | 416 ASSERT(dart_buffer_objects_[i] != NULL); |
324 buffers_[i] = new uint8_t[size]; | 417 buffers_[i] = new uint8_t[size]; |
325 Dart_Handle data = ThrowIfError( | 418 Dart_Handle data = ThrowIfError( |
326 Dart_NewExternalTypedData(Dart_TypedData_kUint8, buffers_[i], size)); | 419 Dart_NewExternalTypedData(Dart_TypedData_kUint8, buffers_[i], size)); |
327 ThrowIfError( | 420 ThrowIfError( |
328 Dart_SetField(Dart_HandleFromPersistent(dart_buffer_objects_[i]), | 421 Dart_SetField(Dart_HandleFromPersistent(dart_buffer_objects_[i]), |
329 data_identifier, | 422 data_identifier, |
330 data)); | 423 data)); |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
619 Dart_DeletePersistentHandle(string_start_); | 712 Dart_DeletePersistentHandle(string_start_); |
620 Dart_DeletePersistentHandle(string_length_); | 713 Dart_DeletePersistentHandle(string_length_); |
621 Dart_DeletePersistentHandle(handshake_complete_); | 714 Dart_DeletePersistentHandle(handshake_complete_); |
622 Dart_DeletePersistentHandle(bad_certificate_callback_); | 715 Dart_DeletePersistentHandle(bad_certificate_callback_); |
623 free(client_certificate_name_); | 716 free(client_certificate_name_); |
624 | 717 |
625 PR_Close(filter_); | 718 PR_Close(filter_); |
626 } | 719 } |
627 | 720 |
628 | 721 |
629 intptr_t SSLFilter::ProcessBuffer(int buffer_index) { | 722 intptr_t SSLFilter::ProcessBuffer(int buffer_index, int start, int end) { |
Søren Gjesse
2013/06/17 07:31:07
You don't need for this CL, but how about just spl
Bill Hesse
2013/06/20 14:56:26
Done.
| |
630 int size = isEncrypted(buffer_index) ? encrypted_buffer_size_ : buffer_size_; | 723 int length = end - start; |
631 Dart_Handle buffer_object = | 724 int bytes_processed = 0; |
632 Dart_HandleFromPersistent(dart_buffer_objects_[buffer_index]); | 725 // The kWritePlaintext case must be called to push data through the filter. |
633 Dart_Handle start_object = ThrowIfError( | 726 if (length > 0 || buffer_index == kWritePlaintext) { |
634 Dart_GetField(buffer_object, Dart_HandleFromPersistent(string_start_))); | 727 uint8_t* buffer = buffers_[buffer_index]; |
635 Dart_Handle length_object = ThrowIfError( | 728 switch (buffer_index) { |
636 Dart_GetField(buffer_object, Dart_HandleFromPersistent(string_length_))); | 729 case kReadPlaintext: { |
637 int64_t unsafe_start = DartUtils::GetIntegerValue(start_object); | 730 bytes_processed = PR_Read(filter_, |
638 int64_t unsafe_length = DartUtils::GetIntegerValue(length_object); | 731 buffer + start, |
639 ASSERT(unsafe_start >= 0); | 732 length); |
640 ASSERT(unsafe_start < size); | 733 if (bytes_processed < 0) { |
641 ASSERT(unsafe_length >= 0); | 734 ASSERT(bytes_processed == -1); |
642 ASSERT(unsafe_length <= size); | 735 // TODO(whesse): Handle unexpected errors here. |
643 int start = static_cast<int>(unsafe_start); | 736 PRErrorCode pr_error = PR_GetError(); |
644 int length = static_cast<int>(unsafe_length); | 737 if (PR_WOULD_BLOCK_ERROR != pr_error) { |
645 uint8_t* buffer = buffers_[buffer_index]; | 738 // TODO(whesse): Handle errors |
Søren Gjesse
2013/06/17 07:31:07
Please open an issue on this.
Bill Hesse
2013/06/20 14:56:26
Done.
| |
739 FATAL("Error reading plaintext from SSLFilter"); | |
740 } | |
741 bytes_processed = 0; | |
742 } | |
743 break; | |
744 } | |
646 | 745 |
647 int bytes_processed = 0; | 746 case kWriteEncrypted: { |
648 switch (buffer_index) { | 747 const uint8_t* buf1; |
649 case kReadPlaintext: { | 748 const uint8_t* buf2; |
650 int bytes_free = size - start - length; | 749 unsigned int len1; |
651 bytes_processed = PR_Read(filter_, | 750 unsigned int len2; |
652 buffer + start + length, | 751 memio_Private* secret = memio_GetSecret(filter_); |
653 bytes_free); | 752 memio_GetWriteParams(secret, &buf1, &len1, &buf2, &len2); |
654 if (bytes_processed < 0) { | 753 int bytes_to_send = |
655 ASSERT(bytes_processed == -1); | 754 dart::Utils::Minimum(len1, static_cast<unsigned>(length)); |
656 // TODO(whesse): Handle unexpected errors here. | 755 if (bytes_to_send > 0) { |
657 PRErrorCode pr_error = PR_GetError(); | 756 memmove(buffer + start, buf1, bytes_to_send); |
658 if (PR_WOULD_BLOCK_ERROR != pr_error) { | 757 bytes_processed = bytes_to_send; |
659 ThrowPRException("Error reading plaintext from SSLFilter"); | |
660 } | 758 } |
661 bytes_processed = 0; | 759 bytes_to_send = dart::Utils::Minimum(len2, |
760 static_cast<unsigned>(length - bytes_processed)); | |
761 if (bytes_to_send > 0) { | |
762 memmove(buffer + start + bytes_processed, buf2, bytes_to_send); | |
763 bytes_processed += bytes_to_send; | |
764 } | |
765 if (bytes_processed > 0) { | |
766 memio_PutWriteResult(secret, bytes_processed); | |
767 } | |
768 break; | |
662 } | 769 } |
663 break; | |
664 } | |
665 | 770 |
666 case kWriteEncrypted: { | 771 case kReadEncrypted: { |
667 const uint8_t* buf1; | |
668 const uint8_t* buf2; | |
669 unsigned int len1; | |
670 unsigned int len2; | |
671 int bytes_free = size - start - length; | |
672 memio_Private* secret = memio_GetSecret(filter_); | |
673 memio_GetWriteParams(secret, &buf1, &len1, &buf2, &len2); | |
674 int bytes_to_send = | |
675 dart::Utils::Minimum(len1, static_cast<unsigned>(bytes_free)); | |
676 if (bytes_to_send > 0) { | |
677 memmove(buffer + start + length, buf1, bytes_to_send); | |
678 bytes_processed = bytes_to_send; | |
679 } | |
680 bytes_to_send = dart::Utils::Minimum(len2, | |
681 static_cast<unsigned>(bytes_free - bytes_processed)); | |
682 if (bytes_to_send > 0) { | |
683 memmove(buffer + start + length + bytes_processed, buf2, | |
684 bytes_to_send); | |
685 bytes_processed += bytes_to_send; | |
686 } | |
687 if (bytes_processed > 0) { | |
688 memio_PutWriteResult(secret, bytes_processed); | |
689 } | |
690 break; | |
691 } | |
692 | |
693 case kReadEncrypted: { | |
694 if (length > 0) { | |
695 bytes_processed = length; | |
696 memio_Private* secret = memio_GetSecret(filter_); | 772 memio_Private* secret = memio_GetSecret(filter_); |
697 uint8_t* filter_buf; | 773 uint8_t* filter_buf; |
698 int free_bytes = memio_GetReadParams(secret, &filter_buf); | 774 int free_bytes = memio_GetReadParams(secret, &filter_buf); |
699 if (free_bytes < bytes_processed) bytes_processed = free_bytes; | 775 bytes_processed = dart::Utils::Minimum(length, free_bytes); |
700 memmove(filter_buf, | 776 memmove(filter_buf, buffer + start, bytes_processed); |
701 buffer + start, | |
702 bytes_processed); | |
703 memio_PutReadResult(secret, bytes_processed); | 777 memio_PutReadResult(secret, bytes_processed); |
704 } | 778 break; |
705 break; | |
706 } | |
707 | |
708 case kWritePlaintext: { | |
709 if (length > 0) { | |
710 bytes_processed = PR_Write(filter_, | |
711 buffer + start, | |
712 length); | |
713 } | 779 } |
714 | 780 |
715 if (bytes_processed < 0) { | 781 case kWritePlaintext: { |
716 ASSERT(bytes_processed == -1); | 782 bytes_processed = PR_Write(filter_, buffer + start, length); |
717 // TODO(whesse): Handle unexpected errors here. | 783 if (bytes_processed < 0) { |
718 PRErrorCode pr_error = PR_GetError(); | 784 ASSERT(bytes_processed == -1); |
719 if (PR_WOULD_BLOCK_ERROR != pr_error) { | 785 // TODO(whesse): Handle unexpected errors here. |
720 ThrowPRException("Error reading plaintext from SSLFilter"); | 786 PRErrorCode pr_error = PR_GetError(); |
787 if (PR_WOULD_BLOCK_ERROR != pr_error) { | |
788 // TODO(whesse): Handle errors | |
789 FATAL("Error reading plaintext from SSLFilter"); | |
790 } | |
791 bytes_processed = 0; | |
721 } | 792 } |
722 bytes_processed = 0; | 793 break; |
723 } | 794 } |
724 break; | |
725 } | 795 } |
726 } | 796 } |
727 return bytes_processed; | 797 return bytes_processed; |
728 } | 798 } |
729 | 799 |
800 | |
801 Dart_Port SSLFilter::GetServicePort() { | |
802 return filter_service_.GetServicePort(); | |
803 } | |
804 | |
805 | |
806 void FUNCTION_NAME(SecureSocket_NewServicePort)(Dart_NativeArguments args) { | |
807 Dart_EnterScope(); | |
808 Dart_SetReturnValue(args, Dart_Null()); | |
809 Dart_Port service_port = SSLFilter::GetServicePort(); | |
810 if (service_port != ILLEGAL_PORT) { | |
811 // Return a send port for the service port. | |
812 Dart_Handle send_port = Dart_NewSendPort(service_port); | |
813 Dart_SetReturnValue(args, send_port); | |
814 } | |
815 Dart_ExitScope(); | |
816 } | |
817 | |
818 | |
730 } // namespace bin | 819 } // namespace bin |
731 } // namespace dart | 820 } // namespace dart |
OLD | NEW |