tls_schannel.c
Go to the documentation of this file.
00001 /*
00002  * SSL/TLS interface functions for Microsoft Schannel
00003  * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 /*
00016  * FIX: Go through all SSPI functions and verify what needs to be freed
00017  * FIX: session resumption
00018  * TODO: add support for server cert chain validation
00019  * TODO: add support for CA cert validation
00020  * TODO: add support for EAP-TLS (client cert/key conf)
00021  */
00022 
00023 #include "includes.h"
00024 #include <windows.h>
00025 #include <wincrypt.h>
00026 #include <schannel.h>
00027 #define SECURITY_WIN32
00028 #include <security.h>
00029 #include <sspi.h>
00030 
00031 #include "common.h"
00032 #include "tls.h"
00033 
00034 
00035 struct tls_global {
00036         HMODULE hsecurity;
00037         PSecurityFunctionTable sspi;
00038         HCERTSTORE my_cert_store;
00039 };
00040 
00041 struct tls_connection {
00042         int established, start;
00043         int failed, read_alerts, write_alerts;
00044 
00045         SCHANNEL_CRED schannel_cred;
00046         CredHandle creds;
00047         CtxtHandle context;
00048 
00049         u8 eap_tls_prf[128];
00050         int eap_tls_prf_set;
00051 };
00052 
00053 
00054 static int schannel_load_lib(struct tls_global *global)
00055 {
00056         INIT_SECURITY_INTERFACE pInitSecurityInterface;
00057 
00058         global->hsecurity = LoadLibrary(TEXT("Secur32.dll"));
00059         if (global->hsecurity == NULL) {
00060                 wpa_printf(MSG_ERROR, "%s: Could not load Secur32.dll - 0x%x",
00061                            __func__, (unsigned int) GetLastError());
00062                 return -1;
00063         }
00064 
00065         pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(
00066                 global->hsecurity, "InitSecurityInterfaceA");
00067         if (pInitSecurityInterface == NULL) {
00068                 wpa_printf(MSG_ERROR, "%s: Could not find "
00069                            "InitSecurityInterfaceA from Secur32.dll",
00070                            __func__);
00071                 FreeLibrary(global->hsecurity);
00072                 global->hsecurity = NULL;
00073                 return -1;
00074         }
00075 
00076         global->sspi = pInitSecurityInterface();
00077         if (global->sspi == NULL) {
00078                 wpa_printf(MSG_ERROR, "%s: Could not read security "
00079                            "interface - 0x%x",
00080                            __func__, (unsigned int) GetLastError());
00081                 FreeLibrary(global->hsecurity);
00082                 global->hsecurity = NULL;
00083                 return -1;
00084         }
00085 
00086         return 0;
00087 }
00088 
00089 
00090 void * tls_init(const struct tls_config *conf)
00091 {
00092         struct tls_global *global;
00093 
00094         global = os_zalloc(sizeof(*global));
00095         if (global == NULL)
00096                 return NULL;
00097         if (schannel_load_lib(global)) {
00098                 os_free(global);
00099                 return NULL;
00100         }
00101         return global;
00102 }
00103 
00104 
00105 void tls_deinit(void *ssl_ctx)
00106 {
00107         struct tls_global *global = ssl_ctx;
00108 
00109         if (global->my_cert_store)
00110                 CertCloseStore(global->my_cert_store, 0);
00111         FreeLibrary(global->hsecurity);
00112         os_free(global);
00113 }
00114 
00115 
00116 int tls_get_errors(void *ssl_ctx)
00117 {
00118         return 0;
00119 }
00120 
00121 
00122 struct tls_connection * tls_connection_init(void *ssl_ctx)
00123 {
00124         struct tls_connection *conn;
00125 
00126         conn = os_zalloc(sizeof(*conn));
00127         if (conn == NULL)
00128                 return NULL;
00129         conn->start = 1;
00130 
00131         return conn;
00132 }
00133 
00134 
00135 void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
00136 {
00137         if (conn == NULL)
00138                 return;
00139 
00140         os_free(conn);
00141 }
00142 
00143 
00144 int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
00145 {
00146         return conn ? conn->established : 0;
00147 }
00148 
00149 
00150 int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
00151 {
00152         struct tls_global *global = ssl_ctx;
00153         if (conn == NULL)
00154                 return -1;
00155 
00156         conn->eap_tls_prf_set = 0;
00157         conn->established = conn->failed = 0;
00158         conn->read_alerts = conn->write_alerts = 0;
00159         global->sspi->DeleteSecurityContext(&conn->context);
00160         /* FIX: what else needs to be reseted? */
00161 
00162         return 0;
00163 }
00164 
00165 
00166 int tls_global_set_params(void *tls_ctx,
00167                           const struct tls_connection_params *params)
00168 {
00169         return -1;
00170 }
00171 
00172 
00173 int tls_global_set_verify(void *ssl_ctx, int check_crl)
00174 {
00175         return -1;
00176 }
00177 
00178 
00179 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
00180                               int verify_peer)
00181 {
00182         return -1;
00183 }
00184 
00185 
00186 int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
00187                             struct tls_keys *keys)
00188 {
00189         /* Schannel does not export master secret or client/server random. */
00190         return -1;
00191 }
00192 
00193 
00194 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
00195                        const char *label, int server_random_first,
00196                        u8 *out, size_t out_len)
00197 {
00198         /*
00199          * Cannot get master_key from Schannel, but EapKeyBlock can be used to
00200          * generate session keys for EAP-TLS and EAP-PEAPv0. EAP-PEAPv2 and
00201          * EAP-TTLS cannot use this, though, since they are using different
00202          * labels. The only option could be to implement TLSv1 completely here
00203          * and just use Schannel or CryptoAPI for low-level crypto
00204          * functionality..
00205          */
00206 
00207         if (conn == NULL || !conn->eap_tls_prf_set || server_random_first ||
00208             os_strcmp(label, "client EAP encryption") != 0 ||
00209             out_len > sizeof(conn->eap_tls_prf))
00210                 return -1;
00211 
00212         os_memcpy(out, conn->eap_tls_prf, out_len);
00213 
00214         return 0;
00215 }
00216 
00217 
00218 static struct wpabuf * tls_conn_hs_clienthello(struct tls_global *global,
00219                                                struct tls_connection *conn)
00220 {
00221         DWORD sspi_flags, sspi_flags_out;
00222         SecBufferDesc outbuf;
00223         SecBuffer outbufs[1];
00224         SECURITY_STATUS status;
00225         TimeStamp ts_expiry;
00226 
00227         sspi_flags = ISC_REQ_REPLAY_DETECT |
00228                 ISC_REQ_CONFIDENTIALITY |
00229                 ISC_RET_EXTENDED_ERROR |
00230                 ISC_REQ_ALLOCATE_MEMORY |
00231                 ISC_REQ_MANUAL_CRED_VALIDATION;
00232 
00233         wpa_printf(MSG_DEBUG, "%s: Generating ClientHello", __func__);
00234 
00235         outbufs[0].pvBuffer = NULL;
00236         outbufs[0].BufferType = SECBUFFER_TOKEN;
00237         outbufs[0].cbBuffer = 0;
00238 
00239         outbuf.cBuffers = 1;
00240         outbuf.pBuffers = outbufs;
00241         outbuf.ulVersion = SECBUFFER_VERSION;
00242 
00243 #ifdef UNICODE
00244         status = global->sspi->InitializeSecurityContextW(
00245                 &conn->creds, NULL, NULL /* server name */, sspi_flags, 0,
00246                 SECURITY_NATIVE_DREP, NULL, 0, &conn->context,
00247                 &outbuf, &sspi_flags_out, &ts_expiry);
00248 #else /* UNICODE */
00249         status = global->sspi->InitializeSecurityContextA(
00250                 &conn->creds, NULL, NULL /* server name */, sspi_flags, 0,
00251                 SECURITY_NATIVE_DREP, NULL, 0, &conn->context,
00252                 &outbuf, &sspi_flags_out, &ts_expiry);
00253 #endif /* UNICODE */
00254         if (status != SEC_I_CONTINUE_NEEDED) {
00255                 wpa_printf(MSG_ERROR, "%s: InitializeSecurityContextA "
00256                            "failed - 0x%x",
00257                            __func__, (unsigned int) status);
00258                 return NULL;
00259         }
00260 
00261         if (outbufs[0].cbBuffer != 0 && outbufs[0].pvBuffer) {
00262                 struct wpabuf *buf;
00263                 wpa_hexdump(MSG_MSGDUMP, "SChannel - ClientHello",
00264                             outbufs[0].pvBuffer, outbufs[0].cbBuffer);
00265                 conn->start = 0;
00266                 buf = wpabuf_alloc_copy(outbufs[0].pvBuffer,
00267                                         outbufs[0].cbBuffer);
00268                 if (buf == NULL)
00269                         return NULL;
00270                 global->sspi->FreeContextBuffer(outbufs[0].pvBuffer);
00271                 return buf;
00272         }
00273 
00274         wpa_printf(MSG_ERROR, "SChannel: Failed to generate ClientHello");
00275 
00276         return NULL;
00277 }
00278 
00279 
00280 #ifndef SECPKG_ATTR_EAP_KEY_BLOCK
00281 #define SECPKG_ATTR_EAP_KEY_BLOCK 0x5b
00282 
00283 typedef struct _SecPkgContext_EapKeyBlock {
00284         BYTE rgbKeys[128];
00285         BYTE rgbIVs[64];
00286 } SecPkgContext_EapKeyBlock, *PSecPkgContext_EapKeyBlock;
00287 #endif /* !SECPKG_ATTR_EAP_KEY_BLOCK */
00288 
00289 static int tls_get_eap(struct tls_global *global, struct tls_connection *conn)
00290 {
00291         SECURITY_STATUS status;
00292         SecPkgContext_EapKeyBlock kb;
00293 
00294         /* Note: Windows NT and Windows Me/98/95 do not support getting
00295          * EapKeyBlock */
00296 
00297         status = global->sspi->QueryContextAttributes(
00298                 &conn->context, SECPKG_ATTR_EAP_KEY_BLOCK, &kb);
00299         if (status != SEC_E_OK) {
00300                 wpa_printf(MSG_DEBUG, "%s: QueryContextAttributes("
00301                            "SECPKG_ATTR_EAP_KEY_BLOCK) failed (%d)",
00302                            __func__, (int) status);
00303                 return -1;
00304         }
00305 
00306         wpa_hexdump_key(MSG_MSGDUMP, "Schannel - EapKeyBlock - rgbKeys",
00307                         kb.rgbKeys, sizeof(kb.rgbKeys));
00308         wpa_hexdump_key(MSG_MSGDUMP, "Schannel - EapKeyBlock - rgbIVs",
00309                         kb.rgbIVs, sizeof(kb.rgbIVs));
00310 
00311         os_memcpy(conn->eap_tls_prf, kb.rgbKeys, sizeof(kb.rgbKeys));
00312         conn->eap_tls_prf_set = 1;
00313         return 0;
00314 }
00315 
00316 
00317 struct wpabuf * tls_connection_handshake(void *tls_ctx,
00318                                          struct tls_connection *conn,
00319                                          const struct wpabuf *in_data,
00320                                          struct wpabuf **appl_data)
00321 {
00322         struct tls_global *global = tls_ctx;
00323         DWORD sspi_flags, sspi_flags_out;
00324         SecBufferDesc inbuf, outbuf;
00325         SecBuffer inbufs[2], outbufs[1];
00326         SECURITY_STATUS status;
00327         TimeStamp ts_expiry;
00328         struct wpabuf *out_buf = NULL;
00329 
00330         if (appl_data)
00331                 *appl_data = NULL;
00332 
00333         if (conn->start)
00334                 return tls_conn_hs_clienthello(global, conn);
00335 
00336         wpa_printf(MSG_DEBUG, "SChannel: %d bytes handshake data to process",
00337                    (int) wpabuf_len(in_data));
00338 
00339         sspi_flags = ISC_REQ_REPLAY_DETECT |
00340                 ISC_REQ_CONFIDENTIALITY |
00341                 ISC_RET_EXTENDED_ERROR |
00342                 ISC_REQ_ALLOCATE_MEMORY |
00343                 ISC_REQ_MANUAL_CRED_VALIDATION;
00344 
00345         /* Input buffer for Schannel */
00346         inbufs[0].pvBuffer = (u8 *) wpabuf_head(in_data);
00347         inbufs[0].cbBuffer = wpabuf_len(in_data);
00348         inbufs[0].BufferType = SECBUFFER_TOKEN;
00349 
00350         /* Place for leftover data from Schannel */
00351         inbufs[1].pvBuffer = NULL;
00352         inbufs[1].cbBuffer = 0;
00353         inbufs[1].BufferType = SECBUFFER_EMPTY;
00354 
00355         inbuf.cBuffers = 2;
00356         inbuf.pBuffers = inbufs;
00357         inbuf.ulVersion = SECBUFFER_VERSION;
00358 
00359         /* Output buffer for Schannel */
00360         outbufs[0].pvBuffer = NULL;
00361         outbufs[0].cbBuffer = 0;
00362         outbufs[0].BufferType = SECBUFFER_TOKEN;
00363 
00364         outbuf.cBuffers = 1;
00365         outbuf.pBuffers = outbufs;
00366         outbuf.ulVersion = SECBUFFER_VERSION;
00367 
00368 #ifdef UNICODE
00369         status = global->sspi->InitializeSecurityContextW(
00370                 &conn->creds, &conn->context, NULL, sspi_flags, 0,
00371                 SECURITY_NATIVE_DREP, &inbuf, 0, NULL,
00372                 &outbuf, &sspi_flags_out, &ts_expiry);
00373 #else /* UNICODE */
00374         status = global->sspi->InitializeSecurityContextA(
00375                 &conn->creds, &conn->context, NULL, sspi_flags, 0,
00376                 SECURITY_NATIVE_DREP, &inbuf, 0, NULL,
00377                 &outbuf, &sspi_flags_out, &ts_expiry);
00378 #endif /* UNICODE */
00379 
00380         wpa_printf(MSG_MSGDUMP, "Schannel: InitializeSecurityContext -> "
00381                    "status=%d inlen[0]=%d intype[0]=%d inlen[1]=%d "
00382                    "intype[1]=%d outlen[0]=%d",
00383                    (int) status, (int) inbufs[0].cbBuffer,
00384                    (int) inbufs[0].BufferType, (int) inbufs[1].cbBuffer,
00385                    (int) inbufs[1].BufferType,
00386                    (int) outbufs[0].cbBuffer);
00387         if (status == SEC_E_OK || status == SEC_I_CONTINUE_NEEDED ||
00388             (FAILED(status) && (sspi_flags_out & ISC_RET_EXTENDED_ERROR))) {
00389                 if (outbufs[0].cbBuffer != 0 && outbufs[0].pvBuffer) {
00390                         wpa_hexdump(MSG_MSGDUMP, "SChannel - output",
00391                                     outbufs[0].pvBuffer, outbufs[0].cbBuffer);
00392                         out_buf = wpabuf_alloc_copy(outbufs[0].pvBuffer,
00393                                                     outbufs[0].cbBuffer);
00394                         global->sspi->FreeContextBuffer(outbufs[0].pvBuffer);
00395                         outbufs[0].pvBuffer = NULL;
00396                         if (out_buf == NULL)
00397                                 return NULL;
00398                 }
00399         }
00400 
00401         switch (status) {
00402         case SEC_E_INCOMPLETE_MESSAGE:
00403                 wpa_printf(MSG_DEBUG, "Schannel: SEC_E_INCOMPLETE_MESSAGE");
00404                 break;
00405         case SEC_I_CONTINUE_NEEDED:
00406                 wpa_printf(MSG_DEBUG, "Schannel: SEC_I_CONTINUE_NEEDED");
00407                 break;
00408         case SEC_E_OK:
00409                 /* TODO: verify server certificate chain */
00410                 wpa_printf(MSG_DEBUG, "Schannel: SEC_E_OK - Handshake "
00411                            "completed successfully");
00412                 conn->established = 1;
00413                 tls_get_eap(global, conn);
00414 
00415                 /* Need to return something to get final TLS ACK. */
00416                 if (out_buf == NULL)
00417                         out_buf = wpabuf_alloc(0);
00418 
00419                 if (inbufs[1].BufferType == SECBUFFER_EXTRA) {
00420                         wpa_hexdump(MSG_MSGDUMP, "SChannel - Encrypted "
00421                                     "application data",
00422                                     inbufs[1].pvBuffer, inbufs[1].cbBuffer);
00423                         if (appl_data) {
00424                                 *appl_data = wpabuf_alloc_copy(
00425                                         outbufs[1].pvBuffer,
00426                                         outbufs[1].cbBuffer);
00427                         }
00428                         global->sspi->FreeContextBuffer(inbufs[1].pvBuffer);
00429                         inbufs[1].pvBuffer = NULL;
00430                 }
00431                 break;
00432         case SEC_I_INCOMPLETE_CREDENTIALS:
00433                 wpa_printf(MSG_DEBUG,
00434                            "Schannel: SEC_I_INCOMPLETE_CREDENTIALS");
00435                 break;
00436         case SEC_E_WRONG_PRINCIPAL:
00437                 wpa_printf(MSG_DEBUG, "Schannel: SEC_E_WRONG_PRINCIPAL");
00438                 break;
00439         case SEC_E_INTERNAL_ERROR:
00440                 wpa_printf(MSG_DEBUG, "Schannel: SEC_E_INTERNAL_ERROR");
00441                 break;
00442         }
00443 
00444         if (FAILED(status)) {
00445                 wpa_printf(MSG_DEBUG, "Schannel: Handshake failed "
00446                            "(out_buf=%p)", out_buf);
00447                 conn->failed++;
00448                 global->sspi->DeleteSecurityContext(&conn->context);
00449                 return out_buf;
00450         }
00451 
00452         if (inbufs[1].BufferType == SECBUFFER_EXTRA) {
00453                 /* TODO: Can this happen? What to do with this data? */
00454                 wpa_hexdump(MSG_MSGDUMP, "SChannel - Leftover data",
00455                             inbufs[1].pvBuffer, inbufs[1].cbBuffer);
00456                 global->sspi->FreeContextBuffer(inbufs[1].pvBuffer);
00457                 inbufs[1].pvBuffer = NULL;
00458         }
00459 
00460         return out_buf;
00461 }
00462 
00463 
00464 struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
00465                                                 struct tls_connection *conn,
00466                                                 const struct wpabuf *in_data,
00467                                                 struct wpabuf **appl_data)
00468 {
00469         return NULL;
00470 }
00471 
00472 
00473 struct wpabuf * tls_connection_encrypt(void *tls_ctx,
00474                                        struct tls_connection *conn,
00475                                        const struct wpabuf *in_data)
00476 {
00477         struct tls_global *global = tls_ctx;
00478         SECURITY_STATUS status;
00479         SecBufferDesc buf;
00480         SecBuffer bufs[4];
00481         SecPkgContext_StreamSizes sizes;
00482         int i;
00483         struct wpabuf *out;
00484 
00485         status = global->sspi->QueryContextAttributes(&conn->context,
00486                                                       SECPKG_ATTR_STREAM_SIZES,
00487                                                       &sizes);
00488         if (status != SEC_E_OK) {
00489                 wpa_printf(MSG_DEBUG, "%s: QueryContextAttributes failed",
00490                            __func__);
00491                 return NULL;
00492         }
00493         wpa_printf(MSG_DEBUG, "%s: Stream sizes: header=%u trailer=%u",
00494                    __func__,
00495                    (unsigned int) sizes.cbHeader,
00496                    (unsigned int) sizes.cbTrailer);
00497 
00498         out = wpabuf_alloc(sizes.cbHeader + wpabuf_len(in_data) +
00499                            sizes.cbTrailer);
00500 
00501         os_memset(&bufs, 0, sizeof(bufs));
00502         bufs[0].pvBuffer = wpabuf_put(out, sizes.cbHeader);
00503         bufs[0].cbBuffer = sizes.cbHeader;
00504         bufs[0].BufferType = SECBUFFER_STREAM_HEADER;
00505 
00506         bufs[1].pvBuffer = wpabuf_put(out, 0);
00507         wpabuf_put_buf(out, in_data);
00508         bufs[1].cbBuffer = wpabuf_len(in_data);
00509         bufs[1].BufferType = SECBUFFER_DATA;
00510 
00511         bufs[2].pvBuffer = wpabuf_put(out, sizes.cbTrailer);
00512         bufs[2].cbBuffer = sizes.cbTrailer;
00513         bufs[2].BufferType = SECBUFFER_STREAM_TRAILER;
00514 
00515         buf.ulVersion = SECBUFFER_VERSION;
00516         buf.cBuffers = 3;
00517         buf.pBuffers = bufs;
00518 
00519         status = global->sspi->EncryptMessage(&conn->context, 0, &buf, 0);
00520 
00521         wpa_printf(MSG_MSGDUMP, "Schannel: EncryptMessage -> "
00522                    "status=%d len[0]=%d type[0]=%d len[1]=%d type[1]=%d "
00523                    "len[2]=%d type[2]=%d",
00524                    (int) status,
00525                    (int) bufs[0].cbBuffer, (int) bufs[0].BufferType,
00526                    (int) bufs[1].cbBuffer, (int) bufs[1].BufferType,
00527                    (int) bufs[2].cbBuffer, (int) bufs[2].BufferType);
00528         wpa_printf(MSG_MSGDUMP, "Schannel: EncryptMessage pointers: "
00529                    "out_data=%p bufs %p %p %p",
00530                    wpabuf_head(out), bufs[0].pvBuffer, bufs[1].pvBuffer,
00531                    bufs[2].pvBuffer);
00532 
00533         for (i = 0; i < 3; i++) {
00534                 if (bufs[i].pvBuffer && bufs[i].BufferType != SECBUFFER_EMPTY)
00535                 {
00536                         wpa_hexdump(MSG_MSGDUMP, "SChannel: bufs",
00537                                     bufs[i].pvBuffer, bufs[i].cbBuffer);
00538                 }
00539         }
00540 
00541         if (status == SEC_E_OK) {
00542                 wpa_printf(MSG_DEBUG, "%s: SEC_E_OK", __func__);
00543                 wpa_hexdump_buf_key(MSG_MSGDUMP, "Schannel: Encrypted data "
00544                                     "from EncryptMessage", out);
00545                 return out;
00546         }
00547 
00548         wpa_printf(MSG_DEBUG, "%s: Failed - status=%d",
00549                    __func__, (int) status);
00550         wpabuf_free(out);
00551         return NULL;
00552 }
00553 
00554 
00555 struct wpabuf * tls_connection_decrypt(void *tls_ctx,
00556                                        struct tls_connection *conn,
00557                                        const struct wpabuf *in_data)
00558 {
00559         struct tls_global *global = tls_ctx;
00560         SECURITY_STATUS status;
00561         SecBufferDesc buf;
00562         SecBuffer bufs[4];
00563         int i;
00564         struct wpabuf *out, *tmp;
00565 
00566         wpa_hexdump_buf(MSG_MSGDUMP,
00567                         "Schannel: Encrypted data to DecryptMessage", in_data);
00568         os_memset(&bufs, 0, sizeof(bufs));
00569         tmp = wpabuf_dup(in_data);
00570         if (tmp == NULL)
00571                 return NULL;
00572         bufs[0].pvBuffer = wpabuf_mhead(tmp);
00573         bufs[0].cbBuffer = wpabuf_len(in_data);
00574         bufs[0].BufferType = SECBUFFER_DATA;
00575 
00576         bufs[1].BufferType = SECBUFFER_EMPTY;
00577         bufs[2].BufferType = SECBUFFER_EMPTY;
00578         bufs[3].BufferType = SECBUFFER_EMPTY;
00579 
00580         buf.ulVersion = SECBUFFER_VERSION;
00581         buf.cBuffers = 4;
00582         buf.pBuffers = bufs;
00583 
00584         status = global->sspi->DecryptMessage(&conn->context, &buf, 0,
00585                                                     NULL);
00586         wpa_printf(MSG_MSGDUMP, "Schannel: DecryptMessage -> "
00587                    "status=%d len[0]=%d type[0]=%d len[1]=%d type[1]=%d "
00588                    "len[2]=%d type[2]=%d len[3]=%d type[3]=%d",
00589                    (int) status,
00590                    (int) bufs[0].cbBuffer, (int) bufs[0].BufferType,
00591                    (int) bufs[1].cbBuffer, (int) bufs[1].BufferType,
00592                    (int) bufs[2].cbBuffer, (int) bufs[2].BufferType,
00593                    (int) bufs[3].cbBuffer, (int) bufs[3].BufferType);
00594         wpa_printf(MSG_MSGDUMP, "Schannel: DecryptMessage pointers: "
00595                    "out_data=%p bufs %p %p %p %p",
00596                    wpabuf_head(tmp), bufs[0].pvBuffer, bufs[1].pvBuffer,
00597                    bufs[2].pvBuffer, bufs[3].pvBuffer);
00598 
00599         switch (status) {
00600         case SEC_E_INCOMPLETE_MESSAGE:
00601                 wpa_printf(MSG_DEBUG, "%s: SEC_E_INCOMPLETE_MESSAGE",
00602                            __func__);
00603                 break;
00604         case SEC_E_OK:
00605                 wpa_printf(MSG_DEBUG, "%s: SEC_E_OK", __func__);
00606                 for (i = 0; i < 4; i++) {
00607                         if (bufs[i].BufferType == SECBUFFER_DATA)
00608                                 break;
00609                 }
00610                 if (i == 4) {
00611                         wpa_printf(MSG_DEBUG, "%s: No output data from "
00612                                    "DecryptMessage", __func__);
00613                         wpabuf_free(tmp);
00614                         return NULL;
00615                 }
00616                 wpa_hexdump_key(MSG_MSGDUMP, "Schannel: Decrypted data from "
00617                                 "DecryptMessage",
00618                                 bufs[i].pvBuffer, bufs[i].cbBuffer);
00619                 out = wpabuf_alloc_copy(bufs[i].pvBuffer, bufs[i].cbBuffer);
00620                 wpabuf_free(tmp);
00621                 return out;
00622         }
00623 
00624         wpa_printf(MSG_DEBUG, "%s: Failed - status=%d",
00625                    __func__, (int) status);
00626         wpabuf_free(tmp);
00627         return NULL;
00628 }
00629 
00630 
00631 int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
00632 {
00633         return 0;
00634 }
00635 
00636 
00637 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
00638                                    u8 *ciphers)
00639 {
00640         return -1;
00641 }
00642 
00643 
00644 int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
00645                    char *buf, size_t buflen)
00646 {
00647         return -1;
00648 }
00649 
00650 
00651 int tls_connection_enable_workaround(void *ssl_ctx,
00652                                      struct tls_connection *conn)
00653 {
00654         return 0;
00655 }
00656 
00657 
00658 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
00659                                     int ext_type, const u8 *data,
00660                                     size_t data_len)
00661 {
00662         return -1;
00663 }
00664 
00665 
00666 int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
00667 {
00668         if (conn == NULL)
00669                 return -1;
00670         return conn->failed;
00671 }
00672 
00673 
00674 int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
00675 {
00676         if (conn == NULL)
00677                 return -1;
00678         return conn->read_alerts;
00679 }
00680 
00681 
00682 int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
00683 {
00684         if (conn == NULL)
00685                 return -1;
00686         return conn->write_alerts;
00687 }
00688 
00689 
00690 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
00691                               const struct tls_connection_params *params)
00692 {
00693         struct tls_global *global = tls_ctx;
00694         ALG_ID algs[1];
00695         SECURITY_STATUS status;
00696         TimeStamp ts_expiry;
00697 
00698         if (conn == NULL)
00699                 return -1;
00700 
00701         if (global->my_cert_store == NULL &&
00702             (global->my_cert_store = CertOpenSystemStore(0, TEXT("MY"))) ==
00703             NULL) {
00704                 wpa_printf(MSG_ERROR, "%s: CertOpenSystemStore failed - 0x%x",
00705                            __func__, (unsigned int) GetLastError());
00706                 return -1;
00707         }
00708 
00709         os_memset(&conn->schannel_cred, 0, sizeof(conn->schannel_cred));
00710         conn->schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
00711         conn->schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1;
00712         algs[0] = CALG_RSA_KEYX;
00713         conn->schannel_cred.cSupportedAlgs = 1;
00714         conn->schannel_cred.palgSupportedAlgs = algs;
00715         conn->schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
00716 #ifdef UNICODE
00717         status = global->sspi->AcquireCredentialsHandleW(
00718                 NULL, UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL,
00719                 &conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry);
00720 #else /* UNICODE */
00721         status = global->sspi->AcquireCredentialsHandleA(
00722                 NULL, UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
00723                 &conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry);
00724 #endif /* UNICODE */
00725         if (status != SEC_E_OK) {
00726                 wpa_printf(MSG_DEBUG, "%s: AcquireCredentialsHandleA failed - "
00727                            "0x%x", __func__, (unsigned int) status);
00728                 return -1;
00729         }
00730 
00731         return 0;
00732 }
00733 
00734 
00735 unsigned int tls_capabilities(void *tls_ctx)
00736 {
00737         return 0;
00738 }
00739 
00740 
00741 int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn,
00742                           int tls_ia)
00743 {
00744         return -1;
00745 }
00746 
00747 
00748 struct wpabuf * tls_connection_ia_send_phase_finished(
00749         void *tls_ctx, struct tls_connection *conn, int final);
00750 {
00751         return NULL;
00752 }
00753 
00754 
00755 int tls_connection_ia_final_phase_finished(void *tls_ctx,
00756                                            struct tls_connection *conn)
00757 {
00758         return -1;
00759 }
00760 
00761 
00762 int tls_connection_ia_permute_inner_secret(void *tls_ctx,
00763                                            struct tls_connection *conn,
00764                                            const u8 *key, size_t key_len)
00765 {
00766         return -1;
00767 }


wpa_supplicant_node
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:33:21