PageRenderTime 49ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/referencesource/System/security/system/security/cryptography/x509/x509certificate2.cs

https://github.com/pruiz/mono
C# | 1183 lines | 945 code | 161 blank | 77 comment | 136 complexity | 4d275f4bd2a963b13efc0cb91280314c MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. // ==++==
  2. //
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. //
  5. // ==--==
  6. //
  7. // X509Certificate2.cs
  8. //
  9. // 09/22/2002
  10. //
  11. namespace System.Security.Cryptography.X509Certificates {
  12. using System;
  13. using System.Diagnostics;
  14. using System.Diagnostics.CodeAnalysis;
  15. using System.IO;
  16. using System.Text;
  17. using System.Runtime.InteropServices;
  18. using System.Runtime.InteropServices.ComTypes;
  19. using System.Runtime.Serialization;
  20. using System.Security.Cryptography;
  21. using System.Security.Permissions;
  22. using System.Runtime.Versioning;
  23. using _FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
  24. public enum X509NameType {
  25. SimpleName = 0,
  26. EmailName,
  27. UpnName,
  28. DnsName,
  29. DnsFromAlternativeName,
  30. UrlName
  31. }
  32. public enum X509IncludeOption {
  33. None = 0,
  34. ExcludeRoot,
  35. EndCertOnly,
  36. WholeChain
  37. }
  38. public sealed class PublicKey {
  39. private AsnEncodedData m_encodedKeyValue;
  40. private AsnEncodedData m_encodedParameters;
  41. private Oid m_oid;
  42. private uint m_aiPubKey = 0;
  43. private byte[] m_cspBlobData = null;
  44. private AsymmetricAlgorithm m_key = null;
  45. private PublicKey() {}
  46. public PublicKey (Oid oid, AsnEncodedData parameters, AsnEncodedData keyValue) {
  47. m_oid = new Oid(oid);
  48. m_encodedParameters = new AsnEncodedData(parameters);
  49. m_encodedKeyValue = new AsnEncodedData(keyValue);
  50. }
  51. internal PublicKey (PublicKey publicKey) {
  52. m_oid = new Oid(publicKey.m_oid);
  53. m_encodedParameters = new AsnEncodedData(publicKey.m_encodedParameters);
  54. m_encodedKeyValue = new AsnEncodedData(publicKey.m_encodedKeyValue);
  55. }
  56. internal uint AlgorithmId {
  57. #if FEATURE_CORESYSTEM
  58. [SecuritySafeCritical]
  59. #endif
  60. get {
  61. if (m_aiPubKey == 0)
  62. m_aiPubKey = X509Utils.OidToAlgId(m_oid.Value);
  63. return m_aiPubKey;
  64. }
  65. }
  66. private byte[] CspBlobData {
  67. #if FEATURE_CORESYSTEM
  68. [SecuritySafeCritical]
  69. #endif
  70. get {
  71. if (m_cspBlobData == null)
  72. DecodePublicKeyObject(AlgorithmId, m_encodedKeyValue.RawData, m_encodedParameters.RawData, out m_cspBlobData);
  73. return m_cspBlobData;
  74. }
  75. }
  76. public AsymmetricAlgorithm Key {
  77. #if FEATURE_CORESYSTEM
  78. [SecuritySafeCritical]
  79. #endif
  80. get {
  81. if (m_key == null) {
  82. switch (AlgorithmId) {
  83. case CAPI.CALG_RSA_KEYX:
  84. case CAPI.CALG_RSA_SIGN:
  85. RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
  86. rsa.ImportCspBlob(CspBlobData);
  87. m_key = rsa;
  88. break;
  89. #if !FEATURE_CORESYSTEM
  90. case CAPI.CALG_DSS_SIGN:
  91. DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
  92. dsa.ImportCspBlob(CspBlobData);
  93. m_key = dsa;
  94. break;
  95. #endif
  96. default:
  97. throw new NotSupportedException(SR.GetString(SR.NotSupported_KeyAlgorithm));
  98. }
  99. }
  100. return m_key;
  101. }
  102. }
  103. public Oid Oid {
  104. get { return new Oid(m_oid); }
  105. }
  106. public AsnEncodedData EncodedKeyValue {
  107. get { return m_encodedKeyValue; }
  108. }
  109. public AsnEncodedData EncodedParameters {
  110. get { return m_encodedParameters; }
  111. }
  112. //
  113. // private static methods.
  114. //
  115. #if FEATURE_CORESYSTEM
  116. [SecuritySafeCritical]
  117. #endif
  118. private static void DecodePublicKeyObject(uint aiPubKey, byte[] encodedKeyValue, byte[] encodedParameters, out byte[] decodedData) {
  119. // Initialize the out parameter
  120. decodedData = null;
  121. IntPtr pszStructType = IntPtr.Zero;
  122. switch (aiPubKey) {
  123. case CAPI.CALG_DSS_SIGN:
  124. pszStructType = new IntPtr(CAPI.X509_DSS_PUBLICKEY);
  125. break;
  126. case CAPI.CALG_RSA_SIGN:
  127. case CAPI.CALG_RSA_KEYX:
  128. pszStructType = new IntPtr(CAPI.RSA_CSP_PUBLICKEYBLOB);
  129. break;
  130. case CAPI.CALG_DH_SF:
  131. case CAPI.CALG_DH_EPHEM:
  132. // We don't support DH for now
  133. throw new NotSupportedException(SR.GetString(SR.NotSupported_KeyAlgorithm));
  134. default:
  135. // We should never get here
  136. Debug.Assert(false);
  137. throw new NotSupportedException(SR.GetString(SR.NotSupported_KeyAlgorithm));
  138. }
  139. SafeLocalAllocHandle decodedKeyValue = null;
  140. uint cbDecodedKeyValue = 0;
  141. bool result = CAPI.DecodeObject(pszStructType,
  142. encodedKeyValue,
  143. out decodedKeyValue,
  144. out cbDecodedKeyValue);
  145. if (!result)
  146. throw new CryptographicException(Marshal.GetLastWin32Error());
  147. if ((uint) pszStructType == CAPI.RSA_CSP_PUBLICKEYBLOB) {
  148. decodedData = new byte[cbDecodedKeyValue];
  149. Marshal.Copy(decodedKeyValue.DangerousGetHandle(), decodedData, 0, decodedData.Length);
  150. } else if ((uint) pszStructType == CAPI.X509_DSS_PUBLICKEY) {
  151. // We need to decode the parameters as well
  152. SafeLocalAllocHandle decodedParameters = null;
  153. uint cbDecodedParameters = 0;
  154. result = CAPI.DecodeObject(new IntPtr(CAPI.X509_DSS_PARAMETERS),
  155. encodedParameters,
  156. out decodedParameters,
  157. out cbDecodedParameters);
  158. if (!result)
  159. throw new CryptographicException(Marshal.GetLastWin32Error());
  160. decodedData = ConstructDSSPubKeyCspBlob(decodedKeyValue, decodedParameters);
  161. decodedParameters.Dispose();
  162. }
  163. decodedKeyValue.Dispose();
  164. }
  165. #if FEATURE_CORESYSTEM
  166. [SecuritySafeCritical]
  167. #endif
  168. private static byte[] ConstructDSSPubKeyCspBlob (SafeLocalAllocHandle decodedKeyValue,
  169. SafeLocalAllocHandle decodedParameters) {
  170. // The CAPI DSS public key representation consists of the following sequence:
  171. // - PUBLICKEYSTRUC
  172. // - DSSPUBKEY
  173. // - rgbP[cbKey]
  174. // - rgbQ[20]
  175. // - rgbG[cbKey]
  176. // - rgbY[cbKey]
  177. // - DSSSEED
  178. CAPI.CRYPTOAPI_BLOB pDssPubKey = (CAPI.CRYPTOAPI_BLOB) Marshal.PtrToStructure(decodedKeyValue.DangerousGetHandle(), typeof(CAPI.CRYPTOAPI_BLOB));
  179. CAPI.CERT_DSS_PARAMETERS pDssParameters = (CAPI.CERT_DSS_PARAMETERS) Marshal.PtrToStructure(decodedParameters.DangerousGetHandle(), typeof(CAPI.CERT_DSS_PARAMETERS));
  180. uint cbKey = pDssParameters.p.cbData;
  181. if (cbKey == 0)
  182. throw new CryptographicException(CAPI.NTE_BAD_PUBLIC_KEY);
  183. const uint DSS_Q_LEN = 20;
  184. uint cbKeyBlob = 8 /* sizeof(CAPI.BLOBHEADER) */ + 8 /* sizeof(CAPI.DSSPUBKEY) */ +
  185. cbKey + DSS_Q_LEN + cbKey + cbKey + 24 /* sizeof(CAPI.DSSSEED) */;
  186. MemoryStream keyBlob = new MemoryStream((int) cbKeyBlob);
  187. BinaryWriter bw = new BinaryWriter(keyBlob);
  188. // PUBLICKEYSTRUC
  189. bw.Write(CAPI.PUBLICKEYBLOB); // pPubKeyStruc->bType = PUBLICKEYBLOB
  190. bw.Write(CAPI.CUR_BLOB_VERSION); // pPubKeyStruc->bVersion = CUR_BLOB_VERSION
  191. bw.Write((short) 0); // pPubKeyStruc->reserved = 0;
  192. bw.Write(CAPI.CALG_DSS_SIGN); // pPubKeyStruc->aiKeyAlg = CALG_DSS_SIGN;
  193. // DSSPUBKEY
  194. bw.Write(CAPI.DSS_MAGIC); // pCspPubKey->magic = DSS_MAGIC; We are constructing a DSS1 Csp blob.
  195. bw.Write(cbKey * 8); // pCspPubKey->bitlen = cbKey * 8;
  196. // rgbP[cbKey]
  197. byte[] p = new byte[pDssParameters.p.cbData];
  198. Marshal.Copy(pDssParameters.p.pbData, p, 0, p.Length);
  199. bw.Write(p);
  200. // rgbQ[20]
  201. uint cb = pDssParameters.q.cbData;
  202. if (cb == 0 || cb > DSS_Q_LEN)
  203. throw new CryptographicException(CAPI.NTE_BAD_PUBLIC_KEY);
  204. byte[] q = new byte[pDssParameters.q.cbData];
  205. Marshal.Copy(pDssParameters.q.pbData, q, 0, q.Length);
  206. bw.Write(q);
  207. if (DSS_Q_LEN > cb)
  208. bw.Write(new byte[DSS_Q_LEN - cb]);
  209. // rgbG[cbKey]
  210. cb = pDssParameters.g.cbData;
  211. if (cb == 0 || cb > cbKey)
  212. throw new CryptographicException(CAPI.NTE_BAD_PUBLIC_KEY);
  213. byte[] g = new byte[pDssParameters.g.cbData];
  214. Marshal.Copy(pDssParameters.g.pbData, g, 0, g.Length);
  215. bw.Write(g);
  216. if (cbKey > cb)
  217. bw.Write(new byte[cbKey - cb]);
  218. // rgbY[cbKey]
  219. cb = pDssPubKey.cbData;
  220. if (cb == 0 || cb > cbKey)
  221. throw new CryptographicException(CAPI.NTE_BAD_PUBLIC_KEY);
  222. byte[] y = new byte[pDssPubKey.cbData];
  223. Marshal.Copy(pDssPubKey.pbData, y, 0, y.Length);
  224. bw.Write(y);
  225. if (cbKey > cb)
  226. bw.Write(new byte[cbKey - cb]);
  227. // DSSSEED: set counter to 0xFFFFFFFF to indicate not available
  228. bw.Write(0xFFFFFFFF);
  229. bw.Write(new byte[20]);
  230. return keyBlob.ToArray();
  231. }
  232. }
  233. #if !FEATURE_CORESYSTEM
  234. [Serializable]
  235. #endif
  236. public class X509Certificate2 : X509Certificate {
  237. private int m_version;
  238. private DateTime m_notBefore;
  239. private DateTime m_notAfter;
  240. private AsymmetricAlgorithm m_privateKey;
  241. private PublicKey m_publicKey;
  242. private X509ExtensionCollection m_extensions;
  243. private Oid m_signatureAlgorithm;
  244. private X500DistinguishedName m_subjectName;
  245. private X500DistinguishedName m_issuerName;
  246. #if FEATURE_CORESYSTEM
  247. [SecurityCritical]
  248. #endif
  249. private SafeCertContextHandle m_safeCertContext = SafeCertContextHandle.InvalidHandle;
  250. private static int s_publicKeyOffset;
  251. //
  252. // public constructors
  253. //
  254. #if FEATURE_CORESYSTEM
  255. [SecuritySafeCritical]
  256. #endif
  257. public X509Certificate2 () : base() {}
  258. #if FEATURE_CORESYSTEM
  259. [SecuritySafeCritical]
  260. #endif
  261. public X509Certificate2 (byte[] rawData) : base (rawData) {
  262. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  263. }
  264. #if FEATURE_CORESYSTEM
  265. [SecuritySafeCritical]
  266. #endif
  267. public X509Certificate2 (byte[] rawData, string password) : base (rawData, password) {
  268. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  269. }
  270. #if !FEATURE_CORESYSTEM
  271. public X509Certificate2 (byte[] rawData, SecureString password) : base (rawData, password) {
  272. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  273. }
  274. #endif
  275. #if FEATURE_CORESYSTEM
  276. [SecuritySafeCritical]
  277. #endif
  278. public X509Certificate2 (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags) : base (rawData, password, keyStorageFlags) {
  279. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  280. }
  281. #if !FEATURE_CORESYSTEM
  282. public X509Certificate2 (byte[] rawData, SecureString password, X509KeyStorageFlags keyStorageFlags) : base (rawData, password, keyStorageFlags) {
  283. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  284. }
  285. #endif
  286. #if FEATURE_CORESYSTEM
  287. [SecuritySafeCritical]
  288. #endif
  289. [ResourceExposure(ResourceScope.Machine)]
  290. #if !FEATURE_CORESYSTEM
  291. [ResourceConsumption(ResourceScope.Machine)]
  292. #endif
  293. public X509Certificate2 (string fileName) : base (fileName) {
  294. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  295. }
  296. #if FEATURE_CORESYSTEM
  297. [SecuritySafeCritical]
  298. #endif
  299. [ResourceExposure(ResourceScope.Machine)]
  300. #if !FEATURE_CORESYSTEM
  301. [ResourceConsumption(ResourceScope.Machine)]
  302. #endif
  303. public X509Certificate2 (string fileName, string password) : base (fileName, password) {
  304. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  305. }
  306. #if !FEATURE_CORESYSTEM
  307. [ResourceExposure(ResourceScope.Machine)]
  308. [ResourceConsumption(ResourceScope.Machine)]
  309. public X509Certificate2 (string fileName, SecureString password) : base (fileName, password) {
  310. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  311. }
  312. #endif
  313. #if FEATURE_CORESYSTEM
  314. [SecuritySafeCritical]
  315. #endif
  316. [ResourceExposure(ResourceScope.Machine)]
  317. #if !FEATURE_CORESYSTEM
  318. [ResourceConsumption(ResourceScope.Machine)]
  319. #endif
  320. public X509Certificate2 (string fileName, string password, X509KeyStorageFlags keyStorageFlags) : base (fileName, password, keyStorageFlags) {
  321. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  322. }
  323. #if !FEATURE_CORESYSTEM
  324. [ResourceExposure(ResourceScope.Machine)]
  325. [ResourceConsumption(ResourceScope.Machine)]
  326. public X509Certificate2 (string fileName, SecureString password, X509KeyStorageFlags keyStorageFlags) : base (fileName, password, keyStorageFlags) {
  327. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  328. }
  329. #endif
  330. #if FEATURE_CORESYSTEM
  331. [SecuritySafeCritical]
  332. #endif
  333. // Package protected constructor for creating a certificate from a PCCERT_CONTEXT
  334. [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
  335. [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
  336. public X509Certificate2 (IntPtr handle) : base (handle) {
  337. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  338. }
  339. #if FEATURE_CORESYSTEM
  340. [SecuritySafeCritical]
  341. #endif
  342. public X509Certificate2 (X509Certificate certificate) : base(certificate) {
  343. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  344. }
  345. #if !FEATURE_CORESYSTEM
  346. [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
  347. [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
  348. protected X509Certificate2(SerializationInfo info, StreamingContext context) : base(info, context) {
  349. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  350. }
  351. #endif
  352. public override string ToString() {
  353. return base.ToString(true);
  354. }
  355. #if FEATURE_CORESYSTEM
  356. [SecuritySafeCritical]
  357. #endif
  358. public override string ToString(bool verbose) {
  359. if (verbose == false || m_safeCertContext.IsInvalid)
  360. return ToString();
  361. StringBuilder sb = new StringBuilder();
  362. string newLine = Environment.NewLine;
  363. string newLine2 = newLine + newLine;
  364. string newLinesp2 = newLine + " ";
  365. // Version
  366. sb.Append("[Version]");
  367. sb.Append(newLinesp2);
  368. sb.Append("V" + this.Version);
  369. // Subject
  370. sb.Append(newLine2);
  371. sb.Append("[Subject]");
  372. sb.Append(newLinesp2);
  373. sb.Append(this.SubjectName.Name);
  374. string simpleName = GetNameInfo(X509NameType.SimpleName, false);
  375. if (simpleName.Length > 0) {
  376. sb.Append(newLinesp2);
  377. sb.Append("Simple Name: ");
  378. sb.Append(simpleName);
  379. }
  380. string emailName = GetNameInfo(X509NameType.EmailName, false);
  381. if (emailName.Length > 0) {
  382. sb.Append(newLinesp2);
  383. sb.Append("Email Name: ");
  384. sb.Append(emailName);
  385. }
  386. string upnName = GetNameInfo(X509NameType.UpnName, false);
  387. if (upnName.Length > 0) {
  388. sb.Append(newLinesp2);
  389. sb.Append("UPN Name: ");
  390. sb.Append(upnName);
  391. }
  392. string dnsName = GetNameInfo(X509NameType.DnsName, false);
  393. if (dnsName.Length > 0) {
  394. sb.Append(newLinesp2);
  395. sb.Append("DNS Name: ");
  396. sb.Append(dnsName);
  397. }
  398. // Issuer
  399. sb.Append(newLine2);
  400. sb.Append("[Issuer]");
  401. sb.Append(newLinesp2);
  402. sb.Append(this.IssuerName.Name);
  403. simpleName = GetNameInfo(X509NameType.SimpleName, true);
  404. if (simpleName.Length > 0) {
  405. sb.Append(newLinesp2);
  406. sb.Append("Simple Name: ");
  407. sb.Append(simpleName);
  408. }
  409. emailName = GetNameInfo(X509NameType.EmailName, true);
  410. if (emailName.Length > 0) {
  411. sb.Append(newLinesp2);
  412. sb.Append("Email Name: ");
  413. sb.Append(emailName);
  414. }
  415. upnName = GetNameInfo(X509NameType.UpnName, true);
  416. if (upnName.Length > 0) {
  417. sb.Append(newLinesp2);
  418. sb.Append("UPN Name: ");
  419. sb.Append(upnName);
  420. }
  421. dnsName = GetNameInfo(X509NameType.DnsName, true);
  422. if (dnsName.Length > 0) {
  423. sb.Append(newLinesp2);
  424. sb.Append("DNS Name: ");
  425. sb.Append(dnsName);
  426. }
  427. // Serial Number
  428. sb.Append(newLine2);
  429. sb.Append("[Serial Number]");
  430. sb.Append(newLinesp2);
  431. sb.Append(this.SerialNumber);
  432. // NotBefore
  433. sb.Append(newLine2);
  434. sb.Append("[Not Before]");
  435. sb.Append(newLinesp2);
  436. sb.Append(FormatDate(this.NotBefore));
  437. // NotAfter
  438. sb.Append(newLine2);
  439. sb.Append("[Not After]");
  440. sb.Append(newLinesp2);
  441. sb.Append(FormatDate(this.NotAfter));
  442. // Thumbprint
  443. sb.Append(newLine2);
  444. sb.Append("[Thumbprint]");
  445. sb.Append(newLinesp2);
  446. sb.Append(this.Thumbprint);
  447. // Signature Algorithm
  448. sb.Append(newLine2);
  449. sb.Append("[Signature Algorithm]");
  450. sb.Append(newLinesp2);
  451. sb.Append(this.SignatureAlgorithm.FriendlyName + "(" + this.SignatureAlgorithm.Value + ")");
  452. // Public Key
  453. sb.Append(newLine2);
  454. sb.Append("[Public Key]");
  455. // It could throw if it's some user-defined CryptoServiceProvider
  456. try {
  457. PublicKey pubKey = this.PublicKey;
  458. string temp = pubKey.Oid.FriendlyName;
  459. sb.Append(newLinesp2);
  460. sb.Append("Algorithm: ");
  461. sb.Append(temp);
  462. // So far, we only support RSACryptoServiceProvider & DSACryptoServiceProvider Keys
  463. try {
  464. temp = pubKey.Key.KeySize.ToString();
  465. sb.Append(newLinesp2);
  466. sb.Append("Length: ");
  467. sb.Append(temp);
  468. }
  469. catch (NotSupportedException) {
  470. }
  471. temp = pubKey.EncodedKeyValue.Format(true);
  472. sb.Append(newLinesp2);
  473. sb.Append("Key Blob: ");
  474. sb.Append(temp);
  475. temp = pubKey.EncodedParameters.Format(true);
  476. sb.Append(newLinesp2);
  477. sb.Append("Parameters: ");
  478. sb.Append(temp);
  479. }
  480. catch (CryptographicException) {
  481. }
  482. // Private key
  483. AppendPrivateKeyInfo(sb);
  484. // Extensions
  485. X509ExtensionCollection extensions = this.Extensions;
  486. if (extensions.Count > 0) {
  487. sb.Append(newLine2);
  488. sb.Append("[Extensions]");
  489. string temp;
  490. foreach (X509Extension extension in extensions) {
  491. try {
  492. temp = extension.Oid.FriendlyName;
  493. sb.Append(newLine);
  494. sb.Append("* " + temp);
  495. sb.Append("(" + extension.Oid.Value + "):");
  496. temp = extension.Format(true);
  497. sb.Append(newLinesp2);
  498. sb.Append(temp);
  499. }
  500. catch (CryptographicException) {
  501. }
  502. }
  503. }
  504. sb.Append(newLine);
  505. return sb.ToString();
  506. }
  507. public bool Archived {
  508. #if FEATURE_CORESYSTEM
  509. [SecuritySafeCritical]
  510. #endif
  511. get {
  512. if (m_safeCertContext.IsInvalid)
  513. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  514. uint cbData = 0;
  515. return CAPI.CertGetCertificateContextProperty(m_safeCertContext,
  516. CAPI.CERT_ARCHIVED_PROP_ID,
  517. SafeLocalAllocHandle.InvalidHandle,
  518. ref cbData);
  519. }
  520. #if FEATURE_CORESYSTEM
  521. [SecuritySafeCritical]
  522. #endif
  523. set {
  524. SafeLocalAllocHandle ptr = SafeLocalAllocHandle.InvalidHandle;
  525. if (value == true)
  526. ptr = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB))));
  527. if (!CAPI.CertSetCertificateContextProperty(m_safeCertContext,
  528. CAPI.CERT_ARCHIVED_PROP_ID,
  529. 0,
  530. ptr))
  531. throw new CryptographicException(Marshal.GetLastWin32Error());
  532. ptr.Dispose();
  533. }
  534. }
  535. public X509ExtensionCollection Extensions {
  536. #if FEATURE_CORESYSTEM
  537. [SecuritySafeCritical]
  538. #endif
  539. get {
  540. if (m_safeCertContext.IsInvalid)
  541. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  542. if (m_extensions == null)
  543. m_extensions = new X509ExtensionCollection(m_safeCertContext);
  544. return m_extensions;
  545. }
  546. }
  547. public string FriendlyName {
  548. #if FEATURE_CORESYSTEM
  549. [SecuritySafeCritical]
  550. #endif
  551. get {
  552. if (m_safeCertContext.IsInvalid)
  553. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  554. SafeLocalAllocHandle ptr = SafeLocalAllocHandle.InvalidHandle;
  555. uint cbData = 0;
  556. if (!CAPI.CertGetCertificateContextProperty(m_safeCertContext,
  557. CAPI.CERT_FRIENDLY_NAME_PROP_ID,
  558. ptr,
  559. ref cbData))
  560. return String.Empty;
  561. ptr = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(cbData));
  562. if (!CAPI.CertGetCertificateContextProperty(m_safeCertContext,
  563. CAPI.CERT_FRIENDLY_NAME_PROP_ID,
  564. ptr,
  565. ref cbData))
  566. return String.Empty;
  567. string friendlyName = Marshal.PtrToStringUni(ptr.DangerousGetHandle());
  568. ptr.Dispose();
  569. return friendlyName;
  570. }
  571. #if FEATURE_CORESYSTEM
  572. [SecuritySafeCritical]
  573. #endif
  574. set {
  575. if (m_safeCertContext.IsInvalid)
  576. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  577. if (value == null)
  578. value = String.Empty;
  579. SetFriendlyNameExtendedProperty(m_safeCertContext, value);
  580. }
  581. }
  582. public X500DistinguishedName IssuerName {
  583. #if FEATURE_CORESYSTEM
  584. [SecuritySafeCritical]
  585. #endif
  586. get {
  587. if (m_safeCertContext.IsInvalid)
  588. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  589. if (m_issuerName == null) {
  590. unsafe {
  591. CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) m_safeCertContext.DangerousGetHandle());
  592. CAPI.CERT_INFO pCertInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO));
  593. m_issuerName = new X500DistinguishedName(pCertInfo.Issuer);
  594. }
  595. }
  596. return m_issuerName;
  597. }
  598. }
  599. public DateTime NotAfter {
  600. #if FEATURE_CORESYSTEM
  601. [SecuritySafeCritical]
  602. #endif
  603. get {
  604. if (m_safeCertContext.IsInvalid)
  605. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  606. if (m_notAfter == DateTime.MinValue) {
  607. unsafe {
  608. CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) m_safeCertContext.DangerousGetHandle());
  609. CAPI.CERT_INFO pCertInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO));
  610. long dt = (((long)(uint)pCertInfo.NotAfter.dwHighDateTime) << 32) | ((long)(uint)pCertInfo.NotAfter.dwLowDateTime);
  611. m_notAfter = DateTime.FromFileTime(dt);
  612. }
  613. }
  614. return m_notAfter;
  615. }
  616. }
  617. public DateTime NotBefore {
  618. #if FEATURE_CORESYSTEM
  619. [SecuritySafeCritical]
  620. #endif
  621. get {
  622. if (m_safeCertContext.IsInvalid)
  623. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  624. if (m_notBefore == DateTime.MinValue) {
  625. unsafe {
  626. CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) m_safeCertContext.DangerousGetHandle());
  627. CAPI.CERT_INFO pCertInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO));
  628. long dt = (((long)(uint)pCertInfo.NotBefore.dwHighDateTime) << 32) | ((long)(uint)pCertInfo.NotBefore.dwLowDateTime);
  629. m_notBefore = DateTime.FromFileTime(dt);
  630. }
  631. }
  632. return m_notBefore;
  633. }
  634. }
  635. public bool HasPrivateKey {
  636. #if FEATURE_CORESYSTEM
  637. [SecuritySafeCritical]
  638. #endif
  639. get {
  640. if (m_safeCertContext.IsInvalid)
  641. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  642. uint cbData = 0;
  643. return CAPI.CertGetCertificateContextProperty(m_safeCertContext,
  644. CAPI.CERT_KEY_PROV_INFO_PROP_ID,
  645. SafeLocalAllocHandle.InvalidHandle,
  646. ref cbData);
  647. }
  648. }
  649. public AsymmetricAlgorithm PrivateKey {
  650. #if FEATURE_CORESYSTEM
  651. [SecuritySafeCritical]
  652. #endif
  653. get {
  654. if (!this.HasPrivateKey)
  655. return null;
  656. if (m_privateKey == null) {
  657. CspParameters parameters = new CspParameters();
  658. if (!GetPrivateKeyInfo(m_safeCertContext, ref parameters))
  659. return null;
  660. // We never want to stomp over certificate private keys.
  661. parameters.Flags |= CspProviderFlags.UseExistingKey;
  662. switch (this.PublicKey.AlgorithmId) {
  663. case CAPI.CALG_RSA_KEYX:
  664. case CAPI.CALG_RSA_SIGN:
  665. m_privateKey = new RSACryptoServiceProvider(parameters);
  666. break;
  667. #if !FEATURE_CORESYSTEM
  668. case CAPI.CALG_DSS_SIGN:
  669. m_privateKey = new DSACryptoServiceProvider(parameters);
  670. break;
  671. #endif
  672. default:
  673. throw new NotSupportedException(SR.GetString(SR.NotSupported_KeyAlgorithm));
  674. }
  675. }
  676. return m_privateKey;
  677. }
  678. #if FEATURE_CORESYSTEM
  679. [SecuritySafeCritical]
  680. #endif
  681. [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread-safety")]
  682. set {
  683. if (m_safeCertContext.IsInvalid)
  684. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  685. // we do not support keys in non-CAPI storage for now.
  686. ICspAsymmetricAlgorithm asymmetricAlgorithm = value as ICspAsymmetricAlgorithm;
  687. if (value != null && asymmetricAlgorithm == null)
  688. throw new NotSupportedException(SR.GetString(SR.NotSupported_InvalidKeyImpl));
  689. // A null value can be passed in to remove the link to the private key from the certificate.
  690. if (asymmetricAlgorithm != null) {
  691. if (asymmetricAlgorithm.CspKeyContainerInfo == null)
  692. throw new ArgumentException("CspKeyContainerInfo");
  693. // check that the public key in the certificate corresponds to the private key passed in.
  694. //
  695. // note that it should be legal to set a key which matches in every aspect but the usage
  696. // i.e. to use a CALG_RSA_KEYX private key to match a CALG_RSA_SIGN public key. A
  697. // PUBLICKEYBLOB is defined as:
  698. //
  699. // BLOBHEADER publickeystruc
  700. // RSAPUBKEY rsapubkey
  701. // BYTE modulus[rsapubkey.bitlen/8]
  702. //
  703. // To allow keys which differ by key usage only, we skip over the BLOBHEADER of the key,
  704. // and start comparing bytes at the RSAPUBKEY structure.
  705. if(s_publicKeyOffset == 0)
  706. s_publicKeyOffset = Marshal.SizeOf(typeof(CAPIBase.BLOBHEADER));
  707. ICspAsymmetricAlgorithm publicKey = this.PublicKey.Key as ICspAsymmetricAlgorithm;
  708. byte[] array1 = publicKey.ExportCspBlob(false);
  709. byte[] array2 = asymmetricAlgorithm.ExportCspBlob(false);
  710. if (array1 == null || array2 == null || array1.Length != array2.Length || array1.Length <= s_publicKeyOffset)
  711. throw new CryptographicUnexpectedOperationException(SR.GetString(SR.Cryptography_X509_KeyMismatch));
  712. for (int index = s_publicKeyOffset; index < array1.Length; index++) {
  713. if (array1[index] != array2[index])
  714. throw new CryptographicUnexpectedOperationException(SR.GetString(SR.Cryptography_X509_KeyMismatch));
  715. }
  716. }
  717. // Establish the link between the certificate and the key container.
  718. SetPrivateKeyProperty(m_safeCertContext, asymmetricAlgorithm);
  719. m_privateKey = value;
  720. }
  721. }
  722. public PublicKey PublicKey {
  723. #if FEATURE_CORESYSTEM
  724. [SecuritySafeCritical]
  725. #endif
  726. get {
  727. if (m_safeCertContext.IsInvalid)
  728. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  729. if (m_publicKey == null) {
  730. string friendlyName = this.GetKeyAlgorithm();
  731. byte[] parameters = this.GetKeyAlgorithmParameters();
  732. byte[] keyValue = this.GetPublicKey();
  733. Oid oid = new Oid(friendlyName, OidGroup.PublicKeyAlgorithm, true);
  734. m_publicKey = new PublicKey(oid, new AsnEncodedData(oid, parameters), new AsnEncodedData(oid, keyValue));
  735. }
  736. return m_publicKey;
  737. }
  738. }
  739. public byte[] RawData {
  740. get {
  741. return GetRawCertData();
  742. }
  743. }
  744. public string SerialNumber {
  745. get {
  746. return GetSerialNumberString();
  747. }
  748. }
  749. public X500DistinguishedName SubjectName {
  750. #if FEATURE_CORESYSTEM
  751. [SecuritySafeCritical]
  752. #endif
  753. get {
  754. if (m_safeCertContext.IsInvalid)
  755. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  756. if (m_subjectName == null) {
  757. unsafe {
  758. CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) m_safeCertContext.DangerousGetHandle());
  759. CAPI.CERT_INFO pCertInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO));
  760. m_subjectName = new X500DistinguishedName(pCertInfo.Subject);
  761. }
  762. }
  763. return m_subjectName;
  764. }
  765. }
  766. public Oid SignatureAlgorithm {
  767. #if FEATURE_CORESYSTEM
  768. [SecuritySafeCritical]
  769. #endif
  770. get {
  771. if (m_safeCertContext.IsInvalid)
  772. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  773. if (m_signatureAlgorithm == null)
  774. m_signatureAlgorithm = GetSignatureAlgorithm(m_safeCertContext);
  775. return m_signatureAlgorithm;
  776. }
  777. }
  778. public string Thumbprint {
  779. get {
  780. return GetCertHashString();
  781. }
  782. }
  783. public int Version {
  784. #if FEATURE_CORESYSTEM
  785. [SecuritySafeCritical]
  786. #endif
  787. get {
  788. if (m_safeCertContext.IsInvalid)
  789. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  790. if (m_version == 0)
  791. m_version = (int) GetVersion(m_safeCertContext);
  792. return m_version;
  793. }
  794. }
  795. #if FEATURE_CORESYSTEM
  796. [SecurityCritical]
  797. #endif
  798. public unsafe string GetNameInfo(X509NameType nameType, bool forIssuer) {
  799. uint issuerFlag = forIssuer ? CAPI.CERT_NAME_ISSUER_FLAG : 0;
  800. uint type = X509Utils.MapNameType(nameType);
  801. switch(type) {
  802. case CAPI.CERT_NAME_SIMPLE_DISPLAY_TYPE:
  803. return CAPI.GetCertNameInfo(m_safeCertContext, issuerFlag, type);
  804. case CAPI.CERT_NAME_EMAIL_TYPE:
  805. return CAPI.GetCertNameInfo(m_safeCertContext, issuerFlag, type);
  806. }
  807. string name = String.Empty;
  808. // If the type requested is not supported in downlevel platforms; we try to decode the alt name extension by hand.
  809. CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) m_safeCertContext.DangerousGetHandle());
  810. CAPI.CERT_INFO pCertInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO));
  811. IntPtr[] pAltName = new IntPtr[2];
  812. pAltName[0] = CAPI.CertFindExtension(forIssuer ? CAPI.szOID_ISSUER_ALT_NAME : CAPI.szOID_SUBJECT_ALT_NAME,
  813. pCertInfo.cExtension,
  814. pCertInfo.rgExtension);
  815. pAltName[1] = CAPI.CertFindExtension(forIssuer ? CAPI.szOID_ISSUER_ALT_NAME2 : CAPI.szOID_SUBJECT_ALT_NAME2,
  816. pCertInfo.cExtension,
  817. pCertInfo.rgExtension);
  818. for (int i = 0; i < pAltName.Length; i++) {
  819. if (pAltName[i] != IntPtr.Zero) {
  820. CAPI.CERT_EXTENSION extension = (CAPI.CERT_EXTENSION) Marshal.PtrToStructure(pAltName[i], typeof(CAPI.CERT_EXTENSION));
  821. byte[] rawData = new byte[extension.Value.cbData];
  822. Marshal.Copy(extension.Value.pbData, rawData, 0, rawData.Length);
  823. uint cbDecoded = 0;
  824. SafeLocalAllocHandle decoded = null;
  825. // Decode the extension.
  826. SafeLocalAllocHandle ptr = X509Utils.StringToAnsiPtr(extension.pszObjId);
  827. bool result = CAPI.DecodeObject(ptr.DangerousGetHandle(),
  828. rawData,
  829. out decoded,
  830. out cbDecoded);
  831. ptr.Dispose();
  832. if (result) {
  833. CAPI.CERT_ALT_NAME_INFO altNameInfo = (CAPI.CERT_ALT_NAME_INFO) Marshal.PtrToStructure(decoded.DangerousGetHandle(), typeof(CAPI.CERT_ALT_NAME_INFO));
  834. for (int index = 0; index < altNameInfo.cAltEntry; index++) {
  835. IntPtr pAltInfoPtr = new IntPtr((long) altNameInfo.rgAltEntry + index * Marshal.SizeOf(typeof(CAPI.CERT_ALT_NAME_ENTRY)));
  836. CAPI.CERT_ALT_NAME_ENTRY altNameEntry = (CAPI.CERT_ALT_NAME_ENTRY) Marshal.PtrToStructure(pAltInfoPtr, typeof(CAPI.CERT_ALT_NAME_ENTRY));
  837. switch(type) {
  838. case CAPI.CERT_NAME_UPN_TYPE:
  839. if (altNameEntry.dwAltNameChoice == CAPI.CERT_ALT_NAME_OTHER_NAME) {
  840. CAPI.CERT_OTHER_NAME otherName = (CAPI.CERT_OTHER_NAME) Marshal.PtrToStructure(altNameEntry.Value.pOtherName, typeof(CAPI.CERT_OTHER_NAME));
  841. if (otherName.pszObjId == CAPI.szOID_NT_PRINCIPAL_NAME) {
  842. uint cbUpnName = 0;
  843. SafeLocalAllocHandle pUpnName = null;
  844. result = CAPI.DecodeObject(new IntPtr(CAPI.X509_UNICODE_ANY_STRING),
  845. X509Utils.PtrToByte(otherName.Value.pbData, otherName.Value.cbData),
  846. out pUpnName,
  847. out cbUpnName);
  848. if (result) {
  849. CAPI.CERT_NAME_VALUE nameValue = (CAPI.CERT_NAME_VALUE) Marshal.PtrToStructure(pUpnName.DangerousGetHandle(), typeof(CAPI.CERT_NAME_VALUE));
  850. if (X509Utils.IsCertRdnCharString(nameValue.dwValueType))
  851. name = Marshal.PtrToStringUni(nameValue.Value.pbData);
  852. pUpnName.Dispose();
  853. }
  854. }
  855. }
  856. break;
  857. case CAPI.CERT_NAME_DNS_TYPE:
  858. if (altNameEntry.dwAltNameChoice == CAPI.CERT_ALT_NAME_DNS_NAME)
  859. name = Marshal.PtrToStringUni(altNameEntry.Value.pwszDNSName);
  860. break;
  861. case CAPI.CERT_NAME_URL_TYPE:
  862. if (altNameEntry.dwAltNameChoice == CAPI.CERT_ALT_NAME_URL)
  863. name = Marshal.PtrToStringUni(altNameEntry.Value.pwszURL);
  864. break;
  865. }
  866. }
  867. decoded.Dispose();
  868. }
  869. }
  870. }
  871. if (nameType == X509NameType.DnsName) {
  872. // If no DNS name is found in the CERT_ALT_NAME extension, return the CommonName.
  873. // Commercial CAs such as Verisign don't include a SubjectAltName extension in the certificates they use for SSL server authentication.
  874. // Instead they use the CommonName in the subject RDN as the server's DNS name.
  875. if (name == null || name.Length == 0)
  876. name = CAPI.GetCertNameInfo(m_safeCertContext, issuerFlag, CAPI.CERT_NAME_ATTR_TYPE);
  877. }
  878. return name;
  879. }
  880. #if !FEATURE_CORESYSTEM
  881. [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
  882. [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
  883. [PermissionSetAttribute(SecurityAction.InheritanceDemand, Unrestricted=true)]
  884. public override void Import(byte[] rawData) {
  885. Reset();
  886. base.Import(rawData);
  887. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  888. }
  889. [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
  890. [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
  891. [PermissionSetAttribute(SecurityAction.InheritanceDemand, Unrestricted=true)]
  892. public override void Import(byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags) {
  893. Reset();
  894. base.Import(rawData, password, keyStorageFlags);
  895. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  896. }
  897. [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
  898. [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
  899. [PermissionSetAttribute(SecurityAction.InheritanceDemand, Unrestricted=true)]
  900. public override void Import(byte[] rawData, SecureString password, X509KeyStorageFlags keyStorageFlags) {
  901. Reset();
  902. base.Import(rawData, password, keyStorageFlags);
  903. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  904. }
  905. [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
  906. [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
  907. [PermissionSetAttribute(SecurityAction.InheritanceDemand, Unrestricted=true)]
  908. [ResourceExposure(ResourceScope.Machine)]
  909. [ResourceConsumption(ResourceScope.Machine)]
  910. public override void Import(string fileName) {
  911. Reset();
  912. base.Import(fileName);
  913. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  914. }
  915. [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
  916. [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
  917. [PermissionSetAttribute(SecurityAction.InheritanceDemand, Unrestricted=true)]
  918. [ResourceExposure(ResourceScope.Machine)]
  919. [ResourceConsumption(ResourceScope.Machine)]
  920. public override void Import(string fileName, string password, X509KeyStorageFlags keyStorageFlags) {
  921. Reset();
  922. base.Import(fileName, password, keyStorageFlags);
  923. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  924. }
  925. [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
  926. [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
  927. [PermissionSetAttribute(SecurityAction.InheritanceDemand, Unrestricted=true)]
  928. [ResourceExposure(ResourceScope.Machine)]
  929. [ResourceConsumption(ResourceScope.Machine)]
  930. public override void Import(string fileName, SecureString password, X509KeyStorageFlags keyStorageFlags) {
  931. Reset();
  932. base.Import(fileName, password, keyStorageFlags);
  933. m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
  934. }
  935. [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
  936. [PermissionSetAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
  937. [PermissionSetAttribute(SecurityAction.InheritanceDemand, Unrestricted=true)]
  938. public override void Reset () {
  939. m_version = 0;
  940. m_notBefore = DateTime.MinValue;
  941. m_notAfter = DateTime.MinValue;
  942. m_privateKey = null;
  943. m_publicKey = null;
  944. m_extensions = null;
  945. m_signatureAlgorithm = null;
  946. m_subjectName = null;
  947. m_issuerName = null;
  948. if (!m_safeCertContext.IsInvalid) {
  949. // Free the current certificate handle
  950. m_safeCertContext.Dispose();
  951. m_safeCertContext = SafeCertContextHandle.InvalidHandle;
  952. }
  953. base.Reset();
  954. }
  955. #endif // !FEATURE_CORESYSTEM
  956. public bool Verify () {
  957. if (m_safeCertContext.IsInvalid)
  958. throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");
  959. int hr = X509Utils.VerifyCertificate(this.CertContext,
  960. null,
  961. null,
  962. X509RevocationMode.Online, // We default to online revocation check.
  963. X509RevocationFlag.ExcludeRoot,
  964. DateTime.Now,
  965. new TimeSpan(0, 0, 0), // default
  966. null,
  967. new IntPtr(CAPI.CERT_CHAIN_POLICY_BASE),
  968. IntPtr.Zero);
  969. return (hr == CAPI.S_OK);
  970. }
  971. //
  972. // public static methods
  973. //
  974. public static X509ContentType GetCertContentType (byte[] rawData) {
  975. if (rawData == null || rawData.Length == 0)
  976. throw new ArgumentException(SR.GetString(SR.Arg_EmptyOrNullArray), "rawData");
  977. uint contentType = QueryCertBlobType(rawData);
  978. return X509Utils.MapContentType(contentType);
  979. }
  980. [ResourceExposure(ResourceScope.Machine)]
  981. #if !FEATURE_CORESYSTEM
  982. [ResourceConsumption(ResourceScope.Machine)]
  983. #endif
  984. public static X509ContentType GetCertContentType (string fileName) {
  985. if (fileName == null)
  986. throw new ArgumentNullException("fileName");
  987. string fullPath = Path.GetFullPath(fileName);
  988. #if !FEATURE_CORESYSTEM
  989. new FileIOPermission (FileIOPermissionAccess.Read, fullPath).Demand();
  990. #endif
  991. uint contentType = QueryCertFileType(fileName);
  992. return X509Utils.MapContentType(contentType);
  993. }
  994. //
  995. // Internal
  996. //
  997. internal SafeCertContextHandle CertContext {
  998. #if FEATURE_CORESYSTEM
  999. [SecuritySafeCritical]
  1000. #endif
  1001. get {
  1002. return m_safeCertContext;
  1003. }
  1004. }
  1005. #if FEATURE_CORESYSTEM
  1006. [SecurityCritical]
  1007. #endif
  1008. internal static bool GetPrivateKeyInfo (SafeCertContextHandle safeCertContext, ref CspParameters parameters) {
  1009. SafeLocalAllocHandle ptr = SafeLocalAllocHandle.InvalidHandle;
  1010. uint cbData = 0;
  1011. if (!CAPI.CertGetCertificateContextProperty(safeCertContext,
  1012. CAPI.CERT_KEY_PROV_INFO_PROP_ID,
  1013. ptr,
  1014. ref cbData)) {
  1015. int dwErrorCode = Marshal.GetLastWin32Error();
  1016. if (dwErrorCode == CAPI.CRYPT_E_NOT_FOUND)
  1017. return false;
  1018. else
  1019. throw new CryptographicException(Marshal.GetLastWin32Error());
  1020. }
  1021. ptr = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(cbData));
  1022. if (!CAPI.CertGetCertificateContextProperty(safeCer