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::{Signature, SigningKey, MAX_KEY_SIZE};
15use crate::{SecurityError, SigningScheme};
16
17#[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 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 pub fn as_bytes(&self) -> &[u8] {
92 &self.key[0..self.len]
93 }
94
95 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}