예제 #1
0
        /// <summary>
        /// Trys to adds a <see cref="SignatureProvider"/> to this cache.
        /// </summary>
        /// <param name="signatureProvider"><see cref="SignatureProvider"/> to cache.</param>
        /// <exception cref="ArgumentNullException">if signatureProvider is null.</exception>
        /// <returns>true if the <see cref="SignatureProvider"/> was added, false if the cache already contained the <see cref="SignatureProvider"/></returns>
        /// <remarks>if the <see cref="SignatureProvider"/> is added <see cref="SignatureProvider.CryptoProviderCache"/> will be set to 'this'.</remarks>
        public override bool TryAdd(SignatureProvider signatureProvider)
        {
            if (signatureProvider == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(signatureProvider));
            }

            var cacheKey = GetCacheKey(signatureProvider);

            if (signatureProvider.WillCreateSignatures)
            {
                if (_signingSignatureProviders.TryAdd(cacheKey, signatureProvider))
                {
                    signatureProvider.CryptoProviderCache = this;
                    return(true);
                }
            }
            else
            {
                if (_verifyingSignatureProviders.TryAdd(cacheKey, signatureProvider))
                {
                    signatureProvider.CryptoProviderCache = this;
                    return(true);
                }
            }

            return(false);
        }
        /// <summary>
        /// Trys to remove a <see cref="SignatureProvider"/> from this cache.
        /// </summary>
        /// <param name="signatureProvider"><see cref="SignatureProvider"/> to remove.</param>
        /// <exception cref="ArgumentNullException">if signatureProvider is null.</exception>
        /// <returns>true if the <see cref="SignatureProvider"/> was removed, false if the <see cref="SignatureProvider"/> was not found.</returns>
        /// <remarks>if the <see cref="SignatureProvider"/> is removed <see cref="SignatureProvider.CryptoProviderCache"/> will be set to null.</remarks>
        public override bool TryRemove(SignatureProvider signatureProvider)
        {
            if (signatureProvider == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(signatureProvider));
            }

            if (!ReferenceEquals(signatureProvider.CryptoProviderCache, this))
            {
                return(false);
            }

            var cacheKey = GetCacheKey(signatureProvider);
            EventBasedLRUCache <string, SignatureProvider> signatureProviderCache;

            // Determine if we are caching a signing or a verifying SignatureProvider.
            if (signatureProvider.WillCreateSignatures)
            {
                signatureProviderCache = _signingSignatureProviders;
            }
            else
            {
                signatureProviderCache = _verifyingSignatureProviders;
            }

            try
            {
                return(signatureProviderCache.TryRemove(cacheKey, out SignatureProvider provider));
            }
            catch (Exception ex)
            {
                LogHelper.LogWarning(LogHelper.FormatInvariant(LogMessages.IDX10699, cacheKey, ex));
                return(false);
            }
        }
        /// <summary>
        /// Trys to adds a <see cref="SignatureProvider"/> to this cache.
        /// </summary>
        /// <param name="signatureProvider"><see cref="SignatureProvider"/> to cache.</param>
        /// <exception cref="ArgumentNullException">if signatureProvider is null.</exception>
        /// <returns>
        /// <c>true</c> if the <see cref="SignatureProvider"/> was added, <c>false</c> if the cache already contained the <see cref="SignatureProvider"/> or if <see cref="SignatureProvider"/> should not be cached.
        /// </returns>
        /// <remarks>if the <see cref="SignatureProvider"/> is added <see cref="SignatureProvider.CryptoProviderCache"/> will be set to 'this'.</remarks>
        public override bool TryAdd(SignatureProvider signatureProvider)
        {
            if (signatureProvider == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(signatureProvider));
            }

            var cacheKey = GetCacheKey(signatureProvider);
            EventBasedLRUCache <string, SignatureProvider> signatureProviderCache;

            // Determine if we are caching a signing or a verifying SignatureProvider.
            if (signatureProvider.WillCreateSignatures)
            {
                signatureProviderCache = _signingSignatureProviders;
            }
            else
            {
                signatureProviderCache = _verifyingSignatureProviders;
            }

            // The cache does NOT already have a crypto provider associated with this key.
            if (!signatureProviderCache.Contains(cacheKey))
            {
                signatureProviderCache.SetValue(cacheKey, signatureProvider);
                signatureProvider.CryptoProviderCache = this;
                return(true);
            }

            return(false);
        }
