Created
September 1, 2015 10:02
-
-
Save Swyter/aedd928c4e7d2b67e22e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: base/applications/rapps/rapps.h | |
=================================================================== | |
--- base/applications/rapps/rapps.h (revision 68875) | |
+++ base/applications/rapps/rapps.h (working copy) | |
@@ -27,7 +27,7 @@ | |
#include "resource.h" | |
/* FIXME: this should be downloaded by HTTPS once is supported */ | |
-#define APPLICATION_DATABASE_URL L"http://svn.reactos.org/packages/rappmgr.cab" | |
+#define APPLICATION_DATABASE_URL L"https://svn.reactos.org/packages/rappmgr.cab" | |
#define SPLIT_WIDTH 4 | |
#define MAX_STR_LEN 256 | |
Index: dll/3rdparty/CMakeLists.txt | |
=================================================================== | |
--- dll/3rdparty/CMakeLists.txt (revision 68875) | |
+++ dll/3rdparty/CMakeLists.txt (working copy) | |
@@ -7,5 +7,4 @@ | |
add_subdirectory(libpng) | |
add_subdirectory(libtiff) | |
add_subdirectory(libxslt) | |
-# FIXME CORE-9065 | |
-#add_subdirectory(mbedtls) | |
+add_subdirectory(mbedtls) | |
Index: dll/3rdparty/mbedtls/CMakeLists.txt | |
=================================================================== | |
--- dll/3rdparty/mbedtls/CMakeLists.txt (revision 68875) | |
+++ dll/3rdparty/mbedtls/CMakeLists.txt (working copy) | |
@@ -71,7 +71,9 @@ | |
x509write_csr.c | |
xtea.c) | |
-add_library(mbedtls SHARED ${src}) | |
+add_rc_deps(mbedtls.rc) | |
+ | |
+add_library(mbedtls SHARED ${src} mbedtls.rc) | |
set_module_type(mbedtls win32dll) | |
target_link_libraries(mbedtls zlib) | |
add_importlibs(mbedtls advapi32 ws2_32 msvcrt kernel32) | |
Index: dll/3rdparty/mbedtls/mbedtls.rc | |
=================================================================== | |
--- dll/3rdparty/mbedtls/mbedtls.rc (revision 0) | |
+++ dll/3rdparty/mbedtls/mbedtls.rc (working copy) | |
@@ -0,0 +1,22 @@ | |
+#include <windef.h> | |
+#include <winuser.h> | |
+#include <polarssl/version.h> | |
+ | |
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | |
+ | |
+#define REACTOS_VERSION_DLL | |
+#define REACTOS_STR_FILE_DESCRIPTION POLARSSL_VERSION_STRING_FULL | |
+#define REACTOS_STR_PRODUCT_NAME POLARSSL_VERSION_STRING_FULL | |
+#define REACTOS_STR_INTERNAL_NAME "mbedtls" | |
+#define REACTOS_STR_ORIGINAL_FILENAME "mbedtls.dll" | |
+ | |
+#define REACTOS_FILEVERSION POLARSSL_VERSION_MAJOR, \ | |
+ POLARSSL_VERSION_MINOR, \ | |
+ POLARSSL_VERSION_PATCH, \ | |
+ 0 | |
+ | |
+#define REACTOS_STR_FILE_VERSION POLARSSL_VERSION_STRING | |
+ | |
+#include <reactos/version.rc> | |
+ | |
+#include <reactos/manifest_dll.rc> | |
\ No newline at end of file | |
Index: dll/win32/schannel/CMakeLists.txt | |
=================================================================== | |
--- dll/win32/schannel/CMakeLists.txt (revision 68875) | |
+++ dll/win32/schannel/CMakeLists.txt (working copy) | |
@@ -1,7 +1,7 @@ | |
include_directories( | |
${REACTOS_SOURCE_DIR}/include/reactos/wine | |
- ${REACTOS_SOURCE_DIR}/include/reactos/libs/gnutls) | |
+ ${REACTOS_SOURCE_DIR}/include/reactos/libs/mbedtls) | |
add_definitions(-D__WINESRC__ -D_WINE) | |
@@ -9,7 +9,7 @@ | |
list(APPEND SOURCE | |
lsamode.c | |
- schannel_gnutls.c | |
+ schannel_mbedtls.c | |
schannel_main.c | |
schannel_wine.c | |
secur32_wine.c | |
@@ -24,7 +24,7 @@ | |
${CMAKE_CURRENT_BINARY_DIR}/schannel.def) | |
set_module_type(schannel win32dll) | |
-target_link_libraries(schannel wine) | |
+target_link_libraries(schannel wine mbedtls) | |
add_importlibs(schannel crypt32 secur32 advapi32 msvcrt kernel32 ntdll) | |
add_pch(schannel precomp.h SOURCE) | |
add_cd_file(TARGET schannel DESTINATION reactos/system32 FOR all) | |
Index: dll/win32/schannel/schannel_mbedtls.c | |
=================================================================== | |
--- dll/win32/schannel/schannel_mbedtls.c (revision 0) | |
+++ dll/win32/schannel/schannel_mbedtls.c (working copy) | |
@@ -0,0 +1,982 @@ | |
+/* Copyright 2015 Peter Hater | |
+ * Copyright 2015 Ismael Ferreras Morezuelas <swyterzone+ros@gmail.com> | |
+ * | |
+ * This library is free software; you can redistribute it and/or | |
+ * modify it under the terms of the GNU Lesser General Public | |
+ * License as published by the Free Software Foundation; either | |
+ * version 2.1 of the License, or (at your option) any later version. | |
+ * | |
+ * This library is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
+ * Lesser General Public License for more details. | |
+ * | |
+ * You should have received a copy of the GNU Lesser General Public | |
+ * License along with this library; if not, write to the Free Software | |
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
+ * | |
+ * -- | |
+ * | |
+ * This file implements the schannel SSL/TLS provider by using the lightweight PolarSSL/mbedTLS open source library. | |
+ */ | |
+ | |
+#ifdef __REACTOS__ | |
+ #include "precomp.h" | |
+ #include <wine/config.h> | |
+ #include <wine/port.h> | |
+ #include <strsafe.h> | |
+ #include "schannel_priv.h" | |
+#else | |
+ #include "config.h" | |
+ #include "wine/port.h" | |
+ #include <errno.h> | |
+ #include <stdarg.h> | |
+ #include "windef.h" | |
+ #include "winbase.h" | |
+ #include "sspi.h" | |
+ #include "schannel.h" | |
+ #include "wine/debug.h" | |
+ #include "secur32_priv.h" | |
+#endif | |
+ | |
+#include <polarssl/config.h> | |
+#include <polarssl/net.h> | |
+#include <polarssl/ssl.h> | |
+#include <polarssl/entropy.h> | |
+#include <polarssl/ctr_drbg.h> | |
+#include <polarssl/certs.h> | |
+#include <polarssl/x509.h> | |
+#include <polarssl/error.h> | |
+#include <polarssl/debug.h> | |
+ | |
+#ifdef __REACTOS__ | |
+ #define __wine_dbch_secur32 __wine_dbch_schannel | |
+#else | |
+ #include "wine/library.h" | |
+ WINE_DEFAULT_DEBUG_CHANNEL(secur32); | |
+ WINE_DECLARE_DEBUG_CHANNEL(winediag); | |
+#endif | |
+ | |
+#define ROS_SCHAN_IS_BLOCKING (0xCCCFFFFF & 0xFFF00000) | |
+#define ROS_SCHAN_IS_BLOCKING_MARSHALL(read_len) (ROS_SCHAN_IS_BLOCKING | (read_len & 0x000FFFFF)) | |
+#define ROS_SCHAN_IS_BLOCKING_RETRIEVE(read_len) (read_len & 0x000FFFFF) | |
+ | |
+typedef struct | |
+{ | |
+ ssl_context ssl; | |
+ entropy_context entropy; | |
+ ctr_drbg_context ctr_drbg; | |
+ struct schan_transport *transport; | |
+ //ulong leftover; | |
+} POLARSSL_SESSION, *PPOLARSSL_SESSION; | |
+ | |
+void dbg_buffer_print(unsigned char *buf, size_t len) | |
+{ | |
+ size_t i = 0; | |
+ | |
+ while(i < len) | |
+ { | |
+ WARN("%#05X| %#02x %c\n", i, buf[i], buf[i]); | |
+ i++; | |
+ } | |
+} | |
+ | |
+/* custom `net_recv` callback adapter, mbedTLS uses it in ssl_read for | |
+ pulling data from the underlying win32 net stack */ | |
+static int schan_pull_adapter(void *session, unsigned char *buff, size_t buff_len) | |
+{ | |
+ POLARSSL_SESSION *s = session; | |
+ size_t requested = buff_len; | |
+ int status; | |
+ | |
+ /* ensure that we close the tap once we've discarded the session */ | |
+ //if (!s || s->transport == NULL) return POLARSSL_ERR_NET_CONNECT_FAILED; | |
+ | |
+ WARN("POLARSSL schan_pull_adapter: (%p/%p, %p, %lu)\n", s, s->transport, buff, buff_len); | |
+ | |
+ status = schan_pull(s->transport, buff, &buff_len); | |
+ | |
+ WARN("POLARSSL schan_pull_adapter: (%p/%p, %p, %lu) status: %#x\n", s, s->transport, buff, buff_len, status); | |
+ | |
+ if (status == NO_ERROR) | |
+ { | |
+ /* great, no more data left */ | |
+ if (buff_len == 0) | |
+ { | |
+ WARN("Connection closed\n"); | |
+ return 0; | |
+ } | |
+ /* there's still some bytes that need pulling */ | |
+ else if (buff_len < requested) | |
+ { | |
+ WARN("Pulled %lu bytes before would block\n", buff_len); | |
+ return ROS_SCHAN_IS_BLOCKING_MARSHALL(buff_len); | |
+ } | |
+ else | |
+ { | |
+ WARN("Pulled %lu bytes\n", buff_len); | |
+ return buff_len; | |
+ } | |
+ } | |
+ else if (status == EAGAIN) | |
+ { | |
+ WARN("Would block before being able to pull anything, passing buff_len=%lu\n", buff_len); | |
+ return ROS_SCHAN_IS_BLOCKING_MARSHALL(buff_len); | |
+ } | |
+ else | |
+ { | |
+ FIXME("Unknown status code from schan_pull: %d\n", status); | |
+ return POLARSSL_ERR_NET_RECV_FAILED; | |
+ } | |
+ | |
+ /* this should be unreachable */ | |
+ return POLARSSL_ERR_NET_CONNECT_FAILED; | |
+} | |
+ | |
+/* custom `net_send` callback adapter, mbedTLS uses it in ssl_write for | |
+ pushing data to the underlying win32 net stack */ | |
+static int schan_push_adapter(void *session, const unsigned char *buff, size_t buff_len) | |
+{ | |
+ POLARSSL_SESSION *s = session; | |
+ int status; | |
+ | |
+ /* ensure that we close the tap once we've discarded the session */ | |
+ //if (!s || s->transport == NULL) return POLARSSL_ERR_NET_CONNECT_FAILED; | |
+ | |
+ WARN("POLARSSL schan_push_adapter: (%p/%p, %p, %lu)\n", s, s->transport, buff, buff_len); | |
+ | |
+ status = schan_push(s->transport, buff, &buff_len); | |
+ | |
+ WARN("POLARSSL schan_push_adapter: (%p/%p, %p, %lu) status: %#x\n", s, s->transport, buff, buff_len, status); | |
+ | |
+ if (status == NO_ERROR) | |
+ { | |
+ WARN("Pushed %lu bytes\n", buff_len); | |
+ return buff_len; | |
+ } | |
+ else if (status == EAGAIN) | |
+ { | |
+ WARN("Would block before being able to push anything. passing %lu\n", buff_len); | |
+ return ROS_SCHAN_IS_BLOCKING_MARSHALL(buff_len); | |
+ } | |
+ else | |
+ { | |
+ FIXME("Unknown status code from schan_push: %d\n", status); | |
+ return POLARSSL_ERR_NET_SEND_FAILED; | |
+ } | |
+ | |
+ /* this should be unreachable */ | |
+ return POLARSSL_ERR_NET_CONNECT_FAILED; | |
+} | |
+ | |
+DWORD schan_imp_enabled_protocols(void) | |
+{ | |
+ /* NOTE: No support for SSL 2.0 */ | |
+ WARN("POLARSSL schan_imp_enabled_protocols()\n"); | |
+ | |
+ return 0 | |
+#ifdef POLARSSL_SSL_PROTO_SSL3 | |
+ | SP_PROT_SSL3_CLIENT | SP_PROT_SSL3_SERVER | |
+#endif | |
+#ifdef POLARSSL_SSL_PROTO_TLS1 | |
+ | SP_PROT_TLS1_0_CLIENT | SP_PROT_TLS1_0_SERVER | |
+#endif | |
+#ifdef POLARSSL_SSL_PROTO_TLS1_1 | |
+ | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_1_SERVER | |
+#endif | |
+#ifdef POLARSSL_SSL_PROTO_TLS1_2 | |
+ | SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_2_SERVER | |
+#endif | |
+ ; | |
+} | |
+ | |
+FILE *log_file = NULL; | |
+ | |
+static void schan_polarssl_log(void *ctx, int level, const char *msg) | |
+{ | |
+ if (!log_file) | |
+ { | |
+ log_file = fopen("c:\\\\polarssl_log.txt", "w+"); | |
+ } | |
+ | |
+ fprintf(log_file, "POLARSSL log: <%d> %s\n", level, msg); | |
+ fflush(log_file); | |
+ | |
+ //WARN("POLARSSL log: <%d> %s\n", level, msg); | |
+} | |
+ | |
+static int schan_verify(void *data, x509_crt *crt, int depth, int *flags) | |
+{ | |
+ char buf[1024]; | |
+ int crt_flags = *flags; | |
+ ((void) data); | |
+ | |
+ WARN("POLARSSL schan_verify: Verify requested for (Depth %d):\n", depth); | |
+ x509_crt_info(buf, sizeof(buf) - 1, "", crt); | |
+ WARN("%s\n", buf); | |
+ | |
+ if (crt_flags & BADCERT_EXPIRED) | |
+ WARN(" ! server certificate has expired\n"); | |
+ if (crt_flags & BADCERT_REVOKED) | |
+ WARN(" ! server certificate has been revoked\n"); | |
+ if (crt_flags & BADCERT_CN_MISMATCH) | |
+ WARN(" ! CN mismatch\n"); | |
+ if (crt_flags & BADCERT_NOT_TRUSTED) | |
+ WARN(" ! self-signed or not signed by a trusted CA\n"); | |
+ if (crt_flags & BADCRL_NOT_TRUSTED) | |
+ WARN(" ! CRL not trusted\n"); | |
+ if (crt_flags & BADCRL_EXPIRED) | |
+ WARN(" ! CRL expired\n"); | |
+ if (crt_flags & BADCERT_OTHER) | |
+ WARN(" ! other (unknown) flag\n"); | |
+ if (crt_flags == 0) | |
+ WARN(" This certificate has no flags\n"); | |
+ return 0; | |
+} | |
+ | |
+BOOL schan_imp_create_session(schan_imp_session *session, schan_credentials *cred) | |
+{ | |
+ POLARSSL_SESSION *s; | |
+ int ret; | |
+ | |
+ WARN("POLARSSL schan_imp_create_session: %p %p %p\n", session, *session, cred); | |
+ s = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(POLARSSL_SESSION)); | |
+ | |
+ if (!(*session = (schan_imp_session)s)) | |
+ { | |
+ ERR("Not enough memory to create session\n"); | |
+ return FALSE; | |
+ } | |
+ | |
+ WARN("POLARSSL init entropy\n"); | |
+ entropy_init(&s->entropy); | |
+ | |
+ FIXME("POLARSSL init random - change static entropy private data\n"); | |
+ ret = ctr_drbg_init(&s->ctr_drbg, entropy_func, &s->entropy, | |
+ (const unsigned char *)"PolarSSL", 8); | |
+ if (ret != 0) | |
+ { | |
+ ERR("ctr_drbg_init failed with -%x\n", -ret); | |
+ entropy_free(&s->entropy); | |
+ HeapFree(GetProcessHeap(), 0, s); | |
+ return FALSE; | |
+ } | |
+ | |
+ WARN("POLARSSL init ssl\n"); | |
+ | |
+ ret = ssl_init(&s->ssl); | |
+ if (ret != 0) | |
+ { | |
+ ERR("Error SSL initialization -%x.\n", -ret); | |
+ ctr_drbg_free(&s->ctr_drbg); | |
+ entropy_free(&s->entropy); | |
+ HeapFree(GetProcessHeap(), 0, s); | |
+ return FALSE; | |
+ } | |
+ | |
+ WARN("POLARSSL set dbg\n"); | |
+ ssl_set_dbg(&s->ssl, schan_polarssl_log, stdout); | |
+ | |
+ WARN("POLARSSL set BIO callbacks\n"); | |
+ ssl_set_bio(&s->ssl, schan_pull_adapter, s, schan_push_adapter, s); | |
+ | |
+ WARN("POLARSSL set endpoint %d\n", cred->credential_use); | |
+ ssl_set_endpoint(&s->ssl, (cred->credential_use & SECPKG_CRED_INBOUND) ? SSL_IS_SERVER : SSL_IS_CLIENT); | |
+ //ssl_set_endpoint(&s->ssl, SSL_IS_CLIENT); | |
+ | |
+ WARN("POLARSSL set authmode\n"); | |
+ ssl_set_authmode(&s->ssl, SSL_VERIFY_NONE); //SSL_VERIFY_REQUIRED); | |
+ | |
+ //WARN("POLARSSL parse certificate %p\n", cred->credentials); | |
+ | |
+ #if 0 | |
+ if (cred->credentials) | |
+ { | |
+ char buf[2000]; | |
+ x509_crt cacert; | |
+ ret = x509_crt_parse(&cacert, (const unsigned char *)cred->credentials, | |
+ strlen((const char *)cred->credentials)); | |
+ | |
+ if (ret < 0) | |
+ { | |
+ ERR("Loading the CA root certificate failed! x509_crt_parse returned -0x%x", -ret); | |
+ | |
+ schan_imp_dispose_session((schan_imp_session)&s); | |
+ return FALSE; | |
+ } | |
+ | |
+ x509_crt_info(buf, sizeof(buf) - 1, "", &cacert); | |
+ ERR("POLARSSL cred->credentials: %s\n", buf); | |
+ | |
+ WARN("POLARSSL set server ca chain\n"); | |
+ | |
+ ssl_set_ca_chain(&s->ssl, (x509_crt *)cred->credentials, NULL, | |
+ (cred->credential_use & SECPKG_CRED_INBOUND) ? "ReactOS w/ PolarSSL Server" : "ReactOS w/ PolarSSL client" ); | |
+ } | |
+ #endif | |
+ | |
+ WARN("POLARSSL set rng\n"); | |
+ ssl_set_rng(&s->ssl, ctr_drbg_random, &s->ctr_drbg); | |
+ | |
+ WARN("POLARSSL set verify\n"); | |
+ ssl_set_verify(&s->ssl, schan_verify, NULL); | |
+ | |
+ WARN("POLARSSL set versions\n"); | |
+ ssl_set_min_version(&s->ssl, SSL_MIN_MAJOR_VERSION, SSL_MIN_MINOR_VERSION); | |
+ ssl_set_max_version(&s->ssl, SSL_MAX_MAJOR_VERSION, SSL_MAX_MINOR_VERSION); | |
+ | |
+ WARN("POLARSSL schan_imp_create_session END!\n"); | |
+ | |
+ return TRUE; | |
+} | |
+ | |
+void schan_imp_dispose_session(schan_imp_session session) | |
+{ | |
+ POLARSSL_SESSION *s = (POLARSSL_SESSION *)session; | |
+ WARN("POLARSSL schan_imp_dispose_session: %p\n", session); | |
+ | |
+ /* tell the other peer (a server) that we are going away */ | |
+ //ssl_close_notify(&s->ssl); | |
+ | |
+ /* wait for a bit, terrible */ | |
+ //Sleep(350); | |
+ | |
+ //s->transport = NULL; | |
+ //ssl_set_bio(&s->ssl, NULL, NULL, NULL, NULL); | |
+ | |
+ ssl_free(&s->ssl); | |
+ ctr_drbg_free(&s->ctr_drbg); | |
+ entropy_free(&s->entropy); | |
+ | |
+ /* safely overwrite the freed context with zeroes */ | |
+ HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, s); | |
+} | |
+ | |
+void schan_imp_set_session_transport(schan_imp_session session, | |
+ struct schan_transport *t) | |
+{ | |
+ POLARSSL_SESSION *s = (POLARSSL_SESSION *)session; | |
+ | |
+ WARN("POLARSSL schan_imp_set_session_transport: %p %p %d\n", session, t, s->ssl.state); | |
+ | |
+ s->transport = t; | |
+} | |
+ | |
+void schan_imp_set_session_target(schan_imp_session session, const char *target) | |
+{ | |
+ POLARSSL_SESSION *s = (POLARSSL_SESSION *)session; | |
+ | |
+ FIXME("POLARSSL schan_imp_set_session_target: sess: %p hostname: %s state: %d\n", session, target, s->ssl.state); | |
+ | |
+ ssl_set_hostname(&s->ssl, target); | |
+} | |
+ | |
+SECURITY_STATUS schan_imp_handshake(schan_imp_session session) | |
+{ | |
+ POLARSSL_SESSION *s = (POLARSSL_SESSION *)session; | |
+ | |
+ int err = ssl_handshake(&s->ssl); | |
+ | |
+ WARN("POLARSSL schan_imp_handshake: %p %d err: %#x \n", session, s->ssl.state, err); | |
+ | |
+ if ((err & ROS_SCHAN_IS_BLOCKING) == ROS_SCHAN_IS_BLOCKING) | |
+ { | |
+ WARN("Received ERR_NET_WANT_READ/WRITE... let's try again!\n"); | |
+ return SEC_I_CONTINUE_NEEDED; | |
+ } | |
+ else if (err == POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE) | |
+ { | |
+ ERR("schan_imp_handshake: SSL Feature unavailable...\n"); | |
+ return SEC_E_UNSUPPORTED_FUNCTION; | |
+ } | |
+ else if (err != 0) | |
+ { | |
+ ERR("schan_imp_handshake: Oops! ssl_handshake returned the following error code: -%#x...\n", -err); | |
+ return SEC_E_INTERNAL_ERROR; | |
+ } | |
+ | |
+ WARN("schan_imp_handshake: Handshake completed!\n"); | |
+ WARN("schan_imp_handshake: Protocol is %s, Cipher suite is %s\n", ssl_get_version(&s->ssl), ssl_get_ciphersuite(&s->ssl)); | |
+ return SEC_E_OK; | |
+} | |
+ | |
+static unsigned int schannel_get_cipher_block_size(int ciphersuite_id) | |
+{ | |
+ const ssl_ciphersuite_t *cipher_suite = ssl_ciphersuite_from_id(ciphersuite_id); | |
+ const struct | |
+ { | |
+ int algo; | |
+ unsigned int size; | |
+ } | |
+ algorithms[] = | |
+ { | |
+ {POLARSSL_CIPHER_NONE, 1}, | |
+ {POLARSSL_CIPHER_NULL, 1}, | |
+ | |
+ #ifdef POLARSSL_AES_C | |
+ {POLARSSL_CIPHER_AES_128_ECB, 16}, | |
+ {POLARSSL_CIPHER_AES_192_ECB, 16}, | |
+ {POLARSSL_CIPHER_AES_256_ECB, 16}, | |
+ {POLARSSL_CIPHER_AES_128_CBC, 16}, | |
+ {POLARSSL_CIPHER_AES_192_CBC, 16}, | |
+ {POLARSSL_CIPHER_AES_256_CBC, 16}, | |
+ {POLARSSL_CIPHER_AES_128_CFB128, 16}, | |
+ {POLARSSL_CIPHER_AES_192_CFB128, 16}, | |
+ {POLARSSL_CIPHER_AES_256_CFB128, 16}, | |
+ {POLARSSL_CIPHER_AES_128_CTR, 16}, | |
+ {POLARSSL_CIPHER_AES_192_CTR, 16}, | |
+ {POLARSSL_CIPHER_AES_256_CTR, 16}, | |
+ {POLARSSL_CIPHER_AES_128_GCM, 16}, | |
+ {POLARSSL_CIPHER_AES_192_GCM, 16}, | |
+ {POLARSSL_CIPHER_AES_256_GCM, 16}, | |
+ #endif | |
+ | |
+ #ifdef POLARSSL_CAMELLIA_C | |
+ {POLARSSL_CIPHER_CAMELLIA_128_ECB, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_ECB, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_ECB, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_128_CBC, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_CBC, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_CBC, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_128_CFB128, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_CFB128, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_CFB128, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_128_CTR, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_CTR, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_CTR, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_128_GCM, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_GCM, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_GCM, 16}, | |
+ #endif | |
+ | |
+ #ifdef POLARSSL_DES_C | |
+ {POLARSSL_CIPHER_DES_ECB, 8}, | |
+ {POLARSSL_CIPHER_DES_CBC, 8}, | |
+ {POLARSSL_CIPHER_DES_EDE_ECB, 8}, | |
+ {POLARSSL_CIPHER_DES_EDE_CBC, 8}, | |
+ {POLARSSL_CIPHER_DES_EDE3_ECB, 8}, | |
+ {POLARSSL_CIPHER_DES_EDE3_CBC, 8}, | |
+ #endif | |
+ | |
+ #ifdef POLARSSL_BLOWFISH_C | |
+ {POLARSSL_CIPHER_BLOWFISH_ECB, 8}, | |
+ {POLARSSL_CIPHER_BLOWFISH_CBC, 8}, | |
+ {POLARSSL_CIPHER_BLOWFISH_CFB64, 8}, | |
+ {POLARSSL_CIPHER_BLOWFISH_CTR, 8}, | |
+ #endif | |
+ | |
+ #ifdef POLARSSL_ARC4_C | |
+ {POLARSSL_CIPHER_ARC4_128, 1}, | |
+ #endif | |
+ | |
+ #ifdef POLARSSL_CCM_C | |
+ {POLARSSL_CIPHER_AES_128_CCM, 16}, | |
+ {POLARSSL_CIPHER_AES_192_CCM, 16}, | |
+ {POLARSSL_CIPHER_AES_256_CCM, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_128_CCM, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_CCM, 16}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_CCM, 16}, | |
+ #endif | |
+ }; | |
+ | |
+ int i; | |
+ for (i = 0; i < _countof(algorithms); i++) | |
+ { | |
+ if (algorithms[i].algo == cipher_suite->cipher) | |
+ return algorithms[i].size; | |
+ } | |
+ | |
+ FIXME("POLARSSL schannel_get_cipher_block_size: Unknown cipher %#x, returning 1\n", ciphersuite_id); | |
+ | |
+ return 1; | |
+} | |
+ | |
+static unsigned int schannel_get_cipher_key_size(int ciphersuite_id) | |
+{ | |
+ const ssl_ciphersuite_t *cipher_suite = ssl_ciphersuite_from_id(ciphersuite_id); | |
+ const struct | |
+ { | |
+ int algo; | |
+ unsigned int size; | |
+ } | |
+ algorithms[] = | |
+ { | |
+ {POLARSSL_CIPHER_NONE, 0}, | |
+ {POLARSSL_CIPHER_NULL, 0}, | |
+ | |
+ #ifdef POLARSSL_AES_C | |
+ {POLARSSL_CIPHER_AES_128_ECB, 128}, | |
+ {POLARSSL_CIPHER_AES_192_ECB, 192}, | |
+ {POLARSSL_CIPHER_AES_256_ECB, 256}, | |
+ {POLARSSL_CIPHER_AES_128_CBC, 128}, | |
+ {POLARSSL_CIPHER_AES_192_CBC, 192}, | |
+ {POLARSSL_CIPHER_AES_256_CBC, 256}, | |
+ {POLARSSL_CIPHER_AES_128_CFB128, 128}, | |
+ {POLARSSL_CIPHER_AES_192_CFB128, 192}, | |
+ {POLARSSL_CIPHER_AES_256_CFB128, 256}, | |
+ {POLARSSL_CIPHER_AES_128_CTR, 128}, | |
+ {POLARSSL_CIPHER_AES_192_CTR, 192}, | |
+ {POLARSSL_CIPHER_AES_256_CTR, 256}, | |
+ {POLARSSL_CIPHER_AES_128_GCM, 128}, | |
+ {POLARSSL_CIPHER_AES_192_GCM, 192}, | |
+ {POLARSSL_CIPHER_AES_256_GCM, 256}, | |
+ #endif | |
+ | |
+ #ifdef POLARSSL_CAMELLIA_C | |
+ {POLARSSL_CIPHER_CAMELLIA_128_ECB, 128}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_ECB, 192}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_ECB, 256}, | |
+ {POLARSSL_CIPHER_CAMELLIA_128_CBC, 128}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_CBC, 192}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_CBC, 256}, | |
+ {POLARSSL_CIPHER_CAMELLIA_128_CFB128, 128}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_CFB128, 192}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_CFB128, 256}, | |
+ {POLARSSL_CIPHER_CAMELLIA_128_CTR, 128}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_CTR, 192}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_CTR, 256}, | |
+ {POLARSSL_CIPHER_CAMELLIA_128_GCM, 128}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_GCM, 192}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_GCM, 256}, | |
+ #endif | |
+ | |
+ #ifdef POLARSSL_DES_C | |
+ {POLARSSL_CIPHER_DES_ECB, 56}, | |
+ {POLARSSL_CIPHER_DES_CBC, 56}, | |
+ {POLARSSL_CIPHER_DES_EDE_ECB, 128}, | |
+ {POLARSSL_CIPHER_DES_EDE_CBC, 128}, | |
+ {POLARSSL_CIPHER_DES_EDE3_ECB, 192}, | |
+ {POLARSSL_CIPHER_DES_EDE3_CBC, 192}, | |
+ #endif | |
+ | |
+ #ifdef POLARSSL_BLOWFISH_C /* lies! actually unlimited, */ | |
+ {POLARSSL_CIPHER_BLOWFISH_ECB, 128}, /* gnutls uses this same value. */ | |
+ {POLARSSL_CIPHER_BLOWFISH_CBC, 128}, /* BLOWFISH_MAX_KEY = 448 bits */ | |
+ {POLARSSL_CIPHER_BLOWFISH_CFB64, 128}, /* BLOWFISH_MIN_KEY = 032 bits */ | |
+ {POLARSSL_CIPHER_BLOWFISH_CTR, 128}, /* see blowfish.h for more info */ | |
+ #endif | |
+ | |
+ #ifdef POLARSSL_ARC4_C | |
+ {POLARSSL_CIPHER_ARC4_128, 128}, | |
+ #endif | |
+ | |
+ #ifdef POLARSSL_CCM_C | |
+ {POLARSSL_CIPHER_AES_128_CCM, 128}, | |
+ {POLARSSL_CIPHER_AES_192_CCM, 192}, | |
+ {POLARSSL_CIPHER_AES_256_CCM, 256}, | |
+ {POLARSSL_CIPHER_CAMELLIA_128_CCM, 128}, | |
+ {POLARSSL_CIPHER_CAMELLIA_192_CCM, 192}, | |
+ {POLARSSL_CIPHER_CAMELLIA_256_CCM, 256}, | |
+ #endif | |
+ }; | |
+ | |
+ int i; | |
+ | |
+ for (i = 0; i < _countof(algorithms); i++) | |
+ { | |
+ if (algorithms[i].algo == cipher_suite->cipher) | |
+ return algorithms[i].size; | |
+ } | |
+ | |
+ FIXME("POLARSSL schannel_get_cipher_key_size: Unknown cipher %#x, returning 0\n", ciphersuite_id); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static unsigned int schannel_get_mac_key_size(int ciphersuite_id) | |
+{ | |
+ const ssl_ciphersuite_t *cipher_suite = ssl_ciphersuite_from_id(ciphersuite_id); | |
+ const unsigned int algorithms[] = | |
+ { | |
+ 0, /* POLARSSL_MD_NONE */ | |
+ 0, /* POLARSSL_MD_MD2 (not used as MAC) */ | |
+ 128, /* POLARSSL_MD_MD4 */ | |
+ 128, /* POLARSSL_MD_MD5 */ | |
+ 160, /* POLARSSL_MD_SHA1 */ | |
+ 224, /* POLARSSL_MD_SHA224 */ | |
+ 256, /* POLARSSL_MD_SHA256 */ | |
+ 384, /* POLARSSL_MD_SHA384 */ | |
+ 512, /* POLARSSL_MD_SHA512 */ | |
+ 160 /* POLARSSL_MD_RIPEMD160 */ | |
+ }; | |
+ | |
+ if (cipher_suite->mac >= 0 && cipher_suite->mac < _countof(algorithms)) | |
+ { | |
+ return algorithms[cipher_suite->mac]; | |
+ } | |
+ | |
+ FIXME("POLARSSL schannel_get_mac_key_size: Unknown mac %#x for ciphersuite %#x, returning 0\n", cipher_suite->mac, ciphersuite_id); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static unsigned int schannel_get_kx_key_size(const ssl_context *ssl, int ciphersuite_id) | |
+{ | |
+ const ssl_ciphersuite_t *cipher_suite = ssl_ciphersuite_from_id(ciphersuite_id); | |
+ | |
+ /* if we are the server take ca_chain, if we are the client take server cert (peer_cert) */ | |
+ x509_crt *server_cert = (ssl->endpoint == SSL_IS_SERVER) ? ssl->ca_chain : ssl->session->peer_cert; | |
+ | |
+ if (cipher_suite->key_exchange != POLARSSL_KEY_EXCHANGE_NONE) | |
+ return server_cert->pk.pk_info->get_size(server_cert->pk.pk_ctx); | |
+ | |
+ FIXME("POLARSSL schannel_get_kx_key_size: Unknown kx %#x, returning 0\n", cipher_suite->key_exchange); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static DWORD schannel_get_protocol(const ssl_context *ssl) | |
+{ | |
+ /* FIXME: currently schannel only implements client connections, but | |
+ * there's no reason it couldn't be used for servers as well. The | |
+ * context doesn't tell us which it is, so decide based on ssl endpoint value. */ | |
+ | |
+ switch (ssl->minor_ver) | |
+ { | |
+ case SSL_MINOR_VERSION_0: | |
+ return (ssl->endpoint == SSL_IS_CLIENT) ? SP_PROT_SSL3_CLIENT : | |
+ SP_PROT_SSL3_SERVER | |
+ ; | |
+ | |
+ case SSL_MINOR_VERSION_1: | |
+ return (ssl->endpoint == SSL_IS_CLIENT) ? SP_PROT_TLS1_0_CLIENT : | |
+ SP_PROT_TLS1_0_SERVER | |
+ ; | |
+ | |
+ case SSL_MINOR_VERSION_2: | |
+ return (ssl->endpoint == SSL_IS_CLIENT) ? SP_PROT_TLS1_1_CLIENT : | |
+ SP_PROT_TLS1_1_SERVER | |
+ ; | |
+ | |
+ case SSL_MINOR_VERSION_3: | |
+ return (ssl->endpoint == SSL_IS_CLIENT) ? SP_PROT_TLS1_2_CLIENT : | |
+ SP_PROT_TLS1_2_SERVER | |
+ ; | |
+ | |
+ default: | |
+ { | |
+ FIXME("POLARSSL schannel_get_protocol: unknown protocol %d\n", ssl->minor_ver); | |
+ return 0; | |
+ } | |
+ } | |
+} | |
+ | |
+static ALG_ID schannel_get_cipher_algid(int ciphersuite_id) | |
+{ | |
+ const ssl_ciphersuite_t *cipher_suite = ssl_ciphersuite_from_id(ciphersuite_id); | |
+ | |
+ switch (cipher_suite->cipher) | |
+ { | |
+ case POLARSSL_CIPHER_NONE: | |
+ case POLARSSL_CIPHER_NULL: | |
+ return 0; | |
+ | |
+#ifdef POLARSSL_ARC4_C | |
+ /* ARC4 */ | |
+ case POLARSSL_CIPHER_ARC4_128: | |
+ return CALG_RC4; | |
+#endif | |
+ | |
+ | |
+#ifdef POLARSSL_DES_C | |
+ /* DES */ | |
+ case POLARSSL_CIPHER_DES_ECB: | |
+ case POLARSSL_CIPHER_DES_CBC: | |
+ case POLARSSL_CIPHER_DES_EDE_ECB: | |
+ case POLARSSL_CIPHER_DES_EDE_CBC: | |
+ return CALG_DES; | |
+ | |
+ case POLARSSL_CIPHER_DES_EDE3_ECB: | |
+ case POLARSSL_CIPHER_DES_EDE3_CBC: | |
+ return CALG_3DES; | |
+#endif | |
+ | |
+#ifdef POLARSSL_AES_C | |
+ /* AES 128 */ | |
+ case POLARSSL_CIPHER_AES_128_ECB: | |
+ case POLARSSL_CIPHER_AES_128_CBC: | |
+ case POLARSSL_CIPHER_AES_128_CFB128: | |
+ case POLARSSL_CIPHER_AES_128_CTR: | |
+ case POLARSSL_CIPHER_AES_128_GCM: | |
+ #ifdef POLARSSL_CCM_C | |
+ case POLARSSL_CIPHER_AES_128_CCM: | |
+ #endif | |
+ return CALG_AES_128; | |
+ | |
+ case POLARSSL_CIPHER_AES_192_ECB: | |
+ case POLARSSL_CIPHER_AES_192_CBC: | |
+ case POLARSSL_CIPHER_AES_192_CFB128: | |
+ case POLARSSL_CIPHER_AES_192_CTR: | |
+ case POLARSSL_CIPHER_AES_192_GCM: | |
+ #ifdef POLARSSL_CCM_C | |
+ case POLARSSL_CIPHER_AES_192_CCM: | |
+ #endif | |
+ return CALG_AES_192; | |
+ | |
+ case POLARSSL_CIPHER_AES_256_ECB: | |
+ case POLARSSL_CIPHER_AES_256_CBC: | |
+ case POLARSSL_CIPHER_AES_256_CFB128: | |
+ case POLARSSL_CIPHER_AES_256_CTR: | |
+ case POLARSSL_CIPHER_AES_256_GCM: | |
+ #ifdef POLARSSL_CCM_C | |
+ case POLARSSL_CIPHER_AES_256_CCM: | |
+ #endif | |
+ return CALG_AES_256; | |
+#endif | |
+ | |
+ /* nothing to show? fall through */ | |
+ default: | |
+ { | |
+ FIXME("POLARSSL schannel_get_cipher_algid: unknown algorithm %d\n", ciphersuite_id); | |
+ return 0; | |
+ } | |
+ } | |
+} | |
+ | |
+static ALG_ID schannel_get_mac_algid(int ciphersuite_id) | |
+{ | |
+ const ssl_ciphersuite_t *cipher_suite = ssl_ciphersuite_from_id(ciphersuite_id); | |
+ | |
+ switch (cipher_suite->mac) | |
+ { | |
+ case POLARSSL_MD_NONE: return 0; | |
+ case POLARSSL_MD_MD2: return CALG_MD2; | |
+ case POLARSSL_MD_MD4: return CALG_MD4; | |
+ case POLARSSL_MD_MD5: return CALG_MD5; | |
+ case POLARSSL_MD_SHA1: return CALG_SHA1; | |
+ case POLARSSL_MD_SHA224: return CALG_SHA; | |
+ case POLARSSL_MD_SHA256: return CALG_SHA_256; | |
+ case POLARSSL_MD_SHA384: return CALG_SHA_384; | |
+ case POLARSSL_MD_SHA512: return CALG_SHA_512; | |
+ case POLARSSL_MD_RIPEMD160: return (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_RIPEMD160); /* there's no CALG_RIPEMD or CALG_RIPEMD160 defined in <wincrypt.h> yet */ | |
+ | |
+ default: | |
+ { | |
+ FIXME("POLARSSL schannel_get_mac_algid: unknown algorithm %d\n", cipher_suite->mac); | |
+ return 0; | |
+ } | |
+ } | |
+} | |
+ | |
+static ALG_ID schannel_get_kx_algid(int ciphersuite_id) | |
+{ | |
+ const ssl_ciphersuite_t *cipher_suite = ssl_ciphersuite_from_id(ciphersuite_id); | |
+ | |
+ switch (cipher_suite->key_exchange) | |
+ { | |
+ case POLARSSL_KEY_EXCHANGE_NONE: | |
+ return 0; | |
+ | |
+ case POLARSSL_KEY_EXCHANGE_ECDH_RSA: | |
+ case POLARSSL_KEY_EXCHANGE_ECDH_ECDSA: | |
+ case POLARSSL_KEY_EXCHANGE_ECDHE_PSK: | |
+ case POLARSSL_KEY_EXCHANGE_ECDHE_RSA: | |
+ return CALG_ECDH; | |
+ | |
+ case POLARSSL_KEY_EXCHANGE_RSA_PSK: | |
+ case POLARSSL_KEY_EXCHANGE_RSA: | |
+ return CALG_RSA_KEYX; | |
+ | |
+ case POLARSSL_KEY_EXCHANGE_DHE_PSK: | |
+ case POLARSSL_KEY_EXCHANGE_DHE_RSA: | |
+ return CALG_DH_EPHEM; | |
+ | |
+ default: | |
+ { | |
+ FIXME("POLARSSL schannel_get_kx_algid: unknown algorithm %d\n", cipher_suite->key_exchange); | |
+ return 0; | |
+ } | |
+ } | |
+} | |
+ | |
+unsigned int schan_imp_get_session_cipher_block_size(schan_imp_session session) | |
+{ | |
+ POLARSSL_SESSION *s = (POLARSSL_SESSION *)session; | |
+ WARN("POLARSSL schan_imp_get_session_cipher_block_size %p.\n", session); | |
+ | |
+ return schannel_get_cipher_block_size(ssl_get_ciphersuite_id(ssl_get_ciphersuite(&s->ssl))); | |
+} | |
+ | |
+unsigned int schan_imp_get_max_message_size(schan_imp_session session) | |
+{ | |
+ POLARSSL_SESSION *s = (POLARSSL_SESSION *)session; | |
+ WARN("POLARSSL schan_imp_get_max_message_size %p.\n", session); | |
+ | |
+ return s->ssl.in_msglen; | |
+} | |
+ | |
+SECURITY_STATUS schan_imp_get_connection_info(schan_imp_session session, | |
+ SecPkgContext_ConnectionInfo *info) | |
+{ | |
+ POLARSSL_SESSION *s = (POLARSSL_SESSION *)session; | |
+ | |
+ int ciphersuite_id = ssl_get_ciphersuite_id(ssl_get_ciphersuite(&s->ssl)); | |
+ | |
+ WARN("POLARSSL schan_imp_get_connection_info %p %p.\n", session, info); | |
+ | |
+ info->dwProtocol = schannel_get_protocol(&s->ssl); | |
+ info->aiCipher = schannel_get_cipher_algid(ciphersuite_id); | |
+ info->dwCipherStrength = schannel_get_cipher_key_size(ciphersuite_id); | |
+ info->aiHash = schannel_get_mac_algid(ciphersuite_id); | |
+ info->dwHashStrength = schannel_get_mac_key_size(ciphersuite_id); | |
+ info->aiExch = schannel_get_kx_algid(ciphersuite_id); | |
+ info->dwExchStrength = schannel_get_kx_key_size(&s->ssl, ciphersuite_id); | |
+ | |
+ return SEC_E_OK; | |
+} | |
+ | |
+SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session, HCERTSTORE store, | |
+ PCCERT_CONTEXT *ret) | |
+{ | |
+ POLARSSL_SESSION *s = (POLARSSL_SESSION *)session; | |
+ PCCERT_CONTEXT cert_context = NULL; | |
+ const x509_crt *next_cert; | |
+ | |
+ WARN("POLARSSL schan_imp_get_session_peer_certificate %p %p %p %p.\n", session, store, ret, ret != NULL ? *ret : NULL); | |
+ | |
+ if (!s->ssl.session->peer_cert) | |
+ return SEC_E_INTERNAL_ERROR; | |
+ | |
+ for (next_cert = s->ssl.session->peer_cert; next_cert != NULL; next_cert = next_cert->next) | |
+ { | |
+ if (!CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, next_cert->raw.p, next_cert->raw.len, | |
+ CERT_STORE_ADD_REPLACE_EXISTING, (next_cert != s->ssl.session->peer_cert) ? NULL : &cert_context)) | |
+ { | |
+ if (next_cert != s->ssl.session->peer_cert) | |
+ CertFreeCertificateContext(cert_context); | |
+ return GetLastError(); | |
+ } | |
+ } | |
+ | |
+ *ret = cert_context; | |
+ return SEC_E_OK; | |
+} | |
+ | |
+SECURITY_STATUS schan_imp_send(schan_imp_session session, const void *buffer, | |
+ SIZE_T *length) | |
+{ | |
+ POLARSSL_SESSION *s = (POLARSSL_SESSION *)session; | |
+ int ret; | |
+ | |
+//again: | |
+ dbg_buffer_print((unsigned char *)buffer, *length); | |
+ ret = ssl_write(&s->ssl, (unsigned char *)buffer, *length); | |
+ | |
+ WARN("POLARSSL schan_imp_send: (%p, %p, %p/%lu)\n", s, buffer, length, *length); | |
+ | |
+ if (ret >= 0) | |
+ { | |
+ WARN("POLARSSL schan_imp_send: ret=%lu.\n", ret); | |
+ | |
+ *length = ret; | |
+ } | |
+ else if ((ret & ROS_SCHAN_IS_BLOCKING) == ROS_SCHAN_IS_BLOCKING) | |
+ { | |
+ *length = ROS_SCHAN_IS_BLOCKING_RETRIEVE(ret); | |
+ | |
+ if (!*length) | |
+ { | |
+ WARN("POLARSSL schan_imp_send: ret=POLARSSL_ERR_NET_WANT_WRITE -> SEC_I_CONTINUE_NEEDED; len=%u", length); | |
+ return SEC_I_CONTINUE_NEEDED; | |
+ } | |
+ else | |
+ { | |
+ WARN("POLARSSL schan_imp_send: ret=POLARSSL_ERR_NET_WANT_WRITE -> SEC_E_OK; len=%u", length); | |
+ return SEC_E_OK; | |
+ } | |
+ } | |
+ else | |
+ { | |
+ ERR("POLARSSL schan_imp_send: ssl_write failed with -%x\n", -ret); | |
+ return SEC_E_INTERNAL_ERROR; | |
+ } | |
+ | |
+ return SEC_E_OK; | |
+} | |
+ | |
+SECURITY_STATUS schan_imp_recv(schan_imp_session session, void *buffer, | |
+ SIZE_T *length) | |
+{ | |
+ PPOLARSSL_SESSION s = (PPOLARSSL_SESSION)session; | |
+ int ret; | |
+ | |
+ WARN("POLARSSL schan_imp_recv: (%p, %p, %p/%lu)\n", s, buffer, length, *length); | |
+ | |
+//again: | |
+ ret = ssl_read(&s->ssl, (unsigned char *)buffer, *length); | |
+ dbg_buffer_print((unsigned char *)buffer, *length); | |
+ | |
+ WARN("POLARSSL schan_imp_recv: (%p, %p, %p/%lu) ret= %#x\n", s, buffer, length, *length, ret); | |
+ | |
+ if (ret >= 0) | |
+ { | |
+ WARN("POLARSSL schan_imp_recv: ret == %lu.\n", ret); | |
+ | |
+ *length = ret; | |
+ } | |
+ else if ((ret & ROS_SCHAN_IS_BLOCKING) == ROS_SCHAN_IS_BLOCKING) | |
+ { | |
+ *length = ROS_SCHAN_IS_BLOCKING_RETRIEVE(ret); | |
+ | |
+ if (!*length) | |
+ { | |
+ WARN("POLARSSL schan_imp_recv: ret=POLARSSL_ERR_NET_WANT_WRITE -> SEC_I_CONTINUE_NEEDED; len=%u", length); | |
+ return SEC_I_CONTINUE_NEEDED; | |
+ } | |
+ else | |
+ { | |
+ WARN("POLARSSL schan_imp_recv: ret=POLARSSL_ERR_NET_WANT_WRITE -> SEC_E_OK; len=%u", length); | |
+ return SEC_E_OK; | |
+ } | |
+ } | |
+ // else if (ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) | |
+ // { | |
+ // WARN("POLARSSL schan_imp_recv: ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY -> SEC_E_OK\n"); | |
+ // return SEC_E_OK; | |
+ // } | |
+ else | |
+ { | |
+ ERR("POLARSSL schan_imp_recv: ssl_read failed with -%x\n", -ret); | |
+ return SEC_E_INTERNAL_ERROR; | |
+ } | |
+ | |
+ return SEC_E_OK; | |
+} | |
+ | |
+BOOL schan_imp_allocate_certificate_credentials(schan_credentials *c) | |
+{ | |
+ WARN("POLARSSL schan_imp_allocate_certificate_credentials %p %p %d\n", c, c->credentials, c->credential_use); | |
+ | |
+ c->credentials = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(x509_crt)); | |
+ | |
+ if (!c->credentials) | |
+ return FALSE; | |
+ | |
+ x509_crt_init((x509_crt *)c->credentials); | |
+ return TRUE; | |
+} | |
+ | |
+void schan_imp_free_certificate_credentials(schan_credentials *c) | |
+{ | |
+ WARN("POLARSSL schan_imp_free_certificate_credentials %p %p %d\n", c, c->credentials, c->credential_use); | |
+ | |
+ if (!c->credentials) | |
+ return; | |
+ | |
+ x509_crt_free( (x509_crt*)c->credentials ); | |
+ HeapFree(GetProcessHeap(), 0, c->credentials); | |
+} | |
+ | |
+BOOL schan_imp_init(void) | |
+{ | |
+ WARN("Schannel POLARSSL schan_imp_init\n"); | |
+ | |
+ //if (WARN_ON(secur32)) | |
+ //debug_set_threshold(5); | |
+ return TRUE; | |
+} | |
+ | |
+void schan_imp_deinit(void) | |
+{ | |
+ WARN("Schannel POLARSSL schan_imp_deinit\n"); | |
+} | |
Index: dll/win32/schannel/schannel_wine.c | |
=================================================================== | |
--- dll/win32/schannel/schannel_wine.c (revision 68875) | |
+++ dll/win32/schannel/schannel_wine.c (working copy) | |
@@ -22,8 +22,6 @@ | |
#include <wine/config.h> | |
-#if defined(SONAME_LIBGNUTLS) || defined (HAVE_SECURITY_SECURITY_H) | |
- | |
#define SCHAN_INVALID_HANDLE ~0UL | |
enum schan_handle_type | |
@@ -57,6 +55,16 @@ | |
/* Protocols disabled by default. They are enabled for using, but disabled when caller asks for default settings. */ | |
static DWORD config_default_disabled_protocols; | |
+static void schan_dump_buffer(char *buffer, SIZE_T len, char *pref) | |
+{ | |
+ size_t i = 0; | |
+ while (i > len) | |
+ { | |
+ WARN("%S => %#04x | %#02x %c\n", pref, buffer[i], buffer[i]); | |
+ i++; | |
+ } | |
+} | |
+ | |
static ULONG_PTR schan_alloc_handle(void *object, enum schan_handle_type type) | |
{ | |
struct schan_handle *handle; | |
@@ -771,7 +779,7 @@ | |
SIZE_T expected_size = ~0UL; | |
SECURITY_STATUS ret; | |
- TRACE("%p %p %s 0x%08x %d %d %p %d %p %p %p %p\n", phCredential, phContext, | |
+ WARN("schan_InitializeSecurityContextW: %p %p %s 0x%08x %d %d %p %d %p %p %p %p\n", phCredential, phContext, | |
debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput, | |
Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry); | |
@@ -782,6 +790,9 @@ | |
{ | |
ULONG_PTR handle; | |
+ WARN("schan_InitializeSecurityContextW called without context\n"); | |
+ | |
+ | |
if (!phCredential) return SEC_E_INVALID_HANDLE; | |
cred = schan_get_object(phCredential->dwLower, SCHAN_HANDLE_CRED); | |
@@ -800,6 +811,9 @@ | |
handle = schan_alloc_handle(ctx, SCHAN_HANDLE_CTX); | |
if (handle == SCHAN_INVALID_HANDLE) | |
{ | |
+ | |
+ WARN("schan_InitializeSecurityContextW returned false ON schan_alloc_handle == SCHAN_INVALID_HANDLE\n"); | |
+ | |
HeapFree(GetProcessHeap(), 0, ctx); | |
return SEC_E_INTERNAL_ERROR; | |
} | |
@@ -806,11 +820,15 @@ | |
if (!schan_imp_create_session(&ctx->session, cred)) | |
{ | |
+ WARN("schan_imp_create_session returned false ON schan_imp_create_session\n"); | |
+ | |
schan_free_handle(handle, SCHAN_HANDLE_CTX); | |
HeapFree(GetProcessHeap(), 0, ctx); | |
return SEC_E_INTERNAL_ERROR; | |
} | |
+ WARN("schan_InitializeSecurityContextW returned true\n"); | |
+ | |
if (pszTargetName) | |
{ | |
UINT len = WideCharToMultiByte( CP_UNIXCP, 0, pszTargetName, -1, NULL, 0, NULL, NULL ); | |
@@ -833,6 +851,8 @@ | |
SecBuffer *buffer; | |
int idx; | |
+ WARN("schan_InitializeSecurityContextW called WITH context\n"); | |
+ | |
if (!pInput) | |
return SEC_E_INCOMPLETE_MESSAGE; | |
@@ -857,12 +877,12 @@ | |
if (!expected_size) | |
{ | |
- TRACE("Expected at least %lu bytes, but buffer only contains %u bytes.\n", | |
+ WARN("Expected at least %lu bytes, but buffer only contains %u bytes.\n", | |
max(6, record_size), buffer->cbBuffer); | |
return SEC_E_INCOMPLETE_MESSAGE; | |
} | |
- TRACE("Using expected_size %lu.\n", expected_size); | |
+ WARN("Using expected_size %lu.\n", expected_size); | |
ctx = schan_get_object(phContext->dwLower, SCHAN_HANDLE_CTX); | |
} | |
@@ -878,6 +898,8 @@ | |
/* Perform the TLS handshake */ | |
ret = schan_imp_handshake(ctx->session); | |
+ WARN("schan_InitializeSecurityContextW with schan_imp_handshake RETURNING %#x.\n", ret); | |
+ | |
if(transport.in.offset && transport.in.offset != pInput->pBuffers[0].cbBuffer) { | |
if(pInput->cBuffers<2 || pInput->pBuffers[1].BufferType!=SECBUFFER_EMPTY) | |
return SEC_E_INVALID_TOKEN; | |
@@ -897,6 +919,8 @@ | |
if (ctx->req_ctx_attr & ISC_REQ_ALLOCATE_MEMORY) | |
*pfContextAttr |= ISC_RET_ALLOCATED_MEMORY; | |
+ WARN("schan_InitializeSecurityContextW RETURNING %#x.\n", ret); | |
+ | |
return ret; | |
} | |
@@ -1083,7 +1107,7 @@ | |
char *data; | |
int idx; | |
- TRACE("context_handle %p, quality %d, message %p, message_seq_no %d\n", | |
+ WARN("schan_EncryptMessage: context_handle %p, quality %d, message %p, message_seq_no %d\n", | |
context_handle, quality, message, message_seq_no); | |
if (!context_handle) return SEC_E_INVALID_HANDLE; | |
@@ -1112,9 +1136,10 @@ | |
schan_imp_set_session_transport(ctx->session, &transport); | |
length = data_size; | |
+ schan_dump_buffer(data, length, "E"); | |
status = schan_imp_send(ctx->session, data, &length); | |
- TRACE("Sent %ld bytes.\n", length); | |
+ WARN("Sent %ld bytes.\n", length); | |
if (length != data_size) | |
status = SEC_E_INTERNAL_ERROR; | |
@@ -1123,7 +1148,7 @@ | |
b->desc->pBuffers[b->current_buffer_idx].cbBuffer = b->offset; | |
HeapFree(GetProcessHeap(), 0, data); | |
- TRACE("Returning %#x.\n", status); | |
+ WARN("schan_EncryptMessage: Returning %#x.\n", status); | |
return status; | |
} | |
@@ -1192,6 +1217,18 @@ | |
buffer->cbBuffer = size; | |
} | |
+ | |
+void dbg_buffer_print_x(unsigned char *buf, size_t len) | |
+{ | |
+ size_t i = 0; | |
+ | |
+ while(i < len) | |
+ { | |
+ WARN("%#05X| %#02x %c\n", i, buf[i], buf[i]); | |
+ i++; | |
+ } | |
+} | |
+ | |
static SECURITY_STATUS SEC_ENTRY schan_DecryptMessage(PCtxtHandle context_handle, | |
PSecBufferDesc message, ULONG message_seq_no, PULONG quality) | |
{ | |
@@ -1205,7 +1242,7 @@ | |
int idx; | |
unsigned char *buf_ptr; | |
- TRACE("context_handle %p, message %p, message_seq_no %d, quality %p\n", | |
+ WARN("schan_DecryptMessage: context_handle %p, message %p, message_seq_no %d, quality %p\n", | |
context_handle, message, message_seq_no, quality); | |
if (!context_handle) return SEC_E_INVALID_HANDLE; | |
@@ -1219,10 +1256,10 @@ | |
buffer = &message->pBuffers[idx]; | |
buf_ptr = buffer->pvBuffer; | |
- expected_size = 5 + ((buf_ptr[3] << 8) | buf_ptr[4]); | |
+ expected_size = (5 + ((buf_ptr[3] << 8) | buf_ptr[4])) + 160; | |
if(buffer->cbBuffer < expected_size) | |
{ | |
- TRACE("Expected %u bytes, but buffer only contains %u bytes\n", expected_size, buffer->cbBuffer); | |
+ WARN("schan_DecryptMessage: Expected %u bytes, but buffer only contains %u bytes\n", expected_size, buffer->cbBuffer); | |
buffer->BufferType = SECBUFFER_MISSING; | |
buffer->cbBuffer = expected_size - buffer->cbBuffer; | |
@@ -1232,7 +1269,7 @@ | |
buffer->BufferType = SECBUFFER_MISSING; | |
buffer->cbBuffer = expected_size - buffer->cbBuffer; | |
- TRACE("Returning SEC_E_INCOMPLETE_MESSAGE\n"); | |
+ WARN("schan_DecryptMessage: Returning SEC_E_INCOMPLETE_MESSAGE\n"); | |
return SEC_E_INCOMPLETE_MESSAGE; | |
} | |
@@ -1256,7 +1293,7 @@ | |
if (status != SEC_E_OK) | |
{ | |
HeapFree(GetProcessHeap(), 0, data); | |
- ERR("Returning %x\n", status); | |
+ ERR("schan_DecryptMessage: Returning %x\n", status); | |
return status; | |
} | |
@@ -1266,7 +1303,8 @@ | |
received += length; | |
} | |
- TRACE("Received %ld bytes\n", received); | |
+ WARN("schan_DecryptMessage: Received %ld bytes, expected %ld bytes //// difference: %ld \n", received, data_size, data_size-received); | |
+ schan_dump_buffer((char *)buf_ptr, data_size, "D"); | |
memcpy(buf_ptr + 5, data, received); | |
HeapFree(GetProcessHeap(), 0, data); | |
@@ -1284,6 +1322,7 @@ | |
buffer->BufferType = SECBUFFER_STREAM_HEADER; | |
buffer->cbBuffer = 5; | |
+ WARN("schan_DecryptMessage: Returning SEC_E_OK\n"); | |
return SEC_E_OK; | |
} | |
@@ -1458,14 +1497,3 @@ | |
HeapFree(GetProcessHeap(), 0, schan_handle_table); | |
schan_imp_deinit(); | |
} | |
- | |
-#else /* SONAME_LIBGNUTLS || HAVE_SECURITY_SECURITY_H */ | |
- | |
-void SECUR32_initSchannelSP(void) | |
-{ | |
- ERR("TLS library not found, SSL connections will fail\n"); | |
-} | |
- | |
-void SECUR32_deinitSchannelSP(void) {} | |
- | |
-#endif /* SONAME_LIBGNUTLS || HAVE_SECURITY_SECURITY_H */ | |
Index: dll/win32/secur32/sspi.c | |
=================================================================== | |
--- dll/win32/secur32/sspi.c (revision 68875) | |
+++ dll/win32/secur32/sspi.c (working copy) | |
@@ -791,7 +791,7 @@ | |
if (ret->provider && !ret->provider->loaded) | |
{ | |
- ret->provider->lib = LoadLibraryW(ret->provider->moduleName); | |
+ ret->provider->lib = LoadLibraryW(L"schannel.dll");//ret->provider->moduleName); | |
if (ret->provider->lib) | |
{ | |
INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW = | |
Index: include/reactos/libs/mbedtls/polarssl/config.h | |
=================================================================== | |
--- include/reactos/libs/mbedtls/polarssl/config.h (revision 68875) | |
+++ include/reactos/libs/mbedtls/polarssl/config.h (working copy) | |
@@ -88,7 +88,7 @@ | |
* | |
* Uncomment if the CPU supports SSE2 (IA-32 specific). | |
*/ | |
-//#define POLARSSL_HAVE_SSE2 | |
+#define POLARSSL_HAVE_SSE2 | |
/** | |
* \def POLARSSL_HAVE_TIME | |
@@ -322,7 +322,7 @@ | |
* | |
* Uncomment this macro to remove RC4 ciphersuites by default. | |
*/ | |
-//#define POLARSSL_REMOVE_ARC4_CIPHERSUITES | |
+#define POLARSSL_REMOVE_ARC4_CIPHERSUITES | |
/** | |
* \def POLARSSL_ECP_XXXX_ENABLED | |
@@ -393,7 +393,7 @@ | |
* TLS_PSK_WITH_3DES_EDE_CBC_SHA | |
* TLS_PSK_WITH_RC4_128_SHA | |
*/ | |
-#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED | |
+//#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED /* (swyter: we don't need pre-shared key negotiation as schannel does not support it) */ | |
/** | |
* \def POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED | |
@@ -417,7 +417,7 @@ | |
* TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA | |
* TLS_DHE_PSK_WITH_RC4_128_SHA | |
*/ | |
-#define POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED | |
+//#define POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED /* (swyter: we don't need pre-shared key negotiation as schannel does not support it) */ | |
/** | |
* \def POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED | |
@@ -437,7 +437,7 @@ | |
* TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA | |
* TLS_ECDHE_PSK_WITH_RC4_128_SHA | |
*/ | |
-#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED | |
+//#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED /* (swyter: we don't need pre-shared key negotiation as schannel does not support it) */ | |
/** | |
* \def POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED | |
@@ -462,7 +462,7 @@ | |
* TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA | |
* TLS_RSA_PSK_WITH_RC4_128_SHA | |
*/ | |
-#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED | |
+//#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED /* (swyter: we don't need pre-shared key negotiation as schannel does not support it) */ | |
/** | |
* \def POLARSSL_KEY_EXCHANGE_RSA_ENABLED | |
@@ -516,7 +516,7 @@ | |
* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA | |
* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA | |
*/ | |
-#define POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED | |
+//#define POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED /* (swyter: we don't need pre-shared key negotiation as schannel does not support it) */ | |
/** | |
* \def POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED | |
@@ -776,7 +776,7 @@ | |
* | |
* Enable the checkup functions (*_self_test). | |
*/ | |
-#define POLARSSL_SELF_TEST | |
+//#define POLARSSL_SELF_TEST | |
/** | |
* \def POLARSSL_SSL_AEAD_RANDOM_IV | |
@@ -818,8 +818,11 @@ | |
* a timing side-channel. | |
* | |
*/ | |
-//#define POLARSSL_SSL_DEBUG_ALL | |
+#if defined(DBG) | |
+ #define POLARSSL_SSL_DEBUG_ALL /* (swyter: enable debug prints only if ReactOS is being built with tracing) */ | |
+#endif | |
+ | |
/** \def POLARSSL_SSL_ENCRYPT_THEN_MAC | |
* | |
* Enable support for Encrypt-then-MAC, RFC 7366. | |
@@ -843,7 +846,7 @@ | |
* Enable support for Extended Master Secret, aka Session Hash | |
* (draft-ietf-tls-session-hash-02). | |
* | |
- * This was introduced as "the proper fix" to the Triple Handshake familiy of | |
+ * This was introduced as "the proper fix" to the Triple Handshake family of | |
* attacks, but it is recommended to always use it (even if you disable | |
* renegotiation), since it actually fixes a more fundamental issue in the | |
* original SSL/TLS design, and has implications beyond Triple Handshake. | |
@@ -911,7 +914,7 @@ | |
* | |
* Uncomment this to disable support for renegotiation. | |
*/ | |
-//#define POLARSSL_SSL_DISABLE_RENEGOTIATION | |
+//#define POLARSSL_SSL_DISABLE_RENEGOTIATION /* (swyter: this closes an entire can of worms for random future attacks) */ | |
/** | |
* \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO | |
@@ -921,7 +924,7 @@ | |
* | |
* Comment this macro to disable support for SSLv2 Client Hello messages. | |
*/ | |
-#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO | |
+//#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO /* (swyter: we don't want this even if we had server-side support in schannel... which we don't) */ | |
/** | |
* \def POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE | |
@@ -952,7 +955,7 @@ | |
* | |
* Comment this macro to disable support for SSL 3.0 | |
*/ | |
-//#define POLARSSL_SSL_PROTO_SSL3 | |
+//#define POLARSSL_SSL_PROTO_SSL3 /* (swyter: broken by the so-called 'BEAST' and more recently 'POODLE' attacks, there's a big-ass flaw in the protocol: http://disablessl3.com/) */ | |
/** | |
* \def POLARSSL_SSL_PROTO_TLS1 | |
@@ -1424,7 +1427,7 @@ | |
* | |
* This module is used for testing (ssl_client/server). | |
*/ | |
-#define POLARSSL_CERTS_C | |
+//#define POLARSSL_CERTS_C | |
/** | |
* \def POLARSSL_CIPHER_C | |
@@ -1464,7 +1467,9 @@ | |
* | |
* This module provides debugging functions. | |
*/ | |
-#define POLARSSL_DEBUG_C | |
+#if defined(DBG) | |
+ #define POLARSSL_DEBUG_C /* (enable debug prints only if ReactOS is being built with tracing) */ | |
+#endif | |
/** | |
* \def POLARSSL_DES_C | |
@@ -1574,7 +1579,7 @@ | |
* | |
* This module enables polarssl_strerror(). | |
*/ | |
-#define POLARSSL_ERROR_C | |
+//#define POLARSSL_ERROR_C | |
/** | |
* \def POLARSSL_GCM_C | |
@@ -1710,7 +1715,7 @@ | |
* | |
* This module provides TCP/IP networking routines. | |
*/ | |
-#define POLARSSL_NET_C | |
+//#define POLARSSL_NET_C /* (swyter: we don't use the network routines, in fact in schannel we replace them with our own shim to forward the managed network buffers) */ | |
/** | |
* \def POLARSSL_OID_C | |
@@ -1988,7 +1993,7 @@ | |
* | |
* Requires: POLARSSL_SSL_CACHE_C | |
*/ | |
-#define POLARSSL_SSL_CACHE_C | |
+//#define POLARSSL_SSL_CACHE_C /* (swyter: the schannel API shim thingie does not expose enough data for this one, maybe in the future, but not prioritary) */ | |
/** | |
* \def POLARSSL_SSL_CLI_C | |
@@ -2016,7 +2021,7 @@ | |
* | |
* This module is required for SSL/TLS server support. | |
*/ | |
-#define POLARSSL_SSL_SRV_C | |
+//#define POLARSSL_SSL_SRV_C | |
/** | |
* \def POLARSSL_SSL_TLS_C |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment