diff options
Diffstat (limited to 'vchat-tls.c')
| -rw-r--r-- | vchat-tls.c | 970 |
1 files changed, 970 insertions, 0 deletions
diff --git a/vchat-tls.c b/vchat-tls.c new file mode 100644 index 0000000..eaa12f4 --- /dev/null +++ b/vchat-tls.c | |||
| @@ -0,0 +1,970 @@ | |||
| 1 | /* | ||
| 2 | * vchat-client - alpha version | ||
| 3 | * vchat-tls.c - handling of SSL connection and X509 certificate | ||
| 4 | * verification | ||
| 5 | * | ||
| 6 | * Copyright (C) 2007 Thorsten Schroeder <ths@berlin.ccc.de> | ||
| 7 | * | ||
| 8 | * This program is free software. It can be redistributed and/or modified, | ||
| 9 | * provided that this copyright notice is kept intact. This program is | ||
| 10 | * distributed in the hope that it will be useful, but without any warranty; | ||
| 11 | * without even the implied warranty of merchantability or fitness for a | ||
| 12 | * particular purpose. In no event shall the copyright holder be liable for | ||
| 13 | * any direct, indirect, incidental or special damages arising in any way out | ||
| 14 | * of the use of this software. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <assert.h> | ||
| 19 | #include <errno.h> | ||
| 20 | #include <stdio.h> | ||
| 21 | #include <stdlib.h> | ||
| 22 | #include <string.h> | ||
| 23 | |||
| 24 | #include <readline/readline.h> | ||
| 25 | |||
| 26 | #include "vchat-tls.h" | ||
| 27 | #include "vchat.h" | ||
| 28 | |||
| 29 | const char *vchat_tls_version = | ||
| 30 | "vchat-tls.c $Id$"; | ||
| 31 | |||
| 32 | /* Helpers to work with vc_x509store_t used by all tls libs */ | ||
| 33 | void vc_cleanup_x509store(vc_x509store_t *store) { | ||
| 34 | free(store->cafile); | ||
| 35 | free(store->capath); | ||
| 36 | free(store->crlfile); | ||
| 37 | free(store->certfile); | ||
| 38 | free(store->keyfile); | ||
| 39 | memset(store, 0, sizeof(vc_x509store_t)); | ||
| 40 | } | ||
| 41 | |||
| 42 | void vc_x509store_setflags(vc_x509store_t *store, int flags) { | ||
| 43 | store->flags |= flags; | ||
| 44 | } | ||
| 45 | void vc_x509store_clearflags(vc_x509store_t *store, int flags) { | ||
| 46 | store->flags &= ~flags; | ||
| 47 | } | ||
| 48 | void vc_x509store_set_pkeycb(vc_x509store_t *store, vc_askpass_cb_t callback) { | ||
| 49 | store->askpass_callback = callback; | ||
| 50 | } | ||
| 51 | |||
| 52 | void vc_x509store_setcafile(vc_x509store_t *store, char *file) { | ||
| 53 | free(store->cafile); | ||
| 54 | store->cafile = (file ? strdup(file) : 0); | ||
| 55 | store->flags |= VC_X509S_USE_CAFILE; | ||
| 56 | } | ||
| 57 | |||
| 58 | void vc_x509store_setcapath(vc_x509store_t *store, char *path) { | ||
| 59 | free(store->capath); | ||
| 60 | store->capath = (path ? strdup(path) : 0); | ||
| 61 | } | ||
| 62 | |||
| 63 | void vc_x509store_setcrlfile(vc_x509store_t *store, char *file) { | ||
| 64 | free(store->crlfile); | ||
| 65 | store->crlfile = (file ? strdup(file) : 0); | ||
| 66 | } | ||
| 67 | |||
| 68 | void vc_x509store_setkeyfile(vc_x509store_t *store, char *file) { | ||
| 69 | free(store->keyfile); | ||
| 70 | store->keyfile = (file ? strdup(file) : 0); | ||
| 71 | } | ||
| 72 | |||
| 73 | void vc_x509store_setcertfile(vc_x509store_t *store, char *file) { | ||
| 74 | free(store->certfile); | ||
| 75 | store->certfile = (file ? strdup(file) : 0); | ||
| 76 | store->flags |= VC_X509S_USE_CERTIFICATE; | ||
| 77 | } | ||
| 78 | |||
| 79 | static int verify_or_store_fingerprint(const char *fingerprint) { | ||
| 80 | char *fingerprint_file_path = tilde_expand(getstroption(CF_FINGERPRINT)); | ||
| 81 | if (!fingerprint_file_path) { | ||
| 82 | writecf(FS_ERR, "Error: The CF_FINGERPRINT path is not set but " | ||
| 83 | "CF_PINFINGER was requested."); | ||
| 84 | return -1; | ||
| 85 | } | ||
| 86 | |||
| 87 | FILE *fingerprint_file = fopen(fingerprint_file_path, "r"); | ||
| 88 | if (fingerprint_file) { | ||
| 89 | /* Read fingerprint from file */ | ||
| 90 | char old_fingerprint[128]; | ||
| 91 | char *r = fgets(old_fingerprint, sizeof(old_fingerprint), fingerprint_file); | ||
| 92 | fclose(fingerprint_file); | ||
| 93 | |||
| 94 | if (r) { | ||
| 95 | /* chomp */ | ||
| 96 | char *nl = strchr(r, '\n'); | ||
| 97 | if (nl) | ||
| 98 | *nl = 0; | ||
| 99 | |||
| 100 | /* verify fingerprint matches stored version */ | ||
| 101 | if (!strcmp(fingerprint, old_fingerprint)) { | ||
| 102 | writecf(FS_SERV, "[FINGERPRINT MATCH ]"); | ||
| 103 | goto cleanup_happy; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | snprintf(tmpstr, TMPSTRSIZE, | ||
| 108 | "Error: Found pinned fingerprint (in %s) %s but expected %s", | ||
| 109 | r ? old_fingerprint : "<FILE READ ERROR>", | ||
| 110 | getstroption(CF_FINGERPRINT), fingerprint); | ||
| 111 | writecf(FS_ERR, tmpstr); | ||
| 112 | writecf(FS_ERR, "Error: Fingerprint mismatch! Server cert updated?"); | ||
| 113 | free(fingerprint_file_path); | ||
| 114 | return 1; | ||
| 115 | } else | ||
| 116 | writecf(FS_ERR, | ||
| 117 | "Warning: No pinned fingerprint found, writing the current one."); | ||
| 118 | |||
| 119 | fingerprint_file = fopen(fingerprint_file_path, "w"); | ||
| 120 | if (!fingerprint_file) { | ||
| 121 | snprintf(tmpstr, TMPSTRSIZE, "Warning: Can't write fingerprint file, %s.", | ||
| 122 | strerror(errno)); | ||
| 123 | writecf(FS_ERR, tmpstr); | ||
| 124 | } else { | ||
| 125 | fputs(fingerprint, fingerprint_file); | ||
| 126 | fclose(fingerprint_file); | ||
| 127 | writecf(FS_SERV, "[FINGERPRINT STORED ]"); | ||
| 128 | } | ||
| 129 | cleanup_happy: | ||
| 130 | free(fingerprint_file_path); | ||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | #ifdef TLS_LIB_OPENSSL | ||
| 135 | |||
| 136 | #include <openssl/bio.h> | ||
| 137 | #include <openssl/conf.h> | ||
| 138 | #include <openssl/err.h> | ||
| 139 | #include <openssl/evp.h> | ||
| 140 | #include <openssl/ssl.h> | ||
| 141 | #include <openssl/x509.h> | ||
| 142 | #include <openssl/x509v3.h> | ||
| 143 | |||
| 144 | char *vc_openssl_version() { | ||
| 145 | snprintf(tmpstr, sizeof(tmpstr), "OpenSSL %s with %s", | ||
| 146 | SSLeay_version(SSLEAY_VERSION), SSLeay_version(SSLEAY_CFLAGS)); | ||
| 147 | return strdup(tmpstr); | ||
| 148 | } | ||
| 149 | |||
| 150 | void vc_openssl_init_x509store(vc_x509store_t *store) { | ||
| 151 | static int sslinit; | ||
| 152 | if (!sslinit++) { | ||
| 153 | SSL_library_init(); | ||
| 154 | SSL_load_error_strings(); | ||
| 155 | } | ||
| 156 | memset(store, 0, sizeof(vc_x509store_t)); | ||
| 157 | |||
| 158 | /* We want to make verifying the peer the default */ | ||
| 159 | store->flags |= VC_X509S_SSL_VERIFY_PEER; | ||
| 160 | } | ||
| 161 | |||
| 162 | /* connection BIO for openssl */ | ||
| 163 | static BIO *server_conn = NULL; | ||
| 164 | |||
| 165 | static SSL_CTX *vc_create_sslctx(vc_x509store_t *vc_store); | ||
| 166 | static int vc_verify_callback(int, X509_STORE_CTX *); | ||
| 167 | static X509_STORE *vc_x509store_create(vc_x509store_t *); | ||
| 168 | |||
| 169 | static SSL_CTX *vc_create_sslctx(vc_x509store_t *vc_store) { | ||
| 170 | int flags = 0; | ||
| 171 | |||
| 172 | /* Explicitly use TLSv1 (or maybe later) */ | ||
| 173 | SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); | ||
| 174 | X509_STORE *store = vc_x509store_create(vc_store); | ||
| 175 | |||
| 176 | if (!ctx || !store) { | ||
| 177 | snprintf(tmpstr, sizeof(tmpstr), "CREATE CTX: %s", | ||
| 178 | ERR_error_string(ERR_get_error(), NULL)); | ||
| 179 | writecf(FS_ERR, tmpstr); | ||
| 180 | if (store) | ||
| 181 | X509_STORE_free(store); | ||
| 182 | if (ctx) | ||
| 183 | SSL_CTX_free(ctx); | ||
| 184 | return NULL; | ||
| 185 | } | ||
| 186 | |||
| 187 | SSL_CTX_set_cert_store(ctx, store); | ||
| 188 | |||
| 189 | /* Disable some insecure protocols explicitly */ | ||
| 190 | SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); | ||
| 191 | if (getstroption(CF_CIPHERSUITE)) | ||
| 192 | SSL_CTX_set_cipher_list(ctx, getstroption(CF_CIPHERSUITE)); | ||
| 193 | else | ||
| 194 | SSL_CTX_set_cipher_list(ctx, | ||
| 195 | "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA"); | ||
| 196 | |||
| 197 | SSL_CTX_set_verify_depth(ctx, getintoption(CF_VERIFYSSL)); | ||
| 198 | |||
| 199 | if (!(vc_store->flags & VC_X509S_SSL_VERIFY_MASK)) { | ||
| 200 | writecf(FS_DBG, tmpstr); | ||
| 201 | flags = SSL_VERIFY_NONE; | ||
| 202 | } else { | ||
| 203 | if (vc_store->flags & VC_X509S_SSL_VERIFY_PEER) | ||
| 204 | flags |= SSL_VERIFY_PEER; | ||
| 205 | if (vc_store->flags & VC_X509S_SSL_VERIFY_FAIL_IF_NO_PEER_CERT) | ||
| 206 | flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; | ||
| 207 | if (vc_store->flags & VC_X509S_SSL_VERIFY_CLIENT_ONCE) | ||
| 208 | flags |= SSL_VERIFY_CLIENT_ONCE; | ||
| 209 | } | ||
| 210 | |||
| 211 | SSL_CTX_set_verify(ctx, flags, vc_verify_callback); | ||
| 212 | |||
| 213 | if (vc_store->flags & VC_X509S_USE_CERTIFICATE) { | ||
| 214 | int r = 0; | ||
| 215 | if (vc_store->certfile) | ||
| 216 | SSL_CTX_use_certificate_chain_file(ctx, vc_store->certfile); | ||
| 217 | |||
| 218 | SSL_CTX_set_default_passwd_cb(ctx, vc_store->askpass_callback); | ||
| 219 | |||
| 220 | if (vc_store->keyfile) | ||
| 221 | r = SSL_CTX_use_PrivateKey_file(ctx, vc_store->keyfile, SSL_FILETYPE_PEM); | ||
| 222 | |||
| 223 | if (r != 1 || !SSL_CTX_check_private_key(ctx)) { | ||
| 224 | snprintf(tmpstr, sizeof(tmpstr), "CREATE CTX: Load private key failed"); | ||
| 225 | writecf(FS_ERR, tmpstr); | ||
| 226 | SSL_CTX_free(ctx); | ||
| 227 | return NULL; | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | SSL_CTX_set_app_data(ctx, vc_store); | ||
| 232 | return (ctx); | ||
| 233 | } | ||
| 234 | |||
| 235 | int vc_openssl_connect(int serverfd, vc_x509store_t *vc_store) { | ||
| 236 | SSL_CTX *ctx = vc_create_sslctx(vc_store); | ||
| 237 | X509 *peercert = NULL; | ||
| 238 | BIO *ssl_conn = NULL; | ||
| 239 | const SSL *sslp = NULL; | ||
| 240 | const SSL_CIPHER *cipher = NULL; | ||
| 241 | |||
| 242 | server_conn = BIO_new_socket(serverfd, 1); | ||
| 243 | |||
| 244 | /* To display and check server fingerprint */ | ||
| 245 | char fingerprint[EVP_MAX_MD_SIZE * 4]; | ||
| 246 | unsigned char fingerprint_bin[EVP_MAX_MD_SIZE]; | ||
| 247 | unsigned int fingerprint_len; | ||
| 248 | |||
| 249 | char *fp = fingerprint; | ||
| 250 | |||
| 251 | long j; | ||
| 252 | |||
| 253 | writecf(FS_SERV, "[SOCKET CONNECTED ]"); | ||
| 254 | writecf(FS_SERV, "[UPGRADING TO TLS ]"); | ||
| 255 | writecf(FS_SERV, "[TLS ENGINE OPENSSL ]"); | ||
| 256 | |||
| 257 | if (!ctx) | ||
| 258 | goto all_errors; | ||
| 259 | |||
| 260 | ssl_conn = BIO_new_ssl(ctx, 1); | ||
| 261 | SSL_CTX_free(ctx); | ||
| 262 | |||
| 263 | if (!ssl_conn) | ||
| 264 | goto ssl_error; | ||
| 265 | |||
| 266 | BIO_push(ssl_conn, server_conn); | ||
| 267 | server_conn = ssl_conn; | ||
| 268 | fflush(stdout); | ||
| 269 | |||
| 270 | if (BIO_do_handshake(server_conn) <= 0) | ||
| 271 | goto ssl_error; | ||
| 272 | |||
| 273 | /* Show information about cipher used */ | ||
| 274 | /* Get cipher object */ | ||
| 275 | BIO_get_ssl(ssl_conn, &sslp); | ||
| 276 | if (!sslp) | ||
| 277 | goto ssl_error; | ||
| 278 | |||
| 279 | cipher = SSL_get_current_cipher(sslp); | ||
| 280 | if (cipher) { | ||
| 281 | char cipher_desc[TMPSTRSIZE]; | ||
| 282 | snprintf(tmpstr, TMPSTRSIZE, "[SSL CIPHER ] %s", | ||
| 283 | SSL_CIPHER_description(cipher, cipher_desc, TMPSTRSIZE)); | ||
| 284 | writecf(FS_SERV, tmpstr); | ||
| 285 | } else { | ||
| 286 | snprintf(tmpstr, TMPSTRSIZE, | ||
| 287 | "[SSL ERROR ] Cipher not known / SSL object can't be " | ||
| 288 | "queried!"); | ||
| 289 | writecf(FS_ERR, tmpstr); | ||
| 290 | } | ||
| 291 | |||
| 292 | /* Accept being connected, _if_ verification passed */ | ||
| 293 | peercert = SSL_get_peer_certificate(sslp); | ||
| 294 | if (!peercert) | ||
| 295 | goto ssl_error; | ||
| 296 | |||
| 297 | /* show basic information about peer cert */ | ||
| 298 | snprintf(tmpstr, TMPSTRSIZE, "[SSL SUBJECT ] %s", | ||
| 299 | X509_NAME_oneline(X509_get_subject_name(peercert), 0, 0)); | ||
| 300 | writecf(FS_SERV, tmpstr); | ||
| 301 | snprintf(tmpstr, TMPSTRSIZE, "[SSL ISSUER ] %s", | ||
| 302 | X509_NAME_oneline(X509_get_issuer_name(peercert), 0, 0)); | ||
| 303 | writecf(FS_SERV, tmpstr); | ||
| 304 | |||
| 305 | /* calculate fingerprint */ | ||
| 306 | if (!X509_digest(peercert, EVP_sha1(), fingerprint_bin, &fingerprint_len)) | ||
| 307 | goto ssl_error; | ||
| 308 | |||
| 309 | assert((fingerprint_len > 1) && (fingerprint_len <= EVP_MAX_MD_SIZE)); | ||
| 310 | for (j = 0; j < (int)fingerprint_len; j++) | ||
| 311 | fp += sprintf(fp, "%02X:", fingerprint_bin[j]); | ||
| 312 | assert(fp > fingerprint); | ||
| 313 | fp[-1] = 0; | ||
| 314 | snprintf(tmpstr, TMPSTRSIZE, "[SSL FINGERPRINT ] %s (from server)", | ||
| 315 | fingerprint); | ||
| 316 | writecf(FS_SERV, tmpstr); | ||
| 317 | |||
| 318 | /* we don't need the peercert anymore */ | ||
| 319 | X509_free(peercert); | ||
| 320 | |||
| 321 | if (getintoption(CF_PINFINGER) && verify_or_store_fingerprint(fingerprint)) | ||
| 322 | return 1; | ||
| 323 | |||
| 324 | /* If verify of x509 chain was requested, do the check here */ | ||
| 325 | if (X509_V_OK == SSL_get_verify_result(sslp)) | ||
| 326 | return 0; | ||
| 327 | |||
| 328 | if (getintoption(CF_IGNSSL)) { | ||
| 329 | writecf(FS_ERR, "[SSL VERIFY ERROR ] FAILURE IGNORED!!!"); | ||
| 330 | return 0; | ||
| 331 | } | ||
| 332 | |||
| 333 | ssl_error: | ||
| 334 | snprintf(tmpstr, TMPSTRSIZE, "[SSL CONNECT ERROR ] %s", | ||
| 335 | ERR_error_string(ERR_get_error(), NULL)); | ||
| 336 | writecf(FS_ERR, tmpstr); | ||
| 337 | all_errors: | ||
| 338 | BIO_free_all(server_conn); | ||
| 339 | server_conn = NULL; | ||
| 340 | return 1; | ||
| 341 | } | ||
| 342 | |||
| 343 | #define VC_STORE_ERR_EXIT(s) \ | ||
| 344 | do { \ | ||
| 345 | fprintf(stderr, "[E] SSL_STORE: %s\n", \ | ||
| 346 | ERR_error_string(ERR_get_error(), NULL)); \ | ||
| 347 | if (s) \ | ||
| 348 | X509_STORE_free(s); \ | ||
| 349 | return (0); \ | ||
| 350 | } while (0) | ||
| 351 | |||
| 352 | X509_STORE *vc_x509store_create(vc_x509store_t *vc_store) { | ||
| 353 | X509_STORE *store = NULL; | ||
| 354 | X509_LOOKUP *lookup = NULL; | ||
| 355 | |||
| 356 | store = X509_STORE_new(); | ||
| 357 | |||
| 358 | X509_STORE_set_verify_cb_func(store, vc_verify_callback); | ||
| 359 | |||
| 360 | if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()))) | ||
| 361 | VC_STORE_ERR_EXIT(store); | ||
| 362 | |||
| 363 | if (!vc_store->cafile) { | ||
| 364 | if (!(vc_store->flags & VC_X509S_USE_CAFILE)) | ||
| 365 | X509_LOOKUP_load_file(lookup, 0, X509_FILETYPE_DEFAULT); | ||
| 366 | } else if (!X509_LOOKUP_load_file(lookup, vc_store->cafile, | ||
| 367 | X509_FILETYPE_PEM)) | ||
| 368 | VC_STORE_ERR_EXIT(store); | ||
| 369 | |||
| 370 | if (vc_store->crlfile) { | ||
| 371 | if (!X509_load_crl_file(lookup, vc_store->crlfile, X509_FILETYPE_PEM)) | ||
| 372 | VC_STORE_ERR_EXIT(store); | ||
| 373 | |||
| 374 | X509_STORE_set_flags(store, | ||
| 375 | X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); | ||
| 376 | } | ||
| 377 | |||
| 378 | if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()))) | ||
| 379 | VC_STORE_ERR_EXIT(store); | ||
| 380 | |||
| 381 | if (!vc_store->capath) { | ||
| 382 | if (!(vc_store->flags & VC_X509S_USE_CAPATH)) | ||
| 383 | X509_LOOKUP_add_dir(lookup, 0, X509_FILETYPE_DEFAULT); | ||
| 384 | } else if (!X509_LOOKUP_add_dir(lookup, vc_store->capath, X509_FILETYPE_PEM)) | ||
| 385 | VC_STORE_ERR_EXIT(store); | ||
| 386 | |||
| 387 | return (store); | ||
| 388 | } | ||
| 389 | |||
| 390 | int vc_verify_callback(int ok, X509_STORE_CTX *store) { | ||
| 391 | if (!ok) { | ||
| 392 | snprintf(tmpstr, TMPSTRSIZE, "[SSL VERIFY ERROR ] %s", | ||
| 393 | X509_verify_cert_error_string(X509_STORE_CTX_get_error(store))); | ||
| 394 | writecf(FS_ERR, tmpstr); | ||
| 395 | } | ||
| 396 | return (ok | getintoption(CF_IGNSSL)); | ||
| 397 | } | ||
| 398 | |||
| 399 | ssize_t vc_openssl_sendmessage(const void *buf, size_t size) { | ||
| 400 | return BIO_write(server_conn, buf, size); | ||
| 401 | } | ||
| 402 | |||
| 403 | ssize_t vc_openssl_receivemessage(void *buf, size_t size) { | ||
| 404 | ssize_t received = (ssize_t)BIO_read(server_conn, buf, size); | ||
| 405 | if (received != 0) | ||
| 406 | return received; | ||
| 407 | if (BIO_should_retry(server_conn)) | ||
| 408 | return -2; | ||
| 409 | return 0; | ||
| 410 | } | ||
| 411 | |||
| 412 | void vc_openssl_cleanup() { | ||
| 413 | BIO_free_all(server_conn); | ||
| 414 | server_conn = NULL; | ||
| 415 | } | ||
| 416 | #endif | ||
| 417 | |||
| 418 | #ifdef TLS_LIB_MBEDTLS | ||
| 419 | |||
| 420 | #include "mbedtls/error.h" | ||
| 421 | #include "mbedtls/version.h" | ||
| 422 | #include <mbedtls/ctr_drbg.h> | ||
| 423 | #include <mbedtls/debug.h> | ||
| 424 | #include <mbedtls/entropy.h> | ||
| 425 | #include <mbedtls/md.h> | ||
| 426 | #include <mbedtls/net_sockets.h> | ||
| 427 | #include <mbedtls/pk.h> | ||
| 428 | #include <mbedtls/ssl.h> | ||
| 429 | #include <mbedtls/x509.h> | ||
| 430 | |||
| 431 | #include <sys/socket.h> | ||
| 432 | |||
| 433 | const char *DRBG_PERS = "mbed TLS vchat client"; | ||
| 434 | #define MAX_SUITES 512 | ||
| 435 | typedef struct { | ||
| 436 | mbedtls_entropy_context _entropy; | ||
| 437 | mbedtls_ctr_drbg_context _ctr_drbg; | ||
| 438 | mbedtls_x509_crt _cacert; | ||
| 439 | mbedtls_x509_crt _cert; | ||
| 440 | mbedtls_pk_context _key; | ||
| 441 | mbedtls_ssl_context _ssl; | ||
| 442 | mbedtls_ssl_config _conf; | ||
| 443 | int ciphersuits[MAX_SUITES]; | ||
| 444 | } mbedstate; | ||
| 445 | static mbedstate _mbedtls_state; | ||
| 446 | |||
| 447 | char *vc_mbedtls_version() { | ||
| 448 | snprintf(tmpstr, sizeof(tmpstr), "%s", MBEDTLS_VERSION_STRING_FULL); | ||
| 449 | return strdup(tmpstr); | ||
| 450 | } | ||
| 451 | |||
| 452 | static int static_tcp_recv(void *ctx, unsigned char *buf, size_t len) { | ||
| 453 | return recv((int)(intptr_t)ctx, buf, len, 0); | ||
| 454 | } | ||
| 455 | static int static_tcp_send(void *ctx, const unsigned char *buf, size_t len) { | ||
| 456 | return send((int)(intptr_t)ctx, buf, len, 0); | ||
| 457 | } | ||
| 458 | static int map_openssl_suite(char *openssl_name); | ||
| 459 | void vc_mbedtls_init_x509store(vc_x509store_t *store) { | ||
| 460 | mbedtls_entropy_init(&_mbedtls_state._entropy); | ||
| 461 | mbedtls_ctr_drbg_init(&_mbedtls_state._ctr_drbg); | ||
| 462 | |||
| 463 | mbedtls_ctr_drbg_seed(&_mbedtls_state._ctr_drbg, mbedtls_entropy_func, | ||
| 464 | &_mbedtls_state._entropy, | ||
| 465 | (const unsigned char *)DRBG_PERS, sizeof(DRBG_PERS)); | ||
| 466 | memset(store, 0, sizeof(vc_x509store_t)); | ||
| 467 | |||
| 468 | /* We want to make verifying the peer the default */ | ||
| 469 | store->flags |= VC_X509S_SSL_VERIFY_PEER; | ||
| 470 | } | ||
| 471 | |||
| 472 | static void vc_tls_report_error(int error, char *message) { | ||
| 473 | size_t used = snprintf(tmpstr, sizeof(tmpstr), "Error: %s", message); | ||
| 474 | mbedtls_strerror(error, tmpstr + used, sizeof(tmpstr) - used); | ||
| 475 | writecf(FS_ERR, tmpstr); | ||
| 476 | } | ||
| 477 | |||
| 478 | int vc_mbedtls_connect(int serverfd, vc_x509store_t *vc_store) { | ||
| 479 | /* Some aliases for shorter references */ | ||
| 480 | mbedstate *s = &_mbedtls_state; | ||
| 481 | mbedtls_ssl_config *conf = &_mbedtls_state._conf; | ||
| 482 | mbedtls_ssl_context *ssl = &_mbedtls_state._ssl; | ||
| 483 | int ret, suitecount = 0; | ||
| 484 | char fingerprint[128], *token; | ||
| 485 | uint8_t digest[20]; | ||
| 486 | |||
| 487 | mbedtls_x509_crt_init(&s->_cacert); | ||
| 488 | mbedtls_x509_crt_init(&s->_cert); | ||
| 489 | mbedtls_pk_init(&s->_key); | ||
| 490 | mbedtls_ssl_init(ssl); | ||
| 491 | mbedtls_ssl_config_init(conf); | ||
| 492 | |||
| 493 | writecf(FS_SERV, "[SOCKET CONNECTED ]"); | ||
| 494 | writecf(FS_SERV, "[UPGRADING TO TLS ]"); | ||
| 495 | writecf(FS_SERV, "[TLS ENGINE MBEDTLS ]"); | ||
| 496 | |||
| 497 | if ((ret = mbedtls_ssl_config_defaults(conf, MBEDTLS_SSL_IS_CLIENT, | ||
| 498 | MBEDTLS_SSL_TRANSPORT_STREAM, | ||
| 499 | MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { | ||
| 500 | vc_tls_report_error(ret, | ||
| 501 | "Can not initialise tls parameters, mbedtls reports: "); | ||
| 502 | return -1; | ||
| 503 | } | ||
| 504 | |||
| 505 | /* TODO: Always verify peer */ | ||
| 506 | mbedtls_ssl_conf_authmode(conf, getintoption(CF_IGNSSL) | ||
| 507 | ? MBEDTLS_SSL_VERIFY_OPTIONAL | ||
| 508 | : MBEDTLS_SSL_VERIFY_REQUIRED); | ||
| 509 | mbedtls_ssl_conf_rng(conf, mbedtls_ctr_drbg_random, &s->_ctr_drbg); | ||
| 510 | |||
| 511 | char *ciphers = getstroption(CF_CIPHERSUITE); | ||
| 512 | if (!ciphers) | ||
| 513 | ciphers = "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA"; | ||
| 514 | ciphers = strdup(ciphers); | ||
| 515 | for (token = strtok(ciphers, ":"); token && suitecount < MAX_SUITES - 1; | ||
| 516 | token = strtok(NULL, ":")) { | ||
| 517 | int suite = mbedtls_ssl_get_ciphersuite_id(token); | ||
| 518 | if (!suite) | ||
| 519 | suite = map_openssl_suite(token); | ||
| 520 | if (suite) | ||
| 521 | s->ciphersuits[suitecount++] = suite; | ||
| 522 | } | ||
| 523 | s->ciphersuits[suitecount++] = 0; | ||
| 524 | free(ciphers); | ||
| 525 | |||
| 526 | mbedtls_ssl_conf_ciphersuites(conf, s->ciphersuits); | ||
| 527 | |||
| 528 | if (vc_store->cafile) { | ||
| 529 | if ((ret = mbedtls_x509_crt_parse_file(&s->_cacert, vc_store->cafile)) != | ||
| 530 | 0) { | ||
| 531 | vc_tls_report_error(ret, "Can not load CA cert, mbedtls reports: "); | ||
| 532 | return -1; | ||
| 533 | } | ||
| 534 | mbedtls_ssl_conf_ca_chain(conf, &s->_cacert, NULL); | ||
| 535 | writecf(FS_SERV, "[CA CERT LOADED ]"); | ||
| 536 | } | ||
| 537 | |||
| 538 | if (vc_store->flags & VC_X509S_USE_CERTIFICATE) { | ||
| 539 | char *password = NULL; | ||
| 540 | char password_buf[1024]; | ||
| 541 | |||
| 542 | if ((ret = mbedtls_x509_crt_parse_file(&s->_cert, vc_store->certfile)) != | ||
| 543 | 0) { | ||
| 544 | vc_tls_report_error(ret, "Can not load client cert, mbedtls reports: "); | ||
| 545 | return -1; | ||
| 546 | } | ||
| 547 | writecf(FS_SERV, "[CLIENT CERT LOADED ]"); | ||
| 548 | |||
| 549 | while (1) { | ||
| 550 | if ((ret = mbedtls_pk_parse_keyfile(&s->_key, vc_store->keyfile, password | ||
| 551 | #if MBEDTLS_VERSION_MAJOR >= 3 | ||
| 552 | , | ||
| 553 | mbedtls_ctr_drbg_random, &s->_ctr_drbg | ||
| 554 | #endif | ||
| 555 | )) == 0) | ||
| 556 | break; | ||
| 557 | if (ret != MBEDTLS_ERR_PK_PASSWORD_REQUIRED && | ||
| 558 | ret != MBEDTLS_ERR_PK_PASSWORD_MISMATCH) { | ||
| 559 | vc_tls_report_error(ret, "Can not load client key, mbedtls reports: "); | ||
| 560 | return -1; | ||
| 561 | } | ||
| 562 | if (ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH) | ||
| 563 | vc_tls_report_error(ret, "Wrong passphrase, mbedtls reports: "); | ||
| 564 | vc_store->askpass_callback(password_buf, sizeof(password_buf), 0, NULL); | ||
| 565 | password = password_buf; | ||
| 566 | } | ||
| 567 | #if defined(__linux__) || defined(__OpenBSD__) | ||
| 568 | explicit_bzero(password_buf, sizeof(password_buf)); | ||
| 569 | #else | ||
| 570 | memset_s(password_buf, sizeof(password_buf), 0, sizeof(password_buf)); | ||
| 571 | #endif | ||
| 572 | writecf(FS_SERV, "[CLIENT KEY LOADED ]"); | ||
| 573 | |||
| 574 | #if MBEDTLS_VERSION_MAJOR == 3 && MBEDTLS_VERSION_MINOR == 0 | ||
| 575 | mbedtls_pk_context *pubkey = &(s->_cert.MBEDTLS_PRIVATE(pk)); | ||
| 576 | #else | ||
| 577 | mbedtls_pk_context *pubkey = &(s->_cert.pk); | ||
| 578 | #endif | ||
| 579 | |||
| 580 | if ((ret = mbedtls_pk_check_pair(pubkey, &s->_key | ||
| 581 | #if MBEDTLS_VERSION_MAJOR >= 3 | ||
| 582 | , | ||
| 583 | mbedtls_ctr_drbg_random, &s->_ctr_drbg | ||
| 584 | #endif | ||
| 585 | )) != 0) { | ||
| 586 | vc_tls_report_error(ret, "Cert and key mismatch, mbedtls reports: "); | ||
| 587 | return 1; | ||
| 588 | } | ||
| 589 | |||
| 590 | if ((ret = mbedtls_ssl_conf_own_cert(conf, &s->_cert, &s->_key)) != 0) { | ||
| 591 | vc_tls_report_error( | ||
| 592 | ret, "Setting key and cert to tls session fails, mbedtls reports: "); | ||
| 593 | return -1; | ||
| 594 | } | ||
| 595 | } | ||
| 596 | |||
| 597 | /* Config constructed, pass to ssl */ | ||
| 598 | /* Init ssl and config structs and configure ssl ctx */ | ||
| 599 | if ((ret = mbedtls_ssl_setup(ssl, conf)) != 0) { | ||
| 600 | vc_tls_report_error( | ||
| 601 | ret, "Can not configure parameters on tls context, mbedtls reports: "); | ||
| 602 | return -1; | ||
| 603 | } | ||
| 604 | /* TODO: mbedtls_ssl_set_hostname(&ssl, SERVER_NAME) */ | ||
| 605 | |||
| 606 | mbedtls_ssl_set_bio(ssl, (void *)(intptr_t)serverfd, static_tcp_send, | ||
| 607 | static_tcp_recv, NULL); | ||
| 608 | |||
| 609 | while ((ret = mbedtls_ssl_handshake(ssl)) != 0) | ||
| 610 | if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { | ||
| 611 | vc_tls_report_error(ret, "TLS handshake failed, mbedtls reports: "); | ||
| 612 | return -1; | ||
| 613 | } | ||
| 614 | |||
| 615 | writecf(FS_SERV, "[TLS HANDSHAKE DONE ]"); | ||
| 616 | snprintf(tmpstr, TMPSTRSIZE, "[TLS CIPHER SUITE ] %s", | ||
| 617 | mbedtls_ssl_get_ciphersuite(ssl)); | ||
| 618 | writecf(FS_SERV, tmpstr); | ||
| 619 | |||
| 620 | const mbedtls_x509_crt *peer_cert = mbedtls_ssl_get_peer_cert(ssl); | ||
| 621 | mbedtls_x509_crt_info(tmpstr, sizeof(tmpstr), "[TLS PEER INFO ] ", | ||
| 622 | peer_cert); | ||
| 623 | |||
| 624 | for (token = strtok(tmpstr, "\n"); token; token = strtok(NULL, "\n")) | ||
| 625 | writecf(FS_SERV, token); | ||
| 626 | |||
| 627 | #if MBEDTLS_VERSION_MAJOR == 3 && MBEDTLS_VERSION_MINOR == 0 | ||
| 628 | const uint8_t *const rawcert_buf = | ||
| 629 | peer_cert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p); | ||
| 630 | size_t rawcert_len = peer_cert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len); | ||
| 631 | #else | ||
| 632 | const uint8_t *const rawcert_buf = peer_cert->raw.p; | ||
| 633 | size_t rawcert_len = peer_cert->raw.len; | ||
| 634 | #endif | ||
| 635 | const mbedtls_md_info_t *mdinfo = mbedtls_md_info_from_string("SHA1"); | ||
| 636 | if (mdinfo) { | ||
| 637 | mbedtls_md(mdinfo, rawcert_buf, rawcert_len, digest); | ||
| 638 | |||
| 639 | char *fp = fingerprint; | ||
| 640 | for (int j = 0; j < mbedtls_md_get_size(mdinfo); j++) | ||
| 641 | fp += sprintf(fp, "%02X:", digest[j]); | ||
| 642 | assert(fp > fingerprint); | ||
| 643 | fp[-1] = 0; | ||
| 644 | snprintf(tmpstr, TMPSTRSIZE, "[TLS FINGERPRINT ] %s (from server)", | ||
| 645 | fingerprint); | ||
| 646 | writecf(FS_SERV, tmpstr); | ||
| 647 | |||
| 648 | if (getintoption(CF_PINFINGER) && verify_or_store_fingerprint(fingerprint)) | ||
| 649 | return 1; | ||
| 650 | } else { | ||
| 651 | writecf(FS_ERR, "Warning: Unable to load SHA-1 md"); | ||
| 652 | if (getintoption(CF_PINFINGER)) { | ||
| 653 | writecf( | ||
| 654 | FS_ERR, | ||
| 655 | "ERROR: Can not compute fingerprint, but pinning check is required"); | ||
| 656 | return 1; | ||
| 657 | } | ||
| 658 | } | ||
| 659 | |||
| 660 | ret = mbedtls_ssl_get_verify_result(ssl); | ||
| 661 | switch (ret) { | ||
| 662 | case 0: | ||
| 663 | writecf(FS_SERV, "[TLS HANDSHAKE OK ]"); | ||
| 664 | break; | ||
| 665 | case -1: | ||
| 666 | writecf(FS_ERR, "Error: TLS verify for an unknown reason"); | ||
| 667 | return -1; | ||
| 668 | case MBEDTLS_X509_BADCERT_SKIP_VERIFY: | ||
| 669 | case MBEDTLS_X509_BADCERT_NOT_TRUSTED: | ||
| 670 | if (getintoption(CF_IGNSSL) || !getintoption(CF_VERIFYSSL)) | ||
| 671 | return 0; | ||
| 672 | vc_tls_report_error(ret, "TLS verify failed, mbedtls reports: "); | ||
| 673 | return -1; | ||
| 674 | default: | ||
| 675 | vc_tls_report_error(ret, "TLS verify failed, mbedtls reports: "); | ||
| 676 | return -1; | ||
| 677 | } | ||
| 678 | |||
| 679 | return 0; | ||
| 680 | } | ||
| 681 | |||
| 682 | ssize_t vc_mbedtls_sendmessage(const void *buf, size_t size) { | ||
| 683 | return mbedtls_ssl_write(&_mbedtls_state._ssl, buf, size); | ||
| 684 | } | ||
| 685 | |||
| 686 | ssize_t vc_mbedtls_receivemessage(void *buf, size_t size) { | ||
| 687 | ssize_t received = (ssize_t)mbedtls_ssl_read(&_mbedtls_state._ssl, buf, size); | ||
| 688 | switch (received) { | ||
| 689 | case MBEDTLS_ERR_SSL_WANT_READ: | ||
| 690 | case MBEDTLS_ERR_SSL_WANT_WRITE: | ||
| 691 | return -2; | ||
| 692 | case MBEDTLS_ERR_SSL_CONN_EOF: | ||
| 693 | case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: | ||
| 694 | case 0: | ||
| 695 | return 0; | ||
| 696 | default: | ||
| 697 | if (received > 0) | ||
| 698 | return received; | ||
| 699 | return -1; | ||
| 700 | } | ||
| 701 | } | ||
| 702 | |||
| 703 | void vc_mbedtls_cleanup() { | ||
| 704 | mbedtls_x509_crt_free(&_mbedtls_state._cacert); | ||
| 705 | mbedtls_x509_crt_free(&_mbedtls_state._cert); | ||
| 706 | mbedtls_pk_free(&_mbedtls_state._key); | ||
| 707 | mbedtls_ssl_free(&_mbedtls_state._ssl); | ||
| 708 | mbedtls_ssl_config_free(&_mbedtls_state._conf); | ||
| 709 | mbedtls_ctr_drbg_free(&_mbedtls_state._ctr_drbg); | ||
| 710 | } | ||
| 711 | |||
| 712 | /* Taken from https://testssl.sh/openssl-iana.mapping.html */ | ||
| 713 | static const char * xlate_openssl[] = { | ||
| 714 | "NULL-MD5", "TLS-RSA-WITH-NULL-MD5", | ||
| 715 | "NULL-SHA", "TLS-RSA-WITH-NULL-SHA", | ||
| 716 | "EXP-RC4-MD5", "TLS-RSA-EXPORT-WITH-RC4-40-MD5", | ||
| 717 | "RC4-MD5", "TLS-RSA-WITH-RC4-128-MD5", | ||
| 718 | "RC4-SHA", "TLS-RSA-WITH-RC4-128-SHA", | ||
| 719 | "EXP-RC2-CBC-MD5", "TLS-RSA-EXPORT-WITH-RC2-CBC-40-MD5", | ||
| 720 | "IDEA-CBC-SHA", "TLS-RSA-WITH-IDEA-CBC-SHA", | ||
| 721 | "EXP-DES-CBC-SHA", "TLS-RSA-EXPORT-WITH-DES40-CBC-SHA", | ||
| 722 | "DES-CBC-SHA", "TLS-RSA-WITH-DES-CBC-SHA", | ||
| 723 | "DES-CBC3-SHA", "TLS-RSA-WITH-3DES-EDE-CBC-SHA", | ||
| 724 | "EXP-DH-DSS-DES-CBC-SHA", "TLS-DH-DSS-EXPORT-WITH-DES40-CBC-SHA", | ||
| 725 | "DH-DSS-DES-CBC-SHA", "TLS-DH-DSS-WITH-DES-CBC-SHA", | ||
| 726 | "DH-DSS-DES-CBC3-SHA", "TLS-DH-DSS-WITH-3DES-EDE-CBC-SHA", | ||
| 727 | "EXP-DH-RSA-DES-CBC-SHA", "TLS-DH-RSA-EXPORT-WITH-DES40-CBC-SHA", | ||
| 728 | "DH-RSA-DES-CBC-SHA", "TLS-DH-RSA-WITH-DES-CBC-SHA", | ||
| 729 | "DH-RSA-DES-CBC3-SHA", "TLS-DH-RSA-WITH-3DES-EDE-CBC-SHA", | ||
| 730 | "EXP-EDH-DSS-DES-CBC-SHA", "TLS-DHE-DSS-EXPORT-WITH-DES40-CBC-SHA", | ||
| 731 | "EDH-DSS-DES-CBC-SHA", "TLS-DHE-DSS-WITH-DES-CBC-SHA", | ||
| 732 | "EDH-DSS-DES-CBC3-SHA", "TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA", | ||
| 733 | "EXP-EDH-RSA-DES-CBC-SHA", "TLS-DHE-RSA-EXPORT-WITH-DES40-CBC-SHA", | ||
| 734 | "EDH-RSA-DES-CBC-SHA", "TLS-DHE-RSA-WITH-DES-CBC-SHA", | ||
| 735 | "EDH-RSA-DES-CBC3-SHA", "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA", | ||
| 736 | "EXP-ADH-RC4-MD5", "TLS-DH-anon-EXPORT-WITH-RC4-40-MD5", | ||
| 737 | "ADH-RC4-MD5", "TLS-DH-anon-WITH-RC4-128-MD5", | ||
| 738 | "EXP-ADH-DES-CBC-SHA", "TLS-DH-anon-EXPORT-WITH-DES40-CBC-SHA", | ||
| 739 | "ADH-DES-CBC-SHA", "TLS-DH-anon-WITH-DES-CBC-SHA", | ||
| 740 | "ADH-DES-CBC3-SHA", "TLS-DH-anon-WITH-3DES-EDE-CBC-SHA", | ||
| 741 | "KRB5-DES-CBC-SHA", "TLS-KRB5-WITH-DES-CBC-SHA", | ||
| 742 | "KRB5-DES-CBC3-SHA", "TLS-KRB5-WITH-3DES-EDE-CBC-SHA", | ||
| 743 | "KRB5-RC4-SHA", "TLS-KRB5-WITH-RC4-128-SHA", | ||
| 744 | "KRB5-IDEA-CBC-SHA", "TLS-KRB5-WITH-IDEA-CBC-SHA", | ||
| 745 | "KRB5-DES-CBC-MD5", "TLS-KRB5-WITH-DES-CBC-MD5", | ||
| 746 | "KRB5-DES-CBC3-MD5", "TLS-KRB5-WITH-3DES-EDE-CBC-MD5", | ||
| 747 | "KRB5-RC4-MD5", "TLS-KRB5-WITH-RC4-128-MD5", | ||
| 748 | "KRB5-IDEA-CBC-MD5", "TLS-KRB5-WITH-IDEA-CBC-MD5", | ||
| 749 | "EXP-KRB5-DES-CBC-SHA", "TLS-KRB5-EXPORT-WITH-DES-CBC-40-SHA", | ||
| 750 | "EXP-KRB5-RC2-CBC-SHA", "TLS-KRB5-EXPORT-WITH-RC2-CBC-40-SHA", | ||
| 751 | "EXP-KRB5-RC4-SHA", "TLS-KRB5-EXPORT-WITH-RC4-40-SHA", | ||
| 752 | "EXP-KRB5-DES-CBC-MD5", "TLS-KRB5-EXPORT-WITH-DES-CBC-40-MD5", | ||
| 753 | "EXP-KRB5-RC2-CBC-MD5", "TLS-KRB5-EXPORT-WITH-RC2-CBC-40-MD5", | ||
| 754 | "EXP-KRB5-RC4-MD5", "TLS-KRB5-EXPORT-WITH-RC4-40-MD5", | ||
| 755 | "PSK-NULL-SHA", "TLS-PSK-WITH-NULL-SHA", | ||
| 756 | "DHE-PSK-NULL-SHA", "TLS-DHE-PSK-WITH-NULL-SHA", | ||
| 757 | "RSA-PSK-NULL-SHA", "TLS-RSA-PSK-WITH-NULL-SHA", | ||
| 758 | "AES128-SHA", "TLS-RSA-WITH-AES-128-CBC-SHA", | ||
| 759 | "DH-DSS-AES128-SHA", "TLS-DH-DSS-WITH-AES-128-CBC-SHA", | ||
| 760 | "DH-RSA-AES128-SHA", "TLS-DH-RSA-WITH-AES-128-CBC-SHA", | ||
| 761 | "DHE-DSS-AES128-SHA", "TLS-DHE-DSS-WITH-AES-128-CBC-SHA", | ||
| 762 | "DHE-RSA-AES128-SHA", "TLS-DHE-RSA-WITH-AES-128-CBC-SHA", | ||
| 763 | "ADH-AES128-SHA", "TLS-DH-anon-WITH-AES-128-CBC-SHA", | ||
| 764 | "AES256-SHA", "TLS-RSA-WITH-AES-256-CBC-SHA", | ||
| 765 | "DH-DSS-AES256-SHA", "TLS-DH-DSS-WITH-AES-256-CBC-SHA", | ||
| 766 | "DH-RSA-AES256-SHA", "TLS-DH-RSA-WITH-AES-256-CBC-SHA", | ||
| 767 | "DHE-DSS-AES256-SHA", "TLS-DHE-DSS-WITH-AES-256-CBC-SHA", | ||
| 768 | "DHE-RSA-AES256-SHA", "TLS-DHE-RSA-WITH-AES-256-CBC-SHA", | ||
| 769 | "ADH-AES256-SHA", "TLS-DH-anon-WITH-AES-256-CBC-SHA", | ||
| 770 | "NULL-SHA256", "TLS-RSA-WITH-NULL-SHA256", | ||
| 771 | "AES128-SHA256", "TLS-RSA-WITH-AES-128-CBC-SHA256", | ||
| 772 | "AES256-SHA256", "TLS-RSA-WITH-AES-256-CBC-SHA256", | ||
| 773 | "DH-DSS-AES128-SHA256", "TLS-DH-DSS-WITH-AES-128-CBC-SHA256", | ||
| 774 | "DH-RSA-AES128-SHA256", "TLS-DH-RSA-WITH-AES-128-CBC-SHA256", | ||
| 775 | "DHE-DSS-AES128-SHA256", "TLS-DHE-DSS-WITH-AES-128-CBC-SHA256", | ||
| 776 | "CAMELLIA128-SHA", "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA", | ||
| 777 | "DH-DSS-CAMELLIA128-SHA", "TLS-DH-DSS-WITH-CAMELLIA-128-CBC-SHA", | ||
| 778 | "DH-RSA-CAMELLIA128-SHA", "TLS-DH-RSA-WITH-CAMELLIA-128-CBC-SHA", | ||
| 779 | "DHE-DSS-CAMELLIA128-SHA", "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA", | ||
| 780 | "DHE-RSA-CAMELLIA128-SHA", "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA", | ||
| 781 | "ADH-CAMELLIA128-SHA", "TLS-DH-anon-WITH-CAMELLIA-128-CBC-SHA", | ||
| 782 | "EXP1024-RC4-MD5", "TLS-RSA-EXPORT1024-WITH-RC4-56-MD5", | ||
| 783 | "EXP1024-RC2-CBC-MD5", "TLS-RSA-EXPORT1024-WITH-RC2-CBC-56-MD5", | ||
| 784 | "EXP1024-DES-CBC-SHA", "TLS-RSA-EXPORT1024-WITH-DES-CBC-SHA", | ||
| 785 | "EXP1024-DHE-DSS-DES-CBC-SHA", "TLS-DHE-DSS-EXPORT1024-WITH-DES-CBC-SHA", | ||
| 786 | "EXP1024-RC4-SHA", "TLS-RSA-EXPORT1024-WITH-RC4-56-SHA", | ||
| 787 | "EXP1024-DHE-DSS-RC4-SHA", "TLS-DHE-DSS-EXPORT1024-WITH-RC4-56-SHA", | ||
| 788 | "DHE-DSS-RC4-SHA", "TLS-DHE-DSS-WITH-RC4-128-SHA", | ||
| 789 | "DHE-RSA-AES128-SHA256", "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256", | ||
| 790 | "DH-DSS-AES256-SHA256", "TLS-DH-DSS-WITH-AES-256-CBC-SHA256", | ||
| 791 | "DH-RSA-AES256-SHA256", "TLS-DH-RSA-WITH-AES-256-CBC-SHA256", | ||
| 792 | "DHE-DSS-AES256-SHA256", "TLS-DHE-DSS-WITH-AES-256-CBC-SHA256", | ||
| 793 | "DHE-RSA-AES256-SHA256", "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256", | ||
| 794 | "ADH-AES128-SHA256", "TLS-DH-anon-WITH-AES-128-CBC-SHA256", | ||
| 795 | "ADH-AES256-SHA256", "TLS-DH-anon-WITH-AES-256-CBC-SHA256", | ||
| 796 | "GOST94-GOST89-GOST89", "TLS-GOSTR341094-WITH-28147-CNT-IMIT", | ||
| 797 | "GOST2001-GOST89-GOST89", "TLS-GOSTR341001-WITH-28147-CNT-IMIT", | ||
| 798 | "GOST94-NULL-GOST94", "TLS-GOSTR341001-WITH-NULL-GOSTR3411", | ||
| 799 | "GOST2001-GOST89-GOST89", "TLS-GOSTR341094-WITH-NULL-GOSTR3411", | ||
| 800 | "CAMELLIA256-SHA", "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA", | ||
| 801 | "DH-DSS-CAMELLIA256-SHA", "TLS-DH-DSS-WITH-CAMELLIA-256-CBC-SHA", | ||
| 802 | "DH-RSA-CAMELLIA256-SHA", "TLS-DH-RSA-WITH-CAMELLIA-256-CBC-SHA", | ||
| 803 | "DHE-DSS-CAMELLIA256-SHA", "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA", | ||
| 804 | "DHE-RSA-CAMELLIA256-SHA", "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA", | ||
| 805 | "ADH-CAMELLIA256-SHA", "TLS-DH-anon-WITH-CAMELLIA-256-CBC-SHA", | ||
| 806 | "PSK-RC4-SHA", "TLS-PSK-WITH-RC4-128-SHA", | ||
| 807 | "PSK-3DES-EDE-CBC-SHA", "TLS-PSK-WITH-3DES-EDE-CBC-SHA", | ||
| 808 | "PSK-AES128-CBC-SHA", "TLS-PSK-WITH-AES-128-CBC-SHA", | ||
| 809 | "PSK-AES256-CBC-SHA", "TLS-PSK-WITH-AES-256-CBC-SHA", | ||
| 810 | "SEED-SHA", "TLS-RSA-WITH-SEED-CBC-SHA", | ||
| 811 | "DH-DSS-SEED-SHA", "TLS-DH-DSS-WITH-SEED-CBC-SHA", | ||
| 812 | "DH-RSA-SEED-SHA", "TLS-DH-RSA-WITH-SEED-CBC-SHA", | ||
| 813 | "DHE-DSS-SEED-SHA", "TLS-DHE-DSS-WITH-SEED-CBC-SHA", | ||
| 814 | "DHE-RSA-SEED-SHA", "TLS-DHE-RSA-WITH-SEED-CBC-SHA", | ||
| 815 | "ADH-SEED-SHA", "TLS-DH-anon-WITH-SEED-CBC-SHA", | ||
| 816 | "AES128-GCM-SHA256", "TLS-RSA-WITH-AES-128-GCM-SHA256", | ||
| 817 | "AES256-GCM-SHA384", "TLS-RSA-WITH-AES-256-GCM-SHA384", | ||
| 818 | "DHE-RSA-AES128-GCM-SHA256", "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256", | ||
| 819 | "DHE-RSA-AES256-GCM-SHA384", "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384", | ||
| 820 | "DH-RSA-AES128-GCM-SHA256", "TLS-DH-RSA-WITH-AES-128-GCM-SHA256", | ||
| 821 | "DH-RSA-AES256-GCM-SHA384", "TLS-DH-RSA-WITH-AES-256-GCM-SHA384", | ||
| 822 | "DHE-DSS-AES128-GCM-SHA256", "TLS-DHE-DSS-WITH-AES-128-GCM-SHA256", | ||
| 823 | "DHE-DSS-AES256-GCM-SHA384", "TLS-DHE-DSS-WITH-AES-256-GCM-SHA384", | ||
| 824 | "DH-DSS-AES128-GCM-SHA256", "TLS-DH-DSS-WITH-AES-128-GCM-SHA256", | ||
| 825 | "DH-DSS-AES256-GCM-SHA384", "TLS-DH-DSS-WITH-AES-256-GCM-SHA384", | ||
| 826 | "ADH-AES128-GCM-SHA256", "TLS-DH-anon-WITH-AES-128-GCM-SHA256", | ||
| 827 | "ADH-AES256-GCM-SHA384", "TLS-DH-anon-WITH-AES-256-GCM-SHA384", | ||
| 828 | "CAMELLIA128-SHA256", "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 829 | "DH-DSS-CAMELLIA128-SHA256", "TLS-DH-DSS-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 830 | "DH-RSA-CAMELLIA128-SHA256", "TLS-DH-RSA-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 831 | "DHE-DSS-CAMELLIA128-SHA256", "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 832 | "DHE-RSA-CAMELLIA128-SHA256", "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 833 | "ADH-CAMELLIA128-SHA256", "TLS-DH-anon-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 834 | "TLS-FALLBACK-SCSV", "TLS-EMPTY-RENEGOTIATION-INFO-SCSV", | ||
| 835 | "TLS-AES-128-GCM-SHA256", "TLS-AES-128-GCM-SHA256", | ||
| 836 | "TLS-AES-256-GCM-SHA384", "TLS-AES-256-GCM-SHA384", | ||
| 837 | "TLS-CHACHA20-POLY1305-SHA256", "TLS-CHACHA20-POLY1305-SHA256", | ||
| 838 | "TLS-AES-128-CCM-SHA256", "TLS-AES-128-CCM-SHA256", | ||
| 839 | "TLS-AES-128-CCM-8-SHA256", "TLS-AES-128-CCM-8-SHA256", | ||
| 840 | "ECDH-ECDSA-NULL-SHA", "TLS-ECDH-ECDSA-WITH-NULL-SHA", | ||
| 841 | "ECDH-ECDSA-RC4-SHA", "TLS-ECDH-ECDSA-WITH-RC4-128-SHA", | ||
| 842 | "ECDH-ECDSA-DES-CBC3-SHA", "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA", | ||
| 843 | "ECDH-ECDSA-AES128-SHA", "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA", | ||
| 844 | "ECDH-ECDSA-AES256-SHA", "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA", | ||
| 845 | "ECDHE-ECDSA-NULL-SHA", "TLS-ECDHE-ECDSA-WITH-NULL-SHA", | ||
| 846 | "ECDHE-ECDSA-RC4-SHA", "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA", | ||
| 847 | "ECDHE-ECDSA-DES-CBC3-SHA", "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA", | ||
| 848 | "ECDHE-ECDSA-AES128-SHA", "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA", | ||
| 849 | "ECDHE-ECDSA-AES256-SHA", "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA", | ||
| 850 | "ECDH-RSA-NULL-SHA", "TLS-ECDH-RSA-WITH-NULL-SHA", | ||
| 851 | "ECDH-RSA-RC4-SHA", "TLS-ECDH-RSA-WITH-RC4-128-SHA", | ||
| 852 | "ECDH-RSA-DES-CBC3-SHA", "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA", | ||
| 853 | "ECDH-RSA-AES128-SHA", "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA", | ||
| 854 | "ECDH-RSA-AES256-SHA", "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA", | ||
| 855 | "ECDHE-RSA-NULL-SHA", "TLS-ECDHE-RSA-WITH-NULL-SHA", | ||
| 856 | "ECDHE-RSA-RC4-SHA", "TLS-ECDHE-RSA-WITH-RC4-128-SHA", | ||
| 857 | "ECDHE-RSA-DES-CBC3-SHA", "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA", | ||
| 858 | "ECDHE-RSA-AES128-SHA", "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA", | ||
| 859 | "ECDHE-RSA-AES256-SHA", "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA", | ||
| 860 | "AECDH-NULL-SHA", "TLS-ECDH-anon-WITH-NULL-SHA", | ||
| 861 | "AECDH-RC4-SHA", "TLS-ECDH-anon-WITH-RC4-128-SHA", | ||
| 862 | "AECDH-DES-CBC3-SHA", "TLS-ECDH-anon-WITH-3DES-EDE-CBC-SHA", | ||
| 863 | "AECDH-AES128-SHA", "TLS-ECDH-anon-WITH-AES-128-CBC-SHA", | ||
| 864 | "AECDH-AES256-SHA", "TLS-ECDH-anon-WITH-AES-256-CBC-SHA", | ||
| 865 | "SRP-3DES-EDE-CBC-SHA", "TLS-SRP-SHA-WITH-3DES-EDE-CBC-SHA", | ||
| 866 | "SRP-RSA-3DES-EDE-CBC-SHA", "TLS-SRP-SHA-RSA-WITH-3DES-EDE-CBC-SHA", | ||
| 867 | "SRP-DSS-3DES-EDE-CBC-SHA", "TLS-SRP-SHA-DSS-WITH-3DES-EDE-CBC-SHA", | ||
| 868 | "SRP-AES-128-CBC-SHA", "TLS-SRP-SHA-WITH-AES-128-CBC-SHA", | ||
| 869 | "SRP-RSA-AES-128-CBC-SHA", "TLS-SRP-SHA-RSA-WITH-AES-128-CBC-SHA", | ||
| 870 | "SRP-DSS-AES-128-CBC-SHA", "TLS-SRP-SHA-DSS-WITH-AES-128-CBC-SHA", | ||
| 871 | "SRP-AES-256-CBC-SHA", "TLS-SRP-SHA-WITH-AES-256-CBC-SHA", | ||
| 872 | "SRP-RSA-AES-256-CBC-SHA", "TLS-SRP-SHA-RSA-WITH-AES-256-CBC-SHA", | ||
| 873 | "SRP-DSS-AES-256-CBC-SHA", "TLS-SRP-SHA-DSS-WITH-AES-256-CBC-SHA", | ||
| 874 | "ECDHE-ECDSA-AES128-SHA256", "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256", | ||
| 875 | "ECDHE-ECDSA-AES256-SHA384", "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384", | ||
| 876 | "ECDH-ECDSA-AES128-SHA256", "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256", | ||
| 877 | "ECDH-ECDSA-AES256-SHA384", "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384", | ||
| 878 | "ECDHE-RSA-AES128-SHA256", "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256", | ||
| 879 | "ECDHE-RSA-AES256-SHA384", "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384", | ||
| 880 | "ECDH-RSA-AES128-SHA256", "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256", | ||
| 881 | "ECDH-RSA-AES256-SHA384", "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384", | ||
| 882 | "ECDHE-ECDSA-AES128-GCM-SHA256", "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256", | ||
| 883 | "ECDHE-ECDSA-AES256-GCM-SHA384", "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384", | ||
| 884 | "ECDH-ECDSA-AES128-GCM-SHA256", "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256", | ||
| 885 | "ECDH-ECDSA-AES256-GCM-SHA384", "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384", | ||
| 886 | "ECDHE-RSA-AES128-GCM-SHA256", "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256", | ||
| 887 | "ECDHE-RSA-AES256-GCM-SHA384", "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384", | ||
| 888 | "ECDH-RSA-AES128-GCM-SHA256", "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256", | ||
| 889 | "ECDH-RSA-AES256-GCM-SHA384", "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384", | ||
| 890 | "ECDHE-PSK-RC4-SHA", "TLS-ECDHE-PSK-WITH-RC4-128-SHA", | ||
| 891 | "ECDHE-PSK-3DES-EDE-CBC-SHA", "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA", | ||
| 892 | "ECDHE-PSK-AES128-CBC-SHA", "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA", | ||
| 893 | "ECDHE-PSK-AES256-CBC-SHA", "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA", | ||
| 894 | "ECDHE-PSK-AES128-CBC-SHA256", "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256", | ||
| 895 | "ECDHE-PSK-AES256-CBC-SHA384", "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384", | ||
| 896 | "ECDHE-PSK-NULL-SHA", "TLS-ECDHE-PSK-WITH-NULL-SHA", | ||
| 897 | "ECDHE-PSK-NULL-SHA256", "TLS-ECDHE-PSK-WITH-NULL-SHA256", | ||
| 898 | "ECDHE-PSK-NULL-SHA384", "TLS-ECDHE-PSK-WITH-NULL-SHA384", | ||
| 899 | "ECDHE-ECDSA-CAMELLIA128-SHA256", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 900 | "ECDHE-ECDSA-CAMELLIA256-SHA38", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", | ||
| 901 | "ECDH-ECDSA-CAMELLIA128-SHA256", "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 902 | "ECDH-ECDSA-CAMELLIA256-SHA384", "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", | ||
| 903 | "ECDHE-RSA-CAMELLIA128-SHA256", "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 904 | "ECDHE-RSA-CAMELLIA256-SHA384", "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384", | ||
| 905 | "ECDH-RSA-CAMELLIA128-SHA256", "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 906 | "ECDH-RSA-CAMELLIA256-SHA384", "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384", | ||
| 907 | "PSK-CAMELLIA128-SHA256", "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 908 | "PSK-CAMELLIA256-SHA384", "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384", | ||
| 909 | "DHE-PSK-CAMELLIA128-SHA256", "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 910 | "DHE-PSK-CAMELLIA256-SHA384", "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", | ||
| 911 | "RSA-PSK-CAMELLIA128-SHA256", "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 912 | "RSA-PSK-CAMELLIA256-SHA384", "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384", | ||
| 913 | "ECDHE-PSK-CAMELLIA128-SHA256", "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", | ||
| 914 | "ECDHE-PSK-CAMELLIA256-SHA384", "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", | ||
| 915 | "AES128-CCM", "TLS-RSA-WITH-AES-128-CCM", | ||
| 916 | "AES256-CCM", "TLS-RSA-WITH-AES-256-CCM", | ||
| 917 | "DHE-RSA-AES128-CCM", "TLS-DHE-RSA-WITH-AES-128-CCM", | ||
| 918 | "DHE-RSA-AES256-CCM", "TLS-DHE-RSA-WITH-AES-256-CCM", | ||
| 919 | "AES128-CCM8", "TLS-RSA-WITH-AES-128-CCM-8", | ||
| 920 | "AES256-CCM8", "TLS-RSA-WITH-AES-256-CCM-8", | ||
| 921 | "DHE-RSA-AES128-CCM8", "TLS-DHE-RSA-WITH-AES-128-CCM-8", | ||
| 922 | "DHE-RSA-AES256-CCM8", "TLS-DHE-RSA-WITH-AES-256-CCM-8", | ||
| 923 | "PSK-AES128-CCM", "TLS-PSK-WITH-AES-128-CCM", | ||
| 924 | "PSK-AES256-CCM", "TLS-PSK-WITH-AES-256-CCM", | ||
| 925 | "DHE-PSK-AES128-CCM", "TLS-DHE-PSK-WITH-AES-128-CCM", | ||
| 926 | "DHE-PSK-AES256-CCM", "TLS-DHE-PSK-WITH-AES-256-CCM", | ||
| 927 | "PSK-AES128-CCM8", "TLS-PSK-WITH-AES-128-CCM-8", | ||
| 928 | "PSK-AES256-CCM8", "TLS-PSK-WITH-AES-256-CCM-8", | ||
| 929 | "DHE-PSK-AES128-CCM8", "TLS-PSK-DHE-WITH-AES-128-CCM-8", | ||
| 930 | "DHE-PSK-AES256-CCM8", "TLS-PSK-DHE-WITH-AES-256-CCM-8", | ||
| 931 | "ECDHE-ECDSA-AES128-CCM", "TLS-ECDHE-ECDSA-WITH-AES-128-CCM", | ||
| 932 | "ECDHE-ECDSA-AES256-CCM", "TLS-ECDHE-ECDSA-WITH-AES-256-CCM", | ||
| 933 | "ECDHE-ECDSA-AES128-CCM8", "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8", | ||
| 934 | "ECDHE-ECDSA-AES256-CCM8", "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8", | ||
| 935 | "ECDHE-RSA-CHACHA20-POLY1305-OLD", "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256-OLD", | ||
| 936 | "ECDHE-ECDSA-CHACHA20-POLY1305-OLD", "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256-OLD", | ||
| 937 | "DHE-RSA-CHACHA20-POLY1305-OLD", "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256-OLD", | ||
| 938 | "ECDHE-RSA-CHACHA20-POLY1305", "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256", | ||
| 939 | "ECDHE-ECDSA-CHACHA20-POLY1305", "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256", | ||
| 940 | "DHE-RSA-CHACHA20-POLY1305", "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256", | ||
| 941 | "PSK-CHACHA20-POLY1305", "TLS-PSK-WITH-CHACHA20-POLY1305-SHA256", | ||
| 942 | "ECDHE-PSK-CHACHA20-POLY1305", "TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256", | ||
| 943 | "DHE-PSK-CHACHA20-POLY1305", "TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256", | ||
| 944 | "RSA-PSK-CHACHA20-POLY1305", "TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256", | ||
| 945 | "GOST-MD5", "TLS-GOSTR341094-RSA-WITH-28147-CNT-MD5", | ||
| 946 | "GOST-GOST94", "TLS-RSA-WITH-28147-CNT-GOST94", | ||
| 947 | "RC4-MD5", "SSL-CK-RC4-128-WITH-MD5", | ||
| 948 | "EXP-RC4-MD5", "SSL-CK-RC4-128-EXPORT40-WITH-MD5", | ||
| 949 | "RC2-CBC-MD5", "SSL-CK-RC2-128-CBC-WITH-MD5", | ||
| 950 | "EXP-RC2-CBC-MD5", "SSL-CK-RC2-128-CBC-EXPORT40-WITH-MD5", | ||
| 951 | "IDEA-CBC-MD5", "SSL-CK-IDEA-128-CBC-WITH-MD5", | ||
| 952 | "DES-CBC-MD5", "SSL-CK-DES-64-CBC-WITH-MD5", | ||
| 953 | "DES-CBC-SHA", "SSL-CK-DES-64-CBC-WITH-SHA", | ||
| 954 | "DES-CBC3-MD5", "SSL-CK-DES-192-EDE3-CBC-WITH-MD5", | ||
| 955 | "DES-CBC3-SHA", "SSL-CK-DES-192-EDE3-CBC-WITH-SHA", | ||
| 956 | "RC4-64-MD5", "SSL-CK-RC4-64-WITH-MD5", | ||
| 957 | "DES-CFB-M1", "SSL-CK-DES-64-CFB64-WITH-MD5-1", | ||
| 958 | NULL | ||
| 959 | }; | ||
| 960 | // fprintf(stderr, "SUCCESS: %s => %s => %d\n\n", xlate_openssl[i], xlate_openssl[i+1], mbedtls_ssl_get_ciphersuite_id(xlate_openssl[i+1])); | ||
| 961 | static int map_openssl_suite(char *openssl_name) { | ||
| 962 | int i; | ||
| 963 | for (i = 0; xlate_openssl[i]; i += 2) { | ||
| 964 | if (!strcmp(xlate_openssl[i], openssl_name)) | ||
| 965 | return mbedtls_ssl_get_ciphersuite_id(xlate_openssl[i + 1]); | ||
| 966 | } | ||
| 967 | return 0; | ||
| 968 | } | ||
| 969 | |||
| 970 | #endif | ||
