protected override DecryptedHeader DecryptHeader(XmlDictionaryReader reader, WrappedKeySecurityToken wrappedKeyToken)
 {
     SecurityToken token;
     EncryptedHeaderXml xml = new EncryptedHeaderXml(base.Version) {
         SecurityTokenSerializer = base.StandardsManager.SecurityTokenSerializer
     };
     xml.ReadFrom(reader, base.MaxReceivedMessageSize);
     if (xml.MustUnderstand != this.MustUnderstand)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("EncryptedHeaderAttributeMismatch", new object[] { XD.MessageDictionary.MustUnderstand.Value, xml.MustUnderstand, this.MustUnderstand })));
     }
     if (xml.Relay != this.Relay)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("EncryptedHeaderAttributeMismatch", new object[] { XD.Message12Dictionary.Relay.Value, xml.Relay, this.Relay })));
     }
     if (xml.Actor != this.Actor)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("EncryptedHeaderAttributeMismatch", new object[] { base.Version.Envelope.DictionaryActor, xml.Actor, this.Actor })));
     }
     if (wrappedKeyToken == null)
     {
         token = WSSecurityOneDotZeroReceiveSecurityHeader.ResolveKeyIdentifier(xml.KeyIdentifier, base.CombinedPrimaryTokenResolver, false);
     }
     else
     {
         token = wrappedKeyToken;
     }
     base.RecordEncryptionToken(token);
     using (SymmetricAlgorithm algorithm = WSSecurityOneDotZeroReceiveSecurityHeader.CreateDecryptionAlgorithm(token, xml.EncryptionMethod, base.AlgorithmSuite))
     {
         xml.SetUpDecryption(algorithm);
         return new DecryptedHeader(xml.GetDecryptedBuffer(), base.SecurityVerifiedMessage.GetEnvelopeAttributes(), base.SecurityVerifiedMessage.GetHeaderAttributes(), base.Version, base.StandardsManager.IdManager, base.ReaderQuotas);
     }
 }
 protected override byte[] DecryptSecurityHeaderElement(EncryptedData encryptedData, WrappedKeySecurityToken wrappedKeyToken, out SecurityToken encryptionToken)
 {
     if ((encryptedData.KeyIdentifier != null) || (wrappedKeyToken == null))
     {
         encryptionToken = ResolveKeyIdentifier(encryptedData.KeyIdentifier, base.CombinedPrimaryTokenResolver, false);
         if ((((wrappedKeyToken != null) && (wrappedKeyToken.ReferenceList != null)) && (encryptedData.HasId && wrappedKeyToken.ReferenceList.ContainsReferredId(encryptedData.Id))) && (wrappedKeyToken != encryptionToken))
         {
             throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("EncryptedKeyWasNotEncryptedWithTheRequiredEncryptingToken", new object[] { wrappedKeyToken })));
         }
     }
     else
     {
         encryptionToken = wrappedKeyToken;
     }
     using (SymmetricAlgorithm algorithm = CreateDecryptionAlgorithm(encryptionToken, encryptedData.EncryptionMethod, base.AlgorithmSuite))
     {
         encryptedData.SetUpDecryption(algorithm);
         return encryptedData.GetDecryptedBuffer();
     }
 }
        protected override DecryptedHeader DecryptHeader(XmlDictionaryReader reader, WrappedKeySecurityToken wrappedKeyToken)
        {
            // If it is the client, then we may need to read the GenericXmlSecurityKeyIdentoifoer clause while reading EncryptedData. 
            EncryptedHeaderXml headerXml = new EncryptedHeaderXml(this.Version, this.MessageDirection == MessageDirection.Output);
            headerXml.SecurityTokenSerializer = this.StandardsManager.SecurityTokenSerializer;
            headerXml.ReadFrom(reader, MaxReceivedMessageSize);

            // The Encrypted Headers MustUnderstand, Relay and Actor attributes should match the
            // Security Headers value.
            if (headerXml.MustUnderstand != this.MustUnderstand)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.EncryptedHeaderAttributeMismatch, XD.MessageDictionary.MustUnderstand.Value, headerXml.MustUnderstand, this.MustUnderstand)));

            if (headerXml.Relay != this.Relay)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.EncryptedHeaderAttributeMismatch, XD.Message12Dictionary.Relay.Value, headerXml.Relay, this.Relay)));

            if (headerXml.Actor != this.Actor)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.EncryptedHeaderAttributeMismatch, this.Version.Envelope.DictionaryActor, headerXml.Actor, this.Actor)));
            
            SecurityToken token;
            if (wrappedKeyToken == null)
            {
                token = ResolveKeyIdentifier(headerXml.KeyIdentifier, this.CombinedPrimaryTokenResolver, false);
            }
            else
            {
                token = wrappedKeyToken;
            }
            RecordEncryptionToken(token);
            using (SymmetricAlgorithm algorithm = CreateDecryptionAlgorithm(token, headerXml.EncryptionMethod, this.AlgorithmSuite))
            {
                headerXml.SetUpDecryption(algorithm);
                return new DecryptedHeader(
                    headerXml.GetDecryptedBuffer(),
                    this.SecurityVerifiedMessage.GetEnvelopeAttributes(), this.SecurityVerifiedMessage.GetHeaderAttributes(),
                    this.Version, this.StandardsManager.IdManager, this.ReaderQuotas);
            }
        }
        protected virtual void IssueServiceToken(SspiNegotiationTokenAuthenticatorState sspiState, ReadOnlyCollection <IAuthorizationPolicy> authorizationPolicies, out SecurityContextSecurityToken serviceToken, out WrappedKeySecurityToken proofToken, out int issuedKeySize)
        {
            UniqueId contextId = System.ServiceModel.Security.SecurityUtils.GenerateUniqueId();
            string   id        = System.ServiceModel.Security.SecurityUtils.GenerateId();

            if (sspiState.RequestedKeySize == 0)
            {
                issuedKeySize = base.SecurityAlgorithmSuite.DefaultSymmetricKeyLength;
            }
            else
            {
                issuedKeySize = sspiState.RequestedKeySize;
            }
            byte[] buffer = new byte[issuedKeySize / 8];
            System.ServiceModel.Security.CryptoHelper.FillRandomBytes(buffer);
            DateTime utcNow = DateTime.UtcNow;
            DateTime tokenExpirationTime = TimeoutHelper.Add(utcNow, base.ServiceTokenLifetime);

            serviceToken = base.IssueSecurityContextToken(contextId, id, buffer, utcNow, tokenExpirationTime, authorizationPolicies, base.EncryptStateInServiceToken);
            proofToken   = new WrappedKeySecurityToken(string.Empty, buffer, sspiState.SspiNegotiation);
        }
