rsa/pkcs1v15/
verifying_key.rs1use super::{oid, pkcs1v15_generate_prefix, verify, Signature};
2use crate::RsaPublicKey;
3use alloc::vec::Vec;
4use core::marker::PhantomData;
5use digest::Digest;
6use pkcs8::{
7 spki::{
8 der::AnyRef, AlgorithmIdentifierRef, AssociatedAlgorithmIdentifier,
9 SignatureAlgorithmIdentifier,
10 },
11 AssociatedOid, Document, EncodePublicKey,
12};
13use signature::{hazmat::PrehashVerifier, DigestVerifier, Verifier};
14
15#[derive(Debug)]
19pub struct VerifyingKey<D>
20where
21 D: Digest,
22{
23 pub(super) inner: RsaPublicKey,
24 pub(super) prefix: Vec<u8>,
25 pub(super) phantom: PhantomData<D>,
26}
27
28impl<D> VerifyingKey<D>
29where
30 D: Digest + AssociatedOid,
31{
32 pub fn new(key: RsaPublicKey) -> Self {
34 Self {
35 inner: key,
36 prefix: pkcs1v15_generate_prefix::<D>(),
37 phantom: Default::default(),
38 }
39 }
40
41 #[deprecated(since = "0.9.0", note = "use VerifyingKey::new instead")]
43 pub fn new_with_prefix(key: RsaPublicKey) -> Self {
44 Self::new(key)
45 }
46}
47
48impl<D> VerifyingKey<D>
49where
50 D: Digest,
51{
52 pub fn new_unprefixed(key: RsaPublicKey) -> Self {
58 Self {
59 inner: key,
60 prefix: Vec::new(),
61 phantom: Default::default(),
62 }
63 }
64}
65
66impl<D> DigestVerifier<D, Signature> for VerifyingKey<D>
71where
72 D: Digest,
73{
74 fn verify_digest(&self, digest: D, signature: &Signature) -> signature::Result<()> {
75 verify(
76 &self.inner,
77 &self.prefix,
78 &digest.finalize(),
79 &signature.inner,
80 signature.len,
81 )
82 .map_err(|e| e.into())
83 }
84}
85
86impl<D> PrehashVerifier<Signature> for VerifyingKey<D>
87where
88 D: Digest,
89{
90 fn verify_prehash(&self, prehash: &[u8], signature: &Signature) -> signature::Result<()> {
91 verify(
92 &self.inner,
93 &self.prefix,
94 prehash,
95 &signature.inner,
96 signature.len,
97 )
98 .map_err(|e| e.into())
99 }
100}
101
102impl<D> Verifier<Signature> for VerifyingKey<D>
103where
104 D: Digest,
105{
106 fn verify(&self, msg: &[u8], signature: &Signature) -> signature::Result<()> {
107 verify(
108 &self.inner,
109 &self.prefix.clone(),
110 &D::digest(msg),
111 &signature.inner,
112 signature.len,
113 )
114 .map_err(|e| e.into())
115 }
116}
117
118impl<D> AsRef<RsaPublicKey> for VerifyingKey<D>
123where
124 D: Digest,
125{
126 fn as_ref(&self) -> &RsaPublicKey {
127 &self.inner
128 }
129}
130
131impl<D> AssociatedAlgorithmIdentifier for VerifyingKey<D>
132where
133 D: Digest,
134{
135 type Params = AnyRef<'static>;
136
137 const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = pkcs1::ALGORITHM_ID;
138}
139
140impl<D> Clone for VerifyingKey<D>
142where
143 D: Digest,
144{
145 fn clone(&self) -> Self {
146 Self {
147 inner: self.inner.clone(),
148 prefix: self.prefix.clone(),
149 phantom: Default::default(),
150 }
151 }
152}
153
154impl<D> EncodePublicKey for VerifyingKey<D>
155where
156 D: Digest,
157{
158 fn to_public_key_der(&self) -> pkcs8::spki::Result<Document> {
159 self.inner.to_public_key_der()
160 }
161}
162
163impl<D> From<RsaPublicKey> for VerifyingKey<D>
164where
165 D: Digest,
166{
167 fn from(key: RsaPublicKey) -> Self {
168 Self::new_unprefixed(key)
169 }
170}
171
172impl<D> From<VerifyingKey<D>> for RsaPublicKey
173where
174 D: Digest,
175{
176 fn from(key: VerifyingKey<D>) -> Self {
177 key.inner
178 }
179}
180
181impl<D> SignatureAlgorithmIdentifier for VerifyingKey<D>
182where
183 D: Digest + oid::RsaSignatureAssociatedOid,
184{
185 type Params = AnyRef<'static>;
186
187 const SIGNATURE_ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> =
188 AlgorithmIdentifierRef {
189 oid: D::OID,
190 parameters: Some(AnyRef::NULL),
191 };
192}
193
194impl<D> TryFrom<pkcs8::SubjectPublicKeyInfoRef<'_>> for VerifyingKey<D>
195where
196 D: Digest + AssociatedOid,
197{
198 type Error = pkcs8::spki::Error;
199
200 fn try_from(spki: pkcs8::SubjectPublicKeyInfoRef<'_>) -> pkcs8::spki::Result<Self> {
201 RsaPublicKey::try_from(spki).map(Self::new)
202 }
203}