EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Timestamp changed SignedInfo

Also by EldoS: Rethync
The cross-platform framework that simplifies synchronizing data between mobile and desktop applications and servers and cloud storages
#14496
Posted: 09/20/2010 03:02:53
by Sašo Osenk (Standard support level)
Joined: 09/20/2010
Posts: 35

Hello!

I'm new in signing xml documents and I have a problem when adding timestamp to my xml document. I use Delphi 7.

The code is:
Code
    XAdESSigner := TElXAdESSigner.Create(nil);
    Osnovna.ELDOS.XAdESProcessor := XAdESSigner;
    xadesSigner.XAdESVersion := XAdES_v1_1_1;
    SetLength(Buf, f.Size);
    f.Read(Buf[0], Length(Buf));

    XAdESSigner.PolicyId.SigPolicyId.Identifier:='TEST SASO';
    XAdESSigner.PolicyId.SigPolicyId.Description := 'TEST SASO 1';
    XAdESSigner.PolicyId.SigPolicyId.DocumentationReferences.add('TEST SASO 2');
    XAdESSigner.PolicyId.SigPolicyHash.DigestMethod := SBXMLSec.DigestMethodToURI(xdmSHA1);
//    XAdESSigner.PolicyId.SigPolicyHash.DigestValue:=SBXMLSec.CalculateDigest(@Buf[0], Length(Buf), xdmSHA1);
    XAdESSigner.PolicyId.SigPolicyQualifiers.Create;
//    XAdESSigner.PolicyId.SigPolicyQualifiers.Item.LoadFromXML[XAdESSigner.QualifyingProperties.SignedProperties.SignedDataObjectProperties.XMLElement];

    XAdESSigner.PolicyId.SigPolicyId.IdentifierQualifier :=xqtNone;

   // xadesSigner.Included:=xipProductionPlace;
    xadesSigner.ProductionPlace.City := '';
    xadesSigner.ProductionPlace.StateOrProvince := X509KeyData.Certificate.SubjectName.StateOrProvince;
    xadesSigner.ProductionPlace.PostalCode := X509KeyData.Certificate.SubjectName.Locality;
    xadesSigner.ProductionPlace.CountryName := X509KeyData.Certificate.SubjectName.Country;


(*    TSPClient := TElHTTPTSPClient.Create(nil);
    HTTPClient := TElHTTPSClient.Create(nil);
    TSPClient.HttpClient := HTTPClient;
    TSPClient.URL :='http://postarca.posta.si/tsa/CasovniZig.wsdl';
    TSPClient.HashAlgorithm := SB_ALGORITHM_DGST_SHA1;
    XAdESSigner.TSPClient := TSPClient;
    XAdESSigner.IgnoreTimestampFailure := False; *)

    Cert := TElX509Certificate.Create(nil);
    F := TFileStream.Create(dir+'\postarca.cer', fmOpenRead or fmShareDenyWrite);
    Cert.LoadFromStream(F);
    FCertStorage := TElMemoryCertStorage.Create(nil);
    FCertStorage.Add(Cert,true);

    XAdESSigner.SigningCertificates := fCertStorage;

    XAdESSigner.SigningTime := LocalTimeToUTCTime(Now);


    xadesSigner.Generate();
