summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ldapd/Makefile8
-rw-r--r--usr.sbin/ldapd/conn.c55
-rw-r--r--usr.sbin/ldapd/evbuffer_tls.c350
-rw-r--r--usr.sbin/ldapd/evbuffer_tls.h37
-rw-r--r--usr.sbin/ldapd/ldapd.c4
-rw-r--r--usr.sbin/ldapd/ldapd.h41
-rw-r--r--usr.sbin/ldapd/ldape.c22
-rw-r--r--usr.sbin/ldapd/parse.y97
-rw-r--r--usr.sbin/ldapd/ssl.c565
-rw-r--r--usr.sbin/ldapd/ssl_privsep.c172
10 files changed, 559 insertions, 792 deletions
diff --git a/usr.sbin/ldapd/Makefile b/usr.sbin/ldapd/Makefile
index d35945bbef8..5d2aea00428 100644
--- a/usr.sbin/ldapd/Makefile
+++ b/usr.sbin/ldapd/Makefile
@@ -1,15 +1,15 @@
-# $OpenBSD: Makefile,v 1.12 2014/07/16 20:07:03 okan Exp $
+# $OpenBSD: Makefile,v 1.13 2016/05/01 00:32:37 jmatthew Exp $
PROG= ldapd
MAN= ldapd.8 ldapd.conf.5
SRCS= ber.c log.c control.c \
util.c ldapd.c ldape.c conn.c attributes.c namespace.c \
btree.c filter.c search.c parse.y \
- auth.c modify.c index.c ssl.c ssl_privsep.c \
+ auth.c modify.c index.c evbuffer_tls.c \
validate.c uuid.c schema.c imsgev.c syntax.c matching.c
-LDADD= -levent -lssl -lcrypto -lz -lutil
-DPADD= ${LIBEVENT} ${LIBCRYPTO} ${LIBSSL} ${LIBZ} ${LIBUTIL}
+LDADD= -ltls -levent -lz -lutil
+DPADD= ${LIBEVENT} ${LIBTLS} ${LIBCRYPTO} ${LIBSSL} ${LIBZ} ${LIBUTIL}
CFLAGS+= -I${.CURDIR} -g
CFLAGS+= -Wall -Wstrict-prototypes -Wmissing-prototypes
CFLAGS+= -Wmissing-declarations
diff --git a/usr.sbin/ldapd/conn.c b/usr.sbin/ldapd/conn.c
index 0a4a02ad323..728c75d69f1 100644
--- a/usr.sbin/ldapd/conn.c
+++ b/usr.sbin/ldapd/conn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conn.c,v 1.12 2015/11/02 06:32:51 jmatthew Exp $ */
+/* $OpenBSD: conn.c,v 1.13 2016/05/01 00:32:37 jmatthew Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -26,6 +26,7 @@
#include "ldapd.h"
int conn_dispatch(struct conn *conn);
+int conn_tls_init(struct conn *);
unsigned long ldap_application(struct ber_element *elm);
struct conn_list conn_list;
@@ -61,7 +62,7 @@ conn_close(struct conn *conn)
/* Cancel any queued requests on this connection. */
namespace_cancel_conn(conn);
- ssl_session_destroy(conn);
+ tls_free(conn->tls);
TAILQ_REMOVE(&conn_list, conn, next);
ber_free(&conn->ber);
@@ -225,9 +226,8 @@ conn_write(struct bufferevent *bev, void *data)
conn_close(conn);
else if (conn->s_flags & F_STARTTLS) {
conn->s_flags &= ~F_STARTTLS;
- bufferevent_free(conn->bev);
- conn->bev = NULL;
- ssl_session_init(conn);
+ if (conn_tls_init(conn) == -1)
+ conn_close(conn);
}
}
@@ -296,24 +296,22 @@ conn_accept(int fd, short event, void *data)
goto giveup;
}
conn->ber.fd = -1;
- conn->s_l = l;
ber_set_application(&conn->ber, ldap_application);
conn->fd = afd;
conn->listener = l;
- if (l->flags & F_LDAPS) {
- ssl_session_init(conn);
- } else {
- conn->bev = bufferevent_new(afd, conn_read, conn_write,
- conn_err, conn);
- if (conn->bev == NULL) {
- log_warn("conn_accept: bufferevent_new");
- free(conn);
- goto giveup;
- }
- bufferevent_enable(conn->bev, EV_READ);
- bufferevent_settimeout(conn->bev, 0, 60);
+ conn->bev = bufferevent_new(afd, conn_read, conn_write,
+ conn_err, conn);
+ if (conn->bev == NULL) {
+ log_warn("conn_accept: bufferevent_new");
+ free(conn);
+ goto giveup;
}
+ bufferevent_enable(conn->bev, EV_READ);
+ bufferevent_settimeout(conn->bev, 0, 60);
+ if (l->flags & F_LDAPS)
+ if (conn_tls_init(conn) == -1)
+ conn_close(conn);
TAILQ_INIT(&conn->searches);
TAILQ_INSERT_HEAD(&conn_list, conn, next);
@@ -366,3 +364,24 @@ conn_close_any()
return -1;
}
+
+int
+conn_tls_init(struct conn *conn)
+{
+ struct listener *l = conn->listener;
+
+ if (!(l->flags & F_SSL))
+ return 0;
+
+ log_debug("conn_tls_init: switching to TLS");
+
+ if (tls_accept_socket(l->tls, &conn->tls, conn->fd) < 0) {
+ log_debug("tls_accept_socket failed");
+ return -1;
+ }
+
+ conn->s_flags |= F_SECURE;
+ buffertls_set(&conn->buftls, conn->bev, conn->tls, conn->fd);
+ buffertls_accept(&conn->buftls, conn->fd);
+ return 0;
+}
diff --git a/usr.sbin/ldapd/evbuffer_tls.c b/usr.sbin/ldapd/evbuffer_tls.c
new file mode 100644
index 00000000000..b0d0e2ee771
--- /dev/null
+++ b/usr.sbin/ldapd/evbuffer_tls.c
@@ -0,0 +1,350 @@
+/* $OpenBSD: evbuffer_tls.c,v 1.1 2016/05/01 00:32:37 jmatthew Exp $ */
+
+/*
+ * Copyright (c) 2002-2004 Niels Provos <provos@citi.umich.edu>
+ * Copyright (c) 2014-2015 Alexander Bluhm <bluhm@openbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+#include <errno.h>
+#include <event.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tls.h>
+
+#include "evbuffer_tls.h"
+
+/* prototypes */
+
+void bufferevent_read_pressure_cb(struct evbuffer *, size_t, size_t, void *);
+static void buffertls_readcb(int, short, void *);
+static void buffertls_writecb(int, short, void *);
+static void buffertls_handshakecb(int, short, void *);
+int evtls_read(struct evbuffer *, int, int, struct tls *);
+int evtls_write(struct evbuffer *, int, struct tls *);
+
+static int
+bufferevent_add(struct event *ev, int timeout)
+{
+ struct timeval tv, *ptv = NULL;
+
+ if (timeout) {
+ timerclear(&tv);
+ tv.tv_sec = timeout;
+ ptv = &tv;
+ }
+
+ return (event_add(ev, ptv));
+}
+
+static void
+buffertls_readcb(int fd, short event, void *arg)
+{
+ struct buffertls *buftls = arg;
+ struct bufferevent *bufev = buftls->bt_bufev;
+ struct tls *ctx = buftls->bt_ctx;
+ int res = 0;
+ short what = EVBUFFER_READ;
+ size_t len;
+ int howmuch = -1;
+
+ if (event == EV_TIMEOUT) {
+ what |= EVBUFFER_TIMEOUT;
+ goto error;
+ }
+
+ /*
+ * If we have a high watermark configured then we don't want to
+ * read more data than would make us reach the watermark.
+ */
+ if (bufev->wm_read.high != 0) {
+ howmuch = bufev->wm_read.high - EVBUFFER_LENGTH(bufev->input);
+ /* we might have lowered the watermark, stop reading */
+ if (howmuch <= 0) {
+ struct evbuffer *buf = bufev->input;
+ event_del(&bufev->ev_read);
+ evbuffer_setcb(buf,
+ bufferevent_read_pressure_cb, bufev);
+ return;
+ }
+ }
+
+ res = evtls_read(bufev->input, fd, howmuch, ctx);
+ switch (res) {
+ case TLS_WANT_POLLIN:
+ bufferevent_add(&bufev->ev_read, bufev->timeout_read);
+ return;
+ case TLS_WANT_POLLOUT:
+ event_del(&bufev->ev_write);
+ event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_readcb,
+ buftls);
+ bufferevent_add(&bufev->ev_write, bufev->timeout_write);
+ return;
+ case -1:
+ what |= EVBUFFER_ERROR;
+ break;
+ case 0:
+ what |= EVBUFFER_EOF;
+ break;
+ }
+ if (res <= 0)
+ goto error;
+
+ event_del(&bufev->ev_write);
+ event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_writecb, buftls);
+ if (bufev->enabled & EV_READ)
+ bufferevent_add(&bufev->ev_read, bufev->timeout_read);
+ if (EVBUFFER_LENGTH(bufev->output) != 0 && bufev->enabled & EV_WRITE)
+ bufferevent_add(&bufev->ev_write, bufev->timeout_write);
+
+ /* See if this callbacks meets the water marks */
+ len = EVBUFFER_LENGTH(bufev->input);
+ if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
+ return;
+ if (bufev->wm_read.high != 0 && len >= bufev->wm_read.high) {
+ struct evbuffer *buf = bufev->input;
+ event_del(&bufev->ev_read);
+
+ /* Now schedule a callback for us when the buffer changes */
+ evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
+ }
+
+ /* Invoke the user callback - must always be called last */
+ if (bufev->readcb != NULL)
+ (*bufev->readcb)(bufev, bufev->cbarg);
+ return;
+
+ error:
+ (*bufev->errorcb)(bufev, what, bufev->cbarg);
+}
+
+static void
+buffertls_writecb(int fd, short event, void *arg)
+{
+ struct buffertls *buftls = arg;
+ struct bufferevent *bufev = buftls->bt_bufev;
+ struct tls *ctx = buftls->bt_ctx;
+ int res = 0;
+ short what = EVBUFFER_WRITE;
+
+ if (event == EV_TIMEOUT) {
+ what |= EVBUFFER_TIMEOUT;
+ goto error;
+ }
+
+ if (EVBUFFER_LENGTH(bufev->output) != 0) {
+ res = evtls_write(bufev->output, fd, ctx);
+ switch (res) {
+ case TLS_WANT_POLLIN:
+ event_del(&bufev->ev_read);
+ event_set(&bufev->ev_read, fd, EV_READ,
+ buffertls_writecb, buftls);
+ bufferevent_add(&bufev->ev_read, bufev->timeout_read);
+ return;
+ case TLS_WANT_POLLOUT:
+ bufferevent_add(&bufev->ev_write, bufev->timeout_write);
+ return;
+ case -1:
+ what |= EVBUFFER_ERROR;
+ break;
+ case 0:
+ what |= EVBUFFER_EOF;
+ break;
+ }
+ if (res <= 0)
+ goto error;
+ }
+
+ event_del(&bufev->ev_read);
+ event_set(&bufev->ev_read, fd, EV_READ, buffertls_readcb, buftls);
+ if (bufev->enabled & EV_READ)
+ bufferevent_add(&bufev->ev_read, bufev->timeout_read);
+ if (EVBUFFER_LENGTH(bufev->output) != 0 && bufev->enabled & EV_WRITE)
+ bufferevent_add(&bufev->ev_write, bufev->timeout_write);
+
+ /*
+ * Invoke the user callback if our buffer is drained or below the
+ * low watermark.
+ */
+ if (bufev->writecb != NULL &&
+ EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low)
+ (*bufev->writecb)(bufev, bufev->cbarg);
+
+ return;
+
+ error:
+ (*bufev->errorcb)(bufev, what, bufev->cbarg);
+}
+
+static void
+buffertls_handshakecb(int fd, short event, void *arg)
+{
+ struct buffertls *buftls = arg;
+ struct bufferevent *bufev = buftls->bt_bufev;
+ struct tls *ctx = buftls->bt_ctx;
+ int res = 0;
+ short what = EVBUFFER_HANDSHAKE;
+
+ if (event == EV_TIMEOUT) {
+ what |= EVBUFFER_TIMEOUT;
+ goto error;
+ }
+
+ res = tls_handshake(ctx);
+ switch (res) {
+ case TLS_WANT_POLLIN:
+ bufferevent_add(&bufev->ev_read, bufev->timeout_read);
+ return;
+ case TLS_WANT_POLLOUT:
+ bufferevent_add(&bufev->ev_write, bufev->timeout_write);
+ return;
+ case -1:
+ what |= EVBUFFER_ERROR;
+ break;
+ }
+ if (res < 0)
+ goto error;
+
+ /* Handshake was successful, change to read and write callback. */
+ event_del(&bufev->ev_read);
+ event_del(&bufev->ev_write);
+ event_set(&bufev->ev_read, fd, EV_READ, buffertls_readcb, buftls);
+ event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_writecb, buftls);
+ if (bufev->enabled & EV_READ)
+ bufferevent_add(&bufev->ev_read, bufev->timeout_read);
+ if (EVBUFFER_LENGTH(bufev->output) != 0 && bufev->enabled & EV_WRITE)
+ bufferevent_add(&bufev->ev_write, bufev->timeout_write);
+
+ return;
+
+ error:
+ (*bufev->errorcb)(bufev, what, bufev->cbarg);
+}
+
+void
+buffertls_set(struct buffertls *buftls, struct bufferevent *bufev,
+ struct tls *ctx, int fd)
+{
+ bufferevent_setfd(bufev, fd);
+ event_set(&bufev->ev_read, fd, EV_READ, buffertls_readcb, buftls);
+ event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_writecb, buftls);
+ buftls->bt_bufev = bufev;
+ buftls->bt_ctx = ctx;
+}
+
+void
+buffertls_accept(struct buffertls *buftls, int fd)
+{
+ struct bufferevent *bufev = buftls->bt_bufev;
+
+ event_del(&bufev->ev_read);
+ event_del(&bufev->ev_write);
+ event_set(&bufev->ev_read, fd, EV_READ, buffertls_handshakecb, buftls);
+ event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_handshakecb,
+ buftls);
+ bufferevent_add(&bufev->ev_read, bufev->timeout_read);
+}
+
+void
+buffertls_connect(struct buffertls *buftls, int fd)
+{
+ struct bufferevent *bufev = buftls->bt_bufev;
+
+ event_del(&bufev->ev_read);
+ event_del(&bufev->ev_write);
+ event_set(&bufev->ev_read, fd, EV_READ, buffertls_handshakecb, buftls);
+ event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_handshakecb,
+ buftls);
+ bufferevent_add(&bufev->ev_write, bufev->timeout_write);
+}
+
+/*
+ * Reads data from a file descriptor into a buffer.
+ */
+
+#define EVBUFFER_MAX_READ 4096
+
+int
+evtls_read(struct evbuffer *buf, int fd, int howmuch, struct tls *ctx)
+{
+ u_char *p;
+ size_t oldoff = buf->off;
+ int n = EVBUFFER_MAX_READ;
+
+ if (ioctl(fd, FIONREAD, &n) == -1 || n <= 0) {
+ n = EVBUFFER_MAX_READ;
+ } else if (n > EVBUFFER_MAX_READ && n > howmuch) {
+ /*
+ * It's possible that a lot of data is available for
+ * reading. We do not want to exhaust resources
+ * before the reader has a chance to do something
+ * about it. If the reader does not tell us how much
+ * data we should read, we artifically limit it.
+ */
+ if ((size_t)n > buf->totallen << 2)
+ n = buf->totallen << 2;
+ if (n < EVBUFFER_MAX_READ)
+ n = EVBUFFER_MAX_READ;
+ }
+ if (howmuch < 0 || howmuch > n)
+ howmuch = n;
+
+ /* If we don't have FIONREAD, we might waste some space here */
+ if (evbuffer_expand(buf, howmuch) == -1)
+ return (-1);
+
+ /* We can append new data at this point */
+ p = buf->buffer + buf->off;
+
+ n = tls_read(ctx, p, howmuch);
+ if (n <= 0)
+ return (n);
+
+ buf->off += n;
+
+ /* Tell someone about changes in this buffer */
+ if (buf->off != oldoff && buf->cb != NULL)
+ (*buf->cb)(buf, oldoff, buf->off, buf->cbarg);
+
+ return (n);
+}
+
+int
+evtls_write(struct evbuffer *buffer, int fd, struct tls *ctx)
+{
+ int n;
+
+ n = tls_write(ctx, buffer->buffer, buffer->off);
+ if (n <= 0)
+ return (n);
+ evbuffer_drain(buffer, n);
+
+ return (n);
+}
diff --git a/usr.sbin/ldapd/evbuffer_tls.h b/usr.sbin/ldapd/evbuffer_tls.h
new file mode 100644
index 00000000000..2f990174e19
--- /dev/null
+++ b/usr.sbin/ldapd/evbuffer_tls.h
@@ -0,0 +1,37 @@
+/* $OpenBSD: evbuffer_tls.h,v 1.1 2016/05/01 00:32:37 jmatthew Exp $ */
+
+/*
+ * Copyright (c) 2014-2015 Alexander Bluhm <bluhm@openbsd.org>
+ *
+ * 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.
+ */
+
+#ifndef _EVBUFFER_TLS_H_
+#define _EVBUFFER_TLS_H_
+
+#define EVBUFFER_HANDSHAKE 0x04
+
+struct bufferevent;
+struct tls;
+
+struct buffertls {
+ struct bufferevent *bt_bufev;
+ struct tls *bt_ctx;
+};
+
+void buffertls_set(struct buffertls *, struct bufferevent *, struct tls *,
+ int);
+void buffertls_accept(struct buffertls *, int);
+void buffertls_connect(struct buffertls *, int);
+
+#endif /* _EVBUFFER_TLS_H_ */
diff --git a/usr.sbin/ldapd/ldapd.c b/usr.sbin/ldapd/ldapd.c
index d8c723d87cc..b41eb2dac2f 100644
--- a/usr.sbin/ldapd/ldapd.c
+++ b/usr.sbin/ldapd/ldapd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldapd.c,v 1.19 2016/02/04 12:48:06 jca Exp $ */
+/* $OpenBSD: ldapd.c,v 1.20 2016/05/01 00:32:37 jmatthew Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -163,7 +163,7 @@ main(int argc, char *argv[])
log_verbose(verbose);
stats.started_at = time(0);
- ssl_init();
+ tls_init();
if (parse_config(conffile) != 0)
exit(2);
diff --git a/usr.sbin/ldapd/ldapd.h b/usr.sbin/ldapd/ldapd.h
index d6b9b8a981d..2cb4050f4dc 100644
--- a/usr.sbin/ldapd/ldapd.h
+++ b/usr.sbin/ldapd/ldapd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldapd.h,v 1.25 2015/11/02 06:32:51 jmatthew Exp $ */
+/* $OpenBSD: ldapd.h,v 1.26 2016/05/01 00:32:37 jmatthew Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -30,11 +30,13 @@
#include <limits.h>
#include <pwd.h>
#include <stdarg.h>
+#include <tls.h>
#include "aldap.h"
#include "schema.h"
#include "btree.h"
#include "imsgev.h"
+#include "evbuffer_tls.h"
#define CONFFILE "/etc/ldapd.conf"
#define LDAPD_USER "_ldapd"
@@ -203,7 +205,7 @@ struct listener {
struct event evt;
char ssl_cert_name[PATH_MAX];
struct ssl *ssl;
- void *ssl_ctx;
+ struct tls *tls;
TAILQ_ENTRY(listener) entry;
};
TAILQ_HEAD(listenerlist, listener);
@@ -223,12 +225,8 @@ struct conn {
struct listener *listener; /* where it connected from */
/* SSL support */
- struct event s_ev;
- struct timeval s_tv;
- struct listener *s_l;
- void *s_ssl;
- unsigned char *s_buf;
- int s_buflen;
+ struct tls *tls;
+ struct buffertls buftls;
unsigned int s_flags;
};
TAILQ_HEAD(conn_list, conn) conn_list;
@@ -236,11 +234,12 @@ TAILQ_HEAD(conn_list, conn) conn_list;
struct ssl {
SPLAY_ENTRY(ssl) ssl_nodes;
char ssl_name[PATH_MAX];
- char *ssl_cert;
- off_t ssl_cert_len;
- char *ssl_key;
- off_t ssl_key_len;
+ uint8_t *ssl_cert;
+ size_t ssl_cert_len;
+ uint8_t *ssl_key;
+ size_t ssl_key_len;
uint8_t flags;
+ struct tls_config *config;
};
struct ldapd_config
@@ -461,6 +460,9 @@ int authorized(struct conn *conn, struct namespace *ns,
/* parse.y */
int parse_config(char *filename);
int cmdline_symset(char *s);
+int ssl_cmp(struct ssl *, struct ssl *);
+SPLAY_PROTOTYPE(ssltree, ssl, ssl_nodes, ssl_cmp);
+
/* log.c */
void log_init(int);
@@ -499,21 +501,6 @@ int unindex_entry(struct namespace *ns, struct btval *dn,
int index_to_dn(struct namespace *ns, struct btval *indx,
struct btval *dn);
-/* ssl.c */
-void ssl_init(void);
-void ssl_transaction(struct conn *);
-
-void ssl_session_init(struct conn *);
-void ssl_session_destroy(struct conn *);
-int ssl_load_certfile(struct ldapd_config *, const char *, u_int8_t);
-void ssl_setup(struct ldapd_config *, struct listener *);
-int ssl_cmp(struct ssl *, struct ssl *);
-SPLAY_PROTOTYPE(ssltree, ssl, ssl_nodes, ssl_cmp);
-
-/* ssl_privsep.c */
-int ssl_ctx_use_private_key(void *, char *, off_t);
-int ssl_ctx_use_certificate_chain(void *, char *, off_t);
-
/* validate.c */
int validate_entry(const char *dn, struct ber_element *entry, int relax);
diff --git a/usr.sbin/ldapd/ldape.c b/usr.sbin/ldapd/ldape.c
index bb681a336dc..36559e1954b 100644
--- a/usr.sbin/ldapd/ldape.c
+++ b/usr.sbin/ldapd/ldape.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldape.c,v 1.23 2015/12/24 17:47:57 mmcc Exp $ */
+/* $OpenBSD: ldape.c,v 1.24 2016/05/01 00:32:37 jmatthew Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -341,6 +341,7 @@ ldape(struct passwd *pw, char *csockpath, int pipe_parent2ldap[2])
struct event ev_sigterm;
struct event ev_sigchld;
struct event ev_sighup;
+ struct ssl key;
char host[128];
mode_t old_umask = 0;
@@ -424,7 +425,24 @@ ldape(struct passwd *pw, char *csockpath, int pipe_parent2ldap[2])
event_add(&l->ev, NULL);
evtimer_set(&l->evt, conn_accept, l);
- ssl_setup(conf, l);
+ if (l->flags & F_SSL) {
+ if (strlcpy(key.ssl_name, l->ssl_cert_name,
+ sizeof(key.ssl_name)) >= sizeof(key.ssl_name))
+ fatal("ldape: certificate name truncated");
+
+ l->ssl = SPLAY_FIND(ssltree, conf->sc_ssl, &key);
+ if (l->ssl == NULL)
+ fatal("ldape: certificate tree corrupted");
+
+ l->tls = tls_server();
+ if (l->tls == NULL)
+ fatal("ldape: couldn't allocate tls context");
+
+ if (tls_configure(l->tls, l->ssl->config)) {
+ log_warn("ldape: %s", tls_error(l->tls));
+ fatal("ldape: couldn't configure tls");
+ }
+ }
}
TAILQ_FOREACH(ns, &conf->namespaces, next) {
diff --git a/usr.sbin/ldapd/parse.y b/usr.sbin/ldapd/parse.y
index 6bbb454397a..aec1d12ab28 100644
--- a/usr.sbin/ldapd/parse.y
+++ b/usr.sbin/ldapd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.16 2014/11/20 05:51:20 jsg Exp $ */
+/* $OpenBSD: parse.y,v 1.17 2016/05/01 00:32:37 jmatthew Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martinh@openbsd.org>
@@ -77,6 +77,7 @@ int host(const char *, const char *,
struct listenerlist *, int, in_port_t, u_int8_t);
int interface(const char *, const char *,
struct listenerlist *, int, in_port_t, u_int8_t);
+int load_certfile(struct ldapd_config *, const char *, u_int8_t);
TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
struct sym {
@@ -91,6 +92,8 @@ char *symget(const char *);
struct ldapd_config *conf;
+SPLAY_GENERATE(ssltree, ssl, ssl_nodes, ssl_cmp);
+
static struct aci *mk_aci(int type, int rights, enum scope scope,
char *target, char *subject);
@@ -181,7 +184,7 @@ conf_main : LISTEN ON STRING port ssl certname {
cert = ($6 != NULL) ? $6 : $3;
if (($5 == F_STARTTLS || $5 == F_LDAPS) &&
- ssl_load_certfile(conf, cert, F_SCERT) < 0) {
+ load_certfile(conf, cert, F_SCERT) < 0) {
yyerror("cannot load certificate: %s", cert);
free($6);
free($3);
@@ -1167,3 +1170,93 @@ namespace_new(const char *suffix)
return ns;
}
+int
+ssl_cmp(struct ssl *s1, struct ssl *s2)
+{
+ return (strcmp(s1->ssl_name, s2->ssl_name));
+}
+
+int
+load_certfile(struct ldapd_config *env, const char *name, u_int8_t flags)
+{
+ struct ssl *s;
+ struct ssl key;
+ char certfile[PATH_MAX];
+
+ if (strlcpy(key.ssl_name, name, sizeof(key.ssl_name))
+ >= sizeof(key.ssl_name)) {
+ log_warn("load_certfile: certificate name truncated");
+ return -1;
+ }
+
+ s = SPLAY_FIND(ssltree, env->sc_ssl, &key);
+ if (s != NULL) {
+ s->flags |= flags;
+ return 0;
+ }
+
+ if ((s = calloc(1, sizeof(*s))) == NULL)
+ fatal(NULL);
+
+ s->flags = flags;
+ (void)strlcpy(s->ssl_name, key.ssl_name, sizeof(s->ssl_name));
+
+ s->config = tls_config_new();
+ if (s->config == NULL)
+ goto err;
+
+ tls_config_set_protocols(s->config, TLS_PROTOCOLS_ALL);
+ if (tls_config_set_ciphers(s->config, "compat")) {
+ log_warn("load_certfile: failed to set tls ciphers: %s",
+ tls_config_error(s->config));
+ goto err;
+ }
+
+ if ((name[0] == '/' &&
+ !bsnprintf(certfile, sizeof(certfile), "%s.crt", name)) ||
+ !bsnprintf(certfile, sizeof(certfile), "/etc/ldap/certs/%s.crt",
+ name)) {
+ log_warn("load_certfile: path truncated");
+ goto err;
+ }
+
+ log_debug("loading certificate file %s", certfile);
+ s->ssl_cert = tls_load_file(certfile, &s->ssl_cert_len, NULL);
+ if (s->ssl_cert == NULL)
+ goto err;
+
+ if (tls_config_set_cert_mem(s->config, s->ssl_cert, s->ssl_cert_len)) {
+ log_warn("load_certfile: failed to set tls certificate: %s",
+ tls_config_error(s->config));
+ goto err;
+ }
+
+ if ((name[0] == '/' &&
+ !bsnprintf(certfile, sizeof(certfile), "%s.key", name)) ||
+ !bsnprintf(certfile, sizeof(certfile), "/etc/ldap/certs/%s.key",
+ name)) {
+ log_warn("load_certfile: path truncated");
+ goto err;
+ }
+
+ log_debug("loading key file %s", certfile);
+ s->ssl_key = tls_load_file(certfile, &s->ssl_key_len, NULL);
+ if (s->ssl_key == NULL)
+ goto err;
+
+ if (tls_config_set_key_mem(s->config, s->ssl_key, s->ssl_key_len)) {
+ log_warn("load_certfile: failed to set tls key: %s",
+ tls_config_error(s->config));
+ goto err;
+ }
+
+ SPLAY_INSERT(ssltree, env->sc_ssl, s);
+
+ return (0);
+err:
+ free(s->ssl_cert);
+ free(s->ssl_key);
+ tls_config_free(s->config);
+ free(s);
+ return (-1);
+}
diff --git a/usr.sbin/ldapd/ssl.c b/usr.sbin/ldapd/ssl.c
deleted file mode 100644
index e723e2af809..00000000000
--- a/usr.sbin/ldapd/ssl.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/* $OpenBSD: ssl.c,v 1.10 2015/12/30 15:59:55 benno Exp $ */
-
-/*
- * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
- * Copyright (c) 2008 Reyk Floeter <reyk@openbsd.org>
- *
- * 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 <sys/types.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <ctype.h>
-#include <event.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <openssl/ssl.h>
-#include <openssl/engine.h>
-#include <openssl/err.h>
-#include <openssl/dh.h>
-#include <openssl/bn.h>
-
-#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
-
-#include "ldapd.h"
-
-#define SSL_CIPHERS "HIGH:!aNULL"
-
-void ssl_error(const char *);
-char *ssl_load_file(const char *, off_t *);
-SSL_CTX *ssl_ctx_create(void);
-void ssl_session_accept(int, short, void *);
-void ssl_read(int, short, void *);
-void ssl_write(int, short, void *);
-int ssl_bufferevent_add(struct event *, int);
-
-DH *get_dh1024(void);
-void ssl_set_ephemeral_key_exchange(SSL_CTX *, DH *);
-
-extern void bufferevent_read_pressure_cb(struct evbuffer *, size_t,
- size_t, void *);
-
-void
-ssl_read(int fd, short event, void *p)
-{
- struct bufferevent *bufev = p;
- struct conn *s = bufev->cbarg;
- int ret;
- int ssl_err;
- short what;
- size_t len;
- char rbuf[IBUF_READ_SIZE];
- int howmuch = IBUF_READ_SIZE;
-
- what = EVBUFFER_READ;
-
- if (event == EV_TIMEOUT) {
- what |= EVBUFFER_TIMEOUT;
- goto err;
- }
-
- if (bufev->wm_read.high != 0)
- howmuch = MINIMUM(sizeof(rbuf), bufev->wm_read.high);
-
- ret = SSL_read(s->s_ssl, rbuf, howmuch);
- if (ret <= 0) {
- ssl_err = SSL_get_error(s->s_ssl, ret);
-
- switch (ssl_err) {
- case SSL_ERROR_WANT_READ:
- goto retry;
- case SSL_ERROR_WANT_WRITE:
- goto retry;
- default:
- if (ret == 0)
- what |= EVBUFFER_EOF;
- else {
- ssl_error("ssl_read");
- what |= EVBUFFER_ERROR;
- }
- goto err;
- }
- }
-
- if (evbuffer_add(bufev->input, rbuf, ret) == -1) {
- what |= EVBUFFER_ERROR;
- goto err;
- }
-
- ssl_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
-
- len = EVBUFFER_LENGTH(bufev->input);
- if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
- return;
- if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) {
- struct evbuffer *buf = bufev->input;
- event_del(&bufev->ev_read);
- evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
- return;
- }
-
- if (bufev->readcb != NULL)
- (*bufev->readcb)(bufev, bufev->cbarg);
- return;
-
-retry:
- ssl_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
- return;
-
-err:
- (*bufev->errorcb)(bufev, what, bufev->cbarg);
-}
-
-
-void
-ssl_write(int fd, short event, void *p)
-{
- struct bufferevent *bufev = p;
- struct conn *s = bufev->cbarg;
- int ret;
- int ssl_err;
- short what;
-
- what = EVBUFFER_WRITE;
-
- if (event == EV_TIMEOUT) {
- what |= EV_TIMEOUT;
- goto err;
- }
-
- if (EVBUFFER_LENGTH(bufev->output)) {
- if (s->s_buf == NULL) {
- s->s_buflen = EVBUFFER_LENGTH(bufev->output);
- if ((s->s_buf = malloc(s->s_buflen)) == NULL) {
- what |= EVBUFFER_ERROR;
- goto err;
- }
- memcpy(s->s_buf, EVBUFFER_DATA(bufev->output),
- s->s_buflen);
- }
-
- ret = SSL_write(s->s_ssl, s->s_buf, s->s_buflen);
- if (ret <= 0) {
- ssl_err = SSL_get_error(s->s_ssl, ret);
-
- switch (ssl_err) {
- case SSL_ERROR_WANT_READ:
- goto retry;
- case SSL_ERROR_WANT_WRITE:
- goto retry;
- default:
- if (ret == 0)
- what |= EVBUFFER_EOF;
- else {
- ssl_error("ssl_write");
- what |= EVBUFFER_ERROR;
- }
- goto err;
- }
- }
- evbuffer_drain(bufev->output, ret);
- }
- if (s->s_buf != NULL) {
- free(s->s_buf);
- s->s_buf = NULL;
- s->s_buflen = 0;
- }
- if (EVBUFFER_LENGTH(bufev->output) != 0)
- ssl_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
-
- if (bufev->writecb != NULL &&
- EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low)
- (*bufev->writecb)(bufev, bufev->cbarg);
- return;
-
-retry:
- if (s->s_buflen != 0)
- ssl_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
- return;
-
-err:
- if (s->s_buf != NULL) {
- free(s->s_buf);
- s->s_buf = NULL;
- s->s_buflen = 0;
- }
- (*bufev->errorcb)(bufev, what, bufev->cbarg);
-}
-
-int
-ssl_bufferevent_add(struct event *ev, int timeout)
-{
- struct timeval tv;
- struct timeval *ptv = NULL;
-
- if (timeout) {
- timerclear(&tv);
- tv.tv_sec = timeout;
- ptv = &tv;
- }
-
- return (event_add(ev, ptv));
-}
-
-int
-ssl_cmp(struct ssl *s1, struct ssl *s2)
-{
- return (strcmp(s1->ssl_name, s2->ssl_name));
-}
-
-SPLAY_GENERATE(ssltree, ssl, ssl_nodes, ssl_cmp);
-
-char *
-ssl_load_file(const char *name, off_t *len)
-{
- struct stat st;
- off_t size;
- char *buf = NULL;
- int fd;
-
- if ((fd = open(name, O_RDONLY)) == -1)
- return (NULL);
- if (fstat(fd, &st) != 0)
- goto fail;
- size = st.st_size;
- if ((buf = calloc(1, size + 1)) == NULL)
- goto fail;
- if (read(fd, buf, size) != size)
- goto fail;
- close(fd);
-
- *len = size + 1;
- return (buf);
-
-fail:
- free(buf);
- close(fd);
- return (NULL);
-}
-
-SSL_CTX *
-ssl_ctx_create(void)
-{
- SSL_CTX *ctx;
-
- ctx = SSL_CTX_new(SSLv23_method());
- if (ctx == NULL) {
- ssl_error("ssl_ctx_create");
- fatal("ssl_ctx_create: could not create SSL context");
- }
-
- SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
- SSL_CTX_set_timeout(ctx, LDAPD_SESSION_TIMEOUT);
- SSL_CTX_set_options(ctx, SSL_OP_ALL);
- SSL_CTX_set_options(ctx,
- SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
-
- if (!SSL_CTX_set_cipher_list(ctx, SSL_CIPHERS)) {
- ssl_error("ssl_ctx_create");
- fatal("ssl_ctx_create: could not set cipher list");
- }
- return (ctx);
-}
-
-int
-ssl_load_certfile(struct ldapd_config *env, const char *name, u_int8_t flags)
-{
- struct ssl *s;
- struct ssl key;
- char certfile[PATH_MAX];
-
- if (strlcpy(key.ssl_name, name, sizeof(key.ssl_name))
- >= sizeof(key.ssl_name)) {
- log_warn("ssl_load_certfile: certificate name truncated");
- return -1;
- }
-
- s = SPLAY_FIND(ssltree, env->sc_ssl, &key);
- if (s != NULL) {
- s->flags |= flags;
- return 0;
- }
-
- if ((s = calloc(1, sizeof(*s))) == NULL)
- fatal(NULL);
-
- s->flags = flags;
- (void)strlcpy(s->ssl_name, key.ssl_name, sizeof(s->ssl_name));
-
- if ((name[0] == '/' &&
- !bsnprintf(certfile, sizeof(certfile), "%s.crt", name)) ||
- !bsnprintf(certfile, sizeof(certfile), "/etc/ldap/certs/%s.crt",
- name)) {
- log_warn("ssl_load_certfile: path truncated");
- free(s);
- return -1;
- }
-
- log_debug("loading certificate file %s", certfile);
- if ((s->ssl_cert = ssl_load_file(certfile, &s->ssl_cert_len)) == NULL) {
- free(s);
- return (-1);
- }
-
- if ((name[0] == '/' &&
- !bsnprintf(certfile, sizeof(certfile), "%s.key", name)) ||
- !bsnprintf(certfile, sizeof(certfile), "/etc/ldap/certs/%s.key",
- name)) {
- log_warn("ssl_load_certfile: path truncated");
- free(s->ssl_cert);
- free(s);
- return -1;
- }
-
- log_debug("loading key file %s", certfile);
- if ((s->ssl_key = ssl_load_file(certfile, &s->ssl_key_len)) == NULL) {
- free(s->ssl_cert);
- free(s);
- return (-1);
- }
-
- SPLAY_INSERT(ssltree, env->sc_ssl, s);
-
- return (0);
-}
-
-void
-ssl_init(void)
-{
- SSL_library_init();
- SSL_load_error_strings();
-
- OpenSSL_add_all_algorithms();
-
- /* Init hardware crypto engines. */
- ENGINE_load_builtin_engines();
- ENGINE_register_all_complete();
-}
-
-void
-ssl_setup(struct ldapd_config *env, struct listener *l)
-{
- struct ssl key;
-
- if (!(l->flags & F_SSL))
- return;
-
- if (strlcpy(key.ssl_name, l->ssl_cert_name, sizeof(key.ssl_name))
- >= sizeof(key.ssl_name))
- fatal("ssl_setup: certificate name truncated");
-
- if ((l->ssl = SPLAY_FIND(ssltree, env->sc_ssl, &key)) == NULL)
- fatal("ssl_setup: certificate tree corrupted");
-
- l->ssl_ctx = ssl_ctx_create();
-
- if (!ssl_ctx_use_certificate_chain(l->ssl_ctx,
- l->ssl->ssl_cert, l->ssl->ssl_cert_len))
- goto err;
- if (!ssl_ctx_use_private_key(l->ssl_ctx,
- l->ssl->ssl_key, l->ssl->ssl_key_len))
- goto err;
-
- if (!SSL_CTX_check_private_key(l->ssl_ctx))
- goto err;
- if (!SSL_CTX_set_session_id_context(l->ssl_ctx,
- (const unsigned char *)l->ssl_cert_name, strlen(l->ssl_cert_name) + 1))
- goto err;
-
- ssl_set_ephemeral_key_exchange(l->ssl_ctx, get_dh1024());
-
- log_debug("ssl_setup: ssl setup finished for listener: %p", l);
- return;
-
-err:
- SSL_CTX_free(l->ssl_ctx);
- ssl_error("ssl_setup");
- fatal("ssl_setup: cannot set SSL up");
-}
-
-void
-ssl_error(const char *where)
-{
- unsigned long code;
- char errbuf[128];
- extern int debug;
-
- if (!debug)
- return;
- for (; (code = ERR_get_error()) != 0 ;) {
- ERR_error_string_n(code, errbuf, sizeof(errbuf));
- log_debug("SSL library error: %s: %s", where, errbuf);
- }
-}
-
-void
-ssl_session_accept(int fd, short event, void *p)
-{
- struct conn *s = p;
- int ret;
- int ssl_err;
-
- if (event == EV_TIMEOUT) {
- log_debug("ssl_session_accept: session timed out");
- conn_close(s);
- return;
- }
-
- log_debug("ssl_session_accept: accepting client");
- ret = SSL_accept(s->s_ssl);
- if (ret <= 0) {
- ssl_err = SSL_get_error(s->s_ssl, ret);
-
- switch (ssl_err) {
- case SSL_ERROR_WANT_READ:
- goto retry;
- case SSL_ERROR_WANT_WRITE:
- goto retry;
- case SSL_ERROR_ZERO_RETURN:
- case SSL_ERROR_SYSCALL:
- if (ret == 0) {
- conn_close(s);
- return;
- }
- /* FALLTHROUGH */
- default:
- ssl_error("ssl_session_accept");
- conn_close(s);
- return;
- }
- }
-
- log_debug("ssl_session_accept: accepted ssl client");
- s->s_flags |= F_SECURE;
-
- s->bev = bufferevent_new(s->fd, conn_read, conn_write, conn_err, s);
- if (s->bev == NULL) {
- log_warn("ssl_session_accept: bufferevent_new");
- conn_close(s);
- return;
- }
- bufferevent_settimeout(s->bev, 0, 60);
-
- event_set(&s->bev->ev_read, s->fd, EV_READ, ssl_read, s->bev);
- event_set(&s->bev->ev_write, s->fd, EV_WRITE, ssl_write, s->bev);
- bufferevent_enable(s->bev, EV_READ);
-
- return;
-retry:
- event_add(&s->s_ev, &s->s_tv);
-}
-
-void
-ssl_session_init(struct conn *s)
-{
- struct listener *l;
- SSL *ssl;
-
- l = s->s_l;
-
- if (!(l->flags & F_SSL))
- return;
-
- log_debug("ssl_session_init: switching to SSL");
- ssl = SSL_new(l->ssl_ctx);
- if (ssl == NULL)
- goto err;
-
- if (!SSL_set_ssl_method(ssl, SSLv23_server_method()))
- goto err;
- if (!SSL_set_fd(ssl, s->fd))
- goto err;
- SSL_set_accept_state(ssl);
-
- s->s_ssl = ssl;
-
- s->s_tv.tv_sec = LDAPD_SESSION_TIMEOUT;
- s->s_tv.tv_usec = 0;
- event_set(&s->s_ev, s->fd, EV_READ|EV_TIMEOUT, ssl_session_accept, s);
- event_add(&s->s_ev, &s->s_tv);
- return;
-
- err:
- SSL_free(ssl);
- ssl_error("ssl_session_init");
-}
-
-void
-ssl_session_destroy(struct conn *s)
-{
- SSL_free(s->s_ssl);
-}
-
-/* From OpenSSL's documentation:
- *
- * If "strong" primes were used to generate the DH parameters, it is
- * not strictly necessary to generate a new key for each handshake
- * but it does improve forward secrecy.
- *
- * -- gilles@
- */
-DH *
-get_dh1024(void)
-{
- DH *dh;
- unsigned char dh1024_p[] = {
- 0xAD,0x37,0xBB,0x26,0x75,0x01,0x27,0x75,
- 0x06,0xB5,0xE7,0x1E,0x1F,0x2B,0xBC,0x51,
- 0xC0,0xF4,0xEB,0x42,0x7A,0x2A,0x83,0x1E,
- 0xE8,0xD1,0xD8,0xCC,0x9E,0xE6,0x15,0x1D,
- 0x06,0x46,0x50,0x94,0xB9,0xEE,0xB6,0x89,
- 0xB7,0x3C,0xAC,0x07,0x5E,0x29,0x37,0xCC,
- 0x8F,0xDF,0x48,0x56,0x85,0x83,0x26,0x02,
- 0xB8,0xB6,0x63,0xAF,0x2D,0x4A,0x57,0x93,
- 0x6B,0x54,0xE1,0x8F,0x28,0x76,0x9C,0x5D,
- 0x90,0x65,0xD1,0x07,0xFE,0x5B,0x05,0x65,
- 0xDA,0xD2,0xE2,0xAF,0x23,0xCA,0x2F,0xD6,
- 0x4B,0xD2,0x04,0xFE,0xDF,0x21,0x2A,0xE1,
- 0xCD,0x1B,0x70,0x76,0xB3,0x51,0xA4,0xC9,
- 0x2B,0x68,0xE3,0xDD,0xCB,0x97,0xDA,0x59,
- 0x50,0x93,0xEE,0xDB,0xBF,0xC7,0xFA,0xA7,
- 0x47,0xC4,0x4D,0xF0,0xC6,0x09,0x4A,0x4B
- };
- unsigned char dh1024_g[] = {
- 0x02
- };
-
- if ((dh = DH_new()) == NULL)
- return NULL;
-
- dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
- dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
- if (dh->p == NULL || dh->g == NULL) {
- DH_free(dh);
- return NULL;
- }
-
- return dh;
-}
-
-void
-ssl_set_ephemeral_key_exchange(SSL_CTX *ctx, DH *dh)
-{
- if (dh == NULL || !SSL_CTX_set_tmp_dh(ctx, dh))
- fatal("ssl_set_ephemeral_key_exchange: cannot set tmp dh");
-}
diff --git a/usr.sbin/ldapd/ssl_privsep.c b/usr.sbin/ldapd/ssl_privsep.c
deleted file mode 100644
index 0e55bae08d0..00000000000
--- a/usr.sbin/ldapd/ssl_privsep.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* $OpenBSD: ssl_privsep.c,v 1.4 2015/01/28 15:50:30 reyk Exp $ */
-
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-/*
- * SSL operations needed when running in a privilege separated environment.
- * Adapted from openssl's ssl_rsa.c by Pierre-Yves Ritschard .
- */
-
-#include <sys/types.h>
-#include <sys/uio.h>
-
-#include <unistd.h>
-#include <stdio.h>
-
-#include <openssl/err.h>
-#include <openssl/bio.h>
-#include <openssl/objects.h>
-#include <openssl/evp.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
-#include <openssl/ssl.h>
-
-int ssl_ctx_use_private_key(SSL_CTX *, char *, off_t);
-int ssl_ctx_use_certificate_chain(SSL_CTX *, char *, off_t);
-
-int
-ssl_ctx_use_private_key(SSL_CTX *ctx, char *buf, off_t len)
-{
- int ret;
- BIO *in;
- EVP_PKEY *pkey;
-
- ret = 0;
-
- if ((in = BIO_new_mem_buf(buf, len)) == NULL) {
- SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB);
- return 0;
- }
-
- pkey = PEM_read_bio_PrivateKey(in, NULL,
- ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata);
-
- if (pkey == NULL) {
- SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_PEM_LIB);
- goto end;
- }
- ret = SSL_CTX_use_PrivateKey(ctx, pkey);
- EVP_PKEY_free(pkey);
-end:
- if (in != NULL)
- BIO_free(in);
- return ret;
-}
-
-int
-ssl_ctx_use_certificate_chain(SSL_CTX *ctx, char *buf, off_t len)
-{
- int ret;
- BIO *in;
- X509 *x;
- X509 *ca;
- unsigned long err;
-
- ret = 0;
- x = ca = NULL;
-
- if ((in = BIO_new_mem_buf(buf, len)) == NULL) {
- SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
- goto end;
- }
-
- if ((x = PEM_read_bio_X509(in, NULL,
- ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata)) == NULL) {
- SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
- goto end;
- }
-
- if (!SSL_CTX_use_certificate(ctx, x) || ERR_peek_error() != 0)
- goto end;
-
- /* If we could set up our certificate, now proceed to
- * the CA certificates.
- */
-
- if (ctx->extra_certs != NULL) {
- sk_X509_pop_free(ctx->extra_certs, X509_free);
- ctx->extra_certs = NULL;
- }
-
- while ((ca = PEM_read_bio_X509(in, NULL,
- ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata)) != NULL) {
-
- if (!SSL_CTX_add_extra_chain_cert(ctx, ca))
- goto end;
- }
-
- err = ERR_peek_last_error();
- if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
- ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
- ERR_clear_error();
- else
- goto end;
-
- ret = 1;
-end:
- if (ca != NULL)
- X509_free(ca);
- if (x != NULL)
- X509_free(x);
- if (in != NULL)
- BIO_free(in);
- return (ret);
-}