SkeinParameters.cs 9.0 KB

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