Digitally signing UBL documents

G. Ken Holman

Crane Softwrights Ltd.

$Date: 2010/11/27 21:40:09 $(UTC)


Table of Contents

1. Introduction
1.1. UBL version compatibility
2. Installation
2.1. Crane's components
2.2. Saxon component
2.3. xmlsec components
3. Keys and certificates
3.1. Getting your own demonstration certificate
4. Adding an enveloped signature to a UBL document
5. Creating a detached signature for a UBL document
6. Verifying a signature in a UBL document
7. Injecting a XML digital signature object extension
8. Cosigning and countersigning
9. Configuring referenced elements
10. Sample session
11. Future work and feedback

1. Introduction

This is a command-line environment to digitally sign XML documents in the OASIS Universal Business Language (UBL) 2.x vocabulary. Digitally signing a document with your private key and certificate allows the recipient to detect any modifications made to it after adding the signature. Therefore, an unmodified UBL instance can be assumed to be coming from you, and you cannot repudiate it coming from you. Using this environment, multiple parties can sign a UBL document one at a time, and all signatures are checked during verification.

Note

The current version of this environment is a pure IETF/W3C digital signature environment and does not (yet) generate the stringent extended XAdES requirements for legal use in Europe per the ETSI specifications. This environment does, however, support incorporating an externally-created XAdES extension object for a digital signature (ref: Section 7, “Injecting a XML digital signature object extension”). Research is underway to support the XAdES generation requirements in a future version of this environment.

This environment is demonstrative and has not been designed to be tamper proof or necessarily run securely as it stands. It does not have a lot of features (for examples, you can only add a single signature at a time and you cannot replace or delete a signature). It is up to the user to adapt this environment for their own use and liability, or use commercially available software offering such guarantees or features and not to rely on this environment to provide same.

This environment is comprised of components from different sources. Please note the following legal information applicable to Crane's components only; please review the legal information associated with all other components from their respective sources:

Copyright (C) - Crane Softwrights Ltd.
              - http://www.CraneSoftwrights.com/links/res-dev.htm

Redistribution and use of components created by Crane Softwrights Ltd. in 
source and binary forms, with or without modification, are permitted 
provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
- The name of the author may not be used to endorse or promote products
  derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Note: for your reference, the above is the "Modified BSD license", this text
      was obtained 2003-07-26 at http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5

THE AUTHOR MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS CODE FOR ANY
PURPOSE. PLEASE CONSULT THE RESPECTIVE RESPONSIBLE PARTIES REGARDING COPYRIGHT
AND LEGAL OBLIGATIONS FOR COMPONENTS NOT WRITTEN BY CRANE SOFTWRIGHTS LTD.

1.1. UBL version compatibility

In any version of UBL the digital signature information is embedded under the extension point of the UBL document in such a way that it does not interfere with XML-based applications reading the content of the instance. Therefore, this environment successfully verifies digital signatures in UBL 2.0 documents even though the signature scaffolding was first released for UBL 2.1. It is not a requirement of this environment to use UBL schemas to validate a document with a signature. Should you wish to do so, the UBL 2.1 Public Review Draft 1 http://docs.oasis-open.org/ubl/prd1-UBL-2.1/ is the first UBL distribution to contain the schema fragments to validate a signature extension. The extension schema module from UBL 2.1 named UBL-ExtensionContentDataType-2.1.xsd is renamed to "2.0" and replaces the like-named module in a UBL 2.0 distribution. The UBL 2.1 signature schema modules are then added to the UBL 2.0 distribution without renaming to satisfy the schema import chain.

2. Installation

There are three sets of components that need to be available to be run. Some may already be installed on your system. Those that are found in the distribution ZIP file are installed in a single directory and that directory must be put on the command search path. The other components not already available from any command prompt can all be put into the same directory created for Crane's components.

2.1. Crane's components

Create a directory in your system for Crane's components and put the contents of the ZIP package into that directory. This directory needs to be added to the system command search path such that running the batch files from any other directory will find the components in the Crane directory.

If you are having problems signing your documents, please review Section 9, “Configuring referenced elements” regarding possible configuration of the invocation files to accommodate custom requirements for ID-typed attributes. This configuration should not be necessary for typical use of this environment.

2.2. Saxon component

From http://saxon.sf.net/#F6.5.5 download saxon6-5-5.zip, unzip it and place saxon.jar in the Crane component directory.

2.3. xmlsec components

