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 1443382998 Lines: 1126 1460 77.1 %
Date: 2015-09-27 Functions: 72 78 92.3 %

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

Generated by: LCOV version 1.10