예제 #4
0
        /// <summary>
        /// Trys to remove a <see cref="SignatureProvider"/> from this cache.
        /// </summary>
        /// <param name="signatureProvider"><see cref="SignatureProvider"/> to remove.</param>
        /// <exception cref="ArgumentNullException">if signatureProvider is null.</exception>
        /// <returns>true if the <see cref="SignatureProvider"/> was removed, false if the <see cref="SignatureProvider"/> was not found.</returns>
        /// <remarks>if the <see cref="SignatureProvider"/> is removed <see cref="SignatureProvider.CryptoProviderCache"/> will be set to null.</remarks>
        public override bool TryRemove(SignatureProvider signatureProvider)
        {
            if (signatureProvider == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(signatureProvider));
            }

            if (!ReferenceEquals(signatureProvider.CryptoProviderCache, this))
            {
                return(false);
            }

            var cacheKey = GetCacheKey(signatureProvider);

            if (signatureProvider.WillCreateSignatures)
            {
                if (_signingSignatureProviders.TryRemove(cacheKey, out SignatureProvider provider))
                {
                    provider.CryptoProviderCache = null;
                    return(true);
                }
            }
            else
            {
                if (_verifyingSignatureProviders.TryRemove(cacheKey, out SignatureProvider provider))
                {
                    provider.CryptoProviderCache = null;
                    return(true);
                }
            }

            return(false);
        }
 /// <summary>
 /// When finished with a <see cref="SignatureProvider"/> call this method for cleanup. The default behavior is to call <see cref="SignatureProvider.Dispose()"/>
 /// </summary>
 /// <param name="signatureProvider"><see cref="SignatureProvider"/> to be released.</param>
 public virtual void ReleaseSignatureProvider(SignatureProvider signatureProvider)
 {
     if (signatureProvider != null)
     {
         signatureProvider.Dispose();
     }
 }
예제 #6
0
 private void OnSignatureProviderRemovedFromCache(SignatureProvider signatureProvider)
 {
     signatureProvider.CryptoProviderCache = null;
     if (signatureProvider.RefCount == 0)
     {
         signatureProvider.Dispose();
     }
 }
        /// <summary>
        /// Returns the cache key to use when looking up an entry into the cache for a <see cref="SignatureProvider" />
        /// </summary>
        /// <param name="signatureProvider">the <see cref="SignatureProvider"/> to create the key for.</param>
        /// <exception cref="ArgumentNullException">if signatureProvider is null.</exception>
        /// <returns>the cache key to use for finding a <see cref="SignatureProvider"/>.</returns>
        protected override string GetCacheKey(SignatureProvider signatureProvider)
        {
            if (signatureProvider == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(signatureProvider));
            }

            return(GetCacheKeyPrivate(signatureProvider.Key, signatureProvider.Algorithm, signatureProvider.GetType().ToString()));
        }
