blob: e1534224c51959c0ea70c38ad888ae3917045ec5 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * SSL/TLS interface functions for OpenSSL
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003 * Copyright (c) 2004-2013, 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 Shmidt9ead16e2014-10-07 13:15:23 -070041#if OPENSSL_VERSION_NUMBER < 0x10000000L
42/* ERR_remove_thread_state replaces ERR_remove_state and the latter is
43 * deprecated. However, OpenSSL 0.9.8 doesn't include
44 * ERR_remove_thread_state. */
45#define ERR_remove_thread_state(tid) ERR_remove_state(0)
46#endif
47
48#if OPENSSL_VERSION_NUMBER >= 0x10000000L
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070049/*
50 * Session ticket override patch was merged into OpenSSL 0.9.9 tree on
51 * 2008-11-15. This version uses a bit different API compared to the old patch.
52 */
53#define CONFIG_OPENSSL_TICKET_OVERRIDE
54#endif
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -070055
56#if defined(OPENSSL_IS_BORINGSSL)
57/* stack_index_t is the return type of OpenSSL's sk_XXX_num() functions. */
58typedef size_t stack_index_t;
59#else
60typedef int stack_index_t;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070061#endif
62
Dmitry Shmidt34af3062013-07-11 10:46:32 -070063#ifdef SSL_set_tlsext_status_type
64#ifndef OPENSSL_NO_TLSEXT
65#define HAVE_OCSP
66#include <openssl/ocsp.h>
67#endif /* OPENSSL_NO_TLSEXT */
68#endif /* SSL_set_tlsext_status_type */
69
Dmitry Shmidtff079172013-11-08 14:10:30 -080070#ifdef ANDROID
71#include <openssl/pem.h>
72#include <keystore/keystore_get.h>
73
74static BIO * BIO_from_keystore(const char *key)
75{
76 BIO *bio = NULL;
77 uint8_t *value = NULL;
78 int length = keystore_get(key, strlen(key), &value);
79 if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL)
80 BIO_write(bio, value, length);
81 free(value);
82 return bio;
83}
84#endif /* ANDROID */
85
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070086static int tls_openssl_ref_count = 0;
87
Dmitry Shmidtea69e842013-05-13 14:52:28 -070088struct tls_context {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070089 void (*event_cb)(void *ctx, enum tls_event ev,
90 union tls_event_data *data);
91 void *cb_ctx;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080092 int cert_in_cb;
Dmitry Shmidt34af3062013-07-11 10:46:32 -070093 char *ocsp_stapling_response;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070094};
95
Dmitry Shmidtea69e842013-05-13 14:52:28 -070096static struct tls_context *tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070097
98
99struct tls_connection {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700100 struct tls_context *context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700101 SSL *ssl;
102 BIO *ssl_in, *ssl_out;
103#ifndef OPENSSL_NO_ENGINE
104 ENGINE *engine; /* functional reference to the engine */
105 EVP_PKEY *private_key; /* the private key if using engine */
106#endif /* OPENSSL_NO_ENGINE */
Dmitry Shmidt051af732013-10-22 13:52:46 -0700107 char *subject_match, *altsubject_match, *suffix_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700108 int read_alerts, write_alerts, failed;
109
110 tls_session_ticket_cb session_ticket_cb;
111 void *session_ticket_cb_ctx;
112
113 /* SessionTicket received from OpenSSL hello_extension_cb (server) */
114 u8 *session_ticket;
115 size_t session_ticket_len;
116
117 unsigned int ca_cert_verify:1;
118 unsigned int cert_probe:1;
119 unsigned int server_cert_only:1;
Jouni Malinen26af48b2014-04-09 13:02:53 +0300120 unsigned int invalid_hb_used:1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700121
122 u8 srv_cert_hash[32];
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700123
124 unsigned int flags;
Dmitry Shmidt34af3062013-07-11 10:46:32 -0700125
126 X509 *peer_cert;
127 X509 *peer_issuer;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800128 X509 *peer_issuer_issuer;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700129};
130
131
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700132static struct tls_context * tls_context_new(const struct tls_config *conf)
133{
134 struct tls_context *context = os_zalloc(sizeof(*context));
135 if (context == NULL)
136 return NULL;
137 if (conf) {
138 context->event_cb = conf->event_cb;
139 context->cb_ctx = conf->cb_ctx;
140 context->cert_in_cb = conf->cert_in_cb;
141 }
142 return context;
143}
144
145
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700146#ifdef CONFIG_NO_STDOUT_DEBUG
147
148static void _tls_show_errors(void)
149{
150 unsigned long err;
151
152 while ((err = ERR_get_error())) {
153 /* Just ignore the errors, since stdout is disabled */
154 }
155}
156#define tls_show_errors(l, f, t) _tls_show_errors()
157
158#else /* CONFIG_NO_STDOUT_DEBUG */
159
160static void tls_show_errors(int level, const char *func, const char *txt)
161{
162 unsigned long err;
163
164 wpa_printf(level, "OpenSSL: %s - %s %s",
165 func, txt, ERR_error_string(ERR_get_error(), NULL));
166
167 while ((err = ERR_get_error())) {
168 wpa_printf(MSG_INFO, "OpenSSL: pending error: %s",
169 ERR_error_string(err, NULL));
170 }
171}
172
173#endif /* CONFIG_NO_STDOUT_DEBUG */
174
175
176#ifdef CONFIG_NATIVE_WINDOWS
177
178/* Windows CryptoAPI and access to certificate stores */
179#include <wincrypt.h>
180
181#ifdef __MINGW32_VERSION
182/*
183 * MinGW does not yet include all the needed definitions for CryptoAPI, so
184 * define here whatever extra is needed.
185 */
186#define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16)
187#define CERT_STORE_READONLY_FLAG 0x00008000
188#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
189
190#endif /* __MINGW32_VERSION */
191
192
193struct cryptoapi_rsa_data {
194 const CERT_CONTEXT *cert;
195 HCRYPTPROV crypt_prov;
196 DWORD key_spec;
197 BOOL free_crypt_prov;
198};
199
200
201static void cryptoapi_error(const char *msg)
202{
203 wpa_printf(MSG_INFO, "CryptoAPI: %s; err=%u",
204 msg, (unsigned int) GetLastError());
205}
206
207
208static int cryptoapi_rsa_pub_enc(int flen, const unsigned char *from,
209 unsigned char *to, RSA *rsa, int padding)
210{
211 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
212 return 0;
213}
214
215
216static int cryptoapi_rsa_pub_dec(int flen, const unsigned char *from,
217 unsigned char *to, RSA *rsa, int padding)
218{
219 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
220 return 0;
221}
222
223
224static int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from,
225 unsigned char *to, RSA *rsa, int padding)
226{
227 struct cryptoapi_rsa_data *priv =
228 (struct cryptoapi_rsa_data *) rsa->meth->app_data;
229 HCRYPTHASH hash;
230 DWORD hash_size, len, i;
231 unsigned char *buf = NULL;
232 int ret = 0;
233
234 if (priv == NULL) {
235 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
236 ERR_R_PASSED_NULL_PARAMETER);
237 return 0;
238 }
239
240 if (padding != RSA_PKCS1_PADDING) {
241 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
242 RSA_R_UNKNOWN_PADDING_TYPE);
243 return 0;
244 }
245
246 if (flen != 16 /* MD5 */ + 20 /* SHA-1 */) {
247 wpa_printf(MSG_INFO, "%s - only MD5-SHA1 hash supported",
248 __func__);
249 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
250 RSA_R_INVALID_MESSAGE_LENGTH);
251 return 0;
252 }
253
254 if (!CryptCreateHash(priv->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash))
255 {
256 cryptoapi_error("CryptCreateHash failed");
257 return 0;
258 }
259
260 len = sizeof(hash_size);
261 if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len,
262 0)) {
263 cryptoapi_error("CryptGetHashParam failed");
264 goto err;
265 }
266
267 if ((int) hash_size != flen) {
268 wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)",
269 (unsigned) hash_size, flen);
270 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
271 RSA_R_INVALID_MESSAGE_LENGTH);
272 goto err;
273 }
274 if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) {
275 cryptoapi_error("CryptSetHashParam failed");
276 goto err;
277 }
278
279 len = RSA_size(rsa);
280 buf = os_malloc(len);
281 if (buf == NULL) {
282 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
283 goto err;
284 }
285
286 if (!CryptSignHash(hash, priv->key_spec, NULL, 0, buf, &len)) {
287 cryptoapi_error("CryptSignHash failed");
288 goto err;
289 }
290
291 for (i = 0; i < len; i++)
292 to[i] = buf[len - i - 1];
293 ret = len;
294
295err:
296 os_free(buf);
297 CryptDestroyHash(hash);
298
299 return ret;
300}
301
302
303static int cryptoapi_rsa_priv_dec(int flen, const unsigned char *from,
304 unsigned char *to, RSA *rsa, int padding)
305{
306 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
307 return 0;
308}
309
310
311static void cryptoapi_free_data(struct cryptoapi_rsa_data *priv)
312{
313 if (priv == NULL)
314 return;
315 if (priv->crypt_prov && priv->free_crypt_prov)
316 CryptReleaseContext(priv->crypt_prov, 0);
317 if (priv->cert)
318 CertFreeCertificateContext(priv->cert);
319 os_free(priv);
320}
321
322
323static int cryptoapi_finish(RSA *rsa)
324{
325 cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data);
326 os_free((void *) rsa->meth);
327 rsa->meth = NULL;
328 return 1;
329}
330
331
332static const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store)
333{
334 HCERTSTORE cs;
335 const CERT_CONTEXT *ret = NULL;
336
337 cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0,
338 store | CERT_STORE_OPEN_EXISTING_FLAG |
339 CERT_STORE_READONLY_FLAG, L"MY");
340 if (cs == NULL) {
341 cryptoapi_error("Failed to open 'My system store'");
342 return NULL;
343 }
344
345 if (strncmp(name, "cert://", 7) == 0) {
346 unsigned short wbuf[255];
347 MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255);
348 ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING |
349 PKCS_7_ASN_ENCODING,
350 0, CERT_FIND_SUBJECT_STR,
351 wbuf, NULL);
352 } else if (strncmp(name, "hash://", 7) == 0) {
353 CRYPT_HASH_BLOB blob;
354 int len;
355 const char *hash = name + 7;
356 unsigned char *buf;
357
358 len = os_strlen(hash) / 2;
359 buf = os_malloc(len);
360 if (buf && hexstr2bin(hash, buf, len) == 0) {
361 blob.cbData = len;
362 blob.pbData = buf;
363 ret = CertFindCertificateInStore(cs,
364 X509_ASN_ENCODING |
365 PKCS_7_ASN_ENCODING,
366 0, CERT_FIND_HASH,
367 &blob, NULL);
368 }
369 os_free(buf);
370 }
371
372 CertCloseStore(cs, 0);
373
374 return ret;
375}
376
377
378static int tls_cryptoapi_cert(SSL *ssl, const char *name)
379{
380 X509 *cert = NULL;
381 RSA *rsa = NULL, *pub_rsa;
382 struct cryptoapi_rsa_data *priv;
383 RSA_METHOD *rsa_meth;
384
385 if (name == NULL ||
386 (strncmp(name, "cert://", 7) != 0 &&
387 strncmp(name, "hash://", 7) != 0))
388 return -1;
389
390 priv = os_zalloc(sizeof(*priv));
391 rsa_meth = os_zalloc(sizeof(*rsa_meth));
392 if (priv == NULL || rsa_meth == NULL) {
393 wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory "
394 "for CryptoAPI RSA method");
395 os_free(priv);
396 os_free(rsa_meth);
397 return -1;
398 }
399
400 priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER);
401 if (priv->cert == NULL) {
402 priv->cert = cryptoapi_find_cert(
403 name, CERT_SYSTEM_STORE_LOCAL_MACHINE);
404 }
405 if (priv->cert == NULL) {
406 wpa_printf(MSG_INFO, "CryptoAPI: Could not find certificate "
407 "'%s'", name);
408 goto err;
409 }
410
411 cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &priv->cert->pbCertEncoded,
412 priv->cert->cbCertEncoded);
413 if (cert == NULL) {
414 wpa_printf(MSG_INFO, "CryptoAPI: Could not process X509 DER "
415 "encoding");
416 goto err;
417 }
418
419 if (!CryptAcquireCertificatePrivateKey(priv->cert,
420 CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
421 NULL, &priv->crypt_prov,
422 &priv->key_spec,
423 &priv->free_crypt_prov)) {
424 cryptoapi_error("Failed to acquire a private key for the "
425 "certificate");
426 goto err;
427 }
428
429 rsa_meth->name = "Microsoft CryptoAPI RSA Method";
430 rsa_meth->rsa_pub_enc = cryptoapi_rsa_pub_enc;
431 rsa_meth->rsa_pub_dec = cryptoapi_rsa_pub_dec;
432 rsa_meth->rsa_priv_enc = cryptoapi_rsa_priv_enc;
433 rsa_meth->rsa_priv_dec = cryptoapi_rsa_priv_dec;
434 rsa_meth->finish = cryptoapi_finish;
435 rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
436 rsa_meth->app_data = (char *) priv;
437
438 rsa = RSA_new();
439 if (rsa == NULL) {
440 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,
441 ERR_R_MALLOC_FAILURE);
442 goto err;
443 }
444
445 if (!SSL_use_certificate(ssl, cert)) {
446 RSA_free(rsa);
447 rsa = NULL;
448 goto err;
449 }
450 pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
451 X509_free(cert);
452 cert = NULL;
453
454 rsa->n = BN_dup(pub_rsa->n);
455 rsa->e = BN_dup(pub_rsa->e);
456 if (!RSA_set_method(rsa, rsa_meth))
457 goto err;
458
459 if (!SSL_use_RSAPrivateKey(ssl, rsa))
460 goto err;
461 RSA_free(rsa);
462
463 return 0;
464
465err:
466 if (cert)
467 X509_free(cert);
468 if (rsa)
469 RSA_free(rsa);
470 else {
471 os_free(rsa_meth);
472 cryptoapi_free_data(priv);
473 }
474 return -1;
475}
476
477
478static int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name)
479{
480 HCERTSTORE cs;
481 PCCERT_CONTEXT ctx = NULL;
482 X509 *cert;
483 char buf[128];
484 const char *store;
485#ifdef UNICODE
486 WCHAR *wstore;
487#endif /* UNICODE */
488
489 if (name == NULL || strncmp(name, "cert_store://", 13) != 0)
490 return -1;
491
492 store = name + 13;
493#ifdef UNICODE
494 wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR));
495 if (wstore == NULL)
496 return -1;
497 wsprintf(wstore, L"%S", store);
498 cs = CertOpenSystemStore(0, wstore);
499 os_free(wstore);
500#else /* UNICODE */
501 cs = CertOpenSystemStore(0, store);
502#endif /* UNICODE */
503 if (cs == NULL) {
504 wpa_printf(MSG_DEBUG, "%s: failed to open system cert store "
505 "'%s': error=%d", __func__, store,
506 (int) GetLastError());
507 return -1;
508 }
509
510 while ((ctx = CertEnumCertificatesInStore(cs, ctx))) {
511 cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ctx->pbCertEncoded,
512 ctx->cbCertEncoded);
513 if (cert == NULL) {
514 wpa_printf(MSG_INFO, "CryptoAPI: Could not process "
515 "X509 DER encoding for CA cert");
516 continue;
517 }
518
519 X509_NAME_oneline(X509_get_subject_name(cert), buf,
520 sizeof(buf));
521 wpa_printf(MSG_DEBUG, "OpenSSL: Loaded CA certificate for "
522 "system certificate store: subject='%s'", buf);
523
524 if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) {
525 tls_show_errors(MSG_WARNING, __func__,
526 "Failed to add ca_cert to OpenSSL "
527 "certificate store");
528 }
529
530 X509_free(cert);
531 }
532
533 if (!CertCloseStore(cs, 0)) {
534 wpa_printf(MSG_DEBUG, "%s: failed to close system cert store "
535 "'%s': error=%d", __func__, name + 13,
536 (int) GetLastError());
537 }
538
539 return 0;
540}
541
542
543#else /* CONFIG_NATIVE_WINDOWS */
544
545static int tls_cryptoapi_cert(SSL *ssl, const char *name)
546{
547 return -1;
548}
549
550#endif /* CONFIG_NATIVE_WINDOWS */
551
552
553static void ssl_info_cb(const SSL *ssl, int where, int ret)
554{
555 const char *str;
556 int w;
557
558 wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret);
559 w = where & ~SSL_ST_MASK;
560 if (w & SSL_ST_CONNECT)
561 str = "SSL_connect";
562 else if (w & SSL_ST_ACCEPT)
563 str = "SSL_accept";
564 else
565 str = "undefined";
566
567 if (where & SSL_CB_LOOP) {
568 wpa_printf(MSG_DEBUG, "SSL: %s:%s",
569 str, SSL_state_string_long(ssl));
570 } else if (where & SSL_CB_ALERT) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700571 struct tls_connection *conn = SSL_get_app_data((SSL *) ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700572 wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s",
573 where & SSL_CB_READ ?
574 "read (remote end reported an error)" :
575 "write (local SSL3 detected an error)",
576 SSL_alert_type_string_long(ret),
577 SSL_alert_desc_string_long(ret));
578 if ((ret >> 8) == SSL3_AL_FATAL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700579 if (where & SSL_CB_READ)
580 conn->read_alerts++;
581 else
582 conn->write_alerts++;
583 }
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700584 if (conn->context->event_cb != NULL) {
Dmitry Shmidt04949592012-07-19 12:16:46 -0700585 union tls_event_data ev;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700586 struct tls_context *context = conn->context;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700587 os_memset(&ev, 0, sizeof(ev));
588 ev.alert.is_local = !(where & SSL_CB_READ);
589 ev.alert.type = SSL_alert_type_string_long(ret);
590 ev.alert.description = SSL_alert_desc_string_long(ret);
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700591 context->event_cb(context->cb_ctx, TLS_ALERT, &ev);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700592 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700593 } else if (where & SSL_CB_EXIT && ret <= 0) {
594 wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s",
595 str, ret == 0 ? "failed" : "error",
596 SSL_state_string_long(ssl));
597 }
598}
599
600
601#ifndef OPENSSL_NO_ENGINE
602/**
603 * tls_engine_load_dynamic_generic - load any openssl engine
604 * @pre: an array of commands and values that load an engine initialized
605 * in the engine specific function
606 * @post: an array of commands and values that initialize an already loaded
607 * engine (or %NULL if not required)
608 * @id: the engine id of the engine to load (only required if post is not %NULL
609 *
610 * This function is a generic function that loads any openssl engine.
611 *
612 * Returns: 0 on success, -1 on failure
613 */
614static int tls_engine_load_dynamic_generic(const char *pre[],
615 const char *post[], const char *id)
616{
617 ENGINE *engine;
618 const char *dynamic_id = "dynamic";
619
620 engine = ENGINE_by_id(id);
621 if (engine) {
622 ENGINE_free(engine);
623 wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already "
624 "available", id);
625 return 0;
626 }
627 ERR_clear_error();
628
629 engine = ENGINE_by_id(dynamic_id);
630 if (engine == NULL) {
631 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
632 dynamic_id,
633 ERR_error_string(ERR_get_error(), NULL));
634 return -1;
635 }
636
637 /* Perform the pre commands. This will load the engine. */
638 while (pre && pre[0]) {
639 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]);
640 if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) {
641 wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: "
642 "%s %s [%s]", pre[0], pre[1],
643 ERR_error_string(ERR_get_error(), NULL));
644 ENGINE_free(engine);
645 return -1;
646 }
647 pre += 2;
648 }
649
650 /*
651 * Free the reference to the "dynamic" engine. The loaded engine can
652 * now be looked up using ENGINE_by_id().
653 */
654 ENGINE_free(engine);
655
656 engine = ENGINE_by_id(id);
657 if (engine == NULL) {
658 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
659 id, ERR_error_string(ERR_get_error(), NULL));
660 return -1;
661 }
662
663 while (post && post[0]) {
664 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]);
665 if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) {
666 wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:"
667 " %s %s [%s]", post[0], post[1],
668 ERR_error_string(ERR_get_error(), NULL));
669 ENGINE_remove(engine);
670 ENGINE_free(engine);
671 return -1;
672 }
673 post += 2;
674 }
675 ENGINE_free(engine);
676
677 return 0;
678}
679
680
681/**
682 * tls_engine_load_dynamic_pkcs11 - load the pkcs11 engine provided by opensc
683 * @pkcs11_so_path: pksc11_so_path from the configuration
684 * @pcks11_module_path: pkcs11_module_path from the configuration
685 */
686static int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path,
687 const char *pkcs11_module_path)
688{
689 char *engine_id = "pkcs11";
690 const char *pre_cmd[] = {
691 "SO_PATH", NULL /* pkcs11_so_path */,
692 "ID", NULL /* engine_id */,
693 "LIST_ADD", "1",
694 /* "NO_VCHECK", "1", */
695 "LOAD", NULL,
696 NULL, NULL
697 };
698 const char *post_cmd[] = {
699 "MODULE_PATH", NULL /* pkcs11_module_path */,
700 NULL, NULL
701 };
702
703 if (!pkcs11_so_path || !pkcs11_module_path)
704 return 0;
705
706 pre_cmd[1] = pkcs11_so_path;
707 pre_cmd[3] = engine_id;
708 post_cmd[1] = pkcs11_module_path;
709
710 wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s",
711 pkcs11_so_path);
712
713 return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id);
714}
715
716
717/**
718 * tls_engine_load_dynamic_opensc - load the opensc engine provided by opensc
719 * @opensc_so_path: opensc_so_path from the configuration
720 */
721static int tls_engine_load_dynamic_opensc(const char *opensc_so_path)
722{
723 char *engine_id = "opensc";
724 const char *pre_cmd[] = {
725 "SO_PATH", NULL /* opensc_so_path */,
726 "ID", NULL /* engine_id */,
727 "LIST_ADD", "1",
728 "LOAD", NULL,
729 NULL, NULL
730 };
731
732 if (!opensc_so_path)
733 return 0;
734
735 pre_cmd[1] = opensc_so_path;
736 pre_cmd[3] = engine_id;
737
738 wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s",
739 opensc_so_path);
740
741 return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id);
742}
743#endif /* OPENSSL_NO_ENGINE */
744
745
746void * tls_init(const struct tls_config *conf)
747{
748 SSL_CTX *ssl;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700749 struct tls_context *context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700750
751 if (tls_openssl_ref_count == 0) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700752 tls_global = context = tls_context_new(conf);
753 if (context == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700754 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700755#ifdef CONFIG_FIPS
756#ifdef OPENSSL_FIPS
757 if (conf && conf->fips_mode) {
758 if (!FIPS_mode_set(1)) {
759 wpa_printf(MSG_ERROR, "Failed to enable FIPS "
760 "mode");
761 ERR_load_crypto_strings();
762 ERR_print_errors_fp(stderr);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700763 os_free(tls_global);
764 tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700765 return NULL;
766 } else
767 wpa_printf(MSG_INFO, "Running in FIPS mode");
768 }
769#else /* OPENSSL_FIPS */
770 if (conf && conf->fips_mode) {
771 wpa_printf(MSG_ERROR, "FIPS mode requested, but not "
772 "supported");
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700773 os_free(tls_global);
774 tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700775 return NULL;
776 }
777#endif /* OPENSSL_FIPS */
778#endif /* CONFIG_FIPS */
779 SSL_load_error_strings();
780 SSL_library_init();
781#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256)
782 EVP_add_digest(EVP_sha256());
783#endif /* OPENSSL_NO_SHA256 */
784 /* TODO: if /dev/urandom is available, PRNG is seeded
785 * automatically. If this is not the case, random data should
786 * be added here. */
787
788#ifdef PKCS12_FUNCS
789#ifndef OPENSSL_NO_RC2
790 /*
791 * 40-bit RC2 is commonly used in PKCS#12 files, so enable it.
792 * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8
793 * versions, but it looks like OpenSSL 1.0.0 does not do that
794 * anymore.
795 */
796 EVP_add_cipher(EVP_rc2_40_cbc());
797#endif /* OPENSSL_NO_RC2 */
798 PKCS12_PBE_add();
799#endif /* PKCS12_FUNCS */
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700800 } else {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700801#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
802 /* Newer OpenSSL can store app-data per-SSL */
803 context = tls_context_new(conf);
804 if (context == NULL)
805 return NULL;
Dmitry Shmidt7d5c8f22014-03-03 13:53:28 -0800806#else /* OPENSSL_SUPPORTS_CTX_APP_DATA */
807 context = tls_global;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700808#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700809 }
810 tls_openssl_ref_count++;
811
812 ssl = SSL_CTX_new(TLSv1_method());
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700813 if (ssl == NULL) {
814 tls_openssl_ref_count--;
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700815#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
816 if (context != tls_global)
817 os_free(context);
818#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700819 if (tls_openssl_ref_count == 0) {
820 os_free(tls_global);
821 tls_global = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700822 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700823 return NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700824 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700825
826 SSL_CTX_set_info_callback(ssl, ssl_info_cb);
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700827#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
828 SSL_CTX_set_app_data(ssl, context);
829#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700830
831#ifndef OPENSSL_NO_ENGINE
832 if (conf &&
833 (conf->opensc_engine_path || conf->pkcs11_engine_path ||
834 conf->pkcs11_module_path)) {
835 wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine");
836 ERR_load_ENGINE_strings();
837 ENGINE_load_dynamic();
838
839 if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) ||
840 tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path,
841 conf->pkcs11_module_path)) {
842 tls_deinit(ssl);
843 return NULL;
844 }
845 }
846#endif /* OPENSSL_NO_ENGINE */
847
848 return ssl;
849}
850
851
852void tls_deinit(void *ssl_ctx)
853{
854 SSL_CTX *ssl = ssl_ctx;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700855#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
856 struct tls_context *context = SSL_CTX_get_app_data(ssl);
857 if (context != tls_global)
858 os_free(context);
859#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700860 SSL_CTX_free(ssl);
861
862 tls_openssl_ref_count--;
863 if (tls_openssl_ref_count == 0) {
864#ifndef OPENSSL_NO_ENGINE
865 ENGINE_cleanup();
866#endif /* OPENSSL_NO_ENGINE */
867 CRYPTO_cleanup_all_ex_data();
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700868 ERR_remove_thread_state(NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700869 ERR_free_strings();
870 EVP_cleanup();
Dmitry Shmidt34af3062013-07-11 10:46:32 -0700871 os_free(tls_global->ocsp_stapling_response);
872 tls_global->ocsp_stapling_response = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700873 os_free(tls_global);
874 tls_global = NULL;
875 }
876}
877
878
879static int tls_engine_init(struct tls_connection *conn, const char *engine_id,
880 const char *pin, const char *key_id,
881 const char *cert_id, const char *ca_cert_id)
882{
883#ifndef OPENSSL_NO_ENGINE
884 int ret = -1;
885 if (engine_id == NULL) {
886 wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set");
887 return -1;
888 }
Kenny Rootdb3c5a42012-03-20 17:00:47 -0700889#ifndef ANDROID
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700890 if (pin == NULL) {
891 wpa_printf(MSG_ERROR, "ENGINE: Smartcard PIN not set");
892 return -1;
893 }
Kenny Rootdb3c5a42012-03-20 17:00:47 -0700894#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700895 if (key_id == NULL) {
896 wpa_printf(MSG_ERROR, "ENGINE: Key Id not set");
897 return -1;
898 }
899
900 ERR_clear_error();
Kenny Rootdb3c5a42012-03-20 17:00:47 -0700901#ifdef ANDROID
902 ENGINE_load_dynamic();
903#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700904 conn->engine = ENGINE_by_id(engine_id);
905 if (!conn->engine) {
906 wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]",
907 engine_id, ERR_error_string(ERR_get_error(), NULL));
908 goto err;
909 }
910 if (ENGINE_init(conn->engine) != 1) {
911 wpa_printf(MSG_ERROR, "ENGINE: engine init failed "
912 "(engine: %s) [%s]", engine_id,
913 ERR_error_string(ERR_get_error(), NULL));
914 goto err;
915 }
916 wpa_printf(MSG_DEBUG, "ENGINE: engine initialized");
917
Kenny Rootdb3c5a42012-03-20 17:00:47 -0700918#ifndef ANDROID
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700919 if (ENGINE_ctrl_cmd_string(conn->engine, "PIN", pin, 0) == 0) {
920 wpa_printf(MSG_ERROR, "ENGINE: cannot set pin [%s]",
921 ERR_error_string(ERR_get_error(), NULL));
922 goto err;
923 }
Kenny Rootdb3c5a42012-03-20 17:00:47 -0700924#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700925 /* load private key first in-case PIN is required for cert */
926 conn->private_key = ENGINE_load_private_key(conn->engine,
927 key_id, NULL, NULL);
928 if (!conn->private_key) {
929 wpa_printf(MSG_ERROR, "ENGINE: cannot load private key with id"
930 " '%s' [%s]", key_id,
931 ERR_error_string(ERR_get_error(), NULL));
932 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
933 goto err;
934 }
935
936 /* handle a certificate and/or CA certificate */
937 if (cert_id || ca_cert_id) {
938 const char *cmd_name = "LOAD_CERT_CTRL";
939
940 /* test if the engine supports a LOAD_CERT_CTRL */
941 if (!ENGINE_ctrl(conn->engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
942 0, (void *)cmd_name, NULL)) {
943 wpa_printf(MSG_ERROR, "ENGINE: engine does not support"
944 " loading certificates");
945 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
946 goto err;
947 }
948 }
949
950 return 0;
951
952err:
953 if (conn->engine) {
954 ENGINE_free(conn->engine);
955 conn->engine = NULL;
956 }
957
958 if (conn->private_key) {
959 EVP_PKEY_free(conn->private_key);
960 conn->private_key = NULL;
961 }
962
963 return ret;
964#else /* OPENSSL_NO_ENGINE */
965 return 0;
966#endif /* OPENSSL_NO_ENGINE */
967}
968
969
970static void tls_engine_deinit(struct tls_connection *conn)
971{
972#ifndef OPENSSL_NO_ENGINE
973 wpa_printf(MSG_DEBUG, "ENGINE: engine deinit");
974 if (conn->private_key) {
975 EVP_PKEY_free(conn->private_key);
976 conn->private_key = NULL;
977 }
978 if (conn->engine) {
979 ENGINE_finish(conn->engine);
980 conn->engine = NULL;
981 }
982#endif /* OPENSSL_NO_ENGINE */
983}
984
985
986int tls_get_errors(void *ssl_ctx)
987{
988 int count = 0;
989 unsigned long err;
990
991 while ((err = ERR_get_error())) {
992 wpa_printf(MSG_INFO, "TLS - SSL error: %s",
993 ERR_error_string(err, NULL));
994 count++;
995 }
996
997 return count;
998}
999
Jouni Malinen26af48b2014-04-09 13:02:53 +03001000
1001static void tls_msg_cb(int write_p, int version, int content_type,
1002 const void *buf, size_t len, SSL *ssl, void *arg)
1003{
1004 struct tls_connection *conn = arg;
1005 const u8 *pos = buf;
1006
1007 wpa_printf(MSG_DEBUG, "OpenSSL: %s ver=0x%x content_type=%d",
1008 write_p ? "TX" : "RX", version, content_type);
1009 wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Message", buf, len);
1010 if (content_type == 24 && len >= 3 && pos[0] == 1) {
1011 size_t payload_len = WPA_GET_BE16(pos + 1);
1012 if (payload_len + 3 > len) {
1013 wpa_printf(MSG_ERROR, "OpenSSL: Heartbeat attack detected");
1014 conn->invalid_hb_used = 1;
1015 }
1016 }
1017}
1018
1019
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001020struct tls_connection * tls_connection_init(void *ssl_ctx)
1021{
1022 SSL_CTX *ssl = ssl_ctx;
1023 struct tls_connection *conn;
1024 long options;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001025#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
Dmitry Shmidt7d5c8f22014-03-03 13:53:28 -08001026 struct tls_context *context = SSL_CTX_get_app_data(ssl);
1027#else /* OPENSSL_SUPPORTS_CTX_APP_DATA */
1028 struct tls_context *context = tls_global;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001029#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001030
1031 conn = os_zalloc(sizeof(*conn));
1032 if (conn == NULL)
1033 return NULL;
1034 conn->ssl = SSL_new(ssl);
1035 if (conn->ssl == NULL) {
1036 tls_show_errors(MSG_INFO, __func__,
1037 "Failed to initialize new SSL connection");
1038 os_free(conn);
1039 return NULL;
1040 }
1041
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001042 conn->context = context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001043 SSL_set_app_data(conn->ssl, conn);
Jouni Malinen26af48b2014-04-09 13:02:53 +03001044 SSL_set_msg_callback(conn->ssl, tls_msg_cb);
1045 SSL_set_msg_callback_arg(conn->ssl, conn);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001046 options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
1047 SSL_OP_SINGLE_DH_USE;
1048#ifdef SSL_OP_NO_COMPRESSION
1049 options |= SSL_OP_NO_COMPRESSION;
1050#endif /* SSL_OP_NO_COMPRESSION */
1051 SSL_set_options(conn->ssl, options);
1052
1053 conn->ssl_in = BIO_new(BIO_s_mem());
1054 if (!conn->ssl_in) {
1055 tls_show_errors(MSG_INFO, __func__,
1056 "Failed to create a new BIO for ssl_in");
1057 SSL_free(conn->ssl);
1058 os_free(conn);
1059 return NULL;
1060 }
1061
1062 conn->ssl_out = BIO_new(BIO_s_mem());
1063 if (!conn->ssl_out) {
1064 tls_show_errors(MSG_INFO, __func__,
1065 "Failed to create a new BIO for ssl_out");
1066 SSL_free(conn->ssl);
1067 BIO_free(conn->ssl_in);
1068 os_free(conn);
1069 return NULL;
1070 }
1071
1072 SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out);
1073
1074 return conn;
1075}
1076
1077
1078void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
1079{
1080 if (conn == NULL)
1081 return;
1082 SSL_free(conn->ssl);
1083 tls_engine_deinit(conn);
1084 os_free(conn->subject_match);
1085 os_free(conn->altsubject_match);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001086 os_free(conn->suffix_match);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001087 os_free(conn->session_ticket);
1088 os_free(conn);
1089}
1090
1091
1092int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
1093{
1094 return conn ? SSL_is_init_finished(conn->ssl) : 0;
1095}
1096
1097
1098int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
1099{
1100 if (conn == NULL)
1101 return -1;
1102
1103 /* Shutdown previous TLS connection without notifying the peer
1104 * because the connection was already terminated in practice
1105 * and "close notify" shutdown alert would confuse AS. */
1106 SSL_set_quiet_shutdown(conn->ssl, 1);
1107 SSL_shutdown(conn->ssl);
1108 return 0;
1109}
1110
1111
1112static int tls_match_altsubject_component(X509 *cert, int type,
1113 const char *value, size_t len)
1114{
1115 GENERAL_NAME *gen;
1116 void *ext;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001117 int found = 0;
1118 stack_index_t i;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001119
1120 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1121
1122 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
1123 gen = sk_GENERAL_NAME_value(ext, i);
1124 if (gen->type != type)
1125 continue;
1126 if (os_strlen((char *) gen->d.ia5->data) == len &&
1127 os_memcmp(value, gen->d.ia5->data, len) == 0)
1128 found++;
1129 }
1130
1131 return found;
1132}
1133
1134
1135static int tls_match_altsubject(X509 *cert, const char *match)
1136{
1137 int type;
1138 const char *pos, *end;
1139 size_t len;
1140
1141 pos = match;
1142 do {
1143 if (os_strncmp(pos, "EMAIL:", 6) == 0) {
1144 type = GEN_EMAIL;
1145 pos += 6;
1146 } else if (os_strncmp(pos, "DNS:", 4) == 0) {
1147 type = GEN_DNS;
1148 pos += 4;
1149 } else if (os_strncmp(pos, "URI:", 4) == 0) {
1150 type = GEN_URI;
1151 pos += 4;
1152 } else {
1153 wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName "
1154 "match '%s'", pos);
1155 return 0;
1156 }
1157 end = os_strchr(pos, ';');
1158 while (end) {
1159 if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
1160 os_strncmp(end + 1, "DNS:", 4) == 0 ||
1161 os_strncmp(end + 1, "URI:", 4) == 0)
1162 break;
1163 end = os_strchr(end + 1, ';');
1164 }
1165 if (end)
1166 len = end - pos;
1167 else
1168 len = os_strlen(pos);
1169 if (tls_match_altsubject_component(cert, type, pos, len) > 0)
1170 return 1;
1171 pos = end + 1;
1172 } while (end);
1173
1174 return 0;
1175}
1176
1177
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001178#ifndef CONFIG_NATIVE_WINDOWS
Dmitry Shmidt051af732013-10-22 13:52:46 -07001179static int domain_suffix_match(const u8 *val, size_t len, const char *match)
1180{
1181 size_t i, match_len;
1182
1183 /* Check for embedded nuls that could mess up suffix matching */
1184 for (i = 0; i < len; i++) {
1185 if (val[i] == '\0') {
1186 wpa_printf(MSG_DEBUG, "TLS: Embedded null in a string - reject");
1187 return 0;
1188 }
1189 }
1190
1191 match_len = os_strlen(match);
1192 if (match_len > len)
1193 return 0;
1194
1195 if (os_strncasecmp((const char *) val + len - match_len, match,
1196 match_len) != 0)
1197 return 0; /* no match */
1198
1199 if (match_len == len)
1200 return 1; /* exact match */
1201
1202 if (val[len - match_len - 1] == '.')
1203 return 1; /* full label match completes suffix match */
1204
1205 wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match");
1206 return 0;
1207}
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001208#endif /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001209
1210
1211static int tls_match_suffix(X509 *cert, const char *match)
1212{
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001213#ifdef CONFIG_NATIVE_WINDOWS
1214 /* wincrypt.h has conflicting X509_NAME definition */
1215 return -1;
1216#else /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001217 GENERAL_NAME *gen;
1218 void *ext;
1219 int i;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001220 stack_index_t j;
Dmitry Shmidt051af732013-10-22 13:52:46 -07001221 int dns_name = 0;
1222 X509_NAME *name;
1223
1224 wpa_printf(MSG_DEBUG, "TLS: Match domain against suffix %s", match);
1225
1226 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1227
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001228 for (j = 0; ext && j < sk_GENERAL_NAME_num(ext); j++) {
1229 gen = sk_GENERAL_NAME_value(ext, j);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001230 if (gen->type != GEN_DNS)
1231 continue;
1232 dns_name++;
1233 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName",
1234 gen->d.dNSName->data,
1235 gen->d.dNSName->length);
1236 if (domain_suffix_match(gen->d.dNSName->data,
1237 gen->d.dNSName->length, match) == 1) {
1238 wpa_printf(MSG_DEBUG, "TLS: Suffix match in dNSName found");
1239 return 1;
1240 }
1241 }
1242
1243 if (dns_name) {
1244 wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched");
1245 return 0;
1246 }
1247
1248 name = X509_get_subject_name(cert);
1249 i = -1;
1250 for (;;) {
1251 X509_NAME_ENTRY *e;
1252 ASN1_STRING *cn;
1253
1254 i = X509_NAME_get_index_by_NID(name, NID_commonName, i);
1255 if (i == -1)
1256 break;
1257 e = X509_NAME_get_entry(name, i);
1258 if (e == NULL)
1259 continue;
1260 cn = X509_NAME_ENTRY_get_data(e);
1261 if (cn == NULL)
1262 continue;
1263 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName",
1264 cn->data, cn->length);
1265 if (domain_suffix_match(cn->data, cn->length, match) == 1) {
1266 wpa_printf(MSG_DEBUG, "TLS: Suffix match in commonName found");
1267 return 1;
1268 }
1269 }
1270
1271 wpa_printf(MSG_DEBUG, "TLS: No CommonName suffix match found");
1272 return 0;
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001273#endif /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001274}
1275
1276
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001277static enum tls_fail_reason openssl_tls_fail_reason(int err)
1278{
1279 switch (err) {
1280 case X509_V_ERR_CERT_REVOKED:
1281 return TLS_FAIL_REVOKED;
1282 case X509_V_ERR_CERT_NOT_YET_VALID:
1283 case X509_V_ERR_CRL_NOT_YET_VALID:
1284 return TLS_FAIL_NOT_YET_VALID;
1285 case X509_V_ERR_CERT_HAS_EXPIRED:
1286 case X509_V_ERR_CRL_HAS_EXPIRED:
1287 return TLS_FAIL_EXPIRED;
1288 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1289 case X509_V_ERR_UNABLE_TO_GET_CRL:
1290 case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
1291 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1292 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1293 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1294 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1295 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1296 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1297 case X509_V_ERR_INVALID_CA:
1298 return TLS_FAIL_UNTRUSTED;
1299 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1300 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
1301 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
1302 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1303 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1304 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
1305 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
1306 case X509_V_ERR_CERT_UNTRUSTED:
1307 case X509_V_ERR_CERT_REJECTED:
1308 return TLS_FAIL_BAD_CERTIFICATE;
1309 default:
1310 return TLS_FAIL_UNSPECIFIED;
1311 }
1312}
1313
1314
1315static struct wpabuf * get_x509_cert(X509 *cert)
1316{
1317 struct wpabuf *buf;
1318 u8 *tmp;
1319
1320 int cert_len = i2d_X509(cert, NULL);
1321 if (cert_len <= 0)
1322 return NULL;
1323
1324 buf = wpabuf_alloc(cert_len);
1325 if (buf == NULL)
1326 return NULL;
1327
1328 tmp = wpabuf_put(buf, cert_len);
1329 i2d_X509(cert, &tmp);
1330 return buf;
1331}
1332
1333
1334static void openssl_tls_fail_event(struct tls_connection *conn,
1335 X509 *err_cert, int err, int depth,
1336 const char *subject, const char *err_str,
1337 enum tls_fail_reason reason)
1338{
1339 union tls_event_data ev;
1340 struct wpabuf *cert = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001341 struct tls_context *context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001342
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001343 if (context->event_cb == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001344 return;
1345
1346 cert = get_x509_cert(err_cert);
1347 os_memset(&ev, 0, sizeof(ev));
1348 ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ?
1349 reason : openssl_tls_fail_reason(err);
1350 ev.cert_fail.depth = depth;
1351 ev.cert_fail.subject = subject;
1352 ev.cert_fail.reason_txt = err_str;
1353 ev.cert_fail.cert = cert;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001354 context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001355 wpabuf_free(cert);
1356}
1357
1358
1359static void openssl_tls_cert_event(struct tls_connection *conn,
1360 X509 *err_cert, int depth,
1361 const char *subject)
1362{
1363 struct wpabuf *cert = NULL;
1364 union tls_event_data ev;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001365 struct tls_context *context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001366#ifdef CONFIG_SHA256
1367 u8 hash[32];
1368#endif /* CONFIG_SHA256 */
1369
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001370 if (context->event_cb == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001371 return;
1372
1373 os_memset(&ev, 0, sizeof(ev));
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001374 if (conn->cert_probe || context->cert_in_cb) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001375 cert = get_x509_cert(err_cert);
1376 ev.peer_cert.cert = cert;
1377 }
1378#ifdef CONFIG_SHA256
1379 if (cert) {
1380 const u8 *addr[1];
1381 size_t len[1];
1382 addr[0] = wpabuf_head(cert);
1383 len[0] = wpabuf_len(cert);
1384 if (sha256_vector(1, addr, len, hash) == 0) {
1385 ev.peer_cert.hash = hash;
1386 ev.peer_cert.hash_len = sizeof(hash);
1387 }
1388 }
1389#endif /* CONFIG_SHA256 */
1390 ev.peer_cert.depth = depth;
1391 ev.peer_cert.subject = subject;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001392 context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001393 wpabuf_free(cert);
1394}
1395
1396
1397static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
1398{
1399 char buf[256];
1400 X509 *err_cert;
1401 int err, depth;
1402 SSL *ssl;
1403 struct tls_connection *conn;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001404 struct tls_context *context;
Dmitry Shmidt051af732013-10-22 13:52:46 -07001405 char *match, *altmatch, *suffix_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001406 const char *err_str;
1407
1408 err_cert = X509_STORE_CTX_get_current_cert(x509_ctx);
Dmitry Shmidt96be6222014-02-13 10:16:51 -08001409 if (!err_cert)
1410 return 0;
1411
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001412 err = X509_STORE_CTX_get_error(x509_ctx);
1413 depth = X509_STORE_CTX_get_error_depth(x509_ctx);
1414 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
1415 SSL_get_ex_data_X509_STORE_CTX_idx());
1416 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
1417
1418 conn = SSL_get_app_data(ssl);
1419 if (conn == NULL)
1420 return 0;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07001421
1422 if (depth == 0)
1423 conn->peer_cert = err_cert;
1424 else if (depth == 1)
1425 conn->peer_issuer = err_cert;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001426 else if (depth == 2)
1427 conn->peer_issuer_issuer = err_cert;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07001428
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001429 context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001430 match = conn->subject_match;
1431 altmatch = conn->altsubject_match;
Dmitry Shmidt051af732013-10-22 13:52:46 -07001432 suffix_match = conn->suffix_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001433
1434 if (!preverify_ok && !conn->ca_cert_verify)
1435 preverify_ok = 1;
1436 if (!preverify_ok && depth > 0 && conn->server_cert_only)
1437 preverify_ok = 1;
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07001438 if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) &&
1439 (err == X509_V_ERR_CERT_HAS_EXPIRED ||
1440 err == X509_V_ERR_CERT_NOT_YET_VALID)) {
1441 wpa_printf(MSG_DEBUG, "OpenSSL: Ignore certificate validity "
1442 "time mismatch");
1443 preverify_ok = 1;
1444 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001445
1446 err_str = X509_verify_cert_error_string(err);
1447
1448#ifdef CONFIG_SHA256
1449 if (preverify_ok && depth == 0 && conn->server_cert_only) {
1450 struct wpabuf *cert;
1451 cert = get_x509_cert(err_cert);
1452 if (!cert) {
1453 wpa_printf(MSG_DEBUG, "OpenSSL: Could not fetch "
1454 "server certificate data");
1455 preverify_ok = 0;
1456 } else {
1457 u8 hash[32];
1458 const u8 *addr[1];
1459 size_t len[1];
1460 addr[0] = wpabuf_head(cert);
1461 len[0] = wpabuf_len(cert);
1462 if (sha256_vector(1, addr, len, hash) < 0 ||
1463 os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
1464 err_str = "Server certificate mismatch";
1465 err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
1466 preverify_ok = 0;
1467 }
1468 wpabuf_free(cert);
1469 }
1470 }
1471#endif /* CONFIG_SHA256 */
1472
1473 if (!preverify_ok) {
1474 wpa_printf(MSG_WARNING, "TLS: Certificate verification failed,"
1475 " error %d (%s) depth %d for '%s'", err, err_str,
1476 depth, buf);
1477 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
1478 err_str, TLS_FAIL_UNSPECIFIED);
1479 return preverify_ok;
1480 }
1481
1482 wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d "
1483 "err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
1484 preverify_ok, err, err_str,
1485 conn->ca_cert_verify, depth, buf);
1486 if (depth == 0 && match && os_strstr(buf, match) == NULL) {
1487 wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not "
1488 "match with '%s'", buf, match);
1489 preverify_ok = 0;
1490 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
1491 "Subject mismatch",
1492 TLS_FAIL_SUBJECT_MISMATCH);
1493 } else if (depth == 0 && altmatch &&
1494 !tls_match_altsubject(err_cert, altmatch)) {
1495 wpa_printf(MSG_WARNING, "TLS: altSubjectName match "
1496 "'%s' not found", altmatch);
1497 preverify_ok = 0;
1498 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
1499 "AltSubject mismatch",
1500 TLS_FAIL_ALTSUBJECT_MISMATCH);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001501 } else if (depth == 0 && suffix_match &&
1502 !tls_match_suffix(err_cert, suffix_match)) {
1503 wpa_printf(MSG_WARNING, "TLS: Domain suffix match '%s' not found",
1504 suffix_match);
1505 preverify_ok = 0;
1506 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
1507 "Domain suffix mismatch",
1508 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001509 } else
1510 openssl_tls_cert_event(conn, err_cert, depth, buf);
1511
1512 if (conn->cert_probe && preverify_ok && depth == 0) {
1513 wpa_printf(MSG_DEBUG, "OpenSSL: Reject server certificate "
1514 "on probe-only run");
1515 preverify_ok = 0;
1516 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
1517 "Server certificate chain probe",
1518 TLS_FAIL_SERVER_CHAIN_PROBE);
1519 }
1520
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001521 if (preverify_ok && context->event_cb != NULL)
1522 context->event_cb(context->cb_ctx,
1523 TLS_CERT_CHAIN_SUCCESS, NULL);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001524
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001525 return preverify_ok;
1526}
1527
1528
1529#ifndef OPENSSL_NO_STDIO
1530static int tls_load_ca_der(void *_ssl_ctx, const char *ca_cert)
1531{
1532 SSL_CTX *ssl_ctx = _ssl_ctx;
1533 X509_LOOKUP *lookup;
1534 int ret = 0;
1535
1536 lookup = X509_STORE_add_lookup(ssl_ctx->cert_store,
1537 X509_LOOKUP_file());
1538 if (lookup == NULL) {
1539 tls_show_errors(MSG_WARNING, __func__,
1540 "Failed add lookup for X509 store");
1541 return -1;
1542 }
1543
1544 if (!X509_LOOKUP_load_file(lookup, ca_cert, X509_FILETYPE_ASN1)) {
1545 unsigned long err = ERR_peek_error();
1546 tls_show_errors(MSG_WARNING, __func__,
1547 "Failed load CA in DER format");
1548 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
1549 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
1550 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
1551 "cert already in hash table error",
1552 __func__);
1553 } else
1554 ret = -1;
1555 }
1556
1557 return ret;
1558}
1559#endif /* OPENSSL_NO_STDIO */
1560
1561
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001562static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn,
1563 const char *ca_cert, const u8 *ca_cert_blob,
1564 size_t ca_cert_blob_len, const char *ca_path)
1565{
1566 SSL_CTX *ssl_ctx = _ssl_ctx;
1567
1568 /*
1569 * Remove previously configured trusted CA certificates before adding
1570 * new ones.
1571 */
1572 X509_STORE_free(ssl_ctx->cert_store);
1573 ssl_ctx->cert_store = X509_STORE_new();
1574 if (ssl_ctx->cert_store == NULL) {
1575 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
1576 "certificate store", __func__);
1577 return -1;
1578 }
1579
1580 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
1581 conn->ca_cert_verify = 1;
1582
1583 if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) {
1584 wpa_printf(MSG_DEBUG, "OpenSSL: Probe for server certificate "
1585 "chain");
1586 conn->cert_probe = 1;
1587 conn->ca_cert_verify = 0;
1588 return 0;
1589 }
1590
1591 if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) {
1592#ifdef CONFIG_SHA256
1593 const char *pos = ca_cert + 7;
1594 if (os_strncmp(pos, "server/sha256/", 14) != 0) {
1595 wpa_printf(MSG_DEBUG, "OpenSSL: Unsupported ca_cert "
1596 "hash value '%s'", ca_cert);
1597 return -1;
1598 }
1599 pos += 14;
1600 if (os_strlen(pos) != 32 * 2) {
1601 wpa_printf(MSG_DEBUG, "OpenSSL: Unexpected SHA256 "
1602 "hash length in ca_cert '%s'", ca_cert);
1603 return -1;
1604 }
1605 if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) {
1606 wpa_printf(MSG_DEBUG, "OpenSSL: Invalid SHA256 hash "
1607 "value in ca_cert '%s'", ca_cert);
1608 return -1;
1609 }
1610 conn->server_cert_only = 1;
1611 wpa_printf(MSG_DEBUG, "OpenSSL: Checking only server "
1612 "certificate match");
1613 return 0;
1614#else /* CONFIG_SHA256 */
1615 wpa_printf(MSG_INFO, "No SHA256 included in the build - "
1616 "cannot validate server certificate hash");
1617 return -1;
1618#endif /* CONFIG_SHA256 */
1619 }
1620
1621 if (ca_cert_blob) {
1622 X509 *cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ca_cert_blob,
1623 ca_cert_blob_len);
1624 if (cert == NULL) {
1625 tls_show_errors(MSG_WARNING, __func__,
1626 "Failed to parse ca_cert_blob");
1627 return -1;
1628 }
1629
1630 if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) {
1631 unsigned long err = ERR_peek_error();
1632 tls_show_errors(MSG_WARNING, __func__,
1633 "Failed to add ca_cert_blob to "
1634 "certificate store");
1635 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
1636 ERR_GET_REASON(err) ==
1637 X509_R_CERT_ALREADY_IN_HASH_TABLE) {
1638 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
1639 "cert already in hash table error",
1640 __func__);
1641 } else {
1642 X509_free(cert);
1643 return -1;
1644 }
1645 }
1646 X509_free(cert);
1647 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob "
1648 "to certificate store", __func__);
1649 return 0;
1650 }
1651
1652#ifdef ANDROID
1653 if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) {
1654 BIO *bio = BIO_from_keystore(&ca_cert[11]);
1655 STACK_OF(X509_INFO) *stack = NULL;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001656 stack_index_t i;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001657
1658 if (bio) {
1659 stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
1660 BIO_free(bio);
1661 }
1662 if (!stack)
1663 return -1;
1664
1665 for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
1666 X509_INFO *info = sk_X509_INFO_value(stack, i);
1667 if (info->x509) {
1668 X509_STORE_add_cert(ssl_ctx->cert_store,
1669 info->x509);
1670 }
1671 if (info->crl) {
1672 X509_STORE_add_crl(ssl_ctx->cert_store,
1673 info->crl);
1674 }
1675 }
1676 sk_X509_INFO_pop_free(stack, X509_INFO_free);
1677 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
1678 return 0;
1679 }
1680#endif /* ANDROID */
1681
1682#ifdef CONFIG_NATIVE_WINDOWS
1683 if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) ==
1684 0) {
1685 wpa_printf(MSG_DEBUG, "OpenSSL: Added CA certificates from "
1686 "system certificate store");
1687 return 0;
1688 }
1689#endif /* CONFIG_NATIVE_WINDOWS */
1690
1691 if (ca_cert || ca_path) {
1692#ifndef OPENSSL_NO_STDIO
1693 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, ca_path) !=
1694 1) {
1695 tls_show_errors(MSG_WARNING, __func__,
1696 "Failed to load root certificates");
1697 if (ca_cert &&
1698 tls_load_ca_der(ssl_ctx, ca_cert) == 0) {
1699 wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded "
1700 "DER format CA certificate",
1701 __func__);
1702 } else
1703 return -1;
1704 } else {
1705 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
1706 "certificate(s) loaded");
1707 tls_get_errors(ssl_ctx);
1708 }
1709#else /* OPENSSL_NO_STDIO */
1710 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
1711 __func__);
1712 return -1;
1713#endif /* OPENSSL_NO_STDIO */
1714 } else {
1715 /* No ca_cert configured - do not try to verify server
1716 * certificate */
1717 conn->ca_cert_verify = 0;
1718 }
1719
1720 return 0;
1721}
1722
1723
1724static int tls_global_ca_cert(SSL_CTX *ssl_ctx, const char *ca_cert)
1725{
1726 if (ca_cert) {
1727 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
1728 {
1729 tls_show_errors(MSG_WARNING, __func__,
1730 "Failed to load root certificates");
1731 return -1;
1732 }
1733
1734 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
1735 "certificate(s) loaded");
1736
1737#ifndef OPENSSL_NO_STDIO
1738 /* Add the same CAs to the client certificate requests */
1739 SSL_CTX_set_client_CA_list(ssl_ctx,
1740 SSL_load_client_CA_file(ca_cert));
1741#endif /* OPENSSL_NO_STDIO */
1742 }
1743
1744 return 0;
1745}
1746
1747
1748int tls_global_set_verify(void *ssl_ctx, int check_crl)
1749{
1750 int flags;
1751
1752 if (check_crl) {
1753 X509_STORE *cs = SSL_CTX_get_cert_store(ssl_ctx);
1754 if (cs == NULL) {
1755 tls_show_errors(MSG_INFO, __func__, "Failed to get "
1756 "certificate store when enabling "
1757 "check_crl");
1758 return -1;
1759 }
1760 flags = X509_V_FLAG_CRL_CHECK;
1761 if (check_crl == 2)
1762 flags |= X509_V_FLAG_CRL_CHECK_ALL;
1763 X509_STORE_set_flags(cs, flags);
1764 }
1765 return 0;
1766}
1767
1768
1769static int tls_connection_set_subject_match(struct tls_connection *conn,
1770 const char *subject_match,
Dmitry Shmidt051af732013-10-22 13:52:46 -07001771 const char *altsubject_match,
1772 const char *suffix_match)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001773{
1774 os_free(conn->subject_match);
1775 conn->subject_match = NULL;
1776 if (subject_match) {
1777 conn->subject_match = os_strdup(subject_match);
1778 if (conn->subject_match == NULL)
1779 return -1;
1780 }
1781
1782 os_free(conn->altsubject_match);
1783 conn->altsubject_match = NULL;
1784 if (altsubject_match) {
1785 conn->altsubject_match = os_strdup(altsubject_match);
1786 if (conn->altsubject_match == NULL)
1787 return -1;
1788 }
1789
Dmitry Shmidt051af732013-10-22 13:52:46 -07001790 os_free(conn->suffix_match);
1791 conn->suffix_match = NULL;
1792 if (suffix_match) {
1793 conn->suffix_match = os_strdup(suffix_match);
1794 if (conn->suffix_match == NULL)
1795 return -1;
1796 }
1797
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001798 return 0;
1799}
1800
1801
1802int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
1803 int verify_peer)
1804{
1805 static int counter = 0;
1806
1807 if (conn == NULL)
1808 return -1;
1809
1810 if (verify_peer) {
1811 conn->ca_cert_verify = 1;
1812 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
1813 SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
1814 SSL_VERIFY_CLIENT_ONCE, tls_verify_cb);
1815 } else {
1816 conn->ca_cert_verify = 0;
1817 SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
1818 }
1819
1820 SSL_set_accept_state(conn->ssl);
1821
1822 /*
1823 * Set session id context in order to avoid fatal errors when client
1824 * tries to resume a session. However, set the context to a unique
1825 * value in order to effectively disable session resumption for now
1826 * since not all areas of the server code are ready for it (e.g.,
1827 * EAP-TTLS needs special handling for Phase 2 after abbreviated TLS
1828 * handshake).
1829 */
1830 counter++;
1831 SSL_set_session_id_context(conn->ssl,
1832 (const unsigned char *) &counter,
1833 sizeof(counter));
1834
1835 return 0;
1836}
1837
1838
1839static int tls_connection_client_cert(struct tls_connection *conn,
1840 const char *client_cert,
1841 const u8 *client_cert_blob,
1842 size_t client_cert_blob_len)
1843{
1844 if (client_cert == NULL && client_cert_blob == NULL)
1845 return 0;
1846
1847 if (client_cert_blob &&
1848 SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob,
1849 client_cert_blob_len) == 1) {
1850 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> "
1851 "OK");
1852 return 0;
1853 } else if (client_cert_blob) {
1854 tls_show_errors(MSG_DEBUG, __func__,
1855 "SSL_use_certificate_ASN1 failed");
1856 }
1857
1858 if (client_cert == NULL)
1859 return -1;
1860
1861#ifdef ANDROID
1862 if (os_strncmp("keystore://", client_cert, 11) == 0) {
1863 BIO *bio = BIO_from_keystore(&client_cert[11]);
1864 X509 *x509 = NULL;
1865 int ret = -1;
1866 if (bio) {
1867 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
1868 BIO_free(bio);
1869 }
1870 if (x509) {
1871 if (SSL_use_certificate(conn->ssl, x509) == 1)
1872 ret = 0;
1873 X509_free(x509);
1874 }
1875 return ret;
1876 }
1877#endif /* ANDROID */
1878
1879#ifndef OPENSSL_NO_STDIO
1880 if (SSL_use_certificate_file(conn->ssl, client_cert,
1881 SSL_FILETYPE_ASN1) == 1) {
1882 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)"
1883 " --> OK");
1884 return 0;
1885 }
1886
1887 if (SSL_use_certificate_file(conn->ssl, client_cert,
1888 SSL_FILETYPE_PEM) == 1) {
1889 ERR_clear_error();
1890 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)"
1891 " --> OK");
1892 return 0;
1893 }
1894
1895 tls_show_errors(MSG_DEBUG, __func__,
1896 "SSL_use_certificate_file failed");
1897#else /* OPENSSL_NO_STDIO */
1898 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
1899#endif /* OPENSSL_NO_STDIO */
1900
1901 return -1;
1902}
1903
1904
1905static int tls_global_client_cert(SSL_CTX *ssl_ctx, const char *client_cert)
1906{
1907#ifndef OPENSSL_NO_STDIO
1908 if (client_cert == NULL)
1909 return 0;
1910
1911 if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
1912 SSL_FILETYPE_ASN1) != 1 &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001913 SSL_CTX_use_certificate_chain_file(ssl_ctx, client_cert) != 1 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001914 SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
1915 SSL_FILETYPE_PEM) != 1) {
1916 tls_show_errors(MSG_INFO, __func__,
1917 "Failed to load client certificate");
1918 return -1;
1919 }
1920 return 0;
1921#else /* OPENSSL_NO_STDIO */
1922 if (client_cert == NULL)
1923 return 0;
1924 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
1925 return -1;
1926#endif /* OPENSSL_NO_STDIO */
1927}
1928
1929
1930static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
1931{
1932 if (password == NULL) {
1933 return 0;
1934 }
1935 os_strlcpy(buf, (char *) password, size);
1936 return os_strlen(buf);
1937}
1938
1939
1940#ifdef PKCS12_FUNCS
1941static int tls_parse_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, PKCS12 *p12,
1942 const char *passwd)
1943{
1944 EVP_PKEY *pkey;
1945 X509 *cert;
1946 STACK_OF(X509) *certs;
1947 int res = 0;
1948 char buf[256];
1949
1950 pkey = NULL;
1951 cert = NULL;
1952 certs = NULL;
1953 if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) {
1954 tls_show_errors(MSG_DEBUG, __func__,
1955 "Failed to parse PKCS12 file");
1956 PKCS12_free(p12);
1957 return -1;
1958 }
1959 wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data");
1960
1961 if (cert) {
1962 X509_NAME_oneline(X509_get_subject_name(cert), buf,
1963 sizeof(buf));
1964 wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: "
1965 "subject='%s'", buf);
1966 if (ssl) {
1967 if (SSL_use_certificate(ssl, cert) != 1)
1968 res = -1;
1969 } else {
1970 if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1)
1971 res = -1;
1972 }
1973 X509_free(cert);
1974 }
1975
1976 if (pkey) {
1977 wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12");
1978 if (ssl) {
1979 if (SSL_use_PrivateKey(ssl, pkey) != 1)
1980 res = -1;
1981 } else {
1982 if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1)
1983 res = -1;
1984 }
1985 EVP_PKEY_free(pkey);
1986 }
1987
1988 if (certs) {
1989 while ((cert = sk_X509_pop(certs)) != NULL) {
1990 X509_NAME_oneline(X509_get_subject_name(cert), buf,
1991 sizeof(buf));
1992 wpa_printf(MSG_DEBUG, "TLS: additional certificate"
1993 " from PKCS12: subject='%s'", buf);
1994 /*
1995 * There is no SSL equivalent for the chain cert - so
1996 * always add it to the context...
1997 */
1998 if (SSL_CTX_add_extra_chain_cert(ssl_ctx, cert) != 1) {
1999 res = -1;
2000 break;
2001 }
2002 }
2003 sk_X509_free(certs);
2004 }
2005
2006 PKCS12_free(p12);
2007
2008 if (res < 0)
2009 tls_get_errors(ssl_ctx);
2010
2011 return res;
2012}
2013#endif /* PKCS12_FUNCS */
2014
2015
2016static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key,
2017 const char *passwd)
2018{
2019#ifdef PKCS12_FUNCS
2020 FILE *f;
2021 PKCS12 *p12;
2022
2023 f = fopen(private_key, "rb");
2024 if (f == NULL)
2025 return -1;
2026
2027 p12 = d2i_PKCS12_fp(f, NULL);
2028 fclose(f);
2029
2030 if (p12 == NULL) {
2031 tls_show_errors(MSG_INFO, __func__,
2032 "Failed to use PKCS#12 file");
2033 return -1;
2034 }
2035
2036 return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd);
2037
2038#else /* PKCS12_FUNCS */
2039 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read "
2040 "p12/pfx files");
2041 return -1;
2042#endif /* PKCS12_FUNCS */
2043}
2044
2045
2046static int tls_read_pkcs12_blob(SSL_CTX *ssl_ctx, SSL *ssl,
2047 const u8 *blob, size_t len, const char *passwd)
2048{
2049#ifdef PKCS12_FUNCS
2050 PKCS12 *p12;
2051
2052 p12 = d2i_PKCS12(NULL, (OPENSSL_d2i_TYPE) &blob, len);
2053 if (p12 == NULL) {
2054 tls_show_errors(MSG_INFO, __func__,
2055 "Failed to use PKCS#12 blob");
2056 return -1;
2057 }
2058
2059 return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd);
2060
2061#else /* PKCS12_FUNCS */
2062 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse "
2063 "p12/pfx blobs");
2064 return -1;
2065#endif /* PKCS12_FUNCS */
2066}
2067
2068
2069#ifndef OPENSSL_NO_ENGINE
2070static int tls_engine_get_cert(struct tls_connection *conn,
2071 const char *cert_id,
2072 X509 **cert)
2073{
2074 /* this runs after the private key is loaded so no PIN is required */
2075 struct {
2076 const char *cert_id;
2077 X509 *cert;
2078 } params;
2079 params.cert_id = cert_id;
2080 params.cert = NULL;
2081
2082 if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL",
2083 0, &params, NULL, 1)) {
2084 wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id"
2085 " '%s' [%s]", cert_id,
2086 ERR_error_string(ERR_get_error(), NULL));
2087 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
2088 }
2089 if (!params.cert) {
2090 wpa_printf(MSG_ERROR, "ENGINE: did not properly cert with id"
2091 " '%s'", cert_id);
2092 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
2093 }
2094 *cert = params.cert;
2095 return 0;
2096}
2097#endif /* OPENSSL_NO_ENGINE */
2098
2099
2100static int tls_connection_engine_client_cert(struct tls_connection *conn,
2101 const char *cert_id)
2102{
2103#ifndef OPENSSL_NO_ENGINE
2104 X509 *cert;
2105
2106 if (tls_engine_get_cert(conn, cert_id, &cert))
2107 return -1;
2108
2109 if (!SSL_use_certificate(conn->ssl, cert)) {
2110 tls_show_errors(MSG_ERROR, __func__,
2111 "SSL_use_certificate failed");
2112 X509_free(cert);
2113 return -1;
2114 }
2115 X509_free(cert);
2116 wpa_printf(MSG_DEBUG, "ENGINE: SSL_use_certificate --> "
2117 "OK");
2118 return 0;
2119
2120#else /* OPENSSL_NO_ENGINE */
2121 return -1;
2122#endif /* OPENSSL_NO_ENGINE */
2123}
2124
2125
2126static int tls_connection_engine_ca_cert(void *_ssl_ctx,
2127 struct tls_connection *conn,
2128 const char *ca_cert_id)
2129{
2130#ifndef OPENSSL_NO_ENGINE
2131 X509 *cert;
2132 SSL_CTX *ssl_ctx = _ssl_ctx;
2133
2134 if (tls_engine_get_cert(conn, ca_cert_id, &cert))
2135 return -1;
2136
2137 /* start off the same as tls_connection_ca_cert */
2138 X509_STORE_free(ssl_ctx->cert_store);
2139 ssl_ctx->cert_store = X509_STORE_new();
2140 if (ssl_ctx->cert_store == NULL) {
2141 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
2142 "certificate store", __func__);
2143 X509_free(cert);
2144 return -1;
2145 }
2146 if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) {
2147 unsigned long err = ERR_peek_error();
2148 tls_show_errors(MSG_WARNING, __func__,
2149 "Failed to add CA certificate from engine "
2150 "to certificate store");
2151 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
2152 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
2153 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring cert"
2154 " already in hash table error",
2155 __func__);
2156 } else {
2157 X509_free(cert);
2158 return -1;
2159 }
2160 }
2161 X509_free(cert);
2162 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added CA certificate from engine "
2163 "to certificate store", __func__);
2164 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002165 conn->ca_cert_verify = 1;
2166
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002167 return 0;
2168
2169#else /* OPENSSL_NO_ENGINE */
2170 return -1;
2171#endif /* OPENSSL_NO_ENGINE */
2172}
2173
2174
2175static int tls_connection_engine_private_key(struct tls_connection *conn)
2176{
2177#ifndef OPENSSL_NO_ENGINE
2178 if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) {
2179 tls_show_errors(MSG_ERROR, __func__,
2180 "ENGINE: cannot use private key for TLS");
2181 return -1;
2182 }
2183 if (!SSL_check_private_key(conn->ssl)) {
2184 tls_show_errors(MSG_INFO, __func__,
2185 "Private key failed verification");
2186 return -1;
2187 }
2188 return 0;
2189#else /* OPENSSL_NO_ENGINE */
2190 wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but "
2191 "engine support was not compiled in");
2192 return -1;
2193#endif /* OPENSSL_NO_ENGINE */
2194}
2195
2196
2197static int tls_connection_private_key(void *_ssl_ctx,
2198 struct tls_connection *conn,
2199 const char *private_key,
2200 const char *private_key_passwd,
2201 const u8 *private_key_blob,
2202 size_t private_key_blob_len)
2203{
2204 SSL_CTX *ssl_ctx = _ssl_ctx;
2205 char *passwd;
2206 int ok;
2207
2208 if (private_key == NULL && private_key_blob == NULL)
2209 return 0;
2210
2211 if (private_key_passwd) {
2212 passwd = os_strdup(private_key_passwd);
2213 if (passwd == NULL)
2214 return -1;
2215 } else
2216 passwd = NULL;
2217
2218 SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
2219 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
2220
2221 ok = 0;
2222 while (private_key_blob) {
2223 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl,
2224 (u8 *) private_key_blob,
2225 private_key_blob_len) == 1) {
2226 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
2227 "ASN1(EVP_PKEY_RSA) --> OK");
2228 ok = 1;
2229 break;
2230 }
2231
2232 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl,
2233 (u8 *) private_key_blob,
2234 private_key_blob_len) == 1) {
2235 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
2236 "ASN1(EVP_PKEY_DSA) --> OK");
2237 ok = 1;
2238 break;
2239 }
2240
2241 if (SSL_use_RSAPrivateKey_ASN1(conn->ssl,
2242 (u8 *) private_key_blob,
2243 private_key_blob_len) == 1) {
2244 wpa_printf(MSG_DEBUG, "OpenSSL: "
2245 "SSL_use_RSAPrivateKey_ASN1 --> OK");
2246 ok = 1;
2247 break;
2248 }
2249
2250 if (tls_read_pkcs12_blob(ssl_ctx, conn->ssl, private_key_blob,
2251 private_key_blob_len, passwd) == 0) {
2252 wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> "
2253 "OK");
2254 ok = 1;
2255 break;
2256 }
2257
2258 break;
2259 }
2260
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002261 while (!ok && private_key) {
2262#ifndef OPENSSL_NO_STDIO
2263 if (SSL_use_PrivateKey_file(conn->ssl, private_key,
2264 SSL_FILETYPE_ASN1) == 1) {
2265 wpa_printf(MSG_DEBUG, "OpenSSL: "
2266 "SSL_use_PrivateKey_File (DER) --> OK");
2267 ok = 1;
2268 break;
2269 }
2270
2271 if (SSL_use_PrivateKey_file(conn->ssl, private_key,
2272 SSL_FILETYPE_PEM) == 1) {
2273 wpa_printf(MSG_DEBUG, "OpenSSL: "
2274 "SSL_use_PrivateKey_File (PEM) --> OK");
2275 ok = 1;
2276 break;
2277 }
2278#else /* OPENSSL_NO_STDIO */
2279 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
2280 __func__);
2281#endif /* OPENSSL_NO_STDIO */
2282
2283 if (tls_read_pkcs12(ssl_ctx, conn->ssl, private_key, passwd)
2284 == 0) {
2285 wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file "
2286 "--> OK");
2287 ok = 1;
2288 break;
2289 }
2290
2291 if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) {
2292 wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to "
2293 "access certificate store --> OK");
2294 ok = 1;
2295 break;
2296 }
2297
2298 break;
2299 }
2300
2301 if (!ok) {
2302 tls_show_errors(MSG_INFO, __func__,
2303 "Failed to load private key");
2304 os_free(passwd);
2305 return -1;
2306 }
2307 ERR_clear_error();
2308 SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
2309 os_free(passwd);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002310
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002311 if (!SSL_check_private_key(conn->ssl)) {
2312 tls_show_errors(MSG_INFO, __func__, "Private key failed "
2313 "verification");
2314 return -1;
2315 }
2316
2317 wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully");
2318 return 0;
2319}
2320
2321
2322static int tls_global_private_key(SSL_CTX *ssl_ctx, const char *private_key,
2323 const char *private_key_passwd)
2324{
2325 char *passwd;
2326
2327 if (private_key == NULL)
2328 return 0;
2329
2330 if (private_key_passwd) {
2331 passwd = os_strdup(private_key_passwd);
2332 if (passwd == NULL)
2333 return -1;
2334 } else
2335 passwd = NULL;
2336
2337 SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
2338 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
2339 if (
2340#ifndef OPENSSL_NO_STDIO
2341 SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
2342 SSL_FILETYPE_ASN1) != 1 &&
2343 SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
2344 SSL_FILETYPE_PEM) != 1 &&
2345#endif /* OPENSSL_NO_STDIO */
2346 tls_read_pkcs12(ssl_ctx, NULL, private_key, passwd)) {
2347 tls_show_errors(MSG_INFO, __func__,
2348 "Failed to load private key");
2349 os_free(passwd);
2350 ERR_clear_error();
2351 return -1;
2352 }
2353 os_free(passwd);
2354 ERR_clear_error();
2355 SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002356
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002357 if (!SSL_CTX_check_private_key(ssl_ctx)) {
2358 tls_show_errors(MSG_INFO, __func__,
2359 "Private key failed verification");
2360 return -1;
2361 }
2362
2363 return 0;
2364}
2365
2366
2367static int tls_connection_dh(struct tls_connection *conn, const char *dh_file)
2368{
2369#ifdef OPENSSL_NO_DH
2370 if (dh_file == NULL)
2371 return 0;
2372 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
2373 "dh_file specified");
2374 return -1;
2375#else /* OPENSSL_NO_DH */
2376 DH *dh;
2377 BIO *bio;
2378
2379 /* TODO: add support for dh_blob */
2380 if (dh_file == NULL)
2381 return 0;
2382 if (conn == NULL)
2383 return -1;
2384
2385 bio = BIO_new_file(dh_file, "r");
2386 if (bio == NULL) {
2387 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
2388 dh_file, ERR_error_string(ERR_get_error(), NULL));
2389 return -1;
2390 }
2391 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
2392 BIO_free(bio);
2393#ifndef OPENSSL_NO_DSA
2394 while (dh == NULL) {
2395 DSA *dsa;
2396 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
2397 " trying to parse as DSA params", dh_file,
2398 ERR_error_string(ERR_get_error(), NULL));
2399 bio = BIO_new_file(dh_file, "r");
2400 if (bio == NULL)
2401 break;
2402 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
2403 BIO_free(bio);
2404 if (!dsa) {
2405 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
2406 "'%s': %s", dh_file,
2407 ERR_error_string(ERR_get_error(), NULL));
2408 break;
2409 }
2410
2411 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
2412 dh = DSA_dup_DH(dsa);
2413 DSA_free(dsa);
2414 if (dh == NULL) {
2415 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
2416 "params into DH params");
2417 break;
2418 }
2419 break;
2420 }
2421#endif /* !OPENSSL_NO_DSA */
2422 if (dh == NULL) {
2423 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
2424 "'%s'", dh_file);
2425 return -1;
2426 }
2427
2428 if (SSL_set_tmp_dh(conn->ssl, dh) != 1) {
2429 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
2430 "%s", dh_file,
2431 ERR_error_string(ERR_get_error(), NULL));
2432 DH_free(dh);
2433 return -1;
2434 }
2435 DH_free(dh);
2436 return 0;
2437#endif /* OPENSSL_NO_DH */
2438}
2439
2440
2441static int tls_global_dh(SSL_CTX *ssl_ctx, const char *dh_file)
2442{
2443#ifdef OPENSSL_NO_DH
2444 if (dh_file == NULL)
2445 return 0;
2446 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
2447 "dh_file specified");
2448 return -1;
2449#else /* OPENSSL_NO_DH */
2450 DH *dh;
2451 BIO *bio;
2452
2453 /* TODO: add support for dh_blob */
2454 if (dh_file == NULL)
2455 return 0;
2456 if (ssl_ctx == NULL)
2457 return -1;
2458
2459 bio = BIO_new_file(dh_file, "r");
2460 if (bio == NULL) {
2461 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
2462 dh_file, ERR_error_string(ERR_get_error(), NULL));
2463 return -1;
2464 }
2465 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
2466 BIO_free(bio);
2467#ifndef OPENSSL_NO_DSA
2468 while (dh == NULL) {
2469 DSA *dsa;
2470 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
2471 " trying to parse as DSA params", dh_file,
2472 ERR_error_string(ERR_get_error(), NULL));
2473 bio = BIO_new_file(dh_file, "r");
2474 if (bio == NULL)
2475 break;
2476 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
2477 BIO_free(bio);
2478 if (!dsa) {
2479 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
2480 "'%s': %s", dh_file,
2481 ERR_error_string(ERR_get_error(), NULL));
2482 break;
2483 }
2484
2485 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
2486 dh = DSA_dup_DH(dsa);
2487 DSA_free(dsa);
2488 if (dh == NULL) {
2489 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
2490 "params into DH params");
2491 break;
2492 }
2493 break;
2494 }
2495#endif /* !OPENSSL_NO_DSA */
2496 if (dh == NULL) {
2497 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
2498 "'%s'", dh_file);
2499 return -1;
2500 }
2501
2502 if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) {
2503 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
2504 "%s", dh_file,
2505 ERR_error_string(ERR_get_error(), NULL));
2506 DH_free(dh);
2507 return -1;
2508 }
2509 DH_free(dh);
2510 return 0;
2511#endif /* OPENSSL_NO_DH */
2512}
2513
2514
2515int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
2516 struct tls_keys *keys)
2517{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002518#ifdef CONFIG_FIPS
2519 wpa_printf(MSG_ERROR, "OpenSSL: TLS keys cannot be exported in FIPS "
2520 "mode");
2521 return -1;
2522#else /* CONFIG_FIPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002523 SSL *ssl;
2524
2525 if (conn == NULL || keys == NULL)
2526 return -1;
2527 ssl = conn->ssl;
2528 if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL)
2529 return -1;
2530
2531 os_memset(keys, 0, sizeof(*keys));
2532 keys->master_key = ssl->session->master_key;
2533 keys->master_key_len = ssl->session->master_key_length;
2534 keys->client_random = ssl->s3->client_random;
2535 keys->client_random_len = SSL3_RANDOM_SIZE;
2536 keys->server_random = ssl->s3->server_random;
2537 keys->server_random_len = SSL3_RANDOM_SIZE;
2538
2539 return 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002540#endif /* CONFIG_FIPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002541}
2542
2543
2544int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
2545 const char *label, int server_random_first,
2546 u8 *out, size_t out_len)
2547{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002548#if OPENSSL_VERSION_NUMBER >= 0x10001000L
2549 SSL *ssl;
2550 if (conn == NULL)
2551 return -1;
2552 if (server_random_first)
2553 return -1;
2554 ssl = conn->ssl;
2555 if (SSL_export_keying_material(ssl, out, out_len, label,
2556 os_strlen(label), NULL, 0, 0) == 1) {
2557 wpa_printf(MSG_DEBUG, "OpenSSL: Using internal PRF");
2558 return 0;
2559 }
2560#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002561 return -1;
2562}
2563
2564
2565static struct wpabuf *
2566openssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data,
2567 int server)
2568{
2569 int res;
2570 struct wpabuf *out_data;
2571
2572 /*
2573 * Give TLS handshake data from the server (if available) to OpenSSL
2574 * for processing.
2575 */
2576 if (in_data &&
2577 BIO_write(conn->ssl_in, wpabuf_head(in_data), wpabuf_len(in_data))
2578 < 0) {
2579 tls_show_errors(MSG_INFO, __func__,
2580 "Handshake failed - BIO_write");
2581 return NULL;
2582 }
2583
2584 /* Initiate TLS handshake or continue the existing handshake */
2585 if (server)
2586 res = SSL_accept(conn->ssl);
2587 else
2588 res = SSL_connect(conn->ssl);
2589 if (res != 1) {
2590 int err = SSL_get_error(conn->ssl, res);
2591 if (err == SSL_ERROR_WANT_READ)
2592 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want "
2593 "more data");
2594 else if (err == SSL_ERROR_WANT_WRITE)
2595 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to "
2596 "write");
2597 else {
2598 tls_show_errors(MSG_INFO, __func__, "SSL_connect");
2599 conn->failed++;
2600 }
2601 }
2602
2603 /* Get the TLS handshake data to be sent to the server */
2604 res = BIO_ctrl_pending(conn->ssl_out);
2605 wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
2606 out_data = wpabuf_alloc(res);
2607 if (out_data == NULL) {
2608 wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
2609 "handshake output (%d bytes)", res);
2610 if (BIO_reset(conn->ssl_out) < 0) {
2611 tls_show_errors(MSG_INFO, __func__,
2612 "BIO_reset failed");
2613 }
2614 return NULL;
2615 }
2616 res = res == 0 ? 0 : BIO_read(conn->ssl_out, wpabuf_mhead(out_data),
2617 res);
2618 if (res < 0) {
2619 tls_show_errors(MSG_INFO, __func__,
2620 "Handshake failed - BIO_read");
2621 if (BIO_reset(conn->ssl_out) < 0) {
2622 tls_show_errors(MSG_INFO, __func__,
2623 "BIO_reset failed");
2624 }
2625 wpabuf_free(out_data);
2626 return NULL;
2627 }
2628 wpabuf_put(out_data, res);
2629
2630 return out_data;
2631}
2632
2633
2634static struct wpabuf *
2635openssl_get_appl_data(struct tls_connection *conn, size_t max_len)
2636{
2637 struct wpabuf *appl_data;
2638 int res;
2639
2640 appl_data = wpabuf_alloc(max_len + 100);
2641 if (appl_data == NULL)
2642 return NULL;
2643
2644 res = SSL_read(conn->ssl, wpabuf_mhead(appl_data),
2645 wpabuf_size(appl_data));
2646 if (res < 0) {
2647 int err = SSL_get_error(conn->ssl, res);
2648 if (err == SSL_ERROR_WANT_READ ||
2649 err == SSL_ERROR_WANT_WRITE) {
2650 wpa_printf(MSG_DEBUG, "SSL: No Application Data "
2651 "included");
2652 } else {
2653 tls_show_errors(MSG_INFO, __func__,
2654 "Failed to read possible "
2655 "Application Data");
2656 }
2657 wpabuf_free(appl_data);
2658 return NULL;
2659 }
2660
2661 wpabuf_put(appl_data, res);
2662 wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application Data in Finished "
2663 "message", appl_data);
2664
2665 return appl_data;
2666}
2667
2668
2669static struct wpabuf *
2670openssl_connection_handshake(struct tls_connection *conn,
2671 const struct wpabuf *in_data,
2672 struct wpabuf **appl_data, int server)
2673{
2674 struct wpabuf *out_data;
2675
2676 if (appl_data)
2677 *appl_data = NULL;
2678
2679 out_data = openssl_handshake(conn, in_data, server);
2680 if (out_data == NULL)
2681 return NULL;
Jouni Malinen26af48b2014-04-09 13:02:53 +03002682 if (conn->invalid_hb_used) {
2683 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
2684 wpabuf_free(out_data);
2685 return NULL;
2686 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002687
2688 if (SSL_is_init_finished(conn->ssl) && appl_data && in_data)
2689 *appl_data = openssl_get_appl_data(conn, wpabuf_len(in_data));
2690
Jouni Malinen26af48b2014-04-09 13:02:53 +03002691 if (conn->invalid_hb_used) {
2692 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
2693 if (appl_data) {
2694 wpabuf_free(*appl_data);
2695 *appl_data = NULL;
2696 }
2697 wpabuf_free(out_data);
2698 return NULL;
2699 }
2700
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002701 return out_data;
2702}
2703
2704
2705struct wpabuf *
2706tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
2707 const struct wpabuf *in_data,
2708 struct wpabuf **appl_data)
2709{
2710 return openssl_connection_handshake(conn, in_data, appl_data, 0);
2711}
2712
2713
2714struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
2715 struct tls_connection *conn,
2716 const struct wpabuf *in_data,
2717 struct wpabuf **appl_data)
2718{
2719 return openssl_connection_handshake(conn, in_data, appl_data, 1);
2720}
2721
2722
2723struct wpabuf * tls_connection_encrypt(void *tls_ctx,
2724 struct tls_connection *conn,
2725 const struct wpabuf *in_data)
2726{
2727 int res;
2728 struct wpabuf *buf;
2729
2730 if (conn == NULL)
2731 return NULL;
2732
2733 /* Give plaintext data for OpenSSL to encrypt into the TLS tunnel. */
2734 if ((res = BIO_reset(conn->ssl_in)) < 0 ||
2735 (res = BIO_reset(conn->ssl_out)) < 0) {
2736 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
2737 return NULL;
2738 }
2739 res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data));
2740 if (res < 0) {
2741 tls_show_errors(MSG_INFO, __func__,
2742 "Encryption failed - SSL_write");
2743 return NULL;
2744 }
2745
2746 /* Read encrypted data to be sent to the server */
2747 buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
2748 if (buf == NULL)
2749 return NULL;
2750 res = BIO_read(conn->ssl_out, wpabuf_mhead(buf), wpabuf_size(buf));
2751 if (res < 0) {
2752 tls_show_errors(MSG_INFO, __func__,
2753 "Encryption failed - BIO_read");
2754 wpabuf_free(buf);
2755 return NULL;
2756 }
2757 wpabuf_put(buf, res);
2758
2759 return buf;
2760}
2761
2762
2763struct wpabuf * tls_connection_decrypt(void *tls_ctx,
2764 struct tls_connection *conn,
2765 const struct wpabuf *in_data)
2766{
2767 int res;
2768 struct wpabuf *buf;
2769
2770 /* Give encrypted data from TLS tunnel for OpenSSL to decrypt. */
2771 res = BIO_write(conn->ssl_in, wpabuf_head(in_data),
2772 wpabuf_len(in_data));
2773 if (res < 0) {
2774 tls_show_errors(MSG_INFO, __func__,
2775 "Decryption failed - BIO_write");
2776 return NULL;
2777 }
2778 if (BIO_reset(conn->ssl_out) < 0) {
2779 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
2780 return NULL;
2781 }
2782
2783 /* Read decrypted data for further processing */
2784 /*
2785 * Even though we try to disable TLS compression, it is possible that
2786 * this cannot be done with all TLS libraries. Add extra buffer space
2787 * to handle the possibility of the decrypted data being longer than
2788 * input data.
2789 */
2790 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
2791 if (buf == NULL)
2792 return NULL;
2793 res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
2794 if (res < 0) {
2795 tls_show_errors(MSG_INFO, __func__,
2796 "Decryption failed - SSL_read");
2797 wpabuf_free(buf);
2798 return NULL;
2799 }
2800 wpabuf_put(buf, res);
2801
Jouni Malinen26af48b2014-04-09 13:02:53 +03002802 if (conn->invalid_hb_used) {
2803 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
2804 wpabuf_free(buf);
2805 return NULL;
2806 }
2807
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002808 return buf;
2809}
2810
2811
2812int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
2813{
2814 return conn ? conn->ssl->hit : 0;
2815}
2816
2817
2818int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
2819 u8 *ciphers)
2820{
2821 char buf[100], *pos, *end;
2822 u8 *c;
2823 int ret;
2824
2825 if (conn == NULL || conn->ssl == NULL || ciphers == NULL)
2826 return -1;
2827
2828 buf[0] = '\0';
2829 pos = buf;
2830 end = pos + sizeof(buf);
2831
2832 c = ciphers;
2833 while (*c != TLS_CIPHER_NONE) {
2834 const char *suite;
2835
2836 switch (*c) {
2837 case TLS_CIPHER_RC4_SHA:
2838 suite = "RC4-SHA";
2839 break;
2840 case TLS_CIPHER_AES128_SHA:
2841 suite = "AES128-SHA";
2842 break;
2843 case TLS_CIPHER_RSA_DHE_AES128_SHA:
2844 suite = "DHE-RSA-AES128-SHA";
2845 break;
2846 case TLS_CIPHER_ANON_DH_AES128_SHA:
2847 suite = "ADH-AES128-SHA";
2848 break;
2849 default:
2850 wpa_printf(MSG_DEBUG, "TLS: Unsupported "
2851 "cipher selection: %d", *c);
2852 return -1;
2853 }
2854 ret = os_snprintf(pos, end - pos, ":%s", suite);
2855 if (ret < 0 || ret >= end - pos)
2856 break;
2857 pos += ret;
2858
2859 c++;
2860 }
2861
2862 wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1);
2863
2864 if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
2865 tls_show_errors(MSG_INFO, __func__,
2866 "Cipher suite configuration failed");
2867 return -1;
2868 }
2869
2870 return 0;
2871}
2872
2873
2874int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
2875 char *buf, size_t buflen)
2876{
2877 const char *name;
2878 if (conn == NULL || conn->ssl == NULL)
2879 return -1;
2880
2881 name = SSL_get_cipher(conn->ssl);
2882 if (name == NULL)
2883 return -1;
2884
2885 os_strlcpy(buf, name, buflen);
2886 return 0;
2887}
2888
2889
2890int tls_connection_enable_workaround(void *ssl_ctx,
2891 struct tls_connection *conn)
2892{
2893 SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
2894
2895 return 0;
2896}
2897
2898
2899#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2900/* ClientHello TLS extensions require a patch to openssl, so this function is
2901 * commented out unless explicitly needed for EAP-FAST in order to be able to
2902 * build this file with unmodified openssl. */
2903int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
2904 int ext_type, const u8 *data,
2905 size_t data_len)
2906{
2907 if (conn == NULL || conn->ssl == NULL || ext_type != 35)
2908 return -1;
2909
2910#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
2911 if (SSL_set_session_ticket_ext(conn->ssl, (void *) data,
2912 data_len) != 1)
2913 return -1;
2914#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
2915 if (SSL_set_hello_extension(conn->ssl, ext_type, (void *) data,
2916 data_len) != 1)
2917 return -1;
2918#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
2919
2920 return 0;
2921}
2922#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2923
2924
2925int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
2926{
2927 if (conn == NULL)
2928 return -1;
2929 return conn->failed;
2930}
2931
2932
2933int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
2934{
2935 if (conn == NULL)
2936 return -1;
2937 return conn->read_alerts;
2938}
2939
2940
2941int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
2942{
2943 if (conn == NULL)
2944 return -1;
2945 return conn->write_alerts;
2946}
2947
2948
Dmitry Shmidt34af3062013-07-11 10:46:32 -07002949#ifdef HAVE_OCSP
2950
2951static void ocsp_debug_print_resp(OCSP_RESPONSE *rsp)
2952{
2953#ifndef CONFIG_NO_STDOUT_DEBUG
Dmitry Shmidt34af3062013-07-11 10:46:32 -07002954 BIO *out;
2955 size_t rlen;
2956 char *txt;
2957 int res;
2958
2959 if (wpa_debug_level > MSG_DEBUG)
2960 return;
2961
2962 out = BIO_new(BIO_s_mem());
2963 if (!out)
2964 return;
2965
2966 OCSP_RESPONSE_print(out, rsp, 0);
2967 rlen = BIO_ctrl_pending(out);
2968 txt = os_malloc(rlen + 1);
2969 if (!txt) {
2970 BIO_free(out);
2971 return;
2972 }
2973
2974 res = BIO_read(out, txt, rlen);
2975 if (res > 0) {
2976 txt[res] = '\0';
2977 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP Response\n%s", txt);
2978 }
2979 os_free(txt);
2980 BIO_free(out);
2981#endif /* CONFIG_NO_STDOUT_DEBUG */
2982}
2983
2984
Dmitry Shmidt71757432014-06-02 13:50:35 -07002985static void debug_print_cert(X509 *cert, const char *title)
2986{
2987#ifndef CONFIG_NO_STDOUT_DEBUG
2988 BIO *out;
2989 size_t rlen;
2990 char *txt;
2991 int res;
2992
2993 if (wpa_debug_level > MSG_DEBUG)
2994 return;
2995
2996 out = BIO_new(BIO_s_mem());
2997 if (!out)
2998 return;
2999
3000 X509_print(out, cert);
3001 rlen = BIO_ctrl_pending(out);
3002 txt = os_malloc(rlen + 1);
3003 if (!txt) {
3004 BIO_free(out);
3005 return;
3006 }
3007
3008 res = BIO_read(out, txt, rlen);
3009 if (res > 0) {
3010 txt[res] = '\0';
3011 wpa_printf(MSG_DEBUG, "OpenSSL: %s\n%s", title, txt);
3012 }
3013 os_free(txt);
3014
3015 BIO_free(out);
3016#endif /* CONFIG_NO_STDOUT_DEBUG */
3017}
3018
3019
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003020static int ocsp_resp_cb(SSL *s, void *arg)
3021{
3022 struct tls_connection *conn = arg;
3023 const unsigned char *p;
3024 int len, status, reason;
3025 OCSP_RESPONSE *rsp;
3026 OCSP_BASICRESP *basic;
3027 OCSP_CERTID *id;
3028 ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08003029 X509_STORE *store;
3030 STACK_OF(X509) *certs = NULL;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003031
3032 len = SSL_get_tlsext_status_ocsp_resp(s, &p);
3033 if (!p) {
3034 wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received");
3035 return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1;
3036 }
3037
3038 wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", p, len);
3039
3040 rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
3041 if (!rsp) {
3042 wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSP response");
3043 return 0;
3044 }
3045
3046 ocsp_debug_print_resp(rsp);
3047
3048 status = OCSP_response_status(rsp);
3049 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
3050 wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d (%s)",
3051 status, OCSP_response_status_str(status));
3052 return 0;
3053 }
3054
3055 basic = OCSP_response_get1_basic(rsp);
3056 if (!basic) {
3057 wpa_printf(MSG_INFO, "OpenSSL: Could not find BasicOCSPResponse");
3058 return 0;
3059 }
3060
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08003061 store = SSL_CTX_get_cert_store(s->ctx);
3062 if (conn->peer_issuer) {
Dmitry Shmidt71757432014-06-02 13:50:35 -07003063 debug_print_cert(conn->peer_issuer, "Add OCSP issuer");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08003064
3065 if (X509_STORE_add_cert(store, conn->peer_issuer) != 1) {
3066 tls_show_errors(MSG_INFO, __func__,
3067 "OpenSSL: Could not add issuer to certificate store\n");
3068 }
3069 certs = sk_X509_new_null();
3070 if (certs) {
3071 X509 *cert;
3072 cert = X509_dup(conn->peer_issuer);
3073 if (cert && !sk_X509_push(certs, cert)) {
3074 tls_show_errors(
3075 MSG_INFO, __func__,
3076 "OpenSSL: Could not add issuer to OCSP responder trust store\n");
3077 X509_free(cert);
3078 sk_X509_free(certs);
3079 certs = NULL;
3080 }
3081 if (conn->peer_issuer_issuer) {
3082 cert = X509_dup(conn->peer_issuer_issuer);
3083 if (cert && !sk_X509_push(certs, cert)) {
3084 tls_show_errors(
3085 MSG_INFO, __func__,
3086 "OpenSSL: Could not add issuer to OCSP responder trust store\n");
3087 X509_free(cert);
3088 }
3089 }
3090 }
3091 }
3092
3093 status = OCSP_basic_verify(basic, certs, store, OCSP_TRUSTOTHER);
3094 sk_X509_pop_free(certs, X509_free);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003095 if (status <= 0) {
3096 tls_show_errors(MSG_INFO, __func__,
3097 "OpenSSL: OCSP response failed verification");
3098 OCSP_BASICRESP_free(basic);
3099 OCSP_RESPONSE_free(rsp);
3100 return 0;
3101 }
3102
3103 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response verification succeeded");
3104
Dmitry Shmidt56052862013-10-04 10:23:25 -07003105 if (!conn->peer_cert) {
3106 wpa_printf(MSG_DEBUG, "OpenSSL: Peer certificate not available for OCSP status check");
3107 OCSP_BASICRESP_free(basic);
3108 OCSP_RESPONSE_free(rsp);
3109 return 0;
3110 }
3111
3112 if (!conn->peer_issuer) {
3113 wpa_printf(MSG_DEBUG, "OpenSSL: Peer issuer certificate not available for OCSP status check");
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003114 OCSP_BASICRESP_free(basic);
3115 OCSP_RESPONSE_free(rsp);
3116 return 0;
3117 }
3118
3119 id = OCSP_cert_to_id(NULL, conn->peer_cert, conn->peer_issuer);
3120 if (!id) {
3121 wpa_printf(MSG_DEBUG, "OpenSSL: Could not create OCSP certificate identifier");
3122 OCSP_BASICRESP_free(basic);
3123 OCSP_RESPONSE_free(rsp);
3124 return 0;
3125 }
3126
3127 if (!OCSP_resp_find_status(basic, id, &status, &reason, &produced_at,
3128 &this_update, &next_update)) {
3129 wpa_printf(MSG_INFO, "OpenSSL: Could not find current server certificate from OCSP response%s",
3130 (conn->flags & TLS_CONN_REQUIRE_OCSP) ? "" :
3131 " (OCSP not required)");
3132 OCSP_BASICRESP_free(basic);
3133 OCSP_RESPONSE_free(rsp);
3134 return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1;
3135 }
3136
3137 if (!OCSP_check_validity(this_update, next_update, 5 * 60, -1)) {
3138 tls_show_errors(MSG_INFO, __func__,
3139 "OpenSSL: OCSP status times invalid");
3140 OCSP_BASICRESP_free(basic);
3141 OCSP_RESPONSE_free(rsp);
3142 return 0;
3143 }
3144
3145 OCSP_BASICRESP_free(basic);
3146 OCSP_RESPONSE_free(rsp);
3147
3148 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status for server certificate: %s",
3149 OCSP_cert_status_str(status));
3150
3151 if (status == V_OCSP_CERTSTATUS_GOOD)
3152 return 1;
3153 if (status == V_OCSP_CERTSTATUS_REVOKED)
3154 return 0;
3155 if (conn->flags & TLS_CONN_REQUIRE_OCSP) {
3156 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required");
3157 return 0;
3158 }
Dmitry Shmidt051af732013-10-22 13:52:46 -07003159 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP was not required, so allow connection to continue");
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003160 return 1;
3161}
3162
3163
3164static int ocsp_status_cb(SSL *s, void *arg)
3165{
3166 char *tmp;
3167 char *resp;
3168 size_t len;
3169
3170 if (tls_global->ocsp_stapling_response == NULL) {
3171 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - no response configured");
3172 return SSL_TLSEXT_ERR_OK;
3173 }
3174
3175 resp = os_readfile(tls_global->ocsp_stapling_response, &len);
3176 if (resp == NULL) {
3177 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - could not read response file");
3178 /* TODO: Build OCSPResponse with responseStatus = internalError
3179 */
3180 return SSL_TLSEXT_ERR_OK;
3181 }
3182 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - send cached response");
3183 tmp = OPENSSL_malloc(len);
3184 if (tmp == NULL) {
3185 os_free(resp);
3186 return SSL_TLSEXT_ERR_ALERT_FATAL;
3187 }
3188
3189 os_memcpy(tmp, resp, len);
3190 os_free(resp);
3191 SSL_set_tlsext_status_ocsp_resp(s, tmp, len);
3192
3193 return SSL_TLSEXT_ERR_OK;
3194}
3195
3196#endif /* HAVE_OCSP */
3197
3198
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003199int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
3200 const struct tls_connection_params *params)
3201{
3202 int ret;
3203 unsigned long err;
3204
3205 if (conn == NULL)
3206 return -1;
3207
3208 while ((err = ERR_get_error())) {
3209 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
3210 __func__, ERR_error_string(err, NULL));
3211 }
3212
3213 if (params->engine) {
3214 wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine");
3215 ret = tls_engine_init(conn, params->engine_id, params->pin,
3216 params->key_id, params->cert_id,
3217 params->ca_cert_id);
3218 if (ret)
3219 return ret;
3220 }
3221 if (tls_connection_set_subject_match(conn,
3222 params->subject_match,
Dmitry Shmidt051af732013-10-22 13:52:46 -07003223 params->altsubject_match,
3224 params->suffix_match))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003225 return -1;
3226
3227 if (params->engine && params->ca_cert_id) {
3228 if (tls_connection_engine_ca_cert(tls_ctx, conn,
3229 params->ca_cert_id))
3230 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
3231 } else if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert,
3232 params->ca_cert_blob,
3233 params->ca_cert_blob_len,
3234 params->ca_path))
3235 return -1;
3236
3237 if (params->engine && params->cert_id) {
3238 if (tls_connection_engine_client_cert(conn, params->cert_id))
3239 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
3240 } else if (tls_connection_client_cert(conn, params->client_cert,
3241 params->client_cert_blob,
3242 params->client_cert_blob_len))
3243 return -1;
3244
3245 if (params->engine && params->key_id) {
3246 wpa_printf(MSG_DEBUG, "TLS: Using private key from engine");
3247 if (tls_connection_engine_private_key(conn))
3248 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
3249 } else if (tls_connection_private_key(tls_ctx, conn,
3250 params->private_key,
3251 params->private_key_passwd,
3252 params->private_key_blob,
3253 params->private_key_blob_len)) {
3254 wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'",
3255 params->private_key);
3256 return -1;
3257 }
3258
3259 if (tls_connection_dh(conn, params->dh_file)) {
3260 wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
3261 params->dh_file);
3262 return -1;
3263 }
3264
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003265#ifdef SSL_OP_NO_TICKET
3266 if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET)
3267 SSL_set_options(conn->ssl, SSL_OP_NO_TICKET);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003268#ifdef SSL_clear_options
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003269 else
3270 SSL_clear_options(conn->ssl, SSL_OP_NO_TICKET);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003271#endif /* SSL_clear_options */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003272#endif /* SSL_OP_NO_TICKET */
3273
Dmitry Shmidt13ca8d82014-02-20 10:18:40 -08003274#ifdef SSL_OP_NO_TLSv1_1
3275 if (params->flags & TLS_CONN_DISABLE_TLSv1_1)
3276 SSL_set_options(conn->ssl, SSL_OP_NO_TLSv1_1);
3277 else
3278 SSL_clear_options(conn->ssl, SSL_OP_NO_TLSv1_1);
3279#endif /* SSL_OP_NO_TLSv1_1 */
3280#ifdef SSL_OP_NO_TLSv1_2
3281 if (params->flags & TLS_CONN_DISABLE_TLSv1_2)
3282 SSL_set_options(conn->ssl, SSL_OP_NO_TLSv1_2);
3283 else
3284 SSL_clear_options(conn->ssl, SSL_OP_NO_TLSv1_2);
3285#endif /* SSL_OP_NO_TLSv1_2 */
3286
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003287#ifdef HAVE_OCSP
3288 if (params->flags & TLS_CONN_REQUEST_OCSP) {
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08003289 SSL_CTX *ssl_ctx = tls_ctx;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003290 SSL_set_tlsext_status_type(conn->ssl, TLSEXT_STATUSTYPE_ocsp);
3291 SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb);
3292 SSL_CTX_set_tlsext_status_arg(ssl_ctx, conn);
3293 }
3294#endif /* HAVE_OCSP */
3295
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07003296 conn->flags = params->flags;
3297
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003298 tls_get_errors(tls_ctx);
3299
3300 return 0;
3301}
3302
3303
3304int tls_global_set_params(void *tls_ctx,
3305 const struct tls_connection_params *params)
3306{
3307 SSL_CTX *ssl_ctx = tls_ctx;
3308 unsigned long err;
3309
3310 while ((err = ERR_get_error())) {
3311 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
3312 __func__, ERR_error_string(err, NULL));
3313 }
3314
3315 if (tls_global_ca_cert(ssl_ctx, params->ca_cert))
3316 return -1;
3317
3318 if (tls_global_client_cert(ssl_ctx, params->client_cert))
3319 return -1;
3320
3321 if (tls_global_private_key(ssl_ctx, params->private_key,
3322 params->private_key_passwd))
3323 return -1;
3324
3325 if (tls_global_dh(ssl_ctx, params->dh_file)) {
3326 wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
3327 params->dh_file);
3328 return -1;
3329 }
3330
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003331#ifdef SSL_OP_NO_TICKET
3332 if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET)
3333 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003334#ifdef SSL_CTX_clear_options
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003335 else
3336 SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TICKET);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003337#endif /* SSL_clear_options */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003338#endif /* SSL_OP_NO_TICKET */
3339
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003340#ifdef HAVE_OCSP
3341 SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_status_cb);
3342 SSL_CTX_set_tlsext_status_arg(ssl_ctx, ssl_ctx);
3343 os_free(tls_global->ocsp_stapling_response);
3344 if (params->ocsp_stapling_response)
3345 tls_global->ocsp_stapling_response =
3346 os_strdup(params->ocsp_stapling_response);
3347 else
3348 tls_global->ocsp_stapling_response = NULL;
3349#endif /* HAVE_OCSP */
3350
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003351 return 0;
3352}
3353
3354
3355int tls_connection_get_keyblock_size(void *tls_ctx,
3356 struct tls_connection *conn)
3357{
3358 const EVP_CIPHER *c;
3359 const EVP_MD *h;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003360 int md_size;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003361
3362 if (conn == NULL || conn->ssl == NULL ||
3363 conn->ssl->enc_read_ctx == NULL ||
3364 conn->ssl->enc_read_ctx->cipher == NULL ||
3365 conn->ssl->read_hash == NULL)
3366 return -1;
3367
3368 c = conn->ssl->enc_read_ctx->cipher;
3369#if OPENSSL_VERSION_NUMBER >= 0x00909000L
3370 h = EVP_MD_CTX_md(conn->ssl->read_hash);
3371#else
3372 h = conn->ssl->read_hash;
3373#endif
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003374 if (h)
3375 md_size = EVP_MD_size(h);
3376#if OPENSSL_VERSION_NUMBER >= 0x10000000L
3377 else if (conn->ssl->s3)
3378 md_size = conn->ssl->s3->tmp.new_mac_secret_size;
3379#endif
3380 else
3381 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003382
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003383 wpa_printf(MSG_DEBUG, "OpenSSL: keyblock size: key_len=%d MD_size=%d "
3384 "IV_len=%d", EVP_CIPHER_key_length(c), md_size,
3385 EVP_CIPHER_iv_length(c));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003386 return 2 * (EVP_CIPHER_key_length(c) +
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003387 md_size +
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003388 EVP_CIPHER_iv_length(c));
3389}
3390
3391
3392unsigned int tls_capabilities(void *tls_ctx)
3393{
3394 return 0;
3395}
3396
3397
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003398#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
3399/* Pre-shared secred requires a patch to openssl, so this function is
3400 * commented out unless explicitly needed for EAP-FAST in order to be able to
3401 * build this file with unmodified openssl. */
3402
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07003403#ifdef OPENSSL_IS_BORINGSSL
3404static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
3405 STACK_OF(SSL_CIPHER) *peer_ciphers,
3406 const SSL_CIPHER **cipher, void *arg)
3407#else /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003408static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
3409 STACK_OF(SSL_CIPHER) *peer_ciphers,
3410 SSL_CIPHER **cipher, void *arg)
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07003411#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003412{
3413 struct tls_connection *conn = arg;
3414 int ret;
3415
3416 if (conn == NULL || conn->session_ticket_cb == NULL)
3417 return 0;
3418
3419 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
3420 conn->session_ticket,
3421 conn->session_ticket_len,
3422 s->s3->client_random,
3423 s->s3->server_random, secret);
3424 os_free(conn->session_ticket);
3425 conn->session_ticket = NULL;
3426
3427 if (ret <= 0)
3428 return 0;
3429
3430 *secret_len = SSL_MAX_MASTER_KEY_LENGTH;
3431 return 1;
3432}
3433
3434
3435#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
3436static int tls_session_ticket_ext_cb(SSL *s, const unsigned char *data,
3437 int len, void *arg)
3438{
3439 struct tls_connection *conn = arg;
3440
3441 if (conn == NULL || conn->session_ticket_cb == NULL)
3442 return 0;
3443
3444 wpa_printf(MSG_DEBUG, "OpenSSL: %s: length=%d", __func__, len);
3445
3446 os_free(conn->session_ticket);
3447 conn->session_ticket = NULL;
3448
3449 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
3450 "extension", data, len);
3451
3452 conn->session_ticket = os_malloc(len);
3453 if (conn->session_ticket == NULL)
3454 return 0;
3455
3456 os_memcpy(conn->session_ticket, data, len);
3457 conn->session_ticket_len = len;
3458
3459 return 1;
3460}
3461#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
3462#ifdef SSL_OP_NO_TICKET
3463static void tls_hello_ext_cb(SSL *s, int client_server, int type,
3464 unsigned char *data, int len, void *arg)
3465{
3466 struct tls_connection *conn = arg;
3467
3468 if (conn == NULL || conn->session_ticket_cb == NULL)
3469 return;
3470
3471 wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__,
3472 type, len);
3473
3474 if (type == TLSEXT_TYPE_session_ticket && !client_server) {
3475 os_free(conn->session_ticket);
3476 conn->session_ticket = NULL;
3477
3478 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
3479 "extension", data, len);
3480 conn->session_ticket = os_malloc(len);
3481 if (conn->session_ticket == NULL)
3482 return;
3483
3484 os_memcpy(conn->session_ticket, data, len);
3485 conn->session_ticket_len = len;
3486 }
3487}
3488#else /* SSL_OP_NO_TICKET */
3489static int tls_hello_ext_cb(SSL *s, TLS_EXTENSION *ext, void *arg)
3490{
3491 struct tls_connection *conn = arg;
3492
3493 if (conn == NULL || conn->session_ticket_cb == NULL)
3494 return 0;
3495
3496 wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__,
3497 ext->type, ext->length);
3498
3499 os_free(conn->session_ticket);
3500 conn->session_ticket = NULL;
3501
3502 if (ext->type == 35) {
3503 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
3504 "extension", ext->data, ext->length);
3505 conn->session_ticket = os_malloc(ext->length);
3506 if (conn->session_ticket == NULL)
3507 return SSL_AD_INTERNAL_ERROR;
3508
3509 os_memcpy(conn->session_ticket, ext->data, ext->length);
3510 conn->session_ticket_len = ext->length;
3511 }
3512
3513 return 0;
3514}
3515#endif /* SSL_OP_NO_TICKET */
3516#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
3517#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
3518
3519
3520int tls_connection_set_session_ticket_cb(void *tls_ctx,
3521 struct tls_connection *conn,
3522 tls_session_ticket_cb cb,
3523 void *ctx)
3524{
3525#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
3526 conn->session_ticket_cb = cb;
3527 conn->session_ticket_cb_ctx = ctx;
3528
3529 if (cb) {
3530 if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
3531 conn) != 1)
3532 return -1;
3533#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
3534 SSL_set_session_ticket_ext_cb(conn->ssl,
3535 tls_session_ticket_ext_cb, conn);
3536#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
3537#ifdef SSL_OP_NO_TICKET
3538 SSL_set_tlsext_debug_callback(conn->ssl, tls_hello_ext_cb);
3539 SSL_set_tlsext_debug_arg(conn->ssl, conn);
3540#else /* SSL_OP_NO_TICKET */
3541 if (SSL_set_hello_extension_cb(conn->ssl, tls_hello_ext_cb,
3542 conn) != 1)
3543 return -1;
3544#endif /* SSL_OP_NO_TICKET */
3545#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
3546 } else {
3547 if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
3548 return -1;
3549#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
3550 SSL_set_session_ticket_ext_cb(conn->ssl, NULL, NULL);
3551#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
3552#ifdef SSL_OP_NO_TICKET
3553 SSL_set_tlsext_debug_callback(conn->ssl, NULL);
3554 SSL_set_tlsext_debug_arg(conn->ssl, conn);
3555#else /* SSL_OP_NO_TICKET */
3556 if (SSL_set_hello_extension_cb(conn->ssl, NULL, NULL) != 1)
3557 return -1;
3558#endif /* SSL_OP_NO_TICKET */
3559#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
3560 }
3561
3562 return 0;
3563#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
3564 return -1;
3565#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
3566}