< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Security.WSSecurityOneDotZeroSendSecurityHeader
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/WSSecurityOneDotZeroSendSecurityHeader.cs
Line coverage
5%
Covered lines: 22
Uncovered lines: 349
Coverable lines: 371
Total lines: 1011
Line coverage: 5.9%
Branch coverage
11%
Covered branches: 19
Total branches: 172
Branch coverage: 11%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/WSSecurityOneDotZeroSendSecurityHeader.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.IO;
 6using System.Security.Cryptography;
 7using System.Security.Cryptography.Xml;
 8using System.Text;
 9using System.Threading.Tasks;
 10using System.Xml;
 11using CoreWCF.Channels;
 12using CoreWCF.Description;
 13using CoreWCF.Diagnostics;
 14using CoreWCF.IdentityModel;
 15using CoreWCF.IdentityModel.Tokens;
 16using CoreWCF.Runtime;
 17using CoreWCF.Security.Tokens;
 18using IPrefixGenerator = CoreWCF.IdentityModel.IPrefixGenerator;
 19using ISecurityElement = CoreWCF.IdentityModel.ISecurityElement;
 20using ISignatureValueSecurityElement = CoreWCF.IdentityModel.ISignatureValueSecurityElement;
 21using KeyInfo = System.Security.Cryptography.Xml.KeyInfo;
 22
 23namespace CoreWCF.Security
 24{
 25    internal class WSSecurityOneDotZeroSendSecurityHeader : SendSecurityHeader
 26    {
 27        private HashStream _hashStream;
 28        private SignedXml _signedXml;
 29        private KeyedHashAlgorithm _signingKey;
 30        private MessagePartSpecification _effectiveSignatureParts;
 31
 32        // For Transport Security we have to sign the 'To' header with the
 33        // supporting tokens.
 34        private Stream _toHeaderStream = null;
 35        private string _toHeaderId = null;
 36
 37        public WSSecurityOneDotZeroSendSecurityHeader(Message message, string actor, bool mustUnderstand, bool relay,
 38            SecurityStandardsManager standardsManager,
 39            SecurityAlgorithmSuite algorithmSuite,
 40            MessageDirection direction)
 6341            : base(message, actor, mustUnderstand, relay, standardsManager, algorithmSuite, direction)
 42        {
 6343        }
 44
 45        protected string EncryptionAlgorithm
 46        {
 047            get { return AlgorithmSuite.DefaultEncryptionAlgorithm; }
 48        }
 49
 50        protected XmlDictionaryString EncryptionAlgorithmDictionaryString
 51        {
 052            get { return AlgorithmSuite.DefaultEncryptionAlgorithmDictionaryString; }
 53        }
 54
 55        private void AddEncryptionReference(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, boo
 56            out MemoryStream plainTextStream, out string encryptedDataId)
 57        {
 058            throw new PlatformNotSupportedException();
 59        }
 60
 61        private void AddSignatureReference(SecurityToken token, int position, SecurityTokenAttachmentMode mode)
 62        {
 063            bool strTransformEnabled = ShouldUseStrTransformForToken(token, position, mode, out SecurityKeyIdentifierCla
 064            AddTokenSignatureReference(token, keyIdentifierClause, strTransformEnabled);
 065        }
 66
 67        private void AddPrimaryTokenSignatureReference(SecurityToken token, SecurityTokenParameters securityTokenParamet
 68        {
 069            return;
 70        }
 71
 72        // Given a token and useStarTransform value this method adds apporopriate reference accordingly.
 73        // 1. If strTransform is disabled, it adds a reference to the token's id.
 74        // 2. Else if strtransform is enabled it adds a reference the security token's keyIdentifier's id.
 75        private void AddTokenSignatureReference(SecurityToken token, SecurityKeyIdentifierClause keyIdentifierClause, bo
 76        {
 077            if (strTransformEnabled)
 78            {
 079                throw new PlatformNotSupportedException();
 80            }
 081        }
 82
 83        private void AddSignatureReference(SendSecurityHeaderElement[] elements)
 84        {
 085            if (elements != null)
 86            {
 087                for (int i = 0; i < elements.Length; ++i)
 88                {
 89                    // signedEncryptedTokenElement can either be a TokenElement ( in SignThenEncrypt case) or EncryptedD
 90                    // STR-Transform does not make sense in !SignThenEncrypt case .
 91                    // note: signedEncryptedTokenElement can also be SignatureConfirmation but we do not care about it h
 092                    bool useStrTransform = elements[i].Item is TokenElement signedEncryptedTokenElement
 093                                           && SignThenEncrypt
 094                                           && ShouldUseStrTransformForToken(signedEncryptedTokenElement.Token,
 095                                                                                 i,
 096                                                                                 SecurityTokenAttachmentMode.SignedEncry
 097                                                                                 out SecurityKeyIdentifierClause keyIden
 98
 099                    if (!useStrTransform && elements[i].Id == null)
 100                    {
 0101                        throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.ElementToSignMustHaveId), Me
 102                    }
 103
 0104                    MemoryStream stream = new MemoryStream();
 0105                    XmlDictionaryWriter utf8Writer = TakeUtf8Writer();
 0106                    utf8Writer.StartCanonicalization(stream, false, null);
 0107                    elements[i].Item.WriteTo(utf8Writer, ServiceModelDictionaryManager.Instance);
 0108                    utf8Writer.EndCanonicalization();
 0109                    stream.Position = 0;
 0110                    if (useStrTransform)
 111                    {
 0112                        throw new PlatformNotSupportedException("StrTransform not supported yet");
 113                    }
 114                    else
 115                    {
 0116                        AddReference("#" + elements[i].Id, stream);
 117                    }
 118                }
 119            }
 0120        }
 121
 122        private string GetSignatureHash(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, XmlDict
 123        {
 0124            HashStream hashStream = TakeHashStream();
 125            XmlDictionaryWriter effectiveWriter;
 0126            XmlBuffer canonicalBuffer = null;
 127
 0128            if (writer.CanCanonicalize)
 129            {
 0130                effectiveWriter = writer;
 131            }
 132            else
 133            {
 0134                canonicalBuffer = new XmlBuffer(int.MaxValue);
 0135                effectiveWriter = canonicalBuffer.OpenSection(XmlDictionaryReaderQuotas.Max);
 136            }
 137
 0138            effectiveWriter.StartCanonicalization(hashStream, false, null);
 139
 0140            header.WriteStartHeader(effectiveWriter, Version);
 0141            if (headerId == null)
 142            {
 0143                headerId = GenerateId();
 0144                StandardsManager.IdManager.WriteIdAttribute(effectiveWriter, headerId);
 145            }
 0146            header.WriteHeaderContents(effectiveWriter, Version);
 0147            effectiveWriter.WriteEndElement();
 0148            effectiveWriter.EndCanonicalization();
 0149            effectiveWriter.Flush();
 150
 0151            if (!ReferenceEquals(effectiveWriter, writer))
 152            {
 153                Fx.Assert(canonicalBuffer != null, "Canonical buffer cannot be null.");
 0154                canonicalBuffer.CloseSection();
 0155                canonicalBuffer.Close();
 0156                XmlDictionaryReader dicReader = canonicalBuffer.GetReader(0);
 0157                writer.WriteNode(dicReader, false);
 0158                dicReader.Close();
 159            }
 160
 0161            hash = hashStream.FlushHashAndGetValue();
 162
 0163            return headerId;
 164        }
 165
 166        private async ValueTask<(string, byte[])> GetSignatureHashAsync(MessageHeader header, string headerId, IPrefixGe
 167        {
 0168            HashStream hashStream = TakeHashStream();
 169            XmlDictionaryWriter effectiveWriter;
 0170            XmlBuffer canonicalBuffer = null;
 171
 0172            if (writer.CanCanonicalize)
 173            {
 0174                effectiveWriter = writer;
 175            }
 176            else
 177            {
 0178                canonicalBuffer = new XmlBuffer(int.MaxValue);
 0179                effectiveWriter = canonicalBuffer.OpenSection(XmlDictionaryReaderQuotas.Max);
 180            }
 181
 0182            effectiveWriter.StartCanonicalization(hashStream, false, null);
 183
 0184            header.WriteStartHeader(effectiveWriter, Version);
 0185            if (headerId == null)
 186            {
 0187                headerId = GenerateId();
 0188                StandardsManager.IdManager.WriteIdAttribute(effectiveWriter, headerId);
 189            }
 0190            header.WriteHeaderContents(effectiveWriter, Version);
 0191            await effectiveWriter.WriteEndElementAsync();
 0192            effectiveWriter.EndCanonicalization();
 0193            await effectiveWriter.FlushAsync();
 194
 0195            if (!ReferenceEquals(effectiveWriter, writer))
 196            {
 197                Fx.Assert(canonicalBuffer != null, "Canonical buffer cannot be null.");
 0198                canonicalBuffer.CloseSection();
 0199                canonicalBuffer.Close();
 0200                XmlDictionaryReader dicReader = canonicalBuffer.GetReader(0);
 0201                await writer.WriteNodeAsync(dicReader, false);
 0202                dicReader.Close();
 0203            }
 204
 0205            var hash = hashStream.FlushHashAndGetValue();
 206
 0207            return (headerId, hash);
 0208        }
 209
 210        private string GetSignatureStream(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, XmlDi
 211        {
 0212            stream = new MemoryStream();
 213            XmlDictionaryWriter effectiveWriter;
 0214            XmlBuffer canonicalBuffer = null;
 215
 0216            if (writer.CanCanonicalize)
 217            {
 0218                effectiveWriter = writer;
 219            }
 220            else
 221            {
 0222                canonicalBuffer = new XmlBuffer(int.MaxValue);
 0223                effectiveWriter = canonicalBuffer.OpenSection(XmlDictionaryReaderQuotas.Max);
 224            }
 225
 0226            effectiveWriter.StartCanonicalization(stream, false, null);
 227
 0228            header.WriteStartHeader(effectiveWriter, Version);
 0229            if (headerId == null)
 230            {
 0231                headerId = GenerateId();
 0232                StandardsManager.IdManager.WriteIdAttribute(effectiveWriter, headerId);
 233            }
 0234            header.WriteHeaderContents(effectiveWriter, Version);
 0235            effectiveWriter.WriteEndElement();
 0236            effectiveWriter.EndCanonicalization();
 0237            effectiveWriter.Flush();
 238
 0239            if (!ReferenceEquals(effectiveWriter, writer))
 240            {
 241                Fx.Assert(canonicalBuffer != null, "Canonical buffer cannot be null.");
 0242                canonicalBuffer.CloseSection();
 0243                canonicalBuffer.Close();
 0244                XmlDictionaryReader dicReader = canonicalBuffer.GetReader(0);
 0245                writer.WriteNode(dicReader, false);
 0246                dicReader.Close();
 247            }
 248
 0249            stream.Position = 0;
 250
 0251            return headerId;
 252        }
 253
 254        private async ValueTask<(string, Stream)> GetSignatureStreamAsync(MessageHeader header, string headerId, IPrefix
 255        {
 0256            Stream stream = new MemoryStream();
 257            XmlDictionaryWriter effectiveWriter;
 0258            XmlBuffer canonicalBuffer = null;
 259
 0260            if (writer.CanCanonicalize)
 261            {
 0262                effectiveWriter = writer;
 263            }
 264            else
 265            {
 0266                canonicalBuffer = new XmlBuffer(int.MaxValue);
 0267                effectiveWriter = canonicalBuffer.OpenSection(XmlDictionaryReaderQuotas.Max);
 268            }
 269
 0270            effectiveWriter.StartCanonicalization(stream, false, null);
 271
 0272            header.WriteStartHeader(effectiveWriter, Version);
 0273            if (headerId == null)
 274            {
 0275                headerId = GenerateId();
 0276                StandardsManager.IdManager.WriteIdAttribute(effectiveWriter, headerId);
 277            }
 0278            header.WriteHeaderContents(effectiveWriter, Version);
 0279            await effectiveWriter.WriteEndElementAsync();
 0280            effectiveWriter.EndCanonicalization();
 0281            await effectiveWriter.FlushAsync();
 282
 0283            if (!ReferenceEquals(effectiveWriter, writer))
 284            {
 285                Fx.Assert(canonicalBuffer != null, "Canonical buffer cannot be null.");
 0286                canonicalBuffer.CloseSection();
 0287                canonicalBuffer.Close();
 0288                XmlDictionaryReader dicReader = canonicalBuffer.GetReader(0);
 0289                await writer.WriteNodeAsync(dicReader, false);
 0290                dicReader.Close();
 0291            }
 292
 0293            stream.Position = 0;
 294
 0295            return (headerId, stream);
 0296        }
 297
 298        private void AddReference(string id, Stream contents)
 299        {
 0300            var reference = new System.Security.Cryptography.Xml.Reference(contents)
 0301            {
 0302                Uri = id,
 0303                DigestMethod = AlgorithmSuite.DefaultDigestAlgorithm
 0304            };
 0305            reference.AddTransform(new XmlDsigExcC14NTransform());
 0306            _signedXml.AddReference(reference);
 0307        }
 308
 309        private void AddSignatureReference(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, XmlD
 310        {
 311            // No transforms added to Reference as the digest value has already been calculated
 0312            headerId = GetSignatureHash(header, headerId, prefixGenerator, writer, out byte[] hashValue);
 0313            var reference = new Reference
 0314            {
 0315                DigestMethod = AlgorithmSuite.DefaultDigestAlgorithm,
 0316                DigestValue = hashValue,
 0317                Id = headerId
 0318            };
 0319            _signedXml.AddReference(reference);
 0320        }
 321
 322        private async ValueTask AddSignatureReferenceAsync(MessageHeader header, string headerId, IPrefixGenerator prefi
 323        {
 324            // No transforms added to Reference as the digest value has already been calculated
 0325            var (generatedHeaderId, hashValue) = await GetSignatureHashAsync(header, headerId, prefixGenerator, writer);
 0326            headerId = generatedHeaderId;
 327
 0328            var reference = new Reference
 0329            {
 0330                DigestMethod = AlgorithmSuite.DefaultDigestAlgorithm,
 0331                DigestValue = hashValue,
 0332                Id = headerId
 0333            };
 0334            _signedXml.AddReference(reference);
 0335        }
 336
 337        private void ApplySecurityAndWriteHeader(MessageHeader header, string headerId, XmlDictionaryWriter writer, IPre
 338        {
 122339            if (!RequireMessageProtection && ShouldSignToHeader)
 340            {
 0341                if ((header.Name == XD.AddressingDictionary.To.Value) &&
 0342                    (header.Namespace == Message.Version.Addressing.Namespace))
 343                {
 0344                    if (_toHeaderStream == null)
 345                    {
 0346                        headerId = GetSignatureStream(header, headerId, prefixGenerator, writer, out Stream headerStream
 0347                        _toHeaderStream = headerStream;
 0348                        _toHeaderId = headerId;
 349                    }
 350                    else
 351                    {
 352                        // More than one 'To' header is specified in the message.
 0353                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.Transp
 354                    }
 355
 356                    return;
 357                }
 358            }
 359
 122360            MessagePartProtectionMode protectionMode = GetProtectionMode(header);
 361            switch (protectionMode)
 362            {
 363                case MessagePartProtectionMode.None:
 122364                    header.WriteHeader(writer, Version);
 122365                    return;
 366                case MessagePartProtectionMode.Sign:
 0367                    AddSignatureReference(header, headerId, prefixGenerator, writer);
 0368                    return;
 369                case MessagePartProtectionMode.SignThenEncrypt:
 370                case MessagePartProtectionMode.Encrypt:
 371                case MessagePartProtectionMode.EncryptThenSign:
 0372                    throw new PlatformNotSupportedException();
 373                default:
 374                    Fx.Assert("Invalid MessagePartProtectionMode");
 375                    return;
 376            }
 377        }
 378
 379        private async ValueTask ApplySecurityAndWriteHeaderAsync(MessageHeader header, string headerId, XmlDictionaryWri
 380        {
 0381            if (!RequireMessageProtection && ShouldSignToHeader)
 382            {
 0383                if ((header.Name == XD.AddressingDictionary.To.Value) &&
 0384                    (header.Namespace == Message.Version.Addressing.Namespace))
 385                {
 0386                    if (_toHeaderStream == null)
 387                    {
 0388                        var (generatedHeaderId, stream) = await GetSignatureStreamAsync(header, headerId, prefixGenerato
 0389                        headerId = generatedHeaderId;
 390
 0391                        _toHeaderStream = stream;
 0392                        _toHeaderId = headerId;
 393                    }
 394                    else
 395                    {
 396                        // More than one 'To' header is specified in the message.
 0397                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.Transp
 398                    }
 399
 0400                    return;
 401                }
 402            }
 403
 0404            MessagePartProtectionMode protectionMode = GetProtectionMode(header);
 405            switch (protectionMode)
 406            {
 407                case MessagePartProtectionMode.None:
 0408                    header.WriteHeader(writer, Version);
 0409                    return;
 410                case MessagePartProtectionMode.Sign:
 0411                    await AddSignatureReferenceAsync(header, headerId, prefixGenerator, writer);
 0412                    return;
 413                case MessagePartProtectionMode.SignThenEncrypt:
 414                case MessagePartProtectionMode.Encrypt:
 415                case MessagePartProtectionMode.EncryptThenSign:
 0416                    throw new PlatformNotSupportedException();
 417                default:
 418                    Fx.Assert("Invalid MessagePartProtectionMode");
 0419                    return;
 420            }
 0421        }
 422
 423        public override void ApplySecurityAndWriteHeaders(MessageHeaders headers, XmlDictionaryWriter writer, IPrefixGen
 424        {
 425            string[] headerIds;
 63426            if (RequireMessageProtection || ShouldSignToHeader)
 427            {
 0428                headerIds = headers.GetHeaderAttributes(UtilityStrings.IdAttribute,
 0429                    StandardsManager.IdManager.DefaultIdNamespaceUri);
 430            }
 431            else
 432            {
 63433                headerIds = null;
 434            }
 370435            for (int i = 0; i < headers.Count; i++)
 436            {
 122437                MessageHeader header = headers.GetMessageHeader(i);
 122438                if (Version.Addressing == AddressingVersion.None && header.Namespace == AddressingVersion.None.Namespace
 439                {
 440                    continue;
 441                }
 442
 122443                if (header != this)
 444                {
 122445                    ApplySecurityAndWriteHeader(header, headerIds?[i], writer, prefixGenerator);
 446                }
 447            }
 63448        }
 449
 450        public override async ValueTask ApplySecurityAndWriteHeadersAsync(MessageHeaders headers, XmlDictionaryWriter wr
 451        {
 452            string[] headerIds;
 0453            if (RequireMessageProtection || ShouldSignToHeader)
 454            {
 0455                headerIds = headers.GetHeaderAttributes(UtilityStrings.IdAttribute,
 0456                    StandardsManager.IdManager.DefaultIdNamespaceUri);
 457            }
 458            else
 459            {
 0460                headerIds = null;
 461            }
 0462            for (int i = 0; i < headers.Count; i++)
 463            {
 0464                MessageHeader header = headers.GetMessageHeader(i);
 0465                if (Version.Addressing == AddressingVersion.None && header.Namespace == AddressingVersion.None.Namespace
 466                {
 467                    continue;
 468                }
 469
 0470                if (header != this)
 471                {
 0472                    await ApplySecurityAndWriteHeaderAsync(header, headerIds?[i], writer, prefixGenerator);
 473                }
 474            }
 0475        }
 476
 477        private static bool CanCanonicalizeAndFragment(XmlDictionaryWriter writer)
 478        {
 0479            if (!writer.CanCanonicalize)
 480            {
 0481                return false;
 482            }
 0483            return writer is IFragmentCapableXmlDictionaryWriter fragmentingWriter && fragmentingWriter.CanFragment;
 484        }
 485
 486        public override void ApplyBodySecurity(XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
 487        {
 63488            SecurityAppliedMessage message = SecurityAppliedMessage;
 63489            switch (message.BodyProtectionMode)
 490            {
 491                case MessagePartProtectionMode.None:
 63492                    return;
 493                case MessagePartProtectionMode.Sign:
 0494                    var ms = new MemoryStream();
 0495                    if (CanCanonicalizeAndFragment(writer))
 496                    {
 0497                        message.WriteBodyToSignWithFragments(ms, false, null, writer);
 498                    }
 499                    else
 500                    {
 0501                        message.WriteBodyToSign(ms);
 502                    }
 503
 0504                    ms.Position = 0;
 0505                    AddReference("#" + message.BodyId, ms);
 0506                    return;
 507                case MessagePartProtectionMode.SignThenEncrypt:
 0508                    throw new PlatformNotSupportedException();
 509                case MessagePartProtectionMode.Encrypt:
 0510                    throw new PlatformNotSupportedException();
 511                case MessagePartProtectionMode.EncryptThenSign:
 0512                    throw new PlatformNotSupportedException();
 513                default:
 514                    Fx.Assert("Invalid MessagePartProtectionMode");
 515                    return;
 516            }
 517        }
 518
 519        public override async ValueTask ApplyBodySecurityAsync(XmlDictionaryWriter writer, IPrefixGenerator prefixGenera
 520        {
 0521            SecurityAppliedMessage message = SecurityAppliedMessage;
 0522            switch (message.BodyProtectionMode)
 523            {
 524                case MessagePartProtectionMode.None:
 0525                    return;
 526                case MessagePartProtectionMode.Sign:
 0527                    var ms = new MemoryStream();
 0528                    if (CanCanonicalizeAndFragment(writer))
 529                    {
 0530                        await message.WriteBodyToSignWithFragmentsAsync(ms, false, null, writer);
 531                    }
 532                    else
 533                    {
 0534                        await message.WriteBodyToSignAsync(ms);
 535                    }
 536
 0537                    ms.Position = 0;
 0538                    AddReference("#" + message.BodyId, ms);
 0539                    return;
 540                case MessagePartProtectionMode.SignThenEncrypt:
 0541                    throw new PlatformNotSupportedException();
 542                case MessagePartProtectionMode.Encrypt:
 0543                    throw new PlatformNotSupportedException();
 544                case MessagePartProtectionMode.EncryptThenSign:
 0545                    throw new PlatformNotSupportedException();
 546                default:
 547                    Fx.Assert("Invalid MessagePartProtectionMode");
 0548                    return;
 549            }
 0550        }
 551
 552        protected override ISignatureValueSecurityElement CompletePrimarySignatureCore(
 553            SendSecurityHeaderElement[] signatureConfirmations,
 554            SecurityToken[] signedEndorsingTokens,
 555            SecurityToken[] signedTokens,
 556            SendSecurityHeaderElement[] basicTokens, bool isPrimarySignature)
 557        {
 63558            if (_signedXml == null)
 559            {
 63560                return null;
 561            }
 562
 0563            SecurityTimestamp timestamp = Timestamp;
 0564            if (timestamp != null)
 565            {
 0566                if (timestamp.Id == null)
 567                {
 0568                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Timestamp
 569                }
 570
 0571                byte[] buffer = new byte[64];
 0572                var ms = new MemoryStream();
 0573                StandardsManager.WSUtilitySpecificationVersion.WriteTimestampCanonicalForm(
 0574                    ms, timestamp, buffer);
 0575                ms.Position = 0;
 0576                AddReference("#" + timestamp.Id, ms);
 0577                var reference = new System.Security.Cryptography.Xml.Reference(ms);
 578            }
 579
 0580            if ((ShouldSignToHeader) && (_signingKey != null || _signedXml.SigningKey != null) && (Version.Addressing !=
 581            {
 0582                if (_toHeaderStream != null)
 583                {
 0584                    AddReference("#" + _toHeaderId, _toHeaderStream);
 585                }
 586                else
 587                {
 0588                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Transport
 589                }
 590            }
 591
 0592            AddSignatureReference(signatureConfirmations);
 0593            if (isPrimarySignature && ShouldProtectTokens)
 594            {
 0595                AddPrimaryTokenSignatureReference(ElementContainer.SourceSigningToken, SigningTokenParameters);
 596            }
 597
 0598            if (RequireMessageProtection)
 599            {
 0600                throw new PlatformNotSupportedException(nameof(RequireMessageProtection));
 601            }
 602
 0603            if (_signedXml.SignedInfo.References.Count == 0)
 604            {
 0605                throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.NoPartsOfMessageMatchedPartsToSign),
 606            }
 607            try
 608            {
 0609                if (_signingKey != null)
 610                {
 0611                    _signedXml.ComputeSignature(_signingKey);
 612                }
 613                else
 614                {
 0615                    _signedXml.ComputeSignature();
 616                }
 617
 0618                return new SignatureValue(_signedXml.Signature);
 619            }
 620            finally
 621            {
 0622                _hashStream = null;
 0623                _signingKey = null;
 0624                _signedXml = null;
 0625                _effectiveSignatureParts = null;
 0626            }
 0627        }
 628
 629        internal class SignatureValue : ISignatureValueSecurityElement
 630        {
 631            private readonly Signature _signature;
 632
 0633            public SignatureValue(Signature signature)
 634            {
 0635                _signature = signature;
 0636            }
 637
 638            public void WriteTo(XmlDictionaryWriter writer, DictionaryManager dictionaryManager)
 639            {
 0640                _signature.GetXml().WriteTo(writer);
 0641            }
 642
 643            public bool HasId
 644            {
 0645                get { return true; }
 646            }
 647
 648            public string Id
 649            {
 0650                get { return _signature.Id; }
 651            }
 652
 653            public byte[] GetSignatureValue()
 654            {
 0655                return _signature.SignatureValue;
 656            }
 657        }
 658
 659        private HashStream TakeHashStream()
 660        {
 661            HashStream hashStream;
 0662            if (_hashStream == null)
 663            {
 0664                _hashStream = hashStream = new HashStream(CryptoHelper.CreateHashAlgorithm(AlgorithmSuite.DefaultDigestA
 665            }
 666            else
 667            {
 0668                hashStream = _hashStream;
 669                ;
 0670                hashStream.Reset();
 671            }
 0672            return hashStream;
 673        }
 674
 675        private XmlDictionaryWriter TakeUtf8Writer()
 676        {
 0677            throw new PlatformNotSupportedException();
 678        }
 679
 680        private MessagePartProtectionMode GetProtectionMode(MessageHeader header)
 681        {
 122682            if (!RequireMessageProtection)
 683            {
 122684                return MessagePartProtectionMode.None;
 685            }
 0686            bool sign = _signedXml != null && _effectiveSignatureParts.IsHeaderIncluded(header);
 0687            bool encrypt = false;
 0688            return MessagePartProtectionModeHelper.GetProtectionMode(sign, encrypt, SignThenEncrypt);
 689        }
 690
 691        protected override void StartPrimarySignatureCore(SecurityToken token,
 692            SecurityKeyIdentifier keyIdentifier,
 693            MessagePartSpecification signatureParts,
 694            bool generateTargettableSignature)
 695        {
 0696            SecurityAlgorithmSuite suite = AlgorithmSuite;
 0697            string canonicalizationAlgorithm = suite.DefaultCanonicalizationAlgorithm;
 0698            if (canonicalizationAlgorithm != SecurityAlgorithms.ExclusiveC14n)
 699            {
 0700                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
 0701                    new MessageSecurityException(SR.Format(SR.UnsupportedCanonicalizationAlgorithm, suite.DefaultCanonic
 702            }
 0703            suite.GetSignatureAlgorithmAndKey(token, out string signatureAlgorithm, out SecurityKey signatureKey, out Xm
 0704            GetSigningAlgorithm(signatureKey, signatureAlgorithm, out _signingKey, out AsymmetricAlgorithm asymmetricAlg
 705
 0706            _signedXml = new SignedXml();
 0707            _signedXml.SignedInfo.CanonicalizationMethod = canonicalizationAlgorithm;
 0708            _signedXml.SignedInfo.SignatureMethod = signatureAlgorithm;
 0709            _signedXml.SigningKey = asymmetricAlgorithm;
 0710            if (keyIdentifier != null)
 711            {
 0712                var stream = new MemoryStream();
 0713                using (var xmlWriter = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, false))
 714                {
 0715                    StandardsManager.SecurityTokenSerializer.WriteKeyIdentifier(xmlWriter, keyIdentifier);
 0716                }
 717
 0718                stream.Position = 0;
 0719                XmlDocument doc = new XmlDocument();
 0720                doc.Load(stream);
 0721                var keyInfo = new KeyInfo();
 0722                keyInfo.LoadXml(doc.DocumentElement);
 0723                _signedXml.KeyInfo = keyInfo;
 724            }
 725
 0726            if (generateTargettableSignature)
 727            {
 0728                _signedXml.Signature.Id = GenerateId();
 729            }
 0730            _effectiveSignatureParts = signatureParts;
 0731        }
 732
 733        private void GetSigningAlgorithm(SecurityKey signatureKey, string algorithmName, out KeyedHashAlgorithm symmetri
 734        {
 0735            symmetricAlgorithm = null;
 0736            asymmetricAlgorithm = null;
 0737            if (signatureKey is SymmetricSecurityKey symmetricKey)
 738            {
 0739                _signingKey = symmetricKey.GetKeyedHashAlgorithm(algorithmName);
 0740                if (_signingKey == null)
 741                {
 0742                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
 0743                        SR.Format("UnableToCreateKeyedHashAlgorithm", symmetricKey, algorithmName)));
 744                }
 745            }
 746            else
 747            {
 0748                if (!(signatureKey is AsymmetricSecurityKey asymmetricKey))
 749                {
 0750                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
 0751                        SR.Format(SR.UnknownICryptoType, _signingKey)));
 752                }
 753
 0754                asymmetricAlgorithm = asymmetricKey.GetAsymmetricAlgorithm(algorithmName, privateKey: true);
 0755                if (asymmetricAlgorithm == null)
 756                {
 757                    //TODO MUST before checkin search and replace SR.Format("
 0758                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
 0759                        SR.Format("UnableToCreateHashAlgorithmFromAsymmetricCrypto", algorithmName,
 0760                            asymmetricKey)));
 761                }
 762            }
 0763        }
 764
 765        protected override ISignatureValueSecurityElement CreateSupportingSignature(SecurityToken token, SecurityKeyIden
 766        {
 0767            StartPrimarySignatureCore(token, identifier, MessagePartSpecification.NoParts, false);
 0768            return CompletePrimarySignatureCore(null, null, null, null, false);
 769        }
 770
 771        protected override ISignatureValueSecurityElement CreateSupportingSignature(SecurityToken token, SecurityKeyIden
 772        {
 0773            AlgorithmSuite.GetSignatureAlgorithmAndKey(token, out string signatureAlgorithm, out SecurityKey signatureKe
 774
 0775            SignedXml signedXml = new SignedXml();
 0776            SignedInfo signedInfo = signedXml.SignedInfo;
 0777            signedInfo.CanonicalizationMethod = AlgorithmSuite.DefaultCanonicalizationAlgorithm;
 0778            signedInfo.SignatureMethod = signatureAlgorithm;
 779
 0780            if (elementToSign.Id == null)
 781            {
 0782                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.ElementToSign
 783            }
 784
 0785            MemoryStream stream = new MemoryStream();
 0786            XmlDictionaryWriter utf8Writer = TakeUtf8Writer();
 0787            utf8Writer.StartCanonicalization(stream, false, null);
 0788            elementToSign.WriteTo(utf8Writer, ServiceModelDictionaryManager.Instance);
 0789            utf8Writer.EndCanonicalization();
 0790            stream.Position = 0;
 0791            AddReference("#" + elementToSign.Id, stream);
 792
 0793            GetSigningAlgorithm(signatureKey, signatureAlgorithm, out KeyedHashAlgorithm keyedHashAlgorithm, out Asymmet
 0794            if (keyedHashAlgorithm != null)
 795            {
 0796                signedXml.ComputeSignature(keyedHashAlgorithm);
 797            }
 798            else
 799            {
 0800                signedXml.SigningKey = asymmetricAlgorithm;
 0801                signedXml.ComputeSignature();
 802            }
 803
 0804            SetKeyInfo(signedXml, identifier);
 0805            return new SignatureValue(signedXml.Signature);
 806        }
 807
 808        private void SetKeyInfo(SignedXml signedXml, SecurityKeyIdentifier identifier)
 809        {
 0810            if (identifier != null)
 811            {
 0812                var stream = new MemoryStream();
 0813                using (var xmlWriter = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, false))
 814                {
 0815                    StandardsManager.SecurityTokenSerializer.WriteKeyIdentifier(xmlWriter, identifier);
 0816                }
 817
 0818                stream.Position = 0;
 0819                XmlDocument doc = new XmlDocument();
 0820                doc.Load(stream);
 0821                var keyInfo = new KeyInfo();
 0822                keyInfo.LoadXml(doc.DocumentElement);
 0823                signedXml.KeyInfo = keyInfo;
 824            }
 0825        }
 826
 827        protected override void WriteSecurityTokenReferencyEntry(XmlDictionaryWriter writer, SecurityToken securityToken
 828        {
 0829            return;
 830        }
 831
 832        protected override void StartEncryptionCore(SecurityToken token, SecurityKeyIdentifier keyIdentifier)
 833        {
 0834            throw new NotImplementedException();
 835        }
 836
 837        protected override ISecurityElement CompleteEncryptionCore(SendSecurityHeaderElement primarySignature, SendSecur
 838        {
 63839            return null;
 840        }
 841    }
 842
 843    internal class WrappedXmlDictionaryWriter : XmlDictionaryWriter
 844    {
 845        private readonly XmlDictionaryWriter _innerWriter;
 846        private int _index;
 847        private bool _insertId;
 848        private bool _isStrReferenceElement;
 849        private readonly string _id;
 850
 851        public WrappedXmlDictionaryWriter(XmlDictionaryWriter writer, string id)
 852        {
 853            _innerWriter = writer;
 854            _index = 0;
 855            _insertId = false;
 856            _isStrReferenceElement = false;
 857            _id = id;
 858        }
 859
 860        public override void WriteStartAttribute(string prefix, string localName, string namespaceUri)
 861        {
 862            if (_isStrReferenceElement && _insertId && localName == XD.UtilityDictionary.IdAttribute.Value)
 863            {
 864                // This means the serializer is already writing the Id out, so we don't write it again.
 865                _insertId = false;
 866            }
 867            _innerWriter.WriteStartAttribute(prefix, localName, namespaceUri);
 868        }
 869
 870        public override void WriteStartElement(string prefix, string localName, string namespaceUri)
 871        {
 872            if (_isStrReferenceElement && _insertId)
 873            {
 874                if (_id != null)
 875                {
 876                    _innerWriter.WriteAttributeString(XD.UtilityDictionary.Prefix.Value, XD.UtilityDictionary.IdAttribut
 877                }
 878
 879                _isStrReferenceElement = false;
 880                _insertId = false;
 881            }
 882
 883            _index++;
 884
 885            if (_index == 1 && localName == XD.SecurityJan2004Dictionary.SecurityTokenReference.Value)
 886            {
 887                _insertId = true;
 888                _isStrReferenceElement = true;
 889            }
 890
 891            _innerWriter.WriteStartElement(prefix, localName, namespaceUri);
 892        }
 893
 894        // Below methods simply call into innerWritter
 895        public override void Close()
 896        {
 897            _innerWriter.Close();
 898        }
 899
 900        public override void Flush()
 901        {
 902            _innerWriter.Flush();
 903        }
 904
 905        public override string LookupPrefix(string ns)
 906        {
 907            return _innerWriter.LookupPrefix(ns);
 908        }
 909
 910        public override void WriteBase64(byte[] buffer, int index, int count)
 911        {
 912            _innerWriter.WriteBase64(buffer, index, count);
 913        }
 914
 915        public override void WriteCData(string text)
 916        {
 917            _innerWriter.WriteCData(text);
 918        }
 919
 920        public override void WriteCharEntity(char ch)
 921        {
 922            _innerWriter.WriteCharEntity(ch);
 923        }
 924
 925        public override void WriteChars(char[] buffer, int index, int count)
 926        {
 927            _innerWriter.WriteChars(buffer, index, count);
 928        }
 929
 930        public override void WriteComment(string text)
 931        {
 932            _innerWriter.WriteComment(text);
 933        }
 934
 935        public override void WriteDocType(string name, string pubid, string sysid, string subset)
 936        {
 937            _innerWriter.WriteDocType(name, pubid, sysid, subset);
 938        }
 939
 940        public override void WriteEndAttribute()
 941        {
 942            _innerWriter.WriteEndAttribute();
 943        }
 944
 945        public override void WriteEndDocument()
 946        {
 947            _innerWriter.WriteEndDocument();
 948        }
 949
 950        public override void WriteEndElement()
 951        {
 952            _innerWriter.WriteEndElement();
 953        }
 954
 955        public override void WriteEntityRef(string name)
 956        {
 957            _innerWriter.WriteEntityRef(name);
 958        }
 959
 960        public override void WriteFullEndElement()
 961        {
 962            _innerWriter.WriteFullEndElement();
 963        }
 964
 965        public override void WriteProcessingInstruction(string name, string text)
 966        {
 967            _innerWriter.WriteProcessingInstruction(name, text);
 968        }
 969
 970        public override void WriteRaw(string data)
 971        {
 972            _innerWriter.WriteRaw(data);
 973        }
 974
 975        public override void WriteRaw(char[] buffer, int index, int count)
 976        {
 977            _innerWriter.WriteRaw(buffer, index, count);
 978        }
 979
 980        public override void WriteStartDocument(bool standalone)
 981        {
 982            _innerWriter.WriteStartDocument(standalone);
 983        }
 984
 985        public override void WriteStartDocument()
 986        {
 987            _innerWriter.WriteStartDocument();
 988        }
 989
 990        public override WriteState WriteState
 991        {
 992            get { return _innerWriter.WriteState; }
 993        }
 994
 995        public override void WriteString(string text)
 996        {
 997            _innerWriter.WriteString(text);
 998        }
 999
 1000        public override void WriteSurrogateCharEntity(char lowChar, char highChar)
 1001        {
 1002            _innerWriter.WriteSurrogateCharEntity(lowChar, highChar);
 1003        }
 1004
 1005        public override void WriteWhitespace(string ws)
 1006        {
 1007            _innerWriter.WriteWhitespace(ws);
 1008        }
 1009    }
 1010}
 1011

Methods/Properties

.ctor(CoreWCF.Channels.Message,System.String,System.Boolean,System.Boolean,CoreWCF.Security.SecurityStandardsManager,CoreWCF.Security.SecurityAlgorithmSuite,CoreWCF.Description.MessageDirection)
EncryptionAlgorithm()
EncryptionAlgorithmDictionaryString()
AddEncryptionReference(CoreWCF.Channels.MessageHeader,System.String,CoreWCF.IdentityModel.IPrefixGenerator,System.Boolean,System.IO.MemoryStream&,System.String&)
AddSignatureReference(CoreWCF.IdentityModel.Tokens.SecurityToken,System.Int32,CoreWCF.Security.SecurityTokenAttachmentMode)
AddPrimaryTokenSignatureReference(CoreWCF.IdentityModel.Tokens.SecurityToken,CoreWCF.Security.Tokens.SecurityTokenParameters)
AddTokenSignatureReference(CoreWCF.IdentityModel.Tokens.SecurityToken,CoreWCF.IdentityModel.SecurityKeyIdentifierClause,System.Boolean)
AddSignatureReference(CoreWCF.Security.SendSecurityHeaderElement[])
GetSignatureHash(CoreWCF.Channels.MessageHeader,System.String,CoreWCF.IdentityModel.IPrefixGenerator,System.Xml.XmlDictionaryWriter,System.Byte[]&)
GetSignatureHashAsync()
GetSignatureStream(CoreWCF.Channels.MessageHeader,System.String,CoreWCF.IdentityModel.IPrefixGenerator,System.Xml.XmlDictionaryWriter,System.IO.Stream&)
GetSignatureStreamAsync()
AddReference(System.String,System.IO.Stream)
AddSignatureReference(CoreWCF.Channels.MessageHeader,System.String,CoreWCF.IdentityModel.IPrefixGenerator,System.Xml.XmlDictionaryWriter)
AddSignatureReferenceAsync()
ApplySecurityAndWriteHeader(CoreWCF.Channels.MessageHeader,System.String,System.Xml.XmlDictionaryWriter,CoreWCF.IdentityModel.IPrefixGenerator)
ApplySecurityAndWriteHeaderAsync()
ApplySecurityAndWriteHeaders(CoreWCF.Channels.MessageHeaders,System.Xml.XmlDictionaryWriter,CoreWCF.IdentityModel.IPrefixGenerator)
ApplySecurityAndWriteHeadersAsync()
CanCanonicalizeAndFragment(System.Xml.XmlDictionaryWriter)
ApplyBodySecurity(System.Xml.XmlDictionaryWriter,CoreWCF.IdentityModel.IPrefixGenerator)
ApplyBodySecurityAsync()
CompletePrimarySignatureCore(CoreWCF.Security.SendSecurityHeaderElement[],CoreWCF.IdentityModel.Tokens.SecurityToken[],CoreWCF.IdentityModel.Tokens.SecurityToken[],CoreWCF.Security.SendSecurityHeaderElement[],System.Boolean)
.ctor(System.Security.Cryptography.Xml.Signature)
WriteTo(System.Xml.XmlDictionaryWriter,CoreWCF.IdentityModel.DictionaryManager)
HasId()
Id()
GetSignatureValue()
TakeHashStream()
TakeUtf8Writer()
GetProtectionMode(CoreWCF.Channels.MessageHeader)
StartPrimarySignatureCore(CoreWCF.IdentityModel.Tokens.SecurityToken,CoreWCF.IdentityModel.Tokens.SecurityKeyIdentifier,CoreWCF.Security.MessagePartSpecification,System.Boolean)
GetSigningAlgorithm(CoreWCF.IdentityModel.Tokens.SecurityKey,System.String,System.Security.Cryptography.KeyedHashAlgorithm&,System.Security.Cryptography.AsymmetricAlgorithm&)
CreateSupportingSignature(CoreWCF.IdentityModel.Tokens.SecurityToken,CoreWCF.IdentityModel.Tokens.SecurityKeyIdentifier)
CreateSupportingSignature(CoreWCF.IdentityModel.Tokens.SecurityToken,CoreWCF.IdentityModel.Tokens.SecurityKeyIdentifier,CoreWCF.IdentityModel.ISecurityElement)
SetKeyInfo(System.Security.Cryptography.Xml.SignedXml,CoreWCF.IdentityModel.Tokens.SecurityKeyIdentifier)
WriteSecurityTokenReferencyEntry(System.Xml.XmlDictionaryWriter,CoreWCF.IdentityModel.Tokens.SecurityToken,CoreWCF.Security.Tokens.SecurityTokenParameters)
StartEncryptionCore(CoreWCF.IdentityModel.Tokens.SecurityToken,CoreWCF.IdentityModel.Tokens.SecurityKeyIdentifier)
CompleteEncryptionCore(CoreWCF.Security.SendSecurityHeaderElement,CoreWCF.Security.SendSecurityHeaderElement[],CoreWCF.Security.SendSecurityHeaderElement[],CoreWCF.Security.SendSecurityHeaderElement[])