1use generic_array::typenum::{marker_traits::Unsigned, U16, U32, U64, U96};
2use generic_array::GenericArray;
3use std::ptr::slice_from_raw_parts;
4use bucky_time::bucky_time_now;
5
6use crate::*;
7
8impl Default for Signature {
9 fn default() -> Self {
10 Self {
11 sign_time: bucky_time_now(),
12 sign: SignData::Rsa1024(GenericArray::default()),
13 }
14 }
15}
16
17#[derive(Clone, Eq, PartialEq, Debug)]
18pub enum SignData {
19 Rsa1024(GenericArray<u32, U32>),
20 Rsa2048(GenericArray<u32, U64>),
21 Rsa3072(GenericArray<u32, U96>),
22 Ecc(GenericArray<u32, U16>),
23}
24
25impl SignData {
26 pub fn sign_type(&self) -> &str {
27 match self {
28 Self::Rsa1024(_) => "rsa1024",
29 Self::Rsa2048(_) => "rsa2048",
30 Self::Rsa3072(_) => "rsa3072",
31 Self::Ecc(_) => "ecc",
32 }
33 }
34
35 pub fn as_slice<'a>(&self) -> &'a [u8] {
36 let sign_slice = match self {
37 SignData::Rsa1024(sign) => unsafe {
38 &*slice_from_raw_parts(
39 sign.as_ptr() as *const u8,
40 std::mem::size_of::<u32>() * U32::to_usize(),
41 )
42 },
43 SignData::Rsa2048(sign) => unsafe {
44 &*slice_from_raw_parts(
45 sign.as_ptr() as *const u8,
46 std::mem::size_of::<u32>() * U64::to_usize(),
47 )
48 },
49 SignData::Rsa3072(sign) => unsafe {
50 &*slice_from_raw_parts(
51 sign.as_ptr() as *const u8,
52 std::mem::size_of::<u32>() * U96::to_usize(),
53 )
54 },
55 SignData::Ecc(sign) => unsafe {
56 &*slice_from_raw_parts(
57 sign.as_ptr() as *const u8,
58 std::mem::size_of::<u32>() * U16::to_usize(),
59 )
60 },
61 };
62 sign_slice
63 }
64}
65
66#[derive(Clone, Eq, PartialEq, Debug)]
67pub struct Signature {
68 sign_time: u64,
69 sign: SignData,
70}
71
72impl Signature {
73 pub fn new(
74 sign_time: u64,
75 sign: SignData,
76 ) -> Self {
77 Self {
78 sign_time: sign_time,
79 sign: sign,
80 }
81 }
82
83 pub fn sign(&self) -> &SignData {
84 &self.sign
85 }
86
87 pub fn as_slice<'a>(&self) -> &'a [u8] {
88 self.sign.as_slice()
89 }
90
91 pub fn sign_time(&self) -> u64 {
92 self.sign_time
93 }
94}
95
96impl RawEncode for Signature {
97 fn raw_measure(&self, _purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
98 let mut size = u64::raw_bytes().unwrap();
100
101 size = size
103 + u8::raw_bytes().unwrap()
104 + std::mem::size_of::<u32>()
105 * match self.sign {
106 SignData::Rsa1024(_) => U32::to_usize(),
107 SignData::Rsa2048(_) => U64::to_usize(),
108 SignData::Rsa3072(_) => U96::to_usize(),
109 SignData::Ecc(_) => U16::to_usize(),
110 };
111
112 Ok(size)
113 }
114
115 fn raw_encode<'a>(
116 &self,
117 buf: &'a mut [u8],
118 purpose: &Option<RawEncodePurpose>,
119 ) -> Result<&'a mut [u8], BuckyError> {
120 let bytes = self.raw_measure(purpose).unwrap();
121 if buf.len() < bytes {
122 let msg = format!(
123 "not enough buffer for encode Signature buf, except={}, got={}",
124 bytes,
125 buf.len()
126 );
127 error!("{}", msg);
128
129 return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
130 }
131
132 let buf = self.sign_time.raw_encode(buf, purpose)?;
134
135 let buf = match self.sign {
137 SignData::Rsa1024(sign) => {
138 let buf = KEY_TYPE_RSA.raw_encode(buf, purpose)?;
139 let bytes = std::mem::size_of::<u32>() * U32::to_usize();
140 unsafe {
141 std::ptr::copy(
142 sign.as_slice().as_ptr() as *const u8,
143 buf.as_mut_ptr(),
144 bytes,
145 );
146 }
147 &mut buf[bytes..]
148 }
149 SignData::Rsa2048(sign) => {
150 let buf = KEY_TYPE_RSA2048.raw_encode(buf, purpose)?;
151 let bytes = std::mem::size_of::<u32>() * U64::to_usize();
152 unsafe {
153 std::ptr::copy(
154 sign.as_slice().as_ptr() as *const u8,
155 buf.as_mut_ptr(),
156 bytes,
157 );
158 }
159 &mut buf[bytes..]
160 }
161 SignData::Rsa3072(sign) => {
162 let buf = KEY_TYPE_RSA3072.raw_encode(buf, purpose)?;
163 let bytes = std::mem::size_of::<u32>() * U96::to_usize();
164 unsafe {
165 std::ptr::copy(
166 sign.as_slice().as_ptr() as *const u8,
167 buf.as_mut_ptr(),
168 bytes,
169 );
170 }
171 &mut buf[bytes..]
172 }
173 SignData::Ecc(sign) => {
174 let buf = KEY_TYPE_SECP256K1.raw_encode(buf, purpose)?;
175 let bytes = std::mem::size_of::<u32>() * U16::to_usize();
176 unsafe {
177 std::ptr::copy(
178 sign.as_slice().as_ptr() as *const u8,
179 buf.as_mut_ptr(),
180 bytes,
181 );
182 }
183 &mut buf[bytes..]
184 }
185 };
186
187 Ok(buf)
188 }
189}
190
191impl<'de> RawDecode<'de> for Signature {
192 fn raw_decode(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
193 let (sign_time, buf) = u64::raw_decode(buf)?;
194
195 let (key_type, buf) = u8::raw_decode(buf)?;
196
197 let (sign, buf) = match key_type {
198 KEY_TYPE_RSA => {
199 let bytes = std::mem::size_of::<u32>() * U32::to_usize();
200 if buf.len() < bytes {
201 return Err(BuckyError::new(
202 BuckyErrorCode::OutOfLimit,
203 "not enough buffer for rsa1024 signature",
204 ));
205 }
206
207 let mut sign = GenericArray::default();
208 unsafe {
209 std::ptr::copy(
210 buf.as_ptr(),
211 sign.as_mut_slice().as_mut_ptr() as *mut u8,
212 bytes,
213 );
214 }
215
216 (SignData::Rsa1024(sign), &buf[bytes..])
217 }
218 KEY_TYPE_RSA2048 => {
219 let bytes = std::mem::size_of::<u32>() * U64::to_usize();
220 if buf.len() < bytes {
221 return Err(BuckyError::new(
222 BuckyErrorCode::OutOfLimit,
223 "not enough buffer for rsa2048 signature",
224 ));
225 }
226
227 let mut sign = GenericArray::default();
228 unsafe {
229 std::ptr::copy(
230 buf.as_ptr(),
231 sign.as_mut_slice().as_mut_ptr() as *mut u8,
232 bytes,
233 );
234 }
235
236 (SignData::Rsa2048(sign), &buf[bytes..])
237 }
238 KEY_TYPE_RSA3072 => {
239 let bytes = std::mem::size_of::<u32>() * U96::to_usize();
240 if buf.len() < bytes {
241 return Err(BuckyError::new(
242 BuckyErrorCode::OutOfLimit,
243 "not enough buffer for rsa3072 signature",
244 ));
245 }
246
247 let mut sign = GenericArray::default();
248 unsafe {
249 std::ptr::copy(
250 buf.as_ptr(),
251 sign.as_mut_slice().as_mut_ptr() as *mut u8,
252 bytes,
253 );
254 }
255
256 (SignData::Rsa3072(sign), &buf[bytes..])
257 }
258 KEY_TYPE_SECP256K1 => {
259 let bytes = std::mem::size_of::<u32>() * U16::to_usize();
260 if buf.len() < bytes {
261 return Err(BuckyError::new(
262 BuckyErrorCode::OutOfLimit,
263 "not enough buffer for secp256k1 signature",
264 ));
265 }
266
267 let mut sign = GenericArray::default();
268 unsafe {
269 std::ptr::copy(
270 buf.as_ptr(),
271 sign.as_mut_slice().as_mut_ptr() as *mut u8,
272 bytes,
273 );
274 }
275
276 (SignData::Ecc(sign), &buf[bytes..])
277 }
278 _ => {
279 return Err(BuckyError::new(
280 BuckyErrorCode::NotMatch,
281 format!("Invalid Signature KeyType:{}", key_type),
282 ));
283 }
284 };
285
286 Ok((
287 Self {
288 sign_time,
289 sign: sign,
290 },
291 buf,
292 ))
293 }
294}
295
296#[cfg(test)]
297mod test {
298 use crate::{RawConvertTo, RawFrom, Signature};
299
300 #[test]
301 fn signature() {
302 let sig1 = Signature::default();
303 let buf = sig1.to_vec().unwrap();
304 let sig2 = Signature::clone_from_slice(&buf).unwrap();
305 assert_eq!(sig1, sig2)
306 }
307}