EldoS | Feel safer!

Software components for data protection, secure storage and transfer

SSL X509

Also by EldoS: Callback File System
Create virtual file systems and disks, expose and manage remote data as if they were files on the local disk.
#15810
Posted: 02/20/2011 18:05:45
by Nelson Benitez (Basic support level)
Joined: 04/25/2010
Posts: 10

As I can do this with SBB?, I was checking the forum and saw that Eugene says that ElHTTPSClient, but not how to implement it in SBB.


This use Synapse.

Code
function TTimbreEngine.Solicita(CFD: TCFD;
  CertPEM_FileName, KeyPEM_FileName: string; var RespuestaDelPAC: string)
  : boolean;
var
  SOAPMsg: string;
  HTTP: THTTPSend;
  auxSL: TStringList;
begin

  RespuestaDelPAC: = 'Unknown Error';
  Result := false;

  HTTP := THTTPSend.Create;
  try
    SOAPMsg := ReqHeader + UTF8Encode(CFD.AsString) + AnsiReplaceStr
      (AnsiReplaceStr(ReqFooter, '%rfcemisor%', CFD.Datos.Emisor.Rfc),
      '%rfcreceptor%', CFD.Datos.Receptor.Rfc);

    HTTP.Document.Write(Pointer(SOAPMsg)^, Length(SOAPMsg));
    HTTP.MimeType := 'text/xml;charset=utf8';
    HTTP.Sock.SSL.CertificateFile := CertPEM_FileName;
    HTTP.Sock.SSL.PrivateKeyFile := KeyPEM_FileName;

    if HTTP.HTTPMethod('POST', URLdelPAC) then
    begin
      auxSL := TStringList.Create;
      auxSL.LoadFromStream(HTTP.Document);
      SOAPMsg := auxSL.Text;
      auxSL.Free;

      Result := (InterpretaMensaje(SOAPMsg) = trTimbre);
      RespuestaDelPAC := SOAPMsg;
    end;
  finally
    HTTP.Free;
  end;
end;



This use Indy:

Code
function TTimbreEngine.Solicita(CFD: TCFD;
  CertPEM_FileName, KeyPEM_FileName: string; var RespuestaDelPAC: string)
  : boolean;
var
  HTTP: TidHTTP;
  SSLIOHand: TIdSSLIOHandlerSocketOpenSSL;
  SOAPMsg: string;
  Source: TMemoryStream;
  Response: TStringStream;
begin
  HTTP := TidHTTP.Create;
  SSLIOHand := TIdSSLIOHandlerSocketOpenSSL.Create;

  HTTP.Request.ContentType := 'text/xml;charset=utf8';
  HTTP.Request.CustomHeaders.Add('Connection: Keep-Alive');
  HTTP.ReadTimeout := 20000;
  HTTP.IOHandler := SSLIOHand;

  SSLIOHand.SSLOptions.CertFile := CertPEM_FileName;
  SSLIOHand.SSLOptions.KeyFile := KeyPEM_FileName;
  SSLIOHand.SSLOptions.Method := sslvSSLv3;
  SSLIOHand.SSLOptions.Mode := sslmClient;
  SSLIOHand.OnStatus := SocketStatus;
  SSLIOHand.OnStatusInfo := SocketStatusInfo;

  SOAPMsg := ReqHeader + UTF8Encode(CFD.AsString) + AnsiReplaceStr
    (AnsiReplaceStr(ReqFooter, '%rfcemisor%', CFD.Datos.Emisor.Rfc),
    '%rfcreceptor%', CFD.Datos.Receptor.Rfc);

  Source := TMemoryStream.Create();
  Source.Write(Pointer(SOAPMsg)^, Length(SOAPMsg));
  Response := TStringStream.Create('');

  try
    HTTP.Post(URLdelPAC, Source, Response);

    // Si tenemos un codigo 200 es bueno, pero de todos modos capturamos la
    // respuesta para analizarla mas adelante
    // if (HTTP.ResponseText = 'HTTP/1.1 200 OK') or (HTTP.ResponseCode = 200) then
    SOAPMsg := Response.DataString;
  except
    Sleep(2000); // Si no le damos tiempo no alcanza a llegar todo el mensaje
    SOAPMsg := HTTP.Socket.InputBufferAsString;
  end;

  Result := (InterpretaMensaje(SOAPMsg) = trTimbre);
  RespuestaDelPAC := SOAPMsg;

  HTTP.Disconnect;

  Response.Free;
  Source.Free;
  SSLIOHand.Free;
  HTTP.Free;
end;



Thank you very much.
#15812
Posted: 02/21/2011 02:10:37
by Vsevolod Ievgiienko (EldoS Corp.)

Thank you for contacting us.

The code for SBB will look like this:
Code
...
procedure TFrmMain.HttpsClientCertificateValidate(Sender: TObject;
  Certificate: TElX509Certificate; var Validate: Boolean);
var
  Validity : TSBCertificateValidity;
  Reason: TSBCertificateValidityReason;
