mscorlib(4.0.0.0) API with additions
X509Utils.cs
1 using Microsoft.Win32;
4 
6 {
7  internal static class X509Utils
8  {
9  private static bool OidGroupWillNotUseActiveDirectory(OidGroup group)
10  {
11  if (group != OidGroup.HashAlgorithm && group != OidGroup.EncryptionAlgorithm && group != OidGroup.PublicKeyAlgorithm && group != OidGroup.SignatureAlgorithm && group != OidGroup.Attribute && group != OidGroup.ExtensionOrAttribute)
12  {
13  return group == OidGroup.KeyDerivationFunction;
14  }
15  return true;
16  }
17 
18  [SecurityCritical]
19  private static CRYPT_OID_INFO FindOidInfo(OidKeyType keyType, string key, OidGroup group)
20  {
21  IntPtr intPtr = IntPtr.Zero;
23  try
24  {
25  intPtr = ((keyType != OidKeyType.Oid) ? Marshal.StringToCoTaskMemUni(key) : Marshal.StringToCoTaskMemAnsi(key));
26  if (!OidGroupWillNotUseActiveDirectory(group))
27  {
28  OidGroup dwGroupId = group | OidGroup.DisableSearchDS;
29  IntPtr intPtr2 = CryptFindOIDInfo(keyType, intPtr, dwGroupId);
30  if (intPtr2 != IntPtr.Zero)
31  {
32  return (CRYPT_OID_INFO)Marshal.PtrToStructure(intPtr2, typeof(CRYPT_OID_INFO));
33  }
34  }
35  IntPtr intPtr3 = CryptFindOIDInfo(keyType, intPtr, group);
36  if (intPtr3 != IntPtr.Zero)
37  {
38  return (CRYPT_OID_INFO)Marshal.PtrToStructure(intPtr3, typeof(CRYPT_OID_INFO));
39  }
40  if (group != 0)
41  {
42  IntPtr intPtr4 = CryptFindOIDInfo(keyType, intPtr, OidGroup.AllGroups);
43  if (intPtr4 != IntPtr.Zero)
44  {
45  return (CRYPT_OID_INFO)Marshal.PtrToStructure(intPtr4, typeof(CRYPT_OID_INFO));
46  }
47  }
48  return default(CRYPT_OID_INFO);
49  }
50  finally
51  {
52  if (intPtr != IntPtr.Zero)
53  {
54  Marshal.FreeCoTaskMem(intPtr);
55  }
56  }
57  }
58 
59  [SecuritySafeCritical]
60  internal static int GetAlgIdFromOid(string oid, OidGroup oidGroup)
61  {
62  if (string.Equals(oid, "2.16.840.1.101.3.4.2.1", StringComparison.Ordinal))
63  {
64  return 32780;
65  }
66  if (string.Equals(oid, "2.16.840.1.101.3.4.2.2", StringComparison.Ordinal))
67  {
68  return 32781;
69  }
70  if (string.Equals(oid, "2.16.840.1.101.3.4.2.3", StringComparison.Ordinal))
71  {
72  return 32782;
73  }
74  return FindOidInfo(OidKeyType.Oid, oid, oidGroup).AlgId;
75  }
76 
77  [SecuritySafeCritical]
78  internal static string GetFriendlyNameFromOid(string oid, OidGroup oidGroup)
79  {
80  CRYPT_OID_INFO cRYPT_OID_INFO = FindOidInfo(OidKeyType.Oid, oid, oidGroup);
81  return cRYPT_OID_INFO.pwszName;
82  }
83 
84  [SecuritySafeCritical]
85  internal static string GetOidFromFriendlyName(string friendlyName, OidGroup oidGroup)
86  {
87  CRYPT_OID_INFO cRYPT_OID_INFO = FindOidInfo(OidKeyType.Name, friendlyName, oidGroup);
88  return cRYPT_OID_INFO.pszOID;
89  }
90 
91  internal static int NameOrOidToAlgId(string oid, OidGroup oidGroup)
92  {
93  if (oid == null)
94  {
95  return 32772;
96  }
97  string text = CryptoConfig.MapNameToOID(oid, oidGroup);
98  if (text == null)
99  {
100  text = oid;
101  }
102  int algIdFromOid = GetAlgIdFromOid(text, oidGroup);
103  if (algIdFromOid == 0 || algIdFromOid == -1)
104  {
105  throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidOID"));
106  }
107  return algIdFromOid;
108  }
109 
110  internal static X509ContentType MapContentType(uint contentType)
111  {
112  switch (contentType)
113  {
114  case 1u:
115  return X509ContentType.Cert;
116  case 4u:
117  return X509ContentType.SerializedStore;
118  case 5u:
119  return X509ContentType.SerializedCert;
120  case 8u:
121  case 9u:
122  return X509ContentType.Pkcs7;
123  case 10u:
124  return X509ContentType.Authenticode;
125  case 12u:
126  return X509ContentType.Pfx;
127  default:
128  return X509ContentType.Unknown;
129  }
130  }
131 
132  internal static uint MapKeyStorageFlags(X509KeyStorageFlags keyStorageFlags)
133  {
134  if ((keyStorageFlags & ~(X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.UserProtected | X509KeyStorageFlags.PersistKeySet)) != 0)
135  {
136  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "keyStorageFlags");
137  }
138  uint num = 0u;
139  if ((keyStorageFlags & X509KeyStorageFlags.UserKeySet) == X509KeyStorageFlags.UserKeySet)
140  {
141  num |= 0x1000;
142  }
143  else if ((keyStorageFlags & X509KeyStorageFlags.MachineKeySet) == X509KeyStorageFlags.MachineKeySet)
144  {
145  num |= 0x20;
146  }
147  if ((keyStorageFlags & X509KeyStorageFlags.Exportable) == X509KeyStorageFlags.Exportable)
148  {
149  num |= 1;
150  }
151  if ((keyStorageFlags & X509KeyStorageFlags.UserProtected) == X509KeyStorageFlags.UserProtected)
152  {
153  num |= 2;
154  }
155  return num;
156  }
157 
158  [SecurityCritical]
159  internal static SafeCertStoreHandle ExportCertToMemoryStore(X509Certificate certificate)
160  {
161  SafeCertStoreHandle safeCertStoreHandle = SafeCertStoreHandle.InvalidHandle;
162  _OpenX509Store(2u, 8704u, null, ref safeCertStoreHandle);
163  _AddCertificateToStore(safeCertStoreHandle, certificate.CertContext);
164  return safeCertStoreHandle;
165  }
166 
167  [SecurityCritical]
168  internal static IntPtr PasswordToHGlobalUni(object password)
169  {
170  if (password != null)
171  {
172  string text = password as string;
173  if (text != null)
174  {
175  return Marshal.StringToHGlobalUni(text);
176  }
177  SecureString secureString = password as SecureString;
178  if (secureString != null)
179  {
180  return Marshal.SecureStringToGlobalAllocUnicode(secureString);
181  }
182  }
183  return IntPtr.Zero;
184  }
185 
186  [DllImport("crypt32")]
187  [SecurityCritical]
188  [SuppressUnmanagedCodeSecurity]
189  private static extern IntPtr CryptFindOIDInfo(OidKeyType dwKeyType, IntPtr pvKey, OidGroup dwGroupId);
190 
191  [MethodImpl(MethodImplOptions.InternalCall)]
192  [SecurityCritical]
193  internal static extern void _AddCertificateToStore(SafeCertStoreHandle safeCertStoreHandle, SafeCertContextHandle safeCertContext);
194 
195  [MethodImpl(MethodImplOptions.InternalCall)]
196  [SecurityCritical]
197  internal static extern void _DuplicateCertContext(IntPtr handle, ref SafeCertContextHandle safeCertContext);
198 
199  [MethodImpl(MethodImplOptions.InternalCall)]
200  [SecurityCritical]
201  internal static extern byte[] _ExportCertificatesToBlob(SafeCertStoreHandle safeCertStoreHandle, X509ContentType contentType, IntPtr password);
202 
203  [MethodImpl(MethodImplOptions.InternalCall)]
204  [SecurityCritical]
205  internal static extern byte[] _GetCertRawData(SafeCertContextHandle safeCertContext);
206 
207  [MethodImpl(MethodImplOptions.InternalCall)]
208  [SecurityCritical]
209  internal static extern void _GetDateNotAfter(SafeCertContextHandle safeCertContext, ref Win32Native.FILE_TIME fileTime);
210 
211  [MethodImpl(MethodImplOptions.InternalCall)]
212  [SecurityCritical]
213  internal static extern void _GetDateNotBefore(SafeCertContextHandle safeCertContext, ref Win32Native.FILE_TIME fileTime);
214 
215  [MethodImpl(MethodImplOptions.InternalCall)]
216  [SecurityCritical]
217  internal static extern string _GetIssuerName(SafeCertContextHandle safeCertContext, bool legacyV1Mode);
218 
219  [MethodImpl(MethodImplOptions.InternalCall)]
220  [SecurityCritical]
221  internal static extern string _GetPublicKeyOid(SafeCertContextHandle safeCertContext);
222 
223  [MethodImpl(MethodImplOptions.InternalCall)]
224  [SecurityCritical]
225  internal static extern byte[] _GetPublicKeyParameters(SafeCertContextHandle safeCertContext);
226 
227  [MethodImpl(MethodImplOptions.InternalCall)]
228  [SecurityCritical]
229  internal static extern byte[] _GetPublicKeyValue(SafeCertContextHandle safeCertContext);
230 
231  [MethodImpl(MethodImplOptions.InternalCall)]
232  [SecurityCritical]
233  internal static extern string _GetSubjectInfo(SafeCertContextHandle safeCertContext, uint displayType, bool legacyV1Mode);
234 
235  [MethodImpl(MethodImplOptions.InternalCall)]
236  [SecurityCritical]
237  internal static extern byte[] _GetSerialNumber(SafeCertContextHandle safeCertContext);
238 
239  [MethodImpl(MethodImplOptions.InternalCall)]
240  [SecurityCritical]
241  internal static extern byte[] _GetThumbprint(SafeCertContextHandle safeCertContext);
242 
243  [MethodImpl(MethodImplOptions.InternalCall)]
244  [SecurityCritical]
245  internal static extern void _LoadCertFromBlob(byte[] rawData, IntPtr password, uint dwFlags, bool persistKeySet, ref SafeCertContextHandle pCertCtx);
246 
247  [MethodImpl(MethodImplOptions.InternalCall)]
248  [SecurityCritical]
249  internal static extern void _LoadCertFromFile(string fileName, IntPtr password, uint dwFlags, bool persistKeySet, ref SafeCertContextHandle pCertCtx);
250 
251  [MethodImpl(MethodImplOptions.InternalCall)]
252  [SecurityCritical]
253  internal static extern void _OpenX509Store(uint storeType, uint flags, string storeName, ref SafeCertStoreHandle safeCertStoreHandle);
254 
255  [MethodImpl(MethodImplOptions.InternalCall)]
256  [SecurityCritical]
257  internal static extern uint _QueryCertBlobType(byte[] rawData);
258 
259  [MethodImpl(MethodImplOptions.InternalCall)]
260  [SecurityCritical]
261  internal static extern uint _QueryCertFileType(string fileName);
262  }
263 }
static unsafe IntPtr StringToHGlobalUni(string s)
Copies the contents of a managed T:System.String into unmanaged memory.
Definition: Marshal.cs:1515
static void FreeCoTaskMem(IntPtr ptr)
Frees a block of memory allocated by the unmanaged COM task memory allocator.
Definition: Marshal.cs:2147
StringComparison
Specifies the culture, case, and sort rules to be used by certain overloads of the M:System....
static IntPtr SecureStringToGlobalAllocUnicode(SecureString s)
Copies the contents of a managed T:System.Security.SecureString object into unmanaged memory.
Definition: Marshal.cs:2986
Definition: __Canon.cs:3
X509ContentType
Specifies the format of an X.509 certificate.
OidGroup
Identifies Windows cryptographic object identifier (OID) groups.
Definition: OidGroup.cs:4
static unsafe IntPtr StringToCoTaskMemAnsi(string s)
Copies the contents of a managed T:System.String to a block of memory allocated from the unmanaged CO...
Definition: Marshal.cs:2124
static void PrepareConstrainedRegions()
Designates a body of code as a constrained execution region (CER).
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks,...
Definition: Marshal.cs:15
MethodImplOptions
Defines the details of how a method is implemented.
static unsafe IntPtr StringToCoTaskMemUni(string s)
Copies the contents of a managed T:System.String to a block of memory allocated from the unmanaged CO...
Definition: Marshal.cs:2084
static void PtrToStructure(IntPtr ptr, object structure)
Marshals data from an unmanaged block of memory to a managed object.
Definition: Marshal.cs:1198
static readonly IntPtr Zero
A read-only field that represents a pointer or handle that has been initialized to zero.
Definition: IntPtr.cs:20
X509KeyStorageFlags
Defines where and how to import the private key of an X.509 certificate.
Provides a set of static methods and properties that provide support for compilers....