twizzler_security/keys/
verify.rs

1#[cfg(feature = "log")]
2use log::{debug, error};
3use p256::{
4    ecdsa::{
5        signature::Verifier, Signature as EcdsaSignature, SigningKey as EcdsaSigningKey,
6        VerifyingKey as EcdsaVerifyingKey,
7    },
8    elliptic_curve::sec1::EncodedPoint,
9    NistP256,
10};
11#[cfg(feature = "user")]
12use twizzler::marker::BaseType;
13
14use super::{Signature, SigningKey, MAX_KEY_SIZE};
15use crate::{SecurityError, SigningScheme};
16
17// making our own struct for verifying key since we need to be able to support keys with different
18// schemes, (meaning they could also be different lengths)
19#[derive(Copy, Clone, Debug, PartialEq, Eq)]
20pub struct VerifyingKey {
21    key: [u8; MAX_KEY_SIZE],
22    len: usize,
23    pub scheme: SigningScheme,
24}
25
26impl VerifyingKey {
27    pub fn new(
28        scheme: &SigningScheme,
29        target_private_key: &SigningKey,
30    ) -> Result<Self, SecurityError> {
31        #[cfg(feature = "log")]
32        debug!("Creating new verifying key with scheme: {:?}", scheme);
33        match scheme {
34            SigningScheme::Ecdsa => {
35                let vkey = EcdsaVerifyingKey::from(TryInto::<EcdsaSigningKey>::try_into(
36                    target_private_key,
37                )?);
38
39                let point = vkey.to_encoded_point(false);
40                let bytes = point.as_bytes();
41
42                let mut buf = [0; MAX_KEY_SIZE];
43                buf[0..bytes.len()].copy_from_slice(bytes);
44
45                Ok(VerifyingKey {
46                    key: buf,
47                    len: bytes.len(),
48                    scheme: SigningScheme::Ecdsa,
49                })
50            }
51        }
52    }
53
54    pub fn from_slice(slice: &[u8], scheme: &SigningScheme) -> Result<Self, SecurityError> {
55        match scheme {
56            SigningScheme::Ecdsa => {
57                let point: EncodedPoint<NistP256> = EncodedPoint::<NistP256>::from_bytes(slice)
58                    .map_err(|_e| {
59                        #[cfg(feature = "log")]
60                        error!(
61                            "Unable to create an encoded point from bytes due to :{:?}",
62                            _e
63                        );
64
65                        SecurityError::InvalidKey
66                    })?;
67
68                // we create key here to ensure its valid
69                let _key = EcdsaVerifyingKey::from_encoded_point(&point).map_err(|_e| {
70                    #[cfg(feature = "log")]
71                    error!(
72                        "Unable to create an EcdsaVerifyingKey from encoded point, due to :{:?}",
73                        _e
74                    );
75
76                    SecurityError::InvalidKey
77                })?;
78
79                let mut buf = [0; MAX_KEY_SIZE];
80                buf[0..slice.len()].copy_from_slice(slice);
81                Ok(VerifyingKey {
82                    key: buf,
83                    len: slice.len(),
84                    scheme: SigningScheme::Ecdsa,
85                })
86            }
87        }
88    }
89
90    // so we can easily extract out the key without worrying about len and the buffer
91    pub fn as_bytes(&self) -> &[u8] {
92        &self.key[0..self.len]
93    }
94
95    /// Checks whether the `sig` can be verified.
96    pub fn verify(&self, msg: &[u8], sig: &Signature) -> Result<(), SecurityError> {
97        match self.scheme {
98            SigningScheme::Ecdsa => {
99                let key: EcdsaVerifyingKey = self.try_into()?;
100                let ecdsa_sig: EcdsaSignature = sig.try_into()?;
101                key.verify(msg, &ecdsa_sig).map_err(|_e| {
102                    #[cfg(feature = "log")]
103                    error!("Failed verification of signature due to: {:#?}", _e);
104
105                    SecurityError::SignatureMismatch
106                })
107            }
108        }
109    }
110}
111
112impl TryFrom<&VerifyingKey> for EcdsaVerifyingKey {
113    type Error = SecurityError;
114    fn try_from(value: &VerifyingKey) -> Result<Self, Self::Error> {
115        let point: EncodedPoint<NistP256> = EncodedPoint::<NistP256>::from_bytes(value.as_bytes())
116            .map_err(|_e| {
117                #[cfg(feature = "log")]
118                error!(
119                    "Failed to create an encoded point from bytes due to :{:#?}",
120                    _e
121                );
122
123                SecurityError::InvalidKey
124            })?;
125
126        let key = EcdsaVerifyingKey::from_encoded_point(&point).map_err(|_e| {
127            #[cfg(feature = "log")]
128            error!(
129                "Failed to create a EcdsaVerifyingKey out of an encoded point due to :{:#?}",
130                _e
131            );
132
133            SecurityError::InvalidKey
134        })?;
135
136        Ok(key)
137    }
138}
139
140impl From<EcdsaVerifyingKey> for VerifyingKey {
141    fn from(value: EcdsaVerifyingKey) -> Self {
142        let point = value.to_encoded_point(false);
143
144        let bytes = point.as_bytes();
145
146        let mut buf = [0; MAX_KEY_SIZE];
147
148        buf[0..bytes.len()].copy_from_slice(bytes);
149
150        VerifyingKey {
151            key: buf,
152            len: bytes.len(),
153            scheme: SigningScheme::Ecdsa,
154        }
155    }
156}
157
158#[cfg(feature = "user")]
159impl BaseType for VerifyingKey {
160    fn fingerprint() -> u64 {
161        return 6;
162    }
163}