public SymmetricSecurityBindingElement(SecurityTokenParameters protectionTokenParameters) : base() { _messageProtectionOrder = SecurityBindingElement.defaultMessageProtectionOrder; _requireSignatureConfirmation = SecurityBindingElement.defaultRequireSignatureConfirmation; _protectionTokenParameters = protectionTokenParameters; }
public void ClientInitiatorHasNoKeysCore(bool deriveKeys, MessageProtectionOrder order) { AsymmetricSecurityBindingElement sbe = new AsymmetricSecurityBindingElement(); sbe.InitiatorTokenParameters = new UserNameSecurityTokenParameters(); sbe.RecipientTokenParameters = new X509SecurityTokenParameters(); sbe.SetKeyDerivation(deriveKeys); sbe.MessageProtectionOrder = order; TransportBindingElement tbe = new HandlerTransportBindingElement(delegate(Message input) { // funky, but .NET does not raise an error // until it writes the message to somewhere. // That is, it won't raise an error if this // HandlerTransportBindingElement does not // write the input message to somewhere. // It is an obvious bug. input.WriteMessage(XmlWriter.Create(TextWriter.Null)); throw new Exception(); }); CustomBinding binding = new CustomBinding(sbe, tbe); EndpointAddress address = new EndpointAddress( new Uri("stream:dummy"), new X509CertificateEndpointIdentity(cert2)); CalcProxy proxy = new CalcProxy(binding, address); proxy.ClientCredentials.UserName.UserName = "******"; proxy.Open(); // Until here the wrong parameters are not checked. proxy.Sum(1, 2); }
internal static bool IsDefined(MessageProtectionOrder value) { if ((value != MessageProtectionOrder.SignBeforeEncrypt) && (value != MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature)) { return (value == MessageProtectionOrder.EncryptBeforeSign); } return true; }
internal static bool IsDefined(MessageProtectionOrder value) { if ((value != MessageProtectionOrder.SignBeforeEncrypt) && (value != MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature)) { return(value == MessageProtectionOrder.EncryptBeforeSign); } return(true); }
private SymmetricSecurityBindingElement(SymmetricSecurityBindingElement elementToBeCloned) : base(elementToBeCloned) { _messageProtectionOrder = elementToBeCloned._messageProtectionOrder; if (elementToBeCloned._protectionTokenParameters != null) { _protectionTokenParameters = (SecurityTokenParameters)elementToBeCloned._protectionTokenParameters.Clone(); } _requireSignatureConfirmation = elementToBeCloned._requireSignatureConfirmation; }
private SymmetricSecurityBindingElement(SymmetricSecurityBindingElement elementToBeCloned) : base((SecurityBindingElement)elementToBeCloned) { this.messageProtectionOrder = elementToBeCloned.messageProtectionOrder; if (elementToBeCloned.protectionTokenParameters != null) { this.protectionTokenParameters = elementToBeCloned.protectionTokenParameters.Clone(); } this.requireSignatureConfirmation = elementToBeCloned.requireSignatureConfirmation; }
internal AsymmetricSecurityBindingElement( SecurityTokenParameters recipientTokenParameters, SecurityTokenParameters initiatorTokenParameters, bool allowSerializedSigningTokenOnReply) : base() { this.messageProtectionOrder = SecurityBindingElement.defaultMessageProtectionOrder; this.requireSignatureConfirmation = SecurityBindingElement.defaultRequireSignatureConfirmation; this.initiatorTokenParameters = initiatorTokenParameters; this.recipientTokenParameters = recipientTokenParameters; this.allowSerializedSigningTokenOnReply = allowSerializedSigningTokenOnReply; this.isCertificateSignatureBinding = false; }
public static void AssertSymmetricSecurityBindingElement( SecurityAlgorithmSuite algorithm, bool includeTimestamp, SecurityKeyEntropyMode keyEntropyMode, MessageProtectionOrder messageProtectionOrder, MessageSecurityVersion messageSecurityVersion, bool requireSignatureConfirmation, SecurityHeaderLayout securityHeaderLayout, // EndpointSupportingTokenParameters int endorsing, int signed, int signedEncrypted, int signedEndorsing, // ProtectionTokenParameters bool hasProtectionTokenParameters, SecurityTokenInclusionMode protectionTokenInclusionMode, SecurityTokenReferenceStyle protectionTokenReferenceStyle, bool protectionTokenRequireDerivedKeys, // LocalClientSettings bool cacheCookies, int renewalThresholdPercentage, bool detectReplays, SymmetricSecurityBindingElement be, string label) { AssertSecurityBindingElement( algorithm, includeTimestamp, keyEntropyMode, messageSecurityVersion, securityHeaderLayout, // EndpointSupportingTokenParameters endorsing, signed, signedEncrypted, signedEndorsing, // LocalClientSettings cacheCookies, renewalThresholdPercentage, detectReplays, be, label); Assert.AreEqual(messageProtectionOrder, be.MessageProtectionOrder, label + ".MessageProtectionOrder"); Assert.AreEqual(requireSignatureConfirmation, be.RequireSignatureConfirmation, label + ".RequireSignatureConfirmation"); if (!hasProtectionTokenParameters) { Assert.IsNull(be.ProtectionTokenParameters, label + ".ProtectionTokenParameters (null)"); } else { AssertSecurityTokenParameters( protectionTokenInclusionMode, protectionTokenReferenceStyle, protectionTokenRequireDerivedKeys, be.ProtectionTokenParameters, label + ".ProtectionTokenParameters"); } }
internal MessageSecurityProtocolFactory(MessageSecurityProtocolFactory factory) : base(factory) { if (factory == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("factory"); this.applyIntegrity = factory.applyIntegrity; this.applyConfidentiality = factory.applyConfidentiality; this.identityVerifier = factory.identityVerifier; this.protectionRequirements = new ChannelProtectionRequirements(factory.protectionRequirements); this.messageProtectionOrder = factory.messageProtectionOrder; this.requireIntegrity = factory.requireIntegrity; this.requireConfidentiality = factory.requireConfidentiality; this.doRequestSignatureConfirmation = factory.doRequestSignatureConfirmation; }
internal MessageSecurityProtocolFactory(MessageSecurityProtocolFactory factory) : base((SecurityProtocolFactory)factory) { if (factory == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("factory"); } this.applyIntegrity = factory.applyIntegrity; this.applyConfidentiality = factory.applyConfidentiality; this.identityVerifier = factory.identityVerifier; this.protectionRequirements = new ChannelProtectionRequirements(factory.protectionRequirements); this.messageProtectionOrder = factory.messageProtectionOrder; this.requireIntegrity = factory.requireIntegrity; this.requireConfidentiality = factory.requireConfidentiality; this.doRequestSignatureConfirmation = factory.doRequestSignatureConfirmation; }
AsymmetricSecurityBindingElement(AsymmetricSecurityBindingElement elementToBeCloned) : base(elementToBeCloned) { if (elementToBeCloned.initiatorTokenParameters != null) { this.initiatorTokenParameters = (SecurityTokenParameters)elementToBeCloned.initiatorTokenParameters.Clone(); } this.messageProtectionOrder = elementToBeCloned.messageProtectionOrder; if (elementToBeCloned.recipientTokenParameters != null) { this.recipientTokenParameters = (SecurityTokenParameters)elementToBeCloned.recipientTokenParameters.Clone(); } this.requireSignatureConfirmation = elementToBeCloned.requireSignatureConfirmation; this.allowSerializedSigningTokenOnReply = elementToBeCloned.allowSerializedSigningTokenOnReply; this.isCertificateSignatureBinding = elementToBeCloned.isCertificateSignatureBinding; }
internal MessageSecurityProtocolFactory(MessageSecurityProtocolFactory factory) : base(factory) { if (factory == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(factory)); } _applyIntegrity = factory._applyIntegrity; _applyConfidentiality = factory._applyConfidentiality; _identityVerifier = factory._identityVerifier; ProtectionRequirements = new ChannelProtectionRequirements(factory.ProtectionRequirements); _messageProtectionOrder = factory._messageProtectionOrder; _requireIntegrity = factory._requireIntegrity; _requireConfidentiality = factory._requireConfidentiality; _doRequestSignatureConfirmation = factory._doRequestSignatureConfirmation; }
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); }
internal static bool IsDefined(MessageProtectionOrder value) { return(value == MessageProtectionOrder.SignBeforeEncrypt || value == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature || value == MessageProtectionOrder.EncryptBeforeSign); }
public void ClientInitiatorHasNoKeysCore (bool deriveKeys, MessageProtectionOrder order) { AsymmetricSecurityBindingElement sbe = new AsymmetricSecurityBindingElement (); sbe.InitiatorTokenParameters = new UserNameSecurityTokenParameters (); sbe.RecipientTokenParameters = new X509SecurityTokenParameters (); sbe.SetKeyDerivation (deriveKeys); sbe.MessageProtectionOrder = order; TransportBindingElement tbe = new HandlerTransportBindingElement (delegate (Message input) { // funky, but .NET does not raise an error // until it writes the message to somewhere. // That is, it won't raise an error if this // HandlerTransportBindingElement does not // write the input message to somewhere. // It is an obvious bug. input.WriteMessage (XmlWriter.Create (TextWriter.Null)); throw new Exception (); }); CustomBinding binding = new CustomBinding (sbe, tbe); EndpointAddress address = new EndpointAddress ( new Uri ("stream:dummy"), new X509CertificateEndpointIdentity (cert2)); CalcProxy proxy = new CalcProxy (binding, address); proxy.ClientCredentials.UserName.UserName = "******"; proxy.Open (); // Until here the wrong parameters are not checked. proxy.Sum (1, 2); }
public void Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy) { Fx.Assert(ReaderQuotas != null, "Reader quotas must be set before processing"); MessageProtectionOrder actualProtectionOrder = _protectionOrder; bool wasProtectionOrderDowngraded = false; if (_protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature) { throw ExceptionHelper.PlatformNotSupported(); // No support for message encryption } _channelBinding = channelBinding; _extendedProtectionPolicy = extendedProtectionPolicy; _orderTracker.SetRequiredProtectionOrder(actualProtectionOrder); SetProcessingStarted(); _timeoutHelper = new TimeoutHelper(timeout); Message = SecurityVerifiedMessage = new SecurityVerifiedMessage(Message, this); XmlDictionaryReader reader = CreateSecurityHeaderReader(); reader.MoveToStartElement(); if (reader.IsEmptyElement) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.SecurityHeaderIsEmpty), Message); } if (RequireMessageProtection) { _securityElementAttributes = XmlAttributeHolder.ReadAttributes(reader); } else { _securityElementAttributes = XmlAttributeHolder.emptyArray; } reader.ReadStartElement(); if (_primaryTokenParameters != null) { _primaryTokenTracker = new TokenTracker(null, _outOfBandPrimaryToken, _allowFirstTokenMismatch); } // universalTokenResolver is used for resolving tokens _universalTokenResolver = new SecurityHeaderTokenResolver(this); // primary token resolver is used for resolving primary signature and decryption _primaryTokenResolver = new SecurityHeaderTokenResolver(this); if (_outOfBandPrimaryToken != null) { _universalTokenResolver.Add(_outOfBandPrimaryToken, SecurityTokenReferenceStyle.External, _primaryTokenParameters); _primaryTokenResolver.Add(_outOfBandPrimaryToken, SecurityTokenReferenceStyle.External, _primaryTokenParameters); } else if (_outOfBandPrimaryTokenCollection != null) { for (int i = 0; i < _outOfBandPrimaryTokenCollection.Count; ++i) { _universalTokenResolver.Add(_outOfBandPrimaryTokenCollection[i], SecurityTokenReferenceStyle.External, _primaryTokenParameters); _primaryTokenResolver.Add(_outOfBandPrimaryTokenCollection[i], SecurityTokenReferenceStyle.External, _primaryTokenParameters); } } if (_wrappingToken != null) { _universalTokenResolver.ExpectedWrapper = _wrappingToken; _universalTokenResolver.ExpectedWrapperTokenParameters = _wrappingTokenParameters; _primaryTokenResolver.ExpectedWrapper = _wrappingToken; _primaryTokenResolver.ExpectedWrapperTokenParameters = _wrappingTokenParameters; } if (_outOfBandTokenResolver == null) { CombinedUniversalTokenResolver = _universalTokenResolver; _combinedPrimaryTokenResolver = _primaryTokenResolver; } else { CombinedUniversalTokenResolver = new AggregateSecurityHeaderTokenResolver(_universalTokenResolver, _outOfBandTokenResolver); _combinedPrimaryTokenResolver = new AggregateSecurityHeaderTokenResolver(_primaryTokenResolver, _outOfBandTokenResolver); } _allowedAuthenticators = new List <SecurityTokenAuthenticator>(); if (_primaryTokenAuthenticator != null) { _allowedAuthenticators.Add(_primaryTokenAuthenticator); } if (DerivedTokenAuthenticator != null) { _allowedAuthenticators.Add(DerivedTokenAuthenticator); } _pendingSupportingTokenAuthenticator = null; int numSupportingTokensRequiringDerivation = 0; if (_supportingTokenAuthenticators != null && _supportingTokenAuthenticators.Count > 0) { _supportingTokenTrackers = new List <TokenTracker>(_supportingTokenAuthenticators.Count); for (int i = 0; i < _supportingTokenAuthenticators.Count; ++i) { SupportingTokenAuthenticatorSpecification spec = _supportingTokenAuthenticators[i]; switch (spec.SecurityTokenAttachmentMode) { case SecurityTokenAttachmentMode.Endorsing: _hasEndorsingOrSignedEndorsingSupportingTokens = true; break; case SecurityTokenAttachmentMode.Signed: break; case SecurityTokenAttachmentMode.SignedEndorsing: _hasEndorsingOrSignedEndorsingSupportingTokens = true; break; case SecurityTokenAttachmentMode.SignedEncrypted: break; } if ((_primaryTokenAuthenticator != null) && (_primaryTokenAuthenticator.GetType().Equals(spec.TokenAuthenticator.GetType()))) { _pendingSupportingTokenAuthenticator = spec.TokenAuthenticator; } else { _allowedAuthenticators.Add(spec.TokenAuthenticator); } if (spec.TokenParameters.RequireDerivedKeys && !spec.TokenParameters.HasAsymmetricKey && (spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.Endorsing || spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.SignedEndorsing)) { ++numSupportingTokensRequiringDerivation; } _supportingTokenTrackers.Add(new TokenTracker(spec)); } } if (DerivedTokenAuthenticator != null) { // we expect key derivation. Compute quotas for derived keys int maxKeyDerivationLengthInBits = AlgorithmSuite.DefaultEncryptionKeyDerivationLength >= AlgorithmSuite.DefaultSignatureKeyDerivationLength ? AlgorithmSuite.DefaultEncryptionKeyDerivationLength : AlgorithmSuite.DefaultSignatureKeyDerivationLength; MaxDerivedKeyLength = maxKeyDerivationLengthInBits / 8; // the upper bound of derived keys is (1 for primary signature + 1 for encryption + supporting token signatures requiring derivation)*2 // the multiplication by 2 is to take care of interop scenarios that may arise that require more derived keys than the lower bound. _maxDerivedKeys = (1 + 1 + numSupportingTokensRequiringDerivation) * 2; } SecurityHeaderElementInferenceEngine engine = SecurityHeaderElementInferenceEngine.GetInferenceEngine(Layout); engine.ExecuteProcessingPasses(this, reader); if (RequireMessageProtection) { throw ExceptionHelper.PlatformNotSupported(); } EnsureDecryptionComplete(); _signatureTracker.SetDerivationSourceIfRequired(); _encryptionTracker.SetDerivationSourceIfRequired(); if (EncryptionToken != null) { throw ExceptionHelper.PlatformNotSupported(); } // ensure that the primary signature was signed with derived keys if required if (EnforceDerivedKeyRequirement) { if (SignatureToken != null) { if (_primaryTokenParameters != null) { if (_primaryTokenParameters.RequireDerivedKeys && !_primaryTokenParameters.HasAsymmetricKey && !_primaryTokenTracker.IsDerivedFrom) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.Format(SR.PrimarySignatureWasNotSignedByDerivedKey, _primaryTokenParameters))); } } else if (_wrappingTokenParameters != null && _wrappingTokenParameters.RequireDerivedKeys) { if (!_signatureTracker.IsDerivedToken) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.Format(SR.PrimarySignatureWasNotSignedByDerivedWrappedKey, _wrappingTokenParameters))); } } } // verify that the encryption is using key derivation if (EncryptionToken != null) { throw ExceptionHelper.PlatformNotSupported(); } } if (wasProtectionOrderDowngraded && (BasicSupportingTokens != null) && (BasicSupportingTokens.Count > 0)) { throw ExceptionHelper.PlatformNotSupported(); } // verify all supporting token parameters have their requirements met if (_supportingTokenTrackers != null && _supportingTokenTrackers.Count > 0) { throw ExceptionHelper.PlatformNotSupported(); } if (_replayDetectionEnabled) { throw ExceptionHelper.PlatformNotSupported(); } if (ExpectSignatureConfirmation) { throw ExceptionHelper.PlatformNotSupported(); } MarkHeaderAsUnderstood(); }
/// <summary>Initializes a new instance of the <see cref="T:System.ServiceModel.Channels.SymmetricSecurityBindingElement" /> class using specified security token parameters. </summary> /// <param name="protectionTokenParameters">The <see cref="T:System.ServiceModel.Security.Tokens.SecurityTokenParameters" />.</param> public SymmetricSecurityBindingElement(SecurityTokenParameters protectionTokenParameters) { this.messageProtectionOrder = MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature; this.requireSignatureConfirmation = false; this.protectionTokenParameters = protectionTokenParameters; }
public void SetRequiredProtectionOrder(MessageProtectionOrder protectionOrder) { _protectionOrder = protectionOrder; _enforce = true; }
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; string messageId = "uuid-" + Guid.NewGuid(); int identForMessageId = 1; XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; // 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 = 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) { 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); }
internal static bool IsDefined(MessageProtectionOrder value) { return value == MessageProtectionOrder.SignBeforeEncrypt || value == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature || value == MessageProtectionOrder.EncryptBeforeSign; }
public virtual XmlElement CreateWsspEncryptBeforeSigningAssertion(MessageProtectionOrder protectionOrder) { if (protectionOrder == MessageProtectionOrder.EncryptBeforeSign) { return CreateWsspAssertion(EncryptBeforeSigningName); } else { return null; } }
public virtual XmlElement CreateWsspEncryptBeforeSigningAssertion(MessageProtectionOrder protectionOrder) { if (protectionOrder == MessageProtectionOrder.EncryptBeforeSign) { return this.CreateWsspAssertion("EncryptBeforeSigning"); } return null; }
public virtual bool TryImportMessageProtectionOrderAssertions(ICollection<XmlElement> assertions, out MessageProtectionOrder order) { if (TryImportWsspAssertion(assertions, EncryptBeforeSigningName)) { order = MessageProtectionOrder.EncryptBeforeSign; } else if (TryImportWsspAssertion(assertions, EncryptSignatureName)) { order = MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature; } else { order = MessageProtectionOrder.SignBeforeEncrypt; } return true; }
public static void AssertAsymmetricSecurityBindingElement ( SecurityAlgorithmSuite algorithm, bool includeTimestamp, SecurityKeyEntropyMode keyEntropyMode, MessageProtectionOrder messageProtectionOrder, MessageSecurityVersion messageSecurityVersion, bool requireSignatureConfirmation, SecurityHeaderLayout securityHeaderLayout, // EndpointSupportingTokenParameters int endorsing, int signed, int signedEncrypted, int signedEndorsing, // InitiatorTokenParameters bool hasInitiatorTokenParameters, SecurityTokenInclusionMode initiatorTokenInclusionMode, SecurityTokenReferenceStyle initiatorTokenReferenceStyle, bool initiatorTokenRequireDerivedKeys, // RecipientTokenParameters bool hasRecipientTokenParameters, SecurityTokenInclusionMode recipientTokenInclusionMode, SecurityTokenReferenceStyle recipientTokenReferenceStyle, bool recipientTokenRequireDerivedKeys, // LocalClientSettings bool cacheCookies, int renewalThresholdPercentage, bool detectReplays, AsymmetricSecurityBindingElement be, string label) { AssertSecurityBindingElement ( algorithm, includeTimestamp, keyEntropyMode, messageSecurityVersion, securityHeaderLayout, // EndpointSupportingTokenParameters endorsing, signed, signedEncrypted, signedEndorsing, // LocalClientSettings cacheCookies, renewalThresholdPercentage, detectReplays, be, label); Assert.AreEqual (messageProtectionOrder, be.MessageProtectionOrder, label + ".MessageProtectionOrder"); Assert.AreEqual (requireSignatureConfirmation, be.RequireSignatureConfirmation, label + ".RequireSignatureConfirmation"); if (!hasInitiatorTokenParameters) Assert.IsNull (be.InitiatorTokenParameters, label + ".InitiatorTokenParameters (null)"); else AssertSecurityTokenParameters ( initiatorTokenInclusionMode, initiatorTokenReferenceStyle, initiatorTokenRequireDerivedKeys, be.InitiatorTokenParameters, label + ".InitiatorTokenParameters"); if (!hasRecipientTokenParameters) Assert.IsNull (be.RecipientTokenParameters, label + ".RecipientTokenParameters (null)"); else AssertSecurityTokenParameters ( recipientTokenInclusionMode, recipientTokenReferenceStyle, recipientTokenRequireDerivedKeys, be.RecipientTokenParameters, label + ".RecipientTokenParameters"); }