public void MatchesKeyIdentifierClause () { UniqueId id = new UniqueId (); X509SecurityToken t = new X509SecurityToken (cert, id.ToString ()); LocalIdKeyIdentifierClause l = new LocalIdKeyIdentifierClause (id.ToString ()); Assert.IsTrue (t.MatchesKeyIdentifierClause (l), "#1-1"); l = new LocalIdKeyIdentifierClause ("#" + id.ToString ()); Assert.IsFalse (t.MatchesKeyIdentifierClause (l), "#1-2"); X509ThumbprintKeyIdentifierClause h = new X509ThumbprintKeyIdentifierClause (cert); Assert.IsTrue (t.MatchesKeyIdentifierClause (h), "#2-1"); h = new X509ThumbprintKeyIdentifierClause (cert2); Assert.IsFalse (t.MatchesKeyIdentifierClause (h), "#2-2"); X509IssuerSerialKeyIdentifierClause i = new X509IssuerSerialKeyIdentifierClause (cert); Assert.IsTrue (t.MatchesKeyIdentifierClause (i), "#3-1"); i = new X509IssuerSerialKeyIdentifierClause (cert2); Assert.IsFalse (t.MatchesKeyIdentifierClause (i), "#3-2"); X509RawDataKeyIdentifierClause s = new X509RawDataKeyIdentifierClause (cert); Assert.IsTrue (t.MatchesKeyIdentifierClause (s), "#4-1"); s = new X509RawDataKeyIdentifierClause (cert2); Assert.IsFalse (t.MatchesKeyIdentifierClause (s), "#4-2"); }
public override bool Matches(SecurityKeyIdentifierClause keyIdentifierClause) { LocalIdKeyIdentifierClause that = keyIdentifierClause as LocalIdKeyIdentifierClause; // PreSharp #pragma warning suppress 56506 return(ReferenceEquals(this, that) || (that != null && that.Matches(this.localId, this.OwnerType))); }
public override bool Matches(SecurityKeyIdentifierClause keyIdentifierClause) { LocalIdKeyIdentifierClause that = keyIdentifierClause as LocalIdKeyIdentifierClause; // PreSharp Bug: Parameter 'that' to this public method must be validated: A null-dereference can occur here. #pragma warning suppress 56506 return(ReferenceEquals(this, that) || (that != null && that.Matches(this.localId, this.OwnerType))); }
public virtual bool MatchesKeyIdentifierClause(SecurityKeyIdentifierClause keyIdentifierClause) { LocalIdKeyIdentifierClause localKeyIdentifierClause = keyIdentifierClause as LocalIdKeyIdentifierClause; if (localKeyIdentifierClause != null) return localKeyIdentifierClause.Matches(this.Id, this.GetType()); return false; }
public virtual bool MatchesKeyIdentifierClause(SecurityKeyIdentifierClause keyIdentifierClause) { LocalIdKeyIdentifierClause identifierClause = keyIdentifierClause as LocalIdKeyIdentifierClause; if (identifierClause != null) { return(identifierClause.Matches(this.Id, this.GetType())); } return(false); }
public override bool Matches(SecurityKeyIdentifierClause keyIdentifierClause) { if (keyIdentifierClause == null) { throw new ArgumentNullException("keyIdentifierClause"); } LocalIdKeyIdentifierClause c = keyIdentifierClause as LocalIdKeyIdentifierClause; return(c != null && Matches(c.LocalId, c.OwnerType)); }
public override void WriteContent(XmlDictionaryWriter writer, SecurityKeyIdentifierClause clause) { LocalIdKeyIdentifierClause localIdClause = clause as LocalIdKeyIdentifierClause; writer.WriteStartElement(XD.SecurityJan2004Dictionary.Prefix.Value, XD.SecurityJan2004Dictionary.Reference, XD.SecurityJan2004Dictionary.Namespace); if (this.emitBspRequiredAttributes) { string tokenTypeUri = GetLocalTokenTypeUri(localIdClause); if (tokenTypeUri != null) { writer.WriteAttributeString(XD.SecurityJan2004Dictionary.ValueType, null, tokenTypeUri); } } writer.WriteAttributeString(XD.SecurityJan2004Dictionary.URI, null, "#" + localIdClause.LocalId); writer.WriteEndElement(); }
public void TryResolveToken () { SecurityTokenResolver r = GetResolver (true, new SecurityToken [0]); SecurityToken token; Assert.IsFalse (r.TryResolveToken (new LocalIdKeyIdentifierClause ("foo"), out token)); UserNameSecurityToken userName = new UserNameSecurityToken ("mono", "", "urn:foo"); LocalIdKeyIdentifierClause kic = new LocalIdKeyIdentifierClause ("urn:foo"); r = GetResolver (true, new SecurityToken [] {userName}); Assert.IsTrue (r.TryResolveToken (kic, out token)); r = GetResolver (false, new SecurityToken [] {userName}); Assert.IsFalse (r.TryResolveToken (kic, out token)); }
public override bool MatchesKeyIdentifierClause( SecurityKeyIdentifierClause keyIdentifierClause) { LocalIdKeyIdentifierClause l = keyIdentifierClause as LocalIdKeyIdentifierClause; if (l != null) { return(l.LocalId == Id); } X509ThumbprintKeyIdentifierClause t = keyIdentifierClause as X509ThumbprintKeyIdentifierClause; if (t != null) { return(t.Matches(cert)); } X509IssuerSerialKeyIdentifierClause i = keyIdentifierClause as X509IssuerSerialKeyIdentifierClause; if (i != null) { return(i.Matches(cert)); } X509SubjectKeyIdentifierClause s = keyIdentifierClause as X509SubjectKeyIdentifierClause; if (s != null) { return(s.Matches(cert)); } X509RawDataKeyIdentifierClause r = keyIdentifierClause as X509RawDataKeyIdentifierClause; if (r != null) { return(r.Matches(cert)); } return(false); }
public override SecurityKeyIdentifierClause ReadClause(XmlDictionaryReader reader, byte[] derivationNonce, int derivationLength, string tokenType) { string uri = reader.GetAttribute(XD.SecurityJan2004Dictionary.URI, null); string tokenTypeUri = reader.GetAttribute(XD.SecurityJan2004Dictionary.ValueType, null); Type[] tokenTypes = null; if (tokenTypeUri != null) { tokenTypes = this.tokenSerializer.GetTokenTypes(tokenTypeUri); } SecurityKeyIdentifierClause clause = new LocalIdKeyIdentifierClause(uri.Substring(1), derivationNonce, derivationLength, tokenTypes); if (reader.IsEmptyElement) { reader.Read(); } else { reader.ReadStartElement(); reader.ReadEndElement(); } return(clause); }
public Message SecureMessage () { secprop = Message.Properties.Security ?? new SecurityMessageProperty (); SecurityToken encToken = secprop.InitiatorToken != null ? secprop.InitiatorToken.SecurityToken : security.EncryptionToken; // FIXME: it might be still incorrect. SecurityToken signToken = Parameters == CounterParameters ? null : security.SigningToken; MessageProtectionOrder protectionOrder = security.MessageProtectionOrder; SecurityBindingElement element = security.Element; SecurityAlgorithmSuite suite = element.DefaultAlgorithmSuite; string messageId = "uuid-" + Guid.NewGuid (); int identForMessageId = 1; XmlDocument doc = new XmlDocument (); doc.PreserveWhitespace = true; var action = msg.Headers.Action; if (msg.Version.Addressing != AddressingVersion.None) { AddAddressingToHeader (msg.Headers); } // wss:Security WSSecurityMessageHeader header = new WSSecurityMessageHeader (security.TokenSerializer); msg.Headers.Add (header); // 1. [Timestamp] if (element.IncludeTimestamp) { AddTimestampToHeader (header, messageId + "-" + identForMessageId++); } XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable); nsmgr.AddNamespace ("s", msg.Version.Envelope.Namespace); nsmgr.AddNamespace ("o", Constants.WssNamespace); nsmgr.AddNamespace ("u", Constants.WsuNamespace); nsmgr.AddNamespace ("o11", Constants.Wss11Namespace); /*WrappedKey*/SecurityToken primaryToken = null; SecurityToken actualToken = null; SecurityKeyIdentifierClause actualClause = null; SymmetricAlgorithm masterKey = new RijndaelManaged (); masterKey.KeySize = suite.DefaultSymmetricKeyLength; masterKey.Mode = CipherMode.CBC; masterKey.Padding = PaddingMode.ISO10126; SymmetricAlgorithm actualKey = masterKey; // 2. [Encryption Token] // SecurityTokenInclusionMode // - Initiator or Recipient // - done or notyet. FIXME: not implemented yet // It also affects on key reference output bool includeEncToken = // /* FIXME: remove this hack */Parameters is SslSecurityTokenParameters ? false : ShouldIncludeToken ( Security.RecipientParameters.InclusionMode, false); bool includeSigToken = // /* FIXME: remove this hack */ Parameters is SslSecurityTokenParameters ? false : ShouldIncludeToken ( Security.InitiatorParameters.InclusionMode, false); SecurityKeyIdentifierClause encClause = ShouldOutputEncryptedKey ? CounterParameters.CallCreateKeyIdentifierClause (encToken, !ShouldOutputEncryptedKey ? SecurityTokenReferenceStyle.Internal : includeEncToken ? Parameters.ReferenceStyle : SecurityTokenReferenceStyle.External) : null; MessagePartSpecification encSpec = EncryptionPart; // encryption key (possibly also used for signing) // FIXME: get correct SymmetricAlgorithm according to the algorithm suite if (secprop.EncryptionKey != null) actualKey.Key = secprop.EncryptionKey; // FIXME: remove thid hack if (!ShouldOutputEncryptedKey) primaryToken = secprop.ProtectionToken.SecurityToken as WrappedKeySecurityToken; else primaryToken = // FIXME: remove this hack? encToken is SecurityContextSecurityToken ? encToken : new WrappedKeySecurityToken (messageId + "-" + identForMessageId++, actualKey.Key, // security.DefaultKeyWrapAlgorithm, Parameters.InternalHasAsymmetricKey ? suite.DefaultAsymmetricKeyWrapAlgorithm : suite.DefaultSymmetricKeyWrapAlgorithm, encToken, encClause != null ? new SecurityKeyIdentifier (encClause) : null); // If it reuses request's encryption key, do not output. if (ShouldOutputEncryptedKey) header.AddContent (primaryToken); actualToken = primaryToken; // FIXME: I doubt it is correct... WrappedKeySecurityToken requestEncKey = ShouldOutputEncryptedKey ? null : primaryToken as WrappedKeySecurityToken; actualClause = requestEncKey == null ? (SecurityKeyIdentifierClause) new LocalIdKeyIdentifierClause (actualToken.Id, typeof (WrappedKeySecurityToken)) : new InternalEncryptedKeyIdentifierClause (SHA1.Create ().ComputeHash (requestEncKey.GetWrappedKey ())); // generate derived key if needed if (CounterParameters.RequireDerivedKeys) { var dkeyToken = CreateDerivedKey (GenerateId (doc), actualClause, actualKey); actualToken = dkeyToken; actualKey.Key = ((SymmetricSecurityKey)dkeyToken.SecurityKeys [0]).GetSymmetricKey (); actualClause = new LocalIdKeyIdentifierClause (dkeyToken.Id); header.AddContent (dkeyToken); } ReferenceList refList = new ReferenceList (); // When encrypted with DerivedKeyToken, put references // immediately after the derived token (not inside the // primary token). // Similarly, when we do not output EncryptedKey, // output ReferenceList in the same way. if (CounterParameters.RequireDerivedKeys || !ShouldOutputEncryptedKey) header.AddContent (refList); else ((WrappedKeySecurityToken) primaryToken).ReferenceList = refList; // [Signature Confirmation] if (security.RequireSignatureConfirmation && secprop.ConfirmedSignatures.Count > 0) foreach (string value in secprop.ConfirmedSignatures) header.AddContent (new Wss11SignatureConfirmation (GenerateId (doc), value)); SupportingTokenInfoCollection tokenInfos = Direction == MessageDirection.Input ? security.CollectSupportingTokens (GetAction ()) : new SupportingTokenInfoCollection (); // empty foreach (SupportingTokenInfo tinfo in tokenInfos) header.AddContent (tinfo.Token); // populate DOM to sign. XPathNavigator nav = doc.CreateNavigator (); using (XmlWriter w = nav.AppendChild ()) { msg.WriteMessage (w); } XmlElement body = doc.SelectSingleNode ("/s:Envelope/s:Body/*", nsmgr) as XmlElement; string bodyId = null; Collection<WSSignedXml> endorsedSignatures = new Collection<WSSignedXml> (); bool signatureProtection = (protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature); // Below are o:Security contents that are not signed... if (includeSigToken && signToken != null) header.AddContent (signToken); switch (protectionOrder) { case MessageProtectionOrder.EncryptBeforeSign: // FIXME: implement throw new NotImplementedException (); case MessageProtectionOrder.SignBeforeEncrypt: case MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature: var sig = CreateSignature (doc, body, nsmgr, tokenInfos, actualClause, actualKey, signToken, includeSigToken, signatureProtection, header, endorsedSignatures, ref bodyId); // encrypt WSEncryptedXml exml = new WSEncryptedXml (doc); EncryptedData edata = Encrypt (body, actualKey, actualToken.Id, refList, actualClause, exml, doc, EncryptedXml.XmlEncElementContentUrl); EncryptedXml.ReplaceElement (body, edata, false); // encrypt signature if (signatureProtection) { XmlElement sigxml = sig.GetXml (); edata = Encrypt (sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc, EncryptedXml.XmlEncElementUrl); header.AddContent (edata); foreach (WSSignedXml ssxml in endorsedSignatures) { sigxml = ssxml.GetXml (); edata = Encrypt (sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc, EncryptedXml.XmlEncElementUrl); header.AddContent (edata); } if (security.RequireSignatureConfirmation) { Collection<Wss11SignatureConfirmation> confs = header.FindAll<Wss11SignatureConfirmation> (); int count = 0; foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr)) { edata = Encrypt (elem, actualKey, confs [count].Id, refList, actualClause, exml, doc, EncryptedXml.XmlEncElementUrl); EncryptedXml.ReplaceElement (elem, edata, false); header.Contents.Insert (header.Contents.IndexOf (confs [count]), edata); header.Contents.Remove (confs [count++]); } } } // encrypt Encrypted supporting tokens foreach (SupportingTokenInfo tinfo in tokenInfos) { if (tinfo.Mode == SecurityTokenAttachmentMode.SignedEncrypted) { XmlElement el = exml.GetIdElement (doc, tinfo.Token.Id); tinfo.Encrypted = Encrypt (el, actualKey, actualToken.Id, refList, actualClause, exml, doc, EncryptedXml.XmlEncElementUrl); EncryptedXml.ReplaceElement (el, tinfo.Encrypted, false); header.Contents.Insert (header.Contents.IndexOf (tinfo.Token), tinfo.Encrypted); header.Contents.Remove (tinfo.Token); } } break; } Message ret = new WSSecurityMessage (Message.CreateMessage (msg.Version, action, new XmlNodeReader (doc.SelectSingleNode ("/s:Envelope/s:Body/*", nsmgr) as XmlElement)), bodyId); ret.Properties.Security = (SecurityMessageProperty) secprop.CreateCopy (); ret.Properties.Security.EncryptionKey = masterKey.Key; // FIXME: can we support TransportToken here? if (element is AsymmetricSecurityBindingElement) { ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification (encToken, null); // FIXME: second argument ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification (signToken, null); // FIXME: second argument } else ret.Properties.Security.ProtectionToken = new SecurityTokenSpecification (primaryToken, null); ret.Headers.Clear (); ret.Headers.CopyHeadersFrom (msg); // Header contents are: // - Timestamp // - SignatureConfirmation if required // - EncryptionToken if included // - derived key token for EncryptionToken // - ReferenceList for encrypted items // - signed supporting tokens // - signed endorsing supporting tokens // (i.e. Signed/SignedEncrypted/SignedEndorsing) // - Signature Token if different from enc token. // - derived key token for sig token if different // - Signature for: // - Timestamp // - supporting tokens (regardless of // its inclusion) // - message parts in SignedParts // - SignatureToken if TokenProtection // (regardless of its inclusion) // - Signatures for the main signature (above), // for every endorsing token and signed // endorsing token. // //MessageBuffer zzz = ret.CreateBufferedCopy (100000); //ret = zzz.CreateMessage (); //Console.WriteLine (zzz.CreateMessage ()); return ret; }
void StartEncryption() { if (this.elementContainer.SourceEncryptionToken == null) { return; } // determine the key identifier clause to use for the source SecurityTokenReferenceStyle sourceEncryptingKeyReferenceStyle = GetTokenReferenceStyle(this.encryptingTokenParameters); bool encryptionTokenSerialized = sourceEncryptingKeyReferenceStyle == SecurityTokenReferenceStyle.Internal; SecurityKeyIdentifierClause sourceEncryptingKeyIdentifierClause = this.encryptingTokenParameters.CreateKeyIdentifierClause(this.elementContainer.SourceEncryptionToken, sourceEncryptingKeyReferenceStyle); if (sourceEncryptingKeyIdentifierClause == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenManagerCannotCreateTokenReference)), this.Message); } SecurityToken sourceToken; SecurityKeyIdentifierClause sourceTokenIdentifierClause; // if the source token cannot do symmetric crypto, create a wrapped key if (!SecurityUtils.HasSymmetricSecurityKey(elementContainer.SourceEncryptionToken)) { int keyLength = Math.Max(128, this.AlgorithmSuite.DefaultSymmetricKeyLength); CryptoHelper.ValidateSymmetricKeyLength(keyLength, this.AlgorithmSuite); byte[] key = new byte[keyLength / 8]; CryptoHelper.FillRandomBytes(key); string keyWrapAlgorithm; XmlDictionaryString keyWrapAlgorithmDictionaryString; this.AlgorithmSuite.GetKeyWrapAlgorithm(elementContainer.SourceEncryptionToken, out keyWrapAlgorithm, out keyWrapAlgorithmDictionaryString); WrappedKeySecurityToken wrappedKey = new WrappedKeySecurityToken(GenerateId(), key, keyWrapAlgorithm, keyWrapAlgorithmDictionaryString, elementContainer.SourceEncryptionToken, new SecurityKeyIdentifier(sourceEncryptingKeyIdentifierClause)); elementContainer.WrappedEncryptionToken = wrappedKey; sourceToken = wrappedKey; sourceTokenIdentifierClause = new LocalIdKeyIdentifierClause(wrappedKey.Id, wrappedKey.GetType()); encryptionTokenSerialized = true; } else { sourceToken = elementContainer.SourceEncryptionToken; sourceTokenIdentifierClause = sourceEncryptingKeyIdentifierClause; } // determine if a key needs to be derived SecurityKeyIdentifierClause encryptingKeyIdentifierClause; // determine if a token needs to be derived if (this.encryptingTokenParameters.RequireDerivedKeys) { string derivationAlgorithm = this.AlgorithmSuite.GetEncryptionKeyDerivationAlgorithm(sourceToken, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion); string expectedDerivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(this.StandardsManager.MessageSecurityVersion.SecureConversationVersion); if (derivationAlgorithm == expectedDerivationAlgorithm) { DerivedKeySecurityToken derivedEncryptingToken = new DerivedKeySecurityToken(-1, 0, this.AlgorithmSuite.GetEncryptionKeyDerivationLength(sourceToken, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, DerivedKeySecurityToken.DefaultNonceLength, sourceToken, sourceTokenIdentifierClause, derivationAlgorithm, GenerateId()); this.encryptingToken = this.elementContainer.DerivedEncryptionToken = derivedEncryptingToken; encryptingKeyIdentifierClause = new LocalIdKeyIdentifierClause(derivedEncryptingToken.Id, derivedEncryptingToken.GetType()); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedCryptoAlgorithm, derivationAlgorithm))); } } else { this.encryptingToken = sourceToken; encryptingKeyIdentifierClause = sourceTokenIdentifierClause; } this.skipKeyInfoForEncryption = encryptionTokenSerialized && this.EncryptedKeyContainsReferenceList && (this.encryptingToken is WrappedKeySecurityToken) && this.signThenEncrypt; SecurityKeyIdentifier identifier; if (this.skipKeyInfoForEncryption) { identifier = null; } else { identifier = new SecurityKeyIdentifier(encryptingKeyIdentifierClause); } StartEncryptionCore(this.encryptingToken, identifier); }
void StartSignature() { if (this.elementContainer.SourceSigningToken == null) { return; } // determine the key identifier clause to use for the source SecurityTokenReferenceStyle sourceSigningKeyReferenceStyle = GetTokenReferenceStyle(this.signingTokenParameters); SecurityKeyIdentifierClause sourceSigningKeyIdentifierClause = this.signingTokenParameters.CreateKeyIdentifierClause(this.elementContainer.SourceSigningToken, sourceSigningKeyReferenceStyle); if (sourceSigningKeyIdentifierClause == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenManagerCannotCreateTokenReference)), this.Message); } SecurityToken signingToken; SecurityKeyIdentifierClause signingKeyIdentifierClause; // determine if a token needs to be derived if (this.signingTokenParameters.RequireDerivedKeys && !this.signingTokenParameters.HasAsymmetricKey) { string derivationAlgorithm = this.AlgorithmSuite.GetSignatureKeyDerivationAlgorithm(this.elementContainer.SourceSigningToken, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion); string expectedDerivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(this.StandardsManager.MessageSecurityVersion.SecureConversationVersion); if (derivationAlgorithm == expectedDerivationAlgorithm) { DerivedKeySecurityToken derivedSigningToken = new DerivedKeySecurityToken(-1, 0, this.AlgorithmSuite.GetSignatureKeyDerivationLength(this.elementContainer.SourceSigningToken, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, DerivedKeySecurityToken.DefaultNonceLength, this.elementContainer.SourceSigningToken, sourceSigningKeyIdentifierClause, derivationAlgorithm, GenerateId()); signingToken = this.elementContainer.DerivedSigningToken = derivedSigningToken; signingKeyIdentifierClause = new LocalIdKeyIdentifierClause(signingToken.Id, signingToken.GetType()); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedCryptoAlgorithm, derivationAlgorithm))); } } else { signingToken = elementContainer.SourceSigningToken; signingKeyIdentifierClause = sourceSigningKeyIdentifierClause; } SecurityKeyIdentifier signingKeyIdentifier = new SecurityKeyIdentifier(signingKeyIdentifierClause); if (signatureConfirmationsToSend != null && signatureConfirmationsToSend.Count > 0) { ISecurityElement[] signatureConfirmationElements; signatureConfirmationElements = CreateSignatureConfirmationElements(signatureConfirmationsToSend); for (int i = 0; i < signatureConfirmationElements.Length; ++i) { SendSecurityHeaderElement sigConfElement = new SendSecurityHeaderElement(signatureConfirmationElements[i].Id, signatureConfirmationElements[i]); sigConfElement.MarkedForEncryption = signatureConfirmationsToSend.IsMarkedForEncryption; this.elementContainer.AddSignatureConfirmation(sigConfElement); } } bool generateTargettablePrimarySignature = ((this.endorsingTokenParameters != null) || (this.signedEndorsingTokenParameters != null)); this.StartPrimarySignatureCore(signingToken, signingKeyIdentifier, this.signatureParts, generateTargettablePrimarySignature); }
void SignWithSupportingTokens() { SecurityToken[] endorsingTokens = this.elementContainer.GetEndorsingSupportingTokens(); if (endorsingTokens != null) { for (int i = 0; i < endorsingTokens.Length; ++i) { SecurityToken source = endorsingTokens[i]; SecurityKeyIdentifierClause sourceKeyClause = endorsingTokenParameters[i].CreateKeyIdentifierClause(source, GetTokenReferenceStyle(endorsingTokenParameters[i])); if (sourceKeyClause == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenManagerCannotCreateTokenReference)), this.Message); } SecurityToken signingToken; SecurityKeyIdentifierClause signingKeyClause; if (endorsingTokenParameters[i].RequireDerivedKeys && !endorsingTokenParameters[i].HasAsymmetricKey) { string derivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(this.StandardsManager.MessageSecurityVersion.SecureConversationVersion); DerivedKeySecurityToken dkt = new DerivedKeySecurityToken(-1, 0, this.AlgorithmSuite.GetSignatureKeyDerivationLength(source, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, DerivedKeySecurityToken.DefaultNonceLength, source, sourceKeyClause, derivationAlgorithm, GenerateId()); signingToken = dkt; signingKeyClause = new LocalIdKeyIdentifierClause(dkt.Id, dkt.GetType()); this.elementContainer.AddEndorsingDerivedSupportingToken(dkt); } else { signingToken = source; signingKeyClause = sourceKeyClause; } SignWithSupportingToken(signingToken, signingKeyClause); } } SecurityToken[] signedEndorsingSupportingTokens = this.elementContainer.GetSignedEndorsingSupportingTokens(); if (signedEndorsingSupportingTokens != null) { for (int i = 0; i < signedEndorsingSupportingTokens.Length; ++i) { SecurityToken source = signedEndorsingSupportingTokens[i]; SecurityKeyIdentifierClause sourceKeyClause = signedEndorsingTokenParameters[i].CreateKeyIdentifierClause(source, GetTokenReferenceStyle(signedEndorsingTokenParameters[i])); if (sourceKeyClause == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenManagerCannotCreateTokenReference)), this.Message); } SecurityToken signingToken; SecurityKeyIdentifierClause signingKeyClause; if (signedEndorsingTokenParameters[i].RequireDerivedKeys && !signedEndorsingTokenParameters[i].HasAsymmetricKey) { string derivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(this.StandardsManager.MessageSecurityVersion.SecureConversationVersion); DerivedKeySecurityToken dkt = new DerivedKeySecurityToken(-1, 0, this.AlgorithmSuite.GetSignatureKeyDerivationLength(source, this.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, DerivedKeySecurityToken.DefaultNonceLength, source, sourceKeyClause, derivationAlgorithm, GenerateId()); signingToken = dkt; signingKeyClause = new LocalIdKeyIdentifierClause(dkt.Id, dkt.GetType()); this.elementContainer.AddSignedEndorsingDerivedSupportingToken(dkt); } else { signingToken = source; signingKeyClause = sourceKeyClause; } SignWithSupportingToken(signingToken, signingKeyClause); } } }
public Message SecureMessage () { secprop = Message.Properties.Security ?? new SecurityMessageProperty (); SecurityToken encToken = secprop.InitiatorToken != null ? secprop.InitiatorToken.SecurityToken : security.EncryptionToken; // FIXME: it might be still incorrect. SecurityToken signToken = Parameters == CounterParameters ? null : security.SigningToken; MessageProtectionOrder protectionOrder = security.MessageProtectionOrder; SecurityTokenSerializer serializer = security.TokenSerializer; SecurityBindingElement element = security.Element; SecurityAlgorithmSuite suite = element.DefaultAlgorithmSuite; // FIXME: remove this hack if (!ShouldOutputEncryptedKey) encToken = new BinarySecretSecurityToken (secprop.EncryptionKey); string messageId = "uuid-" + Guid.NewGuid (); int identForMessageId = 1; XmlDocument doc = new XmlDocument (); doc.PreserveWhitespace = true; UniqueId relatesTo = RelatesTo; if (relatesTo != null) msg.Headers.RelatesTo = relatesTo; else // FIXME: probably it is always added when it is stateful ? msg.Headers.MessageId = new UniqueId ("urn:" + messageId); // FIXME: get correct ReplyTo value if (Direction == MessageDirection.Input) msg.Headers.ReplyTo = new EndpointAddress (Constants.WsaAnonymousUri); if (MessageTo != null) msg.Headers.To = MessageTo.Uri; // wss:Security WSSecurityMessageHeader header = new WSSecurityMessageHeader (serializer); msg.Headers.Add (header); // 1. [Timestamp] if (element.IncludeTimestamp) { WsuTimestamp timestamp = new WsuTimestamp (); timestamp.Id = messageId + "-" + identForMessageId++; timestamp.Created = DateTime.Now; // FIXME: on service side, use element.LocalServiceSettings.TimestampValidityDuration timestamp.Expires = timestamp.Created.Add (element.LocalClientSettings.TimestampValidityDuration); header.AddContent (timestamp); } XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable); nsmgr.AddNamespace ("s", msg.Version.Envelope.Namespace); nsmgr.AddNamespace ("o", Constants.WssNamespace); nsmgr.AddNamespace ("u", Constants.WsuNamespace); nsmgr.AddNamespace ("o11", Constants.Wss11Namespace); /*WrappedKey*/SecurityToken primaryToken = null; DerivedKeySecurityToken dkeyToken = null; SecurityToken actualToken = null; SecurityKeyIdentifierClause actualClause = null; Signature sig = null; List<DerivedKeySecurityToken> derivedKeys = new List<DerivedKeySecurityToken> (); SymmetricAlgorithm masterKey = new RijndaelManaged (); masterKey.KeySize = suite.DefaultSymmetricKeyLength; masterKey.Mode = CipherMode.CBC; masterKey.Padding = PaddingMode.ISO10126; SymmetricAlgorithm actualKey = masterKey; // 2. [Encryption Token] // SecurityTokenInclusionMode // - Initiator or Recipient // - done or notyet. FIXME: not implemented yet // It also affects on key reference output bool includeEncToken = // /* FIXME: remove this hack */Parameters is SslSecurityTokenParameters ? false : ShouldIncludeToken ( Security.RecipientParameters.InclusionMode, false); bool includeSigToken = // /* FIXME: remove this hack */ Parameters is SslSecurityTokenParameters ? false : ShouldIncludeToken ( Security.InitiatorParameters.InclusionMode, false); SecurityKeyIdentifierClause encClause = ShouldOutputEncryptedKey ? CounterParameters.CallCreateKeyIdentifierClause (encToken, !ShouldOutputEncryptedKey ? SecurityTokenReferenceStyle.Internal : includeEncToken ? Parameters.ReferenceStyle : SecurityTokenReferenceStyle.External) : null; MessagePartSpecification sigSpec = SignaturePart; MessagePartSpecification encSpec = EncryptionPart; // encryption key (possibly also used for signing) // FIXME: get correct SymmetricAlgorithm according to the algorithm suite if (secprop.EncryptionKey != null) actualKey.Key = secprop.EncryptionKey; // FIXME: remove thid hack if (!ShouldOutputEncryptedKey) primaryToken = RequestContext.RequestMessage.Properties.Security.ProtectionToken.SecurityToken as WrappedKeySecurityToken; else primaryToken = // FIXME: remove this hack? encToken is SecurityContextSecurityToken ? encToken : new WrappedKeySecurityToken (messageId + "-" + identForMessageId++, actualKey.Key, // security.DefaultKeyWrapAlgorithm, Parameters.InternalHasAsymmetricKey ? suite.DefaultAsymmetricKeyWrapAlgorithm : suite.DefaultSymmetricKeyWrapAlgorithm, encToken, encClause != null ? new SecurityKeyIdentifier (encClause) : null); // If it reuses request's encryption key, do not output. if (ShouldOutputEncryptedKey) header.AddContent (primaryToken); actualToken = primaryToken; // FIXME: I doubt it is correct... WrappedKeySecurityToken requestEncKey = ShouldOutputEncryptedKey ? null : primaryToken as WrappedKeySecurityToken; actualClause = requestEncKey == null ? (SecurityKeyIdentifierClause) new LocalIdKeyIdentifierClause (actualToken.Id, typeof (WrappedKeySecurityToken)) : new InternalEncryptedKeyIdentifierClause (SHA1.Create ().ComputeHash (requestEncKey.GetWrappedKey ())); // generate derived key if needed if (CounterParameters.RequireDerivedKeys) { RijndaelManaged deriv = new RijndaelManaged (); deriv.KeySize = suite.DefaultEncryptionKeyDerivationLength; deriv.Mode = CipherMode.CBC; deriv.Padding = PaddingMode.ISO10126; deriv.GenerateKey (); dkeyToken = new DerivedKeySecurityToken ( GenerateId (doc), null, // algorithm actualClause, new InMemorySymmetricSecurityKey (actualKey.Key), null, // name null, // generation null, // offset deriv.Key.Length, null, // label deriv.Key); derivedKeys.Add (dkeyToken); actualToken = dkeyToken; actualKey.Key = ((SymmetricSecurityKey) dkeyToken.SecurityKeys [0]).GetSymmetricKey (); actualClause = new LocalIdKeyIdentifierClause (dkeyToken.Id); header.AddContent (dkeyToken); } ReferenceList refList = new ReferenceList (); // When encrypted with DerivedKeyToken, put references // immediately after the derived token (not inside the // primary token). // Similarly, when we do not output EncryptedKey, // output ReferenceList in the same way. if (CounterParameters.RequireDerivedKeys || !ShouldOutputEncryptedKey) header.AddContent (refList); else ((WrappedKeySecurityToken) primaryToken).ReferenceList = refList; // [Signature Confirmation] if (security.RequireSignatureConfirmation && secprop.ConfirmedSignatures.Count > 0) foreach (string value in secprop.ConfirmedSignatures) header.AddContent (new Wss11SignatureConfirmation (GenerateId (doc), value)); SupportingTokenInfoCollection tokenInfos = Direction == MessageDirection.Input ? security.CollectSupportingTokens (GetAction ()) : new SupportingTokenInfoCollection (); // empty foreach (SupportingTokenInfo tinfo in tokenInfos) header.AddContent (tinfo.Token); // populate DOM to sign. XPathNavigator nav = doc.CreateNavigator (); using (XmlWriter w = nav.AppendChild ()) { msg.WriteMessage (w); } XmlElement body = doc.SelectSingleNode ("/s:Envelope/s:Body/*", nsmgr) as XmlElement; string bodyId = null; XmlElement secElem = null; Collection<WSSignedXml> endorsedSignatures = new Collection<WSSignedXml> (); bool signatureProtection = (protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature); // Below are o:Security contents that are not signed... if (includeSigToken && signToken != null) header.AddContent (signToken); switch (protectionOrder) { case MessageProtectionOrder.EncryptBeforeSign: // FIXME: implement throw new NotImplementedException (); case MessageProtectionOrder.SignBeforeEncrypt: case MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature: // sign // see clause 8 of WS-SecurityPolicy C.2.2 WSSignedXml sxml = new WSSignedXml (doc); SecurityTokenReferenceKeyInfo sigKeyInfo; sig = sxml.Signature; sig.SignedInfo.CanonicalizationMethod = suite.DefaultCanonicalizationAlgorithm; foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/u:Timestamp", nsmgr)) CreateReference (sig, elem, elem.GetAttribute ("Id", Constants.WsuNamespace)); foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr)) CreateReference (sig, elem, elem.GetAttribute ("Id", Constants.WsuNamespace)); foreach (SupportingTokenInfo tinfo in tokenInfos) if (tinfo.Mode != SecurityTokenAttachmentMode.Endorsing) { XmlElement el = sxml.GetIdElement (doc, tinfo.Token.Id); CreateReference (sig, el, el.GetAttribute ("Id", Constants.WsuNamespace)); } XmlNodeList nodes = doc.SelectNodes ("/s:Envelope/s:Header/*", nsmgr); for (int i = 0; i < msg.Headers.Count; i++) { MessageHeaderInfo h = msg.Headers [i]; if (h.Name == "Security" && h.Namespace == Constants.WssNamespace) secElem = nodes [i] as XmlElement; else if (sigSpec.HeaderTypes.Count == 0 || sigSpec.HeaderTypes.Contains (new XmlQualifiedName (h.Name, h.Namespace))) { string id = GenerateId (doc); h.Id = id; CreateReference (sig, nodes [i] as XmlElement, id); } } if (sigSpec.IsBodyIncluded) { bodyId = GenerateId (doc); CreateReference (sig, body.ParentNode as XmlElement, bodyId); } if (security.DefaultSignatureAlgorithm == SignedXml.XmlDsigHMACSHA1Url) { // FIXME: use appropriate hash algorithm sxml.ComputeSignature (new HMACSHA1 (actualKey.Key)); sigKeyInfo = new SecurityTokenReferenceKeyInfo (actualClause, serializer, doc); } else { SecurityKeyIdentifierClause signClause = CounterParameters.CallCreateKeyIdentifierClause (signToken, includeSigToken ? CounterParameters.ReferenceStyle : SecurityTokenReferenceStyle.External); AsymmetricSecurityKey signKey = (AsymmetricSecurityKey) signToken.ResolveKeyIdentifierClause (signClause); sxml.SigningKey = signKey.GetAsymmetricAlgorithm (security.DefaultSignatureAlgorithm, true); sxml.ComputeSignature (); sigKeyInfo = new SecurityTokenReferenceKeyInfo (signClause, serializer, doc); } sxml.KeyInfo = new KeyInfo (); sxml.KeyInfo.AddClause (sigKeyInfo); if (!signatureProtection) header.AddContent (sig); // endorse the signature with (signed)endorsing // supporting tokens. foreach (SupportingTokenInfo tinfo in tokenInfos) { switch (tinfo.Mode) { case SecurityTokenAttachmentMode.Endorsing: case SecurityTokenAttachmentMode.SignedEndorsing: if (sxml.Signature.Id == null) { sig.Id = GenerateId (doc); secElem.AppendChild (sxml.GetXml ()); } WSSignedXml ssxml = new WSSignedXml (doc); ssxml.Signature.SignedInfo.CanonicalizationMethod = suite.DefaultCanonicalizationAlgorithm; CreateReference (ssxml.Signature, doc, sig.Id); SecurityToken sst = tinfo.Token; SecurityKey ssk = sst.SecurityKeys [0]; // FIXME: could be different? SecurityKeyIdentifierClause tclause = new LocalIdKeyIdentifierClause (sst.Id); // FIXME: could be different? if (ssk is SymmetricSecurityKey) { SymmetricSecurityKey signKey = (SymmetricSecurityKey) ssk; ssxml.ComputeSignature (signKey.GetKeyedHashAlgorithm (suite.DefaultSymmetricSignatureAlgorithm)); } else { AsymmetricSecurityKey signKey = (AsymmetricSecurityKey) ssk; ssxml.SigningKey = signKey.GetAsymmetricAlgorithm (suite.DefaultAsymmetricSignatureAlgorithm, true); ssxml.ComputeSignature (); } ssxml.KeyInfo.AddClause (new SecurityTokenReferenceKeyInfo (tclause, serializer, doc)); if (!signatureProtection) header.AddContent (ssxml.Signature); endorsedSignatures.Add (ssxml); break; } } // encrypt WSEncryptedXml exml = new WSEncryptedXml (doc); EncryptedData edata = Encrypt (body, actualKey, actualToken.Id, refList, actualClause, exml, doc); EncryptedXml.ReplaceElement (body, edata, false); // encrypt signature if (signatureProtection) { XmlElement sigxml = sig.GetXml (); edata = Encrypt (sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc); header.AddContent (edata); foreach (WSSignedXml ssxml in endorsedSignatures) { sigxml = ssxml.GetXml (); edata = Encrypt (sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc); header.AddContent (edata); } if (security.RequireSignatureConfirmation) { Collection<Wss11SignatureConfirmation> confs = header.FindAll<Wss11SignatureConfirmation> (); int count = 0; foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr)) { edata = Encrypt (elem, actualKey, confs [count].Id, refList, actualClause, exml, doc); EncryptedXml.ReplaceElement (elem, edata, false); header.Contents.Insert (header.Contents.IndexOf (confs [count]), edata); header.Contents.Remove (confs [count++]); } } } // encrypt Encrypted supporting tokens foreach (SupportingTokenInfo tinfo in tokenInfos) { if (tinfo.Mode == SecurityTokenAttachmentMode.SignedEncrypted) { XmlElement el = exml.GetIdElement (doc, tinfo.Token.Id); tinfo.Encrypted = Encrypt (el, actualKey, actualToken.Id, refList, actualClause, exml, doc); EncryptedXml.ReplaceElement (el, tinfo.Encrypted, false); header.Contents.Insert (header.Contents.IndexOf (tinfo.Token), tinfo.Encrypted); header.Contents.Remove (tinfo.Token); } } break; } Message ret = new WSSecurityMessage (Message.CreateMessage (msg.Version, msg.Headers.Action, new XmlNodeReader (doc.SelectSingleNode ("/s:Envelope/s:Body/*", nsmgr) as XmlElement)), bodyId); ret.Properties.Security = (SecurityMessageProperty) secprop.CreateCopy (); ret.Properties.Security.EncryptionKey = masterKey.Key; // FIXME: can we support TransportToken here? if (element is AsymmetricSecurityBindingElement) { ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification (encToken, null); // FIXME: second argument ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification (signToken, null); // FIXME: second argument } else ret.Properties.Security.ProtectionToken = new SecurityTokenSpecification (primaryToken, null); ret.Headers.Clear (); ret.Headers.CopyHeadersFrom (msg); // Header contents are: // - Timestamp // - SignatureConfirmation if required // - EncryptionToken if included // - derived key token for EncryptionToken // - ReferenceList for encrypted items // - signed supporting tokens // - signed endorsing supporting tokens // (i.e. Signed/SignedEncrypted/SignedEndorsing) // - Signature Token if different from enc token. // - derived key token for sig token if different // - Signature for: // - Timestamp // - supporting tokens (regardless of // its inclusion) // - message parts in SignedParts // - SignatureToken if TokenProtection // (regardless of its inclusion) // - Signatures for the main signature (above), // for every endorsing token and signed // endorsing token. // //MessageBuffer zzz = ret.CreateBufferedCopy (100000); //ret = zzz.CreateMessage (); //Console.WriteLine (zzz.CreateMessage ()); return ret; }
private void StartSignature() { if (this.elementContainer.SourceSigningToken != null) { SecurityToken sourceSigningToken; SecurityKeyIdentifierClause clause2; SecurityTokenReferenceStyle tokenReferenceStyle = this.GetTokenReferenceStyle(this.signingTokenParameters); SecurityKeyIdentifierClause tokenToDeriveIdentifier = this.signingTokenParameters.CreateKeyIdentifierClause(this.elementContainer.SourceSigningToken, tokenReferenceStyle); if (tokenToDeriveIdentifier == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("TokenManagerCannotCreateTokenReference")), base.Message); } if (this.signingTokenParameters.RequireDerivedKeys && !this.signingTokenParameters.HasAsymmetricKey) { string signatureKeyDerivationAlgorithm = base.AlgorithmSuite.GetSignatureKeyDerivationAlgorithm(this.elementContainer.SourceSigningToken, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion); string keyDerivationAlgorithm = System.ServiceModel.Security.SecurityUtils.GetKeyDerivationAlgorithm(base.StandardsManager.MessageSecurityVersion.SecureConversationVersion); if (signatureKeyDerivationAlgorithm != keyDerivationAlgorithm) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(System.ServiceModel.SR.GetString("UnsupportedCryptoAlgorithm", new object[] { signatureKeyDerivationAlgorithm }))); } DerivedKeySecurityToken token2 = new DerivedKeySecurityToken(-1, 0, base.AlgorithmSuite.GetSignatureKeyDerivationLength(this.elementContainer.SourceSigningToken, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, 0x10, this.elementContainer.SourceSigningToken, tokenToDeriveIdentifier, signatureKeyDerivationAlgorithm, this.GenerateId()); sourceSigningToken = this.elementContainer.DerivedSigningToken = token2; clause2 = new LocalIdKeyIdentifierClause(sourceSigningToken.Id, sourceSigningToken.GetType()); } else { sourceSigningToken = this.elementContainer.SourceSigningToken; clause2 = tokenToDeriveIdentifier; } SecurityKeyIdentifier identifier = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[] { clause2 }); if ((this.signatureConfirmationsToSend != null) && (this.signatureConfirmationsToSend.Count > 0)) { ISecurityElement[] elementArray = this.CreateSignatureConfirmationElements(this.signatureConfirmationsToSend); for (int i = 0; i < elementArray.Length; i++) { SendSecurityHeaderElement confirmation = new SendSecurityHeaderElement(elementArray[i].Id, elementArray[i]) { MarkedForEncryption = this.signatureConfirmationsToSend.IsMarkedForEncryption }; this.elementContainer.AddSignatureConfirmation(confirmation); } } bool generateTargettablePrimarySignature = (this.endorsingTokenParameters != null) || (this.signedEndorsingTokenParameters != null); this.StartPrimarySignatureCore(sourceSigningToken, identifier, this.signatureParts, generateTargettablePrimarySignature); } }
void WriteLocalIdKeyIdentifierClause ( XmlWriter w, LocalIdKeyIdentifierClause ic) { w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace); w.WriteStartElement ("o", "Reference", Constants.WssNamespace); if (EmitBspRequiredAttributes && ic.OwnerType != null) { string vt = GetTokenTypeUri (ic.OwnerType); if (vt != null) w.WriteAttributeString ("ValueType", vt); } w.WriteAttributeString ("URI", "#" + ic.LocalId); w.WriteEndElement (); w.WriteEndElement (); }
private void SignWithSupportingTokens() { SecurityToken[] endorsingSupportingTokens = this.elementContainer.GetEndorsingSupportingTokens(); if (endorsingSupportingTokens != null) { for (int i = 0; i < endorsingSupportingTokens.Length; i++) { SecurityToken token2; SecurityKeyIdentifierClause clause2; SecurityToken token = endorsingSupportingTokens[i]; SecurityKeyIdentifierClause tokenToDeriveIdentifier = this.endorsingTokenParameters[i].CreateKeyIdentifierClause(token, this.GetTokenReferenceStyle(this.endorsingTokenParameters[i])); if (tokenToDeriveIdentifier == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("TokenManagerCannotCreateTokenReference")), base.Message); } if (this.endorsingTokenParameters[i].RequireDerivedKeys && !this.endorsingTokenParameters[i].HasAsymmetricKey) { string keyDerivationAlgorithm = System.ServiceModel.Security.SecurityUtils.GetKeyDerivationAlgorithm(base.StandardsManager.MessageSecurityVersion.SecureConversationVersion); DerivedKeySecurityToken token3 = new DerivedKeySecurityToken(-1, 0, base.AlgorithmSuite.GetSignatureKeyDerivationLength(token, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, 0x10, token, tokenToDeriveIdentifier, keyDerivationAlgorithm, this.GenerateId()); token2 = token3; clause2 = new LocalIdKeyIdentifierClause(token3.Id, token3.GetType()); this.elementContainer.AddEndorsingDerivedSupportingToken(token3); } else { token2 = token; clause2 = tokenToDeriveIdentifier; } this.SignWithSupportingToken(token2, clause2); } } SecurityToken[] signedEndorsingSupportingTokens = this.elementContainer.GetSignedEndorsingSupportingTokens(); if (signedEndorsingSupportingTokens != null) { for (int j = 0; j < signedEndorsingSupportingTokens.Length; j++) { SecurityToken token5; SecurityKeyIdentifierClause clause4; SecurityToken token4 = signedEndorsingSupportingTokens[j]; SecurityKeyIdentifierClause clause3 = this.signedEndorsingTokenParameters[j].CreateKeyIdentifierClause(token4, this.GetTokenReferenceStyle(this.signedEndorsingTokenParameters[j])); if (clause3 == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("TokenManagerCannotCreateTokenReference")), base.Message); } if (this.signedEndorsingTokenParameters[j].RequireDerivedKeys && !this.signedEndorsingTokenParameters[j].HasAsymmetricKey) { string derivationAlgorithm = System.ServiceModel.Security.SecurityUtils.GetKeyDerivationAlgorithm(base.StandardsManager.MessageSecurityVersion.SecureConversationVersion); DerivedKeySecurityToken token6 = new DerivedKeySecurityToken(-1, 0, base.AlgorithmSuite.GetSignatureKeyDerivationLength(token4, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, 0x10, token4, clause3, derivationAlgorithm, this.GenerateId()); token5 = token6; clause4 = new LocalIdKeyIdentifierClause(token6.Id, token6.GetType()); this.elementContainer.AddSignedEndorsingDerivedSupportingToken(token6); } else { token5 = token4; clause4 = clause3; } this.SignWithSupportingToken(token5, clause4); } } }
public override bool Matches(SecurityKeyIdentifierClause keyIdentifierClause) { LocalIdKeyIdentifierClause objB = keyIdentifierClause as LocalIdKeyIdentifierClause; return(object.ReferenceEquals(this, objB) || ((objB != null) && objB.Matches(this.localId, this.OwnerType))); }
SecurityKeyIdentifierClause ReadSecurityTokenReference (XmlReader reader) { reader.ReadStartElement (); reader.MoveToContent (); if (reader.NamespaceURI == SignedXml.XmlDsigNamespaceUrl) { KeyInfoX509Data x509 = new KeyInfoX509Data (); x509.LoadXml (new XmlDocument ().ReadNode (reader) as XmlElement); if (x509.IssuerSerials.Count == 0) throw new XmlException ("'X509IssuerSerial' element is expected inside 'X509Data' element"); X509IssuerSerial s = (X509IssuerSerial) x509.IssuerSerials [0]; reader.MoveToContent (); reader.ReadEndElement (); return new X509IssuerSerialKeyIdentifierClause (s.IssuerName, s.SerialNumber); } if (reader.NamespaceURI != Constants.WssNamespace) throw new XmlException (String.Format ("Unexpected SecurityTokenReference content: expected local name 'Reference' and namespace URI '{0}' but found local name '{1}' and namespace '{2}'.", Constants.WssNamespace, reader.LocalName, reader.NamespaceURI)); switch (reader.LocalName) { case "Reference": Type ownerType = null; // FIXME: there could be more token types. if (reader.MoveToAttribute ("ValueType")) { switch (reader.Value) { case Constants.WSSEncryptedKeyToken: ownerType = typeof (WrappedKeySecurityToken); break; case Constants.WSSX509Token: ownerType = typeof (X509SecurityToken); break; case Constants.WsscContextToken: ownerType = typeof (SecurityContextSecurityToken); break; default: throw new XmlException (String.Format ("Unexpected ValueType in 'Reference' element: '{0}'", reader.Value)); } } reader.MoveToElement (); string uri = reader.GetAttribute ("URI"); if (String.IsNullOrEmpty (uri)) uri = "#"; SecurityKeyIdentifierClause ic = null; if (ownerType == typeof (SecurityContextSecurityToken) && uri [0] != '#') // FIXME: Generation? ic = new SecurityContextKeyIdentifierClause (new UniqueId (uri)); else ic = new LocalIdKeyIdentifierClause (uri.Substring (1), ownerType); reader.Skip (); reader.MoveToContent (); reader.ReadEndElement (); return ic; case "KeyIdentifier": string valueType = reader.GetAttribute ("ValueType"); string value = reader.ReadElementContentAsString (); reader.MoveToContent (); reader.ReadEndElement (); // consume </Reference> switch (valueType) { case Constants.WssKeyIdentifierX509Thumbptint: return new X509ThumbprintKeyIdentifierClause (Convert.FromBase64String (value)); case Constants.WssKeyIdentifierEncryptedKey: return new InternalEncryptedKeyIdentifierClause (Convert.FromBase64String (value)); case Constants.WssKeyIdentifierSamlAssertion: return new SamlAssertionKeyIdentifierClause (value); default: // It is kinda weird but it throws XmlException here ... throw new XmlException (String.Format ("KeyIdentifier type '{0}' is not supported in WSSecurityTokenSerializer.", valueType)); } default: throw new XmlException (String.Format ("Unexpected SecurityTokenReference content: expected local name 'Reference' and namespace URI '{0}' but found local name '{1}' and namespace '{2}'.", Constants.WssNamespace, reader.LocalName, reader.NamespaceURI)); } }
public void WriteLocalIdKeyIdentifierClause3 () { StringWriter sw = new StringWriter (); LocalIdKeyIdentifierClause ic = new LocalIdKeyIdentifierClause ("urn:myIDValue", typeof (WrappedKeySecurityToken)); using (XmlWriter w = XmlWriter.Create (sw, GetWriterSettings ())) { WSSecurityTokenSerializer.DefaultInstance.WriteKeyIdentifierClause (w, ic); } Assert.AreEqual ("<o:SecurityTokenReference xmlns:o=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"><o:Reference URI=\"#urn:myIDValue\" /></o:SecurityTokenReference>", sw.ToString (), "#1"); }
public void WriteLocalIdKeyIdentifierClause2 () { StringWriter sw = new StringWriter (); LocalIdKeyIdentifierClause ic = new LocalIdKeyIdentifierClause ("#urn:myIDValue"); using (XmlWriter w = XmlWriter.Create (sw, GetWriterSettings ())) { WSSecurityTokenSerializer.DefaultInstance.WriteKeyIdentifierClause (w, ic); } // ... so, specifying an URI including '#' does not make sense Assert.AreEqual ("<o:SecurityTokenReference xmlns:o=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"><o:Reference URI=\"##urn:myIDValue\" /></o:SecurityTokenReference>", sw.ToString (), "#2"); }
public override SecurityKeyIdentifierClause ReadClause(XmlDictionaryReader reader, byte[] derivationNonce, int derivationLength, string tokenType) { string attribute = reader.GetAttribute(XD.SecurityJan2004Dictionary.URI, null); string tokenTypeUri = reader.GetAttribute(XD.SecurityJan2004Dictionary.ValueType, null); System.Type[] ownerTypes = null; if (tokenTypeUri != null) { ownerTypes = this.tokenSerializer.GetTokenTypes(tokenTypeUri); } SecurityKeyIdentifierClause clause = new LocalIdKeyIdentifierClause(attribute.Substring(1), derivationNonce, derivationLength, ownerTypes); if (reader.IsEmptyElement) { reader.Read(); return clause; } reader.ReadStartElement(); reader.ReadEndElement(); return clause; }
Signature CreateSignature (XmlDocument doc, XmlElement body, XmlNamespaceManager nsmgr, SupportingTokenInfoCollection tokenInfos, SecurityKeyIdentifierClause actualClause, SymmetricAlgorithm actualKey, SecurityToken signToken, bool includeSigToken, bool signatureProtection, WSSecurityMessageHeader header, Collection<WSSignedXml> endorsedSignatures, ref string bodyId) { // sign // see clause 8 of WS-SecurityPolicy C.2.2 WSSignedXml sxml = new WSSignedXml (doc); SecurityTokenReferenceKeyInfo sigKeyInfo; XmlElement secElem = null; var sigSpec = SignaturePart; var serializer = security.TokenSerializer; var suite = security.Element.DefaultAlgorithmSuite; var sig = sxml.Signature; sig.SignedInfo.CanonicalizationMethod = suite.DefaultCanonicalizationAlgorithm; foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/u:Timestamp", nsmgr)) CreateReference(sig, elem, elem.GetAttribute ("Id", Constants.WsuNamespace)); foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr)) CreateReference(sig, elem, elem.GetAttribute ("Id", Constants.WsuNamespace)); foreach (SupportingTokenInfo tinfo in tokenInfos) if (tinfo.Mode != SecurityTokenAttachmentMode.Endorsing) { XmlElement el = sxml.GetIdElement (doc, tinfo.Token.Id); CreateReference (sig, el, el.GetAttribute ("Id", Constants.WsuNamespace)); } XmlNodeList nodes = doc.SelectNodes ("/s:Envelope/s:Header/*", nsmgr); for (int i = 0; i < msg.Headers.Count; i++) { MessageHeaderInfo h = msg.Headers [i]; if (h.Name == "Security" && h.Namespace == Constants.WssNamespace) secElem = nodes [i] as XmlElement; else if ((sigSpec.HeaderTypes.Count == 0 || sigSpec.HeaderTypes.Contains (new XmlQualifiedName(h.Name, h.Namespace))) && (msg.Version.Addressing != AddressingVersion.None || !String.Equals (h.Name, "Action", StringComparison.Ordinal))) { string id = GenerateId (doc); h.Id = id; CreateReference (sig, nodes [i] as XmlElement, id); } } if (sigSpec.IsBodyIncluded) { bodyId = GenerateId (doc); CreateReference (sig, body.ParentNode as XmlElement, bodyId); } if (security.DefaultSignatureAlgorithm == SignedXml.XmlDsigHMACSHA1Url) { // FIXME: use appropriate hash algorithm sxml.ComputeSignature (new HMACSHA1(actualKey.Key)); sigKeyInfo = new SecurityTokenReferenceKeyInfo (actualClause, serializer, doc); } else { SecurityKeyIdentifierClause signClause = CounterParameters.CallCreateKeyIdentifierClause (signToken, includeSigToken ? CounterParameters.ReferenceStyle : SecurityTokenReferenceStyle.External); AsymmetricSecurityKey signKey = (AsymmetricSecurityKey)signToken.ResolveKeyIdentifierClause (signClause); sxml.SigningKey = signKey.GetAsymmetricAlgorithm (security.DefaultSignatureAlgorithm, true); sxml.ComputeSignature (); sigKeyInfo = new SecurityTokenReferenceKeyInfo (signClause, serializer, doc); } sxml.KeyInfo = new KeyInfo (); sxml.KeyInfo.AddClause (sigKeyInfo); if (!signatureProtection) header.AddContent (sig); // endorse the signature with (signed)endorsing // supporting tokens. foreach (SupportingTokenInfo tinfo in tokenInfos) { switch (tinfo.Mode) { case SecurityTokenAttachmentMode.Endorsing: case SecurityTokenAttachmentMode.SignedEndorsing: if (sxml.Signature.Id == null) { sig.Id = GenerateId (doc); secElem.AppendChild (sxml.GetXml ()); } WSSignedXml ssxml = new WSSignedXml (doc); ssxml.Signature.SignedInfo.CanonicalizationMethod = suite.DefaultCanonicalizationAlgorithm; CreateReference (ssxml.Signature, doc, sig.Id); SecurityToken sst = tinfo.Token; SecurityKey ssk = sst.SecurityKeys [0]; // FIXME: could be different? SecurityKeyIdentifierClause tclause = new LocalIdKeyIdentifierClause (sst.Id); // FIXME: could be different? if (ssk is SymmetricSecurityKey) { SymmetricSecurityKey signKey = (SymmetricSecurityKey)ssk; ssxml.ComputeSignature (signKey.GetKeyedHashAlgorithm(suite.DefaultSymmetricSignatureAlgorithm)); } else { AsymmetricSecurityKey signKey = (AsymmetricSecurityKey)ssk; ssxml.SigningKey = signKey.GetAsymmetricAlgorithm (suite.DefaultAsymmetricSignatureAlgorithm, true); ssxml.ComputeSignature (); } ssxml.KeyInfo.AddClause (new SecurityTokenReferenceKeyInfo (tclause, serializer, doc)); if (!signatureProtection) header.AddContent (ssxml.Signature); endorsedSignatures.Add (ssxml); break; } } return sig; }
public virtual bool MatchesKeyIdentifierClause(SecurityKeyIdentifierClause keyIdentifierClause) { LocalIdKeyIdentifierClause clause = keyIdentifierClause as LocalIdKeyIdentifierClause; return((clause != null) && clause.Matches(this.Id, base.GetType())); }
public override bool Matches(SecurityKeyIdentifierClause keyIdentifierClause) { LocalIdKeyIdentifierClause that = keyIdentifierClause as LocalIdKeyIdentifierClause; return(ReferenceEquals(this, that) || (that != null && that.Matches(_localId, this.OwnerType))); }
public override Type GetTokenType(SecurityKeyIdentifierClause clause) { LocalIdKeyIdentifierClause localClause = clause as LocalIdKeyIdentifierClause; return(localClause.OwnerType); }
public void WriteLocalIdKeyIdentifierClause5 () // derivedKey { StringWriter sw = new StringWriter (); LocalIdKeyIdentifierClause ic = new LocalIdKeyIdentifierClause ("urn:myIDValue", new byte [32], 16, typeof (WrappedKeySecurityToken)); using (XmlWriter w = XmlWriter.Create (sw, GetWriterSettings ())) { new WSSecurityTokenSerializer (true).WriteKeyIdentifierClause (w, ic); } Assert.AreEqual ("<o:SecurityTokenReference xmlns:o=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"><o:Reference ValueType=\"http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey\" URI=\"#urn:myIDValue\" /></o:SecurityTokenReference>", sw.ToString (), "#1"); }
private void StartEncryption() { if (this.elementContainer.SourceEncryptionToken != null) { SecurityToken sourceEncryptionToken; SecurityKeyIdentifierClause clause2; SecurityKeyIdentifierClause clause3; SecurityKeyIdentifier identifier; SecurityTokenReferenceStyle tokenReferenceStyle = this.GetTokenReferenceStyle(this.encryptingTokenParameters); bool flag = tokenReferenceStyle == SecurityTokenReferenceStyle.Internal; SecurityKeyIdentifierClause clause = this.encryptingTokenParameters.CreateKeyIdentifierClause(this.elementContainer.SourceEncryptionToken, tokenReferenceStyle); if (clause == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("TokenManagerCannotCreateTokenReference")), base.Message); } if (!System.ServiceModel.Security.SecurityUtils.HasSymmetricSecurityKey(this.elementContainer.SourceEncryptionToken)) { string str; XmlDictionaryString str2; int keyLength = Math.Max(0x80, base.AlgorithmSuite.DefaultSymmetricKeyLength); System.ServiceModel.Security.CryptoHelper.ValidateSymmetricKeyLength(keyLength, base.AlgorithmSuite); byte[] buffer = new byte[keyLength / 8]; System.ServiceModel.Security.CryptoHelper.FillRandomBytes(buffer); base.AlgorithmSuite.GetKeyWrapAlgorithm(this.elementContainer.SourceEncryptionToken, out str, out str2); WrappedKeySecurityToken token2 = new WrappedKeySecurityToken(this.GenerateId(), buffer, str, str2, this.elementContainer.SourceEncryptionToken, new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[] { clause })); this.elementContainer.WrappedEncryptionToken = token2; sourceEncryptionToken = token2; clause2 = new LocalIdKeyIdentifierClause(token2.Id, token2.GetType()); flag = true; } else { sourceEncryptionToken = this.elementContainer.SourceEncryptionToken; clause2 = clause; } if (this.encryptingTokenParameters.RequireDerivedKeys) { string encryptionKeyDerivationAlgorithm = base.AlgorithmSuite.GetEncryptionKeyDerivationAlgorithm(sourceEncryptionToken, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion); string keyDerivationAlgorithm = System.ServiceModel.Security.SecurityUtils.GetKeyDerivationAlgorithm(base.StandardsManager.MessageSecurityVersion.SecureConversationVersion); if (encryptionKeyDerivationAlgorithm != keyDerivationAlgorithm) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(System.ServiceModel.SR.GetString("UnsupportedCryptoAlgorithm", new object[] { encryptionKeyDerivationAlgorithm }))); } DerivedKeySecurityToken token3 = new DerivedKeySecurityToken(-1, 0, base.AlgorithmSuite.GetEncryptionKeyDerivationLength(sourceEncryptionToken, base.StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, 0x10, sourceEncryptionToken, clause2, encryptionKeyDerivationAlgorithm, this.GenerateId()); this.encryptingToken = this.elementContainer.DerivedEncryptionToken = token3; clause3 = new LocalIdKeyIdentifierClause(token3.Id, token3.GetType()); } else { this.encryptingToken = sourceEncryptionToken; clause3 = clause2; } this.skipKeyInfoForEncryption = ((flag && base.EncryptedKeyContainsReferenceList) && (this.encryptingToken is WrappedKeySecurityToken)) && this.signThenEncrypt; if (this.skipKeyInfoForEncryption) { identifier = null; } else { identifier = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[] { clause3 }); } this.StartEncryptionCore(this.encryptingToken, identifier); } }