attestation_doc_validation/
error.rs1use thiserror::Error;
3
4use crate::{nsm::error::NsmError as InnerNsm, time};
5
6pub type AttestResult<T> = Result<T, AttestError>;
8pub type AttestationResult<T> = Result<T, AttestationError>;
10pub type CertResult<T> = Result<T, CertError>;
12
13#[allow(clippy::module_name_repetitions)]
15#[derive(Error, Debug)]
16pub enum AttestError
17where
18 Self: Send + Sync,
19{
20 #[error("An error occurred while attesting the connection received: {0}")]
21 AttestationError(#[from] AttestationError),
22 #[error("An error occurred while validating the TLS Certificate received: {0}")]
23 CertError(#[from] CertError),
24 #[error("An error occurred interfacing with the Nitro Security Module: {0}")]
25 NsmError(#[from] InnerNsm),
26 #[error("An error occured decoding the public key from the attestation doc's userdata")]
27 DecodeError(#[from] base64::DecodeError),
28 #[error("An error occured parsing the expiry date from the attestation doc's userdata")]
29 DateParseError(#[from] chrono::ParseError),
30}
31
32#[allow(clippy::module_name_repetitions)]
34#[derive(Error, Debug)]
35pub enum AttestationError
36where
37 Self: Send + Sync,
38{
39 #[error("COSE error: `{0}`")]
40 InvalidCose(String),
41 #[error(transparent)]
42 InvalidCbor(#[from] serde_cbor::error::Error),
43 #[error("A part of the attestation doc structure was deemed invalid")]
44 DocStructureInvalid,
45 #[error("The COSE signature does not match the public key provided in the attestation doc")]
46 InvalidCoseSignature,
47 #[error(
48 "The PCRs found were different to the expected values.\n\nExpected:\n{0}\n\nReceived:\n{1}"
49 )]
50 UnexpectedPCRs(String, String),
51 #[error("PCR{0} was missing in the attestation doc")]
52 MissingPCR(usize),
53 #[error("User data was not set in the attestation doc")]
54 MissingUserData,
55 #[error("User data in attestation doc did not contain the certificate public key")]
56 UserDataMismatch,
57 #[error("Nonce in the attestation doc did not match the nonce provided,\n\nExpected: {expected}\nReceived: {received:?}")]
58 NonceMismatch {
59 expected: String,
60 received: Option<String>,
61 },
62 #[error("The module id was missing from the attestation doc")]
63 MissingModuleId,
64 #[error("The digest in the attestation was not SHA384")]
65 DigestAlgorithmInvalid,
66 #[error("The PCRs in the attestation doc were invalid")]
67 InvalidPCRs,
68 #[error("The CA bundle length in the attestation doc was invalid")]
69 InvalidCABundle,
70 #[error("The public key length in the attestation doc was invalid")]
71 InvalidPublicKey,
72 #[error("The nonce length in the attestation doc was invalid")]
73 InvalidNonce,
74 #[error("The user data length in the attestation doc was invalid")]
75 InvalidUserData,
76 #[error("The supplied attestation doc has expired")]
77 ExpiredDocument,
78}
79
80#[allow(clippy::module_name_repetitions)]
82#[derive(Error, Debug)]
83pub enum CertError
84where
85 Self: Send + Sync,
86{
87 #[error("Failed to validate the trust chain for the provided cert — {0}")]
89 InvalidTrustChain(String),
90 #[error("The certificate in the attestation doc was detected as not having the NSM as root")]
91 UntrustedCert,
92 #[error("The received certificate had no Subject Alt Name extension")]
93 NoSubjectAltNames,
94 #[error("Attempts to parse certificate from PEM and DER encoding failed")]
95 DecodeError,
96 #[error("Unable to parse attestation doc bytes from Subject Alt Name extension")]
97 ParseError,
98 #[error(transparent)]
99 HexError(#[from] hex::FromHexError),
100 #[error(transparent)]
101 TimeError(#[from] time::Error),
102 #[error("Failed to parse cert from pem encoding")]
103 PemError(#[from] x509_parser::error::PEMError),
104 #[error("Failed to parse x509 cert from pem encoding")]
105 X509Error,
106 #[error("No cert given")]
107 NoCertGiven,
108}
109
110impl std::convert::From<webpki::Error> for CertError {
111 fn from(value: webpki::Error) -> Self {
112 Self::InvalidTrustChain(value.to_string())
113 }
114}