Ejemplo n.º 1
0
        /// <summary>
        /// Converts to keycollection.
        /// </summary>
        /// <param name="keys">The keys.</param>
        /// <param name="defaultKeyResolver">The default key resolver.</param>
        /// <returns></returns>
        public static PageResponse <Key> ToPageResponse(this IEnumerable <IKey> keys, IDefaultKeyResolver defaultKeyResolver)
        {
            var defaultKeyId = defaultKeyResolver.ResolveDefaultKeyPolicy(DateTimeOffset.UtcNow, keys).DefaultKey?.KeyId;

            return(new PageResponse <Key>
            {
                Count = keys.Count(),
                Items = keys.OrderBy(k => k.CreationDate)
                        .Select(k => new Key
                {
                    ActivationDate = k.ActivationDate,
                    CreationDate = k.CreationDate,
                    ExpirationDate = k.ExpirationDate,
                    Id = k.KeyId.ToString(),
                    IsRevoked = k.IsRevoked,
                    IsDefault = k.KeyId == defaultKeyId
                })
            });
        }
Ejemplo n.º 2
0
 public static DefaultKeyResolution ResolveDefaultKeyPolicy(this IDefaultKeyResolver resolver, string now, params IKey[] allKeys)
 {
     return(resolver.ResolveDefaultKeyPolicy(DateTimeOffset.ParseExact(now, "u", CultureInfo.InvariantCulture), (IEnumerable <IKey>)allKeys));
 }
Ejemplo n.º 3
0
        private CacheableKeyRing CreateCacheableKeyRingCore(DateTimeOffset now, IKey?keyJustAdded)
        {
            // Refresh the list of all keys
            var cacheExpirationToken = _keyManager.GetCacheExpirationToken();
            var allKeys = _keyManager.GetAllKeys();

            // Fetch the current default key from the list of all keys
            var defaultKeyPolicy = _defaultKeyResolver.ResolveDefaultKeyPolicy(now, allKeys);

            if (!defaultKeyPolicy.ShouldGenerateNewKey)
            {
                CryptoUtil.Assert(defaultKeyPolicy.DefaultKey != null, "Expected to see a default key.");
                return(CreateCacheableKeyRingCoreStep2(now, cacheExpirationToken, defaultKeyPolicy.DefaultKey, allKeys));
            }

            _logger.PolicyResolutionStatesThatANewKeyShouldBeAddedToTheKeyRing();

            // We shouldn't call CreateKey more than once, else we risk stack diving. This code path shouldn't
            // get hit unless there was an ineligible key with an activation date slightly later than the one we
            // just added. If this does happen, then we'll just use whatever key we can instead of creating
            // new keys endlessly, eventually falling back to the one we just added if all else fails.
            if (keyJustAdded != null)
            {
                var keyToUse = defaultKeyPolicy.DefaultKey ?? defaultKeyPolicy.FallbackKey ?? keyJustAdded;
                return(CreateCacheableKeyRingCoreStep2(now, cacheExpirationToken, keyToUse, allKeys));
            }

            // At this point, we know we need to generate a new key.

            // We have been asked to generate a new key, but auto-generation of keys has been disabled.
            // We need to use the fallback key or fail.
            if (!_keyManagementOptions.AutoGenerateKeys)
            {
                var keyToUse = defaultKeyPolicy.DefaultKey ?? defaultKeyPolicy.FallbackKey;
                if (keyToUse == null)
                {
                    _logger.KeyRingDoesNotContainValidDefaultKey();
                    throw new InvalidOperationException(Resources.KeyRingProvider_NoDefaultKey_AutoGenerateDisabled);
                }
                else
                {
                    _logger.UsingFallbackKeyWithExpirationAsDefaultKey(keyToUse.KeyId, keyToUse.ExpirationDate);
                    return(CreateCacheableKeyRingCoreStep2(now, cacheExpirationToken, keyToUse, allKeys));
                }
            }

            if (defaultKeyPolicy.DefaultKey == null)
            {
                // The case where there's no default key is the easiest scenario, since it
                // means that we need to create a new key with immediate activation.
                var newKey = _keyManager.CreateNewKey(activationDate: now, expirationDate: now + _keyManagementOptions.NewKeyLifetime);
                return(CreateCacheableKeyRingCore(now, keyJustAdded: newKey)); // recursively call
            }
            else
            {
                // If there is a default key, then the new key we generate should become active upon
                // expiration of the default key. The new key lifetime is measured from the creation
                // date (now), not the activation date.
                var newKey = _keyManager.CreateNewKey(activationDate: defaultKeyPolicy.DefaultKey.ExpirationDate, expirationDate: now + _keyManagementOptions.NewKeyLifetime);
                return(CreateCacheableKeyRingCore(now, keyJustAdded: newKey)); // recursively call
            }
        }
