1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use crate::{Error, PrivateKey, PublicKey};
mod rsa_sha256;
mod hs2019;
use openssl::{hash::MessageDigest, sign::{Signer, Verifier}, rsa::Padding};
pub use rsa_sha256::RsaSha256;
pub use hs2019::Hs2019;
pub fn by_name(name: &str) -> Option<Box<dyn Algorithm>> {
match name {
"rsa-sha256" => Some(Box::new(rsa_sha256::RsaSha256)),
"hs2019" => Some(Box::new(hs2019::Hs2019)),
_ => None,
}
}
pub trait Algorithm {
fn name(&self) -> &'static str;
fn generate_keys(&self) -> Result<(PrivateKey, PublicKey), Error>;
fn message_digest(&self) -> Option<MessageDigest>;
fn rsa_padding(&self) -> Option<Padding> {
None
}
fn sign(&self, private_key: &PrivateKey, data: &[u8]) -> Result<Vec<u8>, Error> {
let pkey = &private_key.0;
let mut signer = match self.message_digest() {
Some(message_digest) =>
Signer::new(message_digest, &pkey)?,
None =>
Signer::new_without_digest(&pkey)?,
};
if let Some(padding) = self.rsa_padding() {
signer.set_rsa_padding(padding)?;
}
let mut len = signer.len()?;
let mut buf = vec![0; len];
len = signer.sign_oneshot(&mut buf, data)?;
buf.truncate(len);
Ok(buf)
}
fn verify(&self, public_key: &PublicKey, data: &[u8], signature: &[u8]) -> Result<bool, Error> {
let pkey = &public_key.0;
let mut verifier = match self.message_digest() {
Some(message_digest) =>
Verifier::new(message_digest, &pkey)?,
None =>
Verifier::new_without_digest(&pkey)?,
};
if let Some(padding) = self.rsa_padding() {
verifier.set_rsa_padding(padding)?;
}
Ok(verifier.verify_oneshot(&signature, data)?)
}
}