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