FileDocCategorySizeDatePackage
SignedObject.javaAPI DocExample8578Mon Sep 22 13:30:32 BST 1997None

SignedObject

public class SignedObject extends Object implements Serializable
A SignedObject is exactly that--an object that bears a digital signature. Subclass this class to add a digital signature to any class you want. Note, however, that the signature is computed using serialization, so only the serializable, non-transient fields of a subclass are included in the signature computation.

Fields Summary
protected String
signername
protected String
algorithm
private byte[]
signature
private transient boolean
signing
Constructors Summary
Methods Summary
public voidremoveSignature()
When the contents of the object change, the signature becomes invalid. When this happens, the signature should be erased, because validation is guaranteed to fail.

 
    signature = null; signername = null; algorithm = null; 
  
public synchronized voidsign(java.lang.String signername, java.lang.String algorithm)
This method computes a digital signature for the current state of the object, excluding the signature-related state of this class. That is, the signature is based only on the state of the subclasses. The arguments specify who is signing the object, and what digital signature algorithm to use. Note that no other threads should be modifying the object while this computation is being performed. If a subclass will be used in a multi-threaded environment, this means that methods of the subclass that modify its state should be synchronized like this one is.

 // A flag used below.

                                                                                                     
         
          
           
  
    // Save the arguments for use by verify()
    this.signername = signername;
    this.algorithm = algorithm;

    // Get a Signature object to compute the signature with
    Signature s = Signature.getInstance(algorithm);

    // Get a Signer object representing the signer
    Signer signer = 
      (Signer)IdentityScope.getSystemScope().getIdentity(signername);

    // Initialize the Signature object using the PrivateKey of the Signer
    s.initSign(signer.getPrivateKey());

    // Create an ObjectOutputStream that writes its output to a 
    // ByteArrayStream.  This is how we capture the state of the object
    // so that it can be signed.
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(bout);

    // Now serialize the object, capturing its state.  We have to set a flag
    // before we do this, so that the signer name, algorithm, and signature
    // itself are not included in this serialized state.  See writeObject()
    // below to see how this works.
    signing = true;
    out.writeObject(this);
    signing = false;

    // Now tell the Signature object about the bytes of serialized state
    // that were stored by the ByteArrayOutputStream
    s.update(bout.toByteArray());

    // And finally, compute the signature
    this.signature = s.sign();
  
public synchronized voidsign(java.lang.String signername)
A simpler version of sign(), that defaults to using the DSA algorithm

    sign(signername, "DSA");
  
public synchronized booleanverify()
This method verifies the signature of any SignedObject subclass. It works much like the sign() method, and is also synchronized.

    // Make sure the object is actually signed.
    if (signature == null) 
      throw new SignatureException("Object is not signed");

    // Get the signature, signer and public key, and initialize, like above,
    // except that this time use a PublicKey instead of a PrivateKey
    Signature s = Signature.getInstance(algorithm);
    Identity signer = 
      (Identity)IdentityScope.getSystemScope().getIdentity(signername);
    s.initVerify(signer.getPublicKey());

    // Create streams and capture the current state of the object 
    // (excluding the signature bytes themselves) in a byte array
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(bout);
    signing = true;
    out.writeObject(this);
    signing = false;

    // Pass state of the object to the Signature, and verify the stored
    // signature bytes against that state.  Return the result of verification.
    s.update(bout.toByteArray());
    return s.verify(this.signature);
  
private voidwriteObject(java.io.ObjectOutputStream out)
This method is invoked to allow custom serialization. We only write out our signature-related state when we are not computing or verifying a signature. When we are computing or verifying, only our subclass state gets written out. If we don't do this, verification will fail because the signature[] array will obviously be different on verification than it is when the signature is generated.

    if (!signing) out.defaultWriteObject();