From the FTP directory at ftp://ftp.zlatkovic.com/libxml/ there are five ZIP files that include required components. Use the latest version of each ZIP file as there are some duplicates. In each case, however, only a select few of the embedded components need to be used. Download each ZIP file and from the "bin/" directory in each package copy only the following 8 files into the Crane component directory:

  • from iconv-*.zip (tested with version 1.9.2)

    • iconv.dll

  • from libxml2-*.zip (tested with version 2.7.7)

    • libxml2.dll

  • from libxmlsec-*.zip (tested with version 1.2.13):

    • libxmlsec-mscrypto.dll

    • libxmlsec-openssl.dll

    • libxmlsec.dll

    • xmlsec.exe

  • from openssl-*.zip (tested with version 0.9.8a)

    • openssl.exe

  • from zlib-*.zip (tested with version 1.2.5)

    • zlib1.dll

Note

Helpful (but unnecessary for this environment) information regarding the xmlsec tool can be found here: http://www.aleksey.com/xmlsec

Note

Helpful (but unnecessary for this environment) information regarding the openssl tool can be found here: http://security.ncsa.illinois.edu/research/grid-howtos/usefulopenssl.html

3. Keys and certificates

A PKCS#12 file contains both a private key (under password control) and a public key certificate that represents you in the digital signature world. These artefacts are issued by a Certificate Authority (CA) who may or may not vouch for your identity in the real world. Typically in a trading partner agreement, the parties would agree on the CA to use for each party's credentials, trusting in the CA to vouch for their identity by whatever mechanisms that CA has engaged.

Crane's environment will not function without a PKCS#12 file. If you already have a private/public key pair in another format other than PKCS#12, the openssl program has some useful conversion routines built in with which to create what is needed.

3.1. Getting your own demonstration certificate

If you need to obtain a test demonstration PKCS#12 file to use, the Albalia Interactiva CA in Spain conveniently offers such a service at this address: http://ca.albalia.com:8080/democa/start.html.

Alternatively, the openssl program has the ability to create such files from scratch as well.

4. Adding an enveloped signature to a UBL document

With the Crane component directory on the command-line search path, executing "envelopedUBL" from a command prompt will add a signature to a UBL document. This batch file will automatically invoke a verification of the signed file after the signature is added.

There are between 5 and 11 arguments on the command line, at a minimum requiring:

inputFileName  outputFileName  final/notfinal  PKCS#12KeyFileName  keyPassword

The "final/notfinal" argument is either the string "final" or "notfinal". When the string is "final" the signature being added will be invalidated if subsequently any signature is added.

The remaining 6 optional quoted arguments are positional arguments, first for the value of the optional Id= attribute on <ds:Signature>, second for the value of the optional Id= attribute on <ds:SignatureValue>, third for the optional <cbc:ID> element child of <sac:SignatureInformation>, fourth for the optional <sbc:ReferencedSignatureID> element child of <sac:SignatureInformation>, fifth for the filename of a signature object extension instance (ref: Section 7, “Injecting a XML digital signature object extension”), and sixth for a white-space separated list of target URI strings for additional <ds:Reference> elements (ref: Section 9, “Configuring referenced elements”). If you need to skip an optional positional argument, then use empty quotes "" in its place. When a non-empty string is specified for an optional argument, the corresponding element is instantiated in the signature extension during the signing process.

This batch file invokes the Crane-Enveloped.xsl stylesheet. That stylesheet takes an additional parameter digestMethod that overrides the default value of http://www.w3.org/2000/09/xmldsig#sha1. This parameter cannot be overridden in the current version of the batch file, but users can modify the batch file accordingly if desired.

5. Creating a detached signature for a UBL document

With the Crane component directory on the command-line search path, executing "detachedUBL" from a command prompt will create a digital signature for a UBL document. This batch file will automatically invoke a verification of the signature file after the signature is added.

There are between 5 and 8 arguments on the command line, at a minimum requiring:

inputFileName  outputFileName  final/notfinal  PKCS#12KeyFileName  keyPassword

The "final/notfinal" argument is either the string "final" or "notfinal". When the string is "final" the signature being created will be invalidated if subsequently any signature is added to the UBL document. If the document being signed does not already have a UBL signature extension, this argument is forced to be "final".

The remaining 4 optional arguments are positional arguments, first for the value of the optional Id= attribute on <ds:Signature>, second for the value of the optional Id= attribute on <ds:SignatureValue>, third for the filename of a signature object extension instance (ref: Section 7, “Injecting a XML digital signature object extension”), and fourth for a white-space separated list of target URI strings for additional <ds:Reference> elements (ref: Section 9, “Configuring referenced elements”).

