3

I have a website I post to that currently supports TLS v1.1 and TLS 1.2. They will soon only allow TLS ver 1.2 connections. I upgraded Delphi 5 to Indy 10 for this reason.

Currently, I create my components in code and everything works great running 3 threads at a time:

HTTp := TIdHttp.Create(nil);
      HTTP.OnSelectAuthorization := HTTPSelectAuthorization;
      HTTP.HTTPOptions := [hoInProcessAuth,hoForceEncodeParams,hoKeepOrigProtocol];

      HTTP.OnStatus := HTTPStatus;
      HTTP.OnWorkEnd := HTTPWorkEnd;
      HTTP.Request.ContentType := 'application/x-www-form-urlencoded';
      HTTP.ProxyParams.ProxyPort := ProxyPort;
      HTTP.ProxyParams.ProxyUsername := ProxyUserName;
      HTTP.ProxyParams.ProxyPassword := ProxyPassword;
      HTTP.ProxyParams.BasicAuthentication := ProxyBasicAuth;
    end;

    If UseSSL and (SSL = nil) then
    Begin
      SSL := TIDSSLIOHandlerSocketOpenSSL.Create(nil);
      SSL.SSLOptions.Mode := sslmClient;
      SSL.OnGetPassword := SSLGetPassword;
      SSL.SSLOptions.Method := sslvTLSv1_2;
      HTTP.IOHandler := SSL;
    end;

Is there an event that I would tell me exactly what TLS version I am current actually connecting with when sending a post? I don't want there to be a surprise when they finally stop accepting TLS v1.1 connections.

Thanks.

  • Does sslvTLSv1_2 allow v1.1 and 1.2, or only 1.2? To be sure I would search for a HTTP server on the Internet which allows only 1.2 and test it. – mjn Sep 16 '16 at 15:57
  • @mjn `sslvTLSv1_2` represents 1.2 only. If you want to support both 1.1 and 1.2, you need to use the `SSLOptions.SSLVersions` property instead of the `SSLOptions.Method` property. That will allow you to enable multiple versions at one time so OpenSSL can perform version negotiation to use the highest available version. – Remy Lebeau Sep 16 '16 at 16:16
  • @RemyLabeau, are you saying that if I am using 'SSL.SSLOptions.Method := sslvTLSv1_2' to assign the SSL if that server didn't support TLS v1.2 I would get an error and Indy would not automatically try to switch to TLSv1_1? If that is the case I don't need to check the status, correct? – Robert Griffin realsol Sep 16 '16 at 19:27

2 Answers2

3

There is no event specifically for that purpose. You would have to query the underlying SSL object directly, such as in the OnStatus event, using the SSL_get_version() function.

However, you are setting the Method to TLS 1.2 exclusively, so that is all Indy will use (as long as you use a version of OpenSSL that supports 1.2, otherwise Indy will silently fallback to 1.0).

On a side note, your UseSSL if block should look more like this:

If UseSSL then
Begin
  If (SSL = nil) then
  Begin
    SSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    SSL.SSLOptions.Mode := sslmClient;
    SSL.OnGetPassword := SSLGetPassword;
    SSL.SSLOptions.Method := sslvTLSv1_2;
  End;
  HTTP.IOHandler := SSL;
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1. With the above code, wouldn't that be just assigning the HTTP.IOHandler as nil, correct? – Robert Griffin realsol Sep 16 '16 at 16:15
  • 1
    @RobertGriffinrealsol my example always assigns `SSL` to the `IOHandler` if `UseSSL` is true, creating `SSL` first if it does not exist yet. In the original code, if `SSL` *already* exists, it is not assigned to the `IOHandler` when `UseSSL` is true. – Remy Lebeau Sep 16 '16 at 16:23
  • 2. I am using the OpenSSL that I downloaded for Indy 10, so I am assuming it supports TLS v1.2. I assume it is correct, thus the reason for the question. Could you give me an example how to use the SSL_get_version() and where to actually put it in the code. The code I use for posting is [HTTP.post(URL,ssSource,ssResult); HTTP.Disconnect;] – Robert Griffin realsol Sep 16 '16 at 16:24
1

