THRIFT-5876: Add Delphi WinHTTP client TLS1.3 support
Client: Delphi
Patch: fcprete & Jens Geyer
This closes #3166
diff --git a/lib/delphi/src/Thrift.Transport.WinHTTP.pas b/lib/delphi/src/Thrift.Transport.WinHTTP.pas
index 2d18ca1..5a6f213 100644
--- a/lib/delphi/src/Thrift.Transport.WinHTTP.pas
+++ b/lib/delphi/src/Thrift.Transport.WinHTTP.pas
@@ -192,7 +192,8 @@
WINHTTP_FLAG_SECURE_PROTOCOL_SSL3,
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1,
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1,
- WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2
+ WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2,
+ WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3
);
var
prot : TSecureProtocol;
diff --git a/lib/delphi/src/Thrift.Transport.pas b/lib/delphi/src/Thrift.Transport.pas
index 4ca3831..6f9a93d 100644
--- a/lib/delphi/src/Thrift.Transport.pas
+++ b/lib/delphi/src/Thrift.Transport.pas
@@ -201,8 +201,14 @@
end;
TSecureProtocol = (
- SSL_2, SSL_3, TLS_1, // outdated, for compatibilty only
- TLS_1_1, TLS_1_2 // secure (as of today)
+ // outdated, for compatibility only
+ SSL_2,
+ SSL_3,
+ TLS_1,
+ TLS_1_1,
+ // secure (as of today)
+ TLS_1_2,
+ TLS_1_3
);
TSecureProtocols = set of TSecureProtocol;
@@ -481,7 +487,13 @@
const
- DEFAULT_THRIFT_SECUREPROTOCOLS = [ TSecureProtocol.TLS_1_1, TSecureProtocol.TLS_1_2];
+ // From https://learn.microsoft.com/en-us/windows/win32/secauthn/protocols-in-tls-ssl--schannel-ssp-
+ // > TLS 1.3 is supported starting in Windows 11 and Windows Server 2022.
+ // > Enabling TLS 1.3 on earlier versions of Windows is not a safe system configuration.
+ DEFAULT_THRIFT_SECUREPROTOCOLS = [
+ TSecureProtocol.TLS_1_2
+ //TSecureProtocol.TLS_1_3 -- not supported on Win10 (see comment)
+ ];
implementation
diff --git a/lib/delphi/src/Thrift.WinHTTP.pas b/lib/delphi/src/Thrift.WinHTTP.pas
index e6642d9..df132d7 100644
--- a/lib/delphi/src/Thrift.WinHTTP.pas
+++ b/lib/delphi/src/Thrift.WinHTTP.pas
@@ -197,27 +197,22 @@
const
- // WinHttpOpen dwAccessType values
- WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0;
- WINHTTP_ACCESS_TYPE_NO_PROXY = 1;
- WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3;
-
- // flags for WinHttpOpen():
- WINHTTP_FLAG_ASYNC = $10000000; // want async session, requires WinHttpSetStatusCallback() usage
-
- WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH = 0;
-
// ports
INTERNET_DEFAULT_PORT = 0; // use the protocol-specific default (80 or 443)
+ INTERNET_DEFAULT_HTTP_PORT = 80;
+ INTERNET_DEFAULT_HTTPS_PORT = 443;
// flags for WinHttpOpenRequest():
WINHTTP_FLAG_SECURE = $00800000; // use SSL if applicable (HTTPS)
WINHTTP_FLAG_ESCAPE_PERCENT = $00000004; // if escaping enabled, escape percent as well
WINHTTP_FLAG_NULL_CODEPAGE = $00000008; // assume all symbols are ASCII, use fast convertion
- WINHTTP_FLAG_BYPASS_PROXY_CACHE = $00000100; // add "pragma: no-cache" request header
- WINHTTP_FLAG_REFRESH = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
WINHTTP_FLAG_ESCAPE_DISABLE = $00000040; // disable escaping
WINHTTP_FLAG_ESCAPE_DISABLE_QUERY = $00000080; // if escaping enabled escape path part, but do not escape query
+ WINHTTP_FLAG_BYPASS_PROXY_CACHE = $00000100; // add "pragma: no-cache" request header
+ WINHTTP_FLAG_REFRESH = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
+
+ // flags for WinHttpOpen():
+ WINHTTP_FLAG_ASYNC = $10000000; // want async session, requires WinHttpSetStatusCallback() usage
// flags for WinHttpSendRequest():
WINHTTP_NO_PROXY_NAME = nil;
@@ -252,10 +247,12 @@
ICU_ESCAPE = $80000000; // (un)escape URL characters
ICU_ESCAPE_AUTHORITY = $00002000; // causes InternetCreateUrlA to escape chars in authority components (user, pwd, host)
- ICU_REJECT_USERPWD = $00004000; // rejects usrls whick have username/pwd sections
+ ICU_REJECT_USERPWD = $00004000; // rejects urls with username/pwd sections
INTERNET_SCHEME_HTTP = INTERNET_SCHEME(1);
INTERNET_SCHEME_HTTPS = INTERNET_SCHEME(2);
+ INTERNET_SCHEME_FTP = INTERNET_SCHEME(3);
+ INTERNET_SCHEME_SOCKS = INTERNET_SCHEME(4);
// options manifests for WinHttp{Query|Set}Option
WINHTTP_OPTION_CALLBACK = 1;
@@ -275,6 +272,7 @@
WINHTTP_OPTION_URL = 34;
WINHTTP_OPTION_SECURITY_KEY_BITNESS = 36;
WINHTTP_OPTION_PROXY = 38;
+ WINHTTP_OPTION_PROXY_RESULT_ENTRY = 39;
WINHTTP_OPTION_USER_AGENT = 41;
WINHTTP_OPTION_CONTEXT_VALUE = 45;
WINHTTP_OPTION_CLIENT_CERT_CONTEXT = 47;
@@ -313,11 +311,77 @@
WINHTTP_OPTION_SERVER_SPN_USED = 106;
WINHTTP_OPTION_PROXY_SPN_USED = 107;
WINHTTP_OPTION_SERVER_CBT = 108;
- // options for newer WinHTTP versions
+ WINHTTP_OPTION_UNSAFE_HEADER_PARSING = 110;
+ WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS = 111;
+ WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET = 114;
+ WINHTTP_OPTION_WEB_SOCKET_CLOSE_TIMEOUT = 115;
+ WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL = 116;
WINHTTP_OPTION_DECOMPRESSION = 118;
- //
+ WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE = 122;
+ WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE = 123;
+ WINHTTP_OPTION_TCP_PRIORITY_HINT = 128;
+ WINHTTP_OPTION_CONNECTION_FILTER = 131;
+ WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL = 133;
+ WINHTTP_OPTION_HTTP_PROTOCOL_USED = 134;
+ WINHTTP_OPTION_KDC_PROXY_SETTINGS = 136;
+ WINHTTP_OPTION_ENCODE_EXTRA = 138;
+ WINHTTP_OPTION_DISABLE_STREAM_QUEUE = 139;
+ WINHTTP_OPTION_IPV6_FAST_FALLBACK = 140;
+ WINHTTP_OPTION_CONNECTION_STATS_V0 = 141;
+ WINHTTP_OPTION_REQUEST_TIMES = 142;
+ WINHTTP_OPTION_EXPIRE_CONNECTION = 143;
+ WINHTTP_OPTION_DISABLE_SECURE_PROTOCOL_FALLBACK = 144;
+ WINHTTP_OPTION_HTTP_PROTOCOL_REQUIRED = 145;
+ WINHTTP_OPTION_REQUEST_STATS = 146;
+ WINHTTP_OPTION_SERVER_CERT_CHAIN_CONTEXT = 147;
+ WINHTTP_OPTION_CONNECTION_STATS_V1 = 150;
+ WINHTTP_OPTION_SECURITY_INFO = 151;
+ WINHTTP_OPTION_TCP_KEEPALIVE = 152;
+ WINHTTP_OPTION_TCP_FAST_OPEN = 153;
+ WINHTTP_OPTION_TCP_FALSE_START = 154;
+ WINHTTP_OPTION_IGNORE_CERT_REVOCATION_OFFLINE = 155;
+ WINHTTP_OPTION_TLS_PROTOCOL_INSECURE_FALLBACK = 158;
+ WINHTTP_OPTION_STREAM_ERROR_CODE = 159;
+ WINHTTP_OPTION_REQUIRE_STREAM_END = 160;
+ WINHTTP_OPTION_ENABLE_HTTP2_PLUS_CLIENT_CERT = 161;
+ WINHTTP_OPTION_FAILED_CONNECTION_RETRIES = 162;
+ WINHTTP_OPTION_HTTP2_KEEPALIVE = 164;
+ WINHTTP_OPTION_RESOLUTION_HOSTNAME = 165;
+ WINHTTP_OPTION_SET_TOKEN_BINDING = 166;
+ WINHTTP_OPTION_TOKEN_BINDING_PUBLIC_KEY = 167;
+ WINHTTP_OPTION_REFERER_TOKEN_BINDING_HOSTNAME = 168;
+ WINHTTP_OPTION_HTTP2_PLUS_TRANSFER_ENCODING = 169;
+ WINHTTP_OPTION_RESOLVER_CACHE_CONFIG = 170;
+ WINHTTP_OPTION_DISABLE_CERT_CHAIN_BUILDING = 171;
+ WINHTTP_OPTION_BACKGROUND_CONNECTIONS = 172;
+ WINHTTP_OPTION_FIRST_AVAILABLE_CONNECTION = 173;
+ WINHTTP_OPTION_TCP_PRIORITY_STATUS = 177;
+ WINHTTP_OPTION_CONNECTION_GUID = 178;
+ WINHTTP_OPTION_MATCH_CONNECTION_GUID = 179;
+ WINHTTP_OPTION_HTTP2_RECEIVE_WINDOW = 183;
+ WINHTTP_OPTION_FEATURE_SUPPORTED = 184;
+ WINHTTP_OPTION_QUIC_STATS = 185;
+ WINHTTP_OPTION_HTTP3_KEEPALIVE = 188;
+ WINHTTP_OPTION_HTTP3_HANDSHAKE_TIMEOUT = 189;
+ WINHTTP_OPTION_HTTP3_INITIAL_RTT = 190;
+ WINHTTP_OPTION_HTTP3_STREAM_ERROR_CODE = 191;
+ WINHTTP_OPTION_REQUEST_ANNOTATION = 192;
+ WINHTTP_OPTION_DISABLE_PROXY_AUTH_SCHEMES = 193;
+ WINHTTP_OPTION_REVERT_IMPERSONATION_SERVER_CERT = 194;
+ WINHTTP_OPTION_DISABLE_GLOBAL_POOLING = 195;
+ WINHTTP_OPTION_USE_SESSION_SCH_CRED = 196;
+ WINHTTP_OPTION_QUIC_STATS_V2 = 200;
+ WINHTTP_OPTION_QUIC_STREAM_STATS = 202;
+ WINHTTP_OPTION_USE_LOOKASIDE = 203;
+ WINHTTP_OPTION_ERROR_LOG_GUID = 204;
+ WINHTTP_OPTION_ENABLE_FAST_FORWARDING = 205;
+ WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_DATA = 206;
+ WINHTTP_OPTION_UPGRADE_TO_PROTOCOL = 207;
+ WINHTTP_OPTION_CONNECTION_STATS_V2 = 208;
+ WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_STATUS = 209;
+
WINHTTP_FIRST_OPTION = WINHTTP_OPTION_CALLBACK;
- //WINHTTP_LAST_OPTION = WINHTTP_OPTION_SERVER_CBT;
+ //WINHTTP_LAST_OPTION = WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_STATUS;
WINHTTP_OPTION_USERNAME = $1000;
WINHTTP_OPTION_PASSWORD = $1001;
@@ -384,6 +448,14 @@
WINHTTP_DECOMPRESSION_FLAG_ALL = WINHTTP_DECOMPRESSION_FLAG_GZIP
or WINHTTP_DECOMPRESSION_FLAG_DEFLATE;
+ // WinHttpOpen dwAccessType values
+ WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0;
+ WINHTTP_ACCESS_TYPE_NO_PROXY = 1;
+ WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3;
+ WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY = 4;
+
+ WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH = 0;
+
// values for WINHTTP_OPTION_SECURITY_FLAGS
// query only
@@ -473,6 +545,7 @@
WINHTTP_QUERY_FLAG_REQUEST_HEADERS = $80000000;
WINHTTP_QUERY_FLAG_SYSTEMTIME = $40000000;
WINHTTP_QUERY_FLAG_NUMBER = $20000000;
+ WINHTTP_QUERY_FLAG_NUMBER64 = $08000000;
// Secure connection error status flags
WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED = $00000001;
@@ -489,19 +562,27 @@
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 = $00000080;
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 = $00000200;
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 = $00000800;
+ WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3 = $00002000;
- // Note: SECURE_PROTOCOL_ALL does not include TLS1.1 and higher!
+ // Note: SECURE_PROTOCOL_ALL does NOT include TLS1.1 and higher!
WINHTTP_FLAG_SECURE_PROTOCOL_ALL = WINHTTP_FLAG_SECURE_PROTOCOL_SSL2
or WINHTTP_FLAG_SECURE_PROTOCOL_SSL3
- or WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
+ or WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
// AutoProxy
WINHTTP_AUTOPROXY_AUTO_DETECT = $00000001;
WINHTTP_AUTOPROXY_CONFIG_URL = $00000002;
WINHTTP_AUTOPROXY_HOST_KEEPCASE = $00000004;
WINHTTP_AUTOPROXY_HOST_LOWERCASE = $00000008;
+ WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG = $00000100;
+ WINHTTP_AUTOPROXY_ALLOW_STATIC = $00000200;
+ WINHTTP_AUTOPROXY_ALLOW_CM = $00000400;
WINHTTP_AUTOPROXY_RUN_INPROCESS = $00010000;
WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY = $00020000;
+ WINHTTP_AUTOPROXY_NO_DIRECTACCESS = $00040000;
+ WINHTTP_AUTOPROXY_NO_CACHE_CLIENT = $00080000;
+ WINHTTP_AUTOPROXY_NO_CACHE_SVC = $00100000;
+ WINHTTP_AUTOPROXY_SORT_RESULTS = $00400000;
// Flags for dwAutoDetectFlags
WINHTTP_AUTO_DETECT_TYPE_DHCP = $00000001;
@@ -525,33 +606,41 @@
ERROR_WINHTTP_CANNOT_CONNECT = WINHTTP_ERROR_BASE + 29;
ERROR_WINHTTP_CONNECTION_ERROR = WINHTTP_ERROR_BASE + 30;
ERROR_WINHTTP_RESEND_REQUEST = WINHTTP_ERROR_BASE + 32;
+ //ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = WINHTTP_ERROR_BASE + 37; - see below
+ //ERROR_WINHTTP_SECURE_CERT_CN_INVALID = WINHTTP_ERROR_BASE + 38; - see below
ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED = WINHTTP_ERROR_BASE + 44;
- ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN = WINHTTP_ERROR_BASE + 100;
- ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND = WINHTTP_ERROR_BASE + 101;
- ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND = WINHTTP_ERROR_BASE + 102;
- ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN = WINHTTP_ERROR_BASE + 103;
+ //ERROR_WINHTTP_SECURE_INVALID_CA = WINHTTP_ERROR_BASE + 45; - see below
+ //ERROR_WINHTTP_SECURE_CERT_REV_FAILED = WINHTTP_ERROR_BASE + 57; - see below
+ ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN = WINHTTP_ERROR_BASE + 100;
+ ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND = WINHTTP_ERROR_BASE + 101;
+ ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND = WINHTTP_ERROR_BASE + 102;
+ ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN = WINHTTP_ERROR_BASE + 103;
ERROR_WINHTTP_HEADER_NOT_FOUND = WINHTTP_ERROR_BASE + 150;
ERROR_WINHTTP_INVALID_SERVER_RESPONSE = WINHTTP_ERROR_BASE + 152;
ERROR_WINHTTP_INVALID_HEADER = WINHTTP_ERROR_BASE + 153;
ERROR_WINHTTP_INVALID_QUERY_REQUEST = WINHTTP_ERROR_BASE + 154;
ERROR_WINHTTP_HEADER_ALREADY_EXISTS = WINHTTP_ERROR_BASE + 155;
ERROR_WINHTTP_REDIRECT_FAILED = WINHTTP_ERROR_BASE + 156;
- ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR = WINHTTP_ERROR_BASE + 178;
+ //ERROR_WINHTTP_SECURE_CHANNEL_ERROR = WINHTTP_ERROR_BASE + 157; - see below
ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT = WINHTTP_ERROR_BASE + 166;
ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT = WINHTTP_ERROR_BASE + 167;
+ //ERROR_WINHTTP_SECURE_INVALID_CERT = WINHTTP_ERROR_BASE + 169; - see below
ERROR_WINHTTP_NOT_INITIALIZED = WINHTTP_ERROR_BASE + 172;
ERROR_WINHTTP_SECURE_FAILURE = WINHTTP_ERROR_BASE + 175;
+ ERROR_WINHTTP_UNHANDLED_SCRIPT_TYPE = WINHTTP_ERROR_BASE + 176;
+ ERROR_WINHTTP_SCRIPT_EXECUTION_ERROR = WINHTTP_ERROR_BASE + 177;
+ ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR = WINHTTP_ERROR_BASE + 178;
// Certificate security errors. Additional information is provided
// via the WINHTTP_CALLBACK_STATUS_SECURE_FAILURE callback notification.
- ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = WINHTTP_ERROR_BASE + 37;
- ERROR_WINHTTP_SECURE_CERT_CN_INVALID = WINHTTP_ERROR_BASE + 38;
- ERROR_WINHTTP_SECURE_INVALID_CA = WINHTTP_ERROR_BASE + 45;
- ERROR_WINHTTP_SECURE_CERT_REV_FAILED = WINHTTP_ERROR_BASE + 57;
- ERROR_WINHTTP_SECURE_CHANNEL_ERROR = WINHTTP_ERROR_BASE + 157;
- ERROR_WINHTTP_SECURE_INVALID_CERT = WINHTTP_ERROR_BASE + 169;
- ERROR_WINHTTP_SECURE_CERT_REVOKED = WINHTTP_ERROR_BASE + 170;
- ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE = WINHTTP_ERROR_BASE + 179;
+ ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = WINHTTP_ERROR_BASE + 37;
+ ERROR_WINHTTP_SECURE_CERT_CN_INVALID = WINHTTP_ERROR_BASE + 38;
+ ERROR_WINHTTP_SECURE_INVALID_CA = WINHTTP_ERROR_BASE + 45;
+ ERROR_WINHTTP_SECURE_CERT_REV_FAILED = WINHTTP_ERROR_BASE + 57;
+ ERROR_WINHTTP_SECURE_CHANNEL_ERROR = WINHTTP_ERROR_BASE + 157;
+ ERROR_WINHTTP_SECURE_INVALID_CERT = WINHTTP_ERROR_BASE + 169;
+ ERROR_WINHTTP_SECURE_CERT_REVOKED = WINHTTP_ERROR_BASE + 170;
+ ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE = WINHTTP_ERROR_BASE + 179;
ERROR_WINHTTP_AUTODETECTION_FAILED = WINHTTP_ERROR_BASE + 180;
ERROR_WINHTTP_HEADER_COUNT_EXCEEDED = WINHTTP_ERROR_BASE + 181;
@@ -560,8 +649,14 @@
ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW = WINHTTP_ERROR_BASE + 184;
ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY = WINHTTP_ERROR_BASE + 185;
ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY = WINHTTP_ERROR_BASE + 186;
+ ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED_PROXY = WINHTTP_ERROR_BASE + 187;
+ ERROR_WINHTTP_SECURE_FAILURE_PROXY = WINHTTP_ERROR_BASE + 188;
+ ERROR_WINHTTP_RESERVED_189 = WINHTTP_ERROR_BASE + 189;
+ ERROR_WINHTTP_HTTP_PROTOCOL_MISMATCH = WINHTTP_ERROR_BASE + 190;
- WINHTTP_ERROR_LAST = WINHTTP_ERROR_BASE + 186;
+ WINHTTP_ERROR_LAST = ERROR_WINHTTP_HTTP_PROTOCOL_MISMATCH;
+
+
const