This batch file invokes the Crane-Detached.xsl stylesheet. That stylesheet takes an additional parameter digestMethod that overrides the default value of http://www.w3.org/2000/09/xmldsig#sha1. This parameter cannot be overridden in the current version of the batch file, but users can modify the batch file accordingly if desired.

6. Verifying a signature in a UBL document

With the Crane component directory on the command-line search path, executing "verifyUBL" from a command prompt will verify a signature in or for a UBL document.

There is only one argument on the command line: the name of either the UBL document containing the enveloped signatures to be verified, or the IETF/W3C digital signature document being verified.

7. Injecting a XML digital signature object extension

The IETF/W3C XML digital signature specification http://www.w3.org/TR/xmldsig-core/ provides an extension point of its own named <ds:Object>. The European XAdES specification http://www.w3.org/TR/XAdES/ is an example of a specification whose implementation is entirely contained under the IETF/W3C signature extension point.

This Crane environment takes as an argument for signing a document the file name of an extension instance defining the extension point to be added to the signature when the document is signed. This extension instance must have <ds:Object> as its document element. The element and all its descendants (including comments and processing instructions) are copied into the signature at the extension point. Any comments and processing instructions before or after the <ds:Object> element are not copied into the signature.

In the demo/ directory the objectTest.xml file is an example of such an extension instance.

As the element and descendants are being copied, the following optional signal attributes are detected. The signal attributes trigger behaviors in the preparation of the signature. All signals are in the "http://www.CraneSoftwrights.com/ns/ublsec" namespace, and any prefix can be used. The "c:" prefix in these examples is only for documentary reasons. Regardless of the use of this namespace, neither this namespace nor any construct in this namespace will be present in the signed file. All signals are consumed and processed, with error messages triggered for inappropriate use of the namespace.

The following attributes are defined in this namespace:

  • c:sign - include this attribute's element in the signature information

    • the value of this attribute is the name of the sibling attribute with the ID-typed attribute identifying the element

    • typical uses are c:sign="xml:id" or c:sign="Id"

      • note that the current version of the xmlsec application will only recognize attributes of the names "xml:id" or "Id" as attributes of type ID for the purposes of identifiers; future versions of xmlsec may be more flexible

    • a <ds:Reference> element is included as part of the signatures signed information, using a relative URI pointer to the identifier value in the attribute named in the c:sign= attribute

  • c:digestMethod - override the default digest method in the <ds:Reference> element with the digest method in this attribute

  • c:xpath - include in the <ds:Reference> element a transformation XPath expression using this attribute's value

8. Cosigning and countersigning

Consider what happens when more than one person signs a document. To cosign a document is simply to add more than one signature, where each signature signs the document content without regard for any other signature that may or may not have existed for the document.

To countersign a document is to sign a document's signature, with or without also signing the document's content. Two ways are available to countersign a signature, based on what signature information can and cannot change for the countersigned signature. Since a signature's hash calculation excludes itself from the document, it is protected from being invalidated by changes that are added to it under its <ds:Signature> element. Such changes may include adding extension information under its <ds:Object> element. One has to decide if the countersignature is invalidated or not by the same kinds of changes.

A countersignature that is not to be invalidated by said changes need only sign the <ds:SignatureValue> element of the countersigned signature. A countersignature that is to be invalidated by any change to the countersigned signature must sign the <ds:Signature> element.

When countersigning, the target elements are included in the signature's <ds:SignedInfo> element by using additional <ds:Reference> elements, each one using a relative identifier to the identifier of a target element.

In the demo/ directory with the files created by Section 10, “Sample session”, the extSigned2.xml file is an example of a UBL document with two signatures, the second one being a countersignature of the first by having <ds:Reference URI="#addedSigVal"> point to the signature value of the first signature added.

9. Configuring referenced elements

The xmlsec utility needs to be taught which attributes of which elements in the input are of type ID in order to support pointing to those elements using URI= in <ds:Reference> elements that are generated.

This environment is already configured to declare the Id= attribute of <ds:Signature> and <ds:SignatureValue> in support of Section 8, “Cosigning and countersigning”.

If you find that xmlsec cannot locate your elements with attributes of type ID, the three files to modify are "envelopedUBL.bat", "detachedUBL.bat" and verifyUBL.bat. You will see the setting of the signIDAttrs environment variable that you augment with the name of the attribute and the namespace and name of the attribute's element.

10. Sample session

