forked from Proxmox/proxmox
subscription: make key optional and support multiple keys
this is a breaking change requiring updates in proxmox-perl-rs and proxmox-backup. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
parent
d228ef6e20
commit
5391f5313b
@ -83,14 +83,14 @@ fn parse_subscription_file(raw: &str) -> Result<Option<SubscriptionInfo>, Error>
|
||||
/// Legacy variants of this format as used by older versions of PVE/PMG are supported.
|
||||
pub fn read_subscription<P: AsRef<Path>>(
|
||||
path: P,
|
||||
signature_key: &openssl::pkey::PKey<openssl::pkey::Public>,
|
||||
signature_keys: &[P],
|
||||
) -> Result<Option<SubscriptionInfo>, Error> {
|
||||
match proxmox_sys::fs::file_read_optional_string(path)? {
|
||||
Some(raw) => {
|
||||
let mut info = parse_subscription_file(&raw)?;
|
||||
if let Some(info) = info.as_mut() {
|
||||
// these will set `status` to INVALID if checks fail!
|
||||
info.check_signature(signature_key);
|
||||
info.check_signature(signature_keys);
|
||||
info.check_server_id();
|
||||
info.check_age(false);
|
||||
};
|
||||
|
@ -1,5 +1,8 @@
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::{bail, format_err, Error};
|
||||
use openssl::hash::{hash, DigestBytes, MessageDigest};
|
||||
use proxmox_sys::fs::file_get_contents;
|
||||
use proxmox_time::TmEditor;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -203,8 +206,12 @@ impl SubscriptionInfo {
|
||||
///
|
||||
/// `status` is set to [SubscriptionStatus::Invalid] and `message` to a human-readable error
|
||||
/// message in case a signature is available but not valid for the given `key`.
|
||||
pub fn check_signature(&mut self, key: &openssl::pkey::PKey<openssl::pkey::Public>) {
|
||||
let verify = |info: &SubscriptionInfo| -> Result<(), Error> {
|
||||
pub fn check_signature<P: AsRef<Path>>(&mut self, keys: &[P]) {
|
||||
let verify = |info: &SubscriptionInfo, path: &P| -> Result<(), Error> {
|
||||
let raw = file_get_contents(path)?;
|
||||
|
||||
let key = openssl::pkey::PKey::public_key_from_pem(&raw)?;
|
||||
|
||||
let (signed, signature) = info.signed_data()?;
|
||||
let signature = match signature {
|
||||
None => bail!("Failed to extract signature value."),
|
||||
@ -216,9 +223,12 @@ impl SubscriptionInfo {
|
||||
};
|
||||
|
||||
if self.is_signed() {
|
||||
if let Err(err) = verify(self) {
|
||||
if keys.is_empty() {
|
||||
self.status = SubscriptionStatus::Invalid;
|
||||
self.message = Some(format!("Signature validation failed - {err}"));
|
||||
self.message = Some("Signature exists, but no key available.".to_string());
|
||||
} else if !keys.iter().any(|key| verify(self, key).is_ok()) {
|
||||
self.status = SubscriptionStatus::Invalid;
|
||||
self.message = Some("Signature validation failed".to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user