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 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 CObjectIntptr filter_object(args[0]); | 307 CObjectIntptr filter_object(args[0]); |
308 SSLFilter* filter = reinterpret_cast<SSLFilter*>(filter_object.Value()); | 308 SSLFilter* filter = reinterpret_cast<SSLFilter*>(filter_object.Value()); |
309 bool in_handshake = CObjectBool(args[1]).Value(); | 309 bool in_handshake = CObjectBool(args[1]).Value(); |
310 int starts[SSLFilter::kNumBuffers]; | 310 int starts[SSLFilter::kNumBuffers]; |
311 int ends[SSLFilter::kNumBuffers]; | 311 int ends[SSLFilter::kNumBuffers]; |
312 for (int i = 0; i < SSLFilter::kNumBuffers; ++i) { | 312 for (int i = 0; i < SSLFilter::kNumBuffers; ++i) { |
313 starts[i] = CObjectInt32(args[2 * i + 2]).Value(); | 313 starts[i] = CObjectInt32(args[2 * i + 2]).Value(); |
314 ends[i] = CObjectInt32(args[2 * i + 3]).Value(); | 314 ends[i] = CObjectInt32(args[2 * i + 3]).Value(); |
315 } | 315 } |
316 | 316 |
317 filter->ProcessAllBuffers(starts, ends, in_handshake); | 317 if (filter->ProcessAllBuffers(starts, ends, in_handshake)) { |
318 | 318 for (int i = 0; i < SSLFilter::kNumBuffers; ++i) { |
319 for (int i = 0; i < SSLFilter::kNumBuffers; ++i) { | 319 args[2 * i + 2]->AsApiCObject()->value.as_int32 = starts[i]; |
320 args[2 * i + 2]->AsApiCObject()->value.as_int32 = starts[i]; | 320 args[2 * i + 3]->AsApiCObject()->value.as_int32 = ends[i]; |
321 args[2 * i + 3]->AsApiCObject()->value.as_int32 = ends[i]; | 321 } |
| 322 Dart_PostCObject(reply_port_id, args.AsApiCObject()); |
| 323 } else { |
| 324 PRErrorCode error_code = PR_GetError(); |
| 325 const char* error_message = PR_ErrorToString(error_code, PR_LANGUAGE_EN); |
| 326 CObjectArray* result = new CObjectArray(CObject::NewArray(2)); |
| 327 result->SetAt(0, new CObjectInt32(CObject::NewInt32(error_code))); |
| 328 result->SetAt(1, new CObjectString(CObject::NewString(error_message))); |
| 329 Dart_PostCObject(reply_port_id, result->AsApiCObject()); |
322 } | 330 } |
323 Dart_PostCObject(reply_port_id, args.AsApiCObject()); | |
324 } | 331 } |
325 | 332 |
326 | 333 |
327 void SSLFilter::ProcessAllBuffers(int starts[kNumBuffers], | 334 bool SSLFilter::ProcessAllBuffers(int starts[kNumBuffers], |
328 int ends[kNumBuffers], | 335 int ends[kNumBuffers], |
329 bool in_handshake) { | 336 bool in_handshake) { |
330 for (int i = 0; i < kNumBuffers; ++i) { | 337 for (int i = 0; i < kNumBuffers; ++i) { |
331 if (in_handshake && (i == kReadPlaintext || i == kWritePlaintext)) continue; | 338 if (in_handshake && (i == kReadPlaintext || i == kWritePlaintext)) continue; |
332 int start = starts[i]; | 339 int start = starts[i]; |
333 int end = ends[i]; | 340 int end = ends[i]; |
334 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; | 341 int size = isBufferEncrypted(i) ? encrypted_buffer_size_ : buffer_size_; |
335 if (start < 0 || end < 0 || start >= size || end >= size) { | 342 if (start < 0 || end < 0 || start >= size || end >= size) { |
336 FATAL("Out-of-bounds internal buffer access in dart:io SecureSocket"); | 343 FATAL("Out-of-bounds internal buffer access in dart:io SecureSocket"); |
337 } | 344 } |
338 switch (i) { | 345 switch (i) { |
339 case kReadPlaintext: | 346 case kReadPlaintext: |
340 case kWriteEncrypted: | 347 case kWriteEncrypted: |
341 // Write data to the circular buffer's free space. If the buffer | 348 // Write data to the circular buffer's free space. If the buffer |
342 // is full, neither if statement is executed and nothing happens. | 349 // is full, neither if statement is executed and nothing happens. |
343 if (start <= end) { | 350 if (start <= end) { |
344 // If the free space may be split into two segments, | 351 // If the free space may be split into two segments, |
345 // then the first is [end, size), unless start == 0. | 352 // then the first is [end, size), unless start == 0. |
346 // Then, since the last free byte is at position start - 2, | 353 // Then, since the last free byte is at position start - 2, |
347 // the interval is [end, size - 1). | 354 // the interval is [end, size - 1). |
348 int buffer_end = (start == 0) ? size - 1 : size; | 355 int buffer_end = (start == 0) ? size - 1 : size; |
349 int bytes = (i == kReadPlaintext) ? | 356 int bytes = (i == kReadPlaintext) ? |
350 ProcessReadPlaintextBuffer(end, buffer_end) : | 357 ProcessReadPlaintextBuffer(end, buffer_end) : |
351 ProcessWriteEncryptedBuffer(end, buffer_end); | 358 ProcessWriteEncryptedBuffer(end, buffer_end); |
| 359 if (bytes < 0) return false; |
352 end += bytes; | 360 end += bytes; |
353 ASSERT(end <= size); | 361 ASSERT(end <= size); |
354 if (end == size) end = 0; | 362 if (end == size) end = 0; |
355 } | 363 } |
356 if (start > end + 1) { | 364 if (start > end + 1) { |
357 int bytes = (i == kReadPlaintext) ? | 365 int bytes = (i == kReadPlaintext) ? |
358 ProcessReadPlaintextBuffer(end, start - 1) : | 366 ProcessReadPlaintextBuffer(end, start - 1) : |
359 ProcessWriteEncryptedBuffer(end, start - 1); | 367 ProcessWriteEncryptedBuffer(end, start - 1); |
| 368 if (bytes < 0) return false; |
360 end += bytes; | 369 end += bytes; |
361 ASSERT(end < start); | 370 ASSERT(end < start); |
362 } | 371 } |
363 ends[i] = end; | 372 ends[i] = end; |
364 break; | 373 break; |
365 case kReadEncrypted: | 374 case kReadEncrypted: |
366 // Read data from circular buffer. | 375 // Read data from circular buffer. |
367 if (end < start) { | 376 if (end < start) { |
368 // Data may be split into two segments. In this case, | 377 // Data may be split into two segments. In this case, |
369 // the first is [start, size). | 378 // the first is [start, size). |
370 int bytes = ProcessReadEncryptedBuffer(start, size); | 379 int bytes = ProcessReadEncryptedBuffer(start, size); |
| 380 if (bytes < 0) return false; |
371 start += bytes; | 381 start += bytes; |
372 ASSERT(start <= size); | 382 ASSERT(start <= size); |
373 if (start == size) start = 0; | 383 if (start == size) start = 0; |
374 } | 384 } |
375 if (start < end) { | 385 if (start < end) { |
376 int bytes = ProcessReadEncryptedBuffer(start, end); | 386 int bytes = ProcessReadEncryptedBuffer(start, end); |
| 387 if (bytes < 0) return false; |
377 start += bytes; | 388 start += bytes; |
378 ASSERT(start <= end); | 389 ASSERT(start <= end); |
379 } | 390 } |
380 starts[i] = start; | 391 starts[i] = start; |
381 break; | 392 break; |
382 case kWritePlaintext: | 393 case kWritePlaintext: |
383 if (end < start) { | 394 if (end < start) { |
384 // Data is split into two segments, [start, size) and [0, end). | 395 // Data is split into two segments, [start, size) and [0, end). |
385 int bytes = ProcessWritePlaintextBuffer(start, size, 0, end); | 396 int bytes = ProcessWritePlaintextBuffer(start, size, 0, end); |
| 397 if (bytes < 0) return false; |
386 start += bytes; | 398 start += bytes; |
387 if (start >= size) start -= size; | 399 if (start >= size) start -= size; |
388 } else { | 400 } else { |
389 int bytes = ProcessWritePlaintextBuffer(start, end, 0, 0); | 401 int bytes = ProcessWritePlaintextBuffer(start, end, 0, 0); |
| 402 if (bytes < 0) return false; |
390 start += bytes; | 403 start += bytes; |
391 ASSERT(start <= end); | 404 ASSERT(start <= end); |
392 } | 405 } |
393 starts[i] = start; | 406 starts[i] = start; |
394 break; | 407 break; |
395 default: | 408 default: |
396 UNREACHABLE(); | 409 UNREACHABLE(); |
397 } | 410 } |
398 } | 411 } |
| 412 return true; |
399 } | 413 } |
400 | 414 |
401 | 415 |
402 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) { | 416 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) { |
403 PRTime start_validity; | 417 PRTime start_validity; |
404 PRTime end_validity; | 418 PRTime end_validity; |
405 SECStatus status = | 419 SECStatus status = |
406 CERT_GetCertTimes(certificate, &start_validity, &end_validity); | 420 CERT_GetCertTimes(certificate, &start_validity, &end_validity); |
407 if (status != SECSuccess) { | 421 if (status != SECSuccess) { |
408 ThrowPRException("CertificateException", | 422 ThrowPRException("CertificateException", |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 int length = end - start; | 845 int length = end - start; |
832 int bytes_processed = 0; | 846 int bytes_processed = 0; |
833 if (length > 0) { | 847 if (length > 0) { |
834 bytes_processed = PR_Read(filter_, | 848 bytes_processed = PR_Read(filter_, |
835 buffers_[kReadPlaintext] + start, | 849 buffers_[kReadPlaintext] + start, |
836 length); | 850 length); |
837 if (bytes_processed < 0) { | 851 if (bytes_processed < 0) { |
838 ASSERT(bytes_processed == -1); | 852 ASSERT(bytes_processed == -1); |
839 PRErrorCode pr_error = PR_GetError(); | 853 PRErrorCode pr_error = PR_GetError(); |
840 if (PR_WOULD_BLOCK_ERROR != pr_error) { | 854 if (PR_WOULD_BLOCK_ERROR != pr_error) { |
841 // TODO(11383): Handle unexpected errors here. | 855 return -1; |
842 FATAL("Error reading plaintext from SSLFilter"); | |
843 } | 856 } |
844 bytes_processed = 0; | 857 bytes_processed = 0; |
845 } | 858 } |
846 } | 859 } |
847 return bytes_processed; | 860 return bytes_processed; |
848 } | 861 } |
849 | 862 |
850 | 863 |
851 intptr_t SSLFilter::ProcessWritePlaintextBuffer(int start1, int end1, | 864 intptr_t SSLFilter::ProcessWritePlaintextBuffer(int start1, int end1, |
852 int start2, int end2) { | 865 int start2, int end2) { |
853 PRIOVec ranges[2]; | 866 PRIOVec ranges[2]; |
854 uint8_t* buffer = buffers_[kWritePlaintext]; | 867 uint8_t* buffer = buffers_[kWritePlaintext]; |
855 ranges[0].iov_base = reinterpret_cast<char*>(buffer + start1); | 868 ranges[0].iov_base = reinterpret_cast<char*>(buffer + start1); |
856 ranges[0].iov_len = end1 - start1; | 869 ranges[0].iov_len = end1 - start1; |
857 ranges[1].iov_base = reinterpret_cast<char*>(buffer + start2); | 870 ranges[1].iov_base = reinterpret_cast<char*>(buffer + start2); |
858 ranges[1].iov_len = end2 - start2; | 871 ranges[1].iov_len = end2 - start2; |
859 int bytes_processed = PR_Writev(filter_, ranges, 2, PR_INTERVAL_NO_TIMEOUT); | 872 int bytes_processed = PR_Writev(filter_, ranges, 2, PR_INTERVAL_NO_TIMEOUT); |
860 if (bytes_processed < 0) { | 873 if (bytes_processed < 0) { |
861 ASSERT(bytes_processed == -1); | 874 ASSERT(bytes_processed == -1); |
862 PRErrorCode pr_error = PR_GetError(); | 875 PRErrorCode pr_error = PR_GetError(); |
863 if (PR_WOULD_BLOCK_ERROR != pr_error) { | 876 if (PR_WOULD_BLOCK_ERROR != pr_error) { |
864 // TODO(11383): Handle unexpected errors here. | 877 return -1; |
865 FATAL("Error reading plaintext from SSLFilter"); | |
866 } | 878 } |
867 bytes_processed = 0; | 879 bytes_processed = 0; |
868 } | 880 } |
869 return bytes_processed; | 881 return bytes_processed; |
870 } | 882 } |
871 | 883 |
872 | 884 |
873 intptr_t SSLFilter::ProcessReadEncryptedBuffer(int start, int end) { | 885 intptr_t SSLFilter::ProcessReadEncryptedBuffer(int start, int end) { |
874 int length = end - start; | 886 int length = end - start; |
875 int bytes_processed = 0; | 887 int bytes_processed = 0; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 // Return a send port for the service port. | 941 // Return a send port for the service port. |
930 Dart_Handle send_port = Dart_NewSendPort(service_port); | 942 Dart_Handle send_port = Dart_NewSendPort(service_port); |
931 Dart_SetReturnValue(args, send_port); | 943 Dart_SetReturnValue(args, send_port); |
932 } | 944 } |
933 Dart_ExitScope(); | 945 Dart_ExitScope(); |
934 } | 946 } |
935 | 947 |
936 | 948 |
937 } // namespace bin | 949 } // namespace bin |
938 } // namespace dart | 950 } // namespace dart |
OLD | NEW |