auth-api: move signing into the private key
this commit moves the current ticket signing code into the private key implementation. the upside is that the caller does not need to deal with openssl's `Signer` directly. it also simplifies and unifies the code by using the same helper for verifying a signature and creating it. also derive `Clone` on `PrivateKey` and `PublicKey`. as they are essentially thin wrappers around `openssl::pkey::PKey<Private>` and `openssl::pkey::PKey<Public>`, which can be cloned, deriving `Clone` just makes them easier to use. Signed-off-by: Stefan Sterz <s.sterz@proxmox.com>
This commit is contained in:
committed by
Wolfgang Bumiller
parent
f240a2bfaa
commit
8e566591d5
@ -9,11 +9,13 @@ use openssl::rsa::Rsa;
|
||||
use openssl::sign::{Signer, Verifier};
|
||||
|
||||
/// A private auth key used for API ticket signing and verification.
|
||||
#[derive(Clone)]
|
||||
pub struct PrivateKey {
|
||||
pub(crate) key: PKey<Private>,
|
||||
}
|
||||
|
||||
/// A private auth key used for API ticket verification.
|
||||
#[derive(Clone)]
|
||||
pub struct PublicKey {
|
||||
pub(crate) key: PKey<Public>,
|
||||
}
|
||||
@ -88,6 +90,13 @@ impl PrivateKey {
|
||||
pub fn public_key(&self) -> Result<PublicKey, Error> {
|
||||
PublicKey::from_pem(&self.public_key_to_pem()?)
|
||||
}
|
||||
|
||||
pub(self) fn sign(&self, digest: MessageDigest, data: &[u8]) -> Result<Vec<u8>, Error> {
|
||||
Signer::new(digest, &self.key)
|
||||
.map_err(|e| format_err!("could not create private key signer - {e}"))?
|
||||
.sign_oneshot_to_vec(data)
|
||||
.map_err(|e| format_err!("could not sign with private key - {e}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PKey<Private>> for PrivateKey {
|
||||
@ -204,15 +213,12 @@ impl Keyring {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
pub(crate) fn signer(&self, digest: MessageDigest) -> Result<Signer, Error> {
|
||||
Signer::new(
|
||||
digest,
|
||||
&self
|
||||
.signing_key
|
||||
.as_ref()
|
||||
.ok_or_else(|| format_err!("no private key available for signing"))?
|
||||
.key,
|
||||
)
|
||||
.map_err(|err| format_err!("failed to create openssl signer - {err}"))
|
||||
pub(crate) fn sign(&self, digest: MessageDigest, data: &[u8]) -> Result<Vec<u8>, Error> {
|
||||
let key = self
|
||||
.signing_key
|
||||
.as_ref()
|
||||
.ok_or_else(|| format_err!("no private key available for signing"))?;
|
||||
|
||||
key.sign(digest, data)
|
||||
}
|
||||
}
|
||||
|
@ -116,27 +116,10 @@ where
|
||||
/// Sign the ticket.
|
||||
pub fn sign(&mut self, keyring: &Keyring, aad: Option<&str>) -> Result<String, Error> {
|
||||
let mut output = self.ticket_data();
|
||||
let mut signer = keyring.signer(MessageDigest::sha256())?;
|
||||
|
||||
signer
|
||||
.update(output.as_bytes())
|
||||
.map_err(Error::from)
|
||||
.and_then(|()| {
|
||||
if let Some(aad) = aad {
|
||||
signer
|
||||
.update(b":")
|
||||
.and_then(|()| signer.update(aad.as_bytes()))
|
||||
.map_err(Error::from)
|
||||
} else {
|
||||
Ok::<_, Error>(())
|
||||
}
|
||||
})
|
||||
let signature = keyring
|
||||
.sign(MessageDigest::sha256(), &self.verification_data(aad))
|
||||
.map_err(|err| format_err!("error signing ticket: {}", err))?;
|
||||
|
||||
let signature = signer
|
||||
.sign_to_vec()
|
||||
.map_err(|err| format_err!("error finishing ticket signature: {}", err))?;
|
||||
|
||||
use std::fmt::Write;
|
||||
write!(
|
||||
&mut output,
|
||||
|
Reference in New Issue
Block a user