mirror of
https://git.proxmox.com/git/proxmox
synced 2025-05-29 18:48:29 +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),
|
.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)]
|
#[derive(Clone, Copy, Eq, PartialEq, Deserialize, Serialize)]
|
||||||
|
@ -548,16 +548,7 @@ impl Client {
|
|||||||
// TODO: This can also work without an account.
|
// TODO: This can also work without an account.
|
||||||
let account = Self::need_account(&self.account)?;
|
let account = Self::need_account(&self.account)?;
|
||||||
|
|
||||||
let cert = if certificate.starts_with(b"-----BEGIN CERTIFICATE-----") {
|
let revocation = account.revoke_certificate(certificate, reason)?;
|
||||||
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 mut retry = retry();
|
let mut retry = retry();
|
||||||
loop {
|
loop {
|
||||||
@ -566,7 +557,7 @@ impl Client {
|
|||||||
let directory =
|
let directory =
|
||||||
Self::get_directory(&mut self.inner, &mut self.directory, &self.directory_url)?;
|
Self::get_directory(&mut self.inner, &mut self.directory, &self.directory_url)?;
|
||||||
let nonce = Self::nonce(&mut self.inner, directory)?;
|
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) {
|
match self.inner.run_request(request) {
|
||||||
Ok(_response) => return Ok(()),
|
Ok(_response) => return Ok(()),
|
||||||
Err(err) if err.is_bad_nonce() => continue,
|
Err(err) if err.is_bad_nonce() => continue,
|
||||||
|
Loading…
Reference in New Issue
Block a user