Beispiel #5
0
 protected override byte[] DecryptSecurityHeaderElement(EncryptedData encryptedData, WrappedKeySecurityToken wrappedKeyToken, out SecurityToken encryptionToken)
 {
     throw new PlatformNotSupportedException();
 }
 protected override void ExecuteMessageProtectionPass(bool hasAtLeastOneSupportingTokenExpectedToBeSigned)
 {
     bool flag8;
     bool flag9;
     SignatureTargetIdManager idManager = base.StandardsManager.IdManager;
     MessagePartSpecification specification = base.RequiredEncryptionParts ?? MessagePartSpecification.NoParts;
     MessagePartSpecification signatureParts = base.RequiredSignatureParts ?? MessagePartSpecification.NoParts;
     bool checkForTokensAtHeaders = hasAtLeastOneSupportingTokenExpectedToBeSigned;
     bool doSoapAttributeChecks = !signatureParts.IsBodyIncluded;
     bool encryptBeforeSignMode = base.EncryptBeforeSignMode;
     SignedInfo signedInfo = (this.pendingSignature != null) ? this.pendingSignature.Signature.SignedInfo : null;
     SignatureConfirmations sentSignatureConfirmations = base.GetSentSignatureConfirmations();
     if (((sentSignatureConfirmations != null) && (sentSignatureConfirmations.Count > 0)) && sentSignatureConfirmations.IsMarkedForEncryption)
     {
         base.VerifySignatureEncryption();
     }
     MessageHeaders headers = base.SecurityVerifiedMessage.Headers;
     XmlDictionaryReader readerAtFirstHeader = base.SecurityVerifiedMessage.GetReaderAtFirstHeader();
     bool atLeastOneHeaderOrBodyEncrypted = false;
     for (int i = 0; i < headers.Count; i++)
     {
         if (readerAtFirstHeader.NodeType != XmlNodeType.Element)
         {
             readerAtFirstHeader.MoveToContent();
         }
         if (i == base.HeaderIndex)
         {
             readerAtFirstHeader.Skip();
         }
         else
         {
             bool flag6;
             bool flag5 = false;
             string str = idManager.ExtractId(readerAtFirstHeader);
             if (str != null)
             {
                 flag5 = this.TryDeleteReferenceListEntry(str);
             }
             if (!flag5 && readerAtFirstHeader.IsStartElement("EncryptedHeader", "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"))
             {
                 XmlDictionaryReader readerAtHeader = headers.GetReaderAtHeader(i);
                 readerAtHeader.ReadStartElement("EncryptedHeader", "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd");
                 if (readerAtHeader.IsStartElement(EncryptedData.ElementName, System.ServiceModel.XD.XmlEncryptionDictionary.Namespace))
                 {
                     string attribute = readerAtHeader.GetAttribute(System.ServiceModel.XD.XmlEncryptionDictionary.Id, null);
                     if ((attribute != null) && this.TryDeleteReferenceListEntry(attribute))
                     {
                         flag5 = true;
                     }
                 }
             }
             base.ElementManager.VerifyUniquenessAndSetHeaderId(str, i);
             MessageHeaderInfo info = headers[i];
             if (!flag5 && specification.IsHeaderIncluded(info.Name, info.Namespace))
             {
                 base.SecurityVerifiedMessage.OnUnencryptedPart(info.Name, info.Namespace);
             }
             if ((!flag5 || encryptBeforeSignMode) && (str != null))
             {
                 flag6 = this.EnsureDigestValidityIfIdMatches(signedInfo, str, readerAtFirstHeader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
             }
             else
             {
                 flag6 = false;
             }
             if (flag5)
             {
                 XmlDictionaryReader reader = flag6 ? headers.GetReaderAtHeader(i) : readerAtFirstHeader;
                 DecryptedHeader header = this.DecryptHeader(reader, this.pendingDecryptionToken);
                 info = header;
                 str = header.Id;
                 base.ElementManager.VerifyUniquenessAndSetDecryptedHeaderId(str, i);
                 headers.ReplaceAt(i, header);
                 if (!object.ReferenceEquals(reader, readerAtFirstHeader))
                 {
                     reader.Close();
                 }
                 if (!encryptBeforeSignMode && (str != null))
                 {
                     XmlDictionaryReader headerReader = header.GetHeaderReader();
                     flag6 = this.EnsureDigestValidityIfIdMatches(signedInfo, str, headerReader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
                     headerReader.Close();
                 }
             }
             if (!flag6 && signatureParts.IsHeaderIncluded(info.Name, info.Namespace))
             {
                 base.SecurityVerifiedMessage.OnUnsignedPart(info.Name, info.Namespace);
             }
             if (flag6 && flag5)
             {
                 base.VerifySignatureEncryption();
             }
             if (flag5 && !flag6)
             {
                 throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("EncryptedHeaderNotSigned", new object[] { info.Name, info.Namespace })));
             }
             if (!flag6 && !flag5)
             {
                 readerAtFirstHeader.Skip();
             }
             atLeastOneHeaderOrBodyEncrypted |= flag5;
         }
     }
     readerAtFirstHeader.ReadEndElement();
     if (readerAtFirstHeader.NodeType != XmlNodeType.Element)
     {
         readerAtFirstHeader.MoveToContent();
     }
     string id = idManager.ExtractId(readerAtFirstHeader);
     base.ElementManager.VerifyUniquenessAndSetBodyId(id);
     base.SecurityVerifiedMessage.SetBodyPrefixAndAttributes(readerAtFirstHeader);
     bool flag7 = specification.IsBodyIncluded || this.HasPendingDecryptionItem();
     if ((!flag7 || encryptBeforeSignMode) && (id != null))
     {
         flag8 = this.EnsureDigestValidityIfIdMatches(signedInfo, id, readerAtFirstHeader, false, null, null, false);
     }
     else
     {
         flag8 = false;
     }
     if (flag7)
     {
         XmlDictionaryReader reader5 = flag8 ? base.SecurityVerifiedMessage.CreateFullBodyReader() : readerAtFirstHeader;
         reader5.ReadStartElement();
         string str4 = idManager.ExtractId(reader5);
         base.ElementManager.VerifyUniquenessAndSetBodyContentId(str4);
         flag9 = (str4 != null) && this.TryDeleteReferenceListEntry(str4);
         if (flag9)
         {
             this.DecryptBody(reader5, this.pendingDecryptionToken);
         }
         if (!object.ReferenceEquals(reader5, readerAtFirstHeader))
         {
             reader5.Close();
         }
         if ((!encryptBeforeSignMode && (signedInfo != null)) && signedInfo.HasUnverifiedReference(id))
         {
             reader5 = base.SecurityVerifiedMessage.CreateFullBodyReader();
             flag8 = this.EnsureDigestValidityIfIdMatches(signedInfo, id, reader5, false, null, null, false);
             reader5.Close();
         }
     }
     else
     {
         flag9 = false;
     }
     if (flag8 && flag9)
     {
         base.VerifySignatureEncryption();
     }
     readerAtFirstHeader.Close();
     if (this.pendingSignature != null)
     {
         this.pendingSignature.CompleteSignatureVerification();
         this.pendingSignature = null;
     }
     this.pendingDecryptionToken = null;
     atLeastOneHeaderOrBodyEncrypted |= flag9;
     if (!flag8 && signatureParts.IsBodyIncluded)
     {
         base.SecurityVerifiedMessage.OnUnsignedPart(System.ServiceModel.XD.MessageDictionary.Body.Value, base.Version.Envelope.Namespace);
     }
     if (!flag9 && specification.IsBodyIncluded)
     {
         base.SecurityVerifiedMessage.OnUnencryptedPart(System.ServiceModel.XD.MessageDictionary.Body.Value, base.Version.Envelope.Namespace);
     }
     base.SecurityVerifiedMessage.OnMessageProtectionPassComplete(atLeastOneHeaderOrBodyEncrypted);
 }
        protected override void ExecuteMessageProtectionPass(bool hasAtLeastOneSupportingTokenExpectedToBeSigned)
        {
            bool flag8;
            bool flag9;
            SignatureTargetIdManager idManager             = base.StandardsManager.IdManager;
            MessagePartSpecification specification         = base.RequiredEncryptionParts ?? MessagePartSpecification.NoParts;
            MessagePartSpecification signatureParts        = base.RequiredSignatureParts ?? MessagePartSpecification.NoParts;
            bool                   checkForTokensAtHeaders = hasAtLeastOneSupportingTokenExpectedToBeSigned;
            bool                   doSoapAttributeChecks   = !signatureParts.IsBodyIncluded;
            bool                   encryptBeforeSignMode   = base.EncryptBeforeSignMode;
            SignedInfo             signedInfo = (this.pendingSignature != null) ? this.pendingSignature.Signature.SignedInfo : null;
            SignatureConfirmations sentSignatureConfirmations = base.GetSentSignatureConfirmations();

            if (((sentSignatureConfirmations != null) && (sentSignatureConfirmations.Count > 0)) && sentSignatureConfirmations.IsMarkedForEncryption)
            {
                base.VerifySignatureEncryption();
            }
            MessageHeaders      headers             = base.SecurityVerifiedMessage.Headers;
            XmlDictionaryReader readerAtFirstHeader = base.SecurityVerifiedMessage.GetReaderAtFirstHeader();
            bool atLeastOneHeaderOrBodyEncrypted    = false;

            for (int i = 0; i < headers.Count; i++)
            {
                if (readerAtFirstHeader.NodeType != XmlNodeType.Element)
                {
                    readerAtFirstHeader.MoveToContent();
                }
                if (i == base.HeaderIndex)
                {
                    readerAtFirstHeader.Skip();
                }
                else
                {
                    bool   flag6;
                    bool   flag5 = false;
                    string str   = idManager.ExtractId(readerAtFirstHeader);
                    if (str != null)
                    {
                        flag5 = this.TryDeleteReferenceListEntry(str);
                    }
                    if (!flag5 && readerAtFirstHeader.IsStartElement("EncryptedHeader", "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"))
                    {
                        XmlDictionaryReader readerAtHeader = headers.GetReaderAtHeader(i);
                        readerAtHeader.ReadStartElement("EncryptedHeader", "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd");
                        if (readerAtHeader.IsStartElement(EncryptedData.ElementName, System.ServiceModel.XD.XmlEncryptionDictionary.Namespace))
                        {
                            string attribute = readerAtHeader.GetAttribute(System.ServiceModel.XD.XmlEncryptionDictionary.Id, null);
                            if ((attribute != null) && this.TryDeleteReferenceListEntry(attribute))
                            {
                                flag5 = true;
                            }
                        }
                    }
                    base.ElementManager.VerifyUniquenessAndSetHeaderId(str, i);
                    MessageHeaderInfo info = headers[i];
                    if (!flag5 && specification.IsHeaderIncluded(info.Name, info.Namespace))
                    {
                        base.SecurityVerifiedMessage.OnUnencryptedPart(info.Name, info.Namespace);
                    }
                    if ((!flag5 || encryptBeforeSignMode) && (str != null))
                    {
                        flag6 = this.EnsureDigestValidityIfIdMatches(signedInfo, str, readerAtFirstHeader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
                    }
                    else
                    {
                        flag6 = false;
                    }
                    if (flag5)
                    {
                        XmlDictionaryReader reader = flag6 ? headers.GetReaderAtHeader(i) : readerAtFirstHeader;
                        DecryptedHeader     header = this.DecryptHeader(reader, this.pendingDecryptionToken);
                        info = header;
                        str  = header.Id;
                        base.ElementManager.VerifyUniquenessAndSetDecryptedHeaderId(str, i);
                        headers.ReplaceAt(i, header);
                        if (!object.ReferenceEquals(reader, readerAtFirstHeader))
                        {
                            reader.Close();
                        }
                        if (!encryptBeforeSignMode && (str != null))
                        {
                            XmlDictionaryReader headerReader = header.GetHeaderReader();
                            flag6 = this.EnsureDigestValidityIfIdMatches(signedInfo, str, headerReader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
                            headerReader.Close();
                        }
                    }
                    if (!flag6 && signatureParts.IsHeaderIncluded(info.Name, info.Namespace))
                    {
                        base.SecurityVerifiedMessage.OnUnsignedPart(info.Name, info.Namespace);
                    }
                    if (flag6 && flag5)
                    {
                        base.VerifySignatureEncryption();
                    }
                    if (flag5 && !flag6)
                    {
                        throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("EncryptedHeaderNotSigned", new object[] { info.Name, info.Namespace })));
                    }
                    if (!flag6 && !flag5)
                    {
                        readerAtFirstHeader.Skip();
                    }
                    atLeastOneHeaderOrBodyEncrypted |= flag5;
                }
            }
            readerAtFirstHeader.ReadEndElement();
            if (readerAtFirstHeader.NodeType != XmlNodeType.Element)
            {
                readerAtFirstHeader.MoveToContent();
            }
            string id = idManager.ExtractId(readerAtFirstHeader);

            base.ElementManager.VerifyUniquenessAndSetBodyId(id);
            base.SecurityVerifiedMessage.SetBodyPrefixAndAttributes(readerAtFirstHeader);
            bool flag7 = specification.IsBodyIncluded || this.HasPendingDecryptionItem();

            if ((!flag7 || encryptBeforeSignMode) && (id != null))
            {
                flag8 = this.EnsureDigestValidityIfIdMatches(signedInfo, id, readerAtFirstHeader, false, null, null, false);
            }
            else
            {
                flag8 = false;
            }
            if (flag7)
            {
                XmlDictionaryReader reader5 = flag8 ? base.SecurityVerifiedMessage.CreateFullBodyReader() : readerAtFirstHeader;
                reader5.ReadStartElement();
                string str4 = idManager.ExtractId(reader5);
                base.ElementManager.VerifyUniquenessAndSetBodyContentId(str4);
                flag9 = (str4 != null) && this.TryDeleteReferenceListEntry(str4);
                if (flag9)
                {
                    this.DecryptBody(reader5, this.pendingDecryptionToken);
                }
                if (!object.ReferenceEquals(reader5, readerAtFirstHeader))
                {
                    reader5.Close();
                }
                if ((!encryptBeforeSignMode && (signedInfo != null)) && signedInfo.HasUnverifiedReference(id))
                {
                    reader5 = base.SecurityVerifiedMessage.CreateFullBodyReader();
                    flag8   = this.EnsureDigestValidityIfIdMatches(signedInfo, id, reader5, false, null, null, false);
                    reader5.Close();
                }
            }
            else
            {
                flag9 = false;
            }
            if (flag8 && flag9)
            {
                base.VerifySignatureEncryption();
            }
            readerAtFirstHeader.Close();
            if (this.pendingSignature != null)
            {
                this.pendingSignature.CompleteSignatureVerification();
                this.pendingSignature = null;
            }
            this.pendingDecryptionToken      = null;
            atLeastOneHeaderOrBodyEncrypted |= flag9;
            if (!flag8 && signatureParts.IsBodyIncluded)
            {
                base.SecurityVerifiedMessage.OnUnsignedPart(System.ServiceModel.XD.MessageDictionary.Body.Value, base.Version.Envelope.Namespace);
            }
            if (!flag9 && specification.IsBodyIncluded)
            {
                base.SecurityVerifiedMessage.OnUnencryptedPart(System.ServiceModel.XD.MessageDictionary.Body.Value, base.Version.Envelope.Namespace);
            }
            base.SecurityVerifiedMessage.OnMessageProtectionPassComplete(atLeastOneHeaderOrBodyEncrypted);
        }
 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);
     }
 }
        protected override void ExecuteMessageProtectionPass(bool hasAtLeastOneSupportingTokenExpectedToBeSigned)
        {
            SignatureTargetIdManager idManager = this.StandardsManager.IdManager;
            MessagePartSpecification encryptionParts = this.RequiredEncryptionParts ?? MessagePartSpecification.NoParts;
            MessagePartSpecification signatureParts = this.RequiredSignatureParts ?? MessagePartSpecification.NoParts;

            bool checkForTokensAtHeaders = hasAtLeastOneSupportingTokenExpectedToBeSigned;
            bool doSoapAttributeChecks = !signatureParts.IsBodyIncluded;
            bool encryptBeforeSign = this.EncryptBeforeSignMode;
            SignedInfo signedInfo = this.pendingSignature != null ? this.pendingSignature.Signature.SignedInfo : null;

            SignatureConfirmations signatureConfirmations = this.GetSentSignatureConfirmations();
            if (signatureConfirmations != null && signatureConfirmations.Count > 0 && signatureConfirmations.IsMarkedForEncryption)
            {
                // If Signature Confirmations are encrypted then the signature should
                // be encrypted as well.
                this.VerifySignatureEncryption();
            }

            MessageHeaders headers = this.SecurityVerifiedMessage.Headers;
            XmlDictionaryReader reader = this.SecurityVerifiedMessage.GetReaderAtFirstHeader();

            bool atLeastOneHeaderOrBodyEncrypted = false;

            for (int i = 0; i < headers.Count; i++)
            {
                if (reader.NodeType != XmlNodeType.Element)
                {
                    reader.MoveToContent();
                }

                if (i == this.HeaderIndex)
                {
                    reader.Skip();
                    continue;
                }

                bool isHeaderEncrypted = false;

                string id = idManager.ExtractId(reader);

                if (id != null)
                {
                    isHeaderEncrypted = TryDeleteReferenceListEntry(id);
                }

                if (!isHeaderEncrypted && reader.IsStartElement(SecurityXXX2005Strings.EncryptedHeader, SecurityXXX2005Strings.Namespace))
                {                    
                    XmlDictionaryReader localreader = headers.GetReaderAtHeader(i);
                    localreader.ReadStartElement(SecurityXXX2005Strings.EncryptedHeader, SecurityXXX2005Strings.Namespace);

                    if (localreader.IsStartElement(EncryptedData.ElementName, XD.XmlEncryptionDictionary.Namespace))
                    {
                        string encryptedDataId = localreader.GetAttribute(XD.XmlEncryptionDictionary.Id, null);

                        if (encryptedDataId != null && TryDeleteReferenceListEntry(encryptedDataId))
                        {
                            isHeaderEncrypted = true;
                        }
                    }                   
                }

                this.ElementManager.VerifyUniquenessAndSetHeaderId(id, i);

                MessageHeaderInfo info = headers[i];

                if (!isHeaderEncrypted && encryptionParts.IsHeaderIncluded(info.Name, info.Namespace))
                {
                    this.SecurityVerifiedMessage.OnUnencryptedPart(info.Name, info.Namespace);
                }

                bool headerSigned;
                if ((!isHeaderEncrypted || encryptBeforeSign) && id != null)
                {
                    headerSigned = EnsureDigestValidityIfIdMatches(signedInfo, id, reader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
                }
                else
                {
                    headerSigned = false;
                }

                if (isHeaderEncrypted)
                {
                    XmlDictionaryReader decryptionReader = headerSigned ? headers.GetReaderAtHeader(i) : reader;
                    DecryptedHeader decryptedHeader = DecryptHeader(decryptionReader, this.pendingDecryptionToken);
                    info = decryptedHeader;
                    id = decryptedHeader.Id;
                    this.ElementManager.VerifyUniquenessAndSetDecryptedHeaderId(id, i);
                    headers.ReplaceAt(i, decryptedHeader);
                    if (!ReferenceEquals(decryptionReader, reader))
                    {
                        decryptionReader.Close();
                    }

                    if (!encryptBeforeSign && id != null)
                    {
                        XmlDictionaryReader decryptedHeaderReader = decryptedHeader.GetHeaderReader();
                        headerSigned = EnsureDigestValidityIfIdMatches(signedInfo, id, decryptedHeaderReader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
                        decryptedHeaderReader.Close();
                    }
                }

                if (!headerSigned && signatureParts.IsHeaderIncluded(info.Name, info.Namespace))
                {
                    this.SecurityVerifiedMessage.OnUnsignedPart(info.Name, info.Namespace);
                }

                if (headerSigned && isHeaderEncrypted)
                {
                    // We have a header that is signed and encrypted. So the accompanying primary signature
                    // should be encrypted as well.
                    this.VerifySignatureEncryption();
                }

                if (isHeaderEncrypted && !headerSigned)
                {
                    // We require all encrypted headers (outside the security header) to be signed.
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.EncryptedHeaderNotSigned, info.Name, info.Namespace)));
                }

                if (!headerSigned && !isHeaderEncrypted)
                {
                    reader.Skip();
                }

                atLeastOneHeaderOrBodyEncrypted |= isHeaderEncrypted;
            }

            reader.ReadEndElement();

            if (reader.NodeType != XmlNodeType.Element)
            {
                reader.MoveToContent();
            }

            string bodyId = idManager.ExtractId(reader);
            this.ElementManager.VerifyUniquenessAndSetBodyId(bodyId);
            this.SecurityVerifiedMessage.SetBodyPrefixAndAttributes(reader);

            bool expectBodyEncryption = encryptionParts.IsBodyIncluded || HasPendingDecryptionItem();

            bool bodySigned;
            if ((!expectBodyEncryption || encryptBeforeSign) && bodyId != null)
            {
                bodySigned = EnsureDigestValidityIfIdMatches(signedInfo, bodyId, reader, false, null, null, false);
            }
            else
            {
                bodySigned = false;
            }

            bool bodyEncrypted;
            if (expectBodyEncryption)
            {
                XmlDictionaryReader bodyReader = bodySigned ? this.SecurityVerifiedMessage.CreateFullBodyReader() : reader;
                bodyReader.ReadStartElement();
                string bodyContentId = idManager.ExtractId(bodyReader);
                this.ElementManager.VerifyUniquenessAndSetBodyContentId(bodyContentId);
                bodyEncrypted = bodyContentId != null && TryDeleteReferenceListEntry(bodyContentId);
                if (bodyEncrypted)
                {
                    DecryptBody(bodyReader, this.pendingDecryptionToken);
                }
                if (!ReferenceEquals(bodyReader, reader))
                {
                    bodyReader.Close();
                }
                if (!encryptBeforeSign && signedInfo != null && signedInfo.HasUnverifiedReference(bodyId))
                {
                    bodyReader = this.SecurityVerifiedMessage.CreateFullBodyReader();
                    bodySigned = EnsureDigestValidityIfIdMatches(signedInfo, bodyId, bodyReader, false, null, null, false);
                    bodyReader.Close();
                }
            }
            else
            {
                bodyEncrypted = false;
            }

            if (bodySigned && bodyEncrypted)
            {
                this.VerifySignatureEncryption();
            }

            reader.Close();

            if (this.pendingSignature != null)
            {
                this.pendingSignature.CompleteSignatureVerification();
                this.pendingSignature = null;
            }
            this.pendingDecryptionToken = null;
            atLeastOneHeaderOrBodyEncrypted |= bodyEncrypted;

            if (!bodySigned && signatureParts.IsBodyIncluded)
            {
                this.SecurityVerifiedMessage.OnUnsignedPart(XD.MessageDictionary.Body.Value, this.Version.Envelope.Namespace);
            }

            if (!bodyEncrypted && encryptionParts.IsBodyIncluded)
            {
                this.SecurityVerifiedMessage.OnUnencryptedPart(XD.MessageDictionary.Body.Value, this.Version.Envelope.Namespace);
            }

            this.SecurityVerifiedMessage.OnMessageProtectionPassComplete(atLeastOneHeaderOrBodyEncrypted);
        }
 protected virtual DecryptedHeader DecryptHeader(XmlDictionaryReader reader, WrappedKeySecurityToken wrappedKeyToken)
 {
     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
         new MessageSecurityException(SR.GetString(SR.HeaderDecryptionNotSupportedInWsSecurityJan2004)));
 }
		public void X509WrappingToken1 ()
		{
			byte [] bytes = new byte [32];
			X509SecurityToken xt = new X509SecurityToken (cert);
			SecurityKeyIdentifierClause kic =
				new X509ThumbprintKeyIdentifierClause (cert);
			string alg = SecurityAlgorithms.RsaOaepKeyWrap;
			WrappedKeySecurityToken token = new WrappedKeySecurityToken ("urn:gyabo",
				bytes, alg, xt,
				new SecurityKeyIdentifier (kic));
			Assert.AreEqual ("urn:gyabo", token.Id, "#1");
			Assert.AreEqual (alg, token.WrappingAlgorithm, "#3");
			Assert.AreEqual (xt, token.WrappingToken, "#4");
			Assert.AreEqual (1, token.WrappingTokenReference.Count, "#5");
			Assert.AreEqual (1, token.SecurityKeys.Count, "#6");
			Assert.IsTrue (token.SecurityKeys [0] is InMemorySymmetricSecurityKey, "#7");
			Assert.AreEqual (bytes, new X509AsymmetricSecurityKey (cert).DecryptKey (token.WrappingAlgorithm, token.GetWrappedKey ()), "#8");
			// wrapped keys cannot be compared, due to the nature of rsa-oaep.
			// Assert.AreEqual (new X509AsymmetricSecurityKey (cert).EncryptKey (token.WrappingAlgorithm, bytes), token.GetWrappedKey (), "#9-1");
			// Assert.AreEqual (token.GetWrappedKey (), new WrappedKeySecurityToken ("urn:gyabo",
			//	bytes, alg, xt,
			//	new SecurityKeyIdentifier (kic)).GetWrappedKey (), "#9");
		}
