LCOV - code coverage report
Current view: top level - src/crypto - tls_openssl.c (source / functions) Hit Total Coverage
Test: wpa_supplicant hwsim test run 1388943092 Lines: 475 1180 40.3 %
Date: 2014-01-05 Functions: 41 68 60.3 %
Branches: 234 699 33.5 %

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

Generated by: LCOV version 1.9