# Using W3C's DSig 1.0 Reference Implementation

> This document is work in progress, please mail your comments to w3c-dsig-ask@w3.org.

## Contents

This note describes how an application programmer can use the DSig reference implementation to create and verify DSig 1.0 digital signatures on PICS labels. This document adds to the JavaDoc source code documentation and other available documentation and is supposed to give short and concise description of the basic API functionality.

This text does not cover the non DSig specific handling of PICS labels, please refer to the appropriate PICS implementation documentation for that. It also does not describe how to extend the capabilities of the reference implementation by adding additional signature suites or certificate types to it, which is described in the source code documentation of the classes in `w3c.www.dsig`.

NOTE: please read the "README" file on to setup and run the DSig demo. Also visit W3C DSig implementation website at http://www.w3.org/PICS/refcode/DSig for the latest update.

## General Information

The W3C DSig Reference Implementation is written in Java 1.1. The core DSig code is part of W3C's Java library and contained in the `w3c.www.dsig` package. It depends on a number of other W3C classes, like utility classes in `w3c.tools.codec`, `w3c.tools.sexpr`, and `w3c.tools.sorter` packages. The core DSig implementation `w3c.www.dsig` can be invoked by two separate PICS parsers, namely `w3c.www.pics` and `w3c.pics.parser` with a common interface `w3c.www.dsig.DSigLabelInterface`. Hence any PICS parser implementing the interface is able to use the DSig core package directly. Note that `w3c.pics.label` PICS parser package is better documented and well debugged, so we encourage you to use this version of PICS parser.

### Verifying a DSig Digital Signature

This is a step-by-step explanation of how to verify a PICS label using the W3C DSig implementation.

NOTE: `w3c.www.pics.SigLabel` class and `w3c.pics.parser.Label` class can be used interchangably, depending on which PICS parser library you use. The document below uses `w3c.www.pics.SigLabel`.

NOTE: All verification methods use tri valued logic to report the verification result. You might want to read about tri valued logic in the appendix before you proceed.

Step 1: Preparation step. Create an object of the `w3c.www.pics.SigLabel`, which is the main DSig class and a subclass of `w3c.www.pics.PICSLabel`. The resulting object will be called `label1` throughout the rest of this section. Use the constructor `SigLabel(PICSLabel)`, or the static methods `SigLabel.newSigLabel(InputStream)` or `SigLabel.newSigLabel(String)` depending on your input data.

Example:

>     SigLabel label1 = SigLabel.newSigLabel(new FileInputStream(filename));

Step 2: Quick verification of the label. If you are interested in a simple and easy way to verify the label you can use the methods `verify()` and `verifyAll()` of the SigLabel class. These methods are provided as a way to make signature verification as simple as possible. If you prefer a more flexible and possibly more efficient verification skip this step and continue with 3 and 4.

The `verifyAll()` method computes the verification result as an logical AND of all signature and hash verification results in tri valued logic, i.e. it will only return `TRUE` if all tests succeed. The `verify()` method performs signature and message digest verification according to the user's default policy. Currently this is defined to be the same as `verifyAll()` but it is anticipated that in the future this function will truely execute the user configured verification policy.

Example:

>     Trivalue result = label1.verify();
>     System.out.println("The verification result is: " + result.toString());

Step 3: Verify the ResInfo extension. The ResInfo contains one or more cryptographic hashes which are used to establish the cryptographic link between the SigLabel and the document it signs. Use `label1.getResInfo()` to obtain the label's ResInfo object. The `ResInfoExtension` class defines a number of methods to verify the hashes:

1. `verifyAll(SigLabel)` and `verifyAll(InputStream)`. These methods will verify all message digests contained in this ResInfo and return the trivalued AND of the individual results. The data to be hashed will either be read from the given input stream or from the URL specified in the 'for' option of the given label.
2. `verify(SigLabel)` and `verify(InputStream)`. Verify according to the user's default policy, currently hardcoded to be verifyAll().
3. `verify(String, SigLabel)` and `verify(String, InputStream)`. Verify just the hash with the given algorithm name. Returns unknown if a hash for that algorithm is not present.

Example:

>     ResInfoExtension resinfo = label1.getResInfo();
>     Trivalue result = resinfo.verify();
>     System.out.println("The resinfo verification result is: " + result.toString());

Step 4: Verify the SigBlock extension. The SigBlock contains the AttribInfo with zero or more certificates and the Signatures section with one or more digital signatures, possibly from multiple signers and/ or using multiple signature algorithms. Use `label1.getSigBlock()` to obtain the label's SigBlock object.

Again, there are methods `verifyAll(SigLabel)` to verify all signatures in this signature block, and `verify(SigLabel)` to perform verification as specified by the user's default policy. Additionally, there is a method `verify(SigLabel, String)` to verify only all signatures created using the given signature algorithm. If more flexibility is desired, the application can fetch a particular signature object using `getSigSuites(String)` or `sigSuites()` and then operate freely on this object. For more information, read the source code documentation.

