Wininet SSL клиент аутентифицирует странность - PullRequest
1 голос
/ 25 марта 2012

У меня есть сканер, который для HTTP переключается на Wininet.

Обычно это работает хорошо, но для веб-сайта я получаю сообщение об ошибке ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED

Пример кода:

vErrorNone := HttpSendRequest(HttpOpen_Request, nil, 0, nil, 0);
if vErrorNone = False then
  begin
    vErrorID := GetLastError;
    if (vErrorID = ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED) then
      begin
        // this error
      end
    ;
  end
;

Затем я попытался поэкспериментировать с:

      TmpFakePointer := nil;
      vErrorNone :=
        InternetErrorDlg(
          GetDesktopWindow()
          ,
          HttpOpen_Request
          ,
          ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED
          ,
          0
          or FLAGS_ERROR_UI_FILTER_FOR_ERRORS
          or FLAGS_ERROR_UI_FLAGS_GENERATE_DATA
          or FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS
          ,
          TmpFakePointer
        )
        = ERROR_SUCCESS
      ;
      if vErrorNone then
        begin
          vErrorNone := HttpSendRequest(HttpOpen_Request, nil, 0, nil, 0);
        end
      ;

Однако здесь есть две странности:

  • 1) Диалоговое окно не отображается
  • 2) Работает
  • 2.1) Нет ошибки на втором HttpSendRequest
  • 2.2) Верные данные возвращены

Вышеуказанная комбинация выглядит очень странно и противоречит документации. Так как пользователь не выбрал ни одного сертификата, почему это работает? Если Wininet возвращается к сертификату аутентификации анонимного клиента, когда диалоговое окно не может быть отображено (я предполагаю, что я дал ему неправильный дескриптор для отображения диалога? Хотя это ошибки, если я явно даю неправильный дескриптор), есть ли способ выбрать это напрямую без звонка в InternetErrorDlg?

1 Ответ

2 голосов
/ 04 апреля 2012

Хорошо

Вы можете сделать две вещи:

1: показать ошибку сертификата пользователю и позволить ему принять решение или не продолжать.
2: Игнорировать любые ошибки сертификата, которые вы получаете.

Я покажу вам, как сделать второй вариант:

Когда вы получаете ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED или любую другую ошибку сертификата, вам нужно позвонить InternetSetOptions, чтобы сообщить wininet, что он должен игнорировать ошибку и продолжить. После этого вам необходимо повторно отправить запрос.

function SetToIgnoreCerticateErrors(var aErrorMsg: string): Boolean;
var
  vDWFlags: DWord;
  vDWFlagsLen: DWord;
begin
  Result := False;
  try
    vDWFlagsLen := SizeOf(vDWFlags);
    if not InternetQueryOptionA(oRequestHandle, INTERNET_OPTION_SECURITY_FLAGS, @vDWFlags, vDWFlagsLen) then begin
      aErrorMsg := 'Internal error in SetToIgnoreCerticateErrors when trying to get wininet flags.' + GetWininetError;
      Exit;
    end;
    vDWFlags := vDWFlags or SECURITY_FLAG_IGNORE_UNKNOWN_CA or SECURITY_FLAG_IGNORE_CERT_DATE_INVALID or SECURITY_FLAG_IGNORE_CERT_CN_INVALID or SECURITY_FLAG_IGNORE_REVOCATION;
    if not InternetSetOptionA(oRequestHandle, INTERNET_OPTION_SECURITY_FLAGS, @vDWFlags, vDWFlagsLen) then begin
      aErrorMsg := 'Internal error in SetToIgnoreCerticateErrors when trying to set wininet INTERNET_OPTION_SECURITY_FLAGS flag .' + GetWininetError;
      Exit;
    end;
    Result := True;
  except
    on E: Exception do begin
      aErrorMsg := 'Unknown error in SetToIgnoreCerticateErrors.' + E.Message;
    end;
  end;
end;


vErrorNone := HttpSendRequest(HttpOpen_Request, nil, 0, nil, 0);
if vErrorNone = False then
  begin
    vErrorID := GetLastError;
    if (vErrorID = ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED) then
    begin
      //call SetToIgnoreCerticateErrors
      //re-send the request 
    end
  end
end;

Я извлек SetToIgnoreCerticateErrors из моего Wininet API, и он может не скомпилировать точно, как это.

Это шаги:

1 - получить ошибку
2 - Проверьте, является ли ошибка сертификатом ошибки
3 - Если это ошибка сертификата, они вызывают InternetSetOption, как я.
4 - повторно отправить запрос.

Я не знаю, как реализовать первый параметр «Показать ошибку сертификата пользователю и позволить ему решить, продолжать или нет». потому что мне никогда не приходилось это делать.

Кроме того, проверьте это: Как обработать неверную ошибку центра сертификации с WinInet

Надеюсь, это вам поможет.

...