begin
  if (Certificate.Chain = nil) or Certificate.Chain.Certificates[0].Equals(Certificate) then
  begin
    CertificateValidator.ValidateForSSL(Certificate, HTTPSClient.RemoteHost, HTTPSClient.RemoteIP, hrServer, nil, true, false, Now, Validity, Reason);
    Validate := Validity = cvOk;
  end
  else
    Validate := true;
end;

procedure TFrmMain.HttpsCertificateNeeded(Sender: TObject; var Certificate : TElX509Certificate);
begin
  // code to load certificate from file
  // can be found in SBB samples
end;

...
var
  HTTPS : TElHTTPSClient;
  MS, Source : TMemoryStream;
  SOAPMsg : string;
begin
  try
    Source := TMemoryStream.Create;
    MS := TMemoryStream.Create;
    HTTPS := TElHTTPSClient.Create(nil);
    HTTPS.SSLEnabled := true;
    HTTPS.OutputStream := MS;
    HTTPS.OnCertificateValidate := HttpsClientCertificateValidate;
    HTTPS.OnCertificateNeededEx := HttpsCertificateNeeded;
    
    SOAPMsg := ReqHeader + UTF8Encode(CFD.AsString) + AnsiReplaceStr
      (AnsiReplaceStr(ReqFooter, '%rfcemisor%', CFD.Datos.Emisor.Rfc),
      '%rfcreceptor%', CFD.Datos.Receptor.Rfc);

    Source := TMemoryStream.Create();
    Source.Write(Pointer(SOAPMsg)^, Length(SOAPMsg));

    HTTPS.Post(URLdelPAC, Source, false);
    // result is in MS stream
  finally
    FreeAndNil(MS);
    FreeAndNil(Source);
    FreeAndNil(HTTPSClient);
  end;
end;
#15860
Posted: 02/22/2011 13:33:28
by Nelson Benitez (Basic support level)
Joined: 04/25/2010
Posts: 10

Thank you very much.

I did what you told me, but I never receive data, the evidence shows that if you send data at the reception also shows that we receive, but the MS variable is empty.

Data sent and received respectively are:

2063 Envoy
Received 4615

2059 Envoy
Received 4615

2063 Envoy
Received 4615

The certificate is loaded, I use the demo SimpleSSL within the SBB demos folder.

Trying to load a MS variable is always empty MeMo.

"Where is my mistake?

Thanks again.



Quote

function TfrmMain.Solicita(CFD: TCFD; var RespuestaDelPAC: string): Boolean;
var
MEMO, MS, Source: TMemoryStream;
SOAPMsg: string;
HTTPS : TElHTTPSClient;
auxSL: TStringList;
Archivo:TFileStream;
begin


RespuestaDelPAC := 'Error Desconocido';
Result := false;

try
HTTPS := TElHTTPSClient.Create(nil);
Source := TMemoryStream.Create;
MS := TMemoryStream.Create;

if HTTPS.Active then

HTTPS.SSLEnabled := true;
HTTPS.OutputStream := MS;

//NJMB
HTTPS.PreferKeepAlive := true;
HTTPS.UseCompression := true;
HTTPS.SocketTimeout := 0;
HTTPS.RequestParameters.AcceptCharset :='text/xml;charset=utf8';
HTTPS.RequestParameters.Accept :='text/xml;charset=utf8';

////

HTTPS.OnCertificateValidate := ClientCertificateValidate;
HTTPS.OnCertificateNeededEx := ClientCertificateNeededEx;

SOAPMsg := ReqHeader + UTF8Encode(CFD.AsString) + AnsiReplaceStr
(AnsiReplaceStr(ReqFooter, '%rfcemisor%', CFD.Datos.Emisor.Rfc),
'%rfcreceptor%', CFD.Datos.Receptor.Rfc);

ShowMessage(SOAPMsg);

Source.Write(Pointer(SOAPMsg)^, Length(SOAPMsg));

// HTTPS.Post(const URLdelPAC:string;const Content:string):integer;
HTTPS.Post(URLdelPAC, Source, False);


ShowMessage('Total send bytes ' +IntToStr( HTTPS.TotalBytesSent)) ;
ShowMessage('Total bytes receive ' +IntToStr( HTTPS.TotalBytesReceived)) ;
auxSL := TStringList.Create;
auxSL.LoadFromStream(MS);
SOAPMsg := auxSL.Text;
auxSL.Free;



ShowMessage(SOAPMsg);

// result is in MS stream
mmo.Lines.LoadFromStream(MS);

Result := (InterpretaMensaje(SOAPMsg) = trTimbre);
RespuestaDelPAC := SOAPMsg;

ShowMessage(RespuestaDelPAC);

finally

FreeAndNil(MS);
FreeAndNil(Source);
FreeAndNil(HTTPS);
end;
end;
#15861
Posted: 02/22/2011 14:13:19
by Vsevolod Ievgiienko (EldoS Corp.)

You should set MS.Position := 0 before use received data.
#15864
Posted: 02/23/2011 11:33:58
by Nelson Benitez (Basic support level)
Joined: 04/25/2010
Posts: 10

Thank you very much.
Also by EldoS: CallbackRegistry
A component to monitor and control Windows registry access and create virtual registry keys.

Reply

Statistics

Topic viewed 1826 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!