Skip to content

Commit

Permalink
Fix OpenSSL 1.0 support in PKINIT
Browse files Browse the repository at this point in the history
Commit f745c9a uses ECDSA_SIG_set0(),
which was added in OpenSSL 1.1.  Add a compatibility version for
OpenSSL 1.0.

Commit bdcd607 uses
EVP_PKEY_get_base_id(), which was added in OpenSSL 1.1.  Add a
compatibility macro to use the old name for OpenSSL 1.0.

Commit 0f870b1 added ECDH support,
but did not change the OpenSSL 1.0 versions of encode_spki(),
decode_spki(), or generate_dh_pkey() to work with elliptic curve
public keys.  In each function, check the key type and skip the
DH-specific handling for key types other than DH.
  • Loading branch information
greghudson committed Mar 24, 2024
1 parent 458afb6 commit 28b1bea
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ create_identifiers_from_stack(STACK_OF(X509) *sk,
#define EVP_MD_CTX_new EVP_MD_CTX_create
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
#define ASN1_STRING_get0_data ASN1_STRING_data
#define EVP_PKEY_get_base_id EVP_PKEY_base_id

/*
* 1.1 adds DHX support, which uses the RFC 3279 DomainParameters encoding we
Expand Down Expand Up @@ -268,6 +269,15 @@ compat_get0_EC(const EVP_PKEY *pkey)
return pkey->pkey.ec;
}

#define ECDSA_SIG_set0 compat_ECDSA_SIG_set0
static int
compat_ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
{
sig->r = r;
sig->s = s;
return 1;
}

/* Return true if the cert c includes a key usage which doesn't include u.
* Define using direct member access for pre-1.1. */
#define ku_reject(c, u) \
Expand Down Expand Up @@ -496,6 +506,17 @@ encode_spki(EVP_PKEY *pkey, krb5_data *spki_out)
ASN1_TYPE parameter;
ASN1_STRING param_str, pubkey_str;

if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) {
/* Only DH keys require special encoding. */
len = i2d_PUBKEY(pkey, NULL);
ret = alloc_data(spki_out, len);
if (ret)
goto cleanup;
outptr = (uint8_t *)spki_out->data;
(void)i2d_PUBKEY(pkey, &outptr);
return 0;
}

dh = EVP_PKEY_get0_DH(pkey);
if (dh == NULL)
goto cleanup;
Expand Down Expand Up @@ -563,6 +584,13 @@ decode_spki(const krb5_data *spki)
if (pubkey == NULL)
goto cleanup;

if (OBJ_cmp(pubkey->algor->algorithm, OBJ_nid2obj(NID_dhKeyAgreement))) {
/* This is not a DH key, so we don't need special decoding. */
X509_PUBKEY_free(pubkey);
inptr = (uint8_t *)spki->data;
return d2i_PUBKEY(NULL, &inptr, spki->length);
}

if (pubkey->algor->parameter->type != V_ASN1_SEQUENCE)
goto cleanup;
params = pubkey->algor->parameter->value.sequence;
Expand Down Expand Up @@ -802,7 +830,8 @@ generate_dh_pkey(EVP_PKEY *params)
goto cleanup;
if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
goto cleanup;
if (!copy_q_openssl10(params, pkey)) {
if (EVP_PKEY_get_base_id(pkey) == EVP_PKEY_DH &&
!copy_q_openssl10(params, pkey)) {
EVP_PKEY_free(pkey);
pkey = NULL;
}
Expand Down

0 comments on commit 28b1bea

Please sign in to comment.