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