Index: runtime/bin/secure_socket.cc |
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc |
index b1be87c5a65b043f7e791af240e70a03619535ad..f4a9d7323feecc26d23e33a1c15550071caced11 100644 |
--- a/runtime/bin/secure_socket.cc |
+++ b/runtime/bin/secure_socket.cc |
@@ -376,16 +376,17 @@ void CheckStatus(int status, |
} |
-void FUNCTION_NAME(SecurityContext_UsePrivateKey)(Dart_NativeArguments args) { |
+void FUNCTION_NAME(SecurityContext_UsePrivateKeyAsBytes)( |
+ 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 key_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
+ if (!Dart_IsTypedData(key_object) && !Dart_IsList(key_object)) { |
Dart_ThrowException(DartUtils::NewDartArgumentError( |
- "File argument to SecurityContext.usePrivateKey is not a String")); |
+ "keyBytes argument to SecurityContext.usePrivateKey " |
+ "is not a List<int>")); |
} |
+ |
Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); |
const char* password = NULL; |
if (Dart_IsString(password_object)) { |
@@ -402,16 +403,40 @@ void FUNCTION_NAME(SecurityContext_UsePrivateKey)(Dart_NativeArguments args) { |
"SecurityContext.usePrivateKey password is not a String or null")); |
} |
- SSL_CTX_set_default_passwd_cb(context, PasswordCallback); |
- SSL_CTX_set_default_passwd_cb_userdata(context, const_cast<char*>(password)); |
- int status = SSL_CTX_use_PrivateKey_file(context, |
- filename, |
- SSL_FILETYPE_PEM); |
+ uint8_t* key_bytes = NULL; |
+ intptr_t key_bytes_len = 0; |
+ bool is_typed_data = false; |
+ if (Dart_IsTypedData(key_object)) { |
+ is_typed_data = true; |
+ Dart_TypedData_Type typ; |
+ ThrowIfError(Dart_TypedDataAcquireData( |
+ key_object, |
+ &typ, |
+ reinterpret_cast<void**>(&key_bytes), |
+ &key_bytes_len)); |
+ } else { |
+ ASSERT(Dart_IsList(key_object)); |
+ ThrowIfError(Dart_ListLength(key_object, &key_bytes_len)); |
+ key_bytes = new uint8_t[key_bytes_len]; |
+ ThrowIfError(Dart_ListGetAsBytes(key_object, 0, key_bytes, key_bytes_len)); |
Bill Hesse
2016/01/29 14:41:50
Leak of key_bytes in this line. Perhaps this is a
zra
2016/01/29 16:47:49
deleted key_bytes on error.
|
+ } |
+ ASSERT(key_bytes != NULL); |
+ |
+ BIO* bio = BIO_new_mem_buf(key_bytes, key_bytes_len); |
+ EVP_PKEY *key = PEM_read_bio_PrivateKey( |
+ bio, NULL, PasswordCallback, const_cast<char*>(password)); |
+ int status = SSL_CTX_use_PrivateKey(context, key); |
+ BIO_free(bio); |
+ if (is_typed_data) { |
+ ThrowIfError(Dart_TypedDataReleaseData(key_object)); |
+ } else { |
+ delete key_bytes; |
+ } |
+ |
// TODO(24184): Handle different expected errors here - file missing, |
// incorrect password, file not a PEM, and throw exceptions. |
// CheckStatus should also throw an exception in uncaught cases. |
CheckStatus(status, "TlsException", "Failure in usePrivateKey"); |
- SSL_CTX_set_default_passwd_cb_userdata(context, NULL); |
} |