rsa/pkcs1v15/
signature.rs1#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5use core::fmt::{Debug, Display, Formatter, LowerHex, UpperHex};
6#[cfg(feature = "alloc")]
7use crypto_bigint::BoxedUint;
8use signature::SignatureEncoding;
9
10use crate::traits::UnsignedModularInt;
11
12#[cfg(feature = "serde")]
13use serdect::serde::{de, Deserialize, Serialize};
14#[cfg(feature = "encoding")]
15use spki::{
16 der::{asn1::BitString, Result as DerResult},
17 SignatureBitStringEncoding,
18};
19
20#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct GenericSignature<T>
25where
26 T: UnsignedModularInt,
27{
28 pub(super) inner: T,
29}
30
31#[derive(Clone)]
33pub struct SignatureBytes<T>(T::Bytes)
34where
35 T: UnsignedModularInt;
36
37#[cfg(feature = "alloc")]
39pub type Signature = GenericSignature<BoxedUint>;
40
41impl<T> GenericSignature<T>
42where
43 T: UnsignedModularInt,
44{
45 pub fn from_inner(inner: T) -> Self {
47 Self { inner }
48 }
49
50 pub fn inner(&self) -> &T {
52 &self.inner
53 }
54}
55
56impl<T> From<T> for GenericSignature<T>
57where
58 T: UnsignedModularInt,
59{
60 fn from(inner: T) -> Self {
61 Self { inner }
62 }
63}
64
65impl<T> SignatureBytes<T>
66where
67 T: UnsignedModularInt,
68{
69 fn new(inner: T::Bytes) -> Self {
70 Self(inner)
71 }
72}
73
74impl<T> AsRef<[u8]> for SignatureBytes<T>
75where
76 T: UnsignedModularInt,
77{
78 fn as_ref(&self) -> &[u8] {
79 self.0.as_ref()
80 }
81}
82
83impl<T> core::ops::Deref for SignatureBytes<T>
84where
85 T: UnsignedModularInt,
86{
87 type Target = [u8];
88
89 fn deref(&self) -> &[u8] {
90 self.0.as_ref()
91 }
92}
93
94impl<T> From<GenericSignature<T>> for SignatureBytes<T>
95where
96 T: UnsignedModularInt,
97{
98 fn from(signature: GenericSignature<T>) -> Self {
99 Self::new(signature.inner.to_be_bytes())
100 }
101}
102
103#[cfg(feature = "alloc")]
104impl<T> TryFrom<&[u8]> for GenericSignature<T>
105where
106 T: UnsignedModularInt,
107{
108 type Error = signature::Error;
109
110 fn try_from(bytes: &[u8]) -> signature::Result<Self> {
111 Ok(Self {
112 inner: T::try_from_be_bytes_vartime(bytes).map_err(signature::Error::from_source)?,
113 })
114 }
115}
116
117#[cfg(feature = "alloc")]
118impl<T> SignatureEncoding for GenericSignature<T>
119where
120 T: UnsignedModularInt + 'static,
121 T::Bytes: Clone + Send + Sync + 'static,
122{
123 type Repr = SignatureBytes<T>;
124}
125
126#[cfg(all(feature = "encoding", feature = "alloc"))]
127impl<T> SignatureBitStringEncoding for GenericSignature<T>
128where
129 T: UnsignedModularInt + 'static,
130 T::Bytes: Clone + Send + Sync + 'static,
131{
132 fn to_bitstring(&self) -> DerResult<BitString> {
133 BitString::new(0, self.to_vec())
134 }
135}
136
137#[cfg(feature = "alloc")]
138impl From<GenericSignature<BoxedUint>> for Box<[u8]> {
139 fn from(signature: GenericSignature<BoxedUint>) -> Box<[u8]> {
140 SignatureBytes::<BoxedUint>::from(signature).0
141 }
142}
143
144impl<T> LowerHex for GenericSignature<T>
145where
146 T: UnsignedModularInt,
147{
148 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
149 let bytes = self.inner.to_be_bytes();
150 for byte in bytes.as_ref() {
151 write!(f, "{:02x}", byte)?;
152 }
153 Ok(())
154 }
155}
156
157impl<T> UpperHex for GenericSignature<T>
158where
159 T: UnsignedModularInt,
160{
161 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
162 let bytes = self.inner.to_be_bytes();
163 for byte in bytes.as_ref() {
164 write!(f, "{:02X}", byte)?;
165 }
166 Ok(())
167 }
168}
169
170impl<T> Display for GenericSignature<T>
171where
172 T: UnsignedModularInt,
173{
174 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
175 write!(f, "{:X}", self)
176 }
177}
178
179#[cfg(feature = "serde")]
180impl<T> Serialize for GenericSignature<T>
181where
182 T: UnsignedModularInt,
183{
184 fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
185 where
186 S: serdect::serde::Serializer,
187 {
188 let bytes = self.inner.to_be_bytes();
189 serdect::slice::serialize_hex_lower_or_bin(&bytes, serializer)
190 }
191}
192
193#[cfg(all(feature = "serde", feature = "alloc"))]
194impl<'de> Deserialize<'de> for GenericSignature<BoxedUint> {
195 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
196 where
197 D: serdect::serde::Deserializer<'de>,
198 {
199 serdect::slice::deserialize_hex_or_bin_vec(deserializer)?
200 .as_slice()
201 .try_into()
202 .map_err(de::Error::custom)
203 }
204}
205
206#[cfg(test)]
207mod tests {
208 #[test]
209 #[cfg(all(feature = "serde", feature = "alloc"))]
210 fn test_serde() {
211 use super::*;
212 use serde_test::{assert_tokens, Configure, Token};
213 let signature = GenericSignature::<BoxedUint> {
214 inner: BoxedUint::from(42u32),
215 };
216
217 let tokens = [Token::Str("000000000000002a")];
218 assert_tokens(&signature.readable(), &tokens);
219 }
220}