cloud_sdk/authentication/signing/
build.rs1use core::fmt;
2
3use cloud_sdk_sanitization::sanitize_bytes;
4
5use super::{MAX_SIGNING_BODY_DIGEST_BYTES, SigningInputError, SigningValueError};
6
7#[derive(Clone, Copy, Eq, PartialEq)]
8pub(super) struct SigningBodyDigest<'a>(&'a [u8]);
9
10impl<'a> SigningBodyDigest<'a> {
11 pub(super) fn new(value: &'a [u8]) -> Result<Self, SigningValueError> {
12 if value.is_empty() {
13 return Err(SigningValueError::Empty);
14 }
15 if value.len() > MAX_SIGNING_BODY_DIGEST_BYTES {
16 return Err(SigningValueError::TooLong);
17 }
18 Ok(Self(value))
19 }
20
21 pub(super) const fn as_bytes(self) -> &'a [u8] {
22 self.0
23 }
24}
25
26impl fmt::Debug for SigningBodyDigest<'_> {
27 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
28 formatter.write_str("SigningBodyDigest([redacted])")
29 }
30}
31
32pub enum SigningBuildError<E> {
34 DigestAlgorithmMismatch,
36 Hasher(E),
38 Digest(SigningValueError),
40 Input(SigningInputError),
42}
43
44impl<E> fmt::Debug for SigningBuildError<E> {
45 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
46 formatter.write_str(match self {
47 Self::DigestAlgorithmMismatch => "SigningBuildError::DigestAlgorithmMismatch",
48 Self::Hasher(_) => "SigningBuildError::Hasher([redacted])",
49 Self::Digest(_) => "SigningBuildError::Digest",
50 Self::Input(_) => "SigningBuildError::Input",
51 })
52 }
53}
54
55impl<E> fmt::Display for SigningBuildError<E> {
56 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
57 formatter.write_str(match self {
58 Self::DigestAlgorithmMismatch => {
59 "request body hasher does not match the signed digest algorithm"
60 }
61 Self::Hasher(_) => "request body hashing failed",
62 Self::Digest(_) => "request body hasher returned an invalid digest length",
63 Self::Input(_) => "canonical signing input construction failed",
64 })
65 }
66}
67
68impl<E> core::error::Error for SigningBuildError<E>
69where
70 E: core::error::Error + 'static,
71{
72 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
73 match self {
74 Self::Hasher(error) => Some(error),
75 Self::Digest(error) => Some(error),
76 Self::Input(error) => Some(error),
77 Self::DigestAlgorithmMismatch => None,
78 }
79 }
80}
81
82pub(super) struct DigestScratch<'a>(&'a mut [u8]);
83
84impl<'a> DigestScratch<'a> {
85 pub(super) fn new(storage: &'a mut [u8]) -> Self {
86 sanitize_bytes(storage);
87 Self(storage)
88 }
89
90 pub(super) fn as_mut(&mut self) -> &mut [u8] {
91 self.0
92 }
93
94 pub(super) fn as_slice(&self) -> &[u8] {
95 self.0
96 }
97}
98
99impl Drop for DigestScratch<'_> {
100 fn drop(&mut self) {
101 sanitize_bytes(self.0);
102 }
103}