badpenguin.dkim
Class DkimSignature

java.lang.Object
  extended by badpenguin.dkim.DkimSignature
All Implemented Interfaces:
java.lang.Cloneable

public class DkimSignature
extends java.lang.Object
implements java.lang.Cloneable

This class represents a DKIM or DomainKey signature. It has methods to manipulate all of the Tags associated with signature and generate the signature string from the tag settings.

Author:
Mark Boddington <dk_NO_im@_SP_bad_AM_penguin.co.uk>
http://www.badpenguin.co.uk

Constructor Summary
DkimSignature(java.lang.String sig, boolean leniency)
          Create a DkimSignature object from an existing Dkim-Signature.
DkimSignature(java.lang.String selector, java.lang.String domain)
          Construct a DkimSignature with the provided selector and domain tags.
DkimSignature(java.lang.String selector, java.lang.String domain, java.lang.String headers)
          Construct a DkimSignature with the provided selector, domain and header tags.
 
Method Summary
 void addHeader(java.lang.String header)
          Add the specified header to the H tag.
You should specify just the header name without the colon separator.
 void checkValidity()
           
 DkimSignature clone()
          Allow this DkimSignature object to be cloned
 java.lang.String genDkimSig()
          Generate the signature from the current tags and return the DKIM signature string.
 java.lang.String getAlgorithm()
          Get the (A)lgorithm tag.
 java.lang.String getAtag()
          Get the current value of the (A)lgorithm tag
 java.lang.String getBHtag()
          Get the current value of the (B)ody (H)ash tag
 java.lang.String getBodyHash()
          Get the body hash data.
 CanonicalMethod getBodyMethod()
          Get the canonicalisation that should be used for processing the body.
 java.lang.String getBtag()
          Get the current value of the (B)ase64 Signature Data
 java.lang.String getCtag()
          Get the current value of the (C)anonicalisation tag
 java.lang.String getDkimSig()
          Get the currently stored signature string.
 java.lang.String getDnsRecord()
          Get the DNS record.
 java.lang.String getDtag()
          Get the current value of the (D)omain tag.
 CanonicalMethod getHeaderMethod()
          Get the canonicalisation that should be used for processing the headers.
 java.lang.String getHtag()
          Get the current value of the (H)eaders tag.
 java.lang.String getItag()
          Get the current value of the (I)dentity tag
 java.lang.String getJavaAlg()
          Get the JAVA version of the (A)lgorithm tag (eg rsa-sha1 == SHA1withRSA)
 long getLtag()
          Get the current value of the (L)ength tag
 java.lang.String getMessageSignature()
          Get the message signature data.
 java.lang.String getStag()
          Get the current value of the (S)elector tag.
 java.lang.String getTtag()
          Get the current value of the (T)imestamp tag.
 java.lang.String getVtag()
          Get the current value of the (V)ersion tag
 java.lang.String getXtag()
          Get the current value of the e(X)pires tag.
 boolean isDKIM()
          Return true if this signature is DKIM, false if it is DomainKey
 void resetDefaultTags()
          Reset the DKIM signature tags to their defaults (include mandatory tags where recommendations/defaults are made in the RFC).
 void resetTags()
          Reset the DKIM Signature tags to their defaults.
 void setAtag(java.lang.String arg)
          Set the (A)lgorithm tag to the specified value (must be either "rsa-sha1" or "rsa-sha256")
 void setBHtag(byte[] data)
          Encode and set the (B)ody (H)ash tag to the specified byte[] value
 void setBHtag(java.lang.String base64)
          Set the (B)ody (H)ash tag to the specified base64 value
 void setBodyMethod(CanonicalMethod method)
          Set the canonicalisation method which should be used for processing the body.
Throw a DkimError if we are a DomainKey signature, because you can't specify defferent encodings for header and body when using DomainKey
 void setBtag(byte[] data)
          Encode and set the signature data to the specified byte[] value.
 void setBtag(java.lang.String base64)
          Set the (B)ase64 encoded signature data to the specified value.
 void setDtag(java.lang.String domain)
          Set the (D)omain tag to the specified value.
The domain specifes here should have a subdomain of _domainkey, which holds the selectors in use.
 void setHeaderMethod(CanonicalMethod method)
          Set the canonicalisation method which should be used for processing the headers.
Throw a DkimError if we are a DomainKey signature, because you can't specify defferent encodings for header and body when using DomainKey
 void setHtag(java.lang.String headers)
          Set the (H)eaders tag to the specified value.
The headers, should be lowercase, and they should be colon separated.
 void setItag(java.lang.String arg0)
          Set the (I)dentity tag to the specified value.
 void setLtag(long length)
          Set the body (L)ength Tag.
 void setMethod(CanonicalMethod method)
          Set both the body and header canonicalisation method to the specified value
 void setStag(java.lang.String selector)
          Set the (S)elector tag to the specified value.
 void setTtag(java.lang.String sigTtag)
          Set the (T)imestamp tag to the specified value.
 void setVtag(java.lang.String version)
          Set the (V)ersion tag to the specified version.
