This document is work in progress, please mail your comments to firstname.lastname@example.org.
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.
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.
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.SigLabel label1 = SigLabel.newSigLabel(new FileInputStream(filename));
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.
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:Trivalue result = label1.verify(); System.out.println("The 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.ResInfoExtension resinfo = label1.getResInfo(); Trivalue result = resinfo.verify(); System.out.println("The resinfo verification result is: " + result.toString());
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.
SigBlockExtension sigblock = label1.getSigBlock(); Trivalue result = sigblock.verify(); System.out.println("The sigblock verification result is: " + result.toString());
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:SigLabel label1 = SigLabel.newSigLabel(new FileInputStream(filename));
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.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());
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.
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).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: You now have a signed SigLabel. Call label1.toString() for its canonical string representation or label1.prettyPrint() for a more readable representation.AttribInfo attribinfo = sigblock.getAttribInfo(); attribinfo.addCert(myCert); attribinfo.addCert(CaCert);
System.out.println("The signed label is:\n" + label1.prettyPrint());
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.