Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can WinInet return which TLS is being used

Tags:

delphi

wininet

We use WinInet and Delphi to communicate using HTTPS. Is there a function in WinInet that will return to me which protocol has been negotiated in the session, i.e. TLS1.1, TLS 1.2 etc.

like image 941
user2968093 Avatar asked Oct 15 '25 15:10

user2968093


1 Answers

Unfortunately, apparently not (tested on Windows 7 with Internet Explorer 11).

Using InternetQueryOption with INTERNET_OPTION_SECURITY_CERTIFICATE or INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT was the closest I could find in WinInet documentation (see lpszProtocolName in INTERNET_CERTIFICATE_INFO), but they return empty strings (see output below).

lpszProtocolName

Pointer to a buffer that contains the name of the protocol used to provide the
secure connection. The application must call LocalFree to release the resources
allocated for this parameter.

I couldn't find anything else suggesting that Wininet exposes the underlying SChannel connection properties.

program test_wininet;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Winapi.Windows,
  Winapi.Wininet;

type
  // fixed declaration
  PInternetCertificateInfo = ^TInternetCertificateInfo;
  TInternetCertificateInfo = record
    ftExpiry: TFileTime;
    ftStart: TFileTime;
    lpszSubjectInfo: PAnsiChar;
    lpszIssuerInfo: PAnsiChar;
    lpszProtocolName: PAnsiChar;
    lpszSignatureAlgName: PAnsiChar;
    lpszEncryptionAlgName: PAnsiChar;
    dwKeySize: DWORD;
  end;

procedure FreeCertificateInfo(var Info: TInternetCertificateInfo);
begin
  if Assigned(Info.lpszSubjectInfo) then
    LocalFree(NativeUInt(Info.lpszSubjectInfo));
  if Assigned(Info.lpszIssuerInfo) then
    LocalFree(NativeUInt(Info.lpszIssuerInfo));
  if Assigned(Info.lpszProtocolName) then
    LocalFree(NativeUInt(Info.lpszProtocolName));
  if Assigned(Info.lpszSignatureAlgName) then
    LocalFree(NativeUInt(Info.lpszSignatureAlgName));
  if Assigned(Info.lpszEncryptionAlgName) then
    LocalFree(NativeUInt(Info.lpszEncryptionAlgName));
end;

function GetCertificateInfo(H: HINTERNET): TInternetCertificateInfo;
var
  Size: Cardinal;
begin
  Size := SizeOf(Result);
  FillChar(Result, Size, 0);
  Win32Check(InternetQueryOption(H, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, @Result, Size));
end;

function GetCertificateInfoStr(H: HINTERNET): AnsiString;
var
  Buffer: array[0..1024] of AnsiChar;
  BufferSize: Cardinal;
  L: Integer;
begin
  Result := '';
  BufferSize := SizeOf(Buffer);
  FillChar(Buffer, BufferSize, 0);
  Win32Check(InternetQueryOption(H, INTERNET_OPTION_SECURITY_CERTIFICATE, @Buffer[0], BufferSize));
  L := StrLen(PAnsiChar(@Buffer[0]));
  if L > 0 then
    SetString(Result, Buffer, L);
end;

procedure Main;
var
  H, H2: HINTERNET;
  Info: TInternetCertificateInfo;
  SysTime: TSystemTime;
begin
  H := InternetOpen('test', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  try
    H2 := InternetOpenUrl(H, 'https://www.microsoft.com', nil, 0, INTERNET_FLAG_NO_UI or INTERNET_FLAG_SECURE, 0);
    try
      Writeln('InternetQueryOption with INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT: ');
      Info := GetCertificateInfo(H2);
      try
        Writeln('Subject:');
        Writeln(Info.lpszSubjectInfo);
        Writeln('Issuer:');
        Writeln(Info.lpszIssuerInfo);
        Writeln(Format('Security Protocol: %s', [Info.lpszProtocolName]));
        Writeln(Format('Signature Type: %s', [Info.lpszSignatureAlgName]));
        Writeln(Format('Encryption Type: %s', [Info.lpszEncryptionAlgName]));
        FileTimeToSystemTime(Info.ftStart, SysTime);
        Writeln(Format('Effective Date: %s', [FormatDateTime('dd/mmm/yy hh:nn:ss', SystemTimeToDateTime(SysTime))]));
        FileTimeToSystemTime(Info.ftExpiry, SysTime);
        Writeln(Format('Expiration Date: %s', [FormatDateTime('dd/mmm/yy hh:nn:ss', SystemTimeToDateTime(SysTime))]));
        Writeln(Format('Key size: %d', [Info.dwKeySize]));
        Writeln;
      finally
        FreeCertificateInfo(Info);
      end;

      Writeln('InternetQueryOption with INTERNET_OPTION_SECURITY_CERTIFICATE:');
      Writeln(GetCertificateInfoStr(H2));
      Writeln;
    finally
      InternetCloseHandle(H2);
    end;
  finally
    InternetCloseHandle(H);
  end;
end;

begin
  try
    Main;
    Readln;
  except
    on E: Exception do
    begin
      ExitCode := 1;
      Writeln(Format('[%s] %s', [E.ClassName, E.Message]));
    end;
  end;
end.

The above code produces the following output:

InternetQueryOption with INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT:
Subject:
US
Washington
Private Organization
600413485
US
98052
Washington
Redmond
1 Microsoft Way
Microsoft Corporation
www.microsoft.com
Issuer:
US
Symantec Corporation
Symantec Trust Network
Symantec Class 3 EV SSL CA - G3
Security Protocol:
Signature Type:
Encryption Type:
Effective Date: 24-Mar-16 00:00:00
Expiration Date: 25-Mar-18 23:59:59
Key size: 256

InternetQueryOption with INTERNET_OPTION_SECURITY_CERTIFICATE:
Subject:
US
Washington
Private Organization
600413485
US
98052
Washington
Redmond
1 Microsoft Way
Microsoft Corporation
www.microsoft.com
Issuer:
US
Symantec Corporation
Symantec Trust Network
Symantec Class 3 EV SSL CA - G3
Effective Date: 24-Mar-16 00:00:00
Expiration Date:        25-Mar-18 23:59:59
Security Protocol:      (null)
Signature Type: (null)
Encryption Type:        (null)
Privacy Strength:       High (256 bits)
like image 131
Ondrej Kelle Avatar answered Oct 18 '25 18:10

Ondrej Kelle