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