LCOV - code coverage report
Current view: top level - crypto - tls_openssl.c (source / functions) Hit Total Coverage
Test: hostapd hwsim test run 1412854115 Lines: 382 1224 31.2 %
Date: 2014-10-09 Functions: 36 70 51.4 %

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

Generated by: LCOV version 1.10