blob: fec8e38558684fa2651993a225bad32d7d5807a6 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * SSL/TLS interface functions for OpenSSL
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07003 * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 */
8
9#include "includes.h"
10
11#ifndef CONFIG_SMARTCARD
12#ifndef OPENSSL_NO_ENGINE
Kenny Rootdb3c5a42012-03-20 17:00:47 -070013#ifndef ANDROID
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070014#define OPENSSL_NO_ENGINE
15#endif
16#endif
Kenny Rootdb3c5a42012-03-20 17:00:47 -070017#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070018
19#include <openssl/ssl.h>
20#include <openssl/err.h>
21#include <openssl/pkcs12.h>
22#include <openssl/x509v3.h>
23#ifndef OPENSSL_NO_ENGINE
24#include <openssl/engine.h>
25#endif /* OPENSSL_NO_ENGINE */
26
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070027#include "common.h"
28#include "crypto.h"
29#include "tls.h"
30
31#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
32#define OPENSSL_d2i_TYPE const unsigned char **
33#else
34#define OPENSSL_d2i_TYPE unsigned char **
35#endif
36
Dmitry Shmidtea69e842013-05-13 14:52:28 -070037#if defined(SSL_CTX_get_app_data) && defined(SSL_CTX_set_app_data)
38#define OPENSSL_SUPPORTS_CTX_APP_DATA
39#endif
40
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070041#ifdef SSL_F_SSL_SET_SESSION_TICKET_EXT
42#ifdef SSL_OP_NO_TICKET
43/*
44 * Session ticket override patch was merged into OpenSSL 0.9.9 tree on
45 * 2008-11-15. This version uses a bit different API compared to the old patch.
46 */
47#define CONFIG_OPENSSL_TICKET_OVERRIDE
48#endif
49#endif
50
Kenny Root3f3ca3b2012-11-12 16:33:36 -080051#ifdef ANDROID
52#include <openssl/pem.h>
53#include <keystore/keystore_get.h>
54
55static BIO * BIO_from_keystore(const char *key)
56{
57 BIO *bio = NULL;
58 uint8_t *value = NULL;
59 int length = keystore_get(key, strlen(key), &value);
60 if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL) {
61 BIO_write(bio, value, length);
62 }
63 free(value);
64 return bio;
65}
66#endif /* ANDROID */
67
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070068static int tls_openssl_ref_count = 0;
69
Dmitry Shmidtea69e842013-05-13 14:52:28 -070070struct tls_context {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070071 void (*event_cb)(void *ctx, enum tls_event ev,
72 union tls_event_data *data);
73 void *cb_ctx;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080074 int cert_in_cb;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070075};
76
Dmitry Shmidtea69e842013-05-13 14:52:28 -070077static struct tls_context *tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070078
79
80struct tls_connection {
Dmitry Shmidtea69e842013-05-13 14:52:28 -070081 struct tls_context *context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070082 SSL *ssl;
83 BIO *ssl_in, *ssl_out;
84#ifndef OPENSSL_NO_ENGINE
85 ENGINE *engine; /* functional reference to the engine */
86 EVP_PKEY *private_key; /* the private key if using engine */
87#endif /* OPENSSL_NO_ENGINE */
88 char *subject_match, *altsubject_match;
89 int read_alerts, write_alerts, failed;
90
91 tls_session_ticket_cb session_ticket_cb;
92 void *session_ticket_cb_ctx;
93
94 /* SessionTicket received from OpenSSL hello_extension_cb (server) */
95 u8 *session_ticket;
96 size_t session_ticket_len;
97
98 unsigned int ca_cert_verify:1;
99 unsigned int cert_probe:1;
100 unsigned int server_cert_only:1;
101
102 u8 srv_cert_hash[32];
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700103
104 unsigned int flags;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700105};
106
107
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700108static struct tls_context * tls_context_new(const struct tls_config *conf)
109{
110 struct tls_context *context = os_zalloc(sizeof(*context));
111 if (context == NULL)
112 return NULL;
113 if (conf) {
114 context->event_cb = conf->event_cb;
115 context->cb_ctx = conf->cb_ctx;
116 context->cert_in_cb = conf->cert_in_cb;
117 }
118 return context;
119}
120
121
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700122#ifdef CONFIG_NO_STDOUT_DEBUG
123
124static void _tls_show_errors(void)
125{
126 unsigned long err;
127
128 while ((err = ERR_get_error())) {
129 /* Just ignore the errors, since stdout is disabled */
130 }
131}
132#define tls_show_errors(l, f, t) _tls_show_errors()
133
134#else /* CONFIG_NO_STDOUT_DEBUG */
135
136static void tls_show_errors(int level, const char *func, const char *txt)
137{
138 unsigned long err;
139
140 wpa_printf(level, "OpenSSL: %s - %s %s",
141 func, txt, ERR_error_string(ERR_get_error(), NULL));
142
143 while ((err = ERR_get_error())) {
144 wpa_printf(MSG_INFO, "OpenSSL: pending error: %s",
145 ERR_error_string(err, NULL));
146 }
147}
148
149#endif /* CONFIG_NO_STDOUT_DEBUG */
150
151
152#ifdef CONFIG_NATIVE_WINDOWS
153
154/* Windows CryptoAPI and access to certificate stores */
155#include <wincrypt.h>
156
157#ifdef __MINGW32_VERSION
158/*
159 * MinGW does not yet include all the needed definitions for CryptoAPI, so
160 * define here whatever extra is needed.
161 */
162#define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16)
163#define CERT_STORE_READONLY_FLAG 0x00008000
164#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
165
166#endif /* __MINGW32_VERSION */
167
168
169struct cryptoapi_rsa_data {
170 const CERT_CONTEXT *cert;
171 HCRYPTPROV crypt_prov;
172 DWORD key_spec;
173 BOOL free_crypt_prov;
174};
175
176
177static void cryptoapi_error(const char *msg)
178{
179 wpa_printf(MSG_INFO, "CryptoAPI: %s; err=%u",
180 msg, (unsigned int) GetLastError());
181}
182
183
184static int cryptoapi_rsa_pub_enc(int flen, const unsigned char *from,
185 unsigned char *to, RSA *rsa, int padding)
186{
187 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
188 return 0;
189}
190
191
192static int cryptoapi_rsa_pub_dec(int flen, const unsigned char *from,
193 unsigned char *to, RSA *rsa, int padding)
194{
195 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
196 return 0;
197}
198
199
200static int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from,
201 unsigned char *to, RSA *rsa, int padding)
202{
203 struct cryptoapi_rsa_data *priv =
204 (struct cryptoapi_rsa_data *) rsa->meth->app_data;
205 HCRYPTHASH hash;
206 DWORD hash_size, len, i;
207 unsigned char *buf = NULL;
208 int ret = 0;
209
210 if (priv == NULL) {
211 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
212 ERR_R_PASSED_NULL_PARAMETER);
213 return 0;
214 }
215
216 if (padding != RSA_PKCS1_PADDING) {
217 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
218 RSA_R_UNKNOWN_PADDING_TYPE);
219 return 0;
220 }
221
222 if (flen != 16 /* MD5 */ + 20 /* SHA-1 */) {
223 wpa_printf(MSG_INFO, "%s - only MD5-SHA1 hash supported",
224 __func__);
225 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
226 RSA_R_INVALID_MESSAGE_LENGTH);
227 return 0;
228 }
229
230 if (!CryptCreateHash(priv->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash))
231 {
232 cryptoapi_error("CryptCreateHash failed");
233 return 0;
234 }
235
236 len = sizeof(hash_size);
237 if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len,
238 0)) {
239 cryptoapi_error("CryptGetHashParam failed");
240 goto err;
241 }
242
243 if ((int) hash_size != flen) {
244 wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)",
245 (unsigned) hash_size, flen);
246 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
247 RSA_R_INVALID_MESSAGE_LENGTH);
248 goto err;
249 }
250 if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) {
251 cryptoapi_error("CryptSetHashParam failed");
252 goto err;
253 }
254
255 len = RSA_size(rsa);
256 buf = os_malloc(len);
257 if (buf == NULL) {
258 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
259 goto err;
260 }
261
262 if (!CryptSignHash(hash, priv->key_spec, NULL, 0, buf, &len)) {
263 cryptoapi_error("CryptSignHash failed");
264 goto err;
265 }
266
267 for (i = 0; i < len; i++)
268 to[i] = buf[len - i - 1];
269 ret = len;
270
271err:
272 os_free(buf);
273 CryptDestroyHash(hash);
274
275 return ret;
276}
277
278
279static int cryptoapi_rsa_priv_dec(int flen, const unsigned char *from,
280 unsigned char *to, RSA *rsa, int padding)
281{
282 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
283 return 0;
284}
285
286
287static void cryptoapi_free_data(struct cryptoapi_rsa_data *priv)
288{
289 if (priv == NULL)
290 return;
291 if (priv->crypt_prov && priv->free_crypt_prov)
292 CryptReleaseContext(priv->crypt_prov, 0);
293 if (priv->cert)
294 CertFreeCertificateContext(priv->cert);
295 os_free(priv);
296}
297
298
299static int cryptoapi_finish(RSA *rsa)
300{
301 cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data);
302 os_free((void *) rsa->meth);
303 rsa->meth = NULL;
304 return 1;
305}
306
307
308static const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store)
309{
310 HCERTSTORE cs;
311 const CERT_CONTEXT *ret = NULL;
312
313 cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0,
314 store | CERT_STORE_OPEN_EXISTING_FLAG |
315 CERT_STORE_READONLY_FLAG, L"MY");
316 if (cs == NULL) {
317 cryptoapi_error("Failed to open 'My system store'");
318 return NULL;
319 }
320
321 if (strncmp(name, "cert://", 7) == 0) {
322 unsigned short wbuf[255];
323 MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255);
324 ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING |
325 PKCS_7_ASN_ENCODING,
326 0, CERT_FIND_SUBJECT_STR,
327 wbuf, NULL);
328 } else if (strncmp(name, "hash://", 7) == 0) {
329 CRYPT_HASH_BLOB blob;
330 int len;
331 const char *hash = name + 7;
332 unsigned char *buf;
333
334 len = os_strlen(hash) / 2;
335 buf = os_malloc(len);
336 if (buf && hexstr2bin(hash, buf, len) == 0) {
337 blob.cbData = len;
338 blob.pbData = buf;
339 ret = CertFindCertificateInStore(cs,
340 X509_ASN_ENCODING |
341 PKCS_7_ASN_ENCODING,
342 0, CERT_FIND_HASH,
343 &blob, NULL);
344 }
345 os_free(buf);
346 }
347
348 CertCloseStore(cs, 0);
349
350 return ret;
351}
352
353
354static int tls_cryptoapi_cert(SSL *ssl, const char *name)
355{
356 X509 *cert = NULL;
357 RSA *rsa = NULL, *pub_rsa;
358 struct cryptoapi_rsa_data *priv;
359 RSA_METHOD *rsa_meth;
360
361 if (name == NULL ||
362 (strncmp(name, "cert://", 7) != 0 &&
363 strncmp(name, "hash://", 7) != 0))
364 return -1;
365
366 priv = os_zalloc(sizeof(*priv));
367 rsa_meth = os_zalloc(sizeof(*rsa_meth));
368 if (priv == NULL || rsa_meth == NULL) {
369 wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory "
370 "for CryptoAPI RSA method");
371 os_free(priv);
372 os_free(rsa_meth);
373 return -1;
374 }
375
376 priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER);
377 if (priv->cert == NULL) {
378 priv->cert = cryptoapi_find_cert(
379 name, CERT_SYSTEM_STORE_LOCAL_MACHINE);
380 }
381 if (priv->cert == NULL) {
382 wpa_printf(MSG_INFO, "CryptoAPI: Could not find certificate "
383 "'%s'", name);
384 goto err;
385 }
386
387 cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &priv->cert->pbCertEncoded,
388 priv->cert->cbCertEncoded);
389 if (cert == NULL) {
390 wpa_printf(MSG_INFO, "CryptoAPI: Could not process X509 DER "
391 "encoding");
392 goto err;
393 }
394
395 if (!CryptAcquireCertificatePrivateKey(priv->cert,
396 CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
397 NULL, &priv->crypt_prov,
398 &priv->key_spec,
399 &priv->free_crypt_prov)) {
400 cryptoapi_error("Failed to acquire a private key for the "
401 "certificate");
402 goto err;
403 }
404
405 rsa_meth->name = "Microsoft CryptoAPI RSA Method";
406 rsa_meth->rsa_pub_enc = cryptoapi_rsa_pub_enc;
407 rsa_meth->rsa_pub_dec = cryptoapi_rsa_pub_dec;
408 rsa_meth->rsa_priv_enc = cryptoapi_rsa_priv_enc;
409 rsa_meth->rsa_priv_dec = cryptoapi_rsa_priv_dec;
410 rsa_meth->finish = cryptoapi_finish;
411 rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
412 rsa_meth->app_data = (char *) priv;
413
414 rsa = RSA_new();
415 if (rsa == NULL) {
416 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,
417 ERR_R_MALLOC_FAILURE);
418 goto err;
419 }
420
421 if (!SSL_use_certificate(ssl, cert)) {
422 RSA_free(rsa);
423 rsa = NULL;
424 goto err;
425 }
426 pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
427 X509_free(cert);
428 cert = NULL;
429
430 rsa->n = BN_dup(pub_rsa->n);
431 rsa->e = BN_dup(pub_rsa->e);
432 if (!RSA_set_method(rsa, rsa_meth))
433 goto err;
434
435 if (!SSL_use_RSAPrivateKey(ssl, rsa))
436 goto err;
437 RSA_free(rsa);
438
439 return 0;
440
441err:
442 if (cert)
443 X509_free(cert);
444 if (rsa)
445 RSA_free(rsa);
446 else {
447 os_free(rsa_meth);
448 cryptoapi_free_data(priv);
449 }
450 return -1;
451}
452
453
454static int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name)
455{
456 HCERTSTORE cs;
457 PCCERT_CONTEXT ctx = NULL;
458 X509 *cert;
459 char buf[128];
460 const char *store;
461#ifdef UNICODE
462 WCHAR *wstore;
463#endif /* UNICODE */
464
465 if (name == NULL || strncmp(name, "cert_store://", 13) != 0)
466 return -1;
467
468 store = name + 13;
469#ifdef UNICODE
470 wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR));
471 if (wstore == NULL)
472 return -1;
473 wsprintf(wstore, L"%S", store);
474 cs = CertOpenSystemStore(0, wstore);
475 os_free(wstore);
476#else /* UNICODE */
477 cs = CertOpenSystemStore(0, store);
478#endif /* UNICODE */
479 if (cs == NULL) {
480 wpa_printf(MSG_DEBUG, "%s: failed to open system cert store "
481 "'%s': error=%d", __func__, store,
482 (int) GetLastError());
483 return -1;
484 }
485
486 while ((ctx = CertEnumCertificatesInStore(cs, ctx))) {
487 cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ctx->pbCertEncoded,
488 ctx->cbCertEncoded);
489 if (cert == NULL) {
490 wpa_printf(MSG_INFO, "CryptoAPI: Could not process "
491 "X509 DER encoding for CA cert");
492 continue;
493 }
494
495 X509_NAME_oneline(X509_get_subject_name(cert), buf,
496 sizeof(buf));
497 wpa_printf(MSG_DEBUG, "OpenSSL: Loaded CA certificate for "
498 "system certificate store: subject='%s'", buf);
499
500 if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) {
501 tls_show_errors(MSG_WARNING, __func__,
502 "Failed to add ca_cert to OpenSSL "
503 "certificate store");
504 }
505
506 X509_free(cert);
507 }
508
509 if (!CertCloseStore(cs, 0)) {
510 wpa_printf(MSG_DEBUG, "%s: failed to close system cert store "
511 "'%s': error=%d", __func__, name + 13,
512 (int) GetLastError());
513 }
514
515 return 0;
516}
517
518
519#else /* CONFIG_NATIVE_WINDOWS */
520
521static int tls_cryptoapi_cert(SSL *ssl, const char *name)
522{
523 return -1;
524}
525
526#endif /* CONFIG_NATIVE_WINDOWS */
527
528
529static void ssl_info_cb(const SSL *ssl, int where, int ret)
530{
531 const char *str;
532 int w;
533
534 wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret);
535 w = where & ~SSL_ST_MASK;
536 if (w & SSL_ST_CONNECT)
537 str = "SSL_connect";
538 else if (w & SSL_ST_ACCEPT)
539 str = "SSL_accept";
540 else
541 str = "undefined";
542
543 if (where & SSL_CB_LOOP) {
544 wpa_printf(MSG_DEBUG, "SSL: %s:%s",
545 str, SSL_state_string_long(ssl));
546 } else if (where & SSL_CB_ALERT) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700547 struct tls_connection *conn = SSL_get_app_data((SSL *) ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700548 wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s",
549 where & SSL_CB_READ ?
550 "read (remote end reported an error)" :
551 "write (local SSL3 detected an error)",
552 SSL_alert_type_string_long(ret),
553 SSL_alert_desc_string_long(ret));
554 if ((ret >> 8) == SSL3_AL_FATAL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700555 if (where & SSL_CB_READ)
556 conn->read_alerts++;
557 else
558 conn->write_alerts++;
559 }
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700560 if (conn->context->event_cb != NULL) {
Dmitry Shmidt04949592012-07-19 12:16:46 -0700561 union tls_event_data ev;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700562 struct tls_context *context = conn->context;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700563 os_memset(&ev, 0, sizeof(ev));
564 ev.alert.is_local = !(where & SSL_CB_READ);
565 ev.alert.type = SSL_alert_type_string_long(ret);
566 ev.alert.description = SSL_alert_desc_string_long(ret);
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700567 context->event_cb(context->cb_ctx, TLS_ALERT, &ev);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700568 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700569 } else if (where & SSL_CB_EXIT && ret <= 0) {
570 wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s",
571 str, ret == 0 ? "failed" : "error",
572 SSL_state_string_long(ssl));
573 }
574}
575
576
577#ifndef OPENSSL_NO_ENGINE
578/**
579 * tls_engine_load_dynamic_generic - load any openssl engine
580 * @pre: an array of commands and values that load an engine initialized
581 * in the engine specific function
582 * @post: an array of commands and values that initialize an already loaded
583 * engine (or %NULL if not required)
584 * @id: the engine id of the engine to load (only required if post is not %NULL
585 *
586 * This function is a generic function that loads any openssl engine.
587 *
588 * Returns: 0 on success, -1 on failure
589 */
590static int tls_engine_load_dynamic_generic(const char *pre[],
591 const char *post[], const char *id)
592{
593 ENGINE *engine;
594 const char *dynamic_id = "dynamic";
595
596 engine = ENGINE_by_id(id);
597 if (engine) {
598 ENGINE_free(engine);
599 wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already "
600 "available", id);
601 return 0;
602 }
603 ERR_clear_error();
604
605 engine = ENGINE_by_id(dynamic_id);
606 if (engine == NULL) {
607 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
608 dynamic_id,
609 ERR_error_string(ERR_get_error(), NULL));
610 return -1;
611 }
612
613 /* Perform the pre commands. This will load the engine. */
614 while (pre && pre[0]) {
615 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]);
616 if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) {
617 wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: "
618 "%s %s [%s]", pre[0], pre[1],
619 ERR_error_string(ERR_get_error(), NULL));
620 ENGINE_free(engine);
621 return -1;
622 }
623 pre += 2;
624 }
625
626 /*
627 * Free the reference to the "dynamic" engine. The loaded engine can
628 * now be looked up using ENGINE_by_id().
629 */
630 ENGINE_free(engine);
631
632 engine = ENGINE_by_id(id);
633 if (engine == NULL) {
634 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
635 id, ERR_error_string(ERR_get_error(), NULL));
636 return -1;
637 }
638
639 while (post && post[0]) {
640 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]);
641 if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) {
642 wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:"
643 " %s %s [%s]", post[0], post[1],
644 ERR_error_string(ERR_get_error(), NULL));
645 ENGINE_remove(engine);
646 ENGINE_free(engine);
647 return -1;
648 }
649 post += 2;
650 }
651 ENGINE_free(engine);
652
653 return 0;
654}
655
656
657/**
658 * tls_engine_load_dynamic_pkcs11 - load the pkcs11 engine provided by opensc
659 * @pkcs11_so_path: pksc11_so_path from the configuration
660 * @pcks11_module_path: pkcs11_module_path from the configuration
661 */
662static int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path,
663 const char *pkcs11_module_path)
664{
665 char *engine_id = "pkcs11";
666 const char *pre_cmd[] = {
667 "SO_PATH", NULL /* pkcs11_so_path */,
668 "ID", NULL /* engine_id */,
669 "LIST_ADD", "1",
670 /* "NO_VCHECK", "1", */
671 "LOAD", NULL,
672 NULL, NULL
673 };
674 const char *post_cmd[] = {
675 "MODULE_PATH", NULL /* pkcs11_module_path */,
676 NULL, NULL
677 };
678
679 if (!pkcs11_so_path || !pkcs11_module_path)
680 return 0;
681
682 pre_cmd[1] = pkcs11_so_path;
683 pre_cmd[3] = engine_id;
684 post_cmd[1] = pkcs11_module_path;
685
686 wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s",
687 pkcs11_so_path);
688
689 return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id);
690}
691
692
693/**
694 * tls_engine_load_dynamic_opensc - load the opensc engine provided by opensc
695 * @opensc_so_path: opensc_so_path from the configuration
696 */
697static int tls_engine_load_dynamic_opensc(const char *opensc_so_path)
698{
699 char *engine_id = "opensc";
700 const char *pre_cmd[] = {
701 "SO_PATH", NULL /* opensc_so_path */,
702 "ID", NULL /* engine_id */,
703 "LIST_ADD", "1",
704 "LOAD", NULL,
705 NULL, NULL
706 };
707
708 if (!opensc_so_path)
709 return 0;
710
711 pre_cmd[1] = opensc_so_path;
712 pre_cmd[3] = engine_id;
713
714 wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s",
715 opensc_so_path);
716
717 return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id);
718}
719#endif /* OPENSSL_NO_ENGINE */
720
721
722void * tls_init(const struct tls_config *conf)
723{
724 SSL_CTX *ssl;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700725 struct tls_context *context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700726
727 if (tls_openssl_ref_count == 0) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700728 tls_global = context = tls_context_new(conf);
729 if (context == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700730 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700731#ifdef CONFIG_FIPS
732#ifdef OPENSSL_FIPS
733 if (conf && conf->fips_mode) {
734 if (!FIPS_mode_set(1)) {
735 wpa_printf(MSG_ERROR, "Failed to enable FIPS "
736 "mode");
737 ERR_load_crypto_strings();
738 ERR_print_errors_fp(stderr);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700739 os_free(tls_global);
740 tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700741 return NULL;
742 } else
743 wpa_printf(MSG_INFO, "Running in FIPS mode");
744 }
745#else /* OPENSSL_FIPS */
746 if (conf && conf->fips_mode) {
747 wpa_printf(MSG_ERROR, "FIPS mode requested, but not "
748 "supported");
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700749 os_free(tls_global);
750 tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700751 return NULL;
752 }
753#endif /* OPENSSL_FIPS */
754#endif /* CONFIG_FIPS */
755 SSL_load_error_strings();
756 SSL_library_init();
757#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256)
758 EVP_add_digest(EVP_sha256());
759#endif /* OPENSSL_NO_SHA256 */
760 /* TODO: if /dev/urandom is available, PRNG is seeded
761 * automatically. If this is not the case, random data should
762 * be added here. */
763
764#ifdef PKCS12_FUNCS
765#ifndef OPENSSL_NO_RC2
766 /*
767 * 40-bit RC2 is commonly used in PKCS#12 files, so enable it.
768 * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8
769 * versions, but it looks like OpenSSL 1.0.0 does not do that
770 * anymore.
771 */
772 EVP_add_cipher(EVP_rc2_40_cbc());
773#endif /* OPENSSL_NO_RC2 */
774 PKCS12_PBE_add();
775#endif /* PKCS12_FUNCS */
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700776 } else {
777 context = tls_global;
778#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
779 /* Newer OpenSSL can store app-data per-SSL */
780 context = tls_context_new(conf);
781 if (context == NULL)
782 return NULL;
783#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700784 }
785 tls_openssl_ref_count++;
786
787 ssl = SSL_CTX_new(TLSv1_method());
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700788 if (ssl == NULL) {
789 tls_openssl_ref_count--;
790 if (tls_openssl_ref_count == 0) {
791 os_free(tls_global);
792 tls_global = NULL;
793 } else if (context != tls_global) {
794 os_free(context);
795 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700796 return NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700797 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700798
799 SSL_CTX_set_info_callback(ssl, ssl_info_cb);
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700800#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
801 SSL_CTX_set_app_data(ssl, context);
802#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700803
804#ifndef OPENSSL_NO_ENGINE
805 if (conf &&
806 (conf->opensc_engine_path || conf->pkcs11_engine_path ||
807 conf->pkcs11_module_path)) {
808 wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine");
809 ERR_load_ENGINE_strings();
810 ENGINE_load_dynamic();
811
812 if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) ||
813 tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path,
814 conf->pkcs11_module_path)) {
815 tls_deinit(ssl);
816 return NULL;
817 }
818 }
819#endif /* OPENSSL_NO_ENGINE */
820
821 return ssl;
822}
823
824
825void tls_deinit(void *ssl_ctx)
826{
827 SSL_CTX *ssl = ssl_ctx;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700828#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
829 struct tls_context *context = SSL_CTX_get_app_data(ssl);
830 if (context != tls_global)
831 os_free(context);
832#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700833 SSL_CTX_free(ssl);
834
835 tls_openssl_ref_count--;
836 if (tls_openssl_ref_count == 0) {
837#ifndef OPENSSL_NO_ENGINE
838 ENGINE_cleanup();
839#endif /* OPENSSL_NO_ENGINE */
840 CRYPTO_cleanup_all_ex_data();
841 ERR_remove_state(0);
842 ERR_free_strings();
843 EVP_cleanup();
844 os_free(tls_global);
845 tls_global = NULL;
846 }
847}
848
849
850static int tls_engine_init(struct tls_connection *conn, const char *engine_id,
851 const char *pin, const char *key_id,
852 const char *cert_id, const char *ca_cert_id)
853{
854#ifndef OPENSSL_NO_ENGINE
855 int ret = -1;
856 if (engine_id == NULL) {
857 wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set");
858 return -1;
859 }
Kenny Rootdb3c5a42012-03-20 17:00:47 -0700860#ifndef ANDROID
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700861 if (pin == NULL) {
862 wpa_printf(MSG_ERROR, "ENGINE: Smartcard PIN not set");
863 return -1;
864 }
Kenny Rootdb3c5a42012-03-20 17:00:47 -0700865#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700866 if (key_id == NULL) {
867 wpa_printf(MSG_ERROR, "ENGINE: Key Id not set");
868 return -1;
869 }
870
871 ERR_clear_error();
Kenny Rootdb3c5a42012-03-20 17:00:47 -0700872#ifdef ANDROID
873 ENGINE_load_dynamic();
874#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700875 conn->engine = ENGINE_by_id(engine_id);
876 if (!conn->engine) {
877 wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]",
878 engine_id, ERR_error_string(ERR_get_error(), NULL));
879 goto err;
880 }
881 if (ENGINE_init(conn->engine) != 1) {
882 wpa_printf(MSG_ERROR, "ENGINE: engine init failed "
883 "(engine: %s) [%s]", engine_id,
884 ERR_error_string(ERR_get_error(), NULL));
885 goto err;
886 }
887 wpa_printf(MSG_DEBUG, "ENGINE: engine initialized");
888
Kenny Rootdb3c5a42012-03-20 17:00:47 -0700889#ifndef ANDROID
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700890 if (ENGINE_ctrl_cmd_string(conn->engine, "PIN", pin, 0) == 0) {
891 wpa_printf(MSG_ERROR, "ENGINE: cannot set pin [%s]",
892 ERR_error_string(ERR_get_error(), NULL));
893 goto err;
894 }
Kenny Rootdb3c5a42012-03-20 17:00:47 -0700895#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700896 /* load private key first in-case PIN is required for cert */
897 conn->private_key = ENGINE_load_private_key(conn->engine,
898 key_id, NULL, NULL);
899 if (!conn->private_key) {
900 wpa_printf(MSG_ERROR, "ENGINE: cannot load private key with id"
901 " '%s' [%s]", key_id,
902 ERR_error_string(ERR_get_error(), NULL));
903 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
904 goto err;
905 }
906
907 /* handle a certificate and/or CA certificate */
908 if (cert_id || ca_cert_id) {
909 const char *cmd_name = "LOAD_CERT_CTRL";
910
911 /* test if the engine supports a LOAD_CERT_CTRL */
912 if (!ENGINE_ctrl(conn->engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
913 0, (void *)cmd_name, NULL)) {
914 wpa_printf(MSG_ERROR, "ENGINE: engine does not support"
915 " loading certificates");
916 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
917 goto err;
918 }
919 }
920
921 return 0;
922
923err:
924 if (conn->engine) {
925 ENGINE_free(conn->engine);
926 conn->engine = NULL;
927 }
928
929 if (conn->private_key) {
930 EVP_PKEY_free(conn->private_key);
931 conn->private_key = NULL;
932 }
933
934 return ret;
935#else /* OPENSSL_NO_ENGINE */
936 return 0;
937#endif /* OPENSSL_NO_ENGINE */
938}
939
940
941static void tls_engine_deinit(struct tls_connection *conn)
942{
943#ifndef OPENSSL_NO_ENGINE
944 wpa_printf(MSG_DEBUG, "ENGINE: engine deinit");
945 if (conn->private_key) {
946 EVP_PKEY_free(conn->private_key);
947 conn->private_key = NULL;
948 }
949 if (conn->engine) {
950 ENGINE_finish(conn->engine);
951 conn->engine = NULL;
952 }
953#endif /* OPENSSL_NO_ENGINE */
954}
955
956
957int tls_get_errors(void *ssl_ctx)
958{
959 int count = 0;
960 unsigned long err;
961
962 while ((err = ERR_get_error())) {
963 wpa_printf(MSG_INFO, "TLS - SSL error: %s",
964 ERR_error_string(err, NULL));
965 count++;
966 }
967
968 return count;
969}
970
971struct tls_connection * tls_connection_init(void *ssl_ctx)
972{
973 SSL_CTX *ssl = ssl_ctx;
974 struct tls_connection *conn;
975 long options;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700976 struct tls_context *context = tls_global;
977#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
978 context = SSL_CTX_get_app_data(ssl);
979#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700980
981 conn = os_zalloc(sizeof(*conn));
982 if (conn == NULL)
983 return NULL;
984 conn->ssl = SSL_new(ssl);
985 if (conn->ssl == NULL) {
986 tls_show_errors(MSG_INFO, __func__,
987 "Failed to initialize new SSL connection");
988 os_free(conn);
989 return NULL;
990 }
991
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700992 conn->context = context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700993 SSL_set_app_data(conn->ssl, conn);
994 options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
995 SSL_OP_SINGLE_DH_USE;
996#ifdef SSL_OP_NO_COMPRESSION
997 options |= SSL_OP_NO_COMPRESSION;
998#endif /* SSL_OP_NO_COMPRESSION */
Brian Carlstrom27bf1072012-07-25 23:11:44 -0700999#ifdef ANDROID
1000 options |= SSL_OP_NO_TLSv1_1;
1001 options |= SSL_OP_NO_TLSv1_2;
1002 options |= SSL_OP_NO_TICKET;
1003#endif /* ANDROID */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001004 SSL_set_options(conn->ssl, options);
1005
1006 conn->ssl_in = BIO_new(BIO_s_mem());
1007 if (!conn->ssl_in) {
1008 tls_show_errors(MSG_INFO, __func__,
1009 "Failed to create a new BIO for ssl_in");
1010 SSL_free(conn->ssl);
1011 os_free(conn);
1012 return NULL;
1013 }
1014
1015 conn->ssl_out = BIO_new(BIO_s_mem());
1016 if (!conn->ssl_out) {
1017 tls_show_errors(MSG_INFO, __func__,
1018 "Failed to create a new BIO for ssl_out");
1019 SSL_free(conn->ssl);
1020 BIO_free(conn->ssl_in);
1021 os_free(conn);
1022 return NULL;
1023 }
1024
1025 SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out);
1026
1027 return conn;
1028}
1029
1030
1031void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
1032{
1033 if (conn == NULL)
1034 return;
1035 SSL_free(conn->ssl);
1036 tls_engine_deinit(conn);
1037 os_free(conn->subject_match);
1038 os_free(conn->altsubject_match);
1039 os_free(conn->session_ticket);
1040 os_free(conn);
1041}
1042
1043
1044int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
1045{
1046 return conn ? SSL_is_init_finished(conn->ssl) : 0;
1047}
1048
1049
1050int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
1051{
1052 if (conn == NULL)
1053 return -1;
1054
1055 /* Shutdown previous TLS connection without notifying the peer
1056 * because the connection was already terminated in practice
1057 * and "close notify" shutdown alert would confuse AS. */
1058 SSL_set_quiet_shutdown(conn->ssl, 1);
1059 SSL_shutdown(conn->ssl);
1060 return 0;
1061}
1062
1063
1064static int tls_match_altsubject_component(X509 *cert, int type,
1065 const char *value, size_t len)
1066{
1067 GENERAL_NAME *gen;
1068 void *ext;
1069 int i, found = 0;
1070
1071 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1072
1073 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
1074 gen = sk_GENERAL_NAME_value(ext, i);
1075 if (gen->type != type)
1076 continue;
1077 if (os_strlen((char *) gen->d.ia5->data) == len &&
1078 os_memcmp(value, gen->d.ia5->data, len) == 0)
1079 found++;
1080 }
1081
1082 return found;
1083}
1084
1085
1086static int tls_match_altsubject(X509 *cert, const char *match)
1087{
1088 int type;
1089 const char *pos, *end;
1090 size_t len;
1091
1092 pos = match;
1093 do {
1094 if (os_strncmp(pos, "EMAIL:", 6) == 0) {
1095 type = GEN_EMAIL;
1096 pos += 6;
1097 } else if (os_strncmp(pos, "DNS:", 4) == 0) {
1098 type = GEN_DNS;
1099 pos += 4;
1100 } else if (os_strncmp(pos, "URI:", 4) == 0) {
1101 type = GEN_URI;
1102 pos += 4;
1103 } else {
1104 wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName "
1105 "match '%s'", pos);
1106 return 0;
1107 }
1108 end = os_strchr(pos, ';');
1109 while (end) {
1110 if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
1111 os_strncmp(end + 1, "DNS:", 4) == 0 ||
1112 os_strncmp(end + 1, "URI:", 4) == 0)
1113 break;
1114 end = os_strchr(end + 1, ';');
1115 }
1116 if (end)
1117 len = end - pos;
1118 else
1119 len = os_strlen(pos);
1120 if (tls_match_altsubject_component(cert, type, pos, len) > 0)
1121 return 1;
1122 pos = end + 1;
1123 } while (end);
1124
1125 return 0;
1126}
1127
1128
1129static enum tls_fail_reason openssl_tls_fail_reason(int err)
1130{
1131 switch (err) {
1132 case X509_V_ERR_CERT_REVOKED:
1133 return TLS_FAIL_REVOKED;
1134 case X509_V_ERR_CERT_NOT_YET_VALID:
1135 case X509_V_ERR_CRL_NOT_YET_VALID:
1136 return TLS_FAIL_NOT_YET_VALID;
1137 case X509_V_ERR_CERT_HAS_EXPIRED:
1138 case X509_V_ERR_CRL_HAS_EXPIRED:
1139 return TLS_FAIL_EXPIRED;
1140 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1141 case X509_V_ERR_UNABLE_TO_GET_CRL:
1142 case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
1143 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1144 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1145 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1146 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1147 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1148 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1149 case X509_V_ERR_INVALID_CA:
1150 return TLS_FAIL_UNTRUSTED;
1151 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1152 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
1153 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
1154 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1155 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1156 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
1157 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
1158 case X509_V_ERR_CERT_UNTRUSTED:
1159 case X509_V_ERR_CERT_REJECTED:
1160 return TLS_FAIL_BAD_CERTIFICATE;
1161 default:
1162 return TLS_FAIL_UNSPECIFIED;
1163 }
1164}
1165
1166
1167static struct wpabuf * get_x509_cert(X509 *cert)
1168{
1169 struct wpabuf *buf;
1170 u8 *tmp;
1171
1172 int cert_len = i2d_X509(cert, NULL);
1173 if (cert_len <= 0)
1174 return NULL;
1175
1176 buf = wpabuf_alloc(cert_len);
1177 if (buf == NULL)
1178 return NULL;
1179
1180 tmp = wpabuf_put(buf, cert_len);
1181 i2d_X509(cert, &tmp);
1182 return buf;
1183}
1184
1185
1186static void openssl_tls_fail_event(struct tls_connection *conn,
1187 X509 *err_cert, int err, int depth,
1188 const char *subject, const char *err_str,
1189 enum tls_fail_reason reason)
1190{
1191 union tls_event_data ev;
1192 struct wpabuf *cert = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001193 struct tls_context *context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001194
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001195 if (context->event_cb == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001196 return;
1197
1198 cert = get_x509_cert(err_cert);
1199 os_memset(&ev, 0, sizeof(ev));
1200 ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ?
1201 reason : openssl_tls_fail_reason(err);
1202 ev.cert_fail.depth = depth;
1203 ev.cert_fail.subject = subject;
1204 ev.cert_fail.reason_txt = err_str;
1205 ev.cert_fail.cert = cert;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001206 context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001207 wpabuf_free(cert);
1208}
1209
1210
1211static void openssl_tls_cert_event(struct tls_connection *conn,
1212 X509 *err_cert, int depth,
1213 const char *subject)
1214{
1215 struct wpabuf *cert = NULL;
1216 union tls_event_data ev;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001217 struct tls_context *context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001218#ifdef CONFIG_SHA256
1219 u8 hash[32];
1220#endif /* CONFIG_SHA256 */
1221
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001222 if (context->event_cb == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001223 return;
1224
1225 os_memset(&ev, 0, sizeof(ev));
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001226 if (conn->cert_probe || context->cert_in_cb) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001227 cert = get_x509_cert(err_cert);
1228 ev.peer_cert.cert = cert;
1229 }
1230#ifdef CONFIG_SHA256
1231 if (cert) {
1232 const u8 *addr[1];
1233 size_t len[1];
1234 addr[0] = wpabuf_head(cert);
1235 len[0] = wpabuf_len(cert);
1236 if (sha256_vector(1, addr, len, hash) == 0) {
1237 ev.peer_cert.hash = hash;
1238 ev.peer_cert.hash_len = sizeof(hash);
1239 }
1240 }
1241#endif /* CONFIG_SHA256 */
1242 ev.peer_cert.depth = depth;
1243 ev.peer_cert.subject = subject;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001244 context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001245 wpabuf_free(cert);
1246}
1247
1248
1249static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
1250{
1251 char buf[256];
1252 X509 *err_cert;
1253 int err, depth;
1254 SSL *ssl;
1255 struct tls_connection *conn;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001256 struct tls_context *context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001257 char *match, *altmatch;
1258 const char *err_str;
1259
1260 err_cert = X509_STORE_CTX_get_current_cert(x509_ctx);
1261 err = X509_STORE_CTX_get_error(x509_ctx);
1262 depth = X509_STORE_CTX_get_error_depth(x509_ctx);
1263 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
1264 SSL_get_ex_data_X509_STORE_CTX_idx());
1265 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
1266
1267 conn = SSL_get_app_data(ssl);
1268 if (conn == NULL)
1269 return 0;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001270 context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001271 match = conn->subject_match;
1272 altmatch = conn->altsubject_match;
1273
1274 if (!preverify_ok && !conn->ca_cert_verify)
1275 preverify_ok = 1;
1276 if (!preverify_ok && depth > 0 && conn->server_cert_only)
1277 preverify_ok = 1;
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07001278 if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) &&
1279 (err == X509_V_ERR_CERT_HAS_EXPIRED ||
1280 err == X509_V_ERR_CERT_NOT_YET_VALID)) {
1281 wpa_printf(MSG_DEBUG, "OpenSSL: Ignore certificate validity "
1282 "time mismatch");
1283 preverify_ok = 1;
1284 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001285
1286 err_str = X509_verify_cert_error_string(err);
1287
1288#ifdef CONFIG_SHA256
1289 if (preverify_ok && depth == 0 && conn->server_cert_only) {
1290 struct wpabuf *cert;
1291 cert = get_x509_cert(err_cert);
1292 if (!cert) {
1293 wpa_printf(MSG_DEBUG, "OpenSSL: Could not fetch "
1294 "server certificate data");
1295 preverify_ok = 0;
1296 } else {
1297 u8 hash[32];
1298 const u8 *addr[1];
1299 size_t len[1];
1300 addr[0] = wpabuf_head(cert);
1301 len[0] = wpabuf_len(cert);
1302 if (sha256_vector(1, addr, len, hash) < 0 ||
1303 os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
1304 err_str = "Server certificate mismatch";
1305 err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
1306 preverify_ok = 0;
1307 }
1308 wpabuf_free(cert);
1309 }
1310 }
1311#endif /* CONFIG_SHA256 */
1312
1313 if (!preverify_ok) {
1314 wpa_printf(MSG_WARNING, "TLS: Certificate verification failed,"
1315 " error %d (%s) depth %d for '%s'", err, err_str,
1316 depth, buf);
1317 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
1318 err_str, TLS_FAIL_UNSPECIFIED);
1319 return preverify_ok;
1320 }
1321
1322 wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d "
1323 "err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
1324 preverify_ok, err, err_str,
1325 conn->ca_cert_verify, depth, buf);
1326 if (depth == 0 && match && os_strstr(buf, match) == NULL) {
1327 wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not "
1328 "match with '%s'", buf, match);
1329 preverify_ok = 0;
1330 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
1331 "Subject mismatch",
1332 TLS_FAIL_SUBJECT_MISMATCH);
1333 } else if (depth == 0 && altmatch &&
1334 !tls_match_altsubject(err_cert, altmatch)) {
1335 wpa_printf(MSG_WARNING, "TLS: altSubjectName match "
1336 "'%s' not found", altmatch);
1337 preverify_ok = 0;
1338 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
1339 "AltSubject mismatch",
1340 TLS_FAIL_ALTSUBJECT_MISMATCH);
1341 } else
1342 openssl_tls_cert_event(conn, err_cert, depth, buf);
1343
1344 if (conn->cert_probe && preverify_ok && depth == 0) {
1345 wpa_printf(MSG_DEBUG, "OpenSSL: Reject server certificate "
1346 "on probe-only run");
1347 preverify_ok = 0;
1348 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
1349 "Server certificate chain probe",
1350 TLS_FAIL_SERVER_CHAIN_PROBE);
1351 }
1352
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001353 if (preverify_ok && context->event_cb != NULL)
1354 context->event_cb(context->cb_ctx,
1355 TLS_CERT_CHAIN_SUCCESS, NULL);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001356
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001357 return preverify_ok;
1358}
1359
1360
1361#ifndef OPENSSL_NO_STDIO
1362static int tls_load_ca_der(void *_ssl_ctx, const char *ca_cert)
1363{
1364 SSL_CTX *ssl_ctx = _ssl_ctx;
1365 X509_LOOKUP *lookup;
1366 int ret = 0;
1367
1368 lookup = X509_STORE_add_lookup(ssl_ctx->cert_store,
1369 X509_LOOKUP_file());
1370 if (lookup == NULL) {
1371 tls_show_errors(MSG_WARNING, __func__,
1372 "Failed add lookup for X509 store");
1373 return -1;
1374 }
1375
1376 if (!X509_LOOKUP_load_file(lookup, ca_cert, X509_FILETYPE_ASN1)) {
1377 unsigned long err = ERR_peek_error();
1378 tls_show_errors(MSG_WARNING, __func__,
1379 "Failed load CA in DER format");
1380 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
1381 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
1382 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
1383 "cert already in hash table error",
1384 __func__);
1385 } else
1386 ret = -1;
1387 }
1388
1389 return ret;
1390}
1391#endif /* OPENSSL_NO_STDIO */
1392
1393
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001394static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn,
1395 const char *ca_cert, const u8 *ca_cert_blob,
1396 size_t ca_cert_blob_len, const char *ca_path)
1397{
1398 SSL_CTX *ssl_ctx = _ssl_ctx;
1399
1400 /*
1401 * Remove previously configured trusted CA certificates before adding
1402 * new ones.
1403 */
1404 X509_STORE_free(ssl_ctx->cert_store);
1405 ssl_ctx->cert_store = X509_STORE_new();
1406 if (ssl_ctx->cert_store == NULL) {
1407 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
1408 "certificate store", __func__);
1409 return -1;
1410 }
1411
1412 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
1413 conn->ca_cert_verify = 1;
1414
1415 if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) {
1416 wpa_printf(MSG_DEBUG, "OpenSSL: Probe for server certificate "
1417 "chain");
1418 conn->cert_probe = 1;
1419 conn->ca_cert_verify = 0;
1420 return 0;
1421 }
1422
1423 if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) {
1424#ifdef CONFIG_SHA256
1425 const char *pos = ca_cert + 7;
1426 if (os_strncmp(pos, "server/sha256/", 14) != 0) {
1427 wpa_printf(MSG_DEBUG, "OpenSSL: Unsupported ca_cert "
1428 "hash value '%s'", ca_cert);
1429 return -1;
1430 }
1431 pos += 14;
1432 if (os_strlen(pos) != 32 * 2) {
1433 wpa_printf(MSG_DEBUG, "OpenSSL: Unexpected SHA256 "
1434 "hash length in ca_cert '%s'", ca_cert);
1435 return -1;
1436 }
1437 if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) {
1438 wpa_printf(MSG_DEBUG, "OpenSSL: Invalid SHA256 hash "
1439 "value in ca_cert '%s'", ca_cert);
1440 return -1;
1441 }
1442 conn->server_cert_only = 1;
1443 wpa_printf(MSG_DEBUG, "OpenSSL: Checking only server "
1444 "certificate match");
1445 return 0;
1446#else /* CONFIG_SHA256 */
1447 wpa_printf(MSG_INFO, "No SHA256 included in the build - "
1448 "cannot validate server certificate hash");
1449 return -1;
1450#endif /* CONFIG_SHA256 */
1451 }
1452
1453 if (ca_cert_blob) {
1454 X509 *cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ca_cert_blob,
1455 ca_cert_blob_len);
1456 if (cert == NULL) {
1457 tls_show_errors(MSG_WARNING, __func__,
1458 "Failed to parse ca_cert_blob");
1459 return -1;
1460 }
1461
1462 if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) {
1463 unsigned long err = ERR_peek_error();
1464 tls_show_errors(MSG_WARNING, __func__,
1465 "Failed to add ca_cert_blob to "
1466 "certificate store");
1467 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
1468 ERR_GET_REASON(err) ==
1469 X509_R_CERT_ALREADY_IN_HASH_TABLE) {
1470 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
1471 "cert already in hash table error",
1472 __func__);
1473 } else {
1474 X509_free(cert);
1475 return -1;
1476 }
1477 }
1478 X509_free(cert);
1479 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob "
1480 "to certificate store", __func__);
1481 return 0;
1482 }
1483
1484#ifdef ANDROID
1485 if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) {
1486 BIO *bio = BIO_from_keystore(&ca_cert[11]);
1487 STACK_OF(X509_INFO) *stack = NULL;
1488 int i;
1489
1490 if (bio) {
1491 stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
1492 BIO_free(bio);
1493 }
1494 if (!stack)
1495 return -1;
1496
1497 for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
1498 X509_INFO *info = sk_X509_INFO_value(stack, i);
1499 if (info->x509) {
1500 X509_STORE_add_cert(ssl_ctx->cert_store,
1501 info->x509);
1502 }
1503 if (info->crl) {
1504 X509_STORE_add_crl(ssl_ctx->cert_store,
1505 info->crl);
1506 }
1507 }
1508 sk_X509_INFO_pop_free(stack, X509_INFO_free);
1509 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
1510 return 0;
1511 }
1512#endif /* ANDROID */
1513
1514#ifdef CONFIG_NATIVE_WINDOWS
1515 if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) ==
1516 0) {
1517 wpa_printf(MSG_DEBUG, "OpenSSL: Added CA certificates from "
1518 "system certificate store");
1519 return 0;
1520 }
1521#endif /* CONFIG_NATIVE_WINDOWS */
1522
1523 if (ca_cert || ca_path) {
1524#ifndef OPENSSL_NO_STDIO
1525 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, ca_path) !=
1526 1) {
1527 tls_show_errors(MSG_WARNING, __func__,
1528 "Failed to load root certificates");
1529 if (ca_cert &&
1530 tls_load_ca_der(ssl_ctx, ca_cert) == 0) {
1531 wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded "
1532 "DER format CA certificate",
1533 __func__);
1534 } else
1535 return -1;
1536 } else {
1537 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
1538 "certificate(s) loaded");
1539 tls_get_errors(ssl_ctx);
1540 }
1541#else /* OPENSSL_NO_STDIO */
1542 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
1543 __func__);
1544 return -1;
1545#endif /* OPENSSL_NO_STDIO */
1546 } else {
1547 /* No ca_cert configured - do not try to verify server
1548 * certificate */
1549 conn->ca_cert_verify = 0;
1550 }
1551
1552 return 0;
1553}
1554
1555
1556static int tls_global_ca_cert(SSL_CTX *ssl_ctx, const char *ca_cert)
1557{
1558 if (ca_cert) {
1559 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
1560 {
1561 tls_show_errors(MSG_WARNING, __func__,
1562 "Failed to load root certificates");
1563 return -1;
1564 }
1565
1566 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
1567 "certificate(s) loaded");
1568
1569#ifndef OPENSSL_NO_STDIO
1570 /* Add the same CAs to the client certificate requests */
1571 SSL_CTX_set_client_CA_list(ssl_ctx,
1572 SSL_load_client_CA_file(ca_cert));
1573#endif /* OPENSSL_NO_STDIO */
1574 }
1575
1576 return 0;
1577}
1578
1579
1580int tls_global_set_verify(void *ssl_ctx, int check_crl)
1581{
1582 int flags;
1583
1584 if (check_crl) {
1585 X509_STORE *cs = SSL_CTX_get_cert_store(ssl_ctx);
1586 if (cs == NULL) {
1587 tls_show_errors(MSG_INFO, __func__, "Failed to get "
1588 "certificate store when enabling "
1589 "check_crl");
1590 return -1;
1591 }
1592 flags = X509_V_FLAG_CRL_CHECK;
1593 if (check_crl == 2)
1594 flags |= X509_V_FLAG_CRL_CHECK_ALL;
1595 X509_STORE_set_flags(cs, flags);
1596 }
1597 return 0;
1598}
1599
1600
1601static int tls_connection_set_subject_match(struct tls_connection *conn,
1602 const char *subject_match,
1603 const char *altsubject_match)
1604{
1605 os_free(conn->subject_match);
1606 conn->subject_match = NULL;
1607 if (subject_match) {
1608 conn->subject_match = os_strdup(subject_match);
1609 if (conn->subject_match == NULL)
1610 return -1;
1611 }
1612
1613 os_free(conn->altsubject_match);
1614 conn->altsubject_match = NULL;
1615 if (altsubject_match) {
1616 conn->altsubject_match = os_strdup(altsubject_match);
1617 if (conn->altsubject_match == NULL)
1618 return -1;
1619 }
1620
1621 return 0;
1622}
1623
1624
1625int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
1626 int verify_peer)
1627{
1628 static int counter = 0;
1629
1630 if (conn == NULL)
1631 return -1;
1632
1633 if (verify_peer) {
1634 conn->ca_cert_verify = 1;
1635 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
1636 SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
1637 SSL_VERIFY_CLIENT_ONCE, tls_verify_cb);
1638 } else {
1639 conn->ca_cert_verify = 0;
1640 SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
1641 }
1642
1643 SSL_set_accept_state(conn->ssl);
1644
1645 /*
1646 * Set session id context in order to avoid fatal errors when client
1647 * tries to resume a session. However, set the context to a unique
1648 * value in order to effectively disable session resumption for now
1649 * since not all areas of the server code are ready for it (e.g.,
1650 * EAP-TTLS needs special handling for Phase 2 after abbreviated TLS
1651 * handshake).
1652 */
1653 counter++;
1654 SSL_set_session_id_context(conn->ssl,
1655 (const unsigned char *) &counter,
1656 sizeof(counter));
1657
1658 return 0;
1659}
1660
1661
1662static int tls_connection_client_cert(struct tls_connection *conn,
1663 const char *client_cert,
1664 const u8 *client_cert_blob,
1665 size_t client_cert_blob_len)
1666{
1667 if (client_cert == NULL && client_cert_blob == NULL)
1668 return 0;
1669
1670 if (client_cert_blob &&
1671 SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob,
1672 client_cert_blob_len) == 1) {
1673 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> "
1674 "OK");
1675 return 0;
1676 } else if (client_cert_blob) {
1677 tls_show_errors(MSG_DEBUG, __func__,
1678 "SSL_use_certificate_ASN1 failed");
1679 }
1680
1681 if (client_cert == NULL)
1682 return -1;
1683
1684#ifdef ANDROID
1685 if (os_strncmp("keystore://", client_cert, 11) == 0) {
1686 BIO *bio = BIO_from_keystore(&client_cert[11]);
1687 X509 *x509 = NULL;
1688 int ret = -1;
1689 if (bio) {
1690 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
1691 BIO_free(bio);
1692 }
1693 if (x509) {
1694 if (SSL_use_certificate(conn->ssl, x509) == 1)
1695 ret = 0;
1696 X509_free(x509);
1697 }
1698 return ret;
1699 }
1700#endif /* ANDROID */
1701
1702#ifndef OPENSSL_NO_STDIO
1703 if (SSL_use_certificate_file(conn->ssl, client_cert,
1704 SSL_FILETYPE_ASN1) == 1) {
1705 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)"
1706 " --> OK");
1707 return 0;
1708 }
1709
1710 if (SSL_use_certificate_file(conn->ssl, client_cert,
1711 SSL_FILETYPE_PEM) == 1) {
1712 ERR_clear_error();
1713 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)"
1714 " --> OK");
1715 return 0;
1716 }
1717
1718 tls_show_errors(MSG_DEBUG, __func__,
1719 "SSL_use_certificate_file failed");
1720#else /* OPENSSL_NO_STDIO */
1721 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
1722#endif /* OPENSSL_NO_STDIO */
1723
1724 return -1;
1725}
1726
1727
1728static int tls_global_client_cert(SSL_CTX *ssl_ctx, const char *client_cert)
1729{
1730#ifndef OPENSSL_NO_STDIO
1731 if (client_cert == NULL)
1732 return 0;
1733
1734 if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
1735 SSL_FILETYPE_ASN1) != 1 &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001736 SSL_CTX_use_certificate_chain_file(ssl_ctx, client_cert) != 1 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001737 SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
1738 SSL_FILETYPE_PEM) != 1) {
1739 tls_show_errors(MSG_INFO, __func__,
1740 "Failed to load client certificate");
1741 return -1;
1742 }
1743 return 0;
1744#else /* OPENSSL_NO_STDIO */
1745 if (client_cert == NULL)
1746 return 0;
1747 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
1748 return -1;
1749#endif /* OPENSSL_NO_STDIO */
1750}
1751
1752
1753static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
1754{
1755 if (password == NULL) {
1756 return 0;
1757 }
1758 os_strlcpy(buf, (char *) password, size);
1759 return os_strlen(buf);
1760}
1761
1762
1763#ifdef PKCS12_FUNCS
1764static int tls_parse_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, PKCS12 *p12,
1765 const char *passwd)
1766{
1767 EVP_PKEY *pkey;
1768 X509 *cert;
1769 STACK_OF(X509) *certs;
1770 int res = 0;
1771 char buf[256];
1772
1773 pkey = NULL;
1774 cert = NULL;
1775 certs = NULL;
1776 if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) {
1777 tls_show_errors(MSG_DEBUG, __func__,
1778 "Failed to parse PKCS12 file");
1779 PKCS12_free(p12);
1780 return -1;
1781 }
1782 wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data");
1783
1784 if (cert) {
1785 X509_NAME_oneline(X509_get_subject_name(cert), buf,
1786 sizeof(buf));
1787 wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: "
1788 "subject='%s'", buf);
1789 if (ssl) {
1790 if (SSL_use_certificate(ssl, cert) != 1)
1791 res = -1;
1792 } else {
1793 if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1)
1794 res = -1;
1795 }
1796 X509_free(cert);
1797 }
1798
1799 if (pkey) {
1800 wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12");
1801 if (ssl) {
1802 if (SSL_use_PrivateKey(ssl, pkey) != 1)
1803 res = -1;
1804 } else {
1805 if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1)
1806 res = -1;
1807 }
1808 EVP_PKEY_free(pkey);
1809 }
1810
1811 if (certs) {
1812 while ((cert = sk_X509_pop(certs)) != NULL) {
1813 X509_NAME_oneline(X509_get_subject_name(cert), buf,
1814 sizeof(buf));
1815 wpa_printf(MSG_DEBUG, "TLS: additional certificate"
1816 " from PKCS12: subject='%s'", buf);
1817 /*
1818 * There is no SSL equivalent for the chain cert - so
1819 * always add it to the context...
1820 */
1821 if (SSL_CTX_add_extra_chain_cert(ssl_ctx, cert) != 1) {
1822 res = -1;
1823 break;
1824 }
1825 }
1826 sk_X509_free(certs);
1827 }
1828
1829 PKCS12_free(p12);
1830
1831 if (res < 0)
1832 tls_get_errors(ssl_ctx);
1833
1834 return res;
1835}
1836#endif /* PKCS12_FUNCS */
1837
1838
1839static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key,
1840 const char *passwd)
1841{
1842#ifdef PKCS12_FUNCS
1843 FILE *f;
1844 PKCS12 *p12;
1845
1846 f = fopen(private_key, "rb");
1847 if (f == NULL)
1848 return -1;
1849
1850 p12 = d2i_PKCS12_fp(f, NULL);
1851 fclose(f);
1852
1853 if (p12 == NULL) {
1854 tls_show_errors(MSG_INFO, __func__,
1855 "Failed to use PKCS#12 file");
1856 return -1;
1857 }
1858
1859 return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd);
1860
1861#else /* PKCS12_FUNCS */
1862 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read "
1863 "p12/pfx files");
1864 return -1;
1865#endif /* PKCS12_FUNCS */
1866}
1867
1868
1869static int tls_read_pkcs12_blob(SSL_CTX *ssl_ctx, SSL *ssl,
1870 const u8 *blob, size_t len, const char *passwd)
1871{
1872#ifdef PKCS12_FUNCS
1873 PKCS12 *p12;
1874
1875 p12 = d2i_PKCS12(NULL, (OPENSSL_d2i_TYPE) &blob, len);
1876 if (p12 == NULL) {
1877 tls_show_errors(MSG_INFO, __func__,
1878 "Failed to use PKCS#12 blob");
1879 return -1;
1880 }
1881
1882 return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd);
1883
1884#else /* PKCS12_FUNCS */
1885 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse "
1886 "p12/pfx blobs");
1887 return -1;
1888#endif /* PKCS12_FUNCS */
1889}
1890
1891
1892#ifndef OPENSSL_NO_ENGINE
1893static int tls_engine_get_cert(struct tls_connection *conn,
1894 const char *cert_id,
1895 X509 **cert)
1896{
1897 /* this runs after the private key is loaded so no PIN is required */
1898 struct {
1899 const char *cert_id;
1900 X509 *cert;
1901 } params;
1902 params.cert_id = cert_id;
1903 params.cert = NULL;
1904
1905 if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL",
1906 0, &params, NULL, 1)) {
1907 wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id"
1908 " '%s' [%s]", cert_id,
1909 ERR_error_string(ERR_get_error(), NULL));
1910 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
1911 }
1912 if (!params.cert) {
1913 wpa_printf(MSG_ERROR, "ENGINE: did not properly cert with id"
1914 " '%s'", cert_id);
1915 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
1916 }
1917 *cert = params.cert;
1918 return 0;
1919}
1920#endif /* OPENSSL_NO_ENGINE */
1921
1922
1923static int tls_connection_engine_client_cert(struct tls_connection *conn,
1924 const char *cert_id)
1925{
1926#ifndef OPENSSL_NO_ENGINE
1927 X509 *cert;
1928
1929 if (tls_engine_get_cert(conn, cert_id, &cert))
1930 return -1;
1931
1932 if (!SSL_use_certificate(conn->ssl, cert)) {
1933 tls_show_errors(MSG_ERROR, __func__,
1934 "SSL_use_certificate failed");
1935 X509_free(cert);
1936 return -1;
1937 }
1938 X509_free(cert);
1939 wpa_printf(MSG_DEBUG, "ENGINE: SSL_use_certificate --> "
1940 "OK");
1941 return 0;
1942
1943#else /* OPENSSL_NO_ENGINE */
1944 return -1;
1945#endif /* OPENSSL_NO_ENGINE */
1946}
1947
1948
1949static int tls_connection_engine_ca_cert(void *_ssl_ctx,
1950 struct tls_connection *conn,
1951 const char *ca_cert_id)
1952{
1953#ifndef OPENSSL_NO_ENGINE
1954 X509 *cert;
1955 SSL_CTX *ssl_ctx = _ssl_ctx;
1956
1957 if (tls_engine_get_cert(conn, ca_cert_id, &cert))
1958 return -1;
1959
1960 /* start off the same as tls_connection_ca_cert */
1961 X509_STORE_free(ssl_ctx->cert_store);
1962 ssl_ctx->cert_store = X509_STORE_new();
1963 if (ssl_ctx->cert_store == NULL) {
1964 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
1965 "certificate store", __func__);
1966 X509_free(cert);
1967 return -1;
1968 }
1969 if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) {
1970 unsigned long err = ERR_peek_error();
1971 tls_show_errors(MSG_WARNING, __func__,
1972 "Failed to add CA certificate from engine "
1973 "to certificate store");
1974 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
1975 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
1976 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring cert"
1977 " already in hash table error",
1978 __func__);
1979 } else {
1980 X509_free(cert);
1981 return -1;
1982 }
1983 }
1984 X509_free(cert);
1985 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added CA certificate from engine "
1986 "to certificate store", __func__);
1987 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001988 conn->ca_cert_verify = 1;
1989
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001990 return 0;
1991
1992#else /* OPENSSL_NO_ENGINE */
1993 return -1;
1994#endif /* OPENSSL_NO_ENGINE */
1995}
1996
1997
1998static int tls_connection_engine_private_key(struct tls_connection *conn)
1999{
2000#ifndef OPENSSL_NO_ENGINE
2001 if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) {
2002 tls_show_errors(MSG_ERROR, __func__,
2003 "ENGINE: cannot use private key for TLS");
2004 return -1;
2005 }
2006 if (!SSL_check_private_key(conn->ssl)) {
2007 tls_show_errors(MSG_INFO, __func__,
2008 "Private key failed verification");
2009 return -1;
2010 }
2011 return 0;
2012#else /* OPENSSL_NO_ENGINE */
2013 wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but "
2014 "engine support was not compiled in");
2015 return -1;
2016#endif /* OPENSSL_NO_ENGINE */
2017}
2018
2019
2020static int tls_connection_private_key(void *_ssl_ctx,
2021 struct tls_connection *conn,
2022 const char *private_key,
2023 const char *private_key_passwd,
2024 const u8 *private_key_blob,
2025 size_t private_key_blob_len)
2026{
2027 SSL_CTX *ssl_ctx = _ssl_ctx;
2028 char *passwd;
2029 int ok;
2030
2031 if (private_key == NULL && private_key_blob == NULL)
2032 return 0;
2033
2034 if (private_key_passwd) {
2035 passwd = os_strdup(private_key_passwd);
2036 if (passwd == NULL)
2037 return -1;
2038 } else
2039 passwd = NULL;
2040
2041 SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
2042 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
2043
2044 ok = 0;
2045 while (private_key_blob) {
2046 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl,
2047 (u8 *) private_key_blob,
2048 private_key_blob_len) == 1) {
2049 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
2050 "ASN1(EVP_PKEY_RSA) --> OK");
2051 ok = 1;
2052 break;
2053 }
2054
2055 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl,
2056 (u8 *) private_key_blob,
2057 private_key_blob_len) == 1) {
2058 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
2059 "ASN1(EVP_PKEY_DSA) --> OK");
2060 ok = 1;
2061 break;
2062 }
2063
2064 if (SSL_use_RSAPrivateKey_ASN1(conn->ssl,
2065 (u8 *) private_key_blob,
2066 private_key_blob_len) == 1) {
2067 wpa_printf(MSG_DEBUG, "OpenSSL: "
2068 "SSL_use_RSAPrivateKey_ASN1 --> OK");
2069 ok = 1;
2070 break;
2071 }
2072
2073 if (tls_read_pkcs12_blob(ssl_ctx, conn->ssl, private_key_blob,
2074 private_key_blob_len, passwd) == 0) {
2075 wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> "
2076 "OK");
2077 ok = 1;
2078 break;
2079 }
2080
2081 break;
2082 }
2083
2084#ifdef ANDROID
2085 if (!ok && private_key &&
2086 os_strncmp("keystore://", private_key, 11) == 0) {
2087 BIO *bio = BIO_from_keystore(&private_key[11]);
2088 EVP_PKEY *pkey = NULL;
2089 if (bio) {
2090 pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
2091 BIO_free(bio);
2092 }
2093 if (pkey) {
2094 if (SSL_use_PrivateKey(conn->ssl, pkey) == 1) {
2095 wpa_printf(MSG_DEBUG, "OpenSSL: Private key "
2096 "from keystore");
2097 ok = 1;
2098 }
2099 EVP_PKEY_free(pkey);
2100 }
2101 }
2102#endif /* ANDROID */
2103
2104 while (!ok && private_key) {
2105#ifndef OPENSSL_NO_STDIO
2106 if (SSL_use_PrivateKey_file(conn->ssl, private_key,
2107 SSL_FILETYPE_ASN1) == 1) {
2108 wpa_printf(MSG_DEBUG, "OpenSSL: "
2109 "SSL_use_PrivateKey_File (DER) --> OK");
2110 ok = 1;
2111 break;
2112 }
2113
2114 if (SSL_use_PrivateKey_file(conn->ssl, private_key,
2115 SSL_FILETYPE_PEM) == 1) {
2116 wpa_printf(MSG_DEBUG, "OpenSSL: "
2117 "SSL_use_PrivateKey_File (PEM) --> OK");
2118 ok = 1;
2119 break;
2120 }
2121#else /* OPENSSL_NO_STDIO */
2122 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
2123 __func__);
2124#endif /* OPENSSL_NO_STDIO */
2125
2126 if (tls_read_pkcs12(ssl_ctx, conn->ssl, private_key, passwd)
2127 == 0) {
2128 wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file "
2129 "--> OK");
2130 ok = 1;
2131 break;
2132 }
2133
2134 if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) {
2135 wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to "
2136 "access certificate store --> OK");
2137 ok = 1;
2138 break;
2139 }
2140
2141 break;
2142 }
2143
2144 if (!ok) {
2145 tls_show_errors(MSG_INFO, __func__,
2146 "Failed to load private key");
2147 os_free(passwd);
2148 return -1;
2149 }
2150 ERR_clear_error();
2151 SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
2152 os_free(passwd);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002153
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002154 if (!SSL_check_private_key(conn->ssl)) {
2155 tls_show_errors(MSG_INFO, __func__, "Private key failed "
2156 "verification");
2157 return -1;
2158 }
2159
2160 wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully");
2161 return 0;
2162}
2163
2164
2165static int tls_global_private_key(SSL_CTX *ssl_ctx, const char *private_key,
2166 const char *private_key_passwd)
2167{
2168 char *passwd;
2169
2170 if (private_key == NULL)
2171 return 0;
2172
2173 if (private_key_passwd) {
2174 passwd = os_strdup(private_key_passwd);
2175 if (passwd == NULL)
2176 return -1;
2177 } else
2178 passwd = NULL;
2179
2180 SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
2181 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
2182 if (
2183#ifndef OPENSSL_NO_STDIO
2184 SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
2185 SSL_FILETYPE_ASN1) != 1 &&
2186 SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
2187 SSL_FILETYPE_PEM) != 1 &&
2188#endif /* OPENSSL_NO_STDIO */
2189 tls_read_pkcs12(ssl_ctx, NULL, private_key, passwd)) {
2190 tls_show_errors(MSG_INFO, __func__,
2191 "Failed to load private key");
2192 os_free(passwd);
2193 ERR_clear_error();
2194 return -1;
2195 }
2196 os_free(passwd);
2197 ERR_clear_error();
2198 SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002199
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002200 if (!SSL_CTX_check_private_key(ssl_ctx)) {
2201 tls_show_errors(MSG_INFO, __func__,
2202 "Private key failed verification");
2203 return -1;
2204 }
2205
2206 return 0;
2207}
2208
2209
2210static int tls_connection_dh(struct tls_connection *conn, const char *dh_file)
2211{
2212#ifdef OPENSSL_NO_DH
2213 if (dh_file == NULL)
2214 return 0;
2215 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
2216 "dh_file specified");
2217 return -1;
2218#else /* OPENSSL_NO_DH */
2219 DH *dh;
2220 BIO *bio;
2221
2222 /* TODO: add support for dh_blob */
2223 if (dh_file == NULL)
2224 return 0;
2225 if (conn == NULL)
2226 return -1;
2227
2228 bio = BIO_new_file(dh_file, "r");
2229 if (bio == NULL) {
2230 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
2231 dh_file, ERR_error_string(ERR_get_error(), NULL));
2232 return -1;
2233 }
2234 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
2235 BIO_free(bio);
2236#ifndef OPENSSL_NO_DSA
2237 while (dh == NULL) {
2238 DSA *dsa;
2239 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
2240 " trying to parse as DSA params", dh_file,
2241 ERR_error_string(ERR_get_error(), NULL));
2242 bio = BIO_new_file(dh_file, "r");
2243 if (bio == NULL)
2244 break;
2245 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
2246 BIO_free(bio);
2247 if (!dsa) {
2248 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
2249 "'%s': %s", dh_file,
2250 ERR_error_string(ERR_get_error(), NULL));
2251 break;
2252 }
2253
2254 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
2255 dh = DSA_dup_DH(dsa);
2256 DSA_free(dsa);
2257 if (dh == NULL) {
2258 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
2259 "params into DH params");
2260 break;
2261 }
2262 break;
2263 }
2264#endif /* !OPENSSL_NO_DSA */
2265 if (dh == NULL) {
2266 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
2267 "'%s'", dh_file);
2268 return -1;
2269 }
2270
2271 if (SSL_set_tmp_dh(conn->ssl, dh) != 1) {
2272 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
2273 "%s", dh_file,
2274 ERR_error_string(ERR_get_error(), NULL));
2275 DH_free(dh);
2276 return -1;
2277 }
2278 DH_free(dh);
2279 return 0;
2280#endif /* OPENSSL_NO_DH */
2281}
2282
2283
2284static int tls_global_dh(SSL_CTX *ssl_ctx, const char *dh_file)
2285{
2286#ifdef OPENSSL_NO_DH
2287 if (dh_file == NULL)
2288 return 0;
2289 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
2290 "dh_file specified");
2291 return -1;
2292#else /* OPENSSL_NO_DH */
2293 DH *dh;
2294 BIO *bio;
2295
2296 /* TODO: add support for dh_blob */
2297 if (dh_file == NULL)
2298 return 0;
2299 if (ssl_ctx == NULL)
2300 return -1;
2301
2302 bio = BIO_new_file(dh_file, "r");
2303 if (bio == NULL) {
2304 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
2305 dh_file, ERR_error_string(ERR_get_error(), NULL));
2306 return -1;
2307 }
2308 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
2309 BIO_free(bio);
2310#ifndef OPENSSL_NO_DSA
2311 while (dh == NULL) {
2312 DSA *dsa;
2313 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
2314 " trying to parse as DSA params", dh_file,
2315 ERR_error_string(ERR_get_error(), NULL));
2316 bio = BIO_new_file(dh_file, "r");
2317 if (bio == NULL)
2318 break;
2319 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
2320 BIO_free(bio);
2321 if (!dsa) {
2322 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
2323 "'%s': %s", dh_file,
2324 ERR_error_string(ERR_get_error(), NULL));
2325 break;
2326 }
2327
2328 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
2329 dh = DSA_dup_DH(dsa);
2330 DSA_free(dsa);
2331 if (dh == NULL) {
2332 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
2333 "params into DH params");
2334 break;
2335 }
2336 break;
2337 }
2338#endif /* !OPENSSL_NO_DSA */
2339 if (dh == NULL) {
2340 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
2341 "'%s'", dh_file);
2342 return -1;
2343 }
2344
2345 if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) {
2346 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
2347 "%s", dh_file,
2348 ERR_error_string(ERR_get_error(), NULL));
2349 DH_free(dh);
2350 return -1;
2351 }
2352 DH_free(dh);
2353 return 0;
2354#endif /* OPENSSL_NO_DH */
2355}
2356
2357
2358int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
2359 struct tls_keys *keys)
2360{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002361#ifdef CONFIG_FIPS
2362 wpa_printf(MSG_ERROR, "OpenSSL: TLS keys cannot be exported in FIPS "
2363 "mode");
2364 return -1;
2365#else /* CONFIG_FIPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002366 SSL *ssl;
2367
2368 if (conn == NULL || keys == NULL)
2369 return -1;
2370 ssl = conn->ssl;
2371 if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL)
2372 return -1;
2373
2374 os_memset(keys, 0, sizeof(*keys));
2375 keys->master_key = ssl->session->master_key;
2376 keys->master_key_len = ssl->session->master_key_length;
2377 keys->client_random = ssl->s3->client_random;
2378 keys->client_random_len = SSL3_RANDOM_SIZE;
2379 keys->server_random = ssl->s3->server_random;
2380 keys->server_random_len = SSL3_RANDOM_SIZE;
2381
2382 return 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002383#endif /* CONFIG_FIPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002384}
2385
2386
2387int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
2388 const char *label, int server_random_first,
2389 u8 *out, size_t out_len)
2390{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002391#if OPENSSL_VERSION_NUMBER >= 0x10001000L
2392 SSL *ssl;
2393 if (conn == NULL)
2394 return -1;
2395 if (server_random_first)
2396 return -1;
2397 ssl = conn->ssl;
2398 if (SSL_export_keying_material(ssl, out, out_len, label,
2399 os_strlen(label), NULL, 0, 0) == 1) {
2400 wpa_printf(MSG_DEBUG, "OpenSSL: Using internal PRF");
2401 return 0;
2402 }
2403#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002404 return -1;
2405}
2406
2407
2408static struct wpabuf *
2409openssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data,
2410 int server)
2411{
2412 int res;
2413 struct wpabuf *out_data;
2414
2415 /*
2416 * Give TLS handshake data from the server (if available) to OpenSSL
2417 * for processing.
2418 */
2419 if (in_data &&
2420 BIO_write(conn->ssl_in, wpabuf_head(in_data), wpabuf_len(in_data))
2421 < 0) {
2422 tls_show_errors(MSG_INFO, __func__,
2423 "Handshake failed - BIO_write");
2424 return NULL;
2425 }
2426
2427 /* Initiate TLS handshake or continue the existing handshake */
2428 if (server)
2429 res = SSL_accept(conn->ssl);
2430 else
2431 res = SSL_connect(conn->ssl);
2432 if (res != 1) {
2433 int err = SSL_get_error(conn->ssl, res);
2434 if (err == SSL_ERROR_WANT_READ)
2435 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want "
2436 "more data");
2437 else if (err == SSL_ERROR_WANT_WRITE)
2438 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to "
2439 "write");
2440 else {
2441 tls_show_errors(MSG_INFO, __func__, "SSL_connect");
2442 conn->failed++;
2443 }
2444 }
2445
2446 /* Get the TLS handshake data to be sent to the server */
2447 res = BIO_ctrl_pending(conn->ssl_out);
2448 wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
2449 out_data = wpabuf_alloc(res);
2450 if (out_data == NULL) {
2451 wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
2452 "handshake output (%d bytes)", res);
2453 if (BIO_reset(conn->ssl_out) < 0) {
2454 tls_show_errors(MSG_INFO, __func__,
2455 "BIO_reset failed");
2456 }
2457 return NULL;
2458 }
2459 res = res == 0 ? 0 : BIO_read(conn->ssl_out, wpabuf_mhead(out_data),
2460 res);
2461 if (res < 0) {
2462 tls_show_errors(MSG_INFO, __func__,
2463 "Handshake failed - BIO_read");
2464 if (BIO_reset(conn->ssl_out) < 0) {
2465 tls_show_errors(MSG_INFO, __func__,
2466 "BIO_reset failed");
2467 }
2468 wpabuf_free(out_data);
2469 return NULL;
2470 }
2471 wpabuf_put(out_data, res);
2472
2473 return out_data;
2474}
2475
2476
2477static struct wpabuf *
2478openssl_get_appl_data(struct tls_connection *conn, size_t max_len)
2479{
2480 struct wpabuf *appl_data;
2481 int res;
2482
2483 appl_data = wpabuf_alloc(max_len + 100);
2484 if (appl_data == NULL)
2485 return NULL;
2486
2487 res = SSL_read(conn->ssl, wpabuf_mhead(appl_data),
2488 wpabuf_size(appl_data));
2489 if (res < 0) {
2490 int err = SSL_get_error(conn->ssl, res);
2491 if (err == SSL_ERROR_WANT_READ ||
2492 err == SSL_ERROR_WANT_WRITE) {
2493 wpa_printf(MSG_DEBUG, "SSL: No Application Data "
2494 "included");
2495 } else {
2496 tls_show_errors(MSG_INFO, __func__,
2497 "Failed to read possible "
2498 "Application Data");
2499 }
2500 wpabuf_free(appl_data);
2501 return NULL;
2502 }
2503
2504 wpabuf_put(appl_data, res);
2505 wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application Data in Finished "
2506 "message", appl_data);
2507
2508 return appl_data;
2509}
2510
2511
2512static struct wpabuf *
2513openssl_connection_handshake(struct tls_connection *conn,
2514 const struct wpabuf *in_data,
2515 struct wpabuf **appl_data, int server)
2516{
2517 struct wpabuf *out_data;
2518
2519 if (appl_data)
2520 *appl_data = NULL;
2521
2522 out_data = openssl_handshake(conn, in_data, server);
2523 if (out_data == NULL)
2524 return NULL;
2525
2526 if (SSL_is_init_finished(conn->ssl) && appl_data && in_data)
2527 *appl_data = openssl_get_appl_data(conn, wpabuf_len(in_data));
2528
2529 return out_data;
2530}
2531
2532
2533struct wpabuf *
2534tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
2535 const struct wpabuf *in_data,
2536 struct wpabuf **appl_data)
2537{
2538 return openssl_connection_handshake(conn, in_data, appl_data, 0);
2539}
2540
2541
2542struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
2543 struct tls_connection *conn,
2544 const struct wpabuf *in_data,
2545 struct wpabuf **appl_data)
2546{
2547 return openssl_connection_handshake(conn, in_data, appl_data, 1);
2548}
2549
2550
2551struct wpabuf * tls_connection_encrypt(void *tls_ctx,
2552 struct tls_connection *conn,
2553 const struct wpabuf *in_data)
2554{
2555 int res;
2556 struct wpabuf *buf;
2557
2558 if (conn == NULL)
2559 return NULL;
2560
2561 /* Give plaintext data for OpenSSL to encrypt into the TLS tunnel. */
2562 if ((res = BIO_reset(conn->ssl_in)) < 0 ||
2563 (res = BIO_reset(conn->ssl_out)) < 0) {
2564 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
2565 return NULL;
2566 }
2567 res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data));
2568 if (res < 0) {
2569 tls_show_errors(MSG_INFO, __func__,
2570 "Encryption failed - SSL_write");
2571 return NULL;
2572 }
2573
2574 /* Read encrypted data to be sent to the server */
2575 buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
2576 if (buf == NULL)
2577 return NULL;
2578 res = BIO_read(conn->ssl_out, wpabuf_mhead(buf), wpabuf_size(buf));
2579 if (res < 0) {
2580 tls_show_errors(MSG_INFO, __func__,
2581 "Encryption failed - BIO_read");
2582 wpabuf_free(buf);
2583 return NULL;
2584 }
2585 wpabuf_put(buf, res);
2586
2587 return buf;
2588}
2589
2590
2591struct wpabuf * tls_connection_decrypt(void *tls_ctx,
2592 struct tls_connection *conn,
2593 const struct wpabuf *in_data)
2594{
2595 int res;
2596 struct wpabuf *buf;
2597
2598 /* Give encrypted data from TLS tunnel for OpenSSL to decrypt. */
2599 res = BIO_write(conn->ssl_in, wpabuf_head(in_data),
2600 wpabuf_len(in_data));
2601 if (res < 0) {
2602 tls_show_errors(MSG_INFO, __func__,
2603 "Decryption failed - BIO_write");
2604 return NULL;
2605 }
2606 if (BIO_reset(conn->ssl_out) < 0) {
2607 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
2608 return NULL;
2609 }
2610
2611 /* Read decrypted data for further processing */
2612 /*
2613 * Even though we try to disable TLS compression, it is possible that
2614 * this cannot be done with all TLS libraries. Add extra buffer space
2615 * to handle the possibility of the decrypted data being longer than
2616 * input data.
2617 */
2618 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
2619 if (buf == NULL)
2620 return NULL;
2621 res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
2622 if (res < 0) {
2623 tls_show_errors(MSG_INFO, __func__,
2624 "Decryption failed - SSL_read");
2625 wpabuf_free(buf);
2626 return NULL;
2627 }
2628 wpabuf_put(buf, res);
2629
2630 return buf;
2631}
2632
2633
2634int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
2635{
2636 return conn ? conn->ssl->hit : 0;
2637}
2638
2639
2640int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
2641 u8 *ciphers)
2642{
2643 char buf[100], *pos, *end;
2644 u8 *c;
2645 int ret;
2646
2647 if (conn == NULL || conn->ssl == NULL || ciphers == NULL)
2648 return -1;
2649
2650 buf[0] = '\0';
2651 pos = buf;
2652 end = pos + sizeof(buf);
2653
2654 c = ciphers;
2655 while (*c != TLS_CIPHER_NONE) {
2656 const char *suite;
2657
2658 switch (*c) {
2659 case TLS_CIPHER_RC4_SHA:
2660 suite = "RC4-SHA";
2661 break;
2662 case TLS_CIPHER_AES128_SHA:
2663 suite = "AES128-SHA";
2664 break;
2665 case TLS_CIPHER_RSA_DHE_AES128_SHA:
2666 suite = "DHE-RSA-AES128-SHA";
2667 break;
2668 case TLS_CIPHER_ANON_DH_AES128_SHA:
2669 suite = "ADH-AES128-SHA";
2670 break;
2671 default:
2672 wpa_printf(MSG_DEBUG, "TLS: Unsupported "
2673 "cipher selection: %d", *c);
2674 return -1;
2675 }
2676 ret = os_snprintf(pos, end - pos, ":%s", suite);
2677 if (ret < 0 || ret >= end - pos)
2678 break;
2679 pos += ret;
2680
2681 c++;
2682 }
2683
2684 wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1);
2685
2686 if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
2687 tls_show_errors(MSG_INFO, __func__,
2688 "Cipher suite configuration failed");
2689 return -1;
2690 }
2691
2692 return 0;
2693}
2694
2695
2696int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
2697 char *buf, size_t buflen)
2698{
2699 const char *name;
2700 if (conn == NULL || conn->ssl == NULL)
2701 return -1;
2702
2703 name = SSL_get_cipher(conn->ssl);
2704 if (name == NULL)
2705 return -1;
2706
2707 os_strlcpy(buf, name, buflen);
2708 return 0;
2709}
2710
2711
2712int tls_connection_enable_workaround(void *ssl_ctx,
2713 struct tls_connection *conn)
2714{
2715 SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
2716
2717 return 0;
2718}
2719
2720
2721#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2722/* ClientHello TLS extensions require a patch to openssl, so this function is
2723 * commented out unless explicitly needed for EAP-FAST in order to be able to
2724 * build this file with unmodified openssl. */
2725int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
2726 int ext_type, const u8 *data,
2727 size_t data_len)
2728{
2729 if (conn == NULL || conn->ssl == NULL || ext_type != 35)
2730 return -1;
2731
2732#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
2733 if (SSL_set_session_ticket_ext(conn->ssl, (void *) data,
2734 data_len) != 1)
2735 return -1;
2736#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
2737 if (SSL_set_hello_extension(conn->ssl, ext_type, (void *) data,
2738 data_len) != 1)
2739 return -1;
2740#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
2741
2742 return 0;
2743}
2744#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2745
2746
2747int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
2748{
2749 if (conn == NULL)
2750 return -1;
2751 return conn->failed;
2752}
2753
2754
2755int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
2756{
2757 if (conn == NULL)
2758 return -1;
2759 return conn->read_alerts;
2760}
2761
2762
2763int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
2764{
2765 if (conn == NULL)
2766 return -1;
2767 return conn->write_alerts;
2768}
2769
2770
2771int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
2772 const struct tls_connection_params *params)
2773{
2774 int ret;
2775 unsigned long err;
2776
2777 if (conn == NULL)
2778 return -1;
2779
2780 while ((err = ERR_get_error())) {
2781 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
2782 __func__, ERR_error_string(err, NULL));
2783 }
2784
2785 if (params->engine) {
2786 wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine");
2787 ret = tls_engine_init(conn, params->engine_id, params->pin,
2788 params->key_id, params->cert_id,
2789 params->ca_cert_id);
2790 if (ret)
2791 return ret;
2792 }
2793 if (tls_connection_set_subject_match(conn,
2794 params->subject_match,
2795 params->altsubject_match))
2796 return -1;
2797
2798 if (params->engine && params->ca_cert_id) {
2799 if (tls_connection_engine_ca_cert(tls_ctx, conn,
2800 params->ca_cert_id))
2801 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
2802 } else if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert,
2803 params->ca_cert_blob,
2804 params->ca_cert_blob_len,
2805 params->ca_path))
2806 return -1;
2807
2808 if (params->engine && params->cert_id) {
2809 if (tls_connection_engine_client_cert(conn, params->cert_id))
2810 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
2811 } else if (tls_connection_client_cert(conn, params->client_cert,
2812 params->client_cert_blob,
2813 params->client_cert_blob_len))
2814 return -1;
2815
2816 if (params->engine && params->key_id) {
2817 wpa_printf(MSG_DEBUG, "TLS: Using private key from engine");
2818 if (tls_connection_engine_private_key(conn))
2819 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
2820 } else if (tls_connection_private_key(tls_ctx, conn,
2821 params->private_key,
2822 params->private_key_passwd,
2823 params->private_key_blob,
2824 params->private_key_blob_len)) {
2825 wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'",
2826 params->private_key);
2827 return -1;
2828 }
2829
2830 if (tls_connection_dh(conn, params->dh_file)) {
2831 wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
2832 params->dh_file);
2833 return -1;
2834 }
2835
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002836#ifdef SSL_OP_NO_TICKET
2837 if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET)
2838 SSL_set_options(conn->ssl, SSL_OP_NO_TICKET);
2839 else
2840 SSL_clear_options(conn->ssl, SSL_OP_NO_TICKET);
2841#endif /* SSL_OP_NO_TICKET */
2842
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07002843 conn->flags = params->flags;
2844
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002845 tls_get_errors(tls_ctx);
2846
2847 return 0;
2848}
2849
2850
2851int tls_global_set_params(void *tls_ctx,
2852 const struct tls_connection_params *params)
2853{
2854 SSL_CTX *ssl_ctx = tls_ctx;
2855 unsigned long err;
2856
2857 while ((err = ERR_get_error())) {
2858 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
2859 __func__, ERR_error_string(err, NULL));
2860 }
2861
2862 if (tls_global_ca_cert(ssl_ctx, params->ca_cert))
2863 return -1;
2864
2865 if (tls_global_client_cert(ssl_ctx, params->client_cert))
2866 return -1;
2867
2868 if (tls_global_private_key(ssl_ctx, params->private_key,
2869 params->private_key_passwd))
2870 return -1;
2871
2872 if (tls_global_dh(ssl_ctx, params->dh_file)) {
2873 wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
2874 params->dh_file);
2875 return -1;
2876 }
2877
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002878#ifdef SSL_OP_NO_TICKET
2879 if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET)
2880 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET);
2881 else
2882 SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TICKET);
2883#endif /* SSL_OP_NO_TICKET */
2884
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002885 return 0;
2886}
2887
2888
2889int tls_connection_get_keyblock_size(void *tls_ctx,
2890 struct tls_connection *conn)
2891{
2892 const EVP_CIPHER *c;
2893 const EVP_MD *h;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002894 int md_size;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002895
2896 if (conn == NULL || conn->ssl == NULL ||
2897 conn->ssl->enc_read_ctx == NULL ||
2898 conn->ssl->enc_read_ctx->cipher == NULL ||
2899 conn->ssl->read_hash == NULL)
2900 return -1;
2901
2902 c = conn->ssl->enc_read_ctx->cipher;
2903#if OPENSSL_VERSION_NUMBER >= 0x00909000L
2904 h = EVP_MD_CTX_md(conn->ssl->read_hash);
2905#else
2906 h = conn->ssl->read_hash;
2907#endif
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002908 if (h)
2909 md_size = EVP_MD_size(h);
2910#if OPENSSL_VERSION_NUMBER >= 0x10000000L
2911 else if (conn->ssl->s3)
2912 md_size = conn->ssl->s3->tmp.new_mac_secret_size;
2913#endif
2914 else
2915 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002916
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002917 wpa_printf(MSG_DEBUG, "OpenSSL: keyblock size: key_len=%d MD_size=%d "
2918 "IV_len=%d", EVP_CIPHER_key_length(c), md_size,
2919 EVP_CIPHER_iv_length(c));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002920 return 2 * (EVP_CIPHER_key_length(c) +
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002921 md_size +
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002922 EVP_CIPHER_iv_length(c));
2923}
2924
2925
2926unsigned int tls_capabilities(void *tls_ctx)
2927{
2928 return 0;
2929}
2930
2931
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002932#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2933/* Pre-shared secred requires a patch to openssl, so this function is
2934 * commented out unless explicitly needed for EAP-FAST in order to be able to
2935 * build this file with unmodified openssl. */
2936
2937static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
2938 STACK_OF(SSL_CIPHER) *peer_ciphers,
2939 SSL_CIPHER **cipher, void *arg)
2940{
2941 struct tls_connection *conn = arg;
2942 int ret;
2943
2944 if (conn == NULL || conn->session_ticket_cb == NULL)
2945 return 0;
2946
2947 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
2948 conn->session_ticket,
2949 conn->session_ticket_len,
2950 s->s3->client_random,
2951 s->s3->server_random, secret);
2952 os_free(conn->session_ticket);
2953 conn->session_ticket = NULL;
2954
2955 if (ret <= 0)
2956 return 0;
2957
2958 *secret_len = SSL_MAX_MASTER_KEY_LENGTH;
2959 return 1;
2960}
2961
2962
2963#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
2964static int tls_session_ticket_ext_cb(SSL *s, const unsigned char *data,
2965 int len, void *arg)
2966{
2967 struct tls_connection *conn = arg;
2968
2969 if (conn == NULL || conn->session_ticket_cb == NULL)
2970 return 0;
2971
2972 wpa_printf(MSG_DEBUG, "OpenSSL: %s: length=%d", __func__, len);
2973
2974 os_free(conn->session_ticket);
2975 conn->session_ticket = NULL;
2976
2977 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
2978 "extension", data, len);
2979
2980 conn->session_ticket = os_malloc(len);
2981 if (conn->session_ticket == NULL)
2982 return 0;
2983
2984 os_memcpy(conn->session_ticket, data, len);
2985 conn->session_ticket_len = len;
2986
2987 return 1;
2988}
2989#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
2990#ifdef SSL_OP_NO_TICKET
2991static void tls_hello_ext_cb(SSL *s, int client_server, int type,
2992 unsigned char *data, int len, void *arg)
2993{
2994 struct tls_connection *conn = arg;
2995
2996 if (conn == NULL || conn->session_ticket_cb == NULL)
2997 return;
2998
2999 wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__,
3000 type, len);
3001
3002 if (type == TLSEXT_TYPE_session_ticket && !client_server) {
3003 os_free(conn->session_ticket);
3004 conn->session_ticket = NULL;
3005
3006 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
3007 "extension", data, len);
3008 conn->session_ticket = os_malloc(len);
3009 if (conn->session_ticket == NULL)
3010 return;
3011
3012 os_memcpy(conn->session_ticket, data, len);
3013 conn->session_ticket_len = len;
3014 }
3015}
3016#else /* SSL_OP_NO_TICKET */
3017static int tls_hello_ext_cb(SSL *s, TLS_EXTENSION *ext, void *arg)
3018{
3019 struct tls_connection *conn = arg;
3020
3021 if (conn == NULL || conn->session_ticket_cb == NULL)
3022 return 0;
3023
3024 wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__,
3025 ext->type, ext->length);
3026
3027 os_free(conn->session_ticket);
3028 conn->session_ticket = NULL;
3029
3030 if (ext->type == 35) {
3031 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
3032 "extension", ext->data, ext->length);
3033 conn->session_ticket = os_malloc(ext->length);
3034 if (conn->session_ticket == NULL)
3035 return SSL_AD_INTERNAL_ERROR;
3036
3037 os_memcpy(conn->session_ticket, ext->data, ext->length);
3038 conn->session_ticket_len = ext->length;
3039 }
3040
3041 return 0;
3042}
3043#endif /* SSL_OP_NO_TICKET */
3044#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
3045#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
3046
3047
3048int tls_connection_set_session_ticket_cb(void *tls_ctx,
3049 struct tls_connection *conn,
3050 tls_session_ticket_cb cb,
3051 void *ctx)
3052{
3053#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
3054 conn->session_ticket_cb = cb;
3055 conn->session_ticket_cb_ctx = ctx;
3056
3057 if (cb) {
3058 if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
3059 conn) != 1)
3060 return -1;
3061#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
3062 SSL_set_session_ticket_ext_cb(conn->ssl,
3063 tls_session_ticket_ext_cb, conn);
3064#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
3065#ifdef SSL_OP_NO_TICKET
3066 SSL_set_tlsext_debug_callback(conn->ssl, tls_hello_ext_cb);
3067 SSL_set_tlsext_debug_arg(conn->ssl, conn);
3068#else /* SSL_OP_NO_TICKET */
3069 if (SSL_set_hello_extension_cb(conn->ssl, tls_hello_ext_cb,
3070 conn) != 1)
3071 return -1;
3072#endif /* SSL_OP_NO_TICKET */
3073#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
3074 } else {
3075 if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
3076 return -1;
3077#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
3078 SSL_set_session_ticket_ext_cb(conn->ssl, NULL, NULL);
3079#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
3080#ifdef SSL_OP_NO_TICKET
3081 SSL_set_tlsext_debug_callback(conn->ssl, NULL);
3082 SSL_set_tlsext_debug_arg(conn->ssl, conn);
3083#else /* SSL_OP_NO_TICKET */
3084 if (SSL_set_hello_extension_cb(conn->ssl, NULL, NULL) != 1)
3085 return -1;
3086#endif /* SSL_OP_NO_TICKET */
3087#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
3088 }
3089
3090 return 0;
3091#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
3092 return -1;
3093#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
3094}