00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
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
00200
00201
00202
00203
00204
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 , sspi_flags, 0,
00246 SECURITY_NATIVE_DREP, NULL, 0, &conn->context,
00247 &outbuf, &sspi_flags_out, &ts_expiry);
00248 #else
00249 status = global->sspi->InitializeSecurityContextA(
00250 &conn->creds, NULL, NULL , sspi_flags, 0,
00251 SECURITY_NATIVE_DREP, NULL, 0, &conn->context,
00252 &outbuf, &sspi_flags_out, &ts_expiry);
00253 #endif
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
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
00295
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
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
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
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
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
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
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
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
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
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
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 }