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 const void *m; 110 SSL_CTX *c; 111 112 #if OPENSSL_VERSION_NUMBER < 0x10100000L 113 static bool _init = false; 114 115 if (!_init) { 116 SSL_load_error_strings(); 117 SSL_library_init(); 118 _init = true; 119 } 120 # ifndef TLS_server_method 121 # define TLS_server_method SSLv23_server_method 122 # endif 123 # ifndef TLS_client_method 124 # define TLS_client_method SSLv23_client_method 125 # endif 126 #endif 127 128 if (server) { 129 m = TLS_server_method(); 130 } else 131 m = TLS_client_method(); 132 133 c = SSL_CTX_new((void *) m); 134 if (!c) 135 return NULL; 136 137 #if defined(HAVE_WOLFSSL) 138 if (server) 139 SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL); 140 else 141 SSL_CTX_set_verify(c, SSL_VERIFY_PEER, NULL); 142 #else 143 SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL); 144 #endif 145 146 SSL_CTX_set_options(c, SSL_OP_NO_COMPRESSION | SSL_OP_SINGLE_ECDH_USE | 147 SSL_OP_CIPHER_SERVER_PREFERENCE); 148 #if defined(SSL_CTX_set_ecdh_auto) && OPENSSL_VERSION_NUMBER < 0x10100000L 149 SSL_CTX_set_ecdh_auto(c, 1); 150 #elif OPENSSL_VERSION_NUMBER >= 0x10101000L 151 SSL_CTX_set_ciphersuites(c, tls13_ciphersuites); 152 #endif 153 if (server) { 154 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 155 SSL_CTX_set_min_proto_version(c, TLS1_2_VERSION); 156 #else 157 SSL_CTX_set_options(c, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | 158 SSL_OP_NO_TLSv1_1); 159 #endif 160 #if defined(HAVE_WOLFSSL) 161 SSL_CTX_set_options(c, SSL_AD_NO_RENEGOTIATION); 162 #else 163 SSL_CTX_set_options(c, SSL_OP_NO_RENEGOTIATION); 164 #endif 165 166 SSL_CTX_set_cipher_list(c, server_cipher_list); 167 } else { 168 SSL_CTX_set_cipher_list(c, client_cipher_list); 169 } 170 SSL_CTX_set_quiet_shutdown(c, 1); 171 172 return (void *) c; 173 } 174 175 __hidden int __ustream_ssl_add_ca_crt_file(struct ustream_ssl_ctx *ctx, const char *file) 176 { 177 int ret; 178 179 ret = SSL_CTX_load_verify_locations((void *) ctx, file, NULL); 180 if (ret < 1) 181 return -1; 182 183 return 0; 184 } 185 186 __hidden int __ustream_ssl_set_crt_file(struct ustream_ssl_ctx *ctx, const char *file) 187 { 188 int ret; 189 190 ret = SSL_CTX_use_certificate_chain_file((void *) ctx, file); 191 if (ret < 1) 192 ret = SSL_CTX_use_certificate_file((void *) ctx, file, SSL_FILETYPE_ASN1); 193 194 if (ret < 1) 195 return -1; 196 197 return 0; 198 } 199 200 __hidden int __ustream_ssl_set_key_file(struct ustream_ssl_ctx *ctx, const char *file) 201 { 202 int ret; 203 204 ret = SSL_CTX_use_PrivateKey_file((void *) ctx, file, SSL_FILETYPE_PEM); 205 if (ret < 1) 206 ret = SSL_CTX_use_PrivateKey_file((void *) ctx, file, SSL_FILETYPE_ASN1); 207 208 if (ret < 1) 209 return -1; 210 211 return 0; 212 } 213 214 __hidden int __ustream_ssl_set_ciphers(struct ustream_ssl_ctx *ctx, const char *ciphers) 215 { 216 int ret = SSL_CTX_set_cipher_list((void *) ctx, ciphers); 217 218 if (ret == 0) 219 return -1; 220 221 return 0; 222 } 223 224 __hidden int __ustream_ssl_set_require_validation(struct ustream_ssl_ctx *ctx, bool require) 225 { 226 int mode = SSL_VERIFY_PEER; 227 228 if (!require) 229 mode = SSL_VERIFY_NONE; 230 231 SSL_CTX_set_verify((void *) ctx, mode, NULL); 232 233 return 0; 234 } 235 236 __hidden void __ustream_ssl_context_free(struct ustream_ssl_ctx *ctx) 237 { 238 SSL_CTX_free((void *) ctx); 239 } 240 241 void __ustream_ssl_session_free(void *ssl) 242 { 243 BIO *bio = SSL_get_wbio(ssl); 244 struct bio_ctx *ctx = BIO_get_data(bio); 245 246 SSL_shutdown(ssl); 247 SSL_free(ssl); 248 if (ctx) { 249 BIO_meth_free(ctx->meth); 250 free(ctx); 251 } 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 cert = SSL_get_peer_certificate(ssl); 293 if (!cert) 294 return; 295 296 us->valid_cert = true; 297 us->valid_cn = ustream_ssl_verify_cn(us, cert); 298 299 X509_free(cert); 300 } 301 302 #ifdef WOLFSSL_SSL_H 303 static bool handle_wolfssl_asn_error(struct ustream_ssl *us, int r) 304 { 305 switch (r) { 306 case ASN_PARSE_E: 307 case ASN_VERSION_E: 308 case ASN_GETINT_E: 309 case ASN_RSA_KEY_E: 310 case ASN_OBJECT_ID_E: 311 case ASN_TAG_NULL_E: 312 case ASN_EXPECT_0_E: 313 case ASN_BITSTR_E: 314 case ASN_UNKNOWN_OID_E: 315 case ASN_DATE_SZ_E: 316 case ASN_BEFORE_DATE_E: 317 case ASN_AFTER_DATE_E: 318 case ASN_SIG_OID_E: 319 case ASN_TIME_E: 320 case ASN_INPUT_E: 321 case ASN_SIG_CONFIRM_E: 322 case ASN_SIG_HASH_E: 323 case ASN_SIG_KEY_E: 324 case ASN_DH_KEY_E: 325 #if LIBWOLFSSL_VERSION_HEX < 0x05000000 326 case ASN_NTRU_KEY_E: 327 #endif 328 case ASN_CRIT_EXT_E: 329 case ASN_ALT_NAME_E: 330 case ASN_NO_PEM_HEADER: 331 case ASN_ECC_KEY_E: 332 case ASN_NO_SIGNER_E: 333 case ASN_CRL_CONFIRM_E: 334 case ASN_CRL_NO_SIGNER_E: 335 case ASN_OCSP_CONFIRM_E: 336 case ASN_NAME_INVALID_E: 337 case ASN_NO_SKID: 338 case ASN_NO_AKID: 339 case ASN_NO_KEYUSAGE: 340 case ASN_COUNTRY_SIZE_E: 341 case ASN_PATHLEN_SIZE_E: 342 case ASN_PATHLEN_INV_E: 343 case ASN_SELF_SIGNED_E: 344 if (us->notify_verify_error) 345 us->notify_verify_error(us, r, wc_GetErrorString(r)); 346 return true; 347 } 348 349 return false; 350 } 351 #endif 352 353 __hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us) 354 { 355 void *ssl = us->ssl; 356 int r; 357 358 ERR_clear_error(); 359 360 if (us->server) 361 r = SSL_accept(ssl); 362 else 363 r = SSL_connect(ssl); 364 365 if (r == 1) { 366 ustream_ssl_verify_cert(us); 367 return U_SSL_OK; 368 } 369 370 r = SSL_get_error(ssl, r); 371 if (r == SSL_ERROR_WANT_READ || r == SSL_ERROR_WANT_WRITE) 372 return U_SSL_PENDING; 373 374 #ifdef WOLFSSL_SSL_H 375 if (handle_wolfssl_asn_error(us, r)) 376 return U_SSL_OK; 377 #endif 378 379 ustream_ssl_error(us, r); 380 return U_SSL_ERROR; 381 } 382 383 __hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len) 384 { 385 void *ssl = us->ssl; 386 int ret; 387 388 ERR_clear_error(); 389 390 ret = SSL_write(ssl, buf, len); 391 392 if (ret < 0) { 393 int err = SSL_get_error(ssl, ret); 394 if (err == SSL_ERROR_WANT_WRITE) 395 return 0; 396 397 ustream_ssl_error(us, err); 398 return -1; 399 } 400 401 return ret; 402 } 403 404 __hidden int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len) 405 { 406 int ret; 407 408 ERR_clear_error(); 409 410 ret = SSL_read(us->ssl, buf, len); 411 412 if (ret < 0) { 413 ret = SSL_get_error(us->ssl, ret); 414 if (ret == SSL_ERROR_WANT_READ) 415 return U_SSL_PENDING; 416 417 ustream_ssl_error(us, ret); 418 return U_SSL_ERROR; 419 } 420 421 return ret; 422 } 423
This page was automatically generated by LXR 0.3.1. • OpenWrt