Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

delphi - TIdHTTP and TLS SNI doesnt work

On my attempt the TLS SNI extension is missing. I don't know why. Can someone point me in the right direction?

Embarcadero? RAD Studio 10 Seattle Version 23.0.21418.4207

Indy version: 10.6.2.5311

OpenSSL: https://indy.fulgan.com/SSL/openssl-1.0.2h-i386-win32.zip

The (WireShark) result is the same with and without the workaround.

Example/demonstration code:

unit CMTelekomTest;
...
var
  IdHTTP1: TIdHTTP;
  IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
  xml: ixmldocument;
  root, node, sibling: ixmlnode;
  httpreturn, xmlfile: string;
  xmlstream: TStringStream;
begin
  // xml stuff
  xml := newxmldocument;
  //xml.Encoding := 'utf-8';
  xml.Options := [doNodeAutoIndent]; // just for xml-formatting
  root := xml.AddChild('MESSAGES');
  node := root.AddChild('AUTHENTICATION');
  node := node.AddChild('PRODUCTTOKEN');
  node.Text := 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
  node := root.AddChild('MSG');
  sibling := node;
  sibling := node.AddChild('FROM');
  sibling.Text := 'Sender';
  sibling := node;
  sibling := node.AddChild('TO');
  sibling.Text := '0049001234567890';
  sibling := node;
  sibling := node.AddChild('BODY');
  sibling.Text := 'Test via Delphi, german umlaut ??ü?.';
  xml.SaveToFile('C:empdelphicmtelecom.xml');
  xml.SaveToXML(xmlfile);
  xmlstream := TStringStream.Create(xmlfile, TEncoding.UTF8);

  // http stuff
  IdSSLIOHandlerSocketOpenSSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1;
  IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1];
  // dont know the exact needed ciphers, so ALL
  // http://stackoverflow.com/questions/27302773/delphi-w-indy-10-unable-to-connect-via-tls-1-2-w-ssl-best-practices-in-place
  IdSSLIOHandlerSocketOpenSSL1.SSLOptions.CipherList := 'ALL';
  IdHTTP1 := tidhttp.Create(nil);
  IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1;
  // https://docs.cmtelecom.com/bulk_sms/v1.0
  // utf-8 and application/xml
  IdHTTP1.Request.ContentEncoding := 'utf-8';
  IdHTTP1.Request.ContentType := 'application/xml';
  httpreturn := IdHTTP1.post('https://sgw01.cm.nl/gateway.ashx', xmlstream);
  // plain old http works fine, https tls is missing TLS SNI :(
  //httpreturn := http.post('http://gw01.cm.nl/gateway.ashx', xmlstream);

  // finishing process stuff
  xmlstream.Free;
  IdHTTP1.Free;
  IdSSLIOHandlerSocketOpenSSL1.Free;
end;

// workaround for TLS SNI - doesnt work for me, dont know why
procedure TForm5.IdSSLIOHandlerSocketOpenSSL1StatusInfoEx(ASender: TObject;
  const AsslSocket: PSSL; const AWhere, Aret: Integer; const AType,
  AMsg: string);
begin
  //https://forums.embarcadero.com/thread.jspa?messageID=675017
  //https://forums.embarcadero.com/thread.jspa?messageID=824615
  SSL_set_tlsext_host_name(AsslSocket, 'sgw01.cm.nl');
end;
...

This is what WireShark has to tell:

Extensions Length: 49
        Extension: ec_point_formats
        Extension: elliptic_curves
        Extension: SessionTicket TLS
        Extension: Heartbeat

No Extension for SNI.

Frame 61: 275 bytes on wire (2200 bits), 275 bytes captured (2200 bits) on interface 0
Ethernet II, Src: FujitsuT_5e:3a:85 (90:1b:0e:5e:3a:85), Dst: SophosLt_33:49:a8 (00:1a:8c:33:49:a8)
Internet Protocol Version 4, Src: 192.168.10.230, Dst: 31.169.57.12
Transmission Control Protocol, Src Port: 51554 (51554), Dst Port: 443 (443), Seq: 1, Ack: 1, Len: 221
    Source Port: 51554
    Destination Port: 443
    [Stream index: 5]
    [TCP Segment Len: 221]
    Sequence number: 1    (relative sequence number)
    [Next sequence number: 222    (relative sequence number)]
    Acknowledgment number: 1    (relative ack number)
    Header Length: 20 bytes
    Flags: 0x018 (PSH, ACK)
    Window size value: 260
    [Calculated window size: 66560]
    [Window size scaling factor: 256]
    Checksum: 0x54d7 [validation disabled]
    Urgent pointer: 0
    [SEQ/ACK analysis]
