-
Notifications
You must be signed in to change notification settings - Fork 32
Support Public Key Algorithms in Crypto Module #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 12 commits
e5c3709
1d8995b
4d02ec5
5aa7a1e
d67eda2
179485e
c3a0bb8
07683d6
160ce72
d0e8a90
650af49
7fe85cb
19bf4fc
cf2a17c
eff4678
0652e73
7350017
18f7b5a
5988cb2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,29 @@ | ||
| //! This is the OpenSSL adaptor. | ||
|
|
||
| use crate::{ | ||
| errors::RvError, | ||
| modules::crypto::{ | ||
| AEADCipher, AESKeySize, BlockCipher, | ||
| CipherMode, AES, | ||
| RSA, RSAKeySize, | ||
| PublicKey, PublicKeyType, | ||
| Signature, Encryption, | ||
| ECDSA, ECCurveName, | ||
| crypto_adaptors::common, | ||
| }, | ||
| }; | ||
|
|
||
| use openssl::{ | ||
| rand::rand_priv_bytes, | ||
| symm::{decrypt, decrypt_aead, encrypt, encrypt_aead, Cipher, Crypter, Mode}, | ||
| rsa::{Rsa, Padding}, | ||
| pkey::{PKey, Private}, | ||
| pkey_ctx::PkeyCtx, | ||
| nid::Nid, | ||
| ec::{EcGroup, EcKey}, | ||
| }; | ||
|
|
||
| use crate::{ | ||
| errors::RvError, | ||
| modules::crypto::{crypto_adaptors::common, AEADCipher, AESKeySize, BlockCipher, CipherMode, AES}, | ||
| }; | ||
| use zeroize::{Zeroize, Zeroizing}; | ||
|
|
||
| pub struct AdaptorCTX { | ||
| ctx: Crypter, | ||
|
|
@@ -81,3 +96,248 @@ impl AEADCipher for AES { | |
| common_aes_set_tag!(self, tag); | ||
| } | ||
| } | ||
|
|
||
| pub struct AdaptorPKeyCTX { | ||
| // The private key in OpenSSL context contains also the public key | ||
| private_key: PKey<Private>, | ||
| } | ||
|
|
||
| // Simply do nothing since OpenSSL will safely clean the memory of a PKEY object (Drop trait) | ||
| impl Zeroize for AdaptorPKeyCTX { | ||
| fn zeroize(&mut self) {} | ||
| } | ||
|
|
||
| impl RSA { | ||
| /// This function is the constructor of the RSA struct, it returns a new RSA object on success. | ||
| /// | ||
| /// size: RSA key size. Valid options are RSA2048 (default), RSA3072, RSA4096, RSA8192. | ||
| /// prime: for multi-prime RSA usage (RFC 8017), default is 2. | ||
| pub fn new( | ||
| prime: Option<u8>, | ||
| size: Option<RSAKeySize>, | ||
| ) -> Result<Self, RvError> { | ||
| return Ok( | ||
|
||
| RSA { | ||
| key_type: PublicKeyType::RSA, | ||
| prime: prime.unwrap_or(2), | ||
| size: size.unwrap_or(RSAKeySize::RSA2048), | ||
| ctx: None, | ||
| } | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| impl PublicKey for RSA { | ||
| fn keygen(&mut self) -> Result<(), RvError> { | ||
| let bits: u32; | ||
| match &self.size { | ||
| RSAKeySize::RSA2048 => bits = 2048, | ||
| RSAKeySize::RSA3072 => bits = 3072, | ||
| RSAKeySize::RSA4096 => bits = 4096, | ||
| RSAKeySize::RSA8192 => bits = 8192, | ||
| } | ||
|
|
||
| let rsa = match Rsa::generate(bits) { | ||
| Ok(r) => r, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyRSAKeyGenFailed), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let rsa = Rsa::generate(bits).map_err(|_| RvError::ErrCryptoPKeyRSAKeyGenFailed)?; |
||
|
|
||
| let pkey = match PKey::from_rsa(rsa) { | ||
| Ok(r) => r, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyRSAKeyGenFailed), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let pkey = PKey::from_rsa(rsa).map_err(|_| RvError::ErrCryptoPKeyRSAKeyGenFailed)?; |
||
|
|
||
| let adaptor_ctx = AdaptorPKeyCTX { private_key: pkey }; | ||
| self.ctx = Some(adaptor_ctx); | ||
|
|
||
| return Ok(()); | ||
| } | ||
|
|
||
| fn get_key_type(&self) -> Result<&PublicKeyType, RvError> { | ||
| return Ok(&self.key_type); | ||
| } | ||
| } | ||
|
|
||
| impl Signature for RSA { | ||
| fn sign(&self, data: &Vec<u8>) -> Result<Vec<u8>, RvError> { | ||
| let key = &self.ctx.as_ref().unwrap().private_key; | ||
|
|
||
| let mut ctx = match PkeyCtx::new(&key) { | ||
| Ok(ctx) => ctx, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let mut ctx = PkeyCtx::new(&key).map_err(|_| RvError::ErrCryptoPKeyInternalError)?; |
||
|
|
||
| match ctx.sign_init() { | ||
| Ok(_ret) => {}, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeySignInitFailed), | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let _ = ctx.sign_init().map_err(|_| RvError::ErrCryptoPKeySignInitFailed)?; |
||
|
|
||
| let mut signature: Vec<u8> = Vec::new(); | ||
| match ctx.sign_to_vec(data, &mut signature) { | ||
| Ok(_ret) => {}, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeySignFailed), | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ctx.sign_to_vec(data, &mut signature).map_err(|_| RvError::ErrCryptoPKeySignFailed)?; |
||
|
|
||
| return Ok(signature); | ||
| } | ||
|
|
||
| fn verify(&self, data: &Vec<u8>, sig: &Vec<u8>) -> Result<bool, RvError> { | ||
| let key = &self.ctx.as_ref().unwrap().private_key; | ||
|
|
||
| let mut ctx = match PkeyCtx::new(&key) { | ||
| Ok(ctx) => ctx, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| match ctx.verify_init() { | ||
| Ok(_ret) => {}, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyInitFailed), | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| let valid = match ctx.verify(data, sig) { | ||
| Ok(ret) => ret, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyFailed), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| return Ok(valid); | ||
| } | ||
| } | ||
|
|
||
| impl Encryption for RSA { | ||
| fn encrypt(&self, plaintext: &Vec<u8>) -> Result<Vec<u8>, RvError> { | ||
| let key = &self.ctx.as_ref().unwrap().private_key; | ||
|
|
||
| let mut ctx = match PkeyCtx::new(&key) { | ||
| Ok(ctx) => ctx, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| match ctx.encrypt_init() { | ||
| Ok(_ret) => {}, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyEncInitFailed), | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| let mut ciphertext: Vec<u8> = Vec::new(); | ||
| match ctx.encrypt_to_vec(plaintext, &mut ciphertext) { | ||
| Ok(_ret) => {}, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyEncFailed), | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| return Ok(ciphertext); | ||
| } | ||
|
|
||
| fn decrypt(&self, ciphertext: &Vec<u8>) -> Result<Vec<u8>, RvError> { | ||
| let key = &self.ctx.as_ref().unwrap().private_key; | ||
|
|
||
| let mut ctx = match PkeyCtx::new(&key) { | ||
| Ok(ctx) => ctx, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| match ctx.decrypt_init() { | ||
| Ok(_ret) => {}, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyDecInitFailed), | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
| } | ||
|
|
||
| let mut plaintext: Vec<u8> = Vec::new(); | ||
| match ctx.decrypt_to_vec(ciphertext, &mut plaintext) { | ||
| Ok(_ret) => {}, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyDecFailed), | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| return Ok(plaintext); | ||
| } | ||
| } | ||
|
|
||
| impl ECDSA { | ||
| /// This function is the constructor of the ECDSA struct, it returns a new ECDSA object | ||
| /// on success. | ||
| /// | ||
| /// curve: RSA key size. Valid options are RSA2048 (default), RSA3072, RSA4096, RSA8192. | ||
| /// prime: for multi-prime RSA usage (RFC 8017), default is 2. | ||
| pub fn new( | ||
| curve: Option<ECCurveName>, | ||
| ) -> Result<Self, RvError> { | ||
| return Ok( | ||
|
||
| ECDSA { | ||
| key_type: PublicKeyType::ECDSA, | ||
| curve: curve.unwrap_or(ECCurveName::Prime256v1), | ||
| ctx: None, | ||
| } | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| impl PublicKey for ECDSA { | ||
| fn keygen(&mut self) -> Result<(), RvError> { | ||
| let nid: Nid; | ||
| match &self.curve { | ||
| ECCurveName::Prime256v1 => nid = Nid::X9_62_PRIME256V1, | ||
| } | ||
|
|
||
| let group = EcGroup::from_curve_name(nid)?; | ||
| let ec = match EcKey::generate(&group) { | ||
| Ok(r) => r, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyECKeyGenFailed), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| let pkey = match PKey::from_ec_key(ec) { | ||
| Ok(r) => r, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyECKeyGenFailed), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| let adaptor_ctx = AdaptorPKeyCTX { private_key: pkey }; | ||
| self.ctx = Some(adaptor_ctx); | ||
|
|
||
| return Ok(()); | ||
| } | ||
|
|
||
| fn get_key_type(&self) -> Result<&PublicKeyType, RvError> { | ||
| return Ok(&self.key_type); | ||
| } | ||
| } | ||
|
|
||
| impl Signature for ECDSA { | ||
| fn sign(&self, data: &Vec<u8>) -> Result<Vec<u8>, RvError> { | ||
| let key = &self.ctx.as_ref().unwrap().private_key; | ||
|
|
||
| let mut ctx = match PkeyCtx::new(&key) { | ||
| Ok(ctx) => ctx, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| match ctx.sign_init() { | ||
| Ok(_ret) => {}, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeySignInitFailed), | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| let mut signature: Vec<u8> = Vec::new(); | ||
| match ctx.sign_to_vec(data, &mut signature) { | ||
| Ok(_ret) => {}, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeySignFailed), | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| return Ok(signature); | ||
| } | ||
|
|
||
| fn verify(&self, data: &Vec<u8>, sig: &Vec<u8>) -> Result<bool, RvError> { | ||
| let key = &self.ctx.as_ref().unwrap().private_key; | ||
|
|
||
| let mut ctx = match PkeyCtx::new(&key) { | ||
| Ok(ctx) => ctx, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| match ctx.verify_init() { | ||
| Ok(_ret) => {}, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyInitFailed), | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| let valid = match ctx.verify(data, sig) { | ||
| Ok(ret) => ret, | ||
| Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyFailed), | ||
| }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
|
|
||
| return Ok(valid); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.