Add the beginnings of logging infrastructure.

Change-Id: Ic36134402bfbb098d2242c463a3b4265d1d65209
diff --git a/asymmetric_key.cpp b/asymmetric_key.cpp
index 8698ff4..b3bf733 100644
--- a/asymmetric_key.cpp
+++ b/asymmetric_key.cpp
@@ -121,7 +121,8 @@
 }
 
 /* static */
-RsaKey* RsaKey::GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error) {
+RsaKey* RsaKey::GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
+                            keymaster_error_t* error) {
     if (!error)
         return NULL;
 
@@ -149,14 +150,14 @@
         return NULL;
     }
 
-    RsaKey* new_key = new RsaKey(rsa_key.release(), authorizations);
+    RsaKey* new_key = new RsaKey(rsa_key.release(), authorizations, logger);
     *error = new_key ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED;
     return new_key;
 }
 
 /* static */
 RsaKey* RsaKey::ImportKey(const AuthorizationSet& key_description, EVP_PKEY* pkey,
-                          keymaster_error_t* error) {
+                          const Logger& logger, keymaster_error_t* error) {
     if (!error)
         return NULL;
     *error = KM_ERROR_UNKNOWN_ERROR;
@@ -213,10 +214,11 @@
     // missing, the error will be diagnosed when the key is used (when auth checking is
     // implemented).
     *error = KM_ERROR_OK;
-    return new RsaKey(rsa_key.release(), authorizations);
+    return new RsaKey(rsa_key.release(), authorizations, logger);
 }
 
-RsaKey::RsaKey(const KeyBlob& blob, keymaster_error_t* error) : AsymmetricKey(blob) {
+RsaKey::RsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error)
+    : AsymmetricKey(blob, logger) {
     if (error)
         *error = LoadKey(blob);
 }
@@ -264,7 +266,8 @@
     delete[] blob.data;
 }
 
-DsaKey* DsaKey::GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error) {
+DsaKey* DsaKey::GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
+                            keymaster_error_t* error) {
     if (!error)
         return NULL;
 
@@ -325,12 +328,13 @@
         return NULL;
     }
 
-    DsaKey* new_key = new DsaKey(dsa_key.release(), authorizations);
+    DsaKey* new_key = new DsaKey(dsa_key.release(), authorizations, logger);
     *error = new_key ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED;
     return new_key;
 }
 
-DsaKey::DsaKey(const KeyBlob& blob, keymaster_error_t* error) : AsymmetricKey(blob) {
+DsaKey::DsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error)
+    : AsymmetricKey(blob, logger) {
     if (error)
         *error = LoadKey(blob);
 }
@@ -363,7 +367,8 @@
 }
 
 /* static */
-EcdsaKey* EcdsaKey::GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error) {
+EcdsaKey* EcdsaKey::GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
+                                keymaster_error_t* error) {
     if (!error)
         return NULL;
 
@@ -396,7 +401,7 @@
         return NULL;
     }
 
-    EcdsaKey* new_key = new EcdsaKey(ecdsa_key.release(), authorizations);
+    EcdsaKey* new_key = new EcdsaKey(ecdsa_key.release(), authorizations, logger);
     *error = new_key ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED;
     return new_key;
 }
@@ -425,7 +430,8 @@
     }
 }
 
-EcdsaKey::EcdsaKey(const KeyBlob& blob, keymaster_error_t* error) : AsymmetricKey(blob) {
+EcdsaKey::EcdsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error)
+    : AsymmetricKey(blob, logger) {
     if (error)
         *error = LoadKey(blob);
 }
