コード例 #1
0
ファイル: AegisArchive.cs プロジェクト: solari23/Aegis
        /// <summary>
        /// Revokes an authorized key so it can no longer unlock the archive.
        /// </summary>
        /// <param name="authorizationId">The authorization ID of the key to revoke.</param>
        /// <exception cref="InvalidOperationException">The specified authorization record was not found.</exception>
        public void RevokeKey(Guid authorizationId)
        {
            var matchingAuthorizations = this.ArchiveMetadata.UserKeyAuthorizations
                                         .Where(k => k.AuthorizationId == authorizationId)
                                         .ToArray();

            if (!matchingAuthorizations.Any())
            {
                throw new EntityNotFoundException(
                          $"Authorization with ID '{authorizationId}' was not found.");
            }

            if (matchingAuthorizations.Length > 1)
            {
                // There should never be two authorizations with the same ID.
                // If this happens, fail closed to avoid any further archive corruption.
                throw new ArchiveCorruptedException(
                          $"Found 2 key authorizations with ID '{authorizationId}'. Cancelling revocation operation.");
            }

            if (this.ArchiveMetadata.UserKeyAuthorizations.Count == 1)
            {
                throw new InvalidOperationException($"Can't revoke the last authorized key.");
            }

            // We'll track the item being removed. If saving the changes fails, we'll
            // revert the removal to put the in-memory structure back into a consistent state.
            UserKeyAuthorization removedAuthorization = null;
            int removedIndex = -1;

            for (int i = 0; i < this.ArchiveMetadata.UserKeyAuthorizations.Count; i++)
            {
                if (this.ArchiveMetadata.UserKeyAuthorizations[i].AuthorizationId == authorizationId)
                {
                    removedAuthorization = this.ArchiveMetadata.UserKeyAuthorizations[i];
                    removedIndex         = i;

                    this.ArchiveMetadata.UserKeyAuthorizations.RemoveAt(i);

                    break;
                }
            }

            try
            {
                this.PersistMetadata();
            }
            catch
            {
                // Revert the change. Keep in-memory structure consistent.
                this.ArchiveMetadata.UserKeyAuthorizations.Insert(
                    removedIndex,
                    removedAuthorization);
                throw;
            }
        }
コード例 #2
0
        public static bool TryDecryptArchiveKey(
            this UserKeyAuthorization authorization,
            UserKey userKey,
            SecuritySettings securitySettings,
            out ArchiveKey archiveKey)
        {
            ArgCheck.NotNull(authorization, nameof(authorization));
            ArgCheck.NotNull(userKey, nameof(userKey));
            ArgCheck.IsValid(securitySettings, nameof(securitySettings));

            archiveKey = null;

            if (!CryptoHelpers.SecureEquals(userKey.KeyId, authorization.KeyId))
            {
                return(false);
            }

            try
            {
                // The SecureArchive file format requires that the friendly name and keyId be
                // checked for tampering when using authenticated cyphers.
                var additionalData = Encoding.UTF8.GetBytes(authorization.FriendlyName + authorization.KeyId);

                var cryptoStrategy      = CryptoHelpers.GetCryptoStrategy(securitySettings.EncryptionAlgo);
                var decryptedArchiveKey = userKey.Decrypt(cryptoStrategy, authorization.EncryptedArchiveKey, additionalData);

                if (!decryptedArchiveKey.IsEmpty)
                {
                    archiveKey = new ArchiveKey(decryptedArchiveKey.ToArray());
                }
            }
            catch
            {
                return(false);
            }

            return(archiveKey != null);
        }