Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create an SSL IOHandler for Win32 that uses Microsoft CryptoAPI instead of OpenSSL #49

Open
rlebeau opened this issue Apr 5, 2017 · 7 comments
Labels
Element: I/O Handlers Issues related to TIdIOHandler and descendants Element: SSL/TLS Issues related to SSL/TLS handling, TIdSSLIOHandlerSocketBase and descendants Status: Deferred Issue to be re-reviewed in a future release Type: Enhancement Issue is proposing a new feature/enhancement
Milestone

Comments

@rlebeau
Copy link
Member

rlebeau commented Apr 5, 2017

See https://github.com/tothpaul/Delphi/tree/master/Indy.SChannel for a 3rd party implementation.

Also of note: https://github.com/Fr0sT-Brutal/Delphi_SChannelTLS#note---schannel-bug

@rlebeau rlebeau added Type: Enhancement Issue is proposing a new feature/enhancement Element: I/O Handlers Issues related to TIdIOHandler and descendants Element: SSL/TLS Issues related to SSL/TLS handling, TIdSSLIOHandlerSocketBase and descendants labels Apr 5, 2017
@rlebeau rlebeau added this to the Indy 12 milestone Apr 5, 2017
@tothpaul
Copy link

Hi Remy, I'm not sure my implementation is perfect because I don't know the internals of Indy...so I've used my units and what's needed to let idHTTP works with it.

I had to override the Connected method because the method that check for KeepAlive tries to read from the socket while the server was waiting for the next request (chunked content).

I've tried to make my code as clear as possible, hope it will be usefull.

@rlebeau
Copy link
Member Author

rlebeau commented Mar 12, 2018

I haven't had a chance to really dig into it yet, but since it is a standalone implementation, it will likely end up being re-written to some extent to utilize Indy's existing SSPI functionality, which itself probably needs to be tweaked a little to make it more reusable, I think. So, your work will probably end up being more inspirational than actually integrated. Not that I'm belittling your work, by any means, as it is more than I have written so far.

@tothpaul
Copy link

Hello, I have a problem with my implementation because of a customer with a Proxy

I've changed the code to take PassThrough into account, but when I start the TLS session, the Host property point to the Proxy name, not the target host and the negociation fails.

CERT_E_CN_NO_MATCH = $800B010F; // The certificate's CN name does not match the passed value.

procedure TIdSSLIOHandlerSocketSChannel.StartSSL;
begin
if not PassThrough then
ConnectSSL;
end;

procedure TIdSSLIOHandlerSocketSChannel.SetPassThrough(const Value: Boolean);
begin
{$IFDEF LOG}System.WriteLn('TIdSSLIOHandlerSocketSChannel.SetPassThrough (', Value,')');{$ENDIF}
if fPassThrough <> Value then begin
if not Value then begin
if BindingAllocated then begin
ConnectSSL;
end;
end;
fPassThrough := Value;
end;
end;

procedure TIdSSLIOHandlerSocketSChannel.ConnectSSL;
begin
{$IFDEF LOG}System.WriteLn('TIdSSLIOHandlerSocketSChannel.ConnectSSL (', Host,')');{$ENDIF}
FSSL := SSLStart(Binding.Handle, AnsiString(Host));
if FSSL = 0 then
raise SChannelError.Create('SChannel initialization fails'#13 + SSLError, CertStatus);
if Assigned(FOnCredentials) then
SSLCredentialsCallBack(FSSL, DoCredentials, Self);
end;

I don't know exactly how an HTTP proxy works for an HTTPS request...do you see a big mistake in my code ?

Paul

@rlebeau
Copy link
Member Author

rlebeau commented Oct 31, 2018

I've changed the code to take PassThrough into account, but when I start the TLS session, the Host property point to the Proxy name, not the target host and the negociation fails.

If you are using TIdHTTP and enabling its ProxyParams, then yes (see the implementation of TIdCustomHTTP.SetHostAndPort() in IdHTTP.pas). TIdHTTP sets its own Host and Port properties to connect to the immediate listening IP/Port, which would be a proxy in your case. After the connection is established, further logic kicks in to direct the proxy to connect a tunnel to the next server. If that tunnel is successful, then TIdHTTP sends its HTTP/S request as needed (which includes initiating the SSL/TLS handshake at this time).

TIdSSLIOHandlerSocketOpenSSL takes into account that TIdHTTP fiddles with its Host property. When determining the hostname to use for SNI validation (see the implementation of TIdSSLIOHandlerSocketOpenSSL.OpenEncodedConnection() in IdSSLOpenSSL.pas), if the IOHandler's URIToCheck property is not blank (TIdHTTP assigns it for each request), then the URI is parsed and its Host portion is used. Otherwise, the IOHandler's TransparentProxy is checked, and if enabled then the last Host in the proxy chain is used. Otherwise, the IOHandler's own Host is used.

You will have to do something similar in your IOHandler when determining which Host to use for validations.

I don't know exactly how an HTTP proxy works for an HTTPS request...

The HTTP client connects to the proxy with an unencrypted connection and instructs it to open a tunnel to the target server, and then the client initiates the SSL/TLS handshake with the target server and sends the HTTP request.

tothpaul added a commit to tothpaul/Delphi that referenced this issue Nov 1, 2018
@tothpaul
Copy link

tothpaul commented Nov 1, 2018

thanks ! it works ! I've updated my repository

perhaps should you add a GetTargetHost method in TIdSSLIOHandlerSocketBase to avoid code duplication

https://github.com/tothpaul/Delphi/blob/master/Indy.SChannel/lib/Execute.IdSSLSChannel.pas#L197

@rlebeau
Copy link
Member Author

rlebeau commented Nov 1, 2018

Yes, that makes sense. I'll incorporate it in a future version.

@silverqx
Copy link

Native ssl implementation with schannel would be great.

@rlebeau rlebeau added the Status: Deferred Issue to be re-reviewed in a future release label Apr 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Element: I/O Handlers Issues related to TIdIOHandler and descendants Element: SSL/TLS Issues related to SSL/TLS handling, TIdSSLIOHandlerSocketBase and descendants Status: Deferred Issue to be re-reviewed in a future release Type: Enhancement Issue is proposing a new feature/enhancement
Projects
None yet
Development

No branches or pull requests

3 participants