//    XAdESSigner.AddCounterSignature(Osnovna.ELDOS.XAdESProcessor);

    XAdESSigner.QualifyingProperties.SignedProperties.SignedSignatureProperties.SignaturePolicyIdentifier.SignaturePolicyImplied := true;

    xadesSigner.QualifyingProperties.XAdESPrefix :='xds';
    XAdESSigner.QualifyingProperties.Target:='#MySignature';


    //konec časovnega žigosanja   *)

    Osnovna.ELDOS.UpdateReferencesDigest;

    Osnovna.ELDOS.Sign;


    Osnovna.ELDOS.Signature.ID:='MySignature';
    Osnovna.ELDOS.Signature.SignaturePrefix := 'ds';

    Osnovna.ELDOS.Signature.SignedInfo.SigPropRef.DigestMethod := xdmSHA1;
    Osnovna.ELDOS.Signature.SignedInfo.SigPropRef.ID := 'idX';
    Osnovna.ELDOS.Signature.SignedInfo.SigPropRef.RefType :='http://uri.etsi.org/01903/v1.1.1#SignedProperties';
    Osnovna.ELDOS.Signature.SignedInfo.SigPropRef.URI:='#SignedPropertiesId';

    SigNode := FXMLDocument.DocumentElement;
    if SigNode is TElXMLDOMDocument then
      SigNode := TElXMLDOMDocument(SigNode).DocumentElement;
    try
      // If the signature type is enveloping, then the signature is placed into the passed node and the contents of the node are moved to inside of the signature.
      // If the signature type is enveloped, the signature is placed as a child of the passed node.
      Osnovna.ELDOS.Save(SigNode);
    except
      on E: Exception do
        raise EElXMLError.CreateFmt('Signed data saving failed. (%s)', [E.Message]);
    end;


Created xml is:
Quote

-<ds:Signature Id="MySignature">
-<ds:SignedInfo Id="SignedInfo-1542316840">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
-<ds:Reference Id="refData" Type="http://www.gzs.si/shemas/eslog/racun/1.4#Racun" URI="#data">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>


and I need a
Quote

-<ds:Signature Id="MySignature">
-<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
-<ds:Reference URI="#data" Id="refData" Type="http://www.gzs.si/shemas/eslog/racun/1.4#Racun">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
...


Can you help me what I'm doing wrong?

I also have trouble with getting timestamp from http://postarca.posta.si/tsa/CasovniZig.wsdl. Error is "Signed data saving failed (Timestamp failed (83970))"
Thank you for your help,

Sašo
#14499
Posted: 09/20/2010 05:43:09
by Dmytro Bogatskyy (EldoS Corp.)

Quote
-<ds:SignedInfo Id="SignedInfo-1542316840">
Can you help me what I'm doing wrong?

This Id is automatically added if you are using XAdES version 1.1.1 or 1.2.2 (but not for 1.3.2) as it may be required for timestamping.
There is no option that could be used to remove it. However you can use FormatElement event to remove an Id from SignedInfo element before signing.
Quote

I also have a question if TSPClient.URL :='http://postarca.posta.si/tsa/CasovniZig.wsdl'; is the right way to get timestamp from my TSA?

No. ElHTTPTSPClient class send a binary request as specified at RFC 3161.
Your url points to page that describes Web services (WSDL).
To timestamp you'll need to use ElFileTSPClient class and handle OnTimestampNeeded event. In the event handler you'll need to format and send a SOAP request to your web service (based on WSDL info).
#14502
Posted: 09/20/2010 08:09:58
by Sašo Osenk (Standard support level)
Joined: 09/20/2010
Posts: 35

Thank's for fast reply.
Do you might have a example for both my trouble?

Thank's for helping,
Sašo
#14514
Posted: 09/20/2010 15:41:27
by Dmytro Bogatskyy (EldoS Corp.)

Quote
Do you might have a example for both my trouble?

First one:
Code
procedure TfrmMain.FormatElement(Sender: TObject;
  Element: TElXMLDOMElement; Level: Integer; const Path: XMLString;
  var StartTagWhitespace, EndTagWhitespace: XMLString);
begin
// ...
  if Element.LocalName = 'SignedInfo' then
    Element.RemoveAttribute('Id');
end;
...
ElXMLSigner.OnFormatElement := FormatElement;

For second question there is no sample, as implementation of web services usually differ.
How to use ElFileTSPClient class was discussed here many times, please do a search, for example:
https://www.eldos.com/forum/read.php?FID=7&TID=2518 (1)
http://www.eldos.com/forum/read.php?FID=7&TID=1630 (implementation of OnTimestampNeeded handler)
...
#14596
Posted: 09/27/2010 03:26:51
by Sašo Osenk (Standard support level)
Joined: 09/20/2010
Posts: 35

I have to remove id from SignedSignatureProperties. With FomatElement it stays in the document.
In my xml I have
Quote
-<xds:SignedSignatureProperties Id="SignedSignatureProperties-170049296">


