twizzler_security/keys/
verify.rs1#[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::{KeyBuffer, Signature, SigningKey};
15use crate::{SecurityError, SigningScheme};
16
17#[derive(Clone, Debug, PartialEq, Eq)]
23pub struct VerifyingKey {
24 key: KeyBuffer,
26 pub scheme: SigningScheme,
28}
29
30impl VerifyingKey {
31 pub fn new(
33 scheme: &SigningScheme,
34 target_private_key: &SigningKey,
35 ) -> Result<Self, SecurityError> {
36 #[cfg(feature = "log")]
37 debug!("Creating new verifying key with scheme: {:?}", scheme);
38 match scheme {
39 SigningScheme::Ecdsa => {
40 let vkey = EcdsaVerifyingKey::from(TryInto::<EcdsaSigningKey>::try_into(
41 target_private_key,
42 )?);
43
44 let point = vkey.to_encoded_point(false);
45 let bytes = point.as_bytes();
46
47 let key = KeyBuffer::from_slice(bytes).expect(
48 "A ECDSA Verifying Key cannot fit within the currently configured MAX_KEY_SIZE",
49 );
50
51 Ok(VerifyingKey {
52 key,
53 scheme: SigningScheme::Ecdsa,
54 })
55 }
56 }
57 }
58
59 pub fn from_slice(slice: &[u8], scheme: SigningScheme) -> Result<Self, SecurityError> {
61 match scheme {
62 SigningScheme::Ecdsa => {
63 let point: EncodedPoint<NistP256> = EncodedPoint::<NistP256>::from_bytes(slice)
64 .map_err(|_e| {
65 #[cfg(feature = "log")]
66 error!(
67 "Unable to create an encoded point from bytes due to :{:?}",
68 _e
69 );
70
71 SecurityError::InvalidKey
72 })?;
73
74 let key = EcdsaVerifyingKey::from_encoded_point(&point).map_err(|_e| {
76 #[cfg(feature = "log")]
77 error!(
78 "Unable to create an EcdsaVerifyingKey from encoded point, due to :{:?}",
79 _e
80 );
81
82 SecurityError::InvalidKey
83 })?;
84
85 Ok(key.into())
86 }
87 }
88 }
89
90 pub fn as_bytes(&self) -> &[u8] {
92 &self.key
93 }
94
95 pub fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), SecurityError> {
97 match self.scheme {
98 SigningScheme::Ecdsa => {
99 let key: EcdsaVerifyingKey = self.try_into()?;
100 let ecdsa_sig: EcdsaSignature = signature.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 key = KeyBuffer::from_slice(point.as_bytes()).expect(
145 "A ECDSA Verifying Key cannot fit within the currently configured MAX_KEY_SIZE",
146 );
147
148 VerifyingKey {
149 key,
150 scheme: SigningScheme::Ecdsa,
151 }
152 }
153}
154
155#[cfg(feature = "user")]
156impl BaseType for VerifyingKey {
157 fn fingerprint() -> u64 {
158 return 6;
159 }
160}