Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
StorePal.cs
Go to the documentation of this file.
1using System;
2using System.IO;
8
10
12{
14
16
17 SafeHandle IStorePal.SafeHandle
18 {
19 get
20 {
21 if (_certStore == null || _certStore.IsInvalid || _certStore.IsClosed)
22 {
24 }
25 return _certStore;
26 }
27 }
28
29 public static IStorePal FromHandle(IntPtr storeHandle)
30 {
31 if (storeHandle == IntPtr.Zero)
32 {
33 throw new ArgumentNullException("storeHandle");
34 }
35 SafeCertStoreHandle safeCertStoreHandle = global::Interop.crypt32.CertDuplicateStore(storeHandle);
36 if (safeCertStoreHandle == null || safeCertStoreHandle.IsInvalid)
37 {
39 }
40 return new StorePal(safeCertStoreHandle);
41 }
42
47
49 {
50 SafeCertContextHandle pCertContext = null;
51 while (global::Interop.crypt32.CertEnumCertificatesInStore(_certStore, ref pCertContext))
52 {
53 X509Certificate2 certificate = new X509Certificate2(pCertContext.DangerousGetHandle());
54 collection.Add(certificate);
55 }
56 }
57
58 public void Add(ICertificatePal certificate)
59 {
60 if (!global::Interop.crypt32.CertAddCertificateContextToStore(_certStore, ((CertificatePal)certificate).CertContext, CertStoreAddDisposition.CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, IntPtr.Zero))
61 {
62 throw Marshal.GetLastWin32Error().ToCryptographicException();
63 }
64 }
65
66 public unsafe void Remove(ICertificatePal certificate)
67 {
68 SafeCertContextHandle certContext = ((CertificatePal)certificate).CertContext;
69 SafeCertContextHandle pCertContext = null;
70 CERT_CONTEXT* certContext2 = certContext.CertContext;
71 if (global::Interop.crypt32.CertFindCertificateInStore(_certStore, CertFindType.CERT_FIND_EXISTING, certContext2, ref pCertContext))
72 {
73 CERT_CONTEXT* pCertContext2 = pCertContext.Disconnect();
74 if (!global::Interop.crypt32.CertDeleteCertificateFromStore(pCertContext2))
75 {
76 throw Marshal.GetLastWin32Error().ToCryptographicException();
77 }
78 GC.KeepAlive(certContext);
79 }
80 }
81
82 public void Dispose()
83 {
85 _certStore = null;
86 certStore?.Dispose();
87 }
88
89 internal StorePal(SafeCertStoreHandle certStore)
90 {
91 _certStore = certStore;
92 }
93
99
100 public unsafe byte[] Export(X509ContentType contentType, SafePasswordHandle password)
101 {
102 switch (contentType)
103 {
104 case X509ContentType.Cert:
105 {
106 SafeCertContextHandle pCertContext = null;
107 if (!global::Interop.crypt32.CertEnumCertificatesInStore(_certStore, ref pCertContext))
108 {
109 return null;
110 }
111 try
112 {
113 byte[] array2 = new byte[pCertContext.CertContext->cbCertEncoded];
114 Marshal.Copy((IntPtr)pCertContext.CertContext->pbCertEncoded, array2, 0, array2.Length);
115 GC.KeepAlive(pCertContext);
116 return array2;
117 }
118 finally
119 {
120 pCertContext.Dispose();
121 }
122 }
123 case X509ContentType.SerializedCert:
124 {
125 SafeCertContextHandle pCertContext2 = null;
126 if (!global::Interop.crypt32.CertEnumCertificatesInStore(_certStore, ref pCertContext2))
127 {
128 return null;
129 }
130 try
131 {
132 int pcbElement = 0;
133 if (!global::Interop.crypt32.CertSerializeCertificateStoreElement(pCertContext2, 0, null, ref pcbElement))
134 {
135 throw Marshal.GetHRForLastWin32Error().ToCryptographicException();
136 }
137 byte[] array3 = new byte[pcbElement];
138 if (!global::Interop.crypt32.CertSerializeCertificateStoreElement(pCertContext2, 0, array3, ref pcbElement))
139 {
140 throw Marshal.GetHRForLastWin32Error().ToCryptographicException();
141 }
142 return array3;
143 }
144 finally
145 {
146 pCertContext2.Dispose();
147 }
148 }
149 case X509ContentType.Pfx:
150 {
151 CRYPTOAPI_BLOB pPFX = new CRYPTOAPI_BLOB(0, null);
152 if (!global::Interop.crypt32.PFXExportCertStore(_certStore, ref pPFX, password, PFXExportFlags.REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY | PFXExportFlags.EXPORT_PRIVATE_KEYS))
153 {
154 throw Marshal.GetHRForLastWin32Error().ToCryptographicException();
155 }
156 byte[] array = new byte[pPFX.cbData];
157 fixed (byte* pbData = array)
158 {
159 pPFX.pbData = pbData;
160 if (!global::Interop.crypt32.PFXExportCertStore(_certStore, ref pPFX, password, PFXExportFlags.REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY | PFXExportFlags.EXPORT_PRIVATE_KEYS))
161 {
162 throw Marshal.GetHRForLastWin32Error().ToCryptographicException();
163 }
164 }
165 return array;
166 }
167 case X509ContentType.SerializedStore:
168 return SaveToMemoryStore(CertStoreSaveAs.CERT_STORE_SAVE_AS_STORE);
169 case X509ContentType.Pkcs7:
170 return SaveToMemoryStore(CertStoreSaveAs.CERT_STORE_SAVE_AS_PKCS7);
171 default:
173 }
174 }
175
176 private unsafe byte[] SaveToMemoryStore(CertStoreSaveAs dwSaveAs)
177 {
178 CRYPTOAPI_BLOB pvSaveToPara = new CRYPTOAPI_BLOB(0, null);
179 if (!global::Interop.crypt32.CertSaveStore(_certStore, CertEncodingType.All, dwSaveAs, CertStoreSaveTo.CERT_STORE_SAVE_TO_MEMORY, ref pvSaveToPara, 0))
180 {
181 throw Marshal.GetLastWin32Error().ToCryptographicException();
182 }
183 byte[] array = new byte[pvSaveToPara.cbData];
184 fixed (byte* pbData = array)
185 {
186 pvSaveToPara.pbData = pbData;
187 if (!global::Interop.crypt32.CertSaveStore(_certStore, CertEncodingType.All, dwSaveAs, CertStoreSaveTo.CERT_STORE_SAVE_TO_MEMORY, ref pvSaveToPara, 0))
188 {
189 throw Marshal.GetLastWin32Error().ToCryptographicException();
190 }
191 }
192 return array;
193 }
194
195 public static ILoaderPal FromBlob(ReadOnlySpan<byte> rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
196 {
197 return FromBlobOrFile(rawData, null, password, keyStorageFlags);
198 }
199
200 public static ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
201 {
202 return FromBlobOrFile(null, fileName, password, keyStorageFlags);
203 }
204
205 private unsafe static StorePal FromBlobOrFile(ReadOnlySpan<byte> rawData, string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
206 {
207 bool flag = fileName != null;
208 fixed (byte* pbData = rawData)
209 {
210 fixed (char* ptr = fileName)
211 {
212 CRYPTOAPI_BLOB cRYPTOAPI_BLOB = new CRYPTOAPI_BLOB((!flag) ? rawData.Length : 0, pbData);
213 bool flag2 = (keyStorageFlags & X509KeyStorageFlags.PersistKeySet) != 0;
214 PfxCertStoreFlags dwFlags = MapKeyStorageFlags(keyStorageFlags);
215 void* pvObject = (flag ? ((void*)ptr) : ((void*)(&cRYPTOAPI_BLOB)));
216 if (!global::Interop.crypt32.CryptQueryObject(flag ? CertQueryObjectType.CERT_QUERY_OBJECT_FILE : CertQueryObjectType.CERT_QUERY_OBJECT_BLOB, pvObject, ExpectedContentTypeFlags.CERT_QUERY_CONTENT_FLAG_CERT | ExpectedContentTypeFlags.CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE | ExpectedContentTypeFlags.CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT | ExpectedContentTypeFlags.CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED | ExpectedContentTypeFlags.CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED | ExpectedContentTypeFlags.CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED | ExpectedContentTypeFlags.CERT_QUERY_CONTENT_FLAG_PFX, ExpectedFormatTypeFlags.CERT_QUERY_FORMAT_FLAG_ALL, 0, IntPtr.Zero, out var pdwContentType, IntPtr.Zero, out var phCertStore, IntPtr.Zero, IntPtr.Zero))
217 {
218 throw Marshal.GetLastWin32Error().ToCryptographicException();
219 }
220 if (pdwContentType == ContentType.CERT_QUERY_CONTENT_PFX)
221 {
222 phCertStore.Dispose();
223 if (flag)
224 {
225 rawData = File.ReadAllBytes(fileName);
226 }
227 fixed (byte* pbData2 = rawData)
228 {
229 CRYPTOAPI_BLOB pPFX = new CRYPTOAPI_BLOB(rawData.Length, pbData2);
230 phCertStore = global::Interop.crypt32.PFXImportCertStore(ref pPFX, password, dwFlags);
231 if (phCertStore == null || phCertStore.IsInvalid)
232 {
233 throw Marshal.GetLastWin32Error().ToCryptographicException();
234 }
235 }
236 if (!flag2)
237 {
238 SafeCertContextHandle pCertContext = null;
239 while (global::Interop.crypt32.CertEnumCertificatesInStore(phCertStore, ref pCertContext))
240 {
241 CRYPTOAPI_BLOB cRYPTOAPI_BLOB2 = new CRYPTOAPI_BLOB(0, null);
242 if (!global::Interop.crypt32.CertSetCertificateContextProperty(pCertContext, CertContextPropId.CERT_CLR_DELETE_KEY_PROP_ID, CertSetPropertyFlags.CERT_SET_PROPERTY_INHIBIT_PERSIST_FLAG, &cRYPTOAPI_BLOB2))
243 {
244 throw Marshal.GetLastWin32Error().ToCryptographicException();
245 }
246 }
247 }
248 }
249 return new StorePal(phCertStore);
250 }
251 }
252 }
253
255 {
256 CertificatePal certificatePal = (CertificatePal)cert;
257 SafeCertStoreHandle safeCertStoreHandle = global::Interop.crypt32.CertOpenStore(CertStoreProvider.CERT_STORE_PROV_MEMORY, CertEncodingType.All, IntPtr.Zero, CertStoreFlags.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG | CertStoreFlags.CERT_STORE_ENUM_ARCHIVED_FLAG | CertStoreFlags.CERT_STORE_CREATE_NEW_FLAG, null);
258 if (safeCertStoreHandle.IsInvalid)
259 {
260 throw Marshal.GetHRForLastWin32Error().ToCryptographicException();
261 }
262 if (!global::Interop.crypt32.CertAddCertificateLinkToStore(safeCertStoreHandle, certificatePal.CertContext, CertStoreAddDisposition.CERT_STORE_ADD_ALWAYS, IntPtr.Zero))
263 {
264 throw Marshal.GetHRForLastWin32Error().ToCryptographicException();
265 }
266 return new StorePal(safeCertStoreHandle);
267 }
268
270 {
271 SafeCertStoreHandle safeCertStoreHandle = global::Interop.crypt32.CertOpenStore(CertStoreProvider.CERT_STORE_PROV_MEMORY, CertEncodingType.All, IntPtr.Zero, CertStoreFlags.CERT_STORE_ENUM_ARCHIVED_FLAG | CertStoreFlags.CERT_STORE_CREATE_NEW_FLAG, null);
272 if (safeCertStoreHandle.IsInvalid)
273 {
274 throw Marshal.GetHRForLastWin32Error().ToCryptographicException();
275 }
276 for (int i = 0; i < certificates.Count; i++)
277 {
278 SafeCertContextHandle certContext = ((CertificatePal)certificates[i].Pal).CertContext;
279 if (!global::Interop.crypt32.CertAddCertificateLinkToStore(safeCertStoreHandle, certContext, CertStoreAddDisposition.CERT_STORE_ADD_ALWAYS, IntPtr.Zero))
280 {
281 throw Marshal.GetLastWin32Error().ToCryptographicException();
282 }
283 }
284 return new StorePal(safeCertStoreHandle);
285 }
286
287 public static IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags)
288 {
289 CertStoreFlags dwFlags = MapX509StoreFlags(storeLocation, openFlags);
290 SafeCertStoreHandle safeCertStoreHandle = global::Interop.crypt32.CertOpenStore(CertStoreProvider.CERT_STORE_PROV_SYSTEM_W, CertEncodingType.All, IntPtr.Zero, dwFlags, storeName);
291 if (safeCertStoreHandle.IsInvalid)
292 {
293 throw Marshal.GetLastWin32Error().ToCryptographicException();
294 }
295 global::Interop.crypt32.CertControlStore(safeCertStoreHandle, CertControlStoreFlags.None, CertControlStoreType.CERT_STORE_CTRL_AUTO_RESYNC, IntPtr.Zero);
296 return new StorePal(safeCertStoreHandle);
297 }
298
300 {
301 PfxCertStoreFlags pfxCertStoreFlags = PfxCertStoreFlags.None;
302 if ((keyStorageFlags & X509KeyStorageFlags.UserKeySet) == X509KeyStorageFlags.UserKeySet)
303 {
304 pfxCertStoreFlags |= PfxCertStoreFlags.CRYPT_USER_KEYSET;
305 }
306 else if ((keyStorageFlags & X509KeyStorageFlags.MachineKeySet) == X509KeyStorageFlags.MachineKeySet)
307 {
308 pfxCertStoreFlags |= PfxCertStoreFlags.CRYPT_MACHINE_KEYSET;
309 }
310 if ((keyStorageFlags & X509KeyStorageFlags.Exportable) == X509KeyStorageFlags.Exportable)
311 {
312 pfxCertStoreFlags |= PfxCertStoreFlags.CRYPT_EXPORTABLE;
313 }
314 if ((keyStorageFlags & X509KeyStorageFlags.UserProtected) == X509KeyStorageFlags.UserProtected)
315 {
316 pfxCertStoreFlags |= PfxCertStoreFlags.CRYPT_USER_PROTECTED;
317 }
318 if ((keyStorageFlags & X509KeyStorageFlags.EphemeralKeySet) == X509KeyStorageFlags.EphemeralKeySet)
319 {
320 pfxCertStoreFlags |= PfxCertStoreFlags.PKCS12_ALWAYS_CNG_KSP | PfxCertStoreFlags.PKCS12_NO_PERSIST_KEY;
321 }
322 return pfxCertStoreFlags;
323 }
324
325 private static CertStoreFlags MapX509StoreFlags(StoreLocation storeLocation, OpenFlags flags)
326 {
327 CertStoreFlags certStoreFlags = CertStoreFlags.None;
328 switch ((uint)(flags & (OpenFlags.ReadWrite | OpenFlags.MaxAllowed)))
329 {
330 case 0u:
331 certStoreFlags |= CertStoreFlags.CERT_STORE_READONLY_FLAG;
332 break;
333 case 2u:
334 certStoreFlags |= CertStoreFlags.CERT_STORE_MAXIMUM_ALLOWED_FLAG;
335 break;
336 }
337 if ((flags & OpenFlags.OpenExistingOnly) == OpenFlags.OpenExistingOnly)
338 {
339 certStoreFlags |= CertStoreFlags.CERT_STORE_OPEN_EXISTING_FLAG;
340 }
341 if ((flags & OpenFlags.IncludeArchived) == OpenFlags.IncludeArchived)
342 {
343 certStoreFlags |= CertStoreFlags.CERT_STORE_ENUM_ARCHIVED_FLAG;
344 }
345 switch (storeLocation)
346 {
347 case StoreLocation.LocalMachine:
348 certStoreFlags |= CertStoreFlags.CERT_SYSTEM_STORE_LOCAL_MACHINE;
349 break;
350 case StoreLocation.CurrentUser:
351 certStoreFlags |= CertStoreFlags.CERT_SYSTEM_STORE_CURRENT_USER;
352 break;
353 }
354 return certStoreFlags;
355 }
356}
unsafe byte[] SaveToMemoryStore(CertStoreSaveAs dwSaveAs)
Definition StorePal.cs:176
SafeCertStoreHandle _certStore
Definition StorePal.cs:13
void CopyTo(X509Certificate2Collection collection)
Definition StorePal.cs:48
StorePal(SafeCertStoreHandle certStore)
Definition StorePal.cs:89
void Add(ICertificatePal certificate)
Definition StorePal.cs:58
static IExportPal FromCertificate(ICertificatePalCore cert)
Definition StorePal.cs:254
static PfxCertStoreFlags MapKeyStorageFlags(X509KeyStorageFlags keyStorageFlags)
Definition StorePal.cs:299
void CloneTo(X509Certificate2Collection collection)
Definition StorePal.cs:43
unsafe byte[] Export(X509ContentType contentType, SafePasswordHandle password)
Definition StorePal.cs:100
static IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags)
Definition StorePal.cs:287
static unsafe StorePal FromBlobOrFile(ReadOnlySpan< byte > rawData, string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
Definition StorePal.cs:205
static ILoaderPal FromBlob(ReadOnlySpan< byte > rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
Definition StorePal.cs:195
void MoveTo(X509Certificate2Collection collection)
Definition StorePal.cs:94
static IStorePal FromHandle(IntPtr storeHandle)
Definition StorePal.cs:29
unsafe void Remove(ICertificatePal certificate)
Definition StorePal.cs:66
static CertStoreFlags MapX509StoreFlags(StoreLocation storeLocation, OpenFlags flags)
Definition StorePal.cs:325
static ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
Definition StorePal.cs:200
static IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates)
Definition StorePal.cs:269
static void KeepAlive(object? obj)
Definition GC.cs:180
Definition GC.cs:8
static byte[] ReadAllBytes(string path)
Definition File.cs:314
static void Copy(int[] source, int startIndex, IntPtr destination, int length)
Definition Marshal.cs:800
static string Cryptography_InvalidStoreHandle
Definition SR.cs:76
static string Cryptography_X509_InvalidContentType
Definition SR.cs:94
static string Cryptography_X509_StoreNotOpen
Definition SR.cs:102
Definition SR.cs:7
static readonly IntPtr Zero
Definition IntPtr.cs:18