< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.IdentityModel.Tokens.RsaSecurityKey
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/IdentityModel/Tokens/RsaSecurityKey.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 97
Coverable lines: 97
Total lines: 278
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 76
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)0%220%
DecryptKey(...)0%660%
EncryptKey(...)0%660%
GetAsymmetricAlgorithm(...)0%440%
GetHashAlgorithmForSignature(...)0%12120%
GetSignatureDeformatter(...)0%12120%
GetSignatureFormatter(...)0%12120%
HasPrivateKey()0%660%
IsSupportedAlgorithm(...)0%16160%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/IdentityModel/Tokens/RsaSecurityKey.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.Security.Cryptography;
 6using System.Security.Cryptography.Xml;
 7
 8namespace CoreWCF.IdentityModel.Tokens
 9{
 10    public sealed class RsaSecurityKey : AsymmetricSecurityKey
 11    {
 12        private PrivateKeyStatus _privateKeyStatus = PrivateKeyStatus.AvailabilityNotDetermined;
 13        private readonly RSA _rsa;
 14
 015        public RsaSecurityKey(RSA rsa)
 16        {
 017            _rsa = rsa ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(rsa));
 018        }
 19
 20        public override int KeySize
 21        {
 022            get { return _rsa.KeySize; }
 23        }
 24
 25        public override byte[] DecryptKey(string algorithm, byte[] keyData)
 26        {
 27            switch (algorithm)
 28            {
 29                case SecurityAlgorithms.RsaV15KeyWrap:
 030                    return EncryptedXml.DecryptKey(keyData, _rsa, false);
 31                case SecurityAlgorithms.RsaOaepKeyWrap:
 032                    return EncryptedXml.DecryptKey(keyData, _rsa, true);
 33                default:
 034                    if (IsSupportedAlgorithm(algorithm))
 35                    {
 036                        return EncryptedXml.DecryptKey(keyData, _rsa, false);
 37                    }
 38
 039                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.Format("c",
 040                 algorithm, "DecryptKey")));
 41            }
 42        }
 43
 44        public override byte[] EncryptKey(string algorithm, byte[] keyData)
 45        {
 46            switch (algorithm)
 47            {
 48                case SecurityAlgorithms.RsaV15KeyWrap:
 049                    return EncryptedXml.EncryptKey(keyData, _rsa, false);
 50                case SecurityAlgorithms.RsaOaepKeyWrap:
 051                    return EncryptedXml.EncryptKey(keyData, _rsa, true);
 52                default:
 053                    if (IsSupportedAlgorithm(algorithm))
 54                    {
 055                        return EncryptedXml.EncryptKey(keyData, _rsa, false);
 56                    }
 57
 058                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.Format(SR.Un
 059                        algorithm, nameof(EncryptKey))));
 60            }
 61        }
 62
 63        public override AsymmetricAlgorithm GetAsymmetricAlgorithm(string algorithm, bool requiresPrivateKey)
 64        {
 065            if (requiresPrivateKey && !HasPrivateKey())
 66            {
 067                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.NoPrivateKeyAvai
 68            }
 69
 070            return _rsa;
 71        }
 72
 73        public override HashAlgorithm GetHashAlgorithmForSignature(string algorithm)
 74        {
 075            if (string.IsNullOrEmpty(algorithm))
 76            {
 077                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(algorithm, SR.Format(SR.EmptyOrNullArgument
 78            }
 79
 080            object algorithmObject = CryptoHelper.GetAlgorithmFromConfig(algorithm);
 81
 082            if (algorithmObject != null)
 83            {
 084                if (algorithmObject is SignatureDescription description)
 85                {
 086                    return description.CreateDigest();
 87                }
 88
 089                if (algorithmObject is HashAlgorithm hashAlgorithm)
 90                {
 091                    return hashAlgorithm;
 92                }
 93
 094                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.Format(SR.Unsupp
 095                        algorithm)));
 96            }
 97
 98            switch (algorithm)
 99            {
 100                case SecurityAlgorithms.RsaSha1Signature:
 0101                    return CryptoHelper.NewSha1HashAlgorithm();
 102                case SecurityAlgorithms.RsaSha256Signature:
 0103                    return CryptoHelper.NewSha256HashAlgorithm();
 104                default:
 0105                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.Format(SR.Un
 0106                        algorithm, "GetHashAlgorithmForSignature")));
 107            }
 108        }
 109
 110        public override AsymmetricSignatureDeformatter GetSignatureDeformatter(string algorithm)
 111        {
 0112            if (string.IsNullOrEmpty(algorithm))
 113            {
 0114                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(algorithm, SR.Format(SR.EmptyOrNullArgument
 115            }
 116
 0117            object algorithmObject = CryptoHelper.GetAlgorithmFromConfig(algorithm);
 0118            if (algorithmObject != null)
 119            {
 0120                if (algorithmObject is SignatureDescription description)
 121                {
 0122                    return description.CreateDeformatter(_rsa);
 123                }
 124
 125                try
 126                {
 0127                    if (algorithmObject is AsymmetricSignatureDeformatter asymmetricSignatureDeformatter)
 128                    {
 0129                        asymmetricSignatureDeformatter.SetKey(_rsa);
 0130                        return asymmetricSignatureDeformatter;
 131                    }
 0132                }
 0133                catch (InvalidCastException e)
 134                {
 0135                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.Format(SR.Alg
 136                }
 137
 0138                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.Format(SR.Unsupp
 0139                       algorithm, "GetSignatureDeformatter")));
 140            }
 141
 142            switch (algorithm)
 143            {
 144                case SecurityAlgorithms.RsaSha1Signature:
 145                case SecurityAlgorithms.RsaSha256Signature:
 0146                    return new RSAPKCS1SignatureDeformatter(_rsa);
 147                default:
 0148                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.Format(SR.Un
 0149                        algorithm, "GetSignatureDeformatter")));
 150            }
 0151        }
 152
 153        public override AsymmetricSignatureFormatter GetSignatureFormatter(string algorithm)
 154        {
 0155            if (string.IsNullOrEmpty(algorithm))
 156            {
 0157                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(algorithm, SR.Format(SR.EmptyOrNullArgument
 158            }
 159
 0160            object algorithmObject = CryptoHelper.GetAlgorithmFromConfig(algorithm);
 0161            if (algorithmObject != null)
 162            {
 0163                if (algorithmObject is SignatureDescription description)
 164                {
 0165                    return description.CreateFormatter(_rsa);
 166                }
 167
 168                try
 169                {
 0170                    if (algorithmObject is AsymmetricSignatureFormatter asymmetricSignatureFormatter)
 171                    {
 0172                        asymmetricSignatureFormatter.SetKey(_rsa);
 0173                        return asymmetricSignatureFormatter;
 174                    }
 0175                }
 0176                catch (InvalidCastException e)
 177                {
 0178                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.Format(SR.Alg
 179                }
 180
 0181                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.Format(SR.Unsupp
 0182                       algorithm, nameof(GetSignatureFormatter))));
 183            }
 184
 185            switch (algorithm)
 186            {
 187                case SecurityAlgorithms.RsaSha1Signature:
 188                case SecurityAlgorithms.RsaSha256Signature:
 189                    // Ensure that we have an RSA algorithm object.
 0190                    return new RSAPKCS1SignatureFormatter(_rsa);
 191                default:
 0192                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.Format(SR.Un
 0193                        algorithm, "GetSignatureFormatter")));
 194            }
 0195        }
 196
 197        public override bool HasPrivateKey()
 198        {
 0199            if (_privateKeyStatus == PrivateKeyStatus.AvailabilityNotDetermined)
 200            {
 0201                if (_rsa is RSACryptoServiceProvider rsaCryptoServiceProvider)
 202                {
 0203                    _privateKeyStatus = rsaCryptoServiceProvider.PublicOnly
 0204                        ? PrivateKeyStatus.DoesNotHavePrivateKey
 0205                        : PrivateKeyStatus.HasPrivateKey;
 206                }
 207                else
 208                {
 209                    try
 210                    {
 0211                        byte[] hash = new byte[20];
 0212                        _rsa.DecryptValue(hash); // imitate signing
 0213                        _privateKeyStatus = PrivateKeyStatus.HasPrivateKey;
 0214                    }
 215#pragma warning disable CA1031 // Do not catch general exception types - interpret as no private key, don't need to use 
 0216                    catch (CryptographicException)
 217                    {
 0218                        _privateKeyStatus = PrivateKeyStatus.DoesNotHavePrivateKey;
 0219                    }
 220#pragma warning restore CA1031 // Do not catch general exception types
 221                }
 222            }
 0223            return _privateKeyStatus == PrivateKeyStatus.HasPrivateKey;
 224        }
 225
 226        public override bool IsSupportedAlgorithm(string algorithm)
 227        {
 0228            if (string.IsNullOrEmpty(algorithm))
 229            {
 0230                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(algorithm, SR.Format(SR.EmptyOrNullArgument
 231            }
 232            object algorithmObject;
 233            try
 234            {
 0235                algorithmObject = CryptoHelper.GetAlgorithmFromConfig(algorithm);
 0236            }
 237#pragma warning disable CA1031 // Do not catch general exception types
 0238            catch (InvalidOperationException)
 239            {
 0240                algorithmObject = null;
 241                // We swallow the exception and continue.
 0242            }
 243#pragma warning restore CA1031 // Do not catch general exception types
 244
 0245            if (algorithmObject != null)
 246            {
 0247                if (algorithmObject is SignatureDescription signatureDescription)
 248                {
 0249                    return true;
 250                }
 251
 0252                if (algorithmObject is AsymmetricAlgorithm asymmetricAlgorithm)
 253                {
 0254                    return true;
 255                }
 256
 0257                return false;
 258            }
 259            switch (algorithm)
 260            {
 261                case SecurityAlgorithms.RsaV15KeyWrap:
 262                case SecurityAlgorithms.RsaOaepKeyWrap:
 263                case SecurityAlgorithms.RsaSha1Signature:
 264                case SecurityAlgorithms.RsaSha256Signature:
 0265                    return true;
 266                default:
 0267                    return false;
 268            }
 269        }
 270
 271        private enum PrivateKeyStatus
 272        {
 273            AvailabilityNotDetermined,
 274            HasPrivateKey,
 275            DoesNotHavePrivateKey
 276        }
 277    }
 278}