сбой рукопожатия оповещения sslv3 Delphi - PullRequest
0 голосов
/ 07 декабря 2018
  • Delphi 10 seattle
  • OpenSSL 1.0.0.10, но тот же результат с более поздними библиотеками.

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

14094410: SSL3_read_bytes: сбой квитирования оповещения sslv3

Использовали wireshark для подтверждения использования TLSv1.2.может предоставить файл захвата при необходимости.

 function GetAddress(ID_ID : Integer; Rijksregister : String) : Boolean;
var

  gp : GetPerson;
  Cor : CorrelationType;
  P : RrSimplePersonService_v02PortType;
  Resp : GetPersonResponse;
  FHTTPRio: THTTPRio;
  FReqResp : TWisaHTTPReqResp;
  FSSLIOHandler: TIdSSLIOHandlerSocketOpenSSL;
  Adr : PersonLegalAddressType;
  CERTPath : String;
  i, j : integer;
begin
  CERTPath := IncludeTrailingPathDelimiter(ExtractFilePath(Paramstr(0)));
  Result := false;
  // declarations
  Cor := CorrelationType.Create;
  Cor.requestorId := '01234567890';
  Cor.requestorName := 'WisaMockupService';
  Cor.applicationId := 'WISA';
  Cor.correlationId := getGUID;
  gp := getPerson.Create;
  gp.identifier := Rijksregister;
  gp.correlation := Cor;
  // actual call
  CoInitialize(nil);
  fHTTPRio:=THTTPRio.Create(Self);
  fHTTPRio.URL:=fURL;
  fHTTPRio.Converter.Options := fHTTPRio.Converter.Options + [soSendMultiRefObj, soTryAllSchema, soRootRefNodesToBody, soCacheMimeResponse, soUTF8EncodeXML, soSOAP12];
  fHTTPRio.OnBeforeExecute := IH7BeforeExecute;
  fHTTPRio.OnAfterExecute := IH7AfterExecute;
  FReqResp := TWisaHTTPReqResp.Create(self);
  FReqResp.URL := fURL;
  FReqResp.InvokeOptions := FReqResp.InvokeOptions + [soNoSOAPActionHeader];
  FReqResp.ConnectTimeout := 60000;
  FReqResp.ReceiveTimeout := 60000;
  FReqResp.SendTimeout := 60000;
  FReqResp.WebNodeOptions:= FReqResp.WebNodeOptions+[wnoSOAP12];
  fHTTPRio.HTTPwebNode := FReqResp;
  fHTTPRio.HTTPwebNode.UserName := fUser;
  fHTTPRio.HTTPwebNode.Password := fPaswoord;
  fHTTPRio.HTTPwebNode.OnBeforePost := BeforePost;
  FSSLIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(self);
  FSSLIOHandler.SSLOptions.Method := sslvTLSv1_2;
  FSSLIOHandler.SSLOptions.SSLVersions := [sslvTLSv1_2,sslvTLSv1_1,sslvTLSv1];
  FSSLIOHandler.SSLOptions.CipherList := 'ALL';
  FSSLIOHandler.SSLOptions.RootCertFile := CERTPath + 'CACert.crt';
  FSSLIOHandler.SSLOptions.KeyFile := CERTPath + 'privateKey.key';
  FSSLIOHandler.SSLOptions.CertFile := CERTPath + 'certificate.crt';
  FSSLIOHandler.SSLOptions.Mode := sslmUnassigned;
  FSSLIOHandler.SSLOptions.VerifyMode := [];
  FSSLIOHandler.SSLOptions.VerifyDepth := 3;
  FSSLIOHandler.OnGetPassword := getPassword;
  FSSLIOHandler.UseNagle := true;
  FSSLIOHandler.ReadTimeout := 60000;
  FSSLIOHandler.ConnectTimeout := 60000;
  FSSLIOHandler.OnStatusInfoEx := SSLStatusInfoEx;
  FSSLIOHandler.OnVerifyPeer := VerifyPeer;
  FReqResp.IOHandler := FSSLIOHandler;
  // actual call
  P := (fHTTPRio as RrSimplePersonService_v02PortType);
  Try
    Resp := P.GetPerson(gp);
  Except
    on e : exception do
      begin
      Showerror(ID_ID, e.message + ' ' + format(rsRijksregister2,
        [Rijksregister]), '', '');
      exit;
      end;
  End;

  if not Assigned(Resp) then
    exit;
  # do something with Response

  # end
  Result := true;
end;


procedure IH7BeforeExecute(const MethodName: string;
  SOAPRequest: TStream);
var
  S : TStringStream;
  MyStringList: TStringList;
  CreateTime, ExpiryTime : TDateTime;