diff --git a/asymmetric_key.h b/asymmetric_key.h
index 2b54f6f..17201e6 100644
--- a/asymmetric_key.h
+++ b/asymmetric_key.h
@@ -29,7 +29,7 @@
 class AsymmetricKey : public Key {
   public:
   protected:
-    AsymmetricKey(const KeyBlob& blob) : Key(blob) {}
+    AsymmetricKey(const KeyBlob& blob, const Logger& logger) : Key(blob, logger) {}
     keymaster_error_t LoadKey(const KeyBlob& blob);
 
     /**
@@ -47,7 +47,7 @@
     virtual Operation* CreateOperation(keymaster_purpose_t purpose, keymaster_error_t* error);
 
   protected:
-    AsymmetricKey(const AuthorizationSet& auths) : Key(auths) {}
+    AsymmetricKey(const AuthorizationSet& auths, const Logger& logger) : Key(auths, logger) {}
 
   private:
     virtual int evp_key_type() = 0;
@@ -59,16 +59,18 @@
 
 class RsaKey : public AsymmetricKey {
   public:
-    static RsaKey* GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error);
+    static RsaKey* GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
+                               keymaster_error_t* error);
     static RsaKey* ImportKey(const AuthorizationSet& key_description, EVP_PKEY* pkey,
-                             keymaster_error_t* error);
-    RsaKey(const KeyBlob& blob, keymaster_error_t* error);
+                             const Logger& logger, keymaster_error_t* error);
+    RsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error);
 
     virtual Operation* CreateOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
                                        keymaster_padding_t padding, keymaster_error_t* error);
 
   private:
-    RsaKey(RSA* rsa_key, const AuthorizationSet& auths) : AsymmetricKey(auths), rsa_key_(rsa_key) {}
+    RsaKey(RSA* rsa_key, const AuthorizationSet& auths, const Logger& logger)
+        : AsymmetricKey(auths, logger), rsa_key_(rsa_key) {}
 
     virtual int evp_key_type() { return EVP_PKEY_RSA; }
     virtual bool InternalToEvp(EVP_PKEY* pkey) const;
@@ -83,14 +85,16 @@
 
 class DsaKey : public AsymmetricKey {
   public:
-    static DsaKey* GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error);
-    DsaKey(const KeyBlob& blob, keymaster_error_t* error);
+    static DsaKey* GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
+                               keymaster_error_t* error);
+    DsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error);
 
     virtual Operation* CreateOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
                                        keymaster_padding_t padding, keymaster_error_t* error);
 
   private:
-    DsaKey(DSA* dsa_key, const AuthorizationSet auths) : AsymmetricKey(auths), dsa_key_(dsa_key) {}
+    DsaKey(DSA* dsa_key, const AuthorizationSet auths, const Logger& logger)
+        : AsymmetricKey(auths, logger), dsa_key_(dsa_key) {}
 
     virtual int evp_key_type() { return EVP_PKEY_DSA; }
     virtual bool InternalToEvp(EVP_PKEY* pkey) const;
@@ -105,15 +109,16 @@
 
 class EcdsaKey : public AsymmetricKey {
   public:
-    static EcdsaKey* GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error);
-    EcdsaKey(const KeyBlob& blob, keymaster_error_t* error);
+    static EcdsaKey* GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
+                                 keymaster_error_t* error);
+    EcdsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error);
 
     virtual Operation* CreateOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
                                        keymaster_padding_t padding, keymaster_error_t* error);
 
   private:
-    EcdsaKey(EC_KEY* ecdsa_key, const AuthorizationSet auths)
-        : AsymmetricKey(auths), ecdsa_key_(ecdsa_key) {}
+    EcdsaKey(EC_KEY* ecdsa_key, const AuthorizationSet auths, const Logger& logger)
+        : AsymmetricKey(auths, logger), ecdsa_key_(ecdsa_key) {}
 
     static EC_GROUP* choose_group(size_t key_size_bits);
 
diff --git a/google_keymaster.cpp b/google_keymaster.cpp
index c0d0cd6..18b1318 100644
--- a/google_keymaster.cpp
+++ b/google_keymaster.cpp
@@ -33,9 +33,9 @@
 
 namespace keymaster {
 
-GoogleKeymaster::GoogleKeymaster(size_t operation_table_size)
+GoogleKeymaster::GoogleKeymaster(size_t operation_table_size, Logger* logger)
     : operation_table_(new OpTableEntry[operation_table_size]),
-      operation_table_size_(operation_table_size) {
+      operation_table_size_(operation_table_size), logger_(logger) {
     if (operation_table_.get() == NULL)
         operation_table_size_ = 0;
 }
@@ -162,7 +162,7 @@
     if (response == NULL)
         return;
 
-    UniquePtr<Key> key(Key::GenerateKey(request.key_description, &response->error));
+    UniquePtr<Key> key(Key::GenerateKey(request.key_description, logger(), &response->error));
     if (response->error != KM_ERROR_OK)
         return;
 
@@ -287,7 +287,7 @@
         return;
 
     UniquePtr<Key> key(Key::ImportKey(request.key_description, request.key_format, request.key_data,
-                                      request.key_data_length, &response->error));
+                                      request.key_data_length, logger(), &response->error));
     if (response->error != KM_ERROR_OK)
         return;
 
@@ -344,7 +344,7 @@
     UniquePtr<KeyBlob> blob(LoadKeyBlob(key, client_params, error));
     if (*error != KM_ERROR_OK)
         return NULL;
-    return Key::CreateKey(*blob, error);
+    return Key::CreateKey(*blob, logger(), error);
 }
 
 KeyBlob* GoogleKeymaster::LoadKeyBlob(const keymaster_key_blob_t& key,
diff --git a/google_keymaster.h b/google_keymaster.h
index e1cc814..a56fe77 100644
--- a/google_keymaster.h
+++ b/google_keymaster.h
@@ -19,6 +19,7 @@
 
 #include "authorization_set.h"
 #include "google_keymaster_messages.h"
+#include "logger.h"
 
 namespace keymaster {
 
@@ -43,7 +44,7 @@
  */
 class GoogleKeymaster {
   public:
-    GoogleKeymaster(size_t operation_table_size);
+    GoogleKeymaster(size_t operation_table_size, Logger* logger);
     virtual ~GoogleKeymaster();
 
     void SupportedAlgorithms(SupportedResponse<keymaster_algorithm_t>* response) const;
@@ -76,6 +77,9 @@
     void FinishOperation(const FinishOperationRequest& request, FinishOperationResponse* response);
     keymaster_error_t AbortOperation(const keymaster_operation_handle_t op_handle);
 
+  protected:
+    const Logger& logger() const { return *logger_; }
+
   private:
     virtual bool is_enforced(keymaster_tag_t tag) = 0;
     virtual keymaster_key_origin_t origin() = 0;
@@ -126,6 +130,7 @@
 
     UniquePtr<OpTableEntry[]> operation_table_;
     size_t operation_table_size_;
+    UniquePtr<Logger> logger_;
 };
 
 }  // namespace keymaster