Secure Sockets Layer
    SSL Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 216
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 212
            Version: TLS 1.0 (0x0301)
            Random
            Session ID Length: 0
            Cipher Suites Length: 122
            Cipher Suites (61 suites)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
                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_DH_RSA_WITH_AES_256_CBC_SHA (0x0037)
                Cipher Suite: TLS_DH_DSS_WITH_AES_256_CBC_SHA (0x0036)
                Cipher Suite: TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0088)
                Cipher Suite: TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA (0x0087)
                Cipher Suite: TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0086)
                Cipher Suite: TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA (0x0085)
                Cipher Suite: TLS_ECDH_anon_WITH_AES_256_CBC_SHA (0xc019)
                Cipher Suite: TLS_DH_anon_WITH_AES_256_CBC_SHA (0x003a)
                Cipher Suite: TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA (0x0089)
                Cipher Suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA (0xc00f)
                Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA (0xc005)
                Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
                Cipher Suite: TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0084)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
                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_DH_RSA_WITH_AES_128_CBC_SHA (0x0031)
                Cipher Suite: TLS_DH_DSS_WITH_AES_128_CBC_SHA (0x0030)
                Cipher Suite: TLS_DHE_RSA_WITH_SEED_CBC_SHA (0x009a)
                Cipher Suite: TLS_DHE_DSS_WITH_SEED_CBC_SHA (0x0099)
                Cipher Suite: TLS_DH_RSA_WITH_SEED_CBC_SHA (0x0098)
                Cipher Suite: TLS_DH_DSS_WITH_SEED_CBC_SHA (0x0097)
                Cipher Suite: TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0045)
                Cipher Suite: TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA (0x0044)
                Cipher Suite: TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0043)
                Cipher Suite: TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA (0x0042)
                Cipher Suite: TLS_ECDH_anon_WITH_AES_128_CBC_SHA (0xc018)
                Cipher Suite: TLS_DH_anon_WITH_AES_128_CBC_SHA (0x0034)
                Cipher Suite: TLS_DH_anon_WITH_SEED_CBC_SHA (0x009b)
                Cipher Suite: TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA (0x0046)
                Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA (0xc00e)
                Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA (0xc004)
                Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
                Cipher Suite: TLS_RSA_WITH_SEED_CBC_SHA (0x0096)
                Cipher Suite: TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0041)
                Cipher Suite: TLS_RSA_WITH_IDEA_CBC_SHA (0x0007)
                Cipher Suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (0xc007)
                Cipher Suite: TLS_ECDH_anon_WITH_RC4_128_SHA (0xc016)
                Cipher Suite: TLS_DH_anon_WITH_RC4_128_MD5 (0x0018)
                Cipher Suite: TLS_ECDH_RSA_WITH_RC4_128_SHA (0xc00c)
                Cipher Suite: TLS_ECDH_ECDSA_WITH_RC4_128_SHA (0xc002)
                Cipher Suite: TLS_RSA_WITH_RC4_128_SHA (0x0005)
                Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004)
                Cipher Suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc008)
                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_DH_RSA_WITH_3DES_EDE_CBC_SHA (0x0010)
                Cipher Suite: TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA (0x000d)
                Cipher Suite: TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA (0xc017)
                Cipher Suite: TLS_DH_anon_WITH_3DES_EDE_CBC_SHA (0x001b)
                Cipher Suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA (0xc00d)
                Cipher Suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc003)
                Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
                Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
            Compression Methods Length: 1
            Compression Methods (1 method)
            Extensions Length: 49
            Extension: ec_point_formats
            Extension: elliptic_curves
            Extension: SessionTicket TLS
            Extension: Heartbeat
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I am not sure in which Indy version it was introduced (probably r5321, you have 5311) so if you update to the latest one, it will use SNI automatically.

I think you forgot to assign the IdSSLIOHandlerSocketOpenSSL1StatusInfoEx procedure to IdSSLIOHandlerSocketOpenSSL1.OnStatusInfoEx event

IdSSLIOHandlerSocketOpenSSL1.OnStatusInfoEx:=IdSSLIOHandlerSocketOpenSSL1StatusInfoEx;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...