Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
CapiHelper.cs
Go to the documentation of this file.
1using System;
4using System.IO;
7using System.Text;
10
11namespace Internal.NativeCrypto;
12
13internal static class CapiHelper
14{
16 {
17 KP_IV = 1,
18 KP_MODE = 4,
19 KP_MODE_BITS = 5,
21 KP_KEYLEN = 9,
22 KP_ALGID = 7
23 }
24
25 internal enum CspAlgorithmType
26 {
27 Rsa,
28 Dss
29 }
30
31 private static ReadOnlySpan<byte> RgbPubKey => new byte[84]
32 {
33 6, 2, 0, 0, 0, 164, 0, 0, 82, 83,
34 65, 49, 0, 2, 0, 0, 1, 0, 0, 0,
35 171, 239, 250, 198, 125, 232, 222, 251, 104, 56,
36 9, 146, 217, 66, 126, 107, 137, 158, 33, 215,
37 82, 28, 153, 60, 23, 72, 78, 58, 68, 2,
38 242, 250, 116, 87, 218, 228, 211, 192, 53, 103,
39 250, 110, 223, 120, 76, 117, 53, 28, 160, 116,
40 73, 227, 32, 19, 113, 53, 101, 223, 18, 32,
41 245, 245, 245, 193
42 };
43
44 internal static byte[] ToKeyBlob(this DSAParameters dsaParameters)
45 {
46 if (dsaParameters.P == null || dsaParameters.P.Length == 0 || dsaParameters.Q == null || dsaParameters.Q.Length != 20)
47 {
48 throw GetBadDataException();
49 }
50 if (dsaParameters.G == null || dsaParameters.G.Length != dsaParameters.P.Length)
51 {
52 throw GetBadDataException();
53 }
54 if (dsaParameters.J != null && dsaParameters.J.Length >= dsaParameters.P.Length)
55 {
56 throw GetBadDataException();
57 }
58 if (dsaParameters.Y != null && dsaParameters.Y.Length != dsaParameters.P.Length)
59 {
60 throw GetBadDataException();
61 }
62 if (dsaParameters.Seed != null && dsaParameters.Seed.Length != 20)
63 {
64 throw GetBadDataException();
65 }
66 bool flag = dsaParameters.X != null && dsaParameters.X.Length != 0;
67 if (flag && dsaParameters.X.Length != 20)
68 {
69 throw GetBadDataException();
70 }
71 uint value = (uint)(dsaParameters.P.Length * 8);
72 uint num = ((dsaParameters.J != null) ? ((uint)(dsaParameters.J.Length * 8)) : 0u);
73 using MemoryStream memoryStream = new MemoryStream();
74 using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
75 WriteKeyBlobHeader(dsaParameters, binaryWriter, flag, out var isV);
76 if (isV)
77 {
78 binaryWriter.Write(flag ? 877876036 : 861098820);
79 binaryWriter.Write(value);
80 binaryWriter.Write((uint)(dsaParameters.Q.Length * 8));
81 binaryWriter.Write(num);
82 if (flag)
83 {
84 binaryWriter.Write((uint)(dsaParameters.X.Length * 8));
85 }
86 WriteDSSSeed(dsaParameters, binaryWriter);
87 binaryWriter.WriteReversed(dsaParameters.P);
88 binaryWriter.WriteReversed(dsaParameters.Q);
89 binaryWriter.WriteReversed(dsaParameters.G);
90 if (num != 0)
91 {
92 binaryWriter.WriteReversed(dsaParameters.J);
93 }
94 binaryWriter.WriteReversed(dsaParameters.Y);
95 if (flag)
96 {
97 binaryWriter.WriteReversed(dsaParameters.X);
98 }
99 }
100 else
101 {
102 binaryWriter.Write(flag ? 844321604 : 827544388);
103 binaryWriter.Write(value);
104 binaryWriter.WriteReversed(dsaParameters.P);
105 binaryWriter.WriteReversed(dsaParameters.Q);
106 binaryWriter.WriteReversed(dsaParameters.G);
107 if (flag)
108 {
109 binaryWriter.WriteReversed(dsaParameters.X);
110 }
111 else
112 {
113 binaryWriter.WriteReversed(dsaParameters.Y);
114 }
115 WriteDSSSeed(dsaParameters, binaryWriter);
116 }
117 binaryWriter.Flush();
118 return memoryStream.ToArray();
119 }
120
121 internal static DSAParameters ToDSAParameters(this byte[] cspBlob, bool includePrivateParameters, byte[] cspPublicBlob)
122 {
123 try
124 {
125 using MemoryStream input = new MemoryStream(cspBlob);
126 using BinaryReader binaryReader = new BinaryReader(input);
127 ReadKeyBlobHeader(binaryReader, out var bVersion);
128 DSAParameters dSAParameters = default(DSAParameters);
129 if (bVersion > 2)
130 {
131 binaryReader.ReadInt32();
132 int count = (binaryReader.ReadInt32() + 7) / 8;
133 int count2 = (binaryReader.ReadInt32() + 7) / 8;
134 int num = (binaryReader.ReadInt32() + 7) / 8;
135 int count3 = 0;
136 if (includePrivateParameters)
137 {
138 count3 = (binaryReader.ReadInt32() + 7) / 8;
139 }
140 ReadDSSSeed(dSAParameters, binaryReader, isV3: true);
141 dSAParameters.P = binaryReader.ReadReversed(count);
142 dSAParameters.Q = binaryReader.ReadReversed(count2);
143 dSAParameters.G = binaryReader.ReadReversed(count);
144 if (num > 0)
145 {
146 dSAParameters.J = binaryReader.ReadReversed(num);
147 }
148 dSAParameters.Y = binaryReader.ReadReversed(count);
149 if (includePrivateParameters)
150 {
151 dSAParameters.X = binaryReader.ReadReversed(count3);
152 }
153 }
154 else
155 {
156 binaryReader.ReadInt32();
157 int count4 = (binaryReader.ReadInt32() + 7) / 8;
158 dSAParameters.P = binaryReader.ReadReversed(count4);
159 dSAParameters.Q = binaryReader.ReadReversed(20);
160 dSAParameters.G = binaryReader.ReadReversed(count4);
161 long position = 0L;
162 if (includePrivateParameters)
163 {
164 position = binaryReader.BaseStream.Position;
165 dSAParameters.X = binaryReader.ReadReversed(20);
166 }
167 else
168 {
169 dSAParameters.Y = binaryReader.ReadReversed(count4);
170 }
171 ReadDSSSeed(dSAParameters, binaryReader, isV3: false);
172 if (includePrivateParameters)
173 {
174 if (cspPublicBlob == null)
175 {
177 }
178 using MemoryStream input2 = new MemoryStream(cspPublicBlob);
179 using BinaryReader binaryReader2 = new BinaryReader(input2);
180 binaryReader2.BaseStream.Position = position;
181 dSAParameters.Y = binaryReader2.ReadReversed(count4);
182 }
183 }
184 return dSAParameters;
185 }
187 {
188 throw GetEFailException();
189 }
190 }
191
192 private static void ReadKeyBlobHeader(BinaryReader br, out byte bVersion)
193 {
194 br.ReadByte();
195 bVersion = br.ReadByte();
196 br.BaseStream.Position += 2L;
197 int num = br.ReadInt32();
198 if (num != 8704)
199 {
201 }
202 }
203
204 private static void WriteKeyBlobHeader(DSAParameters dsaParameters, BinaryWriter bw, bool isPrivate, out bool isV3)
205 {
206 isV3 = false;
207 byte value = 2;
208 if ((dsaParameters.Y != null && isPrivate) || (dsaParameters.Y != null && dsaParameters.J != null))
209 {
210 isV3 = true;
211 value = 3;
212 }
213 bw.Write((byte)(isPrivate ? 7u : 6u));
214 bw.Write(value);
215 bw.Write((ushort)0);
216 bw.Write(8704);
217 }
218
219 private static void ReadDSSSeed(DSAParameters dsaParameters, BinaryReader br, bool isV3)
220 {
221 bool flag = false;
222 int num = br.ReadInt32();
223 if ((!isV3) ? (num > 0) : (num != -1))
224 {
225 dsaParameters.Counter = num;
226 dsaParameters.Seed = br.ReadReversed(20);
227 }
228 else
229 {
230 dsaParameters.Counter = 0;
231 dsaParameters.Seed = null;
232 br.BaseStream.Position += 20L;
233 }
234 }
235
236 private static void WriteDSSSeed(DSAParameters dsaParameters, BinaryWriter bw)
237 {
238 if (dsaParameters.Seed == null || dsaParameters.Seed.Length == 0)
239 {
240 bw.Write(uint.MaxValue);
241 for (int i = 0; i < 20; i += 4)
242 {
243 bw.Write(uint.MaxValue);
244 }
245 }
246 else
247 {
248 bw.Write(dsaParameters.Counter);
249 bw.WriteReversed(dsaParameters.Seed);
250 }
251 }
252
253 internal static byte[] ToKeyBlob(this RSAParameters rsaParameters)
254 {
255 if (rsaParameters.Modulus == null)
256 {
257 throw GetBadDataException();
258 }
259 if (rsaParameters.Exponent == null || rsaParameters.Exponent.Length > 4)
260 {
261 throw GetBadDataException();
262 }
263 int num = rsaParameters.Modulus.Length;
264 int num2 = (num + 1) / 2;
265 if (rsaParameters.P != null)
266 {
267 if (rsaParameters.P.Length != num2)
268 {
269 throw GetBadDataException();
270 }
271 if (rsaParameters.Q == null || rsaParameters.Q.Length != num2)
272 {
273 throw GetBadDataException();
274 }
275 if (rsaParameters.DP == null || rsaParameters.DP.Length != num2)
276 {
277 throw GetBadDataException();
278 }
279 if (rsaParameters.DQ == null || rsaParameters.DQ.Length != num2)
280 {
281 throw GetBadDataException();
282 }
283 if (rsaParameters.InverseQ == null || rsaParameters.InverseQ.Length != num2)
284 {
285 throw GetBadDataException();
286 }
287 if (rsaParameters.D == null || rsaParameters.D.Length != num)
288 {
289 throw GetBadDataException();
290 }
291 }
292 bool flag = rsaParameters.P != null && rsaParameters.P.Length != 0;
293 MemoryStream memoryStream = new MemoryStream();
294 BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
295 binaryWriter.Write((byte)(flag ? 7u : 6u));
296 binaryWriter.Write((byte)2);
297 binaryWriter.Write((ushort)0);
298 binaryWriter.Write(41984u);
299 binaryWriter.Write(flag ? 843141970 : 826364754);
300 binaryWriter.Write((uint)(num * 8));
301 uint num3 = 0u;
302 for (int i = 0; i < rsaParameters.Exponent.Length; i++)
303 {
304 num3 <<= 8;
305 num3 |= rsaParameters.Exponent[i];
306 }
307 binaryWriter.Write(num3);
308 binaryWriter.WriteReversed(rsaParameters.Modulus);
309 if (flag)
310 {
311 binaryWriter.WriteReversed(rsaParameters.P);
312 binaryWriter.WriteReversed(rsaParameters.Q);
313 binaryWriter.WriteReversed(rsaParameters.DP);
314 binaryWriter.WriteReversed(rsaParameters.DQ);
315 binaryWriter.WriteReversed(rsaParameters.InverseQ);
316 binaryWriter.WriteReversed(rsaParameters.D);
317 }
318 binaryWriter.Flush();
319 return memoryStream.ToArray();
320 }
321
322 private static void WriteReversed(this BinaryWriter bw, byte[] bytes)
323 {
324 byte[] array = bytes.CloneByteArray();
326 bw.Write(array);
327 }
328
329 internal static RSAParameters ToRSAParameters(this byte[] cspBlob, bool includePrivateParameters)
330 {
331 try
332 {
333 BinaryReader binaryReader = new BinaryReader(new MemoryStream(cspBlob));
334 binaryReader.ReadByte();
335 binaryReader.ReadByte();
336 binaryReader.ReadUInt16();
337 int num = binaryReader.ReadInt32();
338 if (num != 41984 && num != 9216)
339 {
341 }
342 binaryReader.ReadInt32();
343 int num2 = binaryReader.ReadInt32();
344 int num3 = num2 / 8;
345 int count = (num3 + 1) / 2;
346 uint exponent = binaryReader.ReadUInt32();
347 RSAParameters result = default(RSAParameters);
348 result.Exponent = ExponentAsBytes(exponent);
349 result.Modulus = binaryReader.ReadReversed(num3);
350 if (includePrivateParameters)
351 {
352 result.P = binaryReader.ReadReversed(count);
353 result.Q = binaryReader.ReadReversed(count);
354 result.DP = binaryReader.ReadReversed(count);
355 result.DQ = binaryReader.ReadReversed(count);
356 result.InverseQ = binaryReader.ReadReversed(count);
357 result.D = binaryReader.ReadReversed(num3);
358 }
359 return result;
360 }
362 {
363 throw GetEFailException();
364 }
365 }
366
367 internal static byte GetKeyBlobHeaderVersion(byte[] cspBlob)
368 {
369 if (cspBlob.Length < 8)
370 {
371 throw new EndOfStreamException();
372 }
373 return cspBlob[1];
374 }
375
376 private static byte[] ExponentAsBytes(uint exponent)
377 {
378 if (exponent > 255)
379 {
380 if (exponent > 65535)
381 {
382 if (exponent > 16777215)
383 {
384 return new byte[4]
385 {
386 (byte)(exponent >> 24),
387 (byte)(exponent >> 16),
388 (byte)(exponent >> 8),
389 (byte)exponent
390 };
391 }
392 return new byte[3]
393 {
394 (byte)(exponent >> 16),
395 (byte)(exponent >> 8),
396 (byte)exponent
397 };
398 }
399 return new byte[2]
400 {
401 (byte)(exponent >> 8),
402 (byte)exponent
403 };
404 }
405 return new byte[1] { (byte)exponent };
406 }
407
408 private static byte[] ReadReversed(this BinaryReader br, int count)
409 {
410 byte[] array = br.ReadBytes(count);
412 return array;
413 }
414
415 public static string UpgradeDSS(int dwProvType, string wszProvider)
416 {
417 string result = null;
418 if (string.Equals(wszProvider, "Microsoft Base DSS and Diffie-Hellman Cryptographic Provider", StringComparison.Ordinal))
419 {
420 if (AcquireCryptContext(out var safeProvHandle, null, "Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider", dwProvType, 4026531840u) == 0)
421 {
422 result = "Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider";
423 }
424 safeProvHandle.Dispose();
425 }
426 return result;
427 }
428
429 private static void ReverseDsaSignature(byte[] signature, int cbSignature)
430 {
431 if (cbSignature != 40)
432 {
434 }
435 Array.Reverse(signature, 0, 20);
436 Array.Reverse(signature, 20, 20);
437 }
438
439 public static string UpgradeRSA(int dwProvType, string wszProvider)
440 {
441 bool flag = string.Equals(wszProvider, "Microsoft Enhanced Cryptographic Provider v1.0", StringComparison.Ordinal);
442 bool flag2 = string.Equals(wszProvider, "Microsoft Base Cryptographic Provider v1.0", StringComparison.Ordinal);
443 string result = null;
444 if (flag2 || flag)
445 {
446 if (AcquireCryptContext(out var safeProvHandle, null, "Microsoft Enhanced RSA and AES Cryptographic Provider", dwProvType, 4026531840u) == 0)
447 {
448 result = "Microsoft Enhanced RSA and AES Cryptographic Provider";
449 }
450 safeProvHandle.Dispose();
451 }
452 return result;
453 }
454
455 internal static string GetDefaultProvider(int dwType)
456 {
457 int pcbProvName = 0;
458 if (!global::Interop.Advapi32.CryptGetDefaultProvider(dwType, IntPtr.Zero, global::Interop.Advapi32.GetDefaultProviderFlags.CRYPT_MACHINE_DEFAULT, null, ref pcbProvName))
459 {
460 throw GetErrorCode().ToCryptographicException();
461 }
462 StringBuilder stringBuilder = new StringBuilder(pcbProvName);
463 if (!global::Interop.Advapi32.CryptGetDefaultProvider(dwType, IntPtr.Zero, global::Interop.Advapi32.GetDefaultProviderFlags.CRYPT_MACHINE_DEFAULT, stringBuilder, ref pcbProvName))
464 {
465 throw GetErrorCode().ToCryptographicException();
466 }
467 string text = stringBuilder.ToString();
468 string text2 = null;
469 switch (dwType)
470 {
471 case 1:
472 text2 = UpgradeRSA(dwType, text);
473 break;
474 case 13:
475 text2 = UpgradeDSS(dwType, text);
476 break;
477 }
478 if (text2 == null)
479 {
480 return text;
481 }
482 return text2;
483 }
484
485 private static void CreateCSP(CspParameters parameters, bool randomKeyContainer, out SafeProvHandle safeProvHandle)
486 {
487 uint num = 8u;
488 if (randomKeyContainer)
489 {
490 num |= 0xF0000000u;
491 }
492 SafeProvHandle safeProvHandle2;
493 int num2 = OpenCSP(parameters, num, out safeProvHandle2);
494 if (num2 != 0)
495 {
496 safeProvHandle2.Dispose();
497 throw num2.ToCryptographicException();
498 }
499 safeProvHandle = safeProvHandle2;
500 }
501
502 private static int AcquireCryptContext(out SafeProvHandle safeProvHandle, string keyContainer, string providerName, int providerType, uint flags)
503 {
504 int result = 0;
505 if ((flags & 0xF0000000u) == 4026531840u && (flags & 0x20) == 32)
506 {
507 flags &= 0xFFFFFFDFu;
508 }
509 if (!global::Interop.Advapi32.CryptAcquireContext(out safeProvHandle, keyContainer, providerName, providerType, flags))
510 {
511 result = GetErrorCode();
512 }
513 return result;
514 }
515
516 internal static void AcquireCsp(CspParameters cspParameters, out SafeProvHandle safeProvHandle)
517 {
518 SafeProvHandle safeProvHandle2;
519 int num = OpenCSP(cspParameters, 4026531840u, out safeProvHandle2);
520 if (num != 0)
521 {
522 safeProvHandle2.Dispose();
523 throw num.ToCryptographicException();
524 }
525 safeProvHandle = safeProvHandle2;
526 }
527
528 public static int OpenCSP(CspParameters cspParameters, uint flags, out SafeProvHandle safeProvHandle)
529 {
530 string text = null;
531 if (cspParameters == null)
532 {
533 throw new ArgumentException(System.SR.Format(System.SR.CspParameter_invalid, "cspParameters"));
534 }
535 int providerType = cspParameters.ProviderType;
536 string providerName = ((cspParameters.ProviderName != null) ? cspParameters.ProviderName : (cspParameters.ProviderName = GetDefaultProvider(providerType)));
537 int flags2 = (int)cspParameters.Flags;
538 if (!IsFlagBitSet((uint)flags2, 2u) && cspParameters.KeyContainerName != null)
539 {
540 text = cspParameters.KeyContainerName;
541 }
542 flags |= MapCspProviderFlags((int)cspParameters.Flags);
543 SafeProvHandle safeProvHandle2;
544 int num = AcquireCryptContext(out safeProvHandle2, text, providerName, providerType, flags);
545 if (num != 0)
546 {
547 safeProvHandle2.Dispose();
548 safeProvHandle = SafeProvHandle.InvalidHandle;
549 return num;
550 }
551 safeProvHandle2.ContainerName = text;
552 safeProvHandle2.ProviderName = providerName;
553 safeProvHandle2.Types = providerType;
554 safeProvHandle2.Flags = flags;
555 if (IsFlagBitSet(flags, 4026531840u))
556 {
557 safeProvHandle2.PersistKeyInCsp = false;
558 }
559 safeProvHandle = safeProvHandle2;
560 return 0;
561 }
562
563 internal static SafeProvHandle CreateProvHandle(CspParameters parameters, bool randomKeyContainer)
564 {
565 uint flags = 0u;
566 SafeProvHandle safeProvHandle;
567 uint num = (uint)OpenCSP(parameters, flags, out safeProvHandle);
568 if (num != 0)
569 {
570 safeProvHandle.Dispose();
571 if (IsFlagBitSet((uint)parameters.Flags, 8u) || (num != 2148073497u && num != 2148073494u && num != 2147942402u))
572 {
573 throw ((int)num).ToCryptographicException();
574 }
575 CreateCSP(parameters, randomKeyContainer, out safeProvHandle);
576 }
577 if (parameters.ParentWindowHandle != IntPtr.Zero)
578 {
579 IntPtr pbData = parameters.ParentWindowHandle;
580 if (!global::Interop.Advapi32.CryptSetProvParam(safeProvHandle, global::Interop.Advapi32.CryptProvParam.PP_CLIENT_HWND, ref pbData, 0))
581 {
582 throw GetErrorCode().ToCryptographicException();
583 }
584 }
585 if (parameters.KeyPassword != null)
586 {
588 try
589 {
590 global::Interop.Advapi32.CryptProvParam dwParam = ((parameters.KeyNumber == 2) ? global::Interop.Advapi32.CryptProvParam.PP_SIGNATURE_PIN : global::Interop.Advapi32.CryptProvParam.PP_KEYEXCHANGE_PIN);
591 if (!global::Interop.Advapi32.CryptSetProvParam(safeProvHandle, dwParam, intPtr, 0))
592 {
593 throw GetErrorCode().ToCryptographicException();
594 }
595 }
596 finally
597 {
598 if (intPtr != IntPtr.Zero)
599 {
601 }
602 }
603 }
604 return safeProvHandle;
605 }
606
607 internal static bool IsFlagBitSet(uint dwImp, uint flag)
608 {
609 return (dwImp & flag) == flag;
610 }
611
612 internal static int GetProviderParameterWorker(SafeProvHandle safeProvHandle, byte[] impType, ref int cb, global::Interop.Advapi32.CryptProvParam flags)
613 {
614 int result = 0;
615 if (!global::Interop.Advapi32.CryptGetProvParam(safeProvHandle, flags, impType, ref cb))
616 {
617 throw GetErrorCode().ToCryptographicException();
618 }
619 if (impType != null && cb == 4)
620 {
621 result = BitConverter.ToInt32(impType, 0);
622 }
623 return result;
624 }
625
626 public static object GetProviderParameter(SafeProvHandle safeProvHandle, int keyNumber, int keyParam)
627 {
628 VerifyValidHandle(safeProvHandle);
629 byte[] impType = new byte[4];
630 int cb = 4;
631 SafeKeyHandle safeKeyHandle = SafeKeyHandle.InvalidHandle;
632 int num = 0;
633 int num2 = 0;
634 bool flag = false;
635 string result = null;
636 try
637 {
638 switch (keyParam)
639 {
640 case 3:
641 num = GetProviderParameterWorker(safeProvHandle, impType, ref cb, global::Interop.Advapi32.CryptProvParam.PP_IMPTYPE);
642 if (!IsFlagBitSet((uint)num, 1u))
643 {
644 if (!CryptGetUserKey(safeProvHandle, keyNumber, out safeKeyHandle))
645 {
646 throw GetErrorCode().ToCryptographicException();
647 }
648 byte[] array = null;
649 int num3 = 0;
650 array = new byte[4];
651 cb = 4;
652 if (!global::Interop.Advapi32.CryptGetKeyParam(safeKeyHandle, global::Interop.Advapi32.CryptGetKeyParamFlags.KP_PERMISSIONS, array, ref cb, 0))
653 {
654 throw GetErrorCode().ToCryptographicException();
655 }
656 num3 = BitConverter.ToInt32(array, 0);
657 flag = IsFlagBitSet((uint)num3, 4u);
658 }
659 else
660 {
661 flag = false;
662 }
663 break;
664 case 4:
665 num = GetProviderParameterWorker(safeProvHandle, impType, ref cb, global::Interop.Advapi32.CryptProvParam.PP_IMPTYPE);
666 flag = IsFlagBitSet((uint)num, 8u);
667 break;
668 case 5:
669 case 7:
670 num = GetProviderParameterWorker(safeProvHandle, impType, ref cb, global::Interop.Advapi32.CryptProvParam.PP_IMPTYPE);
671 flag = IsFlagBitSet((uint)num, 1u);
672 break;
673 case 6:
674 flag = (CryptGetUserKey(safeProvHandle, keyNumber, out safeKeyHandle) ? true : false);
675 break;
676 case 8:
677 {
678 num2 = 1;
679 byte[] impType2 = null;
680 num = GetProviderParameterWorker(safeProvHandle, impType2, ref cb, global::Interop.Advapi32.CryptProvParam.PP_UNIQUE_CONTAINER);
681 impType2 = new byte[cb];
682 num = GetProviderParameterWorker(safeProvHandle, impType2, ref cb, global::Interop.Advapi32.CryptProvParam.PP_UNIQUE_CONTAINER);
683 result = Encoding.ASCII.GetString(impType2, 0, cb - 1);
684 break;
685 }
686 }
687 }
688 finally
689 {
690 safeKeyHandle.Dispose();
691 }
692 if (num2 != 0)
693 {
694 return result;
695 }
696 return flag;
697 }
698
699 internal static int GetUserKey(SafeProvHandle safeProvHandle, int keySpec, out SafeKeyHandle safeKeyHandle)
700 {
701 int num = 0;
702 VerifyValidHandle(safeProvHandle);
703 if (!CryptGetUserKey(safeProvHandle, keySpec, out safeKeyHandle))
704 {
705 num = GetErrorCode();
706 }
707 if (num == 0)
708 {
709 safeKeyHandle.KeySpec = keySpec;
710 }
711 return num;
712 }
713
714 internal static int GenerateKey(SafeProvHandle safeProvHandle, int algID, int flags, uint keySize, out SafeKeyHandle safeKeyHandle)
715 {
716 int num = 0;
717 VerifyValidHandle(safeProvHandle);
718 int dwFlags = MapCspKeyFlags(flags) | (int)(keySize << 16);
719 if (!CryptGenKey(safeProvHandle, algID, dwFlags, out safeKeyHandle))
720 {
721 num = GetErrorCode();
722 }
723 if (num != 0)
724 {
725 throw GetErrorCode().ToCryptographicException();
726 }
727 safeKeyHandle.KeySpec = algID;
728 return num;
729 }
730
731 internal static int MapCspKeyFlags(int flags)
732 {
733 int num = 0;
734 if (!IsFlagBitSet((uint)flags, 4u))
735 {
736 num |= 1;
737 }
738 if (IsFlagBitSet((uint)flags, 16u))
739 {
740 num |= 0x4000;
741 }
742 if (IsFlagBitSet((uint)flags, 32u))
743 {
744 num |= 2;
745 }
746 return num;
747 }
748
749 internal static uint MapCspProviderFlags(int flags)
750 {
751 uint num = 0u;
752 if (IsFlagBitSet((uint)flags, 1u))
753 {
754 num |= 0x20u;
755 }
756 if (IsFlagBitSet((uint)flags, 64u))
757 {
758 num |= 0x40u;
759 }
760 if (IsFlagBitSet((uint)flags, 128u))
761 {
762 num |= 0xF0000000u;
763 }
764 return num;
765 }
766
768 {
769 if (handle.IsInvalid)
770 {
772 }
773 }
774
775 internal static byte[] GetKeyParameter(SafeKeyHandle safeKeyHandle, int keyParam)
776 {
777 byte[] array = null;
778 int pdwDataLen = 0;
779 VerifyValidHandle(safeKeyHandle);
780 switch (keyParam)
781 {
782 case 1:
783 if (!global::Interop.Advapi32.CryptGetKeyParam(safeKeyHandle, global::Interop.Advapi32.CryptGetKeyParamFlags.KP_KEYLEN, null, ref pdwDataLen, 0))
784 {
785 throw GetErrorCode().ToCryptographicException();
786 }
787 array = new byte[pdwDataLen];
788 if (!global::Interop.Advapi32.CryptGetKeyParam(safeKeyHandle, global::Interop.Advapi32.CryptGetKeyParamFlags.KP_KEYLEN, array, ref pdwDataLen, 0))
789 {
790 throw GetErrorCode().ToCryptographicException();
791 }
792 break;
793 case 2:
794 array = new byte[1] { (byte)(safeKeyHandle.PublicOnly ? 1 : 0) };
795 break;
796 case 9:
797 if (!global::Interop.Advapi32.CryptGetKeyParam(safeKeyHandle, global::Interop.Advapi32.CryptGetKeyParamFlags.KP_ALGID, null, ref pdwDataLen, 0))
798 {
799 throw GetErrorCode().ToCryptographicException();
800 }
801 array = new byte[pdwDataLen];
802 if (!global::Interop.Advapi32.CryptGetKeyParam(safeKeyHandle, global::Interop.Advapi32.CryptGetKeyParamFlags.KP_ALGID, array, ref pdwDataLen, 0))
803 {
804 throw GetErrorCode().ToCryptographicException();
805 }
806 break;
807 }
808 return array;
809 }
810
811 internal static void SetKeyParameter(SafeKeyHandle safeKeyHandle, CryptGetKeyParamQueryType keyParam, byte[] value)
812 {
813 VerifyValidHandle(safeKeyHandle);
814 if (keyParam == CryptGetKeyParamQueryType.KP_IV && !global::Interop.Advapi32.CryptSetKeyParam(safeKeyHandle, (int)keyParam, value, 0))
815 {
817 }
818 }
819
820 internal static void SetKeyParameter(SafeKeyHandle safeKeyHandle, CryptGetKeyParamQueryType keyParam, int value)
821 {
822 VerifyValidHandle(safeKeyHandle);
823 if (((uint)(keyParam - 4) <= 1u || keyParam == CryptGetKeyParamQueryType.KP_EFFECTIVE_KEYLEN) && !global::Interop.Advapi32.CryptSetKeyParam(safeKeyHandle, (int)keyParam, ref value, 0))
824 {
826 }
827 }
828
829 internal static CspParameters SaveCspParameters(CspAlgorithmType keyType, CspParameters userParameters, CspProviderFlags defaultFlags, out bool randomKeyContainer)
830 {
831 CspParameters cspParameters;
832 if (userParameters == null)
833 {
834 cspParameters = new CspParameters((keyType == CspAlgorithmType.Dss) ? 13 : 24, null, null, defaultFlags);
835 }
836 else
837 {
838 ValidateCspFlags(userParameters.Flags);
839 cspParameters = new CspParameters(userParameters);
840 }
841 if (cspParameters.KeyNumber == -1)
842 {
843 cspParameters.KeyNumber = ((keyType != CspAlgorithmType.Dss) ? 1 : 2);
844 }
845 else if (cspParameters.KeyNumber == 8704 || cspParameters.KeyNumber == 9216)
846 {
847 cspParameters.KeyNumber = 2;
848 }
849 else if (cspParameters.KeyNumber == 41984)
850 {
851 cspParameters.KeyNumber = 1;
852 }
853 randomKeyContainer = IsFlagBitSet((uint)cspParameters.Flags, 128u);
854 if (cspParameters.KeyContainerName == null && !IsFlagBitSet((uint)cspParameters.Flags, 2u))
855 {
856 cspParameters.Flags |= CspProviderFlags.CreateEphemeralKey;
857 randomKeyContainer = true;
858 }
859 return cspParameters;
860 }
861
862 private static void ValidateCspFlags(CspProviderFlags flags)
863 {
864 if (IsFlagBitSet((uint)flags, 8u))
865 {
866 CspProviderFlags cspProviderFlags = CspProviderFlags.UseNonExportableKey | CspProviderFlags.UseArchivableKey | CspProviderFlags.UseUserProtectedKey;
867 if ((flags & cspProviderFlags) != 0)
868 {
869 throw new ArgumentException(System.SR.Format(System.SR.Arg_EnumIllegalVal, flags), "flags");
870 }
871 }
872 }
873
874 internal static SafeKeyHandle GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, int keySize, SafeProvHandle safeProvHandle)
875 {
876 SafeKeyHandle safeKeyHandle;
877 int userKey = GetUserKey(safeProvHandle, parameters.KeyNumber, out safeKeyHandle);
878 if (userKey != 0)
879 {
880 safeKeyHandle.Dispose();
881 if (IsFlagBitSet((uint)parameters.Flags, 8u) || userKey != -2146893811)
882 {
883 throw userKey.ToCryptographicException();
884 }
885 GenerateKey(safeProvHandle, parameters.KeyNumber, (int)parameters.Flags, (uint)keySize, out safeKeyHandle);
886 }
887 byte[] keyParameter = GetKeyParameter(safeKeyHandle, 9);
888 int num = BinaryPrimitives.ReadInt32LittleEndian(keyParameter);
889 if ((keyType == CspAlgorithmType.Rsa && num != 41984 && num != 9216) || (keyType == CspAlgorithmType.Dss && num != 8704))
890 {
891 safeKeyHandle.Dispose();
893 }
894 return safeKeyHandle;
895 }
896
897 internal static int GetErrorCode()
898 {
900 }
901
902 internal static bool GetPersistKeyInCsp(SafeProvHandle safeProvHandle)
903 {
904 VerifyValidHandle(safeProvHandle);
905 return safeProvHandle.PersistKeyInCsp;
906 }
907
908 internal static void SetPersistKeyInCsp(SafeProvHandle safeProvHandle, bool fPersistKeyInCsp)
909 {
910 VerifyValidHandle(safeProvHandle);
911 safeProvHandle.PersistKeyInCsp = fPersistKeyInCsp;
912 }
913
914 internal static void DecryptKey(SafeKeyHandle safeKeyHandle, byte[] encryptedData, int encryptedDataLength, bool fOAEP, out byte[] decryptedData)
915 {
916 VerifyValidHandle(safeKeyHandle);
917 byte[] array = new byte[encryptedDataLength];
918 Buffer.BlockCopy(encryptedData, 0, array, 0, encryptedDataLength);
920 int num = (fOAEP ? 64 : 0);
921 int pdwDataLen = encryptedDataLength;
922 if (!global::Interop.Advapi32.CryptDecrypt(safeKeyHandle, SafeHashHandle.InvalidHandle, Final: true, num, array, ref pdwDataLen))
923 {
924 int errorCode = GetErrorCode();
925 if ((num & 0x40) == 64)
926 {
927 switch (errorCode)
928 {
929 case -2146893815:
930 throw new CryptographicException("Cryptography_OAEP_XPPlus_Only");
931 default:
932 throw new CryptographicException("Cryptography_OAEPDecoding");
933 case -2146893821:
934 break;
935 }
936 }
937 throw errorCode.ToCryptographicException();
938 }
939 decryptedData = new byte[pdwDataLen];
940 Buffer.BlockCopy(array, 0, decryptedData, 0, pdwDataLen);
941 }
942
943 internal static void EncryptKey(SafeKeyHandle safeKeyHandle, byte[] pbKey, int cbKey, bool foep, [NotNull] ref byte[] pbEncryptedKey)
944 {
945 VerifyValidHandle(safeKeyHandle);
946 int dwFlags = (foep ? 64 : 0);
947 int pdwDataLen = cbKey;
948 if (!global::Interop.Advapi32.CryptEncrypt(safeKeyHandle, SafeHashHandle.InvalidHandle, Final: true, dwFlags, null, ref pdwDataLen, pdwDataLen))
949 {
950 throw GetErrorCode().ToCryptographicException();
951 }
952 pbEncryptedKey = new byte[pdwDataLen];
953 Buffer.BlockCopy(pbKey, 0, pbEncryptedKey, 0, cbKey);
954 if (!global::Interop.Advapi32.CryptEncrypt(safeKeyHandle, SafeHashHandle.InvalidHandle, Final: true, dwFlags, pbEncryptedKey, ref cbKey, pdwDataLen))
955 {
956 throw GetErrorCode().ToCryptographicException();
957 }
958 Array.Reverse(pbEncryptedKey);
959 }
960
961 internal static int EncryptData(SafeKeyHandle hKey, ReadOnlySpan<byte> input, Span<byte> output, bool isFinal)
962 {
963 VerifyValidHandle(hKey);
964 int pdwDataLen = input.Length;
965 if (!global::Interop.Advapi32.CryptEncrypt(hKey, SafeHashHandle.InvalidHandle, isFinal, 0, null, ref pdwDataLen, pdwDataLen))
966 {
967 throw GetErrorCode().ToCryptographicException();
968 }
969 byte[] array = new byte[pdwDataLen];
970 input.CopyTo(array);
971 int pdwDataLen2 = input.Length;
972 if (!global::Interop.Advapi32.CryptEncrypt(hKey, SafeHashHandle.InvalidHandle, isFinal, 0, array, ref pdwDataLen2, pdwDataLen))
973 {
974 throw GetErrorCode().ToCryptographicException();
975 }
976 int num = (isFinal ? input.Length : pdwDataLen2);
977 array.AsSpan(0, num).CopyTo(output);
978 return num;
979 }
980
982 {
983 VerifyValidHandle(hKey);
984 byte[] array = new byte[input.Length];
985 input.CopyTo(array);
986 int pdwDataLen = input.Length;
987 if (!global::Interop.Advapi32.CryptDecrypt(hKey, SafeHashHandle.InvalidHandle, Final: false, 0, array, ref pdwDataLen))
988 {
989 throw GetErrorCode().ToCryptographicException();
990 }
991 array.AsSpan(0, pdwDataLen).CopyTo(output);
992 return pdwDataLen;
993 }
994
995 internal static void ImportKeyBlob(SafeProvHandle saveProvHandle, CspProviderFlags flags, bool addNoSaltFlag, byte[] keyBlob, out SafeKeyHandle safeKeyHandle)
996 {
997 bool flag = keyBlob.Length != 0 && keyBlob[0] == 6;
998 int num = MapCspKeyFlags((int)flags);
999 if (flag)
1000 {
1001 num &= -2;
1002 }
1003 if (addNoSaltFlag)
1004 {
1005 num |= 0x10;
1006 }
1007 if (!CryptImportKey(saveProvHandle, keyBlob, SafeKeyHandle.InvalidHandle, num, out var phKey))
1008 {
1009 int hRForLastWin32Error = Marshal.GetHRForLastWin32Error();
1010 phKey.Dispose();
1011 throw hRForLastWin32Error.ToCryptographicException();
1012 }
1013 phKey.PublicOnly = flag;
1014 safeKeyHandle = phKey;
1015 }
1016
1017 internal static byte[] ExportKeyBlob(bool includePrivateParameters, SafeKeyHandle safeKeyHandle)
1018 {
1019 VerifyValidHandle(safeKeyHandle);
1020 int dwDataLen = 0;
1021 int dwBlobType = (includePrivateParameters ? 7 : 6);
1022 if (!global::Interop.Advapi32.CryptExportKey(safeKeyHandle, SafeKeyHandle.InvalidHandle, dwBlobType, 0, null, ref dwDataLen))
1023 {
1024 throw GetErrorCode().ToCryptographicException();
1025 }
1026 byte[] array = new byte[dwDataLen];
1027 if (!global::Interop.Advapi32.CryptExportKey(safeKeyHandle, SafeKeyHandle.InvalidHandle, dwBlobType, 0, array, ref dwDataLen))
1028 {
1029 throw GetErrorCode().ToCryptographicException();
1030 }
1031 return array;
1032 }
1033
1034 public static int NameOrOidToHashAlgId(string nameOrOid, OidGroup oidGroup)
1035 {
1036 if (nameOrOid == null)
1037 {
1038 return 32772;
1039 }
1040 string text = CryptoConfig.MapNameToOID(nameOrOid);
1041 if (text == null)
1042 {
1043 text = nameOrOid;
1044 }
1045 int algIdFromOid = GetAlgIdFromOid(text, oidGroup);
1046 if (algIdFromOid == 0 || algIdFromOid == -1)
1047 {
1049 }
1050 return algIdFromOid;
1051 }
1052
1053 public static int ObjToHashAlgId(object hashAlg)
1054 {
1055 if (hashAlg == null)
1056 {
1057 throw new ArgumentNullException("hashAlg");
1058 }
1059 if (hashAlg is string nameOrOid)
1060 {
1061 return NameOrOidToHashAlgId(nameOrOid, OidGroup.HashAlgorithm);
1062 }
1063 if (hashAlg is HashAlgorithm)
1064 {
1065 if (hashAlg is MD5)
1066 {
1067 return 32771;
1068 }
1069 if (hashAlg is SHA1)
1070 {
1071 return 32772;
1072 }
1073 if (hashAlg is SHA256)
1074 {
1075 return 32780;
1076 }
1077 if (hashAlg is SHA384)
1078 {
1079 return 32781;
1080 }
1081 if (hashAlg is SHA512)
1082 {
1083 return 32782;
1084 }
1085 }
1086 else if (hashAlg is Type c)
1087 {
1088 if (typeof(MD5).IsAssignableFrom(c))
1089 {
1090 return 32771;
1091 }
1092 if (typeof(SHA1).IsAssignableFrom(c))
1093 {
1094 return 32772;
1095 }
1096 if (typeof(SHA256).IsAssignableFrom(c))
1097 {
1098 return 32780;
1099 }
1100 if (typeof(SHA384).IsAssignableFrom(c))
1101 {
1102 return 32781;
1103 }
1104 if (typeof(SHA512).IsAssignableFrom(c))
1105 {
1106 return 32782;
1107 }
1108 }
1109 throw new ArgumentException(System.SR.Argument_InvalidValue, "hashAlg");
1110 }
1111
1112 internal static HashAlgorithm ObjToHashAlgorithm(object hashAlg)
1113 {
1114 return ObjToHashAlgId(hashAlg) switch
1115 {
1116 32771 => MD5.Create(),
1117 32772 => SHA1.Create(),
1118 32780 => SHA256.Create(),
1119 32781 => SHA384.Create(),
1120 32782 => SHA512.Create(),
1121 _ => throw new ArgumentException(System.SR.Argument_InvalidValue, "hashAlg"),
1122 };
1123 }
1124
1125 private static int GetAlgIdFromOid(string oid, OidGroup oidGroup)
1126 {
1127 if (string.Equals(oid, "2.16.840.1.101.3.4.2.1", StringComparison.Ordinal))
1128 {
1129 return 32780;
1130 }
1131 if (string.Equals(oid, "2.16.840.1.101.3.4.2.2", StringComparison.Ordinal))
1132 {
1133 return 32781;
1134 }
1135 if (string.Equals(oid, "2.16.840.1.101.3.4.2.3", StringComparison.Ordinal))
1136 {
1137 return 32782;
1138 }
1139 return global::Interop.Crypt32.FindOidInfo(global::Interop.Crypt32.CryptOidInfoKeyType.CRYPT_OID_INFO_OID_KEY, oid, oidGroup, fallBackToAllGroups: false).AlgId;
1140 }
1141
1142 public static byte[] SignValue(SafeProvHandle hProv, SafeKeyHandle hKey, int keyNumber, int calgKey, int calgHash, byte[] hash)
1143 {
1144 using SafeHashHandle hHash = hProv.CreateHashHandle(hash, calgHash);
1145 int pdwSigLen = 0;
1146 if (!global::Interop.Advapi32.CryptSignHash(hHash, (global::Interop.Advapi32.KeySpec)keyNumber, null, global::Interop.Advapi32.CryptSignAndVerifyHashFlags.None, null, ref pdwSigLen))
1147 {
1148 int hRForLastWin32Error = Marshal.GetHRForLastWin32Error();
1149 throw hRForLastWin32Error.ToCryptographicException();
1150 }
1151 byte[] array = new byte[pdwSigLen];
1152 if (!global::Interop.Advapi32.CryptSignHash(hHash, (global::Interop.Advapi32.KeySpec)keyNumber, null, global::Interop.Advapi32.CryptSignAndVerifyHashFlags.None, array, ref pdwSigLen))
1153 {
1154 int hRForLastWin32Error2 = Marshal.GetHRForLastWin32Error();
1155 throw hRForLastWin32Error2.ToCryptographicException();
1156 }
1157 switch (calgKey)
1158 {
1159 case 9216:
1161 break;
1162 case 8704:
1163 ReverseDsaSignature(array, pdwSigLen);
1164 break;
1165 default:
1166 throw new InvalidOperationException();
1167 }
1168 return array;
1169 }
1170
1171 public static bool VerifySign(SafeProvHandle hProv, SafeKeyHandle hKey, int calgKey, int calgHash, byte[] hash, byte[] signature)
1172 {
1173 switch (calgKey)
1174 {
1175 case 9216:
1176 signature = signature.CloneByteArray();
1177 Array.Reverse(signature);
1178 break;
1179 case 8704:
1180 signature = signature.CloneByteArray();
1181 ReverseDsaSignature(signature, signature.Length);
1182 break;
1183 default:
1184 throw new InvalidOperationException();
1185 }
1186 using SafeHashHandle safeHashHandle = hProv.CreateHashHandle(hash, calgHash, throwOnSizeError: false);
1187 if (safeHashHandle == null)
1188 {
1189 return false;
1190 }
1191 return global::Interop.Advapi32.CryptVerifySignature(safeHashHandle, signature, signature.Length, hKey, null, global::Interop.Advapi32.CryptSignAndVerifyHashFlags.None);
1192 }
1193
1194 public static void DeriveKey(SafeProvHandle hProv, int algid, int algidHash, byte[] password, int cbPassword, int dwFlags, byte[] IV_Out, int cbIV_In, [NotNull] ref byte[] pbKey)
1195 {
1196 VerifyValidHandle(hProv);
1197 SafeHashHandle phHash = null;
1198 SafeKeyHandle phKey = null;
1199 try
1200 {
1201 if (!CryptCreateHash(hProv, algidHash, SafeKeyHandle.InvalidHandle, global::Interop.Advapi32.CryptCreateHashFlags.None, out phHash))
1202 {
1203 int hRForLastWin32Error = Marshal.GetHRForLastWin32Error();
1204 throw hRForLastWin32Error.ToCryptographicException();
1205 }
1206 if (!global::Interop.Advapi32.CryptHashData(phHash, password, cbPassword, 0))
1207 {
1208 int hRForLastWin32Error2 = Marshal.GetHRForLastWin32Error();
1209 throw hRForLastWin32Error2.ToCryptographicException();
1210 }
1211 if (!CryptDeriveKey(hProv, algid, phHash, dwFlags | 1, out phKey))
1212 {
1213 int hRForLastWin32Error3 = Marshal.GetHRForLastWin32Error();
1214 throw hRForLastWin32Error3.ToCryptographicException();
1215 }
1216 byte[] key_out = null;
1217 int cb_out = 0;
1218 UnloadKey(hProv, phKey, ref key_out, ref cb_out);
1219 int pdwDataLen = 0;
1220 if (!global::Interop.Advapi32.CryptGetKeyParam(phKey, global::Interop.Advapi32.CryptGetKeyParamFlags.KP_IV, null, ref pdwDataLen, 0))
1221 {
1222 int hRForLastWin32Error4 = Marshal.GetHRForLastWin32Error();
1223 throw hRForLastWin32Error4.ToCryptographicException();
1224 }
1225 byte[] array = new byte[pdwDataLen];
1226 if (!global::Interop.Advapi32.CryptGetKeyParam(phKey, global::Interop.Advapi32.CryptGetKeyParamFlags.KP_IV, array, ref pdwDataLen, 0))
1227 {
1228 int hRForLastWin32Error5 = Marshal.GetHRForLastWin32Error();
1229 throw hRForLastWin32Error5.ToCryptographicException();
1230 }
1231 if (pdwDataLen != cbIV_In)
1232 {
1234 }
1235 Buffer.BlockCopy(array, 0, IV_Out, 0, pdwDataLen);
1236 pbKey = new byte[cb_out];
1237 Buffer.BlockCopy(key_out, 0, pbKey, 0, cb_out);
1238 }
1239 finally
1240 {
1241 phKey?.Dispose();
1242 phHash?.Dispose();
1243 }
1244 }
1245
1246 private static void UnloadKey(SafeProvHandle hProv, SafeKeyHandle hKey, [NotNull] ref byte[] key_out, ref int cb_out)
1247 {
1248 SafeKeyHandle phKey = null;
1249 try
1250 {
1251 if (!CryptImportKey(hProv, RgbPubKey, SafeKeyHandle.InvalidHandle, 0, out phKey))
1252 {
1253 int hRForLastWin32Error = Marshal.GetHRForLastWin32Error();
1254 throw hRForLastWin32Error.ToCryptographicException();
1255 }
1256 int dwDataLen = 0;
1257 if (!global::Interop.Advapi32.CryptExportKey(hKey, phKey, 1, 0, null, ref dwDataLen))
1258 {
1259 int hRForLastWin32Error2 = Marshal.GetHRForLastWin32Error();
1260 throw hRForLastWin32Error2.ToCryptographicException();
1261 }
1262 byte[] array = new byte[dwDataLen];
1263 if (!global::Interop.Advapi32.CryptExportKey(hKey, phKey, 1, 0, array, ref dwDataLen))
1264 {
1265 int hRForLastWin32Error3 = Marshal.GetHRForLastWin32Error();
1266 throw hRForLastWin32Error3.ToCryptographicException();
1267 }
1268 int num = 8;
1269 int num2 = num + 4;
1270 int num3 = checked(dwDataLen - num - 4 - 2);
1271 while (num3 > 0 && array[num3 + num2] != 0)
1272 {
1273 num3--;
1274 }
1275 key_out = new byte[num3];
1276 Buffer.BlockCopy(array, num2, key_out, 0, num3);
1277 Array.Reverse(key_out);
1278 cb_out = num3;
1279 }
1280 finally
1281 {
1282 phKey?.Dispose();
1283 }
1284 }
1285
1286 private static SafeHashHandle CreateHashHandle(this SafeProvHandle hProv, byte[] hash, int calgHash)
1287 {
1288 return hProv.CreateHashHandle(hash, calgHash, throwOnSizeError: true);
1289 }
1290
1291 private static SafeHashHandle CreateHashHandle(this SafeProvHandle hProv, byte[] hash, int calgHash, bool throwOnSizeError)
1292 {
1293 if (!CryptCreateHash(hProv, calgHash, SafeKeyHandle.InvalidHandle, global::Interop.Advapi32.CryptCreateHashFlags.None, out var phHash))
1294 {
1295 int hRForLastWin32Error = Marshal.GetHRForLastWin32Error();
1296 phHash.Dispose();
1297 throw hRForLastWin32Error.ToCryptographicException();
1298 }
1299 try
1300 {
1301 int pbData = 0;
1302 int pdwDataLen = 4;
1303 if (!global::Interop.Advapi32.CryptGetHashParam(phHash, global::Interop.Advapi32.CryptHashProperty.HP_HASHSIZE, out pbData, ref pdwDataLen, 0))
1304 {
1305 int hRForLastWin32Error2 = Marshal.GetHRForLastWin32Error();
1306 throw hRForLastWin32Error2.ToCryptographicException();
1307 }
1308 if (pbData != hash.Length)
1309 {
1310 if (throwOnSizeError)
1311 {
1312 throw (-2146893821).ToCryptographicException();
1313 }
1314 return null;
1315 }
1316 if (!global::Interop.Advapi32.CryptSetHashParam(phHash, global::Interop.Advapi32.CryptHashProperty.HP_HASHVAL, hash, 0))
1317 {
1318 int hRForLastWin32Error3 = Marshal.GetHRForLastWin32Error();
1319 throw hRForLastWin32Error3.ToCryptographicException();
1320 }
1321 SafeHashHandle result = phHash;
1322 phHash = null;
1323 return result;
1324 }
1325 finally
1326 {
1327 phHash?.Dispose();
1328 }
1329 }
1330
1332 {
1333 return (-2146893819).ToCryptographicException();
1334 }
1335
1337 {
1338 return (-2147467259).ToCryptographicException();
1339 }
1340
1341 public static bool CryptGetUserKey(SafeProvHandle safeProvHandle, int dwKeySpec, out SafeKeyHandle safeKeyHandle)
1342 {
1343 bool result = global::Interop.Advapi32.CryptGetUserKey(safeProvHandle, dwKeySpec, out safeKeyHandle);
1344 safeKeyHandle.SetParent(safeProvHandle);
1345 return result;
1346 }
1347
1348 public static bool CryptGenKey(SafeProvHandle safeProvHandle, int algId, int dwFlags, out SafeKeyHandle safeKeyHandle)
1349 {
1350 bool result = global::Interop.Advapi32.CryptGenKey(safeProvHandle, algId, dwFlags, out safeKeyHandle);
1351 safeKeyHandle.SetParent(safeProvHandle);
1352 return result;
1353 }
1354
1355 public unsafe static bool CryptImportKey(SafeProvHandle hProv, ReadOnlySpan<byte> pbData, SafeKeyHandle hPubKey, int dwFlags, out SafeKeyHandle phKey)
1356 {
1357 fixed (byte* pbData2 = pbData)
1358 {
1359 bool result = global::Interop.Advapi32.CryptImportKey(hProv, pbData2, pbData.Length, hPubKey, dwFlags, out phKey);
1360 phKey.SetParent(hProv);
1361 return result;
1362 }
1363 }
1364
1365 public static bool CryptCreateHash(SafeProvHandle hProv, int algId, SafeKeyHandle hKey, global::Interop.Advapi32.CryptCreateHashFlags dwFlags, out SafeHashHandle phHash)
1366 {
1367 bool result = global::Interop.Advapi32.CryptCreateHash(hProv, algId, hKey, dwFlags, out phHash);
1368 phHash.SetParent(hProv);
1369 return result;
1370 }
1371
1372 public static bool CryptDeriveKey(SafeProvHandle hProv, int algId, SafeHashHandle phHash, int dwFlags, out SafeKeyHandle phKey)
1373 {
1374 bool result = global::Interop.Advapi32.CryptDeriveKey(hProv, algId, phHash, dwFlags, out phKey);
1375 phKey.SetParent(hProv);
1376 return result;
1377 }
1378
1379 internal static byte[] ToPlainTextKeyBlob(int algId, byte[] rawKey)
1380 {
1381 using MemoryStream memoryStream = new MemoryStream();
1382 using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
1383 WriteKeyBlobHeader(algId, binaryWriter);
1384 binaryWriter.Write(rawKey.Length);
1385 binaryWriter.Write(rawKey);
1386 binaryWriter.Flush();
1387 return memoryStream.ToArray();
1388 }
1389
1390 private static void WriteKeyBlobHeader(int algId, BinaryWriter bw)
1391 {
1392 bw.Write((byte)8);
1393 bw.Write((byte)2);
1394 bw.Write((ushort)0);
1395 bw.Write(algId);
1396 }
1397}
static CryptographicException GetEFailException()
static int GetProviderParameterWorker(SafeProvHandle safeProvHandle, byte[] impType, ref int cb, global::Interop.Advapi32.CryptProvParam flags)
static void AcquireCsp(CspParameters cspParameters, out SafeProvHandle safeProvHandle)
static bool CryptCreateHash(SafeProvHandle hProv, int algId, SafeKeyHandle hKey, global::Interop.Advapi32.CryptCreateHashFlags dwFlags, out SafeHashHandle phHash)
static object GetProviderParameter(SafeProvHandle safeProvHandle, int keyNumber, int keyParam)
static int OpenCSP(CspParameters cspParameters, uint flags, out SafeProvHandle safeProvHandle)
static void SetKeyParameter(SafeKeyHandle safeKeyHandle, CryptGetKeyParamQueryType keyParam, byte[] value)
static void UnloadKey(SafeProvHandle hProv, SafeKeyHandle hKey, [NotNull] ref byte[] key_out, ref int cb_out)
static void WriteReversed(this BinaryWriter bw, byte[] bytes)
static void VerifyValidHandle(SafeHandleZeroOrMinusOneIsInvalid handle)
static SafeKeyHandle GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, int keySize, SafeProvHandle safeProvHandle)
static int DecryptData(SafeKeyHandle hKey, ReadOnlySpan< byte > input, Span< byte > output)
static bool GetPersistKeyInCsp(SafeProvHandle safeProvHandle)
static bool IsFlagBitSet(uint dwImp, uint flag)
static int AcquireCryptContext(out SafeProvHandle safeProvHandle, string keyContainer, string providerName, int providerType, uint flags)
static bool CryptGenKey(SafeProvHandle safeProvHandle, int algId, int dwFlags, out SafeKeyHandle safeKeyHandle)
static void SetPersistKeyInCsp(SafeProvHandle safeProvHandle, bool fPersistKeyInCsp)
static bool CryptDeriveKey(SafeProvHandle hProv, int algId, SafeHashHandle phHash, int dwFlags, out SafeKeyHandle phKey)
static ReadOnlySpan< byte > RgbPubKey
Definition CapiHelper.cs:31
static SafeProvHandle CreateProvHandle(CspParameters parameters, bool randomKeyContainer)
static void ReverseDsaSignature(byte[] signature, int cbSignature)
static void ReadDSSSeed(DSAParameters dsaParameters, BinaryReader br, bool isV3)
static void SetKeyParameter(SafeKeyHandle safeKeyHandle, CryptGetKeyParamQueryType keyParam, int value)
static void WriteKeyBlobHeader(DSAParameters dsaParameters, BinaryWriter bw, bool isPrivate, out bool isV3)
static uint MapCspProviderFlags(int flags)
static void ReadKeyBlobHeader(BinaryReader br, out byte bVersion)
static DSAParameters ToDSAParameters(this byte[] cspBlob, bool includePrivateParameters, byte[] cspPublicBlob)
static int ObjToHashAlgId(object hashAlg)
static SafeHashHandle CreateHashHandle(this SafeProvHandle hProv, byte[] hash, int calgHash, bool throwOnSizeError)
static byte[] ToPlainTextKeyBlob(int algId, byte[] rawKey)
static byte[] ToKeyBlob(this DSAParameters dsaParameters)
Definition CapiHelper.cs:44
static CspParameters SaveCspParameters(CspAlgorithmType keyType, CspParameters userParameters, CspProviderFlags defaultFlags, out bool randomKeyContainer)
static bool CryptGetUserKey(SafeProvHandle safeProvHandle, int dwKeySpec, out SafeKeyHandle safeKeyHandle)
static int MapCspKeyFlags(int flags)
static RSAParameters ToRSAParameters(this byte[] cspBlob, bool includePrivateParameters)
static byte GetKeyBlobHeaderVersion(byte[] cspBlob)
static int GenerateKey(SafeProvHandle safeProvHandle, int algID, int flags, uint keySize, out SafeKeyHandle safeKeyHandle)
static int NameOrOidToHashAlgId(string nameOrOid, OidGroup oidGroup)
static string GetDefaultProvider(int dwType)
static int GetAlgIdFromOid(string oid, OidGroup oidGroup)
static void DeriveKey(SafeProvHandle hProv, int algid, int algidHash, byte[] password, int cbPassword, int dwFlags, byte[] IV_Out, int cbIV_In, [NotNull] ref byte[] pbKey)
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 void ValidateCspFlags(CspProviderFlags flags)
static void CreateCSP(CspParameters parameters, bool randomKeyContainer, out SafeProvHandle safeProvHandle)
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 int EncryptData(SafeKeyHandle hKey, ReadOnlySpan< byte > input, Span< byte > output, bool isFinal)
static HashAlgorithm ObjToHashAlgorithm(object hashAlg)
static int GetUserKey(SafeProvHandle safeProvHandle, int keySpec, out SafeKeyHandle safeKeyHandle)
static unsafe bool CryptImportKey(SafeProvHandle hProv, ReadOnlySpan< byte > pbData, SafeKeyHandle hPubKey, int dwFlags, out SafeKeyHandle phKey)
static byte[] ToKeyBlob(this RSAParameters rsaParameters)
static SafeHashHandle CreateHashHandle(this SafeProvHandle hProv, byte[] hash, int calgHash)
static string UpgradeDSS(int dwProvType, string wszProvider)
static string UpgradeRSA(int dwProvType, string wszProvider)
static void WriteKeyBlobHeader(int algId, BinaryWriter bw)
static byte[] ExportKeyBlob(bool includePrivateParameters, SafeKeyHandle safeKeyHandle)
static byte[] ReadReversed(this BinaryReader br, int count)
static byte[] GetKeyParameter(SafeKeyHandle safeKeyHandle, int keyParam)
static bool VerifySign(SafeProvHandle hProv, SafeKeyHandle hKey, int calgKey, int calgHash, byte[] hash, byte[] signature)
static CryptographicException GetBadDataException()
static byte[] ExponentAsBytes(uint exponent)
static void WriteDSSSeed(DSAParameters dsaParameters, BinaryWriter bw)
static void Reverse(Array array)
Definition Array.cs:2207
static int ToInt32(byte[] value, int startIndex)
static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
Definition Buffer.cs:102
static int ReadInt32LittleEndian(ReadOnlySpan< byte > source)
virtual byte ReadByte()
virtual ushort ReadUInt16()
virtual int ReadInt32()
virtual byte[] ReadBytes(int count)
virtual uint ReadUInt32()
virtual void Write(bool value)
virtual byte[] ToArray()
static IntPtr SecureStringToCoTaskMemAnsi(SecureString s)
Definition Marshal.cs:1257
static void ZeroFreeCoTaskMemAnsi(IntPtr s)
Definition Marshal.cs:1490
static string CspParameter_invalid
Definition SR.cs:76
static string Argument_InvalidValue
Definition SR.cs:24
static string Cryptography_InvalidOID
Definition SR.cs:62
static string Arg_EnumIllegalVal
Definition SR.cs:144
static string Cryptography_CSP_WrongKeySpec
Definition SR.cs:26
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string CryptSetKeyParam_Failed
Definition SR.cs:74
static string Cryptography_InvalidDSASignatureSize
Definition SR.cs:30
static string Cryptography_OpenInvalidHandle
Definition SR.cs:92
static string Cryptography_PasswordDerivedBytes_InvalidIV
Definition SR.cs:58
Definition SR.cs:7
static ? string MapNameToOID(string name)
static new MD5 Create()
Definition MD5.cs:57
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)
static Encoding ASCII
Definition Encoding.cs:511
override string ToString()
static readonly IntPtr Zero
Definition IntPtr.cs:18