EldoS | Feel safer!

Software components for data protection, secure storage and transfer

XML Signing Problem

Also by EldoS: CallbackDisk
Create virtual disks backed by memory or custom location, expose disk images as disks and more.
#14916
Posted: 11/02/2010 12:19:37
by Lucas Bek (Basic support level)
Joined: 11/02/2010
Posts: 4

Hello Sears,
I'm using yours vcl component in D2007. I have problem with Xml Signing.
When I'm signing the same document in other application the signature is different
than from your component, and document (from other application) passes the verification
process but when i'm signing with blackbox it does not. Below is code that i use to sign,
documents. Can you tell me what is wrong with it ? I'm sending two xml files too. One is
signed by the code below, and one is signed by another application.

I have second question. When i'm saving xml document using SaveToStream there are two
characters that appear at the beginning of document. I read that i have to use :

var Codec: TelXmlCodec;
Codec:= TelXmlUTF8Codec.Create;
try
codec.WriteBom := false;
XmlDocument.SaveToStream(Stream, xcmNone, Codec)
finally
freeandnill(Codec)
end;

however the saved xml file is not complete. It's ends at the x509certificate node.

Please help me.
With regards
Łukasz Bek

procedure Sign(sDeklaracja: WideString);
var
F: TStringStream;
Signer : TElXMLSigner;
XAdESSigner: TElXAdESSigner;
HMACKeyData: TElXMLKeyInfoHMACData;
RSAKeyData: TElXMLKeyInfoRSAData;
X509KeyData: TElXMLKeyInfoX509Data;
PGPKeyData: TElXMLKeyInfoPGPData;
SigNode: TElXMLDOMNode;
Ref: TElXMLReference;
Refs: TElXMLReferenceList;
NodeSet: TelXMLNodeSet;
Transform :TelXMLC14NTransform;
CertStorage: TElMemoryCertStorage ;
Obj: TElXMLObject;
Cert: TElX509Certificate;
El: TElXMLDOMElement;
SigInfo: TelXmlSignedInfo;
objNoId: TElXMLDOMNode;
begin

F := TStringStream.Create(UTF8Encode(sDeklaracja));

FXMLDocument.LoadFromStream(F, 'utf-8', true);

ref := TelXMLReference.Create();
ref.DigestMethod := xdmSHA1;
ref.URI := '#Dokument-0';
NodeSet := FXMLDocument.SelectNodes('/');
ref.URINode := NodeSet[0];

refs := TelXMLReferenceList.Create();

Refs.Add(Ref);

Cert := Certyficate;

Signer := TelXMLSigner.Create(nil);

Signer.SignatureType := xstEnveloping;
Signer.CanonicalizationMethod := xcmCanon; //frmSign.CanonicalizationMethod;
Signer.SignatureMethodType := xmtSig;
Signer.SignatureMethod := xsmRSA_SHA1;

Signer.References := Refs;
Signer.KeyName := '';
Signer.IncludeKey := true;
// Commented out
X509KeyData := TElXMLKeyInfoX509Data.Create(false);
X509KeyData.Certificate := Cert;
Signer.KeyData := X509KeyData;
XAdESSigner := TElXAdESSigner.Create(nil);
Signer.XAdESProcessor := XAdESSigner;
XAdESSigner.XAdESVersion := XAdES_v1_3_2;
XAdESSigner.PolicyId.SigPolicyId.Description := 'testing';
XAdESSigner.PolicyId.SigPolicyId.DocumentationReferences.Add('testing');
XAdESSigner.PolicyId.SigPolicyId.Identifier := 'testing';
XAdESSigner.PolicyId.SigPolicyId.IdentifierQualifier := xqtOIDAsURI;
CertStorage := TElMemoryCertStorage.Create(nil);
CertStorage.Add(Cert, false);
XAdESSigner.SigningCertificates := CertStorage;
XAdESSigner.PolicyId.SigPolicyHash.DigestMethod := DigestMethodToURI(xdmSHA1);
XAdESSigner.Generate();
XAdESSigner.QualifyingProperties.XAdESPrefix := 'xades';

XAdeSSigner.QualifyingProperties.Target := '#Signature-0';
Signer.UpdateReferencesDigest();
Signer.Sign();


