tls_schannel.c revision 8d520ff1dc2da35cdca849e982051b86468016d8
1/* 2 * SSL/TLS interface functions for Microsoft Schannel 3 * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15/* 16 * FIX: Go through all SSPI functions and verify what needs to be freed 17 * FIX: session resumption 18 * TODO: add support for server cert chain validation 19 * TODO: add support for CA cert validation 20 * TODO: add support for EAP-TLS (client cert/key conf) 21 */ 22 23#include "includes.h" 24#include <windows.h> 25#include <wincrypt.h> 26#include <schannel.h> 27#define SECURITY_WIN32 28#include <security.h> 29#include <sspi.h> 30 31#include "common.h" 32#include "tls.h" 33 34 35struct tls_global { 36 HMODULE hsecurity; 37 PSecurityFunctionTable sspi; 38 HCERTSTORE my_cert_store; 39}; 40 41struct tls_connection { 42 int established, start; 43 int failed, read_alerts, write_alerts; 44 45 SCHANNEL_CRED schannel_cred; 46 CredHandle creds; 47 CtxtHandle context; 48 49 u8 eap_tls_prf[128]; 50 int eap_tls_prf_set; 51}; 52 53 54static int schannel_load_lib(struct tls_global *global) 55{ 56 INIT_SECURITY_INTERFACE pInitSecurityInterface; 57 58 global->hsecurity = LoadLibrary(TEXT("Secur32.dll")); 59 if (global->hsecurity == NULL) { 60 wpa_printf(MSG_ERROR, "%s: Could not load Secur32.dll - 0x%x", 61 __func__, (unsigned int) GetLastError()); 62 return -1; 63 } 64 65 pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress( 66 global->hsecurity, "InitSecurityInterfaceA"); 67 if (pInitSecurityInterface == NULL) { 68 wpa_printf(MSG_ERROR, "%s: Could not find " 69 "InitSecurityInterfaceA from Secur32.dll", 70 __func__); 71 FreeLibrary(global->hsecurity); 72 global->hsecurity = NULL; 73 return -1; 74 } 75 76 global->sspi = pInitSecurityInterface(); 77 if (global->sspi == NULL) { 78 wpa_printf(MSG_ERROR, "%s: Could not read security " 79 "interface - 0x%x", 80 __func__, (unsigned int) GetLastError()); 81 FreeLibrary(global->hsecurity); 82 global->hsecurity = NULL; 83 return -1; 84 } 85 86 return 0; 87} 88 89 90void * tls_init(const struct tls_config *conf) 91{ 92 struct tls_global *global; 93 94 global = os_zalloc(sizeof(*global)); 95 if (global == NULL) 96 return NULL; 97 if (schannel_load_lib(global)) { 98 os_free(global); 99 return NULL; 100 } 101 return global; 102} 103 104 105void tls_deinit(void *ssl_ctx) 106{ 107 struct tls_global *global = ssl_ctx; 108 109 if (global->my_cert_store) 110 CertCloseStore(global->my_cert_store, 0); 111 FreeLibrary(global->hsecurity); 112 os_free(global); 113} 114 115 116int tls_get_errors(void *ssl_ctx) 117{ 118 return 0; 119} 120 121 122struct tls_connection * tls_connection_init(void *ssl_ctx) 123{ 124 struct tls_connection *conn; 125 126 conn = os_zalloc(sizeof(*conn)); 127 if (conn == NULL) 128 return NULL; 129 conn->start = 1; 130 131 return conn; 132} 133 134 135void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 136{ 137 if (conn == NULL) 138 return; 139 140 os_free(conn); 141} 142 143 144int tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 145{ 146 return conn ? conn->established : 0; 147} 148 149 150int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 151{ 152 struct tls_global *global = ssl_ctx; 153 if (conn == NULL) 154 return -1; 155 156 conn->eap_tls_prf_set = 0; 157 conn->established = conn->failed = 0; 158 conn->read_alerts = conn->write_alerts = 0; 159 global->sspi->DeleteSecurityContext(&conn->context); 160 /* FIX: what else needs to be reseted? */ 161 162 return 0; 163} 164 165 166int tls_global_set_params(void *tls_ctx, 167 const struct tls_connection_params *params) 168{ 169 return -1; 170} 171 172 173int tls_global_set_verify(void *ssl_ctx, int check_crl) 174{ 175 return -1; 176} 177 178 179int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 180 int verify_peer) 181{ 182 return -1; 183} 184 185 186int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn, 187 struct tls_keys *keys) 188{ 189 /* Schannel does not export master secret or client/server random. */ 190 return -1; 191} 192 193 194int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 195 const char *label, int server_random_first, 196 u8 *out, size_t out_len) 197{ 198 /* 199 * Cannot get master_key from Schannel, but EapKeyBlock can be used to 200 * generate session keys for EAP-TLS and EAP-PEAPv0. EAP-PEAPv2 and 201 * EAP-TTLS cannot use this, though, since they are using different 202 * labels. The only option could be to implement TLSv1 completely here 203 * and just use Schannel or CryptoAPI for low-level crypto 204 * functionality.. 205 */ 206 207 if (conn == NULL || !conn->eap_tls_prf_set || server_random_first || 208 os_strcmp(label, "client EAP encryption") != 0 || 209 out_len > sizeof(conn->eap_tls_prf)) 210 return -1; 211 212 os_memcpy(out, conn->eap_tls_prf, out_len); 213 214 return 0; 215} 216 217 218static struct wpabuf * tls_conn_hs_clienthello(struct tls_global *global, 219 struct tls_connection *conn) 220{ 221 DWORD sspi_flags, sspi_flags_out; 222 SecBufferDesc outbuf; 223 SecBuffer outbufs[1]; 224 SECURITY_STATUS status; 225 TimeStamp ts_expiry; 226 227 sspi_flags = ISC_REQ_REPLAY_DETECT | 228 ISC_REQ_CONFIDENTIALITY | 229 ISC_RET_EXTENDED_ERROR | 230 ISC_REQ_ALLOCATE_MEMORY | 231 ISC_REQ_MANUAL_CRED_VALIDATION; 232 233 wpa_printf(MSG_DEBUG, "%s: Generating ClientHello", __func__); 234 235 outbufs[0].pvBuffer = NULL; 236 outbufs[0].BufferType = SECBUFFER_TOKEN; 237 outbufs[0].cbBuffer = 0; 238 239 outbuf.cBuffers = 1; 240 outbuf.pBuffers = outbufs; 241 outbuf.ulVersion = SECBUFFER_VERSION; 242 243#ifdef UNICODE 244 status = global->sspi->InitializeSecurityContextW( 245 &conn->creds, NULL, NULL /* server name */, sspi_flags, 0, 246 SECURITY_NATIVE_DREP, NULL, 0, &conn->context, 247 &outbuf, &sspi_flags_out, &ts_expiry); 248#else /* UNICODE */ 249 status = global->sspi->InitializeSecurityContextA( 250 &conn->creds, NULL, NULL /* server name */, sspi_flags, 0, 251 SECURITY_NATIVE_DREP, NULL, 0, &conn->context, 252 &outbuf, &sspi_flags_out, &ts_expiry); 253#endif /* UNICODE */ 254 if (status != SEC_I_CONTINUE_NEEDED) { 255 wpa_printf(MSG_ERROR, "%s: InitializeSecurityContextA " 256 "failed - 0x%x", 257 __func__, (unsigned int) status); 258 return NULL; 259 } 260 261 if (outbufs[0].cbBuffer != 0 && outbufs[0].pvBuffer) { 262 struct wpabuf *buf; 263 wpa_hexdump(MSG_MSGDUMP, "SChannel - ClientHello", 264 outbufs[0].pvBuffer, outbufs[0].cbBuffer); 265 conn->start = 0; 266 buf = wpabuf_alloc_copy(outbufs[0].pvBuffer, 267 outbufs[0].cbBuffer); 268 if (buf == NULL) 269 return NULL; 270 global->sspi->FreeContextBuffer(outbufs[0].pvBuffer); 271 return buf; 272 } 273 274 wpa_printf(MSG_ERROR, "SChannel: Failed to generate ClientHello"); 275 276 return NULL; 277} 278 279 280#ifndef SECPKG_ATTR_EAP_KEY_BLOCK 281#define SECPKG_ATTR_EAP_KEY_BLOCK 0x5b 282 283typedef struct _SecPkgContext_EapKeyBlock { 284 BYTE rgbKeys[128]; 285 BYTE rgbIVs[64]; 286} SecPkgContext_EapKeyBlock, *PSecPkgContext_EapKeyBlock; 287#endif /* !SECPKG_ATTR_EAP_KEY_BLOCK */ 288 289static int tls_get_eap(struct tls_global *global, struct tls_connection *conn) 290{ 291 SECURITY_STATUS status; 292 SecPkgContext_EapKeyBlock kb; 293 294 /* Note: Windows NT and Windows Me/98/95 do not support getting 295 * EapKeyBlock */ 296 297 status = global->sspi->QueryContextAttributes( 298 &conn->context, SECPKG_ATTR_EAP_KEY_BLOCK, &kb); 299 if (status != SEC_E_OK) { 300 wpa_printf(MSG_DEBUG, "%s: QueryContextAttributes(" 301 "SECPKG_ATTR_EAP_KEY_BLOCK) failed (%d)", 302 __func__, (int) status); 303 return -1; 304 } 305 306 wpa_hexdump_key(MSG_MSGDUMP, "Schannel - EapKeyBlock - rgbKeys", 307 kb.rgbKeys, sizeof(kb.rgbKeys)); 308 wpa_hexdump_key(MSG_MSGDUMP, "Schannel - EapKeyBlock - rgbIVs", 309 kb.rgbIVs, sizeof(kb.rgbIVs)); 310 311 os_memcpy(conn->eap_tls_prf, kb.rgbKeys, sizeof(kb.rgbKeys)); 312 conn->eap_tls_prf_set = 1; 313 return 0; 314} 315 316 317struct wpabuf * tls_connection_handshake(void *tls_ctx, 318 struct tls_connection *conn, 319 const struct wpabuf *in_data, 320 struct wpabuf **appl_data) 321{ 322 struct tls_global *global = tls_ctx; 323 DWORD sspi_flags, sspi_flags_out; 324 SecBufferDesc inbuf, outbuf; 325 SecBuffer inbufs[2], outbufs[1]; 326 SECURITY_STATUS status; 327 TimeStamp ts_expiry; 328 struct wpabuf *out_buf = NULL; 329 330 if (appl_data) 331 *appl_data = NULL; 332 333 if (conn->start) 334 return tls_conn_hs_clienthello(global, conn); 335 336 wpa_printf(MSG_DEBUG, "SChannel: %d bytes handshake data to process", 337 (int) wpabuf_len(in_data)); 338 339 sspi_flags = ISC_REQ_REPLAY_DETECT | 340 ISC_REQ_CONFIDENTIALITY | 341 ISC_RET_EXTENDED_ERROR | 342 ISC_REQ_ALLOCATE_MEMORY | 343 ISC_REQ_MANUAL_CRED_VALIDATION; 344 345 /* Input buffer for Schannel */ 346 inbufs[0].pvBuffer = (u8 *) wpabuf_head(in_data); 347 inbufs[0].cbBuffer = wpabuf_len(in_data); 348 inbufs[0].BufferType = SECBUFFER_TOKEN; 349 350 /* Place for leftover data from Schannel */ 351 inbufs[1].pvBuffer = NULL; 352 inbufs[1].cbBuffer = 0; 353 inbufs[1].BufferType = SECBUFFER_EMPTY; 354 355 inbuf.cBuffers = 2; 356 inbuf.pBuffers = inbufs; 357 inbuf.ulVersion = SECBUFFER_VERSION; 358 359 /* Output buffer for Schannel */ 360 outbufs[0].pvBuffer = NULL; 361 outbufs[0].cbBuffer = 0; 362 outbufs[0].BufferType = SECBUFFER_TOKEN; 363 364 outbuf.cBuffers = 1; 365 outbuf.pBuffers = outbufs; 366 outbuf.ulVersion = SECBUFFER_VERSION; 367 368#ifdef UNICODE 369 status = global->sspi->InitializeSecurityContextW( 370 &conn->creds, &conn->context, NULL, sspi_flags, 0, 371 SECURITY_NATIVE_DREP, &inbuf, 0, NULL, 372 &outbuf, &sspi_flags_out, &ts_expiry); 373#else /* UNICODE */ 374 status = global->sspi->InitializeSecurityContextA( 375 &conn->creds, &conn->context, NULL, sspi_flags, 0, 376 SECURITY_NATIVE_DREP, &inbuf, 0, NULL, 377 &outbuf, &sspi_flags_out, &ts_expiry); 378#endif /* UNICODE */ 379 380 wpa_printf(MSG_MSGDUMP, "Schannel: InitializeSecurityContext -> " 381 "status=%d inlen[0]=%d intype[0]=%d inlen[1]=%d " 382 "intype[1]=%d outlen[0]=%d", 383 (int) status, (int) inbufs[0].cbBuffer, 384 (int) inbufs[0].BufferType, (int) inbufs[1].cbBuffer, 385 (int) inbufs[1].BufferType, 386 (int) outbufs[0].cbBuffer); 387 if (status == SEC_E_OK || status == SEC_I_CONTINUE_NEEDED || 388 (FAILED(status) && (sspi_flags_out & ISC_RET_EXTENDED_ERROR))) { 389 if (outbufs[0].cbBuffer != 0 && outbufs[0].pvBuffer) { 390 wpa_hexdump(MSG_MSGDUMP, "SChannel - output", 391 outbufs[0].pvBuffer, outbufs[0].cbBuffer); 392 out_buf = wpabuf_alloc_copy(outbufs[0].pvBuffer, 393 outbufs[0].cbBuffer); 394 global->sspi->FreeContextBuffer(outbufs[0].pvBuffer); 395 outbufs[0].pvBuffer = NULL; 396 if (out_buf == NULL) 397 return NULL; 398 } 399 } 400 401 switch (status) { 402 case SEC_E_INCOMPLETE_MESSAGE: 403 wpa_printf(MSG_DEBUG, "Schannel: SEC_E_INCOMPLETE_MESSAGE"); 404 break; 405 case SEC_I_CONTINUE_NEEDED: 406 wpa_printf(MSG_DEBUG, "Schannel: SEC_I_CONTINUE_NEEDED"); 407 break; 408 case SEC_E_OK: 409 /* TODO: verify server certificate chain */ 410 wpa_printf(MSG_DEBUG, "Schannel: SEC_E_OK - Handshake " 411 "completed successfully"); 412 conn->established = 1; 413 tls_get_eap(global, conn); 414 415 /* Need to return something to get final TLS ACK. */ 416 if (out_buf == NULL) 417 out_buf = wpabuf_alloc(0); 418 419 if (inbufs[1].BufferType == SECBUFFER_EXTRA) { 420 wpa_hexdump(MSG_MSGDUMP, "SChannel - Encrypted " 421 "application data", 422 inbufs[1].pvBuffer, inbufs[1].cbBuffer); 423 if (appl_data) { 424 *appl_data = wpabuf_alloc_copy( 425 outbufs[1].pvBuffer, 426 outbufs[1].cbBuffer); 427 } 428 global->sspi->FreeContextBuffer(inbufs[1].pvBuffer); 429 inbufs[1].pvBuffer = NULL; 430 } 431 break; 432 case SEC_I_INCOMPLETE_CREDENTIALS: 433 wpa_printf(MSG_DEBUG, 434 "Schannel: SEC_I_INCOMPLETE_CREDENTIALS"); 435 break; 436 case SEC_E_WRONG_PRINCIPAL: 437 wpa_printf(MSG_DEBUG, "Schannel: SEC_E_WRONG_PRINCIPAL"); 438 break; 439 case SEC_E_INTERNAL_ERROR: 440 wpa_printf(MSG_DEBUG, "Schannel: SEC_E_INTERNAL_ERROR"); 441 break; 442 } 443 444 if (FAILED(status)) { 445 wpa_printf(MSG_DEBUG, "Schannel: Handshake failed " 446 "(out_buf=%p)", out_buf); 447 conn->failed++; 448 global->sspi->DeleteSecurityContext(&conn->context); 449 return out_buf; 450 } 451 452 if (inbufs[1].BufferType == SECBUFFER_EXTRA) { 453 /* TODO: Can this happen? What to do with this data? */ 454 wpa_hexdump(MSG_MSGDUMP, "SChannel - Leftover data", 455 inbufs[1].pvBuffer, inbufs[1].cbBuffer); 456 global->sspi->FreeContextBuffer(inbufs[1].pvBuffer); 457 inbufs[1].pvBuffer = NULL; 458 } 459 460 return out_buf; 461} 462 463 464struct wpabuf * tls_connection_server_handshake(void *tls_ctx, 465 struct tls_connection *conn, 466 const struct wpabuf *in_data, 467 struct wpabuf **appl_data) 468{ 469 return NULL; 470} 471 472 473struct wpabuf * tls_connection_encrypt(void *tls_ctx, 474 struct tls_connection *conn, 475 const struct wpabuf *in_data) 476{ 477 struct tls_global *global = tls_ctx; 478 SECURITY_STATUS status; 479 SecBufferDesc buf; 480 SecBuffer bufs[4]; 481 SecPkgContext_StreamSizes sizes; 482 int i; 483 struct wpabuf *out; 484 485 status = global->sspi->QueryContextAttributes(&conn->context, 486 SECPKG_ATTR_STREAM_SIZES, 487 &sizes); 488 if (status != SEC_E_OK) { 489 wpa_printf(MSG_DEBUG, "%s: QueryContextAttributes failed", 490 __func__); 491 return NULL; 492 } 493 wpa_printf(MSG_DEBUG, "%s: Stream sizes: header=%u trailer=%u", 494 __func__, 495 (unsigned int) sizes.cbHeader, 496 (unsigned int) sizes.cbTrailer); 497 498 out = wpabuf_alloc(sizes.cbHeader + wpabuf_len(in_data) + 499 sizes.cbTrailer); 500 501 os_memset(&bufs, 0, sizeof(bufs)); 502 bufs[0].pvBuffer = wpabuf_put(out, sizes.cbHeader); 503 bufs[0].cbBuffer = sizes.cbHeader; 504 bufs[0].BufferType = SECBUFFER_STREAM_HEADER; 505 506 bufs[1].pvBuffer = wpabuf_put(out, 0); 507 wpabuf_put_buf(out, in_data); 508 bufs[1].cbBuffer = wpabuf_len(in_data); 509 bufs[1].BufferType = SECBUFFER_DATA; 510 511 bufs[2].pvBuffer = wpabuf_put(out, sizes.cbTrailer); 512 bufs[2].cbBuffer = sizes.cbTrailer; 513 bufs[2].BufferType = SECBUFFER_STREAM_TRAILER; 514 515 buf.ulVersion = SECBUFFER_VERSION; 516 buf.cBuffers = 3; 517 buf.pBuffers = bufs; 518 519 status = global->sspi->EncryptMessage(&conn->context, 0, &buf, 0); 520 521 wpa_printf(MSG_MSGDUMP, "Schannel: EncryptMessage -> " 522 "status=%d len[0]=%d type[0]=%d len[1]=%d type[1]=%d " 523 "len[2]=%d type[2]=%d", 524 (int) status, 525 (int) bufs[0].cbBuffer, (int) bufs[0].BufferType, 526 (int) bufs[1].cbBuffer, (int) bufs[1].BufferType, 527 (int) bufs[2].cbBuffer, (int) bufs[2].BufferType); 528 wpa_printf(MSG_MSGDUMP, "Schannel: EncryptMessage pointers: " 529 "out_data=%p bufs %p %p %p", 530 wpabuf_head(out), bufs[0].pvBuffer, bufs[1].pvBuffer, 531 bufs[2].pvBuffer); 532 533 for (i = 0; i < 3; i++) { 534 if (bufs[i].pvBuffer && bufs[i].BufferType != SECBUFFER_EMPTY) 535 { 536 wpa_hexdump(MSG_MSGDUMP, "SChannel: bufs", 537 bufs[i].pvBuffer, bufs[i].cbBuffer); 538 } 539 } 540 541 if (status == SEC_E_OK) { 542 wpa_printf(MSG_DEBUG, "%s: SEC_E_OK", __func__); 543 wpa_hexdump_buf_key(MSG_MSGDUMP, "Schannel: Encrypted data " 544 "from EncryptMessage", out); 545 return out; 546 } 547 548 wpa_printf(MSG_DEBUG, "%s: Failed - status=%d", 549 __func__, (int) status); 550 wpabuf_free(out); 551 return NULL; 552} 553 554 555struct wpabuf * tls_connection_decrypt(void *tls_ctx, 556 struct tls_connection *conn, 557 const struct wpabuf *in_data) 558{ 559 struct tls_global *global = tls_ctx; 560 SECURITY_STATUS status; 561 SecBufferDesc buf; 562 SecBuffer bufs[4]; 563 int i; 564 struct wpabuf *out, *tmp; 565 566 wpa_hexdump_buf(MSG_MSGDUMP, 567 "Schannel: Encrypted data to DecryptMessage", in_data); 568 os_memset(&bufs, 0, sizeof(bufs)); 569 tmp = wpabuf_dup(in_data); 570 if (tmp == NULL) 571 return NULL; 572 bufs[0].pvBuffer = wpabuf_mhead(tmp); 573 bufs[0].cbBuffer = wpabuf_len(in_data); 574 bufs[0].BufferType = SECBUFFER_DATA; 575 576 bufs[1].BufferType = SECBUFFER_EMPTY; 577 bufs[2].BufferType = SECBUFFER_EMPTY; 578 bufs[3].BufferType = SECBUFFER_EMPTY; 579 580 buf.ulVersion = SECBUFFER_VERSION; 581 buf.cBuffers = 4; 582 buf.pBuffers = bufs; 583 584 status = global->sspi->DecryptMessage(&conn->context, &buf, 0, 585 NULL); 586 wpa_printf(MSG_MSGDUMP, "Schannel: DecryptMessage -> " 587 "status=%d len[0]=%d type[0]=%d len[1]=%d type[1]=%d " 588 "len[2]=%d type[2]=%d len[3]=%d type[3]=%d", 589 (int) status, 590 (int) bufs[0].cbBuffer, (int) bufs[0].BufferType, 591 (int) bufs[1].cbBuffer, (int) bufs[1].BufferType, 592 (int) bufs[2].cbBuffer, (int) bufs[2].BufferType, 593 (int) bufs[3].cbBuffer, (int) bufs[3].BufferType); 594 wpa_printf(MSG_MSGDUMP, "Schannel: DecryptMessage pointers: " 595 "out_data=%p bufs %p %p %p %p", 596 wpabuf_head(tmp), bufs[0].pvBuffer, bufs[1].pvBuffer, 597 bufs[2].pvBuffer, bufs[3].pvBuffer); 598 599 switch (status) { 600 case SEC_E_INCOMPLETE_MESSAGE: 601 wpa_printf(MSG_DEBUG, "%s: SEC_E_INCOMPLETE_MESSAGE", 602 __func__); 603 break; 604 case SEC_E_OK: 605 wpa_printf(MSG_DEBUG, "%s: SEC_E_OK", __func__); 606 for (i = 0; i < 4; i++) { 607 if (bufs[i].BufferType == SECBUFFER_DATA) 608 break; 609 } 610 if (i == 4) { 611 wpa_printf(MSG_DEBUG, "%s: No output data from " 612 "DecryptMessage", __func__); 613 wpabuf_free(tmp); 614 return NULL; 615 } 616 wpa_hexdump_key(MSG_MSGDUMP, "Schannel: Decrypted data from " 617 "DecryptMessage", 618 bufs[i].pvBuffer, bufs[i].cbBuffer); 619 out = wpabuf_alloc_copy(bufs[i].pvBuffer, bufs[i].cbBuffer); 620 wpabuf_free(tmp); 621 return out; 622 } 623 624 wpa_printf(MSG_DEBUG, "%s: Failed - status=%d", 625 __func__, (int) status); 626 wpabuf_free(tmp); 627 return NULL; 628} 629 630 631int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 632{ 633 return 0; 634} 635 636 637int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 638 u8 *ciphers) 639{ 640 return -1; 641} 642 643 644int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 645 char *buf, size_t buflen) 646{ 647 return -1; 648} 649 650 651int tls_connection_enable_workaround(void *ssl_ctx, 652 struct tls_connection *conn) 653{ 654 return 0; 655} 656 657 658int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 659 int ext_type, const u8 *data, 660 size_t data_len) 661{ 662 return -1; 663} 664 665 666int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 667{ 668 if (conn == NULL) 669 return -1; 670 return conn->failed; 671} 672 673 674int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 675{ 676 if (conn == NULL) 677 return -1; 678 return conn->read_alerts; 679} 680 681 682int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 683{ 684 if (conn == NULL) 685 return -1; 686 return conn->write_alerts; 687} 688 689 690int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 691 const struct tls_connection_params *params) 692{ 693 struct tls_global *global = tls_ctx; 694 ALG_ID algs[1]; 695 SECURITY_STATUS status; 696 TimeStamp ts_expiry; 697 698 if (conn == NULL) 699 return -1; 700 701 if (global->my_cert_store == NULL && 702 (global->my_cert_store = CertOpenSystemStore(0, TEXT("MY"))) == 703 NULL) { 704 wpa_printf(MSG_ERROR, "%s: CertOpenSystemStore failed - 0x%x", 705 __func__, (unsigned int) GetLastError()); 706 return -1; 707 } 708 709 os_memset(&conn->schannel_cred, 0, sizeof(conn->schannel_cred)); 710 conn->schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; 711 conn->schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1; 712 algs[0] = CALG_RSA_KEYX; 713 conn->schannel_cred.cSupportedAlgs = 1; 714 conn->schannel_cred.palgSupportedAlgs = algs; 715 conn->schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS; 716#ifdef UNICODE 717 status = global->sspi->AcquireCredentialsHandleW( 718 NULL, UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL, 719 &conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry); 720#else /* UNICODE */ 721 status = global->sspi->AcquireCredentialsHandleA( 722 NULL, UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL, 723 &conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry); 724#endif /* UNICODE */ 725 if (status != SEC_E_OK) { 726 wpa_printf(MSG_DEBUG, "%s: AcquireCredentialsHandleA failed - " 727 "0x%x", __func__, (unsigned int) status); 728 return -1; 729 } 730 731 return 0; 732} 733 734 735unsigned int tls_capabilities(void *tls_ctx) 736{ 737 return 0; 738} 739 740 741int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn, 742 int tls_ia) 743{ 744 return -1; 745} 746 747 748struct wpabuf * tls_connection_ia_send_phase_finished( 749 void *tls_ctx, struct tls_connection *conn, int final); 750{ 751 return NULL; 752} 753 754 755int tls_connection_ia_final_phase_finished(void *tls_ctx, 756 struct tls_connection *conn) 757{ 758 return -1; 759} 760 761 762int tls_connection_ia_permute_inner_secret(void *tls_ctx, 763 struct tls_connection *conn, 764 const u8 *key, size_t key_len) 765{ 766 return -1; 767} 768