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
- MsiStyleLogWriter.cs
- ComponentGuaranteesAttribute.cs
- SqlClientMetaDataCollectionNames.cs
- ProfileParameter.cs
- DesignTimeTemplateParser.cs
- DataGridViewCellLinkedList.cs
- UnsignedPublishLicense.cs
- NameValueConfigurationElement.cs
- BrowserDefinition.cs
- ToolStripProfessionalLowResolutionRenderer.cs
- CodeConstructor.cs
- LongTypeConverter.cs
- FontDialog.cs
- DaylightTime.cs
- ExpressionLexer.cs
- MimeWriter.cs
- QueryCacheEntry.cs
- UInt64Storage.cs
- CreateUserErrorEventArgs.cs
- AutomationTextAttribute.cs
- SignatureHelper.cs
- BinaryReader.cs
- RedistVersionInfo.cs
- Misc.cs
- ExtentJoinTreeNode.cs
- Stroke.cs
- GraphicsState.cs
- FusionWrap.cs
- XmlDataSourceView.cs
- VisualBasicValue.cs
- ExeContext.cs
- ViewKeyConstraint.cs
- ADMembershipUser.cs
- RegexRunnerFactory.cs
- InputLanguageEventArgs.cs
- AutoGeneratedFieldProperties.cs
- ConsoleTraceListener.cs
- DoubleAnimationClockResource.cs
- LinkTarget.cs
- HttpListenerContext.cs
- TextDecorationCollectionConverter.cs
- PersianCalendar.cs
- ValidateNames.cs
- Cell.cs
- BehaviorEditorPart.cs
- KeyNotFoundException.cs
- documentsequencetextpointer.cs
- OdbcUtils.cs
- LayoutTableCell.cs
- InputReport.cs
- CheckBoxAutomationPeer.cs
- SqlFlattener.cs
- filewebrequest.cs
- GatewayDefinition.cs
- CodeCastExpression.cs
- StylusPointDescription.cs
- SocketException.cs
- HttpProcessUtility.cs
- TrackingServices.cs
- WrapPanel.cs
- SharedRuntimeState.cs
- RbTree.cs
- HttpCookie.cs
- DesignSurface.cs
- TextEndOfParagraph.cs
- XPathDocumentIterator.cs
- PreloadedPackages.cs
- InlineCollection.cs
- Grid.cs
- DetailsViewAutoFormat.cs
- GetPageCompletedEventArgs.cs
- ServiceManagerHandle.cs
- TraceContext.cs
- RoleManagerSection.cs
- SignatureHelper.cs
- EdmType.cs
- CustomGrammar.cs
- UnsafeNativeMethods.cs
- HttpCapabilitiesEvaluator.cs
- FormViewCommandEventArgs.cs
- FontUnit.cs
- DataGridViewCellToolTipTextNeededEventArgs.cs
- UTF8Encoding.cs
- ReadOnlyDataSourceView.cs
- GeometryDrawing.cs
- FtpRequestCacheValidator.cs
- GridViewColumnHeaderAutomationPeer.cs
- SolidBrush.cs
- AbandonedMutexException.cs
- ZoneButton.cs
- SafeFileMapViewHandle.cs
- ItemsPanelTemplate.cs
- CompensatableTransactionScopeActivity.cs
- HyperLink.cs
- GraphicsContext.cs
- SQLDoubleStorage.cs
- PropertyStore.cs
- UserNameSecurityTokenParameters.cs
- ScriptManager.cs
- FileResponseElement.cs