Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
RSACryptoServiceProvider.cs
Go to the documentation of this file.
2using System.IO;
6
8
10{
11 private int _keySize;
12
13 private readonly CspParameters _parameters;
14
15 private readonly bool _randomKeyContainer;
16
18
20
21 private static volatile CspProviderFlags s_useMachineKeyStore;
22
23 private bool _disposed;
24
26 {
27 get
28 {
29 if (_safeProvHandle == null)
30 {
31 lock (_parameters)
32 {
33 if (_safeProvHandle == null)
34 {
36 _safeProvHandle = safeProvHandle;
37 }
38 }
39 return _safeProvHandle;
40 }
41 return _safeProvHandle;
42 }
43 set
44 {
45 lock (_parameters)
46 {
47 SafeProvHandle safeProvHandle = _safeProvHandle;
48 if (value != safeProvHandle)
49 {
50 if (safeProvHandle != null)
51 {
52 SafeKeyHandle safeKeyHandle = _safeKeyHandle;
53 _safeKeyHandle = null;
54 safeKeyHandle?.Dispose();
55 safeProvHandle.Dispose();
56 }
58 }
59 }
60 }
61 }
62
64 {
65 get
66 {
67 if (_safeKeyHandle == null)
68 {
69 lock (_parameters)
70 {
71 if (_safeKeyHandle == null)
72 {
74 _safeKeyHandle = keyPairHelper;
75 }
76 }
77 }
78 return _safeKeyHandle;
79 }
80 set
81 {
82 lock (_parameters)
83 {
84 SafeKeyHandle safeKeyHandle = _safeKeyHandle;
85 if (value != safeKeyHandle)
86 {
88 safeKeyHandle?.Dispose();
89 }
90 }
91 }
92 }
93
94 [SupportedOSPlatform("windows")]
96 {
97 get
98 {
99 SafeKeyHandle safeKeyHandle = SafeKeyHandle;
101 }
102 }
103
104 public override int KeySize
105 {
106 get
107 {
108 byte[] keyParameter = CapiHelper.GetKeyParameter(SafeKeyHandle, 1);
110 return _keySize;
111 }
112 }
113
114 public override KeySizes[] LegalKeySizes => new KeySizes[1]
115 {
116 new KeySizes(384, 16384, 8)
117 };
118
119 public bool PersistKeyInCsp
120 {
121 get
122 {
124 }
125 set
126 {
127 bool persistKeyInCsp = PersistKeyInCsp;
128 if (value != persistKeyInCsp)
129 {
131 }
132 }
133 }
134
135 public bool PublicOnly
136 {
137 get
138 {
139 byte[] keyParameter = CapiHelper.GetKeyParameter(SafeKeyHandle, 2);
140 return keyParameter[0] == 1;
141 }
142 }
143
144 public static bool UseMachineKeyStore
145 {
146 get
147 {
148 return s_useMachineKeyStore == CspProviderFlags.UseMachineKeyStore;
149 }
150 set
151 {
152 s_useMachineKeyStore = (value ? CspProviderFlags.UseMachineKeyStore : CspProviderFlags.NoFlags);
153 }
154 }
155
156 public override string? KeyExchangeAlgorithm
157 {
158 get
159 {
160 if (_parameters.KeyNumber == 1)
161 {
162 return "RSA-PKCS1-KeyEx";
163 }
164 return null;
165 }
166 }
167
168 public override string SignatureAlgorithm => "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
169
171 : this(0, new CspParameters(24, null, null, s_useMachineKeyStore), useDefaultKeySize: true)
172 {
173 }
174
175 public RSACryptoServiceProvider(int dwKeySize)
176 : this(dwKeySize, new CspParameters(24, null, null, s_useMachineKeyStore), useDefaultKeySize: false)
177 {
178 }
179
180 [SupportedOSPlatform("windows")]
181 public RSACryptoServiceProvider(int dwKeySize, CspParameters? parameters)
182 : this(dwKeySize, parameters, useDefaultKeySize: false)
183 {
184 }
185
186 [SupportedOSPlatform("windows")]
188 : this(0, parameters, useDefaultKeySize: true)
189 {
190 }
191
192 private RSACryptoServiceProvider(int keySize, CspParameters parameters, bool useDefaultKeySize)
193 {
194 if (keySize < 0)
195 {
196 throw new ArgumentOutOfRangeException("dwKeySize", "ArgumentOutOfRange_NeedNonNegNum");
197 }
199 _keySize = (useDefaultKeySize ? 1024 : keySize);
201 {
202 SafeKeyHandle safeKeyHandle = SafeKeyHandle;
203 }
204 }
205
206 public byte[] Decrypt(byte[] rgb, bool fOAEP)
207 {
208 if (rgb == null)
209 {
210 throw new ArgumentNullException("rgb");
211 }
212 int keySize = KeySize;
213 if (rgb.Length != keySize / 8)
214 {
216 }
217 CapiHelper.DecryptKey(SafeKeyHandle, rgb, rgb.Length, fOAEP, out var decryptedData);
218 return decryptedData;
219 }
220
221 public override byte[] DecryptValue(byte[] rgb)
222 {
223 return base.DecryptValue(rgb);
224 }
225
226 protected override void Dispose(bool disposing)
227 {
228 if (disposing)
229 {
230 if (_safeKeyHandle != null && !_safeKeyHandle.IsClosed)
231 {
233 }
235 {
237 }
238 _disposed = true;
239 }
240 }
241
242 public byte[] Encrypt(byte[] rgb, bool fOAEP)
243 {
244 if (rgb == null)
245 {
246 throw new ArgumentNullException("rgb");
247 }
248 if (fOAEP)
249 {
250 int num = (KeySize + 7) / 8;
251 if (num - 42 < rgb.Length)
252 {
253 throw (-2146893820).ToCryptographicException();
254 }
255 }
256 byte[] pbEncryptedKey = null;
257 CapiHelper.EncryptKey(SafeKeyHandle, rgb, rgb.Length, fOAEP, ref pbEncryptedKey);
258 return pbEncryptedKey;
259 }
260
261 public override byte[] EncryptValue(byte[] rgb)
262 {
263 return base.EncryptValue(rgb);
264 }
265
266 public byte[] ExportCspBlob(bool includePrivateParameters)
267 {
268 return CapiHelper.ExportKeyBlob(includePrivateParameters, SafeKeyHandle);
269 }
270
271 public override RSAParameters ExportParameters(bool includePrivateParameters)
272 {
273 byte[] cspBlob = ExportCspBlob(includePrivateParameters);
274 return cspBlob.ToRSAParameters(includePrivateParameters);
275 }
276
278 {
279 CapiHelper.AcquireCsp(new CspParameters(24), out var safeProvHandle);
280 return safeProvHandle;
281 }
282
283 public void ImportCspBlob(byte[] keyBlob)
284 {
286 SafeKeyHandle safeKeyHandle;
287 if (IsPublic(keyBlob))
288 {
289 SafeProvHandle safeProvHandle = AcquireSafeProviderHandle();
290 CapiHelper.ImportKeyBlob(safeProvHandle, CspProviderFlags.NoFlags, addNoSaltFlag: false, keyBlob, out safeKeyHandle);
291 SafeProvHandle = safeProvHandle;
292 }
293 else
294 {
295 CapiHelper.ImportKeyBlob(SafeProvHandle, _parameters.Flags, addNoSaltFlag: false, keyBlob, out safeKeyHandle);
296 }
297 SafeKeyHandle = safeKeyHandle;
298 }
299
300 public override void ImportParameters(RSAParameters parameters)
301 {
302 byte[] keyBlob = parameters.ToKeyBlob();
303 ImportCspBlob(keyBlob);
304 }
305
306 public override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte> passwordBytes, ReadOnlySpan<byte> source, out int bytesRead)
307 {
309 base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
310 }
311
312 public override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<char> password, ReadOnlySpan<byte> source, out int bytesRead)
313 {
315 base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
316 }
317
318 public byte[] SignData(byte[] buffer, int offset, int count, object halg)
319 {
320 int calgHash = CapiHelper.ObjToHashAlgId(halg);
321 HashAlgorithm hashAlgorithm = CapiHelper.ObjToHashAlgorithm(halg);
322 byte[] rgbHash = hashAlgorithm.ComputeHash(buffer, offset, count);
323 return SignHash(rgbHash, calgHash);
324 }
325
326 public byte[] SignData(byte[] buffer, object halg)
327 {
328 int calgHash = CapiHelper.ObjToHashAlgId(halg);
329 HashAlgorithm hashAlgorithm = CapiHelper.ObjToHashAlgorithm(halg);
330 byte[] rgbHash = hashAlgorithm.ComputeHash(buffer);
331 return SignHash(rgbHash, calgHash);
332 }
333
334 public byte[] SignData(Stream inputStream, object halg)
335 {
336 int calgHash = CapiHelper.ObjToHashAlgId(halg);
337 HashAlgorithm hashAlgorithm = CapiHelper.ObjToHashAlgorithm(halg);
338 byte[] rgbHash = hashAlgorithm.ComputeHash(inputStream);
339 return SignHash(rgbHash, calgHash);
340 }
341
342 public byte[] SignHash(byte[] rgbHash, string? str)
343 {
344 if (rgbHash == null)
345 {
346 throw new ArgumentNullException("rgbHash");
347 }
348 if (PublicOnly)
349 {
351 }
352 int calgHash = CapiHelper.NameOrOidToHashAlgId(str, OidGroup.HashAlgorithm);
353 return SignHash(rgbHash, calgHash);
354 }
355
356 private byte[] SignHash(byte[] rgbHash, int calgHash)
357 {
358 return CapiHelper.SignValue(SafeProvHandle, SafeKeyHandle, _parameters.KeyNumber, 9216, calgHash, rgbHash);
359 }
360
361 public bool VerifyData(byte[] buffer, object halg, byte[] signature)
362 {
363 int calgHash = CapiHelper.ObjToHashAlgId(halg);
364 HashAlgorithm hashAlgorithm = CapiHelper.ObjToHashAlgorithm(halg);
365 byte[] rgbHash = hashAlgorithm.ComputeHash(buffer);
366 return VerifyHash(rgbHash, calgHash, signature);
367 }
368
369 public bool VerifyHash(byte[] rgbHash, string str, byte[] rgbSignature)
370 {
371 if (rgbHash == null)
372 {
373 throw new ArgumentNullException("rgbHash");
374 }
375 if (rgbSignature == null)
376 {
377 throw new ArgumentNullException("rgbSignature");
378 }
379 int calgHash = CapiHelper.NameOrOidToHashAlgId(str, OidGroup.HashAlgorithm);
380 return VerifyHash(rgbHash, calgHash, rgbSignature);
381 }
382
383 private bool VerifyHash(byte[] rgbHash, int calgHash, byte[] rgbSignature)
384 {
385 return CapiHelper.VerifySign(SafeProvHandle, SafeKeyHandle, 9216, calgHash, rgbHash, rgbSignature);
386 }
387
388 private static bool IsPublic(byte[] keyBlob)
389 {
390 if (keyBlob == null)
391 {
392 throw new ArgumentNullException("keyBlob");
393 }
394 if (keyBlob[0] != 6)
395 {
396 return false;
397 }
398 if (keyBlob[11] != 49 || keyBlob[10] != 65 || keyBlob[9] != 83 || keyBlob[8] != 82)
399 {
400 return false;
401 }
402 return true;
403 }
404
405 protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm)
406 {
407 using HashAlgorithm hashAlgorithm2 = GetHashAlgorithm(hashAlgorithm);
408 return hashAlgorithm2.ComputeHash(data, offset, count);
409 }
410
411 protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm)
412 {
413 using HashAlgorithm hashAlgorithm2 = GetHashAlgorithm(hashAlgorithm);
414 return hashAlgorithm2.ComputeHash(data);
415 }
416
418 {
419 return hashAlgorithm.Name switch
420 {
421 "MD5" => MD5.Create(),
422 "SHA1" => SHA1.Create(),
423 "SHA256" => SHA256.Create(),
424 "SHA384" => SHA384.Create(),
425 "SHA512" => SHA512.Create(),
427 };
428 }
429
430 private static int GetAlgorithmId(HashAlgorithmName hashAlgorithm)
431 {
432 return hashAlgorithm.Name switch
433 {
434 "MD5" => 32771,
435 "SHA1" => 32772,
436 "SHA256" => 32780,
437 "SHA384" => 32781,
438 "SHA512" => 32782,
440 };
441 }
442
443 public override byte[] Encrypt(byte[] data, RSAEncryptionPadding padding)
444 {
445 if (data == null)
446 {
447 throw new ArgumentNullException("data");
448 }
449 if (padding == null)
450 {
451 throw new ArgumentNullException("padding");
452 }
453 if (padding == RSAEncryptionPadding.Pkcs1)
454 {
455 return Encrypt(data, fOAEP: false);
456 }
457 if (padding == RSAEncryptionPadding.OaepSHA1)
458 {
459 return Encrypt(data, fOAEP: true);
460 }
462 }
463
464 public override byte[] Decrypt(byte[] data, RSAEncryptionPadding padding)
465 {
466 if (data == null)
467 {
468 throw new ArgumentNullException("data");
469 }
470 if (padding == null)
471 {
472 throw new ArgumentNullException("padding");
473 }
474 if (padding == RSAEncryptionPadding.Pkcs1)
475 {
476 return Decrypt(data, fOAEP: false);
477 }
478 if (padding == RSAEncryptionPadding.OaepSHA1)
479 {
480 return Decrypt(data, fOAEP: true);
481 }
483 }
484
485 public override byte[] SignHash(byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
486 {
487 if (hash == null)
488 {
489 throw new ArgumentNullException("hash");
490 }
491 if (string.IsNullOrEmpty(hashAlgorithm.Name))
492 {
494 }
495 if (padding == null)
496 {
497 throw new ArgumentNullException("padding");
498 }
499 if (padding != RSASignaturePadding.Pkcs1)
500 {
502 }
503 return SignHash(hash, GetAlgorithmId(hashAlgorithm));
504 }
505
506 public override bool VerifyHash(byte[] hash, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
507 {
508 if (hash == null)
509 {
510 throw new ArgumentNullException("hash");
511 }
512 if (signature == null)
513 {
514 throw new ArgumentNullException("signature");
515 }
516 if (string.IsNullOrEmpty(hashAlgorithm.Name))
517 {
519 }
520 if (padding == null)
521 {
522 throw new ArgumentNullException("padding");
523 }
524 if (padding != RSASignaturePadding.Pkcs1)
525 {
527 }
528 return VerifyHash(hash, GetAlgorithmId(hashAlgorithm), signature);
529 }
530
535
540
541 private void ThrowIfDisposed()
542 {
543 if (_disposed)
544 {
545 throw new ObjectDisposedException("DSACryptoServiceProvider");
546 }
547 }
548}
static void AcquireCsp(CspParameters cspParameters, out SafeProvHandle safeProvHandle)
static SafeKeyHandle GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, int keySize, SafeProvHandle safeProvHandle)
static bool GetPersistKeyInCsp(SafeProvHandle safeProvHandle)
static void SetPersistKeyInCsp(SafeProvHandle safeProvHandle, bool fPersistKeyInCsp)
static SafeProvHandle CreateProvHandle(CspParameters parameters, bool randomKeyContainer)
static int ObjToHashAlgId(object hashAlg)
static CspParameters SaveCspParameters(CspAlgorithmType keyType, CspParameters userParameters, CspProviderFlags defaultFlags, out bool randomKeyContainer)
static int NameOrOidToHashAlgId(string nameOrOid, OidGroup oidGroup)
static void DecryptKey(SafeKeyHandle safeKeyHandle, byte[] encryptedData, int encryptedDataLength, bool fOAEP, out byte[] decryptedData)
static void ImportKeyBlob(SafeProvHandle saveProvHandle, CspProviderFlags flags, bool addNoSaltFlag, byte[] keyBlob, out SafeKeyHandle safeKeyHandle)
static byte[] SignValue(SafeProvHandle hProv, SafeKeyHandle hKey, int keyNumber, int calgKey, int calgHash, byte[] hash)
static void EncryptKey(SafeKeyHandle safeKeyHandle, byte[] pbKey, int cbKey, bool foep, [NotNull] ref byte[] pbEncryptedKey)
static HashAlgorithm ObjToHashAlgorithm(object hashAlg)
static byte[] ExportKeyBlob(bool includePrivateParameters, SafeKeyHandle safeKeyHandle)
static byte[] GetKeyParameter(SafeKeyHandle safeKeyHandle, int keyParam)
static bool VerifySign(SafeProvHandle hProv, SafeKeyHandle hKey, int calgKey, int calgHash, byte[] hash, byte[] signature)
static int ReadInt32LittleEndian(ReadOnlySpan< byte > source)
static string Cryptography_RSA_DecryptWrongSize
Definition SR.cs:138
static string Cryptography_UnknownHashAlgorithm
Definition SR.cs:152
static string Cryptography_CSP_NoPrivateKey
Definition SR.cs:48
static string Cryptography_InvalidPaddingMode
Definition SR.cs:46
static string Cryptography_HashAlgorithmNameNullOrEmpty
Definition SR.cs:60
Definition SR.cs:7
static new MD5 Create()
Definition MD5.cs:57
RSACryptoServiceProvider(int keySize, CspParameters parameters, bool useDefaultKeySize)
override byte[] SignHash(byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
static HashAlgorithm GetHashAlgorithm(HashAlgorithmName hashAlgorithm)
byte[] SignData(byte[] buffer, int offset, int count, object halg)
override bool VerifyHash(byte[] hash, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
bool VerifyData(byte[] buffer, object halg, byte[] signature)
override byte[] Encrypt(byte[] data, RSAEncryptionPadding padding)
RSACryptoServiceProvider(int dwKeySize, CspParameters? parameters)
override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm)
override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm)
override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan< char > password, ReadOnlySpan< byte > source, out int bytesRead)
override void ImportEncryptedPkcs8PrivateKey(ReadOnlySpan< byte > passwordBytes, ReadOnlySpan< byte > source, out int bytesRead)
override RSAParameters ExportParameters(bool includePrivateParameters)
bool VerifyHash(byte[] rgbHash, string str, byte[] rgbSignature)
bool VerifyHash(byte[] rgbHash, int calgHash, byte[] rgbSignature)
override byte[] Decrypt(byte[] data, RSAEncryptionPadding padding)
static int GetAlgorithmId(HashAlgorithmName hashAlgorithm)
static new SHA1 Create()
Definition SHA1.cs:55
static new SHA256 Create()
Definition SHA256.cs:55
static new SHA384 Create()
Definition SHA384.cs:55
static new SHA512 Create()
Definition SHA512.cs:55
override void Dispose(bool disposing)
override void Dispose(bool disposing)