You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
9.0 KiB
290 lines
9.0 KiB
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) |
|
#pragma warning disable |
|
using System; |
|
using System.Collections; |
|
using System.Globalization; |
|
using System.IO; |
|
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities; |
|
|
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters |
|
{ |
|
|
|
/// <summary> |
|
/// Parameters for the Skein hash function - a series of byte[] strings identified by integer tags. |
|
/// </summary> |
|
/// <remarks> |
|
/// Parameterised Skein can be used for: |
|
/// <ul> |
|
/// <li>MAC generation, by providing a <see cref="SkeinParameters.Builder.SetKey(byte[])">key</see>.</li> |
|
/// <li>Randomised hashing, by providing a <see cref="SkeinParameters.Builder.SetNonce(byte[])">nonce</see>.</li> |
|
/// <li>A hash function for digital signatures, associating a |
|
/// <see cref="SkeinParameters.Builder.SetPublicKey(byte[])">public key</see> with the message digest.</li> |
|
/// <li>A key derivation function, by providing a |
|
/// <see cref="SkeinParameters.Builder.SetKeyIdentifier(byte[])">key identifier</see>.</li> |
|
/// <li>Personalised hashing, by providing a |
|
/// <see cref="SkeinParameters.Builder.SetPersonalisation(DateTime,string,string)">recommended format</see> or |
|
/// <see cref="SkeinParameters.Builder.SetPersonalisation(byte[])">arbitrary</see> personalisation string.</li> |
|
/// </ul> |
|
/// </remarks> |
|
/// <seealso cref="BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests.SkeinEngine"/> |
|
/// <seealso cref="BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests.SkeinDigest"/> |
|
/// <seealso cref="BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs.SkeinMac"/> |
|
public class SkeinParameters |
|
: ICipherParameters |
|
{ |
|
/// <summary> |
|
/// The parameter type for a secret key, supporting MAC or KDF functions: 0 |
|
/// </summary> |
|
public const int PARAM_TYPE_KEY = 0; |
|
|
|
/// <summary> |
|
/// The parameter type for the Skein configuration block: 4 |
|
/// </summary> |
|
public const int PARAM_TYPE_CONFIG = 4; |
|
|
|
/// <summary> |
|
/// The parameter type for a personalisation string: 8 |
|
/// </summary> |
|
public const int PARAM_TYPE_PERSONALISATION = 8; |
|
|
|
/// <summary> |
|
/// The parameter type for a public key: 12 |
|
/// </summary> |
|
public const int PARAM_TYPE_PUBLIC_KEY = 12; |
|
|
|
/// <summary> |
|
/// The parameter type for a key identifier string: 16 |
|
/// </summary> |
|
public const int PARAM_TYPE_KEY_IDENTIFIER = 16; |
|
|
|
/// <summary> |
|
/// The parameter type for a nonce: 20 |
|
/// </summary> |
|
public const int PARAM_TYPE_NONCE = 20; |
|
|
|
/// <summary> |
|
/// The parameter type for the message: 48 |
|
/// </summary> |
|
public const int PARAM_TYPE_MESSAGE = 48; |
|
|
|
/// <summary> |
|
/// The parameter type for the output transformation: 63 |
|
/// </summary> |
|
public const int PARAM_TYPE_OUTPUT = 63; |
|
|
|
private IDictionary parameters; |
|
|
|
public SkeinParameters() |
|
: this(BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable()) |
|
|
|
{ |
|
} |
|
|
|
private SkeinParameters(IDictionary parameters) |
|
{ |
|
this.parameters = parameters; |
|
} |
|
|
|
/// <summary> |
|
/// Obtains a map of type (int) to value (byte[]) for the parameters tracked in this object. |
|
/// </summary> |
|
public IDictionary GetParameters() |
|
{ |
|
return parameters; |
|
} |
|
|
|
/// <summary> |
|
/// Obtains the value of the <see cref="PARAM_TYPE_KEY">key parameter</see>, or <code>null</code> if not |
|
/// set. |
|
/// </summary> |
|
/// <returns>The key.</returns> |
|
public byte[] GetKey() |
|
{ |
|
return (byte[])parameters[PARAM_TYPE_KEY]; |
|
} |
|
|
|
/// <summary> |
|
/// Obtains the value of the <see cref="PARAM_TYPE_PERSONALISATION">personalisation parameter</see>, or |
|
/// <code>null</code> if not set. |
|
/// </summary> |
|
public byte[] GetPersonalisation() |
|
{ |
|
return (byte[])parameters[PARAM_TYPE_PERSONALISATION]; |
|
} |
|
|
|
/// <summary> |
|
/// Obtains the value of the <see cref="PARAM_TYPE_PUBLIC_KEY">public key parameter</see>, or |
|
/// <code>null</code> if not set. |
|
/// </summary> |
|
public byte[] GetPublicKey() |
|
{ |
|
return (byte[])parameters[PARAM_TYPE_PUBLIC_KEY]; |
|
} |
|
|
|
/// <summary> |
|
/// Obtains the value of the <see cref="PARAM_TYPE_KEY_IDENTIFIER">key identifier parameter</see>, or |
|
/// <code>null</code> if not set. |
|
/// </summary> |
|
public byte[] GetKeyIdentifier() |
|
{ |
|
return (byte[])parameters[PARAM_TYPE_KEY_IDENTIFIER]; |
|
} |
|
|
|
/// <summary> |
|
/// Obtains the value of the <see cref="PARAM_TYPE_NONCE">nonce parameter</see>, or <code>null</code> if |
|
/// not set. |
|
/// </summary> |
|
public byte[] GetNonce() |
|
{ |
|
return (byte[])parameters[PARAM_TYPE_NONCE]; |
|
} |
|
|
|
/// <summary> |
|
/// A builder for <see cref="SkeinParameters"/>. |
|
/// </summary> |
|
public class Builder |
|
{ |
|
private IDictionary parameters = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable(); |
|
|
|
public Builder() |
|
{ |
|
} |
|
|
|
public Builder(IDictionary paramsMap) |
|
{ |
|
IEnumerator keys = paramsMap.Keys.GetEnumerator(); |
|
while (keys.MoveNext()) |
|
{ |
|
int key = (int)keys.Current; |
|
parameters.Add(key, paramsMap[key]); |
|
} |
|
} |
|
|
|
public Builder(SkeinParameters parameters) |
|
{ |
|
IEnumerator keys = parameters.parameters.Keys.GetEnumerator(); |
|
while (keys.MoveNext()) |
|
{ |
|
int key = (int)keys.Current; |
|
this.parameters.Add(key, parameters.parameters[key]); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Sets a parameters to apply to the Skein hash function. |
|
/// </summary> |
|
/// <remarks> |
|
/// Parameter types must be in the range 0,5..62, and cannot use the value 48 |
|
/// (reserved for message body). |
|
/// <p/> |
|
/// Parameters with type < 48 are processed before |
|
/// the message content, parameters with type > 48 |
|
/// are processed after the message and prior to output. |
|
/// </remarks> |
|
/// <param name="type">the type of the parameter, in the range 5..62.</param> |
|
/// <param name="value">the byte sequence of the parameter.</param> |
|
public Builder Set(int type, byte[] value) |
|
{ |
|
if (value == null) |
|
{ |
|
throw new ArgumentException("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 ArgumentException("Parameter types must be in the range 0,5..47,49..62."); |
|
} |
|
if (type == PARAM_TYPE_CONFIG) |
|
{ |
|
throw new ArgumentException("Parameter type " + PARAM_TYPE_CONFIG |
|
+ " is reserved for internal use."); |
|
} |
|
this.parameters.Add(type, value); |
|
return this; |
|
} |
|
|
|
/// <summary> |
|
/// Sets the <see cref="SkeinParameters.PARAM_TYPE_KEY"/> parameter. |
|
/// </summary> |
|
public Builder SetKey(byte[] key) |
|
{ |
|
return Set(PARAM_TYPE_KEY, key); |
|
} |
|
|
|
/// <summary> |
|
/// Sets the <see cref="SkeinParameters.PARAM_TYPE_PERSONALISATION"/> parameter. |
|
/// </summary> |
|
public Builder SetPersonalisation(byte[] personalisation) |
|
{ |
|
return Set(PARAM_TYPE_PERSONALISATION, personalisation); |
|
} |
|
|
|
/// <summary> |
|
/// Implements the recommended personalisation format for Skein defined in Section 4.11 of |
|
/// the Skein 1.3 specification. |
|
/// </summary> |
|
/// <remarks> |
|
/// The format is <code>YYYYMMDD email@address distinguisher</code>, encoded to a byte |
|
/// sequence using UTF-8 encoding. |
|
/// </remarks> |
|
/// <param name="date">the date the personalised application of the Skein was defined.</param> |
|
/// <param name="emailAddress">the email address of the creation of the personalised application.</param> |
|
/// <param name="distinguisher">an arbitrary personalisation string distinguishing the application.</param> |
|
public Builder SetPersonalisation(DateTime date, string emailAddress, string distinguisher) |
|
{ |
|
try |
|
{ |
|
MemoryStream bout = new MemoryStream(); |
|
StreamWriter outBytes = new StreamWriter(bout, System.Text.Encoding.UTF8); |
|
outBytes.Write(date.ToString("YYYYMMDD", CultureInfo.InvariantCulture)); |
|
outBytes.Write(" "); |
|
outBytes.Write(emailAddress); |
|
outBytes.Write(" "); |
|
outBytes.Write(distinguisher); |
|
BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Dispose(outBytes); |
|
return Set(PARAM_TYPE_PERSONALISATION, bout.ToArray()); |
|
} |
|
catch (IOException e) |
|
{ |
|
throw new InvalidOperationException("Byte I/O failed.", e); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Sets the <see cref="SkeinParameters.PARAM_TYPE_KEY_IDENTIFIER"/> parameter. |
|
/// </summary> |
|
public Builder SetPublicKey(byte[] publicKey) |
|
{ |
|
return Set(PARAM_TYPE_PUBLIC_KEY, publicKey); |
|
} |
|
|
|
/// <summary> |
|
/// Sets the <see cref="SkeinParameters.PARAM_TYPE_KEY_IDENTIFIER"/> parameter. |
|
/// </summary> |
|
public Builder SetKeyIdentifier(byte[] keyIdentifier) |
|
{ |
|
return Set(PARAM_TYPE_KEY_IDENTIFIER, keyIdentifier); |
|
} |
|
|
|
/// <summary> |
|
/// Sets the <see cref="SkeinParameters.PARAM_TYPE_NONCE"/> parameter. |
|
/// </summary> |
|
public Builder SetNonce(byte[] nonce) |
|
{ |
|
return Set(PARAM_TYPE_NONCE, nonce); |
|
} |
|
|
|
/// <summary> |
|
/// Constructs a new <see cref="SkeinParameters"/> instance with the parameters provided to this |
|
/// builder. |
|
/// </summary> |
|
public SkeinParameters Build() |
|
{ |
|
return new SkeinParameters(parameters); |
|
} |
|
} |
|
} |
|
} |
|
#pragma warning restore |
|
#endif
|
|
|