diff options
author | Greg Hudson <ghudson@mit.edu> | 2024-03-21 19:04:13 -0400 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 2024-03-26 11:20:23 -0400 |
commit | d6186c447f9ec85b9f5fb11f315db45c7648e919 (patch) | |
tree | 90bc5d60a0f12f6cfd16928781ee5f7f4ed96dec | |
parent | ebe416acff31616a342d27876e510007d426aae9 (diff) | |
download | krb5-d6186c447f9ec85b9f5fb11f315db45c7648e919.zip krb5-d6186c447f9ec85b9f5fb11f315db45c7648e919.tar.gz krb5-d6186c447f9ec85b9f5fb11f315db45c7648e919.tar.bz2 |
Fix OpenSSL 1.0 and 1.1 support in PKINIT
Commit f745c9a9bd6c0c73b944182173f1ac305d03dc3a uses ECDSA_SIG_set0(),
which was added in OpenSSL 1.1. Add a compatibility version for
OpenSSL 1.0.
Commit bdcd6075bd4593c8f67722ce075c9519faec58b7 uses
EVP_PKEY_get_base_id(), which was added in OpenSSL 3.0. Add a
compatibility macro to use the old name for OpenSSL 1.0 and 1.1.
Commit 0f870b1bcad960fd5319a3f97aafd7f4a289e2fb 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.
-rw-r--r-- | src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c index d9cc248..2f26197 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c @@ -268,6 +268,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) \ @@ -285,6 +294,7 @@ compat_get0_EC(const EVP_PKEY *pkey) #define EVP_PKEY_parameters_eq EVP_PKEY_cmp_parameters #define EVP_PKEY_get_size EVP_PKEY_size #define EVP_PKEY_get_bits EVP_PKEY_bits +#define EVP_PKEY_get_base_id EVP_PKEY_base_id /* * Convert *dh to an EVP_PKEY object, taking ownership of *dh and setting it to @@ -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; @@ -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; @@ -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; } |