summaryrefslogtreecommitdiff
path: root/vchat-tls.c
diff options
context:
space:
mode:
Diffstat (limited to 'vchat-tls.c')
-rw-r--r--vchat-tls.c970
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
29const char *vchat_tls_version =
30 "vchat-tls.c $Id$";
31
32/* Helpers to work with vc_x509store_t used by all tls libs */
33void 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
42void vc_x509store_setflags(vc_x509store_t *store, int flags) {
43 store->flags |= flags;
44}
45void vc_x509store_clearflags(vc_x509store_t *store, int flags) {
46 store->flags &= ~flags;
47}
48void vc_x509store_set_pkeycb(vc_x509store_t *store, vc_askpass_cb_t callback) {
49 store->askpass_callback = callback;
50}
51
52void 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
58void vc_x509store_setcapath(vc_x509store_t *store, char *path) {
59 free(store->capath);
60 store->capath = (path ? strdup(path) : 0);
61}
62
63void vc_x509store_setcrlfile(vc_x509store_t *store, char *file) {
64 free(store->crlfile);
65 store->crlfile = (file ? strdup(file) : 0);
66}
67
68void vc_x509store_setkeyfile(vc_x509store_t *store, char *file) {
69 free(store->keyfile);
70 store->keyfile = (file ? strdup(file) : 0);
71}
72
73void 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
79static 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 }
129cleanup_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
144char *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
150void 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 */
163static BIO *server_conn = NULL;
164
165static SSL_CTX *vc_create_sslctx(vc_x509store_t *vc_store);
166static int vc_verify_callback(int, X509_STORE_CTX *);
167static X509_STORE *vc_x509store_create(vc_x509store_t *);
168
169static 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
235int 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
333ssl_error:
334 snprintf(tmpstr, TMPSTRSIZE, "[SSL CONNECT ERROR ] %s",
335 ERR_error_string(ERR_get_error(), NULL));
336 writecf(FS_ERR, tmpstr);
337all_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
352X509_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
390int 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
399ssize_t vc_openssl_sendmessage(const void *buf, size_t size) {
400 return BIO_write(server_conn, buf, size);
401}
402
403ssize_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
412void 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
433const char *DRBG_PERS = "mbed TLS vchat client";
434#define MAX_SUITES 512
435typedef 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;
445static mbedstate _mbedtls_state;
446
447char *vc_mbedtls_version() {
448 snprintf(tmpstr, sizeof(tmpstr), "%s", MBEDTLS_VERSION_STRING_FULL);
449 return strdup(tmpstr);
450}
451
452static int static_tcp_recv(void *ctx, unsigned char *buf, size_t len) {
453 return recv((int)(intptr_t)ctx, buf, len, 0);
454}
455static int static_tcp_send(void *ctx, const unsigned char *buf, size_t len) {
456 return send((int)(intptr_t)ctx, buf, len, 0);
457}
458static int map_openssl_suite(char *openssl_name);
459void 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
472static 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
478int 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
682ssize_t vc_mbedtls_sendmessage(const void *buf, size_t size) {
683 return mbedtls_ssl_write(&_mbedtls_state._ssl, buf, size);
684}
685
686ssize_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
703void 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 */
713static 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",
958NULL
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]));
961static 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