protected override void StartPrimarySignatureCore(SecurityToken token,
                                                          SecurityKeyIdentifier keyIdentifier,
                                                          MessagePartSpecification signatureParts,
                                                          bool generateTargettableSignature)
        {
            SecurityAlgorithmSuite suite     = this.AlgorithmSuite;
            string canonicalizationAlgorithm = suite.DefaultCanonicalizationAlgorithm;
            XmlDictionaryString canonicalizationAlgorithmDictionaryString = suite.DefaultCanonicalizationAlgorithmDictionaryString;

            if (canonicalizationAlgorithm != SecurityAlgorithms.ExclusiveC14n)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new MessageSecurityException(SR.GetString(SR.UnsupportedCanonicalizationAlgorithm, suite.DefaultCanonicalizationAlgorithm)));
            }
            string signatureAlgorithm;
            XmlDictionaryString signatureAlgorithmDictionaryString;

            suite.GetSignatureAlgorithmAndKey(token, out signatureAlgorithm, out this.signatureKey, out signatureAlgorithmDictionaryString);
            string digestAlgorithm = suite.DefaultDigestAlgorithm;
            XmlDictionaryString digestAlgorithmDictionaryString = suite.DefaultDigestAlgorithmDictionaryString;

            this.signedInfo = new PreDigestedSignedInfo(ServiceModelDictionaryManager.Instance, canonicalizationAlgorithm, canonicalizationAlgorithmDictionaryString, digestAlgorithm, digestAlgorithmDictionaryString, signatureAlgorithm, signatureAlgorithmDictionaryString);
            this.signedXml  = new SignedXml(this.signedInfo, ServiceModelDictionaryManager.Instance, this.StandardsManager.SecurityTokenSerializer);
            if (keyIdentifier != null)
            {
                this.signedXml.Signature.KeyIdentifier = keyIdentifier;
            }
            if (generateTargettableSignature)
            {
                this.signedXml.Id = GenerateId();
            }
            this.effectiveSignatureParts = signatureParts;
            this.hashStream = this.signedInfo.ResourcePool.TakeHashStream(digestAlgorithm);
        }
        // Given a token and useStarTransform value this method adds apporopriate reference accordingly.
        // 1. If strTransform is disabled, it adds a reference to the token's id.
        // 2. Else if strtransform is enabled it adds a reference the security token's keyIdentifier's id.
        void AddTokenSignatureReference(SecurityToken token, SecurityKeyIdentifierClause keyIdentifierClause, bool strTransformEnabled)
        {
            if (!strTransformEnabled && token.Id == null)
            {
                throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.ElementToSignMustHaveId)), this.Message);
            }

            HashStream          hashStream = TakeHashStream();
            XmlDictionaryWriter utf8Writer = TakeUtf8Writer();

            utf8Writer.StartCanonicalization(hashStream, false, null);
            this.StandardsManager.SecurityTokenSerializer.WriteToken(utf8Writer, token);
            utf8Writer.EndCanonicalization();

            if (strTransformEnabled)
            {
                if (keyIdentifierClause != null)
                {
                    if (String.IsNullOrEmpty(keyIdentifierClause.Id))
                    {
                        keyIdentifierClause.Id = SecurityUniqueId.Create().Value;
                    }
                    this.ElementContainer.MapSecurityTokenToStrClause(token, keyIdentifierClause);
                    this.signedInfo.AddReference(keyIdentifierClause.Id, hashStream.FlushHashAndGetValue(), true);
                }
                else
                {
                    throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenManagerCannotCreateTokenReference)), this.Message);
                }
            }
            else
            {
                this.signedInfo.AddReference(token.Id, hashStream.FlushHashAndGetValue());
            }
        }
        public override void ApplyBodySecurity(XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
        {
            SecurityAppliedMessage message = this.SecurityAppliedMessage;
            EncryptedData          encryptedData;
            HashStream             hashStream;

            switch (message.BodyProtectionMode)
            {
            case MessagePartProtectionMode.None:
                return;

            case MessagePartProtectionMode.Sign:
                hashStream = TakeHashStream();
                if (CanCanonicalizeAndFragment(writer))
                {
                    message.WriteBodyToSignWithFragments(hashStream, false, null, writer);
                }
                else
                {
                    message.WriteBodyToSign(hashStream);
                }
                this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
                return;

            case MessagePartProtectionMode.SignThenEncrypt:
                hashStream    = TakeHashStream();
                encryptedData = CreateEncryptedDataForBody();
                if (CanCanonicalizeAndFragment(writer))
                {
                    message.WriteBodyToSignThenEncryptWithFragments(hashStream, false, null, encryptedData, this.encryptingSymmetricAlgorithm, writer);
                }
                else
                {
                    message.WriteBodyToSignThenEncrypt(hashStream, encryptedData, this.encryptingSymmetricAlgorithm);
                }
                this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
                this.referenceList.AddReferredId(encryptedData.Id);
                this.hasSignedEncryptedMessagePart = true;
                return;

            case MessagePartProtectionMode.Encrypt:
                encryptedData = CreateEncryptedDataForBody();
                message.WriteBodyToEncrypt(encryptedData, this.encryptingSymmetricAlgorithm);
                this.referenceList.AddReferredId(encryptedData.Id);
                return;

            case MessagePartProtectionMode.EncryptThenSign:
                hashStream    = TakeHashStream();
                encryptedData = CreateEncryptedDataForBody();
                message.WriteBodyToEncryptThenSign(hashStream, encryptedData, this.encryptingSymmetricAlgorithm);
                this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
                this.referenceList.AddReferredId(encryptedData.Id);
                return;

            default:
                Fx.Assert("Invalid MessagePartProtectionMode");
                return;
            }
        }
        void AddSignatureReference(SendSecurityHeaderElement[] elements)
        {
            if (elements != null)
            {
                for (int i = 0; i < elements.Length; ++i)
                {
                    SecurityKeyIdentifierClause keyIdentifierClause = null;
                    TokenElement signedEncryptedTokenElement        = elements[i].Item as TokenElement;

                    // signedEncryptedTokenElement can either be a TokenElement ( in SignThenEncrypt case) or EncryptedData ( in !SignThenEncryptCase)
                    // STR-Transform does not make sense in !SignThenEncrypt case .
                    // note: signedEncryptedTokenElement can also be SignatureConfirmation but we do not care about it here.
                    bool useStrTransform = signedEncryptedTokenElement != null &&
                                           SignThenEncrypt &&
                                           this.ShouldUseStrTransformForToken(signedEncryptedTokenElement.Token,
                                                                              i,
                                                                              SecurityTokenAttachmentMode.SignedEncrypted,
                                                                              out keyIdentifierClause);

                    if (!useStrTransform && elements[i].Id == null)
                    {
                        throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.ElementToSignMustHaveId)), this.Message);
                    }

                    HashStream          hashStream = TakeHashStream();
                    XmlDictionaryWriter utf8Writer = TakeUtf8Writer();
                    utf8Writer.StartCanonicalization(hashStream, false, null);
                    elements[i].Item.WriteTo(utf8Writer, ServiceModelDictionaryManager.Instance);
                    utf8Writer.EndCanonicalization();

                    if (useStrTransform)
                    {
                        if (keyIdentifierClause != null)
                        {
                            if (String.IsNullOrEmpty(keyIdentifierClause.Id))
                            {
                                keyIdentifierClause.Id = SecurityUniqueId.Create().Value;
                            }

                            this.ElementContainer.MapSecurityTokenToStrClause(signedEncryptedTokenElement.Token, keyIdentifierClause);
                            this.signedInfo.AddReference(keyIdentifierClause.Id, hashStream.FlushHashAndGetValue(), true);
                        }
                        else
                        {
                            throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenManagerCannotCreateTokenReference)), this.Message);
                        }
                    }
                    else
                    {
                        this.signedInfo.AddReference(elements[i].Id, hashStream.FlushHashAndGetValue());
                    }
                }
            }
        }
        HashStream TakeHashStream()
        {
            HashStream hashStream = null;

            if (this.hashStream == null)
            {
                this.hashStream = hashStream = new HashStream(CryptoHelper.CreateHashAlgorithm(this.AlgorithmSuite.DefaultDigestAlgorithm));
            }
            else
            {
                hashStream = this.hashStream;;
                hashStream.Reset();
            }
            return(hashStream);
        }
            internal override SecurityTimestamp ReadTimestamp(XmlDictionaryReader reader, string digestAlgorithm, SignatureResourcePool resourcePool)
            {
                bool       canonicalize = digestAlgorithm != null && reader.CanCanonicalize;
                HashStream hashStream   = null;

                reader.MoveToStartElement(XD.UtilityDictionary.Timestamp, XD.UtilityDictionary.Namespace);
                if (canonicalize)
                {
                    hashStream = resourcePool.TakeHashStream(digestAlgorithm);
                    reader.StartCanonicalization(hashStream, false, null);
                }
                string id = reader.GetAttribute(XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace);

                reader.ReadStartElement();

                reader.ReadStartElement(XD.UtilityDictionary.CreatedElement, XD.UtilityDictionary.Namespace);
                DateTime creationTimeUtc = reader.ReadContentAsDateTime().ToUniversalTime();

                reader.ReadEndElement();

                DateTime expiryTimeUtc;

                if (reader.IsStartElement(XD.UtilityDictionary.ExpiresElement, XD.UtilityDictionary.Namespace))
                {
                    reader.ReadStartElement();
                    expiryTimeUtc = reader.ReadContentAsDateTime().ToUniversalTime();
                    reader.ReadEndElement();
                }
                else
                {
                    expiryTimeUtc = SecurityUtils.MaxUtcDateTime;
                }

                reader.ReadEndElement();

                byte[] digest;
                if (canonicalize)
                {
                    reader.EndCanonicalization();
                    digest = hashStream.FlushHashAndGetValue();
                }
                else
                {
                    digest = null;
                }
                return(new SecurityTimestamp(creationTimeUtc, expiryTimeUtc, id, digestAlgorithm, digest));
            }
        string GetSignatureHash(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, XmlDictionaryWriter writer, out byte[] hash)
        {
            HashStream          hashStream = TakeHashStream();
            XmlDictionaryWriter effectiveWriter;
            XmlBuffer           canonicalBuffer = null;

            if (writer.CanCanonicalize)
            {
                effectiveWriter = writer;
            }
            else
            {
                canonicalBuffer = new XmlBuffer(int.MaxValue);
                effectiveWriter = canonicalBuffer.OpenSection(XmlDictionaryReaderQuotas.Max);
            }

            effectiveWriter.StartCanonicalization(hashStream, false, null);

            header.WriteStartHeader(effectiveWriter, this.Version);
            if (headerId == null)
            {
                headerId = GenerateId();
                this.StandardsManager.IdManager.WriteIdAttribute(effectiveWriter, headerId);
            }
            header.WriteHeaderContents(effectiveWriter, this.Version);
            effectiveWriter.WriteEndElement();
            effectiveWriter.EndCanonicalization();
            effectiveWriter.Flush();

            if (!ReferenceEquals(effectiveWriter, writer))
            {
                Fx.Assert(canonicalBuffer != null, "Canonical buffer cannot be null.");
                canonicalBuffer.CloseSection();
                canonicalBuffer.Close();
                XmlDictionaryReader dicReader = canonicalBuffer.GetReader(0);
                writer.WriteNode(dicReader, false);
                dicReader.Close();
            }

            hash = hashStream.FlushHashAndGetValue();

            return(headerId);
        }
 protected override void StartPrimarySignatureCore(SecurityToken token,
     SecurityKeyIdentifier keyIdentifier,
     MessagePartSpecification signatureParts,
     bool generateTargettableSignature)
 {
     SecurityAlgorithmSuite suite = this.AlgorithmSuite;
     string canonicalizationAlgorithm = suite.DefaultCanonicalizationAlgorithm;
     XmlDictionaryString canonicalizationAlgorithmDictionaryString = suite.DefaultCanonicalizationAlgorithmDictionaryString;
     if (canonicalizationAlgorithm != SecurityAlgorithms.ExclusiveC14n)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
             new MessageSecurityException(SR.GetString(SR.UnsupportedCanonicalizationAlgorithm, suite.DefaultCanonicalizationAlgorithm)));
     }
     string signatureAlgorithm;
     XmlDictionaryString signatureAlgorithmDictionaryString;
     suite.GetSignatureAlgorithmAndKey(token, out signatureAlgorithm, out this.signatureKey, out signatureAlgorithmDictionaryString);
     string digestAlgorithm = suite.DefaultDigestAlgorithm;
     XmlDictionaryString digestAlgorithmDictionaryString = suite.DefaultDigestAlgorithmDictionaryString;
     this.signedInfo = new PreDigestedSignedInfo(ServiceModelDictionaryManager.Instance, canonicalizationAlgorithm, canonicalizationAlgorithmDictionaryString, digestAlgorithm, digestAlgorithmDictionaryString, signatureAlgorithm, signatureAlgorithmDictionaryString);
     this.signedXml = new SignedXml(this.signedInfo, ServiceModelDictionaryManager.Instance, this.StandardsManager.SecurityTokenSerializer);
     if (keyIdentifier != null)
     {
         this.signedXml.Signature.KeyIdentifier = keyIdentifier;
     }
     if (generateTargettableSignature)
     {
         this.signedXml.Id = GenerateId();
     }
     this.effectiveSignatureParts = signatureParts;
     this.hashStream = this.signedInfo.ResourcePool.TakeHashStream(digestAlgorithm);
 }
 HashStream TakeHashStream()
 {
     HashStream hashStream = null;
     if (this.hashStream == null)
     {
         this.hashStream = hashStream = new HashStream(CryptoHelper.CreateHashAlgorithm(this.AlgorithmSuite.DefaultDigestAlgorithm));
     }
     else
     {
         hashStream = this.hashStream;;
         hashStream.Reset();
     }
     return hashStream;
 }
        protected override ISignatureValueSecurityElement CompletePrimarySignatureCore(
            SendSecurityHeaderElement[] signatureConfirmations,
            SecurityToken[] signedEndorsingTokens,
            SecurityToken[] signedTokens,
            SendSecurityHeaderElement[] basicTokens, bool isPrimarySignature)
        {
            if (this.signedXml == null)
            {
                return null;
            }

            SecurityTimestamp timestamp = this.Timestamp;
            if (timestamp != null)
            {
                if (timestamp.Id == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TimestampToSignHasNoId)));
                }
                HashStream hashStream = TakeHashStream();
                this.StandardsManager.WSUtilitySpecificationVersion.WriteTimestampCanonicalForm(
                    hashStream, timestamp, this.signedInfo.ResourcePool.TakeEncodingBuffer());
                signedInfo.AddReference(timestamp.Id, hashStream.FlushHashAndGetValue());
            }

            if ((this.ShouldSignToHeader) && (this.signatureKey is AsymmetricSecurityKey) && (this.Version.Addressing != AddressingVersion.None))
            {
                if (this.toHeaderHash != null)
                    signedInfo.AddReference(this.toHeaderId, this.toHeaderHash);
                else
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TransportSecurityRequireToHeader)));
            }

            AddSignatureReference(signatureConfirmations);
            if (isPrimarySignature && this.ShouldProtectTokens)
            {
                AddPrimaryTokenSignatureReference(this.ElementContainer.SourceSigningToken, this.SigningTokenParameters);
            }

            if (this.RequireMessageProtection)
            {
                AddSignatureReference(signedEndorsingTokens, SecurityTokenAttachmentMode.SignedEndorsing);
                AddSignatureReference(signedTokens, SecurityTokenAttachmentMode.Signed);
                AddSignatureReference(basicTokens);
            }

            if (this.signedInfo.ReferenceCount == 0)
            {
                throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoPartsOfMessageMatchedPartsToSign)), this.Message);
            }
            try
            {
                this.signedXml.ComputeSignature(this.signatureKey);
                return this.signedXml;
            }
            finally
            {
                this.hashStream = null;
                this.signedInfo = null;
                this.signedXml = null;
                this.signatureKey = null;
                this.effectiveSignatureParts = null;
            }
        }
 public override void ApplyBodySecurity(XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
 {
     SecurityAppliedMessage message = this.SecurityAppliedMessage;
     EncryptedData encryptedData;
     HashStream hashStream;
     switch (message.BodyProtectionMode)
     {
         case MessagePartProtectionMode.None:
             return;
         case MessagePartProtectionMode.Sign:
             hashStream = TakeHashStream();
             if (CanCanonicalizeAndFragment(writer))
             {
                 message.WriteBodyToSignWithFragments(hashStream, false, null, writer);
             }
             else
             {
                 message.WriteBodyToSign(hashStream);
             }
             this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
             return;
         case MessagePartProtectionMode.SignThenEncrypt:
             hashStream = TakeHashStream();
             encryptedData = CreateEncryptedDataForBody();
             if (CanCanonicalizeAndFragment(writer))
             {
                 message.WriteBodyToSignThenEncryptWithFragments(hashStream, false, null, encryptedData, this.encryptingSymmetricAlgorithm, writer);
             }
             else
             {
                 message.WriteBodyToSignThenEncrypt(hashStream, encryptedData, this.encryptingSymmetricAlgorithm);
             }
             this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
             this.referenceList.AddReferredId(encryptedData.Id);
             this.hasSignedEncryptedMessagePart = true;
             return;
         case MessagePartProtectionMode.Encrypt:
             encryptedData = CreateEncryptedDataForBody();
             message.WriteBodyToEncrypt(encryptedData, this.encryptingSymmetricAlgorithm);
             this.referenceList.AddReferredId(encryptedData.Id);
             return;
         case MessagePartProtectionMode.EncryptThenSign:
             hashStream = TakeHashStream();
             encryptedData = CreateEncryptedDataForBody();
             message.WriteBodyToEncryptThenSign(hashStream, encryptedData, this.encryptingSymmetricAlgorithm);
             this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
             this.referenceList.AddReferredId(encryptedData.Id);
             return;
         default:
             Fx.Assert("Invalid MessagePartProtectionMode");
             return;
     }
 }
        protected override ISignatureValueSecurityElement CompletePrimarySignatureCore(
            SendSecurityHeaderElement[] signatureConfirmations,
            SecurityToken[] signedEndorsingTokens,
            SecurityToken[] signedTokens,
            SendSecurityHeaderElement[] basicTokens, bool isPrimarySignature)
        {
            if (this.signedXml == null)
            {
                return(null);
            }

            SecurityTimestamp timestamp = this.Timestamp;

            if (timestamp != null)
            {
                if (timestamp.Id == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TimestampToSignHasNoId)));
                }
                HashStream hashStream = TakeHashStream();
                this.StandardsManager.WSUtilitySpecificationVersion.WriteTimestampCanonicalForm(
                    hashStream, timestamp, this.signedInfo.ResourcePool.TakeEncodingBuffer());
                signedInfo.AddReference(timestamp.Id, hashStream.FlushHashAndGetValue());
            }

            if ((this.ShouldSignToHeader) && (this.signatureKey is AsymmetricSecurityKey) && (this.Version.Addressing != AddressingVersion.None))
            {
                if (this.toHeaderHash != null)
                {
                    signedInfo.AddReference(this.toHeaderId, this.toHeaderHash);
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TransportSecurityRequireToHeader)));
                }
            }

            AddSignatureReference(signatureConfirmations);
            if (isPrimarySignature && this.ShouldProtectTokens)
            {
                AddPrimaryTokenSignatureReference(this.ElementContainer.SourceSigningToken, this.SigningTokenParameters);
            }

            if (this.RequireMessageProtection)
            {
                AddSignatureReference(signedEndorsingTokens, SecurityTokenAttachmentMode.SignedEndorsing);
                AddSignatureReference(signedTokens, SecurityTokenAttachmentMode.Signed);
                AddSignatureReference(basicTokens);
            }

            if (this.signedInfo.ReferenceCount == 0)
            {
                throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoPartsOfMessageMatchedPartsToSign)), this.Message);
            }
            try
            {
                this.signedXml.ComputeSignature(this.signatureKey);
                return(this.signedXml);
            }
            finally
            {
                this.hashStream              = null;
                this.signedInfo              = null;
                this.signedXml               = null;
                this.signatureKey            = null;
                this.effectiveSignatureParts = null;
            }
        }