diff --git a/crates/derive/keyfork-derive-openpgp/src/lib.rs b/crates/derive/keyfork-derive-openpgp/src/lib.rs index 1292ca7..a5e0232 100644 --- a/crates/derive/keyfork-derive-openpgp/src/lib.rs +++ b/crates/derive/keyfork-derive-openpgp/src/lib.rs @@ -1,6 +1,9 @@ //! Creation of OpenPGP certificates from BIP-0032 derived data. -use std::time::{Duration, SystemTime, SystemTimeError}; +use std::{ + str::FromStr, + time::{Duration, SystemTime, SystemTimeError}, +}; use derive_util::{DerivationIndex, ExtendedPrivateKey, IndexError, PrivateKey}; use ed25519_dalek::SigningKey; @@ -68,7 +71,24 @@ pub fn derive(xprv: XPrv, keys: &[KeyFlags], userid: &UserID) -> Result { }; let epoch = SystemTime::UNIX_EPOCH + Duration::from_secs(1); - let one_day = SystemTime::now() + Duration::from_secs(60 * 60 * 24); + let expiration_date = match std::env::var("KEYFORK_OPENPGP_EXPIRE").as_mut() { + Ok(var) => { + let ch = var.pop(); + match (ch, u64::from_str(&var)) { + (Some(ch @ ('d' | 'm' | 'y')), Ok(expire)) => { + let multiplier = match ch { + 'd' => 1, + 'm' => 30, + 'y' => 365, + _ => unreachable!(), + }; + SystemTime::now() + Duration::from_secs(60 * 60 * 24 * expire * multiplier) + } + _ => SystemTime::now() + Duration::from_secs(60 * 60 * 24), + } + } + Err(_) => SystemTime::now() + Duration::from_secs(60 * 60 * 24), + }; // Create certificate with initial key and signature let derived_primary_key = xprv.derive_child(&DerivationIndex::new(0, true)?)?; @@ -80,7 +100,7 @@ pub fn derive(xprv: XPrv, keys: &[KeyFlags], userid: &UserID) -> Result { // Sign and attach primary key and primary userid let builder = SignatureBuilder::new(SignatureType::PositiveCertification) - .set_key_validity_period(one_day.duration_since(epoch)?)? + .set_key_validity_period(expiration_date.duration_since(epoch)?)? .set_signature_creation_time(epoch)? .set_key_flags(primary_key_flags.clone())?; let binding = userid.bind(&mut primary_key.clone().into_keypair()?, &cert, builder)?; @@ -89,7 +109,8 @@ pub fn derive(xprv: XPrv, keys: &[KeyFlags], userid: &UserID) -> Result { // Set certificate expiration to one day let mut keypair = primary_key.clone().into_keypair()?; - let signatures = cert.set_expiration_time(&policy, None, &mut keypair, Some(one_day))?; + let signatures = + cert.set_expiration_time(&policy, None, &mut keypair, Some(expiration_date))?; let cert = cert.insert_packets(signatures)?; let mut cert = cert; @@ -127,7 +148,7 @@ pub fn derive(xprv: XPrv, keys: &[KeyFlags], userid: &UserID) -> Result { SignatureBuilder::new(SignatureType::SubkeyBinding) .set_key_flags(subkey_flags.clone())? .set_signature_creation_time(epoch)? - .set_key_validity_period(one_day.duration_since(epoch)?)? + .set_key_validity_period(expiration_date.duration_since(epoch)?)? .set_embedded_signature( SignatureBuilder::new(SignatureType::PrimaryKeyBinding) .set_signature_creation_time(epoch)? @@ -141,7 +162,7 @@ pub fn derive(xprv: XPrv, keys: &[KeyFlags], userid: &UserID) -> Result { SignatureBuilder::new(SignatureType::SubkeyBinding) .set_key_flags(subkey_flags.clone())? .set_signature_creation_time(epoch)? - .set_key_validity_period(one_day.duration_since(epoch)?)? + .set_key_validity_period(expiration_date.duration_since(epoch)?)? }; // Sign subkey with primary key and attach to cert