mirror of
https://github.com/systemd/systemd.git
synced 2025-01-25 10:04:04 +03:00
measure: Add pcrpkey verb
This verb writes a public key to stdout extracted from either a public key path, from a certificate (path or provider) or from a private key (path, engine, provider). We'll use this in ukify to get rid of the use of the python cryptography module to convert a private key or certificate to a public key.
This commit is contained in:
parent
a1d46e3078
commit
c4bc0fd6de
@ -104,6 +104,16 @@
|
|||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v252"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v252"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><command>pcrpkey</command></term>
|
||||||
|
|
||||||
|
<listitem><para>This commands prints the public key either given with <option>--public-key=</option>,
|
||||||
|
or extracted from the certificate given with <option>--certificate=</option> or the private key given
|
||||||
|
with <option>--private-key=</option>.</para>
|
||||||
|
|
||||||
|
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
|||||||
" status Show current PCR values\n"
|
" status Show current PCR values\n"
|
||||||
" calculate Calculate expected PCR values\n"
|
" calculate Calculate expected PCR values\n"
|
||||||
" sign Calculate and sign expected PCR values\n"
|
" sign Calculate and sign expected PCR values\n"
|
||||||
|
" pcrpkey Extract the PCR public key\n"
|
||||||
"\n%3$sOptions:%4$s\n"
|
"\n%3$sOptions:%4$s\n"
|
||||||
" -h --help Show this help\n"
|
" -h --help Show this help\n"
|
||||||
" --version Print version\n"
|
" --version Print version\n"
|
||||||
@ -1173,12 +1174,100 @@ static int verb_status(int argc, char *argv[], void *userdata) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int verb_pcrpkey(int argc, char *argv[], void *userdata) {
|
||||||
|
_cleanup_(EVP_PKEY_freep) EVP_PKEY *public_key = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (arg_public_key) {
|
||||||
|
_cleanup_fclose_ FILE *public_keyf = NULL;
|
||||||
|
|
||||||
|
public_keyf = fopen(arg_public_key, "re");
|
||||||
|
if (!public_keyf)
|
||||||
|
return log_error_errno(errno, "Failed to open public key file '%s': %m", arg_public_key);
|
||||||
|
|
||||||
|
public_key = PEM_read_PUBKEY(public_keyf, NULL, NULL, NULL);
|
||||||
|
if (!public_key)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key '%s'.", arg_public_key);
|
||||||
|
|
||||||
|
} else if (arg_certificate) {
|
||||||
|
_cleanup_(X509_freep) X509 *certificate = NULL;
|
||||||
|
|
||||||
|
if (arg_certificate_source_type == OPENSSL_CERTIFICATE_SOURCE_FILE) {
|
||||||
|
r = parse_path_argument(arg_certificate, /*suppress_root=*/ false, &arg_certificate);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = openssl_load_x509_certificate(
|
||||||
|
arg_certificate_source_type,
|
||||||
|
arg_certificate_source,
|
||||||
|
arg_certificate,
|
||||||
|
&certificate);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to load X.509 certificate from %s: %m", arg_certificate);
|
||||||
|
|
||||||
|
public_key = X509_get_pubkey(certificate);
|
||||||
|
if (!public_key)
|
||||||
|
return log_error_errno(
|
||||||
|
SYNTHETIC_ERRNO(EIO),
|
||||||
|
"Failed to extract public key from certificate %s.",
|
||||||
|
arg_certificate);
|
||||||
|
|
||||||
|
} else if (arg_private_key) {
|
||||||
|
_cleanup_(openssl_ask_password_ui_freep) OpenSSLAskPasswordUI *ui = NULL;
|
||||||
|
_cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = NULL;
|
||||||
|
|
||||||
|
if (arg_private_key_source_type == OPENSSL_KEY_SOURCE_FILE) {
|
||||||
|
r = parse_path_argument(arg_private_key, /* suppress_root= */ false, &arg_private_key);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse private key path %s: %m", arg_private_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = openssl_load_private_key(
|
||||||
|
arg_private_key_source_type,
|
||||||
|
arg_private_key_source,
|
||||||
|
arg_private_key,
|
||||||
|
&(AskPasswordRequest) {
|
||||||
|
.id = "measure-private-key-pin",
|
||||||
|
.keyring = arg_private_key,
|
||||||
|
.credential = "measure.private-key-pin",
|
||||||
|
},
|
||||||
|
&private_key,
|
||||||
|
&ui);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to load private key from %s: %m", arg_private_key);
|
||||||
|
|
||||||
|
_cleanup_(memstream_done) MemStream m = {};
|
||||||
|
FILE *tf = memstream_init(&m);
|
||||||
|
if (!tf)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
if (i2d_PUBKEY_fp(tf, private_key) != 1)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EIO),
|
||||||
|
"Failed to extract public key from private key file '%s'.", arg_private_key);
|
||||||
|
|
||||||
|
fflush(tf);
|
||||||
|
rewind(tf);
|
||||||
|
|
||||||
|
if (!d2i_PUBKEY_fp(tf, &public_key))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EIO),
|
||||||
|
"Failed to parse extracted public key of private key file '%s'.", arg_private_key);
|
||||||
|
} else
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "One of --public-key=, --certificate=, or --private-key= must be specified");
|
||||||
|
|
||||||
|
if (PEM_write_PUBKEY(stdout, public_key) == 0)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key to stdout");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int measure_main(int argc, char *argv[]) {
|
static int measure_main(int argc, char *argv[]) {
|
||||||
static const Verb verbs[] = {
|
static const Verb verbs[] = {
|
||||||
{ "help", VERB_ANY, VERB_ANY, 0, help },
|
{ "help", VERB_ANY, VERB_ANY, 0, help },
|
||||||
{ "status", VERB_ANY, 1, VERB_DEFAULT, verb_status },
|
{ "status", VERB_ANY, 1, VERB_DEFAULT, verb_status },
|
||||||
{ "calculate", VERB_ANY, 1, 0, verb_calculate },
|
{ "calculate", VERB_ANY, 1, 0, verb_calculate },
|
||||||
{ "sign", VERB_ANY, 1, 0, verb_sign },
|
{ "sign", VERB_ANY, 1, 0, verb_sign },
|
||||||
|
{ "pcrpkey", VERB_ANY, 1, 0, verb_pcrpkey },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user