mirror of
https://git.proxmox.com/git/proxmox
synced 2025-05-28 11:13:36 +00:00
make revocation workflow accessible without client
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
b624fa1f3c
commit
558f51a167
@ -218,6 +218,49 @@ impl Account {
|
||||
.map(Some),
|
||||
}
|
||||
}
|
||||
|
||||
/// Prepare a request to revoke a certificate.
|
||||
///
|
||||
/// The certificate can be either PEM or DER formatted.
|
||||
///
|
||||
/// Note that this uses the account's key for authorization.
|
||||
///
|
||||
/// Revocation using a certificate's private key is not yet implemented.
|
||||
pub fn revoke_certificate(
|
||||
&self,
|
||||
certificate: &[u8],
|
||||
reason: Option<u32>,
|
||||
) -> Result<CertificateRevocation, Error> {
|
||||
let cert = if certificate.starts_with(b"-----BEGIN CERTIFICATE-----") {
|
||||
b64u::encode(&openssl::x509::X509::from_pem(certificate)?.to_der()?)
|
||||
} else {
|
||||
b64u::encode(certificate)
|
||||
};
|
||||
|
||||
let data = match reason {
|
||||
Some(reason) => serde_json::json!({ "certificate": cert, "reason": reason }),
|
||||
None => serde_json::json!({ "certificate": cert }),
|
||||
};
|
||||
|
||||
Ok(CertificateRevocation {
|
||||
account: self,
|
||||
data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Certificate revocation involves converting the certificate to base64url encoded DER and then
|
||||
/// embedding it in a json structure. Since we also need a nonce and possibly retry the request if
|
||||
/// a `BadNonce` error happens, this caches the converted data for efficiency.
|
||||
pub struct CertificateRevocation<'a> {
|
||||
account: &'a Account,
|
||||
data: Value,
|
||||
}
|
||||
|
||||
impl CertificateRevocation<'_> {
|
||||
pub fn request(&self, directory: &Directory, nonce: &str) -> Result<Request, Error> {
|
||||
self.account.post_request(&directory.data.revoke_cert, nonce, &self.data)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Deserialize, Serialize)]
|
||||
|
@ -548,16 +548,7 @@ impl Client {
|
||||
// TODO: This can also work without an account.
|
||||
let account = Self::need_account(&self.account)?;
|
||||
|
||||
let cert = if certificate.starts_with(b"-----BEGIN CERTIFICATE-----") {
|
||||
b64u::encode(&openssl::x509::X509::from_pem(certificate)?.to_der()?)
|
||||
} else {
|
||||
b64u::encode(certificate)
|
||||
};
|
||||
|
||||
let data = match reason {
|
||||
Some(reason) => serde_json::json!({ "certificate": cert, "reason": reason }),
|
||||
None => serde_json::json!({ "certificate": cert }),
|
||||
};
|
||||
let revocation = account.revoke_certificate(certificate, reason)?;
|
||||
|
||||
let mut retry = retry();
|
||||
loop {
|
||||
@ -566,7 +557,7 @@ impl Client {
|
||||
let directory =
|
||||
Self::get_directory(&mut self.inner, &mut self.directory, &self.directory_url)?;
|
||||
let nonce = Self::nonce(&mut self.inner, directory)?;
|
||||
let request = account.post_request(&directory.data.revoke_cert, nonce, &data)?;
|
||||
let request = revocation.request(&directory, nonce)?;
|
||||
match self.inner.run_request(request) {
|
||||
Ok(_response) => return Ok(()),
|
||||
Err(err) if err.is_bad_nonce() => continue,
|
||||
|
Loading…
Reference in New Issue
Block a user