IMPORT xml MAIN DEFINE doc xml.DomDocument DEFINE doc2 xml.DomDocument DEFINE root xml.DomNode DEFINE node xml.DomNode DEFINE signNode xml.DomNode DEFINE sig xml.Signature DEFINE key xml.CryptoKey DEFINE index INTEGER # Create DomDocument object LET doc = xml.DomDocument.Create() # Notice that whitespaces are significant in cryptography, # therefore it is recommended to remove unnecessary ones CALL doc.setFeature("whitespace-in-element-content",FALSE) TRY # Load document to be signed CALL doc.load("nacetoken.xml") # Create rsa key LET key = xml.CryptoKey.Create("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256") CALL key.loadPEM("apns-key-noenc.pem") # Create signature object with the key to use LET sig = xml.Signature.Create() CALL sig.setKey(key) # Set XML node to be signed. In our case, the node with # attribute 'xml:id="code"' LET index = sig.createReference("", "http://www.w3.org/2001/04/xmlenc#sha256") # Add enveloped method to not take the XML signature node into account # when computing the entire document. CALL sig.appendReferenceTransformation(index, "http://www.w3.org/2000/09/xmldsig#enveloped-signature",doc.getDocumentElement()) # Set canonicalization method on the XML fragment to be signed. CALL sig.appendReferenceTransformation(index, "http://www.w3.org/2001/10/xml-exc-c14n#") # Compute enveloped signature CALL sig.compute(doc) # Retrieve signature document LET doc2=sig.getDocument() # Append the signature node to the original document to get # a valid enveloped signature # Notice that the enveloped signature can be added anywhere in the # original document LET signNode = doc2.getDocumentElement() # Get Signature node # Import it into the original document LET node = doc.importNode(signNode,true) # Retrieve the original document root node LET root = doc.getDocumentElement() # Append the signature node as last child of the original document CALL root.appendChild(node) # Save document with enveloped signature back to disk CALL doc.setFeature("format-pretty-print",TRUE) CALL doc.save("naceSignature.xml") CALL validarx509("naceSignature.xml") CATCH DISPLAY "Unable to create an enveloped signature :",status," ",sqlca.sqlerrm END TRY END MAIN FUNCTION validarX509(archivo) DEFINE archivo STRING DEFINE doc xml.DomDocument DEFINE root xml.DomNode DEFINE node xml.DomNode DEFINE sig xml.Signature DEFINE key xml.CryptoKey DEFINE list xml.DomNodeList DEFINE isVerified INTEGER DEFINE x509 xml.CryptoX509 # Create DomDocument object LET doc = xml.DomDocument.Create() # Notice that whitespaces are significant in cryptography, # therefore it is recommended to remove unnecessary ones CALL doc.setFeature("whitespace-in-element-content",FALSE) LET x509 = xml.CryptoX509.Create() TRY CALL x509.loadPEM("apns-cert.pem") CATCH DISPLAY "Unable to load certificate :",STATUS," ",sqlca.sqlerrm EXIT PROGRAM END TRY TRY # Load original document with enveloped signature into a DomDocument object CALL doc.load(archivo) # Because the signature can be anywhere in the original document, # we must first retrieve it LET list = doc.getElementsByTagNameNS("Signature", "http://www.w3.org/2000/09/xmldsig#") IF list.getCount() != 1 THEN DISPLAY "Unable to find one Signature node" EXIT PROGRAM (-1) ELSE LET node = list.getItem(1) END IF # Create RSA key LET key = xml.CryptoKey.Create( "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256") CALL key.loadPEM("apns.pem") # Create signature object from DomNode object and set RSA key to use LET sig = xml.Signature.CreateFromNode(node) CALL sig.setKey(key) # Verify enveloped signature validity of original document LET isVerified = sig.verify(doc) # Notice that if something has been modified in the node with # attribute 'xml:id="code"' of the original XML document with the # enveloped signature, the program will display "FAILED". IF isVerified THEN DISPLAY "Signature OK" TRY CALL x509.setFeature("X509Certificate",TRUE) # LET signnode = doc.importNode(node,TRUE) # LET root = doc.getDocumentElement() # CALL root.appendChild(signnode) LET doc = x509.save() CALL doc.setFeature("format-pretty-print",TRUE) CALL doc.save("RSAX509Certificate.xml") CATCH DISPLAY "Unable to save certificate :",STATUS END TRY ELSE DISPLAY "Signature FAILED" END IF CATCH DISPLAY "Unable to verify the enveloped signature :",status END TRY END FUNCTION