< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Security.EncryptedKey
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/EncryptedKey.cs
Line coverage
7%
Covered lines: 3
Uncovered lines: 39
Coverable lines: 42
Total lines: 473
Line coverage: 7.1%
Branch coverage
0%
Covered branches: 0
Total branches: 16
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%11100%
ForceEncryption()100%110%
GetWrappedKey()0%220%
SetUpKeyWrap(...)0%440%
ReadAdditionalAttributes(...)100%110%
ReadAdditionalElements(...)0%440%
ReadCipherData(...)100%110%
ReadCipherData(...)100%110%
WriteAdditionalAttributes(...)0%220%
WriteAdditionalElements(...)0%440%
WriteCipherData(...)100%110%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/EncryptedKey.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.Xml;
 6using CoreWCF.IdentityModel;
 7using CoreWCF.IdentityModel.Selectors;
 8using CoreWCF.IdentityModel.Tokens;
 9using CoreWCF.Runtime;
 10using DictionaryManager = CoreWCF.IdentityModel.DictionaryManager;
 11using ISecurityElement = CoreWCF.IdentityModel.ISecurityElement;
 12
 13namespace CoreWCF.Security
 14{
 15    internal sealed class EncryptedKey : EncryptedType
 16    {
 217        internal static readonly XmlDictionaryString CarriedKeyElementName = XD.XmlEncryptionDictionary.CarriedKeyName;
 218        internal static readonly XmlDictionaryString ElementName = XD.XmlEncryptionDictionary.EncryptedKey;
 219        internal static readonly XmlDictionaryString RecipientAttribute = XD.XmlEncryptionDictionary.Recipient;
 20        private byte[] _wrappedKey;
 21
 022        public string CarriedKeyName { get; set; }
 23
 024        public string Recipient { get; set; }
 25
 026        public ReferenceList ReferenceList { get; set; }
 27
 028        protected override XmlDictionaryString OpeningElementName => ElementName;
 29
 30        protected override void ForceEncryption()
 31        {
 32            // no work to be done here since, unlike bulk encryption, key wrapping is done eagerly
 033        }
 34
 35        public byte[] GetWrappedKey()
 36        {
 037            if (State == EncryptionState.New)
 38            {
 039                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.BadEncryption
 40            }
 041            return _wrappedKey;
 42        }
 43
 44        public void SetUpKeyWrap(byte[] wrappedKey)
 45        {
 046            if (State != EncryptionState.New)
 47            {
 048                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.BadEncryption
 49            }
 50
 051            _wrappedKey = wrappedKey ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(wrappedK
 052            State = EncryptionState.Encrypted;
 053        }
 54
 55        protected override void ReadAdditionalAttributes(XmlDictionaryReader reader)
 56        {
 057            Recipient = reader.GetAttribute(RecipientAttribute, null);
 058        }
 59
 60        protected override void ReadAdditionalElements(XmlDictionaryReader reader)
 61        {
 062            if (reader.IsStartElement(ReferenceList.ElementName, NamespaceUri))
 63            {
 064                ReferenceList = new ReferenceList();
 065                ReferenceList.ReadFrom(reader);
 66            }
 067            if (reader.IsStartElement(CarriedKeyElementName, NamespaceUri))
 68            {
 069                reader.ReadStartElement(CarriedKeyElementName, NamespaceUri);
 070                CarriedKeyName = reader.ReadString();
 071                reader.ReadEndElement();
 72            }
 073        }
 74
 75        protected override void ReadCipherData(XmlDictionaryReader reader)
 76        {
 077            _wrappedKey = reader.ReadContentAsBase64();
 078        }
 79
 80        protected override void ReadCipherData(XmlDictionaryReader reader, long maxBufferSize)
 81        {
 082            _wrappedKey = SecurityUtils.ReadContentAsBase64(reader, maxBufferSize);
 083        }
 84
 85        protected override void WriteAdditionalAttributes(XmlDictionaryWriter writer, DictionaryManager dictionaryManage
 86        {
 087            if (Recipient != null)
 88            {
 089                writer.WriteAttributeString(RecipientAttribute, null, Recipient);
 90            }
 091        }
 92
 93        protected override void WriteAdditionalElements(XmlDictionaryWriter writer, DictionaryManager dictionaryManager)
 94        {
 095            if (CarriedKeyName != null)
 96            {
 097                writer.WriteStartElement(CarriedKeyElementName, NamespaceUri);
 098                writer.WriteString(CarriedKeyName);
 099                writer.WriteEndElement(); // CarriedKeyName
 100            }
 0101            if (ReferenceList != null)
 102            {
 0103                ReferenceList.WriteTo(writer, dictionaryManager);
 104            }
 0105        }
 106
 107        protected override void WriteCipherData(XmlDictionaryWriter writer)
 108        {
 0109            writer.WriteBase64(_wrappedKey, 0, _wrappedKey.Length);
 0110        }
 111    }
 112
 113    internal abstract class EncryptedType : ISecurityElement
 114    {
 115        internal static readonly XmlDictionaryString NamespaceUri = XD.XmlEncryptionDictionary.Namespace;
 116        internal static readonly XmlDictionaryString EncodingAttribute = XD.XmlEncryptionDictionary.Encoding;
 117        internal static readonly XmlDictionaryString MimeTypeAttribute = XD.XmlEncryptionDictionary.MimeType;
 118        internal static readonly XmlDictionaryString TypeAttribute = XD.XmlEncryptionDictionary.Type;
 119        internal static readonly XmlDictionaryString CipherDataElementName = XD.XmlEncryptionDictionary.CipherData;
 120        internal static readonly XmlDictionaryString CipherValueElementName = XD.XmlEncryptionDictionary.CipherValue;
 121        private EncryptionMethodElement _encryptionMethod;
 122        private SecurityTokenSerializer _tokenSerializer;
 123
 124        protected EncryptedType()
 125        {
 126            _encryptionMethod.Init();
 127            State = EncryptionState.New;
 128            _tokenSerializer = new KeyInfoSerializer(false);
 129        }
 130
 131        public string Encoding { get; set; }
 132
 133        public string EncryptionMethod
 134        {
 135            get
 136            {
 137                return _encryptionMethod.algorithm;
 138            }
 139            set
 140            {
 141                _encryptionMethod.algorithm = value;
 142            }
 143        }
 144
 145        public XmlDictionaryString EncryptionMethodDictionaryString
 146        {
 147            get
 148            {
 149                return _encryptionMethod.algorithmDictionaryString;
 150            }
 151            set
 152            {
 153                _encryptionMethod.algorithmDictionaryString = value;
 154            }
 155        }
 156
 157        public bool HasId
 158        {
 159            get
 160            {
 161                return true;
 162            }
 163        }
 164
 165        public string Id { get; set; }
 166
 167        // This is set to true on the client side. And this means that when this knob is set to true and the default ser
 168        // to read the KeyInfo clause from the incoming response message from a service; then the ckient should
 169        // try to read the keyInfo clause as GenericXmlSecurityKeyIdentifierClause before throwing.
 170        public bool ShouldReadXmlReferenceKeyInfoClause { get; set; }
 171
 172        public string WsuId { get; set; }
 173
 174        public SecurityKeyIdentifier KeyIdentifier { get; set; }
 175
 176        public string MimeType { get; set; }
 177
 178        public string Type { get; set; }
 179
 180        protected abstract XmlDictionaryString OpeningElementName
 181        {
 182            get;
 183        }
 184
 185        protected EncryptionState State { get; set; }
 186
 187        public SecurityTokenSerializer SecurityTokenSerializer
 188        {
 189            get
 190            {
 191                return _tokenSerializer;
 192            }
 193            set
 194            {
 195                _tokenSerializer = value ?? new KeyInfoSerializer(false);
 196            }
 197        }
 198
 199        protected abstract void ForceEncryption();
 200
 201        protected virtual void ReadAdditionalAttributes(XmlDictionaryReader reader)
 202        {
 203        }
 204
 205        protected virtual void ReadAdditionalElements(XmlDictionaryReader reader)
 206        {
 207        }
 208
 209        protected abstract void ReadCipherData(XmlDictionaryReader reader);
 210        protected abstract void ReadCipherData(XmlDictionaryReader reader, long maxBufferSize);
 211
 212        public void ReadFrom(XmlReader reader)
 213        {
 214            ReadFrom(reader, 0);
 215        }
 216
 217        public void ReadFrom(XmlDictionaryReader reader)
 218        {
 219            ReadFrom(reader, 0);
 220        }
 221
 222        public void ReadFrom(XmlReader reader, long maxBufferSize)
 223        {
 224            ReadFrom(XmlDictionaryReader.CreateDictionaryReader(reader), maxBufferSize);
 225        }
 226
 227        public void ReadFrom(XmlDictionaryReader reader, long maxBufferSize)
 228        {
 229            ValidateReadState();
 230            reader.MoveToStartElement(OpeningElementName, NamespaceUri);
 231            Encoding = reader.GetAttribute(EncodingAttribute, null);
 232            Id = reader.GetAttribute(XD.XmlEncryptionDictionary.Id, null) ?? SecurityUniqueId.Create().Value;
 233            WsuId = reader.GetAttribute(XD.XmlEncryptionDictionary.Id, XD.UtilityDictionary.Namespace) ?? SecurityUnique
 234            MimeType = reader.GetAttribute(MimeTypeAttribute, null);
 235            Type = reader.GetAttribute(TypeAttribute, null);
 236            ReadAdditionalAttributes(reader);
 237            reader.Read();
 238
 239            if (reader.IsStartElement(EncryptionMethodElement.ElementName, NamespaceUri))
 240            {
 241                _encryptionMethod.ReadFrom(reader);
 242            }
 243
 244            if (_tokenSerializer.CanReadKeyIdentifier(reader))
 245            {
 246                XmlElement xml = null;
 247                XmlDictionaryReader localReader;
 248
 249                if (ShouldReadXmlReferenceKeyInfoClause)
 250                {
 251                    // We create the dom only when needed to not affect perf.
 252                    XmlDocument doc = new XmlDocument();
 253                    xml = (doc.ReadNode(reader) as XmlElement);
 254                    localReader = XmlDictionaryReader.CreateDictionaryReader(new XmlNodeReader(xml));
 255                }
 256                else
 257                {
 258                    localReader = reader;
 259                }
 260
 261                try
 262                {
 263                    KeyIdentifier = _tokenSerializer.ReadKeyIdentifier(localReader);
 264                }
 265                catch (Exception e)
 266                {
 267                    // In case when the issued token ( custom token) is used as an initiator token; we will fail
 268                    // to read the keyIdentifierClause using the plugged in default serializer. So We need to try to rea
 269                    // if it is the client side.
 270
 271                    if (Fx.IsFatal(e) || !ShouldReadXmlReferenceKeyInfoClause)
 272                    {
 273                        throw;
 274                    }
 275
 276                    KeyIdentifier = ReadGenericXmlSecurityKeyIdentifier(XmlDictionaryReader.CreateDictionaryReader(new X
 277                }
 278            }
 279
 280            reader.ReadStartElement(CipherDataElementName, NamespaceUri);
 281            reader.ReadStartElement(CipherValueElementName, NamespaceUri);
 282            if (maxBufferSize == 0)
 283            {
 284                ReadCipherData(reader);
 285            }
 286            else
 287            {
 288                ReadCipherData(reader, maxBufferSize);
 289            }
 290
 291            reader.ReadEndElement(); // CipherValue
 292            reader.ReadEndElement(); // CipherData
 293
 294            ReadAdditionalElements(reader);
 295            reader.ReadEndElement(); // OpeningElementName
 296            State = EncryptionState.Read;
 297        }
 298
 299        private SecurityKeyIdentifier ReadGenericXmlSecurityKeyIdentifier(XmlDictionaryReader localReader, Exception pre
 300        {
 301            if (!localReader.IsStartElement(XD.XmlSignatureDictionary.KeyInfo, XD.XmlSignatureDictionary.Namespace))
 302            {
 303                return null;
 304            }
 305
 306            localReader.ReadStartElement(XD.XmlSignatureDictionary.KeyInfo, XD.XmlSignatureDictionary.Namespace);
 307            SecurityKeyIdentifier keyIdentifier = new SecurityKeyIdentifier();
 308
 309            if (localReader.IsStartElement())
 310            {
 311                string strId = localReader.GetAttribute(XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace
 312                XmlDocument doc = new XmlDocument();
 313                XmlElement keyIdentifierReferenceXml = (doc.ReadNode(localReader) as XmlElement);
 314                SecurityKeyIdentifierClause clause = new GenericXmlSecurityKeyIdentifierClause(keyIdentifierReferenceXml
 315                if (!string.IsNullOrEmpty(strId))
 316                {
 317                    clause.Id = strId;
 318                }
 319
 320                keyIdentifier.Add(clause);
 321            }
 322
 323            if (keyIdentifier.Count == 0)
 324            {
 325                throw previousException;
 326            }
 327
 328            localReader.ReadEndElement();
 329            return keyIdentifier;
 330        }
 331
 332        protected virtual void WriteAdditionalAttributes(XmlDictionaryWriter writer, DictionaryManager dictionaryManager
 333        {
 334        }
 335
 336        protected virtual void WriteAdditionalElements(XmlDictionaryWriter writer, DictionaryManager dictionaryManager)
 337        {
 338        }
 339
 340        protected abstract void WriteCipherData(XmlDictionaryWriter writer);
 341
 342        public void WriteTo(XmlDictionaryWriter writer, DictionaryManager dictionaryManager)
 343        {
 344            if (writer == null)
 345            {
 346                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(writer));
 347            }
 348            ValidateWriteState();
 349            writer.WriteStartElement(XmlEncryptionStrings.Prefix, OpeningElementName, NamespaceUri);
 350            if (Id != null && Id.Length != 0)
 351            {
 352                writer.WriteAttributeString(XD.XmlEncryptionDictionary.Id, null, Id);
 353            }
 354            if (Type != null)
 355            {
 356                writer.WriteAttributeString(TypeAttribute, null, Type);
 357            }
 358            if (MimeType != null)
 359            {
 360                writer.WriteAttributeString(MimeTypeAttribute, null, MimeType);
 361            }
 362            if (Encoding != null)
 363            {
 364                writer.WriteAttributeString(EncodingAttribute, null, Encoding);
 365            }
 366            WriteAdditionalAttributes(writer, dictionaryManager);
 367            if (_encryptionMethod.algorithm != null)
 368            {
 369                _encryptionMethod.WriteTo(writer);
 370            }
 371            if (KeyIdentifier != null)
 372            {
 373                _tokenSerializer.WriteKeyIdentifier(writer, KeyIdentifier);
 374            }
 375
 376            writer.WriteStartElement(CipherDataElementName, NamespaceUri);
 377            writer.WriteStartElement(CipherValueElementName, NamespaceUri);
 378            WriteCipherData(writer);
 379            writer.WriteEndElement(); // CipherValue
 380            writer.WriteEndElement(); // CipherData
 381
 382            WriteAdditionalElements(writer, dictionaryManager);
 383            writer.WriteEndElement(); // OpeningElementName
 384        }
 385
 386        private void ValidateReadState()
 387        {
 388            if (State != EncryptionState.New)
 389            {
 390                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityMessageSerializationException(SR.B
 391            }
 392        }
 393
 394        private void ValidateWriteState()
 395        {
 396            if (State == EncryptionState.EncryptionSetup)
 397            {
 398                ForceEncryption();
 399            }
 400            else if (State == EncryptionState.New)
 401            {
 402                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityMessageSerializationException(SR.B
 403            }
 404        }
 405
 406        protected enum EncryptionState
 407        {
 408            New,
 409            Read,
 410            DecryptionSetup,
 411            Decrypted,
 412            EncryptionSetup,
 413            Encrypted
 414        }
 415
 416        private struct EncryptionMethodElement
 417        {
 418            internal string algorithm;
 419            internal XmlDictionaryString algorithmDictionaryString;
 420            internal static readonly XmlDictionaryString ElementName = XD.XmlEncryptionDictionary.EncryptionMethod;
 421
 422            public void Init()
 423            {
 424                algorithm = null;
 425            }
 426
 427            public void ReadFrom(XmlDictionaryReader reader)
 428            {
 429                reader.MoveToStartElement(ElementName, XD.XmlEncryptionDictionary.Namespace);
 430                bool isEmptyElement = reader.IsEmptyElement;
 431                algorithm = reader.GetAttribute(XD.XmlSignatureDictionary.Algorithm, null);
 432                if (algorithm == null)
 433                {
 434                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityMessageSerializationException(
 435                        SR.Format(SR.RequiredAttributeMissing, XD.XmlSignatureDictionary.Algorithm.Value, ElementName.Va
 436                }
 437                reader.Read();
 438                if (!isEmptyElement)
 439                {
 440                    while (reader.IsStartElement())
 441                    {
 442                        reader.Skip();
 443                    }
 444                    reader.ReadEndElement();
 445                }
 446            }
 447
 448            public void WriteTo(XmlDictionaryWriter writer)
 449            {
 450                writer.WriteStartElement(XmlEncryptionStrings.Prefix, ElementName, XD.XmlEncryptionDictionary.Namespace)
 451                if (algorithmDictionaryString != null)
 452                {
 453                    writer.WriteStartAttribute(XD.XmlSignatureDictionary.Algorithm, null);
 454                    writer.WriteString(algorithmDictionaryString);
 455                    writer.WriteEndAttribute();
 456                }
 457                else
 458                {
 459                    writer.WriteAttributeString(XD.XmlSignatureDictionary.Algorithm, null, algorithm);
 460                }
 461                if (algorithm == XD.SecurityAlgorithmDictionary.RsaOaepKeyWrap.Value)
 462                {
 463                    writer.WriteStartElement(XmlSignatureStrings.Prefix, XD.XmlSignatureDictionary.DigestMethod, XD.XmlS
 464                    writer.WriteStartAttribute(XD.XmlSignatureDictionary.Algorithm, null);
 465                    writer.WriteString(XD.SecurityAlgorithmDictionary.Sha1Digest);
 466                    writer.WriteEndAttribute();
 467                    writer.WriteEndElement();
 468                }
 469                writer.WriteEndElement(); // EncryptionMethod
 470            }
 471        }
 472    }
 473}