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

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

Issue 2206233003: Fix memory leaks in BoringSSL secure socket implementation (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Add comments Created 4 years, 4 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/secure_socket_boringssl.h ('k') | no next file » | 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 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED) 5 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED)
6 6
7 #include "platform/globals.h" 7 #include "platform/globals.h"
8 #if defined(TARGET_OS_ANDROID) || \ 8 #if defined(TARGET_OS_ANDROID) || \
9 defined(TARGET_OS_LINUX) || \ 9 defined(TARGET_OS_LINUX) || \
10 defined(TARGET_OS_WINDOWS) 10 defined(TARGET_OS_WINDOWS)
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 } 87 }
88 } 88 }
89 89
90 90
91 /* Handle an error reported from the BoringSSL library. */ 91 /* Handle an error reported from the BoringSSL library. */
92 static void ThrowIOException(int status, 92 static void ThrowIOException(int status,
93 const char* exception_type, 93 const char* exception_type,
94 const char* message) { 94 const char* message) {
95 char error_string[SSL_ERROR_MESSAGE_BUFFER_SIZE]; 95 char error_string[SSL_ERROR_MESSAGE_BUFFER_SIZE];
96 FetchErrorString(error_string, SSL_ERROR_MESSAGE_BUFFER_SIZE); 96 FetchErrorString(error_string, SSL_ERROR_MESSAGE_BUFFER_SIZE);
97 OSError os_error_struct(status, error_string, OSError::kBoringSSL); 97 Dart_Handle exception;
98 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct); 98 {
99 Dart_Handle exception = 99 OSError os_error_struct(status, error_string, OSError::kBoringSSL);
100 DartUtils::NewDartIOException(exception_type, message, os_error); 100 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
101 ASSERT(!Dart_IsError(exception)); 101 exception =
102 DartUtils::NewDartIOException(exception_type, message, os_error);
103 ASSERT(!Dart_IsError(exception));
104 }
102 Dart_ThrowException(exception); 105 Dart_ThrowException(exception);
103 UNREACHABLE(); 106 UNREACHABLE();
104 } 107 }
105 108
106 109
107 static SSLFilter* GetFilter(Dart_NativeArguments args) { 110 static SSLFilter* GetFilter(Dart_NativeArguments args) {
108 SSLFilter* filter; 111 SSLFilter* filter;
109 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); 112 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
110 ASSERT(Dart_IsInstance(dart_this)); 113 ASSERT(Dart_IsInstance(dart_this));
111 ThrowIfError(Dart_GetNativeInstanceField( 114 ThrowIfError(Dart_GetNativeInstanceField(
(...skipping 24 matching lines...) Expand all
136 reinterpret_cast<intptr_t>(filter)); 139 reinterpret_cast<intptr_t>(filter));
137 RETURN_IF_ERROR(err); 140 RETURN_IF_ERROR(err);
138 Dart_NewWeakPersistentHandle(dart_this, 141 Dart_NewWeakPersistentHandle(dart_this,
139 reinterpret_cast<void*>(filter), 142 reinterpret_cast<void*>(filter),
140 sizeof(*filter), 143 sizeof(*filter),
141 DeleteFilter); 144 DeleteFilter);
142 return Dart_Null(); 145 return Dart_Null();
143 } 146 }
144 147
145 148
146 static SSL_CTX* GetSecurityContext(Dart_NativeArguments args) { 149 static SSLContext* GetSecurityContext(Dart_NativeArguments args) {
147 SSL_CTX* context; 150 SSLContext* context;
148 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); 151 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
149 ASSERT(Dart_IsInstance(dart_this)); 152 ASSERT(Dart_IsInstance(dart_this));
150 ThrowIfError(Dart_GetNativeInstanceField( 153 ThrowIfError(Dart_GetNativeInstanceField(
151 dart_this, 154 dart_this,
152 kSecurityContextNativeFieldIndex, 155 kSecurityContextNativeFieldIndex,
153 reinterpret_cast<intptr_t*>(&context))); 156 reinterpret_cast<intptr_t*>(&context)));
154 return context; 157 return context;
155 } 158 }
156 159
157 160
158 static void FreeSecurityContext( 161 static void DeleteSecurityContext(
159 void* isolate_data, 162 void* isolate_data,
160 Dart_WeakPersistentHandle handle, 163 Dart_WeakPersistentHandle handle,
161 void* context_pointer) { 164 void* context_pointer) {
162 SSL_CTX* context = static_cast<SSL_CTX*>(context_pointer); 165 SSLContext* context = static_cast<SSLContext*>(context_pointer);
163 SSL_CTX_free(context); 166 delete context;
164 } 167 }
165 168
166 169
167 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, 170 static Dart_Handle SetSecurityContext(Dart_NativeArguments args,
168 SSL_CTX* context) { 171 SSLContext* context) {
169 const int approximate_size_of_context = 1500; 172 const int approximate_size_of_context = 1500;
170 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); 173 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
171 RETURN_IF_ERROR(dart_this); 174 RETURN_IF_ERROR(dart_this);
172 ASSERT(Dart_IsInstance(dart_this)); 175 ASSERT(Dart_IsInstance(dart_this));
173 Dart_Handle err = Dart_SetNativeInstanceField( 176 Dart_Handle err = Dart_SetNativeInstanceField(
174 dart_this, 177 dart_this,
175 kSecurityContextNativeFieldIndex, 178 kSecurityContextNativeFieldIndex,
176 reinterpret_cast<intptr_t>(context)); 179 reinterpret_cast<intptr_t>(context));
177 RETURN_IF_ERROR(err); 180 RETURN_IF_ERROR(err);
178 Dart_NewWeakPersistentHandle(dart_this, 181 Dart_NewWeakPersistentHandle(dart_this,
179 context, 182 context,
180 approximate_size_of_context, 183 approximate_size_of_context,
181 FreeSecurityContext); 184 DeleteSecurityContext);
182 return Dart_Null(); 185 return Dart_Null();
183 } 186 }
184 187
185 188
186 static X509* GetX509Certificate(Dart_NativeArguments args) { 189 static X509* GetX509Certificate(Dart_NativeArguments args) {
187 X509* certificate; 190 X509* certificate;
188 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); 191 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
189 ASSERT(Dart_IsInstance(dart_this)); 192 ASSERT(Dart_IsInstance(dart_this));
190 ThrowIfError(Dart_GetNativeInstanceField( 193 ThrowIfError(Dart_GetNativeInstanceField(
191 dart_this, 194 dart_this,
192 kX509NativeFieldIndex, 195 kX509NativeFieldIndex,
193 reinterpret_cast<intptr_t*>(&certificate))); 196 reinterpret_cast<intptr_t*>(&certificate)));
194 return certificate; 197 return certificate;
195 } 198 }
196 199
197 200
198 // Forward declaration. 201 // Forward declaration.
199 static void SetAlpnProtocolList(Dart_Handle protocols_handle, 202 static void SetAlpnProtocolList(Dart_Handle protocols_handle,
200 SSL* ssl, 203 SSL* ssl,
201 SSL_CTX* context, 204 SSLContext* context,
202 bool is_server); 205 bool is_server);
203 206
204 207
205 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) { 208 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) {
206 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); 209 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
207 SSLFilter* filter = new SSLFilter(); 210 SSLFilter* filter = new SSLFilter();
208 Dart_Handle err = SetFilter(args, filter); 211 Dart_Handle err = SetFilter(args, filter);
209 if (Dart_IsError(err)) { 212 if (Dart_IsError(err)) {
210 filter->Release(); 213 filter->Release();
211 Dart_PropagateError(err); 214 Dart_PropagateError(err);
(...skipping 16 matching lines...) Expand all
228 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); 231 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
229 bool require_client_certificate = 232 bool require_client_certificate =
230 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5)); 233 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5));
231 Dart_Handle protocols_handle = 234 Dart_Handle protocols_handle =
232 ThrowIfError(Dart_GetNativeArgument(args, 6)); 235 ThrowIfError(Dart_GetNativeArgument(args, 6));
233 236
234 const char* host_name = NULL; 237 const char* host_name = NULL;
235 // TODO(whesse): Is truncating a Dart string containing \0 what we want? 238 // TODO(whesse): Is truncating a Dart string containing \0 what we want?
236 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); 239 ThrowIfError(Dart_StringToCString(host_name_object, &host_name));
237 240
238 SSL_CTX* context = NULL; 241 SSLContext* context = NULL;
239 if (!Dart_IsNull(context_object)) { 242 if (!Dart_IsNull(context_object)) {
240 ThrowIfError(Dart_GetNativeInstanceField( 243 ThrowIfError(Dart_GetNativeInstanceField(
241 context_object, 244 context_object,
242 kSecurityContextNativeFieldIndex, 245 kSecurityContextNativeFieldIndex,
243 reinterpret_cast<intptr_t*>(&context))); 246 reinterpret_cast<intptr_t*>(&context)));
244 } 247 }
245 248
246 // The protocols_handle is guaranteed to be a valid Uint8List. 249 // The protocols_handle is guaranteed to be a valid Uint8List.
247 // It will have the correct length encoding of the protocols array. 250 // It will have the correct length encoding of the protocols array.
248 ASSERT(!Dart_IsNull(protocols_handle)); 251 ASSERT(!Dart_IsNull(protocols_handle));
249 252
250 GetFilter(args)->Connect(host_name, 253 GetFilter(args)->Connect(host_name,
251 context, 254 context->context(),
252 is_server, 255 is_server,
253 request_client_certificate, 256 request_client_certificate,
254 require_client_certificate, 257 require_client_certificate,
255 protocols_handle); 258 protocols_handle);
256 } 259 }
257 260
258 261
259 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { 262 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) {
260 SSLFilter* filter = GetFilter(args); 263 SSLFilter* filter = GetFilter(args);
261 // The SSLFilter is deleted in the finalizer for the Dart object created by 264 // The SSLFilter is deleted in the finalizer for the Dart object created by
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 if (Dart_IsError(result)) { 422 if (Dart_IsError(result)) {
420 filter->callback_error = result; 423 filter->callback_error = result;
421 return 0; 424 return 0;
422 } 425 }
423 return DartUtils::GetBooleanValue(result); 426 return DartUtils::GetBooleanValue(result);
424 } 427 }
425 428
426 429
427 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) { 430 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) {
428 SSLFilter::InitializeLibrary(); 431 SSLFilter::InitializeLibrary();
429 SSL_CTX* context = SSL_CTX_new(TLS_method()); 432 SSL_CTX* ctx = SSL_CTX_new(TLS_method());
430 SSL_CTX_set_verify(context, SSL_VERIFY_PEER, CertificateCallback); 433 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, CertificateCallback);
431 SSL_CTX_set_min_version(context, TLS1_VERSION); 434 SSL_CTX_set_min_version(ctx, TLS1_VERSION);
432 SSL_CTX_set_cipher_list(context, "HIGH:MEDIUM"); 435 SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM");
433 SSL_CTX_set_cipher_list_tls11(context, "HIGH:MEDIUM"); 436 SSL_CTX_set_cipher_list_tls11(ctx, "HIGH:MEDIUM");
437 SSLContext* context = new SSLContext(ctx);
434 Dart_Handle err = SetSecurityContext(args, context); 438 Dart_Handle err = SetSecurityContext(args, context);
435 if (Dart_IsError(err)) { 439 if (Dart_IsError(err)) {
436 SSL_CTX_free(context); 440 delete context;
437 Dart_PropagateError(err); 441 Dart_PropagateError(err);
438 } 442 }
439 } 443 }
440 444
441 445
442 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) { 446 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) {
443 char* password = static_cast<char*>(userdata); 447 char* password = static_cast<char*>(userdata);
444 ASSERT(size == PEM_BUFSIZE); 448 ASSERT(size == PEM_BUFSIZE);
445 strncpy(buf, password, size); 449 strncpy(buf, password, size);
446 return strlen(password); 450 return strlen(password);
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 } else { 660 } else {
657 Dart_ThrowException(DartUtils::NewDartArgumentError( 661 Dart_ThrowException(DartUtils::NewDartArgumentError(
658 "Password is not a String or null")); 662 "Password is not a String or null"));
659 } 663 }
660 return password; 664 return password;
661 } 665 }
662 666
663 667
664 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( 668 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
665 Dart_NativeArguments args) { 669 Dart_NativeArguments args) {
666 SSL_CTX* context = GetSecurityContext(args); 670 SSLContext* context = GetSecurityContext(args);
667 const char* password = GetPasswordArgument(args, 2); 671 const char* password = GetPasswordArgument(args, 2);
668 672
669 int status; 673 int status;
670 { 674 {
671 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 675 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
672 EVP_PKEY *key = GetPrivateKey(bio.bio(), password); 676 EVP_PKEY *key = GetPrivateKey(bio.bio(), password);
673 status = SSL_CTX_use_PrivateKey(context, key); 677 status = SSL_CTX_use_PrivateKey(context->context(), key);
678 // SSL_CTX_use_PrivateKey increments the reference count of key on success,
679 // so we have to call EVP_PKEY_free on both success and failure.
680 EVP_PKEY_free(key);
674 } 681 }
675 682
676 // TODO(24184): Handle different expected errors here - file missing, 683 // TODO(24184): Handle different expected errors here - file missing,
677 // incorrect password, file not a PEM, and throw exceptions. 684 // incorrect password, file not a PEM, and throw exceptions.
678 // CheckStatus should also throw an exception in uncaught cases. 685 // CheckStatus should also throw an exception in uncaught cases.
679 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes"); 686 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes");
680 } 687 }
681 688
682 689
683 static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context, 690 static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context,
684 BIO* bio, 691 BIO* bio,
685 const char* password) { 692 const char* password) {
686 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); 693 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
687 if (p12.get() == NULL) { 694 if (p12.get() == NULL) {
688 return 0; 695 return 0;
689 } 696 }
690 697
691 EVP_PKEY* key = NULL; 698 EVP_PKEY* key = NULL;
692 X509 *cert = NULL; 699 X509 *cert = NULL;
693 STACK_OF(X509) *ca_certs = NULL; 700 STACK_OF(X509) *ca_certs = NULL;
694 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs); 701 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
695 if (status == 0) { 702 if (status == 0) {
696 return status; 703 return status;
697 } 704 }
698 705
699 ScopedX509Stack cert_stack(ca_certs); 706 ScopedX509Stack cert_stack(ca_certs);
700 X509_STORE* store = SSL_CTX_get_cert_store(context); 707 X509_STORE* store = SSL_CTX_get_cert_store(context);
701 status = X509_STORE_add_cert(store, cert); 708 status = X509_STORE_add_cert(store, cert);
709 // X509_STORE_add_cert increments the reference count of cert on success.
710 X509_free(cert);
702 if (status == 0) { 711 if (status == 0) {
703 X509_free(cert);
704 return status; 712 return status;
705 } 713 }
706 714
707 X509* ca; 715 X509* ca;
708 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) { 716 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
709 status = X509_STORE_add_cert(store, ca); 717 status = X509_STORE_add_cert(store, ca);
718 // X509_STORE_add_cert increments the reference count of cert on success.
719 X509_free(ca);
710 if (status == 0) { 720 if (status == 0) {
711 X509_free(ca);
712 return status; 721 return status;
713 } 722 }
714 } 723 }
715 724
716 return status; 725 return status;
717 } 726 }
718 727
719 728
720 static int SetTrustedCertificatesBytesPEM(SSL_CTX* context, BIO* bio) { 729 static int SetTrustedCertificatesBytesPEM(SSL_CTX* context, BIO* bio) {
721 X509_STORE* store = SSL_CTX_get_cert_store(context); 730 X509_STORE* store = SSL_CTX_get_cert_store(context);
722 731
723 int status = 0; 732 int status = 0;
724 X509* cert = NULL; 733 X509* cert = NULL;
725 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { 734 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
726 status = X509_STORE_add_cert(store, cert); 735 status = X509_STORE_add_cert(store, cert);
736 // X509_STORE_add_cert increments the reference count of cert on success.
737 X509_free(cert);
727 if (status == 0) { 738 if (status == 0) {
728 X509_free(cert);
729 return status; 739 return status;
730 } 740 }
731 } 741 }
732 742
733 // If no PEM start line is found, it means that we read to the end of the 743 // If no PEM start line is found, it means that we read to the end of the
734 // file, or that the file isn't PEM. In the first case, status will be 744 // file, or that the file isn't PEM. In the first case, status will be
735 // non-zero indicating success. In the second case, status will be 0, 745 // non-zero indicating success. In the second case, status will be 0,
736 // indicating that we should try to read as PKCS12. If there is some other 746 // indicating that we should try to read as PKCS12. If there is some other
737 // error, we return it up to the caller. 747 // error, we return it up to the caller.
738 return NoPEMStartLine() ? status : 0; 748 return NoPEMStartLine() ? status : 0;
(...skipping 13 matching lines...) Expand all
752 } else { 762 } else {
753 // The PEM file was successfully parsed. 763 // The PEM file was successfully parsed.
754 ERR_clear_error(); 764 ERR_clear_error();
755 } 765 }
756 return status; 766 return status;
757 } 767 }
758 768
759 769
760 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( 770 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)(
761 Dart_NativeArguments args) { 771 Dart_NativeArguments args) {
762 SSL_CTX* context = GetSecurityContext(args); 772 SSLContext* context = GetSecurityContext(args);
763 const char* password = GetPasswordArgument(args, 2); 773 const char* password = GetPasswordArgument(args, 2);
764 int status; 774 int status;
765 { 775 {
766 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 776 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
767 status = SetTrustedCertificatesBytes(context, bio.bio(), password); 777 status = SetTrustedCertificatesBytes(
778 context->context(), bio.bio(), password);
768 } 779 }
769 CheckStatus(status, 780 CheckStatus(status,
770 "TlsException", 781 "TlsException",
771 "Failure in setTrustedCertificatesBytes"); 782 "Failure in setTrustedCertificatesBytes");
772 } 783 }
773 784
774 785
775 void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) { 786 void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) {
776 Dart_SetReturnValue(args, Dart_NewBoolean(true)); 787 Dart_SetReturnValue(args, Dart_NewBoolean(true));
777 } 788 }
778 789
779 790
780 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( 791 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
781 Dart_NativeArguments args) { 792 Dart_NativeArguments args) {
782 SSL_CTX* context = GetSecurityContext(args); 793 SSLContext* context = GetSecurityContext(args);
783 #if defined(TARGET_OS_ANDROID) 794 #if defined(TARGET_OS_ANDROID)
784 // On Android, we don't compile in the trusted root certificates. Insead, 795 // On Android, we don't compile in the trusted root certificates. Insead,
785 // we use the directory of trusted certificates already present on the device. 796 // we use the directory of trusted certificates already present on the device.
786 // This saves ~240KB from the size of the binary. This has the drawback that 797 // This saves ~240KB from the size of the binary. This has the drawback that
787 // SSL_do_handshake will synchronously hit the filesystem looking for root 798 // SSL_do_handshake will synchronously hit the filesystem looking for root
788 // certs during its trust evaluation. We call SSL_do_handshake directly from 799 // certs during its trust evaluation. We call SSL_do_handshake directly from
789 // the Dart thread so that Dart code can be invoked from the "bad certificate" 800 // the Dart thread so that Dart code can be invoked from the "bad certificate"
790 // callback called by SSL_do_handshake. 801 // callback called by SSL_do_handshake.
791 const char* android_cacerts = "/system/etc/security/cacerts"; 802 const char* android_cacerts = "/system/etc/security/cacerts";
792 int status = SSL_CTX_load_verify_locations(context, NULL, android_cacerts); 803 int status = SSL_CTX_load_verify_locations(
804 context->context(), NULL, android_cacerts);
793 CheckStatus(status, "TlsException", "Failure trusting builtint roots"); 805 CheckStatus(status, "TlsException", "Failure trusting builtint roots");
794 #else 806 #else
795 X509_STORE* store = SSL_CTX_get_cert_store(context); 807 X509_STORE* store = SSL_CTX_get_cert_store(context->context());
796 BIO* roots_bio = 808 BIO* roots_bio =
797 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem), 809 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem),
798 root_certificates_pem_length); 810 root_certificates_pem_length);
799 X509* root_cert; 811 X509* root_cert;
800 // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case, 812 // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case,
801 // backed by a memory buffer), and returns X509 objects, one by one. 813 // backed by a memory buffer), and returns X509 objects, one by one.
802 // When the end of the bio is reached, it returns null. 814 // When the end of the bio is reached, it returns null.
803 while ((root_cert = PEM_read_bio_X509(roots_bio, NULL, NULL, NULL)) != NULL) { 815 while ((root_cert = PEM_read_bio_X509(roots_bio, NULL, NULL, NULL)) != NULL) {
804 X509_STORE_add_cert(store, root_cert); 816 int status = X509_STORE_add_cert(store, root_cert);
817 // X509_STORE_add_cert increments the reference count of cert on success.
818 X509_free(root_cert);
819 if (status == 0) {
820 break;
821 }
805 } 822 }
806 BIO_free(roots_bio); 823 BIO_free(roots_bio);
807 // If there is an error here, it must be the error indicating that we are done 824 // If there is an error here, it must be the error indicating that we are done
808 // reading PEM certificates. 825 // reading PEM certificates.
809 ASSERT((ERR_peek_error() == 0) || NoPEMStartLine()); 826 ASSERT((ERR_peek_error() == 0) || NoPEMStartLine());
810 ERR_clear_error(); 827 ERR_clear_error();
811 #endif // defined(TARGET_OS_ANDROID) 828 #endif // defined(TARGET_OS_ANDROID)
812 } 829 }
813 830
814 831
(...skipping 22 matching lines...) Expand all
837 } 854 }
838 if (status == 0) { 855 if (status == 0) {
839 return status; 856 return status;
840 } 857 }
841 858
842 SSL_CTX_clear_chain_certs(context); 859 SSL_CTX_clear_chain_certs(context);
843 860
844 X509* ca; 861 X509* ca;
845 while ((ca = sk_X509_shift(certs.get())) != NULL) { 862 while ((ca = sk_X509_shift(certs.get())) != NULL) {
846 status = SSL_CTX_add0_chain_cert(context, ca); 863 status = SSL_CTX_add0_chain_cert(context, ca);
864 // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the
865 // call fails.
847 if (status == 0) { 866 if (status == 0) {
848 X509_free(ca); 867 X509_free(ca);
849 return status; 868 return status;
850 } 869 }
851 } 870 }
852 871
853 return status; 872 return status;
854 } 873 }
855 874
856 875
(...skipping 11 matching lines...) Expand all
868 } 887 }
869 if (status == 0) { 888 if (status == 0) {
870 return status; 889 return status;
871 } 890 }
872 891
873 SSL_CTX_clear_chain_certs(context); 892 SSL_CTX_clear_chain_certs(context);
874 893
875 X509* ca; 894 X509* ca;
876 while ((ca = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { 895 while ((ca = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
877 status = SSL_CTX_add0_chain_cert(context, ca); 896 status = SSL_CTX_add0_chain_cert(context, ca);
897 // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the
898 // call fails.
878 if (status == 0) { 899 if (status == 0) {
879 X509_free(ca); 900 X509_free(ca);
880 return status; 901 return status;
881 } 902 }
882 // Note that we must not free `ca` if it was successfully added to the 903 // Note that we must not free `ca` if it was successfully added to the
883 // chain. We must free the main certificate x509, though since its reference 904 // chain. We must free the main certificate x509, though since its reference
884 // count is increased by SSL_CTX_use_certificate. 905 // count is increased by SSL_CTX_use_certificate.
885 } 906 }
886 907
887 return NoPEMStartLine() ? status : 0; 908 return NoPEMStartLine() ? status : 0;
(...skipping 11 matching lines...) Expand all
899 } else { 920 } else {
900 // The PEM file was successfully read. 921 // The PEM file was successfully read.
901 ERR_clear_error(); 922 ERR_clear_error();
902 } 923 }
903 return status; 924 return status;
904 } 925 }
905 926
906 927
907 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( 928 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
908 Dart_NativeArguments args) { 929 Dart_NativeArguments args) {
909 SSL_CTX* context = GetSecurityContext(args); 930 SSLContext* context = GetSecurityContext(args);
910 const char* password = GetPasswordArgument(args, 2); 931 const char* password = GetPasswordArgument(args, 2);
911 int status; 932 int status;
912 { 933 {
913 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 934 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
914 status = UseChainBytes(context, bio.bio(), password); 935 status = UseChainBytes(context->context(), bio.bio(), password);
915 } 936 }
916 CheckStatus(status, 937 CheckStatus(status,
917 "TlsException", 938 "TlsException",
918 "Failure in useCertificateChainBytes"); 939 "Failure in useCertificateChainBytes");
919 } 940 }
920 941
921 942
922 static int SetClientAuthoritiesPKCS12(SSL_CTX* context, 943 static int SetClientAuthoritiesPKCS12(SSL_CTX* context,
923 BIO* bio, 944 BIO* bio,
924 const char* password) { 945 const char* password) {
925 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); 946 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
926 if (p12.get() == NULL) { 947 if (p12.get() == NULL) {
927 return 0; 948 return 0;
928 } 949 }
929 950
930 EVP_PKEY* key = NULL; 951 EVP_PKEY* key = NULL;
931 X509 *cert = NULL; 952 X509 *cert = NULL;
932 STACK_OF(X509) *ca_certs = NULL; 953 STACK_OF(X509) *ca_certs = NULL;
933 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs); 954 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
934 if (status == 0) { 955 if (status == 0) {
935 return status; 956 return status;
936 } 957 }
937 958
938 ScopedX509Stack cert_stack(ca_certs); 959 ScopedX509Stack cert_stack(ca_certs);
939 status = SSL_CTX_add_client_CA(context, cert); 960 status = SSL_CTX_add_client_CA(context, cert);
961 // SSL_CTX_add_client_CA increments the reference count of cert on success.
962 X509_free(cert);
940 if (status == 0) { 963 if (status == 0) {
941 X509_free(cert);
942 return status; 964 return status;
943 } 965 }
944 966
945 X509* ca; 967 X509* ca;
946 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) { 968 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
947 status = SSL_CTX_add_client_CA(context, ca); 969 status = SSL_CTX_add_client_CA(context, ca);
970 // SSL_CTX_add_client_CA increments the reference count of ca on success.
948 X509_free(ca); // The name has been extracted. 971 X509_free(ca); // The name has been extracted.
949 if (status == 0) { 972 if (status == 0) {
950 return status; 973 return status;
951 } 974 }
952 } 975 }
953 976
954 return status; 977 return status;
955 } 978 }
956 979
957 980
(...skipping 24 matching lines...) Expand all
982 } else { 1005 } else {
983 // The PEM file was successfully parsed. 1006 // The PEM file was successfully parsed.
984 ERR_clear_error(); 1007 ERR_clear_error();
985 } 1008 }
986 return status; 1009 return status;
987 } 1010 }
988 1011
989 1012
990 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( 1013 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
991 Dart_NativeArguments args) { 1014 Dart_NativeArguments args) {
992 SSL_CTX* context = GetSecurityContext(args); 1015 SSLContext* context = GetSecurityContext(args);
993 const char* password = GetPasswordArgument(args, 2); 1016 const char* password = GetPasswordArgument(args, 2);
994 1017
995 int status; 1018 int status;
996 { 1019 {
997 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 1020 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
998 status = SetClientAuthorities(context, bio.bio(), password); 1021 status = SetClientAuthorities(context->context(), bio.bio(), password);
999 } 1022 }
1000 1023
1001 CheckStatus(status, 1024 CheckStatus(status,
1002 "TlsException", 1025 "TlsException",
1003 "Failure in setClientAuthoritiesBytes"); 1026 "Failure in setClientAuthoritiesBytes");
1004 } 1027 }
1005 1028
1006 1029
1007 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( 1030 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)(
1008 Dart_NativeArguments args) { 1031 Dart_NativeArguments args) {
1009 SSL_CTX* context = GetSecurityContext(args); 1032 SSLContext* context = GetSecurityContext(args);
1010 Dart_Handle protocols_handle = 1033 Dart_Handle protocols_handle =
1011 ThrowIfError(Dart_GetNativeArgument(args, 1)); 1034 ThrowIfError(Dart_GetNativeArgument(args, 1));
1012 Dart_Handle is_server_handle = 1035 Dart_Handle is_server_handle =
1013 ThrowIfError(Dart_GetNativeArgument(args, 2)); 1036 ThrowIfError(Dart_GetNativeArgument(args, 2));
1014 if (Dart_IsBoolean(is_server_handle)) { 1037 if (Dart_IsBoolean(is_server_handle)) {
1015 bool is_server = DartUtils::GetBooleanValue(is_server_handle); 1038 bool is_server = DartUtils::GetBooleanValue(is_server_handle);
1016 SetAlpnProtocolList(protocols_handle, NULL, context, is_server); 1039 SetAlpnProtocolList(protocols_handle, NULL, context, is_server);
1017 } else { 1040 } else {
1018 Dart_ThrowException(DartUtils::NewDartArgumentError( 1041 Dart_ThrowException(DartUtils::NewDartArgumentError(
1019 "Non-boolean is_server argument passed to SetAlpnProtocols")); 1042 "Non-boolean is_server argument passed to SetAlpnProtocols"));
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 server_list += protocol_length; 1379 server_list += protocol_length;
1357 } 1380 }
1358 // TODO(23580): Make failure send a fatal alert instead of ignoring ALPN. 1381 // TODO(23580): Make failure send a fatal alert instead of ignoring ALPN.
1359 return SSL_TLSEXT_ERR_NOACK; 1382 return SSL_TLSEXT_ERR_NOACK;
1360 } 1383 }
1361 1384
1362 1385
1363 // Sets the protocol list for ALPN on a SSL object or a context. 1386 // Sets the protocol list for ALPN on a SSL object or a context.
1364 static void SetAlpnProtocolList(Dart_Handle protocols_handle, 1387 static void SetAlpnProtocolList(Dart_Handle protocols_handle,
1365 SSL* ssl, 1388 SSL* ssl,
1366 SSL_CTX* context, 1389 SSLContext* context,
1367 bool is_server) { 1390 bool is_server) {
1368 // Enable ALPN (application layer protocol negotiation) if the caller provides 1391 // Enable ALPN (application layer protocol negotiation) if the caller provides
1369 // a valid list of supported protocols. 1392 // a valid list of supported protocols.
1370 Dart_TypedData_Type protocols_type; 1393 Dart_TypedData_Type protocols_type;
1371 uint8_t* protocol_string = NULL; 1394 uint8_t* protocol_string = NULL;
1372 uint8_t* protocol_string_copy = NULL; 1395 uint8_t* protocol_string_copy = NULL;
1373 intptr_t protocol_string_len = 0; 1396 intptr_t protocol_string_len = 0;
1374 int status; 1397 int status;
1375 1398
1376 Dart_Handle result = Dart_TypedDataAcquireData( 1399 Dart_Handle result = Dart_TypedDataAcquireData(
(...skipping 16 matching lines...) Expand all
1393 // ALPN on server connections must be set on an SSL_CTX object, 1416 // ALPN on server connections must be set on an SSL_CTX object,
1394 // not on the SSL object of the individual connection. 1417 // not on the SSL object of the individual connection.
1395 ASSERT(context != NULL); 1418 ASSERT(context != NULL);
1396 ASSERT(ssl == NULL); 1419 ASSERT(ssl == NULL);
1397 // Because it must be passed as a single void*, terminate 1420 // Because it must be passed as a single void*, terminate
1398 // the list of (length, data) strings with a length 0 string. 1421 // the list of (length, data) strings with a length 0 string.
1399 protocol_string_copy = 1422 protocol_string_copy =
1400 static_cast<uint8_t*>(malloc(protocol_string_len + 1)); 1423 static_cast<uint8_t*>(malloc(protocol_string_len + 1));
1401 memmove(protocol_string_copy, protocol_string, protocol_string_len); 1424 memmove(protocol_string_copy, protocol_string, protocol_string_len);
1402 protocol_string_copy[protocol_string_len] = '\0'; 1425 protocol_string_copy[protocol_string_len] = '\0';
1403 SSL_CTX_set_alpn_select_cb(context, AlpnCallback, protocol_string_copy); 1426 SSL_CTX_set_alpn_select_cb(
1404 // TODO(whesse): If this function is called again, free the previous 1427 context->context(), AlpnCallback, protocol_string_copy);
1405 // protocol_string_copy. It may be better to keep this as a native 1428 context->set_alpn_protocol_string(protocol_string_copy);
1406 // field on the Dart object, since fetching it from the structure is
1407 // not in the public api.
1408 // Also free protocol_string_copy when the context is destroyed,
1409 // in FreeSecurityContext()
1410 } else { 1429 } else {
1411 // The function makes a local copy of protocol_string, which it owns. 1430 // The function makes a local copy of protocol_string, which it owns.
1412 if (ssl != NULL) { 1431 if (ssl != NULL) {
1413 ASSERT(context == NULL); 1432 ASSERT(context == NULL);
1414 status = SSL_set_alpn_protos(ssl, protocol_string, protocol_string_len); 1433 status = SSL_set_alpn_protos(ssl, protocol_string, protocol_string_len);
1415 } else { 1434 } else {
1416 ASSERT(context != NULL); 1435 ASSERT(context != NULL);
1417 ASSERT(ssl == NULL); 1436 ASSERT(ssl == NULL);
1418 status = SSL_CTX_set_alpn_protos( 1437 status = SSL_CTX_set_alpn_protos(
1419 context, protocol_string, protocol_string_len); 1438 context->context(), protocol_string, protocol_string_len);
1420 } 1439 }
1421 ASSERT(status == 0); // The function returns a non-standard status. 1440 ASSERT(status == 0); // The function returns a non-standard status.
1422 } 1441 }
1423 } 1442 }
1424 Dart_TypedDataReleaseData(protocols_handle); 1443 Dart_TypedDataReleaseData(protocols_handle);
1425 } 1444 }
1426 1445
1427 1446
1428 void SSLFilter::Connect(const char* hostname, 1447 void SSLFilter::Connect(const char* hostname,
1429 SSL_CTX* context, 1448 SSL_CTX* context,
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
1688 return bytes_processed; 1707 return bytes_processed;
1689 } 1708 }
1690 1709
1691 } // namespace bin 1710 } // namespace bin
1692 } // namespace dart 1711 } // namespace dart
1693 1712
1694 #endif // defined(TARGET_OS_LINUX) 1713 #endif // defined(TARGET_OS_LINUX)
1695 1714
1696 #endif // !defined(DART_IO_DISABLED) && 1715 #endif // !defined(DART_IO_DISABLED) &&
1697 // !defined(DART_IO_SECURE_SOCKET_DISABLED) 1716 // !defined(DART_IO_SECURE_SOCKET_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/secure_socket_boringssl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698