Exemplo n.º 1
0
 // Wyprowadza wartość klucza z podanego hasła
 private void DeriveKey(string password)
 {
     if (ArchiveKey != null)
     {
         ArchiveKey.Derive(password);
     }
 }
        /// <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,
            });
        }
Exemplo n.º 3
0
        /*
         *  Metody publiczne realizujące operacje na otwartym archiwum
         */

        // Zamyka otwarte archiwum
        public void Close()
        {
            if (IsOpen)
            {
                Connection.Close();
                ArchiveKey.Reset();
                FilePath = "";
                IdFileNamePairs.Clear();
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Serializes a given object as JSON and encrypts it.
        /// </summary>
        /// <typeparam name="T">The type of the object to serialize.</typeparam>
        /// <param name="objectToSerialize">The object to serialize.</param>
        /// <param name="key">The archive's ecryption key to use.</param>
        /// <param name="securitySettings">The archive's security settings.</param>
        /// <returns>The serialized and encrypted data.</returns>
        public static EncryptedPacket SerializeAndEncrypt <T>(
            T objectToSerialize,
            ArchiveKey key,
            SecuritySettings securitySettings)
        {
            var rawData        = JsonSerializer.SerializeToUtf8Bytes(objectToSerialize);
            var cryptoStrategy = CryptoHelpers.GetCryptoStrategy(securitySettings.EncryptionAlgo);

            return(key.Encrypt(cryptoStrategy, rawData));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Decrypts and deserializes an encrypted JSON object.
        /// </summary>
        /// <typeparam name="T">The type of the object to deserialize.</typeparam>
        /// <param name="encryptedData">The encrypted object data.</param>
        /// <param name="key">The archive's decryption key to use.</param>
        /// <param name="securitySettings">The archive's security settings.</param>
        /// <returns>The requested deserialized object.</returns>
        public static T DecryptAndDeserialize <T>(
            EncryptedPacket encryptedData,
            ArchiveKey key,
            SecuritySettings securitySettings)
        {
            var cryptoStrategy = CryptoHelpers.GetCryptoStrategy(securitySettings.EncryptionAlgo);
            var rawData        = key.Decrypt(cryptoStrategy, encryptedData);

            return(JsonSerializer.Deserialize <T>(rawData));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Decrypts the <see cref="FileIndex"/> data structure contained in the given <see cref="EncryptedPacket"/>.
        /// </summary>
        /// <param name="encryptedPacket">The encrypted data to decrypt the <see cref="FileIndex"/> from.</param>
        /// <param name="archiveKey">The key used for decryption.</param>
        /// <param name="securitySettings">The <see cref="SecuritySettings"/> for the secure archive.</param>
        /// <returns>The decrypted <see cref="FileIndex"/>.</returns>
        public static FileIndex DecryptFrom(
            EncryptedPacket encryptedPacket,
            ArchiveKey archiveKey,
            SecuritySettings securitySettings)
        {
            var indexEntries = JsonHelpers.DecryptAndDeserialize <List <FileIndexEntry> >(
                encryptedPacket,
                archiveKey,
                securitySettings);

            return(new FileIndex(indexEntries));
        }
Exemplo n.º 7
0
        // Tworzy głęboką kopię wystąpienia (niezbędne dla przechowania backupu)
        public FileArchive Clone()
        {
            FileArchive copy = new FileArchive();

            copy.FilePath     = FilePath;
            copy.ArchiveKey   = ArchiveKey.Clone();
            copy.IsCompressed = IsCompressed;

            Hashtable idFileNamePairs = new Hashtable();

            foreach (int id in IdFileNamePairs.Keys)
            {
                idFileNamePairs.Add(id, IdFileNamePairs[id]);
            }
            copy.IdFileNamePairs = idFileNamePairs;

            copy.Connection = (SQLiteConnection)Connection.Clone();

            return(copy);
        }
        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);
        }
Exemplo n.º 9
0
        public static int RunArchive(Options.ArchiveKey ArchiveKeyOpts)
        {
            // Checks
            int           inError    = 0;
            StringBuilder errMsgText = new StringBuilder();

            if (!File.Exists(ArchiveKeyOpts.KeyFile))
            {
                // Provided key file doesn't exist
                inError = 10;
                errMsgText.Append($"- Provided import file, {ArchiveKeyOpts.KeyFile}, doesn't exist.\n");
            }

            try
            {
                using (FileStream tef = File.OpenWrite(ArchiveKeyOpts.Archivefile))
                { }
            } catch (UnauthorizedAccessException)
            {
                inError = 11;
                errMsgText.Append($"- Unable to open output file, {ArchiveKeyOpts.Archivefile}, for writting\n");
            } catch (DirectoryNotFoundException)
            {
                inError = 12;
                errMsgText.Append($"- Directory not found: {ArchiveKeyOpts.Archivefile}\n");
            } catch (Exception ex)
            {
                inError = 19;
                errMsgText.Append($"- Other error occured:\n{ex.Message}\n");
            }

            if (ArchiveKeyOpts.Password.Trim() == string.Empty)
            {
                inError = 13;
                errMsgText.Append($"- Provided password value is empty ({ArchiveKeyOpts.Password})\n");
            }

            ValidatePasswordResult pwresult = Validate.Password(ArchiveKeyOpts.Password.Trim());

            if (pwresult.IsFailed)
            {
                inError = 14;
                errMsgText.Append($"- Failed password validation:\n\n{pwresult.FailedReason.Replace("-", "  -")}\n");
            }

            if (inError > 0)
            {
                Console.Write($"\nTHere is a problem with the provided parameters:\n\n{errMsgText.ToString()}");
                return(inError);
            }

            // Do stuff

            FileInfo         keyToArchive = new FileInfo(ArchiveKeyOpts.KeyFile);
            ArchiveKeyResult result       = ArchiveKey.Archive(ArchiveKeyOpts.Archivefile, ArchiveKeyOpts.Password, keyToArchive);

            if (result.IsInError)
            {
                Console.Write($"\nUnable to archive secure key. Exception message is:\n{result.ErrorString}");
                return(15);
            }

            if (File.Exists(ArchiveKeyOpts.Archivefile) && new FileInfo(ArchiveKeyOpts.Archivefile).Length > 10)
            {
                Console.Write($"\nKey archive created successfully. To transfer the key, copy to another computer and restore it.");
                return(0);
            }
            else
            {
                Console.Write($"\nKey archive creation failed.");
                return(-1);
            }
        }
Exemplo n.º 10
0
 /// <summary>
 /// Encrypts the <see cref="FileIndex"/> for secure storage.
 /// </summary>
 /// <param name="archiveKey">The encryption key to use.</param>
 /// <param name="securitySettings">The <see cref="SecuritySettings"/> for the secure archive.</param>
 /// <returns>The encrypted <see cref="FileIndex"/> data.</returns>
 public EncryptedPacket Encrypt(ArchiveKey archiveKey, SecuritySettings securitySettings)
 => JsonHelpers.SerializeAndEncrypt <List <FileIndexEntry> >(
     this.FileEntriesById.Values.Select(i => i.IndexEntry).ToList(),
     archiveKey,
     securitySettings);
Exemplo n.º 11
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);
        }