< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Security.SecurityHeaderTokenResolver
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/SecurityHeaderTokenResolver.cs
Line coverage
30%
Covered lines: 38
Uncovered lines: 88
Coverable lines: 126
Total lines: 318
Line coverage: 30.1%
Branch coverage
25%
Covered branches: 24
Total branches: 94
Branch coverage: 25.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor()100%110%
.ctor(...)100%11100%
Add(...)100%110%
Add(...)50%6671.42%
EnsureCapacityToAddToken()50%2240%
CheckExternalWrapperMatch(...)0%880%
ResolveToken(...)50%6671.42%
ResolveSecurityKeyCore(...)0%10100%
MatchDirectReference(...)0%220%
ResolveToken(...)30.35%565627.65%
ToString()0%220%
TryResolveTokenCore(...)100%11100%
TryResolveToken(...)100%110%
TryResolveTokenCore(...)100%110%
TryResolveToken(...)100%110%
TryResolveSecurityKey(...)0%220%
TryResolveSecurityKeyCore(...)100%110%
.ctor(...)100%11100%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/SecurityHeaderTokenResolver.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.Globalization;
 6using System.IO;
 7using System.Security.Cryptography.X509Certificates;
 8using CoreWCF.IdentityModel;
 9using CoreWCF.IdentityModel.Selectors;
 10using CoreWCF.IdentityModel.Tokens;
 11using CoreWCF.Security.Tokens;
 12
 13namespace CoreWCF.Security
 14{
 15    internal sealed class SecurityHeaderTokenResolver : SecurityTokenResolver
 16    {
 17        private const int InitialTokenArraySize = 10;
 18        private int _tokenCount;
 19        private SecurityTokenEntry[] _tokens;
 20        private readonly ReceiveSecurityHeader _securityHeader;
 21
 22        public SecurityHeaderTokenResolver()
 023            : this(null)
 24        {
 025        }
 26
 18827        public SecurityHeaderTokenResolver(ReceiveSecurityHeader securityHeader)
 28        {
 18829            _tokens = new SecurityTokenEntry[InitialTokenArraySize];
 18830            _securityHeader = securityHeader;
 18831        }
 32
 033        public SecurityToken ExpectedWrapper { get; set; }
 34
 035        public SecurityTokenParameters ExpectedWrapperTokenParameters { get; set; }
 36
 37        public void Add(SecurityToken token)
 38        {
 039            Add(token, SecurityTokenReferenceStyle.Internal, null);
 040        }
 41
 42        public void Add(SecurityToken token, SecurityTokenReferenceStyle allowedReferenceStyle, SecurityTokenParameters 
 43        {
 6444            if (token == null)
 45            {
 046                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(token));
 47            }
 48
 6449            if ((allowedReferenceStyle == SecurityTokenReferenceStyle.External) && (tokenParameters == null))
 50            {
 051                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.ResolvingExternalTokensRequireSecurityTo
 52            }
 53
 6454            EnsureCapacityToAddToken();
 6455            _tokens[_tokenCount++] = new SecurityTokenEntry(token, tokenParameters, allowedReferenceStyle);
 6456        }
 57
 58        private void EnsureCapacityToAddToken()
 59        {
 6460            if (_tokenCount == _tokens.Length)
 61            {
 062                SecurityTokenEntry[] newTokens = new SecurityTokenEntry[_tokens.Length * 2];
 063                Array.Copy(_tokens, 0, newTokens, 0, _tokenCount);
 064                _tokens = newTokens;
 65            }
 6466        }
 67
 68        public bool CheckExternalWrapperMatch(SecurityKeyIdentifier keyIdentifier)
 69        {
 070            if (ExpectedWrapper == null || ExpectedWrapperTokenParameters == null)
 71            {
 072                return false;
 73            }
 74
 075            for (int i = 0; i < keyIdentifier.Count; i++)
 76            {
 077                if (ExpectedWrapperTokenParameters.MatchesKeyIdentifierClause(ExpectedWrapper, keyIdentifier[i], Securit
 78                {
 079                    return true;
 80                }
 81            }
 082            return false;
 83        }
 84
 85        internal SecurityToken ResolveToken(SecurityKeyIdentifier keyIdentifier, bool matchOnlyExternalTokens, bool reso
 86        {
 2387            if (keyIdentifier == null)
 88            {
 089                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(keyIdentifier));
 90            }
 4691            for (int i = 0; i < keyIdentifier.Count; i++)
 92            {
 2393                SecurityToken token = ResolveToken(keyIdentifier[i], matchOnlyExternalTokens, resolveIntrinsicKeyClause)
 2394                if (token != null)
 95                {
 2396                    return token;
 97                }
 98            }
 099            return null;
 100        }
 101
 102        private SecurityKey ResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, bool createIntrinsic
 103        {
 0104            if (keyIdentifierClause == null)
 105            {
 0106                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(keyIdentifier
 107            }
 108
 109            SecurityKey securityKey;
 0110            for (int i = 0; i < _tokenCount; i++)
 111            {
 0112                securityKey = _tokens[i].Token.ResolveKeyIdentifierClause(keyIdentifierClause);
 0113                if (securityKey != null)
 114                {
 0115                    return securityKey;
 116                }
 117            }
 118
 0119            if (createIntrinsicKeys)
 120            {
 0121                if (SecurityUtils.TryCreateKeyFromIntrinsicKeyClause(keyIdentifierClause, this, out securityKey))
 122                {
 0123                    return securityKey;
 124                }
 125            }
 126
 0127            return null;
 128        }
 129
 130        private bool MatchDirectReference(SecurityToken token, SecurityKeyIdentifierClause keyClause)
 131        {
 0132            if (!(keyClause is LocalIdKeyIdentifierClause localClause))
 133            {
 0134                return false;
 135            }
 136
 0137            return token.MatchesKeyIdentifierClause(localClause);
 138        }
 139
 140        internal SecurityToken ResolveToken(SecurityKeyIdentifierClause keyIdentifierClause, bool matchOnlyExternal, boo
 141        {
 23142            if (keyIdentifierClause == null)
 143            {
 0144                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(keyIdentifierClause));
 145            }
 146
 23147            SecurityToken resolvedToken = null;
 46148            for (int i = 0; i < _tokenCount; i++)
 149            {
 23150                if (matchOnlyExternal && _tokens[i].AllowedReferenceStyle != SecurityTokenReferenceStyle.External)
 151                {
 152                    continue;
 153                }
 154
 23155                SecurityToken token = _tokens[i].Token;
 23156                if (_tokens[i].TokenParameters != null && _tokens[i].TokenParameters.MatchesKeyIdentifierClause(token, k
 157                {
 23158                    resolvedToken = token;
 23159                    break;
 160                }
 0161                else if (_tokens[i].TokenParameters == null)
 162                {
 163                    // match it according to the allowed reference style
 0164                    if (_tokens[i].AllowedReferenceStyle == SecurityTokenReferenceStyle.Internal && MatchDirectReference
 165                    {
 0166                        resolvedToken = token;
 0167                        break;
 168                    }
 169                }
 170            }
 171
 23172            if ((resolvedToken == null) && (keyIdentifierClause is EncryptedKeyIdentifierClause))
 173            {
 0174                EncryptedKeyIdentifierClause keyClause = (EncryptedKeyIdentifierClause)keyIdentifierClause;
 0175                SecurityKeyIdentifier wrappingTokenReference = keyClause.EncryptingKeyIdentifier;
 176                SecurityToken unwrappingToken;
 0177                if (ExpectedWrapper != null
 0178                    && CheckExternalWrapperMatch(wrappingTokenReference))
 179                {
 0180                    unwrappingToken = ExpectedWrapper;
 181                }
 182                else
 183                {
 0184                    unwrappingToken = ResolveToken(wrappingTokenReference, true, resolveIntrinsicKeyClause);
 185                }
 186
 0187                if (unwrappingToken != null)
 188                {
 0189                    resolvedToken = SecurityUtils.CreateTokenFromEncryptedKeyClause(keyClause, unwrappingToken);
 190                }
 191            }
 23192            if ((resolvedToken == null) && (keyIdentifierClause is X509RawDataKeyIdentifierClause) && (!matchOnlyExterna
 193            {
 0194                resolvedToken = new X509SecurityToken(new X509Certificate2(((X509RawDataKeyIdentifierClause)keyIdentifie
 195            }
 23196            byte[] derivationNonce = keyIdentifierClause.GetDerivationNonce();
 23197            if ((resolvedToken != null) && (derivationNonce != null))
 198            {
 199                // A Implicit Derived Key is specified. Create a derived key off of the resolve token.
 0200                if (SecurityUtils.GetSecurityKey<SymmetricSecurityKey>(resolvedToken) == null)
 201                {
 202                    // The resolved token contains no Symmetric Security key and thus we cannot create
 203                    // a derived key off of it.
 0204                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.Format(SR.
 205                }
 206
 0207                int derivationLength = (keyIdentifierClause.DerivationLength == 0) ? DerivedKeySecurityToken.DefaultDeri
 0208                if (derivationLength > _securityHeader.MaxDerivedKeyLength)
 209                {
 0210                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.Format(SR.
 211                }
 212
 0213                bool alreadyDerived = false;
 0214                for (int i = 0; i < _tokenCount; ++i)
 215                {
 0216                    if (_tokens[i].Token is DerivedKeySecurityToken derivedKeyToken)
 217                    {
 0218                        if ((derivedKeyToken.Length == derivationLength) &&
 0219                            (CryptoHelper.IsEqual(derivedKeyToken.Nonce, derivationNonce)) &&
 0220                            (derivedKeyToken.TokenToDerive.MatchesKeyIdentifierClause(keyIdentifierClause)))
 221                        {
 222                            // This is a implcit derived key for which we have already derived the
 223                            // token.
 0224                            resolvedToken = _tokens[i].Token;
 0225                            alreadyDerived = true;
 0226                            break;
 227                        }
 228                    }
 229                }
 230
 0231                if (!alreadyDerived)
 232                {
 0233                    string psha1Algorithm = SecurityUtils.GetKeyDerivationAlgorithm(_securityHeader.StandardsManager.Mes
 234
 0235                    resolvedToken = new DerivedKeySecurityToken(-1, 0, derivationLength, null, derivationNonce, resolved
 0236                    ((DerivedKeySecurityToken)resolvedToken).InitializeDerivedKey(derivationLength);
 0237                    Add(resolvedToken, SecurityTokenReferenceStyle.Internal, null);
 0238                    _securityHeader.EnsureDerivedKeyLimitNotReached();
 239                }
 240            }
 241
 23242            return resolvedToken;
 243        }
 244
 245        public override string ToString()
 246        {
 0247            using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
 248            {
 0249                writer.WriteLine("SecurityTokenResolver");
 0250                writer.WriteLine("    (");
 0251                writer.WriteLine("    TokenCount = {0},", _tokenCount);
 0252                for (int i = 0; i < _tokenCount; i++)
 253                {
 0254                    writer.WriteLine("    TokenEntry[{0}] = (AllowedReferenceStyle={1}, Token={2}, Parameters={3})",
 0255                        i, _tokens[i].AllowedReferenceStyle, _tokens[i].Token.GetType(), _tokens[i].TokenParameters);
 256                }
 0257                writer.WriteLine("    )");
 0258                return writer.ToString();
 259            }
 0260        }
 261
 262        protected override bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token)
 263        {
 23264            token = ResolveToken(keyIdentifier, false, true);
 23265            return token != null;
 266        }
 267
 268        internal bool TryResolveToken(SecurityKeyIdentifier keyIdentifier, bool matchOnlyExternalTokens, bool resolveInt
 269        {
 0270            token = ResolveToken(keyIdentifier, matchOnlyExternalTokens, resolveIntrinsicKeyClause);
 0271            return token != null;
 272        }
 273
 274        protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken t
 275        {
 0276            token = ResolveToken(keyIdentifierClause, false, true);
 0277            return token != null;
 278        }
 279
 280        internal bool TryResolveToken(SecurityKeyIdentifierClause keyIdentifierClause, bool matchOnlyExternalTokens, boo
 281        {
 0282            token = ResolveToken(keyIdentifierClause, matchOnlyExternalTokens, resolveIntrinsicKeyClause);
 0283            return token != null;
 284        }
 285
 286        internal bool TryResolveSecurityKey(SecurityKeyIdentifierClause keyIdentifierClause, bool createIntrinsicKeys, o
 287        {
 0288            if (keyIdentifierClause == null)
 289            {
 0290                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(keyIdentifierClause));
 291            }
 0292            key = ResolveSecurityKeyCore(keyIdentifierClause, createIntrinsicKeys);
 0293            return key != null;
 294        }
 295
 296        protected override bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityK
 297        {
 0298            key = ResolveSecurityKeyCore(keyIdentifierClause, true);
 0299            return key != null;
 300        }
 301
 302        private struct SecurityTokenEntry
 303        {
 304            public SecurityTokenEntry(SecurityToken token, SecurityTokenParameters tokenParameters, SecurityTokenReferen
 305            {
 64306                Token = token;
 64307                TokenParameters = tokenParameters;
 64308                AllowedReferenceStyle = allowedReferenceStyle;
 64309            }
 310
 23311            public SecurityToken Token { get; }
 312
 46313            public SecurityTokenParameters TokenParameters { get; }
 314
 23315            public SecurityTokenReferenceStyle AllowedReferenceStyle { get; }
 316        }
 317    }
 318}

Methods/Properties

.ctor()
.ctor(CoreWCF.Security.ReceiveSecurityHeader)
ExpectedWrapper()
ExpectedWrapperTokenParameters()
Add(CoreWCF.IdentityModel.Tokens.SecurityToken)
Add(CoreWCF.IdentityModel.Tokens.SecurityToken,CoreWCF.Security.Tokens.SecurityTokenReferenceStyle,CoreWCF.Security.Tokens.SecurityTokenParameters)
EnsureCapacityToAddToken()
CheckExternalWrapperMatch(CoreWCF.IdentityModel.Tokens.SecurityKeyIdentifier)
ResolveToken(CoreWCF.IdentityModel.Tokens.SecurityKeyIdentifier,System.Boolean,System.Boolean)
ResolveSecurityKeyCore(CoreWCF.IdentityModel.SecurityKeyIdentifierClause,System.Boolean)
MatchDirectReference(CoreWCF.IdentityModel.Tokens.SecurityToken,CoreWCF.IdentityModel.SecurityKeyIdentifierClause)
ResolveToken(CoreWCF.IdentityModel.SecurityKeyIdentifierClause,System.Boolean,System.Boolean)
ToString()
TryResolveTokenCore(CoreWCF.IdentityModel.Tokens.SecurityKeyIdentifier,CoreWCF.IdentityModel.Tokens.SecurityToken&)
TryResolveToken(CoreWCF.IdentityModel.Tokens.SecurityKeyIdentifier,System.Boolean,System.Boolean,CoreWCF.IdentityModel.Tokens.SecurityToken&)
TryResolveTokenCore(CoreWCF.IdentityModel.SecurityKeyIdentifierClause,CoreWCF.IdentityModel.Tokens.SecurityToken&)
TryResolveToken(CoreWCF.IdentityModel.SecurityKeyIdentifierClause,System.Boolean,System.Boolean,CoreWCF.IdentityModel.Tokens.SecurityToken&)
TryResolveSecurityKey(CoreWCF.IdentityModel.SecurityKeyIdentifierClause,System.Boolean,CoreWCF.IdentityModel.Tokens.SecurityKey&)
TryResolveSecurityKeyCore(CoreWCF.IdentityModel.SecurityKeyIdentifierClause,CoreWCF.IdentityModel.Tokens.SecurityKey&)
.ctor(CoreWCF.IdentityModel.Tokens.SecurityToken,CoreWCF.Security.Tokens.SecurityTokenParameters,CoreWCF.Security.Tokens.SecurityTokenReferenceStyle)
Token()
TokenParameters()
AllowedReferenceStyle()