예제 #8
0
 /// <summary>
 /// When finished with a <see cref="SignatureProvider"/> call this method for cleanup. The default behavior is to call <see cref="SignatureProvider.Dispose()"/>
 /// </summary>
 /// <param name="signatureProvider"><see cref="SignatureProvider"/> to be released.</param>
 public virtual void ReleaseSignatureProvider(SignatureProvider signatureProvider)
 {
     if (signatureProvider == null)
     {
         throw LogHelper.LogArgumentNullException(nameof(signatureProvider));
     }
     else if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(signatureProvider.Algorithm))
     {
         CustomCryptoProvider.Release(signatureProvider);
     }
     else if (signatureProvider.CryptoProviderCache == null)
     {
         signatureProvider.Dispose();
     }
 }
        /// <summary>
        /// Trys to find a <see cref="SignatureProvider"/> to this cache.
        /// </summary>
        /// <param name="securityKey">the key that is used to by the crypto provider.</param>
        /// <param name="algorithm">the algorithm that is used by the crypto provider.</param>
        /// <param name="typeofProvider">the typeof the crypto provider obtained by calling object.GetType().</param>
        /// <param name="willCreateSignatures">a bool to indicate if the <see cref="SignatureProvider"/> will be used to sign.</param>
        /// <param name="signatureProvider">the <see cref="SignatureProvider"/> if found.</param>
        /// <exception cref="ArgumentNullException">if securityKey is null.</exception>
        /// <exception cref="ArgumentNullException">if algorithm is null or empty string.</exception>
        /// <exception cref="ArgumentNullException">if typeofProvider is null or empty string.</exception>
        /// <returns>true if a <see cref="SignatureProvider"/> was found, false otherwise.</returns>
        public override bool TryGetSignatureProvider(SecurityKey securityKey, string algorithm, string typeofProvider, bool willCreateSignatures, out SignatureProvider signatureProvider)
        {
            if (securityKey == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(securityKey));
            }

            if (string.IsNullOrEmpty(algorithm))
            {
                throw LogHelper.LogArgumentNullException(nameof(algorithm));
            }

            if (string.IsNullOrEmpty(typeofProvider))
            {
                throw LogHelper.LogArgumentNullException(nameof(typeofProvider));
            }

            var cacheKey = GetCacheKeyPrivate(securityKey, algorithm, typeofProvider);

            if (willCreateSignatures)
            {
                return(_signingSignatureProviders.TryGetValue(cacheKey, out signatureProvider));
            }
            else
            {
                return(_verifyingSignatureProviders.TryGetValue(cacheKey, out signatureProvider));
            }
        }
        private SignatureProvider CreateSignatureProvider(SecurityKey key, string algorithm, bool willCreateSignatures)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

            if (string.IsNullOrEmpty(algorithm))
            {
                throw LogHelper.LogArgumentNullException(nameof(algorithm));
            }

            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm, key, willCreateSignatures))
            {
                SignatureProvider signatureProvider = CustomCryptoProvider.Create(algorithm, key, willCreateSignatures) as SignatureProvider;
                if (signatureProvider == null)
                {
                    throw LogHelper.LogExceptionMessage(new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10646, algorithm, key, typeof(SignatureProvider))));
                }

                return(signatureProvider);
            }

            if (!IsSupportedAlgorithm(algorithm, key))
            {
                throw LogHelper.LogExceptionMessage(new ArgumentException(String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10634, algorithm, key)));
            }

            AsymmetricSecurityKey asymmetricKey = key as AsymmetricSecurityKey;

            if (asymmetricKey != null)
            {
                return(new AsymmetricSignatureProvider(asymmetricKey, algorithm, willCreateSignatures));
            }

            SymmetricSecurityKey symmetricKey = key as SymmetricSecurityKey;

            if (symmetricKey != null)
            {
                return(new SymmetricSignatureProvider(symmetricKey, algorithm));
            }

            JsonWebKey jsonWebKey = key as JsonWebKey;

            if (jsonWebKey != null)
            {
                if (jsonWebKey.Kty != null)
                {
                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA || jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve)
                    {
                        return(new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures));
                    }

                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.Octet)
                    {
                        return(new SymmetricSignatureProvider(key, algorithm));
                    }
                }
            }

            // TODO improve this message. Nothing about JsonWebKey is mentioned.
            throw LogHelper.LogExceptionMessage(new ArgumentException(String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10600, typeof(SignatureProvider), typeof(SecurityKey), typeof(AsymmetricSecurityKey), typeof(SymmetricSecurityKey), key.GetType())));
        }
