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