/// <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; } }
/// <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); }