SecretTests.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. // Copyright (c) .NET Foundation. All rights reserved.
  2. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  3. using System;
  4. using Microsoft.AspNetCore.Testing;
  5. using Xunit;
  6. namespace Microsoft.AspNetCore.DataProtection
  7. {
  8. public unsafe class SecretTests
  9. {
  10. [Fact]
  11. public void Ctor_ArraySegment_Default_Throws()
  12. {
  13. // Act & assert
  14. ExceptionAssert.ThrowsArgument(
  15. testCode: () => new Secret(default(ArraySegment<byte>)),
  16. paramName: "array",
  17. exceptionMessage: null);
  18. }
  19. [Fact]
  20. public void Ctor_ArraySegment_Success()
  21. {
  22. // Arrange
  23. var input = new ArraySegment<byte>(new byte[] { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 }, 1, 3);
  24. // Act
  25. var secret = new Secret(input);
  26. input.Array[2] = 0xFF; // mutate original array - secret shouldn't be modified
  27. // Assert - length
  28. Assert.Equal(3, secret.Length);
  29. // Assert - managed buffer
  30. var outputSegment = new ArraySegment<byte>(new byte[7], 2, 3);
  31. secret.WriteSecretIntoBuffer(outputSegment);
  32. Assert.Equal(new byte[] { 0x20, 0x30, 0x40 }, outputSegment.AsStandaloneArray());
  33. // Assert - unmanaged buffer
  34. var outputBuffer = new byte[3];
  35. fixed (byte* pOutputBuffer = outputBuffer)
  36. {
  37. secret.WriteSecretIntoBuffer(pOutputBuffer, 3);
  38. }
  39. Assert.Equal(new byte[] { 0x20, 0x30, 0x40 }, outputBuffer);
  40. }
  41. [Fact]
  42. public void Ctor_Buffer_Success()
  43. {
  44. // Arrange
  45. var input = new byte[] { 0x20, 0x30, 0x40 };
  46. // Act
  47. var secret = new Secret(input);
  48. input[1] = 0xFF; // mutate original array - secret shouldn't be modified
  49. // Assert - length
  50. Assert.Equal(3, secret.Length);
  51. // Assert - managed buffer
  52. var outputSegment = new ArraySegment<byte>(new byte[7], 2, 3);
  53. secret.WriteSecretIntoBuffer(outputSegment);
  54. Assert.Equal(new byte[] { 0x20, 0x30, 0x40 }, outputSegment.AsStandaloneArray());
  55. // Assert - unmanaged buffer
  56. var outputBuffer = new byte[3];
  57. fixed (byte* pOutputBuffer = outputBuffer)
  58. {
  59. secret.WriteSecretIntoBuffer(pOutputBuffer, 3);
  60. }
  61. Assert.Equal(new byte[] { 0x20, 0x30, 0x40 }, outputBuffer);
  62. }
  63. [Fact]
  64. public void Ctor_Buffer_ZeroLength_Success()
  65. {
  66. // Act
  67. var secret = new Secret(new byte[0]);
  68. // Assert - none of these methods should throw
  69. Assert.Equal(0, secret.Length);
  70. secret.WriteSecretIntoBuffer(new ArraySegment<byte>(new byte[0]));
  71. byte dummy;
  72. secret.WriteSecretIntoBuffer(&dummy, 0);
  73. }
  74. [Fact]
  75. public void Ctor_Pointer_WithNullPointer_ThrowsArgumentNull()
  76. {
  77. // Act & assert
  78. ExceptionAssert.ThrowsArgumentNull(
  79. testCode: () => new Secret(null, 0),
  80. paramName: "secret");
  81. }
  82. [Fact]
  83. public void Ctor_Pointer_WithNegativeLength_ThrowsArgumentOutOfRange()
  84. {
  85. // Act & assert
  86. ExceptionAssert.ThrowsArgumentOutOfRange(
  87. testCode: () =>
  88. {
  89. byte dummy;
  90. new Secret(&dummy, -1);
  91. },
  92. paramName: "secretLength",
  93. exceptionMessage: Resources.Common_ValueMustBeNonNegative);
  94. }
  95. [Fact]
  96. public void Ctor_Pointer_ZeroLength_Success()
  97. {
  98. // Arrange
  99. byte input;
  100. // Act
  101. var secret = new Secret(&input, 0);
  102. // Assert - none of these methods should throw
  103. Assert.Equal(0, secret.Length);
  104. secret.WriteSecretIntoBuffer(new ArraySegment<byte>(new byte[0]));
  105. byte dummy;
  106. secret.WriteSecretIntoBuffer(&dummy, 0);
  107. }
  108. [Fact]
  109. public void Ctor_Pointer_Success()
  110. {
  111. // Arrange
  112. byte* input = stackalloc byte[3];
  113. input[0] = 0x20;
  114. input[1] = 0x30;
  115. input[2] = 0x40;
  116. // Act
  117. var secret = new Secret(input, 3);
  118. input[1] = 0xFF; // mutate original buffer - secret shouldn't be modified
  119. // Assert - length
  120. Assert.Equal(3, secret.Length);
  121. // Assert - managed buffer
  122. var outputSegment = new ArraySegment<byte>(new byte[7], 2, 3);
  123. secret.WriteSecretIntoBuffer(outputSegment);
  124. Assert.Equal(new byte[] { 0x20, 0x30, 0x40 }, outputSegment.AsStandaloneArray());
  125. // Assert - unmanaged buffer
  126. var outputBuffer = new byte[3];
  127. fixed (byte* pOutputBuffer = outputBuffer)
  128. {
  129. secret.WriteSecretIntoBuffer(pOutputBuffer, 3);
  130. }
  131. Assert.Equal(new byte[] { 0x20, 0x30, 0x40 }, outputBuffer);
  132. }
  133. [Fact]
  134. public void Random_ZeroLength_Success()
  135. {
  136. // Act
  137. var secret = Secret.Random(0);
  138. // Assert
  139. Assert.Equal(0, secret.Length);
  140. }
  141. [Fact]
  142. public void Random_LengthIsMultipleOf16_Success()
  143. {
  144. // Act
  145. var secret = Secret.Random(32);
  146. // Assert
  147. Assert.Equal(32, secret.Length);
  148. Guid* pGuids = stackalloc Guid[2];
  149. secret.WriteSecretIntoBuffer((byte*)pGuids, 32);
  150. Assert.NotEqual(Guid.Empty, pGuids[0]);
  151. Assert.NotEqual(Guid.Empty, pGuids[1]);
  152. Assert.NotEqual(pGuids[0], pGuids[1]);
  153. }
  154. [Fact]
  155. public void Random_LengthIsNotMultipleOf16_Success()
  156. {
  157. // Act
  158. var secret = Secret.Random(31);
  159. // Assert
  160. Assert.Equal(31, secret.Length);
  161. Guid* pGuids = stackalloc Guid[2];
  162. secret.WriteSecretIntoBuffer((byte*)pGuids, 31);
  163. Assert.NotEqual(Guid.Empty, pGuids[0]);
  164. Assert.NotEqual(Guid.Empty, pGuids[1]);
  165. Assert.NotEqual(pGuids[0], pGuids[1]);
  166. Assert.Equal(0, ((byte*)pGuids)[31]); // last byte shouldn't have been overwritten
  167. }
  168. [Fact]
  169. public void WriteSecretIntoBuffer_ArraySegment_IncorrectlySizedBuffer_Throws()
  170. {
  171. // Arrange
  172. var secret = Secret.Random(16);
  173. // Act & assert
  174. ExceptionAssert.ThrowsArgument(
  175. testCode: () => secret.WriteSecretIntoBuffer(new ArraySegment<byte>(new byte[100])),
  176. paramName: "buffer",
  177. exceptionMessage: Resources.FormatCommon_BufferIncorrectlySized(100, 16));
  178. }
  179. [Fact]
  180. public void WriteSecretIntoBuffer_ArraySegment_Disposed_Throws()
  181. {
  182. // Arrange
  183. var secret = Secret.Random(16);
  184. secret.Dispose();
  185. // Act & assert
  186. Assert.Throws<ObjectDisposedException>(
  187. testCode: () => secret.WriteSecretIntoBuffer(new ArraySegment<byte>(new byte[16])));
  188. }
  189. [Fact]
  190. public void WriteSecretIntoBuffer_Pointer_NullBuffer_Throws()
  191. {
  192. // Arrange
  193. var secret = Secret.Random(16);
  194. // Act & assert
  195. ExceptionAssert.ThrowsArgumentNull(
  196. testCode: () => secret.WriteSecretIntoBuffer(null, 100),
  197. paramName: "buffer");
  198. }
  199. [Fact]
  200. public void WriteSecretIntoBuffer_Pointer_IncorrectlySizedBuffer_Throws()
  201. {
  202. // Arrange
  203. var secret = Secret.Random(16);
  204. // Act & assert
  205. ExceptionAssert.ThrowsArgument(
  206. testCode: () =>
  207. {
  208. byte* pBuffer = stackalloc byte[100];
  209. secret.WriteSecretIntoBuffer(pBuffer, 100);
  210. },
  211. paramName: "bufferLength",
  212. exceptionMessage: Resources.FormatCommon_BufferIncorrectlySized(100, 16));
  213. }
  214. [Fact]
  215. public void WriteSecretIntoBuffer_Pointer_Disposed_Throws()
  216. {
  217. // Arrange
  218. var secret = Secret.Random(16);
  219. secret.Dispose();
  220. // Act & assert
  221. Assert.Throws<ObjectDisposedException>(
  222. testCode: () =>
  223. {
  224. byte* pBuffer = stackalloc byte[16];
  225. secret.WriteSecretIntoBuffer(pBuffer, 16);
  226. });
  227. }
  228. }
  229. }