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

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: Fix another leak 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 EVP_PKEY_free(key);
674 } 679 }
675 680
676 // TODO(24184): Handle different expected errors here - file missing, 681 // TODO(24184): Handle different expected errors here - file missing,
677 // incorrect password, file not a PEM, and throw exceptions. 682 // incorrect password, file not a PEM, and throw exceptions.
678 // CheckStatus should also throw an exception in uncaught cases. 683 // CheckStatus should also throw an exception in uncaught cases.
679 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes"); 684 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes");
680 } 685 }
681 686
682 687
683 static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context, 688 static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context,
684 BIO* bio, 689 BIO* bio,
685 const char* password) { 690 const char* password) {
686 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); 691 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
687 if (p12.get() == NULL) { 692 if (p12.get() == NULL) {
688 return 0; 693 return 0;
689 } 694 }
690 695
691 EVP_PKEY* key = NULL; 696 EVP_PKEY* key = NULL;
692 X509 *cert = NULL; 697 X509 *cert = NULL;
693 STACK_OF(X509) *ca_certs = NULL; 698 STACK_OF(X509) *ca_certs = NULL;
694 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs); 699 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
695 if (status == 0) { 700 if (status == 0) {
696 return status; 701 return status;
697 } 702 }
698 703
699 ScopedX509Stack cert_stack(ca_certs); 704 ScopedX509Stack cert_stack(ca_certs);
700 X509_STORE* store = SSL_CTX_get_cert_store(context); 705 X509_STORE* store = SSL_CTX_get_cert_store(context);
701 status = X509_STORE_add_cert(store, cert); 706 status = X509_STORE_add_cert(store, cert);
707 X509_free(cert);
702 if (status == 0) { 708 if (status == 0) {
703 X509_free(cert);
704 return status; 709 return status;
705 } 710 }
706 711
707 X509* ca; 712 X509* ca;
708 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) { 713 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
709 status = X509_STORE_add_cert(store, ca); 714 status = X509_STORE_add_cert(store, ca);
715 X509_free(ca);
710 if (status == 0) { 716 if (status == 0) {
711 X509_free(ca);
712 return status; 717 return status;
713 } 718 }
714 } 719 }
715 720
716 return status; 721 return status;
717 } 722 }
718 723
719 724
720 static int SetTrustedCertificatesBytesPEM(SSL_CTX* context, BIO* bio) { 725 static int SetTrustedCertificatesBytesPEM(SSL_CTX* context, BIO* bio) {
721 X509_STORE* store = SSL_CTX_get_cert_store(context); 726 X509_STORE* store = SSL_CTX_get_cert_store(context);
722 727
723 int status = 0; 728 int status = 0;
724 X509* cert = NULL; 729 X509* cert = NULL;
725 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { 730 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
726 status = X509_STORE_add_cert(store, cert); 731 status = X509_STORE_add_cert(store, cert);
732 X509_free(cert);
727 if (status == 0) { 733 if (status == 0) {
728 X509_free(cert);
729 return status; 734 return status;
730 } 735 }
731 } 736 }
732 737
733 // If no PEM start line is found, it means that we read to the end of the 738 // 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 739 // 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, 740 // 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 741 // indicating that we should try to read as PKCS12. If there is some other
737 // error, we return it up to the caller. 742 // error, we return it up to the caller.
738 return NoPEMStartLine() ? status : 0; 743 return NoPEMStartLine() ? status : 0;
(...skipping 13 matching lines...) Expand all
752 } else { 757 } else {
753 // The PEM file was successfully parsed. 758 // The PEM file was successfully parsed.
754 ERR_clear_error(); 759 ERR_clear_error();
755 } 760 }
756 return status; 761 return status;
757 } 762 }
758 763
759 764
760 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( 765 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)(
761 Dart_NativeArguments args) { 766 Dart_NativeArguments args) {
762 SSL_CTX* context = GetSecurityContext(args); 767 SSLContext* context = GetSecurityContext(args);
763 const char* password = GetPasswordArgument(args, 2); 768 const char* password = GetPasswordArgument(args, 2);
764 int status; 769 int status;
765 { 770 {
766 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 771 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
767 status = SetTrustedCertificatesBytes(context, bio.bio(), password); 772 status = SetTrustedCertificatesBytes(
773 context->context(), bio.bio(), password);
768 } 774 }
769 CheckStatus(status, 775 CheckStatus(status,
770 "TlsException", 776 "TlsException",
771 "Failure in setTrustedCertificatesBytes"); 777 "Failure in setTrustedCertificatesBytes");
772 } 778 }
773 779
774 780
775 void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) { 781 void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) {
776 Dart_SetReturnValue(args, Dart_NewBoolean(true)); 782 Dart_SetReturnValue(args, Dart_NewBoolean(true));
777 } 783 }
778 784
779 785
780 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( 786 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
781 Dart_NativeArguments args) { 787 Dart_NativeArguments args) {
782 SSL_CTX* context = GetSecurityContext(args); 788 SSLContext* context = GetSecurityContext(args);
783 #if defined(TARGET_OS_ANDROID) 789 #if defined(TARGET_OS_ANDROID)
784 // On Android, we don't compile in the trusted root certificates. Insead, 790 // 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. 791 // 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 792 // 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 793 // SSL_do_handshake will synchronously hit the filesystem looking for root
788 // certs during its trust evaluation. We call SSL_do_handshake directly from 794 // 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" 795 // the Dart thread so that Dart code can be invoked from the "bad certificate"
790 // callback called by SSL_do_handshake. 796 // callback called by SSL_do_handshake.
791 const char* android_cacerts = "/system/etc/security/cacerts"; 797 const char* android_cacerts = "/system/etc/security/cacerts";
792 int status = SSL_CTX_load_verify_locations(context, NULL, android_cacerts); 798 int status = SSL_CTX_load_verify_locations(
799 context->context(), NULL, android_cacerts);
793 CheckStatus(status, "TlsException", "Failure trusting builtint roots"); 800 CheckStatus(status, "TlsException", "Failure trusting builtint roots");
794 #else 801 #else
795 X509_STORE* store = SSL_CTX_get_cert_store(context); 802 X509_STORE* store = SSL_CTX_get_cert_store(context->context());
796 BIO* roots_bio = 803 BIO* roots_bio =
797 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem), 804 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem),
798 root_certificates_pem_length); 805 root_certificates_pem_length);
799 X509* root_cert; 806 X509* root_cert;
800 // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case, 807 // 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. 808 // backed by a memory buffer), and returns X509 objects, one by one.
802 // When the end of the bio is reached, it returns null. 809 // 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) { 810 while ((root_cert = PEM_read_bio_X509(roots_bio, NULL, NULL, NULL)) != NULL) {
804 X509_STORE_add_cert(store, root_cert); 811 int status = X509_STORE_add_cert(store, root_cert);
812 X509_free(root_cert);
813 if (status == 0) {
814 break;
815 }
805 } 816 }
806 BIO_free(roots_bio); 817 BIO_free(roots_bio);
807 // If there is an error here, it must be the error indicating that we are done 818 // If there is an error here, it must be the error indicating that we are done
808 // reading PEM certificates. 819 // reading PEM certificates.
809 ASSERT((ERR_peek_error() == 0) || NoPEMStartLine()); 820 ASSERT((ERR_peek_error() == 0) || NoPEMStartLine());
810 ERR_clear_error(); 821 ERR_clear_error();
811 #endif // defined(TARGET_OS_ANDROID) 822 #endif // defined(TARGET_OS_ANDROID)
812 } 823 }
813 824
814 825
(...skipping 22 matching lines...) Expand all
837 } 848 }
838 if (status == 0) { 849 if (status == 0) {
839 return status; 850 return status;
840 } 851 }
841 852
842 SSL_CTX_clear_chain_certs(context); 853 SSL_CTX_clear_chain_certs(context);
843 854
844 X509* ca; 855 X509* ca;
845 while ((ca = sk_X509_shift(certs.get())) != NULL) { 856 while ((ca = sk_X509_shift(certs.get())) != NULL) {
846 status = SSL_CTX_add0_chain_cert(context, ca); 857 status = SSL_CTX_add0_chain_cert(context, ca);
858 // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the
859 // call fails.
847 if (status == 0) { 860 if (status == 0) {
848 X509_free(ca); 861 X509_free(ca);
849 return status; 862 return status;
850 } 863 }
851 } 864 }
852 865
853 return status; 866 return status;
854 } 867 }
855 868
856 869
(...skipping 11 matching lines...) Expand all
868 } 881 }
869 if (status == 0) { 882 if (status == 0) {
870 return status; 883 return status;
871 } 884 }
872 885
873 SSL_CTX_clear_chain_certs(context); 886 SSL_CTX_clear_chain_certs(context);
874 887
875 X509* ca; 888 X509* ca;
876 while ((ca = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { 889 while ((ca = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
877 status = SSL_CTX_add0_chain_cert(context, ca); 890 status = SSL_CTX_add0_chain_cert(context, ca);
891 // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the
892 // call fails.
878 if (status == 0) { 893 if (status == 0) {
879 X509_free(ca); 894 X509_free(ca);
880 return status; 895 return status;
881 } 896 }
882 // Note that we must not free `ca` if it was successfully added to the 897 // 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 898 // chain. We must free the main certificate x509, though since its reference
884 // count is increased by SSL_CTX_use_certificate. 899 // count is increased by SSL_CTX_use_certificate.
885 } 900 }
886 901
887 return NoPEMStartLine() ? status : 0; 902 return NoPEMStartLine() ? status : 0;
(...skipping 11 matching lines...) Expand all
899 } else { 914 } else {
900 // The PEM file was successfully read. 915 // The PEM file was successfully read.
901 ERR_clear_error(); 916 ERR_clear_error();
902 } 917 }
903 return status; 918 return status;
904 } 919 }
905 920
906 921
907 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( 922 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
908 Dart_NativeArguments args) { 923 Dart_NativeArguments args) {
909 SSL_CTX* context = GetSecurityContext(args); 924 SSLContext* context = GetSecurityContext(args);
910 const char* password = GetPasswordArgument(args, 2); 925 const char* password = GetPasswordArgument(args, 2);
911 int status; 926 int status;
912 { 927 {
913 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 928 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
914 status = UseChainBytes(context, bio.bio(), password); 929 status = UseChainBytes(context->context(), bio.bio(), password);
915 } 930 }
916 CheckStatus(status, 931 CheckStatus(status,
917 "TlsException", 932 "TlsException",
918 "Failure in useCertificateChainBytes"); 933 "Failure in useCertificateChainBytes");
919 } 934 }
920 935
921 936
922 static int SetClientAuthoritiesPKCS12(SSL_CTX* context, 937 static int SetClientAuthoritiesPKCS12(SSL_CTX* context,
923 BIO* bio, 938 BIO* bio,
924 const char* password) { 939 const char* password) {
925 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); 940 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
926 if (p12.get() == NULL) { 941 if (p12.get() == NULL) {
927 return 0; 942 return 0;
928 } 943 }
929 944
930 EVP_PKEY* key = NULL; 945 EVP_PKEY* key = NULL;
931 X509 *cert = NULL; 946 X509 *cert = NULL;
932 STACK_OF(X509) *ca_certs = NULL; 947 STACK_OF(X509) *ca_certs = NULL;
933 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs); 948 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
934 if (status == 0) { 949 if (status == 0) {
935 return status; 950 return status;
936 } 951 }
937 952
938 ScopedX509Stack cert_stack(ca_certs); 953 ScopedX509Stack cert_stack(ca_certs);
939 status = SSL_CTX_add_client_CA(context, cert); 954 status = SSL_CTX_add_client_CA(context, cert);
955 X509_free(cert);
siva 2016/08/04 17:25:03 Can you add a comment that SSL_CTX_add_client_CA i
zra 2016/08/04 17:49:34 Done.
940 if (status == 0) { 956 if (status == 0) {
941 X509_free(cert);
942 return status; 957 return status;
943 } 958 }
944 959
945 X509* ca; 960 X509* ca;
946 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) { 961 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
947 status = SSL_CTX_add_client_CA(context, ca); 962 status = SSL_CTX_add_client_CA(context, ca);
948 X509_free(ca); // The name has been extracted. 963 X509_free(ca); // The name has been extracted.
949 if (status == 0) { 964 if (status == 0) {
950 return status; 965 return status;
951 } 966 }
(...skipping 30 matching lines...) Expand all
982 } else { 997 } else {
983 // The PEM file was successfully parsed. 998 // The PEM file was successfully parsed.
984 ERR_clear_error(); 999 ERR_clear_error();
985 } 1000 }
986 return status; 1001 return status;
987 } 1002 }
988 1003
989 1004
990 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( 1005 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
991 Dart_NativeArguments args) { 1006 Dart_NativeArguments args) {
992 SSL_CTX* context = GetSecurityContext(args); 1007 SSLContext* context = GetSecurityContext(args);
993 const char* password = GetPasswordArgument(args, 2); 1008 const char* password = GetPasswordArgument(args, 2);
994 1009
995 int status; 1010 int status;
996 { 1011 {
997 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); 1012 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
998 status = SetClientAuthorities(context, bio.bio(), password); 1013 status = SetClientAuthorities(context->context(), bio.bio(), password);
999 } 1014 }
1000 1015
1001 CheckStatus(status, 1016 CheckStatus(status,
1002 "TlsException", 1017 "TlsException",
1003 "Failure in setClientAuthoritiesBytes"); 1018 "Failure in setClientAuthoritiesBytes");
1004 } 1019 }
1005 1020
1006 1021
1007 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( 1022 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)(
1008 Dart_NativeArguments args) { 1023 Dart_NativeArguments args) {
1009 SSL_CTX* context = GetSecurityContext(args); 1024 SSLContext* context = GetSecurityContext(args);
1010 Dart_Handle protocols_handle = 1025 Dart_Handle protocols_handle =
1011 ThrowIfError(Dart_GetNativeArgument(args, 1)); 1026 ThrowIfError(Dart_GetNativeArgument(args, 1));
1012 Dart_Handle is_server_handle = 1027 Dart_Handle is_server_handle =
1013 ThrowIfError(Dart_GetNativeArgument(args, 2)); 1028 ThrowIfError(Dart_GetNativeArgument(args, 2));
1014 if (Dart_IsBoolean(is_server_handle)) { 1029 if (Dart_IsBoolean(is_server_handle)) {
1015 bool is_server = DartUtils::GetBooleanValue(is_server_handle); 1030 bool is_server = DartUtils::GetBooleanValue(is_server_handle);
1016 SetAlpnProtocolList(protocols_handle, NULL, context, is_server); 1031 SetAlpnProtocolList(protocols_handle, NULL, context, is_server);
1017 } else { 1032 } else {
1018 Dart_ThrowException(DartUtils::NewDartArgumentError( 1033 Dart_ThrowException(DartUtils::NewDartArgumentError(
1019 "Non-boolean is_server argument passed to SetAlpnProtocols")); 1034 "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; 1371 server_list += protocol_length;
1357 } 1372 }
1358 // TODO(23580): Make failure send a fatal alert instead of ignoring ALPN. 1373 // TODO(23580): Make failure send a fatal alert instead of ignoring ALPN.
1359 return SSL_TLSEXT_ERR_NOACK; 1374 return SSL_TLSEXT_ERR_NOACK;
1360 } 1375 }
1361 1376
1362 1377
1363 // Sets the protocol list for ALPN on a SSL object or a context. 1378 // Sets the protocol list for ALPN on a SSL object or a context.
1364 static void SetAlpnProtocolList(Dart_Handle protocols_handle, 1379 static void SetAlpnProtocolList(Dart_Handle protocols_handle,
1365 SSL* ssl, 1380 SSL* ssl,
1366 SSL_CTX* context, 1381 SSLContext* context,
1367 bool is_server) { 1382 bool is_server) {
1368 // Enable ALPN (application layer protocol negotiation) if the caller provides 1383 // Enable ALPN (application layer protocol negotiation) if the caller provides
1369 // a valid list of supported protocols. 1384 // a valid list of supported protocols.
1370 Dart_TypedData_Type protocols_type; 1385 Dart_TypedData_Type protocols_type;
1371 uint8_t* protocol_string = NULL; 1386 uint8_t* protocol_string = NULL;
1372 uint8_t* protocol_string_copy = NULL; 1387 uint8_t* protocol_string_copy = NULL;
1373 intptr_t protocol_string_len = 0; 1388 intptr_t protocol_string_len = 0;
1374 int status; 1389 int status;
1375 1390
1376 Dart_Handle result = Dart_TypedDataAcquireData( 1391 Dart_Handle result = Dart_TypedDataAcquireData(
(...skipping 16 matching lines...) Expand all
1393 // ALPN on server connections must be set on an SSL_CTX object, 1408 // ALPN on server connections must be set on an SSL_CTX object,
1394 // not on the SSL object of the individual connection. 1409 // not on the SSL object of the individual connection.
1395 ASSERT(context != NULL); 1410 ASSERT(context != NULL);
1396 ASSERT(ssl == NULL); 1411 ASSERT(ssl == NULL);
1397 // Because it must be passed as a single void*, terminate 1412 // Because it must be passed as a single void*, terminate
1398 // the list of (length, data) strings with a length 0 string. 1413 // the list of (length, data) strings with a length 0 string.
1399 protocol_string_copy = 1414 protocol_string_copy =
1400 static_cast<uint8_t*>(malloc(protocol_string_len + 1)); 1415 static_cast<uint8_t*>(malloc(protocol_string_len + 1));
1401 memmove(protocol_string_copy, protocol_string, protocol_string_len); 1416 memmove(protocol_string_copy, protocol_string, protocol_string_len);
1402 protocol_string_copy[protocol_string_len] = '\0'; 1417 protocol_string_copy[protocol_string_len] = '\0';
1403 SSL_CTX_set_alpn_select_cb(context, AlpnCallback, protocol_string_copy); 1418 SSL_CTX_set_alpn_select_cb(
1404 // TODO(whesse): If this function is called again, free the previous 1419 context->context(), AlpnCallback, protocol_string_copy);
1405 // protocol_string_copy. It may be better to keep this as a native 1420 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 { 1421 } else {
1411 // The function makes a local copy of protocol_string, which it owns. 1422 // The function makes a local copy of protocol_string, which it owns.
1412 if (ssl != NULL) { 1423 if (ssl != NULL) {
1413 ASSERT(context == NULL); 1424 ASSERT(context == NULL);
1414 status = SSL_set_alpn_protos(ssl, protocol_string, protocol_string_len); 1425 status = SSL_set_alpn_protos(ssl, protocol_string, protocol_string_len);
1415 } else { 1426 } else {
1416 ASSERT(context != NULL); 1427 ASSERT(context != NULL);
1417 ASSERT(ssl == NULL); 1428 ASSERT(ssl == NULL);
1418 status = SSL_CTX_set_alpn_protos( 1429 status = SSL_CTX_set_alpn_protos(
1419 context, protocol_string, protocol_string_len); 1430 context->context(), protocol_string, protocol_string_len);
1420 } 1431 }
1421 ASSERT(status == 0); // The function returns a non-standard status. 1432 ASSERT(status == 0); // The function returns a non-standard status.
1422 } 1433 }
1423 } 1434 }
1424 Dart_TypedDataReleaseData(protocols_handle); 1435 Dart_TypedDataReleaseData(protocols_handle);
1425 } 1436 }
1426 1437
1427 1438
1428 void SSLFilter::Connect(const char* hostname, 1439 void SSLFilter::Connect(const char* hostname,
1429 SSL_CTX* context, 1440 SSL_CTX* context,
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
1688 return bytes_processed; 1699 return bytes_processed;
1689 } 1700 }
1690 1701
1691 } // namespace bin 1702 } // namespace bin
1692 } // namespace dart 1703 } // namespace dart
1693 1704
1694 #endif // defined(TARGET_OS_LINUX) 1705 #endif // defined(TARGET_OS_LINUX)
1695 1706
1696 #endif // !defined(DART_IO_DISABLED) && 1707 #endif // !defined(DART_IO_DISABLED) &&
1697 // !defined(DART_IO_SECURE_SOCKET_DISABLED) 1708 // !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