From 4fe68a979a09d73fb02d2681cacec916b58db752 Mon Sep 17 00:00:00 2001 From: Gilles Chehade Date: Mon, 30 Nov 2020 23:30:29 +0100 Subject: bring privsep ECDSA support for OpenSSL --- usr.sbin/smtpd/ca.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++----- usr.sbin/smtpd/ssl.c | 5 +- 2 files changed, 143 insertions(+), 17 deletions(-) diff --git a/usr.sbin/smtpd/ca.c b/usr.sbin/smtpd/ca.c index a27db87a..78ce64c5 100644 --- a/usr.sbin/smtpd/ca.c +++ b/usr.sbin/smtpd/ca.c @@ -65,13 +65,11 @@ static int rsae_init(RSA *); static int rsae_finish(RSA *); static int rsae_keygen(RSA *, int, BIGNUM *, BN_GENCB *); -#if defined(SUPPORT_ECDSA) static ECDSA_SIG *ecdsae_do_sign(const unsigned char *, int, const BIGNUM *, const BIGNUM *, EC_KEY *); static int ecdsae_sign_setup(EC_KEY *, BN_CTX *, BIGNUM **, BIGNUM **); static int ecdsae_do_verify(const unsigned char *, int, const ECDSA_SIG *, EC_KEY *); -#endif static uint64_t reqid = 0; @@ -230,17 +228,13 @@ void ca_imsg(struct mproc *p, struct imsg *imsg) { RSA *rsa = NULL; -#if defined(SUPPORT_ECDSA) EC_KEY *ecdsa = NULL; -#endif const void *from = NULL; unsigned char *to = NULL; struct msg m; const char *pkiname; size_t flen, tlen, padding; -#if defined(SUPPORT_ECDSA) int buf_len; -#endif struct pki *pki; int ret = 0; uint64_t id; @@ -313,7 +307,6 @@ ca_imsg(struct mproc *p, struct imsg *imsg) RSA_free(rsa); return; -#if defined(SUPPORT_ECDSA) case IMSG_CA_ECDSA_SIGN: m_msg(&m, imsg); m_get_id(&m, &id); @@ -329,6 +322,7 @@ ca_imsg(struct mproc *p, struct imsg *imsg) buf_len = ECDSA_size(ecdsa); if ((to = calloc(1, buf_len)) == NULL) fatalx("ca_imsg: calloc"); + ret = ECDSA_sign(0, from, flen, to, &buf_len, ecdsa); m_create(p, imsg->hdr.type, 0, 0, -1); m_add_id(p, id); @@ -339,7 +333,6 @@ ca_imsg(struct mproc *p, struct imsg *imsg) free(to); EC_KEY_free(ecdsa); return; -#endif } errx(1, "ca_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type)); } @@ -510,15 +503,11 @@ rsae_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) } -#if defined(SUPPORT_ECDSA) /* * ECDSA privsep engine (called from unprivileged processes) */ -const ECDSA_METHOD *ecdsa_default = NULL; - -static ECDSA_METHOD *ecdsae_method = NULL; - +#if defined(SUPPORT_ECDSA) ECDSA_METHOD * ECDSA_METHOD_new_temporary(const char *name, int); @@ -538,6 +527,11 @@ ECDSA_METHOD_new_temporary(const char *name, int flags) ecdsa->flags = flags; return ecdsa; } +#else +const EC_KEY_METHOD *ecdsa_default = NULL; + +static EC_KEY_METHOD *ecdsae_method = NULL; +#endif static ECDSA_SIG * ecdsae_send_enc_imsg(const unsigned char *dgst, int dgst_len, @@ -554,8 +548,13 @@ ecdsae_send_enc_imsg(const unsigned char *dgst, int dgst_len, uint64_t id; ECDSA_SIG *sig = NULL; +#if defined(SUPPORT_ECDSA) if ((pkiname = ECDSA_get_ex_data(eckey, 0)) == NULL) return (0); +#else + if ((pkiname = EC_KEY_get_ex_data(eckey, 0)) == NULL) + return (0); +#endif /* * Send a synchronous imsg because we cannot defer the ECDSA @@ -613,6 +612,7 @@ ecdsae_send_enc_imsg(const unsigned char *dgst, int dgst_len, return (sig); } +#if defined(SUPPORT_ECDSA) ECDSA_SIG * ecdsae_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey) @@ -621,6 +621,7 @@ ecdsae_do_sign(const unsigned char *dgst, int dgst_len, if (ECDSA_get_ex_data(eckey, 0) != NULL) return (ecdsae_send_enc_imsg(dgst, dgst_len, inv, rp, eckey)); return (ecdsa_default->ecdsa_do_sign(dgst, dgst_len, inv, rp, eckey)); + } int @@ -638,6 +639,79 @@ ecdsae_do_verify(const unsigned char *dgst, int dgst_len, log_debug("debug: %s: %s", proc_name(smtpd_process), __func__); return (ecdsa_default->ecdsa_do_verify(dgst, dgst_len, sig, eckey)); } +#else +int +ecdsae_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)(int type, const unsigned char *dgst, + int dlen, unsigned char *sig, + unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey); + + log_debug("debug: %s: %s", proc_name(smtpd_process), __func__); + EC_KEY_METHOD_get_sign(ecdsa_default, + &sign, + NULL, + NULL); + return (sign(type, dgst, dlen, sig, siglen, kinv, r, eckey)); + + + return 0; +} + + +ECDSA_SIG * +ecdsae_do_sign(const unsigned char *dgst, int dgst_len, + const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey) +{ + ECDSA_SIG *(*psign_sig)(const unsigned char *dgst, + int dgst_len, + const BIGNUM *in_kinv, + const BIGNUM *in_r, + EC_KEY *eckey); + + log_debug("debug: %s: %s", proc_name(smtpd_process), __func__); + if (EC_KEY_get_ex_data(eckey, 0) != NULL) + return (ecdsae_send_enc_imsg(dgst, dgst_len, inv, rp, eckey)); + EC_KEY_METHOD_get_sign(ecdsa_default, + NULL, + NULL, + &psign_sig); + return (psign_sig(dgst, dgst_len, inv, rp, eckey)); +} + +int +ecdsae_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, + BIGNUM **r) +{ + int (*psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp); + + log_debug("debug: %s: %s", proc_name(smtpd_process), __func__); + EC_KEY_METHOD_get_sign(ecdsa_default, + NULL, + &psign_setup, + NULL); + return (psign_setup(eckey, ctx, kinv, r)); +} + +int +ecdsae_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) +{ + int (*pverify_sig)(const unsigned char *dgst, + int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey); + + log_debug("debug: %s: %s", proc_name(smtpd_process), __func__); + EC_KEY_METHOD_get_verify(ecdsa_default, + NULL, + &pverify_sig); + return (pverify_sig(dgst, dgst_len, sig, eckey)); +} #endif static void @@ -765,13 +839,64 @@ ecdsa_engine_init(void) ssl_error(errstr); fatalx("%s", errstr); } +#else +static void +ecdsa_engine_init(void) +{ + ENGINE *e; + const char *errstr, *name; + + if ((ecdsae_method = EC_KEY_METHOD_new(NULL)) == NULL) { + errstr = "EC_KEY_new"; + goto fail; + } + + EC_KEY_METHOD_set_sign(ecdsae_method, ecdsae_sign, ecdsae_sign_setup, + ecdsae_do_sign); + EC_KEY_METHOD_set_verify(ecdsae_method, NULL, ecdsae_do_verify); + + if ((e = ENGINE_get_default_EC()) == NULL) { + if ((e = ENGINE_new()) == NULL) { + errstr = "ENGINE_new"; + goto fail; + } + if (!ENGINE_set_name(e, "ECDSA privsep engine")) { + errstr = "ENGINE_set_name"; + goto fail; + } + if ((ecdsa_default = EC_KEY_get_default_method()) == NULL) { + errstr = "EC_KEY_get_default_method"; + goto fail; + } + } else if ((ecdsa_default = ENGINE_get_EC(e)) == NULL) { + errstr = "ENGINE_get_EC"; + goto fail; + } + + if ((name = ENGINE_get_name(e)) == NULL) + name = "unknown ECDSA engine"; + + log_debug("debug: %s: using %s", __func__, name); + + if (!ENGINE_set_EC(e, ecdsae_method)) { + errstr = "ENGINE_set_EC"; + goto fail; + } + if (!ENGINE_set_default_EC(e)) { + errstr = "ENGINE_set_default_EC"; + goto fail; + } + return; + + fail: + ssl_error(errstr); + fatalx("%s", errstr); +} #endif void ca_engine_init(void) { rsa_engine_init(); -#if defined(SUPPORT_ECDSA) ecdsa_engine_init(); -#endif } diff --git a/usr.sbin/smtpd/ssl.c b/usr.sbin/smtpd/ssl.c index a37d6fea..97f7b1df 100644 --- a/usr.sbin/smtpd/ssl.c +++ b/usr.sbin/smtpd/ssl.c @@ -400,11 +400,12 @@ ssl_load_pkey(const void *data, size_t datalen, char *buf, off_t len, #if defined(SUPPORT_ECDSA) if (eckey) ECDSA_set_ex_data(eckey, 0, exdata); +#else + if (eckey) + EC_KEY_set_ex_data(eckey, 0, exdata); #endif RSA_free(rsa); /* dereference, will be cleaned up with pkey */ -#if defined(SUPPORT_ECDSA) EC_KEY_free(eckey); /* dereference, will be cleaned up with pkey */ -#endif } *x509ptr = x509; -- cgit v1.2.3-59-g8ed1b From 2abb6b08f0f04d5c349e0baaee71a4991e7aa304 Mon Sep 17 00:00:00 2001 From: Gilles Chehade Date: Mon, 30 Nov 2020 23:56:53 +0100 Subject: add missing method in engine --- usr.sbin/smtpd/ca.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/usr.sbin/smtpd/ca.c b/usr.sbin/smtpd/ca.c index 78ce64c5..a107eb31 100644 --- a/usr.sbin/smtpd/ca.c +++ b/usr.sbin/smtpd/ca.c @@ -697,6 +697,22 @@ ecdsae_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, return (psign_setup(eckey, ctx, kinv, r)); } +int +ecdsae_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) +{ + int (*verify)(int type, const unsigned + char *dgst, int dgst_len, + const unsigned char *sigbuf, + int sig_len, EC_KEY *eckey); + + log_debug("debug: %s: %s", proc_name(smtpd_process), __func__); + EC_KEY_METHOD_get_verify(ecdsa_default, + &verify, + NULL); + return (verify(type, dgst, dgst_len, sigbuf, sig_len, eckey)); +} + int ecdsae_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey) @@ -853,7 +869,7 @@ ecdsa_engine_init(void) EC_KEY_METHOD_set_sign(ecdsae_method, ecdsae_sign, ecdsae_sign_setup, ecdsae_do_sign); - EC_KEY_METHOD_set_verify(ecdsae_method, NULL, ecdsae_do_verify); + EC_KEY_METHOD_set_verify(ecdsae_method, ecdsae_verify, ecdsae_do_verify); if ((e = ENGINE_get_default_EC()) == NULL) { if ((e = ENGINE_new()) == NULL) { -- cgit v1.2.3-59-g8ed1b From 7e7f97f26ee419f5f074e09cea2761470db93d46 Mon Sep 17 00:00:00 2001 From: Gilles CHEHADE Date: Tue, 1 Dec 2020 18:23:01 +0100 Subject: missing operations for ECDSA --- usr.sbin/smtpd/ca.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/usr.sbin/smtpd/ca.c b/usr.sbin/smtpd/ca.c index a107eb31..56c5be2a 100644 --- a/usr.sbin/smtpd/ca.c +++ b/usr.sbin/smtpd/ca.c @@ -640,6 +640,28 @@ ecdsae_do_verify(const unsigned char *dgst, int dgst_len, return (ecdsa_default->ecdsa_do_verify(dgst, dgst_len, sig, eckey)); } #else +int +ecdsae_keygen(EC_KEY *eckey) +{ + int (*keygen)(EC_KEY *key); + EC_KEY_METHOD_get_keygen(ecdsa_default, + &keygen); + return keygen(eckey); +} + +int +ecdsae_compute_key(unsigned char **psec, size_t *pseclen, + const EC_POINT *pub_key, const EC_KEY *ecdh) +{ + int (*ckey)(unsigned char **psec, + size_t *pseclen, + const EC_POINT *pub_key, + const EC_KEY *ecdh); + EC_KEY_METHOD_get_compute_key(ecdsa_default, + &ckey); + return ckey(psec, pseclen, pub_key, ecdh); +} + int ecdsae_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey) @@ -867,6 +889,8 @@ ecdsa_engine_init(void) goto fail; } + EC_KEY_METHOD_set_keygen(ecdsae_method, ecdsae_keygen); + EC_KEY_METHOD_set_compute_key(ecdsae_method, ecdsae_compute_key); EC_KEY_METHOD_set_sign(ecdsae_method, ecdsae_sign, ecdsae_sign_setup, ecdsae_do_sign); EC_KEY_METHOD_set_verify(ecdsae_method, ecdsae_verify, ecdsae_do_verify); -- cgit v1.2.3-59-g8ed1b From dde3baad351c5f3cba372d2e1d01c3fdbf0ca664 Mon Sep 17 00:00:00 2001 From: Gilles Chehade Date: Tue, 1 Dec 2020 18:26:54 +0100 Subject: whitespces --- usr.sbin/smtpd/ca.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/usr.sbin/smtpd/ca.c b/usr.sbin/smtpd/ca.c index 56c5be2a..a8862cdc 100644 --- a/usr.sbin/smtpd/ca.c +++ b/usr.sbin/smtpd/ca.c @@ -643,23 +643,23 @@ ecdsae_do_verify(const unsigned char *dgst, int dgst_len, int ecdsae_keygen(EC_KEY *eckey) { - int (*keygen)(EC_KEY *key); - EC_KEY_METHOD_get_keygen(ecdsa_default, - &keygen); - return keygen(eckey); + int (*keygen)(EC_KEY *key); + EC_KEY_METHOD_get_keygen(ecdsa_default, + &keygen); + return keygen(eckey); } int ecdsae_compute_key(unsigned char **psec, size_t *pseclen, const EC_POINT *pub_key, const EC_KEY *ecdh) { - int (*ckey)(unsigned char **psec, - size_t *pseclen, - const EC_POINT *pub_key, - const EC_KEY *ecdh); - EC_KEY_METHOD_get_compute_key(ecdsa_default, - &ckey); - return ckey(psec, pseclen, pub_key, ecdh); + int (*ckey)(unsigned char **psec, + size_t *pseclen, + const EC_POINT *pub_key, + const EC_KEY *ecdh); + EC_KEY_METHOD_get_compute_key(ecdsa_default, + &ckey); + return ckey(psec, pseclen, pub_key, ecdh); } int @@ -678,9 +678,6 @@ ecdsae_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, NULL, NULL); return (sign(type, dgst, dlen, sig, siglen, kinv, r, eckey)); - - - return 0; } -- cgit v1.2.3-59-g8ed1b From cc454d93bbca229f0b553f6243cd9b4879192fd1 Mon Sep 17 00:00:00 2001 From: Gilles CHEHADE Date: Wed, 2 Dec 2020 09:27:08 +0100 Subject: if ECDSA_METHOD exists, declare pointers --- usr.sbin/smtpd/ca.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/usr.sbin/smtpd/ca.c b/usr.sbin/smtpd/ca.c index a8862cdc..b36033b4 100644 --- a/usr.sbin/smtpd/ca.c +++ b/usr.sbin/smtpd/ca.c @@ -508,6 +508,10 @@ rsae_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) */ #if defined(SUPPORT_ECDSA) +const ECDSA_METHOD *ecdsa_default = NULL; + +static ECDSA_METHOD *ecdsae_method = NULL; + ECDSA_METHOD * ECDSA_METHOD_new_temporary(const char *name, int); -- cgit v1.2.3-59-g8ed1b