Fr0sT.Brutal 900 Posted October 9, 2019 (edited) Project reached somewhat usable state. Check it here. SChannel is Windows built-in implementation of TLS protocols. This allows supporting secure connections without any external library. Repo contains: unit with transport-agnostic helper functions for easy implementation of TLS communication by means of Windows SChannel. sample of transport-agnostic synchronous TLS handshake using callback functions for real communication API declarations borrowed from JEDI project ICS TWSocket descendant that performs TLS communication demo project for performing any textual (mainly HTTPS) requests via secure connection Note. I first started learning what TLS is a couple of weeks ago :) So units contain only a necessary minimum to interact with TLS server. Certs and other advanced stuff are in TODO. Thanks to author of TLS-Sample from http://www.coastrd.com/c-schannel-smtp and JEDI for WinAPI headers. Edited October 9, 2019 by Fr0sT.Brutal 1 1 Share this post Link to post
Angus Robertson 574 Posted October 9, 2019 Interesting, it does work with modern compilers, not with Delphi 2007, too many new language features. At least the sync request returns a full page, the async request only returns one buffer load of data. While SChannel avoids the need for OpenSSL DLLs, it does mean encryption protocols and ciphers are determined by Microsoft, and they don't really care about keeping up to date, particularly with older operation systems, it took years for Windows Vista and 7 to get TLS/1,2 and probably only because anything older is becoming obsolete soon. TLS/1,3 is still not supported by Windows 10/2019 a year after everyone else started using it, including ICS. If you take this further, ICS already has soon functions to interact with the Windows certificate store for checking certificate chains, it's one of our options, using them will save you a lot of effort. Angus Share this post Link to post
Arnaud Bouchez 407 Posted October 9, 2019 (edited) For information, our Open Source https://github.com/synopse/mORMot/blob/master/SynCrtSock.pas supports SChannel as TLS layer since some time, for its raw socket layer. Of course, there is the additional WinInet/WinHTTP API for HTTP requests, which supports proper Proxy detection. Its SChannel implementation is more concise that your propose, and it works from Delphi 6 and up, and also for FPC. See https://github.com/synopse/mORMot/blob/5777f00d17fcbe0378522ceddceb0abece1dd0e3/SynWinSock.pas#L847 Edited October 9, 2019 by Arnaud Bouchez 1 Share this post Link to post
Fr0sT.Brutal 900 Posted October 10, 2019 (edited) 15 hours ago, Angus Robertson said: Interesting, it does work with modern compilers, not with Delphi 2007, too many new language features. Hmm, this is possible though I tried to keep close to classic feature set. Exception is for Default() use, I like it so much I can't return to ugly FillChar. Quote At least the sync request returns a full page, the async request only returns one buffer load of data. That's weird. Could you post log? I have no problems requesting GET / from google. Quote While SChannel avoids the need for OpenSSL DLLs, it does mean encryption protocols and ciphers are determined by Microsoft, and they don't really care about keeping up to date, particularly with older operation systems, it took years for Windows Vista and 7 to get TLS/1,2 and probably only because anything older is becoming obsolete soon. TLS/1,3 is still not supported by Windows 10/2019 a year after everyone else started using it, including ICS. Well, that's philosophic question. I hate tons of DLLs around my app; if OpenSLL could be compiled statically I'd prefer this option. But this requires too much C++ kung-fu to build them static and much more cross-compiler-fu to make Delphi eat these obj-s. I don't brave enough to start this battle. Anyway, f.ex., cURL uses SChannel by default. Quote If you take this further, ICS already has soon functions to interact with the Windows certificate store for checking certificate chains, it's one of our options, using them will save you a lot of effort. Thanks, I'll have a look. 10 hours ago, Arnaud Bouchez said: For information, our Open Source https://github.com/synopse/mORMot/blob/master/SynCrtSock.pas supports SChannel as TLS layer since some time, for its raw socket layer. Thanks, I'll have a look. My functions could be bound with ANY socket lib - Indy, Synapse, etc, even inter-process pipes. Anyway my purpose was to make TLS-enabled my app that uses ICS. Edited October 10, 2019 by Fr0sT.Brutal 1 Share this post Link to post
Angus Robertson 574 Posted October 10, 2019 I started fixing errors with Delphi 2007 to get it to build, but there were too many. Simple things like type LONG missing. Does not matter for personal projects, but is important if the code is ever to incorporated into libraries. The issue with async requests seems to relate to most of the content not being returned until the connection is closed. This URL works fine: www.magsys.co.uk GET /delphi/ddservice.asp HTTP/1.1 Connection: close Host: www.magsys.co.uk While this does not, the end of the page only appears after the server closes the connection on a 60 second timeout: www.telecom-tariffs.co.uk GET /serverinfo.htm HTTP/1.1 Connection: close The first server is IIS. the second the ICS web server, so it seems we have aggressive Keep-Alive that is ignoring the Close command, another ICS bug for me to fix. But it shows up a bug in your code as well. I chose that page because it shows the SSL/TLS connection parameters selected by the server, useful to check browser capabilities, and the poor range of ciphers supported by SChannel on older versions of Windows. Angus Share this post Link to post
Fr0sT.Brutal 900 Posted October 10, 2019 Angus, I have no D2007 at hand but I'll try to keep compatibility. At least 2007 already has Default so it's worth to support :))) Well, the code is just a demo 😉 it's tuned for connect-request-response-close scheme, I have another setup where a data stream is received as well. As for cipher suites, Windows seems to have plenty - at least for me. Share this post Link to post
Angus Robertson 574 Posted October 10, 2019 Not sure when Default() was added, but it gave an error in Delphi 2007. The keep-alive issue was not in the ICS server, but in my application. But you still need to fix data being received correctly, if you remove the close line for your google example, it takes four minutes for the window to become responsive and display the received data, which is the Google timeout. The Microsoft page actually shows how poor the ciphers are in older Windows versions, it says there are none for TLS/1,2 in Windows 7, although a couple have now been added. but not nearly as good as OpenSSL supports on Windows 7. Angus Share this post Link to post
Fr0sT.Brutal 900 Posted October 10, 2019 (edited) 1 hour ago, Angus Robertson said: But you still need to fix data being received correctly, if you remove the close line for your google example, it takes four minutes for the window to become responsive and display the received data, which is the Google timeout. Yeah, it's buffering issue... AsyncReceive calls ioctl and breaks loop when there are no data in socket left but they are in internal buffer decrypted already. And dummy Recv(0) didn't launch a new FD_READ. I'm now trying posting FMsg_WM_ASYNCSELECT just like in HTTPTunnelSocket. Edited October 10, 2019 by Fr0sT.Brutal Share this post Link to post
Fr0sT.Brutal 900 Posted October 10, 2019 Uploaded new version with many fixes Share this post Link to post
Angus Robertson 574 Posted October 10, 2019 Good, seems to read whole pages correctly now. BTW, your ICS fix is in SVN now. Angus Share this post Link to post
Remy Lebeau 1400 Posted October 11, 2019 On 10/10/2019 at 5:01 AM, Angus Robertson said: Not sure when Default() was added, but it gave an error in Delphi 2007. It was introduced in Delphi 2007 for .NET, so it might not have been available on the Win32 side yet. Share this post Link to post
Angus Robertson 574 Posted October 12, 2019 ICS support Delphi 7 onwards so we avoid any language features or libraries added after that, or have our own versions of them, such as ANSI or Wide5tring functions. Users tell me quickly if I accidentally do something that Delphi 7 does not support so it is still used. Angus Share this post Link to post
Fr0sT.Brutal 900 Posted October 14, 2019 (edited) Well, I won't reject PR's adding compatibility with ancient compilers but unlikely will do that myself. Some of introduced language features are too nice to ignore them. Edited October 14, 2019 by Fr0sT.Brutal Share this post Link to post
Fr0sT.Brutal 900 Posted December 13, 2019 Fixed plenty issues and added some helpers to circumvent SChannel bug. ICS socket handles it internally and transparently. 1 Share this post Link to post
Fr0sT.Brutal 900 Posted December 2, 2021 Several updates released including - Sharing of session data (shorter handshake in next connections to the same host) - More customization and debug abilities - Support TLS to IP - More control over server cert validation: flags to allow ignoring some cert aspects and list of trusted certs that are considered valid without any check. Share this post Link to post