1 /*
2 * SSL/TLS interface functions for wolfSSL TLS case
3 * Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "crypto.h"
13 #include "crypto/sha1.h"
14 #include "crypto/sha256.h"
15 #include "tls.h"
16
17 /* wolfSSL includes */
18 #include <wolfssl/options.h>
19 #include <wolfssl/ssl.h>
20 #include <wolfssl/error-ssl.h>
21 #include <wolfssl/wolfcrypt/asn.h>
22 #include <wolfssl/openssl/x509v3.h>
23
24 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
25 #define HAVE_AESGCM
26 #include <wolfssl/wolfcrypt/aes.h>
27 #endif
28
29 #ifdef CONFIG_FIPS
30 #include <wolfssl/wolfcrypt/fips_test.h>
31 #endif /* CONFIG_FIPS */
32
33 #if !defined(CONFIG_FIPS) && \
34 (defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || \
35 defined(EAP_SERVER_FAST))
36 #define WOLFSSL_NEED_EAP_FAST_PRF
37 #endif
38
39 #define SECRET_LEN 48
40 #define RAN_LEN 32
41 #define SESSION_TICKET_LEN 256
42
43 static int tls_ref_count = 0;
44
45 #define TLS_SESSION_EX_IDX (0)
46 #define TLS_SSL_CTX_CTX_EX_IDX (0)
47 #define TLS_SSL_CON_EX_IDX (0)
48
49
50 /* tls input data for wolfSSL Read Callback */
51 struct tls_in_data {
52 const struct wpabuf *in_data;
53 size_t consumed; /* how many bytes have we used already */
54 };
55
56 /* tls output data for wolfSSL Write Callback */
57 struct tls_out_data {
58 struct wpabuf *out_data;
59 };
60
61 struct tls_context {
62 void (*event_cb)(void *ctx, enum tls_event ev,
63 union tls_event_data *data);
64 void *cb_ctx;
65 int cert_in_cb;
66 char *ocsp_stapling_response;
67 unsigned int tls_session_lifetime;
68 /* This is alloc'ed and needs to be free'd */
69 char *check_cert_subject;
70 };
71
72 static struct tls_context *tls_global = NULL;
73
74 /* wolfssl tls_connection */
75 struct tls_connection {
76 const struct tls_context *context;
77 WOLFSSL *ssl;
78 int read_alerts;
79 int write_alerts;
80 int failed;
81 struct tls_in_data input;
82 struct tls_out_data output;
83 char *subject_match;
84 char *alt_subject_match;
85 char *suffix_match;
86 char *domain_match;
87 char *check_cert_subject;
88
89 u8 srv_cert_hash[32];
90
91 unsigned char client_random[RAN_LEN];
92 unsigned char server_random[RAN_LEN];
93 unsigned int flags;
94 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
95 tls_session_ticket_cb session_ticket_cb;
96 void *session_ticket_cb_ctx;
97 byte session_ticket[SESSION_TICKET_LEN];
98 #endif
99 unsigned int ca_cert_verify:1;
100 unsigned int cert_probe:1;
101 unsigned int server_cert_only:1;
102 unsigned int success_data:1;
103
104 WOLFSSL_X509 *peer_cert;
105 WOLFSSL_X509 *peer_issuer;
106 WOLFSSL_X509 *peer_issuer_issuer;
107 char *peer_subject; /* peer subject info for authenticated peer */
108 };
109
110
tls_context_new(const struct tls_config * conf)111 static struct tls_context * tls_context_new(const struct tls_config *conf)
112 {
113 struct tls_context *context = os_zalloc(sizeof(*context));
114
115 if (!context)
116 return NULL;
117
118 if (conf) {
119 context->event_cb = conf->event_cb;
120 context->cb_ctx = conf->cb_ctx;
121 context->cert_in_cb = conf->cert_in_cb;
122 }
123
124 return context;
125 }
126
127
tls_context_free(struct tls_context * context)128 static void tls_context_free(struct tls_context *context)
129 {
130 if (context) {
131 os_free(context->check_cert_subject);
132 os_free(context);
133 }
134 }
135
136
137 /* Helper to make sure the context stays const */
ssl_ctx_get_tls_context(void * ssl_ctx)138 static const struct tls_context * ssl_ctx_get_tls_context(void *ssl_ctx)
139 {
140 return wolfSSL_CTX_get_ex_data(ssl_ctx, TLS_SSL_CTX_CTX_EX_IDX);
141 }
142
143
wolfssl_reset_in_data(struct tls_in_data * in,const struct wpabuf * buf)144 static void wolfssl_reset_in_data(struct tls_in_data *in,
145 const struct wpabuf *buf)
146 {
147 /* old one not owned by us so don't free */
148 in->in_data = buf;
149 in->consumed = 0;
150 }
151
152
wolfssl_reset_out_data(struct tls_out_data * out)153 static void wolfssl_reset_out_data(struct tls_out_data *out)
154 {
155 /* old one not owned by us so don't free */
156 out->out_data = wpabuf_alloc_copy("", 0);
157 }
158
159
160 /* wolfSSL I/O Receive CallBack */
wolfssl_receive_cb(WOLFSSL * ssl,char * buf,int sz,void * ctx)161 static int wolfssl_receive_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
162 {
163 size_t get = sz;
164 struct tls_in_data *data = ctx;
165
166 if (!data)
167 return -1;
168
169 if (get > (wpabuf_len(data->in_data) - data->consumed))
170 get = wpabuf_len(data->in_data) - data->consumed;
171
172 os_memcpy(buf, wpabuf_head_u8(data->in_data) + data->consumed, get);
173 data->consumed += get;
174
175 if (get == 0)
176 return -2; /* WANT_READ */
177
178 return (int) get;
179 }
180
181
182 /* wolfSSL I/O Send CallBack */
wolfssl_send_cb(WOLFSSL * ssl,char * buf,int sz,void * ctx)183 static int wolfssl_send_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
184 {
185 struct wpabuf *tmp;
186 struct tls_out_data *data = ctx;
187
188 if (!data)
189 return -1;
190
191 wpa_printf(MSG_DEBUG, "SSL: adding %d bytes", sz);
192
193 tmp = wpabuf_alloc_copy(buf, sz);
194 if (!tmp)
195 return -1;
196 data->out_data = wpabuf_concat(data->out_data, tmp);
197 if (!data->out_data)
198 return -1;
199
200 return sz;
201 }
202
203
remove_session_cb(WOLFSSL_CTX * ctx,WOLFSSL_SESSION * sess)204 static void remove_session_cb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
205 {
206 struct wpabuf *buf;
207
208 buf = wolfSSL_SESSION_get_ex_data(sess, TLS_SESSION_EX_IDX);
209 if (!buf)
210 return;
211 wpa_printf(MSG_DEBUG,
212 "wolfSSL: Free application session data %p (sess %p)",
213 buf, sess);
214 wpabuf_free(buf);
215
216 wolfSSL_SESSION_set_ex_data(sess, TLS_SESSION_EX_IDX, NULL);
217 }
218
219
220 #if defined(CONFIG_FIPS) && defined(HAVE_FIPS)
wcFipsCb(int ok,int err,const char * hash)221 static void wcFipsCb(int ok, int err, const char *hash)
222 {
223 wpa_printf(MSG_INFO,
224 "wolfFIPS: wolfCrypt Fips error callback, ok = %d, err = %d",
225 ok, err);
226 wpa_printf(MSG_INFO, "wolfFIPS: message = %s", wc_GetErrorString(err));
227 wpa_printf(MSG_INFO, "wolfFIPS: hash = %s", hash);
228 if (err == IN_CORE_FIPS_E) {
229 wpa_printf(MSG_ERROR,
230 "wolfFIPS: In core integrity hash check failure, copy above hash");
231 wpa_printf(MSG_ERROR, "wolfFIPS: into verifyCore[] in fips_test.c and rebuild");
232 }
233 }
234 #endif /* CONFIG_FIPS && HAVE_FIPS */
235
236
237 #ifdef DEBUG_WOLFSSL
wolfSSL_logging_cb(const int log_level,const char * const log_message)238 static void wolfSSL_logging_cb(const int log_level,
239 const char * const log_message)
240 {
241 (void) log_level;
242 wpa_printf(MSG_DEBUG, "wolfSSL log:%s", log_message);
243 }
244 #endif /* DEBUG_WOLFSSL */
245
246
247 #define SUITEB_OLDTLS_192_CIPHERS "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384"
248 #define SUITEB_TLS13_192_CIPHERS "TLS13-AES256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256"
249 #define SUITEB_TLS_192_CIPHERS SUITEB_TLS13_192_CIPHERS ":" SUITEB_OLDTLS_192_CIPHERS
250
251 #define SUITEB_OLDTLS_128_CIPHERS "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:" SUITEB_OLDTLS_192_CIPHERS
252 #define SUITEB_TLS13_128_CIPHERS "TLS13-AES128-GCM-SHA256:" SUITEB_TLS13_192_CIPHERS
253 #define SUITEB_TLS_128_CIPHERS SUITEB_TLS13_128_CIPHERS ":" SUITEB_OLDTLS_128_CIPHERS
254
255 #define SUITEB_TLS_192_SIGALGS "ECDSA+SHA384:RSA-PSS+SHA384:RSA+SHA384"
256 #define SUITEB_TLS_128_SIGALGS "ECDSA+SHA256:RSA-PSS+SHA256:RSA+SHA256:" SUITEB_TLS_192_SIGALGS
257
258 #define SUITEB_TLS_192_CURVES "P-384:P-521"
259 #define SUITEB_TLS_128_CURVES "P-256:" SUITEB_TLS_192_CURVES
260
261 #define SUITEB_TLS_128_RSA_KEY_SZ 2048
262 #define SUITEB_TLS_192_RSA_KEY_SZ 3072
263
264 #define SUITEB_TLS_128_ECC_KEY_SZ 256
265 #define SUITEB_TLS_192_ECC_KEY_SZ 384
266
handle_ciphersuites(WOLFSSL_CTX * ssl_ctx,WOLFSSL * ssl,const char * openssl_ciphers,unsigned int flags)267 static int handle_ciphersuites(WOLFSSL_CTX *ssl_ctx, WOLFSSL *ssl,
268 const char *openssl_ciphers, unsigned int flags)
269 {
270 const char *ciphers = "DEFAULT:!aNULL";
271 const char *sigalgs = NULL;
272 const char *curves = NULL;
273 bool tls13 = !(flags & TLS_CONN_DISABLE_TLSv1_3);
274 unsigned int tls13_only_mask = TLS_CONN_DISABLE_TLSv1_2 |
275 TLS_CONN_DISABLE_TLSv1_1 | TLS_CONN_DISABLE_TLSv1_0;
276 bool old_tls_only = ((flags & tls13_only_mask) != tls13_only_mask) &&
277 !tls13;
278 bool tls13only = ((flags & tls13_only_mask) == tls13_only_mask) &&
279 !(flags & TLS_CONN_DISABLE_TLSv1_3);
280 short key_sz = 0;
281 short ecc_key_sz = 0;
282
283 if (openssl_ciphers) {
284 if (os_strcmp(openssl_ciphers, "SUITEB128") == 0) {
285 if (tls13only)
286 ciphers = SUITEB_TLS13_128_CIPHERS;
287 else if (old_tls_only)
288 ciphers = SUITEB_OLDTLS_128_CIPHERS;
289 else
290 ciphers = SUITEB_TLS_128_CIPHERS;
291 sigalgs = SUITEB_TLS_128_SIGALGS;
292 key_sz = SUITEB_TLS_128_RSA_KEY_SZ;
293 ecc_key_sz = SUITEB_TLS_128_ECC_KEY_SZ;
294 curves = SUITEB_TLS_128_CURVES;
295 } else if (os_strcmp(openssl_ciphers, "SUITEB192") == 0) {
296 if (tls13only)
297 ciphers = SUITEB_TLS13_192_CIPHERS;
298 else if (old_tls_only)
299 ciphers = SUITEB_OLDTLS_192_CIPHERS;
300 else
301 ciphers = SUITEB_TLS_192_CIPHERS;
302 sigalgs = SUITEB_TLS_192_SIGALGS;
303 key_sz = SUITEB_TLS_192_RSA_KEY_SZ;
304 ecc_key_sz = SUITEB_TLS_192_ECC_KEY_SZ;
305 curves = SUITEB_TLS_192_CURVES;
306 } else {
307 ciphers = openssl_ciphers;
308 }
309 } else if (flags & TLS_CONN_SUITEB) {
310 if (tls13only)
311 ciphers = SUITEB_TLS13_192_CIPHERS;
312 else if (old_tls_only)
313 ciphers = SUITEB_OLDTLS_192_CIPHERS;
314 else
315 ciphers = SUITEB_TLS_192_CIPHERS;
316 sigalgs = SUITEB_TLS_192_SIGALGS;
317 key_sz = SUITEB_TLS_192_RSA_KEY_SZ;
318 ecc_key_sz = SUITEB_TLS_192_ECC_KEY_SZ;
319 curves = SUITEB_TLS_192_CURVES;
320 }
321
322 wpa_printf(MSG_DEBUG, "wolfSSL: cipher suites for %s",
323 ssl_ctx ? "ctx" : "ssl");
324 wpa_printf(MSG_DEBUG, "wolfSSL: openssl_ciphers: %s",
325 openssl_ciphers ? openssl_ciphers : "N/A");
326 wpa_printf(MSG_DEBUG, "wolfSSL: cipher suites: %s",
327 ciphers ? ciphers : "N/A");
328 wpa_printf(MSG_DEBUG, "wolfSSL: sigalgs: %s",
329 sigalgs ? sigalgs : "N/A");
330 wpa_printf(MSG_DEBUG, "wolfSSL: key size: %d", key_sz);
331
332 if (ciphers) {
333 if ((ssl_ctx &&
334 wolfSSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) ||
335 (ssl && wolfSSL_set_cipher_list(ssl, ciphers) != 1)) {
336 wpa_printf(MSG_ERROR,
337 "wolfSSL: Failed to set cipher string '%s'",
338 ciphers);
339 return -1;
340 }
341 }
342
343 if (sigalgs) {
344 if ((ssl_ctx &&
345 wolfSSL_CTX_set1_sigalgs_list(ssl_ctx, sigalgs) != 1) ||
346 (ssl && wolfSSL_set1_sigalgs_list(ssl, sigalgs) != 1)) {
347 wpa_printf(MSG_ERROR,
348 "wolfSSL: Failed to set sigalgs '%s'",
349 sigalgs);
350 return -1;
351 }
352 }
353
354 if (key_sz) {
355 if ((ssl_ctx &&
356 wolfSSL_CTX_SetMinRsaKey_Sz(ssl_ctx, key_sz) != 1) ||
357 (ssl && wolfSSL_SetMinRsaKey_Sz(ssl, key_sz) != 1) ||
358 (ssl_ctx &&
359 wolfSSL_CTX_SetMinDhKey_Sz(ssl_ctx, key_sz) != 1) ||
360 (ssl && wolfSSL_SetMinDhKey_Sz(ssl, key_sz) != 1)) {
361 wpa_printf(MSG_ERROR,
362 "wolfSSL: Failed to set min key size");
363 return -1;
364 }
365 }
366
367 if (ecc_key_sz) {
368 if ((ssl_ctx &&
369 wolfSSL_CTX_SetMinEccKey_Sz(ssl_ctx, ecc_key_sz) != 1) ||
370 (ssl && wolfSSL_SetMinEccKey_Sz(ssl, ecc_key_sz) != 1) ||
371 (ssl_ctx &&
372 wolfSSL_CTX_SetTmpEC_DHE_Sz(ssl_ctx,
373 ecc_key_sz / 8) != 1) ||
374 (ssl &&
375 wolfSSL_SetTmpEC_DHE_Sz(ssl, ecc_key_sz / 8) != 1)) {
376 wpa_printf(MSG_ERROR,
377 "wolfSSL: Failed to set min ecc key size");
378 return -1;
379 }
380 }
381
382 if (curves) {
383 if ((ssl_ctx &&
384 wolfSSL_CTX_set1_curves_list(ssl_ctx, curves) != 1) ||
385 (ssl && wolfSSL_set1_curves_list(ssl, curves) != 1)) {
386 wpa_printf(MSG_ERROR, "wolfSSL: Failed to set curves");
387 return -1;
388 }
389 }
390
391 return 0;
392 }
393
394
tls_init(const struct tls_config * conf)395 void * tls_init(const struct tls_config *conf)
396 {
397 WOLFSSL_CTX *ssl_ctx;
398 struct tls_context *context;
399
400 #ifdef DEBUG_WOLFSSL
401 wolfSSL_SetLoggingCb(wolfSSL_logging_cb);
402 wolfSSL_Debugging_ON();
403 #endif /* DEBUG_WOLFSSL */
404
405 context = tls_context_new(conf);
406 if (!context)
407 return NULL;
408
409 if (tls_ref_count == 0) {
410 tls_global = context;
411
412 if (wolfSSL_Init() < 0)
413 return NULL;
414 #if defined(CONFIG_FIPS) && defined(HAVE_FIPS)
415 wolfCrypt_SetCb_fips(wcFipsCb);
416 #endif /* CONFIG_FIPS && HAVE_FIPS */
417 }
418
419 tls_ref_count++;
420
421 /* start as client */
422 ssl_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
423 if (!ssl_ctx) {
424 tls_ref_count--;
425 if (context != tls_global)
426 tls_context_free(context);
427 if (tls_ref_count == 0) {
428 tls_context_free(tls_global);
429 tls_global = NULL;
430 }
431 return NULL;
432 }
433 wolfSSL_SetIORecv(ssl_ctx, wolfssl_receive_cb);
434 wolfSSL_SetIOSend(ssl_ctx, wolfssl_send_cb);
435 context->tls_session_lifetime = conf->tls_session_lifetime;
436 wolfSSL_CTX_set_ex_data(ssl_ctx, TLS_SSL_CTX_CTX_EX_IDX, context);
437
438 if (conf->tls_session_lifetime > 0) {
439 wolfSSL_CTX_set_session_id_context(ssl_ctx,
440 (const unsigned char *)
441 "hostapd", 7);
442 wolfSSL_CTX_set_quiet_shutdown(ssl_ctx, 1);
443 wolfSSL_CTX_set_session_cache_mode(ssl_ctx,
444 WOLFSSL_SESS_CACHE_SERVER);
445 wolfSSL_CTX_set_timeout(ssl_ctx, conf->tls_session_lifetime);
446 wolfSSL_CTX_sess_set_remove_cb(ssl_ctx, remove_session_cb);
447 } else {
448 wolfSSL_CTX_set_session_cache_mode(ssl_ctx,
449 WOLFSSL_SESS_CACHE_OFF);
450 }
451
452 if (handle_ciphersuites(ssl_ctx, NULL, conf->openssl_ciphers,
453 conf ? conf->tls_flags : 0) != 0) {
454 wpa_printf(MSG_INFO, "wolfssl: Error setting ciphersuites");
455 tls_deinit(ssl_ctx);
456 return NULL;
457 }
458
459
460 return ssl_ctx;
461 }
462
463
tls_deinit(void * ssl_ctx)464 void tls_deinit(void *ssl_ctx)
465 {
466 struct tls_context *context;
467
468 /* Need to cast the const away to be able to free this */
469 context = (struct tls_context *) ssl_ctx_get_tls_context(ssl_ctx);
470 if (context != tls_global)
471 tls_context_free(context);
472
473 wolfSSL_CTX_free((WOLFSSL_CTX *) ssl_ctx);
474
475 tls_ref_count--;
476 if (tls_ref_count == 0) {
477 wolfSSL_Cleanup();
478 tls_context_free(tls_global);
479 tls_global = NULL;
480 }
481 }
482
483
tls_get_errors(void * tls_ctx)484 int tls_get_errors(void *tls_ctx)
485 {
486 #ifdef DEBUG_WOLFSSL
487 #if 0
488 unsigned long err;
489
490 err = wolfSSL_ERR_peek_last_error_line(NULL, NULL);
491 if (err != 0) {
492 wpa_printf(MSG_INFO, "TLS - SSL error: %s",
493 wolfSSL_ERR_error_string(err, NULL));
494 return 1;
495 }
496 #endif
497 #endif /* DEBUG_WOLFSSL */
498 return 0;
499 }
500
501
tls_connection_init(void * tls_ctx)502 struct tls_connection * tls_connection_init(void *tls_ctx)
503 {
504 WOLFSSL_CTX *ssl_ctx = tls_ctx;
505 struct tls_connection *conn;
506
507 wpa_printf(MSG_DEBUG, "SSL: connection init");
508
509 conn = os_zalloc(sizeof(*conn));
510 if (!conn)
511 return NULL;
512 conn->ssl = wolfSSL_new(ssl_ctx);
513 if (!conn->ssl) {
514 os_free(conn);
515 return NULL;
516 }
517
518 wolfSSL_SetIOReadCtx(conn->ssl, &conn->input);
519 wolfSSL_SetIOWriteCtx(conn->ssl, &conn->output);
520 wolfSSL_set_ex_data(conn->ssl, TLS_SSL_CON_EX_IDX, conn);
521 conn->context = ssl_ctx_get_tls_context(ssl_ctx);
522
523 /* Need randoms post-hanshake for EAP-FAST, export key and deriving
524 * session ID in EAP methods. */
525 wolfSSL_KeepArrays(conn->ssl);
526 wolfSSL_KeepHandshakeResources(conn->ssl);
527 wolfSSL_UseClientSuites(conn->ssl);
528
529 return conn;
530 }
531
532
tls_connection_deinit(void * tls_ctx,struct tls_connection * conn)533 void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
534 {
535 if (!conn)
536 return;
537
538 wpa_printf(MSG_DEBUG, "SSL: connection deinit");
539
540 /* parts */
541 wolfSSL_free(conn->ssl);
542 os_free(conn->subject_match);
543 os_free(conn->alt_subject_match);
544 os_free(conn->suffix_match);
545 os_free(conn->domain_match);
546 os_free(conn->peer_subject);
547 os_free(conn->check_cert_subject);
548
549 /* self */
550 os_free(conn);
551 }
552
553
tls_connection_established(void * tls_ctx,struct tls_connection * conn)554 int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
555 {
556 return conn ? wolfSSL_is_init_finished(conn->ssl) : 0;
557 }
558
559
tls_connection_peer_serial_num(void * tls_ctx,struct tls_connection * conn)560 char * tls_connection_peer_serial_num(void *tls_ctx,
561 struct tls_connection *conn)
562 {
563 /* TODO */
564 return NULL;
565 }
566
567
tls_connection_shutdown(void * tls_ctx,struct tls_connection * conn)568 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
569 {
570 WOLFSSL_SESSION *session;
571
572 if (!conn)
573 return -1;
574
575 wpa_printf(MSG_DEBUG, "SSL: connection shutdown");
576
577 /* Set quiet as OpenSSL does */
578 wolfSSL_set_quiet_shutdown(conn->ssl, 1);
579 wolfSSL_shutdown(conn->ssl);
580
581 session = wolfSSL_get1_session(conn->ssl);
582 if (wolfSSL_clear(conn->ssl) != 1) {
583 wolfSSL_SESSION_free(session);
584 return -1;
585 }
586 wolfSSL_set_session(conn->ssl, session);
587 wolfSSL_SESSION_free(session);
588
589 return 0;
590 }
591
592
tls_connection_set_subject_match(struct tls_connection * conn,const char * subject_match,const char * alt_subject_match,const char * suffix_match,const char * domain_match,const char * check_cert_subject)593 static int tls_connection_set_subject_match(struct tls_connection *conn,
594 const char *subject_match,
595 const char *alt_subject_match,
596 const char *suffix_match,
597 const char *domain_match,
598 const char *check_cert_subject)
599 {
600 os_free(conn->subject_match);
601 conn->subject_match = NULL;
602 if (subject_match) {
603 conn->subject_match = os_strdup(subject_match);
604 if (!conn->subject_match)
605 return -1;
606 }
607
608 os_free(conn->alt_subject_match);
609 conn->alt_subject_match = NULL;
610 if (alt_subject_match) {
611 conn->alt_subject_match = os_strdup(alt_subject_match);
612 if (!conn->alt_subject_match)
613 return -1;
614 }
615
616 os_free(conn->suffix_match);
617 conn->suffix_match = NULL;
618 if (suffix_match) {
619 conn->suffix_match = os_strdup(suffix_match);
620 if (!conn->suffix_match)
621 return -1;
622 }
623
624 os_free(conn->domain_match);
625 conn->domain_match = NULL;
626 if (domain_match) {
627 conn->domain_match = os_strdup(domain_match);
628 if (!conn->domain_match)
629 return -1;
630 }
631
632 os_free(conn->check_cert_subject);
633 conn->check_cert_subject = NULL;
634 if (check_cert_subject) {
635 conn->check_cert_subject = os_strdup(check_cert_subject);
636 if (!conn->check_cert_subject)
637 return -1;
638 }
639
640 return 0;
641 }
642
643
tls_connection_client_cert(struct tls_connection * conn,const char * client_cert,const u8 * client_cert_blob,size_t blob_len)644 static int tls_connection_client_cert(struct tls_connection *conn,
645 const char *client_cert,
646 const u8 *client_cert_blob,
647 size_t blob_len)
648 {
649 if (!client_cert && !client_cert_blob)
650 return 0;
651
652 if (client_cert_blob) {
653 if (wolfSSL_use_certificate_chain_buffer_format(
654 conn->ssl, client_cert_blob, blob_len,
655 SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
656 wpa_printf(MSG_INFO,
657 "SSL: use client cert DER blob failed");
658 if (wolfSSL_use_certificate_chain_buffer_format(
659 conn->ssl, client_cert_blob, blob_len,
660 SSL_FILETYPE_PEM) != SSL_SUCCESS) {
661 wpa_printf(MSG_INFO,
662 "SSL: use client cert PEM blob failed");
663 return -1;
664 }
665 }
666 wpa_printf(MSG_DEBUG, "SSL: use client cert blob OK");
667 return 0;
668 }
669
670 if (client_cert) {
671 if (wolfSSL_use_certificate_chain_file(
672 conn->ssl, client_cert) != SSL_SUCCESS) {
673 wpa_printf(MSG_INFO,
674 "SSL: use client cert PEM file failed");
675 if (wolfSSL_use_certificate_chain_file_format(
676 conn->ssl, client_cert,
677 SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
678 wpa_printf(MSG_INFO,
679 "SSL: use client cert DER file failed");
680 return -1;
681 }
682 }
683 wpa_printf(MSG_DEBUG, "SSL: use client cert file OK");
684 return 0;
685 }
686
687 return 0;
688 }
689
690
tls_passwd_cb(char * buf,int size,int rwflag,void * password)691 static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
692 {
693 if (!password)
694 return 0;
695 os_strlcpy(buf, (char *) password, size);
696 return os_strlen(buf);
697 }
698
699
tls_connection_private_key(void * tls_ctx,struct tls_connection * conn,const char * private_key,const char * private_key_passwd,const u8 * private_key_blob,size_t blob_len)700 static int tls_connection_private_key(void *tls_ctx,
701 struct tls_connection *conn,
702 const char *private_key,
703 const char *private_key_passwd,
704 const u8 *private_key_blob,
705 size_t blob_len)
706 {
707 WOLFSSL_CTX *ctx = tls_ctx;
708 char *passwd = NULL;
709 int ok = 0;
710
711 if (!private_key && !private_key_blob)
712 return 0;
713
714 if (private_key_passwd) {
715 passwd = os_strdup(private_key_passwd);
716 if (!passwd)
717 return -1;
718 }
719
720 wolfSSL_CTX_set_default_passwd_cb(ctx, tls_passwd_cb);
721 wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, passwd);
722
723 if (private_key_blob) {
724 if (wolfSSL_use_PrivateKey_buffer(conn->ssl,
725 private_key_blob, blob_len,
726 SSL_FILETYPE_ASN1) !=
727 SSL_SUCCESS) {
728 wpa_printf(MSG_INFO,
729 "SSL: use private DER blob failed");
730 if (wolfSSL_use_PrivateKey_buffer(
731 conn->ssl,
732 private_key_blob, blob_len,
733 SSL_FILETYPE_PEM) != SSL_SUCCESS) {
734 wpa_printf(MSG_INFO,
735 "SSL: use private PEM blob failed");
736 } else {
737 ok = 1;
738 }
739 } else {
740 ok = 1;
741 }
742 if (ok)
743 wpa_printf(MSG_DEBUG, "SSL: use private key blob OK");
744 }
745
746 if (!ok && private_key) {
747 if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
748 SSL_FILETYPE_PEM) !=
749 SSL_SUCCESS) {
750 wpa_printf(MSG_INFO,
751 "SSL: use private key PEM file failed");
752 if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
753 SSL_FILETYPE_ASN1) !=
754 SSL_SUCCESS) {
755 wpa_printf(MSG_INFO,
756 "SSL: use private key DER file failed");
757 } else {
758 ok = 1;
759 }
760 } else {
761 ok = 1;
762 }
763
764 if (ok)
765 wpa_printf(MSG_DEBUG, "SSL: use private key file OK");
766 }
767
768 wolfSSL_CTX_set_default_passwd_cb(ctx, NULL);
769 os_free(passwd);
770
771 if (!ok)
772 return -1;
773
774 return 0;
775 }
776
777
tls_match_alt_subject_component(WOLFSSL_X509 * cert,int type,const char * value,size_t len)778 static int tls_match_alt_subject_component(WOLFSSL_X509 *cert, int type,
779 const char *value, size_t len)
780 {
781 WOLFSSL_GENERAL_NAME *gen;
782 void *ext;
783 int found = 0;
784 int i;
785
786 ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
787
788 for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
789 gen = wolfSSL_sk_value(ext, i);
790 if (!gen || gen->type != type)
791 continue;
792 if ((size_t) wolfSSL_ASN1_STRING_length(gen->d.ia5) == len &&
793 os_memcmp(value, wolfSSL_ASN1_STRING_data(gen->d.ia5),
794 len) == 0)
795 found++;
796 }
797
798 wolfSSL_sk_GENERAL_NAME_free(ext);
799
800 return found;
801 }
802
803
tls_match_alt_subject(WOLFSSL_X509 * cert,const char * match)804 static int tls_match_alt_subject(WOLFSSL_X509 *cert, const char *match)
805 {
806 int type;
807 const char *pos, *end;
808 size_t len;
809
810 pos = match;
811 do {
812 if (os_strncmp(pos, "EMAIL:", 6) == 0) {
813 type = GEN_EMAIL;
814 pos += 6;
815 } else if (os_strncmp(pos, "DNS:", 4) == 0) {
816 type = GEN_DNS;
817 pos += 4;
818 } else if (os_strncmp(pos, "URI:", 4) == 0) {
819 type = GEN_URI;
820 pos += 4;
821 } else {
822 wpa_printf(MSG_INFO,
823 "TLS: Invalid altSubjectName match '%s'",
824 pos);
825 return 0;
826 }
827 end = os_strchr(pos, ';');
828 while (end) {
829 if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
830 os_strncmp(end + 1, "DNS:", 4) == 0 ||
831 os_strncmp(end + 1, "URI:", 4) == 0)
832 break;
833 end = os_strchr(end + 1, ';');
834 }
835 if (end)
836 len = end - pos;
837 else
838 len = os_strlen(pos);
839 if (tls_match_alt_subject_component(cert, type, pos, len) > 0)
840 return 1;
841 pos = end + 1;
842 } while (end);
843
844 return 0;
845 }
846
847
domain_suffix_match(const char * val,size_t len,const char * match,size_t match_len,int full)848 static int domain_suffix_match(const char *val, size_t len, const char *match,
849 size_t match_len, int full)
850 {
851 size_t i;
852
853 /* Check for embedded nuls that could mess up suffix matching */
854 for (i = 0; i < len; i++) {
855 if (val[i] == '\0') {
856 wpa_printf(MSG_DEBUG,
857 "TLS: Embedded null in a string - reject");
858 return 0;
859 }
860 }
861
862 if (match_len > len || (full && match_len != len))
863 return 0;
864
865 if (os_strncasecmp(val + len - match_len, match, match_len) != 0)
866 return 0; /* no match */
867
868 if (match_len == len)
869 return 1; /* exact match */
870
871 if (val[len - match_len - 1] == '.')
872 return 1; /* full label match completes suffix match */
873
874 wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match");
875 return 0;
876 }
877
878
tls_match_suffix_helper(WOLFSSL_X509 * cert,const char * match,size_t match_len,int full)879 static int tls_match_suffix_helper(WOLFSSL_X509 *cert, const char *match,
880 size_t match_len, int full)
881 {
882 WOLFSSL_GENERAL_NAME *gen;
883 void *ext;
884 int i;
885 int j;
886 int dns_name = 0;
887 WOLFSSL_X509_NAME *name;
888
889 wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s",
890 full ? "" : "suffix ", match);
891
892 ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
893
894 for (j = 0; ext && j < wolfSSL_sk_num(ext); j++) {
895 gen = wolfSSL_sk_value(ext, j);
896 if (!gen || gen->type != ASN_DNS_TYPE)
897 continue;
898 dns_name++;
899 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName",
900 wolfSSL_ASN1_STRING_data(gen->d.ia5),
901 wolfSSL_ASN1_STRING_length(gen->d.ia5));
902 if (domain_suffix_match(
903 (const char *) wolfSSL_ASN1_STRING_data(gen->d.ia5),
904 wolfSSL_ASN1_STRING_length(gen->d.ia5), match,
905 match_len, full) == 1) {
906 wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found",
907 full ? "Match" : "Suffix match");
908 wolfSSL_sk_ASN1_OBJECT_free(ext);
909 return 1;
910 }
911 }
912 wolfSSL_sk_GENERAL_NAME_free(ext);
913
914 if (dns_name) {
915 wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched");
916 return 0;
917 }
918
919 name = wolfSSL_X509_get_subject_name(cert);
920 i = -1;
921 for (;;) {
922 WOLFSSL_X509_NAME_ENTRY *e;
923 WOLFSSL_ASN1_STRING *cn;
924
925 i = wolfSSL_X509_NAME_get_index_by_NID(name, NID_commonName, i);
926 if (i == -1)
927 break;
928 e = wolfSSL_X509_NAME_get_entry(name, i);
929 if (!e)
930 continue;
931 cn = wolfSSL_X509_NAME_ENTRY_get_data(e);
932 if (!cn)
933 continue;
934 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName",
935 cn->data, cn->length);
936 if (domain_suffix_match(cn->data, cn->length,
937 match, match_len, full) == 1) {
938 wpa_printf(MSG_DEBUG, "TLS: %s in commonName found",
939 full ? "Match" : "Suffix match");
940 return 1;
941 }
942 }
943
944 wpa_printf(MSG_DEBUG, "TLS: No CommonName %smatch found",
945 full ? "" : "suffix ");
946 return 0;
947 }
948
949
tls_match_suffix(WOLFSSL_X509 * cert,const char * match,int full)950 static int tls_match_suffix(WOLFSSL_X509 *cert, const char *match, int full)
951 {
952 const char *token, *last = NULL;
953
954 /* Process each match alternative separately until a match is found */
955 while ((token = cstr_token(match, ";", &last))) {
956 if (tls_match_suffix_helper(cert, token, last - token, full))
957 return 1;
958 }
959
960 return 0;
961 }
962
963
wolfssl_tls_fail_reason(int err)964 static enum tls_fail_reason wolfssl_tls_fail_reason(int err)
965 {
966 switch (err) {
967 case X509_V_ERR_CERT_REVOKED:
968 return TLS_FAIL_REVOKED;
969 case ASN_BEFORE_DATE_E:
970 case X509_V_ERR_CERT_NOT_YET_VALID:
971 case X509_V_ERR_CRL_NOT_YET_VALID:
972 return TLS_FAIL_NOT_YET_VALID;
973 case ASN_AFTER_DATE_E:
974 case X509_V_ERR_CERT_HAS_EXPIRED:
975 case X509_V_ERR_CRL_HAS_EXPIRED:
976 return TLS_FAIL_EXPIRED;
977 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
978 case X509_V_ERR_UNABLE_TO_GET_CRL:
979 case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
980 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
981 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
982 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
983 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
984 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
985 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
986 case X509_V_ERR_INVALID_CA:
987 return TLS_FAIL_UNTRUSTED;
988 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
989 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
990 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
991 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
992 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
993 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
994 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
995 case X509_V_ERR_CERT_UNTRUSTED:
996 case X509_V_ERR_CERT_REJECTED:
997 return TLS_FAIL_BAD_CERTIFICATE;
998 case RSA_KEY_SIZE_E:
999 return TLS_FAIL_INSUFFICIENT_KEY_LEN;
1000 default:
1001 return TLS_FAIL_UNSPECIFIED;
1002 }
1003 }
1004
1005
wolfssl_tls_err_string(int err,const char * err_str)1006 static const char * wolfssl_tls_err_string(int err, const char *err_str)
1007 {
1008 switch (err) {
1009 case ASN_BEFORE_DATE_E:
1010 return "certificate is not yet valid";
1011 case ASN_AFTER_DATE_E:
1012 return "certificate has expired";
1013 default:
1014 return err_str;
1015 }
1016 }
1017
1018
1019 /**
1020 * match_dn_field - Match configuration DN field against Certificate DN field
1021 * @cert: Certificate
1022 * @nid: NID of DN field
1023 * @field: Field name
1024 * @value DN field value which is passed from configuration
1025 * e.g., if configuration have C=US and this argument will point to US.
1026 * Returns: 1 on success and 0 on failure
1027 */
match_dn_field(WOLFSSL_X509 * cert,int nid,const char * field,const char * value)1028 static int match_dn_field(WOLFSSL_X509 *cert, int nid, const char *field,
1029 const char *value)
1030 {
1031 int ret = 0;
1032 int len = os_strlen(value);
1033 char buf[256];
1034 /* Fetch value based on NID */
1035 int buf_len = wolfSSL_X509_NAME_get_text_by_NID(
1036 wolfSSL_X509_get_subject_name((WOLFSSL_X509 *) cert), nid,
1037 buf, sizeof(buf));
1038
1039 if (buf_len >= 0) {
1040 wpa_printf(MSG_DEBUG,
1041 "wolfSSL: Matching fields: '%s' '%s' '%s'", field,
1042 value, buf);
1043
1044 /* Check wildcard at the right end side */
1045 /* E.g., if OU=develop* mentioned in configuration, allow 'OU'
1046 * of the subject in the client certificate to start with
1047 * 'develop' */
1048 if (len > 0 && value[len - 1] == '*') {
1049 ret = buf_len >= len &&
1050 os_memcmp(buf, value, len - 1) == 0;
1051 } else {
1052 ret = os_strcmp(buf, value) == 0;
1053 }
1054 } else {
1055 wpa_printf(MSG_INFO,
1056 "wolfSSL: cert does not contain entry for '%s'",
1057 field);
1058 }
1059
1060 return ret;
1061 }
1062
1063
1064 #define DN_FIELD_LEN 20
1065
1066 /**
1067 * get_value_from_field - Get value from DN field
1068 * @cert: Certificate
1069 * @field_str: DN field string which is passed from configuration file (e.g.,
1070 * C=US)
1071 * @processed_nids: List of NIDs already processed
1072 * Returns: 1 on success and 0 on failure
1073 */
get_value_from_field(WOLFSSL_X509 * cert,char * field_str,int * processed_nids)1074 static int get_value_from_field(WOLFSSL_X509 *cert, char *field_str,
1075 int *processed_nids)
1076 {
1077 int nid, i;
1078 char *context = NULL, *name, *value;
1079
1080 if (os_strcmp(field_str, "*") == 0)
1081 return 1; /* wildcard matches everything */
1082
1083 name = str_token(field_str, "=", &context);
1084 if (!name)
1085 return 0;
1086
1087 nid = wolfSSL_OBJ_txt2nid(name);
1088 if (nid == NID_undef) {
1089 wpa_printf(MSG_ERROR,
1090 "wolfSSL: Unknown field '%s' in check_cert_subject",
1091 name);
1092 return 0;
1093 }
1094
1095 /* Check for duplicates */
1096 for (i = 0; processed_nids[i] != NID_undef && i < DN_FIELD_LEN; i++) {
1097 if (processed_nids[i] == nid) {
1098 wpa_printf(MSG_ERROR,
1099 "wolfSSL: No support for multiple DN's in check_cert_subject");
1100 return 0;
1101 }
1102 }
1103 if (i == DN_FIELD_LEN) {
1104 wpa_printf(MSG_ERROR,
1105 "wolfSSL: Only %d DN's are supported in check_cert_subject",
1106 DN_FIELD_LEN);
1107 return 0;
1108 }
1109 processed_nids[i] = nid;
1110
1111 value = str_token(field_str, "=", &context);
1112 if (!value) {
1113 wpa_printf(MSG_ERROR,
1114 "wolfSSL: Distinguished Name field '%s' value is not defined in check_cert_subject",
1115 name);
1116 return 0;
1117 }
1118
1119 return match_dn_field(cert, nid, name, value);
1120 }
1121
1122
1123 /**
1124 * tls_match_dn_field - Match subject DN field with check_cert_subject
1125 * @cert: Certificate
1126 * @match: check_cert_subject string
1127 * Returns: Return 1 on success and 0 on failure
1128 */
tls_match_dn_field(WOLFSSL_X509 * cert,const char * match)1129 static int tls_match_dn_field(WOLFSSL_X509 *cert, const char *match)
1130 {
1131 const char *token, *last = NULL;
1132 /* Maximum length of each DN field is 255 characters */
1133 char field[256];
1134 int processed_nids[DN_FIELD_LEN], i;
1135
1136 for (i = 0; i < DN_FIELD_LEN; i++)
1137 processed_nids[i] = NID_undef;
1138
1139 /* Process each '/' delimited field */
1140 while ((token = cstr_token(match, "/", &last))) {
1141 if (last - token >= (int) sizeof(field)) {
1142 wpa_printf(MSG_ERROR,
1143 "wolfSSL: Too long DN matching field value in '%s'",
1144 match);
1145 return 0;
1146 }
1147 os_memcpy(field, token, last - token);
1148 field[last - token] = '\0';
1149
1150 if (!get_value_from_field(cert, field, processed_nids)) {
1151 wpa_printf(MSG_INFO, "wolfSSL: No match for DN '%s'",
1152 field);
1153 return 0;
1154 }
1155 }
1156
1157 return 1;
1158 }
1159
1160
get_x509_cert(WOLFSSL_X509 * cert)1161 static struct wpabuf * get_x509_cert(WOLFSSL_X509 *cert)
1162 {
1163 struct wpabuf *buf = NULL;
1164 const u8 *data;
1165 int cert_len;
1166
1167 data = wolfSSL_X509_get_der(cert, &cert_len);
1168 if (data)
1169 buf = wpabuf_alloc_copy(data, cert_len);
1170
1171 return buf;
1172 }
1173
1174
wolfssl_tls_fail_event(struct tls_connection * conn,WOLFSSL_X509 * err_cert,int err,int depth,const char * subject,const char * err_str,enum tls_fail_reason reason)1175 static void wolfssl_tls_fail_event(struct tls_connection *conn,
1176 WOLFSSL_X509 *err_cert, int err, int depth,
1177 const char *subject, const char *err_str,
1178 enum tls_fail_reason reason)
1179 {
1180 union tls_event_data ev;
1181 struct wpabuf *cert = NULL;
1182 const struct tls_context *context = conn->context;
1183
1184 if (!context->event_cb)
1185 return;
1186
1187 cert = get_x509_cert(err_cert);
1188 os_memset(&ev, 0, sizeof(ev));
1189 ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ?
1190 reason : wolfssl_tls_fail_reason(err);
1191 ev.cert_fail.depth = depth;
1192 ev.cert_fail.subject = subject;
1193 ev.cert_fail.reason_txt = wolfssl_tls_err_string(err, err_str);
1194 ev.cert_fail.cert = cert;
1195 context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
1196 wpabuf_free(cert);
1197 }
1198
1199
wolfssl_cert_tod(X509 * cert)1200 static int wolfssl_cert_tod(X509 *cert)
1201 {
1202 WOLFSSL_STACK *ext;
1203 int i;
1204 char *buf;
1205 int tod = 0;
1206
1207 ext = wolfSSL_X509_get_ext_d2i(cert, CERT_POLICY_OID, NULL, NULL);
1208 if (!ext)
1209 return 0;
1210
1211 for (i = 0; i < wolfSSL_sk_num(ext); i++) {
1212 WOLFSSL_ASN1_OBJECT *policy;
1213
1214 policy = wolfSSL_sk_value(ext, i);
1215 if (!policy)
1216 continue;
1217
1218 buf = (char*)policy->obj;
1219 wpa_printf(MSG_DEBUG, "wolfSSL: Certificate Policy %s", buf);
1220 if (os_strcmp(buf, "1.3.6.1.4.1.40808.1.3.1") == 0)
1221 tod = 1; /* TOD-STRICT */
1222 else if (os_strcmp(buf, "1.3.6.1.4.1.40808.1.3.2") == 0 && !tod)
1223 tod = 2; /* TOD-TOFU */
1224 }
1225 wolfSSL_sk_pop_free(ext, NULL);
1226
1227 return tod;
1228 }
1229
1230
wolfssl_tls_cert_event(struct tls_connection * conn,WOLFSSL_X509 * err_cert,int depth,const char * subject)1231 static void wolfssl_tls_cert_event(struct tls_connection *conn,
1232 WOLFSSL_X509 *err_cert, int depth,
1233 const char *subject)
1234 {
1235 struct wpabuf *cert = NULL;
1236 union tls_event_data ev;
1237 const struct tls_context *context = conn->context;
1238 char *alt_subject[TLS_MAX_ALT_SUBJECT];
1239 int alt, num_alt_subject = 0;
1240 WOLFSSL_GENERAL_NAME *gen;
1241 void *ext;
1242 int i;
1243 #ifdef CONFIG_SHA256
1244 u8 hash[32];
1245 #endif /* CONFIG_SHA256 */
1246
1247 if (!context->event_cb)
1248 return;
1249
1250 os_memset(&ev, 0, sizeof(ev));
1251 if (conn->cert_probe || (conn->flags & TLS_CONN_EXT_CERT_CHECK) ||
1252 context->cert_in_cb) {
1253 cert = get_x509_cert(err_cert);
1254 ev.peer_cert.cert = cert;
1255 }
1256
1257 #ifdef CONFIG_SHA256
1258 if (cert) {
1259 const u8 *addr[1];
1260 size_t len[1];
1261
1262 addr[0] = wpabuf_head(cert);
1263 len[0] = wpabuf_len(cert);
1264 if (sha256_vector(1, addr, len, hash) == 0) {
1265 ev.peer_cert.hash = hash;
1266 ev.peer_cert.hash_len = sizeof(hash);
1267 }
1268 }
1269 #endif /* CONFIG_SHA256 */
1270
1271 ev.peer_cert.depth = depth;
1272 ev.peer_cert.subject = subject;
1273
1274 ext = wolfSSL_X509_get_ext_d2i(err_cert, ALT_NAMES_OID, NULL, NULL);
1275 for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
1276 char *pos;
1277
1278 if (num_alt_subject == TLS_MAX_ALT_SUBJECT)
1279 break;
1280 gen = wolfSSL_sk_value((void *) ext, i);
1281 if (!gen ||
1282 (gen->type != GEN_EMAIL &&
1283 gen->type != GEN_DNS &&
1284 gen->type != GEN_URI))
1285 continue;
1286
1287 pos = os_malloc(10 + wolfSSL_ASN1_STRING_length(gen->d.ia5) +
1288 1);
1289 if (!pos)
1290 break;
1291 alt_subject[num_alt_subject++] = pos;
1292
1293 switch (gen->type) {
1294 case GEN_EMAIL:
1295 os_memcpy(pos, "EMAIL:", 6);
1296 pos += 6;
1297 break;
1298 case GEN_DNS:
1299 os_memcpy(pos, "DNS:", 4);
1300 pos += 4;
1301 break;
1302 case GEN_URI:
1303 os_memcpy(pos, "URI:", 4);
1304 pos += 4;
1305 break;
1306 }
1307
1308 os_memcpy(pos, wolfSSL_ASN1_STRING_data(gen->d.ia5),
1309 wolfSSL_ASN1_STRING_length(gen->d.ia5));
1310 pos += wolfSSL_ASN1_STRING_length(gen->d.ia5);
1311 *pos = '\0';
1312 }
1313 wolfSSL_sk_GENERAL_NAME_free(ext);
1314
1315 for (alt = 0; alt < num_alt_subject; alt++)
1316 ev.peer_cert.altsubject[alt] = alt_subject[alt];
1317 ev.peer_cert.num_altsubject = num_alt_subject;
1318 ev.peer_cert.tod = wolfssl_cert_tod(err_cert);
1319
1320 context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
1321 wpabuf_free(cert);
1322 for (alt = 0; alt < num_alt_subject; alt++)
1323 os_free(alt_subject[alt]);
1324 }
1325
1326
tls_verify_cb(int preverify_ok,WOLFSSL_X509_STORE_CTX * x509_ctx)1327 static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx)
1328 {
1329 char buf[256];
1330 WOLFSSL_X509 *err_cert;
1331 int err, depth;
1332 WOLFSSL *ssl;
1333 struct tls_connection *conn;
1334 const struct tls_context *context;
1335 char *match, *altmatch, *suffix_match, *domain_match;
1336 const char *check_cert_subject;
1337 const char *err_str;
1338
1339 err_cert = wolfSSL_X509_STORE_CTX_get_current_cert(x509_ctx);
1340 if (!err_cert) {
1341 wpa_printf(MSG_DEBUG, "wolfSSL: No Cert");
1342 return 0;
1343 }
1344
1345 err = wolfSSL_X509_STORE_CTX_get_error(x509_ctx);
1346 depth = wolfSSL_X509_STORE_CTX_get_error_depth(x509_ctx);
1347 ssl = wolfSSL_X509_STORE_CTX_get_ex_data(
1348 x509_ctx, wolfSSL_get_ex_data_X509_STORE_CTX_idx());
1349 wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(err_cert), buf,
1350 sizeof(buf));
1351
1352 conn = wolfSSL_get_ex_data(ssl, TLS_SSL_CON_EX_IDX);
1353 if (!conn) {
1354 wpa_printf(MSG_DEBUG, "wolfSSL: No ex_data");
1355 return 0;
1356 }
1357
1358 if (depth == 0)
1359 conn->peer_cert = err_cert;
1360 else if (depth == 1)
1361 conn->peer_issuer = err_cert;
1362 else if (depth == 2)
1363 conn->peer_issuer_issuer = err_cert;
1364
1365 context = conn->context;
1366 match = conn->subject_match;
1367 altmatch = conn->alt_subject_match;
1368 suffix_match = conn->suffix_match;
1369 domain_match = conn->domain_match;
1370
1371 if (!preverify_ok && !conn->ca_cert_verify)
1372 preverify_ok = 1;
1373 if (!preverify_ok && depth > 0 && conn->server_cert_only)
1374 preverify_ok = 1;
1375 if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) &&
1376 (err == X509_V_ERR_CERT_HAS_EXPIRED ||
1377 err == ASN_AFTER_DATE_E || err == ASN_BEFORE_DATE_E ||
1378 err == X509_V_ERR_CERT_NOT_YET_VALID)) {
1379 wpa_printf(MSG_DEBUG,
1380 "wolfSSL: Ignore certificate validity time mismatch");
1381 preverify_ok = 1;
1382 }
1383
1384 err_str = wolfSSL_X509_verify_cert_error_string(err);
1385
1386 #ifdef CONFIG_SHA256
1387 /*
1388 * Do not require preverify_ok so we can explicity allow otherwise
1389 * invalid pinned server certificates.
1390 */
1391 if (depth == 0 && conn->server_cert_only) {
1392 struct wpabuf *cert;
1393
1394 cert = get_x509_cert(err_cert);
1395 if (!cert) {
1396 wpa_printf(MSG_DEBUG,
1397 "wolfSSL: Could not fetch server certificate data");
1398 preverify_ok = 0;
1399 } else {
1400 u8 hash[32];
1401 const u8 *addr[1];
1402 size_t len[1];
1403
1404 addr[0] = wpabuf_head(cert);
1405 len[0] = wpabuf_len(cert);
1406 if (sha256_vector(1, addr, len, hash) < 0 ||
1407 os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
1408 err_str = "Server certificate mismatch";
1409 err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
1410 preverify_ok = 0;
1411 } else if (!preverify_ok) {
1412 /*
1413 * Certificate matches pinned certificate, allow
1414 * regardless of other problems.
1415 */
1416 wpa_printf(MSG_DEBUG,
1417 "wolfSSL: Ignore validation issues for a pinned server certificate");
1418 preverify_ok = 1;
1419 }
1420 wpabuf_free(cert);
1421 }
1422 }
1423 #endif /* CONFIG_SHA256 */
1424
1425 wolfssl_tls_cert_event(conn, err_cert, depth, buf);
1426
1427 if (!preverify_ok) {
1428 wpa_printf(MSG_WARNING,
1429 "TLS: Certificate verification failed, error %d (%s) depth %d for '%s'",
1430 err, err_str, depth, buf);
1431 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1432 err_str, TLS_FAIL_UNSPECIFIED);
1433 return preverify_ok;
1434 }
1435
1436 wpa_printf(MSG_DEBUG,
1437 "TLS: %s - preverify_ok=%d err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
1438 __func__, preverify_ok, err, err_str,
1439 conn->ca_cert_verify, depth, buf);
1440 check_cert_subject = conn->check_cert_subject;
1441 if (!check_cert_subject)
1442 check_cert_subject = conn->context->check_cert_subject;
1443 if (check_cert_subject && depth == 0 &&
1444 !tls_match_dn_field(err_cert, check_cert_subject)) {
1445 wpa_printf(MSG_WARNING,
1446 "TLS: Subject '%s' did not match with '%s'",
1447 buf, check_cert_subject);
1448 preverify_ok = 0;
1449 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1450 "Distinguished Name",
1451 TLS_FAIL_DN_MISMATCH);
1452 } else if (depth == 0 && match && os_strstr(buf, match) == NULL) {
1453 wpa_printf(MSG_WARNING,
1454 "TLS: Subject '%s' did not match with '%s'",
1455 buf, match);
1456 preverify_ok = 0;
1457 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1458 "Subject mismatch",
1459 TLS_FAIL_SUBJECT_MISMATCH);
1460 } else if (depth == 0 && altmatch &&
1461 !tls_match_alt_subject(err_cert, altmatch)) {
1462 wpa_printf(MSG_WARNING,
1463 "TLS: altSubjectName match '%s' not found",
1464 altmatch);
1465 preverify_ok = 0;
1466 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1467 "AltSubject mismatch",
1468 TLS_FAIL_ALTSUBJECT_MISMATCH);
1469 } else if (depth == 0 && suffix_match &&
1470 !tls_match_suffix(err_cert, suffix_match, 0)) {
1471 wpa_printf(MSG_WARNING,
1472 "TLS: Domain suffix match '%s' not found",
1473 suffix_match);
1474 preverify_ok = 0;
1475 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1476 "Domain suffix mismatch",
1477 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
1478 } else if (depth == 0 && domain_match &&
1479 !tls_match_suffix(err_cert, domain_match, 1)) {
1480 wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found",
1481 domain_match);
1482 preverify_ok = 0;
1483 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1484 "Domain mismatch",
1485 TLS_FAIL_DOMAIN_MISMATCH);
1486 }
1487
1488 if (conn->cert_probe && preverify_ok && depth == 0) {
1489 wpa_printf(MSG_DEBUG,
1490 "wolfSSL: Reject server certificate on probe-only run");
1491 preverify_ok = 0;
1492 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1493 "Server certificate chain probe",
1494 TLS_FAIL_SERVER_CHAIN_PROBE);
1495 }
1496
1497 if (depth == 0 && preverify_ok && context->event_cb != NULL)
1498 context->event_cb(context->cb_ctx,
1499 TLS_CERT_CHAIN_SUCCESS, NULL);
1500
1501 if (depth == 0 && preverify_ok) {
1502 os_free(conn->peer_subject);
1503 conn->peer_subject = os_strdup(buf);
1504 }
1505
1506 return preverify_ok;
1507 }
1508
1509
tls_connection_ca_cert(void * tls_ctx,struct tls_connection * conn,const char * ca_cert,const u8 * ca_cert_blob,size_t blob_len,const char * ca_path)1510 static int tls_connection_ca_cert(void *tls_ctx, struct tls_connection *conn,
1511 const char *ca_cert,
1512 const u8 *ca_cert_blob, size_t blob_len,
1513 const char *ca_path)
1514 {
1515 WOLFSSL_CTX *ctx = tls_ctx;
1516
1517 wolfSSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
1518 conn->ca_cert_verify = 1;
1519
1520 if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) {
1521 wpa_printf(MSG_DEBUG,
1522 "wolfSSL: Probe for server certificate chain");
1523 conn->cert_probe = 1;
1524 conn->ca_cert_verify = 0;
1525 return 0;
1526 }
1527
1528 if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) {
1529 #ifdef CONFIG_SHA256
1530 const char *pos = ca_cert + 7;
1531
1532 if (os_strncmp(pos, "server/sha256/", 14) != 0) {
1533 wpa_printf(MSG_DEBUG,
1534 "wolfSSL: Unsupported ca_cert hash value '%s'",
1535 ca_cert);
1536 return -1;
1537 }
1538 pos += 14;
1539 if (os_strlen(pos) != 32 * 2) {
1540 wpa_printf(MSG_DEBUG,
1541 "wolfSSL: Unexpected SHA256 hash length in ca_cert '%s'",
1542 ca_cert);
1543 return -1;
1544 }
1545 if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) {
1546 wpa_printf(MSG_DEBUG,
1547 "wolfSSL: Invalid SHA256 hash value in ca_cert '%s'",
1548 ca_cert);
1549 return -1;
1550 }
1551 conn->server_cert_only = 1;
1552 wpa_printf(MSG_DEBUG,
1553 "wolfSSL: Checking only server certificate match");
1554 return 0;
1555 #else /* CONFIG_SHA256 */
1556 wpa_printf(MSG_INFO,
1557 "No SHA256 included in the build - cannot validate server certificate hash");
1558 return -1;
1559 #endif /* CONFIG_SHA256 */
1560 }
1561
1562 if (ca_cert_blob) {
1563 if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_blob, blob_len,
1564 SSL_FILETYPE_ASN1) !=
1565 SSL_SUCCESS) {
1566 wpa_printf(MSG_INFO, "SSL: failed to load DER CA blob");
1567 if (wolfSSL_CTX_load_verify_buffer(
1568 ctx, ca_cert_blob, blob_len,
1569 SSL_FILETYPE_PEM) != SSL_SUCCESS) {
1570 wpa_printf(MSG_INFO,
1571 "SSL: failed to load PEM CA blob");
1572 return -1;
1573 }
1574 }
1575 wpa_printf(MSG_DEBUG, "SSL: use CA cert blob OK");
1576 return 0;
1577 }
1578
1579 if (ca_cert || ca_path) {
1580 wpa_printf(MSG_DEBUG, "SSL: Loading CA's from '%s' and '%s'",
1581 ca_cert ? ca_cert : "N/A",
1582 ca_path ? ca_path : "N/A");
1583 if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, ca_path) !=
1584 SSL_SUCCESS) {
1585 wpa_printf(MSG_INFO,
1586 "SSL: failed to load ca_cert as PEM");
1587
1588 if (!ca_cert)
1589 return -1;
1590
1591 if (wolfSSL_CTX_der_load_verify_locations(
1592 ctx, ca_cert, SSL_FILETYPE_ASN1) !=
1593 SSL_SUCCESS) {
1594 wpa_printf(MSG_INFO,
1595 "SSL: failed to load ca_cert as DER");
1596 return -1;
1597 }
1598 }
1599 wpa_printf(MSG_DEBUG, "SSL: Loaded ca_cert or ca_path");
1600 return 0;
1601 }
1602
1603 conn->ca_cert_verify = 0;
1604 return 0;
1605 }
1606
1607
tls_set_conn_flags(WOLFSSL * ssl,unsigned int flags)1608 static void tls_set_conn_flags(WOLFSSL *ssl, unsigned int flags)
1609 {
1610 long op = 0;
1611
1612 #ifdef HAVE_SESSION_TICKET
1613 if (!(flags & TLS_CONN_DISABLE_SESSION_TICKET))
1614 wolfSSL_UseSessionTicket(ssl);
1615 #endif /* HAVE_SESSION_TICKET */
1616
1617 wpa_printf(MSG_DEBUG, "SSL: conn_flags: %d", flags);
1618
1619 if (flags & TLS_CONN_DISABLE_TLSv1_0)
1620 op |= WOLFSSL_OP_NO_TLSv1;
1621 if (flags & TLS_CONN_DISABLE_TLSv1_1)
1622 op |= WOLFSSL_OP_NO_TLSv1_1;
1623 if (flags & TLS_CONN_DISABLE_TLSv1_2)
1624 op |= WOLFSSL_OP_NO_TLSv1_2;
1625 if (flags & TLS_CONN_DISABLE_TLSv1_3)
1626 op |= WOLFSSL_OP_NO_TLSv1_3;
1627 wolfSSL_set_options(ssl, op);
1628 }
1629
1630
tls_connection_set_params(void * tls_ctx,struct tls_connection * conn,const struct tls_connection_params * params)1631 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
1632 const struct tls_connection_params *params)
1633 {
1634 wpa_printf(MSG_DEBUG, "SSL: set params");
1635
1636 if (tls_connection_set_subject_match(conn, params->subject_match,
1637 params->altsubject_match,
1638 params->suffix_match,
1639 params->domain_match,
1640 params->check_cert_subject) < 0) {
1641 wpa_printf(MSG_INFO, "Error setting subject match");
1642 return -1;
1643 }
1644
1645 if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert,
1646 params->ca_cert_blob,
1647 params->ca_cert_blob_len,
1648 params->ca_path) < 0) {
1649 wpa_printf(MSG_INFO, "Error setting CA cert");
1650 return -1;
1651 }
1652
1653 if (tls_connection_client_cert(conn, params->client_cert,
1654 params->client_cert_blob,
1655 params->client_cert_blob_len) < 0) {
1656 wpa_printf(MSG_INFO, "Error setting client cert");
1657 return -1;
1658 }
1659
1660 if (tls_connection_private_key(tls_ctx, conn, params->private_key,
1661 params->private_key_passwd,
1662 params->private_key_blob,
1663 params->private_key_blob_len) < 0) {
1664 wpa_printf(MSG_INFO, "Error setting private key");
1665 return -1;
1666 }
1667
1668 if (handle_ciphersuites(NULL, conn->ssl, params->openssl_ciphers,
1669 params->flags) != 0) {
1670 wpa_printf(MSG_INFO, "wolfssl: Error setting ciphersuites");
1671 return -1;
1672 }
1673
1674 if (params->openssl_ecdh_curves &&
1675 wolfSSL_set1_curves_list(conn->ssl, params->openssl_ecdh_curves) !=
1676 1) {
1677 wpa_printf(MSG_INFO, "wolfSSL: Failed to set ECDH curves '%s'",
1678 params->openssl_ecdh_curves);
1679 return -1;
1680 }
1681
1682 tls_set_conn_flags(conn->ssl, params->flags);
1683
1684 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
1685 if (params->flags & TLS_CONN_REQUEST_OCSP) {
1686 if (wolfSSL_UseOCSPStapling(conn->ssl, WOLFSSL_CSR_OCSP,
1687 WOLFSSL_CSR_OCSP_USE_NONCE) !=
1688 SSL_SUCCESS)
1689 return -1;
1690 if (wolfSSL_EnableOCSPStapling(conn->ssl) != SSL_SUCCESS)
1691 return -1;
1692 }
1693 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
1694 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
1695 if (params->flags & TLS_CONN_REQUEST_OCSP) {
1696 if (wolfSSL_UseOCSPStaplingV2(conn->ssl,
1697 WOLFSSL_CSR2_OCSP_MULTI, 0) !=
1698 SSL_SUCCESS)
1699 return -1;
1700 if (wolfSSL_EnableOCSPStapling(conn->ssl) != SSL_SUCCESS)
1701 return -1;
1702 }
1703 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
1704 #if !defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
1705 !defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
1706 #ifdef HAVE_OCSP
1707 if (params->flags & TLS_CONN_REQUEST_OCSP)
1708 wolfSSL_CTX_EnableOCSP(ctx, 0);
1709 #else /* HAVE_OCSP */
1710 if (params->flags & TLS_CONN_REQUIRE_OCSP) {
1711 wpa_printf(MSG_INFO,
1712 "wolfSSL: No OCSP support included - reject configuration");
1713 return -1;
1714 }
1715 if (params->flags & TLS_CONN_REQUEST_OCSP) {
1716 wpa_printf(MSG_DEBUG,
1717 "wolfSSL: No OCSP support included - allow optional OCSP case to continue");
1718 }
1719 #endif /* HAVE_OCSP */
1720 #endif /* !HAVE_CERTIFICATE_STATUS_REQUEST &&
1721 * !HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
1722
1723 conn->flags = params->flags;
1724
1725 return 0;
1726 }
1727
1728
tls_global_ca_cert(void * ssl_ctx,const char * ca_cert)1729 static int tls_global_ca_cert(void *ssl_ctx, const char *ca_cert)
1730 {
1731 WOLFSSL_CTX *ctx = ssl_ctx;
1732
1733 if (ca_cert) {
1734 if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, NULL) != 1)
1735 {
1736 wpa_printf(MSG_WARNING,
1737 "Failed to load root certificates");
1738 return -1;
1739 }
1740
1741 wpa_printf(MSG_DEBUG,
1742 "TLS: Trusted root certificate(s) loaded");
1743 }
1744
1745 return 0;
1746 }
1747
1748
tls_global_client_cert(void * ssl_ctx,const char * client_cert)1749 static int tls_global_client_cert(void *ssl_ctx, const char *client_cert)
1750 {
1751 WOLFSSL_CTX *ctx = ssl_ctx;
1752
1753 if (!client_cert)
1754 return 0;
1755
1756 if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, client_cert,
1757 SSL_FILETYPE_ASN1) !=
1758 SSL_SUCCESS &&
1759 wolfSSL_CTX_use_certificate_chain_file(ctx, client_cert) !=
1760 SSL_SUCCESS) {
1761 wpa_printf(MSG_INFO, "Failed to load client certificate");
1762 return -1;
1763 }
1764
1765 wpa_printf(MSG_DEBUG, "SSL: Loaded global client certificate: %s",
1766 client_cert);
1767
1768 return 0;
1769 }
1770
1771
tls_global_private_key(void * ssl_ctx,const char * private_key,const char * private_key_passwd)1772 static int tls_global_private_key(void *ssl_ctx, const char *private_key,
1773 const char *private_key_passwd)
1774 {
1775 WOLFSSL_CTX *ctx = ssl_ctx;
1776 char *passwd = NULL;
1777 int ret = 0;
1778
1779 if (!private_key)
1780 return 0;
1781
1782 if (private_key_passwd) {
1783 passwd = os_strdup(private_key_passwd);
1784 if (!passwd)
1785 return -1;
1786 }
1787
1788 wolfSSL_CTX_set_default_passwd_cb(ctx, tls_passwd_cb);
1789 wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, passwd);
1790
1791 if (wolfSSL_CTX_use_PrivateKey_file(ctx, private_key,
1792 SSL_FILETYPE_ASN1) != 1 &&
1793 wolfSSL_CTX_use_PrivateKey_file(ctx, private_key,
1794 SSL_FILETYPE_PEM) != 1) {
1795 wpa_printf(MSG_INFO, "Failed to load private key");
1796 ret = -1;
1797 }
1798
1799 wpa_printf(MSG_DEBUG, "SSL: Loaded global private key");
1800
1801 os_free(passwd);
1802 wolfSSL_CTX_set_default_passwd_cb(ctx, NULL);
1803
1804 return ret;
1805 }
1806
1807
tls_global_dh(void * ssl_ctx,const char * dh_file)1808 static int tls_global_dh(void *ssl_ctx, const char *dh_file)
1809 {
1810 WOLFSSL_CTX *ctx = ssl_ctx;
1811
1812 if (dh_file) {
1813 if (wolfSSL_CTX_SetTmpDH_file(ctx, dh_file, SSL_FILETYPE_PEM) <
1814 0) {
1815 wpa_printf(MSG_INFO,
1816 "SSL: global use DH PEM file failed");
1817 if (wolfSSL_CTX_SetTmpDH_file(ctx, dh_file,
1818 SSL_FILETYPE_ASN1) < 0) {
1819 wpa_printf(MSG_INFO,
1820 "SSL: global use DH DER file failed");
1821 return -1;
1822 }
1823 }
1824 wpa_printf(MSG_DEBUG, "SSL: global use DH file OK");
1825 return 0;
1826 }
1827
1828 return 0;
1829 }
1830
1831
1832 #ifdef HAVE_OCSP
1833
ocsp_status_cb(void * unused,const char * url,int url_sz,unsigned char * request,int request_sz,unsigned char ** response)1834 int ocsp_status_cb(void *unused, const char *url, int url_sz,
1835 unsigned char *request, int request_sz,
1836 unsigned char **response)
1837 {
1838 size_t len;
1839
1840 (void) unused;
1841
1842 if (!url) {
1843 wpa_printf(MSG_DEBUG,
1844 "wolfSSL: OCSP status callback - no response configured");
1845 *response = NULL;
1846 return 0;
1847 }
1848
1849 *response = (unsigned char *) os_readfile(url, &len);
1850 if (!*response) {
1851 wpa_printf(MSG_DEBUG,
1852 "wolfSSL: OCSP status callback - could not read response file");
1853 return -1;
1854 }
1855 wpa_printf(MSG_DEBUG,
1856 "wolfSSL: OCSP status callback - send cached response");
1857 return len;
1858 }
1859
1860
ocsp_resp_free_cb(void * ocsp_stapling_response,unsigned char * response)1861 void ocsp_resp_free_cb(void *ocsp_stapling_response, unsigned char *response)
1862 {
1863 os_free(response);
1864 }
1865
1866 #endif /* HAVE_OCSP */
1867
1868
tls_global_set_params(void * tls_ctx,const struct tls_connection_params * params)1869 int tls_global_set_params(void *tls_ctx,
1870 const struct tls_connection_params *params)
1871 {
1872 /* Need to cast away const as this is one of the only places
1873 * where we should modify it */
1874 struct tls_context *context =
1875 (struct tls_context *) ssl_ctx_get_tls_context(tls_ctx);
1876
1877 wpa_printf(MSG_DEBUG, "SSL: global set params");
1878
1879 os_free(context->check_cert_subject);
1880 context->check_cert_subject = NULL;
1881 if (params->check_cert_subject) {
1882 context->check_cert_subject =
1883 os_strdup(params->check_cert_subject);
1884 if (!context->check_cert_subject) {
1885 wpa_printf(MSG_ERROR,
1886 "SSL: Failed to copy check_cert_subject '%s'",
1887 params->check_cert_subject);
1888 return -1;
1889 }
1890 }
1891
1892 if (tls_global_ca_cert(tls_ctx, params->ca_cert) < 0) {
1893 wpa_printf(MSG_INFO, "SSL: Failed to load ca cert file '%s'",
1894 params->ca_cert);
1895 return -1;
1896 }
1897
1898 if (tls_global_client_cert(tls_ctx, params->client_cert) < 0) {
1899 wpa_printf(MSG_INFO,
1900 "SSL: Failed to load client cert file '%s'",
1901 params->client_cert);
1902 return -1;
1903 }
1904
1905 if (tls_global_private_key(tls_ctx, params->private_key,
1906 params->private_key_passwd) < 0) {
1907 wpa_printf(MSG_INFO,
1908 "SSL: Failed to load private key file '%s'",
1909 params->private_key);
1910 return -1;
1911 }
1912
1913 if (tls_global_dh(tls_ctx, params->dh_file) < 0) {
1914 wpa_printf(MSG_INFO, "SSL: Failed to load DH file '%s'",
1915 params->dh_file);
1916 return -1;
1917 }
1918
1919 if (handle_ciphersuites(tls_ctx, NULL, params->openssl_ciphers,
1920 params->flags) != 0) {
1921 wpa_printf(MSG_INFO, "wolfssl: Error setting ciphersuites");
1922 return -1;
1923 }
1924
1925 if (params->openssl_ecdh_curves &&
1926 wolfSSL_CTX_set1_curves_list((WOLFSSL_CTX *) tls_ctx,
1927 params->openssl_ecdh_curves) != 1) {
1928 wpa_printf(MSG_INFO, "wolfSSL: Failed to set ECDH curves '%s'",
1929 params->openssl_ecdh_curves);
1930 return -1;
1931 }
1932
1933 #ifdef HAVE_SESSION_TICKET
1934 /* Session ticket is off by default - can't disable once on. */
1935 if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET) &&
1936 wolfSSL_CTX_UseSessionTicket(tls_ctx) != WOLFSSL_SUCCESS) {
1937 wpa_printf(MSG_ERROR,
1938 "wolfSSL: wolfSSL_CTX_UseSessionTicket failed");
1939 return -1;
1940 }
1941 #endif /* HAVE_SESSION_TICKET */
1942
1943 #ifdef HAVE_OCSP
1944 if (params->ocsp_stapling_response) {
1945 if (wolfSSL_CTX_EnableOCSP(tls_ctx,
1946 WOLFSSL_OCSP_URL_OVERRIDE) !=
1947 WOLFSSL_SUCCESS ||
1948 /* Workaround to force using the override URL without
1949 * enabling OCSP */
1950 wolfSSL_CTX_DisableOCSP(tls_ctx) != WOLFSSL_SUCCESS) {
1951 wpa_printf(MSG_ERROR,
1952 "wolfSSL: wolfSSL_CTX_UseOCSPStapling() failed");
1953 return -1;
1954 }
1955
1956 if (wolfSSL_CTX_UseOCSPStapling(tls_ctx, WOLFSSL_CSR_OCSP,
1957 WOLFSSL_CSR_OCSP_USE_NONCE) !=
1958 WOLFSSL_SUCCESS) {
1959 wpa_printf(MSG_ERROR,
1960 "wolfSSL: wolfSSL_CTX_UseOCSPStapling() failed");
1961 return -1;
1962 }
1963
1964 if (wolfSSL_CTX_EnableOCSPStapling(tls_ctx) !=
1965 WOLFSSL_SUCCESS) {
1966 wpa_printf(MSG_ERROR,
1967 "wolfSSL: wolfSSL_EnableOCSPStapling() failed");
1968 return -1;
1969 }
1970
1971 if (wolfSSL_CTX_SetOCSP_OverrideURL(
1972 tls_ctx,
1973 params->ocsp_stapling_response) !=
1974 WOLFSSL_SUCCESS) {
1975 wpa_printf(MSG_ERROR,
1976 "wolfSSL: wolfSSL_CTX_SetOCSP_OverrideURL() failed");
1977 return -1;
1978 }
1979
1980 if (wolfSSL_CTX_SetOCSP_Cb(tls_ctx, ocsp_status_cb,
1981 ocsp_resp_free_cb, NULL) !=
1982 WOLFSSL_SUCCESS) {
1983 wpa_printf(MSG_ERROR,
1984 "wolfSSL: wolfSSL_CTX_SetOCSP_Cb() failed");
1985 return -1;
1986 }
1987 }
1988 #endif /* HAVE_OCSP */
1989
1990 return 0;
1991 }
1992
1993
tls_global_set_verify(void * tls_ctx,int check_crl,int strict)1994 int tls_global_set_verify(void *tls_ctx, int check_crl, int strict)
1995 {
1996 wpa_printf(MSG_DEBUG, "SSL: global set verify: %d", check_crl);
1997
1998 if (check_crl) {
1999 /* Hack to Enable CRLs. */
2000 wolfSSL_CTX_LoadCRLBuffer(tls_ctx, NULL, 0, SSL_FILETYPE_PEM);
2001 }
2002
2003 return 0;
2004 }
2005
2006
tls_connection_set_verify(void * ssl_ctx,struct tls_connection * conn,int verify_peer,unsigned int flags,const u8 * session_ctx,size_t session_ctx_len)2007 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
2008 int verify_peer, unsigned int flags,
2009 const u8 *session_ctx, size_t session_ctx_len)
2010 {
2011 static int counter = 0;
2012 const struct tls_context *context;
2013
2014 if (!conn)
2015 return -1;
2016
2017 wpa_printf(MSG_DEBUG, "SSL: set verify: %d", verify_peer);
2018 wpa_printf(MSG_DEBUG, "SSL: flags: %d", flags);
2019
2020 if (verify_peer) {
2021 conn->ca_cert_verify = 1;
2022 wolfSSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
2023 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2024 tls_verify_cb);
2025 } else {
2026 conn->ca_cert_verify = 0;
2027 wolfSSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
2028 }
2029
2030 wolfSSL_set_accept_state(conn->ssl);
2031
2032 context = ssl_ctx_get_tls_context(ssl_ctx);
2033 if (context && context->tls_session_lifetime == 0) {
2034 /*
2035 * Set session id context to a unique value to make sure
2036 * session resumption cannot be used either through session
2037 * caching or TLS ticket extension.
2038 */
2039 counter++;
2040 wolfSSL_set_session_id_context(conn->ssl,
2041 (const unsigned char *) &counter,
2042 sizeof(counter));
2043 } else {
2044 wolfSSL_set_session_id_context(conn->ssl, session_ctx,
2045 session_ctx_len);
2046 }
2047
2048 tls_set_conn_flags(conn->ssl, flags);
2049
2050 return 0;
2051 }
2052
2053
wolfssl_handshake(struct tls_connection * conn,const struct wpabuf * in_data,int server)2054 static struct wpabuf * wolfssl_handshake(struct tls_connection *conn,
2055 const struct wpabuf *in_data,
2056 int server)
2057 {
2058 int res;
2059
2060 wolfssl_reset_out_data(&conn->output);
2061
2062 /* Initiate TLS handshake or continue the existing handshake */
2063 if (server) {
2064 wolfSSL_set_accept_state(conn->ssl);
2065 res = wolfSSL_accept(conn->ssl);
2066 wpa_printf(MSG_DEBUG, "SSL: wolfSSL_accept: %d", res);
2067 } else {
2068 wolfSSL_set_connect_state(conn->ssl);
2069 res = wolfSSL_connect(conn->ssl);
2070 wpa_printf(MSG_DEBUG, "SSL: wolfSSL_connect: %d", res);
2071 }
2072
2073 if (res != WOLFSSL_SUCCESS) {
2074 int err = wolfSSL_get_error(conn->ssl, res);
2075
2076 if (err == WOLFSSL_ERROR_NONE) {
2077 wpa_printf(MSG_DEBUG,
2078 "SSL: %s - WOLFSSL_ERROR_NONE (%d)",
2079 server ? "wolfSSL_accept" :
2080 "wolfSSL_connect", res);
2081 } else if (err == WOLFSSL_ERROR_WANT_READ) {
2082 wpa_printf(MSG_DEBUG,
2083 "SSL: %s - want more data",
2084 server ? "wolfSSL_accept" :
2085 "wolfSSL_connect");
2086 } else if (err == WOLFSSL_ERROR_WANT_WRITE) {
2087 wpa_printf(MSG_DEBUG,
2088 "SSL: %s - want to write",
2089 server ? "wolfSSL_accept" :
2090 "wolfSSL_connect");
2091 } else {
2092 char msg[80];
2093
2094 wpa_printf(MSG_DEBUG,
2095 "SSL: %s - failed (%d) %s",
2096 server ? "wolfSSL_accept" :
2097 "wolfSSL_connect", err,
2098 wolfSSL_ERR_error_string(err, msg));
2099 conn->failed++;
2100 }
2101
2102 /* Generate extra events */
2103 if (err == OCSP_CERT_REVOKED ||
2104 err == BAD_CERTIFICATE_STATUS_ERROR ||
2105 err == OCSP_CERT_REVOKED) {
2106 char buf[256];
2107 WOLFSSL_X509 *err_cert;
2108
2109 err_cert = wolfSSL_get_peer_certificate(conn->ssl);
2110 wolfSSL_X509_NAME_oneline(
2111 wolfSSL_X509_get_subject_name(err_cert),
2112 buf, sizeof(buf));
2113 wolfssl_tls_fail_event(conn, err_cert, err, 0, buf,
2114 "bad certificate status response",
2115 TLS_FAIL_UNSPECIFIED);
2116 }
2117 }
2118
2119 return conn->output.out_data;
2120 }
2121
2122
wolfssl_get_appl_data(struct tls_connection * conn,size_t max_len)2123 static struct wpabuf * wolfssl_get_appl_data(struct tls_connection *conn,
2124 size_t max_len)
2125 {
2126 int res;
2127 struct wpabuf *appl_data = wpabuf_alloc(max_len + 100);
2128
2129 if (!appl_data)
2130 return NULL;
2131
2132 res = wolfSSL_read(conn->ssl, wpabuf_mhead(appl_data),
2133 wpabuf_size(appl_data));
2134 if (res < 0) {
2135 int err = wolfSSL_get_error(conn->ssl, res);
2136
2137 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2138 wpa_printf(MSG_DEBUG,
2139 "SSL: No Application Data included");
2140 } else {
2141 char msg[80];
2142
2143 wpa_printf(MSG_DEBUG,
2144 "Failed to read possible Application Data %s",
2145 wolfSSL_ERR_error_string(err, msg));
2146 }
2147
2148 wpabuf_free(appl_data);
2149 return NULL;
2150 }
2151
2152 wpabuf_put(appl_data, res);
2153 wpa_hexdump_buf_key(MSG_MSGDUMP,
2154 "SSL: Application Data in Finished message",
2155 appl_data);
2156 return appl_data;
2157 }
2158
2159
2160 static struct wpabuf *
wolfssl_connection_handshake(struct tls_connection * conn,const struct wpabuf * in_data,struct wpabuf ** appl_data,int server)2161 wolfssl_connection_handshake(struct tls_connection *conn,
2162 const struct wpabuf *in_data,
2163 struct wpabuf **appl_data, int server)
2164 {
2165 struct wpabuf *out_data;
2166
2167 wolfssl_reset_in_data(&conn->input, in_data);
2168
2169 if (appl_data)
2170 *appl_data = NULL;
2171
2172 out_data = wolfssl_handshake(conn, in_data, server);
2173 if (!out_data)
2174 return NULL;
2175
2176 if (wolfSSL_is_init_finished(conn->ssl)) {
2177 wpa_printf(MSG_DEBUG,
2178 "wolfSSL: Handshake finished - resumed=%d",
2179 tls_connection_resumed(NULL, conn));
2180 if (appl_data && in_data)
2181 *appl_data = wolfssl_get_appl_data(conn,
2182 wpabuf_len(in_data));
2183 }
2184
2185 return out_data;
2186 }
2187
2188
tls_connection_handshake(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data,struct wpabuf ** appl_data)2189 struct wpabuf * tls_connection_handshake(void *tls_ctx,
2190 struct tls_connection *conn,
2191 const struct wpabuf *in_data,
2192 struct wpabuf **appl_data)
2193 {
2194 return wolfssl_connection_handshake(conn, in_data, appl_data, 0);
2195 }
2196
2197
tls_connection_server_handshake(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data,struct wpabuf ** appl_data)2198 struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
2199 struct tls_connection *conn,
2200 const struct wpabuf *in_data,
2201 struct wpabuf **appl_data)
2202 {
2203 return wolfssl_connection_handshake(conn, in_data, appl_data, 1);
2204 }
2205
2206
tls_connection_encrypt(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data)2207 struct wpabuf * tls_connection_encrypt(void *tls_ctx,
2208 struct tls_connection *conn,
2209 const struct wpabuf *in_data)
2210 {
2211 int res;
2212
2213 if (!conn)
2214 return NULL;
2215
2216 wpa_printf(MSG_DEBUG, "SSL: encrypt: %zu bytes", wpabuf_len(in_data));
2217
2218 wolfssl_reset_out_data(&conn->output);
2219
2220 res = wolfSSL_write(conn->ssl, wpabuf_head(in_data),
2221 wpabuf_len(in_data));
2222 if (res < 0) {
2223 int err = wolfSSL_get_error(conn->ssl, res);
2224 char msg[80];
2225
2226 wpa_printf(MSG_INFO, "Encryption failed - SSL_write: %s",
2227 wolfSSL_ERR_error_string(err, msg));
2228 return NULL;
2229 }
2230
2231 return conn->output.out_data;
2232 }
2233
2234
tls_connection_decrypt(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data)2235 struct wpabuf * tls_connection_decrypt(void *tls_ctx,
2236 struct tls_connection *conn,
2237 const struct wpabuf *in_data)
2238 {
2239 int res;
2240 struct wpabuf *buf;
2241
2242 if (!conn)
2243 return NULL;
2244
2245 wpa_printf(MSG_DEBUG, "SSL: decrypt");
2246
2247 wolfssl_reset_in_data(&conn->input, in_data);
2248
2249 /* Read decrypted data for further processing */
2250 /*
2251 * Even though we try to disable TLS compression, it is possible that
2252 * this cannot be done with all TLS libraries. Add extra buffer space
2253 * to handle the possibility of the decrypted data being longer than
2254 * input data.
2255 */
2256 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
2257 if (!buf)
2258 return NULL;
2259 res = wolfSSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
2260 if (res < 0) {
2261 wpa_printf(MSG_INFO, "Decryption failed - SSL_read");
2262 wpabuf_free(buf);
2263 return NULL;
2264 }
2265 wpabuf_put(buf, res);
2266
2267 wpa_printf(MSG_DEBUG, "SSL: decrypt: %zu bytes", wpabuf_len(buf));
2268
2269 return buf;
2270 }
2271
2272
tls_connection_resumed(void * tls_ctx,struct tls_connection * conn)2273 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
2274 {
2275 return conn ? wolfSSL_session_reused(conn->ssl) : 0;
2276 }
2277
2278
tls_connection_set_cipher_list(void * tls_ctx,struct tls_connection * conn,u8 * ciphers)2279 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
2280 u8 *ciphers)
2281 {
2282 char buf[128], *pos, *end;
2283 u8 *c;
2284 int ret;
2285 bool set_sig_algs = false;
2286
2287 if (!conn || !conn->ssl || !ciphers)
2288 return -1;
2289
2290 buf[0] = buf[1] = '\0';
2291 pos = buf;
2292 end = pos + sizeof(buf);
2293
2294 c = ciphers;
2295 while (*c != TLS_CIPHER_NONE) {
2296 const char *suite;
2297
2298 switch (*c) {
2299 case TLS_CIPHER_RC4_SHA:
2300 suite = "RC4-SHA";
2301 break;
2302 case TLS_CIPHER_AES128_SHA:
2303 suite = "AES128-SHA";
2304 break;
2305 case TLS_CIPHER_RSA_DHE_AES128_SHA:
2306 suite = "DHE-RSA-AES128-SHA";
2307 break;
2308 case TLS_CIPHER_ANON_DH_AES128_SHA:
2309 suite = "ADH-AES128-SHA";
2310 set_sig_algs = true;
2311 break;
2312 case TLS_CIPHER_RSA_DHE_AES256_SHA:
2313 suite = "DHE-RSA-AES256-SHA";
2314 break;
2315 case TLS_CIPHER_AES256_SHA:
2316 suite = "AES256-SHA";
2317 break;
2318 default:
2319 wpa_printf(MSG_DEBUG,
2320 "TLS: Unsupported cipher selection: %d", *c);
2321 return -1;
2322 }
2323 ret = os_snprintf(pos, end - pos, ":%s", suite);
2324 if (os_snprintf_error(end - pos, ret))
2325 break;
2326 pos += ret;
2327
2328 c++;
2329 }
2330
2331 /* +1 to skip the ":" */
2332 if (handle_ciphersuites(NULL, conn->ssl, buf + 1, conn->flags) != 0) {
2333 wpa_printf(MSG_DEBUG,
2334 "wolfssl: Cipher suite configuration failed");
2335 return -1;
2336 }
2337
2338 if (set_sig_algs &&
2339 wolfSSL_set1_sigalgs_list(conn->ssl, SUITEB_TLS_128_SIGALGS) != 1) {
2340 wpa_printf(MSG_DEBUG, "wolfssl: Sigalg configuration failed");
2341 return -1;
2342 }
2343
2344 return 0;
2345 }
2346
2347
tls_get_cipher(void * tls_ctx,struct tls_connection * conn,char * buf,size_t buflen)2348 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
2349 char *buf, size_t buflen)
2350 {
2351 const char *name;
2352
2353 if (!conn || !conn->ssl)
2354 return -1;
2355
2356 if (wolfSSL_version(conn->ssl) == TLS1_3_VERSION)
2357 name = wolfSSL_get_cipher(conn->ssl);
2358 else
2359 name = wolfSSL_get_cipher_name(conn->ssl);
2360 if (!name)
2361 return -1;
2362
2363 os_strlcpy(buf, name, buflen);
2364
2365 return 0;
2366 }
2367
2368
tls_connection_enable_workaround(void * tls_ctx,struct tls_connection * conn)2369 int tls_connection_enable_workaround(void *tls_ctx,
2370 struct tls_connection *conn)
2371 {
2372 /* no empty fragments in wolfSSL for now */
2373 return 0;
2374 }
2375
2376
tls_connection_get_failed(void * tls_ctx,struct tls_connection * conn)2377 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
2378 {
2379 if (!conn)
2380 return -1;
2381
2382 return conn->failed;
2383 }
2384
2385
tls_connection_get_read_alerts(void * tls_ctx,struct tls_connection * conn)2386 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
2387 {
2388 if (!conn)
2389 return -1;
2390
2391 /* TODO: this is not incremented anywhere */
2392 return conn->read_alerts;
2393 }
2394
2395
tls_connection_get_write_alerts(void * tls_ctx,struct tls_connection * conn)2396 int tls_connection_get_write_alerts(void *tls_ctx,
2397 struct tls_connection *conn)
2398 {
2399 if (!conn)
2400 return -1;
2401
2402 /* TODO: this is not incremented anywhere */
2403 return conn->write_alerts;
2404 }
2405
2406
2407
tls_get_library_version(char * buf,size_t buf_len)2408 int tls_get_library_version(char *buf, size_t buf_len)
2409 {
2410 return os_snprintf(buf, buf_len, "wolfSSL build=%s run=%s",
2411 WOLFSSL_VERSION, wolfSSL_lib_version());
2412 }
2413
tls_get_version(void * ssl_ctx,struct tls_connection * conn,char * buf,size_t buflen)2414 int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
2415 char *buf, size_t buflen)
2416 {
2417 const char *name;
2418
2419 if (!conn || !conn->ssl)
2420 return -1;
2421
2422 name = wolfSSL_get_version(conn->ssl);
2423 if (!name)
2424 return -1;
2425
2426 os_strlcpy(buf, name, buflen);
2427 return 0;
2428 }
2429
2430
tls_connection_get_random(void * ssl_ctx,struct tls_connection * conn,struct tls_random * keys)2431 int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
2432 struct tls_random *keys)
2433 {
2434 WOLFSSL *ssl;
2435
2436 if (!conn || !keys)
2437 return -1;
2438 ssl = conn->ssl;
2439 if (!ssl)
2440 return -1;
2441
2442 os_memset(keys, 0, sizeof(*keys));
2443 keys->client_random = conn->client_random;
2444 keys->client_random_len = wolfSSL_get_client_random(
2445 ssl, conn->client_random, sizeof(conn->client_random));
2446 keys->server_random = conn->server_random;
2447 keys->server_random_len = wolfSSL_get_server_random(
2448 ssl, conn->server_random, sizeof(conn->server_random));
2449
2450 return 0;
2451 }
2452
2453
tls_connection_export_key(void * tls_ctx,struct tls_connection * conn,const char * label,const u8 * context,size_t context_len,u8 * out,size_t out_len)2454 int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
2455 const char *label, const u8 *context,
2456 size_t context_len, u8 *out, size_t out_len)
2457 {
2458 if (!conn)
2459 return -1;
2460 #if LIBWOLFSSL_VERSION_HEX >= 0x04007000
2461 if (wolfSSL_export_keying_material(conn->ssl, out, out_len,
2462 label, os_strlen(label),
2463 context, context_len,
2464 context != NULL) != WOLFSSL_SUCCESS)
2465 return -1;
2466 return 0;
2467 #else
2468 if (context ||
2469 wolfSSL_make_eap_keys(conn->ssl, out, out_len, label) != 0)
2470 return -1;
2471 #endif
2472 return 0;
2473 }
2474
2475
2476 #define SEED_LEN (RAN_LEN + RAN_LEN)
2477
tls_connection_get_eap_fast_key(void * tls_ctx,struct tls_connection * conn,u8 * out,size_t out_len)2478 int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
2479 u8 *out, size_t out_len)
2480 {
2481 byte seed[SEED_LEN];
2482 int ret = -1;
2483 WOLFSSL *ssl;
2484 byte *tmp_out;
2485 byte *_out;
2486 int skip = 0;
2487 byte *master_key;
2488 unsigned int master_key_len;
2489 byte *server_random;
2490 unsigned int server_len;
2491 byte *client_random;
2492 unsigned int client_len;
2493
2494 if (!conn || !conn->ssl)
2495 return -1;
2496 ssl = conn->ssl;
2497
2498 skip = 2 * (wolfSSL_GetKeySize(ssl) + wolfSSL_GetHmacSize(ssl) +
2499 wolfSSL_GetIVSize(ssl));
2500
2501 tmp_out = os_malloc(skip + out_len);
2502 if (!tmp_out)
2503 return -1;
2504 _out = tmp_out;
2505
2506 wolfSSL_get_keys(ssl, &master_key, &master_key_len, &server_random,
2507 &server_len, &client_random, &client_len);
2508 os_memcpy(seed, server_random, RAN_LEN);
2509 os_memcpy(seed + RAN_LEN, client_random, RAN_LEN);
2510
2511 if (wolfSSL_GetVersion(ssl) == WOLFSSL_TLSV1_2) {
2512 tls_prf_sha256(master_key, master_key_len,
2513 "key expansion", seed, sizeof(seed),
2514 _out, skip + out_len);
2515 ret = 0;
2516 } else {
2517 #ifdef CONFIG_FIPS
2518 wpa_printf(MSG_ERROR,
2519 "wolfSSL: Can't use sha1_md5 in FIPS build");
2520 ret = -1;
2521 #else /* CONFIG_FIPS */
2522 ret = tls_prf_sha1_md5(master_key, master_key_len,
2523 "key expansion", seed, sizeof(seed),
2524 _out, skip + out_len);
2525 #endif /* CONFIG_FIPS */
2526 }
2527
2528 forced_memzero(master_key, master_key_len);
2529 if (ret == 0)
2530 os_memcpy(out, _out + skip, out_len);
2531 bin_clear_free(tmp_out, skip + out_len);
2532
2533 return ret;
2534 }
2535
2536
2537 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2538
tls_connection_client_hello_ext(void * ssl_ctx,struct tls_connection * conn,int ext_type,const u8 * data,size_t data_len)2539 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
2540 int ext_type, const u8 *data,
2541 size_t data_len)
2542 {
2543 (void) ssl_ctx;
2544
2545 if (!conn || !conn->ssl || ext_type != 35)
2546 return -1;
2547
2548 if (wolfSSL_set_SessionTicket(conn->ssl, data,
2549 (unsigned int) data_len) != 1)
2550 return -1;
2551
2552 return 0;
2553 }
2554
2555
tls_sess_sec_cb(WOLFSSL * s,void * secret,int * secret_len,void * arg)2556 static int tls_sess_sec_cb(WOLFSSL *s, void *secret, int *secret_len, void *arg)
2557 {
2558 struct tls_connection *conn = arg;
2559 int ret;
2560 unsigned char client_random[RAN_LEN];
2561 unsigned char server_random[RAN_LEN];
2562 word32 ticket_len = sizeof(conn->session_ticket);
2563
2564 if (!conn || !conn->session_ticket_cb)
2565 return 1;
2566
2567 if (wolfSSL_get_client_random(s, client_random,
2568 sizeof(client_random)) == 0 ||
2569 wolfSSL_get_server_random(s, server_random,
2570 sizeof(server_random)) == 0 ||
2571 wolfSSL_get_SessionTicket(s, conn->session_ticket,
2572 &ticket_len) != 1)
2573 return 1;
2574
2575 if (ticket_len == 0)
2576 return 0;
2577
2578 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
2579 conn->session_ticket, ticket_len,
2580 client_random, server_random, secret);
2581 if (ret <= 0)
2582 return 1;
2583
2584 *secret_len = SECRET_LEN;
2585 return 0;
2586 }
2587
2588 #endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2589
2590
tls_connection_set_session_ticket_cb(void * tls_ctx,struct tls_connection * conn,tls_session_ticket_cb cb,void * ctx)2591 int tls_connection_set_session_ticket_cb(void *tls_ctx,
2592 struct tls_connection *conn,
2593 tls_session_ticket_cb cb,
2594 void *ctx)
2595 {
2596 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2597 conn->session_ticket_cb = cb;
2598 conn->session_ticket_cb_ctx = ctx;
2599
2600 if (cb) {
2601 if (wolfSSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
2602 conn) != 1)
2603 return -1;
2604 } else {
2605 if (wolfSSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
2606 return -1;
2607 }
2608
2609 return 0;
2610 #else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2611 return -1;
2612 #endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2613 }
2614
2615
tls_connection_set_success_data_resumed(struct tls_connection * conn)2616 void tls_connection_set_success_data_resumed(struct tls_connection *conn)
2617 {
2618 wpa_printf(MSG_DEBUG,
2619 "wolfSSL: Success data accepted for resumed session");
2620 }
2621
2622
tls_connection_remove_session(struct tls_connection * conn)2623 void tls_connection_remove_session(struct tls_connection *conn)
2624 {
2625 WOLFSSL_SESSION *sess;
2626
2627 sess = wolfSSL_get_session(conn->ssl);
2628 if (!sess)
2629 return;
2630
2631 wolfSSL_SSL_SESSION_set_timeout(sess, 0);
2632 wpa_printf(MSG_DEBUG,
2633 "wolfSSL: Removed cached session to disable session resumption");
2634 }
2635
2636
tls_get_tls_unique(struct tls_connection * conn,u8 * buf,size_t max_len)2637 int tls_get_tls_unique(struct tls_connection *conn, u8 *buf, size_t max_len)
2638 {
2639 size_t len;
2640 int reused;
2641
2642 reused = wolfSSL_session_reused(conn->ssl);
2643 if ((wolfSSL_is_server(conn->ssl) && !reused) ||
2644 (!wolfSSL_is_server(conn->ssl) && reused))
2645 len = wolfSSL_get_peer_finished(conn->ssl, buf, max_len);
2646 else
2647 len = wolfSSL_get_finished(conn->ssl, buf, max_len);
2648
2649 if (len == 0 || len > max_len)
2650 return -1;
2651
2652 return len;
2653 }
2654
2655
tls_connection_get_cipher_suite(struct tls_connection * conn)2656 u16 tls_connection_get_cipher_suite(struct tls_connection *conn)
2657 {
2658 return (u16) wolfSSL_get_current_cipher_suite(conn->ssl);
2659 }
2660
2661
tls_connection_get_peer_subject(struct tls_connection * conn)2662 const char * tls_connection_get_peer_subject(struct tls_connection *conn)
2663 {
2664 if (conn)
2665 return conn->peer_subject;
2666 return NULL;
2667 }
2668
2669
tls_connection_set_success_data(struct tls_connection * conn,struct wpabuf * data)2670 void tls_connection_set_success_data(struct tls_connection *conn,
2671 struct wpabuf *data)
2672 {
2673 WOLFSSL_SESSION *sess;
2674 struct wpabuf *old;
2675
2676 wpa_printf(MSG_DEBUG, "wolfSSL: Set success data");
2677
2678 sess = wolfSSL_get_session(conn->ssl);
2679 if (!sess) {
2680 wpa_printf(MSG_DEBUG,
2681 "wolfSSL: No session found for success data");
2682 goto fail;
2683 }
2684
2685 old = wolfSSL_SESSION_get_ex_data(sess, TLS_SESSION_EX_IDX);
2686 if (old) {
2687 wpa_printf(MSG_DEBUG, "wolfSSL: Replacing old success data %p",
2688 old);
2689 wpabuf_free(old);
2690 }
2691 if (wolfSSL_SESSION_set_ex_data(sess, TLS_SESSION_EX_IDX, data) != 1)
2692 goto fail;
2693
2694 wpa_printf(MSG_DEBUG, "wolfSSL: Stored success data %p", data);
2695 conn->success_data = 1;
2696 return;
2697
2698 fail:
2699 wpa_printf(MSG_INFO, "wolfSSL: Failed to store success data");
2700 wpabuf_free(data);
2701 }
2702
2703
2704 const struct wpabuf *
tls_connection_get_success_data(struct tls_connection * conn)2705 tls_connection_get_success_data(struct tls_connection *conn)
2706 {
2707 WOLFSSL_SESSION *sess;
2708
2709 wpa_printf(MSG_DEBUG, "wolfSSL: Get success data");
2710
2711 sess = wolfSSL_get_session(conn->ssl);
2712 if (!sess)
2713 return NULL;
2714 return wolfSSL_SESSION_get_ex_data(sess, TLS_SESSION_EX_IDX);
2715 }
2716
2717
tls_connection_get_own_cert_used(struct tls_connection * conn)2718 bool tls_connection_get_own_cert_used(struct tls_connection *conn)
2719 {
2720 if (conn)
2721 return wolfSSL_get_certificate(conn->ssl) != NULL;
2722 return false;
2723 }
2724