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