Chromium Code Reviews| 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); |
| } |