cyfs_base/crypto/
signature.rs

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
11// 1.obj_desc.ref_objs,取值范围为[0, 127]
12pub const SIGNATURE_SOURCE_REFINDEX_REF_OBJ_BEGIN: u8 = 0;
13pub const SIGNATURE_SOURCE_REFINDEX_REF_OBJ_END: u8 = 127;
14
15/*
162.逻辑ref (从128-255(可以根据需要扩展)
17ref[255] = 自己 (适用于有权对象)
18ref[254] = owner (使用于有主对象)
19ref[253] = author (适用于填写了作者的对象)
20ref[252-236] = ood_list[x] (适用于所在Zone的ood对象)
21*/
22pub 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                // sign_key_index[. . . . . . x x] type[. .]
131                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        // sign_source_with_ref_index
179        let mut size = u8::raw_bytes().unwrap();
180
181        // signatory: Option<SignatureSource>
182        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        // sign_time: u64
190        size = size + u64::raw_bytes().unwrap();
191
192        // sign_data: Vec<u8>
193        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        // sign_source_with_ref_index
224        let buf = self.sign_source_with_ref_index().raw_encode(buf, purpose)?;
225
226        // signatory: Option<SignatureSource>
227        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        // sign_time
243        let buf = self.sign_time.raw_encode(buf, purpose)?;
244
245        // sign_data: Vec<u8>
246        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        // [. . . . . . ]  [. .]
304        // ref_index     | real_type_code
305        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}