| 1 | #include <stdint.h> |
| 2 | #include <stdio.h> |
| 3 | #include <stdlib.h> |
| 4 | #include <windows.h> |
| 5 | #include <winsock.h> |
| 6 | #include <wincrypt.h> |
| 7 | #include <wintrust.h> |
| 8 | #include <schannel.h> |
| 9 | |
| 10 | #define SECURITY_WIN32 |
| 11 | #include <security.h> |
| 12 | #include <sspi.h> |
| 13 | |
| 14 | #define vsc_init_resp_buff_size 44000 |
| 15 | |
| 16 | #define IO_BUFFER_SIZE 0x10000 |
| 17 | |
| 18 | #define TLS_MAX_BUFSIZ 32768 |
| 19 | |
| 20 | // Define here to be sure |
| 21 | #define SP_PROT_TLS1_2_CLIENT 0x00000800 |
| 22 | |
| 23 | typedef void* (*vschannel_allocator)(void*, INT64); |
| 24 | |
| 25 | typedef struct TlsContext TlsContext; |
| 26 | |
| 27 | TlsContext new_tls_context(); |
| 28 | |
| 29 | static void vschannel_init(TlsContext *tls_ctx, BOOL validate_server_certificate); |
| 30 | |
| 31 | static void vschannel_cleanup(TlsContext *tls_ctx); |
| 32 | |
| 33 | static INT vschannel_last_error(TlsContext *tls_ctx); |
| 34 | |
| 35 | static INT request(TlsContext *tls_ctx, INT iport, LPWSTR host, CHAR *req, DWORD req_len, CHAR **out, vschannel_allocator afn); |
| 36 | |
| 37 | static SECURITY_STATUS https_make_request(TlsContext *tls_ctx, CHAR *req, DWORD req_len, CHAR **out, int *length, vschannel_allocator afn); |
| 38 | |
| 39 | static INT connect_to_server(TlsContext *tls_ctx, LPWSTR host, INT port_number); |
| 40 | |
| 41 | static LONG disconnect_from_server(TlsContext *tls_ctx); |
| 42 | |
| 43 | static SECURITY_STATUS perform_client_handshake(TlsContext *tls_ctx, LPWSTR host, SecBuffer *pExtraData); |
| 44 | |
| 45 | static SECURITY_STATUS client_handshake_loop(TlsContext *tls_ctx, BOOL fDoInitialRead, SecBuffer *pExtraData); |
| 46 | |
| 47 | static DWORD verify_server_certificate(PCCERT_CONTEXT pServerCert, LPWSTR host, DWORD dwCertFlags); |
| 48 | |
| 49 | static SECURITY_STATUS create_credentials(TlsContext *tls_ctx); |
| 50 | |
| 51 | static void get_new_client_credentials(TlsContext *tls_ctx); |
| 52 | |