tls_openssl.c

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

Generated on Sat Nov 21 23:16:51 2009 for hostapd by  doxygen 1.6.1