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