add pbs-api-types subcrate, move key_derivation

move key_derivation to pbs-datastore

pbs-api-types should only contain "basic" types which
* are usually required by clients
* don't depend on pbs-related code directly

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2021-07-07 09:04:09 +02:00
parent f323e90602
commit 86fb38776b
12 changed files with 118 additions and 85 deletions

View File

@ -94,6 +94,7 @@ proxmox-http = { version = "0.2.1", features = [ "client", "http-helpers", "webs
#proxmox-http = { version = "0.2.0", path = "../proxmox/proxmox-http", features = [ "client", "http-helpers", "websocket" ] }
proxmox-openid = "0.6.0"
pbs-api-types = { path = "pbs-api-types" }
pbs-buildcfg = { path = "pbs-buildcfg" }
pbs-datastore = { path = "pbs-datastore" }
pbs-runtime = { path = "pbs-runtime" }

View File

@ -31,6 +31,7 @@ RESTORE_BIN := \
proxmox-restore-daemon
SUBCRATES := \
pbs-api-types \
pbs-buildcfg \
pbs-datastore \
pbs-runtime \

12
pbs-api-types/Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "pbs-api-types"
version = "0.1.0"
authors = ["Proxmox Support Team <support@proxmox.com>"]
edition = "2018"
description = "general API type helpers for PBS"
[dependencies]
lazy_static = "1.4"
regex = "1.2"
proxmox = { version = "0.11.5", default-features = false, features = [ "api-macro" ] }

14
pbs-api-types/src/lib.rs Normal file
View File

@ -0,0 +1,14 @@
use proxmox::api::schema::{ApiStringFormat, Schema, StringSchema};
use proxmox::const_regex;
const_regex! {
pub FINGERPRINT_SHA256_REGEX = r"^(?:[0-9a-fA-F][0-9a-fA-F])(?::[0-9a-fA-F][0-9a-fA-F]){31}$";
}
pub const FINGERPRINT_SHA256_FORMAT: ApiStringFormat =
ApiStringFormat::Pattern(&FINGERPRINT_SHA256_REGEX);
pub const CERT_FINGERPRINT_SHA256_SCHEMA: Schema =
StringSchema::new("X509 certificate fingerprint (sha256).")
.format(&FINGERPRINT_SHA256_FORMAT)
.schema();

View File

@ -12,6 +12,7 @@ endian_trait = { version = "0.6", features = [ "arrays" ] }
nix = "0.19.1"
openssl = "0.10"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
zstd = { version = "0.6", features = [ "bindgen" ] }
pathpatterns = "0.1.2"
@ -19,4 +20,5 @@ pxar = { version = "0.10.1", features = [ "tokio-io" ] }
proxmox = { version = "0.11.5", default-features = false, features = [ "api-macro" ] }
pbs-api-types = { path = "../pbs-api-types" }
pbs-tools = { path = "../pbs-tools" }

View File

@ -1,15 +1,66 @@
use anyhow::{bail, format_err, Context, Error};
use serde::{Deserialize, Serialize};
use crate::backup::{CryptConfig, Fingerprint};
use std::io::Write;
use std::path::Path;
use anyhow::{bail, format_err, Context, Error};
use serde::{Deserialize, Serialize};
use proxmox::api::api;
use proxmox::tools::fs::{file_get_contents, replace_file, CreateOptions};
use proxmox::try_block;
use crate::api2::types::{KeyInfo, Kdf};
use pbs_api_types::CERT_FINGERPRINT_SHA256_SCHEMA;
use crate::crypt_config::{CryptConfig, Fingerprint};
#[api(default: "scrypt")]
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
/// Key derivation function for password protected encryption keys.
pub enum Kdf {
/// Do not encrypt the key.
None,
/// Encrypt they key with a password using SCrypt.
Scrypt,
/// Encrtypt the Key with a password using PBKDF2
PBKDF2,
}
impl Default for Kdf {
#[inline]
fn default() -> Self {
Kdf::Scrypt
}
}
#[api(
properties: {
kdf: {
type: Kdf,
},
fingerprint: {
schema: CERT_FINGERPRINT_SHA256_SCHEMA,
optional: true,
},
},
)]
#[derive(Deserialize, Serialize)]
/// Encryption Key Information
pub struct KeyInfo {
/// Path to key (if stored in a file)
#[serde(skip_serializing_if="Option::is_none")]
pub path: Option<String>,
pub kdf: Kdf,
/// Key creation time
pub created: i64,
/// Key modification time
pub modified: i64,
/// Key fingerprint
#[serde(skip_serializing_if="Option::is_none")]
pub fingerprint: Option<String>,
/// Password hint
#[serde(skip_serializing_if="Option::is_none")]
pub hint: Option<String>,
}
/// Key derivation function configuration
#[derive(Deserialize, Serialize, Clone, Debug)]

