summaryrefslogtreecommitdiff
path: root/vchat-tls.c
diff options
context:
space:
mode:
Diffstat (limited to 'vchat-tls.c')
-rwxr-xr-xvchat-tls.c1036
1 files changed, 538 insertions, 498 deletions
diff --git a/vchat-tls.c b/vchat-tls.c
index 7b0f1fa..187f10b 100755
--- a/vchat-tls.c
+++ b/vchat-tls.c
@@ -15,663 +15,703 @@
15 * 15 *
16 */ 16 */
17 17
18#include <assert.h>
19#include <errno.h>
18#include <stdio.h> 20#include <stdio.h>
19#include <stdlib.h> 21#include <stdlib.h>
20#include <string.h> 22#include <string.h>
21#include <assert.h>
22#include <errno.h>
23 23
24#include <readline/readline.h> 24#include <readline/readline.h>
25 25
26#include "vchat.h"
27#include "vchat-tls.h" 26#include "vchat-tls.h"
27#include "vchat.h"
28 28
29const char *vchat_tls_version = "vchat-tls.c $Id$"; 29const char *vchat_tls_version =
30const char *vchat_tls_version_external = "Unknown implementation; version unknown"; 30 "vchat-tls.c $Id$";
31const char *vchat_tls_version_external =
32 "Unknown implementation; version unknown";
31 33
32/* Helpers to work with vc_x509store_t used by all tls libs */ 34/* Helpers to work with vc_x509store_t used by all tls libs */
33void vc_cleanup_x509store(vc_x509store_t *store) { 35void vc_cleanup_x509store(vc_x509store_t *store) {
34 free(store->cafile); 36 free(store->cafile);
35 free(store->capath); 37 free(store->capath);
36 free(store->crlfile); 38 free(store->crlfile);
37 free(store->certfile); 39 free(store->certfile);
38 free(store->keyfile); 40 free(store->keyfile);
39 memset(store, 0, sizeof(vc_x509store_t)); 41 memset(store, 0, sizeof(vc_x509store_t));
40} 42}
41 43
42void vc_x509store_setflags(vc_x509store_t *store, int flags) { store->flags |= flags; } 44void vc_x509store_setflags(vc_x509store_t *store, int flags) {
43void vc_x509store_clearflags(vc_x509store_t *store, int flags) { store->flags &= ~flags; } 45 store->flags |= flags;
44void vc_x509store_set_pkeycb(vc_x509store_t *store, vc_askpass_cb_t callback) { store->askpass_callback = callback; } 46}
47void vc_x509store_clearflags(vc_x509store_t *store, int flags) {
48 store->flags &= ~flags;
49}
50void vc_x509store_set_pkeycb(vc_x509store_t *store, vc_askpass_cb_t callback) {
51 store->askpass_callback = callback;
52}
45 53
46void vc_x509store_setcafile(vc_x509store_t *store, char *file) { 54void vc_x509store_setcafile(vc_x509store_t *store, char *file) {
47 free(store->cafile); 55 free(store->cafile);
48 store->cafile = ( file ? strdup(file) : 0 ); 56 store->cafile = (file ? strdup(file) : 0);
49 store->flags |= VC_X509S_USE_CAFILE; 57 store->flags |= VC_X509S_USE_CAFILE;
50} 58}
51 59
52void vc_x509store_setcapath(vc_x509store_t *store, char *path) { 60void vc_x509store_setcapath(vc_x509store_t *store, char *path) {
53 free(store->capath); 61 free(store->capath);
54 store->capath = ( path ? strdup(path) : 0 ); 62 store->capath = (path ? strdup(path) : 0);
55} 63}
56 64
57void vc_x509store_setcrlfile(vc_x509store_t *store, char *file) { 65void vc_x509store_setcrlfile(vc_x509store_t *store, char *file) {
58 free(store->crlfile); 66 free(store->crlfile);
59 store->crlfile = ( file ? strdup(file) : 0 ); 67 store->crlfile = (file ? strdup(file) : 0);
60} 68}
61 69
62void vc_x509store_setkeyfile(vc_x509store_t *store, char *file) { 70void vc_x509store_setkeyfile(vc_x509store_t *store, char *file) {
63 free(store->keyfile); 71 free(store->keyfile);
64 store->keyfile = ( file ? strdup(file) : 0 ); 72 store->keyfile = (file ? strdup(file) : 0);
65} 73}
66 74
67void vc_x509store_setcertfile(vc_x509store_t *store, char *file) { 75void vc_x509store_setcertfile(vc_x509store_t *store, char *file) {
68 free(store->certfile); 76 free(store->certfile);
69 store->certfile = ( file ? strdup(file) : 0 ); 77 store->certfile = (file ? strdup(file) : 0);
70 store->flags |= VC_X509S_USE_CERTIFICATE; 78 store->flags |= VC_X509S_USE_CERTIFICATE;
71} 79}
72 80
73static int verify_or_store_fingerprint(const char *fingerprint) { 81static int verify_or_store_fingerprint(const char *fingerprint) {
74 char *fingerprint_file_path = tilde_expand(getstroption(CF_FINGERPRINT)); 82 char *fingerprint_file_path = tilde_expand(getstroption(CF_FINGERPRINT));
75 if (!fingerprint_file_path) { 83 if (!fingerprint_file_path) {
76 writecf(FS_ERR, "Error: The CF_FINGERPRINT path is not set but CF_PINFINGER was requested."); 84 writecf(FS_ERR, "Error: The CF_FINGERPRINT path is not set but "
77 return -1; 85 "CF_PINFINGER was requested.");
86 return -1;
87 }
88
89 FILE *fingerprint_file = fopen(fingerprint_file_path, "r");
90 if (fingerprint_file) {
91 /* Read fingerprint from file */
92 char old_fingerprint[128];
93 char *r = fgets(old_fingerprint, sizeof(old_fingerprint), fingerprint_file);
94 fclose(fingerprint_file);
95
96 if (r) {
97 /* chomp */
98 char *nl = strchr(r, '\n');
99 if (nl)
100 *nl = 0;
101
102 /* verify fingerprint matches stored version */
103 if (!strcmp(fingerprint, old_fingerprint)) {
104 writecf(FS_SERV, "[FINGERPRINT MATCH ]");
105 goto cleanup_happy;
106 }
78 } 107 }
79 108
80 FILE *fingerprint_file = fopen(fingerprint_file_path, "r"); 109 snprintf(tmpstr, TMPSTRSIZE,
81 if (fingerprint_file) { 110 "Error: Found pinned fingerprint (in %s) %s but expected %s",
82 /* Read fingerprint from file */ 111 r ? old_fingerprint : "<FILE READ ERROR>",
83 char old_fingerprint[128]; 112 getstroption(CF_FINGERPRINT), fingerprint);
84 char * r = fgets(old_fingerprint, sizeof(old_fingerprint), fingerprint_file); 113 writecf(FS_ERR, tmpstr);
85 fclose(fingerprint_file); 114 writecf(FS_ERR, "Error: Fingerprint mismatch! Server cert updated?");
86
87 if (r) {
88 /* chomp */
89 char *nl = strchr(r, '\n');
90 if (nl) *nl = 0;
91
92 /* verify fingerprint matches stored version */
93 if (!strcmp(fingerprint, old_fingerprint)) {
94 writecf(FS_SERV, "[FINGERPRINT MATCH ]");
95 goto cleanup_happy;
96 }
97 }
98
99 snprintf(tmpstr, TMPSTRSIZE, "Error: Found pinned fingerprint (in %s) %s but expected %s", r ? old_fingerprint : "<FILE READ ERROR>", getstroption(CF_FINGERPRINT), fingerprint);
100 writecf(FS_ERR, tmpstr);
101 writecf(FS_ERR, "Error: Fingerprint mismatch! Server cert updated?");
102 free(fingerprint_file_path);
103 return 1;
104 } else
105 writecf(FS_ERR, "Warning: No pinned fingerprint found, writing the current one.");
106
107 fingerprint_file = fopen(fingerprint_file_path, "w");
108 if (!fingerprint_file) {
109 snprintf (tmpstr, TMPSTRSIZE, "Warning: Can't write fingerprint file, %s.", strerror(errno));
110 writecf(FS_ERR, tmpstr);
111 } else {
112 fputs(fingerprint, fingerprint_file);
113 fclose(fingerprint_file);
114 writecf(FS_SERV, "[FINGERPRINT STORED ]");
115 }
116cleanup_happy:
117 free(fingerprint_file_path); 115 free(fingerprint_file_path);
118 return 0; 116 return 1;
117 } else
118 writecf(FS_ERR,
119 "Warning: No pinned fingerprint found, writing the current one.");
120
121 fingerprint_file = fopen(fingerprint_file_path, "w");
122 if (!fingerprint_file) {
123 snprintf(tmpstr, TMPSTRSIZE, "Warning: Can't write fingerprint file, %s.",
124 strerror(errno));
125 writecf(FS_ERR, tmpstr);
126 } else {
127 fputs(fingerprint, fingerprint_file);
128 fclose(fingerprint_file);
129 writecf(FS_SERV, "[FINGERPRINT STORED ]");
130 }
131cleanup_happy:
132 free(fingerprint_file_path);
133 return 0;
119} 134}
120 135
121#if defined(TLS_LIB_OPENSSL) && defined(TLS_LIB_MBEDTLS) 136#if defined(TLS_LIB_OPENSSL) && defined(TLS_LIB_MBEDTLS)
122#error "Both TLS_LIB_OPENSSL and TLS_LIB_MBEDTLS are defined. Please select only one." 137#error \
138 "Both TLS_LIB_OPENSSL and TLS_LIB_MBEDTLS are defined. Please select only one."
123#endif 139#endif
124#if !defined(TLS_LIB_OPENSSL) && !defined(TLS_LIB_MBEDTLS) 140#if !defined(TLS_LIB_OPENSSL) && !defined(TLS_LIB_MBEDTLS)
125#error "Neither TLS_LIB_OPENSSL nor TLS_LIB_MBEDTLS are defined. Please select exactly one." 141#error \
142 "Neither TLS_LIB_OPENSSL nor TLS_LIB_MBEDTLS are defined. Please select exactly one."
126#endif 143#endif
127 144
128#ifdef TLS_LIB_OPENSSL 145#ifdef TLS_LIB_OPENSSL
129 146
130#include <openssl/err.h>
131#include <openssl/ssl.h>
132#include <openssl/bio.h> 147#include <openssl/bio.h>
148#include <openssl/conf.h>
149#include <openssl/err.h>
133#include <openssl/evp.h> 150#include <openssl/evp.h>
151#include <openssl/ssl.h>
134#include <openssl/x509.h> 152#include <openssl/x509.h>
135#include <openssl/x509v3.h> 153#include <openssl/x509v3.h>
136#include <openssl/conf.h>
137 154
138void vchat_tls_get_version_external() 155void vchat_tls_get_version_external() {
139{ 156 snprintf(tmpstr, sizeof(tmpstr), "OpenSSL %s with %s",
140 snprintf(tmpstr, sizeof(tmpstr), "OpenSSL %s with %s", SSLeay_version(SSLEAY_VERSION), SSLeay_version(SSLEAY_CFLAGS)); 157 SSLeay_version(SSLEAY_VERSION), SSLeay_version(SSLEAY_CFLAGS));
141 vchat_tls_version_external = strdup(tmpstr); 158 vchat_tls_version_external = strdup(tmpstr);
142} 159}
143 160
144void vc_init_x509store(vc_x509store_t *store) 161void vc_init_x509store(vc_x509store_t *store) {
145{ 162 static int sslinit;
146 static int sslinit; 163 if (!sslinit++) {
147 if (!sslinit++) { 164 SSL_library_init();
148 SSL_library_init (); 165 SSL_load_error_strings();
149 SSL_load_error_strings(); 166 }
150 } 167 memset(store, 0, sizeof(vc_x509store_t));
151 memset(store, 0, sizeof(vc_x509store_t));
152 168
153 /* We want to make verifying the peer the default */ 169 /* We want to make verifying the peer the default */
154 store->flags |= VC_X509S_SSL_VERIFY_PEER; 170 store->flags |= VC_X509S_SSL_VERIFY_PEER;
155} 171}
156 172
157/* connection BIO for openssl */ 173/* connection BIO for openssl */
158static BIO *server_conn = NULL; 174static BIO *server_conn = NULL;
159 175
160static SSL_CTX * vc_create_sslctx( vc_x509store_t *vc_store ); 176static SSL_CTX *vc_create_sslctx(vc_x509store_t *vc_store);
161static int vc_verify_callback(int, X509_STORE_CTX *); 177static int vc_verify_callback(int, X509_STORE_CTX *);
162static X509_STORE * vc_x509store_create(vc_x509store_t *); 178static X509_STORE *vc_x509store_create(vc_x509store_t *);
163
164static SSL_CTX * vc_create_sslctx( vc_x509store_t *vc_store )
165{
166 int flags = 0;
167
168 /* Explicitly use TLSv1 (or maybe later) */
169 SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
170 X509_STORE *store = vc_x509store_create(vc_store);
171
172 if (!ctx || !store) {
173 snprintf(tmpstr, sizeof(tmpstr), "CREATE CTX: %s",ERR_error_string (ERR_get_error (), NULL));
174 writecf(FS_ERR, tmpstr);
175 if (store)
176 X509_STORE_free(store);
177 if (ctx)
178 SSL_CTX_free(ctx);
179 return NULL;
180 }
181
182 SSL_CTX_set_cert_store(ctx, store);
183
184 /* Disable some insecure protocols explicitly */
185 SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
186 if (getstroption(CF_CIPHERSUITE))
187 SSL_CTX_set_cipher_list(ctx, getstroption(CF_CIPHERSUITE));
188 else
189 SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA");
190
191 SSL_CTX_set_verify_depth (ctx, getintoption(CF_VERIFYSSL));
192
193 if( !(vc_store->flags & VC_X509S_SSL_VERIFY_MASK) ) {
194 writecf(FS_DBG, tmpstr);
195 flags = SSL_VERIFY_NONE;
196 } else {
197 if(vc_store->flags & VC_X509S_SSL_VERIFY_PEER)
198 flags |= SSL_VERIFY_PEER;
199 if(vc_store->flags & VC_X509S_SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
200 flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
201 if(vc_store->flags & VC_X509S_SSL_VERIFY_CLIENT_ONCE)
202 flags |= SSL_VERIFY_CLIENT_ONCE;
203 }
204
205 SSL_CTX_set_verify(ctx, flags, vc_verify_callback);
206
207 if(vc_store->flags & VC_X509S_USE_CERTIFICATE) {
208 int r = 0;
209 if(vc_store->certfile)
210 SSL_CTX_use_certificate_chain_file(ctx, vc_store->certfile);
211 179
212 SSL_CTX_set_default_passwd_cb(ctx, vc_store->askpass_callback); 180static SSL_CTX *vc_create_sslctx(vc_x509store_t *vc_store) {
181 int flags = 0;
213 182
214 if(vc_store->keyfile) 183 /* Explicitly use TLSv1 (or maybe later) */
215 r=SSL_CTX_use_PrivateKey_file(ctx, vc_store->keyfile, 184 SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
216 SSL_FILETYPE_PEM); 185 X509_STORE *store = vc_x509store_create(vc_store);
217 186
218 if( r!=1 || !SSL_CTX_check_private_key(ctx)) { 187 if (!ctx || !store) {
219 snprintf(tmpstr, sizeof(tmpstr), "CREATE CTX: Load private key failed"); 188 snprintf(tmpstr, sizeof(tmpstr), "CREATE CTX: %s",
220 writecf(FS_ERR, tmpstr); 189 ERR_error_string(ERR_get_error(), NULL));
221 SSL_CTX_free(ctx); 190 writecf(FS_ERR, tmpstr);
222 return NULL; 191 if (store)
223 } 192 X509_STORE_free(store);
193 if (ctx)
194 SSL_CTX_free(ctx);
195 return NULL;
196 }
197
198 SSL_CTX_set_cert_store(ctx, store);
199
200 /* Disable some insecure protocols explicitly */
201 SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
202 if (getstroption(CF_CIPHERSUITE))
203 SSL_CTX_set_cipher_list(ctx, getstroption(CF_CIPHERSUITE));
204 else
205 SSL_CTX_set_cipher_list(ctx,
206 "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA");
207
208 SSL_CTX_set_verify_depth(ctx, getintoption(CF_VERIFYSSL));
209
210 if (!(vc_store->flags & VC_X509S_SSL_VERIFY_MASK)) {
211 writecf(FS_DBG, tmpstr);
212 flags = SSL_VERIFY_NONE;
213 } else {
214 if (vc_store->flags & VC_X509S_SSL_VERIFY_PEER)
215 flags |= SSL_VERIFY_PEER;
216 if (vc_store->flags & VC_X509S_SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
217 flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
218 if (vc_store->flags & VC_X509S_SSL_VERIFY_CLIENT_ONCE)
219 flags |= SSL_VERIFY_CLIENT_ONCE;
220 }
221
222 SSL_CTX_set_verify(ctx, flags, vc_verify_callback);
223
224 if (vc_store->flags & VC_X509S_USE_CERTIFICATE) {
225 int r = 0;
226 if (vc_store->certfile)
227 SSL_CTX_use_certificate_chain_file(ctx, vc_store->certfile);
228
229 SSL_CTX_set_default_passwd_cb(ctx, vc_store->askpass_callback);
230
231 if (vc_store->keyfile)
232 r = SSL_CTX_use_PrivateKey_file(ctx, vc_store->keyfile, SSL_FILETYPE_PEM);
233
234 if (r != 1 || !SSL_CTX_check_private_key(ctx)) {
235 snprintf(tmpstr, sizeof(tmpstr), "CREATE CTX: Load private key failed");
236 writecf(FS_ERR, tmpstr);
237 SSL_CTX_free(ctx);
238 return NULL;
224 } 239 }
240 }
225 241
226 SSL_CTX_set_app_data(ctx, vc_store); 242 SSL_CTX_set_app_data(ctx, vc_store);
227 return(ctx); 243 return (ctx);
228} 244}
229 245
230int vc_tls_connect( int serverfd, vc_x509store_t *vc_store ) 246int vc_tls_connect(int serverfd, vc_x509store_t *vc_store) {
231{ 247 SSL_CTX *ctx = vc_create_sslctx(vc_store);
232 SSL_CTX * ctx = vc_create_sslctx(vc_store); 248 X509 *peercert = NULL;
233 X509 *peercert = NULL; 249 BIO *ssl_conn = NULL;
234 BIO *ssl_conn = NULL; 250 const SSL *sslp = NULL;
235 const SSL *sslp = NULL; 251 const SSL_CIPHER *cipher = NULL;
236 const SSL_CIPHER * cipher = NULL;
237
238 server_conn = BIO_new_socket( serverfd, 1 );
239
240 /* To display and check server fingerprint */
241 char fingerprint[EVP_MAX_MD_SIZE*4];
242 unsigned char fingerprint_bin[EVP_MAX_MD_SIZE];
243 unsigned int fingerprint_len;
244 252
245 char * fp = fingerprint; 253 server_conn = BIO_new_socket(serverfd, 1);
246 254
247 long j; 255 /* To display and check server fingerprint */
256 char fingerprint[EVP_MAX_MD_SIZE * 4];
257 unsigned char fingerprint_bin[EVP_MAX_MD_SIZE];
258 unsigned int fingerprint_len;
248 259
249 if( !ctx ) 260 char *fp = fingerprint;
250 goto all_errors;
251 261
252 ssl_conn = BIO_new_ssl(ctx, 1); 262 long j;
253 SSL_CTX_free(ctx);
254 263
255 if( !ssl_conn ) 264 if (!ctx)
256 goto ssl_error; 265 goto all_errors;
257 266
258 BIO_push( ssl_conn, server_conn ); 267 ssl_conn = BIO_new_ssl(ctx, 1);
259 server_conn = ssl_conn; 268 SSL_CTX_free(ctx);
260 fflush(stdout);
261 269
262 if( BIO_do_handshake( server_conn ) <= 0 ) 270 if (!ssl_conn)
263 goto ssl_error; 271 goto ssl_error;
264 272
265 /* Show information about cipher used */ 273 BIO_push(ssl_conn, server_conn);
266 /* Get cipher object */ 274 server_conn = ssl_conn;
267 BIO_get_ssl(ssl_conn, &sslp); 275 fflush(stdout);
268 if (!sslp)
269 goto ssl_error;
270 276
271 cipher = SSL_get_current_cipher(sslp); 277 if (BIO_do_handshake(server_conn) <= 0)
272 if (cipher) { 278 goto ssl_error;
273 char cipher_desc[TMPSTRSIZE];
274 snprintf(tmpstr, TMPSTRSIZE, "[SSL CIPHER ] %s", SSL_CIPHER_description(cipher, cipher_desc, TMPSTRSIZE));
275 writecf(FS_SERV, tmpstr);
276 } else {
277 snprintf(tmpstr, TMPSTRSIZE, "[SSL ERROR ] Cipher not known / SSL object can't be queried!");
278 writecf(FS_ERR, tmpstr);
279 }
280 279
281 /* Accept being connected, _if_ verification passed */ 280 /* Show information about cipher used */
282 peercert = SSL_get_peer_certificate(sslp); 281 /* Get cipher object */
283 if (!peercert) 282 BIO_get_ssl(ssl_conn, &sslp);
284 goto ssl_error; 283 if (!sslp)
284 goto ssl_error;
285 285
286 /* show basic information about peer cert */ 286 cipher = SSL_get_current_cipher(sslp);
287 snprintf(tmpstr, TMPSTRSIZE, "[SSL SUBJECT ] %s", X509_NAME_oneline(X509_get_subject_name(peercert),0,0)); 287 if (cipher) {
288 writecf(FS_SERV, tmpstr); 288 char cipher_desc[TMPSTRSIZE];
289 snprintf(tmpstr, TMPSTRSIZE, "[SSL ISSUER ] %s", X509_NAME_oneline(X509_get_issuer_name(peercert),0,0)); 289 snprintf(tmpstr, TMPSTRSIZE, "[SSL CIPHER ] %s",
290 SSL_CIPHER_description(cipher, cipher_desc, TMPSTRSIZE));
290 writecf(FS_SERV, tmpstr); 291 writecf(FS_SERV, tmpstr);
292 } else {
293 snprintf(
294 tmpstr, TMPSTRSIZE,
295 "[SSL ERROR ] Cipher not known / SSL object can't be queried!");
296 writecf(FS_ERR, tmpstr);
297 }
298
299 /* Accept being connected, _if_ verification passed */
300 peercert = SSL_get_peer_certificate(sslp);
301 if (!peercert)
302 goto ssl_error;
303
304 /* show basic information about peer cert */
305 snprintf(tmpstr, TMPSTRSIZE, "[SSL SUBJECT ] %s",
306 X509_NAME_oneline(X509_get_subject_name(peercert), 0, 0));
307 writecf(FS_SERV, tmpstr);
308 snprintf(tmpstr, TMPSTRSIZE, "[SSL ISSUER ] %s",
309 X509_NAME_oneline(X509_get_issuer_name(peercert), 0, 0));
310 writecf(FS_SERV, tmpstr);
311
312 /* calculate fingerprint */
313 if (!X509_digest(peercert, EVP_sha1(), fingerprint_bin, &fingerprint_len))
314 goto ssl_error;
315
316 assert((fingerprint_len > 1) && (fingerprint_len <= EVP_MAX_MD_SIZE));
317 for (j = 0; j < (int)fingerprint_len; j++)
318 fp += sprintf(fp, "%02X:", fingerprint_bin[j]);
319 assert(fp > fingerprint);
320 fp[-1] = 0;
321 snprintf(tmpstr, TMPSTRSIZE, "[SSL FINGERPRINT ] %s (from server)",
322 fingerprint);
323 writecf(FS_SERV, tmpstr);
324
325 /* we don't need the peercert anymore */
326 X509_free(peercert);
327
328 if (getintoption(CF_PINFINGER) && verify_or_store_fingerprint(fingerprint))
329 return 1;
291 330
292 /* calculate fingerprint */ 331 /* If verify of x509 chain was requested, do the check here */
293 if (!X509_digest(peercert,EVP_sha1(),fingerprint_bin,&fingerprint_len)) 332 if (X509_V_OK == SSL_get_verify_result(sslp))
294 goto ssl_error; 333 return 0;
295
296 assert ( ( fingerprint_len > 1 ) && (fingerprint_len <= EVP_MAX_MD_SIZE ));
297 for (j=0; j<(int)fingerprint_len; j++)
298 fp += sprintf(fp, "%02X:", fingerprint_bin[j]);
299 assert ( fp > fingerprint );
300 fp[-1] = 0;
301 snprintf(tmpstr, TMPSTRSIZE, "[SSL FINGERPRINT ] %s (from server)", fingerprint);
302 writecf(FS_SERV, tmpstr);
303
304 /* we don't need the peercert anymore */
305 X509_free(peercert);
306
307 if (getintoption(CF_PINFINGER) && verify_or_store_fingerprint(fingerprint))
308 return 1;
309
310 /* If verify of x509 chain was requested, do the check here */
311 if (X509_V_OK == SSL_get_verify_result(sslp))
312 return 0;
313 334
314 if (getintoption(CF_IGNSSL)) { 335 if (getintoption(CF_IGNSSL)) {
315 writecf(FS_ERR, "[SSL VERIFY ERROR ] FAILURE IGNORED!!!"); 336 writecf(FS_ERR, "[SSL VERIFY ERROR ] FAILURE IGNORED!!!");
316 return 0; 337 return 0;
317 } 338 }
318 339
319ssl_error: 340ssl_error:
320 snprintf(tmpstr, TMPSTRSIZE, "[SSL CONNECT ERROR] %s", ERR_error_string (ERR_get_error (), NULL)); 341 snprintf(tmpstr, TMPSTRSIZE, "[SSL CONNECT ERROR] %s",
321 writecf(FS_ERR, tmpstr); 342 ERR_error_string(ERR_get_error(), NULL));
343 writecf(FS_ERR, tmpstr);
322all_errors: 344all_errors:
323 BIO_free_all( server_conn ); 345 BIO_free_all(server_conn);
324 server_conn = NULL; 346 server_conn = NULL;
325 return 1; 347 return 1;
326} 348}
327 349
328#define VC_STORE_ERR_EXIT(s) do { \ 350#define VC_STORE_ERR_EXIT(s) \
329 fprintf(stderr, "[E] SSL_STORE: %s\n", ERR_error_string (ERR_get_error (), NULL)); \ 351 do { \
330 if(s) X509_STORE_free(s); \ 352 fprintf(stderr, "[E] SSL_STORE: %s\n", \
331 return(0); \ 353 ERR_error_string(ERR_get_error(), NULL)); \
332} while(0) 354 if (s) \
355 X509_STORE_free(s); \
356 return (0); \
357 } while (0)
333 358
334X509_STORE *vc_x509store_create(vc_x509store_t *vc_store) { 359X509_STORE *vc_x509store_create(vc_x509store_t *vc_store) {
335 X509_STORE *store = NULL; 360 X509_STORE *store = NULL;
336 X509_LOOKUP *lookup = NULL; 361 X509_LOOKUP *lookup = NULL;
337 362
338 store = X509_STORE_new(); 363 store = X509_STORE_new();
339 364
340 X509_STORE_set_verify_cb_func(store, vc_verify_callback); 365 X509_STORE_set_verify_cb_func(store, vc_verify_callback);
341 366
342 if( !(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) ) 367 if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())))
343 VC_STORE_ERR_EXIT(store); 368 VC_STORE_ERR_EXIT(store);
344 369
345 if (!vc_store->cafile) { 370 if (!vc_store->cafile) {
346 if( !(vc_store->flags & VC_X509S_USE_CAFILE) ) 371 if (!(vc_store->flags & VC_X509S_USE_CAFILE))
347 X509_LOOKUP_load_file(lookup, 0, X509_FILETYPE_DEFAULT); 372 X509_LOOKUP_load_file(lookup, 0, X509_FILETYPE_DEFAULT);
348 } else if( !X509_LOOKUP_load_file(lookup, vc_store->cafile, 373 } else if (!X509_LOOKUP_load_file(lookup, vc_store->cafile,
349 X509_FILETYPE_PEM) ) 374 X509_FILETYPE_PEM))
350 VC_STORE_ERR_EXIT(store); 375 VC_STORE_ERR_EXIT(store);
351 376
352 if (vc_store->crlfile) { 377 if (vc_store->crlfile) {
353 if( !X509_load_crl_file(lookup, vc_store->crlfile, 378 if (!X509_load_crl_file(lookup, vc_store->crlfile, X509_FILETYPE_PEM))
354 X509_FILETYPE_PEM) ) 379 VC_STORE_ERR_EXIT(store);
355 VC_STORE_ERR_EXIT(store);
356 380
357 X509_STORE_set_flags( store, 381 X509_STORE_set_flags(store,
358 X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL ); 382 X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
359 } 383 }
360 384
361 if ( !(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir())) ) 385 if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir())))
362 VC_STORE_ERR_EXIT(store); 386 VC_STORE_ERR_EXIT(store);
363 387
364 if ( !vc_store->capath ) { 388 if (!vc_store->capath) {
365 if( !(vc_store->flags & VC_X509S_USE_CAPATH) ) 389 if (!(vc_store->flags & VC_X509S_USE_CAPATH))
366 X509_LOOKUP_add_dir(lookup, 0, X509_FILETYPE_DEFAULT); 390 X509_LOOKUP_add_dir(lookup, 0, X509_FILETYPE_DEFAULT);
367 } else if( !X509_LOOKUP_add_dir(lookup, vc_store->capath, 391 } else if (!X509_LOOKUP_add_dir(lookup, vc_store->capath, X509_FILETYPE_PEM))
368 X509_FILETYPE_PEM) ) 392 VC_STORE_ERR_EXIT(store);
369 VC_STORE_ERR_EXIT(store);
370 393
371 return(store); 394 return (store);
372} 395}
373 396
374int vc_verify_callback(int ok, X509_STORE_CTX *store) { 397int vc_verify_callback(int ok, X509_STORE_CTX *store) {
375 if(!ok) { 398 if (!ok) {
376 snprintf(tmpstr, TMPSTRSIZE, "[SSL VERIFY ERROR ] %s", 399 snprintf(tmpstr, TMPSTRSIZE, "[SSL VERIFY ERROR ] %s",
377 X509_verify_cert_error_string(X509_STORE_CTX_get_error(store))); 400 X509_verify_cert_error_string(X509_STORE_CTX_get_error(store)));
378 writecf(FS_ERR, tmpstr); 401 writecf(FS_ERR, tmpstr);
379 } 402 }
380 return (ok | getintoption(CF_IGNSSL)); 403 return (ok | getintoption(CF_IGNSSL));
381} 404}
382 405
383ssize_t vc_tls_sendmessage(const void *buf, size_t size) { 406ssize_t vc_tls_sendmessage(const void *buf, size_t size) {
384 return BIO_write(server_conn, buf, size); 407 return BIO_write(server_conn, buf, size);
385} 408}
386 409
387ssize_t vc_tls_receivemessage(void *buf, size_t size) { 410ssize_t vc_tls_receivemessage(void *buf, size_t size) {
388 ssize_t received = (ssize_t)BIO_read (server_conn, buf, size); 411 ssize_t received = (ssize_t)BIO_read(server_conn, buf, size);
389 if (received != 0) 412 if (received != 0)
390 return received; 413 return received;
391 if (BIO_should_retry(server_conn)) 414 if (BIO_should_retry(server_conn))
392 return -2; 415 return -2;
393 return 0; 416 return 0;
394} 417}
395 418
396void vc_tls_cleanup() { 419void vc_tls_cleanup() {
397 BIO_free_all( server_conn ); 420 BIO_free_all(server_conn);
398 server_conn = NULL; 421 server_conn = NULL;
399} 422}
400#endif 423#endif
401 424
402#ifdef TLS_LIB_MBEDTLS 425#ifdef TLS_LIB_MBEDTLS
403 426
427#include "mbedtls/error.h"
428#include "mbedtls/version.h"
429#include <mbedtls/ctr_drbg.h>
430#include <mbedtls/debug.h>
431#include <mbedtls/entropy.h>
432#include <mbedtls/md.h>
404#include <mbedtls/net_sockets.h> 433#include <mbedtls/net_sockets.h>
434#include <mbedtls/pk.h>
405#include <mbedtls/ssl.h> 435#include <mbedtls/ssl.h>
406#include <mbedtls/entropy.h>
407#include <mbedtls/ctr_drbg.h>
408#include <mbedtls/x509.h> 436#include <mbedtls/x509.h>
409#include <mbedtls/pk.h>
410#include <mbedtls/md.h>
411#include <mbedtls/debug.h>
412#include "mbedtls/error.h"
413#include "mbedtls/version.h"
414 437
415#include <sys/socket.h> 438#include <sys/socket.h>
416 439
417const char *DRBG_PERS = "mbed TLS vchat client"; 440const char *DRBG_PERS = "mbed TLS vchat client";
418#define MAX_SUITES 512 441#define MAX_SUITES 512
419typedef struct { 442typedef struct {
420 mbedtls_entropy_context _entropy; 443 mbedtls_entropy_context _entropy;
421 mbedtls_ctr_drbg_context _ctr_drbg; 444 mbedtls_ctr_drbg_context _ctr_drbg;
422 mbedtls_x509_crt _cacert; 445 mbedtls_x509_crt _cacert;
423 mbedtls_x509_crt _cert; 446 mbedtls_x509_crt _cert;
424 mbedtls_pk_context _key; 447 mbedtls_pk_context _key;
425 mbedtls_ssl_context _ssl; 448 mbedtls_ssl_context _ssl;
426 mbedtls_ssl_config _conf; 449 mbedtls_ssl_config _conf;
427 int ciphersuits[MAX_SUITES]; 450 int ciphersuits[MAX_SUITES];
428} mbedstate; 451} mbedstate;
429static mbedstate _mbedtls_state; 452static mbedstate _mbedtls_state;
430 453
431void vchat_tls_get_version_external() 454void vchat_tls_get_version_external() {
432{ 455 snprintf(tmpstr, sizeof(tmpstr), "%s", MBEDTLS_VERSION_STRING_FULL);
433 snprintf(tmpstr, sizeof(tmpstr), "%s", MBEDTLS_VERSION_STRING_FULL); 456 vchat_tls_version_external = strdup(tmpstr);
434 vchat_tls_version_external = strdup(tmpstr);
435} 457}
436 458
437static int static_tcp_recv(void *ctx, unsigned char *buf, size_t len ) { 459static int static_tcp_recv(void *ctx, unsigned char *buf, size_t len) {
438 return recv((int)(intptr_t)ctx, buf, len, 0); 460 return recv((int)(intptr_t)ctx, buf, len, 0);
439} 461}
440static int static_tcp_send(void *ctx, const unsigned char *buf, size_t len ) { 462static int static_tcp_send(void *ctx, const unsigned char *buf, size_t len) {
441 return send((int)(intptr_t)ctx, buf, len, 0); 463 return send((int)(intptr_t)ctx, buf, len, 0);
442} 464}
443static int map_openssl_suite(char *openssl_name); 465static int map_openssl_suite(char *openssl_name);
444void vc_init_x509store(vc_x509store_t *store) 466void vc_init_x509store(vc_x509store_t *store) {
445{ 467 static int sslinit;
446 static int sslinit; 468 if (!sslinit++) {
447 if (!sslinit++) { 469 mbedtls_entropy_init(&_mbedtls_state._entropy);
448 mbedtls_entropy_init(&_mbedtls_state._entropy); 470 mbedtls_ctr_drbg_init(&_mbedtls_state._ctr_drbg);
449 mbedtls_ctr_drbg_init(&_mbedtls_state._ctr_drbg); 471
450 472 mbedtls_ctr_drbg_seed(&_mbedtls_state._ctr_drbg, mbedtls_entropy_func,
451 mbedtls_ctr_drbg_seed(&_mbedtls_state._ctr_drbg, mbedtls_entropy_func, &_mbedtls_state._entropy, 473 &_mbedtls_state._entropy,
452 (const unsigned char *) DRBG_PERS, sizeof (DRBG_PERS)); 474 (const unsigned char *)DRBG_PERS, sizeof(DRBG_PERS));
453 } 475 }
454 memset(store, 0, sizeof(vc_x509store_t)); 476 memset(store, 0, sizeof(vc_x509store_t));
455 477
456 /* We want to make verifying the peer the default */ 478 /* We want to make verifying the peer the default */
457 store->flags |= VC_X509S_SSL_VERIFY_PEER; 479 store->flags |= VC_X509S_SSL_VERIFY_PEER;
458} 480}
459 481
460static void vc_tls_report_error(int error, char *message) { 482static void vc_tls_report_error(int error, char *message) {
461 size_t used = snprintf(tmpstr, sizeof(tmpstr), "Error: %s", message); 483 size_t used = snprintf(tmpstr, sizeof(tmpstr), "Error: %s", message);
462 mbedtls_strerror(error, tmpstr + used, sizeof(tmpstr) - used); 484 mbedtls_strerror(error, tmpstr + used, sizeof(tmpstr) - used);
463 writecf(FS_ERR, tmpstr); 485 writecf(FS_ERR, tmpstr);
464} 486}
465 487
466int vc_tls_connect( int serverfd, vc_x509store_t *vc_store ) 488int vc_tls_connect(int serverfd, vc_x509store_t *vc_store) {
467{ 489 /* Some aliases for shorter references */
468 /* Some aliases for shorter references */ 490 mbedstate *s = &_mbedtls_state;
469 mbedstate *s = &_mbedtls_state; 491 mbedtls_ssl_config *conf = &_mbedtls_state._conf;
470 mbedtls_ssl_config *conf = &_mbedtls_state._conf; 492 mbedtls_ssl_context *ssl = &_mbedtls_state._ssl;
471 mbedtls_ssl_context *ssl = &_mbedtls_state._ssl; 493 int ret, suitecount = 0;
472 int ret, suitecount = 0; 494 char fingerprint[128], *token;
473 char fingerprint[128], *token; 495 uint8_t digest[20];
474 uint8_t digest[20]; 496
475 497 mbedtls_x509_crt_init(&s->_cacert);
476 mbedtls_x509_crt_init(&s->_cacert); 498 mbedtls_x509_crt_init(&s->_cert);
477 mbedtls_x509_crt_init(&s->_cert); 499 mbedtls_pk_init(&s->_key);
478 mbedtls_pk_init(&s->_key); 500 mbedtls_ssl_init(ssl);
479 mbedtls_ssl_init(ssl); 501 mbedtls_ssl_config_init(conf);
480 mbedtls_ssl_config_init(conf); 502
481 503 writecf(FS_SERV, "[SOCKET CONNECTED ]");
482 writecf(FS_SERV, "[SOCKET CONNECTED ]"); 504 writecf(FS_SERV, "[UPGRADING TO TLS ]");
483 writecf(FS_SERV, "[UPGRADING TO TLS ]"); 505
484 506 if ((ret = mbedtls_ssl_config_defaults(conf, MBEDTLS_SSL_IS_CLIENT,
485 if ((ret = mbedtls_ssl_config_defaults(conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { 507 MBEDTLS_SSL_TRANSPORT_STREAM,
486 vc_tls_report_error(ret, "Can not initialise tls parameters, mbedtls reports: "); 508 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
487 return -1; 509 vc_tls_report_error(ret,
488 } 510 "Can not initialise tls parameters, mbedtls reports: ");
489 511 return -1;
490 /* TODO: Always verify peer */ 512 }
491 mbedtls_ssl_conf_authmode(conf, getintoption(CF_IGNSSL) ? MBEDTLS_SSL_VERIFY_OPTIONAL : MBEDTLS_SSL_VERIFY_REQUIRED); 513
492 mbedtls_ssl_conf_rng(conf, mbedtls_ctr_drbg_random, &s->_ctr_drbg); 514 /* TODO: Always verify peer */
493 515 mbedtls_ssl_conf_authmode(conf, getintoption(CF_IGNSSL)
494 char *ciphers = getstroption(CF_CIPHERSUITE); 516 ? MBEDTLS_SSL_VERIFY_OPTIONAL
495 if (!ciphers) 517 : MBEDTLS_SSL_VERIFY_REQUIRED);
496 ciphers = "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA"; 518 mbedtls_ssl_conf_rng(conf, mbedtls_ctr_drbg_random, &s->_ctr_drbg);
497 ciphers = strdup(ciphers); 519
498 for (token = strtok(ciphers, ":"); token && suitecount < MAX_SUITES - 1; token = strtok(NULL, ":")) { 520 char *ciphers = getstroption(CF_CIPHERSUITE);
499 int suite = mbedtls_ssl_get_ciphersuite_id(token); 521 if (!ciphers)
500 if (!suite) 522 ciphers = "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA";
501 suite = map_openssl_suite(token); 523 ciphers = strdup(ciphers);
502 if (suite) 524 for (token = strtok(ciphers, ":"); token && suitecount < MAX_SUITES - 1;
503 s->ciphersuits[suitecount++] = suite; 525 token = strtok(NULL, ":")) {
526 int suite = mbedtls_ssl_get_ciphersuite_id(token);
527 if (!suite)
528 suite = map_openssl_suite(token);
529 if (suite)
530 s->ciphersuits[suitecount++] = suite;
531 }
532 s->ciphersuits[suitecount++] = 0;
533 free(ciphers);
534
535 mbedtls_ssl_conf_ciphersuites(conf, s->ciphersuits);
536
537 if (vc_store->cafile) {
538 if ((ret = mbedtls_x509_crt_parse_file(&s->_cacert, vc_store->cafile)) !=
539 0) {
540 vc_tls_report_error(ret, "Can not load CA cert, mbedtls reports: ");
541 return -1;
504 } 542 }
505 s->ciphersuits[suitecount++] = 0; 543 mbedtls_ssl_conf_ca_chain(conf, &s->_cacert, NULL);
506 free(ciphers); 544 writecf(FS_SERV, "[CA CERT LOADED ]");
507 545 }
508 mbedtls_ssl_conf_ciphersuites(conf, s->ciphersuits); 546
509 547 if (vc_store->flags & VC_X509S_USE_CERTIFICATE) {
510 if (vc_store->cafile) { 548 char *password = NULL;
511 if ((ret = mbedtls_x509_crt_parse_file(&s->_cacert, vc_store->cafile)) != 0) { 549 char password_buf[1024];
512 vc_tls_report_error(ret, "Can not load CA cert, mbedtls reports: "); 550
513 return -1; 551 if ((ret = mbedtls_x509_crt_parse_file(&s->_cert, vc_store->certfile)) !=
514 } 552 0) {
515 mbedtls_ssl_conf_ca_chain(conf, &s->_cacert, NULL); 553 vc_tls_report_error(ret, "Can not load client cert, mbedtls reports: ");
516 writecf(FS_SERV, "[CA CERT LOADED ]"); 554 return -1;
517 } 555 }
556 writecf(FS_SERV, "[CLIENT CERT LOADED ]");
518 557
519 if (vc_store->flags & VC_X509S_USE_CERTIFICATE) { 558 while (1) {
520 char *password = NULL; 559 if ((ret = mbedtls_pk_parse_keyfile(&s->_key, vc_store->keyfile, password
521 char password_buf[1024];
522
523 if ((ret = mbedtls_x509_crt_parse_file(&s->_cert, vc_store->certfile)) != 0) {
524 vc_tls_report_error(ret, "Can not load client cert, mbedtls reports: ");
525 return -1;
526 }
527 writecf(FS_SERV, "[CLIENT CERT LOADED ]");
528
529 while (1) {
530 if ((ret = mbedtls_pk_parse_keyfile(&s->_key, vc_store->keyfile, password
531#if MBEDTLS_VERSION_MAJOR >= 3 560#if MBEDTLS_VERSION_MAJOR >= 3
532 , mbedtls_ctr_drbg_random, &s->_ctr_drbg 561 ,
562 mbedtls_ctr_drbg_random, &s->_ctr_drbg
533#endif 563#endif
534 )) == 0) 564 )) == 0)
535 break; 565 break;
536 if (ret != MBEDTLS_ERR_PK_PASSWORD_REQUIRED && ret != MBEDTLS_ERR_PK_PASSWORD_MISMATCH) { 566 if (ret != MBEDTLS_ERR_PK_PASSWORD_REQUIRED &&
537 vc_tls_report_error(ret, "Can not load client key, mbedtls reports: "); 567 ret != MBEDTLS_ERR_PK_PASSWORD_MISMATCH) {
538 return -1; 568 vc_tls_report_error(ret, "Can not load client key, mbedtls reports: ");
539 } 569 return -1;
540 if (ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH) 570 }
541 vc_tls_report_error(ret, "Wrong passphrase, mbedtls reports: "); 571 if (ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH)
542 vc_store->askpass_callback(password_buf, sizeof(password_buf), 0, NULL); 572 vc_tls_report_error(ret, "Wrong passphrase, mbedtls reports: ");
543 password = password_buf; 573 vc_store->askpass_callback(password_buf, sizeof(password_buf), 0, NULL);
544 } 574 password = password_buf;
545 memset_s(password_buf, sizeof(password_buf), 0, sizeof(password_buf)); 575 }
546 writecf(FS_SERV, "[CLIENT KEY LOADED ]"); 576 memset_s(password_buf, sizeof(password_buf), 0, sizeof(password_buf));
547 577 writecf(FS_SERV, "[CLIENT KEY LOADED ]");
548 578
549#if MBEDTLS_VERSION_MAJOR == 3 && MBEDTLS_VERSION_MINOR == 0 579#if MBEDTLS_VERSION_MAJOR == 3 && MBEDTLS_VERSION_MINOR == 0
550 mbedtls_pk_context *pubkey = &(s->_cert.MBEDTLS_PRIVATE(pk)); 580 mbedtls_pk_context *pubkey = &(s->_cert.MBEDTLS_PRIVATE(pk));
551#else 581#else
552 mbedtls_pk_context *pubkey = &(s->_cert.pk); 582 mbedtls_pk_context *pubkey = &(s->_cert.pk);
553#endif 583#endif
554 584
555 if ((ret = mbedtls_pk_check_pair(pubkey, &s->_key 585 if ((ret = mbedtls_pk_check_pair(pubkey, &s->_key
556#if MBEDTLS_VERSION_MAJOR >= 3 586#if MBEDTLS_VERSION_MAJOR >= 3
557 , mbedtls_ctr_drbg_random, &s->_ctr_drbg 587 ,
588 mbedtls_ctr_drbg_random, &s->_ctr_drbg
558#endif 589#endif
559 )) != 0) { 590 )) != 0) {
560 vc_tls_report_error(ret, "Cert and key mismatch, mbedtls reports: "); 591 vc_tls_report_error(ret, "Cert and key mismatch, mbedtls reports: ");
561 return 1; 592 return 1;
562 }
563
564 if ((ret = mbedtls_ssl_conf_own_cert(conf, &s->_cert, &s->_key)) != 0) {
565 vc_tls_report_error(ret, "Setting key and cert to tls session fails, mbedtls reports: ");
566 return -1;
567 }
568 } 593 }
569 594
570 /* Config constructed, pass to ssl */ 595 if ((ret = mbedtls_ssl_conf_own_cert(conf, &s->_cert, &s->_key)) != 0) {
571 /* Init ssl and config structs and configure ssl ctx */ 596 vc_tls_report_error(
572 if ((ret = mbedtls_ssl_setup(ssl, conf)) != 0) { 597 ret, "Setting key and cert to tls session fails, mbedtls reports: ");
573 vc_tls_report_error(ret, "Can not configure parameters on tls context, mbedtls reports: "); 598 return -1;
574 return -1; 599 }
600 }
601
602 /* Config constructed, pass to ssl */
603 /* Init ssl and config structs and configure ssl ctx */
604 if ((ret = mbedtls_ssl_setup(ssl, conf)) != 0) {
605 vc_tls_report_error(
606 ret, "Can not configure parameters on tls context, mbedtls reports: ");
607 return -1;
608 }
609 /* TODO: mbedtls_ssl_set_hostname(&ssl, SERVER_NAME) */
610
611 mbedtls_ssl_set_bio(ssl, (void *)(intptr_t)serverfd, static_tcp_send,
612 static_tcp_recv, NULL);
613
614 while ((ret = mbedtls_ssl_handshake(ssl)) != 0)
615 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
616 vc_tls_report_error(ret, "TLS handshake failed, mbedtls reports: ");
617 return -1;
575 } 618 }
576 /* TODO: mbedtls_ssl_set_hostname(&ssl, SERVER_NAME) */
577
578 mbedtls_ssl_set_bio(ssl, (void*)(intptr_t)serverfd, static_tcp_send, static_tcp_recv, NULL );
579 619
580 while ((ret = mbedtls_ssl_handshake(ssl)) != 0) 620 writecf(FS_SERV, "[TLS HANDSHAKE DONE ]");
581 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 621 snprintf(tmpstr, TMPSTRSIZE, "[TLS CIPHER SUITE ] %s",
582 vc_tls_report_error(ret, "TLS handshake failed, mbedtls reports: "); 622 mbedtls_ssl_get_ciphersuite(ssl));
583 return -1; 623 writecf(FS_SERV, tmpstr);
584 }
585 624
586 writecf(FS_SERV,"[TLS HANDSHAKE DONE ]"); 625 const mbedtls_x509_crt *peer_cert = mbedtls_ssl_get_peer_cert(ssl);
587 snprintf(tmpstr, TMPSTRSIZE, "[TLS CIPHER SUITE ] %s", mbedtls_ssl_get_ciphersuite(ssl)); 626 mbedtls_x509_crt_info(tmpstr, sizeof(tmpstr), "[TLS PEER INFO ] ",
588 writecf(FS_SERV, tmpstr); 627 peer_cert);
589 628
590 const mbedtls_x509_crt* peer_cert = mbedtls_ssl_get_peer_cert(ssl); 629 for (token = strtok(tmpstr, "\n"); token; token = strtok(NULL, "\n"))
591 mbedtls_x509_crt_info(tmpstr, sizeof(tmpstr), "[TLS PEER INFO ] ", peer_cert); 630 writecf(FS_SERV, token);
592
593 for (token = strtok(tmpstr, "\n"); token; token = strtok(NULL, "\n"))
594 writecf(FS_SERV, token);
595 631
596#if MBEDTLS_VERSION_MAJOR == 3 && MBEDTLS_VERSION_MINOR == 0 632#if MBEDTLS_VERSION_MAJOR == 3 && MBEDTLS_VERSION_MINOR == 0
597 const uint8_t * const rawcert_buf = peer_cert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p); 633 const uint8_t *const rawcert_buf =
598 size_t rawcert_len = peer_cert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len); 634 peer_cert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p);
635 size_t rawcert_len = peer_cert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len);
599#else 636#else
600 const uint8_t * const rawcert_buf = peer_cert->raw.p; 637 const uint8_t *const rawcert_buf = peer_cert->raw.p;
601 size_t rawcert_len = peer_cert->raw.len; 638 size_t rawcert_len = peer_cert->raw.len;
602#endif 639#endif
603 const mbedtls_md_info_t *mdinfo = mbedtls_md_info_from_string("SHA1"); 640 const mbedtls_md_info_t *mdinfo = mbedtls_md_info_from_string("SHA1");
604 if (mdinfo) { 641 if (mdinfo) {
605 mbedtls_md(mdinfo, rawcert_buf, rawcert_len, digest); 642 mbedtls_md(mdinfo, rawcert_buf, rawcert_len, digest);
606 643
607 char *fp = fingerprint; 644 char *fp = fingerprint;
608 for (int j=0; j<mbedtls_md_get_size(mdinfo); j++) 645 for (int j = 0; j < mbedtls_md_get_size(mdinfo); j++)
609 fp += sprintf(fp, "%02X:", digest[j]); 646 fp += sprintf(fp, "%02X:", digest[j]);
610 assert ( fp > fingerprint ); 647 assert(fp > fingerprint);
611 fp[-1] = 0; 648 fp[-1] = 0;
612 snprintf(tmpstr, TMPSTRSIZE, "[TLS FINGERPRINT ] %s (from server)", fingerprint); 649 snprintf(tmpstr, TMPSTRSIZE, "[TLS FINGERPRINT ] %s (from server)",
613 writecf(FS_SERV, tmpstr); 650 fingerprint);
614 651 writecf(FS_SERV, tmpstr);
615 if (getintoption(CF_PINFINGER) && verify_or_store_fingerprint(fingerprint))
616 return 1;
617 } else {
618 writecf(FS_ERR, "Warning: Unable to load SHA-1 md");
619 if (getintoption(CF_PINFINGER)) {
620 writecf(FS_ERR, "ERROR: Can not compute fingerprint, but pinning check is required");
621 return 1;
622 }
623 }
624 652
625 ret = mbedtls_ssl_get_verify_result(ssl); 653 if (getintoption(CF_PINFINGER) && verify_or_store_fingerprint(fingerprint))
626 switch (ret) { 654 return 1;
627 case 0: 655 } else {
628 writecf(FS_SERV, "[TLS HANDSHAKE OK ]"); 656 writecf(FS_ERR, "Warning: Unable to load SHA-1 md");
629 break; 657 if (getintoption(CF_PINFINGER)) {
630 case -1: 658 writecf(
631 writecf(FS_ERR, "Error: TLS verify for an unknown reason"); 659 FS_ERR,
632 return -1; 660 "ERROR: Can not compute fingerprint, but pinning check is required");
633 case MBEDTLS_X509_BADCERT_SKIP_VERIFY: 661 return 1;
634 case MBEDTLS_X509_BADCERT_NOT_TRUSTED:
635 if (getintoption(CF_IGNSSL) || !getintoption(CF_VERIFYSSL))
636 return 0;
637 vc_tls_report_error(ret, "TLS verify failed, mbedtls reports: ");
638 return -1;
639 default:
640 vc_tls_report_error(ret, "TLS verify failed, mbedtls reports: ");
641 return -1;
642 } 662 }
643 663 }
644 return 0; 664
665 ret = mbedtls_ssl_get_verify_result(ssl);
666 switch (ret) {
667 case 0:
668 writecf(FS_SERV, "[TLS HANDSHAKE OK ]");
669 break;
670 case -1:
671 writecf(FS_ERR, "Error: TLS verify for an unknown reason");
672 return -1;
673 case MBEDTLS_X509_BADCERT_SKIP_VERIFY:
674 case MBEDTLS_X509_BADCERT_NOT_TRUSTED:
675 if (getintoption(CF_IGNSSL) || !getintoption(CF_VERIFYSSL))
676 return 0;
677 vc_tls_report_error(ret, "TLS verify failed, mbedtls reports: ");
678 return -1;
679 default:
680 vc_tls_report_error(ret, "TLS verify failed, mbedtls reports: ");
681 return -1;
682 }
683
684 return 0;
645} 685}
646 686
647ssize_t vc_tls_sendmessage(const void *buf, size_t size) { 687ssize_t vc_tls_sendmessage(const void *buf, size_t size) {
648 return mbedtls_ssl_write( &_mbedtls_state._ssl, buf, size); 688 return mbedtls_ssl_write(&_mbedtls_state._ssl, buf, size);
649} 689}
650 690
651ssize_t vc_tls_receivemessage(void *buf, size_t size) { 691ssize_t vc_tls_receivemessage(void *buf, size_t size) {
652 ssize_t received = (ssize_t)mbedtls_ssl_read (&_mbedtls_state._ssl, buf, size); 692 ssize_t received = (ssize_t)mbedtls_ssl_read(&_mbedtls_state._ssl, buf, size);
653 switch (received) { 693 switch (received) {
654 case MBEDTLS_ERR_SSL_WANT_READ: 694 case MBEDTLS_ERR_SSL_WANT_READ:
655 case MBEDTLS_ERR_SSL_WANT_WRITE: 695 case MBEDTLS_ERR_SSL_WANT_WRITE:
656 return -2; 696 return -2;
657 case MBEDTLS_ERR_SSL_CONN_EOF: 697 case MBEDTLS_ERR_SSL_CONN_EOF:
658 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: 698 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
659 case 0: 699 case 0:
660 return 0; 700 return 0;
661 default: 701 default:
662 if (received > 0) 702 if (received > 0)
663 return received; 703 return received;
664 return -1; 704 return -1;
665 } 705 }
666} 706}
667 707
668void vc_tls_cleanup() { 708void vc_tls_cleanup() {
669 mbedtls_x509_crt_free(&_mbedtls_state._cacert); 709 mbedtls_x509_crt_free(&_mbedtls_state._cacert);
670 mbedtls_x509_crt_free(&_mbedtls_state._cert); 710 mbedtls_x509_crt_free(&_mbedtls_state._cert);
671 mbedtls_pk_free(&_mbedtls_state._key); 711 mbedtls_pk_free(&_mbedtls_state._key);
672 mbedtls_ssl_free(&_mbedtls_state._ssl ); 712 mbedtls_ssl_free(&_mbedtls_state._ssl);
673 mbedtls_ssl_config_free(&_mbedtls_state._conf ); 713 mbedtls_ssl_config_free(&_mbedtls_state._conf);
674 mbedtls_ctr_drbg_free(&_mbedtls_state._ctr_drbg ); 714 mbedtls_ctr_drbg_free(&_mbedtls_state._ctr_drbg);
675} 715}
676 716
677/* Taken from https://testssl.sh/openssl-iana.mapping.html */ 717/* Taken from https://testssl.sh/openssl-iana.mapping.html */
@@ -924,12 +964,12 @@ NULL
924}; 964};
925// fprintf(stderr, "SUCCESS: %s => %s => %d\n\n", xlate_openssl[i], xlate_openssl[i+1], mbedtls_ssl_get_ciphersuite_id(xlate_openssl[i+1])); 965// fprintf(stderr, "SUCCESS: %s => %s => %d\n\n", xlate_openssl[i], xlate_openssl[i+1], mbedtls_ssl_get_ciphersuite_id(xlate_openssl[i+1]));
926static int map_openssl_suite(char *openssl_name) { 966static int map_openssl_suite(char *openssl_name) {
927 int i; 967 int i;
928 for (i=0; xlate_openssl[i]; i+=2) { 968 for (i = 0; xlate_openssl[i]; i += 2) {
929 if (!strcmp(xlate_openssl[i], openssl_name)) 969 if (!strcmp(xlate_openssl[i], openssl_name))
930 return mbedtls_ssl_get_ciphersuite_id(xlate_openssl[i+1]); 970 return mbedtls_ssl_get_ciphersuite_id(xlate_openssl[i + 1]);
931 } 971 }
932 return 0; 972 return 0;
933} 973}
934 974
935#endif 975#endif