Here is an example how you can get info about SSL version. (may need some update as I don't use latest Indy)

Declaration

  procedure IdSSLIOHandlerSocketOpenSSLStatusInfoEx(ASender: TObject;
    const AsslSocket: PSSL; const AWhere, Aret: Integer; const AType,
    AMsg: string);

Assign

SSL.OnStatusInfoEx:=IdSSLIOHandlerSocketOpenSSLStatusInfoEx;

Usage

procedure THttpThread.IdSSLIOHandlerSocketOpenSSLStatusInfoEx(ASender: TObject;
  const AsslSocket: PSSL; const AWhere, Aret: Integer; const AType,
  AMsg: string);
begin
  if AsslSocket.version = TLS1_VERSION then
    ...
end;
smooty86
  • 1,112
  • 7
  • 13
  • Thanks for your code example. I tried it and not yet being that familiar with Indy 10, it fails to compile on the TSSL const being unknown and it looks, from the docs that the StatusInfo event changed some. But I am being told that as long as I use 'SSL.SSLOptions.Method := sslvTLSv1_2' in Indy 10, it is only using sslvTLSv1_2. So I am just going to assume that is how I am connected when sending posts to the 3 sites I send to. I would think I would get some sort of exception if the host didn't support sslvTLSv1_2. – Robert Griffin realsol Sep 20 '16 at 15:35
  • You have to add `IdSSLOpenSSLHeaders` unit to your project `uses` section. – smooty86 Sep 21 '16 at 06:54
  • thanks for the code, but even adding the IdSSLOpenSSLHeaders to the uses clause and assigning the SSL.OnStatusInfoEx:=IdSSLIOHandlerSocketOpenSSLStatusInfoEx;, the IdSSLIOHandlerSocketOpenSSLStatusInfoEx never gets called. I made the event simple for testing and added a Break so the IDE would stop when hitting the event, but the event never fired. Any other way you can think of that will show the version of TLS the software is using when it connects? Thanks. – Robert Griffin realsol Sep 26 '16 at 15:31
  • You definitely do something wrong. Create a new project, create `TIdHTTP` and `TIdSSLIOHandlerSocketOpenSSL` in design time, assign IOHandler and `OnStatusInfoEx` event in design time, add OpenSSL libraries and run (any button to get HTTPS page). 100% works – smooty86 Sep 26 '16 at 20:46
  • Well, it compiles but I added a debug message if the event ever is fired, never displays. So, ran fro the IDE breaking on the event. Never fires. There must be something else that needs to be set in Indy 10 for this event to fire. That is what I am missing. – Robert Griffin realsol Sep 27 '16 at 19:30
  • Thank you for that, but unfortunately, my program was written in Delphi 5. The SSL component in Design mode crashes it. I can see the form, but can't see the properties set on the SSL component without Delphi 5 dying (known Indy 10/Delphi 5 bug). I can't remove the component or view the form as text to remove it without it crashing. Otherwise, I would delete the SSL design component and create it at runtime. I can add a new unit and do this but I would need to know what settings you changed from default on the SSL component so I can match your design time component properties exact. – Robert Griffin realsol Sep 27 '16 at 23:49
  • I tried too, but as soon as I try to see the form as text (.dfm), Delphi crashes. But, I never thought about opening it up in Windows notepad though. This is an old app. I have Delphi Berlin 10.1 that has Indy 10 built in but have yet to use it since my old app will be impossible to port to it. I will open you project with that and see what settings are setup on the SSL component. This whole thing is not really necessary, I just wanted confirmation for myself that i am indeed connecting to this site with TLS ver 1.2 since they currently support 1.1 but will soon be removing it. – Robert Griffin realsol Sep 28 '16 at 14:47
  • Couldn't compile your code in Delphi 10. Avira quarantined the exe as soon as it was created. So, I created my own Win 32 app in Delphi 10 dropping each of the components starting with the simplest (label) on the form to match your example and compiled and ran each time. But as soon as I dropped the IdHTTP component, compiled and tried to run, Avira quarantined it. I'll figure that out later and go back to D5, strip out the SSL from the .dfm and create it in runtime matching the properties that I can now see in D10. I'll let you know. – Robert Griffin realsol Sep 28 '16 at 18:18
  • Since I duplicated your program by trying to figure out why Avira saw malware with the HTTP component, I shut down Avira and ran your program just fine. Indeed it returned 'version 1.2' when connecting to Google.com. Although my code and component properties match exact (even copied your 2 SSL DLL files into the project folder since mine were a little older), the event fires but displays 'Version 1'. Even looked at the DFM file and the component properties matched exactly, except for position. It doesn't make any sense to me, so I am dropping it for now. Thanks for your help – Robert Griffin realsol Sep 28 '16 at 19:27
  • That's false positive. Known "issue" for Delphi exe. Did you check required properties in SSLOptions - SSLVersion? – smooty86 Sep 28 '16 at 19:31
  • Yes, SSLVersions = [sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2] and Method = sslvSSLv23. The only thing is that it is not using the same DLL's that your program is using even though I put them in my program's folder. But I am not yet familiar enough with Delphi 10 to be able to verify this. – Robert Griffin realsol Sep 28 '16 at 19:44
  • I zipped my app (http://realsol.com/download/MySSLTest.zip). I swear it is the same. – Robert Griffin realsol Sep 28 '16 at 20:06
  • Yes, it is same, it should work. Version 1 was for Google or your page? – smooty86 Sep 28 '16 at 20:38
  • Both url's return a version 1 in my code. Both url;s return 1.2 in your code. Other then the placement of the components, I don't know what the difference is. I ran both within D10 Seatle. Upgrading to version 10.1 today to see if there is a difference. Unless your code somehow is pointing to different Indy code they should return the same results. – Robert Griffin realsol Sep 28 '16 at 21:30
  • 1 other note. My demo app was working before dropping in the OpenSSL DLL's although, I was using a different uses clause at the time. Dropped in your DLL's still gave me 'Version 1'. Then I replace my Units uses clause with your unit's uses clause, still with the same results. – Robert Griffin realsol Sep 28 '16 at 21:49
  • I run your exe and it returns 1.2 version. But note that you have to put those DLL files into the same folder with EXE, not project directory (as in your zipped app). Because there may be some old SSL libraries in Windows directory (and other search paths). That could cause the problem. – smooty86 Sep 29 '16 at 07:39
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/124556/discussion-between-robert-griffin-realsol-and-smooty86). – Robert Griffin realsol Sep 29 '16 at 14:49
  • Moved to chat. Don't want to crowd this discussion. – Robert Griffin realsol Sep 29 '16 at 17:06