View File

@ -190,6 +190,7 @@ pub mod data_blob_reader;
pub mod data_blob_writer;
pub mod file_formats;
pub mod index;
pub mod key_derivation;
pub use checksum_reader::ChecksumReader;
pub use checksum_writer::ChecksumWriter;
@ -197,3 +198,7 @@ pub use chunker::Chunker;
pub use crypt_config::{CryptConfig, CryptMode};
pub use crypt_reader::CryptReader;
pub use crypt_writer::CryptWriter;
pub use key_derivation::{
decrypt_key, load_and_decrypt_key, rsa_decrypt_key_config, rsa_encrypt_key_config,
};
pub use key_derivation::{Kdf, KeyConfig, KeyDerivationConfig, KeyInfo};

View File

@ -12,6 +12,8 @@ use proxmox::{
tools::fs::open_file_locked,
};
use pbs_datastore::{KeyInfo, Kdf};
use crate::{
config::{
acl::{
@ -31,8 +33,6 @@ use crate::{
TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
PROXMOX_CONFIG_DIGEST_SCHEMA,
PASSWORD_HINT_SCHEMA,
KeyInfo,
Kdf,
},
backup::{
KeyConfig,

View File

@ -40,6 +40,12 @@ pub use file_restore::*;
mod acme;
pub use acme::*;
pub use pbs_api_types::{
CERT_FINGERPRINT_SHA256_SCHEMA,
FINGERPRINT_SHA256_FORMAT,
FINGERPRINT_SHA256_REGEX,
};
// File names: may not contain slashes, may not start with "."
pub const FILENAME_FORMAT: ApiStringFormat = ApiStringFormat::VerifyFn(|name| {
if name.starts_with('.') {
@ -112,8 +118,6 @@ const_regex!{
pub BACKUP_REPO_URL_REGEX = concat!(r"^^(?:(?:(", USER_ID_REGEX_STR!(), "|", APITOKEN_ID_REGEX_STR!(), ")@)?(", DNS_NAME!(), "|", IPRE_BRACKET!() ,"):)?(?:([0-9]{1,5}):)?(", PROXMOX_SAFE_ID_REGEX_STR!(), r")$");
pub FINGERPRINT_SHA256_REGEX = r"^(?:[0-9a-fA-F][0-9a-fA-F])(?::[0-9a-fA-F][0-9a-fA-F]){31}$";
pub ACL_PATH_REGEX = concat!(r"^(?:/|", r"(?:/", PROXMOX_SAFE_ID_REGEX_STR!(), ")+", r")$");
pub SUBSCRIPTION_KEY_REGEX = concat!(r"^pbs(?:[cbsp])-[0-9a-f]{10}$");
@ -156,9 +160,6 @@ pub const IP_FORMAT: ApiStringFormat =
pub const PVE_CONFIG_DIGEST_FORMAT: ApiStringFormat =
ApiStringFormat::Pattern(&SHA256_HEX_REGEX);
pub const FINGERPRINT_SHA256_FORMAT: ApiStringFormat =
ApiStringFormat::Pattern(&FINGERPRINT_SHA256_REGEX);
pub const PROXMOX_SAFE_ID_FORMAT: ApiStringFormat =
ApiStringFormat::Pattern(&PROXMOX_SAFE_ID_REGEX);
@ -225,12 +226,6 @@ pub const PBS_PASSWORD_SCHEMA: Schema = StringSchema::new("User Password.")
.max_length(64)
.schema();
pub const CERT_FINGERPRINT_SHA256_SCHEMA: Schema = StringSchema::new(
"X509 certificate fingerprint (sha256)."
)
.format(&FINGERPRINT_SHA256_FORMAT)
.schema();
pub const TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA: Schema = StringSchema::new(
"Tape encryption key fingerprint (sha256)."
)
@ -1449,56 +1444,6 @@ pub const PASSWORD_HINT_SCHEMA: Schema = StringSchema::new("Password hint.")
.max_length(64)
.schema();
#[api(default: "scrypt")]
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
/// Key derivation function for password protected encryption keys.
pub enum Kdf {
/// Do not encrypt the key.
None,
/// Encrypt they key with a password using SCrypt.
Scrypt,
/// Encrtypt the Key with a password using PBKDF2
PBKDF2,
}
impl Default for Kdf {
#[inline]
fn default() -> Self {
Kdf::Scrypt
}
}
#[api(
properties: {
kdf: {
type: Kdf,
},
fingerprint: {
schema: CERT_FINGERPRINT_SHA256_SCHEMA,
optional: true,
},
},
)]
#[derive(Deserialize, Serialize)]
/// Encryption Key Information
pub struct KeyInfo {
/// Path to key (if stored in a file)
#[serde(skip_serializing_if="Option::is_none")]
pub path: Option<String>,
pub kdf: Kdf,
/// Key creation time
pub created: i64,
/// Key modification time
pub modified: i64,
/// Key fingerprint
#[serde(skip_serializing_if="Option::is_none")]
pub fingerprint: Option<String>,
/// Password hint
#[serde(skip_serializing_if="Option::is_none")]
pub hint: Option<String>,
}
#[api]
#[derive(Deserialize, Serialize)]
/// RSA public key information

View File

@ -178,12 +178,14 @@ pub fn backup_group() -> Result<nix::unistd::Group, Error> {
}
}
pub use pbs_datastore::catalog::*;
pub use pbs_datastore::catalog;
pub use pbs_datastore::file_formats::*;
pub use pbs_datastore::file_formats;
pub use pbs_datastore::index::*;
pub use pbs_datastore::index;
pub use pbs_datastore::catalog::*;
pub use pbs_datastore::checksum_reader;
pub use pbs_datastore::checksum_reader::*;
pub use pbs_datastore::checksum_writer;
pub use pbs_datastore::checksum_writer::*;
pub use pbs_datastore::chunker;
pub use pbs_datastore::chunker::*;
pub use pbs_datastore::crypt_config;
pub use pbs_datastore::crypt_config::*;
pub use pbs_datastore::crypt_reader;
@ -196,15 +198,12 @@ pub use pbs_datastore::data_blob_reader;
pub use pbs_datastore::data_blob_reader::*;
pub use pbs_datastore::data_blob_writer;
pub use pbs_datastore::data_blob_writer::*;
pub use pbs_datastore::checksum_reader;
pub use pbs_datastore::checksum_reader::*;
pub use pbs_datastore::checksum_writer;
pub use pbs_datastore::checksum_writer::*;
pub use pbs_datastore::chunker;
pub use pbs_datastore::chunker::*;
mod key_derivation;
pub use key_derivation::*;
pub use pbs_datastore::file_formats;
pub use pbs_datastore::file_formats::*;
pub use pbs_datastore::index;
pub use pbs_datastore::index::*;
pub use pbs_datastore::key_derivation;
pub use pbs_datastore::key_derivation::*;
mod manifest;
pub use manifest::*;

View File

@ -13,8 +13,10 @@ use proxmox::api::router::ReturnType;
use proxmox::sys::linux::tty;
use proxmox::tools::fs::{file_get_contents, replace_file, CreateOptions};
use pbs_datastore::{KeyInfo, Kdf};
use proxmox_backup::{
api2::types::{Kdf, KeyInfo, RsaPubKeyInfo, PASSWORD_HINT_SCHEMA},
api2::types::{RsaPubKeyInfo, PASSWORD_HINT_SCHEMA},
backup::{rsa_decrypt_key_config, KeyConfig},
tools,
tools::paperkey::{generate_paper_key, PaperkeyFormat},

View File

@ -11,6 +11,8 @@ use proxmox::{
sys::linux::tty,
};
use pbs_datastore::Kdf;
use proxmox_backup::{
tools::{
paperkey::{
@ -25,7 +27,6 @@ use proxmox_backup::{
DRIVE_NAME_SCHEMA,
TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
PASSWORD_HINT_SCHEMA,
Kdf,
},
},
backup::Fingerprint,