Может ли WinInet вернуть, какой TLS используется

Мы используем WinInet и Delphi для связи по HTTPS. Есть ли в WinInet функция, которая вернет мне, какой протокол был согласован в сеансе, то есть TLS1.1, TLS 1.2 и т. д.


person user2968093    schedule 17.05.2016    source источник


Ответы (1)


К сожалению, по-видимому, нет (проверено на Windows 7 с Internet Explorer 11).

Использование InternetQueryOption с INTERNET_OPTION_SECURITY_CERTIFICATE или INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT было самым близким, что я мог найти в документации WinInet (см. lpszProtocolName в INTERNET_CERTIFICATE_INFO), но они возвращают пустые строки (см. выходные данные ниже).

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.

Я не смог найти ничего другого, указывающего на то, что Wininet раскрывает базовые свойства соединения SChannel.

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.

Приведенный выше код выдает следующий результат:

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)
person Ondrej Kelle    schedule 17.05.2016