mscorlib(4.0.0.0) API with additions
CapiNative.cs
2 
4 {
5  internal static class CapiNative
6  {
7  internal enum AlgorithmClass
8  {
9  Any = 0,
10  Signature = 0x2000,
11  Hash = 0x8000,
12  KeyExchange = 40960
13  }
14 
15  internal enum AlgorithmType
16  {
17  Any = 0,
18  Rsa = 0x400
19  }
20 
21  internal enum AlgorithmSubId
22  {
23  Any = 0,
24  RsaAny = 0,
25  Sha1 = 4,
26  Sha256 = 12,
27  Sha384 = 13,
28  Sha512 = 14
29  }
30 
31  internal enum AlgorithmID
32  {
33  None = 0,
34  RsaSign = 9216,
35  RsaKeyExchange = 41984,
36  Sha1 = 32772,
37  Sha256 = 32780,
38  Sha384 = 32781,
39  Sha512 = 32782
40  }
41 
42  [Flags]
43  internal enum CryptAcquireContextFlags
44  {
45  None = 0x0,
46  NewKeyset = 0x8,
47  DeleteKeyset = 0x10,
48  MachineKeyset = 0x20,
49  Silent = 0x40,
50  VerifyContext = -268435456
51  }
52 
53  internal enum ErrorCode
54  {
55  Ok = 0,
56  MoreData = 234,
57  BadHash = -2146893822,
58  BadData = -2146893819,
59  BadSignature = -2146893818,
60  NoKey = -2146893811
61  }
62 
63  internal enum HashProperty
64  {
65  None = 0,
66  HashValue = 2,
67  HashSize = 4
68  }
69 
70  [Flags]
71  internal enum KeyGenerationFlags
72  {
73  None = 0x0,
74  Exportable = 0x1,
75  UserProtected = 0x2,
76  Archivable = 0x4000
77  }
78 
79  internal enum KeyProperty
80  {
81  None = 0,
82  AlgorithmID = 7,
83  KeyLength = 9
84  }
85 
86  internal enum KeySpec
87  {
88  KeyExchange = 1,
89  Signature
90  }
91 
92  internal static class ProviderNames
93  {
94  internal const string MicrosoftEnhanced = "Microsoft Enhanced Cryptographic Provider v1.0";
95  }
96 
97  internal enum ProviderType
98  {
99  RsaFull = 1
100  }
101 
102  [SecurityCritical]
103  internal static class UnsafeNativeMethods
104  {
105  [DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true)]
106  [return: MarshalAs(UnmanagedType.Bool)]
107  internal static extern bool CryptAcquireContext(out SafeCspHandle phProv, string pszContainer, string pszProvider, ProviderType dwProvType, CryptAcquireContextFlags dwFlags);
108 
109  [DllImport("advapi32", SetLastError = true)]
110  [return: MarshalAs(UnmanagedType.Bool)]
111  internal static extern bool CryptCreateHash(SafeCspHandle hProv, AlgorithmID Algid, IntPtr hKey, int dwFlags, out SafeCspHashHandle phHash);
112 
113  [DllImport("advapi32", SetLastError = true)]
114  [return: MarshalAs(UnmanagedType.Bool)]
115  internal static extern bool CryptGenKey(SafeCspHandle hProv, int Algid, uint dwFlags, out SafeCspKeyHandle phKey);
116 
117  [DllImport("advapi32", SetLastError = true)]
118  [return: MarshalAs(UnmanagedType.Bool)]
119  internal static extern bool CryptGenRandom(SafeCspHandle hProv, int dwLen, [In] [Out] [MarshalAs(UnmanagedType.LPArray)] byte[] pbBuffer);
120 
121  [DllImport("advapi32", SetLastError = true)]
122  [return: MarshalAs(UnmanagedType.Bool)]
123  internal unsafe static extern bool CryptGenRandom(SafeCspHandle hProv, int dwLen, byte* pbBuffer);
124 
125  [DllImport("advapi32", SetLastError = true)]
126  [return: MarshalAs(UnmanagedType.Bool)]
127  internal static extern bool CryptGetHashParam(SafeCspHashHandle hHash, HashProperty dwParam, [In] [Out] [MarshalAs(UnmanagedType.LPArray)] byte[] pbData, [In] [Out] ref int pdwDataLen, int dwFlags);
128 
129  [DllImport("advapi32", SetLastError = true)]
130  [return: MarshalAs(UnmanagedType.Bool)]
131  internal static extern bool CryptGetKeyParam(SafeCspKeyHandle hKey, KeyProperty dwParam, [In] [Out] [MarshalAs(UnmanagedType.LPArray)] byte[] pbData, [In] [Out] ref int pdwDataLen, int dwFlags);
132 
133  [DllImport("advapi32", SetLastError = true)]
134  [return: MarshalAs(UnmanagedType.Bool)]
135  internal static extern bool CryptImportKey(SafeCspHandle hProv, [In] [MarshalAs(UnmanagedType.LPArray)] byte[] pbData, int pdwDataLen, IntPtr hPubKey, KeyGenerationFlags dwFlags, out SafeCspKeyHandle phKey);
136 
137  [DllImport("advapi32", SetLastError = true)]
138  [return: MarshalAs(UnmanagedType.Bool)]
139  internal static extern bool CryptSetHashParam(SafeCspHashHandle hHash, HashProperty dwParam, [In] [MarshalAs(UnmanagedType.LPArray)] byte[] pbData, int dwFlags);
140 
141  [DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true)]
142  [return: MarshalAs(UnmanagedType.Bool)]
143  internal static extern bool CryptVerifySignature(SafeCspHashHandle hHash, [In] [MarshalAs(UnmanagedType.LPArray)] byte[] pbSignature, int dwSigLen, SafeCspKeyHandle hPubKey, string sDescription, int dwFlags);
144  }
145 
146  [SecurityCritical]
147  internal static SafeCspHandle AcquireCsp(string keyContainer, string providerName, ProviderType providerType, CryptAcquireContextFlags flags)
148  {
149  if ((flags & CryptAcquireContextFlags.VerifyContext) == CryptAcquireContextFlags.VerifyContext && (flags & CryptAcquireContextFlags.MachineKeyset) == CryptAcquireContextFlags.MachineKeyset)
150  {
151  flags &= ~CryptAcquireContextFlags.MachineKeyset;
152  }
153  SafeCspHandle phProv = null;
154  if (!UnsafeNativeMethods.CryptAcquireContext(out phProv, keyContainer, providerName, providerType, flags))
155  {
156  throw new CryptographicException(Marshal.GetLastWin32Error());
157  }
158  return phProv;
159  }
160 
161  [SecurityCritical]
162  internal static SafeCspHashHandle CreateHashAlgorithm(SafeCspHandle cspHandle, AlgorithmID algorithm)
163  {
164  SafeCspHashHandle phHash = null;
165  if (!UnsafeNativeMethods.CryptCreateHash(cspHandle, algorithm, IntPtr.Zero, 0, out phHash))
166  {
167  throw new CryptographicException(Marshal.GetLastWin32Error());
168  }
169  return phHash;
170  }
171 
172  [SecurityCritical]
173  internal static void GenerateRandomBytes(SafeCspHandle cspHandle, byte[] buffer)
174  {
175  if (!UnsafeNativeMethods.CryptGenRandom(cspHandle, buffer.Length, buffer))
176  {
177  throw new CryptographicException(Marshal.GetLastWin32Error());
178  }
179  }
180 
181  [SecurityCritical]
182  internal unsafe static void GenerateRandomBytes(SafeCspHandle cspHandle, byte[] buffer, int offset, int count)
183  {
184  fixed (byte* pbBuffer = &buffer[offset])
185  {
186  if (!UnsafeNativeMethods.CryptGenRandom(cspHandle, count, pbBuffer))
187  {
188  throw new CryptographicException(Marshal.GetLastWin32Error());
189  }
190  }
191  }
192 
193  [SecurityCritical]
194  internal static int GetHashPropertyInt32(SafeCspHashHandle hashHandle, HashProperty property)
195  {
196  byte[] hashProperty = GetHashProperty(hashHandle, property);
197  if (hashProperty.Length != 4)
198  {
199  return 0;
200  }
201  return BitConverter.ToInt32(hashProperty, 0);
202  }
203 
204  [SecurityCritical]
205  internal static byte[] GetHashProperty(SafeCspHashHandle hashHandle, HashProperty property)
206  {
207  int pdwDataLen = 0;
208  byte[] pbData = null;
209  if (!UnsafeNativeMethods.CryptGetHashParam(hashHandle, property, pbData, ref pdwDataLen, 0))
210  {
211  int lastWin32Error = Marshal.GetLastWin32Error();
212  if (lastWin32Error != 234)
213  {
214  throw new CryptographicException(lastWin32Error);
215  }
216  }
217  pbData = new byte[pdwDataLen];
218  if (!UnsafeNativeMethods.CryptGetHashParam(hashHandle, property, pbData, ref pdwDataLen, 0))
219  {
220  throw new CryptographicException(Marshal.GetLastWin32Error());
221  }
222  return pbData;
223  }
224 
225  [SecurityCritical]
226  internal static int GetKeyPropertyInt32(SafeCspKeyHandle keyHandle, KeyProperty property)
227  {
228  byte[] keyProperty = GetKeyProperty(keyHandle, property);
229  if (keyProperty.Length != 4)
230  {
231  return 0;
232  }
233  return BitConverter.ToInt32(keyProperty, 0);
234  }
235 
236  [SecurityCritical]
237  internal static byte[] GetKeyProperty(SafeCspKeyHandle keyHandle, KeyProperty property)
238  {
239  int pdwDataLen = 0;
240  byte[] pbData = null;
241  if (!UnsafeNativeMethods.CryptGetKeyParam(keyHandle, property, pbData, ref pdwDataLen, 0))
242  {
243  int lastWin32Error = Marshal.GetLastWin32Error();
244  if (lastWin32Error != 234)
245  {
246  throw new CryptographicException(lastWin32Error);
247  }
248  }
249  pbData = new byte[pdwDataLen];
250  if (!UnsafeNativeMethods.CryptGetKeyParam(keyHandle, property, pbData, ref pdwDataLen, 0))
251  {
252  throw new CryptographicException(Marshal.GetLastWin32Error());
253  }
254  return pbData;
255  }
256 
257  [SecurityCritical]
258  internal static void SetHashProperty(SafeCspHashHandle hashHandle, HashProperty property, byte[] value)
259  {
260  if (!UnsafeNativeMethods.CryptSetHashParam(hashHandle, property, value, 0))
261  {
262  throw new CryptographicException(Marshal.GetLastWin32Error());
263  }
264  }
265 
266  [SecurityCritical]
267  internal static bool VerifySignature(SafeCspHandle cspHandle, SafeCspKeyHandle keyHandle, AlgorithmID signatureAlgorithm, AlgorithmID hashAlgorithm, byte[] hashValue, byte[] signature)
268  {
269  byte[] array = new byte[signature.Length];
270  Array.Copy(signature, array, array.Length);
271  Array.Reverse(array);
272  using (SafeCspHashHandle safeCspHashHandle = CreateHashAlgorithm(cspHandle, hashAlgorithm))
273  {
274  if (hashValue.Length != GetHashPropertyInt32(safeCspHashHandle, HashProperty.HashSize))
275  {
276  throw new CryptographicException(-2146893822);
277  }
278  SetHashProperty(safeCspHashHandle, HashProperty.HashValue, hashValue);
279  if (UnsafeNativeMethods.CryptVerifySignature(safeCspHashHandle, array, array.Length, keyHandle, null, 0))
280  {
281  return true;
282  }
283  int lastWin32Error = Marshal.GetLastWin32Error();
284  if (lastWin32Error != -2146893818)
285  {
286  throw new CryptographicException(lastWin32Error);
287  }
288  return false;
289  }
290  }
291  }
292 }
A hash algorithm is used to generate key material. The P:System.Security.Cryptography....
The Secure Hashing Algorithm 2 (SHA-2), using a 256-bit digest.
The Secure Hashing Algorithm 2 (SHA-2), using a 512-bit digest.
A signature key pair used for authenticating digitally signed messages or files.
Definition: __Canon.cs:3
The Secure Hashing Algorithm 2 (SHA-2), using a 384-bit digest.
UnmanagedType
Identifies how to marshal parameters or fields to unmanaged code.
Definition: UnmanagedType.cs:7
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks,...
Definition: Marshal.cs:15
CharSet
Dictates which character set marshaled strings should use.
Definition: CharSet.cs:7
The email was successfully sent to the SMTP service.
The Secure Hashing Algorithm (SHA1).
Notify the user through a dialog box or other method that the key is accessed. The Cryptographic Serv...
static int GetLastWin32Error()
Returns the error code returned by the last unmanaged function that was called using platform invoke ...