Index: runtime/bin/secure_socket.cc |
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc |
index 7f62fcf6adf913c003a6e38ac0a1d95f94aeef7d..54f9d3838443a855b8517f9a42cdbe6d28a92eb7 100644 |
--- a/runtime/bin/secure_socket.cc |
+++ b/runtime/bin/secure_socket.cc |
@@ -445,29 +445,86 @@ void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( |
} |
-void FUNCTION_NAME(SecurityContext_SetTrustedCertificates)( |
+static int SetTrustedCertificatesBytes( |
+ SSL_CTX* context, uint8_t* certs_bytes, intptr_t certs_bytes_len) { |
+ X509_STORE* store = SSL_CTX_get_cert_store(context); |
+ BIO* bio = BIO_new_mem_buf(certs_bytes, certs_bytes_len); |
+ if (bio == NULL) { |
+ return 0; |
+ } |
+ |
+ int status = 0; |
+ X509* cert = NULL; |
+ while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { |
+ status = X509_STORE_add_cert(store, cert); |
+ if (status == 0) { |
+ X509_free(cert); |
+ BIO_free(bio); |
+ return status; |
+ } |
+ } |
+ |
+ uint32_t err = ERR_peek_last_error(); |
+ if ((ERR_GET_LIB(err) == ERR_LIB_PEM) && |
+ (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { |
+ // Reached the end of the buffer. |
+ ERR_clear_error(); |
+ } else { |
+ // Some real error happened. |
+ status = 0; |
+ } |
+ |
+ BIO_free(bio); |
+ return status; |
+} |
+ |
+ |
+void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( |
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)); |
+ |
+ Dart_Handle certs_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
+ if (!Dart_IsTypedData(certs_object) && !Dart_IsList(certs_object)) { |
+ Dart_ThrowException(DartUtils::NewDartArgumentError( |
+ "certBytes argument to SecurityContext.setTrustedCertificates " |
+ "is not a List<int>")); |
} |
- Dart_Handle directory_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); |
- const char* directory = NULL; |
- if (Dart_IsString(directory_object)) { |
- ThrowIfError(Dart_StringToCString(directory_object, &directory)); |
- } else if (Dart_IsNull(directory_object)) { |
- directory = NULL; |
+ |
+ 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 { |
- Dart_ThrowException(DartUtils::NewDartArgumentError( |
- "Directory argument to SecurityContext.setTrustedCertificates is not " |
- "a String or null")); |
+ 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); |
- int status = SSL_CTX_load_verify_locations(context, filename, directory); |
- CheckStatus( |
- status, "TlsException", "SSL_CTX_load_verify_locations"); |
+ int status = SetTrustedCertificatesBytes( |
+ context, certs_bytes, certs_bytes_len); |
+ |
+ if (is_typed_data) { |
+ ThrowIfError(Dart_TypedDataReleaseData(certs_object)); |
+ } else { |
+ delete[] certs_bytes; |
+ } |
+ CheckStatus(status, |
+ "TlsException", |
+ "Failure in setTrustedCertificatesBytes"); |
} |