From 043c47eb840502d452e179692bbf6ba3ef707943 Mon Sep 17 00:00:00 2001 From: tb Date: Sun, 18 Jun 2023 17:50:28 +0000 Subject: [PATCH] tls_signer: reinstate the default EC_KEY methods Previously, we would set the ECDSA_METHOD on the EC_KEY, which, by way of lovely indirection in our three crypto/ec* directories ended up having no effect on the default methods. Now that we set a new EC_KEY_METHOD, we need to make sure we still have the other handlers that we might need. Like so many things that were made opaque in the 1.1 re"design", the accessors were written without actual application code in mind. In particular, EC_KEY_METHOD lacks a dup(). This means we get to fetch the default methods with getters and then set them again on the new method. This is particularly awesome because once someone adds a new method to the opaque struct, all applications will have to adapt and do a get/set dance. So far this is very reminiscent of PostgreSQL with BIO_meth_* https://github.com/postgres/postgres/blob/a14e75eb0b6a73821e0d66c0d407372ec8376105/src/interfaces/libpq/fe-secure-openssl.c#L1921-L1928 Only it's worse here because someone wanted to be smart and save a few public functions, so we have to use getters that get several functions at once. Which in turn means we need to have function pointers with the precise signatures which are part of the struct that was made opaque. We will add a EC_KEY_METHOD_dup() in the next bump, but for now this is the best fix we can have. Whenever you think you've seen the worst turds in this code base, you find another one that could serve as an exemplar. ok jsing op --- lib/libtls/tls_signer.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/libtls/tls_signer.c b/lib/libtls/tls_signer.c index c1b60bfcc44..78206d1223b 100644 --- a/lib/libtls/tls_signer.c +++ b/lib/libtls/tls_signer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_signer.c,v 1.7 2023/06/18 17:24:09 tb Exp $ */ +/* $OpenBSD: tls_signer.c,v 1.8 2023/06/18 17:50:28 tb Exp $ */ /* * Copyright (c) 2021 Eric Faurot * @@ -423,6 +423,20 @@ EC_KEY_METHOD * tls_signer_ecdsa_method(void) { static EC_KEY_METHOD *ecdsa_method = NULL; + const EC_KEY_METHOD *default_method; + int (*keygen)(EC_KEY *key); + int (*compute_key)(void *out, size_t outlen, const EC_POINT *pub_key, + EC_KEY *ecdh, void *(*KDF) (const void *in, size_t inlen, void *out, + size_t *outlen)); + int (*sign)(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey); + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp); + int (*verify)(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); + int (*verify_sig)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); pthread_mutex_lock(&signer_method_lock); @@ -433,7 +447,20 @@ tls_signer_ecdsa_method(void) if (ecdsa_method == NULL) goto out; - EC_KEY_METHOD_set_sign(ecdsa_method, NULL, NULL, tls_ecdsa_do_sign); + default_method = EC_KEY_get_default_method(); + + EC_KEY_METHOD_get_keygen(default_method, &keygen); + EC_KEY_METHOD_set_keygen(ecdsa_method, keygen); + + EC_KEY_METHOD_get_compute_key(default_method, &compute_key); + EC_KEY_METHOD_set_compute_key(ecdsa_method, compute_key); + + EC_KEY_METHOD_get_sign(default_method, &sign, &sign_setup, NULL); + EC_KEY_METHOD_set_sign(ecdsa_method, sign, sign_setup, + tls_ecdsa_do_sign); + + EC_KEY_METHOD_get_verify(default_method, &verify, &verify_sig); + EC_KEY_METHOD_set_verify(ecdsa_method, verify, verify_sig); out: pthread_mutex_unlock(&signer_method_lock); -- 2.20.1