Implement AuthTokenHandler enum.
This CL implements AuthTokenHandler enum which is used to manage
different states of an auth token during the operation life cycle and
also used by the authorize_* methods of enforcement module to return
the status of the auth token.
Bug: 159461976
Test: TBD
Change-Id: I0c6fc14ece65bc3c161c3403dcb6bbd167780713
diff --git a/keystore2/src/auth_token_handler.rs b/keystore2/src/auth_token_handler.rs
new file mode 100644
index 0000000..8c10442
--- /dev/null
+++ b/keystore2/src/auth_token_handler.rs
@@ -0,0 +1,83 @@
+// Copyright 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.
+
+//! This module defines the AuthTokenHandler enum and its methods. AuthTokenHandler enum represents
+//! the different states an auth token and an associated verification token can be expressed during
+//! the operation life cycle.
+use crate::error::Error as KeystoreError;
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+ HardwareAuthToken::HardwareAuthToken, VerificationToken::VerificationToken,
+};
+use anyhow::{Context, Result};
+use std::sync::mpsc::Receiver;
+
+/// AuthTokenHandler enum has five different variants which are described by the comments above
+// each variant.
+pub enum AuthTokenHandler {
+ /// Used when an operation does not require an auth token for authorization.
+ NoAuthRequired,
+ /// Used to represent the intermediate state between the time the operation is found to be
+ /// requiring per-op auth and the time the auth token for the operation is found.
+ OpAuthRequired,
+ /// Used to represent the intermediate state between the time the operation is found to be
+ /// using a time_out key with STRONGBOX keymint, and the time a verficiation token is requested
+ /// from the worker thread which obtains verification tokens from the TEE KeyMint.
+ VerificationRequired(HardwareAuthToken),
+ /// Used to represent the intermediate state between the time a verification token is requested
+ /// from the worker thread which obtains verification tokens from the TEE KeyMint and the time
+ /// the verification token is received from the worker thread.
+ Channel(Receiver<(HardwareAuthToken, VerificationToken)>),
+ /// Used to represent the final state for all operations requiring an auth token for
+ /// authorization, after the matching auth token (and the associated verification token if
+ /// required) is found.
+ Token(HardwareAuthToken, Option<VerificationToken>),
+}
+
+impl AuthTokenHandler {
+ /// Retrieve auth token and verification token from the Token variant of an AuthTokenHandler
+ /// instance
+ pub fn get_auth_and_verification_tokens(
+ &self,
+ ) -> Option<(&HardwareAuthToken, &VerificationToken)> {
+ if let AuthTokenHandler::Token(auth_token, Some(verification_token)) = self {
+ Some((auth_token, verification_token))
+ } else {
+ None
+ }
+ }
+
+ /// Retrieve auth token from the Token variant of an AuthTokenHandler instance
+ pub fn get_auth_token(&self) -> Option<&HardwareAuthToken> {
+ if let AuthTokenHandler::Token(auth_token, _) = self {
+ Some(auth_token)
+ } else {
+ None
+ }
+ }
+
+ /// If Channel variant, block on it until the verification token is sent by the
+ /// keystore2 worker thread which obtains verification tokens from TEE Keymint
+ pub fn receive_verification_token(&mut self) -> Result<()> {
+ if let AuthTokenHandler::Channel(recv) = self {
+ let (auth_token, verification_token) =
+ recv.recv().context("In receive_verification_token: sender disconnected.")?;
+ *self = AuthTokenHandler::Token(auth_token, Some(verification_token));
+ Ok(())
+ } else {
+ Err(KeystoreError::sys()).context(
+ "In receive_verification_token: Wrong variant found in the authorization object.",
+ )
+ }
+ }
+}
diff --git a/keystore2/src/lib.rs b/keystore2/src/lib.rs
index f75ec77..6299940 100644
--- a/keystore2/src/lib.rs
+++ b/keystore2/src/lib.rs
@@ -14,6 +14,7 @@
//! This crate implements the Android Keystore 2.0 service.
+pub mod auth_token_handler;
pub mod database;
pub mod error;
pub mod globals;