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 SSL_shutdown(us->ssl); 251 SSL_free(us->ssl); 252 } 253 254 static void ustream_ssl_error(struct ustream_ssl *us, int ret) 255 { 256 us->error = ret; 257 uloop_timeout_set(&us->error_timer, 0); 258 } 259 260 static bool ustream_ssl_verify_cn(struct ustream_ssl *us, X509 *cert) 261 { 262 int ret; 263 264 if (!us->peer_cn) 265 return false; 266 267 # ifndef WOLFSSL_OPENSSL_H_ 268 ret = X509_check_host(cert, us->peer_cn, 0, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS, NULL); 269 # else 270 ret = wolfSSL_X509_check_host(cert, us->peer_cn, 0, 0, NULL); 271 # endif 272 return ret == 1; 273 } 274 275 static void ustream_ssl_verify_cert(struct ustream_ssl *us) 276 { 277 void *ssl = us->ssl; 278 X509 *cert; 279 int res; 280 281 #if defined(HAVE_WOLFSSL) && defined(DEBUG) 282 showPeer(ssl); 283 #endif 284 285 res = SSL_get_verify_result(ssl); 286 if (res != X509_V_OK) { 287 if (us->notify_verify_error) 288 us->notify_verify_error(us, res, X509_verify_cert_error_string(res)); 289 return; 290 } 291 292 #if defined(HAVE_WOLFSSL) 293 cert = SSL_get_peer_certificate(ssl); 294 #else 295 cert = SSL_get1_peer_certificate(ssl); 296 #endif 297 if (!cert) 298 return; 299 300 us->valid_cert = true; 301 us->valid_cn = ustream_ssl_verify_cn(us, cert); 302 303 X509_free(cert); 304 } 305 306 #ifdef WOLFSSL_SSL_H 307 static bool handle_wolfssl_asn_error(struct ustream_ssl *us, int r) 308 { 309 switch (r) { 310 case ASN_PARSE_E: 311 case ASN_VERSION_E: 312 case ASN_GETINT_E: 313 case ASN_RSA_KEY_E: 314 case ASN_OBJECT_ID_E: 315 case ASN_TAG_NULL_E: 316 case ASN_EXPECT_0_E: 317 case ASN_BITSTR_E: 318 case ASN_UNKNOWN_OID_E: 319 case ASN_DATE_SZ_E: 320 case ASN_BEFORE_DATE_E: 321 case ASN_AFTER_DATE_E: 322 case ASN_SIG_OID_E: 323 case ASN_TIME_E: 324 case ASN_INPUT_E: 325 case ASN_SIG_CONFIRM_E: 326 case ASN_SIG_HASH_E: 327 case ASN_SIG_KEY_E: 328 case ASN_DH_KEY_E: 329 #if LIBWOLFSSL_VERSION_HEX < 0x05000000 330 case ASN_NTRU_KEY_E: 331 #endif 332 case ASN_CRIT_EXT_E: 333 case ASN_ALT_NAME_E: 334 case ASN_NO_PEM_HEADER: 335 case ASN_ECC_KEY_E: 336 case ASN_NO_SIGNER_E: 337 case ASN_CRL_CONFIRM_E: 338 case ASN_CRL_NO_SIGNER_E: 339 case ASN_OCSP_CONFIRM_E: 340 case ASN_NAME_INVALID_E: 341 case ASN_NO_SKID: 342 case ASN_NO_AKID: 343 case ASN_NO_KEYUSAGE: 344 case ASN_COUNTRY_SIZE_E: 345 case ASN_PATHLEN_SIZE_E: 346 case ASN_PATHLEN_INV_E: 347 case ASN_SELF_SIGNED_E: 348 if (us->notify_verify_error) 349 us->notify_verify_error(us, r, wc_GetErrorString(r)); 350 return true; 351 } 352 353 return false; 354 } 355 #endif 356 357 __hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us) 358 { 359 void *ssl = us->ssl; 360 int r; 361 362 ERR_clear_error(); 363 364 if (us->server) 365 r = SSL_accept(ssl); 366 else 367 r = SSL_connect(ssl); 368 369 if (r == 1) { 370 ustream_ssl_verify_cert(us); 371 return U_SSL_OK; 372 } 373 374 r = SSL_get_error(ssl, r); 375 if (r == SSL_ERROR_WANT_READ || r == SSL_ERROR_WANT_WRITE) 376 return U_SSL_PENDING; 377 378 #ifdef WOLFSSL_SSL_H 379 if (handle_wolfssl_asn_error(us, r)) 380 return U_SSL_OK; 381 #endif 382 383 ustream_ssl_error(us, r); 384 return U_SSL_ERROR; 385 } 386 387 __hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len) 388 { 389 void *ssl = us->ssl; 390 int ret; 391 392 ERR_clear_error(); 393 394 ret = SSL_write(ssl, buf, len); 395 396 if (ret < 0) { 397 int err = SSL_get_error(ssl, ret); 398 if (err == SSL_ERROR_WANT_WRITE) 399 return 0; 400 401 ustream_ssl_error(us, err); 402 return -1; 403 } 404 405 return ret; 406 } 407 408 __hidden int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len) 409 { 410 int ret; 411 412 ERR_clear_error(); 413 414 ret = SSL_read(us->ssl, buf, len); 415 416 if (ret < 0) { 417 ret = SSL_get_error(us->ssl, ret); 418 if (ret == SSL_ERROR_WANT_READ) 419 return U_SSL_PENDING; 420 421 ustream_ssl_error(us, ret); 422 return U_SSL_ERROR; 423 } 424 425 return ret; 426 } 427 428 #ifndef WOLFSSL_SSL_H 429 static long 430 debug_cb(BIO *bio, int cmd, const char *argp, size_t len, int argi, long argl, 431 int ret, size_t *processed) 432 { 433 struct ustream_ssl_ctx *ctx = (void *)BIO_get_callback_arg(bio); 434 char buf[256]; 435 char *str, *sep; 436 ssize_t cur_len; 437 438 if (cmd != (BIO_CB_WRITE|BIO_CB_RETURN)) 439 goto out; 440 441 while (1) { 442 cur_len = BIO_get_mem_data(bio, (void *)&str); 443 if (!cur_len) 444 break; 445 446 sep = memchr(str, '\n', cur_len); 447 if (!sep) 448 break; 449 450 cur_len = sep + 1 - str; 451 if (cur_len >= (ssize_t)sizeof(buf)) 452 cur_len = sizeof(buf) - 1; 453 454 cur_len = BIO_read(bio, buf, cur_len); 455 if (cur_len <= 1) 456 break; 457 458 cur_len--; 459 buf[cur_len] = 0; 460 if (ctx->debug_cb) 461 ctx->debug_cb(ctx->debug_cb_priv, 1, buf); 462 } 463 464 out: 465 return ret; 466 } 467 #endif 468 469 __hidden void __ustream_ssl_set_debug(struct ustream_ssl_ctx *ctx, int level, 470 ustream_ssl_debug_cb cb, void *cb_priv) 471 { 472 #ifndef WOLFSSL_SSL_H 473 if (!ctx->debug_bio) 474 ctx->debug_bio = BIO_new(BIO_s_mem()); 475 476 ctx->debug_cb = cb; 477 ctx->debug_cb_priv = cb_priv; 478 SSL_CTX_set_msg_callback(ctx->ssl, SSL_trace); 479 SSL_CTX_set_msg_callback_arg(ctx->ssl, ctx->debug_bio); 480 481 BIO_set_callback_ex(ctx->debug_bio, debug_cb); 482 BIO_set_callback_arg(ctx->debug_bio, (void *)ctx); 483 #endif 484 } 485
This page was automatically generated by LXR 0.3.1. • OpenWrt