SkeinParameters.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using System.Globalization;
  6. using System.IO;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  8. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters
  9. {
  10. /// <summary>
  11. /// Parameters for the Skein hash function - a series of byte[] strings identified by integer tags.
  12. /// </summary>
  13. /// <remarks>
  14. /// Parameterised Skein can be used for:
  15. /// <ul>
  16. /// <li>MAC generation, by providing a <see cref="SkeinParameters.Builder.SetKey(byte[])">key</see>.</li>
  17. /// <li>Randomised hashing, by providing a <see cref="SkeinParameters.Builder.SetNonce(byte[])">nonce</see>.</li>
  18. /// <li>A hash function for digital signatures, associating a
  19. /// <see cref="SkeinParameters.Builder.SetPublicKey(byte[])">public key</see> with the message digest.</li>
  20. /// <li>A key derivation function, by providing a
  21. /// <see cref="SkeinParameters.Builder.SetKeyIdentifier(byte[])">key identifier</see>.</li>
  22. /// <li>Personalised hashing, by providing a
  23. /// <see cref="SkeinParameters.Builder.SetPersonalisation(DateTime,string,string)">recommended format</see> or
  24. /// <see cref="SkeinParameters.Builder.SetPersonalisation(byte[])">arbitrary</see> personalisation string.</li>
  25. /// </ul>
  26. /// </remarks>
  27. /// <seealso cref="BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests.SkeinEngine"/>
  28. /// <seealso cref="BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests.SkeinDigest"/>
  29. /// <seealso cref="BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs.SkeinMac"/>
  30. public class SkeinParameters
  31. : ICipherParameters
  32. {
  33. /// <summary>
  34. /// The parameter type for a secret key, supporting MAC or KDF functions: 0
  35. /// </summary>
  36. public const int PARAM_TYPE_KEY = 0;
  37. /// <summary>
  38. /// The parameter type for the Skein configuration block: 4
  39. /// </summary>
  40. public const int PARAM_TYPE_CONFIG = 4;
  41. /// <summary>
  42. /// The parameter type for a personalisation string: 8
  43. /// </summary>
  44. public const int PARAM_TYPE_PERSONALISATION = 8;
  45. /// <summary>
  46. /// The parameter type for a public key: 12
  47. /// </summary>
  48. public const int PARAM_TYPE_PUBLIC_KEY = 12;
  49. /// <summary>
  50. /// The parameter type for a key identifier string: 16
  51. /// </summary>
  52. public const int PARAM_TYPE_KEY_IDENTIFIER = 16;
  53. /// <summary>
  54. /// The parameter type for a nonce: 20
  55. /// </summary>
  56. public const int PARAM_TYPE_NONCE = 20;
  57. /// <summary>
  58. /// The parameter type for the message: 48
  59. /// </summary>
  60. public const int PARAM_TYPE_MESSAGE = 48;
  61. /// <summary>
  62. /// The parameter type for the output transformation: 63
  63. /// </summary>
  64. public const int PARAM_TYPE_OUTPUT = 63;
  65. private IDictionary parameters;
  66. public SkeinParameters()
  67. : this(BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable())
  68. {
  69. }
  70. private SkeinParameters(IDictionary parameters)
  71. {
  72. this.parameters = parameters;
  73. }
  74. /// <summary>
  75. /// Obtains a map of type (int) to value (byte[]) for the parameters tracked in this object.
  76. /// </summary>
  77. public IDictionary GetParameters()
  78. {
  79. return parameters;
  80. }
  81. /// <summary>
  82. /// Obtains the value of the <see cref="PARAM_TYPE_KEY">key parameter</see>, or <code>null</code> if not
  83. /// set.
  84. /// </summary>
  85. /// <returns>The key.</returns>
  86. public byte[] GetKey()
  87. {
  88. return (byte[])parameters[PARAM_TYPE_KEY];
  89. }
  90. /// <summary>
  91. /// Obtains the value of the <see cref="PARAM_TYPE_PERSONALISATION">personalisation parameter</see>, or
  92. /// <code>null</code> if not set.
  93. /// </summary>
  94. public byte[] GetPersonalisation()
  95. {
  96. return (byte[])parameters[PARAM_TYPE_PERSONALISATION];
  97. }
  98. /// <summary>
  99. /// Obtains the value of the <see cref="PARAM_TYPE_PUBLIC_KEY">public key parameter</see>, or
  100. /// <code>null</code> if not set.
  101. /// </summary>
  102. public byte[] GetPublicKey()
  103. {
  104. return (byte[])parameters[PARAM_TYPE_PUBLIC_KEY];
  105. }
  106. /// <summary>
  107. /// Obtains the value of the <see cref="PARAM_TYPE_KEY_IDENTIFIER">key identifier parameter</see>, or
  108. /// <code>null</code> if not set.
  109. /// </summary>
  110. public byte[] GetKeyIdentifier()
  111. {
  112. return (byte[])parameters[PARAM_TYPE_KEY_IDENTIFIER];
  113. }
  114. /// <summary>
  115. /// Obtains the value of the <see cref="PARAM_TYPE_NONCE">nonce parameter</see>, or <code>null</code> if
  116. /// not set.
  117. /// </summary>
  118. public byte[] GetNonce()
  119. {
  120. return (byte[])parameters[PARAM_TYPE_NONCE];
  121. }
  122. /// <summary>
  123. /// A builder for <see cref="SkeinParameters"/>.
  124. /// </summary>
  125. public class Builder
  126. {
  127. private IDictionary parameters = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable();
  128. public Builder()
  129. {
  130. }
  131. public Builder(IDictionary paramsMap)
  132. {
  133. IEnumerator keys = paramsMap.Keys.GetEnumerator();
  134. while (keys.MoveNext())
  135. {
  136. int key = (int)keys.Current;
  137. parameters.Add(key, paramsMap[key]);
  138. }
  139. }
  140. public Builder(SkeinParameters parameters)
  141. {
  142. IEnumerator keys = parameters.parameters.Keys.GetEnumerator();
  143. while (keys.MoveNext())
  144. {
  145. int key = (int)keys.Current;
  146. this.parameters.Add(key, parameters.parameters[key]);
  147. }
  148. }
  149. /// <summary>
  150. /// Sets a parameters to apply to the Skein hash function.
  151. /// </summary>
  152. /// <remarks>
  153. /// Parameter types must be in the range 0,5..62, and cannot use the value 48
  154. /// (reserved for message body).
  155. /// <p/>
  156. /// Parameters with type &lt; 48 are processed before
  157. /// the message content, parameters with type &gt; 48
  158. /// are processed after the message and prior to output.
  159. /// </remarks>
  160. /// <param name="type">the type of the parameter, in the range 5..62.</param>
  161. /// <param name="value">the byte sequence of the parameter.</param>
  162. public Builder Set(int type, byte[] value)
  163. {
  164. if (value == null)
  165. {
  166. throw new ArgumentException("Parameter value must not be null.");
  167. }
  168. if ((type != PARAM_TYPE_KEY)
  169. && (type <= PARAM_TYPE_CONFIG || type >= PARAM_TYPE_OUTPUT || type == PARAM_TYPE_MESSAGE))
  170. {
  171. throw new ArgumentException("Parameter types must be in the range 0,5..47,49..62.");
  172. }
  173. if (type == PARAM_TYPE_CONFIG)
  174. {
  175. throw new ArgumentException("Parameter type " + PARAM_TYPE_CONFIG
  176. + " is reserved for internal use.");
  177. }
  178. this.parameters.Add(type, value);
  179. return this;
  180. }
  181. /// <summary>
  182. /// Sets the <see cref="SkeinParameters.PARAM_TYPE_KEY"/> parameter.
  183. /// </summary>
  184. public Builder SetKey(byte[] key)
  185. {
  186. return Set(PARAM_TYPE_KEY, key);
  187. }
  188. /// <summary>
  189. /// Sets the <see cref="SkeinParameters.PARAM_TYPE_PERSONALISATION"/> parameter.
  190. /// </summary>
  191. public Builder SetPersonalisation(byte[] personalisation)
  192. {
  193. return Set(PARAM_TYPE_PERSONALISATION, personalisation);
  194. }
  195. /// <summary>
  196. /// Implements the recommended personalisation format for Skein defined in Section 4.11 of
  197. /// the Skein 1.3 specification.
  198. /// </summary>
  199. /// <remarks>
  200. /// The format is <code>YYYYMMDD email@address distinguisher</code>, encoded to a byte
  201. /// sequence using UTF-8 encoding.
  202. /// </remarks>
  203. /// <param name="date">the date the personalised application of the Skein was defined.</param>
  204. /// <param name="emailAddress">the email address of the creation of the personalised application.</param>
  205. /// <param name="distinguisher">an arbitrary personalisation string distinguishing the application.</param>
  206. public Builder SetPersonalisation(DateTime date, string emailAddress, string distinguisher)
  207. {
  208. try
  209. {
  210. MemoryStream bout = new MemoryStream();
  211. StreamWriter outBytes = new StreamWriter(bout, System.Text.Encoding.UTF8);
  212. outBytes.Write(date.ToString("YYYYMMDD", CultureInfo.InvariantCulture));
  213. outBytes.Write(" ");
  214. outBytes.Write(emailAddress);
  215. outBytes.Write(" ");
  216. outBytes.Write(distinguisher);
  217. BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Dispose(outBytes);
  218. return Set(PARAM_TYPE_PERSONALISATION, bout.ToArray());
  219. }
  220. catch (IOException e)
  221. {
  222. throw new InvalidOperationException("Byte I/O failed.", e);
  223. }
  224. }
  225. /// <summary>
  226. /// Sets the <see cref="SkeinParameters.PARAM_TYPE_KEY_IDENTIFIER"/> parameter.
  227. /// </summary>
  228. public Builder SetPublicKey(byte[] publicKey)
  229. {
  230. return Set(PARAM_TYPE_PUBLIC_KEY, publicKey);
  231. }
  232. /// <summary>
  233. /// Sets the <see cref="SkeinParameters.PARAM_TYPE_KEY_IDENTIFIER"/> parameter.
  234. /// </summary>
  235. public Builder SetKeyIdentifier(byte[] keyIdentifier)
  236. {
  237. return Set(PARAM_TYPE_KEY_IDENTIFIER, keyIdentifier);
  238. }
  239. /// <summary>
  240. /// Sets the <see cref="SkeinParameters.PARAM_TYPE_NONCE"/> parameter.
  241. /// </summary>
  242. public Builder SetNonce(byte[] nonce)
  243. {
  244. return Set(PARAM_TYPE_NONCE, nonce);
  245. }
  246. /// <summary>
  247. /// Constructs a new <see cref="SkeinParameters"/> instance with the parameters provided to this
  248. /// builder.
  249. /// </summary>
  250. public SkeinParameters Build()
  251. {
  252. return new SkeinParameters(parameters);
  253. }
  254. }
  255. }
  256. }
  257. #pragma warning restore
  258. #endif