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

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

Issue 1699163002: More SecurityContext calls accept a password. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix typo Created 4 years, 10 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
« no previous file with comments | « runtime/bin/io_natives.cc ('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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 } 275 }
276 276
277 277
278 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { 278 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) {
279 intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args)); 279 intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args));
280 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); 280 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer));
281 } 281 }
282 282
283 283
284 static Dart_Handle WrappedX509Certificate(X509* certificate) { 284 static Dart_Handle WrappedX509Certificate(X509* certificate) {
285 if (certificate == NULL) return Dart_Null(); 285 if (certificate == NULL) {
286 return Dart_Null();
287 }
286 Dart_Handle x509_type = 288 Dart_Handle x509_type =
287 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); 289 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate");
288 if (Dart_IsError(x509_type)) { 290 if (Dart_IsError(x509_type)) {
289 return x509_type; 291 return x509_type;
290 } 292 }
291 Dart_Handle arguments[] = { NULL }; 293 Dart_Handle arguments[] = { NULL };
292 Dart_Handle result = 294 Dart_Handle result =
293 Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments); 295 Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments);
294 if (Dart_IsError(result)) { 296 if (Dart_IsError(result)) {
295 return result; 297 return result;
296 } 298 }
297 ASSERT(Dart_IsInstance(result)); 299 ASSERT(Dart_IsInstance(result));
298 Dart_Handle status = Dart_SetNativeInstanceField( 300 Dart_Handle status = Dart_SetNativeInstanceField(
299 result, 301 result,
300 kX509NativeFieldIndex, 302 kX509NativeFieldIndex,
301 reinterpret_cast<intptr_t>(certificate)); 303 reinterpret_cast<intptr_t>(certificate));
302 if (Dart_IsError(status)) { 304 if (Dart_IsError(status)) {
303 return status; 305 return status;
304 } 306 }
305 return result; 307 return result;
306 } 308 }
307 309
308 310
309 int CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx) { 311 int CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx) {
310 if (preverify_ok == 1) return 1; 312 if (preverify_ok == 1) {
313 return 1;
314 }
311 Dart_Isolate isolate = Dart_CurrentIsolate(); 315 Dart_Isolate isolate = Dart_CurrentIsolate();
312 if (isolate == NULL) { 316 if (isolate == NULL) {
313 FATAL("CertificateCallback called with no current isolate\n"); 317 FATAL("CertificateCallback called with no current isolate\n");
314 } 318 }
315 X509* certificate = X509_STORE_CTX_get_current_cert(store_ctx); 319 X509* certificate = X509_STORE_CTX_get_current_cert(store_ctx);
316 int ssl_index = SSL_get_ex_data_X509_STORE_CTX_idx(); 320 int ssl_index = SSL_get_ex_data_X509_STORE_CTX_idx();
317 SSL* ssl = static_cast<SSL*>( 321 SSL* ssl = static_cast<SSL*>(
318 X509_STORE_CTX_get_ex_data(store_ctx, ssl_index)); 322 X509_STORE_CTX_get_ex_data(store_ctx, ssl_index));
319 SSLFilter* filter = static_cast<SSLFilter*>( 323 SSLFilter* filter = static_cast<SSLFilter*>(
320 SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index)); 324 SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index));
321 Dart_Handle callback = filter->bad_certificate_callback(); 325 Dart_Handle callback = filter->bad_certificate_callback();
322 if (Dart_IsNull(callback)) return 0; 326 if (Dart_IsNull(callback)) {
327 return 0;
328 }
323 Dart_Handle args[1]; 329 Dart_Handle args[1];
324 args[0] = WrappedX509Certificate(certificate); 330 args[0] = WrappedX509Certificate(certificate);
325 if (Dart_IsError(args[0])) { 331 if (Dart_IsError(args[0])) {
326 filter->callback_error = args[0]; 332 filter->callback_error = args[0];
327 return 0; 333 return 0;
328 } 334 }
329 Dart_Handle result = Dart_InvokeClosure(callback, 1, args); 335 Dart_Handle result = Dart_InvokeClosure(callback, 1, args);
330 if (!Dart_IsError(result) && !Dart_IsBoolean(result)) { 336 if (!Dart_IsError(result) && !Dart_IsBoolean(result)) {
331 result = Dart_NewUnhandledExceptionError(DartUtils::NewDartIOException( 337 result = Dart_NewUnhandledExceptionError(DartUtils::NewDartIOException(
332 "HandshakeException", 338 "HandshakeException",
(...skipping 20 matching lines...) Expand all
353 359
354 360
355 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) { 361 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) {
356 char* password = static_cast<char*>(userdata); 362 char* password = static_cast<char*>(userdata);
357 ASSERT(size == PEM_BUFSIZE); 363 ASSERT(size == PEM_BUFSIZE);
358 strncpy(buf, password, size); 364 strncpy(buf, password, size);
359 return strlen(password); 365 return strlen(password);
360 } 366 }
361 367
362 368
363 void CheckStatus(int status, 369 void CheckStatus(int status, const char* type, const char* message) {
364 const char* type,
365 const char* message) {
366 // TODO(24183): Take appropriate action on failed calls, 370 // TODO(24183): Take appropriate action on failed calls,
367 // throw exception that includes all messages from the error stack. 371 // throw exception that includes all messages from the error stack.
368 if (status == 1) return; 372 if (status == 1) {
373 return;
374 }
369 if (SSL_LOG_STATUS) { 375 if (SSL_LOG_STATUS) {
370 int error = ERR_get_error(); 376 int error = ERR_get_error();
371 Log::PrintErr("Failed: %s status %d", message, status); 377 Log::PrintErr("Failed: %s status %d", message, status);
372 char error_string[SSL_ERROR_MESSAGE_BUFFER_SIZE]; 378 char error_string[SSL_ERROR_MESSAGE_BUFFER_SIZE];
373 ERR_error_string_n(error, error_string, SSL_ERROR_MESSAGE_BUFFER_SIZE); 379 ERR_error_string_n(error, error_string, SSL_ERROR_MESSAGE_BUFFER_SIZE);
374 Log::PrintErr("ERROR: %d %s\n", error, error_string); 380 Log::PrintErr("ERROR: %d %s\n", error, error_string);
375 } 381 }
376 ThrowIOException(status, type, message); 382 ThrowIOException(status, type, message);
377 } 383 }
378 384
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 ERR_clear_error(); 555 ERR_clear_error();
550 BIO_reset(bio); 556 BIO_reset(bio);
551 557
552 // Try to decode as PKCS12 558 // Try to decode as PKCS12
553 key = GetPrivateKeyPKCS12(bio, password); 559 key = GetPrivateKeyPKCS12(bio, password);
554 } 560 }
555 return key; 561 return key;
556 } 562 }
557 563
558 564
565 static const char* GetPasswordArgument(Dart_NativeArguments args,
566 intptr_t index) {
567 Dart_Handle password_object =
568 ThrowIfError(Dart_GetNativeArgument(args, index));
569 const char* password = NULL;
570 if (Dart_IsString(password_object)) {
571 ThrowIfError(Dart_StringToCString(password_object, &password));
572 if (strlen(password) > PEM_BUFSIZE - 1) {
573 Dart_ThrowException(DartUtils::NewDartArgumentError(
574 "Password length is greater than 1023 (PEM_BUFSIZE)"));
575 }
576 } else if (Dart_IsNull(password_object)) {
577 password = "";
578 } else {
579 Dart_ThrowException(DartUtils::NewDartArgumentError(
580 "Password is not a String or null"));
581 }
582 return password;
583 }
584
585
559 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( 586 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
560 Dart_NativeArguments args) { 587 Dart_NativeArguments args) {
561 SSL_CTX* context = GetSecurityContext(args); 588 SSL_CTX* context = GetSecurityContext(args);
562 589 const char* password = GetPasswordArgument(args, 2);
563 Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 2));
564 const char* password = NULL;
565 if (Dart_IsString(password_object)) {
566 ThrowIfError(Dart_StringToCString(password_object, &password));
567 if (strlen(password) > PEM_BUFSIZE - 1) {
568 Dart_ThrowException(DartUtils::NewDartArgumentError(
569 "SecurityContext.usePrivateKey password length is greater than"
570 " 1023 (PEM_BUFSIZE)"));
571 }
572 } else if (Dart_IsNull(password_object)) {
573 password = "";
574 } else {
575 Dart_ThrowException(DartUtils::NewDartArgumentError(
576 "SecurityContext.usePrivateKey password is not a String or null"));
577 }
578 590
579 int status; 591 int status;
580 { 592 {
581 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 593 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
582 EVP_PKEY *key = GetPrivateKey(bio.bio(), password); 594 EVP_PKEY *key = GetPrivateKey(bio.bio(), password);
583 status = SSL_CTX_use_PrivateKey(context, key); 595 status = SSL_CTX_use_PrivateKey(context, key);
584 } 596 }
585 597
586 // TODO(24184): Handle different expected errors here - file missing, 598 // TODO(24184): Handle different expected errors here - file missing,
587 // incorrect password, file not a PEM, and throw exceptions. 599 // incorrect password, file not a PEM, and throw exceptions.
588 // CheckStatus should also throw an exception in uncaught cases. 600 // CheckStatus should also throw an exception in uncaught cases.
589 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes"); 601 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes");
590 } 602 }
591 603
592 604
593 static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context, BIO* bio) { 605 static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context,
606 BIO* bio,
607 const char* password) {
594 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); 608 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
595 if (p12.get() == NULL) { 609 if (p12.get() == NULL) {
596 return NULL; 610 return NULL;
597 } 611 }
598 612
599 EVP_PKEY* key = NULL; 613 EVP_PKEY* key = NULL;
600 X509 *cert = NULL; 614 X509 *cert = NULL;
601 STACK_OF(X509) *ca_certs = NULL; 615 STACK_OF(X509) *ca_certs = NULL;
602 // There should be no private keys in this file, so we hardcode the password 616 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
603 // to "".
604 // TODO(zra): Allow passing a password anyway.
605 int status = PKCS12_parse(p12.get(), "", &key, &cert, &ca_certs);
606 if (status == 0) { 617 if (status == 0) {
607 return status; 618 return status;
608 } 619 }
609 620
610 ScopedX509Stack cert_stack(ca_certs); 621 ScopedX509Stack cert_stack(ca_certs);
611
612 // There should be no private key.
613 if (key != NULL) {
614 X509_free(cert);
615 return 0;
616 }
617
618 X509_STORE* store = SSL_CTX_get_cert_store(context); 622 X509_STORE* store = SSL_CTX_get_cert_store(context);
619 status = X509_STORE_add_cert(store, cert); 623 status = X509_STORE_add_cert(store, cert);
620 if (status == 0) { 624 if (status == 0) {
621 X509_free(cert); 625 X509_free(cert);
622 return status; 626 return status;
623 } 627 }
624 628
625 X509* ca; 629 X509* ca;
626 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) { 630 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
627 status = X509_STORE_add_cert(store, ca); 631 status = X509_STORE_add_cert(store, ca);
(...skipping 27 matching lines...) Expand all
655 (ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) { 659 (ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) {
656 // If bio contains data that is trying to be PEM but is malformed, then 660 // If bio contains data that is trying to be PEM but is malformed, then
657 // this case will be triggered. 661 // this case will be triggered.
658 status = 0; 662 status = 0;
659 } 663 }
660 664
661 return status; 665 return status;
662 } 666 }
663 667
664 668
665 static int SetTrustedCertificatesBytes(SSL_CTX* context, BIO* bio) { 669 static int SetTrustedCertificatesBytes(SSL_CTX* context,
670 BIO* bio,
671 const char* password) {
666 int status = SetTrustedCertificatesBytesPEM(context, bio); 672 int status = SetTrustedCertificatesBytesPEM(context, bio);
667 if (TryPKCS12(status != 0)) { 673 if (TryPKCS12(status != 0)) {
668 ERR_clear_error(); 674 ERR_clear_error();
669 BIO_reset(bio); 675 BIO_reset(bio);
670 status = SetTrustedCertificatesBytesPKCS12(context, bio); 676 status = SetTrustedCertificatesBytesPKCS12(context, bio, password);
671 } else if (status != 0) { 677 } else if (status != 0) {
672 // The PEM file was successfully parsed. 678 // The PEM file was successfully parsed.
673 ERR_clear_error(); 679 ERR_clear_error();
674 } 680 }
675 return status; 681 return status;
676 } 682 }
677 683
678 684
679 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( 685 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)(
680 Dart_NativeArguments args) { 686 Dart_NativeArguments args) {
681 SSL_CTX* context = GetSecurityContext(args); 687 SSL_CTX* context = GetSecurityContext(args);
688 const char* password = GetPasswordArgument(args, 2);
682 int status; 689 int status;
683 { 690 {
684 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 691 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
685 status = SetTrustedCertificatesBytes(context, bio.bio()); 692 status = SetTrustedCertificatesBytes(context, bio.bio(), password);
686 } 693 }
687 CheckStatus(status, 694 CheckStatus(status,
688 "TlsException", 695 "TlsException",
689 "Failure in setTrustedCertificatesBytes"); 696 "Failure in setTrustedCertificatesBytes");
690 } 697 }
691 698
692 699
693 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( 700 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
694 Dart_NativeArguments args) { 701 Dart_NativeArguments args) {
695 SSL_CTX* context = GetSecurityContext(args); 702 SSL_CTX* context = GetSecurityContext(args);
696 X509_STORE* store = SSL_CTX_get_cert_store(context); 703 X509_STORE* store = SSL_CTX_get_cert_store(context);
697 BIO* roots_bio = 704 BIO* roots_bio =
698 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem), 705 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem),
699 root_certificates_pem_length); 706 root_certificates_pem_length);
700 X509* root_cert; 707 X509* root_cert;
701 // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case, 708 // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case,
702 // backed by a memory buffer), and returns X509 objects, one by one. 709 // backed by a memory buffer), and returns X509 objects, one by one.
703 // When the end of the bio is reached, it returns null. 710 // When the end of the bio is reached, it returns null.
704 while ((root_cert = PEM_read_bio_X509(roots_bio, NULL, NULL, NULL))) { 711 while ((root_cert = PEM_read_bio_X509(roots_bio, NULL, NULL, NULL))) {
705 X509_STORE_add_cert(store, root_cert); 712 X509_STORE_add_cert(store, root_cert);
706 } 713 }
707 BIO_free(roots_bio); 714 BIO_free(roots_bio);
708 } 715 }
709 716
710 717
711 static int UseChainBytesPKCS12(SSL_CTX* context, BIO* bio) { 718 static int UseChainBytesPKCS12(SSL_CTX* context,
719 BIO* bio,
720 const char* password) {
712 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); 721 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
713 if (p12.get() == NULL) { 722 if (p12.get() == NULL) {
714 return NULL; 723 return NULL;
715 } 724 }
716 725
717 EVP_PKEY* key = NULL; 726 EVP_PKEY* key = NULL;
718 X509 *cert = NULL; 727 X509 *cert = NULL;
719 STACK_OF(X509) *ca_certs = NULL; 728 STACK_OF(X509) *ca_certs = NULL;
720 // There should be no private keys in this file, so we hardcode the password 729 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
721 // to "".
722 // TODO(zra): Allow passing a password anyway.
723 int status = PKCS12_parse(p12.get(), "", &key, &cert, &ca_certs);
724 if (status == 0) { 730 if (status == 0) {
725 return status; 731 return status;
726 } 732 }
727 733
728 ScopedX509 x509(cert); 734 ScopedX509 x509(cert);
729 ScopedX509Stack certs(ca_certs); 735 ScopedX509Stack certs(ca_certs);
730
731 // There should be no private key.
732 if (key != NULL) {
733 return 0;
734 }
735
736 status = SSL_CTX_use_certificate(context, x509.get()); 736 status = SSL_CTX_use_certificate(context, x509.get());
737 if (ERR_peek_error() != 0) { 737 if (ERR_peek_error() != 0) {
738 // Key/certificate mismatch doesn't imply status is 0. 738 // Key/certificate mismatch doesn't imply status is 0.
739 status = 0; 739 status = 0;
740 } 740 }
741 if (status == 0) { 741 if (status == 0) {
742 return status; 742 return status;
743 } 743 }
744 744
745 SSL_CTX_clear_chain_certs(context); 745 SSL_CTX_clear_chain_certs(context);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 (ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) { 794 (ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) {
795 // If bio contains data that is trying to be PEM but is malformed, then 795 // If bio contains data that is trying to be PEM but is malformed, then
796 // this case will be triggered. 796 // this case will be triggered.
797 status = 0; 797 status = 0;
798 } 798 }
799 799
800 return status; 800 return status;
801 } 801 }
802 802
803 803
804 static int UseChainBytes(SSL_CTX* context, BIO* bio) { 804 static int UseChainBytes(SSL_CTX* context, BIO* bio, const char* password) {
805 int status = UseChainBytesPEM(context, bio); 805 int status = UseChainBytesPEM(context, bio);
806 if (TryPKCS12(status != 0)) { 806 if (TryPKCS12(status != 0)) {
807 ERR_clear_error(); 807 ERR_clear_error();
808 BIO_reset(bio); 808 BIO_reset(bio);
809 status = UseChainBytesPKCS12(context, bio); 809 status = UseChainBytesPKCS12(context, bio, password);
810 } else if (status != 0) { 810 } else if (status != 0) {
811 // The PEM file was successfully read. 811 // The PEM file was successfully read.
812 ERR_clear_error(); 812 ERR_clear_error();
813 } 813 }
814 return status; 814 return status;
815 } 815 }
816 816
817 817
818 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( 818 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
819 Dart_NativeArguments args) { 819 Dart_NativeArguments args) {
820 SSL_CTX* context = GetSecurityContext(args); 820 SSL_CTX* context = GetSecurityContext(args);
821 const char* password = GetPasswordArgument(args, 2);
821 int status; 822 int status;
822 { 823 {
823 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 824 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
824 status = UseChainBytes(context, bio.bio()); 825 status = UseChainBytes(context, bio.bio(), password);
825 } 826 }
826 CheckStatus(status, 827 CheckStatus(status,
827 "TlsException", 828 "TlsException",
828 "Failure in useCertificateChainBytes"); 829 "Failure in useCertificateChainBytes");
829 } 830 }
830 831
831 832
832 static STACK_OF(X509_NAME)* GetCertificateNamesPKCS12(BIO* bio) { 833 static STACK_OF(X509_NAME)* GetCertificateNamesPKCS12(BIO* bio,
834 const char* password) {
833 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); 835 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
834 if (p12.get() == NULL) { 836 if (p12.get() == NULL) {
835 return NULL; 837 return NULL;
836 } 838 }
837 839
838 ScopedX509NAMEStack result(sk_X509_NAME_new_null()); 840 ScopedX509NAMEStack result(sk_X509_NAME_new_null());
839 if (result.get() == NULL) { 841 if (result.get() == NULL) {
840 return NULL; 842 return NULL;
841 } 843 }
842 844
843 EVP_PKEY* key = NULL; 845 EVP_PKEY* key = NULL;
844 X509 *cert = NULL; 846 X509 *cert = NULL;
845 STACK_OF(X509) *ca_certs = NULL; 847 STACK_OF(X509) *ca_certs = NULL;
846 // There should be no private keys in this file, so we hardcode the password 848 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
847 // to "".
848 // TODO(zra): Allow passing a password anyway.
849 int status = PKCS12_parse(p12.get(), "", &key, &cert, &ca_certs);
850 if (status == 0) { 849 if (status == 0) {
851 return NULL; 850 return NULL;
852 } 851 }
853 852
854 ScopedX509 x509(cert); 853 ScopedX509 x509(cert);
855 ScopedX509Stack certs(ca_certs); 854 ScopedX509Stack certs(ca_certs);
856
857 // There should be no private key.
858 if (key != NULL) {
859 return NULL;
860 }
861
862 X509_NAME* x509_name = X509_get_subject_name(x509.get()); 855 X509_NAME* x509_name = X509_get_subject_name(x509.get());
863 if (x509_name == NULL) { 856 if (x509_name == NULL) {
864 return NULL; 857 return NULL;
865 } 858 }
866 859
867 x509_name = X509_NAME_dup(x509_name); 860 x509_name = X509_NAME_dup(x509_name);
868 if (x509_name == NULL) { 861 if (x509_name == NULL) {
869 return NULL; 862 return NULL;
870 } 863 }
871 864
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 if ((ERR_GET_LIB(err) != ERR_LIB_PEM) || 921 if ((ERR_GET_LIB(err) != ERR_LIB_PEM) ||
929 (ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) { 922 (ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) {
930 // The data was trying to be PEM, but was malformed. 923 // The data was trying to be PEM, but was malformed.
931 return NULL; 924 return NULL;
932 } 925 }
933 926
934 return result.release(); 927 return result.release();
935 } 928 }
936 929
937 930
938 static STACK_OF(X509_NAME)* GetCertificateNames(BIO* bio) { 931 static STACK_OF(X509_NAME)* GetCertificateNames(BIO* bio,
932 const char* password) {
939 STACK_OF(X509_NAME)* result = GetCertificateNamesPEM(bio); 933 STACK_OF(X509_NAME)* result = GetCertificateNamesPEM(bio);
940 if (TryPKCS12(result != NULL)) { 934 if (TryPKCS12(result != NULL)) {
941 ERR_clear_error(); 935 ERR_clear_error();
942 BIO_reset(bio); 936 BIO_reset(bio);
943 result = GetCertificateNamesPKCS12(bio); 937 result = GetCertificateNamesPKCS12(bio, password);
944 } else if (result != NULL) { 938 } else if (result != NULL) {
945 // The PEM file was successfully parsed. 939 // The PEM file was successfully parsed.
946 ERR_clear_error(); 940 ERR_clear_error();
947 } 941 }
948 return result; 942 return result;
949 } 943 }
950 944
951 945
952 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( 946 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
953 Dart_NativeArguments args) { 947 Dart_NativeArguments args) {
954 SSL_CTX* context = GetSecurityContext(args); 948 SSL_CTX* context = GetSecurityContext(args);
949 const char* password = GetPasswordArgument(args, 2);
955 STACK_OF(X509_NAME)* certificate_names; 950 STACK_OF(X509_NAME)* certificate_names;
956 951
957 { 952 {
958 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 953 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
959 certificate_names = GetCertificateNames(bio.bio()); 954 certificate_names = GetCertificateNames(bio.bio(), password);
960 } 955 }
961 956
962 if (certificate_names != NULL) { 957 if (certificate_names != NULL) {
963 SSL_CTX_set_client_CA_list(context, certificate_names); 958 SSL_CTX_set_client_CA_list(context, certificate_names);
964 } else { 959 } else {
965 Dart_ThrowException(DartUtils::NewDartArgumentError( 960 Dart_ThrowException(DartUtils::NewDartArgumentError(
966 "Could not load certificate names from file in SetClientAuthorities")); 961 "Could not load certificate names from file in SetClientAuthorities"));
967 } 962 }
968 } 963 }
969 964
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 } else { 1579 } else {
1585 if (SSL_LOG_DATA) Log::Print( 1580 if (SSL_LOG_DATA) Log::Print(
1586 "WriteEncrypted BIO_read wrote %d bytes\n", bytes_processed); 1581 "WriteEncrypted BIO_read wrote %d bytes\n", bytes_processed);
1587 } 1582 }
1588 } 1583 }
1589 return bytes_processed; 1584 return bytes_processed;
1590 } 1585 }
1591 1586
1592 } // namespace bin 1587 } // namespace bin
1593 } // namespace dart 1588 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/bin/io_natives.cc ('k') | runtime/bin/secure_socket_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698