void ValidateTokensByParameters(IEnumerable <SecurityTokenParameters> plist, List <SupportingTokenInfo> tokens, bool optional, SecurityTokenAttachmentMode attachMode) { foreach (SecurityTokenParameters p in plist) { SecurityTokenResolver r; SecurityTokenAuthenticator a = security.CreateTokenAuthenticator(p, out r); SupportingTokenSpecification spec = ValidateTokensByParameters(a, r, tokens); if (spec == null) { if (optional) { continue; } else { throw new MessageSecurityException(String.Format("No security token could be validated for authenticator '{0}' which is indicated by the '{1}' supporting token parameters", a, attachMode)); } } else { // For endorsing tokens, verify corresponding signatures. switch (attachMode) { case SecurityTokenAttachmentMode.Endorsing: case SecurityTokenAttachmentMode.SignedEndorsing: WSSignedXml esxml = GetSignatureForToken(spec.SecurityToken); if (esxml == null) { throw new MessageSecurityException(String.Format("The '{1}' token '{0}' is expected to endorse the primary signature but no corresponding signature is found.", spec.SecurityToken, attachMode)); } bool confirmed; SecurityAlgorithmSuite suite = security.Element.DefaultAlgorithmSuite; foreach (SecurityTokenReferenceKeyInfo kic in esxml.KeyInfo) { SecurityKey signKey = spec.SecurityToken.ResolveKeyIdentifierClause(kic.Clause); SymmetricSecurityKey symkey = signKey as SymmetricSecurityKey; if (symkey != null) { confirmed = esxml.CheckSignature(symkey.GetKeyedHashAlgorithm(suite.DefaultSymmetricSignatureAlgorithm)); } else { AsymmetricAlgorithm alg = ((AsymmetricSecurityKey)signKey).GetAsymmetricAlgorithm(suite.DefaultAsymmetricSignatureAlgorithm, false); confirmed = esxml.CheckSignature(alg); } if (!confirmed) { throw new MessageSecurityException(String.Format("Signature for '{1}' token '{0}' is invalid.", spec.SecurityToken, attachMode)); } break; } sec_prop.ConfirmedSignatures.Insert(0, Convert.ToBase64String(esxml.SignatureValue)); break; } } sec_prop.IncomingSupportingTokens.Add(spec); } }
void ExtractSecurity() { if (security.MessageProtectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature && wss_header.Find <SignedXml> () != null) { throw new MessageSecurityException("The security binding element expects that the message signature is encrypted, while it isn't."); } WrappedKeySecurityToken wk = wss_header.Find <WrappedKeySecurityToken> (); DerivedKeySecurityToken dk = wss_header.Find <DerivedKeySecurityToken> (); if (wk != null) { if (Parameters.RequireDerivedKeys && dk == null) { throw new MessageSecurityException("DerivedKeyToken is required in this contract, but was not found in the message"); } } else { // FIXME: this is kind of hack for symmetric reply processing. wk = RequestSecurity.ProtectionToken != null ? RequestSecurity.ProtectionToken.SecurityToken as WrappedKeySecurityToken : null; } SymmetricSecurityKey wkkey = wk != null ? wk.SecurityKeys [0] as SymmetricSecurityKey : null; wss_header_reader.DecryptSecurity(this, wkkey, RequestSecurity != null ? RequestSecurity.EncryptionKey : null); // signature confirmation WSSignedXml sxml = wss_header.Find <WSSignedXml> (); if (sxml == null) { throw new MessageSecurityException("The the message signature is expected but not found."); } bool confirmed = false; SecurityKeyIdentifierClause sigClause = null; foreach (KeyInfoClause kic in sxml.KeyInfo) { SecurityTokenReferenceKeyInfo r = kic as SecurityTokenReferenceKeyInfo; if (r != null) { sigClause = r.Clause; } } if (sigClause == null) { throw new MessageSecurityException("SecurityTokenReference was not found in dsig:Signature KeyInfo."); } SecurityToken signToken; SecurityKey signKey; signToken = TokenResolver.ResolveToken(sigClause); signKey = signToken.ResolveKeyIdentifierClause(sigClause); SymmetricSecurityKey symkey = signKey as SymmetricSecurityKey; if (symkey != null) { confirmed = sxml.CheckSignature(new HMACSHA1(symkey.GetSymmetricKey())); if (wk != null) { // FIXME: authenticate token sec_prop.ProtectionToken = new SecurityTokenSpecification(wk, null); } } else { AsymmetricAlgorithm alg = ((AsymmetricSecurityKey)signKey).GetAsymmetricAlgorithm(security.DefaultSignatureAlgorithm, false); confirmed = sxml.CheckSignature(alg); sec_prop.InitiatorToken = new SecurityTokenSpecification( signToken, security.TokenAuthenticator.ValidateToken(signToken)); } if (!confirmed) { throw new MessageSecurityException("Message signature is invalid."); } // token authentication // FIXME: it might not be limited to recipient if (Direction == MessageDirection.Input) { ProcessSupportingTokens(sxml); } sec_prop.EncryptionKey = ((SymmetricSecurityKey)wk.SecurityKeys [0]).GetSymmetricKey(); sec_prop.ConfirmedSignatures.Add(Convert.ToBase64String(sxml.SignatureValue)); }