Compare commits

..

No commits in common. "fcdda1d0e5681930ee59ff0710c7a20164c8afe7" and "b36efc13a3c592efd6fcb1dfce5bf61dc513c97c" have entirely different histories.

2 changed files with 11 additions and 122 deletions

View file

@ -2,12 +2,11 @@ use anyhow::{Context, Result};
use sequoia_openpgp::{
cert::CertBuilder,
packet::{signature::SignatureBuilder, Signature},
packet::signature::SignatureBuilder,
types::{KeyFlags, SignatureType},
Cert,
};
use spec::{KeyFlag, Spec};
use spec::KeyFlag;
mod paths;
mod setup;
@ -15,14 +14,6 @@ mod spec;
fn main() -> Result<()> {
let (paths, spec) = crate::setup::setup().context("Failed to setup application")?;
let (cert, rev) = paths.load()?.ok_or(()).or_else(|()| generate_new(spec))?;
paths
.write(cert, rev)
.context("Failed to store certificate!")?;
Ok(())
}
fn generate_new(spec: Spec) -> Result<(Cert, Signature)> {
let mut builder = CertBuilder::new()
.set_primary_key_flags(
spec.primary
@ -66,7 +57,11 @@ fn generate_new(spec: Spec) -> Result<(Cert, Signature)> {
))?;
}
builder
let (cert, rev) = builder
.generate()
.context("Failed to generate certificate!")
.context("Failed to generate certificate!")?;
paths
.write(cert, rev)
.context("Failed to store certificate!")?;
Ok(())
}

View file

@ -1,17 +1,7 @@
use std::{
path::{Path, PathBuf},
time::SystemTime,
};
use std::path::{Path, PathBuf};
use anyhow::{bail, Context, Result};
use sequoia_openpgp::{
cert::CertRevocationBuilder,
packet::Signature,
parse::Parse,
serialize::SerializeInto,
types::{ReasonForRevocation, SignatureType},
Cert, Packet,
};
use anyhow::{Context, Result};
use sequoia_openpgp::{packet::Signature, serialize::SerializeInto, Cert};
pub(crate) struct Paths {
pub(crate) spec: PathBuf,
@ -37,102 +27,6 @@ impl Paths {
rev,
}
}
pub(crate) fn load(&self) -> Result<Option<(Cert, Signature)>> {
let mut merged = if self
.secret
.try_exists()
.context("Couldn't check if secret part of certificate exists")?
{
Cert::from_file(&self.secret)
.context("Couldn't load secret part of certificate from file")?
} else {
return Ok(None);
};
if let (_, Some(secret_material)) = merged.primary_key().key().clone().take_secret() {
if secret_material.is_encrypted() {
bail!("Secret material for primary key is encrypted!");
}
} else {
bail!("Primary key has no secret material!")
}
if self
.public
.try_exists()
.context("Couldn't check if public part of certificate exists")?
{
merged = merged
.merge_public_and_secret(
Cert::from_file(&self.public)
.context("Couldn't load public part from certificate from file")?,
)
.context("Couldn't merge public part onto secret part of certificate")?
}
if self.rev.try_exists()? {
merged = merged
.merge_public_and_secret(
Cert::from_file(&self.rev)
.context("Couldn't load revocation for certificate from file")?,
)
.context("Couldn't merge revocation onto secret part of certificate")?
}
let fingerprint = merged.fingerprint();
let mut filtered = vec![];
let mut revocation = None;
// strip revocation for primary key
for packet in merged.into_packets() {
match packet {
Packet::Signature(Signature::V4(sig)) => {
if sig.typ() == SignatureType::KeyRevocation
&& sig
.issuer_fingerprints()
.any(|issuer| issuer.eq(&fingerprint))
{
revocation = Some(Signature::V4(sig));
} else {
filtered.push(Packet::Signature(Signature::V4(sig)));
}
}
packet => filtered.push(packet),
}
}
let filtered = Cert::from_packets(filtered.into_iter())
.context("Could't parse cert from packets after removing primary key revocations")?;
let revocation = revocation
.ok_or(())
.or_else(|()| {
let now = SystemTime::now();
CertRevocationBuilder::new()
.set_signature_creation_time(now)
.context("Failed to set signature creation time")?
.set_reason_for_revocation(ReasonForRevocation::Unspecified, b"Unspecified")
.context("Failed to set revocation reason")?
.build(
&mut filtered
.primary_key()
.key()
.clone()
.parts_into_secret()
.context("Failed to get secret parts of certificate primary key")?
.into_keypair()
.context("Failed to convert primary key into keypair")?,
&filtered,
None,
)
.context("Failed to generate revocation for certificate primary key")
})
.context("Failed to generate new revocation after not finding an existing one")?;
Ok(Some((filtered, revocation)))
}
pub(crate) fn write(&self, cert: Cert, rev: Signature) -> Result<()> {
self.write_part(Self::public, cert.armored())
.context("Failed to write public certificate to file")?;