Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / IdentityModel / System / IdentityModel / Selectors / X509CertificateStore.cs / 1 / 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() { this.certStoreHandle.Close(); } 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. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PropVariant.cs
- AllowedAudienceUriElement.cs
- SpellCheck.cs
- ToolStripRenderEventArgs.cs
- StylusShape.cs
- selecteditemcollection.cs
- OleDbException.cs
- NetworkCredential.cs
- SafeProcessHandle.cs
- HTMLTextWriter.cs
- UndirectedGraph.cs
- odbcmetadatafactory.cs
- ObjectResult.cs
- AuthenticatingEventArgs.cs
- ComponentEvent.cs
- RegexWorker.cs
- EntityTypeEmitter.cs
- StylusPlugin.cs
- CodeCommentStatementCollection.cs
- Renderer.cs
- XmlSerializerVersionAttribute.cs
- WindowsRichEditRange.cs
- Calendar.cs
- CopyNodeSetAction.cs
- XmlSchemaElement.cs
- ClientApiGenerator.cs
- ImageFormatConverter.cs
- InfiniteTimeSpanConverter.cs
- PerformanceCounterPermissionEntry.cs
- MemberAccessException.cs
- NoneExcludedImageIndexConverter.cs
- WindowsSysHeader.cs
- EdmToObjectNamespaceMap.cs
- ExpressionValueEditor.cs
- ShapingEngine.cs
- SecurityTokenProvider.cs
- IListConverters.cs
- TextComposition.cs
- Privilege.cs
- QualificationDataItem.cs
- EmissiveMaterial.cs
- TransformValueSerializer.cs
- HandoffBehavior.cs
- shaperfactoryquerycacheentry.cs
- QuarticEase.cs
- ToolStripArrowRenderEventArgs.cs
- QilGenerator.cs
- RoleService.cs
- HotSpot.cs
- HashUtility.cs
- KeyNotFoundException.cs
- PageBuildProvider.cs
- WeakRefEnumerator.cs
- FontClient.cs
- StrongNameKeyPair.cs
- StateManagedCollection.cs
- XmlReaderSettings.cs
- ObjectAssociationEndMapping.cs
- TextBox.cs
- DefaultValueTypeConverter.cs
- SchemaObjectWriter.cs
- UniqueID.cs
- WizardStepBase.cs
- TransformProviderWrapper.cs
- HtmlTableRow.cs
- ImageConverter.cs
- Trigger.cs
- EntityViewContainer.cs
- HebrewNumber.cs
- SystemPens.cs
- GatewayIPAddressInformationCollection.cs
- Tag.cs
- AuthenticationService.cs
- Pair.cs
- JsonServiceDocumentSerializer.cs
- StateWorkerRequest.cs
- DocumentSchemaValidator.cs
- TemplateNameScope.cs
- VScrollBar.cs
- AssociativeAggregationOperator.cs
- ServiceDefaults.cs
- CircleHotSpot.cs
- DataServiceProviderMethods.cs
- OracleTimeSpan.cs
- Int32CollectionConverter.cs
- ServerProtocol.cs
- PropertyDescriptor.cs
- Automation.cs
- IImplicitResourceProvider.cs
- DodSequenceMerge.cs
- DiscriminatorMap.cs
- IssuedTokenParametersEndpointAddressElement.cs
- BitmapEffectDrawingContextWalker.cs
- SafeRegistryHandle.cs
- AssemblyCache.cs
- InputGestureCollection.cs
- LineSegment.cs
- CompModSwitches.cs
- KeySplineConverter.cs
- NativeMethods.cs