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 | ||