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 1393793999 Lines: 806 1179 68.4 %
Date: 2014-03-02 Functions: 60 68 88.2 %
Branches: 396 693 57.1 %

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

Generated by: LCOV version 1.9