Ejemplo n.º 4
0
        private CacheableKeyRing CreateCacheableKeyRingCore(DateTimeOffset now, IKey keyJustAdded)
        {
            // Refresh the list of all keys
            var cacheExpirationToken = KeyManager.GetCacheExpirationToken();
            var allKeys = KeyManager.GetAllKeys();

            // Fetch the current default key from the list of all keys
            var defaultKeyPolicy = _defaultKeyResolver.ResolveDefaultKeyPolicy(now, allKeys);

            if (!defaultKeyPolicy.ShouldGenerateNewKey)
            {
                if (defaultKeyPolicy.DefaultKey == null)
                {
                    throw new CryptographicException("Assertion failed: Expected to see a default key."); // original CryptoUtil.Fail call replaced
                }

                return(CreateCacheableKeyRingCoreStep2(now, cacheExpirationToken, defaultKeyPolicy.DefaultKey, allKeys));
            }

            _logger.LogDebug("Policy resolution states that a new key should be added to the key ring."); // original ILogger extensions calls replaced

            // We shouldn't call CreateKey more than once, else we risk stack diving. This code path shouldn't
            // get hit unless there was an ineligible key with an activation date slightly later than the one we
            // just added. If this does happen, then we'll just use whatever key we can instead of creating
            // new keys endlessly, eventually falling back to the one we just added if all else fails.
            if (keyJustAdded != null)
            {
                var keyToUse = defaultKeyPolicy.DefaultKey ?? defaultKeyPolicy.FallbackKey ?? keyJustAdded;
                return(CreateCacheableKeyRingCoreStep2(now, cacheExpirationToken, keyToUse, allKeys));
            }

            // At this point, we know we need to generate a new key.

            // We have been asked to generate a new key, but auto-generation of keys has been disabled.
            // We need to use the fallback key or fail.
            if (!_keyManagementOptions.AutoGenerateKeys)
            {
                var keyToUse = defaultKeyPolicy.DefaultKey ?? defaultKeyPolicy.FallbackKey;
                if (keyToUse == null)
                {
                    _logger.LogError("The key ring does not contain a valid default key, and the key manager is configured with auto-generation of keys disabled."); // original ILogger extensions calls replaced
                    throw new InvalidOperationException("The key ring does not contain a valid default key, and the key manager is configured with auto-generation of keys disabled.");
                }
                else
                {
                    _logger.LogWarning("Policy resolution states that a new key should be added to the key ring, but automatic generation of keys is disabled. Using fallback key {KeyId:B} with expiration {ExpirationDate:u} as default key.",
                                       keyToUse.KeyId,
                                       keyToUse.ExpirationDate); // original ILogger extensions calls replaced
                    return(CreateCacheableKeyRingCoreStep2(now, cacheExpirationToken, keyToUse, allKeys));
                }
            }

            if (defaultKeyPolicy.DefaultKey == null)
            {
                // The case where there's no default key is the easiest scenario, since it
                // means that we need to create a new key with immediate activation.
                var newKey = KeyManager.CreateNewKey(activationDate: now, expirationDate: now + _keyManagementOptions.NewKeyLifetime);
                return(CreateCacheableKeyRingCore(now, keyJustAdded: newKey)); // recursively call
            }
            else
            {
                // If there is a default key, then the new key we generate should become active upon
                // expiration of the default key.
                var newActivationDate = defaultKeyPolicy.DefaultKey.ExpirationDate;
                var newExpirationDate = defaultKeyPolicy.DefaultKey.ExpirationDate + _keyManagementOptions.NewKeyLifetime;
                var keyAlreadyCreated = allKeys.FirstOrDefault(k => k.ActivationDate == newActivationDate && k.ExpirationDate == newExpirationDate && !k.IsRevoked);
                if (keyAlreadyCreated == null)
                {
                    var newKey = KeyManager.CreateNewKey(activationDate: newActivationDate, expirationDate: newExpirationDate); // next key expiration date rule change to use the default key expiration date and not now
                    return(CreateCacheableKeyRingCore(now, keyJustAdded: newKey));                                              // recursively call
                }
                // The next key already exists. Don't need to create a new one. It can occur when the NewKeyLifetime < KeyPropagationWindow
                return(CreateCacheableKeyRingCore(now, keyJustAdded: keyAlreadyCreated)); // recursively call
            }
        }