/// <summary>
        /// Creates a new <see cref="UserKeyAuthorization"/> entry for a user key and a particular archive.
        /// </summary>
        /// <param name="friendlyName">A friendly name to help the user identify the key.</param>
        /// <param name="userKey">The <see cref="UserKey"/> to authorize.</param>
        /// <param name="archiveKey">The key used to encrypt the archive that the user key is being authorized for.</param>
        /// <param name="securitySettings">The archive's <see cref="SecuritySettings"/>.</param>
        /// <returns>The new <see cref="UserKeyAuthorization"/> entry.</returns>
        public static UserKeyAuthorization CreateNewAuthorization(
            UserKeyAuthorizationParameters newKeyParams,
            ReadOnlySpan <byte> keyDerivationSalt,
            ArchiveKey archiveKey,
            SecuritySettings securitySettings)
        {
            ArgCheck.IsValid(newKeyParams, nameof(newKeyParams));
            ArgCheck.NotEmpty(keyDerivationSalt, nameof(keyDerivationSalt));
            ArgCheck.NotNull(archiveKey, nameof(archiveKey));
            ArgCheck.IsValid(securitySettings, nameof(securitySettings));

            using var userKey = UserKey.DeriveFrom(
                      newKeyParams.UserSecret,
                      keyDerivationSalt,
                      securitySettings);

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

            var cryptoStrategy      = CryptoHelpers.GetCryptoStrategy(securitySettings.EncryptionAlgo);
            var encryptedArchiveKey = userKey.EncryptSecret(cryptoStrategy, archiveKey, additionalData);

            return(new UserKeyAuthorization
            {
                AuthorizationId = Guid.NewGuid(),
                FriendlyName = newKeyParams.FriendlyName,
                KeyId = userKey.KeyId,
                TimeAdded = DateTime.UtcNow,
                EncryptedArchiveKey = encryptedArchiveKey,
                SecretMetadata = newKeyParams.SecretMetadata,
            });
        }
Ejemplo n.º 2
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;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SecureArchiveCreationParameters"/> class.
        /// </summary>
        /// <param name="firstKeyAuthorizationParam">The parameters to authorize the first user key.</param>
        public SecureArchiveCreationParameters(UserKeyAuthorizationParameters firstKeyAuthorizationParam)
        {
            ArgCheck.IsValid(firstKeyAuthorizationParam, nameof(firstKeyAuthorizationParam));

            this.FirstKeyAuthorizationParams = firstKeyAuthorizationParam;
        }