Ошибка SSL только с Indy, HTTPRIO не происходит - PullRequest
0 голосов
/ 12 февраля 2020

Мне нужно связаться с правительственным API. Для этого API требуется цифровой сертификат для выполнения запросов.

Если я выполняю запрос с использованием компонентов Indy (TIdHTTP и TIdSSLIOHandlerSocketOpenSSL), я получаю следующее исключение:

"EIdOSSLUnderlyingCryptoError with message: error: 14094412: подпрограммы SSL: SSL3_READ_BYTES: неверный сертификат оповещения sslv3 ".

Если я выполняю запрос с использованием компонента THTTPRIO или THTTPReqResp, исключение не возникает, и я могу получить ответ от запроса.

Почему проблема возникает только с Indy? И что было бы возможным решением?

Я делаю запрос Indy следующим образом:

procedure TFrmApp.btnIndyClick(Sender: TObject);
var
  Response: TStringStream;
  Url: string;
begin

  Response := TStringStream.Create('', TEncoding.UTF8);
  Url := 'https://testes.tcm.go.gov.br:8443/passaporte/api/auth/representacoes';
  try
    try

      // HTTPIndy is TIdHTTP
      // OpenSSLIndy is TIdSSLIOHandlerSocketOpenSSL

      HTTPIndy.IOHandler := OpenSSLIndy;

      OpenSSLIndy.SSLOptions.CertFile := 'cert.pem';
      OpenSSLIndy.SSLOptions.RootCertFile := 'cert_nokeys.pem';
      OpenSSLIndy.SSLOptions.KeyFile := 'server.key';

      HTTPIndy.Get(Url, Response);

      { Response handling... }

    except
      on E: Exception do
        MessageDlg('Error: ' + sLineBreak + sLineBreak + E.message, mtError, [mbOK], 0);
    end;
  finally
    Response.Free;
  end;

end;

.PEM и .KEY файлы были сгенерированы из .PFX с использованием OpenSSL (1.1. 1d), используя следующие команды:

openssl pkcs12 -in "MyCert.pfx" -passin pass:MyPass -out "cert.pem" -nodes    

openssl pkcs12 -in "MyCert.pfx" -passin pass:MyPass -out "cert_nokeys.pem" -clcerts -nokeys

openssl pkcs12 -in "MyCert.pfx" -passin pass:MyPass -out "key.pem" -passout pass:MyPass -nocerts

openssl rsa -in "key.pem" -passin pass:MyPass -out "server.key"

На запрос с использованием HTTPRIO я делаю следующее:

procedure TFrmApp.btnRIOClick(Sender: TObject);
var
  Response: TStringStream;
  Url: string;
begin

  Response := TStringStream.Create('', TEncoding.UTF8);
  Url := 'https://testes.tcm.go.gov.br:8443/passaporte/api/auth/representacoes';
  try
    try

      // HTTPRIO is THTTPRIO

      HTTPRIO.URL := Url;

      HTTPRIO.HTTPWebNode.Get(Response);

      { Response handling ... }

    except
      on E: Exception do
        MessageDlg('Error: ' + sLineBreak + sLineBreak + E.message, mtError, [mbOK], 0);
    end;
  finally
    Response.Free;
  end;

end;
...