Beispiel #1
0
        /// <summary>
        /// Authorizes a new user key to access the archive.
        /// </summary>
        /// <param name="authorizationParameters">The new user key authorization parameters.</param>
        public void AuthorizeNewKey(UserKeyAuthorizationParameters authorizationParameters)
        {
            ArgCheck.IsValid(authorizationParameters, nameof(authorizationParameters));

            this.ThrowIfLocked();

            var newAuthorization = UserKeyAuthorizationExtensions.CreateNewAuthorization(
                authorizationParameters,
                this.ArchiveMetadata.KeyDerivationSalt.ToArray(),
                this.ArchiveKey,
                this.ArchiveMetadata.SecuritySettings);

            this.ArchiveMetadata.UserKeyAuthorizations.Add(newAuthorization);

            try
            {
                this.PersistMetadata();
            }
            catch
            {
                // Revert the change. Keep in-memory structure consistent.
                this.ArchiveMetadata.UserKeyAuthorizations.RemoveAt(
                    this.ArchiveMetadata.UserKeyAuthorizations.Count - 1);
                throw;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Creates a new <see cref="AegisArchive"/> that contains no files.
        /// </summary>
        /// <param name="fileSettings">Settings for where the archive and related files are stored.</param>
        /// <param name="creationParameters">The <see cref="SecureArchiveCreationParameters"/> to use when creating the archive.</param>
        /// <returns>A new <see cref="AegisArchive"/> that is opened but not yet persisted to disk.</returns>
        public static AegisArchive CreateNew(
            SecureArchiveFileSettings fileSettings,
            SecureArchiveCreationParameters creationParameters)
        {
            ArgCheck.IsValid(fileSettings, nameof(fileSettings));
            ArgCheck.IsValid(creationParameters, nameof(creationParameters));

            var currentTime = DateTimeOffset.UtcNow;
            var archiveId   = Guid.NewGuid();

            ArchiveKey tempArchiveKey = null;

            AegisArchive tempArchive = null;
            AegisArchive archive     = null;

            try
            {
                tempArchiveKey = ArchiveKey.CreateNew(creationParameters.SecuritySettings);

                // Derive and authorize the first user key.
                var keyDerivationSalt = CryptoHelpers.GetRandomBytes(creationParameters.KeyDerivationSaltSizeInBytes);

                var firstUserKeyAuthorization = UserKeyAuthorizationExtensions.CreateNewAuthorization(
                    creationParameters.FirstKeyAuthorizationParams,
                    keyDerivationSalt,
                    tempArchiveKey,
                    creationParameters.SecuritySettings);

                var authCanary = tempArchiveKey.Encrypt(
                    CryptoHelpers.GetCryptoStrategy(creationParameters.SecuritySettings.EncryptionAlgo),
                    archiveId.ToByteArray());

                var archiveMetadata = new SecureArchiveMetadata
                {
                    Id = archiveId,
                    SecuritySettings      = creationParameters.SecuritySettings,
                    CreateTime            = currentTime,
                    LastModifiedTime      = currentTime,
                    KeyDerivationSalt     = new List <byte>(keyDerivationSalt),
                    AuthCanary            = authCanary,
                    UserKeyAuthorizations = new List <UserKeyAuthorization> {
                        firstUserKeyAuthorization
                    },
                };

                tempArchive = new AegisArchive
                {
                    ArchiveMetadata = archiveMetadata,
                    ArchiveKey      = tempArchiveKey,
                    FileSettings    = fileSettings,
                    FileIndex       = new FileIndex(),
                    SecureArchive   = OpenSecureArchiveFile(fileSettings, createNewArchive: true),
                };

                tempArchive.PersistMetadata();

                // Transfer the archive reference to the return variable.
                archive     = tempArchive;
                tempArchive = null;

                // Dispose ownership of the archive key now belongs to the archive.
                tempArchiveKey = null;
            }
            finally
            {
                tempArchive?.Dispose();
                tempArchiveKey?.Dispose();
            }

            return(archive);
        }