예제 #11
0
        private SignatureProvider CreateProvider(SecurityKey key, string algorithm, bool willCreateSignatures)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

            if (string.IsNullOrWhiteSpace(algorithm))
            {
                throw LogHelper.LogArgumentNullException(nameof(algorithm));
            }

            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm, key, willCreateSignatures))
            {
                SignatureProvider signatureProvider = CustomCryptoProvider.Create(algorithm, key, willCreateSignatures) as SignatureProvider;
                if (signatureProvider == null)
                {
                    throw LogHelper.LogException <InvalidOperationException>(LogMessages.IDX10646, key, algorithm, typeof(SignatureProvider));
                }

                return(signatureProvider);
            }

            if (!IsSupportedAlgorithm(algorithm, key))
            {
                throw LogHelper.LogException <ArgumentException>(LogMessages.IDX10634, algorithm, key);
            }

            AsymmetricSecurityKey asymmetricKey = key as AsymmetricSecurityKey;

            if (asymmetricKey != null)
            {
                return(new AsymmetricSignatureProvider(asymmetricKey, algorithm, willCreateSignatures));
            }

            SymmetricSecurityKey symmetricKey = key as SymmetricSecurityKey;

            if (symmetricKey != null)
            {
                return(new SymmetricSignatureProvider(symmetricKey, algorithm));
            }

            JsonWebKey jsonWebKey = key as JsonWebKey;

            if (jsonWebKey != null)
            {
                if (jsonWebKey.Kty != null)
                {
                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA || jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve)
                    {
                        return(new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures));
                    }

                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.Octet)
                    {
                        return(new SymmetricSignatureProvider(key, algorithm));
                    }
                }
            }

            throw LogHelper.LogException <ArgumentException>(LogMessages.IDX10600, typeof(SignatureProvider), typeof(SecurityKey), typeof(AsymmetricSecurityKey), typeof(SymmetricSecurityKey), key.GetType());
        }
 /// <summary>
 /// For some security key types, in some runtimes, it's not possible to extract public key material and create an <see cref="SecurityKey.InternalId"/>.
 /// In these cases, <see cref="SecurityKey.InternalId"/> will be an empty string, and these keys should not be cached.
 /// </summary>
 /// <param name="signatureProvider"><see cref="SignatureProvider"/> to be examined.</param>
 /// <returns><c>True</c> if <paramref name="signatureProvider"/> should be cached, <c>false</c> otherwise.</returns>
 private static bool ShouldCacheSignatureProvider(SignatureProvider signatureProvider)
 {
     return(signatureProvider.Key.InternalId.Length != 0);
 }
예제 #13
0
        private SignatureProvider CreateSignatureProvider(SecurityKey key, string algorithm, bool willCreateSignatures)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

            if (string.IsNullOrEmpty(algorithm))
            {
                throw LogHelper.LogArgumentNullException(nameof(algorithm));
            }

            SignatureProvider signatureProvider = null;

            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm, key, willCreateSignatures))
            {
                signatureProvider = CustomCryptoProvider.Create(algorithm, key, willCreateSignatures) as SignatureProvider;
                if (signatureProvider == null)
                {
                    throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10646, algorithm, key, typeof(SignatureProvider))));
                }

                return(signatureProvider);
            }

            // types are checked in order of expected occurrence
            string typeofSignatureProvider = null;
            bool   createAsymmetric        = true;

            if (key is AsymmetricSecurityKey asymmetricSecurityKey)
            {
                typeofSignatureProvider = typeof(AsymmetricSignatureProvider).ToString();
            }
            else if (key is JsonWebKey jsonWebKey)
            {
                if (jsonWebKey.Kty != null)
                {
                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA || jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve)
                    {
                        typeofSignatureProvider = typeof(AsymmetricSignatureProvider).ToString();
                    }

                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.Octet)
                    {
                        typeofSignatureProvider = typeof(SymmetricSignatureProvider).ToString();
                        createAsymmetric        = false;
                    }
                }
            }
            else if (key is SymmetricSecurityKey symmetricSecurityKey)
            {
                typeofSignatureProvider = typeof(SymmetricSignatureProvider).ToString();
                createAsymmetric        = false;
            }

            if (typeofSignatureProvider == null)
            {
                throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10621, typeof(SymmetricSignatureProvider), typeof(SecurityKey), typeof(AsymmetricSecurityKey), typeof(SymmetricSecurityKey), key.GetType())));
            }

            if (!IsSupportedAlgorithm(algorithm, key))
            {
                throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10634, algorithm, key)));
            }

            if (CacheSignatureProviders)
            {
                if (CryptoProviderCache.TryGetSignatureProvider(key, algorithm, typeofSignatureProvider, willCreateSignatures, out signatureProvider))
                {
                    return(signatureProvider);
                }

                lock (_cacheLock)
                {
                    if (CryptoProviderCache.TryGetSignatureProvider(key, algorithm, typeofSignatureProvider, willCreateSignatures, out signatureProvider))
                    {
                        return(signatureProvider);
                    }

                    if (createAsymmetric)
                    {
                        signatureProvider = new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures, this);
                    }
                    else
                    {
                        signatureProvider = new SymmetricSignatureProvider(key, algorithm, willCreateSignatures);
                    }

                    CryptoProviderCache.TryAdd(signatureProvider);
                }
            }
            else if (createAsymmetric)
            {
                signatureProvider = new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures);
            }
            else
            {
                signatureProvider = new SymmetricSignatureProvider(key, algorithm, willCreateSignatures);
            }

            return(signatureProvider);
        }