1*4185b066SAndroid Build Coastguard Worker // Copyright 2023 Google LLC
2*4185b066SAndroid Build Coastguard Worker //
3*4185b066SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*4185b066SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*4185b066SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*4185b066SAndroid Build Coastguard Worker //
7*4185b066SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*4185b066SAndroid Build Coastguard Worker //
9*4185b066SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*4185b066SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*4185b066SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*4185b066SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*4185b066SAndroid Build Coastguard Worker // limitations under the License.
14*4185b066SAndroid Build Coastguard Worker //
15*4185b066SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
16*4185b066SAndroid Build Coastguard Worker
17*4185b066SAndroid Build Coastguard Worker //! Crate that holds common code for an AuthGraph HAL service.
18*4185b066SAndroid Build Coastguard Worker
19*4185b066SAndroid Build Coastguard Worker use android_hardware_security_authgraph::aidl::android::hardware::security::authgraph::{
20*4185b066SAndroid Build Coastguard Worker Arc::Arc, Identity::Identity, KeInitResult::KeInitResult, Key::Key, PlainPubKey::PlainPubKey,
21*4185b066SAndroid Build Coastguard Worker PubKey::PubKey, SessionIdSignature::SessionIdSignature, SessionInfo::SessionInfo,
22*4185b066SAndroid Build Coastguard Worker SessionInitiationInfo::SessionInitiationInfo,
23*4185b066SAndroid Build Coastguard Worker };
24*4185b066SAndroid Build Coastguard Worker use authgraph_wire as wire;
25*4185b066SAndroid Build Coastguard Worker use log::warn;
26*4185b066SAndroid Build Coastguard Worker
27*4185b066SAndroid Build Coastguard Worker pub mod channel;
28*4185b066SAndroid Build Coastguard Worker pub mod service;
29*4185b066SAndroid Build Coastguard Worker
30*4185b066SAndroid Build Coastguard Worker // Neither the AIDL types nor the `authgraph_core` types are local to this crate, which means that
31*4185b066SAndroid Build Coastguard Worker // Rust's orphan rule means we cannot implement the standard conversion traits. So instead define
32*4185b066SAndroid Build Coastguard Worker // our own equivalent conversion traits that are local, and for which we're allowed to provide
33*4185b066SAndroid Build Coastguard Worker // implementations. Give them an odd name to avoid confusion with the standard traits.
34*4185b066SAndroid Build Coastguard Worker
35*4185b066SAndroid Build Coastguard Worker /// Local equivalent of `From` trait, with a different name to avoid clashes.
36*4185b066SAndroid Build Coastguard Worker pub trait Fromm<T>: Sized {
37*4185b066SAndroid Build Coastguard Worker /// Convert `val` into type `Self`.
fromm(val: T) -> Self38*4185b066SAndroid Build Coastguard Worker fn fromm(val: T) -> Self;
39*4185b066SAndroid Build Coastguard Worker }
40*4185b066SAndroid Build Coastguard Worker /// Local equivalent of `TryFrom` trait, with a different name to avoid clashes.
41*4185b066SAndroid Build Coastguard Worker pub trait TryFromm<T>: Sized {
42*4185b066SAndroid Build Coastguard Worker /// Error type emitted on conversion failure.
43*4185b066SAndroid Build Coastguard Worker type Error;
44*4185b066SAndroid Build Coastguard Worker /// Try to convert `val` into type `Self`.
try_fromm(val: T) -> Result<Self, Self::Error>45*4185b066SAndroid Build Coastguard Worker fn try_fromm(val: T) -> Result<Self, Self::Error>;
46*4185b066SAndroid Build Coastguard Worker }
47*4185b066SAndroid Build Coastguard Worker /// Local equivalent of `Into` trait, with a different name to avoid clashes.
48*4185b066SAndroid Build Coastguard Worker pub trait Innto<T> {
49*4185b066SAndroid Build Coastguard Worker /// Convert `self` into type `T`.
innto(self) -> T50*4185b066SAndroid Build Coastguard Worker fn innto(self) -> T;
51*4185b066SAndroid Build Coastguard Worker }
52*4185b066SAndroid Build Coastguard Worker /// Local equivalent of `TryInto` trait, with a different name to avoid clashes.
53*4185b066SAndroid Build Coastguard Worker pub trait TryInnto<T> {
54*4185b066SAndroid Build Coastguard Worker /// Error type emitted on conversion failure.
55*4185b066SAndroid Build Coastguard Worker type Error;
56*4185b066SAndroid Build Coastguard Worker /// Try to convert `self` into type `T`.
try_innto(self) -> Result<T, Self::Error>57*4185b066SAndroid Build Coastguard Worker fn try_innto(self) -> Result<T, Self::Error>;
58*4185b066SAndroid Build Coastguard Worker }
59*4185b066SAndroid Build Coastguard Worker /// Blanket implementation of `Innto` from `Fromm`
60*4185b066SAndroid Build Coastguard Worker impl<T, U> Innto<U> for T
61*4185b066SAndroid Build Coastguard Worker where
62*4185b066SAndroid Build Coastguard Worker U: Fromm<T>,
63*4185b066SAndroid Build Coastguard Worker {
innto(self) -> U64*4185b066SAndroid Build Coastguard Worker fn innto(self) -> U {
65*4185b066SAndroid Build Coastguard Worker U::fromm(self)
66*4185b066SAndroid Build Coastguard Worker }
67*4185b066SAndroid Build Coastguard Worker }
68*4185b066SAndroid Build Coastguard Worker /// Blanket implementation of `TryInnto` from `TryFromm`
69*4185b066SAndroid Build Coastguard Worker impl<T, U> TryInnto<U> for T
70*4185b066SAndroid Build Coastguard Worker where
71*4185b066SAndroid Build Coastguard Worker U: TryFromm<T>,
72*4185b066SAndroid Build Coastguard Worker {
73*4185b066SAndroid Build Coastguard Worker type Error = U::Error;
try_innto(self) -> Result<U, Self::Error>74*4185b066SAndroid Build Coastguard Worker fn try_innto(self) -> Result<U, Self::Error> {
75*4185b066SAndroid Build Coastguard Worker U::try_fromm(self)
76*4185b066SAndroid Build Coastguard Worker }
77*4185b066SAndroid Build Coastguard Worker }
78*4185b066SAndroid Build Coastguard Worker
79*4185b066SAndroid Build Coastguard Worker // Conversions from internal types to HAL-defined types.
80*4185b066SAndroid Build Coastguard Worker
81*4185b066SAndroid Build Coastguard Worker impl Fromm<wire::SessionInitiationInfo> for SessionInitiationInfo {
fromm(val: wire::SessionInitiationInfo) -> Self82*4185b066SAndroid Build Coastguard Worker fn fromm(val: wire::SessionInitiationInfo) -> Self {
83*4185b066SAndroid Build Coastguard Worker Self {
84*4185b066SAndroid Build Coastguard Worker key: val.ke_key.innto(),
85*4185b066SAndroid Build Coastguard Worker identity: Identity { identity: val.identity },
86*4185b066SAndroid Build Coastguard Worker nonce: val.nonce,
87*4185b066SAndroid Build Coastguard Worker version: val.version,
88*4185b066SAndroid Build Coastguard Worker }
89*4185b066SAndroid Build Coastguard Worker }
90*4185b066SAndroid Build Coastguard Worker }
91*4185b066SAndroid Build Coastguard Worker
92*4185b066SAndroid Build Coastguard Worker impl Fromm<wire::Key> for Key {
fromm(val: wire::Key) -> Self93*4185b066SAndroid Build Coastguard Worker fn fromm(val: wire::Key) -> Self {
94*4185b066SAndroid Build Coastguard Worker Self {
95*4185b066SAndroid Build Coastguard Worker pubKey: val
96*4185b066SAndroid Build Coastguard Worker .pub_key
97*4185b066SAndroid Build Coastguard Worker .map(|pub_key| PubKey::PlainKey(PlainPubKey { plainPubKey: pub_key })),
98*4185b066SAndroid Build Coastguard Worker arcFromPBK: val.arc_from_pbk.map(|arc| Arc { arc }),
99*4185b066SAndroid Build Coastguard Worker }
100*4185b066SAndroid Build Coastguard Worker }
101*4185b066SAndroid Build Coastguard Worker }
102*4185b066SAndroid Build Coastguard Worker
103*4185b066SAndroid Build Coastguard Worker impl Fromm<wire::KeInitResult> for KeInitResult {
fromm(val: wire::KeInitResult) -> Self104*4185b066SAndroid Build Coastguard Worker fn fromm(val: wire::KeInitResult) -> Self {
105*4185b066SAndroid Build Coastguard Worker Self {
106*4185b066SAndroid Build Coastguard Worker sessionInitiationInfo: val.session_init_info.innto(),
107*4185b066SAndroid Build Coastguard Worker sessionInfo: val.session_info.innto(),
108*4185b066SAndroid Build Coastguard Worker }
109*4185b066SAndroid Build Coastguard Worker }
110*4185b066SAndroid Build Coastguard Worker }
111*4185b066SAndroid Build Coastguard Worker
112*4185b066SAndroid Build Coastguard Worker impl Fromm<wire::SessionInfo> for SessionInfo {
fromm(val: wire::SessionInfo) -> Self113*4185b066SAndroid Build Coastguard Worker fn fromm(val: wire::SessionInfo) -> Self {
114*4185b066SAndroid Build Coastguard Worker Self {
115*4185b066SAndroid Build Coastguard Worker sharedKeys: val.shared_keys.map(|arc| Arc { arc }),
116*4185b066SAndroid Build Coastguard Worker sessionId: val.session_id,
117*4185b066SAndroid Build Coastguard Worker signature: SessionIdSignature { signature: val.session_id_signature },
118*4185b066SAndroid Build Coastguard Worker }
119*4185b066SAndroid Build Coastguard Worker }
120*4185b066SAndroid Build Coastguard Worker }
121*4185b066SAndroid Build Coastguard Worker
122*4185b066SAndroid Build Coastguard Worker // Conversions from HAL-defined types to internal types.
123*4185b066SAndroid Build Coastguard Worker
124*4185b066SAndroid Build Coastguard Worker impl TryFromm<Key> for wire::Key {
125*4185b066SAndroid Build Coastguard Worker type Error = binder::Status;
try_fromm(aidl: Key) -> Result<Self, Self::Error>126*4185b066SAndroid Build Coastguard Worker fn try_fromm(aidl: Key) -> Result<Self, Self::Error> {
127*4185b066SAndroid Build Coastguard Worker let pub_key = match aidl.pubKey {
128*4185b066SAndroid Build Coastguard Worker None => None,
129*4185b066SAndroid Build Coastguard Worker Some(PubKey::PlainKey(k)) => Some(k.plainPubKey),
130*4185b066SAndroid Build Coastguard Worker Some(PubKey::SignedKey(_)) => return Err(arg_err("expect plain pubkey")),
131*4185b066SAndroid Build Coastguard Worker };
132*4185b066SAndroid Build Coastguard Worker Ok(Self { pub_key, arc_from_pbk: aidl.arcFromPBK.map(|a| a.arc) })
133*4185b066SAndroid Build Coastguard Worker }
134*4185b066SAndroid Build Coastguard Worker }
135*4185b066SAndroid Build Coastguard Worker
136*4185b066SAndroid Build Coastguard Worker /// Generate a binder illegal argument error with the given message.
arg_err(msg: &str) -> binder::Status137*4185b066SAndroid Build Coastguard Worker fn arg_err(msg: &str) -> binder::Status {
138*4185b066SAndroid Build Coastguard Worker binder::Status::new_exception(
139*4185b066SAndroid Build Coastguard Worker binder::ExceptionCode::ILLEGAL_ARGUMENT,
140*4185b066SAndroid Build Coastguard Worker Some(&std::ffi::CString::new(msg).unwrap()),
141*4185b066SAndroid Build Coastguard Worker )
142*4185b066SAndroid Build Coastguard Worker }
143*4185b066SAndroid Build Coastguard Worker
144*4185b066SAndroid Build Coastguard Worker /// Convert a [`wire::ErrorCore`] into a binder error.
errcode_to_binder(err: wire::ErrorCode) -> binder::Status145*4185b066SAndroid Build Coastguard Worker pub fn errcode_to_binder(err: wire::ErrorCode) -> binder::Status {
146*4185b066SAndroid Build Coastguard Worker warn!("operation failed: {err:?}");
147*4185b066SAndroid Build Coastguard Worker // Translate the internal errors for `Unimplemented` and `InternalError` to their counterparts
148*4185b066SAndroid Build Coastguard Worker // in binder errors to have uniformity in the Android HAL layer
149*4185b066SAndroid Build Coastguard Worker match err {
150*4185b066SAndroid Build Coastguard Worker wire::ErrorCode::Unimplemented => {
151*4185b066SAndroid Build Coastguard Worker binder::Status::new_exception(binder::ExceptionCode::UNSUPPORTED_OPERATION, None)
152*4185b066SAndroid Build Coastguard Worker }
153*4185b066SAndroid Build Coastguard Worker wire::ErrorCode::InternalError => {
154*4185b066SAndroid Build Coastguard Worker binder::Status::new_exception(binder::ExceptionCode::SERVICE_SPECIFIC, None)
155*4185b066SAndroid Build Coastguard Worker }
156*4185b066SAndroid Build Coastguard Worker _ => binder::Status::new_service_specific_error(err as i32, None),
157*4185b066SAndroid Build Coastguard Worker }
158*4185b066SAndroid Build Coastguard Worker }
159