Index: runtime/bin/secure_socket.cc |
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc |
index 7f62fcf6adf913c003a6e38ac0a1d95f94aeef7d..f4b14b2798e86642ce29f227b1d3f3779db8014f 100644 |
--- a/runtime/bin/secure_socket.cc |
+++ b/runtime/bin/secure_socket.cc |
@@ -597,20 +597,94 @@ void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( |
} |
-void FUNCTION_NAME(SecurityContext_SetClientAuthorities)( |
+static STACK_OF(X509_NAME)* GetCertificateNames( |
+ uint8_t* certs_bytes, intptr_t certs_bytes_len) { |
+ BIO* bio = BIO_new_mem_buf(certs_bytes, certs_bytes_len); |
+ if (bio == NULL) { |
+ return NULL; |
+ } |
+ |
+ STACK_OF(X509_NAME)* result = sk_X509_NAME_new_null(); |
+ if (result == NULL) { |
+ BIO_free(bio); |
+ return NULL; |
+ } |
+ |
+ while (true) { |
+ X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); |
+ if (x509 == NULL) { |
+ break; |
+ } |
+ |
+ X509_NAME* x509_name = X509_get_subject_name(x509); |
+ if (x509_name == NULL) { |
+ sk_X509_NAME_pop_free(result, X509_NAME_free); |
+ BIO_free(bio); |
+ X509_free(x509); |
+ return NULL; |
+ } |
+ |
+ // Duplicate the name to put it on the stack. |
+ x509_name = X509_NAME_dup(x509_name); |
+ if (x509_name == NULL) { |
+ sk_X509_NAME_pop_free(result, X509_NAME_free); |
+ BIO_free(bio); |
+ X509_free(x509); |
+ return NULL; |
+ } |
+ sk_X509_NAME_push(result, x509_name); |
+ X509_free(x509); |
+ } |
+ |
+ BIO_free(bio); |
+ return result; |
+} |
+ |
+ |
+void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( |
Dart_NativeArguments args) { |
SSL_CTX* context = GetSecurityContext(args); |
- Dart_Handle filename_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
- const char* filename = NULL; |
- if (Dart_IsString(filename_object)) { |
- ThrowIfError(Dart_StringToCString(filename_object, &filename)); |
- } else { |
+ |
+ Dart_Handle certs_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
+ if (!Dart_IsTypedData(certs_object) && !Dart_IsList(certs_object)) { |
Dart_ThrowException(DartUtils::NewDartArgumentError( |
- "file argument in SecurityContext.setClientAuthorities" |
- " is not a String")); |
+ "authCertBytes argument to SecurityContext.setClientAuthoritiesBytes " |
+ "is not a List<int>")); |
} |
- STACK_OF(X509_NAME)* certificate_names; |
- certificate_names = SSL_load_client_CA_file(filename); |
+ |
+ uint8_t* certs_bytes = NULL; |
+ intptr_t certs_bytes_len = 0; |
+ bool is_typed_data = false; |
+ if (Dart_IsTypedData(certs_object)) { |
+ is_typed_data = true; |
+ Dart_TypedData_Type typ; |
+ ThrowIfError(Dart_TypedDataAcquireData( |
+ certs_object, |
+ &typ, |
+ reinterpret_cast<void**>(&certs_bytes), |
+ &certs_bytes_len)); |
+ } else { |
+ ASSERT(Dart_IsList(certs_object)); |
+ ThrowIfError(Dart_ListLength(certs_object, &certs_bytes_len)); |
+ certs_bytes = new uint8_t[certs_bytes_len]; |
+ Dart_Handle err = |
+ Dart_ListGetAsBytes(certs_object, 0, certs_bytes, certs_bytes_len); |
+ if (Dart_IsError(err)) { |
+ delete[] certs_bytes; |
+ Dart_PropagateError(err); |
+ } |
+ } |
+ ASSERT(certs_bytes != NULL); |
+ |
+ STACK_OF(X509_NAME)* certificate_names = |
+ GetCertificateNames(certs_bytes, certs_bytes_len); |
+ |
+ if (is_typed_data) { |
+ ThrowIfError(Dart_TypedDataReleaseData(certs_object)); |
+ } else { |
+ delete[] certs_bytes; |
+ } |
+ |
if (certificate_names != NULL) { |
SSL_CTX_set_client_CA_list(context, certificate_names); |
} else { |