From: reyk Date: Tue, 20 May 2014 17:33:36 +0000 (+0000) Subject: Unify the SSL privsep key loading functions. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=d5cc82f924d898862a07be7309a19b6e058300f5;p=openbsd Unify the SSL privsep key loading functions. ok eric@ --- diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c index d6d4cf6e43b..02d52aecc20 100644 --- a/usr.sbin/relayd/relay.c +++ b/usr.sbin/relayd/relay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay.c,v 1.169 2014/04/22 08:04:23 reyk Exp $ */ +/* $OpenBSD: relay.c,v 1.170 2014/05/20 17:33:36 reyk Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -1914,7 +1914,7 @@ relay_ssl_ctx_create(struct relay *rlay) log_debug("%s: loading private key", __func__); if (!ssl_ctx_fake_private_key(ctx, - &rlay->rl_conf.ssl_keyid, + &rlay->rl_conf.ssl_keyid, sizeof(rlay->rl_conf.ssl_keyid), rlay->rl_ssl_cert, rlay->rl_conf.ssl_cert_len, &rlay->rl_ssl_x509, &rlay->rl_ssl_pkey)) goto err; @@ -1924,9 +1924,9 @@ relay_ssl_ctx_create(struct relay *rlay) if (rlay->rl_conf.ssl_cacert_len) { log_debug("%s: loading CA private key", __func__); - if (!ssl_ctx_load_pkey(ctx, - &rlay->rl_conf.ssl_cakeyid, rlay->rl_ssl_cacert, - rlay->rl_conf.ssl_cacert_len, + if (!ssl_load_pkey(&rlay->rl_conf.ssl_cakeyid, + sizeof(rlay->rl_conf.ssl_cakeyid), + rlay->rl_ssl_cacert, rlay->rl_conf.ssl_cacert_len, &rlay->rl_ssl_cacertx509, &rlay->rl_ssl_capkey)) goto err; } diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index d5adaac4f14..9e95790e9d1 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.179 2014/05/08 13:08:48 blambert Exp $ */ +/* $OpenBSD: relayd.h,v 1.180 2014/05/20 17:33:36 reyk Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -1111,10 +1111,10 @@ SSL_CTX *ssl_ctx_create(struct relayd *); void ssl_error(const char *, const char *); char *ssl_load_key(struct relayd *, const char *, off_t *, char *); X509 *ssl_update_certificate(X509 *, EVP_PKEY *, EVP_PKEY *, X509 *); -int ssl_ctx_load_pkey(SSL_CTX *, void *, char *, off_t, - X509 **, EVP_PKEY **); -int ssl_ctx_fake_private_key(SSL_CTX *, void *, char *, off_t, +int ssl_load_pkey(const void *, size_t, char *, off_t, X509 **, EVP_PKEY **); +int ssl_ctx_fake_private_key(SSL_CTX *, const void *, size_t, + char *, off_t, X509 **, EVP_PKEY **); /* ssl_privsep.c */ int ssl_ctx_use_certificate_chain(SSL_CTX *, char *, off_t); diff --git a/usr.sbin/relayd/ssl.c b/usr.sbin/relayd/ssl.c index 9f09d6ba0b8..4544d53cc3a 100644 --- a/usr.sbin/relayd/ssl.c +++ b/usr.sbin/relayd/ssl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl.c,v 1.23 2014/05/06 11:03:02 reyk Exp $ */ +/* $OpenBSD: ssl.c,v 1.24 2014/05/20 17:33:36 reyk Exp $ */ /* * Copyright (c) 2007 - 2014 Reyk Floeter @@ -405,14 +405,14 @@ ssl_update_certificate(X509 *oldcert, EVP_PKEY *pkey, EVP_PKEY *capkey, } int -ssl_ctx_load_pkey(SSL_CTX *ctx, void *data, char *buf, off_t len, +ssl_load_pkey(const void *data, size_t datalen, char *buf, off_t len, X509 **x509ptr, EVP_PKEY **pkeyptr) { - int ret = 0; BIO *in; X509 *x509 = NULL; EVP_PKEY *pkey = NULL; RSA *rsa = NULL; + void *exdata = NULL; if ((in = BIO_new_mem_buf(buf, len)) == NULL) { SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_BUF_LIB); @@ -430,42 +430,48 @@ ssl_ctx_load_pkey(SSL_CTX *ctx, void *data, char *buf, off_t len, goto fail; } - if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_EVP_LIB); - goto fail; - } + BIO_free(in); - RSA_set_ex_data(rsa, 0, data); - RSA_free(rsa); /* dereference, will be cleaned up with pkey */ + if (data != NULL && datalen) { + if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL || + (exdata = malloc(datalen)) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_EVP_LIB); + goto fail; + } + + memcpy(exdata, data, datalen); + RSA_set_ex_data(rsa, 0, exdata); + RSA_free(rsa); /* dereference, will be cleaned up with pkey */ + } *x509ptr = x509; *pkeyptr = pkey; - ret = 1; - goto done; + return (1); fail: + if (rsa != NULL) + RSA_free(rsa); + if (in != NULL) + BIO_free(in); if (pkey != NULL) EVP_PKEY_free(pkey); if (x509 != NULL) X509_free(x509); - done: - if (in != NULL) - BIO_free(in); - - return ret; + return (0); } int -ssl_ctx_fake_private_key(SSL_CTX *ctx, void *data, char *buf, off_t len, - X509 **x509ptr, EVP_PKEY **pkeyptr) +ssl_ctx_fake_private_key(SSL_CTX *ctx, const void *data, size_t datalen, + char *buf, off_t len, X509 **x509ptr, EVP_PKEY **pkeyptr) { - int ret; + int ret = 0; + EVP_PKEY *pkey = NULL; + X509 *x509 = NULL; - if (!(ret = ssl_ctx_load_pkey(ctx, data, buf, len, - x509ptr, pkeyptr))) - goto fail; + if (!ssl_load_pkey(data, datalen, buf, len, &x509, &pkey)) + return (0); /* * Use the public key as the "private" key - the secret key @@ -473,20 +479,20 @@ ssl_ctx_fake_private_key(SSL_CTX *ctx, void *data, char *buf, off_t len, * contacted by the RSA engine. The SSL/TLS library needs at * least the public key parameters in the current process. */ - if (!SSL_CTX_use_PrivateKey(ctx, *pkeyptr)) { + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + if (!ret) SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_SSL_LIB); - goto fail; - } - return (1); + if (pkeyptr != NULL) + *pkeyptr = pkey; + else if (pkey != NULL) + EVP_PKEY_free(pkey); - fail: - if (*pkeyptr != NULL) - EVP_PKEY_free(*pkeyptr); - if (*x509ptr != NULL) - X509_free(*x509ptr); - *x509ptr = NULL; - *pkeyptr = NULL; + if (x509ptr != NULL) + *x509ptr = x509; + else if (x509 != NULL) + X509_free(x509); - return (0); + return (ret); } + diff --git a/usr.sbin/smtpd/ssl.c b/usr.sbin/smtpd/ssl.c index 6ea7c6b7df0..d402992a604 100644 --- a/usr.sbin/smtpd/ssl.c +++ b/usr.sbin/smtpd/ssl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl.c,v 1.66 2014/05/20 14:21:45 reyk Exp $ */ +/* $OpenBSD: ssl.c,v 1.67 2014/05/20 17:33:36 reyk Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard @@ -153,7 +153,7 @@ ssl_password_cb(char *buf, int size, int rwflag, void *u) #endif static int -ssl_getpass_cb(char *buf, int size, int rwflag, void *u) +ssl_password_cb(char *buf, int size, int rwflag, void *u) { int ret = 0; size_t len; @@ -209,7 +209,7 @@ ssl_load_key(const char *name, off_t *len, char *pass, mode_t perm, const char * } (void)snprintf(prompt, sizeof prompt, "passphrase for %s: ", pkiname); - key = PEM_read_PrivateKey(fp, NULL, ssl_getpass_cb, prompt); + key = PEM_read_PrivateKey(fp, NULL, ssl_password_cb, prompt); fclose(fp); fp = NULL; if (key == NULL) @@ -276,7 +276,7 @@ ssl_ctx_create(const char *pkiname, char *cert, off_t cert_len) ssl_error("ssl_ctx_create"); fatal("ssl_ctx_create: invalid certificate chain"); } else if (!ssl_ctx_fake_private_key(ctx, - pkiname, pkinamelen, cert, cert_len)) { + pkiname, pkinamelen, cert, cert_len, NULL, NULL)) { ssl_error("ssl_ctx_create"); fatal("ssl_ctx_create: could not fake private key"); } else if (!SSL_CTX_check_private_key(ctx)) { @@ -462,12 +462,14 @@ ssl_set_ecdh_curve(SSL_CTX *ctx, const char *curve) } int -ssl_ctx_load_pkey(SSL_CTX *ctx, char *buf, off_t len, +ssl_load_pkey(const void *data, size_t datalen, char *buf, off_t len, X509 **x509ptr, EVP_PKEY **pkeyptr) { BIO *in; X509 *x509 = NULL; EVP_PKEY *pkey = NULL; + RSA *rsa = NULL; + void *exdata = NULL; if ((in = BIO_new_mem_buf(buf, len)) == NULL) { SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_BUF_LIB); @@ -475,7 +477,7 @@ ssl_ctx_load_pkey(SSL_CTX *ctx, char *buf, off_t len, } if ((x509 = PEM_read_bio_X509(in, NULL, - ssl_getpass_cb, NULL)) == NULL) { + ssl_password_cb, NULL)) == NULL) { SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PEM_LIB); goto fail; } @@ -487,14 +489,26 @@ ssl_ctx_load_pkey(SSL_CTX *ctx, char *buf, off_t len, BIO_free(in); + if (data != NULL && datalen) { + if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL || + (exdata = malloc(datalen)) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_EVP_LIB); + goto fail; + } + + memcpy(exdata, data, datalen); + RSA_set_ex_data(rsa, 0, exdata); + RSA_free(rsa); /* dereference, will be cleaned up with pkey */ + } + *x509ptr = x509; *pkeyptr = pkey; return (1); fail: - ssl_error("ssl_ctx_load_pkey"); - + if (rsa != NULL) + RSA_free(rsa); if (in != NULL) BIO_free(in); if (pkey != NULL) @@ -507,28 +521,15 @@ ssl_ctx_load_pkey(SSL_CTX *ctx, char *buf, off_t len, int ssl_ctx_fake_private_key(SSL_CTX *ctx, const void *data, size_t datalen, - char *buf, off_t len) + char *buf, off_t len, X509 **x509ptr, EVP_PKEY **pkeyptr) { int ret = 0; EVP_PKEY *pkey = NULL; X509 *x509 = NULL; - RSA *rsa = NULL; - void *exdata = NULL; - if (!ssl_ctx_load_pkey(ctx, buf, len, &x509, &pkey)) + if (!ssl_load_pkey(data, datalen, buf, len, &x509, &pkey)) return (0); - if (data != NULL && datalen) { - if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL || - (exdata = malloc(datalen)) == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_EVP_LIB); - goto done; - } - - memcpy(exdata, data, datalen); - RSA_set_ex_data(rsa, 0, exdata); - } - /* * Use the public key as the "private" key - the secret key * parameters are hidden in an extra process that will be @@ -536,17 +537,17 @@ ssl_ctx_fake_private_key(SSL_CTX *ctx, const void *data, size_t datalen, * least the public key parameters in the current process. */ ret = SSL_CTX_use_PrivateKey(ctx, pkey); - if (!ret) { + if (!ret) SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_SSL_LIB); - ssl_error("ssl_ctx_fake_private_key"); - } - done: - if (rsa != NULL) - RSA_free(rsa); - if (pkey != NULL) + if (pkeyptr != NULL) + *pkeyptr = pkey; + else if (pkey != NULL) EVP_PKEY_free(pkey); - if (x509 != NULL) + + if (x509ptr != NULL) + *x509ptr = x509; + else if (x509 != NULL) X509_free(x509); return (ret); diff --git a/usr.sbin/smtpd/ssl.h b/usr.sbin/smtpd/ssl.h index 923746eefd6..414e120e083 100644 --- a/usr.sbin/smtpd/ssl.h +++ b/usr.sbin/smtpd/ssl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl.h,v 1.8 2014/05/20 14:21:46 reyk Exp $ */ +/* $OpenBSD: ssl.h,v 1.9 2014/05/20 17:33:36 reyk Exp $ */ /* * Copyright (c) 2013 Gilles Chehade * @@ -61,11 +61,10 @@ int ssl_load_certificate(struct pki *, const char *); int ssl_load_keyfile(struct pki *, const char *, const char *); int ssl_load_cafile(struct pki *, const char *); int ssl_load_dhparams(struct pki *, const char *); - -int ssl_ctx_load_pkey(SSL_CTX *, char *, off_t, +int ssl_load_pkey(const void *, size_t, char *, off_t, X509 **, EVP_PKEY **); int ssl_ctx_fake_private_key(SSL_CTX *, const void *, size_t, - char *, off_t); + char *, off_t, X509 **, EVP_PKEY **); /* ssl_privsep.c */ int ssl_ctx_use_certificate_chain(SSL_CTX *, char *, off_t);