begin
  MyStringList := TStringList.Create;
  try
    Inherited;
    CreateTime := Now;
    ExpiryTime := IncSecond(CreateTime,600);
    SOAPRequest.Position := 0;
    MyStringList.LoadFromStream(SOAPRequest);
    MyStringList.Text := StringReplace(MyStringList.Text, '<soap-env:body>', Format(SoapHeader,[getTSToken, TimeToString(CreateTime), TimeToString(ExpiryTime), getToken, fGebruiker, fPaswoord]) + '<SOAP-ENV:Body>', [RfIgnoreCase]);
    MyStringList.Text := StringReplace(MyStringList.Text, '</GetPerson>', '</ws:GetPerson>', [RfIgnoreCase]);
    MyStringList.Text := StringReplace(MyStringList.Text, 'SOAP-ENV:', 'SOAP:', [RfReplaceAll, RfIgnoreCase]);
    MyStringList.Text := StringReplace(MyStringList.Text, 'SOAP-ENV=', 'SOAP=', [RfReplaceAll, RfIgnoreCase]);
    MyStringList.Text := StringReplace(MyStringList.Text, '<SOAP:Envelope xmlns:SOAP="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">', '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://person.ws.egov.apogado.com/SimplePersonSchema/v1_2/ws">', [RfReplaceAll, RfIgnoreCase]);
    MyStringList.Text := StringReplace(MyStringList.Text, 'SOAP:Body', 'soap:Body', [RfReplaceAll]);
    MyStringList.Text := StringReplace(MyStringList.Text, '<GetPerson xmlns="http://person.ws.egov.apogado.com/SimplePersonSchema/v1_2/ws">', '<ws:GetPerson>', [RfReplaceAll]);
    MyStringList.Text := StringReplace(MyStringList.Text, '<transaction xmlns="" xsi:nil="true"/>', '', [RfReplaceAll]);
    MyStringList.Text := StringReplace(MyStringList.Text, '</SOAP:Envelope>', '</soap:Envelope>', [RfReplaceAll]);
    MyStringList.Text := StringReplace(MyStringList.Text, '<identifier xmlns="urn:oslo:names:specification:schema:xsd:CommonBasicComponents-1"><Identifier xmlns="http://www.w3.org/ns/corevocabulary/BasicComponents">', '<identifier>', [RfReplaceAll]);
    MyStringList.Text := StringReplace(MyStringList.Text, '</Identifier>', '', [RfReplaceAll]);
    MyStringList.Text := StringReplace(MyStringList.Text, 'SOAP:Header', 'soap:Header', [RfReplaceAll]);
    MyStringList.Text := StringReplace(MyStringList.Text, 'SOAP:mustUnderstand="true"', 'soap:mustUnderstand="true"', [RfReplaceAll]);
    SOAPRequest.Position := 0;
    SOAPRequest.Size:=0;
    MyStringList.SaveToStream(SOAPRequest);
  finally
    MyStringList.Free;
  end;
  S:=TStringStream.Create('');
  try
    S.CopyFrom(SOAPRequest,0);
    SOAPRequest.Position:=0;
    // eventueel loggen van request
    //Log('HTTPRIO Verstuurd bericht:'+sLineBreak+S.DataString);
  finally
    S.Free;
  end;
end;

procedure IH7AfterExecute(const MethodName: string;
  SOAPResponse: TStream);
Var
  S : TStringStream;
begin
  S:=TStringStream.Create('');
  try
    S.CopyFrom(SOAPResponse,0);
    SOAPResponse.Position:=0;
  finally
    S.Free;
  end;
end;

Procedure GetPassword(var Password: string);
begin
  Password := ansistring('********');
end;

procedure SSLStatusInfoEx(ASender: TObject; const AsslSocket: PSSL;
const AWhere, Aret: Integer; const AType, AMsg: string);
begin
  SSL_set_tlsext_host_name(AsslSocket, fURL);
end;

procedure BeforePost(const HTTPReqResp: THTTPReqResp; Data: Pointer);
begin
 // nothing atm
end;

1 Ответ

0 голосов
/ 07 декабря 2018

Из pcap видно, что первоначальное успешное рукопожатие TLS выполнено, а также данные приложения передаются от клиента к серверу, а затем сервер инициирует новое рукопожатие с последующим отправлением сервером предупреждения.Успешное начальное рукопожатие означает, что ни версия протокола TLS, ни шифр, ни сертификат сервера не являются проблемой.

Хотя невозможно посмотреть детали данных приложения, второе рукопожатие и предупреждение, так как ониЗашифрованная последовательность записей предполагает, что:

  1. После успешного начального рукопожатия TLS выполняется HTTP-запрос (т. е. данные приложения) для ресурса, который требует аутентификации с помощью сертификата клиента.
  2. Поэтому сервер инициирует повторное согласование.Во втором рукопожатии TLS сервер запросит этот сертификат.
  3. Сервер не любит сертификат, отправленный клиентом, или клиент не отправляет сертификат.Поэтому сервер прерывает соединение с помощью предупреждающего сообщения.

Учитывая, что оно работало раньше, но не работает сейчас, я полагаю, что одна из них является причиной проблемы:

  • Возможно, срок действия существующего сертификата истек или отозван.
  • Изменения на сервере приводят к тому, что сервер больше не принимает сертификат, например, из-за того, что ЦС больше не является доверенным.
  • Сертификат был заменен нана стороне клиента.Но новый сертификат - это не то, что сервер ожидает получить или неправильно настроен (например, отсутствует цепной сертификат).
...