Skip to content

Commit

Permalink
refactor: 🏷️ Add KeyPair type for better organizing keys.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jisu-Woniu committed Nov 12, 2023
1 parent 97c24d9 commit 733f975
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 19 deletions.
22 changes: 22 additions & 0 deletions src-tauri/crypto/src/key_pair.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use pgp::{SignedPublicKey, SignedSecretKey};

pub(crate) struct KeyPair {
secret_key: SignedSecretKey,
public_key: SignedPublicKey,
}

impl KeyPair {
pub(crate) fn from_keys(secret_key: SignedSecretKey, public_key: SignedPublicKey) -> Self {
Self {
secret_key,
public_key,
}
}
pub(crate) fn secret_key(&self) -> &SignedSecretKey {
&self.secret_key
}

pub(crate) fn public_key(&self) -> &SignedPublicKey {
&self.public_key
}
}
21 changes: 12 additions & 9 deletions src-tauri/crypto/src/keygen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::path::Path;
use pgp::{
crypto::{hash::HashAlgorithm, sym::SymmetricKeyAlgorithm},
types::{CompressionAlgorithm, KeyTrait, SecretKeyTrait as _},
KeyType, SecretKeyParamsBuilder, SignedPublicKey, SignedSecretKey,
KeyType, SecretKeyParamsBuilder,
};
use smallvec::smallvec;
use tokio::{
Expand All @@ -12,15 +12,17 @@ use tokio::{
};
use zeroize::Zeroizing;

use crate::{error::Result, secret_file::write_secret_file};
use crate::{error::Result, key_pair::KeyPair, secret_file::write_secret_file};

pub async fn write_key_pair(name: &str, email: &str, path: impl AsRef<Path>) -> Result<()> {
let path = path.as_ref();

// Create output directory if not exist.
DirBuilder::new().recursive(true).create(path).await?;

let (signed_secret_key, signed_public_key) = gen_key_pair(name, email)?;
let key_pair = gen_key_pair(name, email)?;
let signed_secret_key = key_pair.secret_key();
let signed_public_key = key_pair.public_key();
let keyid = &hex::encode_upper(&signed_secret_key.key_id().as_ref()[4..]);

let secret_key = path.join(format!("{}_0x{}_SECRET.asc", name, keyid));
Expand All @@ -37,7 +39,7 @@ pub async fn write_key_pair(name: &str, email: &str, path: impl AsRef<Path>) ->
Ok(())
}

pub(crate) fn gen_key_pair(name: &str, email: &str) -> Result<(SignedSecretKey, SignedPublicKey)> {
pub(crate) fn gen_key_pair(name: &str, email: &str) -> Result<KeyPair> {
let secret_key = SecretKeyParamsBuilder::default()
// Set keygen params.
.key_type(KeyType::EdDSA)
Expand Down Expand Up @@ -70,20 +72,20 @@ pub(crate) fn gen_key_pair(name: &str, email: &str) -> Result<(SignedSecretKey,
let public_key = signed_secret_key.public_key();
let signed_public_key = public_key.sign(&signed_secret_key, passwd_fn)?;

Ok((signed_secret_key, signed_public_key))
Ok(KeyPair::from_keys(signed_secret_key, signed_public_key))
}

#[cfg(test)]
mod tests {
use pgp::{types::KeyTrait, Deserializable, SignedSecretKey};
use tokio::fs::read_to_string;

use super::{gen_key_pair, Result};

#[tokio::test]
#[ignore = "Manual testing for file generation."]
async fn test() -> Result<()> {
let (secret_key, public_key) = gen_key_pair("极速蜗牛", "[email protected]")?;
let key_pair = gen_key_pair("DS", "[email protected]")?;
let (secret_key, public_key) = (key_pair.secret_key(), key_pair.public_key());
println!("{}", secret_key.to_armored_string(None)?);
println!("{}", public_key.to_armored_string(None)?);
dbg!(public_key);
Expand All @@ -93,8 +95,9 @@ mod tests {
#[tokio::test]
#[ignore = "Manual testing for file parsing."]
async fn extract_key_info() -> Result<()> {
let secret_key_str =
read_to_string("/home/jswn/GpgPlayground/极速蜗牛_0x21B55C62_SECRET.asc").await?;
let secret_key_str = gen_key_pair("DS", "[email protected]")?
.secret_key()
.to_armored_string(None)?;

let secret_key = SignedSecretKey::from_string(&secret_key_str)?.0;
dbg!(&secret_key);
Expand Down
1 change: 1 addition & 0 deletions src-tauri/crypto/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod error;
mod key_pair;
pub mod keygen;
mod secret_file;
pub mod signing;
3 changes: 1 addition & 2 deletions src-tauri/crypto/src/secret_file.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// use crate::error::Result;
use std::io::Result;
use std::path::Path;
use std::{io::Result, path::Path};

#[cfg(unix)]
pub(crate) async fn write_secret_file(path: impl AsRef<Path>, data: &[u8]) -> Result<()> {
Expand Down
14 changes: 6 additions & 8 deletions src-tauri/crypto/src/signing.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use chrono::Utc;
use pgp::{
packet::{
SignatureConfigBuilder, SignatureType, Subpacket,
SubpacketData::{self},
},
packet::{SignatureConfigBuilder, SignatureType, Subpacket, SubpacketData},
types::{PublicKeyTrait, SecretKeyTrait},
Signature,
};
Expand Down Expand Up @@ -32,21 +29,22 @@ pub fn verify(data: &[u8], public_key: &impl PublicKeyTrait, signature: &Signatu

#[cfg(test)]
mod tests {
use crate::keygen::gen_key_pair;

use super::{sign, verify, Result};
use crate::keygen::gen_key_pair;

#[test]
fn test_sign() -> Result<()> {
let (secret_key, public_key) = gen_key_pair("DS", "[email protected]")?;
let key_pair = gen_key_pair("DS", "[email protected]")?;
let (secret_key, public_key) = (key_pair.secret_key(), key_pair.public_key());
let signature = sign(b"Hello", &secret_key)?;
verify(b"Hello", &public_key, &signature)?;
Ok(())
}

#[test]
fn test_sign_error() -> Result<()> {
let (secret_key, public_key) = gen_key_pair("DS", "[email protected]")?;
let key_pair = gen_key_pair("DS", "[email protected]")?;
let (secret_key, public_key) = (key_pair.secret_key(), key_pair.public_key());
let signature = sign(b"Hello", &secret_key)?;
eprintln!(
"{:?}",
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
group_imports = "StdExternalCrate"
imports_granularity = "Crate"
unstable_features = true

0 comments on commit 733f975

Please sign in to comment.