Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / IdentityModel / System / IdentityModel / Selectors / X509CertificateStore.cs / 1305376 / X509CertificateStore.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.IdentityModel.Selectors { using Microsoft.Win32.SafeHandles; using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Security; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; class X509CertificateStore { SafeCertStoreHandle certStoreHandle = SafeCertStoreHandle.InvalidHandle; string storeName; StoreLocation storeLocation; public X509CertificateStore(StoreName storeName, StoreLocation storeLocation) { switch (storeName) { case StoreName.AddressBook: this.storeName = "AddressBook"; break; case StoreName.AuthRoot: this.storeName = "AuthRoot"; break; case StoreName.CertificateAuthority: this.storeName = "CA"; break; case StoreName.Disallowed: this.storeName = "Disallowed"; break; case StoreName.My: this.storeName = "My"; break; case StoreName.Root: this.storeName = "Root"; break; case StoreName.TrustedPeople: this.storeName = "TrustedPeople"; break; case StoreName.TrustedPublisher: this.storeName = "TrustedPublisher"; break; default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("storeName", (int)storeName, typeof(StoreName))); } if (storeLocation != StoreLocation.CurrentUser && storeLocation != StoreLocation.LocalMachine) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("storeLocation", SR.GetString(SR.X509CertStoreLocationNotValid))); } this.storeLocation = storeLocation; } public void Close() { // Accessing via IDisposable to avoid Security check (functionally the same) ((IDisposable)this.certStoreHandle).Dispose(); } public void Open(OpenFlags openFlags) { DiagnosticUtility.DebugAssert(this.certStoreHandle.IsInvalid, ""); uint dwOpenFlags = MapX509StoreFlags(this.storeLocation, openFlags); SafeCertStoreHandle certStoreHandle = CAPI.CertOpenStore(new IntPtr(CAPI.CERT_STORE_PROV_SYSTEM), CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, IntPtr.Zero, dwOpenFlags, this.storeName); if (certStoreHandle == null || certStoreHandle.IsInvalid) { int error = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error)); } this.certStoreHandle = certStoreHandle; } public X509Certificate2Collection Find(X509FindType findType, object findValue, bool validOnly) { DiagnosticUtility.DebugAssert(!this.certStoreHandle.IsInvalid, ""); uint dwFindType; SafeHGlobalHandle pvFindPara = SafeHGlobalHandle.InvalidHandle; SafeCertContextHandle pCertContext = SafeCertContextHandle.InvalidHandle; X509Certificate2Collection result = new X509Certificate2Collection(); SafeHGlobalHandle pvTemp = SafeHGlobalHandle.InvalidHandle; string strFindValue; byte[] bytes; try { switch (findType) { case X509FindType.FindBySubjectName: strFindValue = findValue as string; if (strFindValue == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType()))); dwFindType = CAPI.CERT_FIND_SUBJECT_STR; pvFindPara = SafeHGlobalHandle.AllocHGlobal(strFindValue); break; case X509FindType.FindByThumbprint: bytes = findValue as byte[]; if (bytes == null) { strFindValue = findValue as string; if (strFindValue == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatchMulti, findType, typeof(string), typeof(byte[]), findValue.GetType()))); bytes = SecurityUtils.DecodeHexString(strFindValue); } CAPI.CRYPTOAPI_BLOB blob = new CAPI.CRYPTOAPI_BLOB(); pvTemp = SafeHGlobalHandle.AllocHGlobal(bytes); blob.pbData = pvTemp.DangerousGetHandle(); blob.cbData = (uint)bytes.Length; dwFindType = CAPI.CERT_FIND_HASH; pvFindPara = SafeHGlobalHandle.AllocHGlobal(CAPI.CRYPTOAPI_BLOB.Size); Marshal.StructureToPtr(blob, pvFindPara.DangerousGetHandle(), false); break; case X509FindType.FindBySubjectDistinguishedName: if (!(findValue is string)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType()))); dwFindType = CAPI.CERT_FIND_ANY; break; case X509FindType.FindByIssuerName: strFindValue = findValue as string; if (strFindValue == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType()))); dwFindType = CAPI.CERT_FIND_ISSUER_STR; pvFindPara = SafeHGlobalHandle.AllocHGlobal(strFindValue); break; case X509FindType.FindByIssuerDistinguishedName: if (!(findValue is string)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType()))); dwFindType = CAPI.CERT_FIND_ANY; break; case X509FindType.FindBySerialNumber: bytes = findValue as byte[]; if (bytes == null) { strFindValue = findValue as string; if (strFindValue == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatchMulti, findType, typeof(string), typeof(byte[]), findValue.GetType()))); bytes = SecurityUtils.DecodeHexString(strFindValue); // reverse bits int len = bytes.Length; for (int i = 0, j = len - 1; i < bytes.Length / 2; ++i, --j) { byte tmp = bytes[i]; bytes[i] = bytes[j]; bytes[j] = tmp; } } findValue = bytes; dwFindType = CAPI.CERT_FIND_ANY; break; case X509FindType.FindBySubjectKeyIdentifier: bytes = findValue as byte[]; if (bytes == null) { strFindValue = findValue as string; if (strFindValue == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatchMulti, findType, typeof(string), typeof(byte[]), findValue.GetType()))); bytes = SecurityUtils.DecodeHexString(strFindValue); } findValue = bytes; dwFindType = CAPI.CERT_FIND_ANY; break; default: // Fallback to CLR implementation X509Store store = new X509Store(this.certStoreHandle.DangerousGetHandle()); try { return store.Certificates.Find(findType, findValue, validOnly); } finally { store.Close(); } } #pragma warning suppress 56523 // We are not interested in CRYPT_E_NOT_FOUND error, it return null anyway. pCertContext = CAPI.CertFindCertificateInStore(this.certStoreHandle, CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, 0, dwFindType, pvFindPara, pCertContext); while (pCertContext != null && !pCertContext.IsInvalid) { X509Certificate2 cert; if (TryGetMatchingX509Certificate(pCertContext.DangerousGetHandle(), findType, dwFindType, findValue, validOnly, out cert)) { result.Add(cert); } // CER RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { // Suppress the finalizer #pragma warning suppress 56508 // CertFindCertificateInStore will release the prev one. GC.SuppressFinalize(pCertContext); #pragma warning suppress 56523 // We are not interested in CRYPT_E_NOT_FOUND error, it return null anyway. pCertContext = CAPI.CertFindCertificateInStore(this.certStoreHandle, CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, 0, dwFindType, pvFindPara, pCertContext); } } } finally { if (pCertContext != null) { pCertContext.Close(); } pvFindPara.Close(); pvTemp.Close(); } return result; } bool TryGetMatchingX509Certificate(IntPtr certContext, X509FindType findType, uint dwFindType, object findValue, bool validOnly, out X509Certificate2 cert) { cert = new X509Certificate2(certContext); if (dwFindType == CAPI.CERT_FIND_ANY) { switch (findType) { case X509FindType.FindBySubjectDistinguishedName: if (0 != String.Compare((string)findValue, cert.SubjectName.Name, StringComparison.OrdinalIgnoreCase)) { cert.Reset(); cert = null; return false; } break; case X509FindType.FindByIssuerDistinguishedName: if (0 != String.Compare((string)findValue, cert.IssuerName.Name, StringComparison.OrdinalIgnoreCase)) { cert.Reset(); cert = null; return false; } break; case X509FindType.FindBySerialNumber: if (!BinaryMatches((byte[])findValue, cert.GetSerialNumber())) { cert.Reset(); cert = null; return false; } break; case X509FindType.FindBySubjectKeyIdentifier: X509SubjectKeyIdentifierExtension skiExtension = cert.Extensions[CAPI.SubjectKeyIdentifierOid] as X509SubjectKeyIdentifierExtension; if (skiExtension == null || !BinaryMatches((byte[])findValue, skiExtension.RawData)) { cert.Reset(); cert = null; return false; } break; default: DiagnosticUtility.DebugAssert(findType + " is not supported!"); break; } } if (validOnly) { X509Chain chain = new X509Chain(false); chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; if (!chain.Build(cert)) { cert.Reset(); cert = null; return false; } } return cert != null; } bool BinaryMatches(byte[] src, byte[] dst) { if (src.Length != dst.Length) return false; for (int i = 0; i < src.Length; ++i) { if (src[i] != dst[i]) return false; } return true; } // this method maps X509Store OpenFlags to a combination of crypto API flags uint MapX509StoreFlags(StoreLocation storeLocation, OpenFlags flags) { uint dwFlags = 0; uint openMode = ((uint)flags) & 0x3; switch (openMode) { case (uint)OpenFlags.ReadOnly: dwFlags |= CAPI.CERT_STORE_READONLY_FLAG; break; case (uint)OpenFlags.MaxAllowed: dwFlags |= CAPI.CERT_STORE_MAXIMUM_ALLOWED_FLAG; break; } if ((flags & OpenFlags.OpenExistingOnly) == OpenFlags.OpenExistingOnly) dwFlags |= CAPI.CERT_STORE_OPEN_EXISTING_FLAG; if ((flags & OpenFlags.IncludeArchived) == OpenFlags.IncludeArchived) dwFlags |= CAPI.CERT_STORE_ENUM_ARCHIVED_FLAG; if (storeLocation == StoreLocation.LocalMachine) dwFlags |= CAPI.CERT_SYSTEM_STORE_LOCAL_MACHINE; else if (storeLocation == StoreLocation.CurrentUser) dwFlags |= CAPI.CERT_SYSTEM_STORE_CURRENT_USER; return dwFlags; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ImageMap.cs
- WindowsScrollBar.cs
- Container.cs
- SimpleMailWebEventProvider.cs
- MenuRenderer.cs
- LogLogRecord.cs
- XD.cs
- XPathDocumentNavigator.cs
- URLString.cs
- Int16Animation.cs
- AttachedPropertyBrowsableAttribute.cs
- ScriptReference.cs
- Executor.cs
- ToolStripDropDownMenu.cs
- ContentDisposition.cs
- InputLanguageManager.cs
- PropertyFilterAttribute.cs
- ActivityBindForm.Designer.cs
- Interop.cs
- ErrorFormatter.cs
- ExclusiveTcpTransportManager.cs
- thaishape.cs
- DrawingAttributeSerializer.cs
- FunctionNode.cs
- ObjectFullSpanRewriter.cs
- PrivilegeNotHeldException.cs
- ValidateNames.cs
- SecurityCriticalDataForSet.cs
- HtmlToClrEventProxy.cs
- TableItemStyle.cs
- clipboard.cs
- MarkupProperty.cs
- PartialTrustValidationBehavior.cs
- XmlJsonWriter.cs
- DoubleSumAggregationOperator.cs
- MultiTrigger.cs
- WebPartDeleteVerb.cs
- RunInstallerAttribute.cs
- webeventbuffer.cs
- InstanceDataCollection.cs
- ToolboxControl.cs
- SocketException.cs
- UnionCodeGroup.cs
- GridViewColumn.cs
- DataSetUtil.cs
- ObjectQuery.cs
- StateManagedCollection.cs
- CodeMemberField.cs
- EventWaitHandleSecurity.cs
- FontClient.cs
- ThumbAutomationPeer.cs
- ErrorInfoXmlDocument.cs
- RangeBase.cs
- PartialList.cs
- DefaultProxySection.cs
- FlowPosition.cs
- XmlSerializerNamespaces.cs
- XDeferredAxisSource.cs
- InputLanguageManager.cs
- FacetValueContainer.cs
- EnumType.cs
- InProcStateClientManager.cs
- _Win32.cs
- ServiceNameElement.cs
- CustomCategoryAttribute.cs
- UrlMappingsModule.cs
- Polyline.cs
- RepeatBehaviorConverter.cs
- DPCustomTypeDescriptor.cs
- FigureHelper.cs
- DataTrigger.cs
- AutomationProperty.cs
- PrintControllerWithStatusDialog.cs
- ParamArrayAttribute.cs
- ListViewEditEventArgs.cs
- ExtendedProtectionPolicy.cs
- ExpressionBindings.cs
- XmlAnyAttributeAttribute.cs
- OpacityConverter.cs
- UIElement3D.cs
- PrivateFontCollection.cs
- SiteMap.cs
- sqlcontext.cs
- PenContexts.cs
- Knowncolors.cs
- TextParagraphCache.cs
- GeneratedView.cs
- MetadataProperty.cs
- WebPartsPersonalization.cs
- PersonalizationDictionary.cs
- XamlToRtfWriter.cs
- HtmlAnchor.cs
- PolyQuadraticBezierSegment.cs
- GlyphElement.cs
- ServiceContractGenerator.cs
- CodeTypeOfExpression.cs
- ToolStripContentPanelDesigner.cs
- ProjectionRewriter.cs
- safesecurityhelperavalon.cs
- DataServiceClientException.cs