Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
ECDiffieHellmanImplementation.cs
Go to the documentation of this file.
2
4
5internal static class ECDiffieHellmanImplementation
6{
7 public sealed class ECDiffieHellmanCng : ECDiffieHellman
8 {
9 private readonly ECCngKey _key = new ECCngKey("ECDH", "ECDiffieHellman");
10
12 {
13 get
14 {
15 string oidValue;
16 string curveName = GetCurveName(out oidValue);
17 return new ECDiffieHellmanCngPublicKey((curveName == null) ? ExportFullKeyBlob(includePrivateParameters: false) : ExportKeyBlob(includePrivateParameters: false), curveName);
18 }
19 }
20
21 public override int KeySize
22 {
23 get
24 {
25 return base.KeySize;
26 }
27 set
28 {
29 if (KeySize != value)
30 {
31 base.KeySize = value;
32 DisposeKey();
33 }
34 }
35 }
36
37 public override KeySizes[] LegalKeySizes => new KeySizes[2]
38 {
39 new KeySizes(256, 384, 128),
40 new KeySizes(521, 521, 0)
41 };
42
43 protected override void Dispose(bool disposing)
44 {
45 if (disposing)
46 {
48 }
49 base.Dispose(disposing);
50 }
51
52 private void ThrowIfDisposed()
53 {
55 }
56
57 private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters)
58 {
59 string blobType = (includePrivateParameters ? "ECCFULLPRIVATEBLOB" : "ECCFULLPUBLICBLOB");
60 SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecfullKeyBlob);
61 _key.SetHandle(keyHandle, "ECDH");
63 }
64
65 private void ImportKeyBlob(byte[] ecKeyBlob, string curveName, bool includePrivateParameters)
66 {
67 string blobType = (includePrivateParameters ? "ECCPRIVATEBLOB" : "ECCPUBLICBLOB");
68 SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecKeyBlob, curveName);
69 _key.SetHandle(keyHandle, ECCng.EcdhCurveNameToAlgorithm(curveName));
71 }
72
73 private byte[] ExportKeyBlob(bool includePrivateParameters)
74 {
75 string blobType = (includePrivateParameters ? "ECCPRIVATEBLOB" : "ECCPUBLICBLOB");
77 return CngKeyLite.ExportKeyBlob(keyHandle, blobType);
78 }
79
80 private byte[] ExportFullKeyBlob(bool includePrivateParameters)
81 {
82 string blobType = (includePrivateParameters ? "ECCFULLPRIVATEBLOB" : "ECCFULLPUBLICBLOB");
84 return CngKeyLite.ExportKeyBlob(keyHandle, blobType);
85 }
86
87 private byte[] ExportEncryptedPkcs8(ReadOnlySpan<char> pkcs8Password, int kdfCount)
88 {
90 return CngKeyLite.ExportPkcs8KeyBlob(keyHandle, pkcs8Password, kdfCount);
91 }
92
93 private bool TryExportEncryptedPkcs8(ReadOnlySpan<char> pkcs8Password, int kdfCount, Span<byte> destination, out int bytesWritten)
94 {
96 return CngKeyLite.TryExportPkcs8KeyBlob(keyHandle, pkcs8Password, kdfCount, destination, out bytesWritten);
97 }
98
99 private void AcceptImport(CngPkcs8.Pkcs8Response response)
100 {
101 SafeNCryptKeyHandle keyHandle = response.KeyHandle;
102 _key.SetHandle(keyHandle, CngKeyLite.GetPropertyAsString(keyHandle, "Algorithm Name", CngPropertyOptions.None));
104 }
105
106 public override byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey)
107 {
108 if (otherPartyPublicKey == null)
109 {
110 throw new ArgumentNullException("otherPartyPublicKey");
111 }
112 return DeriveKeyFromHash(otherPartyPublicKey, HashAlgorithmName.SHA256);
113 }
114
116 {
117 if (otherPartyPublicKey == null)
118 {
119 throw new ArgumentNullException("otherPartyPublicKey");
120 }
121 ECParameters parameters = otherPartyPublicKey.ExportParameters();
122 using ECDiffieHellmanCng eCDiffieHellmanCng = (ECDiffieHellmanCng)ECDiffieHellman.Create(parameters);
123 using SafeNCryptKeyHandle safeNCryptKeyHandle = eCDiffieHellmanCng.GetDuplicatedKeyHandle();
124 string propertyAsString = CngKeyLite.GetPropertyAsString(safeNCryptKeyHandle, "Algorithm Group", CngPropertyOptions.None);
125 if (propertyAsString != "ECDH")
126 {
127 throw new ArgumentException(System.SR.Cryptography_ArgECDHRequiresECDHKey, "otherPartyPublicKey");
128 }
129 if (CngKeyLite.GetKeyLength(safeNCryptKeyHandle) != KeySize)
130 {
131 throw new ArgumentException(System.SR.Cryptography_ArgECDHKeySizeMismatch, "otherPartyPublicKey");
132 }
133 using SafeNCryptKeyHandle privateKey = GetDuplicatedKeyHandle();
134 return global::Interop.NCrypt.DeriveSecretAgreement(privateKey, safeNCryptKeyHandle);
135 }
136
137 private string GetCurveName(out string oidValue)
138 {
139 return _key.GetCurveName(KeySize, out oidValue);
140 }
141
142 public override void GenerateKey(ECCurve curve)
143 {
144 _key.GenerateKey(curve);
146 }
147
152
153 private void DisposeKey()
154 {
156 }
157
159 : this(521)
160 {
161 }
162
163 public ECDiffieHellmanCng(int keySize)
164 {
165 KeySize = keySize;
166 }
167
169 {
170 GenerateKey(curve);
171 }
172
173 private void ForceSetKeySize(int newKeySize)
174 {
175 KeySizeValue = newKeySize;
176 }
177
178 public override byte[] DeriveKeyFromHash(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm, byte[] secretPrepend, byte[] secretAppend)
179 {
180 if (otherPartyPublicKey == null)
181 {
182 throw new ArgumentNullException("otherPartyPublicKey");
183 }
184 if (string.IsNullOrEmpty(hashAlgorithm.Name))
185 {
187 }
188 using SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey);
189 return global::Interop.NCrypt.DeriveKeyMaterialHash(secretAgreement, hashAlgorithm.Name, secretPrepend, secretAppend, global::Interop.NCrypt.SecretAgreementFlags.None);
190 }
191
192 public override byte[] DeriveKeyFromHmac(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm, byte[] hmacKey, byte[] secretPrepend, byte[] secretAppend)
193 {
194 if (otherPartyPublicKey == null)
195 {
196 throw new ArgumentNullException("otherPartyPublicKey");
197 }
198 if (string.IsNullOrEmpty(hashAlgorithm.Name))
199 {
201 }
202 using SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey);
203 global::Interop.NCrypt.SecretAgreementFlags flags = ((hmacKey == null) ? global::Interop.NCrypt.SecretAgreementFlags.UseSecretAsHmacKey : global::Interop.NCrypt.SecretAgreementFlags.None);
204 return global::Interop.NCrypt.DeriveKeyMaterialHmac(secretAgreement, hashAlgorithm.Name, hmacKey, secretPrepend, secretAppend, flags);
205 }
206
207 public override byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed)
208 {
209 if (otherPartyPublicKey == null)
210 {
211 throw new ArgumentNullException("otherPartyPublicKey");
212 }
213 if (prfLabel == null)
214 {
215 throw new ArgumentNullException("prfLabel");
216 }
217 if (prfSeed == null)
218 {
219 throw new ArgumentNullException("prfSeed");
220 }
221 using SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey);
222 return global::Interop.NCrypt.DeriveKeyMaterialTls(secretAgreement, prfLabel, prfSeed, global::Interop.NCrypt.SecretAgreementFlags.None);
223 }
224
225 public override void ImportParameters(ECParameters parameters)
226 {
227 parameters.Validate();
229 ECCurve curve = parameters.Curve;
230 bool flag = parameters.D != null;
231 bool flag2 = parameters.Q.X != null && parameters.Q.Y != null;
232 if (curve.IsPrime)
233 {
234 if (!flag2 && flag)
235 {
236 byte[] array = new byte[parameters.D.Length];
237 ECParameters parameters2 = parameters;
238 parameters2.Q.X = array;
239 parameters2.Q.Y = array;
240 byte[] primeCurveBlob = ECCng.GetPrimeCurveBlob(ref parameters2, ecdh: true);
241 ImportFullKeyBlob(primeCurveBlob, includePrivateParameters: true);
242 }
243 else
244 {
245 byte[] primeCurveBlob2 = ECCng.GetPrimeCurveBlob(ref parameters, ecdh: true);
246 ImportFullKeyBlob(primeCurveBlob2, flag);
247 }
248 return;
249 }
250 if (curve.IsNamed)
251 {
252 if (string.IsNullOrEmpty(curve.Oid.FriendlyName))
253 {
255 }
256 if (!flag2 && flag)
257 {
258 byte[] array2 = new byte[parameters.D.Length];
259 ECParameters parameters3 = parameters;
260 parameters3.Q.X = array2;
261 parameters3.Q.Y = array2;
262 byte[] namedCurveBlob = ECCng.GetNamedCurveBlob(ref parameters3, ecdh: true);
263 ImportKeyBlob(namedCurveBlob, curve.Oid.FriendlyName, includePrivateParameters: true);
264 }
265 else
266 {
267 byte[] namedCurveBlob2 = ECCng.GetNamedCurveBlob(ref parameters, ecdh: true);
268 ImportKeyBlob(namedCurveBlob2, curve.Oid.FriendlyName, flag);
269 }
270 return;
271 }
273 }
274
275 public override ECParameters ExportExplicitParameters(bool includePrivateParameters)
276 {
277 byte[] array = ExportFullKeyBlob(includePrivateParameters);
278 try
279 {
280 ECParameters ecParams = default(ECParameters);
281 ECCng.ExportPrimeCurveParameters(ref ecParams, array, includePrivateParameters);
282 return ecParams;
283 }
284 finally
285 {
287 }
288 }
289
290 public override ECParameters ExportParameters(bool includePrivateParameters)
291 {
292 ECParameters ecParams = default(ECParameters);
293 string oidValue;
294 string curveName = GetCurveName(out oidValue);
295 byte[] array = null;
296 try
297 {
298 if (string.IsNullOrEmpty(curveName))
299 {
300 array = ExportFullKeyBlob(includePrivateParameters);
301 ECCng.ExportPrimeCurveParameters(ref ecParams, array, includePrivateParameters);
302 }
303 else
304 {
305 array = ExportKeyBlob(includePrivateParameters);
306 ECCng.ExportNamedCurveParameters(ref ecParams, array, includePrivateParameters);
307 ecParams.Curve = ECCurve.CreateFromOid(new Oid(oidValue, curveName));
308 }
309 return ecParams;
310 }
311 finally
312 {
313 if (array != null)
314 {
316 }
317 }
318 }
319
320 public override void ImportPkcs8PrivateKey(ReadOnlySpan<byte> source, out int bytesRead)
321 {
323 int bytesRead2;
325 ProcessPkcs8Response(response);
326 bytesRead = bytesRead2;
327 }
328
329 public override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte> passwordBytes, ReadOnlySpan<byte> source, out int bytesRead)
330 {
332 int bytesRead2;
333 CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead2);
334 ProcessPkcs8Response(response);
335 bytesRead = bytesRead2;
336 }
337
338 public override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<char> password, ReadOnlySpan<byte> source, out int bytesRead)
339 {
341 int bytesRead2;
342 CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead2);
343 ProcessPkcs8Response(response);
344 bytesRead = bytesRead2;
345 }
346
348 {
349 if (response.GetAlgorithmGroup() != "ECDH")
350 {
351 response.FreeKey();
353 }
354 AcceptImport(response);
355 }
356
357 public override byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte> passwordBytes, PbeParameters pbeParameters)
358 {
359 if (pbeParameters == null)
360 {
361 throw new ArgumentNullException("pbeParameters");
362 }
363 return CngPkcs8.ExportEncryptedPkcs8PrivateKey(this, passwordBytes, pbeParameters);
364 }
365
366 public override byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan<char> password, PbeParameters pbeParameters)
367 {
368 if (pbeParameters == null)
369 {
370 throw new ArgumentNullException("pbeParameters");
371 }
373 if (CngPkcs8.IsPlatformScheme(pbeParameters))
374 {
375 return ExportEncryptedPkcs8(password, pbeParameters.IterationCount);
376 }
377 return CngPkcs8.ExportEncryptedPkcs8PrivateKey(this, password, pbeParameters);
378 }
379
380 public override bool TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte> passwordBytes, PbeParameters pbeParameters, Span<byte> destination, out int bytesWritten)
381 {
382 if (pbeParameters == null)
383 {
384 throw new ArgumentNullException("pbeParameters");
385 }
387 return CngPkcs8.TryExportEncryptedPkcs8PrivateKey(this, passwordBytes, pbeParameters, destination, out bytesWritten);
388 }
389
390 public override bool TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<char> password, PbeParameters pbeParameters, Span<byte> destination, out int bytesWritten)
391 {
392 if (pbeParameters == null)
393 {
394 throw new ArgumentNullException("pbeParameters");
395 }
397 if (CngPkcs8.IsPlatformScheme(pbeParameters))
398 {
399 return TryExportEncryptedPkcs8(password, pbeParameters.IterationCount, destination, out bytesWritten);
400 }
401 return CngPkcs8.TryExportEncryptedPkcs8PrivateKey(this, password, pbeParameters, destination, out bytesWritten);
402 }
403 }
404
406 {
407 private byte[] _keyBlob;
408
409 internal string _curveName;
410
411 protected override void Dispose(bool disposing)
412 {
413 _keyBlob = null;
414 base.Dispose(disposing);
415 }
416
417 public override string ToXmlString()
418 {
420 }
421
422 internal ECDiffieHellmanCngPublicKey(byte[] keyBlob, string curveName)
423 : base(keyBlob)
424 {
425 _keyBlob = keyBlob;
426 _curveName = curveName;
427 }
428
430 {
431 if (_keyBlob == null)
432 {
433 throw new ObjectDisposedException("ECDiffieHellmanPublicKey");
434 }
435 ECParameters ecParams = default(ECParameters);
436 ECCng.ExportPrimeCurveParameters(ref ecParams, _keyBlob, includePrivateParameters: false);
437 return ecParams;
438 }
439
441 {
442 if (_keyBlob == null)
443 {
444 throw new ObjectDisposedException("ECDiffieHellmanPublicKey");
445 }
446 if (string.IsNullOrEmpty(_curveName))
447 {
449 }
450 ECParameters ecParams = default(ECParameters);
451 ECCng.ExportNamedCurveParameters(ref ecParams, _keyBlob, includePrivateParameters: false);
452 ecParams.Curve = ECCurve.CreateFromFriendlyName(_curveName);
453 return ecParams;
454 }
455 }
456}
static unsafe void Clear(Array array)
Definition Array.cs:755
static string Cryptography_CurveNotSupported
Definition SR.cs:64
static string Cryptography_ArgECDHRequiresECDHKey
Definition SR.cs:42
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string Cryptography_NotValidPublicOrPrivateKey
Definition SR.cs:122
static string Cryptography_ArgECDHKeySizeMismatch
Definition SR.cs:40
static string Cryptography_InvalidCurveOid
Definition SR.cs:66
static string Cryptography_HashAlgorithmNameNullOrEmpty
Definition SR.cs:60
Definition SR.cs:7
static bool TryExportPkcs8KeyBlob(SafeNCryptKeyHandle keyHandle, ReadOnlySpan< char > password, int kdfCount, Span< byte > destination, out int bytesWritten)
Definition CngKeyLite.cs:93
static byte[] ExportPkcs8KeyBlob(SafeNCryptKeyHandle keyHandle, ReadOnlySpan< char > password, int kdfCount)
Definition CngKeyLite.cs:85
static unsafe SafeNCryptKeyHandle ImportKeyBlob(string blobType, ReadOnlySpan< byte > keyBlob, bool encrypted=false, ReadOnlySpan< char > password=default(ReadOnlySpan< char >))
Definition CngKeyLite.cs:14
static byte[] ExportKeyBlob(SafeNCryptKeyHandle keyHandle, string blobType)
Definition CngKeyLite.cs:58
static int GetKeyLength(SafeNCryptKeyHandle keyHandle)
static unsafe string GetPropertyAsString(SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options)
static bool IsPlatformScheme(PbeParameters pbeParameters)
Definition CngPkcs8.cs:44
static unsafe Pkcs8Response ImportEncryptedPkcs8PrivateKey(ReadOnlySpan< byte > passwordBytes, ReadOnlySpan< byte > source, out int bytesRead)
Definition CngPkcs8.cs:134
static byte[] ExportEncryptedPkcs8PrivateKey(AsymmetricAlgorithm key, ReadOnlySpan< byte > passwordBytes, PbeParameters pbeParameters)
Definition CngPkcs8.cs:53
static Pkcs8Response ImportPkcs8PrivateKey(ReadOnlySpan< byte > source, out int bytesRead)
Definition CngPkcs8.cs:90
static bool TryExportEncryptedPkcs8PrivateKey(AsymmetricAlgorithm key, ReadOnlySpan< byte > passwordBytes, PbeParameters pbeParameters, Span< byte > destination, out int bytesWritten)
Definition CngPkcs8.cs:68
void GenerateKey(ECCurve curve)
Definition ECCngKey.cs:68
string GetCurveName(int callerKeySizeProperty, out string oidValue)
Definition ECCngKey.cs:27
void SetHandle(SafeNCryptKeyHandle keyHandle, string algorithmName)
Definition ECCngKey.cs:156
SafeNCryptKeyHandle GetDuplicatedKeyHandle(int callerKeySizeProperty)
Definition ECCngKey.cs:39
static string EcdhCurveNameToAlgorithm(string algorithm)
Definition ECCng.cs:367
static unsafe byte[] GetPrimeCurveBlob(ref ECParameters parameters, bool ecdh)
Definition ECCng.cs:88
static unsafe void ExportNamedCurveParameters(ref ECParameters ecParams, byte[] ecBlob, bool includePrivateParameters)
Definition ECCng.cs:131
static unsafe byte[] GetNamedCurveBlob(ref ECParameters parameters, bool ecdh)
Definition ECCng.cs:63
static unsafe void ExportPrimeCurveParameters(ref ECParameters ecParams, byte[] ecBlob, bool includePrivateParameters)
Definition ECCng.cs:155
void ImportKeyBlob(byte[] ecKeyBlob, string curveName, bool includePrivateParameters)
override void ImportPkcs8PrivateKey(ReadOnlySpan< byte > source, out int bytesRead)
override byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan< char > password, PbeParameters pbeParameters)
SafeNCryptSecretHandle DeriveSecretAgreementHandle(ECDiffieHellmanPublicKey otherPartyPublicKey)
override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan< byte > passwordBytes, ReadOnlySpan< byte > source, out int bytesRead)
override byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed)
override byte[] DeriveKeyFromHash(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm, byte[] secretPrepend, byte[] secretAppend)
override byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey)
override byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan< byte > passwordBytes, PbeParameters pbeParameters)
override bool TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan< byte > passwordBytes, PbeParameters pbeParameters, Span< byte > destination, out int bytesWritten)
override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan< char > password, ReadOnlySpan< byte > source, out int bytesRead)
override bool TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan< char > password, PbeParameters pbeParameters, Span< byte > destination, out int bytesWritten)
bool TryExportEncryptedPkcs8(ReadOnlySpan< char > pkcs8Password, int kdfCount, Span< byte > destination, out int bytesWritten)
override byte[] DeriveKeyFromHmac(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm, byte[] hmacKey, byte[] secretPrepend, byte[] secretAppend)
static new? ECDiffieHellman Create(string algorithm)
static void ValidatePbeParameters(PbeParameters pbeParameters, ReadOnlySpan< char > password, ReadOnlySpan< byte > passwordBytes)
static ECCurve CreateFromOid(Oid curveOid)
Definition ECCurve.cs:127
static ECCurve CreateFromFriendlyName(string oidFriendlyName)
Definition ECCurve.cs:135