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 SSL_CTX_set_cipher_list(c, server_cipher_list); 161 } else { 162 SSL_CTX_set_cipher_list(c, client_cipher_list); 163 } 164 SSL_CTX_set_quiet_shutdown(c, 1); 165 166 return (void *) c; 167 } 168 169 __hidden int __ustream_ssl_add_ca_crt_file(struct ustream_ssl_ctx *ctx, const char *file) 170 { 171 int ret; 172 173 ret = SSL_CTX_load_verify_locations((void *) ctx, file, NULL); 174 if (ret < 1) 175 return -1; 176 177 return 0; 178 } 179 180 __hidden int __ustream_ssl_set_crt_file(struct ustream_ssl_ctx *ctx, const char *file) 181 { 182 int ret; 183 184 ret = SSL_CTX_use_certificate_chain_file((void *) ctx, file); 185 if (ret < 1) 186 ret = SSL_CTX_use_certificate_file((void *) ctx, file, SSL_FILETYPE_ASN1); 187 188 if (ret < 1) 189 return -1; 190 191 return 0; 192 } 193 194 __hidden int __ustream_ssl_set_key_file(struct ustream_ssl_ctx *ctx, const char *file) 195 { 196 int ret; 197 198 ret = SSL_CTX_use_PrivateKey_file((void *) ctx, file, SSL_FILETYPE_PEM); 199 if (ret < 1) 200 ret = SSL_CTX_use_PrivateKey_file((void *) ctx, file, SSL_FILETYPE_ASN1); 201 202 if (ret < 1) 203 return -1; 204 205 return 0; 206 } 207 208 __hidden int __ustream_ssl_set_ciphers(struct ustream_ssl_ctx *ctx, const char *ciphers) 209 { 210 int ret = SSL_CTX_set_cipher_list((void *) ctx, ciphers); 211 212 if (ret == 0) 213 return -1; 214 215 return 0; 216 } 217 218 __hidden int __ustream_ssl_set_require_validation(struct ustream_ssl_ctx *ctx, bool require) 219 { 220 int mode = SSL_VERIFY_PEER; 221 222 if (!require) 223 mode = SSL_VERIFY_NONE; 224 225 SSL_CTX_set_verify((void *) ctx, mode, NULL); 226 227 return 0; 228 } 229 230 __hidden void __ustream_ssl_context_free(struct ustream_ssl_ctx *ctx) 231 { 232 SSL_CTX_free((void *) ctx); 233 } 234 235 void __ustream_ssl_session_free(void *ssl) 236 { 237 BIO *bio = SSL_get_wbio(ssl); 238 struct bio_ctx *ctx = BIO_get_data(bio); 239 240 SSL_shutdown(ssl); 241 SSL_free(ssl); 242 if (ctx) { 243 BIO_meth_free(ctx->meth); 244 free(ctx); 245 } 246 } 247 248 static void ustream_ssl_error(struct ustream_ssl *us, int ret) 249 { 250 us->error = ret; 251 uloop_timeout_set(&us->error_timer, 0); 252 } 253 254 static bool ustream_ssl_verify_cn(struct ustream_ssl *us, X509 *cert) 255 { 256 int ret; 257 258 if (!us->peer_cn) 259 return false; 260 261 # ifndef WOLFSSL_OPENSSL_H_ 262 ret = X509_check_host(cert, us->peer_cn, 0, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS, NULL); 263 # else 264 ret = wolfSSL_X509_check_host(cert, us->peer_cn, 0, 0, NULL); 265 # endif 266 return ret == 1; 267 } 268 269 static void ustream_ssl_verify_cert(struct ustream_ssl *us) 270 { 271 void *ssl = us->ssl; 272 X509 *cert; 273 int res; 274 275 #if defined(HAVE_WOLFSSL) && defined(DEBUG) 276 showPeer(ssl); 277 #endif 278 279 res = SSL_get_verify_result(ssl); 280 if (res != X509_V_OK) { 281 if (us->notify_verify_error) 282 us->notify_verify_error(us, res, X509_verify_cert_error_string(res)); 283 return; 284 } 285 286 cert = SSL_get_peer_certificate(ssl); 287 if (!cert) 288 return; 289 290 us->valid_cert = true; 291 us->valid_cn = ustream_ssl_verify_cn(us, cert); 292 293 X509_free(cert); 294 } 295 296 #ifdef WOLFSSL_SSL_H 297 static bool handle_wolfssl_asn_error(struct ustream_ssl *us, int r) 298 { 299 switch (r) { 300 case ASN_PARSE_E: 301 case ASN_VERSION_E: 302 case ASN_GETINT_E: 303 case ASN_RSA_KEY_E: 304 case ASN_OBJECT_ID_E: 305 case ASN_TAG_NULL_E: 306 case ASN_EXPECT_0_E: 307 case ASN_BITSTR_E: 308 case ASN_UNKNOWN_OID_E: 309 case ASN_DATE_SZ_E: 310 case ASN_BEFORE_DATE_E: 311 case ASN_AFTER_DATE_E: 312 case ASN_SIG_OID_E: 313 case ASN_TIME_E: 314 case ASN_INPUT_E: 315 case ASN_SIG_CONFIRM_E: 316 case ASN_SIG_HASH_E: 317 case ASN_SIG_KEY_E: 318 case ASN_DH_KEY_E: 319 #if LIBWOLFSSL_VERSION_HEX < 0x05000000 320 case ASN_NTRU_KEY_E: 321 #endif 322 case ASN_CRIT_EXT_E: 323 case ASN_ALT_NAME_E: 324 case ASN_NO_PEM_HEADER: 325 case ASN_ECC_KEY_E: 326 case ASN_NO_SIGNER_E: 327 case ASN_CRL_CONFIRM_E: 328 case ASN_CRL_NO_SIGNER_E: 329 case ASN_OCSP_CONFIRM_E: 330 case ASN_NAME_INVALID_E: 331 case ASN_NO_SKID: 332 case ASN_NO_AKID: 333 case ASN_NO_KEYUSAGE: 334 case ASN_COUNTRY_SIZE_E: 335 case ASN_PATHLEN_SIZE_E: 336 case ASN_PATHLEN_INV_E: 337 case ASN_SELF_SIGNED_E: 338 if (us->notify_verify_error) 339 us->notify_verify_error(us, r, wc_GetErrorString(r)); 340 return true; 341 } 342 343 return false; 344 } 345 #endif 346 347 __hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us) 348 { 349 void *ssl = us->ssl; 350 int r; 351 352 ERR_clear_error(); 353 354 if (us->server) 355 r = SSL_accept(ssl); 356 else 357 r = SSL_connect(ssl); 358 359 if (r == 1) { 360 ustream_ssl_verify_cert(us); 361 return U_SSL_OK; 362 } 363 364 r = SSL_get_error(ssl, r); 365 if (r == SSL_ERROR_WANT_READ || r == SSL_ERROR_WANT_WRITE) 366 return U_SSL_PENDING; 367 368 #ifdef WOLFSSL_SSL_H 369 if (handle_wolfssl_asn_error(us, r)) 370 return U_SSL_OK; 371 #endif 372 373 ustream_ssl_error(us, r); 374 return U_SSL_ERROR; 375 } 376 377 __hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len) 378 { 379 void *ssl = us->ssl; 380 int ret; 381 382 ERR_clear_error(); 383 384 ret = SSL_write(ssl, buf, len); 385 386 if (ret < 0) { 387 int err = SSL_get_error(ssl, ret); 388 if (err == SSL_ERROR_WANT_WRITE) 389 return 0; 390 391 ustream_ssl_error(us, err); 392 return -1; 393 } 394 395 return ret; 396 } 397 398 __hidden int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len) 399 { 400 int ret; 401 402 ERR_clear_error(); 403 404 ret = SSL_read(us->ssl, buf, len); 405 406 if (ret < 0) { 407 ret = SSL_get_error(us->ssl, ret); 408 if (ret == SSL_ERROR_WANT_READ) 409 return U_SSL_PENDING; 410 411 ustream_ssl_error(us, ret); 412 return U_SSL_ERROR; 413 } 414 415 return ret; 416 } 417
This page was automatically generated by LXR 0.3.1. • OpenWrt