| 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 {
|
|
|