LCOV - code coverage report
Current view: top level - src/crypto - tls_openssl.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1422976643 Lines: 939 1315 71.4 %
Date: 2015-02-03 Functions: 64 71 90.1 %

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

Generated by: LCOV version 1.10