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