diff --git a/google_keymaster_test.cpp b/google_keymaster_test.cpp
index 670810e..bfb6a6f 100644
--- a/google_keymaster_test.cpp
+++ b/google_keymaster_test.cpp
@@ -44,7 +44,7 @@
 
 class KeymasterTest : public testing::Test {
   protected:
-    KeymasterTest() : device(5) { RAND_seed("foobar", 6); }
+    KeymasterTest() : device(5, new StdoutLogger) { RAND_seed("foobar", 6); }
     ~KeymasterTest() {}
 
     GoogleSoftKeymaster device;
diff --git a/google_keymaster_test_utils.h b/google_keymaster_test_utils.h
index cabe3bc..3112a39 100644
--- a/google_keymaster_test_utils.h
+++ b/google_keymaster_test_utils.h
@@ -21,17 +21,37 @@
  * Utilities used to help with testing.  Not used in production code.
  */
 
+#include <stdarg.h>
+
 #include <ostream>
 
-#include "keymaster_defs.h"
 #include "authorization_set.h"
+#include "keymaster_defs.h"
+#include "logger.h"
 
 std::ostream& operator<<(std::ostream& os, const keymaster_key_param_t& param);
 bool operator==(const keymaster_key_param_t& a, const keymaster_key_param_t& b);
 
 namespace keymaster {
+
 bool operator==(const AuthorizationSet& a, const AuthorizationSet& b);
+
 std::ostream& operator<<(std::ostream& os, const AuthorizationSet& set);
+
+namespace test {
+
+class StdoutLogger : public Logger {
+  public:
+    int log(const char* fmt, ...) const {
+        va_list args;
+        va_start(args, fmt);
+        int result = vprintf(fmt, args);
+        va_end(args);
+        return result;
+    }
+};
+
+}  // namespace test
 }  // namespace keymaster
 
 #endif  // SYSTEM_KEYMASTER_GOOGLE_KEYMASTER_TEST_UTILS_H_
diff --git a/google_softkeymaster.h b/google_softkeymaster.h
index fc6a2d1..5d9185d 100644
--- a/google_softkeymaster.h
+++ b/google_softkeymaster.h
@@ -23,17 +23,20 @@
 
 class GoogleSoftKeymaster : public GoogleKeymaster {
   public:
-    GoogleSoftKeymaster(size_t operation_table_size) : GoogleKeymaster(operation_table_size) {
+    GoogleSoftKeymaster(size_t operation_table_size)
+        : GoogleKeymaster(operation_table_size, new Logger) {
         root_of_trust.tag = KM_TAG_ROOT_OF_TRUST;
         root_of_trust.blob.data = reinterpret_cast<const uint8_t*>("SW");
         root_of_trust.blob.data_length = 2;
     }
-    bool is_enforced(keymaster_tag_t /* tag */) {
-        return false;
+    GoogleSoftKeymaster(size_t operation_table_size, Logger* logger)
+        : GoogleKeymaster(operation_table_size, logger) {
+        root_of_trust.tag = KM_TAG_ROOT_OF_TRUST;
+        root_of_trust.blob.data = reinterpret_cast<const uint8_t*>("SW");
+        root_of_trust.blob.data_length = 2;
     }
-    keymaster_key_origin_t origin() {
-        return KM_ORIGIN_SOFTWARE;
-    }
+    bool is_enforced(keymaster_tag_t /* tag */) { return false; }
+    keymaster_key_origin_t origin() { return KM_ORIGIN_SOFTWARE; }
 
   private:
     static uint8_t master_key_[];
@@ -50,9 +53,7 @@
             nonce[i] = 0;
     }
 
-    keymaster_key_param_t RootOfTrustTag() {
-        return root_of_trust;
-    }
+    keymaster_key_param_t RootOfTrustTag() { return root_of_trust; }
 
     keymaster_key_param_t root_of_trust;
 };
diff --git a/key.cpp b/key.cpp
index 0706ce7..df668eb 100644
--- a/key.cpp
+++ b/key.cpp
@@ -28,20 +28,20 @@
     void operator()(PKCS8_PRIV_KEY_INFO* p) const { PKCS8_PRIV_KEY_INFO_free(p); }
 };
 
-Key::Key(const KeyBlob& blob) {
+Key::Key(const KeyBlob& blob, const Logger& logger) : logger_(logger) {
     authorizations_.push_back(blob.unenforced());
     authorizations_.push_back(blob.enforced());
 }
 
 /* static */
-Key* Key::CreateKey(const KeyBlob& blob, keymaster_error_t* error) {
+Key* Key::CreateKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error) {
     switch (blob.algorithm()) {
     case KM_ALGORITHM_RSA:
-        return new RsaKey(blob, error);
+        return new RsaKey(blob, logger, error);
     case KM_ALGORITHM_DSA:
-        return new DsaKey(blob, error);
+        return new DsaKey(blob, logger, error);
     case KM_ALGORITHM_ECDSA:
-        return new EcdsaKey(blob, error);
+        return new EcdsaKey(blob, logger, error);
     default:
         *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
         return NULL;
@@ -49,7 +49,8 @@
 }
 
 /* static */
-Key* Key::GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error) {
+Key* Key::GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
+                      keymaster_error_t* error) {
     keymaster_algorithm_t algorithm;
     if (!key_description.GetTagValue(TAG_ALGORITHM, &algorithm)) {
         *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
@@ -58,11 +59,11 @@
 
     switch (algorithm) {
     case KM_ALGORITHM_RSA:
-        return RsaKey::GenerateKey(key_description, error);
+        return RsaKey::GenerateKey(key_description, logger, error);
     case KM_ALGORITHM_DSA:
-        return DsaKey::GenerateKey(key_description, error);
+        return DsaKey::GenerateKey(key_description, logger, error);
     case KM_ALGORITHM_ECDSA:
-        return EcdsaKey::GenerateKey(key_description, error);
+        return EcdsaKey::GenerateKey(key_description, logger, error);
     default:
         *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
         return NULL;
@@ -71,7 +72,8 @@
 
 /* static */
 Key* Key::ImportKey(const AuthorizationSet& key_description, keymaster_key_format_t key_format,
-                    const uint8_t* key_data, size_t key_data_length, keymaster_error_t* error) {
+                    const uint8_t* key_data, size_t key_data_length, const Logger& logger,
+                    keymaster_error_t* error) {
     *error = KM_ERROR_OK;
 
     if (key_data == NULL || key_data_length <= 0) {
@@ -100,7 +102,7 @@
     UniquePtr<Key> key;
     switch (EVP_PKEY_type(pkey->type)) {
     case EVP_PKEY_RSA:
-        return RsaKey::ImportKey(key_description, pkey.get(), error);
+        return RsaKey::ImportKey(key_description, pkey.get(), logger, error);
     case EVP_PKEY_DSA:
     case EVP_PKEY_EC:
     default:
diff --git a/key.h b/key.h
index 39e8d1f..2f239e7 100644
--- a/key.h
+++ b/key.h
@@ -19,6 +19,7 @@
 
 #include "authorization_set.h"
 #include "keymaster_defs.h"
+#include "logger.h"
 
 namespace keymaster {
 
@@ -27,11 +28,12 @@
 
 class Key {
   public:
-    static Key* CreateKey(const KeyBlob& blob, keymaster_error_t* error);
-    static Key* GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error);
+    static Key* CreateKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error);
+    static Key* GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
+                            keymaster_error_t* error);
     static Key* ImportKey(const AuthorizationSet& key_description,
                           keymaster_key_format_t key_format, const uint8_t* key_data,
-                          size_t key_data_length, keymaster_error_t* error);
+                          size_t key_data_length, const Logger& logger, keymaster_error_t* error);
 
     virtual ~Key() {}
     virtual Operation* CreateOperation(keymaster_purpose_t purpose, keymaster_error_t* error) = 0;
@@ -51,8 +53,11 @@
     const AuthorizationSet& authorizations() const { return authorizations_; }
 
   protected:
-    Key(const KeyBlob& blob);
-    Key(const AuthorizationSet& authorizations) : authorizations_(authorizations) {}
+    Key(const KeyBlob& blob, const Logger& logger);
+    Key(const AuthorizationSet& authorizations, const Logger& logger)
+        : authorizations_(authorizations), logger_(logger) {}
+
+    const Logger& logger_;
 
   private:
     AuthorizationSet authorizations_;
diff --git a/logger.h b/logger.h
new file mode 100644
index 0000000..23f0d90
--- /dev/null
+++ b/logger.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SYSTEM_KEYMASTER_LOGGER_H_
+#define SYSTEM_KEYMASTER_LOGGER_H_
+
+namespace keymaster {
+
+class Logger {
+  public:
+    Logger() {}
+    virtual ~Logger() {}
+    virtual int log(const char* fmt, ...) const { fmt; return 0; }
+
+  private:
+    // Disallow copying.
+    Logger(const Logger&);
+    void operator=(const Logger&);
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_LOGGER_H_