135 lines
4.9 KiB
Plaintext
135 lines
4.9 KiB
Plaintext
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 |