1
0
mirror of https://github.com/systemd/systemd.git synced 2025-08-29 01:49:55 +03:00

tpm2: move openssl-required ifdef code out of policy-building function

This commit is contained in:
Dan Streetman
2022-12-08 16:57:47 -05:00
committed by Luca Boccassi
parent 46b8c3f5b2
commit 9589824158

View File

@ -1476,21 +1476,38 @@ static int tpm2_make_encryption_session(
return 0;
}
static int openssl_pubkey_to_tpm2_pubkey(
const void *pubkey,
size_t pubkey_size,
TPM2B_PUBLIC *output,
void **ret_fp,
size_t *ret_fp_size) {
#if HAVE_OPENSSL
static int openssl_pubkey_to_tpm2_pubkey(EVP_PKEY *input, TPM2B_PUBLIC *output) {
#if OPENSSL_VERSION_MAJOR >= 3
_cleanup_(BN_freep) BIGNUM *n = NULL, *e = NULL;
#else
const BIGNUM *n = NULL, *e = NULL;
const RSA *rsa = NULL;
#endif
int n_bytes, e_bytes;
int r, n_bytes, e_bytes;
assert(input);
assert(pubkey);
assert(pubkey_size > 0);
assert(output);
/* Converts an OpenSSL public key to a structure that the TPM chip can process. */
_cleanup_fclose_ FILE *f = NULL;
f = fmemopen((void*) pubkey, pubkey_size, "r");
if (!f)
return log_oom();
_cleanup_(EVP_PKEY_freep) EVP_PKEY *input = NULL;
input = PEM_read_PUBKEY(f, NULL, NULL, NULL);
if (!input)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse PEM public key.");
if (EVP_PKEY_base_id(input) != EVP_PKEY_RSA)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Provided public key is not an RSA key.");
@ -1557,22 +1574,38 @@ static int openssl_pubkey_to_tpm2_pubkey(EVP_PKEY *input, TPM2B_PUBLIC *output)
if (BN_bn2bin(e, (unsigned char*) &output->publicArea.parameters.rsaDetail.exponent) <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to convert RSA exponent.");
if (ret_fp) {
_cleanup_free_ void *fp = NULL;
size_t fp_size;
assert(ret_fp_size);
r = pubkey_fingerprint(input, EVP_sha256(), &fp, &fp_size);
if (r < 0)
return log_error_errno(r, "Failed to calculate public key fingerprint: %m");
*ret_fp = TAKE_PTR(fp);
*ret_fp_size = fp_size;
}
return 0;
#else /* HAVE_OPENSSL */
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
#endif
}
static int find_signature(
JsonVariant *v,
uint16_t pcr_bank,
uint32_t pcr_mask,
EVP_PKEY *pk,
const TPML_PCR_SELECTION *pcr_selection,
const void *fp,
size_t fp_size,
const void *policy,
size_t policy_size,
void *ret_signature,
size_t *ret_signature_size) {
_cleanup_free_ void *fp = NULL;
#if HAVE_OPENSSL
JsonVariant *b, *i;
size_t fp_size;
const char *k;
int r;
@ -1582,6 +1615,12 @@ static int find_signature(
if (!json_variant_is_object(v))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Signature is not a JSON object.");
uint16_t pcr_bank = pcr_selection->pcrSelections[0].hash;
uint32_t pcr_mask;
r = tpm2_tpml_pcr_selection_to_mask(pcr_selection, pcr_bank, &pcr_mask);
if (r < 0)
return r;
k = tpm2_hash_alg_to_string(pcr_bank);
if (!k)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Don't know PCR bank %" PRIu16, pcr_bank);
@ -1625,12 +1664,6 @@ static int find_signature(
if (r < 0)
return log_error_errno(r, "Failed to decode fingerprint in JSON data: %m");
if (!fp) {
r = pubkey_fingerprint(pk, EVP_sha256(), &fp, &fp_size);
if (r < 0)
return log_error_errno(r, "Failed to calculate public key fingerprint: %m");
}
if (memcmp_nn(fp, fp_size, fpj_data, fpj_size) != 0)
continue; /* Not for this public key */
@ -1655,8 +1688,10 @@ static int find_signature(
}
return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "Couldn't find signature for this PCR bank, PCR index and public key.");
}
#else /* HAVE_OPENSSL */
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
#endif
}
static int tpm2_make_policy_session(
Tpm2Context *c,
@ -1718,21 +1753,6 @@ static int tpm2_make_policy_session(
}
}
#if HAVE_OPENSSL
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pk = NULL;
if (pubkey_size > 0) {
/* If a pubkey is specified, load it to validate it, even if the PCR mask for this is
* actually zero, and we are thus not going to use it. */
_cleanup_fclose_ FILE *f = fmemopen((void*) pubkey, pubkey_size, "r");
if (!f)
return log_oom();
pk = PEM_read_PUBKEY(f, NULL, NULL, NULL);
if (!pk)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse PEM public key.");
}
#endif
_cleanup_tpm2_handle_ Tpm2Handle *session = NULL;
r = tpm2_handle_new(c, &session);
if (r < 0)
@ -1755,12 +1775,14 @@ static int tpm2_make_policy_session(
"Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc));
if (pubkey_pcr_mask != 0) {
#if HAVE_OPENSSL
_cleanup_free_ void *fp = NULL;
size_t fp_size = 0;
TPM2B_PUBLIC pubkey_tpm2;
log_debug("Configuring public key based PCR policy.");
/* First: load public key into the TPM */
TPM2B_PUBLIC pubkey_tpm2;
r = openssl_pubkey_to_tpm2_pubkey(pk, &pubkey_tpm2);
/* Convert the PEM key to TPM2 format */
r = openssl_pubkey_to_tpm2_pubkey(pubkey, pubkey_size, &pubkey_tpm2, &fp, &fp_size);
if (r < 0)
return r;
@ -1828,9 +1850,8 @@ static int tpm2_make_policy_session(
r = find_signature(
signature_json,
pcr_bank,
pubkey_pcr_mask,
pk,
&pcr_selection,
fp, fp_size,
approved_policy->buffer,
approved_policy->size,
&signature_raw,
@ -1894,9 +1915,6 @@ static int tpm2_make_policy_session(
if (rc != TSS2_RC_SUCCESS)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
"Failed to push Authorize policy into TPM: %s", sym_Tss2_RC_Decode(rc));
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
#endif
}
if (hash_pcr_mask != 0) {