mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
f2ac1ece55
add
1388 lines
58 KiB
C#
1388 lines
58 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: Microsoft.InfoCards.InfoCard
|
|
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|
|
// MVID: 516D8B44-4448-4D2C-8B8E-FFBB3FFE472B
|
|
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00000-msil\Virus.Win32.Expiro.w-69bb73081eac86b8cf86f45e33515d0095855636967076e2b593d7a30cd80a07.exe
|
|
|
|
using Microsoft.InfoCards.Diagnostics;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using System.ServiceModel;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Xml;
|
|
using System.Xml.Serialization;
|
|
|
|
namespace Microsoft.InfoCards
|
|
{
|
|
internal class InfoCard : IXmlSerializable
|
|
{
|
|
private const int InvalidRow = 0;
|
|
private const byte Marker = 29;
|
|
private const byte Version = 1;
|
|
public const int KeySize = 2048;
|
|
public const int MasterKeySize = 32;
|
|
public const int SaltSize = 16;
|
|
private InfoCardClaimCollection m_claims;
|
|
private DateTime m_expiresOn = DateTime.MaxValue;
|
|
private uint m_epoch;
|
|
private Uri m_id;
|
|
private DateTime m_issuedOn = DateTime.MinValue;
|
|
private bool m_isImported;
|
|
private DateTime m_installedOn = DateTime.Now;
|
|
private string m_issuerName = string.Empty;
|
|
private string m_language = string.Empty;
|
|
private LedgerEntryCollection m_ledger;
|
|
private byte[] m_logo;
|
|
private string m_mimeType = string.Empty;
|
|
private string m_name = string.Empty;
|
|
private DateTime m_lastUpdate = DateTime.MinValue;
|
|
private int m_rowId;
|
|
private StoreConnection m_storeConnection;
|
|
private int m_backgroundColor;
|
|
private string[] m_tokenTypes;
|
|
private RequireAppliesToStatus m_requireAppliesTo;
|
|
private byte[] m_pinHash;
|
|
private bool m_isSelfIssued;
|
|
private byte[] m_salt;
|
|
private InfoCardMasterKey m_masterKey;
|
|
private string m_privacyPolicyLink = string.Empty;
|
|
private byte[] m_issuerIdentifierAsBytes;
|
|
private Uri m_issuer;
|
|
private uint m_privacyPolicyVersion;
|
|
private string m_pin = string.Empty;
|
|
private string m_oldPin = string.Empty;
|
|
private InfoCard.PinAction m_pinAction;
|
|
private InfocardExtendedInformationCollection m_extendedInformation;
|
|
private bool m_readIssuerInformation;
|
|
private RPIdentityRequirement m_rpStrongIdentityRequired;
|
|
private List<TokenCreationParameter> m_creationParameters;
|
|
|
|
public InfoCard() => this.m_lastUpdate = DateTime.UtcNow;
|
|
|
|
public InfoCard(Uri id) => this.m_id = id;
|
|
|
|
public InfoCard(Stream stream) => this.Deserialize(stream);
|
|
|
|
public string[] TokenTypes
|
|
{
|
|
set => this.m_tokenTypes = value;
|
|
}
|
|
|
|
public List<TokenCreationParameter> CreationParameters
|
|
{
|
|
get
|
|
{
|
|
if (this.m_creationParameters == null)
|
|
this.m_creationParameters = new List<TokenCreationParameter>();
|
|
return this.m_creationParameters;
|
|
}
|
|
}
|
|
|
|
public InfoCardClaimCollection GetClaims()
|
|
{
|
|
if (this.m_claims == null)
|
|
{
|
|
if ((Uri) null == this.m_id)
|
|
InfoCardTrace.Assert((Uri) null != this.m_id, "m_id");
|
|
this.m_claims = new InfoCardClaimCollection(this.m_id);
|
|
if (this.m_storeConnection != null)
|
|
this.m_claims.Get(this.m_storeConnection);
|
|
}
|
|
return this.m_claims;
|
|
}
|
|
|
|
public static IssuerInformation GetIssuerInformation(string xml)
|
|
{
|
|
IssuerInformation issuerInformation = new IssuerInformation();
|
|
if (!string.IsNullOrEmpty(xml))
|
|
{
|
|
try
|
|
{
|
|
issuerInformation.ReadIssuerInformation(InfoCardSchemas.CreateReader(xml));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (!InfoCardTrace.IsFatal(ex))
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("ServiceUnableToDeserializeInfoCardStream"), ex));
|
|
throw;
|
|
}
|
|
}
|
|
return issuerInformation;
|
|
}
|
|
|
|
public InfocardExtendedInformationCollection GetExtendedInformation()
|
|
{
|
|
if (this.m_extendedInformation == null)
|
|
{
|
|
InfoCardTrace.Assert((Uri) null != this.m_id, "m_id");
|
|
this.m_extendedInformation = new InfocardExtendedInformationCollection(this.m_id);
|
|
if (this.m_storeConnection != null)
|
|
this.m_extendedInformation.Get(this.m_storeConnection);
|
|
}
|
|
return this.m_extendedInformation;
|
|
}
|
|
|
|
public RPIdentityRequirement GetRPIdentityRequirement()
|
|
{
|
|
if (this.m_rpStrongIdentityRequired == null)
|
|
{
|
|
this.m_rpStrongIdentityRequired = new RPIdentityRequirement(this.m_id, false);
|
|
if (this.m_storeConnection != null)
|
|
this.m_rpStrongIdentityRequired.Get(this.m_storeConnection);
|
|
}
|
|
return this.m_rpStrongIdentityRequired;
|
|
}
|
|
|
|
public void AddClaim(InfoCardClaim claim)
|
|
{
|
|
InfoCardTrace.Assert(null != claim, "null claim");
|
|
this.GetClaims().Add(claim);
|
|
}
|
|
|
|
public void AddLedgerEntry(LedgerEntry entry)
|
|
{
|
|
InfoCardTrace.Assert(null != entry, "null ledger entry");
|
|
this.GetLedger().Add(entry);
|
|
}
|
|
|
|
public DateTime ExpiresOn
|
|
{
|
|
get => this.m_expiresOn;
|
|
set => this.m_expiresOn = value;
|
|
}
|
|
|
|
public uint Epoch
|
|
{
|
|
get => this.m_epoch;
|
|
set => this.m_epoch = value;
|
|
}
|
|
|
|
public Uri Id
|
|
{
|
|
get => this.m_id;
|
|
set => this.m_id = value;
|
|
}
|
|
|
|
public DateTime IssuedOn
|
|
{
|
|
get => this.m_issuedOn;
|
|
set => this.m_issuedOn = value;
|
|
}
|
|
|
|
public string IssuerName
|
|
{
|
|
get => this.m_issuerName;
|
|
set => this.m_issuerName = value;
|
|
}
|
|
|
|
public byte[] IssuerIdentifierAsBytes
|
|
{
|
|
get => this.m_issuerIdentifierAsBytes;
|
|
set => this.m_issuerIdentifierAsBytes = value;
|
|
}
|
|
|
|
public Uri Issuer
|
|
{
|
|
set => this.m_issuer = value;
|
|
}
|
|
|
|
public string Language
|
|
{
|
|
get => this.m_language;
|
|
set => this.m_language = value;
|
|
}
|
|
|
|
public RequireAppliesToStatus RequireAppliesto
|
|
{
|
|
get => this.m_requireAppliesTo;
|
|
set => this.m_requireAppliesTo = value;
|
|
}
|
|
|
|
public bool IsSelfIssued
|
|
{
|
|
get => this.m_isSelfIssued;
|
|
set => this.m_isSelfIssued = value;
|
|
}
|
|
|
|
public string PrivacyPolicyLink
|
|
{
|
|
get => this.m_privacyPolicyLink;
|
|
set => this.m_privacyPolicyLink = value;
|
|
}
|
|
|
|
public uint PrivacyPolicyVersion => this.m_privacyPolicyVersion;
|
|
|
|
public LedgerEntryCollection GetLedger()
|
|
{
|
|
if (this.m_ledger == null)
|
|
{
|
|
InfoCardTrace.Assert((Uri) null != this.m_id, "m_id is null");
|
|
this.m_ledger = new LedgerEntryCollection(this.m_id);
|
|
if (this.m_storeConnection != null)
|
|
this.m_ledger.Get(this.m_storeConnection);
|
|
}
|
|
return this.m_ledger;
|
|
}
|
|
|
|
public StoreConnection Connection
|
|
{
|
|
set => this.m_storeConnection = value;
|
|
}
|
|
|
|
public LedgerEntry TryGetLedgerEntry(
|
|
StoreConnection connection,
|
|
string recipientIdentifier)
|
|
{
|
|
LedgerEntry ledgerEntry = (LedgerEntry) null;
|
|
InfoCardTrace.Assert(null != connection, "The store connection cannot be null.");
|
|
InfoCardTrace.Assert(!string.IsNullOrEmpty(recipientIdentifier), "A recipient identifier must be specified.");
|
|
if (this.m_ledger != null && this.m_ledger.ContainsKey(recipientIdentifier))
|
|
ledgerEntry = this.m_ledger[recipientIdentifier];
|
|
if (ledgerEntry == null)
|
|
{
|
|
DataRow singleRow = connection.GetSingleRow(new QueryParameter("ix_objecttype", new object[1]
|
|
{
|
|
(object) -1
|
|
}), new QueryParameter("ix_parentid", new object[1]
|
|
{
|
|
(object) GlobalId.DeriveFrom(this.m_id.ToString())
|
|
}), new QueryParameter("ix_name", new object[1]
|
|
{
|
|
(object) recipientIdentifier
|
|
}));
|
|
if (singleRow != null)
|
|
ledgerEntry = new LedgerEntry((Stream) new MemoryStream(singleRow.GetDataField()), connection);
|
|
}
|
|
return ledgerEntry;
|
|
}
|
|
|
|
public LedgerEntry CreateLedgerEntry(
|
|
Recipient recipient,
|
|
string immediateTokenRecipientOrganizationIdentifier)
|
|
{
|
|
InfoCardTrace.Assert(null != recipient, "A recipient must be specified.");
|
|
if (this.m_ledger == null)
|
|
{
|
|
InfoCardTrace.Assert((Uri) null != this.m_id, "The card identifier must be defined.");
|
|
this.m_ledger = new LedgerEntryCollection(this.Id);
|
|
}
|
|
LedgerEntry entry = LedgerEntry.NewLedgerEntry(this.Id, recipient, this.Key, immediateTokenRecipientOrganizationIdentifier);
|
|
this.m_ledger.Add(entry);
|
|
return entry;
|
|
}
|
|
|
|
public void CheckAndUpdateLedgerEntry(LedgerEntry entry, string immediateTokenRecipientOrgId)
|
|
{
|
|
if (!entry.CheckAndUpdateSubjectKey(immediateTokenRecipientOrgId, this.Key))
|
|
return;
|
|
if (this.m_ledger == null)
|
|
{
|
|
InfoCardTrace.Assert((Uri) null != this.Id, "The card identifier must be defined.");
|
|
this.m_ledger = new LedgerEntryCollection(this.Id);
|
|
}
|
|
if (this.m_ledger.ContainsKey(entry.Recipient.RecipientId))
|
|
this.m_ledger[entry.Recipient.RecipientId] = entry;
|
|
else
|
|
this.m_ledger.Add(entry);
|
|
}
|
|
|
|
public byte[] Logo
|
|
{
|
|
get => this.m_logo;
|
|
set => this.m_logo = value;
|
|
}
|
|
|
|
public string LogoMimeType
|
|
{
|
|
get => this.m_mimeType;
|
|
set => this.m_mimeType = value;
|
|
}
|
|
|
|
public string Name
|
|
{
|
|
get => this.m_name;
|
|
set => this.m_name = value;
|
|
}
|
|
|
|
public DateTime LastUpdate
|
|
{
|
|
get => this.m_lastUpdate;
|
|
set => this.m_lastUpdate = value;
|
|
}
|
|
|
|
public int BackgroundColor
|
|
{
|
|
get => this.m_backgroundColor;
|
|
set => this.m_backgroundColor = value;
|
|
}
|
|
|
|
public byte[] HashSalt
|
|
{
|
|
set => this.m_salt = value;
|
|
get => this.m_salt;
|
|
}
|
|
|
|
public string[] SupportedClaimTypes
|
|
{
|
|
get
|
|
{
|
|
List<string> stringList = new List<string>();
|
|
foreach (string key in this.GetClaims().Keys)
|
|
{
|
|
if (!this.IsSelfIssued || !string.IsNullOrEmpty(this.GetClaims()[key].Value))
|
|
stringList.Add(key);
|
|
}
|
|
return stringList.ToArray();
|
|
}
|
|
}
|
|
|
|
public bool IsImported
|
|
{
|
|
set => this.m_isImported = value;
|
|
}
|
|
|
|
public DateTime InstalledOn
|
|
{
|
|
set => this.m_installedOn = value;
|
|
}
|
|
|
|
public bool IsPinProtected => this.m_pinHash != null && this.m_pinHash.Length > 0;
|
|
|
|
public string Pin => this.m_pin;
|
|
|
|
public InfoCardMasterKey GetMasterKey(StoreConnection connection)
|
|
{
|
|
InfoCardTrace.Assert(null != connection, "Store connection should not be null");
|
|
this.m_masterKey = new InfoCardMasterKey(this.m_id);
|
|
this.m_masterKey.Get(connection);
|
|
return this.m_masterKey;
|
|
}
|
|
|
|
public void Decrypt()
|
|
{
|
|
InfoCardTrace.Assert(null != this.m_masterKey, "The GetMasterKey must be called before using this method.");
|
|
PinProtectionHelper pinHelper = this.m_masterKey.GetPinHelper(this.m_pin);
|
|
this.m_masterKey.Decrypt(pinHelper);
|
|
this.GetClaims().Decrypt(pinHelper);
|
|
}
|
|
|
|
public byte[] Key => this.m_masterKey != null ? this.m_masterKey.Key : (byte[]) null;
|
|
|
|
public void ClearSensitiveData()
|
|
{
|
|
if (this.m_masterKey == null)
|
|
return;
|
|
Array.Clear((Array) this.m_masterKey.Key, 0, this.m_masterKey.Key.Length);
|
|
}
|
|
|
|
public static byte[] GenerateSalt()
|
|
{
|
|
byte[] data = new byte[16];
|
|
new RNGCryptoServiceProvider().GetBytes(data);
|
|
return data;
|
|
}
|
|
|
|
public void ThrowIfNotComplete()
|
|
{
|
|
if (!this.IsComplete())
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new SerializationIncompleteException(this.GetType()));
|
|
}
|
|
|
|
public bool IsComplete()
|
|
{
|
|
bool flag = !string.IsNullOrEmpty(this.m_language) && (Uri) null != this.m_id && (Uri) null != this.m_issuer && !Utility.ArrayIsNullOrEmpty((Array) this.m_tokenTypes) && this.m_privacyPolicyLink != null && !Utility.ArrayIsNullOrEmpty((Array) this.m_salt) && this.m_epoch > 0U && DateTime.MinValue != this.m_issuedOn && DateTime.MinValue != this.m_expiresOn && DateTime.MinValue != this.m_lastUpdate;
|
|
if (!this.IsSelfIssued)
|
|
flag = flag && this.CreationParameters.Count > 0 && null != this.m_issuerIdentifierAsBytes;
|
|
return flag;
|
|
}
|
|
|
|
private RSACryptoServiceProvider GetPrivateKeyPairRsaProvider(
|
|
string recipientIdentifier)
|
|
{
|
|
LedgerEntry ledgerEntry = this.TryGetLedgerEntry(this.m_storeConnection, recipientIdentifier);
|
|
InfoCardTrace.Assert(null != ledgerEntry, "null ledger");
|
|
RSACryptoServiceProvider keyPairRsaProvider = new RSACryptoServiceProvider(2048);
|
|
keyPairRsaProvider.ImportCspBlob(ledgerEntry.SubjectKey);
|
|
return keyPairRsaProvider;
|
|
}
|
|
|
|
public RSACryptoServiceProvider GetPrivateCryptography(
|
|
string recipientIdentifier)
|
|
{
|
|
return this.GetPrivateKeyPairRsaProvider(recipientIdentifier);
|
|
}
|
|
|
|
public RSACryptoServiceProvider GetPublicCryptography(
|
|
string recipientIdentifier)
|
|
{
|
|
RSACryptoServiceProvider keyPairRsaProvider = this.GetPrivateKeyPairRsaProvider(recipientIdentifier);
|
|
keyPairRsaProvider.ImportCspBlob(keyPairRsaProvider.ExportCspBlob(false));
|
|
InfoCardTrace.Assert(keyPairRsaProvider.PublicOnly, "GetPublicCryptography returns a public only rsa");
|
|
return keyPairRsaProvider;
|
|
}
|
|
|
|
private void Serialize(Stream stream)
|
|
{
|
|
this.ThrowIfNotComplete();
|
|
BinaryWriter writer = new BinaryWriter(stream, Encoding.Unicode);
|
|
writer.Write((byte) 1);
|
|
writer.Write(this.m_expiresOn.ToFileTimeUtc());
|
|
writer.Write(this.m_epoch);
|
|
Utility.SerializeUri(writer, this.m_id);
|
|
writer.Write(this.m_issuedOn.ToFileTimeUtc());
|
|
writer.Write(this.m_isImported);
|
|
writer.Write(this.m_installedOn.ToFileTimeUtc());
|
|
writer.Write(this.m_isSelfIssued);
|
|
Utility.SerializeUri(writer, this.m_issuer);
|
|
Utility.SerializeString(writer, this.m_issuerName);
|
|
Utility.SerializeBytes(writer, this.m_issuerIdentifierAsBytes);
|
|
Utility.SerializeString(writer, this.m_language);
|
|
Utility.SerializeBytes(writer, this.m_logo);
|
|
Utility.SerializeString(writer, this.m_mimeType);
|
|
Utility.SerializeString(writer, this.m_name);
|
|
writer.Write(this.m_lastUpdate.ToFileTimeUtc());
|
|
writer.Write(this.m_backgroundColor);
|
|
writer.Write((byte) this.m_requireAppliesTo);
|
|
Utility.SerializeString(writer, this.m_privacyPolicyLink);
|
|
writer.Write(this.m_privacyPolicyVersion);
|
|
Utility.SerializeBytes(writer, this.m_pinHash);
|
|
Utility.SerializeBytes(writer, this.m_salt);
|
|
writer.Write(this.m_tokenTypes.Length);
|
|
for (int index = 0; index < this.m_tokenTypes.Length; ++index)
|
|
Utility.SerializeString(writer, this.m_tokenTypes[index]);
|
|
writer.Write(this.m_creationParameters == null ? 0 : this.m_creationParameters.Count);
|
|
if (this.m_creationParameters != null)
|
|
{
|
|
for (int index = 0; index < this.m_creationParameters.Count; ++index)
|
|
this.m_creationParameters[index].Serialize(writer);
|
|
}
|
|
Utility.SerializeString(writer, string.Empty);
|
|
Utility.SerializeString(writer, string.Empty);
|
|
writer.Write((byte) this.m_pinAction);
|
|
writer.Write((byte) 29);
|
|
}
|
|
|
|
public void AgentSerialize(
|
|
Stream stream,
|
|
bool initCalcAttributesForGetToken,
|
|
InfoCardPolicy policy,
|
|
StoreConnection storeConnection,
|
|
CultureInfo userCulture)
|
|
{
|
|
this.Serialize(stream);
|
|
this.m_storeConnection = storeConnection;
|
|
this.GetRPIdentityRequirement().Serialize(stream);
|
|
this.GetExtendedInformation().Serialize(stream);
|
|
InfoCard.GetIssuerInformation(this.GetExtendedInformation().GetIssuerInformationElement()).Serialize(stream);
|
|
InfoCardClaimCollection claims = this.GetClaims();
|
|
if (policy != null && this.IsSelfIssued)
|
|
{
|
|
CultureInfo currentUiCulture = Thread.CurrentThread.CurrentUICulture;
|
|
try
|
|
{
|
|
Thread.CurrentThread.CurrentUICulture = userCulture;
|
|
string ppid = Utility.CreatePpid(Convert.FromBase64String(policy.ImmediateTokenRecipient.GetOrganizationPPIDIdentifier()), this.m_id);
|
|
claims.Add(new InfoCardClaim(InfoCardConstants.PPIDClaimsUri, ppid, InfoCardConstants.ClaimsDescription(InfoCardConstants.PPID), InfoCardConstants.ClaimDisplayTag(InfoCardConstants.PPID)));
|
|
}
|
|
finally
|
|
{
|
|
Thread.CurrentThread.CurrentUICulture = currentUiCulture;
|
|
}
|
|
}
|
|
claims.AgentSerialize(stream);
|
|
BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.Unicode);
|
|
if (initCalcAttributesForGetToken)
|
|
{
|
|
binaryWriter.Write(this.DoesCardMatchPolicySet(policy));
|
|
binaryWriter.Write(this.CardMatchesPolicyRequiredIssuer(policy));
|
|
binaryWriter.Write(this.HasCardBeenUsedBefore(policy.Recipient.GetIdentifier(), storeConnection));
|
|
binaryWriter.Write(this.HaveRequestedClaimsChanged(policy, storeConnection));
|
|
binaryWriter.Write(this.WillSendAppliesToInRst(policy));
|
|
binaryWriter.Write(this.DoesCardSupportAnyOptionalClaims(policy));
|
|
binaryWriter.Write(this.DoesCardMatchNonClaimPolicyRequirements(policy));
|
|
}
|
|
else
|
|
{
|
|
binaryWriter.Write(false);
|
|
binaryWriter.Write(false);
|
|
binaryWriter.Write(false);
|
|
binaryWriter.Write(false);
|
|
binaryWriter.Write(false);
|
|
binaryWriter.Write(false);
|
|
binaryWriter.Write(false);
|
|
}
|
|
binaryWriter.Flush();
|
|
}
|
|
|
|
public void CopyMetaData(InfoCard card)
|
|
{
|
|
this.m_salt = new byte[card.HashSalt.Length];
|
|
Array.Copy((Array) card.HashSalt, 0, (Array) this.m_salt, 0, card.HashSalt.Length);
|
|
this.m_pinHash = new byte[card.m_pinHash.Length];
|
|
Array.Copy((Array) card.m_pinHash, 0, (Array) this.m_pinHash, 0, card.m_pinHash.Length);
|
|
}
|
|
|
|
private bool DoesCardSupportAnyOptionalClaims(InfoCardPolicy policy)
|
|
{
|
|
List<string> stringList = new List<string>((IEnumerable<string>) policy.OptionalClaims);
|
|
foreach (string key in this.GetClaims().Keys)
|
|
{
|
|
if (stringList.Contains(key))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool WillSendAppliesToInRst(InfoCardPolicy policy)
|
|
{
|
|
AppliesToBehaviorDecision decisionForPolicyMatch = AppliesToBehaviorDecisionTable.GetAppliesToBehaviorDecisionForPolicyMatch(policy, this.RequireAppliesto);
|
|
return AppliesToBehaviorDecision.SendCustomAppliesTo == decisionForPolicyMatch || AppliesToBehaviorDecision.SendRPAppliesTo == decisionForPolicyMatch;
|
|
}
|
|
|
|
private void Deserialize(Stream stream)
|
|
{
|
|
BinaryReader reader = (BinaryReader) new InfoCardBinaryReader(stream, Encoding.Unicode);
|
|
this.m_expiresOn = (byte) 1 == reader.ReadByte() ? DateTime.FromFileTimeUtc(reader.ReadInt64()) : throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException("ServiceCardWrongVersion"));
|
|
this.m_epoch = reader.ReadUInt32();
|
|
this.m_id = new Uri(Utility.DeserializeString(reader));
|
|
this.m_issuedOn = DateTime.FromFileTimeUtc(reader.ReadInt64());
|
|
this.m_isImported = reader.ReadBoolean();
|
|
this.m_installedOn = DateTime.FromFileTimeUtc(reader.ReadInt64());
|
|
this.m_isSelfIssued = reader.ReadBoolean();
|
|
this.m_issuer = Utility.DeserializeUri(reader);
|
|
this.m_issuerName = Utility.DeserializeString(reader);
|
|
int count1 = reader.ReadInt32();
|
|
this.m_issuerIdentifierAsBytes = reader.ReadBytes(count1);
|
|
this.m_language = Utility.DeserializeString(reader);
|
|
int count2 = reader.ReadInt32();
|
|
InfoCardTrace.Assert((0 > count2 ? 0 : (count2 < 1048576 ? 1 : 0)) != 0, "logo length out of range {0}", (object) count2);
|
|
this.m_logo = reader.ReadBytes(count2);
|
|
this.m_mimeType = Utility.DeserializeString(reader);
|
|
this.m_name = Utility.DeserializeString(reader);
|
|
this.m_lastUpdate = DateTime.FromFileTimeUtc(reader.ReadInt64());
|
|
this.m_backgroundColor = reader.ReadInt32();
|
|
this.m_requireAppliesTo = (RequireAppliesToStatus) reader.ReadByte();
|
|
this.m_privacyPolicyLink = Utility.DeserializeString(reader);
|
|
this.m_privacyPolicyVersion = reader.ReadUInt32();
|
|
int count3 = reader.ReadInt32();
|
|
InfoCardTrace.Assert((0 > count3 ? 0 : (count3 < 1024 ? 1 : 0)) != 0, "pin hash out fo range {0}", (object) count3);
|
|
this.m_pinHash = reader.ReadBytes(count3);
|
|
int count4 = reader.ReadInt32();
|
|
InfoCardTrace.Assert((0 > count4 ? 0 : (count4 < 1024 ? 1 : 0)) != 0, "salt length out of range {0}", (object) count4);
|
|
this.m_salt = reader.ReadBytes(count4);
|
|
int length = reader.ReadInt32();
|
|
InfoCardTrace.Assert(32 > length, "too many token types");
|
|
this.m_tokenTypes = new string[length];
|
|
for (int index = 0; index < length; ++index)
|
|
this.m_tokenTypes[index] = Utility.DeserializeString(reader);
|
|
int num = reader.ReadInt32();
|
|
InfoCardTrace.Assert((0 > num ? 0 : (num < 128 ? 1 : 0)) != 0, "creation parametes out of range {0}", (object) num);
|
|
for (int index = 0; index < num; ++index)
|
|
{
|
|
TokenCreationParameter creationParameter = new TokenCreationParameter();
|
|
creationParameter.Deserialize(reader);
|
|
this.CreationParameters.Add(creationParameter);
|
|
}
|
|
this.m_pin = Utility.DeserializeString(reader);
|
|
this.m_oldPin = Utility.DeserializeString(reader);
|
|
this.m_pinAction = (InfoCard.PinAction) reader.ReadByte();
|
|
if ((byte) 29 != reader.ReadByte())
|
|
InfoCardTrace.Assert(false, "malformed stream detected");
|
|
this.ThrowIfNotComplete();
|
|
}
|
|
|
|
public Dictionary<string, bool> GetClaimsToBeDisclosed(
|
|
InfoCardPolicy policy,
|
|
bool discloseOptional)
|
|
{
|
|
Dictionary<string, bool> claimsToBeDisclosed = new Dictionary<string, bool>(policy.RequiredClaims.Length);
|
|
for (int index = 0; index < policy.RequiredClaims.Length; ++index)
|
|
claimsToBeDisclosed.Add(policy.RequiredClaims[index], false);
|
|
if (discloseOptional)
|
|
{
|
|
for (int index = 0; index < policy.OptionalClaims.Length; ++index)
|
|
{
|
|
string optionalClaim = policy.OptionalClaims[index];
|
|
if (this.GetClaims().ContainsKey(optionalClaim))
|
|
claimsToBeDisclosed.Add(policy.OptionalClaims[index], true);
|
|
}
|
|
}
|
|
return claimsToBeDisclosed;
|
|
}
|
|
|
|
public bool DoesCardMatchPolicySet(InfoCardPolicy policy)
|
|
{
|
|
InfoCardTrace.Assert(null != policy, "null policy");
|
|
bool flag = true;
|
|
List<string> stringList = new List<string>((IEnumerable<string>) this.SupportedClaimTypes);
|
|
if (policy.RequiredClaims != null)
|
|
{
|
|
foreach (string requiredClaim in policy.RequiredClaims)
|
|
{
|
|
if (!stringList.Contains(requiredClaim) && (!this.IsSelfIssued || !(InfoCardConstants.PPIDClaimsUri == requiredClaim)))
|
|
{
|
|
flag = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return flag && this.DoesCardMatchNonClaimPolicyRequirements(policy);
|
|
}
|
|
|
|
public bool DoesCardMatchNonClaimPolicyRequirements(InfoCardPolicy policy)
|
|
{
|
|
InfoCardTrace.Assert(null != policy, "null policy");
|
|
bool flag1 = true;
|
|
if (!this.IsSelfIssued && AppliesToBehaviorDecision.FailMatch == AppliesToBehaviorDecisionTable.GetAppliesToBehaviorDecisionForPolicyMatch(policy, this.RequireAppliesto))
|
|
flag1 = false;
|
|
bool flag2 = true;
|
|
if (this.GetRPIdentityRequirement().StrongIdentityRequired && !(policy.ImmediateTokenRecipient is X509RecipientIdentity))
|
|
flag2 = false;
|
|
return (!this.IsSelfIssued || !policy.RequiresManagedCard) && this.CardMatchesPolicyTokenType(policy) && this.CardMatchesPolicyRequiredIssuer(policy) && flag1 && flag2;
|
|
}
|
|
|
|
public bool HaveRequestedClaimsChanged(InfoCardPolicy policy, StoreConnection connection)
|
|
{
|
|
InfoCardTrace.Assert((Uri) null != this.m_id, "Null id");
|
|
InfoCardTrace.Assert(null != policy, "null policy");
|
|
InfoCardTrace.Assert(null != connection, "null connection");
|
|
LedgerEntry ledgerEntry = this.TryGetLedgerEntry(connection, policy.Recipient.GetIdentifier());
|
|
if (ledgerEntry == null)
|
|
return true;
|
|
IList list = (IList) (ledgerEntry.DisclosedClaims ?? new string[0]);
|
|
int num1 = 0;
|
|
if (policy.RequiredClaims != null)
|
|
num1 = policy.RequiredClaims.Length;
|
|
if (num1 > list.Count)
|
|
return true;
|
|
bool flag = true;
|
|
foreach (string requiredClaim in policy.RequiredClaims)
|
|
{
|
|
if (!list.Contains((object) requiredClaim))
|
|
{
|
|
flag = false;
|
|
break;
|
|
}
|
|
}
|
|
int num2 = flag ? 1 : 0;
|
|
return !flag;
|
|
}
|
|
|
|
private bool CardMatchesPolicyTokenType(InfoCardPolicy policy)
|
|
{
|
|
if (string.IsNullOrEmpty(policy.OptionalRstParams.TokenType))
|
|
return true;
|
|
foreach (string tokenType in this.m_tokenTypes)
|
|
{
|
|
if (tokenType == policy.OptionalRstParams.TokenType)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool CardMatchesPolicyRequiredIssuer(InfoCardPolicy policy) => (EndpointAddress) null == policy.Issuer || (Uri) null == policy.Issuer.Uri || Utility.CompareUri(policy.Issuer.Uri, XmlNames.WSIdentity.AnonymousIssuerUriValue) || this.m_isSelfIssued && Utility.CompareUri(policy.Issuer.Uri, XmlNames.WSIdentity.SelfIssuerUriValue) || !this.m_isSelfIssued && Utility.CompareUri(policy.Issuer.Uri, this.m_issuer);
|
|
|
|
public bool HasCardBeenUsedBefore(string recipientId, StoreConnection connection) => null != connection.GetSingleRow(QueryDetails.Identifiers, new QueryParameter("ix_objecttype", new object[1]
|
|
{
|
|
(object) -1
|
|
}), new QueryParameter("ix_name", new object[1]
|
|
{
|
|
(object) recipientId
|
|
}), new QueryParameter("ix_parentid", new object[1]
|
|
{
|
|
(object) GlobalId.DeriveFrom(this.m_id.ToString())
|
|
}));
|
|
|
|
public void Get(StoreConnection con)
|
|
{
|
|
InfoCardTrace.Assert((Uri) null != this.m_id, "null id");
|
|
InfoCardTrace.Assert(null != con, "null connection");
|
|
this.m_storeConnection = con;
|
|
DataRow row = this.GetRow(con, QueryDetails.FullRow);
|
|
this.Deserialize((Stream) new MemoryStream(row.GetDataField()));
|
|
this.m_rowId = row.LocalId;
|
|
}
|
|
|
|
public void Save(StoreConnection con)
|
|
{
|
|
this.ThrowIfNotComplete();
|
|
InfoCardTrace.Assert(null != con, "null connection");
|
|
DataRow row = this.TryGetRow(con, QueryDetails.FullHeader);
|
|
bool flag = false;
|
|
if (row == null)
|
|
{
|
|
if (this.m_masterKey == null)
|
|
this.m_masterKey = InfoCardMasterKey.NewMasterKey(this.m_id);
|
|
flag = true;
|
|
row = new DataRow();
|
|
row.ObjectType = 1;
|
|
row.GlobalId = GlobalId.DeriveFrom(this.m_id.ToString());
|
|
}
|
|
InfoCardClaimCollection cardClaimCollection = (InfoCardClaimCollection) null;
|
|
switch (this.m_pinAction)
|
|
{
|
|
case InfoCard.PinAction.PinSame:
|
|
cardClaimCollection = this.m_claims.Clone();
|
|
this.GetMasterKey(con);
|
|
this.m_claims.Encrypt(this.m_masterKey.GetPinHelper(this.m_pin));
|
|
break;
|
|
case InfoCard.PinAction.PinAdded:
|
|
cardClaimCollection = this.m_claims.Clone();
|
|
this.GetMasterKey(con);
|
|
PinProtectionHelper pinHelper1 = new PinProtectionHelper(this.m_pin);
|
|
this.m_masterKey.Encrypt(pinHelper1);
|
|
this.m_claims.Encrypt(pinHelper1);
|
|
flag = true;
|
|
break;
|
|
case InfoCard.PinAction.PinRemoved:
|
|
this.GetMasterKey(con);
|
|
this.m_masterKey.Decrypt(this.m_masterKey.GetPinHelper(this.m_oldPin));
|
|
flag = true;
|
|
break;
|
|
case InfoCard.PinAction.PinChanged:
|
|
cardClaimCollection = this.m_claims.Clone();
|
|
this.GetMasterKey(con);
|
|
this.m_masterKey.Decrypt(this.m_masterKey.GetPinHelper(this.m_oldPin));
|
|
PinProtectionHelper pinHelper2 = new PinProtectionHelper(this.m_pin);
|
|
this.m_masterKey.Encrypt(pinHelper2);
|
|
this.m_claims.Encrypt(pinHelper2);
|
|
flag = true;
|
|
break;
|
|
}
|
|
if (flag)
|
|
this.m_masterKey.Save(con);
|
|
this.m_pinAction = this.IsPinProtected ? InfoCard.PinAction.PinSame : InfoCard.PinAction.NoPin;
|
|
string[] strArray;
|
|
if (this.IsSelfIssued)
|
|
{
|
|
strArray = new string[1]
|
|
{
|
|
"http://schemas.xmlsoap.org/ws/2005/05/identity/issuer/self"
|
|
};
|
|
}
|
|
else
|
|
{
|
|
strArray = new string[this.CreationParameters.Count];
|
|
int num = 0;
|
|
foreach (TokenCreationParameter creationParameter in this.CreationParameters)
|
|
strArray[num++] = creationParameter.Epr.Uri.ToString();
|
|
}
|
|
row.SetIndexValue("ix_production_svc_uri", (object[]) strArray);
|
|
InfoCardTrace.Assert(null != this.m_claims, "Must already be initialized at this point");
|
|
row.SetIndexValue("ix_supportclaim", (object[]) this.SupportedClaimTypes);
|
|
if (this.CreationParameters.Count > 0)
|
|
{
|
|
object[] objArray = new object[this.CreationParameters.Count];
|
|
int num = 0;
|
|
foreach (TokenCreationParameter creationParameter in this.CreationParameters)
|
|
objArray[num++] = (object) (int) creationParameter.CredentialType;
|
|
row.SetIndexValue("ix_supportauth", objArray);
|
|
}
|
|
MemoryStream memoryStream = new MemoryStream();
|
|
this.Serialize((Stream) memoryStream);
|
|
row.SetDataField(memoryStream.ToArray());
|
|
con.Save(row);
|
|
this.m_rowId = row.LocalId;
|
|
if (this.m_extendedInformation != null)
|
|
this.m_extendedInformation.Save(con);
|
|
this.m_claims.Save(con, this.m_isSelfIssued);
|
|
if (cardClaimCollection != null)
|
|
this.m_claims = cardClaimCollection;
|
|
this.GetRPIdentityRequirement().Save(con);
|
|
}
|
|
|
|
public override string ToString() => base.ToString();
|
|
|
|
public static InfoCard NewCard(CultureInfo userCulture)
|
|
{
|
|
InfoCard infoCard = new InfoCard();
|
|
infoCard.m_expiresOn = DateTime.MaxValue;
|
|
infoCard.m_epoch = 1U;
|
|
infoCard.m_id = new Uri("urn:uuid:" + Guid.NewGuid().ToString());
|
|
infoCard.m_issuedOn = DateTime.UtcNow;
|
|
infoCard.m_isImported = false;
|
|
infoCard.m_installedOn = DateTime.UtcNow;
|
|
infoCard.m_isSelfIssued = true;
|
|
infoCard.m_issuerName = SR.GetString("SelfIssuedIssuerName");
|
|
infoCard.m_issuer = XmlNames.WSIdentity.SelfIssuerUriValue;
|
|
infoCard.m_language = userCulture.TwoLetterISOLanguageName;
|
|
infoCard.m_logo = new byte[0];
|
|
infoCard.m_name = (string) null;
|
|
infoCard.m_lastUpdate = DateTime.UtcNow;
|
|
infoCard.m_backgroundColor = 16777215;
|
|
infoCard.m_requireAppliesTo = RequireAppliesToStatus.NotPresent;
|
|
infoCard.m_salt = InfoCard.GenerateSalt();
|
|
infoCard.m_tokenTypes = new string[2]
|
|
{
|
|
"urn:oasis:names:tc:SAML:1.0:assertion",
|
|
"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"
|
|
};
|
|
CultureInfo currentUiCulture = Thread.CurrentThread.CurrentUICulture;
|
|
try
|
|
{
|
|
Thread.CurrentThread.CurrentUICulture = userCulture;
|
|
for (int index = 0; index < InfoCardConstants.SelfIssuedClaimsUris.Length; ++index)
|
|
{
|
|
InfoCardClaim claim = new InfoCardClaim(InfoCardConstants.SelfIssuedClaimsUris[index], (string) null, InfoCardConstants.ClaimsDescription(InfoCardConstants.SelfIssuedClaimsUris[index]), InfoCardConstants.ClaimDisplayTag(InfoCardConstants.SelfIssuedClaimsUris[index]));
|
|
infoCard.AddClaim(claim);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Thread.CurrentThread.CurrentUICulture = currentUiCulture;
|
|
}
|
|
InfoCardTrace.Assert(null == infoCard.m_masterKey, "Card key is only populated during save");
|
|
return infoCard;
|
|
}
|
|
|
|
protected DataRow GetRow(StoreConnection con, QueryDetails details)
|
|
{
|
|
InfoCardTrace.Assert(null != con, " null connection");
|
|
DataRow row = this.TryGetRow(con, details);
|
|
InfoCardTrace.Assert(null != row, "null row");
|
|
InfoCardTrace.Assert((1 == row.ObjectType ? 1 : 0) != 0, "Attempt to deserialize an incorrect object type {0}", (object) row.ObjectType);
|
|
return row;
|
|
}
|
|
|
|
protected DataRow TryGetRow(StoreConnection con, QueryDetails details)
|
|
{
|
|
InfoCardTrace.Assert((Uri) null != this.m_id, "null id");
|
|
InfoCardTrace.Assert(null != con, "null connection");
|
|
return con.GetSingleRow(details, new QueryParameter("ix_globalid", new object[1]
|
|
{
|
|
(object) GlobalId.DeriveFrom(this.m_id.ToString())
|
|
}));
|
|
}
|
|
|
|
public void ReadXml(XmlReader reader)
|
|
{
|
|
if ("RoamingInformationCard" == reader.LocalName)
|
|
this.ReadRoamingInfoCard(reader);
|
|
else if ("InformationCard" == reader.LocalName)
|
|
this.ReadImportedInfoCard(reader);
|
|
else
|
|
InfoCardTrace.Assert(false, "Invalid element found. Did schema validation fail? Found {0}", (object) reader.LocalName);
|
|
}
|
|
|
|
public System.Xml.Schema.XmlSchema GetSchema() => (System.Xml.Schema.XmlSchema) null;
|
|
|
|
public void WriteXml(XmlWriter writer)
|
|
{
|
|
this.ThrowIfNotComplete();
|
|
writer.WriteStartElement("RoamingInformationCard", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteStartElement("InformationCardMetaData", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteAttributeString("lang", "http://www.w3.org/XML/1998/namespace", this.m_language);
|
|
writer.WriteStartElement("InformationCardReference", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteStartElement("CardId", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteString(this.m_id.AbsoluteUri);
|
|
writer.WriteEndElement();
|
|
writer.WriteStartElement("CardVersion", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteString(this.m_epoch.ToString((IFormatProvider) CultureInfo.InvariantCulture));
|
|
writer.WriteEndElement();
|
|
writer.WriteEndElement();
|
|
if (!string.IsNullOrEmpty(this.m_name))
|
|
{
|
|
writer.WriteStartElement("CardName", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteString(this.m_name);
|
|
writer.WriteEndElement();
|
|
}
|
|
if (this.m_logo != null && this.m_logo.Length != 0)
|
|
{
|
|
writer.WriteStartElement("CardImage", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
if (!string.IsNullOrEmpty(this.m_mimeType))
|
|
writer.WriteAttributeString("MimeType", this.m_mimeType);
|
|
string base64String = Convert.ToBase64String(this.m_logo);
|
|
writer.WriteString(base64String);
|
|
writer.WriteEndElement();
|
|
}
|
|
writer.WriteStartElement("Issuer", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
if ((Uri) null != this.m_issuer)
|
|
writer.WriteString(this.m_issuer.AbsoluteUri);
|
|
writer.WriteEndElement();
|
|
writer.WriteStartElement("TimeIssued", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteString(XmlConvert.ToString(this.m_issuedOn, XmlDateTimeSerializationMode.Utc));
|
|
writer.WriteEndElement();
|
|
writer.WriteStartElement("TimeExpires", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteString(XmlConvert.ToString(this.m_expiresOn, XmlDateTimeSerializationMode.Utc));
|
|
writer.WriteEndElement();
|
|
if (this.m_creationParameters != null)
|
|
{
|
|
writer.WriteStartElement("TokenServiceList", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
foreach (TokenCreationParameter creationParameter in this.m_creationParameters)
|
|
creationParameter.WriteXml(writer);
|
|
writer.WriteEndElement();
|
|
}
|
|
writer.WriteStartElement("SupportedTokenTypeList", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
foreach (string tokenType in this.m_tokenTypes)
|
|
writer.WriteElementString("TokenType", "http://schemas.xmlsoap.org/ws/2005/02/trust", tokenType);
|
|
writer.WriteEndElement();
|
|
writer.WriteStartElement("SupportedClaimTypeList", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
foreach (string key in this.GetClaims().Keys)
|
|
{
|
|
InfoCardClaim claim = this.GetClaims()[key];
|
|
if (!this.m_isSelfIssued || !Utility.CompareUri(claim.Id, InfoCardConstants.PPIDClaimsUri))
|
|
{
|
|
writer.WriteStartElement("SupportedClaimType", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteAttributeString("Uri", claim.Id);
|
|
if (!string.IsNullOrEmpty(claim.DisplayTag))
|
|
writer.WriteElementString("DisplayTag", "http://schemas.xmlsoap.org/ws/2005/05/identity", claim.DisplayTag);
|
|
if (!string.IsNullOrEmpty(claim.Description))
|
|
writer.WriteElementString("Description", "http://schemas.xmlsoap.org/ws/2005/05/identity", claim.Description);
|
|
writer.WriteEndElement();
|
|
}
|
|
}
|
|
writer.WriteEndElement();
|
|
if (this.m_requireAppliesTo != RequireAppliesToStatus.NotPresent)
|
|
{
|
|
writer.WriteStartElement("RequireAppliesTo", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
if (RequireAppliesToStatus.Optional == this.m_requireAppliesTo)
|
|
writer.WriteAttributeString("Optional", "true");
|
|
writer.WriteEndElement();
|
|
}
|
|
if (!string.IsNullOrEmpty(this.m_privacyPolicyLink))
|
|
{
|
|
writer.WriteStartElement("PrivacyNotice", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
if (0U < this.m_privacyPolicyVersion)
|
|
writer.WriteAttributeString("Version", this.m_privacyPolicyVersion.ToString((IFormatProvider) CultureInfo.InvariantCulture));
|
|
writer.WriteString(this.m_privacyPolicyLink);
|
|
writer.WriteEndElement();
|
|
}
|
|
if (this.GetRPIdentityRequirement().StrongIdentityRequired)
|
|
{
|
|
writer.WriteStartElement("RequireStrongRecipientIdentity", "http://schemas.xmlsoap.org/ws/2007/01/identity");
|
|
writer.WriteEndElement();
|
|
}
|
|
if (this.GetExtendedInformation() != null)
|
|
{
|
|
foreach (InfocardExtendedInformationEntry informationEntry in (List<InfocardExtendedInformationEntry>) this.m_extendedInformation)
|
|
informationEntry.WriteXml(writer);
|
|
}
|
|
writer.WriteStartElement("IsSelfIssued", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteString(XmlConvert.ToString(this.m_isSelfIssued));
|
|
writer.WriteEndElement();
|
|
if (!Utility.ArrayIsNullOrEmpty((Array) this.m_pinHash))
|
|
{
|
|
writer.WriteStartElement("PinDigest", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteString(Convert.ToBase64String(this.m_pinHash));
|
|
writer.WriteEndElement();
|
|
}
|
|
writer.WriteStartElement("HashSalt", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteString(Convert.ToBase64String(this.m_salt));
|
|
writer.WriteEndElement();
|
|
writer.WriteStartElement("TimeLastUpdated", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteString(XmlConvert.ToString(this.m_lastUpdate, XmlDateTimeSerializationMode.Utc));
|
|
writer.WriteEndElement();
|
|
writer.WriteStartElement("IssuerId", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
if (this.m_issuerIdentifierAsBytes != null)
|
|
writer.WriteString(Convert.ToBase64String(this.m_issuerIdentifierAsBytes, Base64FormattingOptions.None));
|
|
writer.WriteEndElement();
|
|
writer.WriteStartElement("IssuerName", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
if (!string.IsNullOrEmpty(this.m_issuerName))
|
|
writer.WriteString(this.m_issuerName);
|
|
writer.WriteEndElement();
|
|
writer.WriteStartElement("BackgroundColor", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteString(XmlConvert.ToString(this.m_backgroundColor));
|
|
writer.WriteEndElement();
|
|
writer.WriteEndElement();
|
|
writer.WriteStartElement("InformationCardPrivateData", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
InfoCardTrace.Assert(null != this.m_masterKey, "Masterkey Cannot be null when trying to export a card");
|
|
writer.WriteStartElement("MasterKey", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteString(Convert.ToBase64String(this.m_masterKey.Key));
|
|
writer.WriteEndElement();
|
|
if (this.IsSelfIssued)
|
|
{
|
|
writer.WriteStartElement("ClaimValueList", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
foreach (string key in this.GetClaims().Keys)
|
|
{
|
|
InfoCardClaim claim = this.GetClaims()[key];
|
|
if (!Utility.CompareUri(claim.Id, InfoCardConstants.PPIDClaimsUri))
|
|
{
|
|
writer.WriteStartElement("ClaimValue", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
writer.WriteAttributeString("Uri", claim.Id);
|
|
if (!string.IsNullOrEmpty(claim.Value))
|
|
writer.WriteElementString("Value", "http://schemas.xmlsoap.org/ws/2005/05/identity", claim.Value);
|
|
else
|
|
writer.WriteElementString("Value", "http://schemas.xmlsoap.org/ws/2005/05/identity", string.Empty);
|
|
writer.WriteEndElement();
|
|
}
|
|
}
|
|
writer.WriteEndElement();
|
|
}
|
|
writer.WriteEndElement();
|
|
writer.WriteEndElement();
|
|
}
|
|
|
|
private void ReadImportedInfoCard(XmlReader reader)
|
|
{
|
|
InfoCardTrace.Assert(null != reader, "null reader");
|
|
this.Language = reader.IsStartElement("InformationCard", "http://schemas.xmlsoap.org/ws/2005/05/identity") ? reader.GetAttribute("lang", "http://www.w3.org/XML/1998/namespace") : throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("UnexpectedElement")));
|
|
if (string.IsNullOrEmpty(this.Language))
|
|
this.Language = reader.GetAttribute("lang");
|
|
reader.ReadStartElement();
|
|
this.ReadBaseInfoCard(reader);
|
|
if (!this.IsSelfIssued && Utility.CompareUri(this.m_issuer, XmlNames.WSIdentity.SelfIssuerUriValue))
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("SelfIssuedUriUsed")));
|
|
if (this.m_extendedInformation != null)
|
|
return;
|
|
this.m_extendedInformation = new InfocardExtendedInformationCollection(this.m_id);
|
|
}
|
|
|
|
private void ReadRoamingInfoCard(XmlReader reader)
|
|
{
|
|
InfoCardTrace.Assert(null != reader, "null reader");
|
|
if (!reader.IsStartElement("RoamingInformationCard", "http://schemas.xmlsoap.org/ws/2005/05/identity"))
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("UnexpectedElement")));
|
|
reader.ReadStartElement();
|
|
this.Language = reader.GetAttribute("lang", "http://www.w3.org/XML/1998/namespace");
|
|
if (string.IsNullOrEmpty(this.Language))
|
|
this.Language = reader.GetAttribute("lang");
|
|
this.ReadBaseInfoCard(reader);
|
|
if (this.m_isSelfIssued && this.GetClaims().ContainsKey(InfoCardConstants.PPIDClaimsUri))
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("InvalidImportFile")));
|
|
this.ReadInfoCardPrivateData(reader);
|
|
}
|
|
|
|
private void ReadInfoCardPrivateData(XmlReader reader)
|
|
{
|
|
while (reader.Read())
|
|
{
|
|
switch (reader.LocalName)
|
|
{
|
|
case "RoamingInformationCard":
|
|
if (XmlNodeType.EndElement == reader.NodeType)
|
|
return;
|
|
continue;
|
|
case "MasterKey":
|
|
byte[] array = Utility.ReadByteStreamFromBase64(reader).ToArray();
|
|
if (this.IsPinProtected)
|
|
{
|
|
if (array == null || PinProtectionHelper.EncryptedMasterKeySize != array.Length)
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("InvalidImportFile")));
|
|
this.m_masterKey = new InfoCardMasterKey(this.m_id, array);
|
|
continue;
|
|
}
|
|
this.m_masterKey = array != null && 32 == array.Length ? new InfoCardMasterKey(this.m_id, array) : throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("InvalidImportFile")));
|
|
continue;
|
|
case "ClaimValueList":
|
|
this.ReadClaimValues(reader);
|
|
continue;
|
|
default:
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ReadBaseInfoCard(XmlReader reader)
|
|
{
|
|
try
|
|
{
|
|
while (reader.Read())
|
|
{
|
|
if ("http://schemas.xmlsoap.org/ws/2005/05/identity" == reader.NamespaceURI && XmlNodeType.EndElement == reader.NodeType && ("InformationCard" == reader.LocalName || "InformationCardMetaData" == reader.LocalName))
|
|
{
|
|
reader.ReadEndElement();
|
|
break;
|
|
}
|
|
if ("http://schemas.xmlsoap.org/ws/2005/05/identity" != reader.NamespaceURI && XmlNodeType.Element == reader.NodeType)
|
|
{
|
|
if ("http://schemas.xmlsoap.org/ws/2007/01/identity" == reader.NamespaceURI && "IssuerInformation" == reader.LocalName)
|
|
{
|
|
if (this.m_readIssuerInformation)
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("MultipleIssuerInformation")));
|
|
InfocardExtendedInformationEntry informationEntry = new InfocardExtendedInformationEntry();
|
|
informationEntry.ReadXml(reader);
|
|
if (this.m_extendedInformation == null)
|
|
this.m_extendedInformation = new InfocardExtendedInformationCollection(this.m_id);
|
|
this.m_extendedInformation.Add(informationEntry);
|
|
this.m_readIssuerInformation = true;
|
|
continue;
|
|
}
|
|
new InfocardExtendedInformationEntry().ReadXml(reader);
|
|
}
|
|
if ("http://schemas.xmlsoap.org/ws/2005/05/identity" == reader.NamespaceURI && XmlNodeType.EndElement != reader.NodeType)
|
|
{
|
|
switch (reader.LocalName)
|
|
{
|
|
case "CardId":
|
|
this.Id = new Uri(reader.ReadString().Trim());
|
|
continue;
|
|
case "CardVersion":
|
|
this.Epoch = Convert.ToUInt32(reader.ReadString().Trim(), (IFormatProvider) CultureInfo.InvariantCulture);
|
|
continue;
|
|
case "CardImage":
|
|
this.LogoMimeType = reader.GetAttribute("MimeType", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
if (string.IsNullOrEmpty(this.LogoMimeType))
|
|
this.LogoMimeType = reader.GetAttribute("MimeType");
|
|
this.Logo = Utility.ReadByteStreamFromBase64(reader).ToArray();
|
|
continue;
|
|
case "CardName":
|
|
this.Name = reader.ReadString().Trim();
|
|
continue;
|
|
case "IssuerName":
|
|
this.IssuerName = reader.ReadString().Trim();
|
|
continue;
|
|
case "Issuer":
|
|
this.Issuer = new Uri(reader.ReadString().Trim());
|
|
continue;
|
|
case "TimeExpires":
|
|
this.ExpiresOn = XmlConvert.ToDateTime(reader.ReadString().Trim(), XmlDateTimeSerializationMode.Utc);
|
|
continue;
|
|
case "TimeIssued":
|
|
this.IssuedOn = XmlConvert.ToDateTime(reader.ReadString().Trim(), XmlDateTimeSerializationMode.Utc);
|
|
continue;
|
|
case "SupportedClaimTypeList":
|
|
this.ReadClaims(reader);
|
|
continue;
|
|
case "SupportedTokenTypeList":
|
|
this.TokenTypes = this.ReadTokenType(reader).ToArray();
|
|
continue;
|
|
case "RequireAppliesTo":
|
|
string attribute = reader.GetAttribute("Optional", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
if (string.IsNullOrEmpty(attribute))
|
|
attribute = reader.GetAttribute("Optional");
|
|
this.RequireAppliesto = string.IsNullOrEmpty(attribute) || !("true" == attribute) && !("1" == attribute) ? RequireAppliesToStatus.Required : RequireAppliesToStatus.Optional;
|
|
continue;
|
|
case "TokenServiceList":
|
|
this.ReadAuthServices(reader);
|
|
continue;
|
|
case "PrivacyNotice":
|
|
this.ReadPrivacyPolicy(reader);
|
|
continue;
|
|
case "IsSelfIssued":
|
|
this.IsSelfIssued = Convert.ToBoolean(reader.ReadString().Trim(), (IFormatProvider) CultureInfo.InvariantCulture);
|
|
if (this.IsSelfIssued && this.m_readIssuerInformation)
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("ExtendedInfoInSelfIssued")));
|
|
continue;
|
|
case "PinDigest":
|
|
byte[] array1 = Utility.ReadByteStreamFromBase64(reader).ToArray();
|
|
if (array1 != null && array1.Length != 0)
|
|
{
|
|
this.m_pinHash = array1;
|
|
continue;
|
|
}
|
|
continue;
|
|
case "HashSalt":
|
|
byte[] array2 = Utility.ReadByteStreamFromBase64(reader).ToArray();
|
|
if (array2 != null && array2.Length != 0)
|
|
{
|
|
this.HashSalt = array2;
|
|
continue;
|
|
}
|
|
continue;
|
|
case "TimeLastUpdated":
|
|
string s = reader.ReadString().Trim();
|
|
if (!string.IsNullOrEmpty(s))
|
|
{
|
|
this.LastUpdate = XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.Utc);
|
|
continue;
|
|
}
|
|
continue;
|
|
case "IssuerId":
|
|
byte[] array3 = Utility.ReadByteStreamFromBase64(reader).ToArray();
|
|
if (array3 != null && array3.Length != 0)
|
|
{
|
|
this.IssuerIdentifierAsBytes = array3;
|
|
continue;
|
|
}
|
|
continue;
|
|
case "BackgroundColor":
|
|
this.BackgroundColor = Convert.ToInt32(reader.ReadString().Trim(), (IFormatProvider) CultureInfo.InvariantCulture);
|
|
continue;
|
|
default:
|
|
continue;
|
|
}
|
|
}
|
|
else if ("http://schemas.xmlsoap.org/ws/2007/01/identity" == reader.NamespaceURI && XmlNodeType.EndElement != reader.NodeType && "RequireStrongRecipientIdentity" == reader.LocalName && "http://schemas.xmlsoap.org/ws/2007/01/identity" == reader.NamespaceURI)
|
|
this.GetRPIdentityRequirement().StrongIdentityRequired = true;
|
|
}
|
|
}
|
|
catch (UriFormatException ex)
|
|
{
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("InvalidUriFormat"), (Exception) ex));
|
|
}
|
|
}
|
|
|
|
private void ReadPrivacyPolicy(XmlReader reader)
|
|
{
|
|
InfoCardTrace.Assert(null != reader, "null reader");
|
|
string str = reader.IsStartElement("PrivacyNotice", "http://schemas.xmlsoap.org/ws/2005/05/identity") ? reader.GetAttribute("Version", "http://www.w3.org/XML/1998/namespace") : throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("UnexpectedElement")));
|
|
if (string.IsNullOrEmpty(str))
|
|
str = reader.GetAttribute("Version");
|
|
if (!string.IsNullOrEmpty(str))
|
|
this.m_privacyPolicyVersion = Convert.ToUInt32(str, (IFormatProvider) CultureInfo.InvariantCulture);
|
|
this.m_privacyPolicyLink = reader.ReadString().Trim();
|
|
}
|
|
|
|
private void ReadClaimValues(XmlReader reader)
|
|
{
|
|
InfoCardTrace.Assert(null != reader, "null reader");
|
|
if (!reader.IsStartElement("ClaimValueList", "http://schemas.xmlsoap.org/ws/2005/05/identity"))
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("UnexpectedElement")));
|
|
while (reader.Read() && (XmlNodeType.EndElement != reader.NodeType || !("ClaimValueList" == reader.LocalName)))
|
|
{
|
|
if ("http://schemas.xmlsoap.org/ws/2005/05/identity" == reader.NamespaceURI && "ClaimValue" == reader.LocalName && XmlNodeType.Element == reader.NodeType)
|
|
{
|
|
string attribute = reader.GetAttribute("Uri", "http://www.w3.org/XML/1998/namespace");
|
|
if (string.IsNullOrEmpty(attribute))
|
|
attribute = reader.GetAttribute("Uri");
|
|
reader.Read();
|
|
string s = reader.ReadString().Trim();
|
|
if (!this.IsPinProtected && s.Length > (int) byte.MaxValue)
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("TooLongClaimValue")));
|
|
if (!string.IsNullOrEmpty(attribute))
|
|
{
|
|
if (!this.m_claims.ContainsKey(attribute))
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("InvalidImportFile")));
|
|
if (!string.IsNullOrEmpty(s) && !this.IsPinProtected)
|
|
{
|
|
if (InfoCardConstants.Gender == attribute && !("0" == s) && !("1" == s) && !("2" == s))
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("InvalidImportFile")));
|
|
if (InfoCardConstants.DateOfBirth == attribute)
|
|
{
|
|
try
|
|
{
|
|
XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.Utc);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (InfoCardTrace.IsFatal(ex))
|
|
InfoCardService.Crash(ex);
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("InvalidImportFile")));
|
|
}
|
|
}
|
|
}
|
|
this.m_claims[attribute].Value = s;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ReadClaims(XmlReader reader)
|
|
{
|
|
InfoCardTrace.Assert(null != reader, "null reader");
|
|
if (!reader.IsStartElement("SupportedClaimTypeList", "http://schemas.xmlsoap.org/ws/2005/05/identity"))
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("UnexpectedElement")));
|
|
while (reader.Read() && (XmlNodeType.EndElement != reader.NodeType || !("SupportedClaimTypeList" == reader.LocalName)))
|
|
{
|
|
if ("http://schemas.xmlsoap.org/ws/2005/05/identity" == reader.NamespaceURI && "SupportedClaimType" == reader.LocalName)
|
|
{
|
|
InfoCardClaim claim = this.ReadSingleClaim(reader);
|
|
if (claim != null)
|
|
this.AddClaim(claim);
|
|
}
|
|
}
|
|
}
|
|
|
|
private InfoCardClaim ReadSingleClaim(XmlReader reader)
|
|
{
|
|
InfoCardTrace.Assert(null != reader, "null reader");
|
|
if (!reader.IsStartElement("SupportedClaimType", "http://schemas.xmlsoap.org/ws/2005/05/identity"))
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("UnexpectedElement")));
|
|
string displaytag = (string) null;
|
|
string description = (string) null;
|
|
string str = (string) null;
|
|
string attribute = reader.GetAttribute("Uri", "http://schemas.xmlsoap.org/ws/2005/05/identity");
|
|
if (string.IsNullOrEmpty(attribute))
|
|
attribute = reader.GetAttribute("Uri");
|
|
if (reader.IsEmptyElement)
|
|
{
|
|
if (!string.IsNullOrEmpty(attribute))
|
|
return new InfoCardClaim(attribute, str, description, displaytag);
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("ClaimIdNull")));
|
|
}
|
|
while (reader.Read())
|
|
{
|
|
switch (reader.LocalName)
|
|
{
|
|
case "SupportedClaimType":
|
|
if (XmlNodeType.EndElement == reader.NodeType)
|
|
{
|
|
if (!string.IsNullOrEmpty(attribute))
|
|
return new InfoCardClaim(attribute, str, description, displaytag);
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("ClaimIdNull")));
|
|
}
|
|
continue;
|
|
case "Description":
|
|
description = reader.ReadString().Trim();
|
|
continue;
|
|
case "DisplayTag":
|
|
displaytag = reader.ReadString().Trim();
|
|
continue;
|
|
case "ClaimValue":
|
|
if (this.IsSelfIssued)
|
|
{
|
|
str = reader.ReadString().Trim();
|
|
continue;
|
|
}
|
|
continue;
|
|
default:
|
|
continue;
|
|
}
|
|
}
|
|
return (InfoCardClaim) null;
|
|
}
|
|
|
|
private void ReadAuthServices(XmlReader reader)
|
|
{
|
|
InfoCardTrace.Assert(null != reader, "null reader");
|
|
if (!reader.IsStartElement("TokenServiceList", "http://schemas.xmlsoap.org/ws/2005/05/identity"))
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("UnexpectedElement")));
|
|
if (reader.IsEmptyElement)
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("NoAuthenticationServicesInCard")));
|
|
while (reader.Read())
|
|
{
|
|
switch (reader.LocalName)
|
|
{
|
|
case "TokenService":
|
|
if (reader.NodeType != XmlNodeType.EndElement)
|
|
{
|
|
TokenCreationParameter creationParameter = new TokenCreationParameter();
|
|
creationParameter.ReadXml(reader);
|
|
if (!creationParameter.IsComplete())
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("ServiceInvalidTokenService")));
|
|
this.CreationParameters.Add(creationParameter);
|
|
continue;
|
|
}
|
|
continue;
|
|
case "TokenServiceList":
|
|
return;
|
|
default:
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
private List<string> ReadTokenType(XmlReader reader)
|
|
{
|
|
InfoCardTrace.Assert(null != reader, "null reader");
|
|
if (!reader.IsStartElement("SupportedTokenTypeList", "http://schemas.xmlsoap.org/ws/2005/05/identity"))
|
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("UnexpectedElement")));
|
|
List<string> stringList = new List<string>();
|
|
while (reader.Read() && (XmlNodeType.EndElement != reader.NodeType || !("SupportedTokenTypeList" == reader.LocalName)))
|
|
{
|
|
if ("TokenType" == reader.LocalName && "http://schemas.xmlsoap.org/ws/2005/02/trust" == reader.NamespaceURI && XmlNodeType.EndElement != reader.NodeType && !reader.IsEmptyElement)
|
|
{
|
|
string str = reader.ReadString().Trim();
|
|
if (!string.IsNullOrEmpty(str))
|
|
stringList.Add(str);
|
|
}
|
|
}
|
|
return stringList;
|
|
}
|
|
|
|
private enum PinAction : byte
|
|
{
|
|
NoPin,
|
|
PinSame,
|
|
PinAdded,
|
|
PinRemoved,
|
|
PinChanged,
|
|
}
|
|
}
|
|
}
|