1use super::{verify_digest, Signature};
2use crate::RsaPublicKey;
3use core::marker::PhantomData;
4use digest::{Digest, FixedOutputReset};
5use pkcs8::{
6 spki::{der::AnyRef, AlgorithmIdentifierRef, AssociatedAlgorithmIdentifier},
7 Document, EncodePublicKey,
8};
9use signature::{hazmat::PrehashVerifier, DigestVerifier, Verifier};
10
11#[derive(Debug)]
16pub struct VerifyingKey<D>
17where
18 D: Digest,
19{
20 pub(super) inner: RsaPublicKey,
21 pub(super) salt_len: usize,
22 pub(super) phantom: PhantomData<D>,
23}
24
25impl<D> VerifyingKey<D>
26where
27 D: Digest,
28{
29 pub fn new(key: RsaPublicKey) -> Self {
32 Self::new_with_salt_len(key, <D as Digest>::output_size())
33 }
34
35 pub fn new_with_salt_len(key: RsaPublicKey, salt_len: usize) -> Self {
37 Self {
38 inner: key,
39 salt_len,
40 phantom: Default::default(),
41 }
42 }
43}
44
45impl<D> DigestVerifier<D, Signature> for VerifyingKey<D>
50where
51 D: Digest + FixedOutputReset,
52{
53 fn verify_digest(&self, digest: D, signature: &Signature) -> signature::Result<()> {
54 verify_digest::<D>(
55 &self.inner,
56 &digest.finalize(),
57 &signature.inner,
58 signature.len,
59 self.salt_len,
60 )
61 .map_err(|e| e.into())
62 }
63}
64
65impl<D> PrehashVerifier<Signature> for VerifyingKey<D>
66where
67 D: Digest + FixedOutputReset,
68{
69 fn verify_prehash(&self, prehash: &[u8], signature: &Signature) -> signature::Result<()> {
70 verify_digest::<D>(
71 &self.inner,
72 prehash,
73 &signature.inner,
74 signature.len,
75 self.salt_len,
76 )
77 .map_err(|e| e.into())
78 }
79}
80
81impl<D> Verifier<Signature> for VerifyingKey<D>
82where
83 D: Digest + FixedOutputReset,
84{
85 fn verify(&self, msg: &[u8], signature: &Signature) -> signature::Result<()> {
86 verify_digest::<D>(
87 &self.inner,
88 &D::digest(msg),
89 &signature.inner,
90 signature.len,
91 self.salt_len,
92 )
93 .map_err(|e| e.into())
94 }
95}
96
97impl<D> AsRef<RsaPublicKey> for VerifyingKey<D>
102where
103 D: Digest,
104{
105 fn as_ref(&self) -> &RsaPublicKey {
106 &self.inner
107 }
108}
109
110impl<D> AssociatedAlgorithmIdentifier for VerifyingKey<D>
111where
112 D: Digest,
113{
114 type Params = AnyRef<'static>;
115
116 const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = pkcs1::ALGORITHM_ID;
117}
118
119impl<D> Clone for VerifyingKey<D>
121where
122 D: Digest,
123{
124 fn clone(&self) -> Self {
125 Self {
126 inner: self.inner.clone(),
127 salt_len: self.salt_len,
128 phantom: Default::default(),
129 }
130 }
131}
132
133impl<D> EncodePublicKey for VerifyingKey<D>
134where
135 D: Digest,
136{
137 fn to_public_key_der(&self) -> pkcs8::spki::Result<Document> {
138 self.inner.to_public_key_der()
139 }
140}
141
142impl<D> From<RsaPublicKey> for VerifyingKey<D>
143where
144 D: Digest,
145{
146 fn from(key: RsaPublicKey) -> Self {
147 Self::new(key)
148 }
149}
150
151impl<D> From<VerifyingKey<D>> for RsaPublicKey
152where
153 D: Digest,
154{
155 fn from(key: VerifyingKey<D>) -> Self {
156 key.inner
157 }
158}