Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
ECDsaImplementation.cs
Go to the documentation of this file.
1using System.IO;
4
6
7internal static class ECDsaImplementation
8{
9 public sealed class ECDsaCng : ECDsa
10 {
11 private readonly ECCngKey _key = new ECCngKey("ECDSA", "ECDsa");
12
13 public override int KeySize
14 {
15 get
16 {
17 return base.KeySize;
18 }
19 set
20 {
21 if (KeySize != value)
22 {
23 base.KeySize = value;
24 DisposeKey();
25 }
26 }
27 }
28
29 public override KeySizes[] LegalKeySizes => new KeySizes[2]
30 {
31 new KeySizes(256, 384, 128),
32 new KeySizes(521, 521, 0)
33 };
34
35 protected override void Dispose(bool disposing)
36 {
37 if (disposing)
38 {
40 }
41 base.Dispose(disposing);
42 }
43
44 private void ThrowIfDisposed()
45 {
47 }
48
49 private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters)
50 {
51 string blobType = (includePrivateParameters ? "ECCFULLPRIVATEBLOB" : "ECCFULLPUBLICBLOB");
52 SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecfullKeyBlob);
53 _key.SetHandle(keyHandle, "ECDSA");
55 }
56
57 private void ImportKeyBlob(byte[] ecKeyBlob, string curveName, bool includePrivateParameters)
58 {
59 string blobType = (includePrivateParameters ? "ECCPRIVATEBLOB" : "ECCPUBLICBLOB");
60 SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecKeyBlob, curveName);
61 _key.SetHandle(keyHandle, ECCng.EcdsaCurveNameToAlgorithm(curveName));
63 }
64
65 private byte[] ExportKeyBlob(bool includePrivateParameters)
66 {
67 string blobType = (includePrivateParameters ? "ECCPRIVATEBLOB" : "ECCPUBLICBLOB");
69 return CngKeyLite.ExportKeyBlob(keyHandle, blobType);
70 }
71
72 private byte[] ExportFullKeyBlob(bool includePrivateParameters)
73 {
74 string blobType = (includePrivateParameters ? "ECCFULLPRIVATEBLOB" : "ECCFULLPUBLICBLOB");
76 return CngKeyLite.ExportKeyBlob(keyHandle, blobType);
77 }
78
79 private byte[] ExportEncryptedPkcs8(ReadOnlySpan<char> pkcs8Password, int kdfCount)
80 {
82 return CngKeyLite.ExportPkcs8KeyBlob(keyHandle, pkcs8Password, kdfCount);
83 }
84
85 private bool TryExportEncryptedPkcs8(ReadOnlySpan<char> pkcs8Password, int kdfCount, Span<byte> destination, out int bytesWritten)
86 {
88 return CngKeyLite.TryExportPkcs8KeyBlob(keyHandle, pkcs8Password, kdfCount, destination, out bytesWritten);
89 }
90
91 private void AcceptImport(CngPkcs8.Pkcs8Response response)
92 {
93 SafeNCryptKeyHandle keyHandle = response.KeyHandle;
94 _key.SetHandle(keyHandle, CngKeyLite.GetPropertyAsString(keyHandle, "Algorithm Name", CngPropertyOptions.None));
96 }
97
98 private string GetCurveName(out string oidValue)
99 {
100 return _key.GetCurveName(KeySize, out oidValue);
101 }
102
103 public override void GenerateKey(ECCurve curve)
104 {
105 _key.GenerateKey(curve);
107 }
108
113
114 private void DisposeKey()
115 {
117 }
118
119 public ECDsaCng(ECCurve curve)
120 {
121 GenerateKey(curve);
122 }
123
124 public ECDsaCng()
125 : this(521)
126 {
127 }
128
129 public ECDsaCng(int keySize)
130 {
131 KeySize = keySize;
132 }
133
134 private void ForceSetKeySize(int newKeySize)
135 {
136 KeySizeValue = newKeySize;
137 }
138
139 protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm)
140 {
141 return CngCommon.HashData(data, offset, count, hashAlgorithm);
142 }
143
144 protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm)
145 {
146 return CngCommon.HashData(data, hashAlgorithm);
147 }
148
149 protected override bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten)
150 {
151 return CngCommon.TryHashData(source, destination, hashAlgorithm, out bytesWritten);
152 }
153
154 public override void ImportParameters(ECParameters parameters)
155 {
156 parameters.Validate();
158 ECCurve curve = parameters.Curve;
159 bool flag = parameters.D != null;
160 bool flag2 = parameters.Q.X != null && parameters.Q.Y != null;
161 if (curve.IsPrime)
162 {
163 if (!flag2 && flag)
164 {
165 byte[] array = new byte[parameters.D.Length];
166 ECParameters parameters2 = parameters;
167 parameters2.Q.X = array;
168 parameters2.Q.Y = array;
169 byte[] primeCurveBlob = ECCng.GetPrimeCurveBlob(ref parameters2, ecdh: false);
170 ImportFullKeyBlob(primeCurveBlob, includePrivateParameters: true);
171 }
172 else
173 {
174 byte[] primeCurveBlob2 = ECCng.GetPrimeCurveBlob(ref parameters, ecdh: false);
175 ImportFullKeyBlob(primeCurveBlob2, flag);
176 }
177 return;
178 }
179 if (curve.IsNamed)
180 {
181 if (string.IsNullOrEmpty(curve.Oid.FriendlyName))
182 {
184 }
185 if (!flag2 && flag)
186 {
187 byte[] array2 = new byte[parameters.D.Length];
188 ECParameters parameters3 = parameters;
189 parameters3.Q.X = array2;
190 parameters3.Q.Y = array2;
191 byte[] namedCurveBlob = ECCng.GetNamedCurveBlob(ref parameters3, ecdh: false);
192 ImportKeyBlob(namedCurveBlob, curve.Oid.FriendlyName, includePrivateParameters: true);
193 }
194 else
195 {
196 byte[] namedCurveBlob2 = ECCng.GetNamedCurveBlob(ref parameters, ecdh: false);
197 ImportKeyBlob(namedCurveBlob2, curve.Oid.FriendlyName, flag);
198 }
199 return;
200 }
202 }
203
204 public override ECParameters ExportExplicitParameters(bool includePrivateParameters)
205 {
206 byte[] ecBlob = ExportFullKeyBlob(includePrivateParameters);
207 ECParameters ecParams = default(ECParameters);
208 ECCng.ExportPrimeCurveParameters(ref ecParams, ecBlob, includePrivateParameters);
209 return ecParams;
210 }
211
212 public override ECParameters ExportParameters(bool includePrivateParameters)
213 {
214 ECParameters ecParams = default(ECParameters);
215 string oidValue;
216 string curveName = GetCurveName(out oidValue);
217 if (string.IsNullOrEmpty(curveName))
218 {
219 byte[] ecBlob = ExportFullKeyBlob(includePrivateParameters);
220 ECCng.ExportPrimeCurveParameters(ref ecParams, ecBlob, includePrivateParameters);
221 }
222 else
223 {
224 byte[] ecBlob2 = ExportKeyBlob(includePrivateParameters);
225 ECCng.ExportNamedCurveParameters(ref ecParams, ecBlob2, includePrivateParameters);
226 ecParams.Curve = ECCurve.CreateFromOid(new Oid(oidValue, curveName));
227 }
228 return ecParams;
229 }
230
231 public override void ImportPkcs8PrivateKey(ReadOnlySpan<byte> source, out int bytesRead)
232 {
234 int bytesRead2;
236 ProcessPkcs8Response(response);
237 bytesRead = bytesRead2;
238 }
239
240 public override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte> passwordBytes, ReadOnlySpan<byte> source, out int bytesRead)
241 {
243 int bytesRead2;
244 CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead2);
245 ProcessPkcs8Response(response);
246 bytesRead = bytesRead2;
247 }
248
249 public override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<char> password, ReadOnlySpan<byte> source, out int bytesRead)
250 {
252 int bytesRead2;
253 CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead2);
254 ProcessPkcs8Response(response);
255 bytesRead = bytesRead2;
256 }
257
259 {
260 string algorithmGroup = response.GetAlgorithmGroup();
261 if (algorithmGroup == "ECDSA" || algorithmGroup == "ECDH")
262 {
263 AcceptImport(response);
264 return;
265 }
266 response.FreeKey();
268 }
269
270 public override byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte> passwordBytes, PbeParameters pbeParameters)
271 {
272 if (pbeParameters == null)
273 {
274 throw new ArgumentNullException("pbeParameters");
275 }
276 return CngPkcs8.ExportEncryptedPkcs8PrivateKey(this, passwordBytes, pbeParameters);
277 }
278
279 public override byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan<char> password, PbeParameters pbeParameters)
280 {
281 if (pbeParameters == null)
282 {
283 throw new ArgumentNullException("pbeParameters");
284 }
286 if (CngPkcs8.IsPlatformScheme(pbeParameters))
287 {
288 return ExportEncryptedPkcs8(password, pbeParameters.IterationCount);
289 }
290 return CngPkcs8.ExportEncryptedPkcs8PrivateKey(this, password, pbeParameters);
291 }
292
293 public override bool TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte> passwordBytes, PbeParameters pbeParameters, Span<byte> destination, out int bytesWritten)
294 {
295 if (pbeParameters == null)
296 {
297 throw new ArgumentNullException("pbeParameters");
298 }
300 return CngPkcs8.TryExportEncryptedPkcs8PrivateKey(this, passwordBytes, pbeParameters, destination, out bytesWritten);
301 }
302
303 public override bool TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<char> password, PbeParameters pbeParameters, Span<byte> destination, out int bytesWritten)
304 {
305 if (pbeParameters == null)
306 {
307 throw new ArgumentNullException("pbeParameters");
308 }
310 if (CngPkcs8.IsPlatformScheme(pbeParameters))
311 {
312 return TryExportEncryptedPkcs8(password, pbeParameters.IterationCount, destination, out bytesWritten);
313 }
314 return CngPkcs8.TryExportEncryptedPkcs8PrivateKey(this, password, pbeParameters, destination, out bytesWritten);
315 }
316
317 public unsafe override byte[] SignHash(byte[] hash)
318 {
319 if (hash == null)
320 {
321 throw new ArgumentNullException("hash");
322 }
323 int estimatedSize = KeySize switch
324 {
325 256 => 64,
326 384 => 96,
327 521 => 132,
328 _ => KeySize / 4,
329 };
331 return keyHandle.SignHash(hash, global::Interop.NCrypt.AsymmetricPaddingMode.None, null, estimatedSize);
332 }
333
334 public override bool TrySignHash(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten)
335 {
336 return TrySignHashCore(source, destination, DSASignatureFormat.IeeeP1363FixedFieldConcatenation, out bytesWritten);
337 }
338
339 protected unsafe override bool TrySignHashCore(ReadOnlySpan<byte> hash, Span<byte> destination, DSASignatureFormat signatureFormat, out int bytesWritten)
340 {
341 using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
342 {
343 if (!keyHandle.TrySignHash(hash, destination, global::Interop.NCrypt.AsymmetricPaddingMode.None, null, out bytesWritten))
344 {
345 bytesWritten = 0;
346 return false;
347 }
348 }
349 return signatureFormat switch
350 {
351 DSASignatureFormat.IeeeP1363FixedFieldConcatenation => true,
352 DSASignatureFormat.Rfc3279DerSequence => AsymmetricAlgorithmHelpers.TryConvertIeee1363ToDer(destination.Slice(0, bytesWritten), destination, out bytesWritten),
353 _ => throw new CryptographicException(System.SR.Cryptography_UnknownSignatureFormat, signatureFormat.ToString()),
354 };
355 }
356
357 public override bool VerifyHash(byte[] hash, byte[] signature)
358 {
359 if (hash == null)
360 {
361 throw new ArgumentNullException("hash");
362 }
363 if (signature == null)
364 {
365 throw new ArgumentNullException("signature");
366 }
367 return VerifyHashCore(hash, signature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation);
368 }
369
370 public override bool VerifyHash(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature)
371 {
372 return VerifyHashCore(hash, signature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation);
373 }
374
375 protected unsafe override bool VerifyHashCore(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature, DSASignatureFormat signatureFormat)
376 {
377 if (signatureFormat != 0)
378 {
379 signature = this.ConvertSignatureToIeeeP1363(signatureFormat, signature);
380 }
382 return keyHandle.VerifyHash(hash, signature, global::Interop.NCrypt.AsymmetricPaddingMode.None, null);
383 }
384 }
385}
static bool TryConvertIeee1363ToDer(ReadOnlySpan< byte > input, Span< byte > destination, out int bytesWritten)
static byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm)
Definition CngCommon.cs:10
static bool TryHashData(ReadOnlySpan< byte > source, Span< byte > destination, HashAlgorithmName hashAlgorithm, out int bytesWritten)
Definition CngCommon.cs:17
static string Cryptography_CurveNotSupported
Definition SR.cs:64
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string Cryptography_NotValidPublicOrPrivateKey
Definition SR.cs:122
static string Cryptography_UnknownSignatureFormat
Definition SR.cs:156
static string Cryptography_InvalidCurveOid
Definition SR.cs:66
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 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 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 string EcdsaCurveNameToAlgorithm(string algorithm)
Definition ECCng.cs:349
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
override byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan< char > password, PbeParameters pbeParameters)
override ECParameters ExportParameters(bool includePrivateParameters)
override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan< byte > passwordBytes, ReadOnlySpan< byte > source, out int bytesRead)
override bool VerifyHash(byte[] hash, byte[] signature)
override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm)
unsafe override bool TrySignHashCore(ReadOnlySpan< byte > hash, Span< byte > destination, DSASignatureFormat signatureFormat, out int bytesWritten)
override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm)
override byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan< byte > passwordBytes, PbeParameters pbeParameters)
override bool TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan< byte > passwordBytes, PbeParameters pbeParameters, Span< byte > destination, out int bytesWritten)
byte[] ExportEncryptedPkcs8(ReadOnlySpan< char > pkcs8Password, int kdfCount)
override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan< char > password, ReadOnlySpan< byte > source, out int bytesRead)
override void ImportPkcs8PrivateKey(ReadOnlySpan< byte > source, out int bytesRead)
void ImportKeyBlob(byte[] ecKeyBlob, string curveName, bool includePrivateParameters)
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 bool TryHashData(ReadOnlySpan< byte > source, Span< byte > destination, HashAlgorithmName hashAlgorithm, out int bytesWritten)
override bool VerifyHash(ReadOnlySpan< byte > hash, ReadOnlySpan< byte > signature)
void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters)
override bool TrySignHash(ReadOnlySpan< byte > source, Span< byte > destination, out int bytesWritten)
unsafe override bool VerifyHashCore(ReadOnlySpan< byte > hash, ReadOnlySpan< byte > signature, DSASignatureFormat signatureFormat)
override ECParameters ExportExplicitParameters(bool includePrivateParameters)
static void ValidatePbeParameters(PbeParameters pbeParameters, ReadOnlySpan< char > password, ReadOnlySpan< byte > passwordBytes)
static ECCurve CreateFromOid(Oid curveOid)
Definition ECCurve.cs:127