Signer.Signature.SignaturePrefix := 'ds';
SigNode := TElXMLDOMNode(NodeSet[0]);
if (SigNode is TElXMLDOMDocument) then
SigNode := (TElXMLDOMDocument(SigNode).DocumentElement);

obj := TElXMLObject.Create();
obj.ID := 'Dokument-0';
obj.DataList.Add(SigNode.CloneNode(true));

Signer.Signature.Objects.Add(obj);
Signer.Signature.SignedInfo.ID := 'SignedInfo-0';
Signer.Signature.ID := 'Signature-0';
Signer.Signature.KeyInfo.ID := 'KeyInfo-0';
Signer.Save(SigNode);

objNoId := SigNode.LastChild;
SigNode.RemoveChild(objNoId);

FXMLDocument.SaveToStream(F);

end;


[ Download ]
#14920
Posted: 11/02/2010 14:13:31
by Dmytro Bogatskyy (EldoS Corp.)

First, please do not use TStringStream. Use TFileStream, TMemoryStream and etc. TStringStream doesn't work well with non-ASCII data.
Second when you save a document "FXMLDocument.SaveToStream(F);" you need to set stream Position property to 0 (or better to create new stream).
If you need to pass signed data to some service you may use FXMLDocument.DocumentElement.OuterXML property that will return xml element as unicode string.

Third, The code above work for me ok with TFileStream, but I suggest to slightly modify it, to use detached signature type not an enveloping as you creating an Object by your self.
So, remove a following lines:
Code
NodeSet := FXMLDocument.SelectNodes('/');  
ref.URINode := NodeSet[0];
and
Signer.UpdateReferencesDigest();

they are not needed as reference points inside a signature, and references will be updated anyway on signing

replace:
Signer.SignatureType := xstEnveloping;
with
Signer.SignatureType := xstDetached;

replace
Code
SigNode := TElXMLDOMNode(NodeSet[0]);
if (SigNode is TElXMLDOMDocument) then
SigNode := (TElXMLDOMDocument(SigNode).DocumentElement);

obj := TElXMLObject.Create();
obj.ID := 'Dokument-0';
obj.DataList.Add(SigNode.CloneNode(true));

with
Code
obj := TElXMLObject.Create();
obj.ID := 'Dokument-0';
obj.DataList.Add(FXMLDocument.DocumentElement.CloneNode(true));


and replace
Code
Signer.Save(SigNode);

objNoId := SigNode.LastChild;
SigNode.RemoveChild(objNoId);

FXMLDocument.SaveToStream(F);

with
Code
NewXMLDocument := TElXMLDOMDocument.Create;
SigNode := NewXMLDocument;
Signer.Save(SigNode);

NewXMLDocument.SaveToStream(...)
FreeAndNil(NewXMLDocument);
#14948
Posted: 11/04/2010 04:09:43
by Lucas Bek (Basic support level)
Joined: 11/02/2010
Posts: 4

Thanks for quickly reply.
I used your advices
but I still have a problem. Both of files passes the verification when i'm using blackbox verifier but only one is succesfully accepted by webservice where i'm sending it. That is the one signed by other application. Maybe problem is in structure of signature... How can i rid of 'issuer' node from qualifingproperties ? This is only one thing i see that differs those files ...
#14949
Posted: 11/04/2010 04:29:34
by Dmytro Bogatskyy (EldoS Corp.)

Quote
How can i rid of 'issuer' node from qualifingproperties ?

SigningCertificate/IssuerSerial/X509IssuerName node?
Could you post both samples.
#14950
Posted: 11/04/2010 04:49:53
by Lucas Bek (Basic support level)
Joined: 11/02/2010
Posts: 4

Below is my procedure in delphi.
Those two files in attachment are
dopodpisu.xml - file that i want to sign
poprawny.xml - signed file that i want have. (signed with other application)

i can not do it properly.
Please help.