Beispiel #12
0
        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);
        }
        // helpers
        protected virtual void IssueServiceToken(SspiNegotiationTokenAuthenticatorState sspiState, ReadOnlyCollection <IAuthorizationPolicy> authorizationPolicies, out SecurityContextSecurityToken serviceToken, out WrappedKeySecurityToken proofToken,
                                                 out int issuedKeySize)
        {
            UniqueId contextId = SecurityUtils.GenerateUniqueId();
            string   id        = SecurityUtils.GenerateId();

            if (sspiState.RequestedKeySize == 0)
            {
                issuedKeySize = SecurityAlgorithmSuite.DefaultSymmetricKeyLength;
            }
            else
            {
                issuedKeySize = sspiState.RequestedKeySize;
            }
            byte[] key = new byte[issuedKeySize / 8];
            CryptoHelper.FillRandomBytes(key);
            DateTime effectiveTime  = DateTime.UtcNow;
            DateTime expirationTime = TimeoutHelper.Add(effectiveTime, ServiceTokenLifetime);

            serviceToken = IssueSecurityContextToken(contextId, id, key, effectiveTime, expirationTime, authorizationPolicies, EncryptStateInServiceToken);
            proofToken   = new WrappedKeySecurityToken(string.Empty, key, sspiState.SspiNegotiation);
        }
		public void CreateBinarySecretKeyIdentifierClause ()
		{
			byte [] bytes = new byte [32];
			SecurityToken wt = new BinarySecretSecurityToken (bytes);
			SecurityKeyIdentifierClause kic =
				new BinarySecretKeyIdentifierClause (bytes);
			WrappedKeySecurityToken token = new WrappedKeySecurityToken ("urn:gyabo",
				bytes, SecurityAlgorithms.Aes256KeyWrap, wt,
				new SecurityKeyIdentifier (kic));
			token.CreateKeyIdentifierClause<BinarySecretKeyIdentifierClause> ();
		}
		public void ReadWrappedKeySecurityTokenImplCheck ()
		{
			SecurityTokenResolver tokenResolver = GetResolver (new X509SecurityToken (cert));
			XmlReader reader = XmlReader.Create (new StringReader (wrapped_key1));
			WSSecurityTokenSerializer serializer =
				WSSecurityTokenSerializer.DefaultInstance;

			EncryptedKey ek = new EncryptedKey ();
			ek.LoadXml (new XmlDocument ().ReadNode (reader) as XmlElement);
			SecurityKeyIdentifier ki = new SecurityKeyIdentifier ();
			foreach (KeyInfoClause kic in ek.KeyInfo)
				ki.Add (serializer.ReadKeyIdentifierClause (new XmlNodeReader (kic.GetXml ())));
			SecurityToken token = tokenResolver.ResolveToken (ki);
			string alg = ek.EncryptionMethod.KeyAlgorithm;

			SecurityKey skey = token.SecurityKeys [0];
			Assert.IsTrue (skey is X509AsymmetricSecurityKey, "#1");
			Assert.IsTrue (skey.IsSupportedAlgorithm (alg), "#2");
			Assert.AreEqual (
				EncryptedXml.DecryptKey (ek.CipherData.CipherValue, cert.PrivateKey as RSA, true),
				skey.DecryptKey (alg, ek.CipherData.CipherValue),
				"#3");

			byte [] key = skey.DecryptKey (alg, ek.CipherData.CipherValue);
			WrappedKeySecurityToken wk =
				new WrappedKeySecurityToken (ek.Id, key, alg, token, ki);
			Assert.AreEqual (
				EncryptedXml.DecryptKey (ek.CipherData.CipherValue, cert.PrivateKey as RSA, true),
				skey.DecryptKey (alg, wk.GetWrappedKey ()),
				"#4");
		}
		public void WriteWrappedKeySecurityToken ()
		{
			StringWriter sw = new StringWriter ();
			byte [] bytes = new byte [64];
			for (byte i = 1; i < 64; i++)
				bytes [i] = i;

			SecurityToken wt = new X509SecurityToken (cert);
			SecurityKeyIdentifier ski = new SecurityKeyIdentifier (
				wt.CreateKeyIdentifierClause< X509ThumbprintKeyIdentifierClause> ());
			WrappedKeySecurityToken t = new WrappedKeySecurityToken (
				"urn:wrapper-key:1", bytes, SecurityAlgorithms.RsaOaepKeyWrap, wt, ski);

			using (XmlWriter w = XmlWriter.Create (sw, GetWriterSettings ())) {
				WSSecurityTokenSerializer.DefaultInstance.WriteToken (w, t);
			}
			string actual = sw.ToString ();
			int idx = actual.IndexOf ("<e:CipherValue>", StringComparison.Ordinal);
			Assert.IsTrue (idx >= 0, "No <CipherValue>");
			actual = 
				actual.Substring (0, idx) +
				"<e:CipherValue>removed here" +
				actual.Substring (actual.IndexOf ("</e:CipherValue>", StringComparison.Ordinal));
			Assert.AreEqual ("GQ3YHlGQhDF1bvMixHliX4uLjlY=", Convert.ToBase64String (cert.GetCertHash ()), "premise#1");
			Assert.AreEqual (
				String.Format ("<e:EncryptedKey Id=\"urn:wrapper-key:1\" xmlns:e=\"{0}\"><e:EncryptionMethod Algorithm=\"{1}\"><DigestMethod Algorithm=\"{2}\" xmlns=\"{3}\" /></e:EncryptionMethod><KeyInfo xmlns=\"{3}\"><o:SecurityTokenReference xmlns:o=\"{4}\"><o:KeyIdentifier ValueType=\"{5}\">{6}</o:KeyIdentifier></o:SecurityTokenReference></KeyInfo><e:CipherData><e:CipherValue>removed here</e:CipherValue></e:CipherData></e:EncryptedKey>",
					EncryptedXml.XmlEncNamespaceUrl,
					SecurityAlgorithms.RsaOaepKeyWrap,
					SignedXml.XmlDsigSHA1Url,
					SignedXml.XmlDsigNamespaceUrl,
					"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
					"http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1",
					Convert.ToBase64String (cert.GetCertHash ())),// "GQ3YHlGQhDF1bvMixHliX4uLjlY="
				actual);
		}
