ustream-ssl: add support for using a fd instead of ustream as backing
[project/ustream-ssl.git] / ustream-openssl.c
1 /*
2 * ustream-ssl - library for SSL over ustream
3 *
4 * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <string.h>
20 #include <ctype.h>
21 #include "ustream-ssl.h"
22 #include "ustream-internal.h"
23
24 #if !defined(HAVE_WOLFSSL)
25 #include <openssl/x509v3.h>
26 #endif
27
28 #if defined(HAVE_WOLFSSL) && defined(DEBUG)
29 #include <wolfssl/test.h>
30 #endif
31
32 /* Ciphersuite preference:
33 * - for server, no weak ciphers are used if you use an ECDSA key.
34 * - forward-secret (pfs), authenticated (AEAD) ciphers are at the top:
35 * chacha20-poly1305, the fastest in software, 256-bits
36 * aes128-gcm, 128-bits
37 * aes256-gcm, 256-bits
38 * - key exchange: prefer ECDHE, then DHE (client only)
39 * - forward-secret ECDSA CBC ciphers (client-only)
40 * - forward-secret RSA CBC ciphers
41 * - non-pfs ciphers
42 * aes128, aes256, 3DES(client only)
43 */
44
45 #ifdef WOLFSSL_SSL_H
46 # define top_ciphers \
47 "TLS13-CHACHA20-POLY1305-SHA256:" \
48 "TLS13-AES128-GCM-SHA256:" \
49 "TLS13-AES256-GCM-SHA384:" \
50 ecdhe_aead_ciphers
51 #else
52 # define tls13_ciphersuites "TLS_CHACHA20_POLY1305_SHA256:" \
53 "TLS_AES_128_GCM_SHA256:" \
54 "TLS_AES_256_GCM_SHA384"
55
56 # define top_ciphers \
57 ecdhe_aead_ciphers
58 #endif
59
60 #define ecdhe_aead_ciphers \
61 "ECDHE-ECDSA-CHACHA20-POLY1305:" \
62 "ECDHE-ECDSA-AES128-GCM-SHA256:" \
63 "ECDHE-ECDSA-AES256-GCM-SHA384:" \
64 "ECDHE-RSA-CHACHA20-POLY1305:" \
65 "ECDHE-RSA-AES128-GCM-SHA256:" \
66 "ECDHE-RSA-AES256-GCM-SHA384"
67
68 #define dhe_aead_ciphers \
69 "DHE-RSA-CHACHA20-POLY1305:" \
70 "DHE-RSA-AES128-GCM-SHA256:" \
71 "DHE-RSA-AES256-GCM-SHA384"
72
73 #define ecdhe_ecdsa_cbc_ciphers \
74 "ECDHE-ECDSA-AES128-SHA:" \
75 "ECDHE-ECDSA-AES256-SHA"
76
77 #define ecdhe_rsa_cbc_ciphers \
78 "ECDHE-RSA-AES128-SHA:" \
79 "ECDHE-RSA-AES256-SHA"
80
81 #define dhe_cbc_ciphers \
82 "DHE-RSA-AES128-SHA:" \
83 "DHE-RSA-AES256-SHA:" \
84 "DHE-DES-CBC3-SHA"
85
86 #define non_pfs_aes \
87 "AES128-GCM-SHA256:" \
88 "AES256-GCM-SHA384:" \
89 "AES128-SHA:" \
90 "AES256-SHA"
91
92 #define server_cipher_list \
93 top_ciphers ":" \
94 ecdhe_rsa_cbc_ciphers ":" \
95 non_pfs_aes
96
97 #define client_cipher_list \
98 top_ciphers ":" \
99 dhe_aead_ciphers ":" \
100 ecdhe_ecdsa_cbc_ciphers ":" \
101 ecdhe_rsa_cbc_ciphers ":" \
102 dhe_cbc_ciphers ":" \
103 non_pfs_aes ":" \
104 "DES-CBC3-SHA"
105
106 __hidden struct ustream_ssl_ctx *
107 __ustream_ssl_context_new(bool server)
108 {
109 struct ustream_ssl_ctx *ctx;
110 const void *m;
111 SSL_CTX *c;
112
113 #if OPENSSL_VERSION_NUMBER < 0x10100000L
114 static bool _init = false;
115
116 if (!_init) {
117 SSL_load_error_strings();
118 SSL_library_init();
119 _init = true;
120 }
121 # ifndef TLS_server_method
122 # define TLS_server_method SSLv23_server_method
123 # endif
124 # ifndef TLS_client_method
125 # define TLS_client_method SSLv23_client_method
126 # endif
127 #endif
128
129 if (server) {
130 m = TLS_server_method();
131 } else
132 m = TLS_client_method();
133
134 c = SSL_CTX_new((void *) m);
135 if (!c)
136 return NULL;
137
138 ctx = calloc(1, sizeof(*ctx));
139 ctx->ssl = c;
140
141 #if defined(HAVE_WOLFSSL)
142 if (server)
143 SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL);
144 else
145 SSL_CTX_set_verify(c, SSL_VERIFY_PEER, NULL);
146 #else
147 SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL);
148 #endif
149
150 SSL_CTX_set_options(c, SSL_OP_NO_COMPRESSION | SSL_OP_SINGLE_ECDH_USE |
151 SSL_OP_CIPHER_SERVER_PREFERENCE);
152 #if defined(SSL_CTX_set_ecdh_auto) && OPENSSL_VERSION_NUMBER < 0x10100000L
153 SSL_CTX_set_ecdh_auto(c, 1);
154 #elif OPENSSL_VERSION_NUMBER >= 0x10101000L
155 SSL_CTX_set_ciphersuites(c, tls13_ciphersuites);
156 #endif
157 if (server) {
158 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
159 SSL_CTX_set_min_proto_version(c, TLS1_2_VERSION);
160 #else
161 SSL_CTX_set_options(c, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 |
162 SSL_OP_NO_TLSv1_1);
163 #endif
164 #if defined(HAVE_WOLFSSL)
165 SSL_CTX_set_options(c, SSL_AD_NO_RENEGOTIATION);
166 #else
167 SSL_CTX_set_options(c, SSL_OP_NO_RENEGOTIATION);
168 #endif
169
170 SSL_CTX_set_cipher_list(c, server_cipher_list);
171 } else {
172 SSL_CTX_set_cipher_list(c, client_cipher_list);
173 }
174 SSL_CTX_set_quiet_shutdown(c, 1);
175
176 return ctx;
177 }
178
179 __hidden int __ustream_ssl_add_ca_crt_file(struct ustream_ssl_ctx *ctx, const char *file)
180 {
181 int ret;
182
183 ret = SSL_CTX_load_verify_locations(ctx->ssl, file, NULL);
184 if (ret < 1)
185 return -1;
186
187 return 0;
188 }
189
190 __hidden int __ustream_ssl_set_crt_file(struct ustream_ssl_ctx *ctx, const char *file)
191 {
192 int ret;
193
194 ret = SSL_CTX_use_certificate_chain_file(ctx->ssl, file);
195 if (ret < 1)
196 ret = SSL_CTX_use_certificate_file(ctx->ssl, file, SSL_FILETYPE_ASN1);
197
198 if (ret < 1)
199 return -1;
200
201 return 0;
202 }
203
204 __hidden int __ustream_ssl_set_key_file(struct ustream_ssl_ctx *ctx, const char *file)
205 {
206 int ret;
207
208 ret = SSL_CTX_use_PrivateKey_file(ctx->ssl, file, SSL_FILETYPE_PEM);
209 if (ret < 1)
210 ret = SSL_CTX_use_PrivateKey_file(ctx->ssl, file, SSL_FILETYPE_ASN1);
211
212 if (ret < 1)
213 return -1;
214
215 return 0;
216 }
217
218 __hidden int __ustream_ssl_set_ciphers(struct ustream_ssl_ctx *ctx, const char *ciphers)
219 {
220 int ret = SSL_CTX_set_cipher_list(ctx->ssl, ciphers);
221
222 if (ret == 0)
223 return -1;
224
225 return 0;
226 }
227
228 __hidden int __ustream_ssl_set_require_validation(struct ustream_ssl_ctx *ctx, bool require)
229 {
230 int mode = SSL_VERIFY_PEER;
231
232 if (!require)
233 mode = SSL_VERIFY_NONE;
234
235 SSL_CTX_set_verify(ctx->ssl, mode, NULL);
236
237 return 0;
238 }
239
240 __hidden void __ustream_ssl_context_free(struct ustream_ssl_ctx *ctx)
241 {
242 SSL_CTX_free(ctx->ssl);
243 if (ctx->debug_bio)
244 BIO_free(ctx->debug_bio);
245 free(ctx);
246 }
247
248 __hidden void __ustream_ssl_session_free(struct ustream_ssl *us)
249 {
250 BIO *bio = SSL_get_wbio(us->ssl);
251 struct bio_ctx *ctx;
252
253 SSL_shutdown(us->ssl);
254 SSL_free(us->ssl);
255
256 if (!us->conn)
257 return;
258
259 ctx = BIO_get_data(bio);
260 if (ctx) {
261 BIO_meth_free(ctx->meth);
262 free(ctx);
263 }
264 }
265
266 static void ustream_ssl_error(struct ustream_ssl *us, int ret)
267 {
268 us->error = ret;
269 uloop_timeout_set(&us->error_timer, 0);
270 }
271
272 static bool ustream_ssl_verify_cn(struct ustream_ssl *us, X509 *cert)
273 {
274 int ret;
275
276 if (!us->peer_cn)
277 return false;
278
279 # ifndef WOLFSSL_OPENSSL_H_
280 ret = X509_check_host(cert, us->peer_cn, 0, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS, NULL);
281 # else
282 ret = wolfSSL_X509_check_host(cert, us->peer_cn, 0, 0, NULL);
283 # endif
284 return ret == 1;
285 }
286
287 static void ustream_ssl_verify_cert(struct ustream_ssl *us)
288 {
289 void *ssl = us->ssl;
290 X509 *cert;
291 int res;
292
293 #if defined(HAVE_WOLFSSL) && defined(DEBUG)
294 showPeer(ssl);
295 #endif
296
297 res = SSL_get_verify_result(ssl);
298 if (res != X509_V_OK) {
299 if (us->notify_verify_error)
300 us->notify_verify_error(us, res, X509_verify_cert_error_string(res));
301 return;
302 }
303
304 cert = SSL_get_peer_certificate(ssl);
305 if (!cert)
306 return;
307
308 us->valid_cert = true;
309 us->valid_cn = ustream_ssl_verify_cn(us, cert);
310
311 X509_free(cert);
312 }
313
314 #ifdef WOLFSSL_SSL_H
315 static bool handle_wolfssl_asn_error(struct ustream_ssl *us, int r)
316 {
317 switch (r) {
318 case ASN_PARSE_E:
319 case ASN_VERSION_E:
320 case ASN_GETINT_E:
321 case ASN_RSA_KEY_E:
322 case ASN_OBJECT_ID_E:
323 case ASN_TAG_NULL_E:
324 case ASN_EXPECT_0_E:
325 case ASN_BITSTR_E:
326 case ASN_UNKNOWN_OID_E:
327 case ASN_DATE_SZ_E:
328 case ASN_BEFORE_DATE_E:
329 case ASN_AFTER_DATE_E:
330 case ASN_SIG_OID_E:
331 case ASN_TIME_E:
332 case ASN_INPUT_E:
333 case ASN_SIG_CONFIRM_E:
334 case ASN_SIG_HASH_E:
335 case ASN_SIG_KEY_E:
336 case ASN_DH_KEY_E:
337 #if LIBWOLFSSL_VERSION_HEX < 0x05000000
338 case ASN_NTRU_KEY_E:
339 #endif
340 case ASN_CRIT_EXT_E:
341 case ASN_ALT_NAME_E:
342 case ASN_NO_PEM_HEADER:
343 case ASN_ECC_KEY_E:
344 case ASN_NO_SIGNER_E:
345 case ASN_CRL_CONFIRM_E:
346 case ASN_CRL_NO_SIGNER_E:
347 case ASN_OCSP_CONFIRM_E:
348 case ASN_NAME_INVALID_E:
349 case ASN_NO_SKID:
350 case ASN_NO_AKID:
351 case ASN_NO_KEYUSAGE:
352 case ASN_COUNTRY_SIZE_E:
353 case ASN_PATHLEN_SIZE_E:
354 case ASN_PATHLEN_INV_E:
355 case ASN_SELF_SIGNED_E:
356 if (us->notify_verify_error)
357 us->notify_verify_error(us, r, wc_GetErrorString(r));
358 return true;
359 }
360
361 return false;
362 }
363 #endif
364
365 __hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us)
366 {
367 void *ssl = us->ssl;
368 int r;
369
370 ERR_clear_error();
371
372 if (us->server)
373 r = SSL_accept(ssl);
374 else
375 r = SSL_connect(ssl);
376
377 if (r == 1) {
378 ustream_ssl_verify_cert(us);
379 return U_SSL_OK;
380 }
381
382 r = SSL_get_error(ssl, r);
383 if (r == SSL_ERROR_WANT_READ || r == SSL_ERROR_WANT_WRITE)
384 return U_SSL_PENDING;
385
386 #ifdef WOLFSSL_SSL_H
387 if (handle_wolfssl_asn_error(us, r))
388 return U_SSL_OK;
389 #endif
390
391 ustream_ssl_error(us, r);
392 return U_SSL_ERROR;
393 }
394
395 __hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len)
396 {
397 void *ssl = us->ssl;
398 int ret;
399
400 ERR_clear_error();
401
402 ret = SSL_write(ssl, buf, len);
403
404 if (ret < 0) {
405 int err = SSL_get_error(ssl, ret);
406 if (err == SSL_ERROR_WANT_WRITE)
407 return 0;
408
409 ustream_ssl_error(us, err);
410 return -1;
411 }
412
413 return ret;
414 }
415
416 __hidden int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len)
417 {
418 int ret;
419
420 ERR_clear_error();
421
422 ret = SSL_read(us->ssl, buf, len);
423
424 if (ret < 0) {
425 ret = SSL_get_error(us->ssl, ret);
426 if (ret == SSL_ERROR_WANT_READ)
427 return U_SSL_PENDING;
428
429 ustream_ssl_error(us, ret);
430 return U_SSL_ERROR;
431 }
432
433 return ret;
434 }
435
436 #ifndef WOLFSSL_SSL_H
437 static long
438 debug_cb(BIO *bio, int cmd, const char *argp, size_t len, int argi, long argl,
439 int ret, size_t *processed)
440 {
441 struct ustream_ssl_ctx *ctx = (void *)BIO_get_callback_arg(bio);
442 char buf[256];
443 char *str, *sep;
444 ssize_t cur_len;
445
446 if (cmd != (BIO_CB_WRITE|BIO_CB_RETURN))
447 goto out;
448
449 while (1) {
450 cur_len = BIO_get_mem_data(bio, (void *)&str);
451 if (!cur_len)
452 break;
453
454 sep = memchr(str, '\n', cur_len);
455 if (!sep)
456 break;
457
458 cur_len = sep + 1 - str;
459 if (cur_len >= (ssize_t)sizeof(buf))
460 cur_len = sizeof(buf) - 1;
461
462 cur_len = BIO_read(bio, buf, cur_len);
463 if (cur_len <= 1)
464 break;
465
466 cur_len--;
467 buf[cur_len] = 0;
468 if (ctx->debug_cb)
469 ctx->debug_cb(ctx->debug_cb_priv, 1, buf);
470 }
471
472 out:
473 return ret;
474 }
475 #endif
476
477 __hidden void __ustream_ssl_set_debug(struct ustream_ssl_ctx *ctx, int level,
478 ustream_ssl_debug_cb cb, void *cb_priv)
479 {
480 #ifndef WOLFSSL_SSL_H
481 if (!ctx->debug_bio)
482 ctx->debug_bio = BIO_new(BIO_s_mem());
483
484 ctx->debug_cb = cb;
485 ctx->debug_cb_priv = cb_priv;
486 SSL_CTX_set_msg_callback(ctx->ssl, SSL_trace);
487 SSL_CTX_set_msg_callback_arg(ctx->ssl, ctx->debug_bio);
488
489 BIO_set_callback_ex(ctx->debug_bio, debug_cb);
490 BIO_set_callback_arg(ctx->debug_bio, (void *)ctx);
491 #endif
492 }