Implement get auth token from database.

This CL implements the functionality related to retrieving an auth token
from the auth token table in keystore perboot database.

Bug: 171503352
Test: TBD
Change-Id: Iefa988cfbe6b01f65dacb029ffdf986216ff9895
diff --git a/keystore2/src/enforcements.rs b/keystore2/src/enforcements.rs
index 473686c..1f82e57 100644
--- a/keystore2/src/enforcements.rs
+++ b/keystore2/src/enforcements.rs
@@ -12,9 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//TODO: remove this after implementing the methods.
-#![allow(dead_code)]
-
 //! This is the Keystore 2.0 Enforcements module.
 // TODO: more description to follow.
 use crate::auth_token_handler::AuthTokenHandler;
@@ -150,8 +147,7 @@
         purpose: KeyPurpose,
         key_params: &[KeyParameter],
         op_params: &[KeyParameter],
-        // security_level will be used in the next CL
-        _security_level: SecurityLevel,
+        security_level: SecurityLevel,
     ) -> Result<AuthTokenHandler> {
         match purpose {
             // Allow SIGN, DECRYPT for both symmetric and asymmetric keys.
@@ -188,11 +184,13 @@
         // reduce the number of for loops on key parameters from 3 to 1, compared to legacy keystore
         let mut key_purpose_authorized: bool = false;
         let mut is_time_out_key: bool = false;
-        let mut auth_type: Option<HardwareAuthenticatorType> = None;
+        let mut user_auth_type: Option<HardwareAuthenticatorType> = None;
         let mut no_auth_required: bool = false;
         let mut caller_nonce_allowed = false;
         let mut user_id: i32 = -1;
         let mut user_secure_ids = Vec::<i64>::new();
+        let mut key_time_out: Option<i64> = None;
+        let mut allow_while_on_body = false;
 
         // iterate through key parameters, recording information we need for authorization
         // enforcements later, or enforcing authorizations in place, where applicable
@@ -201,11 +199,12 @@
                 KeyParameterValue::NoAuthRequired => {
                     no_auth_required = true;
                 }
-                KeyParameterValue::AuthTimeout(_) => {
+                KeyParameterValue::AuthTimeout(t) => {
                     is_time_out_key = true;
+                    key_time_out = Some(*t as i64);
                 }
                 KeyParameterValue::HardwareAuthenticatorType(a) => {
-                    auth_type = Some(*a);
+                    user_auth_type = Some(*a);
                 }
                 KeyParameterValue::KeyPurpose(p) => {
                     // Note: if there can be multiple KeyPurpose key parameters (TODO: confirm this),
@@ -255,6 +254,9 @@
                             .context("In authorize_create: device is locked.");
                     }
                 }
+                KeyParameterValue::AllowWhileOnBody => {
+                    allow_while_on_body = true;
+                }
                 // NOTE: as per offline discussion, sanitizing key parameters and rejecting
                 // create operation if any non-allowed tags are present, is not done in
                 // authorize_create (unlike in legacy keystore where AuthorizeBegin is rejected if
@@ -279,8 +281,8 @@
         }
 
         // if either of auth_type or secure_id is present and the other is not present, return error
-        if (auth_type.is_some() && user_secure_ids.is_empty())
-            || (auth_type.is_none() && !user_secure_ids.is_empty())
+        if (user_auth_type.is_some() && user_secure_ids.is_empty())
+            || (user_auth_type.is_none() && !user_secure_ids.is_empty())
         {
             return Err(KeystoreError::Km(Ec::KEY_USER_NOT_AUTHENTICATED)).context(
                 "In authorize_create: Auth required, but either auth type or secure ids
@@ -299,13 +301,37 @@
         }
 
         if !user_secure_ids.is_empty() {
-            // per op auth token
+            // key requiring authentication per operation
             if !is_time_out_key {
                 return Ok(AuthTokenHandler::OpAuthRequired);
             } else {
-                //time out token
-                // TODO: retrieve it from the database
-                // - in an upcoming CL
+                // key requiring time-out based authentication
+                let auth_token = DB
+                    .with::<_, Result<HardwareAuthToken>>(|db| {
+                        let mut db = db.borrow_mut();
+                        match (user_auth_type, key_time_out) {
+                            (Some(auth_type), Some(key_time_out)) => {
+                                let matching_entry = db
+                                    .find_timed_auth_token_entry(
+                                        &user_secure_ids,
+                                        auth_type,
+                                        key_time_out,
+                                        allow_while_on_body,
+                                    )
+                                    .context("Failed to find timed auth token.")?;
+                                Ok(matching_entry.get_auth_token())
+                            }
+                            (_, _) => Err(KeystoreError::Km(Ec::KEY_USER_NOT_AUTHENTICATED))
+                                .context("Authenticator type and/or key time out is not given."),
+                        }
+                    })
+                    .context("In authorize_create.")?;
+
+                if security_level == SecurityLevel::STRONGBOX {
+                    return Ok(AuthTokenHandler::VerificationRequired(auth_token));
+                } else {
+                    return Ok(AuthTokenHandler::Token(auth_token, None));
+                }
             }
         }