WARNING: Currently this can only be "1", you don't need to use this (yet)!
 void setXtag(java.lang.String sigXtag)
          Set the e(X)pires tag to the specified value.
 void updateSigfromTags()
          Update the internal DKIM-Signature string to match the values currently set in the Tags.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

DkimSignature

public DkimSignature(java.lang.String sig,
                     boolean leniency)
              throws DkimException
Create a DkimSignature object from an existing Dkim-Signature. This is the recommended way to instantiate a DkimSignature object for verification.

You SHOULD be strict when verifying signatures, but if you would like us to assume defaults for mandatory parameters which may be missing, then set leniency to true.

If you are intending to sign an object then you should use one of the other constructors as they sets mandatory flags to sensible values.

Parameters:
sig - - The DKIM-Signature
leniency - - Use defaults for missing mandatory tags?
Throws:
DkimException

DkimSignature

public DkimSignature(java.lang.String selector,
                     java.lang.String domain,
                     java.lang.String headers)
              throws DkimException
Construct a DkimSignature with the provided selector, domain and header tags.
This Signature object will be created for DKIM, and will set all optional flags which have defaults to their defaults. The mandatory flags with no defaults will be set to the values you specify.

Throws:
DkimException

DkimSignature

public DkimSignature(java.lang.String selector,
                     java.lang.String domain)
              throws DkimException
Construct a DkimSignature with the provided selector and domain tags. The header tag will be set to "from:to:subject:message-id".
This Signature object will be created for DKIM, and will set all optional flags which have defaults to their defaults. The mandatory flags with no defaults will be set to the values you specify.

Parameters:
selector -
domain -
Throws:
DkimException
Method Detail

clone

public DkimSignature clone()
                    throws java.lang.CloneNotSupportedException
Allow this DkimSignature object to be cloned

Overrides:
clone in class java.lang.Object
Throws:
java.lang.CloneNotSupportedException

updateSigfromTags

public void updateSigfromTags()
Update the internal DKIM-Signature string to match the values currently set in the Tags.


checkValidity

public void checkValidity()
                   throws DkimException
Throws:
DkimException

getAtag

public java.lang.String getAtag()
Get the current value of the (A)lgorithm tag

Returns:
The A tag

setAtag

public void setAtag(java.lang.String arg)
             throws DkimException
Set the (A)lgorithm tag to the specified value (must be either "rsa-sha1" or "rsa-sha256")

Parameters:
arg - - The Algorithm to use
Throws:
DkimException - - If an invalid algorithm is specified.

getBtag

public java.lang.String getBtag()
Get the current value of the (B)ase64 Signature Data

Returns:
The Base64 encoded signature data.

setBtag

public void setBtag(java.lang.String base64)
Set the (B)ase64 encoded signature data to the specified value.

Parameters:
base64 - - Base64 encoded signature data.

setBtag

public void setBtag(byte[] data)
Encode and set the signature data to the specified byte[] value.

Parameters:
data - - byte array to be encoded to Base64.

getBHtag

public java.lang.String getBHtag()
Get the current value of the (B)ody (H)ash tag

Returns:
The Base64 encoded BH tag

setBHtag

public void setBHtag(java.lang.String base64)
Set the (B)ody (H)ash tag to the specified base64 value

Parameters:
base64 - - base64 encoded Body Hash

setBHtag

public void setBHtag(byte[] data)
Encode and set the (B)ody (H)ash tag to the specified byte[] value

Parameters:
data - - byte array to be encoded to Base64.

getVtag

public java.lang.String getVtag()
Get the current value of the (V)ersion tag

Returns:
The V tag

setVtag

public void setVtag(java.lang.String version)
Set the (V)ersion tag to the specified version.
WARNING: Currently this can only be "1", you don't need to use this (yet)!

Parameters:
version -

getCtag

public java.lang.String getCtag()
Get the current value of the (C)anonicalisation tag

Returns:
The C Tag

getLtag

public long getLtag()
Get the current value of the (L)ength tag

Returns:
The L Tag

setLtag

public void setLtag(long length)
Set the body (L)ength Tag. The body data will be truncated at the length specified for signing/verifying.
Setting this value to -1 will sign the entire body (the default). A setting of 0 will sign "CRLF".

Parameters:
length - - The bytes of body data to sign.

getHtag

public java.lang.String getHtag()
Get the current value of the (H)eaders tag.

Returns:
The H tag - A colon separated list of headers

setHtag

public void setHtag(java.lang.String headers)
             throws DkimException
Set the (H)eaders tag to the specified value.
The headers, should be lowercase, and they should be colon separated.

Parameters:
headers - - The colon separate list of headers to set.
Throws:
DkimException

getItag

public java.lang.String getItag()
Get the current value of the (I)dentity tag

Returns:
The I tag

setItag

public void setItag(java.lang.String arg0)
Set the (I)dentity tag to the specified value.

