Add key importing, RSA only.

Change-Id: I639e797939a28b2b2a815541c9926dc194657c54
diff --git a/google_keymaster_test.cpp b/google_keymaster_test.cpp
index 5f1f016..670810e 100644
--- a/google_keymaster_test.cpp
+++ b/google_keymaster_test.cpp
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#include <string>
+#include <fstream>
+
 #include <gtest/gtest.h>
 
 #include <openssl/engine.h>
@@ -23,6 +26,10 @@
 #include "google_softkeymaster.h"
 #include "keymaster_tags.h"
 
+using std::string;
+using std::ifstream;
+using std::istreambuf_iterator;
+
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
     int result = RUN_ALL_TESTS();
@@ -445,9 +452,13 @@
     }
 
     void SignMessage(const void* message, size_t size) {
+        SignMessage(generate_response_.key_blob, message, size);
+    }
+
+    void SignMessage(const keymaster_key_blob_t& key_blob, const void* message, size_t size) {
         BeginOperationRequest begin_request;
         BeginOperationResponse begin_response;
-        begin_request.SetKeyMaterial(generate_response_.key_blob);
+        begin_request.SetKeyMaterial(key_blob);
         begin_request.purpose = KM_PURPOSE_SIGN;
         AddClientParams(&begin_request.additional_params);
 
@@ -883,5 +894,84 @@
     ASSERT_TRUE(response.key_data == NULL);
 }
 
+static string read_file(const string& file_name) {
+    ifstream file_stream(file_name, std::ios::binary);
+    istreambuf_iterator<char> file_begin(file_stream);
+    istreambuf_iterator<char> file_end;
+    return string(file_begin, file_end);
+}
+
+typedef SigningOperationsTest ImportKeyTest;
+TEST_F(ImportKeyTest, RsaSuccess) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
+        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+        Authorization(TAG_DIGEST, KM_DIGEST_NONE),
+        Authorization(TAG_PADDING, KM_PAD_NONE),
+        Authorization(TAG_USER_ID, 7),
+        Authorization(TAG_USER_AUTH_ID, 8),
+        Authorization(TAG_APPLICATION_ID, "app_id", 6),
+        Authorization(TAG_AUTH_TIMEOUT, 300),
+    };
+
+    string pk8_key = read_file("privkey_pk8.der");
+    ASSERT_EQ(633U, pk8_key.size());
+
+    ImportKeyRequest import_request;
+    import_request.key_description.Reinitialize(params, array_length(params));
+    import_request.key_format = KM_KEY_FORMAT_PKCS8;
+    import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
+
+    ImportKeyResponse import_response;
+    device.ImportKey(import_request, &import_response);
+    ASSERT_EQ(KM_ERROR_OK, import_response.error);
+    EXPECT_EQ(0U, import_response.enforced.size());
+    EXPECT_GT(import_response.unenforced.size(), 0U);
+
+    // Check values derived from the key.
+    EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
+    EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 1024));
+    EXPECT_TRUE(contains(import_response.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537U));
+
+    // And values provided by GoogleKeymaster
+    EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
+    EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
+
+    size_t message_len = 1024 / 8;
+    UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
+    std::fill(message.get(), message.get() + message_len, 'a');
+    SignMessage(import_response.key_blob, message.get(), message_len);
+    ASSERT_TRUE(signature() != NULL);
+
+    BeginOperationRequest begin_request;
+    BeginOperationResponse begin_response;
+    begin_request.SetKeyMaterial(import_response.key_blob);
+    begin_request.purpose = KM_PURPOSE_VERIFY;
+    AddClientParams(&begin_request.additional_params);
+
+    device.BeginOperation(begin_request, &begin_response);
+    ASSERT_EQ(KM_ERROR_OK, begin_response.error);
+
+    UpdateOperationRequest update_request;
+    UpdateOperationResponse update_response;
+    update_request.op_handle = begin_response.op_handle;
+    update_request.input.Reinitialize(message.get(), message_len);
+    EXPECT_EQ(message_len, update_request.input.available_read());
+
+    device.UpdateOperation(update_request, &update_response);
+    ASSERT_EQ(KM_ERROR_OK, update_response.error);
+    EXPECT_EQ(0U, update_response.output.available_read());
+
+    FinishOperationRequest finish_request;
+    finish_request.op_handle = begin_response.op_handle;
+    finish_request.signature.Reinitialize(*signature());
+    FinishOperationResponse finish_response;
+    device.FinishOperation(finish_request, &finish_response);
+    ASSERT_EQ(KM_ERROR_OK, finish_response.error);
+    EXPECT_EQ(0U, finish_response.output.available_read());
+
+    EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
+}
+
 }  // namespace test
 }  // namespace keymaster