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