EIdOSSLUnderlyingCryptoError and “Error connecting with SSL. error:14094410…”

匿名 (未验证) 提交于 2019-12-03 01:05:01

问题:

I have a problem with Indy components in Delphi 10.1 Berlin on OS X. I'm using TIdHTTP to connect to a webservice using HTTPS. The problem is connecting to a server from an OS X client. When running on OS X, I get this same error all the time:

Project raised exception class EIdOSSLUnderlyingCryptoError with message 'Error connecting  with SSL. error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure'. 

I set the TIdHTTP.IOHandler property to use OpenSSL:

IdHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); 

On OS X, when I run this command in a terminal:

openssl version

It returns OpenSSL 0.9, which is the default version that comes with OS X.

Even if I install the latest version of OpenSSL using Homebrew or MacPort, it does not help. It give me the same error every time.

I have OS X installed in VMWare, if this helps. I also tried two versions of OS X: Yosemite and El Capitan. Same problem.

This is code I use:

unit uApiClient1;  interface  uses   IdHTTP, System.JSON, IdSSLOpenSSLHeaders, System.Classes, IdCTypes,   System.SysUtils, IdSSLOpenSSL;  const   API_URL = 'https://www.myserver.com/ws.php';   WS_METHOD = 'validate_status';  type   TAPIClient = class(TObject)     function ValidateStatus(userId, deviceId: string): TJSONObject;   private     procedure PrepareHTTPObject(var IdHTTP: TIdHTTP);   end;   implementation  { APIClient }  procedure TAPIClient.PrepareHTTPObject(var IdHTTP: TIdHTTP); begin   IdHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);   TIdSSLIOHandlerSocketOpenSSL(IdHTTP.IOHandler).SSLOptions.Method := sslvTLSv1_2;   //   IdHTTP.Request.Accept := 'text/javascript';   IdHTTP.Request.ContentType := 'application/json';   IdHTTP.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0'; end;  function TAPIClient.ValidateStatus(userId, deviceId: string): TJSONObject; var   IdHTTP: TIdHTTP;   LJSONObject: TJSONObject;   dataResult: string; begin   LJSONObject := nil;   IdHTTP := TIdHTTP.Create(nil);   try     try       PrepareHTTPObject(IdHTTP);       dataResult := IdHTTP.Get(API_URL + format('?action=%s&user_id=%s&device_id=%s', [WS_METHOD, userId, deviceid]));       LJSONObject := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(dataResult), 0) as TJSONObject;     except     end;   finally    IdHTTP.Free;   end;   Result := LJSONObject; end;  end. 

I tried to compare packets from WireShark generated by my application and by Safari and this is what I get:

My application:

Handshake Protocol: Client Hello     Handshake Type: Client Hello (1)     Length: 114     Version: TLS 1.0 (0x0301)     Random         GMT Unix Time: Aug 24, 2016 20:26:07.000000000 EEST         Random Bytes: 49c48ba758048a2429dd01ee2e390ed06eb320e5248d016d...     Session ID Length: 0     Cipher Suites Length: 46     Cipher Suites (23 suites)         Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)         Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038)         Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)         Cipher Suite: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (0x0016)         Cipher Suite: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013)         Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)         Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)         Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032)         Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)         Cipher Suite: TLS_DHE_RSA_WITH_SEED_CBC_SHA (0x009a)         Cipher Suite: TLS_DHE_DSS_WITH_SEED_CBC_SHA (0x0099)         Cipher Suite: TLS_RSA_WITH_SEED_CBC_SHA (0x0096)         Cipher Suite: TLS_RSA_WITH_RC4_128_SHA (0x0005)         Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004)         Cipher Suite: TLS_DHE_RSA_WITH_DES_CBC_SHA (0x0015)         Cipher Suite: TLS_DHE_DSS_WITH_DES_CBC_SHA (0x0012)         Cipher Suite: TLS_RSA_WITH_DES_CBC_SHA (0x0009)         Cipher Suite: TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0014)         Cipher Suite: TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA (0x0011)         Cipher Suite: TLS_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0008)         Cipher Suite: TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (0x0006)         Cipher Suite: TLS_RSA_EXPORT_WITH_RC4_40_MD5 (0x0003)         Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)     Compression Methods Length: 1     Compression Methods (1 method)     Extensions Length: 27     Extension: server_name     Extension: SessionTicket TLS         Type: SessionTicket TLS (0x0023)         Length: 0         Data (0 bytes) 

Safari browser:

Handshake Protocol: Client Hello     Handshake Type: Client Hello (1)     Length: 229     Version: TLS 1.2 (0x0303)     Random         GMT Unix Time: Aug 24, 2016 20:35:07.000000000 EEST         Random Bytes: d0f0bc116fd51dff15c739bb76f7e6032a931d07e2e56a56...     Session ID Length: 0     Cipher Suites Length: 44     Cipher Suites (22 suites)         Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)         Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)         Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)         Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)         Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)         Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)         Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)         Cipher Suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc008)         Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)         Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)         Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)         Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)         Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)         Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)         Cipher Suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012)         Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)         Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)         Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)         Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)         Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)         Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)         Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)     Compression Methods Length: 1     Compression Methods (1 method)     Extensions Length: 144     Extension: server_name     Extension: elliptic_curves     Extension: ec_point_formats     Extension: signature_algorithms         Type: signature_algorithms (0x000d)         Length: 14         Signature Hash Algorithms Length: 12         Signature Hash Algorithms (6 algorithms)     Extension: next_protocol_negotiation         Type: next_protocol_negotiation (0x3374)         Length: 0     Extension: Application Layer Protocol Negotiation         Type: Application Layer Protocol Negotiation (0x0010)         Length: 48         ALPN Extension Length: 46         ALPN Protocol     Extension: status_request         Type: status_request (0x0005)         Length: 5         Certificate Status Type: OCSP (1)         Responder ID list Length: 0         Request Extensions Length: 0     Extension: signed_certificate_timestamp         Type: signed_certificate_timestamp (0x0012)         Length: 0         Data (0 bytes) 

In protocol column of the WireShark, for Savari is TLSv1.2, and for my application is TLSv1, even I set method to sslvTLSv1_2 in code.

For both SNI is set correctly.


This is TLS alert from WireShark:

Secure Sockets Layer     TLSv1 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)         Content Type: Alert (21)         Version: TLS 1.0 (0x0301)         Length: 2         Alert Message             Level: Fatal (2)             Description: Handshake Failure (40) 

回答1:

Finally after many days of research I found how to solve my problem.

To ensure application uses last version of OpenSSL libraries, that not depend on installed in OS X, I found that I can include compiled OpenSSL libraries in application package.

In my case I need x86 compiled version of openSSL libraries. Homebrew and Macport when installing last openssl, compile x64 version of the libraries, that's why using this link:

Compilation and Installation of OpenSSL libraries

I compiled x86 version of openSSL libraries.

Next thanks to Marco Cantu tech Blog, I found that I can use IdOpenSSLSetLibPath method to set openssl libraries path.

Finally, including compiled libraries with application in same package and using this code:

IdOpenSSLSetLibPath(ExtractFilePath(ParamStr(0))); 

I get correct version of openssl libraries, that support TLSv1.2



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!