bucky_crypto/
public_key.rs

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