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