What I need is
Quote
-<xds:SignedSignatureProperties>


Code in FomatElement procedure is
Code
      if Element.LocalName = 'SignedInfo' then
        Element.RemoveAttribute('Id');
      if Element.LocalName = 'SignedProperties' then
        Element.SetAttribute('Id','SignedPropertiesId');
      if Element.LocalName = 'SignedSignatureProperties' then
        Element.RemoveAttribute('Id');
      if (Element.LocalName = 'Reference') then
       begin
          z:=z+1;
          if z=2 then
            Element.RemoveAttribute('Id');
       end;

I also have to fill
Quote
-<xds:SigPolicyQualifiers>
-<xds:SigPolicyQualifier>
<xds:SPURI>http://www.crea.si/CreaWWW2004/Public/Software/CreaSignVerifier/demopolitika.html</xds:SPURI>
</xds:SigPolicyQualifier>
</xds:SigPolicyQualifiers>

Can you help me how?
Thanks for helping.
Sašo
#14599
Posted: 09/27/2010 07:07:08
by Dmytro Bogatskyy (EldoS Corp.)

Quote
Code in FormatElement procedure is
...

Please do not use FormatElement workaround for inserting an attribute, you can use a following code:
Code
...
XAdESSigner.Generate();
...
XAdESSigner.QualifyingProperties.SignedProperties.ID = 'SignedPropertiesId';

Unfortunately you can't remove a auto-generated id for SignedSignatureProperties element, I'll fix this for the next build, so you will be able to remove it in FormatElement method.
Quote

I also have to fill
-<xds:SigPolicyQualifiers>

This item can contain a list of any elements. Please use a following code:
Code
TElXMLAnyType item = new TElXMLAnyType(XAdESSigner.XAdESVersion);
item.Value = FXMLDocument.CreateElement("temp"); // use new node or cloned node, works as container for xml tree
TElXMLDOMElement innerElement = FXMLDocument.CreateElementNS(SBXMLDefs.Unit.xmlXAdESNamespace_v1_1_1, "SPURI");
item.Value.AppendChild(innerElement);
innerElement.AppendChild(FXMLDocument.CreateTextNode("http://www.crea.si/CreaWWW2004/Public...:SPURI"));
XAdESSigner.PolicyId.SigPolicyQualifiers.Add(item);
#14641
Posted: 10/01/2010 04:49:41
by Sašo Osenk (Standard support level)
Joined: 09/20/2010
Posts: 35

Thanks for help. The ID from SignedSignatureProperties has gone away when I add timestamp.

I have so more troubles that I need your help.
First is how to remove SignatureValue Id? I need only SignatureValue Value in my xml document.
Second is how to remove UnsignedProperties? I don't need it at all.
Third is if you could take a look at my code below for timestamp if it is OK.

