openssl: impl serde

This commit is contained in:
Aode (lion) 2021-11-18 16:08:30 -06:00
parent bad92a5832
commit 4d6a94d67f
2 changed files with 64 additions and 0 deletions

View file

@ -8,3 +8,7 @@ edition = "2021"
[dependencies]
apub-core = { version = "0.1.0", path = "../apub-core/" }
openssl = "0.10.36"
serde = { version = "1", features = ["derive"] }
[dev-dependencies]
serde_json = "1"

View file

@ -16,8 +16,10 @@ pub struct OpenSslSigner {
private_key: PKey<Private>,
}
#[derive(Clone, serde::Deserialize, serde::Serialize)]
pub struct OpenSsl {
key_id: String,
#[serde(with = "openssl_private_key")]
private_key: PKey<Private>,
}
@ -101,3 +103,61 @@ impl Debug for OpenSsl {
.finish()
}
}
mod openssl_private_key {
use openssl::pkey::{PKey, Private};
use serde::{
de::{Deserialize, Deserializer},
ser::{Serialize, Serializer},
};
pub(super) fn serialize<S: Serializer>(
private_key: &PKey<Private>,
serializer: S,
) -> Result<S::Ok, S::Error> {
use serde::ser::Error;
let der = private_key.private_key_to_der().map_err(S::Error::custom)?;
let der_string = openssl::base64::encode_block(&der);
String::serialize(&der_string, serializer)
}
pub(super) fn deserialize<'de, D: Deserializer<'de>>(
deserializer: D,
) -> Result<PKey<Private>, D::Error> {
use serde::de::Error;
let der_string = String::deserialize(deserializer)?;
let der = openssl::base64::decode_block(&der_string).map_err(D::Error::custom)?;
PKey::<Private>::private_key_from_der(&der).map_err(D::Error::custom)
}
}
#[cfg(test)]
pub mod tests {
use super::OpenSsl;
use apub_core::signature::{Sign, SignFactory};
use openssl::{pkey::PKey, rsa::Rsa};
#[test]
fn round_trip() {
let private_key = PKey::from_rsa(Rsa::generate(1024).unwrap()).unwrap();
let crypto = OpenSsl::new("key-id".into(), private_key);
let signer = crypto.signer();
let first_sign = signer.sign("hello").unwrap();
let s = serde_json::to_string(&crypto).unwrap();
let crypto2: OpenSsl = serde_json::from_str(&s).unwrap();
let signer2 = crypto2.signer();
let second_sign = signer2.sign("hello").unwrap();
let s2 = serde_json::to_string(&crypto2).unwrap();
assert_eq!(s, s2);
assert_eq!(first_sign, second_sign);
}
}