The following takes the noExtIn.xml example of a UBL invoice (with no UBL extensions embedded) and adds two signatures through two invocations of the envelopedUBL.bat file, then creates two detached signatures through two invocations of the detachedUBL.bat file:

rem Demonstration of signing and verifying UBL documents

rem Standalone validation of a document with no signatures...
call verifyUBL.bat noExtIn.xml
Preparing verification of the document...
Verifying the document...
No signatures found in input file.

rem Adding a signature to a document without any pre-existing extensions...
call envelopedUBL.bat noExtIn.xml extSigned1.xml notfinal keynr.p12 password
                      addedSig addedSigVal "" "" objectTest.xml
Adding UBL signature scaffolding at the end of the signatures...
Injecting signature information into the last scaffolding found...
Preparing verification of the document...
Verifying the document...
Checking signature 1 of 1...
OK
SignedInfo References (ok/all): 2/2
Manifests References (ok/all): 0/0
The one signature found is valid

rem Standalone validation...
call verifyUBL.bat extSigned1.xml
Preparing verification of the document...
Verifying the document...
Checking signature 1 of 1...
OK
SignedInfo References (ok/all): 2/2
Manifests References (ok/all): 0/0
The one signature found is valid

rem Adding a countersigning signature to a document that already has one...
call envelopedUBL.bat extSigned1.xml extSigned2.xml final keywr.p12 password
                      "" "" "" "" "" "#addedSigVal"
Adding UBL signature scaffolding at the end of the signatures...
Injecting signature information into the last scaffolding found...
Preparing verification of the document...
Verifying the document...
Checking signature 1 of 2...
OK
SignedInfo References (ok/all): 2/2
Manifests References (ok/all): 0/0
Checking signature 2 of 2...
OK
SignedInfo References (ok/all): 2/2
Manifests References (ok/all): 0/0
All 2 signatures valid

rem Standalone validation...
call verifyUBL.bat extSigned2.xml
Preparing verification of the document...
Verifying the document...
Checking signature 1 of 2...
OK
SignedInfo References (ok/all): 2/2
Manifests References (ok/all): 0/0
Checking signature 2 of 2...
OK
SignedInfo References (ok/all): 2/2
Manifests References (ok/all): 0/0
All 2 signatures valid

rem Creating a detached signature of the document without signatures...
call detachedUBL.bat noExtIn.xml detUnsigned.xml notfinal keynr.p12 password
                     addedSig addedSigVal objectTest.xml
Creating digital signature scaffolding for the XML document...
WARNING: the "final" argument is assumed to be "final" (the original value
 of "notfinal" is ignored) because there are no pre-existing UBL signatures
 to protect in the document at "noExtIn.xml".

Injecting signature information into the scaffold...
Preparing verification of the document...
Verifying the document...
Checking signature 1 of 1...
OK
SignedInfo References (ok/all): 2/2
Manifests References (ok/all): 0/0
The one signature found is valid

rem Standalone validation...
call verifyUBL.bat detUnsigned.xml
Preparing verification of the document...
Verifying the document...
Checking signature 1 of 1...
OK
SignedInfo References (ok/all): 2/2
Manifests References (ok/all): 0/0
The one signature found is valid

rem Creating a detached signature of the document with signatures...
call detachedUBL.bat extSigned2.xml detSigned.xml final keynr.p12 password
Creating digital signature scaffolding for the XML document...
Injecting signature information into the scaffold...
Preparing verification of the document...
Verifying the document...
Checking signature 1 of 1...
OK
SignedInfo References (ok/all): 1/1
Manifests References (ok/all): 0/0
The one signature found is valid

rem Standalone validation...
call verifyUBL.bat detSigned.xml
Preparing verification of the document...
Verifying the document...
Checking signature 1 of 1...
OK
SignedInfo References (ok/all): 1/1
Manifests References (ok/all): 0/0
The one signature found is valid

The demo/ directory of this package's ZIP file contains the input and output UBL documents from this example.

11. Future work and feedback

When creating or verifying a "not final" detached digital signature, the Windows version of the xmlsec program crashes with a fatal error after the program successfully creates or verifies the signature. The end results appear to be perfectly fine, as the fatal error seems related solely to the program operation after the results are created. This is being reported to the xmlsec team. A future release of this package will remove this documentation when a problem-free xmlsec is available.

I'm looking into how to access an installed certificate/key in the built-in Windows key management system. This is low priority. Please let us know if this is high priority for you.

Please send any comments, suggestions or critical feedback to mailto:info@CraneSoftwrights.com. Thank you!