mirror of
https://github.com/stefanberger/libtpms
synced 2025-12-31 20:04:03 +00:00
tpm2: Implement BuildRSAKey for building an RSA EVP_PKEY
Implement BuildRSAKey for building an RSA EVP_PKEY from copies of the BIGNUMs it gets passed. This way it is clear that the caller has to free the BIGNUMs it passed itself also in case of error returned by BuildRSAKey. Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
parent
6a919f1c6a
commit
3eef1fb035
@ -407,20 +407,95 @@ ComputePrivateExponentD(
|
||||
return pOK;
|
||||
}
|
||||
|
||||
/* Build an RSA key from the given BIGUMs. The caller must always free
|
||||
* the passed BIGNUMs.
|
||||
*/
|
||||
static int
|
||||
BuildRSAKey(EVP_PKEY **ppkey, // OUT
|
||||
const BIGNUM *N, const BIGNUM *E, const BIGNUM *D,
|
||||
const BIGNUM *P, const BIGNUM *Q,
|
||||
const BIGNUM *DP, const BIGNUM *DQ, const BIGNUM *QInv)
|
||||
{
|
||||
BIGNUM *p, *q, *dP, *dQ, *qInv;
|
||||
BIGNUM *n = BN_dup(N);
|
||||
BIGNUM *e = BN_dup(E);
|
||||
BIGNUM *d = BN_dup(D);
|
||||
RSA *rsa;
|
||||
|
||||
if ((N && !n) || (E && !e) || (D && !d))
|
||||
goto error_free_ned;
|
||||
|
||||
if (P && Q && DP && DQ && QInv) {
|
||||
p = BN_dup(P);
|
||||
q = BN_dup(Q);
|
||||
dP = BN_dup(DP);
|
||||
dQ = BN_dup(DQ);
|
||||
qInv = BN_dup(QInv);
|
||||
if (!p || !q || !dP || !dQ || !qInv)
|
||||
goto error_free_bn;
|
||||
} else {
|
||||
p = q = dP = dQ = qInv = NULL;
|
||||
}
|
||||
|
||||
rsa = RSA_new();
|
||||
if (!rsa)
|
||||
goto error_free_bn;
|
||||
|
||||
if (RSA_set0_key(rsa, n, e, d) != 1)
|
||||
goto error;
|
||||
|
||||
n = e = d = NULL;
|
||||
|
||||
if (p) {
|
||||
if (RSA_set0_factors(rsa, p, q) != 1)
|
||||
goto error_free_rsa;
|
||||
p = q = NULL;
|
||||
|
||||
if (RSA_set0_crt_params(rsa, dP, dQ, qInv) != 1)
|
||||
goto error_free_rsa;
|
||||
dP = dQ = qInv = NULL;
|
||||
}
|
||||
|
||||
*ppkey = EVP_PKEY_new();
|
||||
if (*ppkey == NULL ||
|
||||
EVP_PKEY_assign_RSA(*ppkey, rsa) != 1)
|
||||
goto error;
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
EVP_PKEY_free(*ppkey);
|
||||
*ppkey = NULL;
|
||||
|
||||
error_free_rsa:
|
||||
RSA_free(rsa);
|
||||
|
||||
error_free_bn:
|
||||
BN_clear_free(p);
|
||||
BN_clear_free(q);
|
||||
BN_clear_free(dP);
|
||||
BN_clear_free(dQ);
|
||||
BN_clear_free(qInv);
|
||||
|
||||
error_free_ned:
|
||||
BN_free(n);
|
||||
BN_free(e);
|
||||
BN_clear_free(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIB_EXPORT TPM_RC
|
||||
InitOpenSSLRSAPublicKey(OBJECT *key, // IN
|
||||
EVP_PKEY **pkey // OUT
|
||||
)
|
||||
{
|
||||
TPM_RC retVal;
|
||||
RSA *rsakey = RSA_new();
|
||||
BIGNUM *N = NULL;
|
||||
BIGNUM *E = BN_new();
|
||||
BN_ULONG eval;
|
||||
|
||||
*pkey = EVP_PKEY_new();
|
||||
|
||||
if (rsakey == NULL || *pkey == NULL || E == NULL)
|
||||
if (E == NULL)
|
||||
ERROR_RETURN(TPM_RC_FAILURE);
|
||||
|
||||
if(key->publicArea.parameters.rsaDetail.exponent != 0)
|
||||
@ -434,17 +509,16 @@ InitOpenSSLRSAPublicKey(OBJECT *key, // IN
|
||||
N = BN_bin2bn(key->publicArea.unique.rsa.b.buffer,
|
||||
key->publicArea.unique.rsa.b.size, NULL);
|
||||
if (N == NULL ||
|
||||
RSA_set0_key(rsakey, N, E, NULL) != 1 ||
|
||||
EVP_PKEY_assign_RSA(*pkey, rsakey) == 0)
|
||||
BuildRSAKey(pkey, N, E, NULL, NULL, NULL, NULL, NULL, NULL) != 1)
|
||||
ERROR_RETURN(TPM_RC_FAILURE)
|
||||
|
||||
RSA_set_flags(rsakey, RSA_FLAG_NO_BLINDING);
|
||||
|
||||
retVal = TPM_RC_SUCCESS;
|
||||
|
||||
Exit:
|
||||
BN_free(N);
|
||||
BN_free(E);
|
||||
|
||||
if (retVal != TPM_RC_SUCCESS) {
|
||||
RSA_free(rsakey);
|
||||
EVP_PKEY_free(*pkey);
|
||||
*pkey = NULL;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user