1 /*	$OpenBSD: ssl.c,v 1.50 2012/11/12 14:58:53 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 <err.h>
29 #include <event.h>
30 #include <fcntl.h>
31 #include <imsg.h>
32 #include <pwd.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37 
38 #include <openssl/ssl.h>
39 #include <openssl/engine.h>
40 #include <openssl/err.h>
41 
42 #define SSL_CIPHERS	"HIGH"
43 
44 void	ssl_error(const char *);
45 
46 static void	ssl_init(void);
47 static SSL_CTX *ssl_ctx_create(void);
48 static void    *ssl_client_ctx(void);
49 
50 static void
ssl_init(void)51 ssl_init(void)
52 {
53 	static int	init = 0;
54 
55 	if (init)
56 		return;
57 
58 	init = 1;
59 
60 	SSL_library_init();
61 	SSL_load_error_strings();
62 
63 	OpenSSL_add_all_algorithms();
64 
65 	/* Init hardware crypto engines. */
66 	ENGINE_load_builtin_engines();
67 	ENGINE_register_all_complete();
68 }
69 
70 void
ssl_error(const char * where)71 ssl_error(const char *where)
72 {
73 	unsigned long	code;
74 	char		errbuf[128];
75 
76 	for (; (code = ERR_get_error()) != 0 ;) {
77 		ERR_error_string_n(code, errbuf, sizeof(errbuf));
78 		fprintf(stderr, "debug: SSL library error: %s: %s",
79 		    where, errbuf);
80 	}
81 }
82 
83 void *
ssl_connect(int sock)84 ssl_connect(int sock)
85 {
86 	SSL	*ssl;
87 
88 	ssl = ssl_client_ctx();
89 
90 	if (SSL_set_fd(ssl, sock) == 0) {
91 		ssl_error("ssl_connect:SSL_set_fd");
92 		SSL_free(ssl);
93 		return (NULL);
94 	}
95 
96 	if (SSL_connect(ssl) != 1) {
97 		ssl_error("ssl_connect:SSL_connect");
98 		SSL_free(ssl);
99 		return (NULL);
100 	}
101 
102 	return ((void*)ssl);
103 }
104 
105 void
ssl_close(void * a)106 ssl_close(void *a)
107 {
108 	SSL	*ssl = a;
109 
110 	SSL_free(ssl);
111 }
112 
113 static SSL_CTX *
ssl_ctx_create(void)114 ssl_ctx_create(void)
115 {
116 	SSL_CTX	*ctx;
117 
118 	ssl_init();
119 
120 	ctx = SSL_CTX_new(SSLv23_method());
121 	if (ctx == NULL) {
122 		ssl_error("ssl_ctx_create");
123 		errx(1, "ssl_ctx_create: could not create SSL context");
124 	}
125 
126 	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
127 	SSL_CTX_set_timeout(ctx, 30);
128 	SSL_CTX_set_options(ctx,
129 	    SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_TICKET);
130 	SSL_CTX_set_options(ctx,
131 	    SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
132 
133 	if (!SSL_CTX_set_cipher_list(ctx, SSL_CIPHERS)) {
134 		ssl_error("ssl_ctx_create");
135 		errx(1, "ssl_ctx_create: could not set cipher list");
136 	}
137 
138 	return (ctx);
139 }
140 
141 static void *
ssl_client_ctx(void)142 ssl_client_ctx(void)
143 {
144 	SSL_CTX		*ctx;
145 	SSL		*ssl = NULL;
146 	int		 rv = -1;
147 
148 	ctx = ssl_ctx_create();
149 
150 	if ((ssl = SSL_new(ctx)) == NULL)
151 		goto done;
152 	SSL_CTX_free(ctx);
153 
154 	if (!SSL_set_ssl_method(ssl, SSLv23_client_method()))
155 		goto done;
156 
157 	rv = 0;
158 done:
159 	if (rv) {
160 		if (ssl)
161 			SSL_free(ssl);
162 		else if (ctx)
163 			SSL_CTX_free(ctx);
164 		ssl = NULL;
165 	}
166 	return (void*)(ssl);
167 }
168