Skip to main content

reqtls/boring/rsa/
mod.rs

1use crate::boring::bindings::*;
2use crate::boring::BoringResExt;
3use crate::error::RlsResult;
4use crate::ffi::CPointer;
5use crate::RlsError;
6use bindings::*;
7use std::ptr::null_mut;
8pub use key::RsaKey;
9pub use padding::RsaPadding;
10
11pub mod certificate;
12#[allow(dead_code)]
13pub(crate) mod bindings;
14mod key;
15mod padding;
16
17pub struct RsaCipher {
18    ctx: CPointer<EVP_PKEY_CTX>,
19    padding: RsaPadding,
20}
21
22impl RsaCipher {
23    pub fn new(key: &CPointer<EVP_PKEY>) -> RlsResult<RsaCipher> {
24        let ctx = CPointer::new(unsafe { EVP_PKEY_CTX_new(key.as_mut_ptr(), null_mut()) });
25        if ctx.is_null() { return Err(RlsError::RsaNewError); }
26        Ok(RsaCipher {
27            ctx,
28            padding: RsaPadding::Pkcs1,
29        })
30    }
31    pub fn from_rsa_key(key: &RsaKey) -> RlsResult<RsaCipher> {
32        RsaCipher::new(key.pkey())
33    }
34
35    pub fn encrypt(&self, data: impl AsRef<[u8]>) -> RlsResult<Vec<u8>> {
36        unsafe { EVP_PKEY_encrypt_init(self.ctx.as_mut_ptr()) }.ok(RlsError::InitEncryptError)?;
37        unsafe { EVP_PKEY_CTX_set_rsa_padding(self.ctx.as_mut_ptr(), self.padding.as_i32()) }.ok(RlsError::RsaSetPaddingError)?;
38        let mut out_len = 0;
39        unsafe {
40            EVP_PKEY_encrypt(
41                self.ctx.as_mut_ptr(),
42                null_mut(),
43                &mut out_len,
44                data.as_ref().as_ptr(),
45                data.as_ref().len(),
46            )
47        }.ok(RlsError::PkeyEncryptError)?;
48        let mut out = vec![0u8; out_len];
49        unsafe {
50            EVP_PKEY_encrypt(
51                self.ctx.as_mut_ptr(),
52                out.as_mut_ptr(),
53                &mut out_len,
54                data.as_ref().as_ptr(),
55                data.as_ref().len(),
56            )
57        }.ok(RlsError::PkeyEncryptError)?;
58        Ok(out)
59    }
60
61    pub fn decrypt(&self, data: impl AsRef<[u8]>) -> RlsResult<Vec<u8>> {
62        unsafe { EVP_PKEY_decrypt_init(self.ctx.as_mut_ptr()) }.ok(RlsError::InitDecryptError)?;
63        unsafe { EVP_PKEY_CTX_set_rsa_padding(self.ctx.as_mut_ptr(), self.padding.as_i32()) }.ok(RlsError::RsaSetPaddingError)?;
64        let mut out_len = data.as_ref().len();
65        let mut out = vec![0u8; data.as_ref().len()];
66        unsafe {
67            EVP_PKEY_decrypt(
68                self.ctx.as_mut_ptr(),
69                out.as_mut_ptr(),
70                &mut out_len,
71                data.as_ref().as_ptr(),
72                data.as_ref().len(),
73            )
74        }.ok(RlsError::PkeyDecryptError)?;
75        out.truncate(out_len);
76        Ok(out)
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use crate::{RsaCipher, RsaKey};
83
84    #[test]
85    fn test_rsa() {
86        let key = RsaKey::gen_new_key(2048).unwrap();
87        println!("{}", key.to_pri_pem().unwrap());
88        println!("{}", key.to_pub_pem().unwrap());
89        println!("{:?}", key.to_pri_der());
90        println!("{:?}", key.to_pub_der());
91        let nkey = RsaKey::from_pub_der(key.to_pub_der().as_slice()).unwrap();
92        let rsa = RsaCipher::from_rsa_key(&nkey).unwrap();
93        let encrypted = rsa.encrypt("adsdfds").unwrap();
94        println!("{} {:?}", encrypted.len(), encrypted);
95
96        let nkey = RsaKey::from_pri_der(key.to_pri_der().as_slice()).unwrap();
97        let rsa = RsaCipher::from_rsa_key(&nkey).unwrap();
98        let decrypted = rsa.decrypt(encrypted.as_slice()).unwrap();
99        println!("{} {:?}", decrypted.len(), decrypted);
100    }
101}