Chromium Code Reviews| Index: runtime/bin/secure_socket.cc |
| diff --git a/runtime/bin/secure_socket_boringssl.cc b/runtime/bin/secure_socket.cc |
| similarity index 66% |
| copy from runtime/bin/secure_socket_boringssl.cc |
| copy to runtime/bin/secure_socket.cc |
| index a3740a84a3af54282e6afd402d4af37a05661bf2..b48b0501a299697c1cefec9e45e1f222f35231a8 100644 |
| --- a/runtime/bin/secure_socket_boringssl.cc |
| +++ b/runtime/bin/secure_socket.cc |
| @@ -4,12 +4,7 @@ |
| #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED) |
| -#include "platform/globals.h" |
| -#if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) || \ |
| - defined(HOST_OS_WINDOWS) || defined(HOST_OS_FUCHSIA) |
| - |
| #include "bin/secure_socket.h" |
| -#include "bin/secure_socket_boringssl.h" |
| #include <errno.h> |
| #include <fcntl.h> |
| @@ -26,6 +21,8 @@ |
| #include <openssl/tls1.h> |
| #include <openssl/x509.h> |
| +#include "platform/globals.h" |
| + |
| #include "bin/builtin.h" |
| #include "bin/dartutils.h" |
| #include "bin/directory.h" |
| @@ -37,9 +34,6 @@ |
| #include "bin/utils.h" |
| #include "platform/text_buffer.h" |
| #include "platform/utils.h" |
| - |
| -#include "include/dart_api.h" |
| - |
| // Return the error from the containing function if handle is an error handle. |
| #define RETURN_IF_ERROR(handle) \ |
| { \ |
| @@ -61,24 +55,12 @@ const intptr_t SSLFilter::kInternalBIOSize = 10 * KB; |
| const intptr_t SSLFilter::kApproximateSize = |
| sizeof(SSLFilter) + (2 * SSLFilter::kInternalBIOSize); |
| -// The security context won't necessarily use the compiled-in root certificates, |
| -// but since there is no way to update the size of the allocation after creating |
| -// the weak persistent handle, we assume that it will. Note that when the |
| -// root certs aren't compiled in, |root_certificates_pem_length| is 0. |
| -const intptr_t SSLContext::kApproximateSize = |
| - sizeof(SSLContext) + root_certificates_pem_length; |
| - |
| -static const int kSSLFilterNativeFieldIndex = 0; |
| -static const int kSecurityContextNativeFieldIndex = 0; |
| -static const int kX509NativeFieldIndex = 0; |
| - |
| -static const bool SSL_LOG_STATUS = false; |
| -static const bool SSL_LOG_DATA = false; |
| +const int kSSLFilterNativeFieldIndex = 0; |
| +const int kSecurityContextNativeFieldIndex = 0; |
| static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000; |
| -const char* commandline_root_certs_file = NULL; |
| -const char* commandline_root_certs_cache = NULL; |
| +extern int CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx); |
|
bkonyi
2017/05/25 22:49:20
I'm not sure if this is what we should do, or if w
zra
2017/05/26 18:11:12
Yes, try to put the declaration in a header.
bkonyi
2017/05/26 23:35:30
Done.
|
| // Get the error messages from BoringSSL, and put them in buffer as a |
| // null-terminated string. |
| @@ -107,10 +89,10 @@ static void FetchErrorString(const SSL* ssl, TextBuffer* text_buffer) { |
| // Handle an error reported from the BoringSSL library. |
| -static void ThrowIOException(int status, |
| - const char* exception_type, |
| - const char* message, |
| - const SSL* ssl) { |
| +void ThrowIOException(int status, |
| + const char* exception_type, |
| + const char* message, |
| + const SSL* ssl) { |
| Dart_Handle exception; |
| { |
| TextBuffer error_string(SSL_ERROR_MESSAGE_BUFFER_SIZE); |
| @@ -160,8 +142,8 @@ static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { |
| } |
| -static SSLContext* GetSecurityContext(Dart_NativeArguments args) { |
| - SSLContext* context; |
| +SSLCertContext* SSLCertContext::GetSecurityContext(Dart_NativeArguments args) { |
| + SSLCertContext* context; |
| Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| ASSERT(Dart_IsInstance(dart_this)); |
| ThrowIfError( |
| @@ -174,13 +156,17 @@ static SSLContext* GetSecurityContext(Dart_NativeArguments args) { |
| static void DeleteSecurityContext(void* isolate_data, |
| Dart_WeakPersistentHandle handle, |
| void* context_pointer) { |
| - SSLContext* context = static_cast<SSLContext*>(context_pointer); |
| + SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer); |
| +#if !defined(HOST_OS_MACOS) |
|
zra
2017/05/26 18:11:12
Let's not have platform #ifdefs in the non-platfor
bkonyi
2017/05/26 23:35:30
Done.
|
| delete context; |
| +#else |
| + context->Release(); |
| +#endif |
| } |
| static Dart_Handle SetSecurityContext(Dart_NativeArguments args, |
| - SSLContext* context) { |
| + SSLCertContext* context) { |
| Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); |
| RETURN_IF_ERROR(dart_this); |
| ASSERT(Dart_IsInstance(dart_this)); |
| @@ -188,27 +174,17 @@ static Dart_Handle SetSecurityContext(Dart_NativeArguments args, |
| Dart_SetNativeInstanceField(dart_this, kSecurityContextNativeFieldIndex, |
| reinterpret_cast<intptr_t>(context)); |
| RETURN_IF_ERROR(err); |
| - Dart_NewWeakPersistentHandle(dart_this, context, SSLContext::kApproximateSize, |
| + Dart_NewWeakPersistentHandle(dart_this, context, |
| + SSLCertContext::kApproximateSize, |
| DeleteSecurityContext); |
| return Dart_Null(); |
| } |
| -static X509* GetX509Certificate(Dart_NativeArguments args) { |
| - X509* certificate; |
| - Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| - ASSERT(Dart_IsInstance(dart_this)); |
| - ThrowIfError( |
| - Dart_GetNativeInstanceField(dart_this, kX509NativeFieldIndex, |
| - reinterpret_cast<intptr_t*>(&certificate))); |
| - return certificate; |
| -} |
| - |
| - |
| // Forward declaration. |
| static void SetAlpnProtocolList(Dart_Handle protocols_handle, |
| SSL* ssl, |
| - SSLContext* context, |
| + SSLCertContext* context, |
| bool is_server); |
| @@ -244,7 +220,7 @@ void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) { |
| // TODO(whesse): Is truncating a Dart string containing \0 what we want? |
| ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); |
| - SSLContext* context = NULL; |
| + SSLCertContext* context = NULL; |
| if (!Dart_IsNull(context_object)) { |
| ThrowIfError(Dart_GetNativeInstanceField( |
| context_object, kSecurityContextNativeFieldIndex, |
| @@ -255,7 +231,7 @@ void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) { |
| // It will have the correct length encoding of the protocols array. |
| ASSERT(!Dart_IsNull(protocols_handle)); |
| - GetFilter(args)->Connect(host_name, context->context(), is_server, |
| + GetFilter(args)->Connect(host_name, context, is_server, |
| request_client_certificate, |
| require_client_certificate, protocols_handle); |
| } |
| @@ -339,108 +315,13 @@ void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { |
| } |
| -static void ReleaseCertificate(void* isolate_data, |
| - Dart_WeakPersistentHandle handle, |
| - void* context_pointer) { |
| - X509* cert = reinterpret_cast<X509*>(context_pointer); |
| - X509_free(cert); |
| -} |
| - |
| - |
| -static intptr_t EstimateX509Size(X509* certificate) { |
| - intptr_t length = i2d_X509(certificate, NULL); |
| - return length > 0 ? length : 0; |
| -} |
| - |
| - |
| -// Returns the handle for a Dart object wrapping the X509 certificate object. |
| -// The caller should own a reference to the X509 object whose reference count |
| -// won't drop to zero before the ReleaseCertificate finalizer runs. |
| -static Dart_Handle WrappedX509Certificate(X509* certificate) { |
| - if (certificate == NULL) { |
| - return Dart_Null(); |
| - } |
| - Dart_Handle x509_type = |
| - DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); |
| - if (Dart_IsError(x509_type)) { |
| - X509_free(certificate); |
| - return x509_type; |
| - } |
| - Dart_Handle arguments[] = {NULL}; |
| - Dart_Handle result = |
| - Dart_New(x509_type, DartUtils::NewString("_"), 0, arguments); |
| - if (Dart_IsError(result)) { |
| - X509_free(certificate); |
| - return result; |
| - } |
| - ASSERT(Dart_IsInstance(result)); |
| - Dart_Handle status = Dart_SetNativeInstanceField( |
| - result, kX509NativeFieldIndex, reinterpret_cast<intptr_t>(certificate)); |
| - if (Dart_IsError(status)) { |
| - X509_free(certificate); |
| - return status; |
| - } |
| - const intptr_t approximate_size_of_certificate = |
| - sizeof(*certificate) + EstimateX509Size(certificate); |
| - ASSERT(approximate_size_of_certificate > 0); |
| - Dart_NewWeakPersistentHandle(result, reinterpret_cast<void*>(certificate), |
| - approximate_size_of_certificate, |
| - ReleaseCertificate); |
| - return result; |
| -} |
| - |
| - |
| -int CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx) { |
| - if (preverify_ok == 1) { |
| - return 1; |
| - } |
| - Dart_Isolate isolate = Dart_CurrentIsolate(); |
| - if (isolate == NULL) { |
| - FATAL("CertificateCallback called with no current isolate\n"); |
| - } |
| - X509* certificate = X509_STORE_CTX_get_current_cert(store_ctx); |
| - int ssl_index = SSL_get_ex_data_X509_STORE_CTX_idx(); |
| - SSL* ssl = |
| - static_cast<SSL*>(X509_STORE_CTX_get_ex_data(store_ctx, ssl_index)); |
| - SSLFilter* filter = static_cast<SSLFilter*>( |
| - SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index)); |
| - Dart_Handle callback = filter->bad_certificate_callback(); |
| - if (Dart_IsNull(callback)) { |
| - return 0; |
| - } |
| - |
| - // Upref since the Dart X509 object may outlive the SecurityContext. |
| - if (certificate != NULL) { |
| - X509_up_ref(certificate); |
| - } |
| - Dart_Handle args[1]; |
| - args[0] = WrappedX509Certificate(certificate); |
| - if (Dart_IsError(args[0])) { |
| - filter->callback_error = args[0]; |
| - return 0; |
| - } |
| - Dart_Handle result = Dart_InvokeClosure(callback, 1, args); |
| - if (!Dart_IsError(result) && !Dart_IsBoolean(result)) { |
| - result = Dart_NewUnhandledExceptionError(DartUtils::NewDartIOException( |
| - "HandshakeException", |
| - "BadCertificateCallback returned a value that was not a boolean", |
| - Dart_Null())); |
| - } |
| - if (Dart_IsError(result)) { |
| - filter->callback_error = result; |
| - return 0; |
| - } |
| - return DartUtils::GetBooleanValue(result); |
| -} |
| - |
| - |
| void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) { |
| SSLFilter::InitializeLibrary(); |
| SSL_CTX* ctx = SSL_CTX_new(TLS_method()); |
| SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, CertificateCallback); |
| SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION); |
| SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM"); |
| - SSLContext* context = new SSLContext(ctx); |
| + SSLCertContext* context = new SSLCertContext(ctx); |
| Dart_Handle err = SetSecurityContext(args, context); |
| if (Dart_IsError(err)) { |
| delete context; |
| @@ -655,8 +536,8 @@ static EVP_PKEY* GetPrivateKey(BIO* bio, const char* password) { |
| } |
| -static const char* GetPasswordArgument(Dart_NativeArguments args, |
| - intptr_t index) { |
| +const char* SSLCertContext::GetPasswordArgument(Dart_NativeArguments args, |
| + intptr_t index) { |
| Dart_Handle password_object = |
| ThrowIfError(Dart_GetNativeArgument(args, index)); |
| const char* password = NULL; |
| @@ -678,8 +559,8 @@ static const char* GetPasswordArgument(Dart_NativeArguments args, |
| void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( |
| Dart_NativeArguments args) { |
| - SSLContext* context = GetSecurityContext(args); |
| - const char* password = GetPasswordArgument(args, 2); |
| + SSLCertContext* context = SSLCertContext::GetSecurityContext(args); |
| + const char* password = SSLCertContext::GetPasswordArgument(args, 2); |
| int status; |
| { |
| @@ -698,418 +579,9 @@ void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( |
| } |
| -static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context, |
| - BIO* bio, |
| - const char* password) { |
| - ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); |
| - if (p12.get() == NULL) { |
| - return 0; |
| - } |
| - |
| - 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 status; |
| - } |
| - |
| - ScopedX509Stack cert_stack(ca_certs); |
| - X509_STORE* store = SSL_CTX_get_cert_store(context); |
| - status = X509_STORE_add_cert(store, cert); |
| - // X509_STORE_add_cert increments the reference count of cert on success. |
| - X509_free(cert); |
| - if (status == 0) { |
| - return status; |
| - } |
| - |
| - X509* ca; |
| - while ((ca = sk_X509_shift(cert_stack.get())) != NULL) { |
| - status = X509_STORE_add_cert(store, ca); |
| - // X509_STORE_add_cert increments the reference count of cert on success. |
| - X509_free(ca); |
| - if (status == 0) { |
| - return status; |
| - } |
| - } |
| - |
| - return status; |
| -} |
| - |
| - |
| -static int SetTrustedCertificatesBytesPEM(SSL_CTX* context, BIO* bio) { |
| - X509_STORE* store = SSL_CTX_get_cert_store(context); |
| - |
| - int status = 0; |
| - X509* cert = NULL; |
| - while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { |
| - status = X509_STORE_add_cert(store, cert); |
| - // X509_STORE_add_cert increments the reference count of cert on success. |
| - X509_free(cert); |
| - if (status == 0) { |
| - return status; |
| - } |
| - } |
| - |
| - // If no PEM start line is found, it means that we read to the end of the |
| - // file, or that the file isn't PEM. In the first case, status will be |
| - // non-zero indicating success. In the second case, status will be 0, |
| - // indicating that we should try to read as PKCS12. If there is some other |
| - // error, we return it up to the caller. |
| - return NoPEMStartLine() ? status : 0; |
| -} |
| - |
| - |
| -static int SetTrustedCertificatesBytes(SSL_CTX* context, |
| - BIO* bio, |
| - const char* password) { |
| - int status = SetTrustedCertificatesBytesPEM(context, bio); |
| - if (status == 0) { |
| - if (NoPEMStartLine()) { |
| - ERR_clear_error(); |
| - BIO_reset(bio); |
| - status = SetTrustedCertificatesBytesPKCS12(context, bio, password); |
| - } |
| - } else { |
| - // The PEM file was successfully parsed. |
| - ERR_clear_error(); |
| - } |
| - return status; |
| -} |
| - |
| - |
| -void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( |
| - Dart_NativeArguments args) { |
| - SSLContext* context = GetSecurityContext(args); |
| - const char* password = GetPasswordArgument(args, 2); |
| - int status; |
| - { |
| - ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); |
| - status = |
| - SetTrustedCertificatesBytes(context->context(), bio.bio(), password); |
| - } |
| - CheckStatus(status, "TlsException", "Failure in setTrustedCertificatesBytes"); |
| -} |
| - |
| - |
| -void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) { |
| - Dart_SetReturnValue(args, Dart_NewBoolean(true)); |
| -} |
| - |
| - |
| -static void AddCompiledInCerts(SSLContext* context) { |
| - if (root_certificates_pem == NULL) { |
| - if (SSL_LOG_STATUS) { |
| - Log::Print("Missing compiled-in roots\n"); |
| - } |
| - return; |
| - } |
| - X509_STORE* store = SSL_CTX_get_cert_store(context->context()); |
| - BIO* roots_bio = |
| - BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem), |
| - root_certificates_pem_length); |
| - X509* root_cert; |
| - // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case, |
| - // backed by a memory buffer), and returns X509 objects, one by one. |
| - // When the end of the bio is reached, it returns null. |
| - while ((root_cert = PEM_read_bio_X509(roots_bio, NULL, NULL, NULL)) != NULL) { |
| - int status = X509_STORE_add_cert(store, root_cert); |
| - // X509_STORE_add_cert increments the reference count of cert on success. |
| - X509_free(root_cert); |
| - if (status == 0) { |
| - break; |
| - } |
| - } |
| - BIO_free(roots_bio); |
| - // If there is an error here, it must be the error indicating that we are done |
| - // reading PEM certificates. |
| - ASSERT((ERR_peek_error() == 0) || NoPEMStartLine()); |
| - ERR_clear_error(); |
| -} |
| - |
| - |
| -static void LoadRootCertFile(SSLContext* context, const char* file) { |
| - if (SSL_LOG_STATUS) { |
| - Log::Print("Looking for trusted roots in %s\n", file); |
| - } |
| - if (!File::Exists(file)) { |
| - ThrowIOException(-1, "TlsException", "Failed to find root cert file", NULL); |
| - } |
| - int status = SSL_CTX_load_verify_locations(context->context(), file, NULL); |
| - CheckStatus(status, "TlsException", "Failure trusting builtin roots"); |
| - if (SSL_LOG_STATUS) { |
| - Log::Print("Trusting roots from: %s\n", file); |
| - } |
| -} |
| - |
| - |
| -static void LoadRootCertCache(SSLContext* context, const char* cache) { |
| - if (SSL_LOG_STATUS) { |
| - Log::Print("Looking for trusted roots in %s\n", cache); |
| - } |
| - if (Directory::Exists(cache) != Directory::EXISTS) { |
| - ThrowIOException(-1, "TlsException", "Failed to find root cert cache", |
| - NULL); |
| - } |
| - int status = SSL_CTX_load_verify_locations(context->context(), NULL, cache); |
| - CheckStatus(status, "TlsException", "Failure trusting builtin roots"); |
| - if (SSL_LOG_STATUS) { |
| - Log::Print("Trusting roots from: %s\n", cache); |
| - } |
| -} |
| - |
| - |
| -void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( |
| - Dart_NativeArguments args) { |
| - SSLContext* context = GetSecurityContext(args); |
| - |
| - // First, try to use locations specified on the command line. |
| - if (commandline_root_certs_file != NULL) { |
| - LoadRootCertFile(context, commandline_root_certs_file); |
| - return; |
| - } |
| - |
| - if (commandline_root_certs_cache != NULL) { |
| - LoadRootCertCache(context, commandline_root_certs_cache); |
| - return; |
| - } |
| - |
| -#if defined(HOST_OS_ANDROID) |
| - // On Android, we don't compile in the trusted root certificates. Insead, |
| - // we use the directory of trusted certificates already present on the device. |
| - // This saves ~240KB from the size of the binary. This has the drawback that |
| - // SSL_do_handshake will synchronously hit the filesystem looking for root |
| - // certs during its trust evaluation. We call SSL_do_handshake directly from |
| - // the Dart thread so that Dart code can be invoked from the "bad certificate" |
| - // callback called by SSL_do_handshake. |
| - const char* android_cacerts = "/system/etc/security/cacerts"; |
| - LoadRootCertCache(context, android_cacerts); |
| - return; |
| -#elif defined(HOST_OS_LINUX) |
| - // On Linux, we use the compiled-in trusted certs as a last resort. First, |
| - // we try to find the trusted certs in various standard locations. A good |
| - // discussion of the complexities of this endeavor can be found here: |
| - // |
| - // https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/ |
| - const char* bundle = "/etc/pki/tls/certs/ca-bundle.crt"; |
| - const char* cachedir = "/etc/ssl/certs"; |
| - if (File::Exists(bundle)) { |
| - LoadRootCertFile(context, bundle); |
| - return; |
| - } |
| - |
| - if (Directory::Exists(cachedir) == Directory::EXISTS) { |
| - LoadRootCertCache(context, cachedir); |
| - return; |
| - } |
| -#endif // defined(HOST_OS_ANDROID) |
| - |
| - // Fall back on the compiled-in certs if the standard locations don't exist, |
| - // or we aren't on Linux. |
| - if (SSL_LOG_STATUS) { |
| - Log::Print("Trusting compiled-in roots\n"); |
| - } |
| - AddCompiledInCerts(context); |
| -} |
| - |
| - |
| -static int UseChainBytesPKCS12(SSL_CTX* context, |
| - BIO* bio, |
| - const char* password) { |
| - ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); |
| - if (p12.get() == NULL) { |
| - return 0; |
| - } |
| - |
| - 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 status; |
| - } |
| - |
| - ScopedX509 x509(cert); |
| - ScopedX509Stack certs(ca_certs); |
| - status = SSL_CTX_use_certificate(context, x509.get()); |
| - if (ERR_peek_error() != 0) { |
| - // Key/certificate mismatch doesn't imply status is 0. |
| - status = 0; |
| - } |
| - if (status == 0) { |
| - return status; |
| - } |
| - |
| - SSL_CTX_clear_chain_certs(context); |
| - |
| - X509* ca; |
| - while ((ca = sk_X509_shift(certs.get())) != NULL) { |
| - status = SSL_CTX_add0_chain_cert(context, ca); |
| - // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the |
| - // call fails. |
| - if (status == 0) { |
| - X509_free(ca); |
| - return status; |
| - } |
| - } |
| - |
| - return status; |
| -} |
| - |
| - |
| -static int UseChainBytesPEM(SSL_CTX* context, BIO* bio) { |
| - int status = 0; |
| - ScopedX509 x509(PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)); |
| - if (x509.get() == NULL) { |
| - return 0; |
| - } |
| - |
| - status = SSL_CTX_use_certificate(context, x509.get()); |
| - if (ERR_peek_error() != 0) { |
| - // Key/certificate mismatch doesn't imply status is 0. |
| - status = 0; |
| - } |
| - if (status == 0) { |
| - return status; |
| - } |
| - |
| - SSL_CTX_clear_chain_certs(context); |
| - |
| - X509* ca; |
| - while ((ca = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { |
| - status = SSL_CTX_add0_chain_cert(context, ca); |
| - // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the |
| - // call fails. |
| - if (status == 0) { |
| - X509_free(ca); |
| - return status; |
| - } |
| - // Note that we must not free `ca` if it was successfully added to the |
| - // chain. We must free the main certificate x509, though since its reference |
| - // count is increased by SSL_CTX_use_certificate. |
| - } |
| - |
| - return NoPEMStartLine() ? status : 0; |
| -} |
| - |
| - |
| -static int UseChainBytes(SSL_CTX* context, BIO* bio, const char* password) { |
| - int status = UseChainBytesPEM(context, bio); |
| - if (status == 0) { |
| - if (NoPEMStartLine()) { |
| - ERR_clear_error(); |
| - BIO_reset(bio); |
| - status = UseChainBytesPKCS12(context, bio, password); |
| - } |
| - } else { |
| - // The PEM file was successfully read. |
| - ERR_clear_error(); |
| - } |
| - return status; |
| -} |
| - |
| - |
| -void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( |
| - Dart_NativeArguments args) { |
| - SSLContext* context = GetSecurityContext(args); |
| - const char* password = GetPasswordArgument(args, 2); |
| - int status; |
| - { |
| - ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); |
| - status = UseChainBytes(context->context(), bio.bio(), password); |
| - } |
| - CheckStatus(status, "TlsException", "Failure in useCertificateChainBytes"); |
| -} |
| - |
| - |
| -static int SetClientAuthoritiesPKCS12(SSL_CTX* context, |
| - BIO* bio, |
| - const char* password) { |
| - ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); |
| - if (p12.get() == NULL) { |
| - return 0; |
| - } |
| - |
| - 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 status; |
| - } |
| - |
| - ScopedX509Stack cert_stack(ca_certs); |
| - status = SSL_CTX_add_client_CA(context, cert); |
| - // SSL_CTX_add_client_CA increments the reference count of cert on success. |
| - X509_free(cert); |
| - if (status == 0) { |
| - return status; |
| - } |
| - |
| - X509* ca; |
| - while ((ca = sk_X509_shift(cert_stack.get())) != NULL) { |
| - status = SSL_CTX_add_client_CA(context, ca); |
| - // SSL_CTX_add_client_CA increments the reference count of ca on success. |
| - X509_free(ca); // The name has been extracted. |
| - if (status == 0) { |
| - return status; |
| - } |
| - } |
| - |
| - return status; |
| -} |
| - |
| - |
| -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; |
| - } |
| - } |
| - return NoPEMStartLine() ? status : 0; |
| -} |
| - |
| - |
| -static int SetClientAuthorities(SSL_CTX* context, |
| - BIO* bio, |
| - const char* password) { |
| - int status = SetClientAuthoritiesPEM(context, bio); |
| - if (status == 0) { |
| - if (NoPEMStartLine()) { |
| - ERR_clear_error(); |
| - BIO_reset(bio); |
| - status = SetClientAuthoritiesPKCS12(context, bio, password); |
| - } |
| - } else { |
| - // The PEM file was successfully parsed. |
| - ERR_clear_error(); |
| - } |
| - return status; |
| -} |
| - |
| - |
| -void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( |
| - Dart_NativeArguments args) { |
| - SSLContext* context = GetSecurityContext(args); |
| - const char* password = GetPasswordArgument(args, 2); |
| - |
| - int status; |
| - { |
| - ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); |
| - status = SetClientAuthorities(context->context(), bio.bio(), password); |
| - } |
| - |
| - CheckStatus(status, "TlsException", "Failure in setClientAuthoritiesBytes"); |
| -} |
| - |
| - |
| void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( |
| Dart_NativeArguments args) { |
| - SSLContext* context = GetSecurityContext(args); |
| + SSLCertContext* context = SSLCertContext::GetSecurityContext(args); |
| Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
| Dart_Handle is_server_handle = ThrowIfError(Dart_GetNativeArgument(args, 2)); |
| if (Dart_IsBoolean(is_server_handle)) { |
| @@ -1122,51 +594,6 @@ void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( |
| } |
| -void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) { |
| - X509* certificate = GetX509Certificate(args); |
| - X509_NAME* subject = X509_get_subject_name(certificate); |
| - char* subject_string = X509_NAME_oneline(subject, NULL, 0); |
| - Dart_SetReturnValue(args, Dart_NewStringFromCString(subject_string)); |
| - OPENSSL_free(subject_string); |
| -} |
| - |
| - |
| -void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) { |
| - X509* certificate = GetX509Certificate(args); |
| - X509_NAME* issuer = X509_get_issuer_name(certificate); |
| - char* issuer_string = X509_NAME_oneline(issuer, NULL, 0); |
| - Dart_SetReturnValue(args, Dart_NewStringFromCString(issuer_string)); |
| - OPENSSL_free(issuer_string); |
| -} |
| - |
| -static Dart_Handle ASN1TimeToMilliseconds(ASN1_TIME* aTime) { |
| - ASN1_UTCTIME* epoch_start = M_ASN1_UTCTIME_new(); |
| - ASN1_UTCTIME_set_string(epoch_start, "700101000000Z"); |
| - int days; |
| - int seconds; |
| - int result = ASN1_TIME_diff(&days, &seconds, epoch_start, aTime); |
| - M_ASN1_UTCTIME_free(epoch_start); |
| - if (result != 1) { |
| - // TODO(whesse): Propagate an error to Dart. |
| - Log::PrintErr("ASN1Time error %d\n", result); |
| - } |
| - return Dart_NewInteger((86400LL * days + seconds) * 1000LL); |
| -} |
| - |
| -void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) { |
| - X509* certificate = GetX509Certificate(args); |
| - ASN1_TIME* not_before = X509_get_notBefore(certificate); |
| - Dart_SetReturnValue(args, ASN1TimeToMilliseconds(not_before)); |
| -} |
| - |
| - |
| -void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) { |
| - X509* certificate = GetX509Certificate(args); |
| - ASN1_TIME* not_after = X509_get_notAfter(certificate); |
| - Dart_SetReturnValue(args, ASN1TimeToMilliseconds(not_after)); |
| -} |
| - |
| - |
| /** |
| * Pushes data through the SSL filter, reading and writing from circular |
| * buffers shared with Dart. |
| @@ -1304,10 +731,8 @@ Dart_Handle SSLFilter::Init(Dart_Handle dart_this) { |
| ASSERT(string_length_ == NULL); |
| string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length")); |
| ASSERT(string_length_ != NULL); |
| - ASSERT(bad_certificate_callback_ == NULL); |
|
zra
2017/05/26 18:11:12
Why remove this assert?
bkonyi
2017/05/26 23:35:29
Probably did it during all the refactoring and did
|
| bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null()); |
| ASSERT(bad_certificate_callback_ != NULL); |
| - |
| // Caller handles cleanup on an error. |
| return InitializeBuffers(dart_this); |
| } |
| @@ -1419,14 +844,6 @@ void SSLFilter::InitializeLibrary() { |
| } |
| -Dart_Handle SSLFilter::PeerCertificate() { |
| - // SSL_get_peer_certificate incs the refcount of certificate. X509_free is |
| - // called by the finalizer set up by WrappedX509Certificate. |
| - X509* certificate = SSL_get_peer_certificate(ssl_); |
| - return WrappedX509Certificate(certificate); |
| -} |
| - |
| - |
| int AlpnCallback(SSL* ssl, |
| const uint8_t** out, |
| uint8_t* outlen, |
| @@ -1460,7 +877,7 @@ int AlpnCallback(SSL* ssl, |
| // Sets the protocol list for ALPN on a SSL object or a context. |
| static void SetAlpnProtocolList(Dart_Handle protocols_handle, |
| SSL* ssl, |
| - SSLContext* context, |
| + SSLCertContext* context, |
| bool is_server) { |
| // Enable ALPN (application layer protocol negotiation) if the caller provides |
| // a valid list of supported protocols. |
| @@ -1517,7 +934,7 @@ static void SetAlpnProtocolList(Dart_Handle protocols_handle, |
| void SSLFilter::Connect(const char* hostname, |
| - SSL_CTX* context, |
| + SSLCertContext* context, |
| bool is_server, |
| bool request_client_certificate, |
| bool require_client_certificate, |
| @@ -1534,11 +951,13 @@ void SSLFilter::Connect(const char* hostname, |
| kInternalBIOSize); |
| CheckStatusSSL(status, "TlsException", "BIO_new_bio_pair", ssl_); |
| - assert(context != NULL); |
| - ssl_ = SSL_new(context); |
| + ASSERT(context != NULL); |
| + ASSERT(context->context() != NULL); |
| + ssl_ = SSL_new(context->context()); |
| SSL_set_bio(ssl_, ssl_side, ssl_side); |
| SSL_set_mode(ssl_, SSL_MODE_AUTO_RETRY); // TODO(whesse): Is this right? |
| SSL_set_ex_data(ssl_, filter_ssl_index, this); |
| + RegisterCallbacks(context); |
| if (is_server_) { |
| int certificate_mode = |
| @@ -1801,7 +1220,5 @@ int SSLFilter::ProcessWriteEncryptedBuffer(int start, int end) { |
| } // namespace bin |
| } // namespace dart |
| -#endif // defined(HOST_OS_LINUX) |
| - |
| #endif // !defined(DART_IO_DISABLED) && |
| // !defined(DART_IO_SECURE_SOCKET_DISABLED) |