trz_gateway_common/x509/
key.rs1use nameth::NamedEnumValues as _;
2use nameth::nameth;
3use openssl::ec::EcGroup;
4use openssl::ec::EcKey;
5use openssl::error::ErrorStack;
6use openssl::nid::Nid;
7use openssl::pkey::PKey;
8use openssl::pkey::Private;
9
10pub fn make_key() -> Result<PKey<Private>, MakeKeyError> {
12 let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).map_err(MakeKeyError::GetCurve)?;
13 let ec_key = EcKey::generate(&group).map_err(MakeKeyError::Generate)?;
14 let key = PKey::from_ec_key(ec_key).map_err(MakeKeyError::ToKey)?;
15 Ok(key)
16}
17
18#[nameth]
19#[derive(thiserror::Error, Debug)]
20pub enum MakeKeyError {
21 #[error("[{n}] Failed to get the elliptic curve: {0}", n = self.name())]
22 GetCurve(ErrorStack),
23
24 #[error("[{n}] Failed to generate an elliptic curve key: {0}", n = self.name())]
25 Generate(ErrorStack),
26
27 #[error("[{n}] Failed to convert the elliptic curve key: {0}", n = self.name())]
28 ToKey(ErrorStack),
29}
30
31#[cfg(test)]
32mod tests {
33 use std::error::Error;
34
35 use openssl::pkey::PKey;
36
37 use crate::x509::PemString as _;
38
39 #[test]
40 fn make_key() -> Result<(), Box<dyn Error>> {
41 Ok({
42 let private_key = super::make_key()?;
43 let public_key = private_key.public_key_to_pem()?;
44 let public_key = public_key.pem_string()?;
45 let _debug = scopeguard::guard_on_unwind((), |_| {
46 println!("Public key is\n{public_key}");
47 });
48 assert!(public_key.starts_with("-----BEGIN PUBLIC KEY-----"));
49 let public_key = PKey::public_key_from_pem(public_key.as_bytes())?;
50 assert_eq!(
51 (256, 128, 72),
52 (
53 public_key.bits(),
54 public_key.security_bits(),
55 public_key.size()
56 )
57 );
58 assert!(public_key.public_eq(&private_key));
59 })
60 }
61}