Parameters:
arg0 - - The I tag

getDtag

public java.lang.String getDtag()
Get the current value of the (D)omain tag.

Returns:
The D tag

setDtag

public void setDtag(java.lang.String domain)
Set the (D)omain tag to the specified value.
The domain specifes here should have a subdomain of _domainkey, which holds the selectors in use.

Parameters:
domain - - The domain for this message

getStag

public java.lang.String getStag()
Get the current value of the (S)elector tag.

Returns:
The S tag

setStag

public void setStag(java.lang.String selector)
Set the (S)elector tag to the specified value.

Parameters:
selector - - The Selector

getTtag

public java.lang.String getTtag()
Get the current value of the (T)imestamp tag.

Returns:
The timestamp tag

setTtag

public void setTtag(java.lang.String sigTtag)
Set the (T)imestamp tag to the specified value.

Parameters:
sigTtag - - The timestamp tag

getXtag

public java.lang.String getXtag()
Get the current value of the e(X)pires tag.

Returns:
The X tag

setXtag

public void setXtag(java.lang.String sigXtag)
Set the e(X)pires tag to the specified value.

Parameters:
sigXtag - - The eXpires Tag

addHeader

public void addHeader(java.lang.String header)
Add the specified header to the H tag.
You should specify just the header name without the colon separator. Although this method will remove any colons and attempt to format the header correctly.

Parameters:
header - - The header to add.

getDnsRecord

public java.lang.String getDnsRecord()
                              throws DkimException
Get the DNS record. The S tag (dot) _domainkey (dot) D tag.

Returns:
the DNS record to lookup
Throws:
DkimException
If
- the Q tag doesn't specify DNS.
DkimException

getJavaAlg

public java.lang.String getJavaAlg()
Get the JAVA version of the (A)lgorithm tag (eg rsa-sha1 == SHA1withRSA)

Returns:
The Java Algorithm name

getAlgorithm

public java.lang.String getAlgorithm()
Get the (A)lgorithm tag. This is the same as getAtag().

Returns:
The A tag

getBodyHash

public java.lang.String getBodyHash()
Get the body hash data. This is the same as getBHtag().

Returns:
The BH tag (Base64 encoded body hash).

getMessageSignature

public java.lang.String getMessageSignature()
Get the message signature data. This is the same as getBtag()

Returns:
- The B tag (Base64 encoded signature)

isDKIM

public boolean isDKIM()
Return true if this signature is DKIM, false if it is DomainKey

Returns:
is DKIM?

getHeaderMethod

public CanonicalMethod getHeaderMethod()
Get the canonicalisation that should be used for processing the headers.

Returns:
- simple, relaxed, or nofws

getBodyMethod

public CanonicalMethod getBodyMethod()
Get the canonicalisation that should be used for processing the body.

Returns:
- simple, relaxed, or nofws

setHeaderMethod

public void setHeaderMethod(CanonicalMethod method)
                     throws DkimException
Set the canonicalisation method which should be used for processing the headers.
Throw a DkimError if we are a DomainKey signature, because you can't specify defferent encodings for header and body when using DomainKey

Parameters:
method - - The Canonicalisation method
Throws:
DkimException

setBodyMethod

public void setBodyMethod(CanonicalMethod method)
                   throws DkimException
Set the canonicalisation method which should be used for processing the body.
Throw a DkimError if we are a DomainKey signature, because you can't specify defferent encodings for header and body when using DomainKey

Parameters:
method - - The Canonicalisation method
Throws:
DkimException

setMethod

public void setMethod(CanonicalMethod method)
               throws DkimException
Set both the body and header canonicalisation method to the specified value

Parameters:
method - (simple|nofws|relaxed)
Throws:
DkimException

genDkimSig

public java.lang.String genDkimSig()
Generate the signature from the current tags and return the DKIM signature string. This function is intended to be used during Signing, for Verification, getDkimSig() is more appropriate.

Returns:
DKIM-Signature.

getDkimSig

public java.lang.String getDkimSig()
Get the currently stored signature string. This is safer than genDkimSig() for verification purposes. Particularly if Leniency is enabled, as we may set tags, that the signer did not.

Returns:
DKIM-Signature.

resetTags

public void resetTags()
Reset the DKIM Signature tags to their defaults. Warning, this will also set mandatory tags to the null string. If you create an instance of this class and want to verify a signature is valid, then resetting the tags will detect if the signature is missing mandatory flags and breaking the RFC. If you wish to create a new message and/or be lenient on malformed tags (ie assume default values when mandatory flags are missing), then use the resetDefaultTags() method instead.


resetDefaultTags

public void resetDefaultTags()
Reset the DKIM signature tags to their defaults (include mandatory tags where recommendations/defaults are made in the RFC). This is a little more lenient on bad signatures, but is mostly intended to be used when creating a signature rather than verifying one.



© Copyright 2009 Mark Boddington (www.badpenguin.co.uk)