Merge "Treat the alias column as a BLOB."
diff --git a/keystore/legacy_keymaster_device_wrapper.cpp b/keystore/legacy_keymaster_device_wrapper.cpp
index 86d286e..052f394 100644
--- a/keystore/legacy_keymaster_device_wrapper.cpp
+++ b/keystore/legacy_keymaster_device_wrapper.cpp
@@ -532,7 +532,7 @@
 
 sp<IKeymasterDevice> makeSoftwareKeymasterDevice() {
     keymaster2_device_t* dev = nullptr;
-    dev = (new SoftKeymasterDevice)->keymaster2_device();
+    dev = (new SoftKeymasterDevice(keymaster::KmVersion::KEYMASTER_2))->keymaster2_device();
 
     auto kmrc = ::keymaster::ConfigureDevice(dev);
     if (kmrc != KM_ERROR_OK) {
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index 9552df5..dab6123 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -36,8 +36,9 @@
     name: "keystore2_test",
     crate_name: "keystore2",
     srcs: ["src/lib.rs"],
-    test_suites: ["general-tests"],
-    auto_gen_config: true,
+    test_suites: ["device-tests"],
+    auto_gen_config: false,
+    test_config: "AndroidTest.xml",
     rustlibs: [
         "android.system.keystore2-rust",
         "android.hardware.keymint-rust",
@@ -64,3 +65,22 @@
     ],
     init_rc: ["keystore2.rc"],
 }
+
+aidl_interface {
+    name: "android.security.attestationmanager",
+    srcs: [
+        "aidl/android/security/ByteArray.aidl",
+        "aidl/android/security/IAttestationManager.aidl",
+    ],
+    local_include_dir: "aidl",
+    imports: [ "android.hardware.keymint" ],
+    unstable: true,
+    backend: {
+        java: {
+            sdk_version: "module_current",
+        },
+        rust: {
+            enabled: true,
+        },
+    },
+}
diff --git a/keystore2/AndroidTest.xml b/keystore2/AndroidTest.xml
new file mode 100644
index 0000000..b295947
--- /dev/null
+++ b/keystore2/AndroidTest.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration description="Config to run keystore2_test device tests.">
+
+    <option name="test-suite-tag" value="rust-tests" />
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="keystore2_test->/data/local/tmp/keystore2_test" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
+        <option name="test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="keystore2_test" />
+    </test>
+</configuration>
diff --git a/keystore2/aidl/android/security/ByteArray.aidl b/keystore2/aidl/android/security/ByteArray.aidl
new file mode 100644
index 0000000..db2e18c
--- /dev/null
+++ b/keystore2/aidl/android/security/ByteArray.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package android.security;
+
+/**
+ * Simple data holder for a byte array, allowing for multidimensional arrays in AIDL.
+ *
+ * @hide
+ */
+parcelable ByteArray {
+    byte[] data;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/IAttestationManager.aidl b/keystore2/aidl/android/security/IAttestationManager.aidl
new file mode 100644
index 0000000..1953cca
--- /dev/null
+++ b/keystore2/aidl/android/security/IAttestationManager.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package android.security;
+
+import android.security.ByteArray;
+import android.hardware.keymint.KeyParameter;
+
+/**
+ * Internal interface for performing device attestation.
+ *
+ * @hide
+ */
+interface IAttestationManager {
+    /**
+     * Attest a provided list of device identifiers.
+     *
+     * @return The signed certificate chain, with each individual certificate encoded as a byte
+     *         array.
+     */
+    ByteArray[] attestDevice(
+            in KeyParameter[] deviceIdentifiers, boolean useIndividualAttestation,
+            in byte[] attestationChallenge, int securityLevel);
+}
\ No newline at end of file
diff --git a/keystore2/src/crypto/certificate_utils.cpp b/keystore2/src/crypto/certificate_utils.cpp
index 56dd3f4..500600f 100644
--- a/keystore2/src/crypto/certificate_utils.cpp
+++ b/keystore2/src/crypto/certificate_utils.cpp
@@ -537,7 +537,7 @@
     }
 
     uint8_t* cert_buf = nullptr;
-    size_t buf_len = i2d_re_X509_tbs(certificate, &cert_buf);
+    int buf_len = i2d_re_X509_tbs(certificate, &cert_buf);
     if (buf_len < 0) {
         return CertUtilsError::Encoding;
     }
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index 1f77cbe..0db4162 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -150,6 +150,7 @@
     fn drop(&mut self) {
         let mut locked_keys = KEY_ID_LOCK.locked_keys.lock().unwrap();
         locked_keys.remove(&self.0);
+        drop(locked_keys);
         KEY_ID_LOCK.cond_var.notify_all();
     }
 }
