xref: /openbsd-src/usr.sbin/smtpd/ssl.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*	$OpenBSD: ssl.c,v 1.37 2011/09/01 19:56:49 eric Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
5  * Copyright (c) 2008 Reyk Floeter <reyk@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <sys/queue.h>
22 #include <sys/tree.h>
23 #include <sys/param.h>
24 #include <sys/socket.h>
25 #include <sys/stat.h>
26 
27 #include <ctype.h>
28 #include <event.h>
29 #include <fcntl.h>
30 #include <imsg.h>
31 #include <pwd.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 
37 #include <openssl/ssl.h>
38 #include <openssl/engine.h>
39 #include <openssl/err.h>
40 
41 #include "smtpd.h"
42 #include "log.h"
43 
44 #define SSL_CIPHERS	"HIGH"
45 
46 void	 ssl_error(const char *);
47 char	*ssl_load_file(const char *, off_t *);
48 SSL_CTX	*ssl_ctx_create(void);
49 void	 ssl_session_accept(int, short, void *);
50 void	 ssl_read(int, short, void *);
51 void	 ssl_write(int, short, void *);
52 int	 ssl_bufferevent_add(struct event *, int);
53 void	 ssl_connect(int, short, void *);
54 
55 SSL	*ssl_client_init(int, char *, size_t, char *, size_t);
56 
57 int	 ssl_buf_read(SSL *, struct ibuf_read *);
58 int	 ssl_buf_write(SSL *, struct msgbuf *);
59 
60 DH	*get_dh1024(void);
61 DH	*get_dh_from_memory(char *, size_t);
62 void	 ssl_set_ephemeral_key_exchange(SSL_CTX *, DH *);
63 
64 extern void	bufferevent_read_pressure_cb(struct evbuffer *, size_t,
65 		    size_t, void *);
66 
67 void
68 ssl_connect(int fd, short event, void *p)
69 {
70 	struct session	*s = p;
71 	int		 ret;
72 	int		 retry_flag;
73 	int		 ssl_err;
74 
75 	if (event == EV_TIMEOUT) {
76 		log_debug("ssl_connect: session timed out");
77 		session_destroy(s);
78 		return;
79 	}
80 
81 	ret = SSL_connect(s->s_ssl);
82 	if (ret <= 0) {
83 		ssl_err = SSL_get_error(s->s_ssl, ret);
84 
85 		switch (ssl_err) {
86 		case SSL_ERROR_WANT_READ:
87 			retry_flag = EV_READ;
88 			goto retry;
89 		case SSL_ERROR_WANT_WRITE:
90 			retry_flag = EV_WRITE;
91 			goto retry;
92 		case SSL_ERROR_ZERO_RETURN:
93 		case SSL_ERROR_SYSCALL:
94 			if (ret == 0) {
95 				log_debug("session destroy in MTA #1");
96 				session_destroy(s);
97 				return;
98 			}
99 			/* FALLTHROUGH */
100 		default:
101 			ssl_error("ssl_session_connect");
102 			session_destroy(s);
103 			return;
104 		}
105 	}
106 
107 	event_set(&s->s_bev->ev_read, s->s_fd, EV_READ, ssl_read, s->s_bev);
108 	event_set(&s->s_bev->ev_write, s->s_fd, EV_WRITE, ssl_write, s->s_bev);
109 
110 	log_info("ssl_connect: connected to remote ssl server");
111 	bufferevent_enable(s->s_bev, EV_READ|EV_WRITE);
112 	s->s_flags |= F_SECURE;
113 
114 	if (s->s_flags & F_PEERHASTLS) {
115 		session_respond(s, "EHLO %s", env->sc_hostname);
116 	}
117 
118 	return;
119 retry:
120 	event_set(&s->s_ev, s->s_fd, EV_TIMEOUT|retry_flag, ssl_connect, s);
121 	event_add(&s->s_ev, &s->s_tv);
122 }
123 
124 void
125 ssl_read(int fd, short event, void *p)
126 {
127 	struct bufferevent	*bufev = p;
128 	struct session		*s = bufev->cbarg;
129 	int			 ret;
130 	int			 ssl_err;
131 	short			 what;
132 	size_t			 len;
133 	char			 rbuf[IBUF_READ_SIZE];
134 	int			 howmuch = IBUF_READ_SIZE;
135 
136 	what = EVBUFFER_READ;
137 	ret = ssl_err = 0;
138 
139 	if (event == EV_TIMEOUT) {
140 		what |= EVBUFFER_TIMEOUT;
141 		goto err;
142 	}
143 
144 	if (bufev->wm_read.high != 0)
145 		howmuch = MIN(sizeof(rbuf), bufev->wm_read.high);
146 
147 	ret = SSL_read(s->s_ssl, rbuf, howmuch);
148 	if (ret <= 0) {
149 		ssl_err = SSL_get_error(s->s_ssl, ret);
150 
151 		switch (ssl_err) {
152 		case SSL_ERROR_WANT_READ:
153 			goto retry;
154 		case SSL_ERROR_WANT_WRITE:
155 			goto retry;
156 		default:
157 			if (ret == 0)
158 				what |= EVBUFFER_EOF;
159 			else {
160 				ssl_error("ssl_read");
161 				what |= EVBUFFER_ERROR;
162 			}
163 			goto err;
164 		}
165 	}
166 
167 	if (evbuffer_add(bufev->input, rbuf, ret) == -1) {
168 		what |= EVBUFFER_ERROR;
169 		goto err;
170 	}
171 
172 	ssl_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
173 
174 	len = EVBUFFER_LENGTH(bufev->input);
175 	if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
176 		return;
177 	if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) {
178 		struct evbuffer *buf = bufev->input;
179 		event_del(&bufev->ev_read);
180 		evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
181 		return;
182 	}
183 
184 	if (bufev->readcb != NULL)
185 		(*bufev->readcb)(bufev, bufev->cbarg);
186 	return;
187 
188 retry:
189 	ssl_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
190 	return;
191 
192 err:
193 	(*bufev->errorcb)(bufev, what, bufev->cbarg);
194 }
195 
196 
197 void
198 ssl_write(int fd, short event, void *p)
199 {
200 	struct bufferevent	*bufev = p;
201 	struct session		*s = bufev->cbarg;
202 	int			 ret;
203 	int			 ssl_err;
204 	short			 what;
205 
206 	ret = 0;
207 	what = EVBUFFER_WRITE;
208 
209 	if (event == EV_TIMEOUT) {
210 		what |= EV_TIMEOUT;
211 		goto err;
212 	}
213 
214 	if (EVBUFFER_LENGTH(bufev->output)) {
215 		if (s->s_buf == NULL) {
216 			s->s_buflen = EVBUFFER_LENGTH(bufev->output);
217 			if ((s->s_buf = malloc(s->s_buflen)) == NULL) {
218 				what |= EVBUFFER_ERROR;
219 				goto err;
220 			}
221 			memcpy(s->s_buf, EVBUFFER_DATA(bufev->output),
222 			    s->s_buflen);
223 		}
224 
225 		ret = SSL_write(s->s_ssl, s->s_buf, s->s_buflen);
226 		if (ret <= 0) {
227 			ssl_err = SSL_get_error(s->s_ssl, ret);
228 
229 			switch (ssl_err) {
230 			case SSL_ERROR_WANT_READ:
231 				goto retry;
232 			case SSL_ERROR_WANT_WRITE:
233 				goto retry;
234 			default:
235 				if (ret == 0)
236 					what |= EVBUFFER_EOF;
237 				else {
238 					ssl_error("ssl_write");
239 					what |= EVBUFFER_ERROR;
240 				}
241 				goto err;
242 			}
243 		}
244 		evbuffer_drain(bufev->output, ret);
245 	}
246 	if (s->s_buf != NULL) {
247 		free(s->s_buf);
248 		s->s_buf = NULL;
249 		s->s_buflen = 0;
250 	}
251 	if (EVBUFFER_LENGTH(bufev->output) != 0)
252 		ssl_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
253 
254 	if (bufev->writecb != NULL &&
255 	    EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low)
256 		(*bufev->writecb)(bufev, bufev->cbarg);
257 	return;
258 
259 retry:
260 	if (s->s_buflen != 0)
261 		ssl_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
262 	return;
263 
264 err:
265 	if (s->s_buf != NULL) {
266 		free(s->s_buf);
267 		s->s_buf = NULL;
268 		s->s_buflen = 0;
269 	}
270 	(*bufev->errorcb)(bufev, what, bufev->cbarg);
271 }
272 
273 int
274 ssl_bufferevent_add(struct event *ev, int timeout)
275 {
276 	struct timeval	 tv;
277 	struct timeval	*ptv = NULL;
278 
279 	if (timeout) {
280 		timerclear(&tv);
281 		tv.tv_sec = timeout;
282 		ptv = &tv;
283 	}
284 
285 	return (event_add(ev, ptv));
286 }
287 
288 int
289 ssl_cmp(struct ssl *s1, struct ssl *s2)
290 {
291 	return (strcmp(s1->ssl_name, s2->ssl_name));
292 }
293 
294 SPLAY_GENERATE(ssltree, ssl, ssl_nodes, ssl_cmp);
295 
296 char *
297 ssl_load_file(const char *name, off_t *len)
298 {
299 	struct stat	 st;
300 	off_t		 size;
301 	char		*buf = NULL;
302 	int		 fd;
303 
304 	if ((fd = open(name, O_RDONLY)) == -1)
305 		return (NULL);
306 	if (fstat(fd, &st) != 0)
307 		goto fail;
308 	size = st.st_size;
309 	if ((buf = calloc(1, size + 1)) == NULL)
310 		goto fail;
311 	if (read(fd, buf, size) != size)
312 		goto fail;
313 	close(fd);
314 
315 	*len = size + 1;
316 	return (buf);
317 
318 fail:
319 	if (buf != NULL)
320 		free(buf);
321 	close(fd);
322 	return (NULL);
323 }
324 
325 SSL_CTX *
326 ssl_ctx_create(void)
327 {
328 	SSL_CTX	*ctx;
329 
330 	ctx = SSL_CTX_new(SSLv23_method());
331 	if (ctx == NULL) {
332 		ssl_error("ssl_ctx_create");
333 		fatal("ssl_ctx_create: could not create SSL context");
334 	}
335 
336 	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
337 	SSL_CTX_set_timeout(ctx, SMTPD_SESSION_TIMEOUT);
338 	SSL_CTX_set_options(ctx, SSL_OP_ALL);
339 	SSL_CTX_set_options(ctx,
340 	    SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
341 
342 	if (!SSL_CTX_set_cipher_list(ctx, SSL_CIPHERS)) {
343 		ssl_error("ssl_ctx_create");
344 		fatal("ssl_ctx_create: could not set cipher list");
345 	}
346 	return (ctx);
347 }
348 
349 int
350 ssl_load_certfile(const char *name, u_int8_t flags)
351 {
352 	struct ssl	*s;
353 	struct ssl	 key;
354 	char		 certfile[PATH_MAX];
355 
356 	if (strlcpy(key.ssl_name, name, sizeof(key.ssl_name))
357 	    >= sizeof(key.ssl_name)) {
358 		log_warn("ssl_load_certfile: certificate name truncated");
359 		return -1;
360 	}
361 
362 	s = SPLAY_FIND(ssltree, env->sc_ssl, &key);
363 	if (s != NULL) {
364 		s->flags |= flags;
365 		return 0;
366 	}
367 
368 	if ((s = calloc(1, sizeof(*s))) == NULL)
369 		fatal(NULL);
370 
371 	s->flags = flags;
372 	(void)strlcpy(s->ssl_name, key.ssl_name, sizeof(s->ssl_name));
373 
374 	if (! bsnprintf(certfile, sizeof(certfile),
375 		"/etc/mail/certs/%s.crt", name))
376 		goto err;
377 
378 	if ((s->ssl_cert = ssl_load_file(certfile, &s->ssl_cert_len)) == NULL)
379 		goto err;
380 
381 	if (! bsnprintf(certfile, sizeof(certfile),
382 		"/etc/mail/certs/%s.key", name))
383 		goto err;
384 
385 	if ((s->ssl_key = ssl_load_file(certfile, &s->ssl_key_len)) == NULL)
386 		goto err;
387 
388 	if (! bsnprintf(certfile, sizeof(certfile),
389 		"/etc/mail/certs/%s.dh", name))
390 		goto err;
391 
392 	if ((s->ssl_dhparams = ssl_load_file(certfile,
393 		    &s->ssl_dhparams_len)) == NULL) {
394 		log_info("no DH parameters found in %s", certfile);
395 		log_info("using built-in DH parameters");
396 	}
397 
398 	SPLAY_INSERT(ssltree, env->sc_ssl, s);
399 
400 	return (0);
401 err:
402 	if (s->ssl_cert != NULL)
403 		free(s->ssl_cert);
404 	if (s->ssl_key != NULL)
405 		free(s->ssl_key);
406 	if (s->ssl_dhparams != NULL)
407 		free(s->ssl_dhparams);
408 	if (s != NULL)
409 		free(s);
410 	return (-1);
411 }
412 
413 void
414 ssl_init(void)
415 {
416 	SSL_library_init();
417 	SSL_load_error_strings();
418 
419 	OpenSSL_add_all_algorithms();
420 
421 	/* Init hardware crypto engines. */
422 	ENGINE_load_builtin_engines();
423 	ENGINE_register_all_complete();
424 }
425 
426 void
427 ssl_setup(struct listener *l)
428 {
429 	struct ssl	key;
430 	DH *dh;
431 
432 	if (!(l->flags & F_SSL))
433 		return;
434 
435 	if (strlcpy(key.ssl_name, l->ssl_cert_name, sizeof(key.ssl_name))
436 	    >= sizeof(key.ssl_name))
437 		fatal("ssl_setup: certificate name truncated");
438 
439 	if ((l->ssl = SPLAY_FIND(ssltree, env->sc_ssl, &key)) == NULL)
440 		fatal("ssl_setup: certificate tree corrupted");
441 
442 	l->ssl_ctx = ssl_ctx_create();
443 
444 	if (!ssl_ctx_use_certificate_chain(l->ssl_ctx,
445 	    l->ssl->ssl_cert, l->ssl->ssl_cert_len))
446 		goto err;
447 	if (!ssl_ctx_use_private_key(l->ssl_ctx,
448 	    l->ssl->ssl_key, l->ssl->ssl_key_len))
449 		goto err;
450 
451 	if (!SSL_CTX_check_private_key(l->ssl_ctx))
452 		goto err;
453 	if (!SSL_CTX_set_session_id_context(l->ssl_ctx,
454 		(const unsigned char *)l->ssl_cert_name,
455 		strlen(l->ssl_cert_name) + 1))
456 		goto err;
457 
458 
459 
460 	if (l->ssl->ssl_dhparams_len == 0)
461 		dh = get_dh1024();
462 	else
463 		dh = get_dh_from_memory(l->ssl->ssl_dhparams,
464 		    l->ssl->ssl_dhparams_len);
465 	ssl_set_ephemeral_key_exchange(l->ssl_ctx, dh);
466 
467 	log_debug("ssl_setup: ssl setup finished for listener: %p", l);
468 	return;
469 
470 err:
471 	if (l->ssl_ctx != NULL)
472 		SSL_CTX_free(l->ssl_ctx);
473 	ssl_error("ssl_setup");
474 	fatal("ssl_setup: cannot set SSL up");
475 	return;
476 }
477 
478 void
479 ssl_error(const char *where)
480 {
481 	unsigned long	code;
482 	char		errbuf[128];
483 	extern int	debug;
484 
485 	if (!debug)
486 		return;
487 	for (; (code = ERR_get_error()) != 0 ;) {
488 		ERR_error_string_n(code, errbuf, sizeof(errbuf));
489 		log_debug("SSL library error: %s: %s", where, errbuf);
490 	}
491 }
492 
493 void
494 ssl_session_accept(int fd, short event, void *p)
495 {
496 	struct session	*s = p;
497 	int		 ret;
498 	int		 retry_flag;
499 	int		 ssl_err;
500 
501 	if (event == EV_TIMEOUT) {
502 		log_debug("ssl_session_accept: session timed out");
503 		session_destroy(s);
504 		return;
505 	}
506 
507 	retry_flag = ssl_err = 0;
508 
509 	log_debug("ssl_session_accept: accepting client");
510 	ret = SSL_accept(s->s_ssl);
511 	if (ret <= 0) {
512 		ssl_err = SSL_get_error(s->s_ssl, ret);
513 
514 		switch (ssl_err) {
515 		case SSL_ERROR_WANT_READ:
516 			retry_flag = EV_READ;
517 			goto retry;
518 		case SSL_ERROR_WANT_WRITE:
519 			retry_flag = EV_WRITE;
520 			goto retry;
521 		case SSL_ERROR_ZERO_RETURN:
522 		case SSL_ERROR_SYSCALL:
523 			if (ret == 0) {
524 				session_destroy(s);
525 				return;
526 			}
527 			/* FALLTHROUGH */
528 		default:
529 			ssl_error("ssl_session_accept");
530 			session_destroy(s);
531 			return;
532 		}
533 	}
534 
535 
536 	log_info("ssl_session_accept: accepted ssl client");
537 	s->s_flags |= F_SECURE;
538 
539 	if (s->s_l->flags & F_SMTPS)
540 		stat_increment(STATS_SMTP_SMTPS);
541 
542 	if (s->s_l->flags & F_STARTTLS)
543 		stat_increment(STATS_SMTP_STARTTLS);
544 
545 	session_bufferevent_new(s);
546 	event_set(&s->s_bev->ev_read, s->s_fd, EV_READ, ssl_read, s->s_bev);
547 	event_set(&s->s_bev->ev_write, s->s_fd, EV_WRITE, ssl_write, s->s_bev);
548 	session_pickup(s, NULL);
549 
550 	return;
551 retry:
552 	event_add(&s->s_ev, &s->s_tv);
553 }
554 
555 void
556 ssl_session_init(struct session *s)
557 {
558 	struct listener	*l;
559 	SSL             *ssl;
560 
561 	l = s->s_l;
562 
563 	if (!(l->flags & F_SSL))
564 		return;
565 
566 	log_debug("ssl_session_init: switching to SSL");
567 	ssl = SSL_new(l->ssl_ctx);
568 	if (ssl == NULL)
569 		goto err;
570 
571 	if (!SSL_set_ssl_method(ssl, SSLv23_server_method()))
572 		goto err;
573 	if (!SSL_set_fd(ssl, s->s_fd))
574 		goto err;
575 	SSL_set_accept_state(ssl);
576 
577 	s->s_ssl = ssl;
578 
579 	s->s_tv.tv_sec = SMTPD_SESSION_TIMEOUT;
580 	s->s_tv.tv_usec = 0;
581 	event_set(&s->s_ev, s->s_fd, EV_READ|EV_TIMEOUT, ssl_session_accept, s);
582 	event_add(&s->s_ev, &s->s_tv);
583 	return;
584 
585  err:
586 	if (ssl != NULL)
587 		SSL_free(ssl);
588 	ssl_error("ssl_session_init");
589 }
590 
591 SSL *
592 ssl_client_init(int fd, char *cert, size_t certsz, char *key, size_t keysz)
593 {
594 	SSL_CTX		*ctx;
595 	SSL		*ssl = NULL;
596 	int		 rv = -1;
597 
598 	ctx = ssl_ctx_create();
599 
600 	if (cert && key) {
601 		if (!ssl_ctx_use_certificate_chain(ctx, cert, certsz))
602 			goto done;
603 		else if (!ssl_ctx_use_private_key(ctx, key, keysz))
604 			goto done;
605 		else if (!SSL_CTX_check_private_key(ctx))
606 			goto done;
607 	}
608 
609 	if ((ssl = SSL_new(ctx)) == NULL)
610 		goto done;
611 
612 	if (!SSL_set_ssl_method(ssl, SSLv23_client_method()))
613 		goto done;
614 	if (!SSL_set_fd(ssl, fd))
615 		goto done;
616 	SSL_set_connect_state(ssl);
617 
618 	rv = 0;
619 done:
620 	if (rv) {
621 		if (ssl)
622 			SSL_free(ssl);
623 		else if (ctx)
624 			SSL_CTX_free(ctx);
625 		ssl = NULL;
626 	}
627 	return (ssl);
628 }
629 
630 void
631 ssl_session_destroy(struct session *s)
632 {
633 	SSL_free(s->s_ssl);
634 
635 	if (s->s_l == NULL) {
636 		/* called from mta */
637 		return;
638 	}
639 
640 	if (s->s_l->flags & F_SMTPS)
641 		if (s->s_flags & F_SECURE)
642 			stat_decrement(STATS_SMTP_SMTPS);
643 
644 	if (s->s_l->flags & F_STARTTLS)
645 		if (s->s_flags & F_SECURE)
646 			stat_decrement(STATS_SMTP_STARTTLS);
647 }
648 
649 int
650 ssl_buf_read(SSL *s, struct ibuf_read *r)
651 {
652 	u_char	*buf = r->buf + r->wpos;
653 	ssize_t	 bufsz = sizeof(r->buf) - r->wpos;
654 	int	 ret;
655 
656 	if (bufsz == 0) {
657 		errno = EMSGSIZE;
658 		return (SSL_ERROR_SYSCALL);
659 	}
660 
661 	if ((ret = SSL_read(s, buf, bufsz)) > 0)
662 		r->wpos += ret;
663 
664 	return SSL_get_error(s, ret);
665 }
666 
667 int
668 ssl_buf_write(SSL *s, struct msgbuf *msgbuf)
669 {
670 	struct ibuf	*buf;
671 	int		 ret;
672 
673 	buf = TAILQ_FIRST(&msgbuf->bufs);
674 	if (buf == NULL)
675 		return (SSL_ERROR_NONE);
676 
677 	ret = SSL_write(s, buf->buf + buf->rpos, buf->wpos - buf->rpos);
678 
679 	if (ret > 0)
680 		msgbuf_drain(msgbuf, ret);
681 
682 	return SSL_get_error(s, ret);
683 }
684 
685 /* From OpenSSL's documentation:
686  *
687  * If "strong" primes were used to generate the DH parameters, it is
688  * not strictly necessary to generate a new key for each handshake
689  * but it does improve forward secrecy.
690  *
691  * -- gilles@
692  */
693 DH *
694 get_dh1024(void)
695 {
696 	DH *dh;
697 	unsigned char dh1024_p[] = {
698 		0xAD,0x37,0xBB,0x26,0x75,0x01,0x27,0x75,
699 		0x06,0xB5,0xE7,0x1E,0x1F,0x2B,0xBC,0x51,
700 		0xC0,0xF4,0xEB,0x42,0x7A,0x2A,0x83,0x1E,
701 		0xE8,0xD1,0xD8,0xCC,0x9E,0xE6,0x15,0x1D,
702 		0x06,0x46,0x50,0x94,0xB9,0xEE,0xB6,0x89,
703 		0xB7,0x3C,0xAC,0x07,0x5E,0x29,0x37,0xCC,
704 		0x8F,0xDF,0x48,0x56,0x85,0x83,0x26,0x02,
705 		0xB8,0xB6,0x63,0xAF,0x2D,0x4A,0x57,0x93,
706 		0x6B,0x54,0xE1,0x8F,0x28,0x76,0x9C,0x5D,
707 		0x90,0x65,0xD1,0x07,0xFE,0x5B,0x05,0x65,
708 		0xDA,0xD2,0xE2,0xAF,0x23,0xCA,0x2F,0xD6,
709 		0x4B,0xD2,0x04,0xFE,0xDF,0x21,0x2A,0xE1,
710 		0xCD,0x1B,0x70,0x76,0xB3,0x51,0xA4,0xC9,
711 		0x2B,0x68,0xE3,0xDD,0xCB,0x97,0xDA,0x59,
712 		0x50,0x93,0xEE,0xDB,0xBF,0xC7,0xFA,0xA7,
713 		0x47,0xC4,0x4D,0xF0,0xC6,0x09,0x4A,0x4B
714 	};
715 	unsigned char dh1024_g[] = {
716 		0x02
717 	};
718 
719         if ((dh = DH_new()) == NULL)
720 		return NULL;
721 
722         dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
723         dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
724         if (dh->p == NULL || dh->g == NULL) {
725 		DH_free(dh);
726 		return NULL;
727 	}
728 
729         return dh;
730 }
731 
732 DH *
733 get_dh_from_memory(char *params, size_t len)
734 {
735 	BIO *mem;
736         DH *dh;
737 
738 	mem = BIO_new_mem_buf(params, len);
739 	if (mem == NULL)
740 		return NULL;
741 	dh = PEM_read_bio_DHparams(mem, NULL, NULL, NULL);
742 	if (dh == NULL)
743 		goto err;
744         if (dh->p == NULL || dh->g == NULL)
745 		goto err;
746 	return dh;
747 
748 err:
749 	if (mem != NULL)
750 		BIO_free(mem);
751 	if (dh != NULL)
752 		DH_free(dh);
753 	return NULL;
754 }
755 
756 
757 void
758 ssl_set_ephemeral_key_exchange(SSL_CTX *ctx, DH *dh)
759 {
760 	if (dh == NULL || !SSL_CTX_set_tmp_dh(ctx, dh)) {
761 		ssl_error("ssl_set_ephemeral_key_exchange");
762 		fatal("ssl_set_ephemeral_key_exchange: cannot set tmp dh");
763 	}
764 }
765