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