Beispiel #17
0
        protected override void ExecuteMessageProtectionPass(bool hasAtLeastOneSupportingTokenExpectedToBeSigned)
        {
            SignatureTargetIdManager idManager       = this.StandardsManager.IdManager;
            MessagePartSpecification encryptionParts = this.RequiredEncryptionParts ?? MessagePartSpecification.NoParts;
            MessagePartSpecification signatureParts  = this.RequiredSignatureParts ?? MessagePartSpecification.NoParts;

            bool       checkForTokensAtHeaders = hasAtLeastOneSupportingTokenExpectedToBeSigned;
            bool       doSoapAttributeChecks   = !signatureParts.IsBodyIncluded;
            bool       encryptBeforeSign       = this.EncryptBeforeSignMode;
            SignedInfo signedInfo = this.pendingSignature != null ? this.pendingSignature.Signature.SignedInfo : null;

            SignatureConfirmations signatureConfirmations = this.GetSentSignatureConfirmations();

            if (signatureConfirmations != null && signatureConfirmations.Count > 0 && signatureConfirmations.IsMarkedForEncryption)
            {
                // If Signature Confirmations are encrypted then the signature should
                // be encrypted as well.
                this.VerifySignatureEncryption();
            }

            MessageHeaders      headers = this.SecurityVerifiedMessage.Headers;
            XmlDictionaryReader reader  = this.SecurityVerifiedMessage.GetReaderAtFirstHeader();

            bool atLeastOneHeaderOrBodyEncrypted = false;

            for (int i = 0; i < headers.Count; i++)
            {
                if (reader.NodeType != XmlNodeType.Element)
                {
                    reader.MoveToContent();
                }

                if (i == this.HeaderIndex)
                {
                    reader.Skip();
                    continue;
                }

                bool isHeaderEncrypted = false;

                string id = idManager.ExtractId(reader);

                if (id != null)
                {
                    isHeaderEncrypted = TryDeleteReferenceListEntry(id);
                }

                if (!isHeaderEncrypted && reader.IsStartElement(SecurityXXX2005Strings.EncryptedHeader, SecurityXXX2005Strings.Namespace))
                {
                    XmlDictionaryReader localreader = headers.GetReaderAtHeader(i);
                    localreader.ReadStartElement(SecurityXXX2005Strings.EncryptedHeader, SecurityXXX2005Strings.Namespace);

                    if (localreader.IsStartElement(EncryptedData.ElementName, XD.XmlEncryptionDictionary.Namespace))
                    {
                        string encryptedDataId = localreader.GetAttribute(XD.XmlEncryptionDictionary.Id, null);

                        if (encryptedDataId != null && TryDeleteReferenceListEntry(encryptedDataId))
                        {
                            isHeaderEncrypted = true;
                        }
                    }
                }

                this.ElementManager.VerifyUniquenessAndSetHeaderId(id, i);

                MessageHeaderInfo info = headers[i];

                if (!isHeaderEncrypted && encryptionParts.IsHeaderIncluded(info.Name, info.Namespace))
                {
                    this.SecurityVerifiedMessage.OnUnencryptedPart(info.Name, info.Namespace);
                }

                bool headerSigned;
                if ((!isHeaderEncrypted || encryptBeforeSign) && id != null)
                {
                    headerSigned = EnsureDigestValidityIfIdMatches(signedInfo, id, reader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
                }
                else
                {
                    headerSigned = false;
                }

                if (isHeaderEncrypted)
                {
                    XmlDictionaryReader decryptionReader = headerSigned ? headers.GetReaderAtHeader(i) : reader;
                    DecryptedHeader     decryptedHeader  = DecryptHeader(decryptionReader, this.pendingDecryptionToken);
                    info = decryptedHeader;
                    id   = decryptedHeader.Id;
                    this.ElementManager.VerifyUniquenessAndSetDecryptedHeaderId(id, i);
                    headers.ReplaceAt(i, decryptedHeader);
                    if (!ReferenceEquals(decryptionReader, reader))
                    {
                        decryptionReader.Close();
                    }

                    if (!encryptBeforeSign && id != null)
                    {
                        XmlDictionaryReader decryptedHeaderReader = decryptedHeader.GetHeaderReader();
                        headerSigned = EnsureDigestValidityIfIdMatches(signedInfo, id, decryptedHeaderReader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
                        decryptedHeaderReader.Close();
                    }
                }

                if (!headerSigned && signatureParts.IsHeaderIncluded(info.Name, info.Namespace))
                {
                    this.SecurityVerifiedMessage.OnUnsignedPart(info.Name, info.Namespace);
                }

                if (headerSigned && isHeaderEncrypted)
                {
                    // We have a header that is signed and encrypted. So the accompanying primary signature
                    // should be encrypted as well.
                    this.VerifySignatureEncryption();
                }

                if (isHeaderEncrypted && !headerSigned)
                {
                    // We require all encrypted headers (outside the security header) to be signed.
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.EncryptedHeaderNotSigned, info.Name, info.Namespace)));
                }

                if (!headerSigned && !isHeaderEncrypted)
                {
                    reader.Skip();
                }

                atLeastOneHeaderOrBodyEncrypted |= isHeaderEncrypted;
            }

            reader.ReadEndElement();

            if (reader.NodeType != XmlNodeType.Element)
            {
                reader.MoveToContent();
            }

            string bodyId = idManager.ExtractId(reader);

            this.ElementManager.VerifyUniquenessAndSetBodyId(bodyId);
            this.SecurityVerifiedMessage.SetBodyPrefixAndAttributes(reader);

            bool expectBodyEncryption = encryptionParts.IsBodyIncluded || HasPendingDecryptionItem();

            bool bodySigned;

            if ((!expectBodyEncryption || encryptBeforeSign) && bodyId != null)
            {
                bodySigned = EnsureDigestValidityIfIdMatches(signedInfo, bodyId, reader, false, null, null, false);
            }
            else
            {
                bodySigned = false;
            }

            bool bodyEncrypted;

            if (expectBodyEncryption)
            {
                XmlDictionaryReader bodyReader = bodySigned ? this.SecurityVerifiedMessage.CreateFullBodyReader() : reader;
                bodyReader.ReadStartElement();
                string bodyContentId = idManager.ExtractId(bodyReader);
                this.ElementManager.VerifyUniquenessAndSetBodyContentId(bodyContentId);
                bodyEncrypted = bodyContentId != null && TryDeleteReferenceListEntry(bodyContentId);
                if (bodyEncrypted)
                {
                    DecryptBody(bodyReader, this.pendingDecryptionToken);
                }
                if (!ReferenceEquals(bodyReader, reader))
                {
                    bodyReader.Close();
                }
                if (!encryptBeforeSign && signedInfo != null && signedInfo.HasUnverifiedReference(bodyId))
                {
                    bodyReader = this.SecurityVerifiedMessage.CreateFullBodyReader();
                    bodySigned = EnsureDigestValidityIfIdMatches(signedInfo, bodyId, bodyReader, false, null, null, false);
                    bodyReader.Close();
                }
            }
            else
            {
                bodyEncrypted = false;
            }

            if (bodySigned && bodyEncrypted)
            {
                this.VerifySignatureEncryption();
            }

            reader.Close();

            if (this.pendingSignature != null)
            {
                this.pendingSignature.CompleteSignatureVerification();
                this.pendingSignature = null;
            }
            this.pendingDecryptionToken      = null;
            atLeastOneHeaderOrBodyEncrypted |= bodyEncrypted;

            if (!bodySigned && signatureParts.IsBodyIncluded)
            {
                this.SecurityVerifiedMessage.OnUnsignedPart(XD.MessageDictionary.Body.Value, this.Version.Envelope.Namespace);
            }

            if (!bodyEncrypted && encryptionParts.IsBodyIncluded)
            {
                this.SecurityVerifiedMessage.OnUnencryptedPart(XD.MessageDictionary.Body.Value, this.Version.Envelope.Namespace);
            }

            this.SecurityVerifiedMessage.OnMessageProtectionPassComplete(atLeastOneHeaderOrBodyEncrypted);
        }
		WrappedKeySecurityToken ReadWrappedKeySecurityTokenCore (
			XmlReader reader, SecurityTokenResolver tokenResolver)
		{
			if (tokenResolver == null)
				throw new ArgumentNullException ("tokenResolver");
			EncryptedKey ek = new EncryptedKey ();
			ek.LoadXml (new XmlDocument ().ReadNode (reader) as XmlElement);
			SecurityKeyIdentifier ki = new SecurityKeyIdentifier ();
			foreach (KeyInfoClause kic in ek.KeyInfo)
				ki.Add (ReadKeyIdentifierClause (new XmlNodeReader (kic.GetXml ())));
			SecurityToken token = tokenResolver.ResolveToken (ki);
			string alg = ek.EncryptionMethod.KeyAlgorithm;
			foreach (SecurityKey skey in token.SecurityKeys)
				if (skey.IsSupportedAlgorithm (alg)) {
					byte [] key = skey.DecryptKey (alg, ek.CipherData.CipherValue);
					WrappedKeySecurityToken wk =
						new WrappedKeySecurityToken (ek.Id, key, alg, token, ki);
					// FIXME: This should not be required.
					wk.SetWrappedKey (ek.CipherData.CipherValue);
					wk.ReferenceList = ek.ReferenceList;
					return wk;
				}
			throw new InvalidOperationException (String.Format ("Cannot resolve security key with the resolved SecurityToken specified by the key identifier in the EncryptedKey XML. The key identifier is: {0}", ki));
		}
