Files
MBS/WEBSERVICES/test/firmarsakey.4gl
T

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