Code
procedure TdmSigner.Test();
var
  Signer : TElXMLSigner;
  XAdESSigner: TElXAdESSigner;
  HMACKeyData: TElXMLKeyInfoHMACData;
  RSAKeyData: TElXMLKeyInfoRSAData;
  X509KeyData: TElXMLKeyInfoX509Data;
  PGPKeyData: TElXMLKeyInfoPGPData;
  SigNode: TElXMLDOMNode;
  Ref: TElXMLReference;
  Refs: TElXMLReferenceList;
  NodeSet: TelXMLNodeSet;
  Transform :TelXMLC14NTransform;
  CertStorage: TElMemoryCertStorage ;
  Obj: TElXMLObject;
  Cert: TElX509Certificate;
  El: TElXMLDOMElement;
  SigInfo: TelXmlSignedInfo;
  objNoId: TElXMLDOMNode;
  TmpNode:TElXMLDOMNode;
  F, FW: TFileStream;
begin

  F:= TFileStream.Create('c:\testyxml\dopodpisu.xml', fmOpenRead);

  FXMLDocument := TelXmlDomDocument.Create();

  FXMLDocument.LoadFromStream(F, 'UTF-8', true);

  ref := TelXMLReference.Create();
  ref.DigestMethod := xdmSHA1;
  ref.URI := '#Dokument-0';

  refs := TelXMLReferenceList.Create;

  refs.Add(ref);

  Cert := Certyficate;

  Signer := TelXmlSigner.Create(nil);
  Signer.OnFormatElement := FormatElement;
  Signer.OnFormatText := FormatText;

  Signer.SignatureType := xstDetached;
  Signer.CanonicalizationMethod := xcmCanon;
  Signer.SignatureMethodType := xmtSig;
  Signer.SignatureMethod := xsmRSA_SHA1;

  Signer.References := refs;
  Signer.KeyName := '';

  X509KeyData := TelXmlKeyInfoX509Data.Create(false);

  X509KeyData.Certificate := Cert;
  X509KeyData.IncludeKeyValue := false;

  Signer.KeyData := X509KeyData;

  XAdESSigner := TelXAdESSigner.Create(nil);

  Signer.XAdESProcessor := XAdESSigner;

  XAdESSigner.XAdESVersion := XAdES_v1_3_2;

  CertStorage := TelMemoryCertStorage.Create(nil);

  CertStorage.Add(Cert, false);

  XAdESSigner.SigningCertificates := CertStorage;


  XAdESSigner.Generate();

  XAdESSigner.QualifyingProperties.XAdESPrefix := 'xades';

  XAdESSigner.QualifyingProperties.Target := '#Signature-0';

  Signer.Sign;

  Signer.Signature.SignaturePrefix := 'ds';

  obj := TelXmlObject.Create;
  obj.ID := 'Dokument-0';
  obj.DataList.Add(FXMLDocument.DocumentElement.CloneNode(true));

  Signer.Signature.Objects.Add(obj);
  Signer.Signature.SignedInfo.ID := 'SignedInfo-0';
  Signer.Signature.ID := 'Signature-0';
  Signer.Signature.KeyInfo.ID := 'KeyInfo-0';


  NewXMLDocument := TelXmlDomDocument.Create;
  SigNode := NewXmlDocument;

  Signer.Save(SigNode);

  FW := TFileStream.Create('C:\testyxml\podpisany.xml', fmCreate or fmOpenWrite);
  FW.Position := 0;

  NewxmlDocument.SaveToStream(FW, xcmNone, 'UTF-8');

  FreeAndNil(NewXmlDocument);
  FreeAndNil(FW);

end;


[ Download ]
#14955
Posted: 11/04/2010 08:14:14
by Lucas Bek (Basic support level)
Joined: 11/02/2010
Posts: 4

I've tried everythig to sign the document, so it can be like that i want. Digest values for document object and signed properties references differs from those from my propper signed document and i don't have any idea why.
Please help.
#14960
Posted: 11/04/2010 18:45:36
by Dmytro Bogatskyy (EldoS Corp.)

Quote
Digest values for document object and signed properties references differs from those from my propper signed document and i don't have any idea why.

Digest value for a document object is different because in your signed document an application that signed it removed all whitespace characters (spaces, newlines) between tags from "Deklaracja" element.
You can do the same by enumerating all nodes in this element and removing text nodes with whitespace characters before signing.
As for signed properties references do you test with the same certificate? That included in SigningCertificate. Could you attach a signed xml document that you create.
Also by EldoS: RawDisk
Access locked and protected files in Windows, read and write disks and partitions and more.

Reply

Statistics

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