1use generic_array::typenum::{marker_traits::Unsigned, U16, U32, U64, U96};
2use generic_array::GenericArray;
3use std::ptr::slice_from_raw_parts;
4
5use crate::*;
6
7pub const SIGNATURE_REF_INDEX: u8 = 0b_00000000;
8pub const SIGNATURE_OBJECT: u8 = 0b_00000001;
9pub const SIGNATURE_KEY: u8 = 0b_00000010;
10
11pub const SIGNATURE_SOURCE_REFINDEX_REF_OBJ_BEGIN: u8 = 0;
13pub const SIGNATURE_SOURCE_REFINDEX_REF_OBJ_END: u8 = 127;
14
15pub const SIGNATURE_SOURCE_REFINDEX_SELF: u8 = 255;
23pub const SIGNATURE_SOURCE_REFINDEX_OWNER: u8 = 254;
24pub const SIGNATURE_SOURCE_REFINDEX_AUTHOR: u8 = 253;
25
26pub const SIGNATURE_SOURCE_REFINDEX_ZONE_OOD_BEGIN: u8 = 252;
27pub const SIGNATURE_SOURCE_REFINDEX_ZONE_OOD_END: u8 = 236;
28
29#[derive(Clone, Eq, PartialEq, Debug)]
30pub enum SignatureSource {
31 RefIndex(u8),
32 Object(ObjectLink),
33 Key(PublicKeyValue),
34}
35
36impl Default for Signature {
37 fn default() -> Self {
38 Self {
39 sign_source: SignatureSource::RefIndex(0),
40 sign_time: bucky_time_now(),
41 sign_key_index: 0,
42 sign: SignData::Rsa1024(GenericArray::default()),
43 }
44 }
45}
46
47#[derive(Clone, Eq, PartialEq, Debug)]
48pub enum SignData {
49 Rsa1024(GenericArray<u32, U32>),
50 Rsa2048(GenericArray<u32, U64>),
51 Rsa3072(GenericArray<u32, U96>),
52 Ecc(GenericArray<u32, U16>),
53}
54
55impl SignData {
56 pub fn sign_type(&self) -> &str {
57 match self {
58 Self::Rsa1024(_) => "rsa1024",
59 Self::Rsa2048(_) => "rsa2048",
60 Self::Rsa3072(_) => "rsa3072",
61 Self::Ecc(_) => "ecc",
62 }
63 }
64
65 pub fn as_slice<'a>(&self) -> &'a [u8] {
66 let sign_slice = match self {
67 SignData::Rsa1024(sign) => unsafe {
68 &*slice_from_raw_parts(
69 sign.as_ptr() as *const u8,
70 std::mem::size_of::<u32>() * U32::to_usize(),
71 )
72 },
73 SignData::Rsa2048(sign) => unsafe {
74 &*slice_from_raw_parts(
75 sign.as_ptr() as *const u8,
76 std::mem::size_of::<u32>() * U64::to_usize(),
77 )
78 },
79 SignData::Rsa3072(sign) => unsafe {
80 &*slice_from_raw_parts(
81 sign.as_ptr() as *const u8,
82 std::mem::size_of::<u32>() * U96::to_usize(),
83 )
84 },
85 SignData::Ecc(sign) => unsafe {
86 &*slice_from_raw_parts(
87 sign.as_ptr() as *const u8,
88 std::mem::size_of::<u32>() * U16::to_usize(),
89 )
90 },
91 };
92 sign_slice
93 }
94}
95
96#[derive(Clone, Eq, PartialEq, Debug)]
97pub struct Signature {
98 sign_source: SignatureSource,
99 sign_key_index: u8,
100 sign_time: u64,
101 sign: SignData,
102}
103
104impl Signature {
105 pub fn new(
106 sign_source: SignatureSource,
107 sign_key_index: u8,
108 sign_time: u64,
109 sign: SignData,
110 ) -> Self {
111 Self {
112 sign_source: sign_source,
113 sign_key_index,
114 sign_time: sign_time,
115 sign: sign,
116 }
117 }
118
119 pub fn sign(&self) -> &SignData {
120 &self.sign
121 }
122
123 pub fn as_slice<'a>(&self) -> &'a [u8] {
124 self.sign.as_slice()
125 }
126
127 fn sign_source_with_ref_index(&self) -> u8 {
128 match self.sign_source {
129 SignatureSource::RefIndex(_index) => {
130 SIGNATURE_REF_INDEX | (self.sign_key_index << 2)
132 }
133 SignatureSource::Object(_) => SIGNATURE_OBJECT | (self.sign_key_index << 2),
134 SignatureSource::Key(_) => SIGNATURE_KEY,
135 }
136 }
137
138 pub fn is_ref_index(&self) -> bool {
139 match self.sign_source {
140 SignatureSource::RefIndex(_) => true,
141 _ => false,
142 }
143 }
144
145 pub fn is_object(&self) -> bool {
146 match self.sign_source {
147 SignatureSource::Object(_) => true,
148 _ => false,
149 }
150 }
151
152 pub fn is_key(&self) -> bool {
153 match self.sign_source {
154 SignatureSource::Key(_) => true,
155 _ => false,
156 }
157 }
158
159 pub fn sign_source(&self) -> &SignatureSource {
160 &self.sign_source
161 }
162
163 pub fn sign_time(&self) -> u64 {
164 self.sign_time
165 }
166
167 pub fn sign_key_index(&self) -> u8 {
168 self.sign_key_index
169 }
170
171 pub fn compare_source(&self, other: &Self) -> bool {
172 self.sign_source == other.sign_source && self.sign_key_index == other.sign_key_index
173 }
174}
175
176impl RawEncode for Signature {
177 fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
178 let mut size = u8::raw_bytes().unwrap();
180
181 size = size
183 + match &self.sign_source {
184 SignatureSource::RefIndex(_) => u8::raw_bytes().unwrap(),
185 SignatureSource::Object(obj) => obj.raw_measure(purpose)?,
186 SignatureSource::Key(key) => key.raw_measure(purpose)?,
187 };
188
189 size = size + u64::raw_bytes().unwrap();
191
192 size = size
194 + u8::raw_bytes().unwrap()
195 + std::mem::size_of::<u32>()
196 * match self.sign {
197 SignData::Rsa1024(_) => U32::to_usize(),
198 SignData::Rsa2048(_) => U64::to_usize(),
199 SignData::Rsa3072(_) => U96::to_usize(),
200 SignData::Ecc(_) => U16::to_usize(),
201 };
202
203 Ok(size)
204 }
205
206 fn raw_encode<'a>(
207 &self,
208 buf: &'a mut [u8],
209 purpose: &Option<RawEncodePurpose>,
210 ) -> Result<&'a mut [u8], BuckyError> {
211 let bytes = self.raw_measure(purpose).unwrap();
212 if buf.len() < bytes {
213 let msg = format!(
214 "not enough buffer for encode Signature buf, except={}, got={}",
215 bytes,
216 buf.len()
217 );
218 error!("{}", msg);
219
220 return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
221 }
222
223 let buf = self.sign_source_with_ref_index().raw_encode(buf, purpose)?;
225
226 let buf = match &self.sign_source {
228 SignatureSource::RefIndex(t) => {
229 let buf = t.raw_encode(buf, purpose)?;
230 buf
231 }
232 SignatureSource::Object(t) => {
233 let buf = t.raw_encode(buf, purpose)?;
234 buf
235 }
236 SignatureSource::Key(t) => {
237 let buf = t.raw_encode(buf, purpose)?;
238 buf
239 }
240 };
241
242 let buf = self.sign_time.raw_encode(buf, purpose)?;
244
245 let buf = match self.sign {
247 SignData::Rsa1024(sign) => {
248 let buf = KEY_TYPE_RSA.raw_encode(buf, purpose)?;
249 let bytes = std::mem::size_of::<u32>() * U32::to_usize();
250 unsafe {
251 std::ptr::copy(
252 sign.as_slice().as_ptr() as *const u8,
253 buf.as_mut_ptr(),
254 bytes,
255 );
256 }
257 &mut buf[bytes..]
258 }
259 SignData::Rsa2048(sign) => {
260 let buf = KEY_TYPE_RSA2048.raw_encode(buf, purpose)?;
261 let bytes = std::mem::size_of::<u32>() * U64::to_usize();
262 unsafe {
263 std::ptr::copy(
264 sign.as_slice().as_ptr() as *const u8,
265 buf.as_mut_ptr(),
266 bytes,
267 );
268 }
269 &mut buf[bytes..]
270 }
271 SignData::Rsa3072(sign) => {
272 let buf = KEY_TYPE_RSA3072.raw_encode(buf, purpose)?;
273 let bytes = std::mem::size_of::<u32>() * U96::to_usize();
274 unsafe {
275 std::ptr::copy(
276 sign.as_slice().as_ptr() as *const u8,
277 buf.as_mut_ptr(),
278 bytes,
279 );
280 }
281 &mut buf[bytes..]
282 }
283 SignData::Ecc(sign) => {
284 let buf = KEY_TYPE_SECP256K1.raw_encode(buf, purpose)?;
285 let bytes = std::mem::size_of::<u32>() * U16::to_usize();
286 unsafe {
287 std::ptr::copy(
288 sign.as_slice().as_ptr() as *const u8,
289 buf.as_mut_ptr(),
290 bytes,
291 );
292 }
293 &mut buf[bytes..]
294 }
295 };
296
297 Ok(buf)
298 }
299}
300
301impl<'de> RawDecode<'de> for Signature {
302 fn raw_decode(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
303 let (sign_source_with_ref_index, buf) = u8::raw_decode(buf)?;
306
307 let sign_source_code = sign_source_with_ref_index << 6 >> 6;
308 let sign_key_index = sign_source_with_ref_index >> 2;
309
310 let (sign_source, buf) = match sign_source_code {
311 SIGNATURE_REF_INDEX => {
312 let (ref_index, buf) = u8::raw_decode(buf)?;
313 Ok((SignatureSource::RefIndex(ref_index), buf))
314 }
315 SIGNATURE_OBJECT => {
316 let (obj_link, buf) = ObjectLink::raw_decode(buf)?;
317 Ok((SignatureSource::Object(obj_link), buf))
318 }
319 SIGNATURE_KEY => {
320 let (key, buf) = PublicKeyValue::raw_decode(buf)?;
321 Ok((SignatureSource::Key(key), buf))
322 }
323 _ => Err(BuckyError::from("invalid signature type")),
324 }?;
325
326 let (sign_time, buf) = u64::raw_decode(buf)?;
327
328 let (key_type, buf) = u8::raw_decode(buf)?;
329
330 let (sign, buf) = match key_type {
331 KEY_TYPE_RSA => {
332 let bytes = std::mem::size_of::<u32>() * U32::to_usize();
333 if buf.len() < bytes {
334 return Err(BuckyError::new(
335 BuckyErrorCode::OutOfLimit,
336 "not enough buffer for rsa1024 signature",
337 ));
338 }
339
340 let mut sign = GenericArray::default();
341 unsafe {
342 std::ptr::copy(
343 buf.as_ptr(),
344 sign.as_mut_slice().as_mut_ptr() as *mut u8,
345 bytes,
346 );
347 }
348
349 (SignData::Rsa1024(sign), &buf[bytes..])
350 }
351 KEY_TYPE_RSA2048 => {
352 let bytes = std::mem::size_of::<u32>() * U64::to_usize();
353 if buf.len() < bytes {
354 return Err(BuckyError::new(
355 BuckyErrorCode::OutOfLimit,
356 "not enough buffer for rsa2048 signature",
357 ));
358 }
359
360 let mut sign = GenericArray::default();
361 unsafe {
362 std::ptr::copy(
363 buf.as_ptr(),
364 sign.as_mut_slice().as_mut_ptr() as *mut u8,
365 bytes,
366 );
367 }
368
369 (SignData::Rsa2048(sign), &buf[bytes..])
370 }
371 KEY_TYPE_RSA3072 => {
372 let bytes = std::mem::size_of::<u32>() * U96::to_usize();
373 if buf.len() < bytes {
374 return Err(BuckyError::new(
375 BuckyErrorCode::OutOfLimit,
376 "not enough buffer for rsa3072 signature",
377 ));
378 }
379
380 let mut sign = GenericArray::default();
381 unsafe {
382 std::ptr::copy(
383 buf.as_ptr(),
384 sign.as_mut_slice().as_mut_ptr() as *mut u8,
385 bytes,
386 );
387 }
388
389 (SignData::Rsa3072(sign), &buf[bytes..])
390 }
391 KEY_TYPE_SECP256K1 => {
392 let bytes = std::mem::size_of::<u32>() * U16::to_usize();
393 if buf.len() < bytes {
394 return Err(BuckyError::new(
395 BuckyErrorCode::OutOfLimit,
396 "not enough buffer for secp256k1 signature",
397 ));
398 }
399
400 let mut sign = GenericArray::default();
401 unsafe {
402 std::ptr::copy(
403 buf.as_ptr(),
404 sign.as_mut_slice().as_mut_ptr() as *mut u8,
405 bytes,
406 );
407 }
408
409 (SignData::Ecc(sign), &buf[bytes..])
410 }
411 _ => {
412 return Err(BuckyError::new(
413 BuckyErrorCode::NotMatch,
414 format!("Invalid Signature KeyType:{}", key_type),
415 ));
416 }
417 };
418
419 Ok((
420 Self {
421 sign_source: sign_source,
422 sign_key_index,
423 sign_time,
424 sign: sign,
425 },
426 buf,
427 ))
428 }
429}
430
431#[cfg(test)]
432mod test {
433 use crate::{RawConvertTo, RawFrom, Signature};
434
435 #[test]
436 fn signature() {
437 let sig1 = Signature::default();
438 let buf = sig1.to_vec().unwrap();
439 let sig2 = Signature::clone_from_slice(&buf).unwrap();
440 assert_eq!(sig1, sig2)
441 }
442}