Create an enveloping signature using a DSA key

In this example, a XML document ("MyDocument.xml") is loaded and signed with a DSA key.

You can use the sample content provided in XML document (unsigned) for the purpose of testing the code. Copy the content to a file named "MyDocument.xml" in a directory where you test the sample code.

A DSA key ("DSAKey.pem") is used to sign the document. You will need to generate this key. The key can be created with the OpenSSL tool.
  1. Generate parameters from which to generate the key:
    openssl dsaparam -out DSAparam.pem 2048
    The number 2048 is the size of the key in bits.
  2. Generate a private key and save it to DSAKey.pem
    openssl gendsa -out DSAKey.pem DSAparam.pem
Copy the file "DSAKey.pem" to a directory where you test the sample code.

All keys or certificates in PEM or DER format were created with the OpenSSL tool. For information on how the OpenSSL tool works, refer to the openssl (external link) documentation.

IMPORT xml

MAIN
  DEFINE doc xml.DomDocument
  DEFINE sig xml.Signature
  DEFINE key xml.CryptoKey
  DEFINE index INTEGER
  DEFINE objInd 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("MyDocument.xml")
    # Create DSA key and load it from file
    LET key = xml.CryptoKey.Create(
      "http://www.w3.org/2000/09/xmldsig#dsa-sha1")
    CALL key.loadPEM("DSAKey.pem")
    # Create signature object with the key to use
    LET sig = xml.Signature.Create()
    CALL sig.setKey(key)
    # Create an object inside the signature to envelop the root node 
    LET objInd = sig.createObject()
    # Set the object id to get a reference
    CALL sig.setObjectId(objInd,"data")
    # Copy the enveloping node from the document
    CALL sig.appendObjectData(objInd,doc.getDocumentElement())
    # Set the reference to be signed on the object node. 
    # In our case, the object node with attribute 'data'
    LET index = sig.createReference("#data",
      "http://www.w3.org/2000/09/xmldsig#sha1")
    # Set canonicalization method on the enveloping object to be signed.
    CALL sig.appendReferenceTransformation(index,
      "http://www.w3.org/2001/10/xml-exc-c14n#")
    # Compute enveloping signature
    CALL sig.compute(NULL)
    # Retrieve signature document
    LET doc=sig.getDocument()
    # Save signature on disk
    CALL doc.setFeature("format-pretty-print",TRUE)
    CALL doc.save("MyDocumentEnvelopingSignature.xml")
  CATCH
    DISPLAY "Unable to create an enveloping signature :",status
  END TRY
END MAIN