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 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 delete[] key_bytes; | 438 delete[] key_bytes; |
439 } | 439 } |
440 | 440 |
441 // TODO(24184): Handle different expected errors here - file missing, | 441 // TODO(24184): Handle different expected errors here - file missing, |
442 // incorrect password, file not a PEM, and throw exceptions. | 442 // incorrect password, file not a PEM, and throw exceptions. |
443 // CheckStatus should also throw an exception in uncaught cases. | 443 // CheckStatus should also throw an exception in uncaught cases. |
444 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes"); | 444 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes"); |
445 } | 445 } |
446 | 446 |
447 | 447 |
448 void FUNCTION_NAME(SecurityContext_SetTrustedCertificates)( | 448 static int SetTrustedCertificatesBytes( |
449 Dart_NativeArguments args) { | 449 SSL_CTX* context, uint8_t* certs_bytes, intptr_t certs_bytes_len) { |
450 SSL_CTX* context = GetSecurityContext(args); | 450 X509_STORE* store = SSL_CTX_get_cert_store(context); |
451 Dart_Handle filename_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 451 BIO* bio = BIO_new_mem_buf(certs_bytes, certs_bytes_len); |
452 const char* filename = NULL; | 452 if (bio == NULL) { |
453 if (Dart_IsString(filename_object)) { | 453 return 0; |
454 ThrowIfError(Dart_StringToCString(filename_object, &filename)); | |
455 } | |
456 Dart_Handle directory_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); | |
457 const char* directory = NULL; | |
458 if (Dart_IsString(directory_object)) { | |
459 ThrowIfError(Dart_StringToCString(directory_object, &directory)); | |
460 } else if (Dart_IsNull(directory_object)) { | |
461 directory = NULL; | |
462 } else { | |
463 Dart_ThrowException(DartUtils::NewDartArgumentError( | |
464 "Directory argument to SecurityContext.setTrustedCertificates is not " | |
465 "a String or null")); | |
466 } | 454 } |
467 | 455 |
468 int status = SSL_CTX_load_verify_locations(context, filename, directory); | 456 int status = 0; |
469 CheckStatus( | 457 X509* cert = NULL; |
470 status, "TlsException", "SSL_CTX_load_verify_locations"); | 458 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { |
| 459 status = X509_STORE_add_cert(store, cert); |
| 460 if (status == 0) { |
| 461 X509_free(cert); |
| 462 BIO_free(bio); |
| 463 return status; |
| 464 } |
| 465 } |
| 466 |
| 467 uint32_t err = ERR_peek_last_error(); |
| 468 if ((ERR_GET_LIB(err) == ERR_LIB_PEM) && |
| 469 (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { |
| 470 // Reached the end of the buffer. |
| 471 ERR_clear_error(); |
| 472 } else { |
| 473 // Some real error happened. |
| 474 status = 0; |
| 475 } |
| 476 |
| 477 BIO_free(bio); |
| 478 return status; |
471 } | 479 } |
472 | 480 |
473 | 481 |
| 482 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( |
| 483 Dart_NativeArguments args) { |
| 484 SSL_CTX* context = GetSecurityContext(args); |
| 485 |
| 486 Dart_Handle certs_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
| 487 if (!Dart_IsTypedData(certs_object) && !Dart_IsList(certs_object)) { |
| 488 Dart_ThrowException(DartUtils::NewDartArgumentError( |
| 489 "certBytes argument to SecurityContext.setTrustedCertificates " |
| 490 "is not a List<int>")); |
| 491 } |
| 492 |
| 493 uint8_t* certs_bytes = NULL; |
| 494 intptr_t certs_bytes_len = 0; |
| 495 bool is_typed_data = false; |
| 496 if (Dart_IsTypedData(certs_object)) { |
| 497 is_typed_data = true; |
| 498 Dart_TypedData_Type typ; |
| 499 ThrowIfError(Dart_TypedDataAcquireData( |
| 500 certs_object, |
| 501 &typ, |
| 502 reinterpret_cast<void**>(&certs_bytes), |
| 503 &certs_bytes_len)); |
| 504 } else { |
| 505 ASSERT(Dart_IsList(certs_object)); |
| 506 ThrowIfError(Dart_ListLength(certs_object, &certs_bytes_len)); |
| 507 certs_bytes = new uint8_t[certs_bytes_len]; |
| 508 Dart_Handle err = |
| 509 Dart_ListGetAsBytes(certs_object, 0, certs_bytes, certs_bytes_len); |
| 510 if (Dart_IsError(err)) { |
| 511 delete[] certs_bytes; |
| 512 Dart_PropagateError(err); |
| 513 } |
| 514 } |
| 515 ASSERT(certs_bytes != NULL); |
| 516 |
| 517 int status = SetTrustedCertificatesBytes( |
| 518 context, certs_bytes, certs_bytes_len); |
| 519 |
| 520 if (is_typed_data) { |
| 521 ThrowIfError(Dart_TypedDataReleaseData(certs_object)); |
| 522 } else { |
| 523 delete[] certs_bytes; |
| 524 } |
| 525 CheckStatus(status, |
| 526 "TlsException", |
| 527 "Failure in setTrustedCertificatesBytes"); |
| 528 } |
| 529 |
| 530 |
474 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( | 531 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( |
475 Dart_NativeArguments args) { | 532 Dart_NativeArguments args) { |
476 SSL_CTX* context = GetSecurityContext(args); | 533 SSL_CTX* context = GetSecurityContext(args); |
477 X509_STORE* store = SSL_CTX_get_cert_store(context); | 534 X509_STORE* store = SSL_CTX_get_cert_store(context); |
478 BIO* roots_bio = | 535 BIO* roots_bio = |
479 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem), | 536 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem), |
480 root_certificates_pem_length); | 537 root_certificates_pem_length); |
481 X509* root_cert; | 538 X509* root_cert; |
482 // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case, | 539 // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case, |
483 // backed by a memory buffer), and returns X509 objects, one by one. | 540 // backed by a memory buffer), and returns X509 objects, one by one. |
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 } else { | 1293 } else { |
1237 if (SSL_LOG_DATA) Log::Print( | 1294 if (SSL_LOG_DATA) Log::Print( |
1238 "WriteEncrypted BIO_read wrote %d bytes\n", bytes_processed); | 1295 "WriteEncrypted BIO_read wrote %d bytes\n", bytes_processed); |
1239 } | 1296 } |
1240 } | 1297 } |
1241 return bytes_processed; | 1298 return bytes_processed; |
1242 } | 1299 } |
1243 | 1300 |
1244 } // namespace bin | 1301 } // namespace bin |
1245 } // namespace dart | 1302 } // namespace dart |
OLD | NEW |