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 <limits.h> 20 #include <string.h> 21 #include <ctype.h> 22 #include <arpa/inet.h> 23 #include "ustream-ssl.h" 24 #include "ustream-internal.h" 25 26 #if !defined(HAVE_WOLFSSL) 27 #include <openssl/x509v3.h> 28 #endif 29 30 #if defined(HAVE_WOLFSSL) && defined(DEBUG) 31 #include <wolfssl/test.h> 32 #endif 33 34 /* Ciphersuite preference: 35 * - for server, no weak ciphers are used if you use an ECDSA key. 36 * - forward-secret (pfs), authenticated (AEAD) ciphers are at the top: 37 * chacha20-poly1305, the fastest in software, 256-bits 38 * aes128-gcm, 128-bits 39 * aes256-gcm, 256-bits 40 * - key exchange: prefer ECDHE, then DHE (client only) 41 * - forward-secret ECDSA CBC ciphers (client-only) 42 * - forward-secret RSA CBC ciphers 43 * - non-pfs ciphers 44 * aes128, aes256, 3DES(client only) 45 */ 46 47 #ifdef WOLFSSL_SSL_H 48 # define top_ciphers \ 49 "TLS13-CHACHA20-POLY1305-SHA256:" \ 50 "TLS13-AES128-GCM-SHA256:" \ 51 "TLS13-AES256-GCM-SHA384:" \ 52 ecdhe_aead_ciphers 53 #else 54 # define tls13_ciphersuites "TLS_CHACHA20_POLY1305_SHA256:" \ 55 "TLS_AES_128_GCM_SHA256:" \ 56 "TLS_AES_256_GCM_SHA384" 57 58 # define top_ciphers \ 59 ecdhe_aead_ciphers 60 #endif 61 62 #define ecdhe_aead_ciphers \ 63 "ECDHE-ECDSA-CHACHA20-POLY1305:" \ 64 "ECDHE-ECDSA-AES128-GCM-SHA256:" \ 65 "ECDHE-ECDSA-AES256-GCM-SHA384:" \ 66 "ECDHE-RSA-CHACHA20-POLY1305:" \ 67 "ECDHE-RSA-AES128-GCM-SHA256:" \ 68 "ECDHE-RSA-AES256-GCM-SHA384" 69 70 #define dhe_aead_ciphers \ 71 "DHE-RSA-CHACHA20-POLY1305:" \ 72 "DHE-RSA-AES128-GCM-SHA256:" \ 73 "DHE-RSA-AES256-GCM-SHA384" 74 75 #define ecdhe_ecdsa_cbc_ciphers \ 76 "ECDHE-ECDSA-AES128-SHA:" \ 77 "ECDHE-ECDSA-AES256-SHA" 78 79 #define ecdhe_rsa_cbc_ciphers \ 80 "ECDHE-RSA-AES128-SHA:" \ 81 "ECDHE-RSA-AES256-SHA" 82 83 #define dhe_cbc_ciphers \ 84 "DHE-RSA-AES128-SHA:" \ 85 "DHE-RSA-AES256-SHA:" \ 86 "DHE-DES-CBC3-SHA" 87 88 #define non_pfs_aes \ 89 "AES128-GCM-SHA256:" \ 90 "AES256-GCM-SHA384:" \ 91 "AES128-SHA:" \ 92 "AES256-SHA" 93 94 #define server_cipher_list \ 95 top_ciphers ":" \ 96 ecdhe_rsa_cbc_ciphers ":" \ 97 non_pfs_aes 98 99 #define client_cipher_list \ 100 top_ciphers ":" \ 101 dhe_aead_ciphers ":" \ 102 ecdhe_ecdsa_cbc_ciphers ":" \ 103 ecdhe_rsa_cbc_ciphers ":" \ 104 dhe_cbc_ciphers ":" \ 105 non_pfs_aes ":" \ 106 "DES-CBC3-SHA" 107 108 __hidden struct ustream_ssl_ctx * 109 __ustream_ssl_context_new(bool server) 110 { 111 struct ustream_ssl_ctx *ctx; 112 const void *m; 113 SSL_CTX *c; 114 115 #if OPENSSL_VERSION_NUMBER < 0x10100000L 116 static bool _init = false; 117 118 if (!_init) { 119 SSL_load_error_strings(); 120 SSL_library_init(); 121 _init = true; 122 } 123 # ifndef TLS_server_method 124 # define TLS_server_method SSLv23_server_method 125 # endif 126 # ifndef TLS_client_method 127 # define TLS_client_method SSLv23_client_method 128 # endif 129 #endif 130 131 if (server) { 132 m = TLS_server_method(); 133 } else 134 m = TLS_client_method(); 135 136 c = SSL_CTX_new((void *) m); 137 if (!c) 138 return NULL; 139 140 ctx = calloc(1, sizeof(*ctx)); 141 if (!ctx) { 142 SSL_CTX_free(c); 143 return NULL; 144 } 145 ctx->ssl = c; 146 147 #if defined(HAVE_WOLFSSL) 148 if (server) 149 SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL); 150 else 151 SSL_CTX_set_verify(c, SSL_VERIFY_PEER, NULL); 152 #else 153 SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL); 154 #endif 155 156 SSL_CTX_set_options(c, SSL_OP_NO_COMPRESSION | SSL_OP_SINGLE_ECDH_USE | 157 SSL_OP_CIPHER_SERVER_PREFERENCE); 158 159 /* Blocked writes are buffered by the ustream core and retried from the 160 * buffers instead of the original caller address. Limit the write 161 * state pending inside the SSL library to a single record and allow 162 * the retry to come from a different address. 163 */ 164 #ifdef SSL_MODE_ENABLE_PARTIAL_WRITE 165 # ifdef SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 166 SSL_CTX_set_mode(c, SSL_MODE_ENABLE_PARTIAL_WRITE | 167 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); 168 # else 169 SSL_CTX_set_mode(c, SSL_MODE_ENABLE_PARTIAL_WRITE); 170 # endif 171 #endif 172 #if defined(SSL_CTX_set_ecdh_auto) && OPENSSL_VERSION_NUMBER < 0x10100000L 173 SSL_CTX_set_ecdh_auto(c, 1); 174 #elif OPENSSL_VERSION_NUMBER >= 0x10101000L 175 SSL_CTX_set_ciphersuites(c, tls13_ciphersuites); 176 #endif 177 if (server) { 178 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 179 SSL_CTX_set_min_proto_version(c, TLS1_2_VERSION); 180 #else 181 SSL_CTX_set_options(c, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | 182 SSL_OP_NO_TLSv1_1); 183 #endif 184 #if defined(HAVE_WOLFSSL) 185 SSL_CTX_set_options(c, SSL_AD_NO_RENEGOTIATION); 186 #else 187 SSL_CTX_set_options(c, SSL_OP_NO_RENEGOTIATION); 188 #endif 189 190 SSL_CTX_set_cipher_list(c, server_cipher_list); 191 } else { 192 SSL_CTX_set_cipher_list(c, client_cipher_list); 193 } 194 SSL_CTX_set_quiet_shutdown(c, 1); 195 196 return ctx; 197 } 198 199 __hidden int __ustream_ssl_add_ca_crt_file(struct ustream_ssl_ctx *ctx, const char *file) 200 { 201 int ret; 202 203 ret = SSL_CTX_load_verify_locations(ctx->ssl, file, NULL); 204 if (ret < 1) 205 return -1; 206 207 return 0; 208 } 209 210 __hidden int __ustream_ssl_set_crt_file(struct ustream_ssl_ctx *ctx, const char *file) 211 { 212 int ret; 213 214 ret = SSL_CTX_use_certificate_chain_file(ctx->ssl, file); 215 if (ret < 1) 216 ret = SSL_CTX_use_certificate_file(ctx->ssl, file, SSL_FILETYPE_ASN1); 217 218 if (ret < 1) 219 return -1; 220 221 return 0; 222 } 223 224 __hidden int __ustream_ssl_set_key_file(struct ustream_ssl_ctx *ctx, const char *file) 225 { 226 int ret; 227 228 ret = SSL_CTX_use_PrivateKey_file(ctx->ssl, file, SSL_FILETYPE_PEM); 229 if (ret < 1) 230 ret = SSL_CTX_use_PrivateKey_file(ctx->ssl, file, SSL_FILETYPE_ASN1); 231 232 if (ret < 1) 233 return -1; 234 235 return 0; 236 } 237 238 __hidden int __ustream_ssl_set_ciphers(struct ustream_ssl_ctx *ctx, const char *ciphers) 239 { 240 int ret = SSL_CTX_set_cipher_list(ctx->ssl, ciphers); 241 242 if (ret == 0) 243 return -1; 244 245 return 0; 246 } 247 248 __hidden int __ustream_ssl_set_require_validation(struct ustream_ssl_ctx *ctx, bool require) 249 { 250 int mode = SSL_VERIFY_PEER; 251 252 if (!require) 253 mode = SSL_VERIFY_NONE; 254 255 SSL_CTX_set_verify(ctx->ssl, mode, NULL); 256 257 return 0; 258 } 259 260 __hidden void __ustream_ssl_context_free(struct ustream_ssl_ctx *ctx) 261 { 262 SSL_CTX_free(ctx->ssl); 263 if (ctx->debug_bio) 264 BIO_free(ctx->debug_bio); 265 free(ctx); 266 } 267 268 __hidden void __ustream_ssl_session_free(struct ustream_ssl *us) 269 { 270 SSL_shutdown(us->ssl); 271 SSL_free(us->ssl); 272 } 273 274 static void ustream_ssl_error(struct ustream_ssl *us, int ret) 275 { 276 unsigned long err = ERR_peek_error(); 277 278 /* The error member is passed to ERR_error_string(), which can only 279 * decode packed error queue codes, not SSL_get_error() class codes. 280 * Keep the class code when the queue is empty or the code does not 281 * survive the round trip through the int member. 282 */ 283 if (err && err <= INT_MAX) 284 us->error = err; 285 else 286 us->error = ret; 287 288 uloop_timeout_set(&us->error_timer, 0); 289 } 290 291 #ifndef WOLFSSL_OPENSSL_H_ 292 static bool peer_cn_is_ip_addr(const char *peer_cn) 293 { 294 struct in6_addr addr; 295 296 return inet_pton(AF_INET, peer_cn, &addr) == 1 || 297 inet_pton(AF_INET6, peer_cn, &addr) == 1; 298 } 299 #endif 300 301 static bool ustream_ssl_verify_cn(struct ustream_ssl *us, X509 *cert) 302 { 303 int ret; 304 305 if (!us->peer_cn) 306 return false; 307 308 # ifndef WOLFSSL_OPENSSL_H_ 309 if (peer_cn_is_ip_addr(us->peer_cn)) 310 ret = X509_check_ip_asc(cert, us->peer_cn, 0); 311 else 312 ret = X509_check_host(cert, us->peer_cn, 0, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS, NULL); 313 # else 314 ret = wolfSSL_X509_check_host(cert, us->peer_cn, 0, 0, NULL); 315 # endif 316 return ret == 1; 317 } 318 319 static void ustream_ssl_verify_cert(struct ustream_ssl *us) 320 { 321 void *ssl = us->ssl; 322 X509 *cert; 323 int res; 324 325 #if defined(HAVE_WOLFSSL) && defined(DEBUG) 326 showPeer(ssl); 327 #endif 328 329 res = SSL_get_verify_result(ssl); 330 if (res != X509_V_OK) { 331 if (us->notify_verify_error) 332 us->notify_verify_error(us, res, X509_verify_cert_error_string(res)); 333 return; 334 } 335 336 #if defined(HAVE_WOLFSSL) 337 cert = SSL_get_peer_certificate(ssl); 338 #else 339 cert = SSL_get1_peer_certificate(ssl); 340 #endif 341 if (!cert) 342 return; 343 344 us->valid_cert = true; 345 us->valid_cn = ustream_ssl_verify_cn(us, cert); 346 347 X509_free(cert); 348 } 349 350 #ifdef WOLFSSL_SSL_H 351 static bool handle_wolfssl_asn_error(struct ustream_ssl *us, int r) 352 { 353 switch (r) { 354 case ASN_PARSE_E: 355 case ASN_VERSION_E: 356 case ASN_GETINT_E: 357 case ASN_RSA_KEY_E: 358 case ASN_OBJECT_ID_E: 359 case ASN_TAG_NULL_E: 360 case ASN_EXPECT_0_E: 361 case ASN_BITSTR_E: 362 case ASN_UNKNOWN_OID_E: 363 case ASN_DATE_SZ_E: 364 case ASN_BEFORE_DATE_E: 365 case ASN_AFTER_DATE_E: 366 case ASN_SIG_OID_E: 367 case ASN_TIME_E: 368 case ASN_INPUT_E: 369 case ASN_SIG_CONFIRM_E: 370 case ASN_SIG_HASH_E: 371 case ASN_SIG_KEY_E: 372 case ASN_DH_KEY_E: 373 #if LIBWOLFSSL_VERSION_HEX < 0x05000000 374 case ASN_NTRU_KEY_E: 375 #endif 376 case ASN_CRIT_EXT_E: 377 case ASN_ALT_NAME_E: 378 case ASN_NO_PEM_HEADER: 379 case ASN_ECC_KEY_E: 380 case ASN_NO_SIGNER_E: 381 case ASN_CRL_CONFIRM_E: 382 case ASN_CRL_NO_SIGNER_E: 383 case ASN_OCSP_CONFIRM_E: 384 case ASN_NAME_INVALID_E: 385 case ASN_NO_SKID: 386 case ASN_NO_AKID: 387 case ASN_NO_KEYUSAGE: 388 case ASN_COUNTRY_SIZE_E: 389 case ASN_PATHLEN_SIZE_E: 390 case ASN_PATHLEN_INV_E: 391 case ASN_SELF_SIGNED_E: 392 if (us->notify_verify_error) 393 us->notify_verify_error(us, r, wc_GetErrorString(r)); 394 return true; 395 } 396 397 return false; 398 } 399 #endif 400 401 __hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us) 402 { 403 void *ssl = us->ssl; 404 int r; 405 406 ERR_clear_error(); 407 408 if (us->server) 409 r = SSL_accept(ssl); 410 else 411 r = SSL_connect(ssl); 412 413 if (r == 1) { 414 ustream_ssl_verify_cert(us); 415 return U_SSL_OK; 416 } 417 418 r = SSL_get_error(ssl, r); 419 if (r == SSL_ERROR_WANT_READ || r == SSL_ERROR_WANT_WRITE) 420 return U_SSL_PENDING; 421 422 #ifdef WOLFSSL_SSL_H 423 if (handle_wolfssl_asn_error(us, r)) 424 return U_SSL_OK; 425 #endif 426 427 ustream_ssl_error(us, r); 428 return U_SSL_ERROR; 429 } 430 431 __hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len) 432 { 433 void *ssl = us->ssl; 434 int ret; 435 436 ERR_clear_error(); 437 438 ret = SSL_write(ssl, buf, len); 439 440 if (ret < 0) { 441 int err = SSL_get_error(ssl, ret); 442 if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) 443 return 0; 444 445 ustream_ssl_error(us, err); 446 return -1; 447 } 448 449 return ret; 450 } 451 452 __hidden int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len) 453 { 454 int ret; 455 456 ERR_clear_error(); 457 458 ret = SSL_read(us->ssl, buf, len); 459 460 if (ret < 0) { 461 ret = SSL_get_error(us->ssl, ret); 462 if (ret == SSL_ERROR_WANT_READ || ret == SSL_ERROR_WANT_WRITE) 463 return U_SSL_PENDING; 464 465 ustream_ssl_error(us, ret); 466 return U_SSL_ERROR; 467 } 468 469 return ret; 470 } 471 472 #ifndef WOLFSSL_SSL_H 473 static long 474 debug_cb(BIO *bio, int cmd, const char *argp, size_t len, int argi, long argl, 475 int ret, size_t *processed) 476 { 477 struct ustream_ssl_ctx *ctx = (void *)BIO_get_callback_arg(bio); 478 char buf[256]; 479 char *str, *sep; 480 ssize_t cur_len; 481 482 if (cmd != (BIO_CB_WRITE|BIO_CB_RETURN)) 483 goto out; 484 485 while (1) { 486 cur_len = BIO_get_mem_data(bio, (void *)&str); 487 if (!cur_len) 488 break; 489 490 sep = memchr(str, '\n', cur_len); 491 if (!sep) 492 break; 493 494 cur_len = sep + 1 - str; 495 if (cur_len >= (ssize_t)sizeof(buf)) 496 cur_len = sizeof(buf) - 1; 497 498 cur_len = BIO_read(bio, buf, cur_len); 499 if (cur_len <= 1) 500 break; 501 502 cur_len--; 503 buf[cur_len] = 0; 504 if (ctx->debug_cb) 505 ctx->debug_cb(ctx->debug_cb_priv, 1, buf); 506 } 507 508 out: 509 return ret; 510 } 511 #endif 512 513 __hidden void __ustream_ssl_set_debug(struct ustream_ssl_ctx *ctx, int level, 514 ustream_ssl_debug_cb cb, void *cb_priv) 515 { 516 #ifndef WOLFSSL_SSL_H 517 if (!ctx->debug_bio) 518 ctx->debug_bio = BIO_new(BIO_s_mem()); 519 if (!ctx->debug_bio) 520 return; 521 522 ctx->debug_cb = cb; 523 ctx->debug_cb_priv = cb_priv; 524 SSL_CTX_set_msg_callback(ctx->ssl, SSL_trace); 525 SSL_CTX_set_msg_callback_arg(ctx->ssl, ctx->debug_bio); 526 527 BIO_set_callback_ex(ctx->debug_bio, debug_cb); 528 BIO_set_callback_arg(ctx->debug_bio, (void *)ctx); 529 #endif 530 } 531
This page was automatically generated by LXR 0.3.1. • OpenWrt