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 /* Ciphersuite preference: 29 * - for server, no weak ciphers are used if you use an ECDSA key. 30 * - forward-secret (pfs), authenticated (AEAD) ciphers are at the top: 31 * chacha20-poly1305, the fastest in software, 256-bits 32 * aes128-gcm, 128-bits 33 * aes256-gcm, 256-bits 34 * - key exchange: prefer ECDHE, then DHE (client only) 35 * - forward-secret ECDSA CBC ciphers (client-only) 36 * - forward-secret RSA CBC ciphers 37 * - non-pfs ciphers 38 * aes128, aes256, 3DES(client only) 39 */ 40 41 #ifdef WOLFSSL_SSL_H 42 # define top_ciphers \ 43 "TLS13-CHACHA20-POLY1305-SHA256:" \ 44 "TLS13-AES128-GCM-SHA256:" \ 45 "TLS13-AES256-GCM-SHA384:" \ 46 ecdhe_aead_ciphers 47 #else 48 # define tls13_ciphersuites "TLS_CHACHA20_POLY1305_SHA256:" \ 49 "TLS_AES_128_GCM_SHA256:" \ 50 "TLS_AES_256_GCM_SHA384" 51 52 # define top_ciphers \ 53 ecdhe_aead_ciphers 54 #endif 55 56 #define ecdhe_aead_ciphers \ 57 "ECDHE-ECDSA-CHACHA20-POLY1305:" \ 58 "ECDHE-ECDSA-AES128-GCM-SHA256:" \ 59 "ECDHE-ECDSA-AES256-GCM-SHA384:" \ 60 "ECDHE-RSA-CHACHA20-POLY1305:" \ 61 "ECDHE-RSA-AES128-GCM-SHA256:" \ 62 "ECDHE-RSA-AES256-GCM-SHA384" 63 64 #define dhe_aead_ciphers \ 65 "DHE-RSA-CHACHA20-POLY1305:" \ 66 "DHE-RSA-AES128-GCM-SHA256:" \ 67 "DHE-RSA-AES256-GCM-SHA384" 68 69 #define ecdhe_ecdsa_cbc_ciphers \ 70 "ECDHE-ECDSA-AES128-SHA:" \ 71 "ECDHE-ECDSA-AES256-SHA" 72 73 #define ecdhe_rsa_cbc_ciphers \ 74 "ECDHE-RSA-AES128-SHA:" \ 75 "ECDHE-RSA-AES256-SHA" 76 77 #define dhe_cbc_ciphers \ 78 "DHE-RSA-AES128-SHA:" \ 79 "DHE-RSA-AES256-SHA:" \ 80 "DHE-DES-CBC3-SHA" 81 82 #define non_pfs_aes \ 83 "AES128-GCM-SHA256:" \ 84 "AES256-GCM-SHA384:" \ 85 "AES128-SHA:" \ 86 "AES256-SHA" 87 88 #define server_cipher_list \ 89 top_ciphers ":" \ 90 ecdhe_rsa_cbc_ciphers ":" \ 91 non_pfs_aes 92 93 #define client_cipher_list \ 94 top_ciphers ":" \ 95 dhe_aead_ciphers ":" \ 96 ecdhe_ecdsa_cbc_ciphers ":" \ 97 ecdhe_rsa_cbc_ciphers ":" \ 98 dhe_cbc_ciphers ":" \ 99 non_pfs_aes ":" \ 100 "DES-CBC3-SHA" 101 102 __hidden struct ustream_ssl_ctx * 103 __ustream_ssl_context_new(bool server) 104 { 105 const void *m; 106 SSL_CTX *c; 107 108 #if OPENSSL_VERSION_NUMBER < 0x10100000L 109 static bool _init = false; 110 111 if (!_init) { 112 SSL_load_error_strings(); 113 SSL_library_init(); 114 _init = true; 115 } 116 # ifndef TLS_server_method 117 # define TLS_server_method SSLv23_server_method 118 # endif 119 # ifndef TLS_client_method 120 # define TLS_client_method SSLv23_client_method 121 # endif 122 #endif 123 124 if (server) { 125 m = TLS_server_method(); 126 } else 127 m = TLS_client_method(); 128 129 c = SSL_CTX_new((void *) m); 130 if (!c) 131 return NULL; 132 133 #if defined(HAVE_WOLFSSL) 134 if (server) 135 SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL); 136 else 137 SSL_CTX_set_verify(c, SSL_VERIFY_PEER, NULL); 138 #else 139 SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL); 140 #endif 141 142 SSL_CTX_set_options(c, SSL_OP_NO_COMPRESSION | SSL_OP_SINGLE_ECDH_USE | 143 SSL_OP_CIPHER_SERVER_PREFERENCE); 144 #if defined(SSL_CTX_set_ecdh_auto) && OPENSSL_VERSION_NUMBER < 0x10100000L 145 SSL_CTX_set_ecdh_auto(c, 1); 146 #elif OPENSSL_VERSION_NUMBER >= 0x10101000L 147 SSL_CTX_set_ciphersuites(c, tls13_ciphersuites); 148 #endif 149 if (server) { 150 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 151 SSL_CTX_set_min_proto_version(c, TLS1_2_VERSION); 152 #else 153 SSL_CTX_set_options(c, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | 154 SSL_OP_NO_TLSv1_1); 155 #endif 156 SSL_CTX_set_cipher_list(c, server_cipher_list); 157 } else { 158 SSL_CTX_set_cipher_list(c, client_cipher_list); 159 } 160 SSL_CTX_set_quiet_shutdown(c, 1); 161 162 return (void *) c; 163 } 164 165 __hidden int __ustream_ssl_add_ca_crt_file(struct ustream_ssl_ctx *ctx, const char *file) 166 { 167 int ret; 168 169 ret = SSL_CTX_load_verify_locations((void *) ctx, file, NULL); 170 if (ret < 1) 171 return -1; 172 173 return 0; 174 } 175 176 __hidden int __ustream_ssl_set_crt_file(struct ustream_ssl_ctx *ctx, const char *file) 177 { 178 int ret; 179 180 ret = SSL_CTX_use_certificate_chain_file((void *) ctx, file); 181 if (ret < 1) 182 ret = SSL_CTX_use_certificate_file((void *) ctx, file, SSL_FILETYPE_ASN1); 183 184 if (ret < 1) 185 return -1; 186 187 return 0; 188 } 189 190 __hidden int __ustream_ssl_set_key_file(struct ustream_ssl_ctx *ctx, const char *file) 191 { 192 int ret; 193 194 ret = SSL_CTX_use_PrivateKey_file((void *) ctx, file, SSL_FILETYPE_PEM); 195 if (ret < 1) 196 ret = SSL_CTX_use_PrivateKey_file((void *) ctx, file, SSL_FILETYPE_ASN1); 197 198 if (ret < 1) 199 return -1; 200 201 return 0; 202 } 203 204 __hidden int __ustream_ssl_set_ciphers(struct ustream_ssl_ctx *ctx, const char *ciphers) 205 { 206 int ret = SSL_CTX_set_cipher_list((void *) ctx, ciphers); 207 208 if (ret == 0) 209 return -1; 210 211 return 0; 212 } 213 214 __hidden int __ustream_ssl_set_require_validation(struct ustream_ssl_ctx *ctx, bool require) 215 { 216 int mode = SSL_VERIFY_PEER; 217 218 if (!require) 219 mode = SSL_VERIFY_NONE; 220 221 SSL_CTX_set_verify((void *) ctx, mode, NULL); 222 223 return 0; 224 } 225 226 __hidden void __ustream_ssl_context_free(struct ustream_ssl_ctx *ctx) 227 { 228 SSL_CTX_free((void *) ctx); 229 } 230 231 void __ustream_ssl_session_free(void *ssl) 232 { 233 BIO *bio = SSL_get_wbio(ssl); 234 struct bio_ctx *ctx = BIO_get_data(bio); 235 236 SSL_shutdown(ssl); 237 SSL_free(ssl); 238 if (ctx) { 239 BIO_meth_free(ctx->meth); 240 free(ctx); 241 } 242 } 243 244 static void ustream_ssl_error(struct ustream_ssl *us, int ret) 245 { 246 us->error = ret; 247 uloop_timeout_set(&us->error_timer, 0); 248 } 249 250 static bool ustream_ssl_verify_cn(struct ustream_ssl *us, X509 *cert) 251 { 252 int ret; 253 254 if (!us->peer_cn) 255 return false; 256 257 # ifndef WOLFSSL_OPENSSL_H_ 258 ret = X509_check_host(cert, us->peer_cn, 0, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS, NULL); 259 # else 260 ret = wolfSSL_X509_check_host(cert, us->peer_cn, 0, 0, NULL); 261 # endif 262 return ret == 1; 263 } 264 265 static void ustream_ssl_verify_cert(struct ustream_ssl *us) 266 { 267 void *ssl = us->ssl; 268 X509 *cert; 269 int res; 270 271 res = SSL_get_verify_result(ssl); 272 if (res != X509_V_OK) { 273 if (us->notify_verify_error) 274 us->notify_verify_error(us, res, X509_verify_cert_error_string(res)); 275 return; 276 } 277 278 cert = SSL_get_peer_certificate(ssl); 279 if (!cert) 280 return; 281 282 us->valid_cert = true; 283 us->valid_cn = ustream_ssl_verify_cn(us, cert); 284 285 X509_free(cert); 286 } 287 288 #ifdef WOLFSSL_SSL_H 289 static bool handle_wolfssl_asn_error(struct ustream_ssl *us, int r) 290 { 291 switch (r) { 292 case ASN_PARSE_E: 293 case ASN_VERSION_E: 294 case ASN_GETINT_E: 295 case ASN_RSA_KEY_E: 296 case ASN_OBJECT_ID_E: 297 case ASN_TAG_NULL_E: 298 case ASN_EXPECT_0_E: 299 case ASN_BITSTR_E: 300 case ASN_UNKNOWN_OID_E: 301 case ASN_DATE_SZ_E: 302 case ASN_BEFORE_DATE_E: 303 case ASN_AFTER_DATE_E: 304 case ASN_SIG_OID_E: 305 case ASN_TIME_E: 306 case ASN_INPUT_E: 307 case ASN_SIG_CONFIRM_E: 308 case ASN_SIG_HASH_E: 309 case ASN_SIG_KEY_E: 310 case ASN_DH_KEY_E: 311 case ASN_NTRU_KEY_E: 312 case ASN_CRIT_EXT_E: 313 case ASN_ALT_NAME_E: 314 case ASN_NO_PEM_HEADER: 315 case ASN_ECC_KEY_E: 316 case ASN_NO_SIGNER_E: 317 case ASN_CRL_CONFIRM_E: 318 case ASN_CRL_NO_SIGNER_E: 319 case ASN_OCSP_CONFIRM_E: 320 case ASN_NAME_INVALID_E: 321 case ASN_NO_SKID: 322 case ASN_NO_AKID: 323 case ASN_NO_KEYUSAGE: 324 case ASN_COUNTRY_SIZE_E: 325 case ASN_PATHLEN_SIZE_E: 326 case ASN_PATHLEN_INV_E: 327 case ASN_SELF_SIGNED_E: 328 if (us->notify_verify_error) 329 us->notify_verify_error(us, r, wc_GetErrorString(r)); 330 return true; 331 } 332 333 return false; 334 } 335 #endif 336 337 __hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us) 338 { 339 void *ssl = us->ssl; 340 int r; 341 342 ERR_clear_error(); 343 344 if (us->server) 345 r = SSL_accept(ssl); 346 else 347 r = SSL_connect(ssl); 348 349 if (r == 1) { 350 ustream_ssl_verify_cert(us); 351 return U_SSL_OK; 352 } 353 354 r = SSL_get_error(ssl, r); 355 if (r == SSL_ERROR_WANT_READ || r == SSL_ERROR_WANT_WRITE) 356 return U_SSL_PENDING; 357 358 #ifdef WOLFSSL_SSL_H 359 if (handle_wolfssl_asn_error(us, r)) 360 return U_SSL_OK; 361 #endif 362 363 ustream_ssl_error(us, r); 364 return U_SSL_ERROR; 365 } 366 367 __hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len) 368 { 369 void *ssl = us->ssl; 370 int ret; 371 372 ERR_clear_error(); 373 374 ret = SSL_write(ssl, buf, len); 375 376 if (ret < 0) { 377 int err = SSL_get_error(ssl, ret); 378 if (err == SSL_ERROR_WANT_WRITE) 379 return 0; 380 381 ustream_ssl_error(us, err); 382 return -1; 383 } 384 385 return ret; 386 } 387 388 __hidden int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len) 389 { 390 int ret; 391 392 ERR_clear_error(); 393 394 ret = SSL_read(us->ssl, buf, len); 395 396 if (ret < 0) { 397 ret = SSL_get_error(us->ssl, ret); 398 if (ret == SSL_ERROR_WANT_READ) 399 return U_SSL_PENDING; 400 401 ustream_ssl_error(us, ret); 402 return U_SSL_ERROR; 403 } 404 405 return ret; 406 } 407
This page was automatically generated by LXR 0.3.1. • OpenWrt