Beispiel #19
0
        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.Add(MessageHeader.CreateHeader("ReplyTo", msg.Version.Addressing.Namespace, EndpointAddress10.FromEndpointAddress(new EndpointAddress(Constants.WsaAnonymousUri))));
            }

            if (MessageTo != null)
            {
                msg.Headers.Add(MessageHeader.CreateHeader("To", msg.Version.Addressing.Namespace, MessageTo.Uri.AbsoluteUri, true));
            }

            // 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 = Message.CreateMessage(msg.Version, msg.Headers.Action, new XmlNodeReader(doc.SelectSingleNode("/s:Envelope/s:Body/*", nsmgr) as XmlElement));

            ret.Properties.Security = (SecurityMessageProperty)secprop.CreateCopy();
            ret.Properties.Security.EncryptionKey = masterKey.Key;
            ret.BodyId = bodyId;

            // 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 WriteWrappedKeySecurityToken (XmlWriter w, WrappedKeySecurityToken token)
		{
			string encNS = EncryptedXml.XmlEncNamespaceUrl;
			w.WriteStartElement ("e", "EncryptedKey", encNS);
			w.WriteAttributeString ("Id", token.Id);
			w.WriteStartElement ("EncryptionMethod", encNS);
			w.WriteAttributeString ("Algorithm", token.WrappingAlgorithm);
			w.WriteStartElement ("DigestMethod", SignedXml.XmlDsigNamespaceUrl);
			w.WriteAttributeString ("Algorithm", SignedXml.XmlDsigSHA1Url);
			w.WriteEndElement ();
			w.WriteEndElement ();

			w.WriteStartElement ("KeyInfo", SignedXml.XmlDsigNamespaceUrl);
			if (token.WrappingTokenReference != null)
				foreach (SecurityKeyIdentifierClause kic in token.WrappingTokenReference)
					WriteKeyIdentifierClause (w, kic);
			w.WriteEndElement ();
			w.WriteStartElement ("CipherData", encNS);
			w.WriteStartElement ("CipherValue", encNS);
			w.WriteString (Convert.ToBase64String (token.GetWrappedKey ()));
			w.WriteEndElement ();
			w.WriteEndElement ();
			if (token.ReferenceList != null) {
				w.WriteStartElement ("e", "ReferenceList", encNS);
				foreach (DataReference er in token.ReferenceList) {
					w.WriteStartElement ("DataReference", encNS);
					w.WriteAttributeString ("URI", er.Uri);
					w.WriteEndElement ();
				}
				w.WriteEndElement ();
			}
			w.WriteEndElement ();
		}
 protected virtual DecryptedHeader DecryptHeader(XmlDictionaryReader reader, WrappedKeySecurityToken wrappedKeyToken)
 {
     throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("HeaderDecryptionNotSupportedInWsSecurityJan2004")));
 }
 protected override void ProcessReferenceListCore(ReferenceList referenceList, WrappedKeySecurityToken wrappedKeyToken)
 {
     this.pendingReferenceList = referenceList;
     this.pendingDecryptionToken = wrappedKeyToken;
 }
 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);
     }
 }
 protected override byte[] DecryptSecurityHeaderElement(
     EncryptedData encryptedData, WrappedKeySecurityToken wrappedKeyToken, out SecurityToken encryptionToken)
 {
     if ((encryptedData.KeyIdentifier != null) || (wrappedKeyToken == null))
     {
         // The EncryptedData might have a KeyInfo inside it. Try resolving the SecurityKeyIdentifier. 
         encryptionToken = ResolveKeyIdentifier(encryptedData.KeyIdentifier, this.CombinedPrimaryTokenResolver, false);
         if (wrappedKeyToken != null && wrappedKeyToken.ReferenceList != null && encryptedData.HasId && wrappedKeyToken.ReferenceList.ContainsReferredId(encryptedData.Id) && (wrappedKeyToken != encryptionToken))
         {
             // We have a EncryptedKey with a ReferenceList inside it. This would mean that 
             // all the EncryptedData pointed by the ReferenceList should be encrypted only
             // by this key. The individual EncryptedData elements if containing a KeyInfo
             // clause should point back to the same EncryptedKey token.
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.EncryptedKeyWasNotEncryptedWithTheRequiredEncryptingToken, wrappedKeyToken)));
         }
     }
     else
     {
         encryptionToken = wrappedKeyToken;
     }
     using (SymmetricAlgorithm algorithm = CreateDecryptionAlgorithm(encryptionToken, encryptedData.EncryptionMethod, this.AlgorithmSuite))
     {
         encryptedData.SetUpDecryption(algorithm);
         return encryptedData.GetDecryptedBuffer();
     }
 }
