1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
//-----------------------------------------------------------------------
// <copyright file="X509CertificateStoreTokenResolver.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace System.IdentityModel.Tokens
{
using System;
using System.Collections.Generic;
using System.IdentityModel.Selectors;
using System.Security.Cryptography.X509Certificates;
using System.Text;
/// <summary>
/// Token Resolver that can resolve X509SecurityTokens against a given X.509 Certificate Store.
/// </summary>
public class X509CertificateStoreTokenResolver : SecurityTokenResolver
{
private string storeName;
private StoreLocation storeLocation;
/// <summary>
/// Initializes an instance of <see cref="X509CertificateStoreTokenResolver"/>
/// </summary>
public X509CertificateStoreTokenResolver()
: this(System.Security.Cryptography.X509Certificates.StoreName.My, StoreLocation.LocalMachine)
{
}
/// <summary>
/// Initializes an instance of <see cref="X509CertificateStoreTokenResolver"/>
/// </summary>
/// <param name="storeName">StoreName of the X.509 Certificate Store.</param>
/// <param name="storeLocation">StoreLocation of the X.509 Certificate store.</param>
public X509CertificateStoreTokenResolver(StoreName storeName, StoreLocation storeLocation)
: this(Enum.GetName(typeof(System.Security.Cryptography.X509Certificates.StoreName), storeName), storeLocation)
{
}
/// <summary>
/// Initializes an instance of <see cref="X509CertificateStoreTokenResolver"/>
/// </summary>
/// <param name="storeName">StoreName of the X.509 Certificate Store.</param>
/// <param name="storeLocation">StoreLocation of the X.509 Certificate store.</param>
public X509CertificateStoreTokenResolver(string storeName, StoreLocation storeLocation)
{
if (string.IsNullOrEmpty(storeName))
{
throw DiagnosticUtility.ThrowHelperArgumentNullOrEmptyString("storeName");
}
this.storeName = storeName;
this.storeLocation = storeLocation;
}
/// <summary>
/// Gets the StoreName used by this TokenResolver.
/// </summary>
public string StoreName
{
get { return this.storeName; }
}
/// <summary>
/// Gets the StoreLocation used by this TokenResolver.
/// </summary>
public StoreLocation StoreLocation
{
get { return this.storeLocation; }
}
/// <summary>
/// Resolves the given SecurityKeyIdentifierClause to a SecurityKey.
/// </summary>
/// <param name="keyIdentifierClause">SecurityKeyIdentifierClause to resolve</param>
/// <param name="key">The resolved SecurityKey.</param>
/// <returns>True if successfully resolved.</returns>
/// <exception cref="ArgumentNullException">The input argument 'keyIdentifierClause' is null.</exception>
protected override bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key)
{
if (keyIdentifierClause == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
}
key = null;
EncryptedKeyIdentifierClause encryptedKeyIdentifierClause = keyIdentifierClause as EncryptedKeyIdentifierClause;
if (encryptedKeyIdentifierClause != null)
{
SecurityKeyIdentifier keyIdentifier = encryptedKeyIdentifierClause.EncryptingKeyIdentifier;
if (keyIdentifier != null && keyIdentifier.Count > 0)
{
for (int i = 0; i < keyIdentifier.Count; i++)
{
SecurityKey unwrappingSecurityKey = null;
if (TryResolveSecurityKey(keyIdentifier[i], out unwrappingSecurityKey))
{
byte[] wrappedKey = encryptedKeyIdentifierClause.GetEncryptedKey();
string wrappingAlgorithm = encryptedKeyIdentifierClause.EncryptionMethod;
byte[] unwrappedKey = unwrappingSecurityKey.DecryptKey(wrappingAlgorithm, wrappedKey);
key = new InMemorySymmetricSecurityKey(unwrappedKey, false);
return true;
}
}
}
}
else
{
SecurityToken token = null;
if (TryResolveToken(keyIdentifierClause, out token))
{
if (token.SecurityKeys.Count > 0)
{
key = token.SecurityKeys[0];
return true;
}
}
}
return false;
}
/// <summary>
/// Resolves the given SecurityKeyIdentifier to a SecurityToken.
/// </summary>
/// <param name="keyIdentifier">SecurityKeyIdentifier to resolve.</param>
/// <param name="token">The resolved SecurityToken.</param>
/// <returns>True if successfully resolved.</returns>
/// <exception cref="ArgumentNullException">The input argument 'keyIdentifier' is null.</exception>
protected override bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token)
{
if (keyIdentifier == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier");
}
token = null;
foreach (SecurityKeyIdentifierClause clause in keyIdentifier)
{
if (TryResolveToken(clause, out token))
{
return true;
}
}
return false;
}
/// <summary>
/// Resolves the given SecurityKeyIdentifierClause to a SecurityToken.
/// </summary>
/// <param name="keyIdentifierClause">SecurityKeyIdentifierClause to resolve.</param>
/// <param name="token">The resolved SecurityToken.</param>
/// <returns>True if successfully resolved.</returns>
/// <exception cref="ArgumentNullException">The input argument 'keyIdentifierClause' is null.</exception>
protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
{
if (keyIdentifierClause == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifierClause");
}
token = null;
X509Store store = null;
X509Certificate2Collection certs = null;
try
{
store = new X509Store(this.storeName, this.storeLocation);
store.Open(OpenFlags.ReadOnly);
certs = store.Certificates;
foreach (X509Certificate2 cert in certs)
{
X509ThumbprintKeyIdentifierClause thumbprintKeyIdentifierClause = keyIdentifierClause as X509ThumbprintKeyIdentifierClause;
if (thumbprintKeyIdentifierClause != null && thumbprintKeyIdentifierClause.Matches(cert))
{
token = new X509SecurityToken(cert);
return true;
}
X509IssuerSerialKeyIdentifierClause issuerSerialKeyIdentifierClause = keyIdentifierClause as X509IssuerSerialKeyIdentifierClause;
if (issuerSerialKeyIdentifierClause != null && issuerSerialKeyIdentifierClause.Matches(cert))
{
token = new X509SecurityToken(cert);
return true;
}
X509SubjectKeyIdentifierClause subjectKeyIdentifierClause = keyIdentifierClause as X509SubjectKeyIdentifierClause;
if (subjectKeyIdentifierClause != null && subjectKeyIdentifierClause.Matches(cert))
{
token = new X509SecurityToken(cert);
return true;
}
X509RawDataKeyIdentifierClause rawDataKeyIdentifierClause = keyIdentifierClause as X509RawDataKeyIdentifierClause;
if (rawDataKeyIdentifierClause != null && rawDataKeyIdentifierClause.Matches(cert))
{
token = new X509SecurityToken(cert);
return true;
}
}
}
finally
{
if (certs != null)
{
for (int i = 0; i < certs.Count; i++)
{
certs[i].Reset();
}
}
if (store != null)
{
store.Close();
}
}
return false;
}
}
}
|