Code
    F := TFileStream.Create(dir+'\Racun_'+SifraRacuna+'.xml', fmOpenRead or fmShareDenyWrite);

    FreeAndNil(FXMLDocument);
    FXMLDocument := TElXMLDOMDocument.Create;
    try
       FXMLDocument.LoadFromStream(F, '', false);
    except
      on E : Exception do
      begin
        MessageDlg('Error: ' + E.Message, mtError, [mbOk], 0);
      end;
    end;
    XAdESSigner := nil;
    TSPClient := nil;
    HTTPClient := nil;
    X509KeyData := nil;

    Ref := nil;
    Refs := TElXMLReferenceList.Create;

    Ref := TElXMLReference.Create;
    Ref.DigestMethod := xdmSHA1;
    Ref.UriNode := FXMLDocument.DocumentElement;
    Ref.URI :='#data';
    Ref.ID:='refData';
    Ref.RefType:='http://www.gzs.si/shemas/eslog/racun/1.4#Racun';
    Refs.Add(Ref);
    Ref:=nil;

    SigNode.Free;

    ELDOS.References := Refs;

    X509KeyData := TElXMLKeyInfoX509Data.Create(False);
    X509KeyData.IncludeDataParams := [xkidX509Certificate];
    X509KeyData.Certificate := NajdiCertifikat;          //, xkidX509CRL,xkidX509IssuerSerial,xkidX509SKI,xkidX509SubjectName
    ELDOS.KeyData := X509KeyData;
    X509KeyData.IncludeKeyValue := False;

   //&#269;asnovno &#382;igosanje
    XAdESSigner := TElXAdESSigner.Create(nil);
    ELDOS.XAdESProcessor := XAdESSigner;
    xadesSigner.XAdESVersion := XAdES_v1_1_1;
    SetLength(Buf, f.Size);
    f.Read(Buf[0], Length(Buf));

    XAdESSigner.PolicyId.SigPolicyId.Identifier:='TEST SASO';
    XAdESSigner.PolicyId.SigPolicyId.Description := 'TEST SASO 1';
    XAdESSigner.PolicyId.SigPolicyId.DocumentationReferences.add('TEST SASO 2');
    XAdESSigner.PolicyId.SigPolicyHash.DigestMethod := SBXMLSec.DigestMethodToURI(xdmSHA1);
    XAdESSigner.PolicyId.SigPolicyHash.DigestValue:=SBXMLSec.CalculateDigest(@Buf[0], Length(Buf), xdmSHA1);

    XAdESSigner.PolicyId.SigPolicyId.IdentifierQualifier :=xqtNone;

    xadesSigner.ProductionPlace.City := '';
    xadesSigner.ProductionPlace.StateOrProvince := X509KeyData.Certificate.SubjectName.StateOrProvince;
    xadesSigner.ProductionPlace.PostalCode := X509KeyData.Certificate.SubjectName.Locality;
    xadesSigner.ProductionPlace.CountryName := X509KeyData.Certificate.SubjectName.Country;


//    TSPClient.URL :='http://postarca.posta.si/tsa/CasovniZig.wsdl';

    XAdESSigner.IgnoreTimestampFailure := false;

    FCertStorage := TElMemoryCertStorage.Create(nil);
    FCertStorage.Add(NajdiCertifikat,true);

    TSPFileClient:=ElFileTSPClient.Create(nil);
    TSPFileClient.IncludeCertificates:=true;
    TSPFIleClient.CertStorage:=FCertStorage;
    TSPFileClient.HashAlgorithm:=SB_ALGORITHM_DGST_SHA1;
    TSPFileClient.TSPInfo.TSAName.IpAddress:='http://postarca.posta.si/tsa/CasovniZig.wsdl';



    XAdESSigner.SigningCertificates := fCertStorage;
    XAdESSigner.TSPClient:=TSPFileClient;

    item:=TElXMLAnyType.Create(XAdESSigner.XAdESVersion);
    item.Value := FXMLDocument.CreateElement('temp'); // use new node or cloned node, works as container for xml tree
    EL := FXMLDocument.CreateElementNS(xmlXAdESNamespace_v1_1_1, 'SPURI');
    item.Value.AppendChild(EL);
    El.AppendChild(FXMLDocument.CreateTextNode('SASO TEST SPURI:SPURI'));
    XAdESSigner.PolicyId.SigPolicyQualifiers.Add(item);
//    XAdESSigner.QualifyingProperties.UnsignedProperties.Clear;

//    XAdESSigner.XAdESForm :=XAdES_T;

    xadesSigner.Generate();


    XAdESSigner.QualifyingProperties.SignedProperties.ID:='SignedPropertiesId';

    xadesSigner.QualifyingProperties.XAdESPrefix :='xds';
    XAdESSigner.QualifyingProperties.Target:='#MySignature';
    //konec &#269;asovnega &#382;igosanja   *)

    ELDOS.UpdateReferencesDigest;

    TSPFIleClient.OnTimestampNeeded:=TSBTimestampNeededEvent;
    ELDOS.Sign;

    ELDOS.Signature.SignatureValue.ID:='';

    ELDOS.Signature.ID:='MySignature';
    ELDOS.Signature.SignaturePrefix := 'ds';

    ELDOS.Signature.SignedInfo.SigPropRef.DigestMethod := xdmSHA1;
    ELDOS.Signature.SignedInfo.SigPropRef.ID := '';
    ELDOS.Signature.SignedInfo.SigPropRef.RefType :='http://uri.etsi.org/01903/v1.1.1#SignedProperties';
    ELDOS.Signature.SignedInfo.SigPropRef.URI:='#SignedPropertiesId';
