• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ustream-ssl/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 }
493 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt