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

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

Issue 1761583002: Regularize some errors thrown by SecureContext. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 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 | « no previous file | tests/standalone/io/security_context_argument_test.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 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 Dart_Handle object_; 517 Dart_Handle object_;
518 uint8_t* bytes_; 518 uint8_t* bytes_;
519 intptr_t bytes_len_; 519 intptr_t bytes_len_;
520 BIO* bio_; 520 BIO* bio_;
521 bool is_typed_data_; 521 bool is_typed_data_;
522 522
523 DISALLOW_ALLOCATION(); 523 DISALLOW_ALLOCATION();
524 DISALLOW_COPY_AND_ASSIGN(ScopedMemBIO); 524 DISALLOW_COPY_AND_ASSIGN(ScopedMemBIO);
525 }; 525 };
526 526
527
528 template<typename T, void (*free_func)(T*)> 527 template<typename T, void (*free_func)(T*)>
529 class ScopedSSLType { 528 class ScopedSSLType {
530 public: 529 public:
531 explicit ScopedSSLType(T* obj) : obj_(obj) {} 530 explicit ScopedSSLType(T* obj) : obj_(obj) {}
532 531
533 ~ScopedSSLType() { 532 ~ScopedSSLType() {
534 if (obj_ != NULL) { 533 if (obj_ != NULL) {
535 free_func(obj_); 534 free_func(obj_);
536 } 535 }
537 } 536 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 574
576 private: 575 private:
577 T* obj_; 576 T* obj_;
578 577
579 DISALLOW_ALLOCATION(); 578 DISALLOW_ALLOCATION();
580 DISALLOW_COPY_AND_ASSIGN(ScopedSSLStackType); 579 DISALLOW_COPY_AND_ASSIGN(ScopedSSLStackType);
581 }; 580 };
582 581
583 typedef ScopedSSLType<PKCS12, PKCS12_free> ScopedPKCS12; 582 typedef ScopedSSLType<PKCS12, PKCS12_free> ScopedPKCS12;
584 typedef ScopedSSLType<X509, X509_free> ScopedX509; 583 typedef ScopedSSLType<X509, X509_free> ScopedX509;
585
586 typedef ScopedSSLStackType<STACK_OF(X509), X509, X509_free> ScopedX509Stack; 584 typedef ScopedSSLStackType<STACK_OF(X509), X509, X509_free> ScopedX509Stack;
587 typedef ScopedSSLStackType<STACK_OF(X509_NAME), X509_NAME, X509_NAME_free>
588 ScopedX509NAMEStack;
589
590 585
591 // We try reading data as PKCS12 only if reading as PEM was unsuccessful and 586 // We try reading data as PKCS12 only if reading as PEM was unsuccessful and
592 // if there is no indication that the data is malformed PEM. We assume the data 587 // if there is no indication that the data is malformed PEM. We assume the data
593 // is malformed PEM if it contains the start line, i.e. a line with ----- BEGIN. 588 // is malformed PEM if it contains the start line, i.e. a line with ----- BEGIN.
594 static bool TryPKCS12(bool pem_success) { 589 static bool TryPKCS12(bool pem_success) {
595 uint32_t last_error = ERR_peek_last_error(); 590 uint32_t last_error = ERR_peek_last_error();
596 return !pem_success && 591 return !pem_success &&
597 (ERR_GET_LIB(last_error) == ERR_LIB_PEM) && 592 (ERR_GET_LIB(last_error) == ERR_LIB_PEM) &&
598 (ERR_GET_REASON(last_error) == PEM_R_NO_START_LINE); 593 (ERR_GET_REASON(last_error) == PEM_R_NO_START_LINE);
599 } 594 }
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 { 891 {
897 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 892 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
898 status = UseChainBytes(context, bio.bio(), password); 893 status = UseChainBytes(context, bio.bio(), password);
899 } 894 }
900 CheckStatus(status, 895 CheckStatus(status,
901 "TlsException", 896 "TlsException",
902 "Failure in useCertificateChainBytes"); 897 "Failure in useCertificateChainBytes");
903 } 898 }
904 899
905 900
906 static STACK_OF(X509_NAME)* GetCertificateNamesPKCS12(BIO* bio, 901 static int SetClientAuthoritiesPKCS12(SSL_CTX* context,
907 const char* password) { 902 BIO* bio,
903 const char* password) {
908 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); 904 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
909 if (p12.get() == NULL) { 905 if (p12.get() == NULL) {
910 return NULL; 906 return NULL;
911 } 907 }
912 908
913 ScopedX509NAMEStack result(sk_X509_NAME_new_null());
914 if (result.get() == NULL) {
915 return NULL;
916 }
917
918 EVP_PKEY* key = NULL; 909 EVP_PKEY* key = NULL;
919 X509 *cert = NULL; 910 X509 *cert = NULL;
920 STACK_OF(X509) *ca_certs = NULL; 911 STACK_OF(X509) *ca_certs = NULL;
921 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs); 912 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
922 if (status == 0) { 913 if (status == 0) {
923 return NULL; 914 return status;
924 } 915 }
925 916
926 ScopedX509 x509(cert); 917 ScopedX509Stack cert_stack(ca_certs);
927 ScopedX509Stack certs(ca_certs); 918 status = SSL_CTX_add_client_CA(context, cert);
928 X509_NAME* x509_name = X509_get_subject_name(x509.get()); 919 if (status == 0) {
929 if (x509_name == NULL) { 920 X509_free(cert);
930 return NULL; 921 return status;
931 } 922 }
932 923
933 x509_name = X509_NAME_dup(x509_name); 924 X509* ca;
934 if (x509_name == NULL) { 925 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
935 return NULL; 926 status = SSL_CTX_add_client_CA(context, ca);
927 X509_free(ca); // The name has been extracted.
928 if (status == 0) {
929 return status;
930 }
936 } 931 }
937 932
938 sk_X509_NAME_push(result.get(), x509_name); 933 return status;
939
940 while (true) {
941 ScopedX509 ca(sk_X509_shift(certs.get()));
942 if (ca.get() == NULL) {
943 break;
944 }
945
946 X509_NAME* x509_name = X509_get_subject_name(ca.get());
947 if (x509_name == NULL) {
948 return NULL;
949 }
950
951 x509_name = X509_NAME_dup(x509_name);
952 if (x509_name == NULL) {
953 return NULL;
954 }
955
956 sk_X509_NAME_push(result.get(), x509_name);
957 }
958
959 return result.release();
960 } 934 }
961 935
962 936
963 static STACK_OF(X509_NAME)* GetCertificateNamesPEM(BIO* bio) { 937 static int SetClientAuthoritiesPEM(SSL_CTX* context, BIO* bio) {
964 ScopedX509NAMEStack result(sk_X509_NAME_new_null()); 938 int status = 0;
965 if (result.get() == NULL) { 939 X509* cert = NULL;
966 return NULL; 940 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
941 status = SSL_CTX_add_client_CA(context, cert);
942 X509_free(cert); // The name has been extracted.
943 if (status == 0) {
944 return status;
945 }
967 } 946 }
968 947
969 while (true) { 948 // If bio does not contain PEM data, the first call to PEM_read_bio_X509 will
970 ScopedX509 x509(PEM_read_bio_X509(bio, NULL, NULL, NULL)); 949 // return NULL, and the while-loop will exit while status is still 0.
971 if (x509.get() == NULL) {
972 break;
973 }
974
975 X509_NAME* x509_name = X509_get_subject_name(x509.get());
976 if (x509_name == NULL) {
977 return NULL;
978 }
979
980 // Duplicate the name to put it on the stack.
981 x509_name = X509_NAME_dup(x509_name);
982 if (x509_name == NULL) {
983 return NULL;
984 }
985 sk_X509_NAME_push(result.get(), x509_name);
986 }
987
988 if (sk_X509_NAME_num(result.get()) == 0) {
989 // The data was not PEM.
990 return NULL;
991 }
992
993 uint32_t err = ERR_peek_last_error(); 950 uint32_t err = ERR_peek_last_error();
994 if ((ERR_GET_LIB(err) != ERR_LIB_PEM) || 951 if ((ERR_GET_LIB(err) != ERR_LIB_PEM) ||
995 (ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) { 952 (ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) {
996 // The data was trying to be PEM, but was malformed. 953 // If bio contains data that is trying to be PEM but is malformed, then
997 return NULL; 954 // this case will be triggered.
955 status = 0;
998 } 956 }
999 957
1000 return result.release(); 958 return status;
1001 } 959 }
1002 960
1003 961
1004 static STACK_OF(X509_NAME)* GetCertificateNames(BIO* bio, 962 static int SetClientAuthorities(SSL_CTX* context,
1005 const char* password) { 963 BIO* bio,
1006 STACK_OF(X509_NAME)* result = GetCertificateNamesPEM(bio); 964 const char* password) {
1007 if (TryPKCS12(result != NULL)) { 965 int status = SetClientAuthoritiesPEM(context, bio);
966 if (TryPKCS12(status != 0)) {
Ivan Posva 2016/03/02 21:56:50 Can we please rewrite this to be less backwards to
zra 2016/03/02 23:12:34 Done.
1008 ERR_clear_error(); 967 ERR_clear_error();
1009 BIO_reset(bio); 968 BIO_reset(bio);
1010 result = GetCertificateNamesPKCS12(bio, password); 969 status = SetClientAuthoritiesPKCS12(context, bio, password);
1011 } else if (result != NULL) { 970 } else if (status != 0) {
1012 // The PEM file was successfully parsed. 971 // The PEM file was successfully parsed.
1013 ERR_clear_error(); 972 ERR_clear_error();
1014 } 973 }
1015 return result; 974 return status;
1016 } 975 }
1017 976
1018 977
1019 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( 978 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
1020 Dart_NativeArguments args) { 979 Dart_NativeArguments args) {
1021 SSL_CTX* context = GetSecurityContext(args); 980 SSL_CTX* context = GetSecurityContext(args);
1022 const char* password = GetPasswordArgument(args, 2); 981 const char* password = GetPasswordArgument(args, 2);
1023 STACK_OF(X509_NAME)* certificate_names;
1024 982
983 int status;
1025 { 984 {
1026 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 985 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
1027 certificate_names = GetCertificateNames(bio.bio(), password); 986 status = SetClientAuthorities(context, bio.bio(), password);
1028 } 987 }
1029 988
1030 if (certificate_names != NULL) { 989 CheckStatus(status,
1031 SSL_CTX_set_client_CA_list(context, certificate_names); 990 "TlsException",
1032 } else { 991 "Failure in setClientAuthoritiesBytes");
1033 Dart_ThrowException(DartUtils::NewDartArgumentError(
1034 "Could not load certificate names from file in SetClientAuthorities"));
1035 }
1036 } 992 }
1037 993
1038 994
1039 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( 995 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)(
1040 Dart_NativeArguments args) { 996 Dart_NativeArguments args) {
1041 SSL_CTX* context = GetSecurityContext(args); 997 SSL_CTX* context = GetSecurityContext(args);
1042 Dart_Handle protocols_handle = 998 Dart_Handle protocols_handle =
1043 ThrowIfError(Dart_GetNativeArgument(args, 1)); 999 ThrowIfError(Dart_GetNativeArgument(args, 1));
1044 Dart_Handle is_server_handle = 1000 Dart_Handle is_server_handle =
1045 ThrowIfError(Dart_GetNativeArgument(args, 2)); 1001 ThrowIfError(Dart_GetNativeArgument(args, 2));
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
1713 } else { 1669 } else {
1714 if (SSL_LOG_DATA) Log::Print( 1670 if (SSL_LOG_DATA) Log::Print(
1715 "WriteEncrypted BIO_read wrote %d bytes\n", bytes_processed); 1671 "WriteEncrypted BIO_read wrote %d bytes\n", bytes_processed);
1716 } 1672 }
1717 } 1673 }
1718 return bytes_processed; 1674 return bytes_processed;
1719 } 1675 }
1720 1676
1721 } // namespace bin 1677 } // namespace bin
1722 } // namespace dart 1678 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | tests/standalone/io/security_context_argument_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698