//    ELDOS.Signature.SignedInfo.SigPropRef.


    z:=0;
    ELDOS.OnFormatElement := FormatElement;
    SigNode := FXMLDocument.DocumentElement;
    if SigNode is TElXMLDOMDocument then
      SigNode := TElXMLDOMDocument(SigNode).DocumentElement;
    try
      // If the signature type is enveloping, then the signature is placed into the passed node and the contents of the node are moved to inside of the signature.
      // If the signature type is enveloped, the signature is placed as a child of the passed node.
      z:=0;
      ELDOS.OnFormatElement := FormatElement;
      ELDOS.Save(SigNode);
      ELDOS.OnFormatElement := FormatElement;
    except
      on E: Exception do
        raise EElXMLError.CreateFmt('Signed data saving failed. (%s)', [E.Message]);
    end;

    F1 := TFileStream.Create(dir+'\Racun_'+SifraRacuna+'_podpisan.xml', fmCreate or fmOpenWrite);
    try
      z:=0;
      ELDOS.OnFormatElement := FormatElement;
      FXMLDocument.SaveToStream(F1, xcmNone, 'utf-8');
    except
      on E : Exception do
      begin
        MessageDlg('Error: ' + E.Message, mtError, [mbOk], 0);
      end;
    end;


Thank you for all your help,
Sašo
#14678
Posted: 10/11/2010 00:55:24
by Sašo Osenk (Standard support level)
Joined: 09/20/2010
Posts: 35

Could anyone help me?

Thanks,
Sašo
#14679
Posted: 10/11/2010 03:46:14
by Dmytro Bogatskyy (EldoS Corp.)

Sorry, missed your message.
Quote
First is how to remove SignatureValue Id? I need only SignatureValue Value in my xml document.

As you want to timestamp, an Id for a SignatureValue element is added automatically as for version 1.1.1 and 1.2.2 explicit mechanism is used for timestamping data (timestamped data should be referenced by an Id or xpointer expression).
Quote

Second is how to remove UnsignedProperties? I don't need it at all.
Third is if you could take a look at my code below for timestamp if it is OK.

You want to remove UnsignedProperties element but you want to timestamp? A SignatureTimeStamp element is placed under UnsignedSignatureProperties element that should, by specification, to be under UnsignedProperties element.
As for your timestamp code:
Quote
TSPFIleClient.OnTimestampNeeded:=TSBTimestampNeededEvent;

Here should be an event handler, not an event type.
#14680
Posted: 10/11/2010 05:04:14
by Sašo Osenk (Standard support level)
Joined: 09/20/2010
Posts: 35

In attachment is the original file that I try to create. It has no SignatureValue ID and no UnsignedProperties. Is there a way to remove this items?
When I remove it myself I get an error from verifier that "Signing certificate from signed properties does not match the real one
". Any idea why?

TSBTimestampNeededEvent is a procedure below.

Code
Procedure TFeRacun.TSBTimestampNeededEvent(Sender : TObject; RequestStream, ReplyStream: TStream; var Succeeded : boolean);
var srv:TElFileTSPServer;
    r:integer;
begin
  srv:=TElFileTSPServer.create(nil);
  srv.Certificates := TElMemoryCertStorage.create(nil);
  srv.Certificates.Add(NajdiCertifikat,true);
  RequestStream.Position := 0;
  r := srv.LoadRequestFromStream(RequestStream);
  srv.SaveReplyToStream(psGranted, 0, ReplyStream);
  Succeeded := true;
end;



Thanks.

Sašo


[ Download ]
Also by EldoS: BizCrypto
Components for BizTalk® and SQL Server® Integration Services that let you securely store and transfer information in your business automation solutions.

Reply

Statistics

Topic viewed 26398 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!