From 98f7a0569cdb22d4aee6b1bc932422bb66279df2 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Tue, 30 Jan 2024 12:56:13 +0100 Subject: [PATCH] rust/pvsecret: User defined signatures and verifications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduces the ability to `pvsecret` to add a signature (ecdsa or rsa) to the program-reserved space (user-data) of an add-secret request during the request creation. Additionally, some arbitrary data may be inserted. The new command `verify` checks if add-secret requests are sane (e.g. start with the correct magic value). If the request contains a user-signature `verify` will also verify this signature. Acked-by: Marc Hartmayer Signed-off-by: Steffen Eiden Signed-off-by: Jan Höppner --- rust/pvsecret/README.md | 112 +++++++++++++- rust/pvsecret/man/pvsecret-add.1 | 2 +- .../man/pvsecret-create-association.1 | 2 +- rust/pvsecret/man/pvsecret-create-meta.1 | 2 +- rust/pvsecret/man/pvsecret-create.1 | 33 ++++- rust/pvsecret/man/pvsecret-list.1 | 2 +- rust/pvsecret/man/pvsecret-lock.1 | 2 +- rust/pvsecret/man/pvsecret-verify.1 | 139 ++++++++++++++++++ rust/pvsecret/man/pvsecret.1 | 6 +- rust/pvsecret/src/cli.rs | 57 ++++++- rust/pvsecret/src/cmd.rs | 3 + rust/pvsecret/src/cmd/create.rs | 25 +++- rust/pvsecret/src/cmd/verify.rs | 46 ++++++ rust/pvsecret/src/main.rs | 2 + 14 files changed, 418 insertions(+), 15 deletions(-) create mode 100644 rust/pvsecret/man/pvsecret-verify.1 create mode 100644 rust/pvsecret/src/cmd/verify.rs diff --git a/rust/pvsecret/README.md b/rust/pvsecret/README.md index 4015dacc..cc8d2f2e 100644 --- a/rust/pvsecret/README.md +++ b/rust/pvsecret/README.md @@ -45,6 +45,11 @@ Lock the secret-store (s390x only) List all ultravisor secrets (s390x only) +- **verify** +
    +Verify that an add-secret request is sane +
+ ## Options `-v`, `--verbose` @@ -180,9 +185,9 @@ all requests.
    Use HEXSTRING as the Configuration Unique ID. Must be a hex 128-bit unsigned big endian number string. Leading zeros must be provided. If specified, the value -must match with the Config-UID from the attestation result of that guest. If -not specified, the CUID will be ignored by the ultravisor during the -verification of the request. +must match with the Config-UID from the attestation result of that guest. If not +specified, the CUID will be ignored by the ultravisor during the verification of +the request.
@@ -204,6 +209,37 @@ Flags for the add-secret request +`--user-data ` +
    +Use the content of FILE as user-data. Passes user data defined in through +the add-secret request to the ultravisor. The user data can be up to 512 bytes +of arbitrary data, and the maximum size depends on the size of the user-signing +key: + + - No key: user data can be 512 bytes. + + - EC(secp521r1) or RSA 2048 keys: user data can be 256 bytes. + + - RSA 3072 key: user data can be 128 bytes. + +The firmware ignores this data, but the request tag protects the user-data. +Optional. No user-data by default. +
+ + +`--user-sign-key ` +
    +Use the content of FILE as user signing key. Adds a signature defined calculated +from the key in to the add-secret request. The file must be in DER or PEM +format containing a private key. Supported are RSA 2048 & 3072-bit and +EC(secp521r1) keys. The firmware ignores the content, but the request tag +protects the signature. The user-signing key signs the request. The location of +the signature is filled with zeros during the signature calculation. The request +tag also secures the signature. See man pvsecret verify for more details. +Optional. No signature by default. +
