diff options
author | Gilles Chehade <gilles@poolp.org> | 2019-05-24 20:48:02 +0200 |
---|---|---|
committer | Gilles Chehade <gilles@poolp.org> | 2019-05-24 20:48:02 +0200 |
commit | 57d46628330af7e80a065cd57cae53973c08b1a6 (patch) | |
tree | 2e5a4b92865d2c58e6670cdbd2f03c769c31864a | |
parent | Merge branch 'master' into portable (diff) | |
parent | sync with OpenBSD (diff) | |
download | OpenSMTPD-57d46628330af7e80a065cd57cae53973c08b1a6.tar.xz OpenSMTPD-57d46628330af7e80a065cd57cae53973c08b1a6.zip |
Merge branch 'master' into portable
-rw-r--r-- | smtpd/ca.c | 56 | ||||
-rw-r--r-- | smtpd/crypto.c | 69 | ||||
-rw-r--r-- | smtpd/mproc.c | 4 | ||||
-rw-r--r-- | smtpd/parse.y | 6 | ||||
-rw-r--r-- | smtpd/ssl.c | 15 |
5 files changed, 82 insertions, 68 deletions
@@ -1,4 +1,4 @@ -/* $OpenBSD: ca.c,v 1.29 2018/05/24 11:38:24 gilles Exp $ */ +/* $OpenBSD: ca.c,v 1.32 2019/05/24 15:34:05 gilles Exp $ */ /* * Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org> @@ -177,6 +177,7 @@ ca_X509_verify(void *certificate, void *chain, const char *CAfile, X509_STORE *store = NULL; X509_STORE_CTX *xsc = NULL; int ret = 0; + long error = 0; if ((store = X509_STORE_new()) == NULL) goto end; @@ -200,8 +201,10 @@ ca_X509_verify(void *certificate, void *chain, const char *CAfile, end: *errstr = NULL; if (ret != 1) { - if (xsc) - *errstr = X509_verify_cert_error_string(xsc->error); + if (xsc) { + error = X509_STORE_CTX_get_error(xsc); + *errstr = X509_verify_cert_error_string(error); + } else if (ERR_peek_last_error()) *errstr = ERR_error_string(ERR_peek_last_error(), NULL); } @@ -304,22 +307,7 @@ ca_imsg(struct mproc *p, struct imsg *imsg) const RSA_METHOD *rsa_default = NULL; -static RSA_METHOD rsae_method = { - "RSA privsep engine", - rsae_pub_enc, - rsae_pub_dec, - rsae_priv_enc, - rsae_priv_dec, - rsae_mod_exp, - rsae_bn_mod_exp, - rsae_init, - rsae_finish, - 0, - NULL, - NULL, - NULL, - rsae_keygen -}; +static RSA_METHOD *rsae_method = NULL; static int rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to, @@ -485,12 +473,25 @@ ca_engine_init(void) ENGINE *e; const char *errstr, *name; + if ((rsae_method = RSA_meth_new("RSA privsep engine", 0)) == NULL) + goto fail; + + rsae_method->rsa_pub_enc = rsae_pub_enc; + rsae_method->rsa_pub_dec = rsae_pub_dec; + rsae_method->rsa_priv_enc = rsae_priv_enc; + rsae_method->rsa_priv_dec = rsae_priv_dec; + rsae_method->rsa_mod_exp = rsae_mod_exp; + rsae_method->bn_mod_exp = rsae_bn_mod_exp; + rsae_method->init = rsae_init; + rsae_method->finish = rsae_finish; + rsae_method->rsa_keygen = rsae_keygen; + if ((e = ENGINE_get_default_RSA()) == NULL) { if ((e = ENGINE_new()) == NULL) { errstr = "ENGINE_new"; goto fail; } - if (!ENGINE_set_name(e, rsae_method.name)) { + if (!ENGINE_set_name(e, rsae_method->name)) { errstr = "ENGINE_set_name"; goto fail; } @@ -508,20 +509,17 @@ ca_engine_init(void) log_debug("debug: %s: using %s", __func__, name); - if (rsa_default->flags & RSA_FLAG_SIGN_VER) - fatalx("unsupported RSA engine"); - if (rsa_default->rsa_mod_exp == NULL) - rsae_method.rsa_mod_exp = NULL; + rsae_method->rsa_mod_exp = NULL; if (rsa_default->bn_mod_exp == NULL) - rsae_method.bn_mod_exp = NULL; + rsae_method->bn_mod_exp = NULL; if (rsa_default->rsa_keygen == NULL) - rsae_method.rsa_keygen = NULL; - rsae_method.flags = rsa_default->flags | + rsae_method->rsa_keygen = NULL; + rsae_method->flags = rsa_default->flags | RSA_METHOD_FLAG_NO_CHECK; - rsae_method.app_data = rsa_default->app_data; + rsae_method->app_data = rsa_default->app_data; - if (!ENGINE_set_RSA(e, &rsae_method)) { + if (!ENGINE_set_RSA(e, rsae_method)) { errstr = "ENGINE_set_RSA"; goto fail; } diff --git a/smtpd/crypto.c b/smtpd/crypto.c index 76f98807..2f718db9 100644 --- a/smtpd/crypto.c +++ b/smtpd/crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto.c,v 1.6 2016/09/03 14:42:08 gilles Exp $ */ +/* $OpenBSD: crypto.c,v 1.7 2019/05/24 18:01:52 gilles Exp $ */ /* * Copyright (c) 2013 Gilles Chehade <gilles@openbsd.org> @@ -64,7 +64,7 @@ crypto_setup(const char *key, size_t len) int crypto_encrypt_file(FILE * in, FILE * out) { - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx; uint8_t ibuf[CRYPTO_BUFFER_SIZE]; uint8_t obuf[CRYPTO_BUFFER_SIZE]; uint8_t iv[IV_SIZE]; @@ -91,12 +91,15 @@ crypto_encrypt_file(FILE * in, FILE * out) if ((w = fwrite(iv, 1, sizeof iv, out)) != sizeof iv) return 0; - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, cp.key, iv); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return 0; + + EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, cp.key, iv); /* encrypt until end of file */ while ((r = fread(ibuf, 1, CRYPTO_BUFFER_SIZE, in)) != 0) { - if (!EVP_EncryptUpdate(&ctx, obuf, &len, ibuf, r)) + if (!EVP_EncryptUpdate(ctx, obuf, &len, ibuf, r)) goto end; if (len && (w = fwrite(obuf, len, 1, out)) != 1) goto end; @@ -105,13 +108,13 @@ crypto_encrypt_file(FILE * in, FILE * out) goto end; /* finalize and write last chunk if any */ - if (!EVP_EncryptFinal_ex(&ctx, obuf, &len)) + if (!EVP_EncryptFinal_ex(ctx, obuf, &len)) goto end; if (len && (w = fwrite(obuf, len, 1, out)) != 1) goto end; /* get and append tag */ - EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, sizeof tag, tag); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, sizeof tag, tag); if ((w = fwrite(tag, sizeof tag, 1, out)) != 1) goto end; @@ -119,14 +122,14 @@ crypto_encrypt_file(FILE * in, FILE * out) ret = 1; end: - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); return ret; } int crypto_decrypt_file(FILE * in, FILE * out) { - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx; uint8_t ibuf[CRYPTO_BUFFER_SIZE]; uint8_t obuf[CRYPTO_BUFFER_SIZE]; uint8_t iv[IV_SIZE]; @@ -170,12 +173,14 @@ crypto_decrypt_file(FILE * in, FILE * out) sz -= sizeof iv; sz -= sizeof tag; + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return 0; - EVP_CIPHER_CTX_init(&ctx); - EVP_DecryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, cp.key, iv); + EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, cp.key, iv); /* set expected tag */ - EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, sizeof tag, tag); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, sizeof tag, tag); /* decrypt until end of ciphertext */ while (sz) { @@ -185,7 +190,7 @@ crypto_decrypt_file(FILE * in, FILE * out) r = fread(ibuf, 1, sz, in); if (!r) break; - if (!EVP_DecryptUpdate(&ctx, obuf, &len, ibuf, r)) + if (!EVP_DecryptUpdate(ctx, obuf, &len, ibuf, r)) goto end; if (len && (w = fwrite(obuf, len, 1, out)) != 1) goto end; @@ -195,7 +200,7 @@ crypto_decrypt_file(FILE * in, FILE * out) goto end; /* finalize, write last chunk if any and perform authentication check */ - if (!EVP_DecryptFinal_ex(&ctx, obuf, &len)) + if (!EVP_DecryptFinal_ex(ctx, obuf, &len)) goto end; if (len && (w = fwrite(obuf, len, 1, out)) != 1) goto end; @@ -204,14 +209,14 @@ crypto_decrypt_file(FILE * in, FILE * out) ret = 1; end: - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); return ret; } size_t crypto_encrypt_buffer(const char *in, size_t inlen, char *out, size_t outlen) { - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx; uint8_t iv[IV_SIZE]; uint8_t tag[GCM_TAG_SIZE]; uint8_t version = API_VERSION; @@ -239,33 +244,36 @@ crypto_encrypt_buffer(const char *in, size_t inlen, char *out, size_t outlen) memcpy(out + len, iv, sizeof iv); len += sizeof iv; - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, cp.key, iv); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return 0; + + EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, cp.key, iv); /* encrypt buffer */ - if (!EVP_EncryptUpdate(&ctx, out + len, &olen, in, inlen)) + if (!EVP_EncryptUpdate(ctx, out + len, &olen, in, inlen)) goto end; len += olen; /* finalize and write last chunk if any */ - if (!EVP_EncryptFinal_ex(&ctx, out + len, &olen)) + if (!EVP_EncryptFinal_ex(ctx, out + len, &olen)) goto end; len += olen; /* get and append tag */ - EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, sizeof tag, tag); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, sizeof tag, tag); memcpy(out + len, tag, sizeof tag); ret = len + sizeof tag; end: - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); return ret; } size_t crypto_decrypt_buffer(const char *in, size_t inlen, char *out, size_t outlen) { - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx; uint8_t iv[IV_SIZE]; uint8_t tag[GCM_TAG_SIZE]; int olen; @@ -292,24 +300,27 @@ crypto_decrypt_buffer(const char *in, size_t inlen, char *out, size_t outlen) inlen -= sizeof iv; in += sizeof iv; - EVP_CIPHER_CTX_init(&ctx); - EVP_DecryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, cp.key, iv); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return 0; + + EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, cp.key, iv); /* set expected tag */ - EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, sizeof tag, tag); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, sizeof tag, tag); /* decrypt buffer */ - if (!EVP_DecryptUpdate(&ctx, out, &olen, in, inlen)) + if (!EVP_DecryptUpdate(ctx, out, &olen, in, inlen)) goto end; len += olen; /* finalize, write last chunk if any and perform authentication check */ - if (!EVP_DecryptFinal_ex(&ctx, out + len, &olen)) + if (!EVP_DecryptFinal_ex(ctx, out + len, &olen)) goto end; ret = len + olen; end: - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); return ret; } diff --git a/smtpd/mproc.c b/smtpd/mproc.c index e1bf324f..bb5e4a5f 100644 --- a/smtpd/mproc.c +++ b/smtpd/mproc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mproc.c,v 1.32 2018/12/17 08:56:31 eric Exp $ */ +/* $OpenBSD: mproc.c,v 1.33 2019/05/24 14:31:30 gilles Exp $ */ /* * Copyright (c) 2012 Eric Faurot <eric@faurot.net> @@ -310,7 +310,7 @@ m_add(struct mproc *p, const void *data, size_t len) void *tmp; if (p->m_pos + len + IMSG_HEADER_SIZE > MAX_IMSGSIZE) { - log_warnx("warn: message to large"); + log_warnx("warn: message too large"); fatal(NULL); } diff --git a/smtpd/parse.y b/smtpd/parse.y index 8f331315..b37c390d 100644 --- a/smtpd/parse.y +++ b/smtpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.251 2019/02/13 22:57:08 deraadt Exp $ */ +/* $OpenBSD: parse.y,v 1.252 2019/05/20 07:04:13 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> @@ -670,11 +670,11 @@ MBOX { } dispatcher_local_options | LMTP STRING { asprintf(&dispatcher->u.local.command, - PATH_LIBEXEC"/mail.lmtp -f %%{mbox.from} -d %s %%{user.username}", $2); + PATH_LIBEXEC"/mail.lmtp -f \"%%{sender}\" -d %s %%{user.username}", $2); } dispatcher_local_options | LMTP STRING RCPT_TO { asprintf(&dispatcher->u.local.command, - PATH_LIBEXEC"/mail.lmtp -f %%{mbox.from} -d %s %%{dest}", $2); + PATH_LIBEXEC"/mail.lmtp -f \"%%{sender}\" -d %s %%{dest}", $2); } dispatcher_local_options | MDA STRING { asprintf(&dispatcher->u.local.command, diff --git a/smtpd/ssl.c b/smtpd/ssl.c index 74932247..166160fa 100644 --- a/smtpd/ssl.c +++ b/smtpd/ssl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl.c,v 1.90 2018/12/20 19:40:13 gilles Exp $ */ +/* $OpenBSD: ssl.c,v 1.92 2019/05/24 16:29:41 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -185,7 +185,7 @@ ssl_load_key(const char *name, off_t *len, char *pass, mode_t perm, const char * EVP_PKEY *key = NULL; BIO *bio = NULL; long size; - char *data, *buf = NULL; + char *data, *buf, *filebuf; struct stat st; char mode[12]; char prompt[2048]; @@ -198,6 +198,9 @@ ssl_load_key(const char *name, off_t *len, char *pass, mode_t perm, const char * */ if ((fp = fopen(name, "r")) == NULL) return (NULL); + if ((filebuf = malloc_conceal(BUFSIZ)) == NULL) + goto fail; + setvbuf(fp, filebuf, _IOFBF, BUFSIZ); if (fstat(fileno(fp), &st) != 0) goto fail; @@ -218,6 +221,8 @@ ssl_load_key(const char *name, off_t *len, char *pass, mode_t perm, const char * key = PEM_read_PrivateKey(fp, NULL, ssl_password_cb, prompt); fclose(fp); fp = NULL; + freezero(filebuf, BUFSIZ); + filebuf = NULL; if (key == NULL) goto fail; /* @@ -229,7 +234,7 @@ ssl_load_key(const char *name, off_t *len, char *pass, mode_t perm, const char * goto fail; if ((size = BIO_get_mem_data(bio, &data)) <= 0) goto fail; - if ((buf = calloc(1, size + 1)) == NULL) + if ((buf = calloc_conceal(1, size + 1)) == NULL) goto fail; memcpy(buf, data, size); @@ -241,11 +246,11 @@ ssl_load_key(const char *name, off_t *len, char *pass, mode_t perm, const char * fail: ssl_error("ssl_load_key"); - free(buf); BIO_free_all(bio); EVP_PKEY_free(key); if (fp) fclose(fp); + freezero(filebuf, BUFSIZ); return (NULL); } @@ -425,7 +430,7 @@ ssl_ctx_fake_private_key(SSL_CTX *ctx, const void *data, size_t datalen, */ ret = SSL_CTX_use_PrivateKey(ctx, pkey); if (!ret) - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_SSL_LIB); + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_LIB_SSL); if (pkeyptr != NULL) *pkeyptr = pkey; |