tls_openssl.c
Go to the documentation of this file.
00001 /*
00002  * SSL/TLS interface functions for OpenSSL
00003  * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #ifndef CONFIG_SMARTCARD
00018 #ifndef OPENSSL_NO_ENGINE
00019 #define OPENSSL_NO_ENGINE
00020 #endif
00021 #endif
00022 
00023 #include <openssl/ssl.h>
00024 #include <openssl/err.h>
00025 #include <openssl/pkcs12.h>
00026 #include <openssl/x509v3.h>
00027 #ifndef OPENSSL_NO_ENGINE
00028 #include <openssl/engine.h>
00029 #endif /* OPENSSL_NO_ENGINE */
00030 
00031 #include "common.h"
00032 #include "crypto.h"
00033 #include "tls.h"
00034 
00035 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
00036 #define OPENSSL_d2i_TYPE const unsigned char **
00037 #else
00038 #define OPENSSL_d2i_TYPE unsigned char **
00039 #endif
00040 
00041 #ifdef SSL_F_SSL_SET_SESSION_TICKET_EXT
00042 #ifdef SSL_OP_NO_TICKET
00043 /*
00044  * Session ticket override patch was merged into OpenSSL 0.9.9 tree on
00045  * 2008-11-15. This version uses a bit different API compared to the old patch.
00046  */
00047 #define CONFIG_OPENSSL_TICKET_OVERRIDE
00048 #endif
00049 #endif
00050 
00051 static int tls_openssl_ref_count = 0;
00052 
00053 struct tls_global {
00054         void (*event_cb)(void *ctx, enum tls_event ev,
00055                          union tls_event_data *data);
00056         void *cb_ctx;
00057 };
00058 
00059 static struct tls_global *tls_global = NULL;
00060 
00061 
00062 struct tls_connection {
00063         SSL *ssl;
00064         BIO *ssl_in, *ssl_out;
00065 #ifndef OPENSSL_NO_ENGINE
00066         ENGINE *engine;        /* functional reference to the engine */
00067         EVP_PKEY *private_key; /* the private key if using engine */
00068 #endif /* OPENSSL_NO_ENGINE */
00069         char *subject_match, *altsubject_match;
00070         int read_alerts, write_alerts, failed;
00071 
00072         tls_session_ticket_cb session_ticket_cb;
00073         void *session_ticket_cb_ctx;
00074 
00075         /* SessionTicket received from OpenSSL hello_extension_cb (server) */
00076         u8 *session_ticket;
00077         size_t session_ticket_len;
00078 
00079         unsigned int ca_cert_verify:1;
00080         unsigned int cert_probe:1;
00081         unsigned int server_cert_only:1;
00082 
00083         u8 srv_cert_hash[32];
00084 };
00085 
00086 
00087 #ifdef CONFIG_NO_STDOUT_DEBUG
00088 
00089 static void _tls_show_errors(void)
00090 {
00091         unsigned long err;
00092 
00093         while ((err = ERR_get_error())) {
00094                 /* Just ignore the errors, since stdout is disabled */
00095         }
00096 }
00097 #define tls_show_errors(l, f, t) _tls_show_errors()
00098 
00099 #else /* CONFIG_NO_STDOUT_DEBUG */
00100 
00101 static void tls_show_errors(int level, const char *func, const char *txt)
00102 {
00103         unsigned long err;
00104 
00105         wpa_printf(level, "OpenSSL: %s - %s %s",
00106                    func, txt, ERR_error_string(ERR_get_error(), NULL));
00107 
00108         while ((err = ERR_get_error())) {
00109                 wpa_printf(MSG_INFO, "OpenSSL: pending error: %s",
00110                            ERR_error_string(err, NULL));
00111         }
00112 }
00113 
00114 #endif /* CONFIG_NO_STDOUT_DEBUG */
00115 
00116 
00117 #ifdef CONFIG_NATIVE_WINDOWS
00118 
00119 /* Windows CryptoAPI and access to certificate stores */
00120 #include <wincrypt.h>
00121 
00122 #ifdef __MINGW32_VERSION
00123 /*
00124  * MinGW does not yet include all the needed definitions for CryptoAPI, so
00125  * define here whatever extra is needed.
00126  */
00127 #define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16)
00128 #define CERT_STORE_READONLY_FLAG 0x00008000
00129 #define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
00130 
00131 #endif /* __MINGW32_VERSION */
00132 
00133 
00134 struct cryptoapi_rsa_data {
00135         const CERT_CONTEXT *cert;
00136         HCRYPTPROV crypt_prov;
00137         DWORD key_spec;
00138         BOOL free_crypt_prov;
00139 };
00140 
00141 
00142 static void cryptoapi_error(const char *msg)
00143 {
00144         wpa_printf(MSG_INFO, "CryptoAPI: %s; err=%u",
00145                    msg, (unsigned int) GetLastError());
00146 }
00147 
00148 
00149 static int cryptoapi_rsa_pub_enc(int flen, const unsigned char *from,
00150                                  unsigned char *to, RSA *rsa, int padding)
00151 {
00152         wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
00153         return 0;
00154 }
00155 
00156 
00157 static int cryptoapi_rsa_pub_dec(int flen, const unsigned char *from,
00158                                  unsigned char *to, RSA *rsa, int padding)
00159 {
00160         wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
00161         return 0;
00162 }
00163 
00164 
00165 static int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from,
00166                                   unsigned char *to, RSA *rsa, int padding)
00167 {
00168         struct cryptoapi_rsa_data *priv =
00169                 (struct cryptoapi_rsa_data *) rsa->meth->app_data;
00170         HCRYPTHASH hash;
00171         DWORD hash_size, len, i;
00172         unsigned char *buf = NULL;
00173         int ret = 0;
00174 
00175         if (priv == NULL) {
00176                 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
00177                        ERR_R_PASSED_NULL_PARAMETER);
00178                 return 0;
00179         }
00180 
00181         if (padding != RSA_PKCS1_PADDING) {
00182                 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
00183                        RSA_R_UNKNOWN_PADDING_TYPE);
00184                 return 0;
00185         }
00186 
00187         if (flen != 16 /* MD5 */ + 20 /* SHA-1 */) {
00188                 wpa_printf(MSG_INFO, "%s - only MD5-SHA1 hash supported",
00189                            __func__);
00190                 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
00191                        RSA_R_INVALID_MESSAGE_LENGTH);
00192                 return 0;
00193         }
00194 
00195         if (!CryptCreateHash(priv->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash))
00196         {
00197                 cryptoapi_error("CryptCreateHash failed");
00198                 return 0;
00199         }
00200 
00201         len = sizeof(hash_size);
00202         if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len,
00203                                0)) {
00204                 cryptoapi_error("CryptGetHashParam failed");
00205                 goto err;
00206         }
00207 
00208         if ((int) hash_size != flen) {
00209                 wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)",
00210                            (unsigned) hash_size, flen);
00211                 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
00212                        RSA_R_INVALID_MESSAGE_LENGTH);
00213                 goto err;
00214         }
00215         if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) {
00216                 cryptoapi_error("CryptSetHashParam failed");
00217                 goto err;
00218         }
00219 
00220         len = RSA_size(rsa);
00221         buf = os_malloc(len);
00222         if (buf == NULL) {
00223                 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
00224                 goto err;
00225         }
00226 
00227         if (!CryptSignHash(hash, priv->key_spec, NULL, 0, buf, &len)) {
00228                 cryptoapi_error("CryptSignHash failed");
00229                 goto err;
00230         }
00231 
00232         for (i = 0; i < len; i++)
00233                 to[i] = buf[len - i - 1];
00234         ret = len;
00235 
00236 err:
00237         os_free(buf);
00238         CryptDestroyHash(hash);
00239 
00240         return ret;
00241 }
00242 
00243 
00244 static int cryptoapi_rsa_priv_dec(int flen, const unsigned char *from,
00245                                   unsigned char *to, RSA *rsa, int padding)
00246 {
00247         wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
00248         return 0;
00249 }
00250 
00251 
00252 static void cryptoapi_free_data(struct cryptoapi_rsa_data *priv)
00253 {
00254         if (priv == NULL)
00255                 return;
00256         if (priv->crypt_prov && priv->free_crypt_prov)
00257                 CryptReleaseContext(priv->crypt_prov, 0);
00258         if (priv->cert)
00259                 CertFreeCertificateContext(priv->cert);
00260         os_free(priv);
00261 }
00262 
00263 
00264 static int cryptoapi_finish(RSA *rsa)
00265 {
00266         cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data);
00267         os_free((void *) rsa->meth);
00268         rsa->meth = NULL;
00269         return 1;
00270 }
00271 
00272 
00273 static const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store)
00274 {
00275         HCERTSTORE cs;
00276         const CERT_CONTEXT *ret = NULL;
00277 
00278         cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0,
00279                            store | CERT_STORE_OPEN_EXISTING_FLAG |
00280                            CERT_STORE_READONLY_FLAG, L"MY");
00281         if (cs == NULL) {
00282                 cryptoapi_error("Failed to open 'My system store'");
00283                 return NULL;
00284         }
00285 
00286         if (strncmp(name, "cert://", 7) == 0) {
00287                 unsigned short wbuf[255];
00288                 MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255);
00289                 ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING |
00290                                                  PKCS_7_ASN_ENCODING,
00291                                                  0, CERT_FIND_SUBJECT_STR,
00292                                                  wbuf, NULL);
00293         } else if (strncmp(name, "hash://", 7) == 0) {
00294                 CRYPT_HASH_BLOB blob;
00295                 int len;
00296                 const char *hash = name + 7;
00297                 unsigned char *buf;
00298 
00299                 len = os_strlen(hash) / 2;
00300                 buf = os_malloc(len);
00301                 if (buf && hexstr2bin(hash, buf, len) == 0) {
00302                         blob.cbData = len;
00303                         blob.pbData = buf;
00304                         ret = CertFindCertificateInStore(cs,
00305                                                          X509_ASN_ENCODING |
00306                                                          PKCS_7_ASN_ENCODING,
00307                                                          0, CERT_FIND_HASH,
00308                                                          &blob, NULL);
00309                 }
00310                 os_free(buf);
00311         }
00312 
00313         CertCloseStore(cs, 0);
00314 
00315         return ret;
00316 }
00317 
00318 
00319 static int tls_cryptoapi_cert(SSL *ssl, const char *name)
00320 {
00321         X509 *cert = NULL;
00322         RSA *rsa = NULL, *pub_rsa;
00323         struct cryptoapi_rsa_data *priv;
00324         RSA_METHOD *rsa_meth;
00325 
00326         if (name == NULL ||
00327             (strncmp(name, "cert://", 7) != 0 &&
00328              strncmp(name, "hash://", 7) != 0))
00329                 return -1;
00330 
00331         priv = os_zalloc(sizeof(*priv));
00332         rsa_meth = os_zalloc(sizeof(*rsa_meth));
00333         if (priv == NULL || rsa_meth == NULL) {
00334                 wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory "
00335                            "for CryptoAPI RSA method");
00336                 os_free(priv);
00337                 os_free(rsa_meth);
00338                 return -1;
00339         }
00340 
00341         priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER);
00342         if (priv->cert == NULL) {
00343                 priv->cert = cryptoapi_find_cert(
00344                         name, CERT_SYSTEM_STORE_LOCAL_MACHINE);
00345         }
00346         if (priv->cert == NULL) {
00347                 wpa_printf(MSG_INFO, "CryptoAPI: Could not find certificate "
00348                            "'%s'", name);
00349                 goto err;
00350         }
00351 
00352         cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &priv->cert->pbCertEncoded,
00353                         priv->cert->cbCertEncoded);
00354         if (cert == NULL) {
00355                 wpa_printf(MSG_INFO, "CryptoAPI: Could not process X509 DER "
00356                            "encoding");
00357                 goto err;
00358         }
00359 
00360         if (!CryptAcquireCertificatePrivateKey(priv->cert,
00361                                                CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
00362                                                NULL, &priv->crypt_prov,
00363                                                &priv->key_spec,
00364                                                &priv->free_crypt_prov)) {
00365                 cryptoapi_error("Failed to acquire a private key for the "
00366                                 "certificate");
00367                 goto err;
00368         }
00369 
00370         rsa_meth->name = "Microsoft CryptoAPI RSA Method";
00371         rsa_meth->rsa_pub_enc = cryptoapi_rsa_pub_enc;
00372         rsa_meth->rsa_pub_dec = cryptoapi_rsa_pub_dec;
00373         rsa_meth->rsa_priv_enc = cryptoapi_rsa_priv_enc;
00374         rsa_meth->rsa_priv_dec = cryptoapi_rsa_priv_dec;
00375         rsa_meth->finish = cryptoapi_finish;
00376         rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
00377         rsa_meth->app_data = (char *) priv;
00378 
00379         rsa = RSA_new();
00380         if (rsa == NULL) {
00381                 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,
00382                        ERR_R_MALLOC_FAILURE);
00383                 goto err;
00384         }
00385 
00386         if (!SSL_use_certificate(ssl, cert)) {
00387                 RSA_free(rsa);
00388                 rsa = NULL;
00389                 goto err;
00390         }
00391         pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
00392         X509_free(cert);
00393         cert = NULL;
00394 
00395         rsa->n = BN_dup(pub_rsa->n);
00396         rsa->e = BN_dup(pub_rsa->e);
00397         if (!RSA_set_method(rsa, rsa_meth))
00398                 goto err;
00399 
00400         if (!SSL_use_RSAPrivateKey(ssl, rsa))
00401                 goto err;
00402         RSA_free(rsa);
00403 
00404         return 0;
00405 
00406 err:
00407         if (cert)
00408                 X509_free(cert);
00409         if (rsa)
00410                 RSA_free(rsa);
00411         else {
00412                 os_free(rsa_meth);
00413                 cryptoapi_free_data(priv);
00414         }
00415         return -1;
00416 }
00417 
00418 
00419 static int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name)
00420 {
00421         HCERTSTORE cs;
00422         PCCERT_CONTEXT ctx = NULL;
00423         X509 *cert;
00424         char buf[128];
00425         const char *store;
00426 #ifdef UNICODE
00427         WCHAR *wstore;
00428 #endif /* UNICODE */
00429 
00430         if (name == NULL || strncmp(name, "cert_store://", 13) != 0)
00431                 return -1;
00432 
00433         store = name + 13;
00434 #ifdef UNICODE
00435         wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR));
00436         if (wstore == NULL)
00437                 return -1;
00438         wsprintf(wstore, L"%S", store);
00439         cs = CertOpenSystemStore(0, wstore);
00440         os_free(wstore);
00441 #else /* UNICODE */
00442         cs = CertOpenSystemStore(0, store);
00443 #endif /* UNICODE */
00444         if (cs == NULL) {
00445                 wpa_printf(MSG_DEBUG, "%s: failed to open system cert store "
00446                            "'%s': error=%d", __func__, store,
00447                            (int) GetLastError());
00448                 return -1;
00449         }
00450 
00451         while ((ctx = CertEnumCertificatesInStore(cs, ctx))) {
00452                 cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ctx->pbCertEncoded,
00453                                 ctx->cbCertEncoded);
00454                 if (cert == NULL) {
00455                         wpa_printf(MSG_INFO, "CryptoAPI: Could not process "
00456                                    "X509 DER encoding for CA cert");
00457                         continue;
00458                 }
00459 
00460                 X509_NAME_oneline(X509_get_subject_name(cert), buf,
00461                                   sizeof(buf));
00462                 wpa_printf(MSG_DEBUG, "OpenSSL: Loaded CA certificate for "
00463                            "system certificate store: subject='%s'", buf);
00464 
00465                 if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) {
00466                         tls_show_errors(MSG_WARNING, __func__,
00467                                         "Failed to add ca_cert to OpenSSL "
00468                                         "certificate store");
00469                 }
00470 
00471                 X509_free(cert);
00472         }
00473 
00474         if (!CertCloseStore(cs, 0)) {
00475                 wpa_printf(MSG_DEBUG, "%s: failed to close system cert store "
00476                            "'%s': error=%d", __func__, name + 13,
00477                            (int) GetLastError());
00478         }
00479 
00480         return 0;
00481 }
00482 
00483 
00484 #else /* CONFIG_NATIVE_WINDOWS */
00485 
00486 static int tls_cryptoapi_cert(SSL *ssl, const char *name)
00487 {
00488         return -1;
00489 }
00490 
00491 #endif /* CONFIG_NATIVE_WINDOWS */
00492 
00493 
00494 static void ssl_info_cb(const SSL *ssl, int where, int ret)
00495 {
00496         const char *str;
00497         int w;
00498 
00499         wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret);
00500         w = where & ~SSL_ST_MASK;
00501         if (w & SSL_ST_CONNECT)
00502                 str = "SSL_connect";
00503         else if (w & SSL_ST_ACCEPT)
00504                 str = "SSL_accept";
00505         else
00506                 str = "undefined";
00507 
00508         if (where & SSL_CB_LOOP) {
00509                 wpa_printf(MSG_DEBUG, "SSL: %s:%s",
00510                            str, SSL_state_string_long(ssl));
00511         } else if (where & SSL_CB_ALERT) {
00512                 wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s",
00513                            where & SSL_CB_READ ?
00514                            "read (remote end reported an error)" :
00515                            "write (local SSL3 detected an error)",
00516                            SSL_alert_type_string_long(ret),
00517                            SSL_alert_desc_string_long(ret));
00518                 if ((ret >> 8) == SSL3_AL_FATAL) {
00519                         struct tls_connection *conn =
00520                                 SSL_get_app_data((SSL *) ssl);
00521                         if (where & SSL_CB_READ)
00522                                 conn->read_alerts++;
00523                         else
00524                                 conn->write_alerts++;
00525                 }
00526         } else if (where & SSL_CB_EXIT && ret <= 0) {
00527                 wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s",
00528                            str, ret == 0 ? "failed" : "error",
00529                            SSL_state_string_long(ssl));
00530         }
00531 }
00532 
00533 
00534 #ifndef OPENSSL_NO_ENGINE
00535 
00547 static int tls_engine_load_dynamic_generic(const char *pre[],
00548                                            const char *post[], const char *id)
00549 {
00550         ENGINE *engine;
00551         const char *dynamic_id = "dynamic";
00552 
00553         engine = ENGINE_by_id(id);
00554         if (engine) {
00555                 ENGINE_free(engine);
00556                 wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already "
00557                            "available", id);
00558                 return 0;
00559         }
00560         ERR_clear_error();
00561 
00562         engine = ENGINE_by_id(dynamic_id);
00563         if (engine == NULL) {
00564                 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
00565                            dynamic_id,
00566                            ERR_error_string(ERR_get_error(), NULL));
00567                 return -1;
00568         }
00569 
00570         /* Perform the pre commands. This will load the engine. */
00571         while (pre && pre[0]) {
00572                 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]);
00573                 if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) {
00574                         wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: "
00575                                    "%s %s [%s]", pre[0], pre[1],
00576                                    ERR_error_string(ERR_get_error(), NULL));
00577                         ENGINE_free(engine);
00578                         return -1;
00579                 }
00580                 pre += 2;
00581         }
00582 
00583         /*
00584          * Free the reference to the "dynamic" engine. The loaded engine can
00585          * now be looked up using ENGINE_by_id().
00586          */
00587         ENGINE_free(engine);
00588 
00589         engine = ENGINE_by_id(id);
00590         if (engine == NULL) {
00591                 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
00592                            id, ERR_error_string(ERR_get_error(), NULL));
00593                 return -1;
00594         }
00595 
00596         while (post && post[0]) {
00597                 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]);
00598                 if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) {
00599                         wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:"
00600                                 " %s %s [%s]", post[0], post[1],
00601                                    ERR_error_string(ERR_get_error(), NULL));
00602                         ENGINE_remove(engine);
00603                         ENGINE_free(engine);
00604                         return -1;
00605                 }
00606                 post += 2;
00607         }
00608         ENGINE_free(engine);
00609 
00610         return 0;
00611 }
00612 
00613 
00619 static int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path,
00620                                           const char *pkcs11_module_path)
00621 {
00622         char *engine_id = "pkcs11";
00623         const char *pre_cmd[] = {
00624                 "SO_PATH", NULL /* pkcs11_so_path */,
00625                 "ID", NULL /* engine_id */,
00626                 "LIST_ADD", "1",
00627                 /* "NO_VCHECK", "1", */
00628                 "LOAD", NULL,
00629                 NULL, NULL
00630         };
00631         const char *post_cmd[] = {
00632                 "MODULE_PATH", NULL /* pkcs11_module_path */,
00633                 NULL, NULL
00634         };
00635 
00636         if (!pkcs11_so_path || !pkcs11_module_path)
00637                 return 0;
00638 
00639         pre_cmd[1] = pkcs11_so_path;
00640         pre_cmd[3] = engine_id;
00641         post_cmd[1] = pkcs11_module_path;
00642 
00643         wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s",
00644                    pkcs11_so_path);
00645 
00646         return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id);
00647 }
00648 
00649 
00654 static int tls_engine_load_dynamic_opensc(const char *opensc_so_path)
00655 {
00656         char *engine_id = "opensc";
00657         const char *pre_cmd[] = {
00658                 "SO_PATH", NULL /* opensc_so_path */,
00659                 "ID", NULL /* engine_id */,
00660                 "LIST_ADD", "1",
00661                 "LOAD", NULL,
00662                 NULL, NULL
00663         };
00664 
00665         if (!opensc_so_path)
00666                 return 0;
00667 
00668         pre_cmd[1] = opensc_so_path;
00669         pre_cmd[3] = engine_id;
00670 
00671         wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s",
00672                    opensc_so_path);
00673 
00674         return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id);
00675 }
00676 #endif /* OPENSSL_NO_ENGINE */
00677 
00678 
00679 void * tls_init(const struct tls_config *conf)
00680 {
00681         SSL_CTX *ssl;
00682 
00683         if (tls_openssl_ref_count == 0) {
00684                 tls_global = os_zalloc(sizeof(*tls_global));
00685                 if (tls_global == NULL)
00686                         return NULL;
00687                 if (conf) {
00688                         tls_global->event_cb = conf->event_cb;
00689                         tls_global->cb_ctx = conf->cb_ctx;
00690                 }
00691 
00692 #ifdef CONFIG_FIPS
00693 #ifdef OPENSSL_FIPS
00694                 if (conf && conf->fips_mode) {
00695                         if (!FIPS_mode_set(1)) {
00696                                 wpa_printf(MSG_ERROR, "Failed to enable FIPS "
00697                                            "mode");
00698                                 ERR_load_crypto_strings();
00699                                 ERR_print_errors_fp(stderr);
00700                                 return NULL;
00701                         } else
00702                                 wpa_printf(MSG_INFO, "Running in FIPS mode");
00703                 }
00704 #else /* OPENSSL_FIPS */
00705                 if (conf && conf->fips_mode) {
00706                         wpa_printf(MSG_ERROR, "FIPS mode requested, but not "
00707                                    "supported");
00708                         return NULL;
00709                 }
00710 #endif /* OPENSSL_FIPS */
00711 #endif /* CONFIG_FIPS */
00712                 SSL_load_error_strings();
00713                 SSL_library_init();
00714 #ifndef OPENSSL_NO_SHA256
00715                 EVP_add_digest(EVP_sha256());
00716 #endif /* OPENSSL_NO_SHA256 */
00717                 /* TODO: if /dev/urandom is available, PRNG is seeded
00718                  * automatically. If this is not the case, random data should
00719                  * be added here. */
00720 
00721 #ifdef PKCS12_FUNCS
00722 #ifndef OPENSSL_NO_RC2
00723                 /*
00724                  * 40-bit RC2 is commonly used in PKCS#12 files, so enable it.
00725                  * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8
00726                  * versions, but it looks like OpenSSL 1.0.0 does not do that
00727                  * anymore.
00728                  */
00729                 EVP_add_cipher(EVP_rc2_40_cbc());
00730 #endif /* OPENSSL_NO_RC2 */
00731                 PKCS12_PBE_add();
00732 #endif  /* PKCS12_FUNCS */
00733         }
00734         tls_openssl_ref_count++;
00735 
00736         ssl = SSL_CTX_new(TLSv1_method());
00737         if (ssl == NULL)
00738                 return NULL;
00739 
00740         SSL_CTX_set_info_callback(ssl, ssl_info_cb);
00741 
00742 #ifndef OPENSSL_NO_ENGINE
00743         if (conf &&
00744             (conf->opensc_engine_path || conf->pkcs11_engine_path ||
00745              conf->pkcs11_module_path)) {
00746                 wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine");
00747                 ERR_load_ENGINE_strings();
00748                 ENGINE_load_dynamic();
00749 
00750                 if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) ||
00751                     tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path,
00752                                                    conf->pkcs11_module_path)) {
00753                         tls_deinit(ssl);
00754                         return NULL;
00755                 }
00756         }
00757 #endif /* OPENSSL_NO_ENGINE */
00758 
00759         return ssl;
00760 }
00761 
00762 
00763 void tls_deinit(void *ssl_ctx)
00764 {
00765         SSL_CTX *ssl = ssl_ctx;
00766         SSL_CTX_free(ssl);
00767 
00768         tls_openssl_ref_count--;
00769         if (tls_openssl_ref_count == 0) {
00770 #ifndef OPENSSL_NO_ENGINE
00771                 ENGINE_cleanup();
00772 #endif /* OPENSSL_NO_ENGINE */
00773                 CRYPTO_cleanup_all_ex_data();
00774                 ERR_remove_state(0);
00775                 ERR_free_strings();
00776                 EVP_cleanup();
00777                 os_free(tls_global);
00778                 tls_global = NULL;
00779         }
00780 }
00781 
00782 
00783 static int tls_engine_init(struct tls_connection *conn, const char *engine_id,
00784                            const char *pin, const char *key_id,
00785                            const char *cert_id, const char *ca_cert_id)
00786 {
00787 #ifndef OPENSSL_NO_ENGINE
00788         int ret = -1;
00789         if (engine_id == NULL) {
00790                 wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set");
00791                 return -1;
00792         }
00793         if (pin == NULL) {
00794                 wpa_printf(MSG_ERROR, "ENGINE: Smartcard PIN not set");
00795                 return -1;
00796         }
00797         if (key_id == NULL) {
00798                 wpa_printf(MSG_ERROR, "ENGINE: Key Id not set");
00799                 return -1;
00800         }
00801 
00802         ERR_clear_error();
00803         conn->engine = ENGINE_by_id(engine_id);
00804         if (!conn->engine) {
00805                 wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]",
00806                            engine_id, ERR_error_string(ERR_get_error(), NULL));
00807                 goto err;
00808         }
00809         if (ENGINE_init(conn->engine) != 1) {
00810                 wpa_printf(MSG_ERROR, "ENGINE: engine init failed "
00811                            "(engine: %s) [%s]", engine_id,
00812                            ERR_error_string(ERR_get_error(), NULL));
00813                 goto err;
00814         }
00815         wpa_printf(MSG_DEBUG, "ENGINE: engine initialized");
00816 
00817         if (ENGINE_ctrl_cmd_string(conn->engine, "PIN", pin, 0) == 0) {
00818                 wpa_printf(MSG_ERROR, "ENGINE: cannot set pin [%s]",
00819                            ERR_error_string(ERR_get_error(), NULL));
00820                 goto err;
00821         }
00822         /* load private key first in-case PIN is required for cert */
00823         conn->private_key = ENGINE_load_private_key(conn->engine,
00824                                                     key_id, NULL, NULL);
00825         if (!conn->private_key) {
00826                 wpa_printf(MSG_ERROR, "ENGINE: cannot load private key with id"
00827                                 " '%s' [%s]", key_id,
00828                            ERR_error_string(ERR_get_error(), NULL));
00829                 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
00830                 goto err;
00831         }
00832 
00833         /* handle a certificate and/or CA certificate */
00834         if (cert_id || ca_cert_id) {
00835                 const char *cmd_name = "LOAD_CERT_CTRL";
00836 
00837                 /* test if the engine supports a LOAD_CERT_CTRL */
00838                 if (!ENGINE_ctrl(conn->engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
00839                                  0, (void *)cmd_name, NULL)) {
00840                         wpa_printf(MSG_ERROR, "ENGINE: engine does not support"
00841                                    " loading certificates");
00842                         ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
00843                         goto err;
00844                 }
00845         }
00846 
00847         return 0;
00848 
00849 err:
00850         if (conn->engine) {
00851                 ENGINE_free(conn->engine);
00852                 conn->engine = NULL;
00853         }
00854 
00855         if (conn->private_key) {
00856                 EVP_PKEY_free(conn->private_key);
00857                 conn->private_key = NULL;
00858         }
00859 
00860         return ret;
00861 #else /* OPENSSL_NO_ENGINE */
00862         return 0;
00863 #endif /* OPENSSL_NO_ENGINE */
00864 }
00865 
00866 
00867 static void tls_engine_deinit(struct tls_connection *conn)
00868 {
00869 #ifndef OPENSSL_NO_ENGINE
00870         wpa_printf(MSG_DEBUG, "ENGINE: engine deinit");
00871         if (conn->private_key) {
00872                 EVP_PKEY_free(conn->private_key);
00873                 conn->private_key = NULL;
00874         }
00875         if (conn->engine) {
00876                 ENGINE_finish(conn->engine);
00877                 conn->engine = NULL;
00878         }
00879 #endif /* OPENSSL_NO_ENGINE */
00880 }
00881 
00882 
00883 int tls_get_errors(void *ssl_ctx)
00884 {
00885         int count = 0;
00886         unsigned long err;
00887 
00888         while ((err = ERR_get_error())) {
00889                 wpa_printf(MSG_INFO, "TLS - SSL error: %s",
00890                            ERR_error_string(err, NULL));
00891                 count++;
00892         }
00893 
00894         return count;
00895 }
00896 
00897 struct tls_connection * tls_connection_init(void *ssl_ctx)
00898 {
00899         SSL_CTX *ssl = ssl_ctx;
00900         struct tls_connection *conn;
00901         long options;
00902 
00903         conn = os_zalloc(sizeof(*conn));
00904         if (conn == NULL)
00905                 return NULL;
00906         conn->ssl = SSL_new(ssl);
00907         if (conn->ssl == NULL) {
00908                 tls_show_errors(MSG_INFO, __func__,
00909                                 "Failed to initialize new SSL connection");
00910                 os_free(conn);
00911                 return NULL;
00912         }
00913 
00914         SSL_set_app_data(conn->ssl, conn);
00915         options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
00916                 SSL_OP_SINGLE_DH_USE;
00917 #ifdef SSL_OP_NO_COMPRESSION
00918         options |= SSL_OP_NO_COMPRESSION;
00919 #endif /* SSL_OP_NO_COMPRESSION */
00920         SSL_set_options(conn->ssl, options);
00921 
00922         conn->ssl_in = BIO_new(BIO_s_mem());
00923         if (!conn->ssl_in) {
00924                 tls_show_errors(MSG_INFO, __func__,
00925                                 "Failed to create a new BIO for ssl_in");
00926                 SSL_free(conn->ssl);
00927                 os_free(conn);
00928                 return NULL;
00929         }
00930 
00931         conn->ssl_out = BIO_new(BIO_s_mem());
00932         if (!conn->ssl_out) {
00933                 tls_show_errors(MSG_INFO, __func__,
00934                                 "Failed to create a new BIO for ssl_out");
00935                 SSL_free(conn->ssl);
00936                 BIO_free(conn->ssl_in);
00937                 os_free(conn);
00938                 return NULL;
00939         }
00940 
00941         SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out);
00942 
00943         return conn;
00944 }
00945 
00946 
00947 void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
00948 {
00949         if (conn == NULL)
00950                 return;
00951         SSL_free(conn->ssl);
00952         tls_engine_deinit(conn);
00953         os_free(conn->subject_match);
00954         os_free(conn->altsubject_match);
00955         os_free(conn->session_ticket);
00956         os_free(conn);
00957 }
00958 
00959 
00960 int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
00961 {
00962         return conn ? SSL_is_init_finished(conn->ssl) : 0;
00963 }
00964 
00965 
00966 int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
00967 {
00968         if (conn == NULL)
00969                 return -1;
00970 
00971         /* Shutdown previous TLS connection without notifying the peer
00972          * because the connection was already terminated in practice
00973          * and "close notify" shutdown alert would confuse AS. */
00974         SSL_set_quiet_shutdown(conn->ssl, 1);
00975         SSL_shutdown(conn->ssl);
00976         return 0;
00977 }
00978 
00979 
00980 static int tls_match_altsubject_component(X509 *cert, int type,
00981                                           const char *value, size_t len)
00982 {
00983         GENERAL_NAME *gen;
00984         void *ext;
00985         int i, found = 0;
00986 
00987         ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
00988 
00989         for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
00990                 gen = sk_GENERAL_NAME_value(ext, i);
00991                 if (gen->type != type)
00992                         continue;
00993                 if (os_strlen((char *) gen->d.ia5->data) == len &&
00994                     os_memcmp(value, gen->d.ia5->data, len) == 0)
00995                         found++;
00996         }
00997 
00998         return found;
00999 }
01000 
01001 
01002 static int tls_match_altsubject(X509 *cert, const char *match)
01003 {
01004         int type;
01005         const char *pos, *end;
01006         size_t len;
01007 
01008         pos = match;
01009         do {
01010                 if (os_strncmp(pos, "EMAIL:", 6) == 0) {
01011                         type = GEN_EMAIL;
01012                         pos += 6;
01013                 } else if (os_strncmp(pos, "DNS:", 4) == 0) {
01014                         type = GEN_DNS;
01015                         pos += 4;
01016                 } else if (os_strncmp(pos, "URI:", 4) == 0) {
01017                         type = GEN_URI;
01018                         pos += 4;
01019                 } else {
01020                         wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName "
01021                                    "match '%s'", pos);
01022                         return 0;
01023                 }
01024                 end = os_strchr(pos, ';');
01025                 while (end) {
01026                         if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
01027                             os_strncmp(end + 1, "DNS:", 4) == 0 ||
01028                             os_strncmp(end + 1, "URI:", 4) == 0)
01029                                 break;
01030                         end = os_strchr(end + 1, ';');
01031                 }
01032                 if (end)
01033                         len = end - pos;
01034                 else
01035                         len = os_strlen(pos);
01036                 if (tls_match_altsubject_component(cert, type, pos, len) > 0)
01037                         return 1;
01038                 pos = end + 1;
01039         } while (end);
01040 
01041         return 0;
01042 }
01043 
01044 
01045 static enum tls_fail_reason openssl_tls_fail_reason(int err)
01046 {
01047         switch (err) {
01048         case X509_V_ERR_CERT_REVOKED:
01049                 return TLS_FAIL_REVOKED;
01050         case X509_V_ERR_CERT_NOT_YET_VALID:
01051         case X509_V_ERR_CRL_NOT_YET_VALID:
01052                 return TLS_FAIL_NOT_YET_VALID;
01053         case X509_V_ERR_CERT_HAS_EXPIRED:
01054         case X509_V_ERR_CRL_HAS_EXPIRED:
01055                 return TLS_FAIL_EXPIRED;
01056         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
01057         case X509_V_ERR_UNABLE_TO_GET_CRL:
01058         case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
01059         case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
01060         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
01061         case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
01062         case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
01063         case X509_V_ERR_CERT_CHAIN_TOO_LONG:
01064         case X509_V_ERR_PATH_LENGTH_EXCEEDED:
01065         case X509_V_ERR_INVALID_CA:
01066                 return TLS_FAIL_UNTRUSTED;
01067         case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
01068         case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
01069         case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
01070         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
01071         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
01072         case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
01073         case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
01074         case X509_V_ERR_CERT_UNTRUSTED:
01075         case X509_V_ERR_CERT_REJECTED:
01076                 return TLS_FAIL_BAD_CERTIFICATE;
01077         default:
01078                 return TLS_FAIL_UNSPECIFIED;
01079         }
01080 }
01081 
01082 
01083 static struct wpabuf * get_x509_cert(X509 *cert)
01084 {
01085         struct wpabuf *buf;
01086         u8 *tmp;
01087 
01088         int cert_len = i2d_X509(cert, NULL);
01089         if (cert_len <= 0)
01090                 return NULL;
01091 
01092         buf = wpabuf_alloc(cert_len);
01093         if (buf == NULL)
01094                 return NULL;
01095 
01096         tmp = wpabuf_put(buf, cert_len);
01097         i2d_X509(cert, &tmp);
01098         return buf;
01099 }
01100 
01101 
01102 static void openssl_tls_fail_event(struct tls_connection *conn,
01103                                    X509 *err_cert, int err, int depth,
01104                                    const char *subject, const char *err_str,
01105                                    enum tls_fail_reason reason)
01106 {
01107         union tls_event_data ev;
01108         struct wpabuf *cert = NULL;
01109 
01110         if (tls_global->event_cb == NULL)
01111                 return;
01112 
01113         cert = get_x509_cert(err_cert);
01114         os_memset(&ev, 0, sizeof(ev));
01115         ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ?
01116                 reason : openssl_tls_fail_reason(err);
01117         ev.cert_fail.depth = depth;
01118         ev.cert_fail.subject = subject;
01119         ev.cert_fail.reason_txt = err_str;
01120         ev.cert_fail.cert = cert;
01121         tls_global->event_cb(tls_global->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
01122         wpabuf_free(cert);
01123 }
01124 
01125 
01126 static void openssl_tls_cert_event(struct tls_connection *conn,
01127                                    X509 *err_cert, int depth,
01128                                    const char *subject)
01129 {
01130         struct wpabuf *cert = NULL;
01131         union tls_event_data ev;
01132 #ifdef CONFIG_SHA256
01133         u8 hash[32];
01134 #endif /* CONFIG_SHA256 */
01135 
01136         if (tls_global->event_cb == NULL)
01137                 return;
01138 
01139         os_memset(&ev, 0, sizeof(ev));
01140         if (conn->cert_probe) {
01141                 cert = get_x509_cert(err_cert);
01142                 ev.peer_cert.cert = cert;
01143         }
01144 #ifdef CONFIG_SHA256
01145         if (cert) {
01146                 const u8 *addr[1];
01147                 size_t len[1];
01148                 addr[0] = wpabuf_head(cert);
01149                 len[0] = wpabuf_len(cert);
01150                 if (sha256_vector(1, addr, len, hash) == 0) {
01151                         ev.peer_cert.hash = hash;
01152                         ev.peer_cert.hash_len = sizeof(hash);
01153                 }
01154         }
01155 #endif /* CONFIG_SHA256 */
01156         ev.peer_cert.depth = depth;
01157         ev.peer_cert.subject = subject;
01158         tls_global->event_cb(tls_global->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
01159         wpabuf_free(cert);
01160 }
01161 
01162 
01163 static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
01164 {
01165         char buf[256];
01166         X509 *err_cert;
01167         int err, depth;
01168         SSL *ssl;
01169         struct tls_connection *conn;
01170         char *match, *altmatch;
01171         const char *err_str;
01172 
01173         err_cert = X509_STORE_CTX_get_current_cert(x509_ctx);
01174         err = X509_STORE_CTX_get_error(x509_ctx);
01175         depth = X509_STORE_CTX_get_error_depth(x509_ctx);
01176         ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
01177                                          SSL_get_ex_data_X509_STORE_CTX_idx());
01178         X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
01179 
01180         conn = SSL_get_app_data(ssl);
01181         match = conn ? conn->subject_match : NULL;
01182         altmatch = conn ? conn->altsubject_match : NULL;
01183 
01184         if (!preverify_ok && !conn->ca_cert_verify)
01185                 preverify_ok = 1;
01186         if (!preverify_ok && depth > 0 && conn->server_cert_only)
01187                 preverify_ok = 1;
01188 
01189         err_str = X509_verify_cert_error_string(err);
01190 
01191 #ifdef CONFIG_SHA256
01192         if (preverify_ok && depth == 0 && conn->server_cert_only) {
01193                 struct wpabuf *cert;
01194                 cert = get_x509_cert(err_cert);
01195                 if (!cert) {
01196                         wpa_printf(MSG_DEBUG, "OpenSSL: Could not fetch "
01197                                    "server certificate data");
01198                         preverify_ok = 0;
01199                 } else {
01200                         u8 hash[32];
01201                         const u8 *addr[1];
01202                         size_t len[1];
01203                         addr[0] = wpabuf_head(cert);
01204                         len[0] = wpabuf_len(cert);
01205                         if (sha256_vector(1, addr, len, hash) < 0 ||
01206                             os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
01207                                 err_str = "Server certificate mismatch";
01208                                 err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
01209                                 preverify_ok = 0;
01210                         }
01211                         wpabuf_free(cert);
01212                 }
01213         }
01214 #endif /* CONFIG_SHA256 */
01215 
01216         if (!preverify_ok) {
01217                 wpa_printf(MSG_WARNING, "TLS: Certificate verification failed,"
01218                            " error %d (%s) depth %d for '%s'", err, err_str,
01219                            depth, buf);
01220                 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
01221                                        err_str, TLS_FAIL_UNSPECIFIED);
01222                 return preverify_ok;
01223         }
01224 
01225         wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d "
01226                    "err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
01227                    preverify_ok, err, err_str,
01228                    conn->ca_cert_verify, depth, buf);
01229         if (depth == 0 && match && os_strstr(buf, match) == NULL) {
01230                 wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not "
01231                            "match with '%s'", buf, match);
01232                 preverify_ok = 0;
01233                 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
01234                                        "Subject mismatch",
01235                                        TLS_FAIL_SUBJECT_MISMATCH);
01236         } else if (depth == 0 && altmatch &&
01237                    !tls_match_altsubject(err_cert, altmatch)) {
01238                 wpa_printf(MSG_WARNING, "TLS: altSubjectName match "
01239                            "'%s' not found", altmatch);
01240                 preverify_ok = 0;
01241                 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
01242                                        "AltSubject mismatch",
01243                                        TLS_FAIL_ALTSUBJECT_MISMATCH);
01244         } else
01245                 openssl_tls_cert_event(conn, err_cert, depth, buf);
01246 
01247         if (conn->cert_probe && preverify_ok && depth == 0) {
01248                 wpa_printf(MSG_DEBUG, "OpenSSL: Reject server certificate "
01249                            "on probe-only run");
01250                 preverify_ok = 0;
01251                 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
01252                                        "Server certificate chain probe",
01253                                        TLS_FAIL_SERVER_CHAIN_PROBE);
01254         }
01255 
01256         return preverify_ok;
01257 }
01258 
01259 
01260 #ifndef OPENSSL_NO_STDIO
01261 static int tls_load_ca_der(void *_ssl_ctx, const char *ca_cert)
01262 {
01263         SSL_CTX *ssl_ctx = _ssl_ctx;
01264         X509_LOOKUP *lookup;
01265         int ret = 0;
01266 
01267         lookup = X509_STORE_add_lookup(ssl_ctx->cert_store,
01268                                        X509_LOOKUP_file());
01269         if (lookup == NULL) {
01270                 tls_show_errors(MSG_WARNING, __func__,
01271                                 "Failed add lookup for X509 store");
01272                 return -1;
01273         }
01274 
01275         if (!X509_LOOKUP_load_file(lookup, ca_cert, X509_FILETYPE_ASN1)) {
01276                 unsigned long err = ERR_peek_error();
01277                 tls_show_errors(MSG_WARNING, __func__,
01278                                 "Failed load CA in DER format");
01279                 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
01280                     ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
01281                         wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
01282                                    "cert already in hash table error",
01283                                    __func__);
01284                 } else
01285                         ret = -1;
01286         }
01287 
01288         return ret;
01289 }
01290 #endif /* OPENSSL_NO_STDIO */
01291 
01292 
01293 static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn,
01294                                   const char *ca_cert, const u8 *ca_cert_blob,
01295                                   size_t ca_cert_blob_len, const char *ca_path)
01296 {
01297         SSL_CTX *ssl_ctx = _ssl_ctx;
01298 
01299         /*
01300          * Remove previously configured trusted CA certificates before adding
01301          * new ones.
01302          */
01303         X509_STORE_free(ssl_ctx->cert_store);
01304         ssl_ctx->cert_store = X509_STORE_new();
01305         if (ssl_ctx->cert_store == NULL) {
01306                 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
01307                            "certificate store", __func__);
01308                 return -1;
01309         }
01310 
01311         SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
01312         conn->ca_cert_verify = 1;
01313 
01314         if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) {
01315                 wpa_printf(MSG_DEBUG, "OpenSSL: Probe for server certificate "
01316                            "chain");
01317                 conn->cert_probe = 1;
01318                 conn->ca_cert_verify = 0;
01319                 return 0;
01320         }
01321 
01322         if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) {
01323 #ifdef CONFIG_SHA256
01324                 const char *pos = ca_cert + 7;
01325                 if (os_strncmp(pos, "server/sha256/", 14) != 0) {
01326                         wpa_printf(MSG_DEBUG, "OpenSSL: Unsupported ca_cert "
01327                                    "hash value '%s'", ca_cert);
01328                         return -1;
01329                 }
01330                 pos += 14;
01331                 if (os_strlen(pos) != 32 * 2) {
01332                         wpa_printf(MSG_DEBUG, "OpenSSL: Unexpected SHA256 "
01333                                    "hash length in ca_cert '%s'", ca_cert);
01334                         return -1;
01335                 }
01336                 if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) {
01337                         wpa_printf(MSG_DEBUG, "OpenSSL: Invalid SHA256 hash "
01338                                    "value in ca_cert '%s'", ca_cert);
01339                         return -1;
01340                 }
01341                 conn->server_cert_only = 1;
01342                 wpa_printf(MSG_DEBUG, "OpenSSL: Checking only server "
01343                            "certificate match");
01344                 return 0;
01345 #else /* CONFIG_SHA256 */
01346                 wpa_printf(MSG_INFO, "No SHA256 included in the build - "
01347                            "cannot validate server certificate hash");
01348                 return -1;
01349 #endif /* CONFIG_SHA256 */
01350         }
01351 
01352         if (ca_cert_blob) {
01353                 X509 *cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ca_cert_blob,
01354                                       ca_cert_blob_len);
01355                 if (cert == NULL) {
01356                         tls_show_errors(MSG_WARNING, __func__,
01357                                         "Failed to parse ca_cert_blob");
01358                         return -1;
01359                 }
01360 
01361                 if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) {
01362                         unsigned long err = ERR_peek_error();
01363                         tls_show_errors(MSG_WARNING, __func__,
01364                                         "Failed to add ca_cert_blob to "
01365                                         "certificate store");
01366                         if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
01367                             ERR_GET_REASON(err) ==
01368                             X509_R_CERT_ALREADY_IN_HASH_TABLE) {
01369                                 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
01370                                            "cert already in hash table error",
01371                                            __func__);
01372                         } else {
01373                                 X509_free(cert);
01374                                 return -1;
01375                         }
01376                 }
01377                 X509_free(cert);
01378                 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob "
01379                            "to certificate store", __func__);
01380                 return 0;
01381         }
01382 
01383 #ifdef CONFIG_NATIVE_WINDOWS
01384         if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) ==
01385             0) {
01386                 wpa_printf(MSG_DEBUG, "OpenSSL: Added CA certificates from "
01387                            "system certificate store");
01388                 return 0;
01389         }
01390 #endif /* CONFIG_NATIVE_WINDOWS */
01391 
01392         if (ca_cert || ca_path) {
01393 #ifndef OPENSSL_NO_STDIO
01394                 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, ca_path) !=
01395                     1) {
01396                         tls_show_errors(MSG_WARNING, __func__,
01397                                         "Failed to load root certificates");
01398                         if (ca_cert &&
01399                             tls_load_ca_der(ssl_ctx, ca_cert) == 0) {
01400                                 wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded "
01401                                            "DER format CA certificate",
01402                                            __func__);
01403                         } else
01404                                 return -1;
01405                 } else {
01406                         wpa_printf(MSG_DEBUG, "TLS: Trusted root "
01407                                    "certificate(s) loaded");
01408                         tls_get_errors(ssl_ctx);
01409                 }
01410 #else /* OPENSSL_NO_STDIO */
01411                 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
01412                            __func__);
01413                 return -1;
01414 #endif /* OPENSSL_NO_STDIO */
01415         } else {
01416                 /* No ca_cert configured - do not try to verify server
01417                  * certificate */
01418                 conn->ca_cert_verify = 0;
01419         }
01420 
01421         return 0;
01422 }
01423 
01424 
01425 static int tls_global_ca_cert(SSL_CTX *ssl_ctx, const char *ca_cert)
01426 {
01427         if (ca_cert) {
01428                 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
01429                 {
01430                         tls_show_errors(MSG_WARNING, __func__,
01431                                         "Failed to load root certificates");
01432                         return -1;
01433                 }
01434 
01435                 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
01436                            "certificate(s) loaded");
01437 
01438 #ifndef OPENSSL_NO_STDIO
01439                 /* Add the same CAs to the client certificate requests */
01440                 SSL_CTX_set_client_CA_list(ssl_ctx,
01441                                            SSL_load_client_CA_file(ca_cert));
01442 #endif /* OPENSSL_NO_STDIO */
01443         }
01444 
01445         return 0;
01446 }
01447 
01448 
01449 int tls_global_set_verify(void *ssl_ctx, int check_crl)
01450 {
01451         int flags;
01452 
01453         if (check_crl) {
01454                 X509_STORE *cs = SSL_CTX_get_cert_store(ssl_ctx);
01455                 if (cs == NULL) {
01456                         tls_show_errors(MSG_INFO, __func__, "Failed to get "
01457                                         "certificate store when enabling "
01458                                         "check_crl");
01459                         return -1;
01460                 }
01461                 flags = X509_V_FLAG_CRL_CHECK;
01462                 if (check_crl == 2)
01463                         flags |= X509_V_FLAG_CRL_CHECK_ALL;
01464                 X509_STORE_set_flags(cs, flags);
01465         }
01466         return 0;
01467 }
01468 
01469 
01470 static int tls_connection_set_subject_match(struct tls_connection *conn,
01471                                             const char *subject_match,
01472                                             const char *altsubject_match)
01473 {
01474         os_free(conn->subject_match);
01475         conn->subject_match = NULL;
01476         if (subject_match) {
01477                 conn->subject_match = os_strdup(subject_match);
01478                 if (conn->subject_match == NULL)
01479                         return -1;
01480         }
01481 
01482         os_free(conn->altsubject_match);
01483         conn->altsubject_match = NULL;
01484         if (altsubject_match) {
01485                 conn->altsubject_match = os_strdup(altsubject_match);
01486                 if (conn->altsubject_match == NULL)
01487                         return -1;
01488         }
01489 
01490         return 0;
01491 }
01492 
01493 
01494 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
01495                               int verify_peer)
01496 {
01497         static int counter = 0;
01498 
01499         if (conn == NULL)
01500                 return -1;
01501 
01502         if (verify_peer) {
01503                 conn->ca_cert_verify = 1;
01504                 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
01505                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
01506                                SSL_VERIFY_CLIENT_ONCE, tls_verify_cb);
01507         } else {
01508                 conn->ca_cert_verify = 0;
01509                 SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
01510         }
01511 
01512         SSL_set_accept_state(conn->ssl);
01513 
01514         /*
01515          * Set session id context in order to avoid fatal errors when client
01516          * tries to resume a session. However, set the context to a unique
01517          * value in order to effectively disable session resumption for now
01518          * since not all areas of the server code are ready for it (e.g.,
01519          * EAP-TTLS needs special handling for Phase 2 after abbreviated TLS
01520          * handshake).
01521          */
01522         counter++;
01523         SSL_set_session_id_context(conn->ssl,
01524                                    (const unsigned char *) &counter,
01525                                    sizeof(counter));
01526 
01527         return 0;
01528 }
01529 
01530 
01531 static int tls_connection_client_cert(struct tls_connection *conn,
01532                                       const char *client_cert,
01533                                       const u8 *client_cert_blob,
01534                                       size_t client_cert_blob_len)
01535 {
01536         if (client_cert == NULL && client_cert_blob == NULL)
01537                 return 0;
01538 
01539         if (client_cert_blob &&
01540             SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob,
01541                                      client_cert_blob_len) == 1) {
01542                 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> "
01543                            "OK");
01544                 return 0;
01545         } else if (client_cert_blob) {
01546                 tls_show_errors(MSG_DEBUG, __func__,
01547                                 "SSL_use_certificate_ASN1 failed");
01548         }
01549 
01550         if (client_cert == NULL)
01551                 return -1;
01552 
01553 #ifndef OPENSSL_NO_STDIO
01554         if (SSL_use_certificate_file(conn->ssl, client_cert,
01555                                      SSL_FILETYPE_ASN1) == 1) {
01556                 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)"
01557                            " --> OK");
01558                 return 0;
01559         } else {
01560                 tls_show_errors(MSG_DEBUG, __func__,
01561                                 "SSL_use_certificate_file (DER) failed");
01562         }
01563 
01564         if (SSL_use_certificate_file(conn->ssl, client_cert,
01565                                      SSL_FILETYPE_PEM) == 1) {
01566                 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)"
01567                            " --> OK");
01568                 return 0;
01569         } else {
01570                 tls_show_errors(MSG_DEBUG, __func__,
01571                                 "SSL_use_certificate_file (PEM) failed");
01572         }
01573 #else /* OPENSSL_NO_STDIO */
01574         wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
01575 #endif /* OPENSSL_NO_STDIO */
01576 
01577         return -1;
01578 }
01579 
01580 
01581 static int tls_global_client_cert(SSL_CTX *ssl_ctx, const char *client_cert)
01582 {
01583 #ifndef OPENSSL_NO_STDIO
01584         if (client_cert == NULL)
01585                 return 0;
01586 
01587         if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
01588                                          SSL_FILETYPE_ASN1) != 1 &&
01589             SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
01590                                          SSL_FILETYPE_PEM) != 1) {
01591                 tls_show_errors(MSG_INFO, __func__,
01592                                 "Failed to load client certificate");
01593                 return -1;
01594         }
01595         return 0;
01596 #else /* OPENSSL_NO_STDIO */
01597         if (client_cert == NULL)
01598                 return 0;
01599         wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
01600         return -1;
01601 #endif /* OPENSSL_NO_STDIO */
01602 }
01603 
01604 
01605 static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
01606 {
01607         if (password == NULL) {
01608                 return 0;
01609         }
01610         os_strlcpy(buf, (char *) password, size);
01611         return os_strlen(buf);
01612 }
01613 
01614 
01615 #ifdef PKCS12_FUNCS
01616 static int tls_parse_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, PKCS12 *p12,
01617                             const char *passwd)
01618 {
01619         EVP_PKEY *pkey;
01620         X509 *cert;
01621         STACK_OF(X509) *certs;
01622         int res = 0;
01623         char buf[256];
01624 
01625         pkey = NULL;
01626         cert = NULL;
01627         certs = NULL;
01628         if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) {
01629                 tls_show_errors(MSG_DEBUG, __func__,
01630                                 "Failed to parse PKCS12 file");
01631                 PKCS12_free(p12);
01632                 return -1;
01633         }
01634         wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data");
01635 
01636         if (cert) {
01637                 X509_NAME_oneline(X509_get_subject_name(cert), buf,
01638                                   sizeof(buf));
01639                 wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: "
01640                            "subject='%s'", buf);
01641                 if (ssl) {
01642                         if (SSL_use_certificate(ssl, cert) != 1)
01643                                 res = -1;
01644                 } else {
01645                         if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1)
01646                                 res = -1;
01647                 }
01648                 X509_free(cert);
01649         }
01650 
01651         if (pkey) {
01652                 wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12");
01653                 if (ssl) {
01654                         if (SSL_use_PrivateKey(ssl, pkey) != 1)
01655                                 res = -1;
01656                 } else {
01657                         if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1)
01658                                 res = -1;
01659                 }
01660                 EVP_PKEY_free(pkey);
01661         }
01662 
01663         if (certs) {
01664                 while ((cert = sk_X509_pop(certs)) != NULL) {
01665                         X509_NAME_oneline(X509_get_subject_name(cert), buf,
01666                                           sizeof(buf));
01667                         wpa_printf(MSG_DEBUG, "TLS: additional certificate"
01668                                    " from PKCS12: subject='%s'", buf);
01669                         /*
01670                          * There is no SSL equivalent for the chain cert - so
01671                          * always add it to the context...
01672                          */
01673                         if (SSL_CTX_add_extra_chain_cert(ssl_ctx, cert) != 1) {
01674                                 res = -1;
01675                                 break;
01676                         }
01677                 }
01678                 sk_X509_free(certs);
01679         }
01680 
01681         PKCS12_free(p12);
01682 
01683         if (res < 0)
01684                 tls_get_errors(ssl_ctx);
01685 
01686         return res;
01687 }
01688 #endif  /* PKCS12_FUNCS */
01689 
01690 
01691 static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key,
01692                            const char *passwd)
01693 {
01694 #ifdef PKCS12_FUNCS
01695         FILE *f;
01696         PKCS12 *p12;
01697 
01698         f = fopen(private_key, "rb");
01699         if (f == NULL)
01700                 return -1;
01701 
01702         p12 = d2i_PKCS12_fp(f, NULL);
01703         fclose(f);
01704 
01705         if (p12 == NULL) {
01706                 tls_show_errors(MSG_INFO, __func__,
01707                                 "Failed to use PKCS#12 file");
01708                 return -1;
01709         }
01710 
01711         return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd);
01712 
01713 #else /* PKCS12_FUNCS */
01714         wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read "
01715                    "p12/pfx files");
01716         return -1;
01717 #endif  /* PKCS12_FUNCS */
01718 }
01719 
01720 
01721 static int tls_read_pkcs12_blob(SSL_CTX *ssl_ctx, SSL *ssl,
01722                                 const u8 *blob, size_t len, const char *passwd)
01723 {
01724 #ifdef PKCS12_FUNCS
01725         PKCS12 *p12;
01726 
01727         p12 = d2i_PKCS12(NULL, (OPENSSL_d2i_TYPE) &blob, len);
01728         if (p12 == NULL) {
01729                 tls_show_errors(MSG_INFO, __func__,
01730                                 "Failed to use PKCS#12 blob");
01731                 return -1;
01732         }
01733 
01734         return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd);
01735 
01736 #else /* PKCS12_FUNCS */
01737         wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse "
01738                    "p12/pfx blobs");
01739         return -1;
01740 #endif  /* PKCS12_FUNCS */
01741 }
01742 
01743 
01744 #ifndef OPENSSL_NO_ENGINE
01745 static int tls_engine_get_cert(struct tls_connection *conn,
01746                                const char *cert_id,
01747                                X509 **cert)
01748 {
01749         /* this runs after the private key is loaded so no PIN is required */
01750         struct {
01751                 const char *cert_id;
01752                 X509 *cert;
01753         } params;
01754         params.cert_id = cert_id;
01755         params.cert = NULL;
01756 
01757         if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL",
01758                              0, &params, NULL, 1)) {
01759                 wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id"
01760                            " '%s' [%s]", cert_id,
01761                            ERR_error_string(ERR_get_error(), NULL));
01762                 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
01763         }
01764         if (!params.cert) {
01765                 wpa_printf(MSG_ERROR, "ENGINE: did not properly cert with id"
01766                            " '%s'", cert_id);
01767                 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
01768         }
01769         *cert = params.cert;
01770         return 0;
01771 }
01772 #endif /* OPENSSL_NO_ENGINE */
01773 
01774 
01775 static int tls_connection_engine_client_cert(struct tls_connection *conn,
01776                                              const char *cert_id)
01777 {
01778 #ifndef OPENSSL_NO_ENGINE
01779         X509 *cert;
01780 
01781         if (tls_engine_get_cert(conn, cert_id, &cert))
01782                 return -1;
01783 
01784         if (!SSL_use_certificate(conn->ssl, cert)) {
01785                 tls_show_errors(MSG_ERROR, __func__,
01786                                 "SSL_use_certificate failed");
01787                 X509_free(cert);
01788                 return -1;
01789         }
01790         X509_free(cert);
01791         wpa_printf(MSG_DEBUG, "ENGINE: SSL_use_certificate --> "
01792                    "OK");
01793         return 0;
01794 
01795 #else /* OPENSSL_NO_ENGINE */
01796         return -1;
01797 #endif /* OPENSSL_NO_ENGINE */
01798 }
01799 
01800 
01801 static int tls_connection_engine_ca_cert(void *_ssl_ctx,
01802                                          struct tls_connection *conn,
01803                                          const char *ca_cert_id)
01804 {
01805 #ifndef OPENSSL_NO_ENGINE
01806         X509 *cert;
01807         SSL_CTX *ssl_ctx = _ssl_ctx;
01808 
01809         if (tls_engine_get_cert(conn, ca_cert_id, &cert))
01810                 return -1;
01811 
01812         /* start off the same as tls_connection_ca_cert */
01813         X509_STORE_free(ssl_ctx->cert_store);
01814         ssl_ctx->cert_store = X509_STORE_new();
01815         if (ssl_ctx->cert_store == NULL) {
01816                 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
01817                            "certificate store", __func__);
01818                 X509_free(cert);
01819                 return -1;
01820         }
01821         if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) {
01822                 unsigned long err = ERR_peek_error();
01823                 tls_show_errors(MSG_WARNING, __func__,
01824                                 "Failed to add CA certificate from engine "
01825                                 "to certificate store");
01826                 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
01827                     ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
01828                         wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring cert"
01829                                    " already in hash table error",
01830                                    __func__);
01831                 } else {
01832                         X509_free(cert);
01833                         return -1;
01834                 }
01835         }
01836         X509_free(cert);
01837         wpa_printf(MSG_DEBUG, "OpenSSL: %s - added CA certificate from engine "
01838                    "to certificate store", __func__);
01839         SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
01840         return 0;
01841 
01842 #else /* OPENSSL_NO_ENGINE */
01843         return -1;
01844 #endif /* OPENSSL_NO_ENGINE */
01845 }
01846 
01847 
01848 static int tls_connection_engine_private_key(struct tls_connection *conn)
01849 {
01850 #ifndef OPENSSL_NO_ENGINE
01851         if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) {
01852                 tls_show_errors(MSG_ERROR, __func__,
01853                                 "ENGINE: cannot use private key for TLS");
01854                 return -1;
01855         }
01856         if (!SSL_check_private_key(conn->ssl)) {
01857                 tls_show_errors(MSG_INFO, __func__,
01858                                 "Private key failed verification");
01859                 return -1;
01860         }
01861         return 0;
01862 #else /* OPENSSL_NO_ENGINE */
01863         wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but "
01864                    "engine support was not compiled in");
01865         return -1;
01866 #endif /* OPENSSL_NO_ENGINE */
01867 }
01868 
01869 
01870 static int tls_connection_private_key(void *_ssl_ctx,
01871                                       struct tls_connection *conn,
01872                                       const char *private_key,
01873                                       const char *private_key_passwd,
01874                                       const u8 *private_key_blob,
01875                                       size_t private_key_blob_len)
01876 {
01877         SSL_CTX *ssl_ctx = _ssl_ctx;
01878         char *passwd;
01879         int ok;
01880 
01881         if (private_key == NULL && private_key_blob == NULL)
01882                 return 0;
01883 
01884         if (private_key_passwd) {
01885                 passwd = os_strdup(private_key_passwd);
01886                 if (passwd == NULL)
01887                         return -1;
01888         } else
01889                 passwd = NULL;
01890 
01891         SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
01892         SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
01893 
01894         ok = 0;
01895         while (private_key_blob) {
01896                 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl,
01897                                             (u8 *) private_key_blob,
01898                                             private_key_blob_len) == 1) {
01899                         wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
01900                                    "ASN1(EVP_PKEY_RSA) --> OK");
01901                         ok = 1;
01902                         break;
01903                 } else {
01904                         tls_show_errors(MSG_DEBUG, __func__,
01905                                         "SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA)"
01906                                         " failed");
01907                 }
01908 
01909                 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl,
01910                                             (u8 *) private_key_blob,
01911                                             private_key_blob_len) == 1) {
01912                         wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
01913                                    "ASN1(EVP_PKEY_DSA) --> OK");
01914                         ok = 1;
01915                         break;
01916                 } else {
01917                         tls_show_errors(MSG_DEBUG, __func__,
01918                                         "SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA)"
01919                                         " failed");
01920                 }
01921 
01922                 if (SSL_use_RSAPrivateKey_ASN1(conn->ssl,
01923                                                (u8 *) private_key_blob,
01924                                                private_key_blob_len) == 1) {
01925                         wpa_printf(MSG_DEBUG, "OpenSSL: "
01926                                    "SSL_use_RSAPrivateKey_ASN1 --> OK");
01927                         ok = 1;
01928                         break;
01929                 } else {
01930                         tls_show_errors(MSG_DEBUG, __func__,
01931                                         "SSL_use_RSAPrivateKey_ASN1 failed");
01932                 }
01933 
01934                 if (tls_read_pkcs12_blob(ssl_ctx, conn->ssl, private_key_blob,
01935                                          private_key_blob_len, passwd) == 0) {
01936                         wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> "
01937                                    "OK");
01938                         ok = 1;
01939                         break;
01940                 }
01941 
01942                 break;
01943         }
01944 
01945         while (!ok && private_key) {
01946 #ifndef OPENSSL_NO_STDIO
01947                 if (SSL_use_PrivateKey_file(conn->ssl, private_key,
01948                                             SSL_FILETYPE_ASN1) == 1) {
01949                         wpa_printf(MSG_DEBUG, "OpenSSL: "
01950                                    "SSL_use_PrivateKey_File (DER) --> OK");
01951                         ok = 1;
01952                         break;
01953                 } else {
01954                         tls_show_errors(MSG_DEBUG, __func__,
01955                                         "SSL_use_PrivateKey_File (DER) "
01956                                         "failed");
01957                 }
01958 
01959                 if (SSL_use_PrivateKey_file(conn->ssl, private_key,
01960                                             SSL_FILETYPE_PEM) == 1) {
01961                         wpa_printf(MSG_DEBUG, "OpenSSL: "
01962                                    "SSL_use_PrivateKey_File (PEM) --> OK");
01963                         ok = 1;
01964                         break;
01965                 } else {
01966                         tls_show_errors(MSG_DEBUG, __func__,
01967                                         "SSL_use_PrivateKey_File (PEM) "
01968                                         "failed");
01969                 }
01970 #else /* OPENSSL_NO_STDIO */
01971                 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
01972                            __func__);
01973 #endif /* OPENSSL_NO_STDIO */
01974 
01975                 if (tls_read_pkcs12(ssl_ctx, conn->ssl, private_key, passwd)
01976                     == 0) {
01977                         wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file "
01978                                    "--> OK");
01979                         ok = 1;
01980                         break;
01981                 }
01982 
01983                 if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) {
01984                         wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to "
01985                                    "access certificate store --> OK");
01986                         ok = 1;
01987                         break;
01988                 }
01989 
01990                 break;
01991         }
01992 
01993         if (!ok) {
01994                 wpa_printf(MSG_INFO, "OpenSSL: Failed to load private key");
01995                 os_free(passwd);
01996                 ERR_clear_error();
01997                 return -1;
01998         }
01999         ERR_clear_error();
02000         SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
02001         os_free(passwd);
02002         
02003         if (!SSL_check_private_key(conn->ssl)) {
02004                 tls_show_errors(MSG_INFO, __func__, "Private key failed "
02005                                 "verification");
02006                 return -1;
02007         }
02008 
02009         wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully");
02010         return 0;
02011 }
02012 
02013 
02014 static int tls_global_private_key(SSL_CTX *ssl_ctx, const char *private_key,
02015                                   const char *private_key_passwd)
02016 {
02017         char *passwd;
02018 
02019         if (private_key == NULL)
02020                 return 0;
02021 
02022         if (private_key_passwd) {
02023                 passwd = os_strdup(private_key_passwd);
02024                 if (passwd == NULL)
02025                         return -1;
02026         } else
02027                 passwd = NULL;
02028 
02029         SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
02030         SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
02031         if (
02032 #ifndef OPENSSL_NO_STDIO
02033             SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
02034                                         SSL_FILETYPE_ASN1) != 1 &&
02035             SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
02036                                         SSL_FILETYPE_PEM) != 1 &&
02037 #endif /* OPENSSL_NO_STDIO */
02038             tls_read_pkcs12(ssl_ctx, NULL, private_key, passwd)) {
02039                 tls_show_errors(MSG_INFO, __func__,
02040                                 "Failed to load private key");
02041                 os_free(passwd);
02042                 ERR_clear_error();
02043                 return -1;
02044         }
02045         os_free(passwd);
02046         ERR_clear_error();
02047         SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
02048         
02049         if (!SSL_CTX_check_private_key(ssl_ctx)) {
02050                 tls_show_errors(MSG_INFO, __func__,
02051                                 "Private key failed verification");
02052                 return -1;
02053         }
02054 
02055         return 0;
02056 }
02057 
02058 
02059 static int tls_connection_dh(struct tls_connection *conn, const char *dh_file)
02060 {
02061 #ifdef OPENSSL_NO_DH
02062         if (dh_file == NULL)
02063                 return 0;
02064         wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
02065                    "dh_file specified");
02066         return -1;
02067 #else /* OPENSSL_NO_DH */
02068         DH *dh;
02069         BIO *bio;
02070 
02071         /* TODO: add support for dh_blob */
02072         if (dh_file == NULL)
02073                 return 0;
02074         if (conn == NULL)
02075                 return -1;
02076 
02077         bio = BIO_new_file(dh_file, "r");
02078         if (bio == NULL) {
02079                 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
02080                            dh_file, ERR_error_string(ERR_get_error(), NULL));
02081                 return -1;
02082         }
02083         dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
02084         BIO_free(bio);
02085 #ifndef OPENSSL_NO_DSA
02086         while (dh == NULL) {
02087                 DSA *dsa;
02088                 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
02089                            " trying to parse as DSA params", dh_file,
02090                            ERR_error_string(ERR_get_error(), NULL));
02091                 bio = BIO_new_file(dh_file, "r");
02092                 if (bio == NULL)
02093                         break;
02094                 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
02095                 BIO_free(bio);
02096                 if (!dsa) {
02097                         wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
02098                                    "'%s': %s", dh_file,
02099                                    ERR_error_string(ERR_get_error(), NULL));
02100                         break;
02101                 }
02102 
02103                 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
02104                 dh = DSA_dup_DH(dsa);
02105                 DSA_free(dsa);
02106                 if (dh == NULL) {
02107                         wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
02108                                    "params into DH params");
02109                         break;
02110                 }
02111                 break;
02112         }
02113 #endif /* !OPENSSL_NO_DSA */
02114         if (dh == NULL) {
02115                 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
02116                            "'%s'", dh_file);
02117                 return -1;
02118         }
02119 
02120         if (SSL_set_tmp_dh(conn->ssl, dh) != 1) {
02121                 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
02122                            "%s", dh_file,
02123                            ERR_error_string(ERR_get_error(), NULL));
02124                 DH_free(dh);
02125                 return -1;
02126         }
02127         DH_free(dh);
02128         return 0;
02129 #endif /* OPENSSL_NO_DH */
02130 }
02131 
02132 
02133 static int tls_global_dh(SSL_CTX *ssl_ctx, const char *dh_file)
02134 {
02135 #ifdef OPENSSL_NO_DH
02136         if (dh_file == NULL)
02137                 return 0;
02138         wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
02139                    "dh_file specified");
02140         return -1;
02141 #else /* OPENSSL_NO_DH */
02142         DH *dh;
02143         BIO *bio;
02144 
02145         /* TODO: add support for dh_blob */
02146         if (dh_file == NULL)
02147                 return 0;
02148         if (ssl_ctx == NULL)
02149                 return -1;
02150 
02151         bio = BIO_new_file(dh_file, "r");
02152         if (bio == NULL) {
02153                 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
02154                            dh_file, ERR_error_string(ERR_get_error(), NULL));
02155                 return -1;
02156         }
02157         dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
02158         BIO_free(bio);
02159 #ifndef OPENSSL_NO_DSA
02160         while (dh == NULL) {
02161                 DSA *dsa;
02162                 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
02163                            " trying to parse as DSA params", dh_file,
02164                            ERR_error_string(ERR_get_error(), NULL));
02165                 bio = BIO_new_file(dh_file, "r");
02166                 if (bio == NULL)
02167                         break;
02168                 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
02169                 BIO_free(bio);
02170                 if (!dsa) {
02171                         wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
02172                                    "'%s': %s", dh_file,
02173                                    ERR_error_string(ERR_get_error(), NULL));
02174                         break;
02175                 }
02176 
02177                 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
02178                 dh = DSA_dup_DH(dsa);
02179                 DSA_free(dsa);
02180                 if (dh == NULL) {
02181                         wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
02182                                    "params into DH params");
02183                         break;
02184                 }
02185                 break;
02186         }
02187 #endif /* !OPENSSL_NO_DSA */
02188         if (dh == NULL) {
02189                 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
02190                            "'%s'", dh_file);
02191                 return -1;
02192         }
02193 
02194         if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) {
02195                 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
02196                            "%s", dh_file,
02197                            ERR_error_string(ERR_get_error(), NULL));
02198                 DH_free(dh);
02199                 return -1;
02200         }
02201         DH_free(dh);
02202         return 0;
02203 #endif /* OPENSSL_NO_DH */
02204 }
02205 
02206 
02207 int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
02208                             struct tls_keys *keys)
02209 {
02210         SSL *ssl;
02211 
02212         if (conn == NULL || keys == NULL)
02213                 return -1;
02214         ssl = conn->ssl;
02215         if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL)
02216                 return -1;
02217 
02218         os_memset(keys, 0, sizeof(*keys));
02219         keys->master_key = ssl->session->master_key;
02220         keys->master_key_len = ssl->session->master_key_length;
02221         keys->client_random = ssl->s3->client_random;
02222         keys->client_random_len = SSL3_RANDOM_SIZE;
02223         keys->server_random = ssl->s3->server_random;
02224         keys->server_random_len = SSL3_RANDOM_SIZE;
02225 
02226         return 0;
02227 }
02228 
02229 
02230 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
02231                        const char *label, int server_random_first,
02232                        u8 *out, size_t out_len)
02233 {
02234         return -1;
02235 }
02236 
02237 
02238 static struct wpabuf *
02239 openssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data,
02240                   int server)
02241 {
02242         int res;
02243         struct wpabuf *out_data;
02244 
02245         /*
02246          * Give TLS handshake data from the server (if available) to OpenSSL
02247          * for processing.
02248          */
02249         if (in_data &&
02250             BIO_write(conn->ssl_in, wpabuf_head(in_data), wpabuf_len(in_data))
02251             < 0) {
02252                 tls_show_errors(MSG_INFO, __func__,
02253                                 "Handshake failed - BIO_write");
02254                 return NULL;
02255         }
02256 
02257         /* Initiate TLS handshake or continue the existing handshake */
02258         if (server)
02259                 res = SSL_accept(conn->ssl);
02260         else
02261                 res = SSL_connect(conn->ssl);
02262         if (res != 1) {
02263                 int err = SSL_get_error(conn->ssl, res);
02264                 if (err == SSL_ERROR_WANT_READ)
02265                         wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want "
02266                                    "more data");
02267                 else if (err == SSL_ERROR_WANT_WRITE)
02268                         wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to "
02269                                    "write");
02270                 else {
02271                         tls_show_errors(MSG_INFO, __func__, "SSL_connect");
02272                         conn->failed++;
02273                 }
02274         }
02275 
02276         /* Get the TLS handshake data to be sent to the server */
02277         res = BIO_ctrl_pending(conn->ssl_out);
02278         wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
02279         out_data = wpabuf_alloc(res);
02280         if (out_data == NULL) {
02281                 wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
02282                            "handshake output (%d bytes)", res);
02283                 if (BIO_reset(conn->ssl_out) < 0) {
02284                         tls_show_errors(MSG_INFO, __func__,
02285                                         "BIO_reset failed");
02286                 }
02287                 return NULL;
02288         }
02289         res = res == 0 ? 0 : BIO_read(conn->ssl_out, wpabuf_mhead(out_data),
02290                                       res);
02291         if (res < 0) {
02292                 tls_show_errors(MSG_INFO, __func__,
02293                                 "Handshake failed - BIO_read");
02294                 if (BIO_reset(conn->ssl_out) < 0) {
02295                         tls_show_errors(MSG_INFO, __func__,
02296                                         "BIO_reset failed");
02297                 }
02298                 wpabuf_free(out_data);
02299                 return NULL;
02300         }
02301         wpabuf_put(out_data, res);
02302 
02303         return out_data;
02304 }
02305 
02306 
02307 static struct wpabuf *
02308 openssl_get_appl_data(struct tls_connection *conn, size_t max_len)
02309 {
02310         struct wpabuf *appl_data;
02311         int res;
02312 
02313         appl_data = wpabuf_alloc(max_len + 100);
02314         if (appl_data == NULL)
02315                 return NULL;
02316 
02317         res = SSL_read(conn->ssl, wpabuf_mhead(appl_data),
02318                        wpabuf_size(appl_data));
02319         if (res < 0) {
02320                 int err = SSL_get_error(conn->ssl, res);
02321                 if (err == SSL_ERROR_WANT_READ ||
02322                     err == SSL_ERROR_WANT_WRITE) {
02323                         wpa_printf(MSG_DEBUG, "SSL: No Application Data "
02324                                    "included");
02325                 } else {
02326                         tls_show_errors(MSG_INFO, __func__,
02327                                         "Failed to read possible "
02328                                         "Application Data");
02329                 }
02330                 wpabuf_free(appl_data);
02331                 return NULL;
02332         }
02333 
02334         wpabuf_put(appl_data, res);
02335         wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application Data in Finished "
02336                             "message", appl_data);
02337 
02338         return appl_data;
02339 }
02340 
02341 
02342 static struct wpabuf *
02343 openssl_connection_handshake(struct tls_connection *conn,
02344                              const struct wpabuf *in_data,
02345                              struct wpabuf **appl_data, int server)
02346 {
02347         struct wpabuf *out_data;
02348 
02349         if (appl_data)
02350                 *appl_data = NULL;
02351 
02352         out_data = openssl_handshake(conn, in_data, server);
02353         if (out_data == NULL)
02354                 return NULL;
02355 
02356         if (SSL_is_init_finished(conn->ssl) && appl_data && in_data)
02357                 *appl_data = openssl_get_appl_data(conn, wpabuf_len(in_data));
02358 
02359         return out_data;
02360 }
02361 
02362 
02363 struct wpabuf *
02364 tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
02365                          const struct wpabuf *in_data,
02366                          struct wpabuf **appl_data)
02367 {
02368         return openssl_connection_handshake(conn, in_data, appl_data, 0);
02369 }
02370 
02371 
02372 struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
02373                                                 struct tls_connection *conn,
02374                                                 const struct wpabuf *in_data,
02375                                                 struct wpabuf **appl_data)
02376 {
02377         return openssl_connection_handshake(conn, in_data, appl_data, 1);
02378 }
02379 
02380 
02381 struct wpabuf * tls_connection_encrypt(void *tls_ctx,
02382                                        struct tls_connection *conn,
02383                                        const struct wpabuf *in_data)
02384 {
02385         int res;
02386         struct wpabuf *buf;
02387 
02388         if (conn == NULL)
02389                 return NULL;
02390 
02391         /* Give plaintext data for OpenSSL to encrypt into the TLS tunnel. */
02392         if ((res = BIO_reset(conn->ssl_in)) < 0 ||
02393             (res = BIO_reset(conn->ssl_out)) < 0) {
02394                 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
02395                 return NULL;
02396         }
02397         res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data));
02398         if (res < 0) {
02399                 tls_show_errors(MSG_INFO, __func__,
02400                                 "Encryption failed - SSL_write");
02401                 return NULL;
02402         }
02403 
02404         /* Read encrypted data to be sent to the server */
02405         buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
02406         if (buf == NULL)
02407                 return NULL;
02408         res = BIO_read(conn->ssl_out, wpabuf_mhead(buf), wpabuf_size(buf));
02409         if (res < 0) {
02410                 tls_show_errors(MSG_INFO, __func__,
02411                                 "Encryption failed - BIO_read");
02412                 wpabuf_free(buf);
02413                 return NULL;
02414         }
02415         wpabuf_put(buf, res);
02416 
02417         return buf;
02418 }
02419 
02420 
02421 struct wpabuf * tls_connection_decrypt(void *tls_ctx,
02422                                        struct tls_connection *conn,
02423                                        const struct wpabuf *in_data)
02424 {
02425         int res;
02426         struct wpabuf *buf;
02427 
02428         /* Give encrypted data from TLS tunnel for OpenSSL to decrypt. */
02429         res = BIO_write(conn->ssl_in, wpabuf_head(in_data),
02430                         wpabuf_len(in_data));
02431         if (res < 0) {
02432                 tls_show_errors(MSG_INFO, __func__,
02433                                 "Decryption failed - BIO_write");
02434                 return NULL;
02435         }
02436         if (BIO_reset(conn->ssl_out) < 0) {
02437                 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
02438                 return NULL;
02439         }
02440 
02441         /* Read decrypted data for further processing */
02442         /*
02443          * Even though we try to disable TLS compression, it is possible that
02444          * this cannot be done with all TLS libraries. Add extra buffer space
02445          * to handle the possibility of the decrypted data being longer than
02446          * input data.
02447          */
02448         buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
02449         if (buf == NULL)
02450                 return NULL;
02451         res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
02452         if (res < 0) {
02453                 tls_show_errors(MSG_INFO, __func__,
02454                                 "Decryption failed - SSL_read");
02455                 wpabuf_free(buf);
02456                 return NULL;
02457         }
02458         wpabuf_put(buf, res);
02459 
02460         return buf;
02461 }
02462 
02463 
02464 int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
02465 {
02466         return conn ? conn->ssl->hit : 0;
02467 }
02468 
02469 
02470 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
02471                                    u8 *ciphers)
02472 {
02473         char buf[100], *pos, *end;
02474         u8 *c;
02475         int ret;
02476 
02477         if (conn == NULL || conn->ssl == NULL || ciphers == NULL)
02478                 return -1;
02479 
02480         buf[0] = '\0';
02481         pos = buf;
02482         end = pos + sizeof(buf);
02483 
02484         c = ciphers;
02485         while (*c != TLS_CIPHER_NONE) {
02486                 const char *suite;
02487 
02488                 switch (*c) {
02489                 case TLS_CIPHER_RC4_SHA:
02490                         suite = "RC4-SHA";
02491                         break;
02492                 case TLS_CIPHER_AES128_SHA:
02493                         suite = "AES128-SHA";
02494                         break;
02495                 case TLS_CIPHER_RSA_DHE_AES128_SHA:
02496                         suite = "DHE-RSA-AES128-SHA";
02497                         break;
02498                 case TLS_CIPHER_ANON_DH_AES128_SHA:
02499                         suite = "ADH-AES128-SHA";
02500                         break;
02501                 default:
02502                         wpa_printf(MSG_DEBUG, "TLS: Unsupported "
02503                                    "cipher selection: %d", *c);
02504                         return -1;
02505                 }
02506                 ret = os_snprintf(pos, end - pos, ":%s", suite);
02507                 if (ret < 0 || ret >= end - pos)
02508                         break;
02509                 pos += ret;
02510 
02511                 c++;
02512         }
02513 
02514         wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1);
02515 
02516         if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
02517                 tls_show_errors(MSG_INFO, __func__,
02518                                 "Cipher suite configuration failed");
02519                 return -1;
02520         }
02521 
02522         return 0;
02523 }
02524 
02525 
02526 int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
02527                    char *buf, size_t buflen)
02528 {
02529         const char *name;
02530         if (conn == NULL || conn->ssl == NULL)
02531                 return -1;
02532 
02533         name = SSL_get_cipher(conn->ssl);
02534         if (name == NULL)
02535                 return -1;
02536 
02537         os_strlcpy(buf, name, buflen);
02538         return 0;
02539 }
02540 
02541 
02542 int tls_connection_enable_workaround(void *ssl_ctx,
02543                                      struct tls_connection *conn)
02544 {
02545         SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
02546 
02547         return 0;
02548 }
02549 
02550 
02551 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
02552 /* ClientHello TLS extensions require a patch to openssl, so this function is
02553  * commented out unless explicitly needed for EAP-FAST in order to be able to
02554  * build this file with unmodified openssl. */
02555 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
02556                                     int ext_type, const u8 *data,
02557                                     size_t data_len)
02558 {
02559         if (conn == NULL || conn->ssl == NULL || ext_type != 35)
02560                 return -1;
02561 
02562 #ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
02563         if (SSL_set_session_ticket_ext(conn->ssl, (void *) data,
02564                                        data_len) != 1)
02565                 return -1;
02566 #else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
02567         if (SSL_set_hello_extension(conn->ssl, ext_type, (void *) data,
02568                                     data_len) != 1)
02569                 return -1;
02570 #endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
02571 
02572         return 0;
02573 }
02574 #endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
02575 
02576 
02577 int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
02578 {
02579         if (conn == NULL)
02580                 return -1;
02581         return conn->failed;
02582 }
02583 
02584 
02585 int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
02586 {
02587         if (conn == NULL)
02588                 return -1;
02589         return conn->read_alerts;
02590 }
02591 
02592 
02593 int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
02594 {
02595         if (conn == NULL)
02596                 return -1;
02597         return conn->write_alerts;
02598 }
02599 
02600 
02601 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
02602                               const struct tls_connection_params *params)
02603 {
02604         int ret;
02605         unsigned long err;
02606 
02607         if (conn == NULL)
02608                 return -1;
02609 
02610         while ((err = ERR_get_error())) {
02611                 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
02612                            __func__, ERR_error_string(err, NULL));
02613         }
02614 
02615         if (params->engine) {
02616                 wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine");
02617                 ret = tls_engine_init(conn, params->engine_id, params->pin,
02618                                       params->key_id, params->cert_id,
02619                                       params->ca_cert_id);
02620                 if (ret)
02621                         return ret;
02622         }
02623         if (tls_connection_set_subject_match(conn,
02624                                              params->subject_match,
02625                                              params->altsubject_match))
02626                 return -1;
02627 
02628         if (params->engine && params->ca_cert_id) {
02629                 if (tls_connection_engine_ca_cert(tls_ctx, conn,
02630                                                   params->ca_cert_id))
02631                         return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
02632         } else if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert,
02633                                           params->ca_cert_blob,
02634                                           params->ca_cert_blob_len,
02635                                           params->ca_path))
02636                 return -1;
02637 
02638         if (params->engine && params->cert_id) {
02639                 if (tls_connection_engine_client_cert(conn, params->cert_id))
02640                         return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
02641         } else if (tls_connection_client_cert(conn, params->client_cert,
02642                                               params->client_cert_blob,
02643                                               params->client_cert_blob_len))
02644                 return -1;
02645 
02646         if (params->engine && params->key_id) {
02647                 wpa_printf(MSG_DEBUG, "TLS: Using private key from engine");
02648                 if (tls_connection_engine_private_key(conn))
02649                         return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
02650         } else if (tls_connection_private_key(tls_ctx, conn,
02651                                               params->private_key,
02652                                               params->private_key_passwd,
02653                                               params->private_key_blob,
02654                                               params->private_key_blob_len)) {
02655                 wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'",
02656                            params->private_key);
02657                 return -1;
02658         }
02659 
02660         if (tls_connection_dh(conn, params->dh_file)) {
02661                 wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
02662                            params->dh_file);
02663                 return -1;
02664         }
02665 
02666         tls_get_errors(tls_ctx);
02667 
02668         return 0;
02669 }
02670 
02671 
02672 int tls_global_set_params(void *tls_ctx,
02673                           const struct tls_connection_params *params)
02674 {
02675         SSL_CTX *ssl_ctx = tls_ctx;
02676         unsigned long err;
02677 
02678         while ((err = ERR_get_error())) {
02679                 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
02680                            __func__, ERR_error_string(err, NULL));
02681         }
02682 
02683         if (tls_global_ca_cert(ssl_ctx, params->ca_cert))
02684                 return -1;
02685 
02686         if (tls_global_client_cert(ssl_ctx, params->client_cert))
02687                 return -1;
02688 
02689         if (tls_global_private_key(ssl_ctx, params->private_key,
02690                                    params->private_key_passwd))
02691                 return -1;
02692 
02693         if (tls_global_dh(ssl_ctx, params->dh_file)) {
02694                 wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
02695                            params->dh_file);
02696                 return -1;
02697         }
02698 
02699         return 0;
02700 }
02701 
02702 
02703 int tls_connection_get_keyblock_size(void *tls_ctx,
02704                                      struct tls_connection *conn)
02705 {
02706         const EVP_CIPHER *c;
02707         const EVP_MD *h;
02708 
02709         if (conn == NULL || conn->ssl == NULL ||
02710             conn->ssl->enc_read_ctx == NULL ||
02711             conn->ssl->enc_read_ctx->cipher == NULL ||
02712             conn->ssl->read_hash == NULL)
02713                 return -1;
02714 
02715         c = conn->ssl->enc_read_ctx->cipher;
02716 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
02717         h = EVP_MD_CTX_md(conn->ssl->read_hash);
02718 #else
02719         h = conn->ssl->read_hash;
02720 #endif
02721 
02722         return 2 * (EVP_CIPHER_key_length(c) +
02723                     EVP_MD_size(h) +
02724                     EVP_CIPHER_iv_length(c));
02725 }
02726 
02727 
02728 unsigned int tls_capabilities(void *tls_ctx)
02729 {
02730         return 0;
02731 }
02732 
02733 
02734 int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn,
02735                           int tls_ia)
02736 {
02737         return -1;
02738 }
02739 
02740 
02741 struct wpabuf * tls_connection_ia_send_phase_finished(
02742         void *tls_ctx, struct tls_connection *conn, int final)
02743 {
02744         return NULL;
02745 }
02746 
02747 
02748 int tls_connection_ia_final_phase_finished(void *tls_ctx,
02749                                            struct tls_connection *conn)
02750 {
02751         return -1;
02752 }
02753 
02754 
02755 int tls_connection_ia_permute_inner_secret(void *tls_ctx,
02756                                            struct tls_connection *conn,
02757                                            const u8 *key, size_t key_len)
02758 {
02759         return -1;
02760 }
02761 
02762 
02763 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
02764 /* Pre-shared secred requires a patch to openssl, so this function is
02765  * commented out unless explicitly needed for EAP-FAST in order to be able to
02766  * build this file with unmodified openssl. */
02767 
02768 static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
02769                            STACK_OF(SSL_CIPHER) *peer_ciphers,
02770                            SSL_CIPHER **cipher, void *arg)
02771 {
02772         struct tls_connection *conn = arg;
02773         int ret;
02774 
02775         if (conn == NULL || conn->session_ticket_cb == NULL)
02776                 return 0;
02777 
02778         ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
02779                                       conn->session_ticket,
02780                                       conn->session_ticket_len,
02781                                       s->s3->client_random,
02782                                       s->s3->server_random, secret);
02783         os_free(conn->session_ticket);
02784         conn->session_ticket = NULL;
02785 
02786         if (ret <= 0)
02787                 return 0;
02788 
02789         *secret_len = SSL_MAX_MASTER_KEY_LENGTH;
02790         return 1;
02791 }
02792 
02793 
02794 #ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
02795 static int tls_session_ticket_ext_cb(SSL *s, const unsigned char *data,
02796                                      int len, void *arg)
02797 {
02798         struct tls_connection *conn = arg;
02799 
02800         if (conn == NULL || conn->session_ticket_cb == NULL)
02801                 return 0;
02802 
02803         wpa_printf(MSG_DEBUG, "OpenSSL: %s: length=%d", __func__, len);
02804 
02805         os_free(conn->session_ticket);
02806         conn->session_ticket = NULL;
02807 
02808         wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
02809                     "extension", data, len);
02810 
02811         conn->session_ticket = os_malloc(len);
02812         if (conn->session_ticket == NULL)
02813                 return 0;
02814 
02815         os_memcpy(conn->session_ticket, data, len);
02816         conn->session_ticket_len = len;
02817 
02818         return 1;
02819 }
02820 #else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
02821 #ifdef SSL_OP_NO_TICKET
02822 static void tls_hello_ext_cb(SSL *s, int client_server, int type,
02823                              unsigned char *data, int len, void *arg)
02824 {
02825         struct tls_connection *conn = arg;
02826 
02827         if (conn == NULL || conn->session_ticket_cb == NULL)
02828                 return;
02829 
02830         wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__,
02831                    type, len);
02832 
02833         if (type == TLSEXT_TYPE_session_ticket && !client_server) {
02834                 os_free(conn->session_ticket);
02835                 conn->session_ticket = NULL;
02836 
02837                 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
02838                             "extension", data, len);
02839                 conn->session_ticket = os_malloc(len);
02840                 if (conn->session_ticket == NULL)
02841                         return;
02842 
02843                 os_memcpy(conn->session_ticket, data, len);
02844                 conn->session_ticket_len = len;
02845         }
02846 }
02847 #else /* SSL_OP_NO_TICKET */
02848 static int tls_hello_ext_cb(SSL *s, TLS_EXTENSION *ext, void *arg)
02849 {
02850         struct tls_connection *conn = arg;
02851 
02852         if (conn == NULL || conn->session_ticket_cb == NULL)
02853                 return 0;
02854 
02855         wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__,
02856                    ext->type, ext->length);
02857 
02858         os_free(conn->session_ticket);
02859         conn->session_ticket = NULL;
02860 
02861         if (ext->type == 35) {
02862                 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
02863                             "extension", ext->data, ext->length);
02864                 conn->session_ticket = os_malloc(ext->length);
02865                 if (conn->session_ticket == NULL)
02866                         return SSL_AD_INTERNAL_ERROR;
02867 
02868                 os_memcpy(conn->session_ticket, ext->data, ext->length);
02869                 conn->session_ticket_len = ext->length;
02870         }
02871 
02872         return 0;
02873 }
02874 #endif /* SSL_OP_NO_TICKET */
02875 #endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
02876 #endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
02877 
02878 
02879 int tls_connection_set_session_ticket_cb(void *tls_ctx,
02880                                          struct tls_connection *conn,
02881                                          tls_session_ticket_cb cb,
02882                                          void *ctx)
02883 {
02884 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
02885         conn->session_ticket_cb = cb;
02886         conn->session_ticket_cb_ctx = ctx;
02887 
02888         if (cb) {
02889                 if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
02890                                               conn) != 1)
02891                         return -1;
02892 #ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
02893                 SSL_set_session_ticket_ext_cb(conn->ssl,
02894                                               tls_session_ticket_ext_cb, conn);
02895 #else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
02896 #ifdef SSL_OP_NO_TICKET
02897                 SSL_set_tlsext_debug_callback(conn->ssl, tls_hello_ext_cb);
02898                 SSL_set_tlsext_debug_arg(conn->ssl, conn);
02899 #else /* SSL_OP_NO_TICKET */
02900                 if (SSL_set_hello_extension_cb(conn->ssl, tls_hello_ext_cb,
02901                                                conn) != 1)
02902                         return -1;
02903 #endif /* SSL_OP_NO_TICKET */
02904 #endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
02905         } else {
02906                 if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
02907                         return -1;
02908 #ifdef CONFIG_OPENSSL_TICKET_OVERRIDE
02909                 SSL_set_session_ticket_ext_cb(conn->ssl, NULL, NULL);
02910 #else /* CONFIG_OPENSSL_TICKET_OVERRIDE */
02911 #ifdef SSL_OP_NO_TICKET
02912                 SSL_set_tlsext_debug_callback(conn->ssl, NULL);
02913                 SSL_set_tlsext_debug_arg(conn->ssl, conn);
02914 #else /* SSL_OP_NO_TICKET */
02915                 if (SSL_set_hello_extension_cb(conn->ssl, NULL, NULL) != 1)
02916                         return -1;
02917 #endif /* SSL_OP_NO_TICKET */
02918 #endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */
02919         }
02920 
02921         return 0;
02922 #else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
02923         return -1;
02924 #endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
02925 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:26:38