Chromium Code Reviews| Index: runtime/bin/secure_socket.cc |
| diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc |
| index 7d79dc60158e9d7b056afdf79b11bd59ea14812d..d40eeb5a1f400c7263dfda2a92efa530754cafb7 100644 |
| --- a/runtime/bin/secure_socket.cc |
| +++ b/runtime/bin/secure_socket.cc |
| @@ -524,7 +524,6 @@ class ScopedMemBIO { |
| DISALLOW_COPY_AND_ASSIGN(ScopedMemBIO); |
| }; |
| - |
| template<typename T, void (*free_func)(T*)> |
| class ScopedSSLType { |
| public: |
| @@ -582,11 +581,7 @@ class ScopedSSLStackType { |
| typedef ScopedSSLType<PKCS12, PKCS12_free> ScopedPKCS12; |
| typedef ScopedSSLType<X509, X509_free> ScopedX509; |
| - |
| typedef ScopedSSLStackType<STACK_OF(X509), X509, X509_free> ScopedX509Stack; |
| -typedef ScopedSSLStackType<STACK_OF(X509_NAME), X509_NAME, X509_NAME_free> |
| - ScopedX509NAMEStack; |
| - |
| // We try reading data as PKCS12 only if reading as PEM was unsuccessful and |
| // if there is no indication that the data is malformed PEM. We assume the data |
| @@ -903,116 +898,80 @@ void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( |
| } |
| -static STACK_OF(X509_NAME)* GetCertificateNamesPKCS12(BIO* bio, |
| - const char* password) { |
| +static int SetClientAuthoritiesPKCS12(SSL_CTX* context, |
| + BIO* bio, |
| + const char* password) { |
| ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); |
| if (p12.get() == NULL) { |
| return NULL; |
| } |
| - ScopedX509NAMEStack result(sk_X509_NAME_new_null()); |
| - if (result.get() == NULL) { |
| - return NULL; |
| - } |
| - |
| EVP_PKEY* key = NULL; |
| X509 *cert = NULL; |
| STACK_OF(X509) *ca_certs = NULL; |
| int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs); |
| if (status == 0) { |
| - return NULL; |
| - } |
| - |
| - ScopedX509 x509(cert); |
| - ScopedX509Stack certs(ca_certs); |
| - X509_NAME* x509_name = X509_get_subject_name(x509.get()); |
| - if (x509_name == NULL) { |
| - return NULL; |
| + return status; |
| } |
| - x509_name = X509_NAME_dup(x509_name); |
| - if (x509_name == NULL) { |
| - return NULL; |
| + ScopedX509Stack cert_stack(ca_certs); |
| + status = SSL_CTX_add_client_CA(context, cert); |
| + if (status == 0) { |
| + X509_free(cert); |
| + return status; |
| } |
| - sk_X509_NAME_push(result.get(), x509_name); |
| - |
| - while (true) { |
| - ScopedX509 ca(sk_X509_shift(certs.get())); |
| - if (ca.get() == NULL) { |
| - break; |
| - } |
| - |
| - X509_NAME* x509_name = X509_get_subject_name(ca.get()); |
| - if (x509_name == NULL) { |
| - return NULL; |
| - } |
| - |
| - x509_name = X509_NAME_dup(x509_name); |
| - if (x509_name == NULL) { |
| - return NULL; |
| + X509* ca; |
| + while ((ca = sk_X509_shift(cert_stack.get())) != NULL) { |
| + status = SSL_CTX_add_client_CA(context, ca); |
| + X509_free(ca); // The name has been extracted. |
| + if (status == 0) { |
| + return status; |
| } |
| - |
| - sk_X509_NAME_push(result.get(), x509_name); |
| } |
| - return result.release(); |
| + return status; |
| } |
| -static STACK_OF(X509_NAME)* GetCertificateNamesPEM(BIO* bio) { |
| - ScopedX509NAMEStack result(sk_X509_NAME_new_null()); |
| - if (result.get() == NULL) { |
| - return NULL; |
| - } |
| - |
| - while (true) { |
| - ScopedX509 x509(PEM_read_bio_X509(bio, NULL, NULL, NULL)); |
| - if (x509.get() == NULL) { |
| - break; |
| - } |
| - |
| - X509_NAME* x509_name = X509_get_subject_name(x509.get()); |
| - if (x509_name == NULL) { |
| - return NULL; |
| - } |
| - |
| - // Duplicate the name to put it on the stack. |
| - x509_name = X509_NAME_dup(x509_name); |
| - if (x509_name == NULL) { |
| - return NULL; |
| +static int SetClientAuthoritiesPEM(SSL_CTX* context, BIO* bio) { |
| + int status = 0; |
| + X509* cert = NULL; |
| + while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { |
| + status = SSL_CTX_add_client_CA(context, cert); |
| + X509_free(cert); // The name has been extracted. |
| + if (status == 0) { |
| + return status; |
| } |
| - sk_X509_NAME_push(result.get(), x509_name); |
| - } |
| - |
| - if (sk_X509_NAME_num(result.get()) == 0) { |
| - // The data was not PEM. |
| - return NULL; |
| } |
| + // If bio does not contain PEM data, the first call to PEM_read_bio_X509 will |
| + // return NULL, and the while-loop will exit while status is still 0. |
| uint32_t err = ERR_peek_last_error(); |
| if ((ERR_GET_LIB(err) != ERR_LIB_PEM) || |
| (ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) { |
| - // The data was trying to be PEM, but was malformed. |
| - return NULL; |
| + // If bio contains data that is trying to be PEM but is malformed, then |
| + // this case will be triggered. |
| + status = 0; |
| } |
| - return result.release(); |
| + return status; |
| } |
| -static STACK_OF(X509_NAME)* GetCertificateNames(BIO* bio, |
| - const char* password) { |
| - STACK_OF(X509_NAME)* result = GetCertificateNamesPEM(bio); |
| - if (TryPKCS12(result != NULL)) { |
| +static int SetClientAuthorities(SSL_CTX* context, |
| + BIO* bio, |
| + const char* password) { |
| + int status = SetClientAuthoritiesPEM(context, bio); |
| + 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.
|
| ERR_clear_error(); |
| BIO_reset(bio); |
| - result = GetCertificateNamesPKCS12(bio, password); |
| - } else if (result != NULL) { |
| + status = SetClientAuthoritiesPKCS12(context, bio, password); |
| + } else if (status != 0) { |
| // The PEM file was successfully parsed. |
| ERR_clear_error(); |
| } |
| - return result; |
| + return status; |
| } |
| @@ -1020,19 +979,16 @@ void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( |
| Dart_NativeArguments args) { |
| SSL_CTX* context = GetSecurityContext(args); |
| const char* password = GetPasswordArgument(args, 2); |
| - STACK_OF(X509_NAME)* certificate_names; |
| + int status; |
| { |
| ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); |
| - certificate_names = GetCertificateNames(bio.bio(), password); |
| + status = SetClientAuthorities(context, bio.bio(), password); |
| } |
| - if (certificate_names != NULL) { |
| - SSL_CTX_set_client_CA_list(context, certificate_names); |
| - } else { |
| - Dart_ThrowException(DartUtils::NewDartArgumentError( |
| - "Could not load certificate names from file in SetClientAuthorities")); |
| - } |
| + CheckStatus(status, |
| + "TlsException", |
| + "Failure in setClientAuthoritiesBytes"); |
| } |