tls_schannel.c

Go to the documentation of this file.
00001 
00016 /*
00017  * FIX: Go through all SSPI functions and verify what needs to be freed
00018  * FIX: session resumption
00019  * TODO: add support for server cert chain validation
00020  * TODO: add support for CA cert validation
00021  * TODO: add support for EAP-TLS (client cert/key conf)
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         /* FIX: what else needs to be reseted? */
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         /* Schannel does not export master secret or client/server random. */
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          * Cannot get master_key from Schannel, but EapKeyBlock can be used to
00201          * generate session keys for EAP-TLS and EAP-PEAPv0. EAP-PEAPv2 and
00202          * EAP-TTLS cannot use this, though, since they are using different
00203          * labels. The only option could be to implement TLSv1 completely here
00204          * and just use Schannel or CryptoAPI for low-level crypto
00205          * functionality..
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 /* server name */, sspi_flags, 0,
00248                 SECURITY_NATIVE_DREP, NULL, 0, &conn->context,
00249                 &outbuf, &sspi_flags_out, &ts_expiry);
00250 #else /* UNICODE */
00251         status = global->sspi->InitializeSecurityContextA(
00252                 &conn->creds, NULL, NULL /* server name */, sspi_flags, 0,
00253                 SECURITY_NATIVE_DREP, NULL, 0, &conn->context,
00254                 &outbuf, &sspi_flags_out, &ts_expiry);
00255 #endif /* UNICODE */
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 /* !SECPKG_ATTR_EAP_KEY_BLOCK */
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         /* Note: Windows NT and Windows Me/98/95 do not support getting
00298          * EapKeyBlock */
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         /* Input buffer for Schannel */
00350         inbufs[0].pvBuffer = (u8 *) in_data;
00351         inbufs[0].cbBuffer = in_len;
00352         inbufs[0].BufferType = SECBUFFER_TOKEN;
00353 
00354         /* Place for leftover data from Schannel */
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         /* Output buffer for Schannel */
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 /* UNICODE */
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 /* UNICODE */
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                 /* TODO: verify server certificate chain */
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                 /* Need to return something to get final TLS ACK. */
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                 /* TODO: Can this happen? What to do with this data? */
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 /* UNICODE */
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 /* UNICODE */
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:51 2009 for hostapd by  doxygen 1.6.1