4

As you know the new poodle is in town, Witch barks got Twitter, Cloudflare to drop support to SSL3.

The Indy(TidHttp) 10.6.0.0 revives this nice exception:

EidOsslUnerlayingCryptoError message 'Error connecting with SSL. error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure'

My question is what is the definition required to handle TLS?

update: here is a code that throw the exception: full working code.

var
  parameters:TStringList;
  keySecretBase64:string;
  stream:TStringStream;
  IdEncoderMIME1 : TIdEncoderMIME;
  idHttp1 : TIdHTTP;
  IdSSLIOHandlerSocketOpenSSL1:TIdSSLIOHandlerSocketOpenSSL;//assume on Form
begin
  stream:=TStringStream.create;
  parameters:=TStringList.Create;
  IdEncoderMIME1 := TIdEncoderMIME.Create(nil);
  idHttp1 := TIdHTTP.Create(nil);
  IdSSLIOHandlerSocketOpenSSL1:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1_2;
  IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_2];
    with IdSSLIOHandlerSocketOpenSSL1 do begin
      SSLOptions.Method := sslvSSLv3;
      SSLOptions.Mode :=  sslmUnassigned;
      SSLOptions.VerifyMode := [];
      SSLOptions.VerifyDepth := 2;
    end;
    with idHttp1 do begin
      IOHandler := IdSSLIOHandlerSocketOpenSSL1;
      ReadTimeout := 0;
      AllowCookies := True;
      ProxyParams.BasicAuthentication := False;
      ProxyParams.ProxyPort := 0;
      Request.ContentLength := -1;
      Request.ContentRangeEnd := 0;
      Request.ContentRangeStart := 0;
      Request.ContentType := 'application/x-www-form-urlencoded';
      Request.Accept := 'text/html, */*';

      Request.BasicAuthentication := False;
      Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
      HTTPOptions := [hoForceEncodeParams];
    end;
    parameters.Clear;
    idHttp1.Request.CustomHeaders.Clear;
    IdEncoderMIME1.FillChar:='=';

  try
    keySecretBase64 := TIdEncoderMIME.EncodeString(key+ ':' + secret, IndyTextEncoding_UTF8);// this is twitter provided key and secret
    parameters.Add('grant_type=client_credentials');
    idHttp1.Request.CustomHeaders.AddValue('Authorization','Basic '+keySecretBase64);
    idHttp1.post(URL,parameters,stream);
  finally
    stream.Free;
    parameters.Free;
    parameters.Free;
    IdSSLIOHandlerSocketOpenSSL1.Free;
  end;
end;
TLama
  • 75,147
  • 17
  • 214
  • 392
none
  • 4,669
  • 14
  • 62
  • 102
  • You are connecting with TLSv1 only, so you can only connect to servers using the SSLv23 wildcard or TLSv1 specifically, otherwise your TLSv1 handshake will fail. – Remy Lebeau Oct 20 '14 at 19:32
  • Your example code could be so much shorter - only `IdHttp.Get('https://www.google.com')` or a different https address and the SSLIOHandler part is required – mjn Oct 27 '14 at 13:58
  • true. however google does not deny ssl and force tls, as far as i know, check the second link about twitter and cloudflare. – none Oct 27 '14 at 15:57
  • @RemyLebeau I am using Delphi 2007. Where can I find a version of Indy10 that will be compatible with sslvTLSv1_2? The version I get from http://indy.fulgan.com/zip/ is throwing "TIdTextEncoding undefined" errors. – M Schenkel Jan 07 '15 at 22:10
  • 1
    @MSchenkel: The `TIdTextEncoding` class was replaced with a new `IIdTextEncoding` interface in Indy 10.6. See [this blog article](http://www.indyproject.org/sockets/blogs/changeLog/20130423.EN.aspx). – Remy Lebeau Jan 07 '15 at 23:26
  • 1
    @mjn: the code can be shortened even further if you take into account that `TIdHTTP` can now create its own `SSLIOHandler` (that defaults to TLSv1), if one has not already been assigned, when requesting an HTTPS url. See [this blog article](http://www.indyproject.org/sockets/blogs/changeLog/20141222.EN.aspx). – Remy Lebeau Jan 07 '15 at 23:30
  • @RemyLebeau Thank you Remy as always - I was able to get it going. – M Schenkel Jan 08 '15 at 02:35

2 Answers2

3

Your code selects TLS 1.2 in the SSLOptions property Method:

IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1_2;
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_2];

However, two lines later this value is overwritten with SSL 3:

with IdSSLIOHandlerSocketOpenSSL1 do begin
  SSLOptions.Method := sslvSSLv3;
  ...
end;

So the client will not connect with the newer TLS 1.2 protocol but with SSL 3, which is no longer supported by the server.

This explains the error message, which says that the SSL 3 handshake (which the client tried) failed:

SSL. error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure'

If you remove the second assignment, the IdHTTP client will use TLS 1.2 for the connect.

mjn
  • 36,362
  • 28
  • 176
  • 378
  • you did progress the problem, however there is now a "Soket Error # 10054 connection reset by peer", which doesnt make the tls connection. reason code incomplete. – none Oct 30 '14 at 16:42
1

SSL2, SSL3 and TLS1.0 are all vulnerable for man-in-th-middle attacks. You should use TLS 1.1 and upper for secure connection. Unfortunately, Indy 9 does not support TLS 1.1 and upper.

This answer reports that there is an option TLSv1_2 for TLS 1.2 in Indy 10, but it is not presented in Indy 10 online documentation.

Community
  • 1
  • 1