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 1426431149 Lines: 941 1319 71.3 %
Date: 2015-03-15 Functions: 64 71 90.1 %

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

Generated by: LCOV version 1.10