package org.spongycastle.crypto.params; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Locale; import org.spongycastle.crypto.CipherParameters; import org.spongycastle.crypto.digests.SkeinDigest; import org.spongycastle.crypto.digests.SkeinEngine; import org.spongycastle.crypto.macs.SkeinMac; import org.spongycastle.util.Integers; /** * Parameters for the Skein hash function - a series of byte[] strings identified by integer tags. *
* Parameterised Skein can be used for: *
null
if not
* set.
*/
public byte[] getKey()
{
return (byte[])parameters.get(Integers.valueOf(PARAM_TYPE_KEY));
}
/**
* Obtains the value of the {@link #PARAM_TYPE_PERSONALISATION personalisation parameter}, or
* null
if not set.
*/
public byte[] getPersonalisation()
{
return (byte[])parameters.get(Integers.valueOf(PARAM_TYPE_PERSONALISATION));
}
/**
* Obtains the value of the {@link #PARAM_TYPE_PUBLIC_KEY public key parameter}, or
* null
if not set.
*/
public byte[] getPublicKey()
{
return (byte[])parameters.get(Integers.valueOf(PARAM_TYPE_PUBLIC_KEY));
}
/**
* Obtains the value of the {@link #PARAM_TYPE_KEY_IDENTIFIER key identifier parameter}, or
* null
if not set.
*/
public byte[] getKeyIdentifier()
{
return (byte[])parameters.get(Integers.valueOf(PARAM_TYPE_KEY_IDENTIFIER));
}
/**
* Obtains the value of the {@link #PARAM_TYPE_NONCE nonce parameter}, or null
if
* not set.
*/
public byte[] getNonce()
{
return (byte[])parameters.get(Integers.valueOf(PARAM_TYPE_NONCE));
}
/**
* A builder for {@link SkeinParameters}.
*/
public static class Builder
{
private Hashtable parameters = new Hashtable();
public Builder()
{
}
public Builder(Hashtable paramsMap)
{
Enumeration keys = paramsMap.keys();
while (keys.hasMoreElements())
{
Integer key = (Integer)keys.nextElement();
parameters.put(key, paramsMap.get(key));
}
}
public Builder(SkeinParameters params)
{
Enumeration keys = params.parameters.keys();
while (keys.hasMoreElements())
{
Integer key = (Integer)keys.nextElement();
parameters.put(key, params.parameters.get(key));
}
}
/**
* Sets a parameters to apply to the Skein hash function.* Parameters with type < {@value SkeinParameters#PARAM_TYPE_MESSAGE} are processed before * the message content, parameters with type > {@value SkeinParameters#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 SkeinParameters#PARAM_TYPE_KEY} parameter. */ public Builder setKey(byte[] key) { return set(PARAM_TYPE_KEY, key); } /** * Sets the {@link SkeinParameters#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. *
* The format is YYYYMMDD email@address distinguisher
, 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 the current builder.
*/
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.
*
* The format is YYYYMMDD email@address distinguisher
, 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 SkeinParameters#PARAM_TYPE_KEY_IDENTIFIER} parameter.
*/
public Builder setPublicKey(byte[] publicKey)
{
return set(PARAM_TYPE_PUBLIC_KEY, publicKey);
}
/**
* Sets the {@link SkeinParameters#PARAM_TYPE_KEY_IDENTIFIER} parameter.
*/
public Builder setKeyIdentifier(byte[] keyIdentifier)
{
return set(PARAM_TYPE_KEY_IDENTIFIER, keyIdentifier);
}
/**
* Sets the {@link SkeinParameters#PARAM_TYPE_NONCE} parameter.
*/
public Builder setNonce(byte[] nonce)
{
return set(PARAM_TYPE_NONCE, nonce);
}
/**
* Constructs a new {@link SkeinParameters} instance with the parameters provided to this
* builder.
*/
public SkeinParameters build()
{
return new SkeinParameters(parameters);
}
}
}