From 8fe98976a8bf451af22e05d035c9e9aed71e14f7 Mon Sep 17 00:00:00 2001 From: eric Date: Tue, 25 May 2021 19:39:22 +0000 Subject: [PATCH] remove obsolete files --- usr.sbin/smtpd/cert.c | 414 ------------------------------------ usr.sbin/smtpd/ssl_smtpd.c | 103 --------- usr.sbin/smtpd/ssl_verify.c | 296 -------------------------- 3 files changed, 813 deletions(-) delete mode 100644 usr.sbin/smtpd/cert.c delete mode 100644 usr.sbin/smtpd/ssl_smtpd.c delete mode 100644 usr.sbin/smtpd/ssl_verify.c diff --git a/usr.sbin/smtpd/cert.c b/usr.sbin/smtpd/cert.c deleted file mode 100644 index 05aff4181b1..00000000000 --- a/usr.sbin/smtpd/cert.c +++ /dev/null @@ -1,414 +0,0 @@ -/* $OpenBSD: cert.c,v 1.2 2018/12/11 07:25:57 eric Exp $ */ - -/* - * Copyright (c) 2018 Eric Faurot - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "smtpd.h" -#include "ssl.h" - -#define p_cert p_lka - -struct request { - SPLAY_ENTRY(request) entry; - uint32_t id; - void (*cb_get_certificate)(void *, int, const char *, - const void *, size_t); - void (*cb_verify)(void *, int); - void *arg; -}; - -#define MAX_CERTS 16 -#define MAX_CERT_LEN (MAX_IMSGSIZE - (IMSG_HEADER_SIZE + sizeof(size_t))) - -struct session { - SPLAY_ENTRY(session) entry; - uint32_t id; - struct mproc *proc; - char *cert[MAX_CERTS]; - size_t cert_len[MAX_CERTS]; - int cert_count; -}; - -SPLAY_HEAD(cert_reqtree, request); -SPLAY_HEAD(cert_sestree, session); - -static int request_cmp(struct request *, struct request *); -static int session_cmp(struct session *, struct session *); -SPLAY_PROTOTYPE(cert_reqtree, request, entry, request_cmp); -SPLAY_PROTOTYPE(cert_sestree, session, entry, session_cmp); - -static void cert_do_verify(struct session *, const char *, int); -static int cert_X509_verify(struct session *, const char *, const char *); - -static struct cert_reqtree reqs = SPLAY_INITIALIZER(&reqs); -static struct cert_sestree sess = SPLAY_INITIALIZER(&sess); - -int -cert_init(const char *name, int fallback, void (*cb)(void *, int, - const char *, const void *, size_t), void *arg) -{ - struct request *req; - - req = calloc(1, sizeof(*req)); - if (req == NULL) { - cb(arg, CA_FAIL, NULL, NULL, 0); - return 0; - } - while (req->id == 0 || SPLAY_FIND(cert_reqtree, &reqs, req)) - req->id = arc4random(); - req->cb_get_certificate = cb; - req->arg = arg; - SPLAY_INSERT(cert_reqtree, &reqs, req); - - m_create(p_cert, IMSG_CERT_INIT, req->id, 0, -1); - m_add_string(p_cert, name); - m_add_int(p_cert, fallback); - m_close(p_cert); - - return 1; -} - -int -cert_verify(const void *ssl, const char *name, int fallback, - void (*cb)(void *, int), void *arg) -{ - struct request *req; - X509 *x; - STACK_OF(X509) *xchain; - unsigned char *cert_der[MAX_CERTS]; - int cert_len[MAX_CERTS]; - int i, cert_count, ret; - - x = SSL_get_peer_certificate(ssl); - if (x == NULL) { - cb(arg, CERT_NOCERT); - return 0; - } - - ret = 0; - memset(cert_der, 0, sizeof(cert_der)); - - req = calloc(1, sizeof(*req)); - if (req == NULL) - goto end; - while (req->id == 0 || SPLAY_FIND(cert_reqtree, &reqs, req)) - req->id = arc4random(); - req->cb_verify = cb; - req->arg = arg; - SPLAY_INSERT(cert_reqtree, &reqs, req); - - cert_count = 1; - if ((xchain = SSL_get_peer_cert_chain(ssl))) { - cert_count += sk_X509_num(xchain); - if (cert_count > MAX_CERTS) { - log_warnx("warn: certificate chain too long"); - goto end; - } - } - - for (i = 0; i < cert_count; ++i) { - if (i != 0) { - if ((x = sk_X509_value(xchain, i - 1)) == NULL) { - log_warnx("warn: failed to retrieve certificate"); - goto end; - } - } - - cert_len[i] = i2d_X509(x, &cert_der[i]); - if (i == 0) - X509_free(x); - - if (cert_len[i] < 0) { - log_warnx("warn: failed to encode certificate"); - goto end; - } - - log_debug("debug: certificate %i: len=%d", i, cert_len[i]); - if (cert_len[i] > (int)MAX_CERT_LEN) { - log_warnx("warn: certificate too long"); - goto end; - } - } - - /* Send the cert chain, one cert at a time */ - for (i = 0; i < cert_count; ++i) { - m_create(p_cert, IMSG_CERT_CERTIFICATE, req->id, 0, -1); - m_add_data(p_cert, cert_der[i], cert_len[i]); - m_close(p_cert); - } - - /* Tell lookup process that it can start verifying, we're done */ - m_create(p_cert, IMSG_CERT_VERIFY, req->id, 0, -1); - m_add_string(p_cert, name); - m_add_int(p_cert, fallback); - m_close(p_cert); - - ret = 1; - - end: - for (i = 0; i < MAX_CERTS; ++i) - free(cert_der[i]); - - if (ret == 0) { - if (req) - SPLAY_REMOVE(cert_reqtree, &reqs, req); - free(req); - cb(arg, CERT_ERROR); - } - - return ret; -} - - -void -cert_dispatch_request(struct mproc *proc, struct imsg *imsg) -{ - struct pki *pki; - struct session key, *s; - const char *name; - const void *data; - size_t datalen; - struct msg m; - uint32_t reqid; - char buf[LINE_MAX]; - int fallback; - - reqid = imsg->hdr.peerid; - m_msg(&m, imsg); - - switch (imsg->hdr.type) { - - case IMSG_CERT_INIT: - m_get_string(&m, &name); - m_get_int(&m, &fallback); - m_end(&m); - - xlowercase(buf, name, sizeof(buf)); - log_debug("debug: looking up pki \"%s\"", buf); - pki = dict_get(env->sc_pki_dict, buf); - if (pki == NULL && fallback) - pki = dict_get(env->sc_pki_dict, "*"); - - m_create(proc, IMSG_CERT_INIT, reqid, 0, -1); - if (pki) { - m_add_int(proc, CA_OK); - m_add_string(proc, pki->pki_name); - m_add_data(proc, pki->pki_cert, pki->pki_cert_len); - } else { - m_add_int(proc, CA_FAIL); - m_add_string(proc, NULL); - m_add_data(proc, NULL, 0); - } - m_close(proc); - return; - - case IMSG_CERT_CERTIFICATE: - m_get_data(&m, &data, &datalen); - m_end(&m); - - key.id = reqid; - key.proc = proc; - s = SPLAY_FIND(cert_sestree, &sess, &key); - if (s == NULL) { - s = calloc(1, sizeof(*s)); - s->proc = proc; - s->id = reqid; - SPLAY_INSERT(cert_sestree, &sess, s); - } - - if (s->cert_count == MAX_CERTS) - fatalx("%s: certificate chain too long", __func__); - - s->cert[s->cert_count] = xmemdup(data, datalen); - s->cert_len[s->cert_count] = datalen; - s->cert_count++; - return; - - case IMSG_CERT_VERIFY: - m_get_string(&m, &name); - m_get_int(&m, &fallback); - m_end(&m); - - key.id = reqid; - key.proc = proc; - s = SPLAY_FIND(cert_sestree, &sess, &key); - if (s == NULL) - fatalx("%s: no certificate", __func__); - - SPLAY_REMOVE(cert_sestree, &sess, s); - cert_do_verify(s, name, fallback); - return; - - default: - fatalx("%s: %s", __func__, imsg_to_str(imsg->hdr.type)); - } -} - -void -cert_dispatch_result(struct mproc *proc, struct imsg *imsg) -{ - struct request key, *req; - struct msg m; - const void *cert; - const char *name; - size_t cert_len; - int res; - - key.id = imsg->hdr.peerid; - req = SPLAY_FIND(cert_reqtree, &reqs, &key); - if (req == NULL) - fatalx("%s: unknown request %08x", __func__, imsg->hdr.peerid); - - m_msg(&m, imsg); - - switch (imsg->hdr.type) { - - case IMSG_CERT_INIT: - m_get_int(&m, &res); - m_get_string(&m, &name); - m_get_data(&m, &cert, &cert_len); - m_end(&m); - SPLAY_REMOVE(cert_reqtree, &reqs, req); - req->cb_get_certificate(req->arg, res, name, cert, cert_len); - free(req); - break; - - case IMSG_CERT_VERIFY: - m_get_int(&m, &res); - m_end(&m); - SPLAY_REMOVE(cert_reqtree, &reqs, req); - req->cb_verify(req->arg, res); - free(req); - break; - } -} - -static void -cert_do_verify(struct session *s, const char *name, int fallback) -{ - struct ca *ca; - const char *cafile; - int i, res; - - ca = dict_get(env->sc_ca_dict, name); - if (ca == NULL) - if (fallback) - ca = dict_get(env->sc_ca_dict, "*"); - cafile = ca ? ca->ca_cert_file : CA_FILE; - - if (ca == NULL && !fallback) - res = CERT_NOCA; - else if (!cert_X509_verify(s, cafile, NULL)) - res = CERT_INVALID; - else - res = CERT_OK; - - for (i = 0; i < s->cert_count; ++i) - free(s->cert[i]); - - m_create(s->proc, IMSG_CERT_VERIFY, s->id, 0, -1); - m_add_int(s->proc, res); - m_close(s->proc); - - free(s); -} - -static int -cert_X509_verify(struct session *s, const char *CAfile, - const char *CRLfile) -{ - X509 *x509; - X509 *x509_tmp; - STACK_OF(X509) *x509_chain; - const unsigned char *d2i; - int i, ret = 0; - const char *errstr; - - x509 = NULL; - x509_tmp = NULL; - x509_chain = NULL; - - d2i = s->cert[0]; - if (d2i_X509(&x509, &d2i, s->cert_len[0]) == NULL) { - x509 = NULL; - goto end; - } - - if (s->cert_count > 1) { - x509_chain = sk_X509_new_null(); - for (i = 1; i < s->cert_count; ++i) { - d2i = s->cert[i]; - if (d2i_X509(&x509_tmp, &d2i, s->cert_len[i]) == NULL) - goto end; - sk_X509_insert(x509_chain, x509_tmp, i); - x509_tmp = NULL; - } - } - if (!ca_X509_verify(x509, x509_chain, CAfile, NULL, &errstr)) - log_debug("debug: X509 verify: %s", errstr); - else - ret = 1; - -end: - X509_free(x509); - X509_free(x509_tmp); - if (x509_chain) - sk_X509_pop_free(x509_chain, X509_free); - - return ret; -} - -static int -request_cmp(struct request *a, struct request *b) -{ - if (a->id < b->id) - return -1; - if (a->id > b->id) - return 1; - return 0; -} - -SPLAY_GENERATE(cert_reqtree, request, entry, request_cmp); - -static int -session_cmp(struct session *a, struct session *b) -{ - if (a->id < b->id) - return -1; - if (a->id > b->id) - return 1; - if (a->proc < b->proc) - return -1; - if (a->proc > b->proc) - return 1; - return 0; -} - -SPLAY_GENERATE(cert_sestree, session, entry, session_cmp); diff --git a/usr.sbin/smtpd/ssl_smtpd.c b/usr.sbin/smtpd/ssl_smtpd.c deleted file mode 100644 index 1f1e62d27c1..00000000000 --- a/usr.sbin/smtpd/ssl_smtpd.c +++ /dev/null @@ -1,103 +0,0 @@ -/* $OpenBSD: ssl_smtpd.c,v 1.13 2015/12/30 16:02:08 benno Exp $ */ - -/* - * Copyright (c) 2008 Pierre-Yves Ritschard - * Copyright (c) 2008 Reyk Floeter - * Copyright (c) 2012 Gilles Chehade - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "smtpd.h" -#include "log.h" -#include "ssl.h" - - -void * -ssl_mta_init(void *pkiname, char *cert, off_t cert_len, const char *ciphers) -{ - SSL_CTX *ctx = NULL; - SSL *ssl = NULL; - - ctx = ssl_ctx_create(pkiname, cert, cert_len, ciphers); - - if ((ssl = SSL_new(ctx)) == NULL) - goto err; - if (!SSL_set_ssl_method(ssl, SSLv23_client_method())) - goto err; - - SSL_CTX_free(ctx); - return (void *)(ssl); - -err: - SSL_free(ssl); - SSL_CTX_free(ctx); - ssl_error("ssl_mta_init"); - return (NULL); -} - -/* dummy_verify */ -static int -dummy_verify(int ok, X509_STORE_CTX *store) -{ - /* - * We *want* SMTP to request an optional client certificate, however we don't want the - * verification to take place in the SMTP process. This dummy verify will allow us to - * asynchronously verify in the lookup process. - */ - return 1; -} - -void * -ssl_smtp_init(void *ssl_ctx, int verify) -{ - SSL *ssl = NULL; - - log_debug("debug: session_start_ssl: switching to SSL"); - - if (verify) - SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, dummy_verify); - - if ((ssl = SSL_new(ssl_ctx)) == NULL) - goto err; - if (!SSL_set_ssl_method(ssl, SSLv23_server_method())) - goto err; - - return (void *)(ssl); - -err: - SSL_free(ssl); - ssl_error("ssl_smtp_init"); - return (NULL); -} diff --git a/usr.sbin/smtpd/ssl_verify.c b/usr.sbin/smtpd/ssl_verify.c deleted file mode 100644 index 02148862f70..00000000000 --- a/usr.sbin/smtpd/ssl_verify.c +++ /dev/null @@ -1,296 +0,0 @@ -/* $OpenBSD: ssl_verify.c,v 1.2 2019/11/02 03:16:45 gilles Exp $ */ -/* - * Copyright (c) 2014 Jeremie Courreges-Anglas - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* Adapted from lib/libtls/tls_verify.c */ - - -#include - -#include -#include - -#include -#include - -#include - -#if 0 -#include -#include "tls_internal.h" -#endif - -#include "ssl.h" -#include "log.h" - -struct tls; -#define tls_set_errorx(ctx, ...) log_warnx(__VA_ARGS__) -union tls_addr { - struct in_addr in; - struct in6_addr in6; -}; - -static int -tls_match_name(const char *cert_name, const char *name) -{ - const char *cert_domain, *domain, *next_dot; - - if (strcasecmp(cert_name, name) == 0) - return 0; - - /* Wildcard match? */ - if (cert_name[0] == '*') { - /* - * Valid wildcards: - * - "*.domain.tld" - * - "*.sub.domain.tld" - * - etc. - * Reject "*.tld". - * No attempt to prevent the use of eg. "*.co.uk". - */ - cert_domain = &cert_name[1]; - /* Disallow "*" */ - if (cert_domain[0] == '\0') - return -1; - /* Disallow "*foo" */ - if (cert_domain[0] != '.') - return -1; - /* Disallow "*.." */ - if (cert_domain[1] == '.') - return -1; - next_dot = strchr(&cert_domain[1], '.'); - /* Disallow "*.bar" */ - if (next_dot == NULL) - return -1; - /* Disallow "*.bar.." */ - if (next_dot[1] == '.') - return -1; - - domain = strchr(name, '.'); - - /* No wildcard match against a name with no host part. */ - if (name[0] == '.') - return -1; - /* No wildcard match against a name with no domain part. */ - if (domain == NULL || strlen(domain) == 1) - return -1; - - if (strcasecmp(cert_domain, domain) == 0) - return 0; - } - - return -1; -} - -/* - * See RFC 5280 section 4.2.1.6 for SubjectAltName details. - * alt_match is set to 1 if a matching alternate name is found. - * alt_exists is set to 1 if any known alternate name exists in the certificate. - */ -static int -tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *name, - int *alt_match, int *alt_exists) -{ - STACK_OF(GENERAL_NAME) *altname_stack = NULL; - union tls_addr addrbuf; - int addrlen, type; - int count, i; - int rv = 0; - - *alt_match = 0; - *alt_exists = 0; - - altname_stack = X509_get_ext_d2i(cert, NID_subject_alt_name, - NULL, NULL); - if (altname_stack == NULL) - return 0; - - if (inet_pton(AF_INET, name, &addrbuf) == 1) { - type = GEN_IPADD; - addrlen = 4; - } else if (inet_pton(AF_INET6, name, &addrbuf) == 1) { - type = GEN_IPADD; - addrlen = 16; - } else { - type = GEN_DNS; - addrlen = 0; - } - - count = sk_GENERAL_NAME_num(altname_stack); - for (i = 0; i < count; i++) { - GENERAL_NAME *altname; - - altname = sk_GENERAL_NAME_value(altname_stack, i); - - if (altname->type == GEN_DNS || altname->type == GEN_IPADD) - *alt_exists = 1; - - if (altname->type != type) - continue; - - if (type == GEN_DNS) { - const unsigned char *data; - int format, len; - - format = ASN1_STRING_type(altname->d.dNSName); - if (format == V_ASN1_IA5STRING) { - data = ASN1_STRING_get0_data(altname->d.dNSName); - len = ASN1_STRING_length(altname->d.dNSName); - - if (len < 0 || (size_t)len != strlen(data)) { - tls_set_errorx(ctx, - "error verifying name '%s': " - "NUL byte in subjectAltName, " - "probably a malicious certificate", - name); - rv = -1; - break; - } - - /* - * Per RFC 5280 section 4.2.1.6: - * " " is a legal domain name, but that - * dNSName must be rejected. - */ - if (strcmp(data, " ") == 0) { - tls_set_errorx(ctx, - "error verifying name '%s': " - "a dNSName of \" \" must not be " - "used", name); - rv = -1; - break; - } - - if (tls_match_name(data, name) == 0) { - *alt_match = 1; - break; - } - } else { -#ifdef DEBUG - fprintf(stdout, "%s: unhandled subjectAltName " - "dNSName encoding (%d)\n", getprogname(), - format); -#endif - } - - } else if (type == GEN_IPADD) { - const unsigned char *data; - int datalen; - - datalen = ASN1_STRING_length(altname->d.iPAddress); - data = ASN1_STRING_get0_data(altname->d.iPAddress); - - if (datalen < 0) { - tls_set_errorx(ctx, - "Unexpected negative length for an " - "IP address: %d", datalen); - rv = -1; - break; - } - - /* - * Per RFC 5280 section 4.2.1.6: - * IPv4 must use 4 octets and IPv6 must use 16 octets. - */ - if (datalen == addrlen && - memcmp(data, &addrbuf, addrlen) == 0) { - *alt_match = 1; - break; - } - } - } - - sk_GENERAL_NAME_pop_free(altname_stack, GENERAL_NAME_free); - return rv; -} - -static int -tls_check_common_name(struct tls *ctx, X509 *cert, const char *name, - int *cn_match) -{ - X509_NAME *subject_name; - char *common_name = NULL; - union tls_addr addrbuf; - int common_name_len; - int rv = 0; - - *cn_match = 0; - - subject_name = X509_get_subject_name(cert); - if (subject_name == NULL) - goto done; - - common_name_len = X509_NAME_get_text_by_NID(subject_name, - NID_commonName, NULL, 0); - if (common_name_len < 0) - goto done; - - common_name = calloc(common_name_len + 1, 1); - if (common_name == NULL) - goto done; - - X509_NAME_get_text_by_NID(subject_name, NID_commonName, common_name, - common_name_len + 1); - - /* NUL bytes in CN? */ - if (common_name_len < 0 || - (size_t)common_name_len != strlen(common_name)) { - tls_set_errorx(ctx, "error verifying name '%s': " - "NUL byte in Common Name field, " - "probably a malicious certificate", name); - rv = -1; - goto done; - } - - /* - * We don't want to attempt wildcard matching against IP addresses, - * so perform a simple comparison here. - */ - if (inet_pton(AF_INET, name, &addrbuf) == 1 || - inet_pton(AF_INET6, name, &addrbuf) == 1) { - if (strcmp(common_name, name) == 0) - *cn_match = 1; - goto done; - } - - if (tls_match_name(common_name, name) == 0) - *cn_match = 1; - - done: - free(common_name); - return rv; -} - -int -ssl_check_name(X509 *cert, const char *name, int *match) -{ - int alt_exists; - - *match = 0; - - if (tls_check_subject_altname(NULL, cert, name, match, - &alt_exists) == -1) - return -1; - - /* - * As per RFC 6125 section 6.4.4, if any known alternate name existed - * in the certificate, we do not attempt to match on the CN. - */ - if (*match || alt_exists) - return 0; - - return tls_check_common_name(NULL, cert, name, match); -} -- 2.20.1