PC SOFT

FOROS PROFESIONALES
WINDEVWEBDEV y WINDEV Mobile

Inicio → WINDEV 2024 → [WD19] How to build and sign an XML file?
[WD19] How to build and sign an XML file?
Iniciado por guest, 07,mar. 2016 10:40 - 6 respuestas
Publicado el 07,marzo 2016 - 10:40
Hi all,

I need to build and sign an XML file called Application Request and finally sending it to a bank using a webservice called CorporateFileService. This goes beyond my procedurally thinking brains, so I need help from xml/ws specialists to get started.

The necessary schema, certificate and WSDL files are available here:
http://www.nordea.fi/en/corporate-customers/payments/electronic-banking/testing.html…

Aditional documents are here:
http://www.nordea.fi/en/corporate-customers/payments/electronic-banking/web-services.html…

And the detailed message descriptions (in English, despite the link text's language) are here:
http://www.finanssiala.fi/maksujenvalitys/dokumentit/WebServices_Messages_20081022_105.pdf…

To start with, I need to build an "ApplicationRequest" XML file like below, where ... (3 dots) dots indicates that a portion of the string has been cut away. I have all the data prepared, the content base 64 -coded and the certificate containing the provate key in a separate file, I just need to know how to insert them into an xml file like this:
(Note: <> have been replaced with [] to keep it readable, the smiley has replaced characters ":p")
[ApplicationRequest xmlns="http://bxd.fi/xmldata/"] [CustomerId]679155330[/CustomerId] [Command]UploadFile[/Command] [Timestamp]2010-09-13T13:04:57.768+03:00[/Timestamp] [Environment]PRODUCTION[/Environment] [TargetId]11111111A1[/TargetId] [SoftwareId]MyProgram[/SoftwareId] [FileType]NDCORPAYS[/FileType] [Content]PD94bWwgdmVy ... dW1lbnQ+[/Content] [Signature xmlns="http://www.w3.org/2000/09/xmldsig#"] [SignedInfo] [CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315…] [SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig…] [Reference URI=""] [Transforms] [Transform Algorithm="http://www.w3.org/2000/09/xmldsig…] [/Transforms] [DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig…] [DigestValue]qBXne/Fko6yvVadNZVpbQQ8afWI=[/DigestValue] [/Reference] [/SignedInfo] [SignatureValue]fOJ3EwA ... 4Kd0o=[/SignatureValue] [KeyInfo] [X509Data] [X509Certificate]MIID+jCCAuKg ... BPkZp8OKo=[/X509Certificate] [X509IssuerSerial] [X509IssuerName]2.5.4.5=#130b3531363430362d30313230,CN=Nordea role-certificates CA 01,O=Nordea Bank AB (publ),C=SE[/X509IssuerName] [X509SerialNumber]13070788[/X509SerialNumber] [/X509IssuerSerial] [/X509Data] [/KeyInfo] [/Signature] [/ApplicationRequest] The schema looks like this (middle part cut away):
[?xml version="1.0" encoding="UTF-8"?] [!-- edited with XMLSpy v2009 (http://www.altova.com) by Petri Luoto (Nordea) --] [xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:bxd="http://bxd.fi/xmldata/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" targetNamespace="http://bxd.fi/xmldata/" elementFormDefault="qualified" attributeFormDefault="unqualified"] [xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/] [xs:element name="ApplicationRequest"] [xs:annotation] [xs:documentation]Wrapper for data. Used for transmitting data. Can be XML Digital Signed.[/xs:documentation] [/xs:annotation] [xs:complexType] [xs:sequence] [xs:element name="CustomerId" nillable="false"] [xs:simpleType] [xs:restriction base="xs:string"] [xs:minLength value="1"/] [xs:maxLength value="16"/] [/xs:restriction] [/xs:simpleType] [/xs:element] [xs:element name="Command" nillable="false" minOccurs="0"] [xs:simpleType] [xs:restriction base="xs:string"] [xs:maxLength value="32"/] [xs:minLength value="1"/] [/xs:restriction] [/xs:simpleType] [/xs:element] [xs:element name="Timestamp" type="xs:dateTime"/] ... (here many elements have been cut away) ... [xs:element name="Content" type="xs:base64Binary" nillable="true" minOccurs="0"/] [xs:element ref="ds:Signature" minOccurs="0"/] [/xs:sequence] [/xs:complexType] [/xs:element] [xs:simpleType name="EnvironmentCode"] [xs:annotation] [xs:documentation]Production or Test[/xs:documentation] [/xs:annotation] [xs:restriction base="xs:NMTOKEN"] [xs:pattern value="(PRODUCTION|TEST)"/] [/xs:restriction] [/xs:simpleType] [/xs:schema] So how do I code this?
I suppose I need to start with something like this:
xAppReq is xmlDocument [description="ApplicationRequest"] xNode is xmlNode //Or dynamic?!?!? How to continue?

Best regards
Ola
Publicado el 07,marzo 2016 - 23:20
Hi again,

I think I got over the first treshold, and my code now looks like this:
xAppReq is xmlDocument xNode is xmlNode xNode..Name = "ApplicationRequest" //But how to add the attribute //xmlns="http://bxd.fi/xmldata/" //to this first node? Add(xAppReq,xNode) xAppReq.ApplicationRequest[1].CustomerId = wCustomerId xAppReq.ApplicationRequest[1].Timestamp = wTimeStamp xAppReq.ApplicationRequest[1].Environment = wEnvironment xAppReq.ApplicationRequest[1].TargetId = wTargetId xAppReq.ApplicationRequest[1].Compression = "false" xAppReq.ApplicationRequest[1].AmountTotal = C_Sum xAppReq.ApplicationRequest[1].TransactionCount = C_Counter xAppReq.ApplicationRequest[1].SoftwareId = wSoftwareId xAppReq.ApplicationRequest[1].FileType = "pain.001.001.02" xAppReq.ApplicationRequest[1].Content = XFileInString64 ...and next the signature. Any hints on it?
Am I on the right track?

best regards
Ola
Publicado el 08,marzo 2016 - 08:29
Hi,

I used the namespace for the ubl stuff ( xml invoicing )

Maybe this helps:

sPath_Pdf is string
sPath is string
xmlfact is xmlDocument ,description="UBL-Invoice"
//xmlfact = XMLOpen("UBL-Invoice.xml")
xmlfact..Encoding = "UTF-8"
nNamespace1 is xmlNamespace
nNamespace2 is xmlNamespace
nNamespace3 is xmlNamespace
nNamespace4 is xmlNamespace
nNode is dynamic xmlNode
nNode = xmlfact.Invoice




nNamespace4..URI = "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" //1
nNamespace3..URI = "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" //2
nNamespace3..Name = "cac" //2
nNamespace2..Name = "cbc"
nNamespace2..URI = "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"//3
nNamespace1..Name = "xsi"
nNamespace1..URI = "http://www.w3.org/2001/XMLSchema-instance"

Add(nNode..NamespaceDeclared, nNamespace4)
Add(nNode..NamespaceDeclared, nNamespace3)
Add(nNode..NamespaceDeclared, nNamespace2)
Add(nNode..NamespaceDeclared, nNamespace1)

nNode:schemaLocation..Value = "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd"
nNode:schemaLocation..Namespace = nNamespace1

regards

Allard
Publicado el 08,marzo 2016 - 11:56
Thanks Allard,

I'll try using the namespace to add the attribute.

Best regards
Ola
Publicado el 09,marzo 2016 - 11:31
Namespace did the trick of adding the attribute to the first node, but it caused also a problem:
xAppReq is xmlDocument xNamespace is xmlNamespace xNode is dynamic xmlNode xNode = xAppReq.ApplicationRequest //xNamespace..Name = "xmlns" //This validates, but creates a double entry like this: //[ApplicationRequest xmlns="http://bxd.fi/xmldata/" xmlns:xmlns="http://bxd.fi/xmldata/"] xNamespace..URI = "http://bxd.fi/xmldata/" //"xmlns=" is added automatically in front of URI! Add(xNode..NamespaceDeclared,xNamespace) The Add generates a Weird error, although the file looks perfectly good and the file validates when saving it!
'Add' function, syntax 1
The '' namespace is already defined in this node.
Two namespaces with the same name cannot exist within the same node.
Error code: 40039
Level: non-fatal error (EL_ONRETURN)
This error does not pop-up itself, but it is launched,
if the process is interrupted for any reason, like manual cancellation.
- this is obviously caused because I took ouit the xNamespace..Name = "xmlns" line,
which caused a double entry
- so how should i handle the xNamespace..Name = "xmlns" line ???

How can I kill this error (or add the attribute "correctly")?

Best regards
Ola
Publicado el 09,marzo 2016 - 12:52
Hi. If you use a XSD file you don't need assign the namespace. Windev add it when you chech and save the xml.

Linea is xmlDocument, description="XSD file name" // imported in project

// Add here your nodes with the XSD order

Linea.Node Name = Node Value
......
......


IF XMLValidDocument(Linea) = True THEN
XMLSave(Linea, fExeDir() + "\XML_Temp\File.xml")
IF ErrorOccurred = True THEN
Error("Unable to save the XML document", ErrorInfo())
ELSE
Info("OK", fExeDir() + "\XML_Temp\File.xml")
END
ELSE
Error("The XML document is invalid", ErrorInfo())
END


When you Save the XML then Windev apply the XSD format to XML resultant and check the correct XML content.


Rubén
Publicado el 09,marzo 2016 - 17:26
Hi Ruben,

Thank you very much; it works like you said. I tried this also earlier, but then it didn't work -- possibly because then there was some other problems with the code.
But now the attribute is there, and the xml building code now looks like this:
xAppReq is xmlDocument, description="ApplicationRequest" //Imported WSDL xNode is dynamic xmlNode xNode = xAppReq.ApplicationRequest xAppReq.ApplicationRequest[1].CustomerId = wCustomerId xAppReq.ApplicationRequest[1].Timestamp = wTimeStamp xAppReq.ApplicationRequest[1].Environment = wEnvironment xAppReq.ApplicationRequest[1].TargetId = wTargetId xAppReq.ApplicationRequest[1].Compression = "false" xAppReq.ApplicationRequest[1].AmountTotal = C_Sum xAppReq.ApplicationRequest[1].TransactionCount = C_Counter xAppReq.ApplicationRequest[1].SoftwareId = wSoftwareId xAppReq.ApplicationRequest[1].FileType = "pain.001.001.02" xAppReq.ApplicationRequest[1].Content = XFileInString64 //Base 64 -coded "payload" So far this is good. The file validates without hick-ups and the correct dota seems to be in correct places.

The next step is the signing. According to documents: "Digitally sign (Enveloped -type) the whole "Application Request" with the Private Key of the Signing Certificate."

I am trying to initialize the signature with a code piece mainly copied from WD help example:
MySignature is xmlSignature MySignature..AlgorithmNormalization = atC14NExclusive //What is this? MySignature..AlgorithmSignature = asRSA_SHA_160 //Obviously same as the RSA SHA-1 required by Nordea // Key file OR certificate retrieved by the certificate functions: MySignature..Key = wWsPrivCertFile //File name with full path of the private certificate file MySignature..KeyPassword = wPassword //Password for testing = "WSNDEA1234" MySignature..KeyFileType = tfcPKCS12 //certificate file has ".p12" extension MySignature..Reference[1]..AlgorithmHash = HA_SHA_160 MySignature..Reference[1]..URI = "#xpointer(/)" //in WD sample: "#" + id - wonder what this is. //is it OK to just add verbatim the "#xpointer(/)", like in the example file? MySignature..Reference[1]..Transformation[1] = atEnveloped //Type of signatue MySignature..Reference[1]..Transformation[2] = atC14NExclusive //What is this? x509 is xmlSignatureInformationKeyX509 x509..WithCertificate = True MySignature..KeyInformation[1] = x509 This probably is not yet fully correct, but at this point I am just trying to get some kind of,/any kind of signature into the document.

So how should I add these signature elements to the document? The next node, with these kinds of child elements is "Signature".
The first message in this thread shows how the signature section looks like in the sample file and the schema.

best regards
Ola