]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/hostapd/tls_openssl.c
This commit was generated by cvs2svn to compensate for changes in r155094,
[FreeBSD/FreeBSD.git] / contrib / hostapd / tls_openssl.c
1 /*
2  * WPA Supplicant / SSL/TLS interface functions for openssl
3  * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <openssl/ssl.h>
19 #include <openssl/err.h>
20 #include <openssl/pkcs12.h>
21
22 #include "common.h"
23 #include "tls.h"
24
25
26 struct tls_connection {
27         SSL *ssl;
28         BIO *ssl_in, *ssl_out;
29         char *subject_match;
30 };
31
32
33 static void ssl_info_cb(const SSL *ssl, int where, int ret)
34 {
35         const char *str;
36         int w;
37
38         wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret);
39         w = where & ~SSL_ST_MASK;
40         if (w & SSL_ST_CONNECT)
41                 str = "SSL_connect";
42         else if (w & SSL_ST_ACCEPT)
43                 str = "SSL_accept";
44         else
45                 str = "undefined";
46
47         if (where & SSL_CB_LOOP) {
48                 wpa_printf(MSG_DEBUG, "SSL: %s:%s",
49                            str, SSL_state_string_long(ssl));
50         } else if (where & SSL_CB_ALERT) {
51                 wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s",
52                            where & SSL_CB_READ ?
53                            "read (authentication server reported an error)" :
54                            "write (local SSL3 detected an error)",
55                            SSL_alert_type_string_long(ret),
56                            SSL_alert_desc_string_long(ret));
57         } else if (where & SSL_CB_EXIT && ret <= 0) {
58                 wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s",
59                            str, ret == 0 ? "failed" : "error",
60                            SSL_state_string_long(ssl));
61         }
62 }
63
64
65 void * tls_init(void)
66 {
67         SSL_CTX *ssl;
68
69         SSL_load_error_strings();
70         SSL_library_init();
71         /* TODO: if /dev/urandom is available, PRNG is seeded automatically.
72          * If this is not the case, random data should be added here. */
73
74 #ifdef PKCS12_FUNCS
75         PKCS12_PBE_add();
76 #endif  /* PKCS12_FUNCS */
77
78         ssl = SSL_CTX_new(TLSv1_method());
79         if (ssl == NULL)
80                 return NULL;
81
82         SSL_CTX_set_info_callback(ssl, ssl_info_cb);
83
84         return ssl;
85 }
86
87
88 void tls_deinit(void *ssl_ctx)
89 {
90         SSL_CTX *ssl = ssl_ctx;
91         SSL_CTX_free(ssl);
92         ERR_free_strings();
93         EVP_cleanup();
94 }
95
96
97 int tls_get_errors(void *ssl_ctx)
98 {
99         int count = 0;
100         unsigned long err;
101
102         while ((err = ERR_get_error())) {
103                 wpa_printf(MSG_INFO, "TLS - SSL error: %s",
104                            ERR_error_string(err, NULL));
105                 count++;
106         }
107
108         return count;
109 }
110
111 struct tls_connection * tls_connection_init(void *ssl_ctx)
112 {
113         SSL_CTX *ssl = ssl_ctx;
114         struct tls_connection *conn;
115
116         conn = malloc(sizeof(*conn));
117         if (conn == NULL)
118                 return NULL;
119         memset(conn, 0, sizeof(*conn));
120         conn->ssl = SSL_new(ssl);
121         if (conn->ssl == NULL) {
122                 wpa_printf(MSG_INFO, "TLS: Failed to initialize new SSL "
123                            "connection: %s",
124                            ERR_error_string(ERR_get_error(), NULL));
125                 free(conn);
126                 return NULL;
127         }
128
129         SSL_set_options(conn->ssl,
130                         SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
131                         SSL_OP_SINGLE_DH_USE);
132
133         conn->ssl_in = BIO_new(BIO_s_mem());
134         if (!conn->ssl_in) {
135                 wpa_printf(MSG_INFO, "SSL: Failed to create a new BIO for "
136                            "ssl_in: %s",
137                            ERR_error_string(ERR_get_error(), NULL));
138                 SSL_free(conn->ssl);
139                 free(conn);
140                 return NULL;
141         }
142
143         conn->ssl_out = BIO_new(BIO_s_mem());
144         if (!conn->ssl_out) {
145                 wpa_printf(MSG_INFO, "SSL: Failed to create a new BIO for "
146                            "ssl_out: %s",
147                            ERR_error_string(ERR_get_error(), NULL));
148                 SSL_free(conn->ssl);
149                 BIO_free(conn->ssl_in);
150                 free(conn);
151                 return NULL;
152         }
153
154         SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out);
155
156         return conn;
157 }
158
159
160 void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
161 {
162         if (conn == NULL)
163                 return;
164         SSL_free(conn->ssl);
165         free(conn->subject_match);
166         free(conn);
167 }
168
169
170 int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
171 {
172         return conn ? SSL_is_init_finished(conn->ssl) : 0;
173 }
174
175
176 int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
177 {
178         if (conn == NULL)
179                 return -1;
180
181         /* Shutdown previous TLS connection without notifying the peer
182          * because the connection was already terminated in practice
183          * and "close notify" shutdown alert would confuse AS. */
184         SSL_set_quiet_shutdown(conn->ssl, 1);
185         SSL_shutdown(conn->ssl);
186         return 0;
187 }
188
189
190 static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
191 {
192         char buf[256];
193         X509 *err_cert;
194         int err, depth;
195         SSL *ssl;
196         struct tls_connection *conn;
197         char *match;
198
199         err_cert = X509_STORE_CTX_get_current_cert(x509_ctx);
200         err = X509_STORE_CTX_get_error(x509_ctx);
201         depth = X509_STORE_CTX_get_error_depth(x509_ctx);
202         ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
203                                          SSL_get_ex_data_X509_STORE_CTX_idx());
204         X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
205
206         conn = SSL_get_app_data(ssl);
207         match = conn ? conn->subject_match : NULL;
208
209         if (!preverify_ok) {
210                 wpa_printf(MSG_WARNING, "TLS: Certificate verification failed,"
211                            " error %d (%s) depth %d for '%s'", err,
212                            X509_verify_cert_error_string(err), depth, buf);
213         } else {
214                 wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - "
215                            "preverify_ok=%d err=%d (%s) depth=%d buf='%s'",
216                            preverify_ok, err,
217                            X509_verify_cert_error_string(err), depth, buf);
218                 if (depth == 0 && match && strstr(buf, match) == NULL) {
219                         wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not "
220                                    "match with '%s'", buf, match);
221                         preverify_ok = 0;
222                 }
223         }
224
225         return preverify_ok;
226 }
227
228
229 int tls_connection_ca_cert(void *ssl_ctx, struct tls_connection *conn,
230                            const char *ca_cert, const char *subject_match)
231 {
232         if (conn == NULL)
233                 return -1;
234
235         free(conn->subject_match);
236         conn->subject_match = NULL;
237         if (subject_match) {
238                 conn->subject_match = strdup(subject_match);
239                 if (conn->subject_match == NULL)
240                         return -1;
241         }
242
243         if (ca_cert) {
244                 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
245                 {
246                         wpa_printf(MSG_WARNING, "TLS: Failed to load root "
247                                    "certificates: %s",
248                                    ERR_error_string(ERR_get_error(), NULL));
249                         return -1;
250                 } else {
251                         wpa_printf(MSG_DEBUG, "TLS: Trusted root "
252                                    "certificate(s) loaded");
253                         tls_get_errors(ssl_ctx);
254                 }
255                 SSL_set_app_data(conn->ssl, conn);
256                 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
257         } else {
258                 /* No ca_cert configured - do not try to verify server
259                  * certificate */
260                 SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
261         }
262
263         return 0;
264 }
265
266
267 int tls_global_ca_cert(void *_ssl_ctx, const char *ca_cert)
268 {
269         SSL_CTX *ssl_ctx = _ssl_ctx;
270         if (ca_cert) {
271                 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
272                 {
273                         wpa_printf(MSG_WARNING, "TLS: Failed to load root "
274                                    "certificates: %s",
275                                    ERR_error_string(ERR_get_error(), NULL));
276                         return -1;
277                 } else {
278                         wpa_printf(MSG_DEBUG, "TLS: Trusted root "
279                                    "certificate(s) loaded");
280                 }
281         }
282
283         return 0;
284 }
285
286
287 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
288                               int verify_peer, const char *subject_match)
289 {
290         if (conn == NULL)
291                 return -1;
292
293         free(conn->subject_match);
294         conn->subject_match = NULL;
295         if (subject_match) {
296                 conn->subject_match = strdup(subject_match);
297                 if (conn->subject_match == NULL)
298                         return -1;
299         }
300
301         if (verify_peer) {
302                 SSL_set_app_data(conn->ssl, conn);
303                 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
304                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
305                                SSL_VERIFY_CLIENT_ONCE, tls_verify_cb);
306         } else {
307                 SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
308         }
309
310         SSL_set_accept_state(conn->ssl);
311
312         return 0;
313 }
314
315
316 int tls_connection_client_cert(void *ssl_ctx, struct tls_connection *conn,
317                                const char *client_cert)
318 {
319         if (client_cert == NULL)
320                 return 0;
321         if (conn == NULL)
322                 return -1;
323
324         if (SSL_use_certificate_file(conn->ssl, client_cert,
325                                      SSL_FILETYPE_ASN1) != 1 &&
326             SSL_use_certificate_file(conn->ssl, client_cert,
327                                      SSL_FILETYPE_PEM) != 1) {
328                 wpa_printf(MSG_INFO, "TLS: Failed to load client "
329                            "certificate: %s",
330                            ERR_error_string(ERR_get_error(), NULL));
331                 return -1;
332         }
333         return 0;
334 }
335
336
337 int tls_global_client_cert(void *_ssl_ctx, const char *client_cert)
338 {
339         SSL_CTX *ssl_ctx = _ssl_ctx;
340         if (client_cert == NULL)
341                 return 0;
342
343         if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
344                                          SSL_FILETYPE_ASN1) != 1 &&
345             SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
346                                          SSL_FILETYPE_PEM) != 1) {
347                 wpa_printf(MSG_INFO, "TLS: Failed to load client "
348                            "certificate: %s",
349                            ERR_error_string(ERR_get_error(), NULL));
350                 return -1;
351         }
352         return 0;
353 }
354
355
356 static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
357 {
358         if (password == NULL) {
359                 return 0;
360         }
361         strncpy(buf, (char *) password, size);
362         buf[size - 1] = '\0';
363         return strlen(buf);
364 }
365
366
367 static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key,
368                            const char *passwd)
369 {
370 #ifdef PKCS12_FUNCS
371         FILE *f;
372         PKCS12 *p12;
373         EVP_PKEY *pkey;
374         X509 *cert;
375         int res = 0;
376
377         f = fopen(private_key, "r");
378         if (f == NULL)
379                 return -1;
380
381         p12 = d2i_PKCS12_fp(f, NULL);
382         if (p12 == NULL) {
383                 wpa_printf(MSG_DEBUG, "TLS: Failed to read PKCS12 file '%s'",
384                            private_key);
385                 fclose(f);
386                 return -1;
387         }
388         fclose(f);
389
390         pkey = NULL;
391         cert = NULL;
392         if (!PKCS12_parse(p12, passwd, &pkey, &cert, NULL)) {
393                 wpa_printf(MSG_DEBUG, "TLS: Failed to parse PKCS12 file '%s': "
394                            "%s", private_key,
395                            ERR_error_string(ERR_get_error(), NULL));
396                 return -1;
397         }
398         wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 file '%s'",
399                    private_key);
400
401         if (cert) {
402                 wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12");
403                 if (ssl) {
404                         if (SSL_use_certificate(ssl, cert) != 1)
405                                 res = -1;
406                 } else {
407                         if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1)
408                                 res = -1;
409                 }
410                 X509_free(cert);
411         }
412
413         if (pkey) {
414                 wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12");
415                 if (ssl) {
416                         if (SSL_use_PrivateKey(ssl, pkey) != 1)
417                                 res = -1;
418                 } else {
419                         if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1)
420                                 res = -1;
421                 }
422                 EVP_PKEY_free(pkey);
423         }
424
425         PKCS12_free(p12);
426
427         return res;
428 #else /* PKCS12_FUNCS */
429         wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read "
430                    "p12/pfx files");
431         return -1;
432 #endif  /* PKCS12_FUNCS */
433 }
434
435
436 int tls_connection_private_key(void *_ssl_ctx, struct tls_connection *conn,
437                                const char *private_key,
438                                const char *private_key_passwd)
439 {
440         SSL_CTX *ssl_ctx = _ssl_ctx;
441         char *passwd;
442
443         if (private_key == NULL)
444                 return 0;
445         if (conn == NULL)
446                 return -1;
447
448         if (private_key_passwd) {
449                 passwd = strdup(private_key_passwd);
450                 if (passwd == NULL)
451                         return -1;
452         } else
453                 passwd = NULL;
454
455         SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
456         SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
457         if (SSL_use_PrivateKey_file(conn->ssl, private_key,
458                                     SSL_FILETYPE_ASN1) != 1 &&
459             SSL_use_PrivateKey_file(conn->ssl, private_key,
460                                     SSL_FILETYPE_PEM) != 1 &&
461             tls_read_pkcs12(ssl_ctx, conn->ssl, private_key, passwd)) {
462                 wpa_printf(MSG_INFO, "SSL: Failed to load private key: %s",
463                            ERR_error_string(ERR_get_error(), NULL));
464                 free(passwd);
465                 ERR_clear_error();
466                 return -1;
467         }
468         ERR_clear_error();
469         free(passwd);
470         SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
471         
472         if (!SSL_check_private_key(conn->ssl)) {
473                 wpa_printf(MSG_INFO, "SSL: Private key failed "
474                            "verification: %s",
475                            ERR_error_string(ERR_get_error(), NULL));
476                 return -1;
477         }
478
479         return 0;
480 }
481
482
483 int tls_global_private_key(void *_ssl_ctx, const char *private_key,
484                            const char *private_key_passwd)
485 {
486         SSL_CTX *ssl_ctx = _ssl_ctx;
487         char *passwd;
488
489         if (private_key == NULL)
490                 return 0;
491
492         if (private_key_passwd) {
493                 passwd = strdup(private_key_passwd);
494                 if (passwd == NULL)
495                         return -1;
496         } else
497                 passwd = NULL;
498
499         SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
500         SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
501         if (SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
502                                         SSL_FILETYPE_ASN1) != 1 &&
503             SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
504                                         SSL_FILETYPE_PEM) != 1 &&
505             tls_read_pkcs12(ssl_ctx, NULL, private_key, passwd)) {
506                 wpa_printf(MSG_INFO, "SSL: Failed to load private key: %s",
507                            ERR_error_string(ERR_get_error(), NULL));
508                 free(passwd);
509                 ERR_clear_error();
510                 return -1;
511         }
512         free(passwd);
513         ERR_clear_error();
514         SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
515         
516         if (!SSL_CTX_check_private_key(ssl_ctx)) {
517                 wpa_printf(MSG_INFO, "SSL: Private key failed "
518                            "verification: %s",
519                            ERR_error_string(ERR_get_error(), NULL));
520                 return -1;
521         }
522
523         return 0;
524 }
525
526
527 int tls_connection_dh(void *ssl_ctx, struct tls_connection *conn,
528                       const char *dh_file)
529 {
530 #ifdef OPENSSL_NO_DH
531         if (dh_file == NULL)
532                 return 0;
533         wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
534                    "dh_file specified");
535         return -1;
536 #else /* OPENSSL_NO_DH */
537         DH *dh;
538         BIO *bio;
539
540         if (dh_file == NULL)
541                 return 0;
542         if (conn == NULL)
543                 return -1;
544
545         bio = BIO_new_file(dh_file, "r");
546         if (bio == NULL) {
547                 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
548                            dh_file, ERR_error_string(ERR_get_error(), NULL));
549                 return -1;
550         }
551         dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
552         BIO_free(bio);
553 #ifndef OPENSSL_NO_DSA
554         while (dh == NULL) {
555                 DSA *dsa;
556                 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
557                            " trying to parse as DSA params", dh_file,
558                            ERR_error_string(ERR_get_error(), NULL));
559                 bio = BIO_new_file(dh_file, "r");
560                 if (bio == NULL)
561                         break;
562                 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
563                 BIO_free(bio);
564                 if (!dsa) {
565                         wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
566                                    "'%s': %s", dh_file,
567                                    ERR_error_string(ERR_get_error(), NULL));
568                         break;
569                 }
570
571                 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
572                 dh = DSA_dup_DH(dsa);
573                 DSA_free(dsa);
574                 if (dh == NULL) {
575                         wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
576                                    "params into DH params");
577                         break;
578                 }
579                 break;
580         }
581 #endif /* !OPENSSL_NO_DSA */
582         if (dh == NULL) {
583                 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
584                            "'%s'", dh_file);
585                 return -1;
586         }
587
588         if (SSL_set_tmp_dh(conn->ssl, dh) != 1) {
589                 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
590                            "%s", dh_file,
591                            ERR_error_string(ERR_get_error(), NULL));
592                 DH_free(dh);
593                 return -1;
594         }
595         DH_free(dh);
596         return 0;
597 #endif /* OPENSSL_NO_DH */
598 }
599
600
601 int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
602                             struct tls_keys *keys)
603 {
604         SSL *ssl;
605
606         if (conn == NULL || keys == NULL)
607                 return -1;
608         ssl = conn->ssl;
609         if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL)
610                 return -1;
611
612         keys->master_key = ssl->session->master_key;
613         keys->master_key_len = ssl->session->master_key_length;
614         keys->client_random = ssl->s3->client_random;
615         keys->client_random_len = SSL3_RANDOM_SIZE;
616         keys->server_random = ssl->s3->server_random;
617         keys->server_random_len = SSL3_RANDOM_SIZE;
618
619         return 0;
620 }
621
622
623 u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
624                               const u8 *in_data, size_t in_len,
625                               size_t *out_len)
626 {
627         int res;
628         u8 *out_data;
629
630         if (in_data &&
631             BIO_write(conn->ssl_in, in_data, in_len) < 0) {
632                 wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_write: %s",
633                            ERR_error_string(ERR_get_error(), NULL));
634                 return NULL;
635         }
636
637         res = SSL_connect(conn->ssl);
638         if (res != 1) {
639                 int err = SSL_get_error(conn->ssl, res);
640                 if (err == SSL_ERROR_WANT_READ)
641                         wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want "
642                                    "more data");
643                 else if (err == SSL_ERROR_WANT_WRITE)
644                         wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to "
645                                    "write");
646                 else {
647                         wpa_printf(MSG_INFO, "SSL: SSL_connect: %s",
648                                    ERR_error_string(ERR_get_error(), NULL));
649                         return NULL;
650                 }
651         }
652
653         res = BIO_ctrl_pending(conn->ssl_out);
654         wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
655         out_data = malloc(res == 0 ? 1 : res);
656         if (out_data == NULL) {
657                 wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
658                            "handshake output (%d bytes)", res);
659                 BIO_reset(conn->ssl_out);
660                 *out_len = 0;
661                 return NULL;
662         }
663         res = res == 0 ? 0 : BIO_read(conn->ssl_out, out_data, res);
664         if (res < 0) {
665                 wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_read: %s",
666                            ERR_error_string(ERR_get_error(), NULL));
667                 BIO_reset(conn->ssl_out);
668                 *out_len = 0;
669                 return NULL;
670         }
671         *out_len = res;
672         return out_data;
673 }
674
675
676 u8 * tls_connection_server_handshake(void *ssl_ctx,
677                                      struct tls_connection *conn,
678                                      const u8 *in_data, size_t in_len,
679                                      size_t *out_len)
680 {
681         int res;
682         u8 *out_data;
683         char buf[10];
684
685         if (in_data &&
686             BIO_write(conn->ssl_in, in_data, in_len) < 0) {
687                 wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_write: %s",
688                            ERR_error_string(ERR_get_error(), NULL));
689                 return NULL;
690         }
691
692         res = SSL_read(conn->ssl, buf, sizeof(buf));
693         if (res >= 0) {
694                 wpa_printf(MSG_DEBUG, "SSL: Unexpected data from SSL_read "
695                            "(res=%d)", res);
696         }
697
698         res = BIO_ctrl_pending(conn->ssl_out);
699         wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
700         out_data = malloc(res == 0 ? 1 : res);
701         if (out_data == NULL) {
702                 wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
703                            "handshake output (%d bytes)", res);
704                 BIO_reset(conn->ssl_out);
705                 *out_len = 0;
706                 return NULL;
707         }
708         res = res == 0 ? 0 : BIO_read(conn->ssl_out, out_data, res);
709         if (res < 0) {
710                 wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_read: %s",
711                            ERR_error_string(ERR_get_error(), NULL));
712                 BIO_reset(conn->ssl_out);
713                 *out_len = 0;
714                 return NULL;
715         }
716         *out_len = res;
717         return out_data;
718 }
719
720
721 int tls_connection_encrypt(void *ssl_ctx, struct tls_connection *conn,
722                            u8 *in_data, size_t in_len,
723                            u8 *out_data, size_t out_len)
724 {
725         int res;
726
727         if (conn == NULL)
728                 return -1;
729
730         BIO_reset(conn->ssl_in);
731         BIO_reset(conn->ssl_out);
732         res = SSL_write(conn->ssl, in_data, in_len);
733         if (res < 0) {
734                 wpa_printf(MSG_INFO, "TLS: Encryption failed - SSL_write: %s",
735                            ERR_error_string(ERR_get_error(), NULL));
736                 return res;
737         }
738
739         res = BIO_read(conn->ssl_out, out_data, out_len);
740         if (res < 0) {
741                 wpa_printf(MSG_INFO, "TLS: Encryption failed - BIO_read: %s",
742                            ERR_error_string(ERR_get_error(), NULL));
743                 return res;
744         }
745
746         return res;
747 }
748
749
750 int tls_connection_decrypt(void *ssl_ctx, struct tls_connection *conn,
751                            u8 *in_data, size_t in_len,
752                            u8 *out_data, size_t out_len)
753 {
754         int res;
755
756         res = BIO_write(conn->ssl_in, in_data, in_len);
757         if (res < 0) {
758                 wpa_printf(MSG_INFO, "TLS: Decryption failed - BIO_write: %s",
759                            ERR_error_string(ERR_get_error(), NULL));
760                 return res;
761         }
762         BIO_reset(conn->ssl_out);
763
764         res = SSL_read(conn->ssl, out_data, out_len);
765         if (res < 0) {
766                 wpa_printf(MSG_INFO, "TLS: Decryption failed - SSL_read: %s",
767                            ERR_error_string(ERR_get_error(), NULL));
768                 return res;
769         }
770
771         return res;
772 }
773
774
775 int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
776 {
777         return conn ? conn->ssl->hit : 0;
778 }
779
780
781 int tls_connection_set_master_key(void *ssl_ctx, struct tls_connection *conn,
782                                   const u8 *key, size_t key_len)
783 {
784         SSL *ssl;
785
786         if (conn == NULL || key == NULL || key_len > SSL_MAX_MASTER_KEY_LENGTH)
787                 return -1;
788         ssl = conn->ssl;
789         if (ssl == NULL || ssl->session == NULL)
790                 return -1;
791
792         memcpy(ssl->session->master_key, key, key_len);
793         ssl->session->master_key_length = key_len;
794
795         return 0;
796 }
797
798
799 int tls_connection_set_anon_dh(void *ssl_ctx, struct tls_connection *conn)
800 {
801         if (conn == NULL || conn->ssl == NULL)
802                 return -1;
803
804         if (SSL_set_cipher_list(conn->ssl, "ADH-AES128-SHA") != 1) {
805                 wpa_printf(MSG_INFO, "TLS: Anon DH configuration failed - %s",
806                            ERR_error_string(ERR_get_error(), NULL));
807                 return -1;
808         }
809
810         return 0;
811 }
812
813
814 int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
815                    char *buf, size_t buflen)
816 {
817         const char *name;
818         if (conn == NULL || conn->ssl == NULL)
819                 return -1;
820
821         name = SSL_get_cipher(conn->ssl);
822         if (name == NULL)
823                 return -1;
824
825         snprintf(buf, buflen, "%s", name);
826         return 0;
827 }
828
829
830 int tls_connection_enable_workaround(void *ssl_ctx,
831                                      struct tls_connection *conn)
832 {
833         SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
834
835         return 0;
836 }
837
838
839 #ifdef EAP_FAST
840 /* ClientHello TLS extensions require a patch to openssl, so this function is
841  * commented out unless explicitly needed for EAP-FAST in order to be able to
842  * build this file with unmodified openssl. */
843 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
844                                     int ext_type, const u8 *data,
845                                     size_t data_len)
846 {
847         struct tls_ext_hdr {
848                 u16 extensions_len;
849                 u16 extension_type;
850                 u16 extension_len;
851         } *hdr;
852
853         if (conn == NULL || conn->ssl == NULL)
854                 return -1;
855         OPENSSL_free(conn->ssl->hello_extension);
856         if (data == NULL) {
857                 conn->ssl->hello_extension = NULL;
858                 conn->ssl->hello_extension_len = 0;
859                 return 0;
860         }
861         if (data_len == 0) {
862                 conn->ssl->hello_extension = OPENSSL_malloc(1);
863                 conn->ssl->hello_extension_len = 0;
864                 return 0;
865         }
866         conn->ssl->hello_extension = OPENSSL_malloc(sizeof(*hdr) + data_len);
867         if (conn->ssl->hello_extension == NULL)
868                 return -1;
869
870         hdr = (struct tls_ext_hdr *) conn->ssl->hello_extension;
871         hdr->extensions_len = host_to_be16(sizeof(*hdr) - 2 + data_len);
872         hdr->extension_type = host_to_be16(ext_type);
873         hdr->extension_len = host_to_be16(data_len);
874         memcpy(hdr + 1, data, data_len);
875         conn->ssl->hello_extension_len = sizeof(*hdr) + data_len;
876
877         return 0;
878 }
879 #endif /* EAP_FAST */