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