diff --git a/keystore2/src/error.rs b/keystore2/src/error.rs
index 63ebe62..49d72bb 100644
--- a/keystore2/src/error.rs
+++ b/keystore2/src/error.rs
@@ -99,34 +99,34 @@
 }
 
 /// This function should be used by Keystore service calls to translate error conditions
-/// into `android.system.keystore2.Result` which is imported here as `aidl::Result`
-/// and newtyped as AidlResult.
-/// All error conditions get logged by this function.
-/// All `Error::Rc(x)` variants get mapped onto `aidl::Result{x, 0}`.
-/// All `Error::Km(x)` variants get mapped onto
-/// `aidl::Result{aidl::ResponseCode::KeymintErrorCode, x}`.
-/// `selinux::Error::perm()` is mapped on `aidl::Result{aidl::ResponseCode::PERMISSION_DENIED, 0}`.
+/// into service specific exceptions.
 ///
-/// All non `Error` error conditions get mapped onto
-/// `aidl::Result{aidl::ResponseCode::SYSTEM_ERROR}`.
+/// All error conditions get logged by this function.
+///
+/// All `Error::Rc(x)` and `Error::Km(x)` variants get mapped onto a service specific error
+/// code of x. This is possible because KeyMint `ErrorCode` errors are always negative and
+/// `ResponseCode` codes are always positive.
+/// `selinux::Error::PermissionDenied` is mapped on `ResponseCode::PERMISSION_DENIED`.
+///
+/// All non `Error` error conditions and the Error::Binder variant get mapped onto
+/// ResponseCode::SYSTEM_ERROR`.
 ///
 /// `handle_ok` will be called if `result` is `Ok(value)` where `value` will be passed
-/// as argument to `handle_ok`. `handle_ok` must generate an `AidlResult`, typically
-/// `AidlResult::ok()`, but other response codes may be used, e.g.,
-/// `aidl::ResponseCode::OpAuthNeeded` which does not required logging.
+/// as argument to `handle_ok`. `handle_ok` must generate a `BinderResult<T>`, but it
+/// typically returns Ok(value).
 ///
 /// # Examples
 ///
 /// ```
-/// fn loadKey() -> anyhow::Result<aidl::ResponseCode> {
+/// fn loadKey() -> anyhow::Result<Vec<u8>> {
 ///     if (good_but_auth_required) {
-///         Ok(aidl::ResponseCode::OpAuthRequired)
+///         Ok(vec!['k', 'e', 'y'])
 ///     } else {
-///         Err(anyhow!(Error::Rc(aidl::ResponseCode::KEY_NOT_FOUND)))
+///         Err(anyhow!(Error::Rc(ResponseCode::KEY_NOT_FOUND)))
 ///     }
 /// }
 ///
-/// aidl_result_ = map_or_log_err(loadKey(), |r| { some_side_effect(); AidlResult::rc(r) });
+/// map_or_log_err(loadKey(), Ok)
 /// ```
 pub fn map_or_log_err<T, U, F>(result: anyhow::Result<U>, handle_ok: F) -> BinderResult<T>
 where
diff --git a/keystore2/src/keystore2_main.rs b/keystore2/src/keystore2_main.rs
index dea0a93..ab00794 100644
--- a/keystore2/src/keystore2_main.rs
+++ b/keystore2/src/keystore2_main.rs
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//! This crate implements Keystore 2.0.
+//! This crate implements the Keystore 2.0 service entry point.
 
 use binder::Interface;
 use keystore2::service::KeystoreService;
@@ -53,7 +53,10 @@
     });
 
     info!("Successfully registered Keystore 2.0 service.");
-    info!("Joining threadpool now.");
 
+    info!("Starting thread pool now.");
+    binder::ProcessState::start_thread_pool();
+
+    info!("Joining thread pool now.");
     binder::ProcessState::join_thread_pool();
 }