cyfs_base/crypto/
public_key.rs

1use crate::*;
2
3use rand::thread_rng;
4use rsa::{PublicKey as RSAPublicKeyTrait, PublicKeyParts};
5use std::convert::From;
6
7// RSA
8const RAW_PUBLIC_KEY_RSA_1024_CODE: u8 = 0_u8;
9const RAW_PUBLIC_KEY_RSA_1024_LENGTH: usize = 162;
10
11const RAW_PUBLIC_KEY_RSA_2048_CODE: u8 = 1_u8;
12const RAW_PUBLIC_KEY_RSA_2048_LENGTH: usize = 294;
13
14const RAW_PUBLIC_KEY_RSA_3072_CODE: u8 = 2_u8;
15const RAW_PUBLIC_KEY_RSA_3072_LENGTH: usize = 422;
16
17// SECP256K1
18const RAW_PUBLIC_KEY_SECP256K1_CODE: u8 = 10_u8;
19
20#[derive(Clone, Debug, PartialEq, Eq)]
21pub enum PublicKey {
22    Rsa(rsa::RSAPublicKey),
23    Secp256k1(::secp256k1::PublicKey),
24    Invalid,
25}
26
27impl Default for PublicKey {
28    fn default() -> Self {
29        PublicKey::Invalid
30    }
31}
32
33impl PublicKey {
34    pub fn key_type_str(&self) -> &str {
35        match self {
36            Self::Rsa(_) => PrivateKeyType::Rsa.as_str(),
37            Self::Secp256k1(_) => PrivateKeyType::Secp256k1.as_str(),
38            Self::Invalid => "invalid",
39        }
40    }
41
42    pub fn key_size(&self) -> usize {
43        match self {
44            Self::Rsa(pk) => pk.size() as usize,
45            Self::Secp256k1(_) => {
46                // 采用压缩格式存储 33个字节
47                ::secp256k1::util::COMPRESSED_PUBLIC_KEY_SIZE
48            }
49            Self::Invalid => panic!("Should not come here"),
50        }
51    }
52
53    pub fn encrypt(&self, data: &[u8], output: &mut [u8]) -> BuckyResult<usize> {
54        let encrypted_buf = self.encrypt_data(data)?;
55        if output.len() < encrypted_buf.len() {
56            let msg = format!(
57                "not enough buffer for public key encrypt buf: {} < {}",
58                output.len(),
59                encrypted_buf.len()
60            );
61            Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg))
62        } else {
63            output[..encrypted_buf.len()].copy_from_slice(encrypted_buf.as_slice());
64            Ok(encrypted_buf.len())
65        }
66    }
67
68    pub fn encrypt_data(&self, data: &[u8]) -> BuckyResult<Vec<u8>> {
69        match self {
70            Self::Rsa(public_key) => {
71                let mut rng = thread_rng();
72                let encrypted_buf =
73                    match public_key.encrypt(&mut rng, rsa::PaddingScheme::PKCS1v15Encrypt, data) {
74                        Ok(v) => v,
75                        Err(e) => match e {
76                            rsa::errors::Error::MessageTooLong => {
77                                let msg = format!(
78                                    "encrypt data is too long! data len={}, max len={}",
79                                    data.len(),
80                                    public_key.size() - 11
81                                );
82                                error!("{}", msg);
83                                return Err(BuckyError::new(BuckyErrorCode::InvalidData, msg));
84                            }
85                            _ => return Err(BuckyError::from(e)),
86                        },
87                    };
88
89                Ok(encrypted_buf)
90            }
91            Self::Secp256k1(_) => {
92                // 目前secp256k1的非对称加解密只支持交换aes_key时候使用
93                let msg = format!("direct encyrpt with private key of secp256 not support!");
94                error!("{}", msg);
95                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
96            }
97            PublicKey::Invalid => panic!("Should not come here"),
98        }
99    }
100
101    pub fn gen_aeskey_and_encrypt(&self) -> BuckyResult<(AesKey, Vec<u8>)> {
102        match self {
103            Self::Rsa(pk) => {
104                // 先产生一个临时的aes_key
105                let key = AesKey::random();
106
107                // 使用publicKey对aes_key加密
108                let mut output = Vec::with_capacity(pk.size());
109                unsafe {
110                    output.set_len(pk.size());
111                };
112                self.encrypt(key.as_slice(), &mut output)?;
113
114                Ok((key, output))
115            }
116            Self::Secp256k1(public_key) => {
117                let (ephemeral_sk, ephemeral_pk) = cyfs_ecies::utils::generate_keypair();
118
119                let aes_key = cyfs_ecies::utils::encapsulate(&ephemeral_sk, &public_key);
120                let pk_buf = ephemeral_pk.serialize_compressed();
121
122                let key = AesKey::from(&aes_key);
123                Ok((key, pk_buf.to_vec()))
124            }
125            Self::Invalid => panic!("Should not come here"),
126        }
127    }
128
129    pub fn verify(&self, data: &[u8], sign: &Signature) -> bool {
130        let create_time = sign.sign_time();
131        let mut data_new = data.to_vec();
132        data_new.resize(data.len() + create_time.raw_measure(&None).unwrap(), 0);
133        create_time
134            .raw_encode(&mut data_new.as_mut_slice()[data.len()..], &None)
135            .unwrap();
136
137        match self {
138            Self::Rsa(public_key) => {
139                let hash = hash_data(&data_new);
140                public_key
141                    .verify(
142                        rsa::PaddingScheme::new_pkcs1v15_sign(Some(rsa::Hash::SHA2_256)),
143                        hash.as_slice(),
144                        sign.as_slice(),
145                    )
146                    .is_ok()
147            }
148            Self::Secp256k1(public_key) => {
149                // 生成消息摘要
150                let hash = hash_data(&data_new);
151                assert_eq!(HashValue::len(), ::secp256k1::util::MESSAGE_SIZE);
152                let ctx = ::secp256k1::Message::parse(hash.as_slice().try_into().unwrap());
153
154                // 解析签名段
155                let sign = match ::secp256k1::Signature::parse_slice(sign.as_slice()) {
156                    Ok(sign) => sign,
157                    Err(e) => {
158                        error!("parse secp256k1 signature error: {}", e);
159                        return false;
160                    }
161                };
162
163                // 使用公钥进行校验
164                secp256k1::verify(&ctx, &sign, &public_key)
165            }
166            Self::Invalid => panic!("Should not come here"),
167        }
168    }
169}
170
171impl RawFixedBytes for PublicKey {
172    fn raw_min_bytes() -> Option<usize> {
173        Some(1 + RAW_PUBLIC_KEY_RSA_1024_LENGTH)
174    }
175
176    fn raw_max_bytes() -> Option<usize> {
177        Some(1 + RAW_PUBLIC_KEY_RSA_3072_LENGTH)
178    }
179}
180
181impl RawEncode for PublicKey {
182    fn raw_measure(&self, _purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
183        match self {
184            Self::Rsa(ref pk) => {
185                match pk.size() {
186                    // 1024 bits, 128 bytes
187                    RSA_KEY_BYTES => Ok(RAW_PUBLIC_KEY_RSA_1024_LENGTH + 1),
188                    RSA2048_KEY_BYTES => Ok(RAW_PUBLIC_KEY_RSA_2048_LENGTH + 1),
189                    RSA3072_KEY_BYTES => Ok(RAW_PUBLIC_KEY_RSA_3072_LENGTH + 1),
190                    len @ _ => {
191                        let msg = format!("invalid rsa public key length! {}", len);
192                        error!("{}", msg);
193                        Err(BuckyError::new(BuckyErrorCode::InvalidParam, msg))
194                    }
195                }
196            }
197            Self::Secp256k1(_) => Ok(::secp256k1::util::COMPRESSED_PUBLIC_KEY_SIZE + 1),
198            Self::Invalid => {
199                let msg = format!("invalid publicKey!");
200                error!("{}", msg);
201
202                Err(BuckyError::new(BuckyErrorCode::InvalidFormat, msg))
203            }
204        }
205    }
206
207    fn raw_encode<'a>(
208        &self,
209        buf: &'a mut [u8],
210        _purpose: &Option<RawEncodePurpose>,
211    ) -> Result<&'a mut [u8], BuckyError> {
212        match self {
213            Self::Rsa(ref pk) => {
214                let (code, len) = {
215                    match pk.size() {
216                        RSA_KEY_BYTES => Ok((
217                            RAW_PUBLIC_KEY_RSA_1024_CODE,
218                            RAW_PUBLIC_KEY_RSA_1024_LENGTH + 1,
219                        )),
220                        RSA2048_KEY_BYTES => Ok((
221                            RAW_PUBLIC_KEY_RSA_2048_CODE,
222                            RAW_PUBLIC_KEY_RSA_2048_LENGTH + 1,
223                        )),
224                        RSA3072_KEY_BYTES => Ok((
225                            RAW_PUBLIC_KEY_RSA_3072_CODE,
226                            RAW_PUBLIC_KEY_RSA_3072_LENGTH + 1,
227                        )),
228                        len @ _ => {
229                            let msg = format!("invalid rsa public key length! {}", len);
230                            error!("{}", msg);
231                            Err(BuckyError::new(BuckyErrorCode::InvalidParam, msg))
232                        }
233                    }
234                }?;
235                if buf.len() < len {
236                    let msg = format!(
237                        "not enough buffer for encode privateKey, except={}, got={}",
238                        len,
239                        buf.len()
240                    );
241                    error!("{}", msg);
242
243                    return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
244                }
245
246                let spki_der = rsa_export::pkcs1::public_key(pk)?;
247                assert!(spki_der.len() <= len - 1);
248                buf[0] = code;
249                buf[1..spki_der.len() + 1].copy_from_slice(&spki_der.as_slice());
250                buf[spki_der.len() + 1..]
251                    .iter_mut()
252                    .for_each(|padding| *padding = 0);
253
254                Ok(&mut buf[len..])
255            }
256            Self::Secp256k1(public_key) => {
257                buf[0] = RAW_PUBLIC_KEY_SECP256K1_CODE;
258                let key_buf = public_key.serialize_compressed();
259                let total_len = ::secp256k1::util::COMPRESSED_PUBLIC_KEY_SIZE + 1;
260                buf[1..total_len].copy_from_slice(&key_buf);
261
262                Ok(&mut buf[total_len..])
263            }
264            Self::Invalid => panic!("should not reach here"),
265        }
266    }
267}
268
269impl<'de> RawDecode<'de> for PublicKey {
270    fn raw_decode(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
271        if buf.len() < 1 {
272            let msg = format!(
273                "not enough buffer for decode PublicKey, min bytes={}, got={}",
274                1,
275                buf.len()
276            );
277            error!("{}", msg);
278
279            return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
280        }
281        let code = buf[0];
282        match code {
283            RAW_PUBLIC_KEY_RSA_1024_CODE
284            | RAW_PUBLIC_KEY_RSA_2048_CODE
285            | RAW_PUBLIC_KEY_RSA_3072_CODE => {
286                let len = {
287                    match code {
288                        RAW_PUBLIC_KEY_RSA_1024_CODE => RAW_PUBLIC_KEY_RSA_1024_LENGTH + 1,
289                        RAW_PUBLIC_KEY_RSA_2048_CODE => RAW_PUBLIC_KEY_RSA_2048_LENGTH + 1,
290                        RAW_PUBLIC_KEY_RSA_3072_CODE => RAW_PUBLIC_KEY_RSA_3072_LENGTH + 1,
291                        _ => unreachable!(),
292                    }
293                };
294                if buf.len() < len {
295                    let msg = format!(
296                        "not enough buffer for decode rsa PublicKey, except={}, got={}",
297                        len,
298                        buf.len()
299                    );
300                    error!("{}", msg);
301
302                    return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
303                }
304                let pk = rsa::RSAPublicKey::from_pkcs1(&buf[1..len])?;
305                Ok((PublicKey::Rsa(pk), &buf[len..]))
306            }
307            RAW_PUBLIC_KEY_SECP256K1_CODE => {
308                let len = ::secp256k1::util::COMPRESSED_PUBLIC_KEY_SIZE + 1;
309                if buf.len() < len {
310                    let msg = format!(
311                        "not enough buffer for decode secp256k1 PublicKey, except={}, got={}",
312                        len,
313                        buf.len()
314                    );
315                    error!("{}", msg);
316
317                    return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
318                }
319
320                match ::secp256k1::PublicKey::parse_compressed((&buf[1..len]).try_into().unwrap()) {
321                    Ok(public_key) => Ok((PublicKey::Secp256k1(public_key), &buf[len..])),
322                    Err(e) => {
323                        let msg = format!("parse secp256k1 public key error: {}", e);
324                        error!("{}", msg);
325
326                        Err(BuckyError::new(BuckyErrorCode::InvalidFormat, msg))
327                    }
328                }
329            }
330            v @ _ => Err(BuckyError::new(
331                BuckyErrorCode::InvalidData,
332                &format!("invalid public key type code {}", v),
333            )),
334        }
335    }
336}
337
338// threshold, public_key list
339pub type MNPublicKey = (u8, Vec<PublicKey>);
340
341#[derive(Clone, Eq, PartialEq, Debug)]
342pub enum PublicKeyValue {
343    Single(PublicKey),
344    MN(MNPublicKey),
345}
346
347pub enum PublicKeyRef<'a> {
348    Single(&'a PublicKey),
349    MN(&'a MNPublicKey),
350}
351
352impl PublicKeyValue {
353    pub fn as_ref(&self) -> PublicKeyRef {
354        match self {
355            Self::Single(v) => PublicKeyRef::Single(v),
356            Self::MN(v) => PublicKeyRef::MN(v),
357        }
358    }
359}
360
361impl<'a> From<&'a PublicKey> for PublicKeyRef<'a> {
362    fn from(key: &'a PublicKey) -> Self {
363        PublicKeyRef::Single(key)
364    }
365}
366
367impl<'a> From<&'a MNPublicKey> for PublicKeyRef<'a> {
368    fn from(key: &'a MNPublicKey) -> Self {
369        PublicKeyRef::MN(key)
370    }
371}
372
373impl RawEncode for PublicKeyValue {
374    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
375        match self {
376            PublicKeyValue::Single(key) => Ok(u8::raw_bytes().unwrap() + key.raw_measure(purpose)?),
377            PublicKeyValue::MN(key) => Ok(u8::raw_bytes().unwrap() + key.raw_measure(purpose)?),
378        }
379    }
380
381    fn raw_encode<'a>(
382        &self,
383        buf: &'a mut [u8],
384        purpose: &Option<RawEncodePurpose>,
385    ) -> Result<&'a mut [u8], BuckyError> {
386        let size = self.raw_measure(purpose).unwrap();
387        if buf.len() < size {
388            return Err(BuckyError::new(
389                BuckyErrorCode::OutOfLimit,
390                "[raw_encode] not enough buffer for publick_key_value",
391            ));
392        }
393
394        match self {
395            PublicKeyValue::Single(key) => {
396                let buf = 0u8.raw_encode(buf, purpose)?;
397                let buf = key.raw_encode(buf, purpose)?;
398                Ok(buf)
399            }
400            PublicKeyValue::MN(key) => {
401                let buf = 1u8.raw_encode(buf, purpose)?;
402                let buf = key.raw_encode(buf, purpose)?;
403                Ok(buf)
404            }
405        }
406    }
407}
408
409impl<'de> RawDecode<'de> for PublicKeyValue {
410    fn raw_decode(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
411        let (key_type, buf) = u8::raw_decode(buf)?;
412
413        match key_type {
414            0u8 => {
415                let (key, buf) = PublicKey::raw_decode(buf)?;
416                Ok((PublicKeyValue::Single(key), buf))
417            }
418            1u8 => {
419                let (key, buf) = MNPublicKey::raw_decode(buf)?;
420                Ok((PublicKeyValue::MN(key), buf))
421            }
422            _ => Err(BuckyError::new(
423                BuckyErrorCode::InvalidData,
424                "public key type invalid",
425            )),
426        }
427    }
428}
429
430impl<'r> RawEncode for PublicKeyRef<'r> {
431    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
432        match self {
433            PublicKeyRef::Single(key) => Ok(u8::raw_bytes().unwrap() + key.raw_measure(purpose)?),
434            PublicKeyRef::MN(key) => Ok(u8::raw_bytes().unwrap() + key.raw_measure(purpose)?),
435        }
436    }
437
438    fn raw_encode<'a>(
439        &self,
440        buf: &'a mut [u8],
441        purpose: &Option<RawEncodePurpose>,
442    ) -> Result<&'a mut [u8], BuckyError> {
443        let size = self.raw_measure(purpose).unwrap();
444        if buf.len() < size {
445            return Err(BuckyError::new(
446                BuckyErrorCode::OutOfLimit,
447                "[raw_encode] not enough buffer for public_key",
448            ));
449        }
450
451        match *self {
452            PublicKeyRef::Single(key) => {
453                let buf = 0u8.raw_encode(buf, purpose)?;
454                let buf = key.raw_encode(buf, purpose)?;
455                Ok(buf)
456            }
457            PublicKeyRef::MN(key) => {
458                let buf = 1u8.raw_encode(buf, purpose)?;
459                let buf = key.raw_encode(buf, purpose)?;
460                Ok(buf)
461            }
462        }
463    }
464}
465
466#[cfg(test)]
467mod test {
468    use crate::{PrivateKey, PublicKey, RawConvertTo, RawDecode};
469
470    #[test]
471    fn public_key() {
472        let sk1 = PrivateKey::generate_rsa(1024).unwrap();
473        let pk1_buf = sk1.public().to_vec().unwrap();
474        println!("encrypt max len: {}", sk1.public().key_size() - 11);
475        let (pk2, buf) = PublicKey::raw_decode(&pk1_buf).unwrap();
476        assert!(buf.len() == 0);
477        assert_eq!(sk1.public(), pk2);
478
479        let sk1 = PrivateKey::generate_rsa(2048).unwrap();
480        let pk1_buf = sk1.public().to_vec().unwrap();
481        println!("encrypt max len: {}", sk1.public().key_size() - 11);
482        let (pk2, buf) = PublicKey::raw_decode(&pk1_buf).unwrap();
483        assert!(buf.len() == 0);
484        assert_eq!(sk1.public(), pk2);
485
486        let sk1 = PrivateKey::generate_secp256k1().unwrap();
487        let pk1_buf = sk1.to_vec().unwrap();
488        let (pk2, buf) = PrivateKey::raw_decode(&pk1_buf).unwrap();
489        assert!(buf.len() == 0);
490        assert_eq!(sk1, pk2);
491
492        let pk1_buf = sk1.public().to_vec().unwrap();
493        let (pk2, buf) = PublicKey::raw_decode(&pk1_buf).unwrap();
494        assert!(buf.len() == 0);
495
496        assert_eq!(sk1.public(), pk2);
497    }
498}