xref: /dragonfly/contrib/wpa_supplicant/src/crypto/tls_wolfssl.c (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
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 
23 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
24 #define HAVE_AESGCM
25 #include <wolfssl/wolfcrypt/aes.h>
26 #endif
27 
28 #if !defined(CONFIG_FIPS) &&                             \
29     (defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) ||   \
30      defined(EAP_SERVER_FAST))
31 #define WOLFSSL_NEED_EAP_FAST_PRF
32 #endif
33 
34 #define SECRET_LEN          48
35 #define RAN_LEN             32
36 #define SESSION_TICKET_LEN  256
37 
38 static int tls_ref_count = 0;
39 
40 static int tls_ex_idx_session = 0;
41 
42 
43 /* tls input data for wolfSSL Read Callback */
44 struct tls_in_data {
45           const struct wpabuf *in_data;
46           size_t consumed; /* how many bytes have we used already */
47 };
48 
49 /* tls output data for wolfSSL Write Callback */
50 struct tls_out_data {
51           struct wpabuf *out_data;
52 };
53 
54 struct tls_context {
55           void (*event_cb)(void *ctx, enum tls_event ev,
56                                union tls_event_data *data);
57           void *cb_ctx;
58           int cert_in_cb;
59           char *ocsp_stapling_response;
60 };
61 
62 static struct tls_context *tls_global = NULL;
63 
64 /* wolfssl tls_connection */
65 struct tls_connection {
66           struct tls_context *context;
67           WOLFSSL *ssl;
68           int read_alerts;
69           int write_alerts;
70           int failed;
71           struct tls_in_data input;
72           struct tls_out_data output;
73           char *subject_match;
74           char *alt_subject_match;
75           char *suffix_match;
76           char *domain_match;
77 
78           u8 srv_cert_hash[32];
79 
80           unsigned char client_random[RAN_LEN];
81           unsigned char server_random[RAN_LEN];
82           unsigned int flags;
83 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
84           tls_session_ticket_cb session_ticket_cb;
85           void *session_ticket_cb_ctx;
86           byte session_ticket[SESSION_TICKET_LEN];
87 #endif
88           unsigned int ca_cert_verify:1;
89           unsigned int cert_probe:1;
90           unsigned int server_cert_only:1;
91           unsigned int success_data:1;
92 
93           WOLFSSL_X509 *peer_cert;
94           WOLFSSL_X509 *peer_issuer;
95           WOLFSSL_X509 *peer_issuer_issuer;
96 };
97 
98 
tls_context_new(const struct tls_config * conf)99 static struct tls_context * tls_context_new(const struct tls_config *conf)
100 {
101           struct tls_context *context = os_zalloc(sizeof(*context));
102 
103           if (!context)
104                     return NULL;
105 
106           if (conf) {
107                     context->event_cb = conf->event_cb;
108                     context->cb_ctx = conf->cb_ctx;
109                     context->cert_in_cb = conf->cert_in_cb;
110           }
111 
112           return context;
113 }
114 
115 
wolfssl_reset_in_data(struct tls_in_data * in,const struct wpabuf * buf)116 static void wolfssl_reset_in_data(struct tls_in_data *in,
117                                           const struct wpabuf *buf)
118 {
119           /* old one not owned by us so don't free */
120           in->in_data = buf;
121           in->consumed = 0;
122 }
123 
124 
wolfssl_reset_out_data(struct tls_out_data * out)125 static void wolfssl_reset_out_data(struct tls_out_data *out)
126 {
127           /* old one not owned by us so don't free */
128           out->out_data = wpabuf_alloc_copy("", 0);
129 }
130 
131 
132 /* wolfSSL I/O Receive CallBack */
wolfssl_receive_cb(WOLFSSL * ssl,char * buf,int sz,void * ctx)133 static int wolfssl_receive_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
134 {
135           size_t get = sz;
136           struct tls_in_data *data = ctx;
137 
138           if (!data)
139                     return -1;
140 
141           if (get > (wpabuf_len(data->in_data) - data->consumed))
142                     get = wpabuf_len(data->in_data) - data->consumed;
143 
144           os_memcpy(buf, wpabuf_head_u8(data->in_data) + data->consumed, get);
145           data->consumed += get;
146 
147           if (get == 0)
148                     return -2; /* WANT_READ */
149 
150           return (int) get;
151 }
152 
153 
154 /* wolfSSL I/O Send CallBack */
wolfssl_send_cb(WOLFSSL * ssl,char * buf,int sz,void * ctx)155 static int wolfssl_send_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
156 {
157           struct wpabuf *tmp;
158           struct tls_out_data *data = ctx;
159 
160           if (!data)
161                     return -1;
162 
163           wpa_printf(MSG_DEBUG, "SSL: adding %d bytes", sz);
164 
165           tmp = wpabuf_alloc_copy(buf, sz);
166           if (!tmp)
167                     return -1;
168           data->out_data = wpabuf_concat(data->out_data, tmp);
169           if (!data->out_data)
170                     return -1;
171 
172           return sz;
173 }
174 
175 
remove_session_cb(WOLFSSL_CTX * ctx,WOLFSSL_SESSION * sess)176 static void remove_session_cb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
177 {
178           struct wpabuf *buf;
179 
180           buf = wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
181           if (!buf)
182                     return;
183           wpa_printf(MSG_DEBUG,
184                        "wolfSSL: Free application session data %p (sess %p)",
185                        buf, sess);
186           wpabuf_free(buf);
187 
188           wolfSSL_SESSION_set_ex_data(sess, tls_ex_idx_session, NULL);
189 }
190 
191 
tls_init(const struct tls_config * conf)192 void * tls_init(const struct tls_config *conf)
193 {
194           WOLFSSL_CTX *ssl_ctx;
195           struct tls_context *context;
196           const char *ciphers;
197 
198 #ifdef DEBUG_WOLFSSL
199           wolfSSL_Debugging_ON();
200 #endif /* DEBUG_WOLFSSL */
201 
202           context = tls_context_new(conf);
203           if (!context)
204                     return NULL;
205 
206           if (tls_ref_count == 0) {
207                     tls_global = context;
208 
209                     if (wolfSSL_Init() < 0)
210                               return NULL;
211                     /* wolfSSL_Debugging_ON(); */
212           }
213 
214           tls_ref_count++;
215 
216           /* start as client */
217           ssl_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
218           if (!ssl_ctx) {
219                     tls_ref_count--;
220                     if (context != tls_global)
221                               os_free(context);
222                     if (tls_ref_count == 0) {
223                               os_free(tls_global);
224                               tls_global = NULL;
225                     }
226           }
227           wolfSSL_SetIORecv(ssl_ctx, wolfssl_receive_cb);
228           wolfSSL_SetIOSend(ssl_ctx, wolfssl_send_cb);
229           wolfSSL_CTX_set_ex_data(ssl_ctx, 0, context);
230 
231           if (conf->tls_session_lifetime > 0) {
232                     wolfSSL_CTX_set_quiet_shutdown(ssl_ctx, 1);
233                     wolfSSL_CTX_set_session_cache_mode(ssl_ctx,
234                                                                SSL_SESS_CACHE_SERVER);
235                     wolfSSL_CTX_set_timeout(ssl_ctx, conf->tls_session_lifetime);
236                     wolfSSL_CTX_sess_set_remove_cb(ssl_ctx, remove_session_cb);
237           } else {
238                     wolfSSL_CTX_set_session_cache_mode(ssl_ctx,
239                                                                SSL_SESS_CACHE_CLIENT);
240           }
241 
242           if (conf && conf->openssl_ciphers)
243                     ciphers = conf->openssl_ciphers;
244           else
245                     ciphers = "ALL";
246           if (wolfSSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) {
247                     wpa_printf(MSG_ERROR,
248                                  "wolfSSL: Failed to set cipher string '%s'",
249                                  ciphers);
250                     tls_deinit(ssl_ctx);
251                     return NULL;
252           }
253 
254           return ssl_ctx;
255 }
256 
257 
tls_deinit(void * ssl_ctx)258 void tls_deinit(void *ssl_ctx)
259 {
260           struct tls_context *context = wolfSSL_CTX_get_ex_data(ssl_ctx, 0);
261 
262           if (context != tls_global)
263                     os_free(context);
264 
265           wolfSSL_CTX_free((WOLFSSL_CTX *) ssl_ctx);
266 
267           tls_ref_count--;
268           if (tls_ref_count == 0) {
269                     wolfSSL_Cleanup();
270                     os_free(tls_global);
271                     tls_global = NULL;
272           }
273 }
274 
275 
tls_get_errors(void * tls_ctx)276 int tls_get_errors(void *tls_ctx)
277 {
278 #ifdef DEBUG_WOLFSSL
279 #if 0
280           unsigned long err;
281 
282           err = wolfSSL_ERR_peek_last_error_line(NULL, NULL);
283           if (err != 0) {
284                     wpa_printf(MSG_INFO, "TLS - SSL error: %s",
285                                  wolfSSL_ERR_error_string(err, NULL));
286                     return 1;
287           }
288 #endif
289 #endif /* DEBUG_WOLFSSL */
290           return 0;
291 }
292 
293 
tls_connection_init(void * tls_ctx)294 struct tls_connection * tls_connection_init(void *tls_ctx)
295 {
296           WOLFSSL_CTX *ssl_ctx = tls_ctx;
297           struct tls_connection *conn;
298 
299           wpa_printf(MSG_DEBUG, "SSL: connection init");
300 
301           conn = os_zalloc(sizeof(*conn));
302           if (!conn)
303                     return NULL;
304           conn->ssl = wolfSSL_new(ssl_ctx);
305           if (!conn->ssl) {
306                     os_free(conn);
307                     return NULL;
308           }
309 
310           wolfSSL_SetIOReadCtx(conn->ssl,  &conn->input);
311           wolfSSL_SetIOWriteCtx(conn->ssl, &conn->output);
312           wolfSSL_set_ex_data(conn->ssl, 0, conn);
313           conn->context = wolfSSL_CTX_get_ex_data(ssl_ctx, 0);
314 
315           /* Need randoms post-hanshake for EAP-FAST, export key and deriving
316            * session ID in EAP methods. */
317           wolfSSL_KeepArrays(conn->ssl);
318           wolfSSL_KeepHandshakeResources(conn->ssl);
319           wolfSSL_UseClientSuites(conn->ssl);
320 
321           return conn;
322 }
323 
324 
tls_connection_deinit(void * tls_ctx,struct tls_connection * conn)325 void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
326 {
327           if (!conn)
328                     return;
329 
330           wpa_printf(MSG_DEBUG, "SSL: connection deinit");
331 
332           /* parts */
333           wolfSSL_free(conn->ssl);
334           os_free(conn->subject_match);
335           os_free(conn->alt_subject_match);
336           os_free(conn->suffix_match);
337           os_free(conn->domain_match);
338 
339           /* self */
340           os_free(conn);
341 }
342 
343 
tls_connection_established(void * tls_ctx,struct tls_connection * conn)344 int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
345 {
346           return conn ? wolfSSL_is_init_finished(conn->ssl) : 0;
347 }
348 
349 
tls_connection_peer_serial_num(void * tls_ctx,struct tls_connection * conn)350 char * tls_connection_peer_serial_num(void *tls_ctx,
351                                               struct tls_connection *conn)
352 {
353           /* TODO */
354           return NULL;
355 }
356 
357 
tls_connection_shutdown(void * tls_ctx,struct tls_connection * conn)358 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
359 {
360           WOLFSSL_SESSION *session;
361 
362           if (!conn)
363                     return -1;
364 
365           wpa_printf(MSG_DEBUG, "SSL: connection shutdown");
366 
367           /* Set quiet as OpenSSL does */
368           wolfSSL_set_quiet_shutdown(conn->ssl, 1);
369           wolfSSL_shutdown(conn->ssl);
370 
371           session = wolfSSL_get_session(conn->ssl);
372           if (wolfSSL_clear(conn->ssl) != 1)
373                     return -1;
374           wolfSSL_set_session(conn->ssl, session);
375 
376           return 0;
377 }
378 
379 
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)380 static int tls_connection_set_subject_match(struct tls_connection *conn,
381                                                       const char *subject_match,
382                                                       const char *alt_subject_match,
383                                                       const char *suffix_match,
384                                                       const char *domain_match)
385 {
386           os_free(conn->subject_match);
387           conn->subject_match = NULL;
388           if (subject_match) {
389                     conn->subject_match = os_strdup(subject_match);
390                     if (!conn->subject_match)
391                               return -1;
392           }
393 
394           os_free(conn->alt_subject_match);
395           conn->alt_subject_match = NULL;
396           if (alt_subject_match) {
397                     conn->alt_subject_match = os_strdup(alt_subject_match);
398                     if (!conn->alt_subject_match)
399                               return -1;
400           }
401 
402           os_free(conn->suffix_match);
403           conn->suffix_match = NULL;
404           if (suffix_match) {
405                     conn->suffix_match = os_strdup(suffix_match);
406                     if (!conn->suffix_match)
407                               return -1;
408           }
409 
410           os_free(conn->domain_match);
411           conn->domain_match = NULL;
412           if (domain_match) {
413                     conn->domain_match = os_strdup(domain_match);
414                     if (!conn->domain_match)
415                               return -1;
416           }
417 
418           return 0;
419 }
420 
421 
tls_connection_dh(struct tls_connection * conn,const char * dh_file,const u8 * dh_blob,size_t blob_len)422 static int tls_connection_dh(struct tls_connection *conn, const char *dh_file,
423                                    const u8 *dh_blob, size_t blob_len)
424 {
425           if (!dh_file && !dh_blob)
426                     return 0;
427 
428           wolfSSL_set_accept_state(conn->ssl);
429 
430           if (dh_blob) {
431                     if (wolfSSL_SetTmpDH_buffer(conn->ssl, dh_blob, blob_len,
432                                                       SSL_FILETYPE_ASN1) < 0) {
433                               wpa_printf(MSG_INFO, "SSL: use DH DER blob failed");
434                               return -1;
435                     }
436                     wpa_printf(MSG_DEBUG, "SSL: use DH blob OK");
437                     return 0;
438           }
439 
440           if (dh_file) {
441                     wpa_printf(MSG_INFO, "SSL: use DH PEM file: %s", dh_file);
442                     if (wolfSSL_SetTmpDH_file(conn->ssl, dh_file,
443                                                     SSL_FILETYPE_PEM) < 0) {
444                               wpa_printf(MSG_INFO, "SSL: use DH PEM file failed");
445                               if (wolfSSL_SetTmpDH_file(conn->ssl, dh_file,
446                                                               SSL_FILETYPE_ASN1) < 0) {
447                                         wpa_printf(MSG_INFO,
448                                                      "SSL: use DH DER file failed");
449                                         return -1;
450                               }
451                     }
452                     wpa_printf(MSG_DEBUG, "SSL: use DH file OK");
453                     return 0;
454           }
455 
456           return 0;
457 }
458 
459 
tls_connection_client_cert(struct tls_connection * conn,const char * client_cert,const u8 * client_cert_blob,size_t blob_len)460 static int tls_connection_client_cert(struct tls_connection *conn,
461                                               const char *client_cert,
462                                               const u8 *client_cert_blob,
463                                               size_t blob_len)
464 {
465           if (!client_cert && !client_cert_blob)
466                     return 0;
467 
468           if (client_cert_blob) {
469                     if (wolfSSL_use_certificate_chain_buffer_format(
470                                   conn->ssl, client_cert_blob, blob_len,
471                                   SSL_FILETYPE_ASN1) < 0) {
472                               wpa_printf(MSG_INFO,
473                                            "SSL: use client cert DER blob failed");
474                               return -1;
475                     }
476                     wpa_printf(MSG_DEBUG, "SSL: use client cert blob OK");
477                     return 0;
478           }
479 
480           if (client_cert) {
481                     if (wolfSSL_use_certificate_chain_file(conn->ssl,
482                                                                    client_cert) < 0) {
483                               wpa_printf(MSG_INFO,
484                                            "SSL: use client cert PEM file failed");
485                               if (wolfSSL_use_certificate_chain_file_format(
486                                             conn->ssl, client_cert,
487                                             SSL_FILETYPE_ASN1) < 0) {
488                                         wpa_printf(MSG_INFO,
489                                                      "SSL: use client cert DER file failed");
490                                         return -1;
491                               }
492                     }
493                     wpa_printf(MSG_DEBUG, "SSL: use client cert file OK");
494                     return 0;
495           }
496 
497           return 0;
498 }
499 
500 
tls_passwd_cb(char * buf,int size,int rwflag,void * password)501 static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
502 {
503           if (!password)
504                     return 0;
505           os_strlcpy(buf, (char *) password, size);
506           return os_strlen(buf);
507 }
508 
509 
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)510 static int tls_connection_private_key(void *tls_ctx,
511                                               struct tls_connection *conn,
512                                               const char *private_key,
513                                               const char *private_key_passwd,
514                                               const u8 *private_key_blob,
515                                               size_t blob_len)
516 {
517           WOLFSSL_CTX *ctx = tls_ctx;
518           char *passwd = NULL;
519           int ok = 0;
520 
521           if (!private_key && !private_key_blob)
522                     return 0;
523 
524           if (private_key_passwd) {
525                     passwd = os_strdup(private_key_passwd);
526                     if (!passwd)
527                               return -1;
528           }
529 
530           wolfSSL_CTX_set_default_passwd_cb(ctx, tls_passwd_cb);
531           wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, passwd);
532 
533           if (private_key_blob) {
534                     if (wolfSSL_use_PrivateKey_buffer(conn->ssl,
535                                                               private_key_blob, blob_len,
536                                                               SSL_FILETYPE_ASN1) < 0) {
537                               wpa_printf(MSG_INFO,
538                                            "SSL: use private DER blob failed");
539                     } else {
540                               wpa_printf(MSG_DEBUG, "SSL: use private key blob OK");
541                               ok = 1;
542                     }
543           }
544 
545           if (!ok && private_key) {
546                     if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
547                                                             SSL_FILETYPE_PEM) < 0) {
548                               wpa_printf(MSG_INFO,
549                                            "SSL: use private key PEM file failed");
550                               if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
551                                                                       SSL_FILETYPE_ASN1) < 0)
552                               {
553                                         wpa_printf(MSG_INFO,
554                                                      "SSL: use private key DER file failed");
555                               } else {
556                                         ok = 1;
557                               }
558                     } else {
559                               ok = 1;
560                     }
561 
562                     if (ok)
563                               wpa_printf(MSG_DEBUG, "SSL: use private key file OK");
564           }
565 
566           wolfSSL_CTX_set_default_passwd_cb(ctx, NULL);
567           os_free(passwd);
568 
569           if (!ok)
570                     return -1;
571 
572           return 0;
573 }
574 
575 
tls_match_alt_subject_component(WOLFSSL_X509 * cert,int type,const char * value,size_t len)576 static int tls_match_alt_subject_component(WOLFSSL_X509 *cert, int type,
577                                                      const char *value, size_t len)
578 {
579           WOLFSSL_ASN1_OBJECT *gen;
580           void *ext;
581           int found = 0;
582           int i;
583 
584           ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
585 
586           for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
587                     gen = wolfSSL_sk_value(ext, i);
588                     if (gen->type != type)
589                               continue;
590                     if (os_strlen((char *) gen->obj) == len &&
591                         os_memcmp(value, gen->obj, len) == 0)
592                               found++;
593           }
594 
595           wolfSSL_sk_ASN1_OBJECT_free(ext);
596 
597           return found;
598 }
599 
600 
tls_match_alt_subject(WOLFSSL_X509 * cert,const char * match)601 static int tls_match_alt_subject(WOLFSSL_X509 *cert, const char *match)
602 {
603           int type;
604           const char *pos, *end;
605           size_t len;
606 
607           pos = match;
608           do {
609                     if (os_strncmp(pos, "EMAIL:", 6) == 0) {
610                               type = GEN_EMAIL;
611                               pos += 6;
612                     } else if (os_strncmp(pos, "DNS:", 4) == 0) {
613                               type = GEN_DNS;
614                               pos += 4;
615                     } else if (os_strncmp(pos, "URI:", 4) == 0) {
616                               type = GEN_URI;
617                               pos += 4;
618                     } else {
619                               wpa_printf(MSG_INFO,
620                                            "TLS: Invalid altSubjectName match '%s'",
621                                            pos);
622                               return 0;
623                     }
624                     end = os_strchr(pos, ';');
625                     while (end) {
626                               if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
627                                   os_strncmp(end + 1, "DNS:", 4) == 0 ||
628                                   os_strncmp(end + 1, "URI:", 4) == 0)
629                                         break;
630                               end = os_strchr(end + 1, ';');
631                     }
632                     if (end)
633                               len = end - pos;
634                     else
635                               len = os_strlen(pos);
636                     if (tls_match_alt_subject_component(cert, type, pos, len) > 0)
637                               return 1;
638                     pos = end + 1;
639           } while (end);
640 
641           return 0;
642 }
643 
644 
domain_suffix_match(const char * val,size_t len,const char * match,size_t match_len,int full)645 static int domain_suffix_match(const char *val, size_t len, const char *match,
646                                      size_t match_len, int full)
647 {
648           size_t i;
649 
650           /* Check for embedded nuls that could mess up suffix matching */
651           for (i = 0; i < len; i++) {
652                     if (val[i] == '\0') {
653                               wpa_printf(MSG_DEBUG,
654                                            "TLS: Embedded null in a string - reject");
655                               return 0;
656                     }
657           }
658 
659           if (match_len > len || (full && match_len != len))
660                     return 0;
661 
662           if (os_strncasecmp(val + len - match_len, match, match_len) != 0)
663                     return 0; /* no match */
664 
665           if (match_len == len)
666                     return 1; /* exact match */
667 
668           if (val[len - match_len - 1] == '.')
669                     return 1; /* full label match completes suffix match */
670 
671           wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match");
672           return 0;
673 }
674 
675 
tls_match_suffix_helper(WOLFSSL_X509 * cert,const char * match,size_t match_len,int full)676 static int tls_match_suffix_helper(WOLFSSL_X509 *cert, const char *match,
677                                            size_t match_len, int full)
678 {
679           WOLFSSL_ASN1_OBJECT *gen;
680           void *ext;
681           int i;
682           int j;
683           int dns_name = 0;
684           WOLFSSL_X509_NAME *name;
685 
686           wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s",
687                        full ? "" : "suffix ", match);
688 
689           ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
690 
691           for (j = 0; ext && j < wolfSSL_sk_num(ext); j++) {
692                     gen = wolfSSL_sk_value(ext, j);
693                     if (gen->type != ASN_DNS_TYPE)
694                               continue;
695                     dns_name++;
696                     wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName",
697                                           gen->obj, os_strlen((char *)gen->obj));
698                     if (domain_suffix_match((const char *) gen->obj,
699                                                   os_strlen((char *) gen->obj), match,
700                                                   match_len, full) == 1) {
701                               wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found",
702                                            full ? "Match" : "Suffix match");
703                               wolfSSL_sk_ASN1_OBJECT_free(ext);
704                               return 1;
705                     }
706           }
707           wolfSSL_sk_ASN1_OBJECT_free(ext);
708 
709           if (dns_name) {
710                     wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched");
711                     return 0;
712           }
713 
714           name = wolfSSL_X509_get_subject_name(cert);
715           i = -1;
716           for (;;) {
717                     WOLFSSL_X509_NAME_ENTRY *e;
718                     WOLFSSL_ASN1_STRING *cn;
719 
720                     i = wolfSSL_X509_NAME_get_index_by_NID(name, ASN_COMMON_NAME,
721                                                                    i);
722                     if (i == -1)
723                               break;
724                     e = wolfSSL_X509_NAME_get_entry(name, i);
725                     if (!e)
726                               continue;
727                     cn = wolfSSL_X509_NAME_ENTRY_get_data(e);
728                     if (!cn)
729                               continue;
730                     wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName",
731                                           cn->data, cn->length);
732                     if (domain_suffix_match(cn->data, cn->length,
733                                                   match, match_len, full) == 1) {
734                               wpa_printf(MSG_DEBUG, "TLS: %s in commonName found",
735                                            full ? "Match" : "Suffix match");
736                               return 1;
737                     }
738           }
739 
740           wpa_printf(MSG_DEBUG, "TLS: No CommonName %smatch found",
741                        full ? "" : "suffix ");
742           return 0;
743 }
744 
745 
tls_match_suffix(WOLFSSL_X509 * cert,const char * match,int full)746 static int tls_match_suffix(WOLFSSL_X509 *cert, const char *match, int full)
747 {
748           const char *token, *last = NULL;
749 
750           /* Process each match alternative separately until a match is found */
751           while ((token = cstr_token(match, ";", &last))) {
752                     if (tls_match_suffix_helper(cert, token, last - token, full))
753                               return 1;
754           }
755 
756           return 0;
757 }
758 
759 
wolfssl_tls_fail_reason(int err)760 static enum tls_fail_reason wolfssl_tls_fail_reason(int err)
761 {
762           switch (err) {
763           case X509_V_ERR_CERT_REVOKED:
764                     return TLS_FAIL_REVOKED;
765           case ASN_BEFORE_DATE_E:
766           case X509_V_ERR_CERT_NOT_YET_VALID:
767           case X509_V_ERR_CRL_NOT_YET_VALID:
768                     return TLS_FAIL_NOT_YET_VALID;
769           case ASN_AFTER_DATE_E:
770           case X509_V_ERR_CERT_HAS_EXPIRED:
771           case X509_V_ERR_CRL_HAS_EXPIRED:
772                     return TLS_FAIL_EXPIRED;
773           case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
774           case X509_V_ERR_UNABLE_TO_GET_CRL:
775           case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
776           case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
777           case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
778           case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
779           case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
780           case X509_V_ERR_CERT_CHAIN_TOO_LONG:
781           case X509_V_ERR_PATH_LENGTH_EXCEEDED:
782           case X509_V_ERR_INVALID_CA:
783                     return TLS_FAIL_UNTRUSTED;
784           case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
785           case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
786           case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
787           case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
788           case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
789           case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
790           case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
791           case X509_V_ERR_CERT_UNTRUSTED:
792           case X509_V_ERR_CERT_REJECTED:
793                     return TLS_FAIL_BAD_CERTIFICATE;
794           default:
795                     return TLS_FAIL_UNSPECIFIED;
796           }
797 }
798 
799 
wolfssl_tls_err_string(int err,const char * err_str)800 static const char * wolfssl_tls_err_string(int err, const char *err_str)
801 {
802           switch (err) {
803           case ASN_BEFORE_DATE_E:
804                     return "certificate is not yet valid";
805           case ASN_AFTER_DATE_E:
806                     return "certificate has expired";
807           default:
808                     return err_str;
809           }
810 }
811 
812 
get_x509_cert(WOLFSSL_X509 * cert)813 static struct wpabuf * get_x509_cert(WOLFSSL_X509 *cert)
814 {
815           struct wpabuf *buf = NULL;
816           const u8 *data;
817           int cert_len;
818 
819           data = wolfSSL_X509_get_der(cert, &cert_len);
820           if (!data)
821                     buf = wpabuf_alloc_copy(data, cert_len);
822 
823           return buf;
824 }
825 
826 
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)827 static void wolfssl_tls_fail_event(struct tls_connection *conn,
828                                            WOLFSSL_X509 *err_cert, int err, int depth,
829                                            const char *subject, const char *err_str,
830                                            enum tls_fail_reason reason)
831 {
832           union tls_event_data ev;
833           struct wpabuf *cert = NULL;
834           struct tls_context *context = conn->context;
835 
836           if (!context->event_cb)
837                     return;
838 
839           cert = get_x509_cert(err_cert);
840           os_memset(&ev, 0, sizeof(ev));
841           ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ?
842                     reason : wolfssl_tls_fail_reason(err);
843           ev.cert_fail.depth = depth;
844           ev.cert_fail.subject = subject;
845           ev.cert_fail.reason_txt = wolfssl_tls_err_string(err, err_str);
846           ev.cert_fail.cert = cert;
847           context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
848           wpabuf_free(cert);
849 }
850 
851 
wolfssl_tls_cert_event(struct tls_connection * conn,WOLFSSL_X509 * err_cert,int depth,const char * subject)852 static void wolfssl_tls_cert_event(struct tls_connection *conn,
853                                            WOLFSSL_X509 *err_cert, int depth,
854                                            const char *subject)
855 {
856           struct wpabuf *cert = NULL;
857           union tls_event_data ev;
858           struct tls_context *context = conn->context;
859           char *alt_subject[TLS_MAX_ALT_SUBJECT];
860           int alt, num_alt_subject = 0;
861           WOLFSSL_ASN1_OBJECT *gen;
862           void *ext;
863           int i;
864 #ifdef CONFIG_SHA256
865           u8 hash[32];
866 #endif /* CONFIG_SHA256 */
867 
868           if (!context->event_cb)
869                     return;
870 
871           os_memset(&ev, 0, sizeof(ev));
872           if (conn->cert_probe || (conn->flags & TLS_CONN_EXT_CERT_CHECK) ||
873               context->cert_in_cb) {
874                     cert = get_x509_cert(err_cert);
875                     ev.peer_cert.cert = cert;
876           }
877 
878 #ifdef CONFIG_SHA256
879           if (cert) {
880                     const u8 *addr[1];
881                     size_t len[1];
882 
883                     addr[0] = wpabuf_head(cert);
884                     len[0] = wpabuf_len(cert);
885                     if (sha256_vector(1, addr, len, hash) == 0) {
886                               ev.peer_cert.hash = hash;
887                               ev.peer_cert.hash_len = sizeof(hash);
888                     }
889           }
890 #endif /* CONFIG_SHA256 */
891 
892           ev.peer_cert.depth = depth;
893           ev.peer_cert.subject = subject;
894 
895           ext = wolfSSL_X509_get_ext_d2i(err_cert, ALT_NAMES_OID, NULL, NULL);
896           for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
897                     char *pos;
898 
899                     if (num_alt_subject == TLS_MAX_ALT_SUBJECT)
900                               break;
901                     gen = wolfSSL_sk_value((void *) ext, i);
902                     if (gen->type != GEN_EMAIL &&
903                         gen->type != GEN_DNS &&
904                         gen->type != GEN_URI)
905                               continue;
906 
907                     pos = os_malloc(10 + os_strlen((char *) gen->obj) + 1);
908                     if (!pos)
909                               break;
910                     alt_subject[num_alt_subject++] = pos;
911 
912                     switch (gen->type) {
913                     case GEN_EMAIL:
914                               os_memcpy(pos, "EMAIL:", 6);
915                               pos += 6;
916                               break;
917                     case GEN_DNS:
918                               os_memcpy(pos, "DNS:", 4);
919                               pos += 4;
920                               break;
921                     case GEN_URI:
922                               os_memcpy(pos, "URI:", 4);
923                               pos += 4;
924                               break;
925                     }
926 
927                     os_memcpy(pos, gen->obj, os_strlen((char *)gen->obj));
928                     pos += os_strlen((char *)gen->obj);
929                     *pos = '\0';
930           }
931           wolfSSL_sk_ASN1_OBJECT_free(ext);
932 
933           for (alt = 0; alt < num_alt_subject; alt++)
934                     ev.peer_cert.altsubject[alt] = alt_subject[alt];
935           ev.peer_cert.num_altsubject = num_alt_subject;
936 
937           context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
938           wpabuf_free(cert);
939           for (alt = 0; alt < num_alt_subject; alt++)
940                     os_free(alt_subject[alt]);
941 }
942 
943 
tls_verify_cb(int preverify_ok,WOLFSSL_X509_STORE_CTX * x509_ctx)944 static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx)
945 {
946           char buf[256];
947           WOLFSSL_X509 *err_cert;
948           int err, depth;
949           WOLFSSL *ssl;
950           struct tls_connection *conn;
951           struct tls_context *context;
952           char *match, *altmatch, *suffix_match, *domain_match;
953           const char *err_str;
954 
955           err_cert = wolfSSL_X509_STORE_CTX_get_current_cert(x509_ctx);
956           if (!err_cert) {
957                     wpa_printf(MSG_DEBUG, "wolfSSL: No Cert");
958                     return 0;
959           }
960 
961           err = wolfSSL_X509_STORE_CTX_get_error(x509_ctx);
962           depth = wolfSSL_X509_STORE_CTX_get_error_depth(x509_ctx);
963           ssl = wolfSSL_X509_STORE_CTX_get_ex_data(
964                     x509_ctx, wolfSSL_get_ex_data_X509_STORE_CTX_idx());
965           wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(err_cert), buf,
966                                           sizeof(buf));
967 
968           conn = wolfSSL_get_ex_data(ssl, 0);
969           if (!conn) {
970                     wpa_printf(MSG_DEBUG, "wolfSSL: No ex_data");
971                     return 0;
972           }
973 
974           if (depth == 0)
975                     conn->peer_cert = err_cert;
976           else if (depth == 1)
977                     conn->peer_issuer = err_cert;
978           else if (depth == 2)
979                     conn->peer_issuer_issuer = err_cert;
980 
981           context = conn->context;
982           match = conn->subject_match;
983           altmatch = conn->alt_subject_match;
984           suffix_match = conn->suffix_match;
985           domain_match = conn->domain_match;
986 
987           if (!preverify_ok && !conn->ca_cert_verify)
988                     preverify_ok = 1;
989           if (!preverify_ok && depth > 0 && conn->server_cert_only)
990                     preverify_ok = 1;
991           if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) &&
992               (err == X509_V_ERR_CERT_HAS_EXPIRED ||
993                err == ASN_AFTER_DATE_E || err == ASN_BEFORE_DATE_E ||
994                err == X509_V_ERR_CERT_NOT_YET_VALID)) {
995                     wpa_printf(MSG_DEBUG,
996                                  "wolfSSL: Ignore certificate validity time mismatch");
997                     preverify_ok = 1;
998           }
999 
1000           err_str = wolfSSL_X509_verify_cert_error_string(err);
1001 
1002 #ifdef CONFIG_SHA256
1003           /*
1004            * Do not require preverify_ok so we can explicity allow otherwise
1005            * invalid pinned server certificates.
1006            */
1007           if (depth == 0 && conn->server_cert_only) {
1008                     struct wpabuf *cert;
1009 
1010                     cert = get_x509_cert(err_cert);
1011                     if (!cert) {
1012                               wpa_printf(MSG_DEBUG,
1013                                            "wolfSSL: Could not fetch server certificate data");
1014                               preverify_ok = 0;
1015                     } else {
1016                               u8 hash[32];
1017                               const u8 *addr[1];
1018                               size_t len[1];
1019 
1020                               addr[0] = wpabuf_head(cert);
1021                               len[0] = wpabuf_len(cert);
1022                               if (sha256_vector(1, addr, len, hash) < 0 ||
1023                                   os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
1024                                         err_str = "Server certificate mismatch";
1025                                         err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
1026                                         preverify_ok = 0;
1027                               } else if (!preverify_ok) {
1028                                         /*
1029                                          * Certificate matches pinned certificate, allow
1030                                          * regardless of other problems.
1031                                          */
1032                                         wpa_printf(MSG_DEBUG,
1033                                                      "wolfSSL: Ignore validation issues for a pinned server certificate");
1034                                         preverify_ok = 1;
1035                               }
1036                               wpabuf_free(cert);
1037                     }
1038           }
1039 #endif /* CONFIG_SHA256 */
1040 
1041           if (!preverify_ok) {
1042                     wpa_printf(MSG_WARNING,
1043                                  "TLS: Certificate verification failed, error %d (%s) depth %d for '%s'",
1044                                  err, err_str, depth, buf);
1045                     wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1046                                                err_str, TLS_FAIL_UNSPECIFIED);
1047                     return preverify_ok;
1048           }
1049 
1050           wpa_printf(MSG_DEBUG,
1051                        "TLS: %s - preverify_ok=%d err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
1052                        __func__, preverify_ok, err, err_str,
1053                        conn->ca_cert_verify, depth, buf);
1054           if (depth == 0 && match && os_strstr(buf, match) == NULL) {
1055                     wpa_printf(MSG_WARNING,
1056                                  "TLS: Subject '%s' did not match with '%s'",
1057                                  buf, match);
1058                     preverify_ok = 0;
1059                     wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1060                                                "Subject mismatch",
1061                                                TLS_FAIL_SUBJECT_MISMATCH);
1062           } else if (depth == 0 && altmatch &&
1063                        !tls_match_alt_subject(err_cert, altmatch)) {
1064                     wpa_printf(MSG_WARNING,
1065                                  "TLS: altSubjectName match '%s' not found",
1066                                  altmatch);
1067                     preverify_ok = 0;
1068                     wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1069                                                "AltSubject mismatch",
1070                                                TLS_FAIL_ALTSUBJECT_MISMATCH);
1071           } else if (depth == 0 && suffix_match &&
1072                        !tls_match_suffix(err_cert, suffix_match, 0)) {
1073                     wpa_printf(MSG_WARNING,
1074                                  "TLS: Domain suffix match '%s' not found",
1075                                  suffix_match);
1076                     preverify_ok = 0;
1077                     wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1078                                                "Domain suffix mismatch",
1079                                                TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
1080           } else if (depth == 0 && domain_match &&
1081                        !tls_match_suffix(err_cert, domain_match, 1)) {
1082                     wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found",
1083                                  domain_match);
1084                     preverify_ok = 0;
1085                     wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1086                                                "Domain mismatch",
1087                                                TLS_FAIL_DOMAIN_MISMATCH);
1088           } else {
1089                     wolfssl_tls_cert_event(conn, err_cert, depth, buf);
1090           }
1091 
1092           if (conn->cert_probe && preverify_ok && depth == 0) {
1093                     wpa_printf(MSG_DEBUG,
1094                                  "wolfSSL: Reject server certificate on probe-only run");
1095                     preverify_ok = 0;
1096                     wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1097                                                "Server certificate chain probe",
1098                                                TLS_FAIL_SERVER_CHAIN_PROBE);
1099           }
1100 
1101 #ifdef HAVE_OCSP_WOLFSSL
1102           if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) &&
1103               preverify_ok) {
1104                     enum ocsp_result res;
1105 
1106                     res = check_ocsp_resp(conn->ssl_ctx, conn->ssl, err_cert,
1107                                               conn->peer_issuer,
1108                                               conn->peer_issuer_issuer);
1109                     if (res == OCSP_REVOKED) {
1110                               preverify_ok = 0;
1111                               wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1112                                                          "certificate revoked",
1113                                                          TLS_FAIL_REVOKED);
1114                               if (err == X509_V_OK)
1115                                         X509_STORE_CTX_set_error(
1116                                                   x509_ctx, X509_V_ERR_CERT_REVOKED);
1117                     } else if (res != OCSP_GOOD &&
1118                                  (conn->flags & TLS_CONN_REQUIRE_OCSP)) {
1119                               preverify_ok = 0;
1120                               wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1121                                                          "bad certificate status response",
1122                                                          TLS_FAIL_UNSPECIFIED);
1123                     }
1124           }
1125 #endif /* HAVE_OCSP_WOLFSSL */
1126           if (depth == 0 && preverify_ok && context->event_cb != NULL)
1127                     context->event_cb(context->cb_ctx,
1128                                           TLS_CERT_CHAIN_SUCCESS, NULL);
1129 
1130           return preverify_ok;
1131 }
1132 
1133 
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)1134 static int tls_connection_ca_cert(void *tls_ctx, struct tls_connection *conn,
1135                                           const char *ca_cert,
1136                                           const u8 *ca_cert_blob, size_t blob_len,
1137                                           const char *ca_path)
1138 {
1139           WOLFSSL_CTX *ctx = tls_ctx;
1140 
1141           wolfSSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
1142           conn->ca_cert_verify = 1;
1143 
1144           if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) {
1145                     wpa_printf(MSG_DEBUG,
1146                                  "wolfSSL: Probe for server certificate chain");
1147                     conn->cert_probe = 1;
1148                     conn->ca_cert_verify = 0;
1149                     return 0;
1150           }
1151 
1152           if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) {
1153 #ifdef CONFIG_SHA256
1154                     const char *pos = ca_cert + 7;
1155 
1156                     if (os_strncmp(pos, "server/sha256/", 14) != 0) {
1157                               wpa_printf(MSG_DEBUG,
1158                                            "wolfSSL: Unsupported ca_cert hash value '%s'",
1159                                            ca_cert);
1160                               return -1;
1161                     }
1162                     pos += 14;
1163                     if (os_strlen(pos) != 32 * 2) {
1164                               wpa_printf(MSG_DEBUG,
1165                                            "wolfSSL: Unexpected SHA256 hash length in ca_cert '%s'",
1166                                            ca_cert);
1167                               return -1;
1168                     }
1169                     if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) {
1170                               wpa_printf(MSG_DEBUG,
1171                                            "wolfSSL: Invalid SHA256 hash value in ca_cert '%s'",
1172                                            ca_cert);
1173                               return -1;
1174                     }
1175                     conn->server_cert_only = 1;
1176                     wpa_printf(MSG_DEBUG,
1177                                  "wolfSSL: Checking only server certificate match");
1178                     return 0;
1179 #else /* CONFIG_SHA256 */
1180                     wpa_printf(MSG_INFO,
1181                                  "No SHA256 included in the build - cannot validate server certificate hash");
1182                     return -1;
1183 #endif /* CONFIG_SHA256 */
1184           }
1185 
1186           if (ca_cert_blob) {
1187                     if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_blob, blob_len,
1188                                                                SSL_FILETYPE_ASN1) !=
1189                         SSL_SUCCESS) {
1190                               wpa_printf(MSG_INFO, "SSL: failed to load CA blob");
1191                               return -1;
1192                     }
1193                     wpa_printf(MSG_DEBUG, "SSL: use CA cert blob OK");
1194                     return 0;
1195           }
1196 
1197           if (ca_cert || ca_path) {
1198                     WOLFSSL_X509_STORE *cm = wolfSSL_X509_STORE_new();
1199 
1200                     if (!cm) {
1201                               wpa_printf(MSG_INFO,
1202                                            "SSL: failed to create certificate store");
1203                               return -1;
1204                     }
1205                     wolfSSL_CTX_set_cert_store(ctx, cm);
1206 
1207                     if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, ca_path) !=
1208                         SSL_SUCCESS) {
1209                               wpa_printf(MSG_INFO,
1210                                            "SSL: failed to load ca_cert as PEM");
1211 
1212                               if (!ca_cert)
1213                                         return -1;
1214 
1215                               if (wolfSSL_CTX_der_load_verify_locations(
1216                                             ctx, ca_cert, SSL_FILETYPE_ASN1) !=
1217                                   SSL_SUCCESS) {
1218                                         wpa_printf(MSG_INFO,
1219                                                      "SSL: failed to load ca_cert as DER");
1220                                         return -1;
1221                               }
1222                     }
1223                     return 0;
1224           }
1225 
1226           conn->ca_cert_verify = 0;
1227           return 0;
1228 }
1229 
1230 
tls_set_conn_flags(WOLFSSL * ssl,unsigned int flags)1231 static void tls_set_conn_flags(WOLFSSL *ssl, unsigned int flags)
1232 {
1233 #ifdef HAVE_SESSION_TICKET
1234 #if 0
1235           if (!(flags & TLS_CONN_DISABLE_SESSION_TICKET))
1236                     wolfSSL_UseSessionTicket(ssl);
1237 #endif
1238 #endif /* HAVE_SESSION_TICKET */
1239 
1240           if (flags & TLS_CONN_DISABLE_TLSv1_0)
1241                     wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1);
1242           if (flags & TLS_CONN_DISABLE_TLSv1_1)
1243                     wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
1244           if (flags & TLS_CONN_DISABLE_TLSv1_2)
1245                     wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1_2);
1246 }
1247 
1248 
tls_connection_set_params(void * tls_ctx,struct tls_connection * conn,const struct tls_connection_params * params)1249 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
1250                                     const struct tls_connection_params *params)
1251 {
1252           wpa_printf(MSG_DEBUG, "SSL: set params");
1253 
1254           if (tls_connection_set_subject_match(conn, params->subject_match,
1255                                                        params->altsubject_match,
1256                                                        params->suffix_match,
1257                                                        params->domain_match) < 0) {
1258                     wpa_printf(MSG_INFO, "Error setting subject match");
1259                     return -1;
1260           }
1261 
1262           if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert,
1263                                            params->ca_cert_blob,
1264                                            params->ca_cert_blob_len,
1265                                            params->ca_path) < 0) {
1266                     wpa_printf(MSG_INFO, "Error setting CA cert");
1267                     return -1;
1268           }
1269 
1270           if (tls_connection_client_cert(conn, params->client_cert,
1271                                                params->client_cert_blob,
1272                                                params->client_cert_blob_len) < 0) {
1273                     wpa_printf(MSG_INFO, "Error setting client cert");
1274                     return -1;
1275           }
1276 
1277           if (tls_connection_private_key(tls_ctx, conn, params->private_key,
1278                                                params->private_key_passwd,
1279                                                params->private_key_blob,
1280                                                params->private_key_blob_len) < 0) {
1281                     wpa_printf(MSG_INFO, "Error setting private key");
1282                     return -1;
1283           }
1284 
1285           if (tls_connection_dh(conn, params->dh_file, params->dh_blob,
1286                                     params->dh_blob_len) < 0) {
1287                     wpa_printf(MSG_INFO, "Error setting DH");
1288                     return -1;
1289           }
1290 
1291           if (params->openssl_ciphers &&
1292               wolfSSL_set_cipher_list(conn->ssl, params->openssl_ciphers) != 1) {
1293                     wpa_printf(MSG_INFO,
1294                                  "wolfSSL: Failed to set cipher string '%s'",
1295                                  params->openssl_ciphers);
1296                     return -1;
1297           }
1298 
1299           tls_set_conn_flags(conn->ssl, params->flags);
1300 
1301 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
1302           if (params->flags & TLS_CONN_REQUEST_OCSP) {
1303                     if (wolfSSL_UseOCSPStapling(conn->ssl, WOLFSSL_CSR_OCSP,
1304                                                       WOLFSSL_CSR_OCSP_USE_NONCE) !=
1305                         SSL_SUCCESS)
1306                               return -1;
1307                     wolfSSL_CTX_EnableOCSP(tls_ctx, 0);
1308           }
1309 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
1310 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
1311           if (params->flags & TLS_CONN_REQUEST_OCSP) {
1312                     if (wolfSSL_UseOCSPStaplingV2(conn->ssl,
1313                                                         WOLFSSL_CSR2_OCSP_MULTI, 0) !=
1314                         SSL_SUCCESS)
1315                               return -1;
1316                     wolfSSL_CTX_EnableOCSP(tls_ctx, 0);
1317           }
1318 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
1319 #if !defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
1320     !defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
1321 #ifdef HAVE_OCSP
1322           if (params->flags & TLS_CONN_REQUEST_OCSP)
1323                     wolfSSL_CTX_EnableOCSP(ctx, 0);
1324 #else /* HAVE_OCSP */
1325           if (params->flags & TLS_CONN_REQUIRE_OCSP) {
1326                     wpa_printf(MSG_INFO,
1327                                  "wolfSSL: No OCSP support included - reject configuration");
1328                     return -1;
1329           }
1330           if (params->flags & TLS_CONN_REQUEST_OCSP) {
1331                     wpa_printf(MSG_DEBUG,
1332                                  "wolfSSL: No OCSP support included - allow optional OCSP case to continue");
1333           }
1334 #endif /* HAVE_OCSP */
1335 #endif /* !HAVE_CERTIFICATE_STATUS_REQUEST &&
1336           * !HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
1337 
1338           conn->flags = params->flags;
1339 
1340           return 0;
1341 }
1342 
1343 
tls_global_ca_cert(void * ssl_ctx,const char * ca_cert)1344 static int tls_global_ca_cert(void *ssl_ctx, const char *ca_cert)
1345 {
1346           WOLFSSL_CTX *ctx = ssl_ctx;
1347 
1348           if (ca_cert) {
1349                     if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, NULL) != 1)
1350                     {
1351                               wpa_printf(MSG_WARNING,
1352                                            "Failed to load root certificates");
1353                               return -1;
1354                     }
1355 
1356                     wpa_printf(MSG_DEBUG,
1357                                  "TLS: Trusted root certificate(s) loaded");
1358           }
1359 
1360           return 0;
1361 }
1362 
1363 
tls_global_client_cert(void * ssl_ctx,const char * client_cert)1364 static int tls_global_client_cert(void *ssl_ctx, const char *client_cert)
1365 {
1366           WOLFSSL_CTX *ctx = ssl_ctx;
1367 
1368           if (!client_cert)
1369                     return 0;
1370 
1371           if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, client_cert,
1372                                                                         SSL_FILETYPE_ASN1) !=
1373               SSL_SUCCESS &&
1374               wolfSSL_CTX_use_certificate_chain_file(ctx, client_cert) !=
1375               SSL_SUCCESS) {
1376                     wpa_printf(MSG_INFO, "Failed to load client certificate");
1377                     return -1;
1378           }
1379 
1380           wpa_printf(MSG_DEBUG, "SSL: Loaded global client certificate: %s",
1381                        client_cert);
1382 
1383           return 0;
1384 }
1385 
1386 
tls_global_private_key(void * ssl_ctx,const char * private_key,const char * private_key_passwd)1387 static int tls_global_private_key(void *ssl_ctx, const char *private_key,
1388                                           const char *private_key_passwd)
1389 {
1390           WOLFSSL_CTX *ctx = ssl_ctx;
1391           char *passwd = NULL;
1392           int ret = 0;
1393 
1394           if (!private_key)
1395                     return 0;
1396 
1397           if (private_key_passwd) {
1398                     passwd = os_strdup(private_key_passwd);
1399                     if (!passwd)
1400                               return -1;
1401           }
1402 
1403           wolfSSL_CTX_set_default_passwd_cb(ctx, tls_passwd_cb);
1404           wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, passwd);
1405 
1406           if (wolfSSL_CTX_use_PrivateKey_file(ctx, private_key,
1407                                                       SSL_FILETYPE_ASN1) != 1 &&
1408               wolfSSL_CTX_use_PrivateKey_file(ctx, private_key,
1409                                                       SSL_FILETYPE_PEM) != 1) {
1410                     wpa_printf(MSG_INFO, "Failed to load private key");
1411                     ret = -1;
1412           }
1413 
1414           wpa_printf(MSG_DEBUG, "SSL: Loaded global private key");
1415 
1416           os_free(passwd);
1417           wolfSSL_CTX_set_default_passwd_cb(ctx, NULL);
1418 
1419           return ret;
1420 }
1421 
1422 
tls_global_dh(void * ssl_ctx,const char * dh_file,const u8 * dh_blob,size_t blob_len)1423 static int tls_global_dh(void *ssl_ctx, const char *dh_file,
1424                                const u8 *dh_blob, size_t blob_len)
1425 {
1426           WOLFSSL_CTX *ctx = ssl_ctx;
1427 
1428           if (!dh_file && !dh_blob)
1429                     return 0;
1430 
1431           if (dh_blob) {
1432                     if (wolfSSL_CTX_SetTmpDH_buffer(ctx, dh_blob, blob_len,
1433                                                             SSL_FILETYPE_ASN1) < 0) {
1434                               wpa_printf(MSG_INFO,
1435                                            "SSL: global use DH DER blob failed");
1436                               return -1;
1437                     }
1438                     wpa_printf(MSG_DEBUG, "SSL: global use DH blob OK");
1439                     return 0;
1440           }
1441 
1442           if (dh_file) {
1443                     if (wolfSSL_CTX_SetTmpDH_file(ctx, dh_file, SSL_FILETYPE_PEM) <
1444                         0) {
1445                               wpa_printf(MSG_INFO,
1446                                            "SSL: global use DH PEM file failed");
1447                               if (wolfSSL_CTX_SetTmpDH_file(ctx, dh_file,
1448                                                                   SSL_FILETYPE_ASN1) < 0) {
1449                                         wpa_printf(MSG_INFO,
1450                                                      "SSL: global use DH DER file failed");
1451                                         return -1;
1452                               }
1453                     }
1454                     wpa_printf(MSG_DEBUG, "SSL: global use DH file OK");
1455                     return 0;
1456           }
1457 
1458           return 0;
1459 }
1460 
1461 
1462 #ifdef HAVE_OCSP
1463 
ocsp_status_cb(void * unused,const char * url,int url_sz,unsigned char * request,int request_sz,unsigned char ** response)1464 int ocsp_status_cb(void *unused, const char *url, int url_sz,
1465                        unsigned char *request, int request_sz,
1466                        unsigned char **response)
1467 {
1468           size_t len;
1469 
1470           (void) unused;
1471 
1472           if (!url) {
1473                     wpa_printf(MSG_DEBUG,
1474                                  "wolfSSL: OCSP status callback - no response configured");
1475                     *response = NULL;
1476                     return 0;
1477           }
1478 
1479           *response = (unsigned char *) os_readfile(url, &len);
1480           if (!*response) {
1481                     wpa_printf(MSG_DEBUG,
1482                                  "wolfSSL: OCSP status callback - could not read response file");
1483                     return -1;
1484           }
1485           wpa_printf(MSG_DEBUG,
1486                        "wolfSSL: OCSP status callback - send cached response");
1487           return len;
1488 }
1489 
1490 
ocsp_resp_free_cb(void * ocsp_stapling_response,unsigned char * response)1491 void ocsp_resp_free_cb(void *ocsp_stapling_response, unsigned char *response)
1492 {
1493           os_free(response);
1494 }
1495 
1496 #endif /* HAVE_OCSP */
1497 
1498 
tls_global_set_params(void * tls_ctx,const struct tls_connection_params * params)1499 int tls_global_set_params(void *tls_ctx,
1500                                 const struct tls_connection_params *params)
1501 {
1502           wpa_printf(MSG_DEBUG, "SSL: global set params");
1503 
1504           if (params->check_cert_subject)
1505                     return -1; /* not yet supported */
1506 
1507           if (tls_global_ca_cert(tls_ctx, params->ca_cert) < 0) {
1508                     wpa_printf(MSG_INFO, "SSL: Failed to load ca cert file '%s'",
1509                                  params->ca_cert);
1510                     return -1;
1511           }
1512 
1513           if (tls_global_client_cert(tls_ctx, params->client_cert) < 0) {
1514                     wpa_printf(MSG_INFO,
1515                                  "SSL: Failed to load client cert file '%s'",
1516                                  params->client_cert);
1517                     return -1;
1518           }
1519 
1520           if (tls_global_private_key(tls_ctx, params->private_key,
1521                                            params->private_key_passwd) < 0) {
1522                     wpa_printf(MSG_INFO,
1523                                  "SSL: Failed to load private key file '%s'",
1524                                  params->private_key);
1525                     return -1;
1526           }
1527 
1528           if (tls_global_dh(tls_ctx, params->dh_file, params->dh_blob,
1529                                 params->dh_blob_len) < 0) {
1530                     wpa_printf(MSG_INFO, "SSL: Failed to load DH file '%s'",
1531                                  params->dh_file);
1532                     return -1;
1533           }
1534 
1535           if (params->openssl_ciphers &&
1536               wolfSSL_CTX_set_cipher_list(tls_ctx,
1537                                                   params->openssl_ciphers) != 1) {
1538                     wpa_printf(MSG_INFO,
1539                                  "wolfSSL: Failed to set cipher string '%s'",
1540                                  params->openssl_ciphers);
1541                     return -1;
1542           }
1543 
1544           if (params->openssl_ecdh_curves) {
1545                     wpa_printf(MSG_INFO,
1546                                  "wolfSSL: openssl_ecdh_curves not supported");
1547                     return -1;
1548           }
1549 
1550 #ifdef HAVE_SESSION_TICKET
1551           /* Session ticket is off by default - can't disable once on. */
1552           if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET))
1553                     wolfSSL_CTX_UseSessionTicket(tls_ctx);
1554 #endif /* HAVE_SESSION_TICKET */
1555 
1556 #ifdef HAVE_OCSP
1557           if (params->ocsp_stapling_response) {
1558                     wolfSSL_CTX_SetOCSP_OverrideURL(tls_ctx,
1559                                                             params->ocsp_stapling_response);
1560                     wolfSSL_CTX_SetOCSP_Cb(tls_ctx, ocsp_status_cb,
1561                                                ocsp_resp_free_cb, NULL);
1562           }
1563 #endif /* HAVE_OCSP */
1564 
1565           return 0;
1566 }
1567 
1568 
tls_global_set_verify(void * tls_ctx,int check_crl,int strict)1569 int tls_global_set_verify(void *tls_ctx, int check_crl, int strict)
1570 {
1571           wpa_printf(MSG_DEBUG, "SSL: global set verify: %d", check_crl);
1572 
1573           if (check_crl) {
1574                     /* Hack to Enable CRLs. */
1575                     wolfSSL_CTX_LoadCRLBuffer(tls_ctx, NULL, 0, SSL_FILETYPE_PEM);
1576           }
1577 
1578           return 0;
1579 }
1580 
1581 
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)1582 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
1583                                     int verify_peer, unsigned int flags,
1584                                     const u8 *session_ctx, size_t session_ctx_len)
1585 {
1586           if (!conn)
1587                     return -1;
1588 
1589           wpa_printf(MSG_DEBUG, "SSL: set verify: %d", verify_peer);
1590 
1591           if (verify_peer) {
1592                     conn->ca_cert_verify = 1;
1593                     wolfSSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
1594                                            SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1595                                            tls_verify_cb);
1596           } else {
1597                     conn->ca_cert_verify = 0;
1598                     wolfSSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
1599           }
1600 
1601           wolfSSL_set_accept_state(conn->ssl);
1602 
1603           /* TODO: do we need to fake a session like OpenSSL does here? */
1604 
1605           return 0;
1606 }
1607 
1608 
wolfssl_handshake(struct tls_connection * conn,const struct wpabuf * in_data,int server)1609 static struct wpabuf * wolfssl_handshake(struct tls_connection *conn,
1610                                                    const struct wpabuf *in_data,
1611                                                    int server)
1612 {
1613           int res;
1614 
1615           wolfssl_reset_out_data(&conn->output);
1616 
1617           /* Initiate TLS handshake or continue the existing handshake */
1618           if (server) {
1619                     wolfSSL_set_accept_state(conn->ssl);
1620                     res = wolfSSL_accept(conn->ssl);
1621                     wpa_printf(MSG_DEBUG, "SSL: wolfSSL_accept: %d", res);
1622           } else {
1623                     wolfSSL_set_connect_state(conn->ssl);
1624                     res = wolfSSL_connect(conn->ssl);
1625                     wpa_printf(MSG_DEBUG, "SSL: wolfSSL_connect: %d", res);
1626           }
1627 
1628           if (res != 1) {
1629                     int err = wolfSSL_get_error(conn->ssl, res);
1630 
1631                     if (err == SSL_ERROR_WANT_READ) {
1632                               wpa_printf(MSG_DEBUG,
1633                                            "SSL: wolfSSL_connect - want more data");
1634                     } else if (err == SSL_ERROR_WANT_WRITE) {
1635                               wpa_printf(MSG_DEBUG,
1636                                            "SSL: wolfSSL_connect - want to write");
1637                     } else {
1638                               char msg[80];
1639 
1640                               wpa_printf(MSG_DEBUG,
1641                                            "SSL: wolfSSL_connect - failed %s",
1642                                            wolfSSL_ERR_error_string(err, msg));
1643                               conn->failed++;
1644                     }
1645           }
1646 
1647           return conn->output.out_data;
1648 }
1649 
1650 
wolfssl_get_appl_data(struct tls_connection * conn,size_t max_len)1651 static struct wpabuf * wolfssl_get_appl_data(struct tls_connection *conn,
1652                                                        size_t max_len)
1653 {
1654           int res;
1655           struct wpabuf *appl_data = wpabuf_alloc(max_len + 100);
1656 
1657           if (!appl_data)
1658                     return NULL;
1659 
1660           res = wolfSSL_read(conn->ssl, wpabuf_mhead(appl_data),
1661                                  wpabuf_size(appl_data));
1662           if (res < 0) {
1663                     int err = wolfSSL_get_error(conn->ssl, res);
1664 
1665                     if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1666                               wpa_printf(MSG_DEBUG,
1667                                            "SSL: No Application Data included");
1668                     } else {
1669                               char msg[80];
1670 
1671                               wpa_printf(MSG_DEBUG,
1672                                            "Failed to read possible Application Data %s",
1673                                            wolfSSL_ERR_error_string(err, msg));
1674                     }
1675 
1676                     wpabuf_free(appl_data);
1677                     return NULL;
1678           }
1679 
1680           wpabuf_put(appl_data, res);
1681           wpa_hexdump_buf_key(MSG_MSGDUMP,
1682                                   "SSL: Application Data in Finished message",
1683                                   appl_data);
1684           return appl_data;
1685 }
1686 
1687 
1688 static struct wpabuf *
wolfssl_connection_handshake(struct tls_connection * conn,const struct wpabuf * in_data,struct wpabuf ** appl_data,int server)1689 wolfssl_connection_handshake(struct tls_connection *conn,
1690                                    const struct wpabuf *in_data,
1691                                    struct wpabuf **appl_data, int server)
1692 {
1693           struct wpabuf *out_data;
1694 
1695           wolfssl_reset_in_data(&conn->input, in_data);
1696 
1697           if (appl_data)
1698                     *appl_data = NULL;
1699 
1700           out_data = wolfssl_handshake(conn, in_data, server);
1701           if (!out_data)
1702                     return NULL;
1703 
1704           if (wolfSSL_is_init_finished(conn->ssl)) {
1705                     wpa_printf(MSG_DEBUG,
1706                                  "wolfSSL: Handshake finished - resumed=%d",
1707                                  tls_connection_resumed(NULL, conn));
1708                     if (appl_data && in_data)
1709                               *appl_data = wolfssl_get_appl_data(conn,
1710                                                                          wpabuf_len(in_data));
1711           }
1712 
1713           return out_data;
1714 }
1715 
1716 
tls_connection_handshake(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data,struct wpabuf ** appl_data)1717 struct wpabuf * tls_connection_handshake(void *tls_ctx,
1718                                                    struct tls_connection *conn,
1719                                                    const struct wpabuf *in_data,
1720                                                    struct wpabuf **appl_data)
1721 {
1722           return wolfssl_connection_handshake(conn, in_data, appl_data, 0);
1723 }
1724 
1725 
tls_connection_server_handshake(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data,struct wpabuf ** appl_data)1726 struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
1727                                                             struct tls_connection *conn,
1728                                                             const struct wpabuf *in_data,
1729                                                             struct wpabuf **appl_data)
1730 {
1731           return wolfssl_connection_handshake(conn, in_data, appl_data, 1);
1732 }
1733 
1734 
tls_connection_encrypt(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data)1735 struct wpabuf * tls_connection_encrypt(void *tls_ctx,
1736                                                struct tls_connection *conn,
1737                                                const struct wpabuf *in_data)
1738 {
1739           int res;
1740 
1741           if (!conn)
1742                     return NULL;
1743 
1744           wpa_printf(MSG_DEBUG, "SSL: encrypt: %ld bytes", wpabuf_len(in_data));
1745 
1746           wolfssl_reset_out_data(&conn->output);
1747 
1748           res = wolfSSL_write(conn->ssl, wpabuf_head(in_data),
1749                                   wpabuf_len(in_data));
1750           if (res < 0) {
1751                     int  err = wolfSSL_get_error(conn->ssl, res);
1752                     char msg[80];
1753 
1754                     wpa_printf(MSG_INFO, "Encryption failed - SSL_write: %s",
1755                                  wolfSSL_ERR_error_string(err, msg));
1756                     return NULL;
1757           }
1758 
1759           return conn->output.out_data;
1760 }
1761 
1762 
tls_connection_decrypt(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data)1763 struct wpabuf * tls_connection_decrypt(void *tls_ctx,
1764                                                struct tls_connection *conn,
1765                                                const struct wpabuf *in_data)
1766 {
1767           int res;
1768           struct wpabuf *buf;
1769 
1770           if (!conn)
1771                     return NULL;
1772 
1773           wpa_printf(MSG_DEBUG, "SSL: decrypt");
1774 
1775           wolfssl_reset_in_data(&conn->input, in_data);
1776 
1777           /* Read decrypted data for further processing */
1778           /*
1779            * Even though we try to disable TLS compression, it is possible that
1780            * this cannot be done with all TLS libraries. Add extra buffer space
1781            * to handle the possibility of the decrypted data being longer than
1782            * input data.
1783            */
1784           buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
1785           if (!buf)
1786                     return NULL;
1787           res = wolfSSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
1788           if (res < 0) {
1789                     wpa_printf(MSG_INFO, "Decryption failed - SSL_read");
1790                     wpabuf_free(buf);
1791                     return NULL;
1792           }
1793           wpabuf_put(buf, res);
1794 
1795           wpa_printf(MSG_DEBUG, "SSL: decrypt: %ld bytes", wpabuf_len(buf));
1796 
1797           return buf;
1798 }
1799 
1800 
tls_connection_resumed(void * tls_ctx,struct tls_connection * conn)1801 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
1802 {
1803           return conn ? wolfSSL_session_reused(conn->ssl) : 0;
1804 }
1805 
1806 
tls_connection_set_cipher_list(void * tls_ctx,struct tls_connection * conn,u8 * ciphers)1807 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
1808                                            u8 *ciphers)
1809 {
1810           char buf[128], *pos, *end;
1811           u8 *c;
1812           int ret;
1813 
1814           if (!conn || !conn->ssl || !ciphers)
1815                     return -1;
1816 
1817           buf[0] = '\0';
1818           pos = buf;
1819           end = pos + sizeof(buf);
1820 
1821           c = ciphers;
1822           while (*c != TLS_CIPHER_NONE) {
1823                     const char *suite;
1824 
1825                     switch (*c) {
1826                     case TLS_CIPHER_RC4_SHA:
1827                               suite = "RC4-SHA";
1828                               break;
1829                     case TLS_CIPHER_AES128_SHA:
1830                               suite = "AES128-SHA";
1831                               break;
1832                     case TLS_CIPHER_RSA_DHE_AES128_SHA:
1833                               suite = "DHE-RSA-AES128-SHA";
1834                               break;
1835                     case TLS_CIPHER_ANON_DH_AES128_SHA:
1836                               suite = "ADH-AES128-SHA";
1837                               break;
1838                     case TLS_CIPHER_RSA_DHE_AES256_SHA:
1839                               suite = "DHE-RSA-AES256-SHA";
1840                               break;
1841                     case TLS_CIPHER_AES256_SHA:
1842                               suite = "AES256-SHA";
1843                               break;
1844                     default:
1845                               wpa_printf(MSG_DEBUG,
1846                                            "TLS: Unsupported cipher selection: %d", *c);
1847                               return -1;
1848                     }
1849                     ret = os_snprintf(pos, end - pos, ":%s", suite);
1850                     if (os_snprintf_error(end - pos, ret))
1851                               break;
1852                     pos += ret;
1853 
1854                     c++;
1855           }
1856 
1857           wpa_printf(MSG_DEBUG, "wolfSSL: cipher suites: %s", buf + 1);
1858 
1859           if (wolfSSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
1860                     wpa_printf(MSG_DEBUG, "Cipher suite configuration failed");
1861                     return -1;
1862           }
1863 
1864           return 0;
1865 }
1866 
1867 
tls_get_cipher(void * tls_ctx,struct tls_connection * conn,char * buf,size_t buflen)1868 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
1869                        char *buf, size_t buflen)
1870 {
1871           WOLFSSL_CIPHER *cipher;
1872           const char *name;
1873 
1874           if (!conn || !conn->ssl)
1875                     return -1;
1876 
1877           cipher = wolfSSL_get_current_cipher(conn->ssl);
1878           if (!cipher)
1879                     return -1;
1880 
1881           name = wolfSSL_CIPHER_get_name(cipher);
1882           if (!name)
1883                     return -1;
1884 
1885           if (os_strcmp(name, "SSL_RSA_WITH_RC4_128_SHA") == 0)
1886                     os_strlcpy(buf, "RC4-SHA", buflen);
1887           else if (os_strcmp(name, "TLS_RSA_WITH_AES_128_CBC_SHA") == 0)
1888                     os_strlcpy(buf, "AES128-SHA", buflen);
1889           else if (os_strcmp(name, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA") == 0)
1890                     os_strlcpy(buf, "DHE-RSA-AES128-SHA", buflen);
1891           else if (os_strcmp(name, "TLS_DH_anon_WITH_AES_128_CBC_SHA") == 0)
1892                     os_strlcpy(buf, "ADH-AES128-SHA", buflen);
1893           else if (os_strcmp(name, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA") == 0)
1894                     os_strlcpy(buf, "DHE-RSA-AES256-SHA", buflen);
1895           else if (os_strcmp(name, "TLS_RSA_WITH_AES_256_CBC_SHA") == 0)
1896                     os_strlcpy(buf, "AES256-SHA", buflen);
1897           else
1898                     os_strlcpy(buf, name, buflen);
1899 
1900           return 0;
1901 }
1902 
1903 
tls_connection_enable_workaround(void * tls_ctx,struct tls_connection * conn)1904 int tls_connection_enable_workaround(void *tls_ctx,
1905                                              struct tls_connection *conn)
1906 {
1907           /* no empty fragments in wolfSSL for now */
1908           return 0;
1909 }
1910 
1911 
tls_connection_get_failed(void * tls_ctx,struct tls_connection * conn)1912 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
1913 {
1914           if (!conn)
1915                     return -1;
1916 
1917           return conn->failed;
1918 }
1919 
1920 
tls_connection_get_read_alerts(void * tls_ctx,struct tls_connection * conn)1921 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
1922 {
1923           if (!conn)
1924                     return -1;
1925 
1926           /* TODO: this is not incremented anywhere */
1927           return conn->read_alerts;
1928 }
1929 
1930 
tls_connection_get_write_alerts(void * tls_ctx,struct tls_connection * conn)1931 int tls_connection_get_write_alerts(void *tls_ctx,
1932                                             struct tls_connection *conn)
1933 {
1934           if (!conn)
1935                     return -1;
1936 
1937           /* TODO: this is not incremented anywhere */
1938           return conn->write_alerts;
1939 }
1940 
1941 
1942 
tls_get_library_version(char * buf,size_t buf_len)1943 int tls_get_library_version(char *buf, size_t buf_len)
1944 {
1945           return os_snprintf(buf, buf_len, "wolfSSL build=%s run=%s",
1946                                  WOLFSSL_VERSION, wolfSSL_lib_version());
1947 }
1948 
tls_get_version(void * ssl_ctx,struct tls_connection * conn,char * buf,size_t buflen)1949 int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
1950                         char *buf, size_t buflen)
1951 {
1952           const char *name;
1953 
1954           if (!conn || !conn->ssl)
1955                     return -1;
1956 
1957           name = wolfSSL_get_version(conn->ssl);
1958           if (!name)
1959                     return -1;
1960 
1961           os_strlcpy(buf, name, buflen);
1962           return 0;
1963 }
1964 
1965 
tls_connection_get_random(void * ssl_ctx,struct tls_connection * conn,struct tls_random * keys)1966 int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
1967                                     struct tls_random *keys)
1968 {
1969           WOLFSSL *ssl;
1970 
1971           if (!conn || !keys)
1972                     return -1;
1973           ssl = conn->ssl;
1974           if (!ssl)
1975                     return -1;
1976 
1977           os_memset(keys, 0, sizeof(*keys));
1978           keys->client_random = conn->client_random;
1979           keys->client_random_len = wolfSSL_get_client_random(
1980                     ssl, conn->client_random, sizeof(conn->client_random));
1981           keys->server_random = conn->server_random;
1982           keys->server_random_len = wolfSSL_get_server_random(
1983                     ssl, conn->server_random, sizeof(conn->server_random));
1984 
1985           return 0;
1986 }
1987 
1988 
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)1989 int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
1990                                     const char *label, const u8 *context,
1991                                     size_t context_len, u8 *out, size_t out_len)
1992 {
1993           if (context)
1994                     return -1;
1995           if (!conn || wolfSSL_make_eap_keys(conn->ssl, out, out_len, label) != 0)
1996                     return -1;
1997           return 0;
1998 }
1999 
2000 
2001 #define SEED_LEN    (RAN_LEN + RAN_LEN)
2002 
tls_connection_get_eap_fast_key(void * tls_ctx,struct tls_connection * conn,u8 * out,size_t out_len)2003 int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
2004                                             u8 *out, size_t out_len)
2005 {
2006           byte seed[SEED_LEN];
2007           int ret = -1;
2008           WOLFSSL *ssl;
2009           byte *tmp_out;
2010           byte *_out;
2011           int skip = 0;
2012           byte *master_key;
2013           unsigned int master_key_len;
2014           byte *server_random;
2015           unsigned int server_len;
2016           byte *client_random;
2017           unsigned int client_len;
2018 
2019           if (!conn || !conn->ssl)
2020                     return -1;
2021           ssl = conn->ssl;
2022 
2023           skip = 2 * (wolfSSL_GetKeySize(ssl) + wolfSSL_GetHmacSize(ssl) +
2024                         wolfSSL_GetIVSize(ssl));
2025 
2026           tmp_out = os_malloc(skip + out_len);
2027           if (!tmp_out)
2028                     return -1;
2029           _out = tmp_out;
2030 
2031           wolfSSL_get_keys(ssl, &master_key, &master_key_len, &server_random,
2032                                &server_len, &client_random, &client_len);
2033           os_memcpy(seed, server_random, RAN_LEN);
2034           os_memcpy(seed + RAN_LEN, client_random, RAN_LEN);
2035 
2036           if (wolfSSL_GetVersion(ssl) == WOLFSSL_TLSV1_2) {
2037                     tls_prf_sha256(master_key, master_key_len,
2038                                      "key expansion", seed, sizeof(seed),
2039                                      _out, skip + out_len);
2040                     ret = 0;
2041           } else {
2042                     ret = tls_prf_sha1_md5(master_key, master_key_len,
2043                                                "key expansion", seed, sizeof(seed),
2044                                                _out, skip + out_len);
2045           }
2046 
2047           forced_memzero(master_key, master_key_len);
2048           if (ret == 0)
2049                     os_memcpy(out, _out + skip, out_len);
2050           bin_clear_free(tmp_out, skip + out_len);
2051 
2052           return ret;
2053 }
2054 
2055 
2056 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2057 
tls_connection_client_hello_ext(void * ssl_ctx,struct tls_connection * conn,int ext_type,const u8 * data,size_t data_len)2058 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
2059                                             int ext_type, const u8 *data,
2060                                             size_t data_len)
2061 {
2062           (void) ssl_ctx;
2063 
2064           if (!conn || !conn->ssl || ext_type != 35)
2065                     return -1;
2066 
2067           if (wolfSSL_set_SessionTicket(conn->ssl, data,
2068                                               (unsigned int) data_len) != 1)
2069                     return -1;
2070 
2071           return 0;
2072 }
2073 
2074 
tls_sess_sec_cb(WOLFSSL * s,void * secret,int * secret_len,void * arg)2075 static int tls_sess_sec_cb(WOLFSSL *s, void *secret, int *secret_len, void *arg)
2076 {
2077           struct tls_connection *conn = arg;
2078           int ret;
2079           unsigned char client_random[RAN_LEN];
2080           unsigned char server_random[RAN_LEN];
2081           word32 ticket_len = sizeof(conn->session_ticket);
2082 
2083           if (!conn || !conn->session_ticket_cb)
2084                     return 1;
2085 
2086           if (wolfSSL_get_client_random(s, client_random,
2087                                               sizeof(client_random)) == 0 ||
2088               wolfSSL_get_server_random(s, server_random,
2089                                               sizeof(server_random)) == 0 ||
2090               wolfSSL_get_SessionTicket(s, conn->session_ticket,
2091                                               &ticket_len) != 1)
2092                     return 1;
2093 
2094           if (ticket_len == 0)
2095                     return 0;
2096 
2097           ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
2098                                               conn->session_ticket, ticket_len,
2099                                               client_random, server_random, secret);
2100           if (ret <= 0)
2101                     return 1;
2102 
2103           *secret_len = SECRET_LEN;
2104           return 0;
2105 }
2106 
2107 #endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2108 
2109 
tls_connection_set_session_ticket_cb(void * tls_ctx,struct tls_connection * conn,tls_session_ticket_cb cb,void * ctx)2110 int tls_connection_set_session_ticket_cb(void *tls_ctx,
2111                                                    struct tls_connection *conn,
2112                                                    tls_session_ticket_cb cb,
2113                                                    void *ctx)
2114 {
2115 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2116           conn->session_ticket_cb = cb;
2117           conn->session_ticket_cb_ctx = ctx;
2118 
2119           if (cb) {
2120                     if (wolfSSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
2121                                                               conn) != 1)
2122                               return -1;
2123           } else {
2124                     if (wolfSSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
2125                               return -1;
2126           }
2127 
2128           return 0;
2129 #else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2130           return -1;
2131 #endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2132 }
2133 
2134 
tls_connection_set_success_data_resumed(struct tls_connection * conn)2135 void tls_connection_set_success_data_resumed(struct tls_connection *conn)
2136 {
2137           wpa_printf(MSG_DEBUG,
2138                        "wolfSSL: Success data accepted for resumed session");
2139 }
2140 
2141 
tls_connection_remove_session(struct tls_connection * conn)2142 void tls_connection_remove_session(struct tls_connection *conn)
2143 {
2144           WOLFSSL_SESSION *sess;
2145 
2146           sess = wolfSSL_get_session(conn->ssl);
2147           if (!sess)
2148                     return;
2149 
2150           wolfSSL_SSL_SESSION_set_timeout(sess, 0);
2151           wpa_printf(MSG_DEBUG,
2152                        "wolfSSL: Removed cached session to disable session resumption");
2153 }
2154 
2155 
tls_connection_set_success_data(struct tls_connection * conn,struct wpabuf * data)2156 void tls_connection_set_success_data(struct tls_connection *conn,
2157                                              struct wpabuf *data)
2158 {
2159           WOLFSSL_SESSION *sess;
2160           struct wpabuf *old;
2161 
2162           wpa_printf(MSG_DEBUG, "wolfSSL: Set success data");
2163 
2164           sess = wolfSSL_get_session(conn->ssl);
2165           if (!sess) {
2166                     wpa_printf(MSG_DEBUG,
2167                                  "wolfSSL: No session found for success data");
2168                     goto fail;
2169           }
2170 
2171           old = wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
2172           if (old) {
2173                     wpa_printf(MSG_DEBUG, "wolfSSL: Replacing old success data %p",
2174                                  old);
2175                     wpabuf_free(old);
2176           }
2177           if (wolfSSL_SESSION_set_ex_data(sess, tls_ex_idx_session, data) != 1)
2178                     goto fail;
2179 
2180           wpa_printf(MSG_DEBUG, "wolfSSL: Stored success data %p", data);
2181           conn->success_data = 1;
2182           return;
2183 
2184 fail:
2185           wpa_printf(MSG_INFO, "wolfSSL: Failed to store success data");
2186           wpabuf_free(data);
2187 }
2188 
2189 
2190 const struct wpabuf *
tls_connection_get_success_data(struct tls_connection * conn)2191 tls_connection_get_success_data(struct tls_connection *conn)
2192 {
2193           WOLFSSL_SESSION *sess;
2194 
2195           wpa_printf(MSG_DEBUG, "wolfSSL: Get success data");
2196 
2197           sess = wolfSSL_get_session(conn->ssl);
2198           if (!sess)
2199                     return NULL;
2200           return wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
2201 }
2202