Beispiel #25
0
 protected override void ProcessReferenceListCore(ReferenceList referenceList, WrappedKeySecurityToken wrappedKeyToken)
 {
     throw new PlatformNotSupportedException();
 }
 protected override void ProcessReferenceListCore(ReferenceList referenceList, WrappedKeySecurityToken wrappedKeyToken)
 {
     this.pendingReferenceList   = referenceList;
     this.pendingDecryptionToken = wrappedKeyToken;
 }
        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 ExtractSecurity()
        {
            if (security.MessageProtectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature &&
                wss_header.Find <SignedXml> () != null)
            {
                throw new MessageSecurityException("The security binding element expects that the message signature is encrypted, while it isn't.");
            }

            WrappedKeySecurityToken wk = wss_header.Find <WrappedKeySecurityToken> ();
            DerivedKeySecurityToken dk = wss_header.Find <DerivedKeySecurityToken> ();

            if (wk != null)
            {
                if (Parameters.RequireDerivedKeys && dk == null)
                {
                    throw new MessageSecurityException("DerivedKeyToken is required in this contract, but was not found in the message");
                }
            }
            else
            {
                // FIXME: this is kind of hack for symmetric reply processing.
                wk = RequestSecurity.ProtectionToken != null ? RequestSecurity.ProtectionToken.SecurityToken as WrappedKeySecurityToken : null;
            }

            SymmetricSecurityKey wkkey = wk != null ? wk.SecurityKeys [0] as SymmetricSecurityKey : null;

            wss_header_reader.DecryptSecurity(this, wkkey, RequestSecurity != null ? RequestSecurity.EncryptionKey : null);

            // signature confirmation
            WSSignedXml sxml = wss_header.Find <WSSignedXml> ();

            if (sxml == null)
            {
                throw new MessageSecurityException("The the message signature is expected but not found.");
            }

            bool confirmed = false;

            SecurityKeyIdentifierClause sigClause = null;

            foreach (KeyInfoClause kic in sxml.KeyInfo)
            {
                SecurityTokenReferenceKeyInfo r = kic as SecurityTokenReferenceKeyInfo;
                if (r != null)
                {
                    sigClause = r.Clause;
                }
            }
            if (sigClause == null)
            {
                throw new MessageSecurityException("SecurityTokenReference was not found in dsig:Signature KeyInfo.");
            }

            SecurityToken signToken;
            SecurityKey   signKey;

            signToken = TokenResolver.ResolveToken(sigClause);
            signKey   = signToken.ResolveKeyIdentifierClause(sigClause);
            SymmetricSecurityKey symkey = signKey as SymmetricSecurityKey;

            if (symkey != null)
            {
                confirmed = sxml.CheckSignature(new HMACSHA1(symkey.GetSymmetricKey()));
                if (wk != null)
                {
                    // FIXME: authenticate token
                    sec_prop.ProtectionToken = new SecurityTokenSpecification(wk, null);
                }
            }
            else
            {
                AsymmetricAlgorithm alg = ((AsymmetricSecurityKey)signKey).GetAsymmetricAlgorithm(security.DefaultSignatureAlgorithm, false);
                confirmed = sxml.CheckSignature(alg);
                sec_prop.InitiatorToken = new SecurityTokenSpecification(
                    signToken,
                    security.TokenAuthenticator.ValidateToken(signToken));
            }
            if (!confirmed)
            {
                throw new MessageSecurityException("Message signature is invalid.");
            }

            // token authentication
            // FIXME: it might not be limited to recipient
            if (Direction == MessageDirection.Input)
            {
                ProcessSupportingTokens(sxml);
            }

            sec_prop.EncryptionKey = ((SymmetricSecurityKey)wk.SecurityKeys [0]).GetSymmetricKey();
            sec_prop.ConfirmedSignatures.Add(Convert.ToBase64String(sxml.SignatureValue));
        }
Beispiel #29
0
        private 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.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.Format(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);
        }