Index: runtime/bin/secure_socket.cc |
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc |
index b1be87c5a65b043f7e791af240e70a03619535ad..0a73bed219751232650843ed710a31194779bec3 100644 |
--- a/runtime/bin/secure_socket.cc |
+++ b/runtime/bin/secure_socket.cc |
@@ -415,6 +415,70 @@ void FUNCTION_NAME(SecurityContext_UsePrivateKey)(Dart_NativeArguments args) { |
} |
+void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( |
+ Dart_NativeArguments args) { |
+ SSL_CTX* context = GetSecurityContext(args); |
+ |
+ Dart_Handle key_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
+ if (!Dart_IsTypedData(key_object) && !Dart_IsList(key_object)) { |
+ Dart_ThrowException(DartUtils::NewDartArgumentError( |
+ "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)) { |
+ ThrowIfError(Dart_StringToCString(password_object, &password)); |
+ if (strlen(password) > PEM_BUFSIZE - 1) { |
+ Dart_ThrowException(DartUtils::NewDartArgumentError( |
+ "SecurityContext.usePrivateKey password length is greater than" |
+ " 1023 (PEM_BUFSIZE)")); |
+ } |
+ } else if (Dart_IsNull(password_object)) { |
+ password = ""; |
+ } else { |
+ Dart_ThrowException(DartUtils::NewDartArgumentError( |
+ "SecurityContext.usePrivateKey password is not a String or null")); |
+ } |
+ |
+ 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)); |
+ } |
+ 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"); |
+} |
+ |
+ |
void FUNCTION_NAME(SecurityContext_SetTrustedCertificates)( |
Dart_NativeArguments args) { |
SSL_CTX* context = GetSecurityContext(args); |