1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //! Error-like data structures. See `ResponsePacketError` in the CDDL 18 19 // derive(N) generates a method that is missing a docstring. 20 #![allow(missing_docs)] 21 22 use crate::cbor_convert::value_to_integer; 23 use crate::data_types::response::Response; 24 use alloc::boxed::Box; 25 use alloc::vec::Vec; 26 use ciborium::Value; 27 use coset::CoseError; 28 use enumn::N; 29 30 /// 'Error code' corresponding to successful response. 31 pub const ERROR_OK: u16 = 0; // All real errors must have non-zero error_codes 32 33 /// Errors from Secretkeeper API. Keep in sync with `ErrorCode` defined for Secretkeeper HAL 34 /// at SecretManagement.cddl 35 #[derive(Clone, Copy, Debug, Eq, N, PartialEq)] 36 pub enum SecretkeeperError { 37 // This is the Error code used if no other error codes explains the issue. 38 UnexpectedServerError = 1, 39 // Indicates the Request was malformed & hence couldn't be served. 40 RequestMalformed = 2, 41 /// Requested Entry not found. 42 EntryNotFound = 3, 43 /// Errors originating during serialization or deserialization 44 SerializationError = 4, 45 /// Policy matching did not succeed & hence access not granted. 46 DicePolicyError = 5, 47 } 48 49 // [`SecretkeeperError`] is a valid [`Response`] type. 50 // For more information see `ErrorCode` in SecretManagement.cddl alongside ISecretkeeper.aidl 51 impl Response for SecretkeeperError { new(response_cbor: Vec<Value>) -> Result<Box<Self>, Error>52 fn new(response_cbor: Vec<Value>) -> Result<Box<Self>, Error> { 53 // TODO(b/291228655): This method currently discards the second value in response_cbor, 54 // which contains additional human-readable context in error. Include it! 55 if response_cbor.is_empty() || response_cbor.len() > 2 { 56 return Err(Error::ResponseMalformed); 57 } 58 let error_code: u16 = value_to_integer(&response_cbor[0])?.try_into()?; 59 SecretkeeperError::n(error_code) 60 .map_or_else(|| Err(Error::ResponseMalformed), |sk_err| Ok(Box::new(sk_err))) 61 } 62 error_code(&self) -> u1663 fn error_code(&self) -> u16 { 64 *self as u16 65 } 66 } 67 68 /// Errors thrown internally by the library. 69 #[derive(Debug, PartialEq)] 70 pub enum Error { 71 /// Request was malformed. 72 RequestMalformed, 73 /// Response received from the server was malformed. 74 ResponseMalformed, 75 /// An error happened when serializing to/from a [`Value`]. 76 CborValueError, 77 /// An error happened while casting a type to different type, 78 /// including one [`Value`] type to another. 79 ConversionError, 80 /// These are unexpected errors, which should never really happen. 81 UnexpectedError, 82 /// Sequence number has reached the upper limit. 83 SequenceNumberExhausted, 84 } 85 86 impl From<ciborium::value::Error> for Error { from(_e: ciborium::value::Error) -> Self87 fn from(_e: ciborium::value::Error) -> Self { 88 Self::CborValueError 89 } 90 } 91 92 impl From<ciborium::Value> for Error { from(_e: ciborium::Value) -> Self93 fn from(_e: ciborium::Value) -> Self { 94 Self::ConversionError 95 } 96 } 97 98 impl From<core::num::TryFromIntError> for Error { from(_e: core::num::TryFromIntError) -> Self99 fn from(_e: core::num::TryFromIntError) -> Self { 100 Self::ConversionError 101 } 102 } 103 104 impl From<coset::CoseError> for Error { from(e: coset::CoseError) -> Self105 fn from(e: coset::CoseError) -> Self { 106 match e { 107 CoseError::DecodeFailed(_) 108 | CoseError::EncodeFailed 109 | CoseError::UnexpectedItem(_, _) => Self::ConversionError, 110 _ => { 111 // TODO: Map other COSE errors to precise errors when we use coset more heavily. 112 Self::UnexpectedError 113 } 114 } 115 } 116 } 117