+ + ### pvsecret create meta #### Synopsis `pvsecret create meta` @@ -301,3 +337,73 @@ Define the output format of the list - **yaml**: Use yaml format - **bin**: Use the format the ultravisor uses to pass the list + + +## pvsecret verify +### Synopsis +`pvsecret verify [OPTIONS] ` +### Description +Verifies that the given request is an Add-Secret request by testing for some +values to be present. If the request contains signed user-data, the signature +is verified with the provided key. Outputs the arbitrary user-data. All data in +the request is in big endian. `verify` checks the following: + + - The first 6 bytes of the request are equal to: `B6173 7263 624d | asrcbM` + - The sizes in the request header are sane and do not point out of the file + - The request version is supported by the binary + - If user-data contains a signature, verify the signature using a public key + +The content of bytes 6&7 of the request define which kind of user-data the +request contains. + - **0x0000** `no user-data (512 bytes zero)` + - **0x0001** `512 bytes user-data` + - **0x0002** `265 bytes user-data| 139 bytes ecdsa signature | 5 bytes reserved +| 2 bytes signature size | ...` + - **0x0003** `256 bytes user-data | 256 bytes rsa2048 signature` + - **0x0004** `128 bytes user-data | 384 bytes rsa3072 signature` + +The actual user-data may be less than the capacity. If less data was provided +during `create` zeros are appended. +For type 2-4 The signature is calculated as follows: +1) The request is generated with the user-data in place and zeros for the +signature data. +2) The signature is calculated for the request. The signature signs the +authenticated data and the encrypted data, but not the request tag. I.e. the +signature signs the whole request but the last 16 bytes a,d with the signature +bytes set to zero. +3) The signature is inserted to its location in the request. +4) The request GCM tag is calculated. + +The verification process works as follows: +1) copy the signature to a buffer +2) overwrite the signature with zeros +3) verify the signature of the request but the last 16 bytes + +### Arguments + +`` +
    +Specify the request to be checked +
+ + +### Options + +`--user-cert ` +
    +Certificate containing a public key used to verify the user data signature. +Specifies a public key used to verify the user-data signature. The file must be +a X509 certificate in DSA or PEM format. The certificate must hold the public +EC, RSA 2048, or RSA 3072 key corresponding to the private user-key used during +`create`. No chain of trust is established. Ensuring that the certificate can be +trusted is the responsibility of the user. The EC key must use the NIST/SECG +curve over a 521 bit prime field (secp521r1). +
+ + +`-o`, `--output ` +
    +Store the result in FILE If the request contained abirtary user-data the output +contains this user-data with padded zeros if available. + Default value: '-' +