Example:

>     SigBlockExtension sigblock = label1.getSigBlock();
>     Trivalue result = sigblock.verify();
>     System.out.println("The sigblock verification result is: " + result.toString());

### Creating a DSig Digital Signature

Step 1: Preparation step. Create an instance of the class `w3c.www.pics.SigLabel`. Use the constructor `SigLabel(PICSLabel)`, or the static methods `SigLabel.newSigLabel(InputStream)` or `SigLabel.newSigLabel(String)` depending on your input data.

Example:

>     SigLabel label1 = SigLabel.newSigLabel(new FileInputStream(filename));

Step 2: Build the ResInfo. Add one or more hashes of the labeled document to the ResInfo of the label. To do this first obtain (initially empty) `ResInfoExtension` object of your label by calling `getResInfo` Then add a digest using one of the `addDigest` methods:

1. `addDigest(String alg, SigLabel label, ISODate date)` will add a digest calculated from the URL specified in the 'for' option of the label. using the algorithm `alg` and add it to this ResInfo with `date` as its date. If `date` is `null`, no date will be added.
2. `addDigest(String alg, InputStream ins, ISODate date)` will add a digest calculated from the data in the InputStream `ins` using the algorithm `alg` and add it to this ResInfo with `date` as its date. If `date` is `null`, no date will be added.
3. `addDigest(String alg, String val, ISODate date)` will add a the pre-calculated digest `val` of the algorithm `alg` and add it to this ResInfo with `date` as its date. If `date` is `null`, no date will be added.

Example:

>     ResInfoExtension resinfo = label1.getResInfo();
>     resinfo.addDigest("http://www.w3.org/TR/1998/REC-DSig-label/MD5-1_0", label1, null);
>     resinfo.addDigest("http://www.w3.org/TR/1998/REC-DSig-label/SHA1-1_0", label1, new ISODate());

Step 3: Add signatures to your sigblock. First choose the signature suite you want to use for signing. The class `w3c.www.dsig.SigSuiteRegistry` can queried for the installed signature suites and to obtain an instance of this class (for more information please refer to the JavaDoc generated API documentation). To obtain an instance of a particular signature suite for signing call `SigSuiteRegistry.getInstance(String)` where the string argument is the URL identifying the algorithm.

To compute the signature just call `SigLabel_object.sign(SigSuite_object, PrivateKey)` with your private key for this algorithm. Then you should add information about yourself (the signer) to the Signature Suite. In DSig, the signer can either be identified via his name, his public key, or the hash of his public key. Use `setBy("ByName",String)`, `setBy("ByKey",PublicKey)`, or `setBy("ByHash",PublicKey)`. Note that individual signature suites need not support all three types and can also support additional forms of By*. However, usually at least these three will be supported.

Example:

>     SigBlockExtension sigblock = label1.getSigBlock();
>     sigdss = SigSuiteRegistry.getInstance("http://www.w3.org/TR/1998/REC-DSig-label/DSS-1_0");
>     label1.sign(sigdss, myDsaPrivateKey);
>     sigdss.setBy("ByName", "My name");

Step 4: Add certificates to the AttribInfo of your SigBlock. First obtain the SigBlock's current AttribInfo using `sigblock.getAttribInfo()`, then add all desired certificates to it by repeatedly calling `addCert(SigCert)`.

Example:

>     AttribInfo attribinfo = sigblock.getAttribInfo();
>     attribinfo.addCert(myCert);
>     attribinfo.addCert(CaCert);

Step 4: You now have a signed SigLabel. Call `label1.toString()` for its canonical string representation or `label1.prettyPrint()` for a more readable representation.

Example:

>     System.out.println("The signed label is:\n" + label1.prettyPrint());

## Appendix

### Tri-valued Logic

The W3C DSig implementation employs tri-valued logic to indicate the result of operations. Tri-valued logic is boolean (true/ false) logic extended by a third value called "unknown."

The handling of tri-valued logic is implemented via the class `w3c.www.dsig.Trivalue`.

A value of `TRI_TRUE` denotes that the verification was successful, the value `TRI_FALSE` signifies that the verification result was negative, and a value of `TRI_UNKNOWN` means that the verification could not be completed successfully because of missing or currently unavailable information. In case the verification function has to conduct several tests, the resulting value obeys to the AND function for three-valued logic. That is, it returns only `TRI_TRUE` if all tests gave the result `TRI_TRUE`, `TRI_FALSE` if at least one result was `TRI_FALSE`, and `TRI_UNKNOWN` otherwise (i.e. at least one result was `TRI_UNKNOWN`, possible some `TRI_TRUE` but none `TRI_FALSE`). An application is free to decide how to handle `TRI_UNKNOWN` results, it is recommended to treat them as `TRI_FALSE` if no special handling is possible or desired.