mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
rust/pvsecret: User defined signatures and verifications
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 <mhartmay@linux.ibm.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
551f66282e
commit
98f7a0569c
@@ -45,6 +45,11 @@ Lock the secret-store (s390x only)
|
||||
List all ultravisor secrets (s390x only)
|
||||
</ul>
|
||||
|
||||
- **verify**
|
||||
<ul>
|
||||
Verify that an add-secret request is sane
|
||||
</ul>
|
||||
|
||||
## Options
|
||||
|
||||
`-v`, `--verbose`
|
||||
@@ -180,9 +185,9 @@ all requests.
|
||||
<ul>
|
||||
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.
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -204,6 +209,37 @@ Flags for the add-secret request
|
||||
</ul>
|
||||
|
||||
|
||||
`--user-data <FILE>`
|
||||
<ul>
|
||||
Use the content of FILE as user-data. Passes user data defined in <FILE> 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.
|
||||
</ul>
|
||||
|
||||
|
||||
`--user-sign-key <FILE>`
|
||||
<ul>
|
||||
Use the content of FILE as user signing key. Adds a signature defined calculated
|
||||
from the key in <FILE> 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.
|
||||
</ul>
|
||||
|
||||
|
||||
### 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
|
||||
</ul>
|
||||
|
||||
|
||||
## pvsecret verify
|
||||
### Synopsis
|
||||
`pvsecret verify [OPTIONS] <FILE>`
|
||||
### 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
|
||||
|
||||
`<FILE>`
|
||||
<ul>
|
||||
Specify the request to be checked
|
||||
</ul>
|
||||
|
||||
|
||||
### Options
|
||||
|
||||
`--user-cert <FILE>`
|
||||
<ul>
|
||||
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).
|
||||
</ul>
|
||||
|
||||
|
||||
`-o`, `--output <FILE>`
|
||||
<ul>
|
||||
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: '-'
|
||||
</ul>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <FILE>
|
||||
.RS 4
|
||||
Use the content of FILE as user-data. Passes user data defined in <FILE> 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 <FILE>
|
||||
.RS 4
|
||||
Use the content of FILE as user signing key. Adds a signature defined calculated
|
||||
from the key in <FILE> 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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
139
rust/pvsecret/man/pvsecret-verify.1
Normal file
139
rust/pvsecret/man/pvsecret-verify.1
Normal file
@@ -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] <FILE>
|
||||
.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
|
||||
<FILE>
|
||||
.RS 4
|
||||
Specify the request to be checked.
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.PP
|
||||
\-\-user-cert <FILE>
|
||||
.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 <FILE>
|
||||
.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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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<CreateSecretFlags>,
|
||||
|
||||
/// Use the content of FILE as user-data.
|
||||
///
|
||||
/// Passes user data defined in <FILE> 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<String>,
|
||||
|
||||
/// Use the content of FILE as user signing key.
|
||||
///
|
||||
/// Adds a signature calculated from the key in <FILE> 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<String>,
|
||||
}
|
||||
|
||||
#[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<String>,
|
||||
|
||||
/// 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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<AddSecretRequest> {
|
||||
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<ConfigUid> {
|
||||
.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::<ConfigUid>() * 2 {
|
||||
return Err(anyhow!(format!("len invalid ({})", cuid.len())));
|
||||
|
||||
46
rust/pvsecret/src/cmd/verify.rs
Normal file
46
rust/pvsecret/src/cmd/verify.rs
Normal file
@@ -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<PKey<Public>> {
|
||||
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(())
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user