// Decompiled with JetBrains decompiler // Type: Microsoft.InfoCards.SelfIssuedSamlTokenFactory // Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 // MVID: ADE0A079-11DB-4A46-8BDE-D2A592CA8DEA // Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00000-msil\Virus.Win32.Expiro.w-67b630ead60119692b9abbdfd8717c96904ef041127c2cae033c86b718eaa61e.exe using Microsoft.InfoCards.Diagnostics; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.IdentityModel.Tokens; using System.IO; using System.Security.Cryptography; using System.ServiceModel; using System.ServiceModel.Security; using System.Xml; namespace Microsoft.InfoCards { internal class SelfIssuedSamlTokenFactory : TokenFactoryBase { private const string SamlAssertionIdPrefix = "SamlSecurityToken-"; private const string DefaultDigestAlgorithm = "http://www.w3.org/2000/09/xmldsig#sha1"; public static readonly TimeSpan TokenLifetime = new TimeSpan(1, 0, 0); private static readonly SamlSerializer samlSerializer = new SamlSerializer(); private string m_signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; private string m_encryptionAlgorithm = SecurityAlgorithmSuite.Default.DefaultEncryptionAlgorithm; private string m_encryptWithAlgorithm; private string m_keyWrapAlgorithm; protected override TokenDescriptor ProduceToken( InfoCard card, TokenCreationParameter creationParam, TokenFactoryCredential credential, InfoCardPolicy policy, bool discloseOptional) { RSACryptoServiceProvider cryptoServiceProvider = (RSACryptoServiceProvider) null; SymmetricAlgorithm symmetricProof = (SymmetricAlgorithm) null; if (!string.IsNullOrEmpty(policy.OptionalRstParams.SignatureAlgorithm)) this.m_signatureAlgorithm = policy.OptionalRstParams.SignatureAlgorithm; if (!string.IsNullOrEmpty(policy.OptionalRstParams.EncryptionAlgorithm)) this.m_encryptionAlgorithm = policy.OptionalRstParams.EncryptionAlgorithm; TokenDescriptor tokenDescriptor; try { List claimSet = this.GetClaimSet(card, policy, discloseOptional); List disclosedClaims = new List(claimSet.Count); for (int index = 0; index < claimSet.Count; ++index) disclosedClaims.Add(claimSet[index].Id); SamlSecurityToken samlToken; DisplayToken displayToken; XmlElement protectedToken; using (RSACryptoServiceProvider publicCryptography = card.GetPublicCryptography(policy.Recipient.GetIdentifier())) { SecurityKeyIdentifier issuerKeyIdentifier = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[1] { (SecurityKeyIdentifierClause) new RsaKeyIdentifierClause((RSA) publicCryptography) }); SecurityKeyIdentifier proofKeyIdentifier; SecurityKey proofCryptoInsideSamlToken; if (policy.KeyType == SecurityKeyTypeInternal.SymmetricKey) { InfoCardTrace.Assert(policy.ImmediateTokenRecipient is X509RecipientIdentity, "Symmetric key type is not allowed when no certifcate is provided for the token recipeint"); this.m_keyWrapAlgorithm = SecurityAlgorithmSuite.Default.DefaultAsymmetricKeyWrapAlgorithm; InfoCardTrace.Assert("http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" == this.m_keyWrapAlgorithm, "What we have chosen"); this.m_encryptWithAlgorithm = string.IsNullOrEmpty(policy.OptionalRstParams.EncryptWith) ? SecurityAlgorithmSuite.Default.DefaultEncryptionAlgorithm : policy.OptionalRstParams.EncryptWith; symmetricProof = (SymmetricAlgorithm) new RijndaelManaged(); SecurityAlgorithmSuite securityAlgorithmSuite; switch (this.m_encryptWithAlgorithm) { case "http://www.w3.org/2001/04/xmlenc#aes128-cbc": securityAlgorithmSuite = SecurityAlgorithmSuite.Basic128; break; case "http://www.w3.org/2001/04/xmlenc#aes192-cbc": securityAlgorithmSuite = SecurityAlgorithmSuite.Basic192; break; case "http://www.w3.org/2001/04/xmlenc#aes256-cbc": securityAlgorithmSuite = SecurityAlgorithmSuite.Basic256; break; case "http://www.w3.org/2001/04/xmlenc#tripledes-cbc": securityAlgorithmSuite = SecurityAlgorithmSuite.TripleDes; break; default: throw InfoCardTrace.ThrowHelperError((Exception) new TokenCreationException(SR.GetString("UnsupportedEncryptWithAlgorithm", (object) this.m_encryptWithAlgorithm))); } symmetricProof.KeySize = securityAlgorithmSuite.DefaultSymmetricKeyLength; X509SecurityToken x509SecurityToken = new X509SecurityToken(((X509RecipientIdentity) policy.ImmediateTokenRecipient).LeafCertificate, Guid.NewGuid().ToString()); SecurityKeyIdentifier encryptingKeyIdentifier = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[1] { (SecurityKeyIdentifierClause) x509SecurityToken.CreateKeyIdentifierClause() }); proofKeyIdentifier = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[1] { (SecurityKeyIdentifierClause) new EncryptedKeyIdentifierClause(x509SecurityToken.SecurityKeys[0].EncryptKey(this.m_keyWrapAlgorithm, symmetricProof.Key), this.m_keyWrapAlgorithm, encryptingKeyIdentifier) }); proofCryptoInsideSamlToken = (SecurityKey) new InMemorySymmetricSecurityKey(symmetricProof.Key); this.ThrowIfProofKeyOperationsNotSupported(policy, proofCryptoInsideSamlToken); } else if (SecurityKeyTypeInternal.AsymmetricKey == policy.KeyType) { this.m_encryptWithAlgorithm = string.IsNullOrEmpty(policy.OptionalRstParams.EncryptWith) ? SecurityAlgorithmSuite.Default.DefaultAsymmetricKeyWrapAlgorithm : policy.OptionalRstParams.EncryptWith; this.m_keyWrapAlgorithm = this.m_encryptWithAlgorithm; symmetricProof = (SymmetricAlgorithm) null; cryptoServiceProvider = publicCryptography; proofKeyIdentifier = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[1] { (SecurityKeyIdentifierClause) new RsaKeyIdentifierClause((RSA) cryptoServiceProvider) }); proofCryptoInsideSamlToken = proofKeyIdentifier.CreateKey(); this.ThrowIfProofKeyOperationsNotSupported(policy, proofCryptoInsideSamlToken); } else { this.m_keyWrapAlgorithm = SecurityAlgorithmSuite.Default.DefaultAsymmetricKeyWrapAlgorithm; InfoCardTrace.Assert("http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" == this.m_keyWrapAlgorithm, "What we have chosen"); InfoCardTrace.Assert(SecurityKeyTypeInternal.NoKey == policy.KeyType, "Bad enum member for SecurityKeyTypeInternal."); proofKeyIdentifier = (SecurityKeyIdentifier) null; proofCryptoInsideSamlToken = (SecurityKey) null; } using (SelfIssuedAuthAsymmetricKey issuerSigningKey = new SelfIssuedAuthAsymmetricKey(card.GetPrivateCryptography(policy.Recipient.GetIdentifier()))) { Uri uri = policy.ImmediateTokenRecipient.Address.Uri; if ((EndpointAddress) null != policy.PolicyAppliesTo) uri = policy.PolicyAppliesTo.Uri; samlToken = this.CreateSamlToken(claimSet, issuerKeyIdentifier, proofKeyIdentifier, proofCryptoInsideSamlToken, (SecurityKey) issuerSigningKey, uri); displayToken = this.CreateDisplayToken(claimSet); if (policy.ImmediateTokenRecipient is X509RecipientIdentity immediateTokenRecipient) { protectedToken = EncryptionUtility.EncryptSecurityToken((SecurityToken) samlToken, immediateTokenRecipient.LeafCertificate, this.m_encryptionAlgorithm, this.m_keyWrapAlgorithm, policy.ProtocolVersionProfile); } else { MemoryStream input = new MemoryStream(); XmlDictionaryWriter dictionaryWriter = XmlDictionaryWriter.CreateDictionaryWriter((XmlWriter) new XmlTextWriter((TextWriter) new StreamWriter((Stream) input))); policy.ProtocolVersionProfile.TokenSerializer.WriteToken((XmlWriter) dictionaryWriter, (SecurityToken) samlToken); dictionaryWriter.Flush(); input.Seek(0L, SeekOrigin.Begin); protectedToken = (XmlElement) new XmlDocument().ReadNode((XmlReader) Utility.CreateReaderWithQuotas((Stream) input)); Array.Clear((Array) input.GetBuffer(), 0, Convert.ToInt32(input.Length)); input.Close(); } } } StringWriter w = new StringWriter((IFormatProvider) CultureInfo.InvariantCulture); policy.ProtocolVersionProfile.TokenSerializer.WriteKeyIdentifierClause((XmlWriter) XmlDictionaryWriter.CreateDictionaryWriter((XmlWriter) new XmlTextWriter((TextWriter) w)), (SecurityKeyIdentifierClause) new SamlAssertionKeyIdentifierClause(samlToken.Id)); w.Flush(); string str = w.GetStringBuilder().ToString(); tokenDescriptor = new TokenDescriptor(samlToken.Id, samlToken.ValidFrom, samlToken.ValidTo, protectedToken, displayToken, symmetricProof, str, str, (IEnumerable) disclosedClaims); symmetricProof = (SymmetricAlgorithm) null; } catch (InfoCardBaseException ex) { throw; } catch (Exception ex) { if (!InfoCardTrace.IsFatal(ex)) throw InfoCardTrace.ThrowHelperError((Exception) new TokenCreationException((string) null, ex)); throw; } finally { cryptoServiceProvider?.Dispose(); symmetricProof?.Dispose(); } return tokenDescriptor; } private void ThrowIfProofKeyOperationsNotSupported( InfoCardPolicy policy, SecurityKey proofCryptoInsideSamlToken) { if (!string.IsNullOrEmpty(policy.OptionalRstParams.SignWith) && !proofCryptoInsideSamlToken.IsSupportedAlgorithm(policy.OptionalRstParams.SignWith)) throw InfoCardTrace.ThrowHelperError((Exception) new TokenCreationException(SR.GetString("UnsupportedSignWithAlgorithm", (object) policy.OptionalRstParams.SignWith))); if (!proofCryptoInsideSamlToken.IsSupportedAlgorithm(this.m_encryptWithAlgorithm)) throw InfoCardTrace.ThrowHelperError((Exception) new TokenCreationException(SR.GetString("UnsupportedEncryptWithAlgorithm", (object) this.m_encryptWithAlgorithm))); } private SamlSecurityToken CreateSamlToken( List claims, SecurityKeyIdentifier issuerKeyIdentifier, SecurityKeyIdentifier proofKeyIdentifier, SecurityKey proofCryptoInsideSamlToken, SecurityKey issuerSigningKey, Uri immediateTokenRecipientUri) { DateTime utcNow = DateTime.UtcNow; SamlAudienceRestrictionCondition restrictionCondition = new SamlAudienceRestrictionCondition((IEnumerable) new Collection() { immediateTokenRecipientUri }); SamlConditions samlConditions = new SamlConditions(utcNow, utcNow.Add(SelfIssuedSamlTokenFactory.TokenLifetime), (IEnumerable) new Collection() { (SamlCondition) restrictionCondition }); SamlSubject samlSubject = new SamlSubject((string) null, (string) null, (string) null, (IEnumerable) new string[1] { proofKeyIdentifier != null ? SamlConstants.HolderOfKey : "urn:oasis:names:tc:SAML:1.0:cm:bearer" }, (string) null, proofKeyIdentifier); if (proofCryptoInsideSamlToken != null) samlSubject.Crypto = proofCryptoInsideSamlToken; List attributes = new List(claims.Count); char[] chArray = new char[1]{ '/' }; for (int index = 0; index < claims.Count; ++index) { string[] strArray = claims[index].Id.Split(chArray); InfoCardTrace.ThrowInvalidArgumentConditional(0 == strArray.Length, "claimUri"); string attributeName = strArray[strArray.Length - 1]; if (claims[index].Id == InfoCardConstants.Gender) InfoCardTrace.Assert(claims[index].Value == "0" || claims[index].Value == "1" || claims[index].Value == "2", "Wrong value type for gender claim, only values '0' (Unspecified), '1' (Male) and '2' (Female) are allowed "); if (claims[index].Id == InfoCardConstants.DateOfBirth) { DateTime universalTime = DateTime.Parse(claims[index].Value, (IFormatProvider) CultureInfo.InvariantCulture).ToUniversalTime(); InfoCardTrace.Assert(true, "Invalid value for date of birth "); attributes.Add(new SamlAttribute("http://schemas.xmlsoap.org/ws/2005/05/identity/claims", attributeName, (IEnumerable) new string[1] { XmlConvert.ToString(universalTime, XmlDateTimeSerializationMode.Utc) })); } else attributes.Add(new SamlAttribute("http://schemas.xmlsoap.org/ws/2005/05/identity/claims", attributeName, (IEnumerable) new string[1] { claims[index].ToString() })); } SamlAttributeStatement attributeStatement = new SamlAttributeStatement(samlSubject, (IEnumerable) attributes); SamlAssertion assertion = new SamlAssertion("SamlSecurityToken-" + Guid.NewGuid().ToString(), "http://schemas.xmlsoap.org/ws/2005/05/identity/issuer/self", utcNow, samlConditions, (SamlAdvice) null, (IEnumerable) new List(1) { (SamlStatement) attributeStatement }); if (!issuerSigningKey.IsSupportedAlgorithm(this.m_signatureAlgorithm)) throw InfoCardTrace.ThrowHelperError((Exception) new TokenCreationException(SR.GetString("UnsupportedSignatureAlgorithm", (object) this.m_signatureAlgorithm))); assertion.SigningCredentials = new SigningCredentials(issuerSigningKey, this.m_signatureAlgorithm, "http://www.w3.org/2000/09/xmldsig#sha1", issuerKeyIdentifier); return new SamlSecurityToken(assertion); } private DisplayToken CreateDisplayToken(List claims) { List claimList = new List(); for (int index = 0; index < claims.Count; ++index) { DisplayClaim displayClaim = new DisplayClaim(InfoCardConstants.ClaimDisplayTag(claims[index].Id.ToString()), new List() { claims[index].Value }, InfoCardConstants.ClaimsDescription(claims[index].Id.ToString()), claims[index].Id.ToString()); claimList.Add(displayClaim); } return new DisplayToken(claimList); } private List GetClaimSet( InfoCard card, InfoCardPolicy policy, bool discloseOptional) { StoreConnection connection = StoreConnection.GetConnection(); try { List intersectedClaims = (List) null; if (policy.RequiredClaims != null) { intersectedClaims = new List(policy.RequiredClaims.Length); this.AddClaimsThatIntersect(policy.RequiredClaims, false, card.GetClaims(), policy.ImmediateTokenRecipient.GetOrganizationPPIDIdentifier(), card.Id, intersectedClaims); } if (discloseOptional && policy.OptionalClaims != null) { if (intersectedClaims == null) intersectedClaims = new List(policy.OptionalClaims.Length); this.AddClaimsThatIntersect(policy.OptionalClaims, true, card.GetClaims(), policy.ImmediateTokenRecipient.GetOrganizationPPIDIdentifier(), card.Id, intersectedClaims); } return intersectedClaims; } finally { connection.Close(); } } private void AddClaimsThatIntersect( string[] policyClaims, bool processingOptionalClaims, InfoCardClaimCollection claims, string recipientidentifier, Uri cardId, List intersectedClaims) { foreach (string policyClaim in policyClaims) { if (policyClaim == InfoCardConstants.PPIDClaimsUri) { string ppid = Utility.CreatePpid(Convert.FromBase64String(recipientidentifier), cardId); intersectedClaims.Add(new InfoCardClaim(InfoCardConstants.PPIDClaimsUri, ppid)); } else if (!processingOptionalClaims) { InfoCardTrace.ThrowInvalidArgumentConditional(!claims.ContainsKey(policyClaim) || claims[policyClaim] == null || string.IsNullOrEmpty(claims[policyClaim].Value), "policyClaimUri"); intersectedClaims.Add(claims[policyClaim]); } else { InfoCardClaim infoCardClaim = (InfoCardClaim) null; if (claims.ContainsKey(policyClaim)) infoCardClaim = claims[policyClaim]; if (infoCardClaim != null && !string.IsNullOrEmpty(infoCardClaim.Value)) intersectedClaims.Add(infoCardClaim); } } } } }