diff options
Diffstat (limited to 'prov/src/main/java/org/spongycastle/jcajce/spec/SkeinParameterSpec.java')
-rw-r--r-- | prov/src/main/java/org/spongycastle/jcajce/spec/SkeinParameterSpec.java | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/prov/src/main/java/org/spongycastle/jcajce/spec/SkeinParameterSpec.java b/prov/src/main/java/org/spongycastle/jcajce/spec/SkeinParameterSpec.java new file mode 100644 index 00000000..e92fde23 --- /dev/null +++ b/prov/src/main/java/org/spongycastle/jcajce/spec/SkeinParameterSpec.java @@ -0,0 +1,319 @@ +package org.spongycastle.jcajce.spec; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.security.spec.AlgorithmParameterSpec; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; + +import org.spongycastle.util.Arrays; +import org.spongycastle.util.Integers; + +/** + * Parameters for the Skein hash function - a series of byte[] strings identified by integer tags. + * <p/> + * Parameterised Skein can be used for: + * <ul> + * <li>MAC generation, by providing a {@link org.spongycastle.jcajce.spec.SkeinParameterSpec.Builder#setKey(byte[]) key}.</li> + * <li>Randomised hashing, by providing a {@link org.spongycastle.jcajce.spec.SkeinParameterSpec.Builder#setNonce(byte[]) nonce}.</li> + * <li>A hash function for digital signatures, associating a + * {@link org.spongycastle.jcajce.spec.SkeinParameterSpec.Builder#setPublicKey(byte[]) public key} with the message digest.</li> + * <li>A key derivation function, by providing a + * {@link org.spongycastle.jcajce.spec.SkeinParameterSpec.Builder#setKeyIdentifier(byte[]) key identifier}.</li> + * <li>Personalised hashing, by providing a + * {@link org.spongycastle.jcajce.spec.SkeinParameterSpec.Builder#setPersonalisation(java.util.Date, String, String) recommended format} or + * {@link org.spongycastle.jcajce.spec.SkeinParameterSpec.Builder#setPersonalisation(byte[]) arbitrary} personalisation string.</li> + * </ul> + * + * @see org.spongycastle.crypto.digests.SkeinEngine + * @see org.spongycastle.crypto.digests.SkeinDigest + * @see org.spongycastle.crypto.macs.SkeinMac + */ +public class SkeinParameterSpec + implements AlgorithmParameterSpec +{ + /** + * The parameter type for a secret key, supporting MAC or KDF functions: {@value + * #PARAM_TYPE_KEY}. + */ + public static final int PARAM_TYPE_KEY = 0; + + /** + * The parameter type for the Skein configuration block: {@value #PARAM_TYPE_CONFIG}. + */ + public static final int PARAM_TYPE_CONFIG = 4; + + /** + * The parameter type for a personalisation string: {@value #PARAM_TYPE_PERSONALISATION}. + */ + public static final int PARAM_TYPE_PERSONALISATION = 8; + + /** + * The parameter type for a public key: {@value #PARAM_TYPE_PUBLIC_KEY}. + */ + public static final int PARAM_TYPE_PUBLIC_KEY = 12; + + /** + * The parameter type for a key identifier string: {@value #PARAM_TYPE_KEY_IDENTIFIER}. + */ + public static final int PARAM_TYPE_KEY_IDENTIFIER = 16; + + /** + * The parameter type for a nonce: {@value #PARAM_TYPE_NONCE}. + */ + public static final int PARAM_TYPE_NONCE = 20; + + /** + * The parameter type for the message: {@value #PARAM_TYPE_MESSAGE}. + */ + public static final int PARAM_TYPE_MESSAGE = 48; + + /** + * The parameter type for the output transformation: {@value #PARAM_TYPE_OUTPUT}. + */ + public static final int PARAM_TYPE_OUTPUT = 63; + + private Map parameters; + + public SkeinParameterSpec() + { + this(new HashMap()); + } + + private SkeinParameterSpec(Map parameters) + { + this.parameters = Collections.unmodifiableMap(parameters); + } + + /** + * Obtains a map of type (Integer) to value (byte[]) for the parameters tracked in this object. + */ + public Map getParameters() + { + return parameters; + } + + /** + * Obtains the value of the {@link #PARAM_TYPE_KEY key parameter}, or <code>null</code> if not + * set. + */ + public byte[] getKey() + { + return Arrays.clone((byte[])parameters.get(Integers.valueOf(PARAM_TYPE_KEY))); + } + + /** + * Obtains the value of the {@link #PARAM_TYPE_PERSONALISATION personalisation parameter}, or + * <code>null</code> if not set. + */ + public byte[] getPersonalisation() + { + return Arrays.clone((byte[])parameters.get(Integers.valueOf(PARAM_TYPE_PERSONALISATION))); + } + + /** + * Obtains the value of the {@link #PARAM_TYPE_PUBLIC_KEY public key parameter}, or + * <code>null</code> if not set. + */ + public byte[] getPublicKey() + { + return Arrays.clone((byte[])parameters.get(Integers.valueOf(PARAM_TYPE_PUBLIC_KEY))); + } + + /** + * Obtains the value of the {@link #PARAM_TYPE_KEY_IDENTIFIER key identifier parameter}, or + * <code>null</code> if not set. + */ + public byte[] getKeyIdentifier() + { + return Arrays.clone((byte[])parameters.get(Integers.valueOf(PARAM_TYPE_KEY_IDENTIFIER))); + } + + /** + * Obtains the value of the {@link #PARAM_TYPE_NONCE nonce parameter}, or <code>null</code> if + * not set. + */ + public byte[] getNonce() + { + return Arrays.clone((byte[])parameters.get(Integers.valueOf(PARAM_TYPE_NONCE))); + } + + /** + * A builder for {@link org.spongycastle.jcajce.spec.SkeinParameterSpec}. + */ + public static class Builder + { + private Map parameters = new HashMap(); + + public Builder() + { + } + + public Builder(SkeinParameterSpec params) + { + Iterator keys = params.parameters.keySet().iterator(); + while (keys.hasNext()) + { + Integer key = (Integer)keys.next(); + parameters.put(key, params.parameters.get(key)); + } + } + + /** + * Sets a parameters to apply to the Skein hash function.<br> + * Parameter types must be in the range 0,5..62, and cannot use the value {@value + * org.spongycastle.jcajce.spec.SkeinParameterSpec#PARAM_TYPE_MESSAGE} (reserved for message body). + * <p/> + * Parameters with type < {@value org.spongycastle.jcajce.spec.SkeinParameterSpec#PARAM_TYPE_MESSAGE} are processed before + * the message content, parameters with type > {@value org.spongycastle.jcajce.spec.SkeinParameterSpec#PARAM_TYPE_MESSAGE} + * are processed after the message and prior to output. + * + * @param type the type of the parameter, in the range 5..62. + * @param value the byte sequence of the parameter. + * @return + */ + public Builder set(int type, byte[] value) + { + if (value == null) + { + throw new IllegalArgumentException("Parameter value must not be null."); + } + if ((type != PARAM_TYPE_KEY) + && (type <= PARAM_TYPE_CONFIG || type >= PARAM_TYPE_OUTPUT || type == PARAM_TYPE_MESSAGE)) + { + throw new IllegalArgumentException("Parameter types must be in the range 0,5..47,49..62."); + } + if (type == PARAM_TYPE_CONFIG) + { + throw new IllegalArgumentException("Parameter type " + PARAM_TYPE_CONFIG + + " is reserved for internal use."); + } + this.parameters.put(Integers.valueOf(type), value); + return this; + } + + /** + * Sets the {@link org.spongycastle.jcajce.spec.SkeinParameterSpec#PARAM_TYPE_KEY} parameter. + */ + public Builder setKey(byte[] key) + { + return set(PARAM_TYPE_KEY, key); + } + + /** + * Sets the {@link org.spongycastle.jcajce.spec.SkeinParameterSpec#PARAM_TYPE_PERSONALISATION} parameter. + */ + public Builder setPersonalisation(byte[] personalisation) + { + return set(PARAM_TYPE_PERSONALISATION, personalisation); + } + + /** + * Implements the recommended personalisation format for Skein defined in Section 4.11 of + * the Skein 1.3 specification. + * <p/> + * The format is <code>YYYYMMDD email@address distinguisher</code>, encoded to a byte + * sequence using UTF-8 encoding. + * + * @param date the date the personalised application of the Skein was defined. + * @param emailAddress the email address of the creation of the personalised application. + * @param distinguisher an arbitrary personalisation string distinguishing the application. + * @return + */ + public Builder setPersonalisation(Date date, String emailAddress, String distinguisher) + { + try + { + final ByteArrayOutputStream bout = new ByteArrayOutputStream(); + final OutputStreamWriter out = new OutputStreamWriter(bout, "UTF-8"); + final DateFormat format = new SimpleDateFormat("YYYYMMDD"); + out.write(format.format(date)); + out.write(" "); + out.write(emailAddress); + out.write(" "); + out.write(distinguisher); + out.close(); + return set(PARAM_TYPE_PERSONALISATION, bout.toByteArray()); + } + catch (IOException e) + { + throw new IllegalStateException("Byte I/O failed: " + e); + } + } + + /** + * Implements the recommended personalisation format for Skein defined in Section 4.11 of + * the Skein 1.3 specification. You may need to use this method if the default locale + * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible implementations. + * <p> + * The format is <code>YYYYMMDD email@address distinguisher</code>, encoded to a byte + * sequence using UTF-8 encoding. + * + * @param date the date the personalised application of the Skein was defined. + * @param dateLocale locale to be used for date interpretation. + * @param emailAddress the email address of the creation of the personalised application. + * @param distinguisher an arbitrary personalisation string distinguishing the application. + * @return the current builder. + */ + public Builder setPersonalisation(Date date, Locale dateLocale, String emailAddress, String distinguisher) + { + try + { + final ByteArrayOutputStream bout = new ByteArrayOutputStream(); + final OutputStreamWriter out = new OutputStreamWriter(bout, "UTF-8"); + final DateFormat format = new SimpleDateFormat("YYYYMMDD", dateLocale); + out.write(format.format(date)); + out.write(" "); + out.write(emailAddress); + out.write(" "); + out.write(distinguisher); + out.close(); + return set(PARAM_TYPE_PERSONALISATION, bout.toByteArray()); + } + catch (IOException e) + { + throw new IllegalStateException("Byte I/O failed: " + e); + } + } + + /** + * Sets the {@link org.spongycastle.jcajce.spec.SkeinParameterSpec#PARAM_TYPE_KEY_IDENTIFIER} parameter. + */ + public Builder setPublicKey(byte[] publicKey) + { + return set(PARAM_TYPE_PUBLIC_KEY, publicKey); + } + + /** + * Sets the {@link org.spongycastle.jcajce.spec.SkeinParameterSpec#PARAM_TYPE_KEY_IDENTIFIER} parameter. + */ + public Builder setKeyIdentifier(byte[] keyIdentifier) + { + return set(PARAM_TYPE_KEY_IDENTIFIER, keyIdentifier); + } + + /** + * Sets the {@link org.spongycastle.jcajce.spec.SkeinParameterSpec#PARAM_TYPE_NONCE} parameter. + */ + public Builder setNonce(byte[] nonce) + { + return set(PARAM_TYPE_NONCE, nonce); + } + + /** + * Constructs a new {@link org.spongycastle.jcajce.spec.SkeinParameterSpec} instance with the parameters provided to this + * builder. + */ + public SkeinParameterSpec build() + { + return new SkeinParameterSpec(parameters); + } + } +} |