diff --git a/rust/pvsecret/man/pvsecret-add.1 b/rust/pvsecret/man/pvsecret-add.1 index 96a94e40..0d05d318 100644 --- a/rust/pvsecret/man/pvsecret-add.1 +++ b/rust/pvsecret/man/pvsecret-add.1 @@ -3,7 +3,7 @@ .\" it under the terms of the MIT license. See LICENSE for details. .\" -.TH pvsecret-add 1 "2023-10-09" "s390-tools" "UV-Secret Manual" +.TH pvsecret-add 1 "2024-01-30" "s390-tools" "UV-Secret Manual" .nh .ad l .SH NAME diff --git a/rust/pvsecret/man/pvsecret-create-association.1 b/rust/pvsecret/man/pvsecret-create-association.1 index 1d62bd94..8341a83a 100644 --- a/rust/pvsecret/man/pvsecret-create-association.1 +++ b/rust/pvsecret/man/pvsecret-create-association.1 @@ -3,7 +3,7 @@ .\" it under the terms of the MIT license. See LICENSE for details. .\" -.TH pvsecret-create-association 1 "2023-10-09" "s390-tools" "UV-Secret Manual" +.TH pvsecret-create-association 1 "2024-01-30" "s390-tools" "UV-Secret Manual" .nh .ad l .SH NAME diff --git a/rust/pvsecret/man/pvsecret-create-meta.1 b/rust/pvsecret/man/pvsecret-create-meta.1 index dc3519a5..c89cee77 100644 --- a/rust/pvsecret/man/pvsecret-create-meta.1 +++ b/rust/pvsecret/man/pvsecret-create-meta.1 @@ -3,7 +3,7 @@ .\" it under the terms of the MIT license. See LICENSE for details. .\" -.TH pvsecret-create-meta 1 "2023-10-09" "s390-tools" "UV-Secret Manual" +.TH pvsecret-create-meta 1 "2024-01-30" "s390-tools" "UV-Secret Manual" .nh .ad l .SH NAME diff --git a/rust/pvsecret/man/pvsecret-create.1 b/rust/pvsecret/man/pvsecret-create.1 index 981c6f58..16d1c1b3 100644 --- a/rust/pvsecret/man/pvsecret-create.1 +++ b/rust/pvsecret/man/pvsecret-create.1 @@ -3,7 +3,7 @@ .\" it under the terms of the MIT license. See LICENSE for details. .\" -.TH pvsecret-create 1 "2023-10-09" "s390-tools" "UV-Secret Manual" +.TH pvsecret-create 1 "2024-01-30" "s390-tools" "UV-Secret Manual" .nh .ad l .SH NAME @@ -146,6 +146,37 @@ Possible values: .RS 4 - \fBdisable-dump\fP: Disables host-initiated dumping for the target guest instance. +.RE +.RE +.PP +\-\-user-data +.RS 4 +Use the content of FILE as user-data. Passes user data defined in through +the add-secret request to the ultravisor. The user data can be up to 512 bytes +of arbitrary data, and the maximum size depends on the size of the user-signing +key: + + - No key: user data can be 512 bytes. + + - EC(secp521r1) or RSA 2048 keys: user data can be 256 bytes. + + - RSA 3072 key: user data can be 128 bytes. + +The firmware ignores this data, but the request tag protects the user-data. +Optional. No user-data by default. +.RE +.RE +.PP +\-\-user-sign-key +.RS 4 +Use the content of FILE as user signing key. Adds a signature defined calculated +from the key in to the add-secret request. The file must be in DER or PEM +format containing a private key. Supported are RSA 2048 & 3072-bit and +EC(secp521r1) keys. The firmware ignores the content, but the request tag +protects the signature. The user-signing key signs the request. The location of +the signature is filled with zeros during the signature calculation. The request +tag also secures the signature. See man pvsecret verify for more details. +Optional. No signature by default. .RE .RE diff --git a/rust/pvsecret/man/pvsecret-list.1 b/rust/pvsecret/man/pvsecret-list.1 index 17e9bb0a..c10fba65 100644 --- a/rust/pvsecret/man/pvsecret-list.1 +++ b/rust/pvsecret/man/pvsecret-list.1 @@ -3,7 +3,7 @@ .\" it under the terms of the MIT license. See LICENSE for details. .\" -.TH pvsecret-list 1 "2023-10-09" "s390-tools" "UV-Secret Manual" +.TH pvsecret-list 1 "2024-01-30" "s390-tools" "UV-Secret Manual" .nh .ad l .SH NAME diff --git a/rust/pvsecret/man/pvsecret-lock.1 b/rust/pvsecret/man/pvsecret-lock.1 index 1b3b473a..2dab290a 100644 --- a/rust/pvsecret/man/pvsecret-lock.1 +++ b/rust/pvsecret/man/pvsecret-lock.1 @@ -3,7 +3,7 @@ .\" it under the terms of the MIT license. See LICENSE for details. .\" -.TH pvsecret-lock 1 "2023-10-09" "s390-tools" "UV-Secret Manual" +.TH pvsecret-lock 1 "2024-01-30" "s390-tools" "UV-Secret Manual" .nh .ad l .SH NAME diff --git a/rust/pvsecret/man/pvsecret-verify.1 b/rust/pvsecret/man/pvsecret-verify.1 new file mode 100644 index 00000000..0a733cab --- /dev/null +++ b/rust/pvsecret/man/pvsecret-verify.1 @@ -0,0 +1,139 @@ +.\" Copyright 2023 IBM Corp. +.\" s390-tools is free software; you can redistribute it and/or modify +.\" it under the terms of the MIT license. See LICENSE for details. +.\" + +.TH pvsecret-verify 1 "2024-01-30" "s390-tools" "UV-Secret Manual" +.nh +.ad l +.SH NAME +\fBpvsecret verify\fP - Verify that an add-secret request is sane +\fB +.SH SYNOPSIS +.nf +.fam C +pvsecret verify [OPTIONS] +.fam C +.fi +.SH DESCRIPTION +.PP +Verifies that the given request is an Add-Secret request by testing for some +values to be present. If the request contains signed user-data, the signature is +verified with the provided key. Outputs the arbitrary user-data. All data in the +request is in big endian. +.PP +\fIverify\fP checks the following: +.RS +.IP \[bu] 2 +The first 6 bytes of the request are equal to: \fB6173 7263 624d | asrcbM\fP +.IP \[bu] 2 +The sizes in the request header are sane and do not point out of the +file +.IP \[bu] 2 +The request version is supported by the binary +.IP \[bu] 2 +If user-data contains a signature, verify the signature using a public +key +.RE +.PP +The content of bytes 6&7 of the request define which kind +of user-data the request contains. +.IP \fB0x0000\fP 8 +no user-data (512 bytes zero) +.IP \fB0x0001\fP 8 +512 bytes user-data +.IP \fB0x0002\fP 8 +265 bytes user-data| 139 bytes ecdsa signature | 5 bytes reserved | 2 bytes +signature size | ... +.IP \fB0x0003\fP 8 +256 bytes user-data | 256 bytes rsa2048 signature +.IP \fB0x0004\fP 8 +128 bytes user-data | 384 bytes rsa3072 signature +.PP +The actual user-data may be less than the capacity. If less data was provided +during \fIcreate\fP zeros are appended. +. +For type 2-4 The signature is calculated as follows: +.RS +.IP "1." 3 +The request is generated with the user-data in place and zeros for the +signature data. +.IP "2." 3 +The signature is calculated for the request. The signature signs the +authenticated data and the encrypted data, but not the request tag. I.e. the +signature signs the whole request but the last 16 bytes and with the signature +bytes set to zero. +.IP "3." 3 +The signature is inserted to its location in the request. +.IP "4." 3 +The request GCM tag is calculated. +.PP +.RE + +The verification process works as follows: +.RS +.IP "1." 3 +copy the signature to a buffer +.IP "2." 3 +overwrite the signature with zeros +.IP "3." 3 +verify the signature of the request but the last 16 bytes +.RE + +.SH OPTIONS +.PP + +.RS 4 +Specify the request to be checked. +.RE +.RE + +.PP +\-\-user-cert +.RS 4 +Certificate containing a public key used to verify the user data signature. +Specifies a public key used to verify the user-data signature. The file must be +a X509 certificate in DSA or PEM format. The certificate must hold the public +EC, RSA 2048, or RSA 3072 key corresponding to the private user-key used during +`create`. No chain of trust is established. Ensuring that the certificate can be +trusted is the responsibility of the user. The EC key must use the NIST/SECG +curve over a 521 bit prime field (secp521r1). +.RE +.RE +.PP +\-o, \-\-output +.RS 4 +Store the result in FILE If the request contained abirtary user-data the output +contains this user-data with padded zeros if available. +[default: '-'] +.RE +.RE + +.SH EXAMPLES +.PP +Create the add-secret request on a trusted system with signed user datai similar to the example for \fFpvsecret\fP. Let's assume there are three more files present .\fFuser_data\fP contains ascii "some example user-data", a private user-signing key e.g. rsa3072 \fFusr_sgn_key.priv.pem\fF, and a certificate containing the corresponding public key to the private rsa3072 key \fFuser_cert.pem\fP. +.PP +.RS +.IP trusted:~$ 12 +pvsecret create -k hkd.crt --cert CA.crt --cert ibmsk.crt --hdr pvimage -o addsecreq.bin --user-data user_data --user-sign-key usr_sgn_key.priv.pem association EXAMPLE +.RE +.RS +Successfully generated the request +.br +Successfully wrote association info to 'EXAMPLE.yaml' +.RE + +For example, on the SE-guest, perform \fIverify\fP on the request to verify the user-signature and the saneness of the request. On success, The user-data is printed to stdout (if \fI--output\fP was not specified) and \fFSuccesfully verified the request.\fP is printed to stderr. +.PP +.RS +.IP seguest:~$ 12 +pvsecret verify --user-cert user_cert.pem -o addsecreq.bin +.RE +.RS +some example user-data +.br +Successfully verified the request +.RE +.SH "SEE ALSO" +.sp +\fBpvsecret\fR(1) diff --git a/rust/pvsecret/man/pvsecret.1 b/rust/pvsecret/man/pvsecret.1 index 32856408..fed8a72e 100644 --- a/rust/pvsecret/man/pvsecret.1 +++ b/rust/pvsecret/man/pvsecret.1 @@ -3,7 +3,7 @@ .\" it under the terms of the MIT license. See LICENSE for details. .\" -.TH pvsecret 1 "2023-10-09" "s390-tools" "UV-Secret Manual" +.TH pvsecret 1 "2024-01-30" "s390-tools" "UV-Secret Manual" .nh .ad l .SH NAME @@ -30,7 +30,7 @@ guest where you want to inject the secrets. This approach prevents the secrets from being in cleartext on the guest. For extra safety, do an attestation with \fBpvattest\fR of your guest beforehand, and include the configuration UID in the secret request using \fB--cuid\fR. Refer to \fBpvsecret-add\fR(1) for more -information. For all certificates, revocation lists, and host-key documents, +information. For all certificates, revocation lists, and host-key documents, both the PEM and DER input formats are supported. .SH OPTIONS @@ -96,4 +96,4 @@ On the SE-guest, \fIlock\fP the secret store. .fi .SH "SEE ALSO" .sp -\fBpvsecret-create\fR(1) \fBpvsecret-add\fR(1) \fBpvsecret-lock\fR(1) \fBpvsecret-list\fR(1) +\fBpvsecret-create\fR(1) \fBpvsecret-add\fR(1) \fBpvsecret-lock\fR(1) \fBpvsecret-list\fR(1) \fBpvsecret-verify\fR(1) diff --git a/rust/pvsecret/src/cli.rs b/rust/pvsecret/src/cli.rs index 96f97b42..d1028f40 100644 --- a/rust/pvsecret/src/cli.rs +++ b/rust/pvsecret/src/cli.rs @@ -4,7 +4,6 @@ use clap::{ArgGroup, Args, CommandFactory, Parser, Subcommand, ValueEnum, ValueHint}; use pv::misc::CertificateOptions; -#[cfg(target_arch = "s390x")] use pv::misc::STDOUT; /// Manage secrets for IBM Secure Execution guests. @@ -113,6 +112,31 @@ pub struct CreateSecretOpt { value_delimiter = ',' )] pub flags: Vec, + + /// Use the content of FILE as user-data. + /// + /// Passes user data defined in through the add-secret request to the ultravisor. The + /// user data can be up to 512 bytes of arbitrary data, and the maximum size depends on the + /// size of the user-signing key: + /// - No key: user data can be 512 bytes. + /// - EC or RSA 2048 keys: user data can be 256 bytes. + /// - RSA 3072 key: user data can be 128 bytes. + /// + /// The firmware ignores this data, but the request tag protects the user-data. Optional. No + /// user-data by default. + #[arg(long, value_name = "FILE", value_hint = ValueHint::FilePath,)] + pub user_data: Option, + + /// Use the content of FILE as user signing key. + /// + /// Adds a signature calculated from the key in to the add-secret request. The + /// file must be in DER or PEM format containing a private key. Supported are RSA 2048 & + /// 3072-bit and EC(secp521r1) keys. The firmware ignores the content, but the request tag protects the + /// signature. The user-signing key signs the request. The location of the signature is filled + /// with zeros during the signature calculation. The request tag also secures the signature. + /// See man pvsecret verify for more details. Optional. No signature by default. + #[arg(long, value_name = "FILE", value_hint = ValueHint::FilePath,)] + pub user_sign_key: Option, } #[derive(Subcommand, Debug)] @@ -189,6 +213,30 @@ pub struct ListSecretOpt { pub format: ListSecretOutputType, } +#[derive(Args, Debug)] +pub struct VerifyOpt { + /// Specify the request to be checked. + #[arg(value_name = "FILE", value_hint = ValueHint::FilePath,)] + pub input: String, + + /// Certificate containing a public key used to verify the user data signature. + /// + /// Specifies a public key used to verify the user-data signature. The file must be a X509 + /// certificate in DSA or PEM format. The certificate must hold the public EC, RSA 2048, or RSA + /// 3072 key corresponding to the private user-key used during `create`. No chain of trust is + /// established. Ensuring that the certificate can be trusted is the responsibility of the + /// user. The EC key must use the NIST/SECG curve over a 521 bit prime field (secp521r1). + #[arg(long, value_name = "FILE", value_hint = ValueHint::FilePath,)] + pub user_cert: Option, + + /// Store the result in FILE + /// + /// If the request contained abirtary user-data the output contains this user-data with padded + /// zeros if available. + #[arg(short, long, value_name = "FILE", default_value = STDOUT, value_hint = ValueHint::FilePath,)] + pub output: String, +} + #[derive(Subcommand, Debug)] pub enum Command { /// Create a new add-secret request. @@ -218,6 +266,13 @@ pub enum Command { /// running IBM Secure Execution guest. Only available on s390x. List(ListSecretOpt), + /// Verify that an add-secret request is sane. + /// + /// Verifies that the given request is an add-secret request by testing for some values to be + /// present. If the request contains signed user-data, the signature is verified with the + /// provided key. Outputs the arbitrary user-data. + Verify(VerifyOpt), + /// Print version information and exit. #[command(aliases(["--version"]), hide(true))] Version, diff --git a/rust/pvsecret/src/cmd.rs b/rust/pvsecret/src/cmd.rs index 5a655c4b..428605ce 100644 --- a/rust/pvsecret/src/cmd.rs +++ b/rust/pvsecret/src/cmd.rs @@ -5,6 +5,9 @@ mod create; pub use create::create; +mod verify; +pub use verify::verify; + // Commands (directly) related to UVCs are only available on s389x #[cfg(target_arch = "s390x")] mod add; diff --git a/rust/pvsecret/src/cmd/create.rs b/rust/pvsecret/src/cmd/create.rs index 203c65df..2c6fbe32 100644 --- a/rust/pvsecret/src/cmd/create.rs +++ b/rust/pvsecret/src/cmd/create.rs @@ -8,7 +8,7 @@ use log::{debug, info, trace, warn}; use pv::{ misc::{ get_writer_from_cli_file_arg, open_file, parse_hex, pv_guest_bit_set, read_certs, - read_exact_file, read_file, try_parse_u128, try_parse_u64, write, + read_exact_file, read_file, read_private_key, try_parse_u128, try_parse_u64, write, }, request::{ openssl::pkey::{PKey, Public}, @@ -106,6 +106,27 @@ fn build_asrcb(opt: &CreateSecretOpt) -> Result { asrcb.set_ext_secret(ExtSecret::Derived(read_exact_file(path, "CCK")?.into()))?; } + // add user data + let user_data = opt + .user_data + .as_ref() + .map(|p| read_file(p, "user-data")) + .transpose()?; + if user_data.as_ref().is_some_and(|data| data.is_empty()) { + warn!("Added empty user-data file."); + } + + let user_key = opt + .user_sign_key + .as_ref() + .map(|p| read_file(p, "User-signing key")) + .transpose()? + .map(|buf| read_private_key(&buf)) + .transpose()?; + + if user_data.is_some() || user_key.is_some() { + asrcb.set_user_data(user_data.unwrap_or_default(), user_key)?; + } Ok(asrcb) } @@ -140,7 +161,7 @@ fn try_from_val(val: Value) -> anyhow::Result { .ok_or(anyhow!("No 'cuid' entry found"))?; let cuid = cuid .strip_prefix("0x") - .ok_or(anyhow!("Value starts not with 0x".to_string()))? + .ok_or(anyhow!("CUID value starts not with 0x".to_string()))? .to_owned(); if cuid.len() != ::std::mem::size_of::() * 2 { return Err(anyhow!(format!("len invalid ({})", cuid.len()))); diff --git a/rust/pvsecret/src/cmd/verify.rs b/rust/pvsecret/src/cmd/verify.rs new file mode 100644 index 00000000..bfa79cfa --- /dev/null +++ b/rust/pvsecret/src/cmd/verify.rs @@ -0,0 +1,46 @@ +use anyhow::{anyhow, Context, Result}; +use log::warn; +use pv::{ + misc::{get_reader_from_cli_file_arg, get_writer_from_cli_file_arg, read_certs, read_file}, + request::{ + openssl::pkey::{PKey, Public}, + uvsecret::verify_asrcb_and_get_user_data, + }, +}; + +use crate::cli::VerifyOpt; + +/// read the content of a DER or PEM x509 and return the public key +fn read_sgn_key(path: &str) -> Result> { + read_certs(&read_file(path, "user-signing key")?)? + .get(0) + .ok_or(anyhow!("File does not contain a X509 certificate"))? + .public_key() + .map_err(anyhow::Error::new) +} + +pub fn verify(opt: &VerifyOpt) -> Result<()> { + let mut rd_in = get_reader_from_cli_file_arg(&opt.input)?; + let mut data_in = Vec::with_capacity(0x1000); + rd_in + .read_to_end(&mut data_in) + .with_context(|| format!("Cannot read input file {}", opt.input))?; + + let verify_cert = opt + .user_cert + .as_ref() + .map(|p| read_sgn_key(p)) + .transpose() + .context("Cannot read user-verification certificate.")?; + + let user_data = verify_asrcb_and_get_user_data(data_in, verify_cert) + .context("Could not verify the the Add-secret request")?; + + if let Some(user_data) = user_data { + get_writer_from_cli_file_arg(&opt.output)? + .write_all(&user_data) + .with_context(|| format!("Cannot write user data to {}", opt.output))?; + } + warn!("Successfully verified the request."); + Ok(()) +} diff --git a/rust/pvsecret/src/main.rs b/rust/pvsecret/src/main.rs index ebb2be27..5bcca106 100644 --- a/rust/pvsecret/src/main.rs +++ b/rust/pvsecret/src/main.rs @@ -25,6 +25,7 @@ const FEATURES: &[&str] = &[ "+lock", #[cfg(target_arch = "s390x")] "+list", + "+verify", ]; fn print_error(e: anyhow::Error, verbosity: u8) -> ExitCode { @@ -116,6 +117,7 @@ fn main() -> ExitCode { Command::Lock => not_supported(), Command::Create(opt) => cmd::create(opt), Command::Version => print_version(cli.verbose), + Command::Verify(opt) => cmd::verify(opt), }; match res {