예제 #1
0
        public static (IntPtr, int) SecureStringToKeyDeriveReturnPointer(SecureString password, IEnumerable salt, PerformanceDerivative performanceDerivative, Type keyDeriveAlgorithm, out KeyDerive keyDerive)
        {
            // Turn the secure string into a string to pass it into keyDevice for the shortest interval possible
            IntPtr ptrSecureString = IntPtr.Zero;

            try
            {
                ptrSecureString = Marshal.SecureStringToGlobalAllocUnicode(password);

                var dataInsecureBytes = new byte[password.Length * sizeof(char)];

                GCHandle bytesHandle = GCHandle.Alloc(dataInsecureBytes, GCHandleType.Pinned);

                for (var i = 0; i < password.Length * sizeof(char); i++)
                {
                    dataInsecureBytes[i] = Marshal.ReadByte(ptrSecureString, i);
                }

                // Create an object array of parameters
                var parametersForInstance = new object[] { dataInsecureBytes, salt, null };

                // Parameters for static function call
                var parametersForStatic = new object[] { performanceDerivative, performanceDerivative.Milliseconds };

                object val = keyDeriveAlgorithm.GetMethod("TransformPerformance")?.Invoke(null, parametersForStatic);

                parametersForInstance[2] = val;

                keyDerive = (KeyDerive)Activator.CreateInstance(keyDeriveAlgorithm, parametersForInstance);

                password.Dispose();

                return(bytesHandle.AddrOfPinnedObject(), dataInsecureBytes.Length);
            }
            catch (NotSupportedException e)
            {
                password.Dispose();
                FileStatics.WriteToLogFile(e);
                MessageBox.Show("Fatal error while managing password. Check log file for details");
                throw;
            }
            catch (OutOfMemoryException e)
            {
                password.Dispose();
                FileStatics.WriteToLogFile(e);
                MessageBox.Show("Fatal error while managing password. Check log file for details");
                throw;
            }
            finally
            {
                // Destroy the managed string
                Marshal.ZeroFreeGlobalAllocUnicode(ptrSecureString);
            }
        }
예제 #2
0
        internal static Dictionary <string, Assembly> GetAssemblies(params string[] simpleNames)
        {
            var assemblies = new Dictionary <string, Assembly>();

            foreach (string name in simpleNames)
            {
                Assembly loadedAsm = null;

                try
                {
                    if (File.Exists(Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), name)))
                    {
                        loadedAsm = Assembly.LoadFile(Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), name));
                    }

                    if (File.Exists(name))
                    {
                        loadedAsm = Assembly.LoadFile(name);
                    }
                }
                catch (FileLoadException e)
                {
                    FileStatics.WriteToLogFile(e);
                    MessageBox.Show(
                        $"Error loading assemblies - assembly \"{e.FileName}\" could be found but not loaded");

                    loadedAsm = null;
                }
                catch (BadImageFormatException e)
                {
                    FileStatics.WriteToLogFile(e);
                    MessageBox.Show(
                        $"Error loading assemblies - assembly \"{e.FileName}\" is corrupted");

                    loadedAsm = null;
                }

                assemblies.Add(name, loadedAsm);
            }

            return(assemblies);
        }
예제 #3
0
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="request"></param>
        /// <param name="password"></param>
        /// <param name="desiredKeyDerivationMilliseconds"></param>
        public void EncryptDataWithHeader(RequestStateRecord request, SecureString password,
                                          int desiredKeyDerivationMilliseconds)
        {
            if (request.Contract.InstanceKeyContract == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            ((IProgress <int>) this._progress)?.Report(0);
            password.MakeReadOnly();


            var salt = new byte[request.Contract.InstanceKeyContract.Value.SaltLengthBytes];

            var iv  = new byte[request.Contract.TransformationContract.InitializationVectorSizeBytes];
            var rng = new RNGCryptoServiceProvider();

            try
            {
                rng.GetBytes(salt);
                rng.GetBytes(iv);
            }
            catch (CryptographicException exception)
            {
                FileStatics.WriteToLogFile(exception);
                MessageBox.Show(
                    "There was an error generating secure random numbers. Please try again - check log file for more details");
            }

            var performanceDerivative =
                new PerformanceDerivative(request.Contract.InstanceKeyContract.Value.PerformanceDerivative);


            ((IProgress <int>) this._progress)?.Report(25);

            // Get the password

            if (password.Length == 0)
            {
                MessageBox.Show("You must enter a password");

                ((IProgress <int>) this._progress)?.Report(0);
                return;
            }
#if TRACE
            if (password.Length < App.This.CurrentSettings.MinPasswordLength)
            {
                MessageBox.Show("Password too short");
                ((IProgress <int>)_progress)?.Report(0);
                return;
            }
#endif
            GCHandle byteHandle = SecureStringConverter.SecureStringToKeyDerive(password, salt,
                                                                                performanceDerivative, request.Contract.InstanceKeyContract.Value.KeyAlgorithm, out KeyDerive keyDevice);

            ((IProgress <int>) this._progress)?.Report(35);

            HMAC hmacAlg = null;

            if (request.Contract.HmacContract != null)
            {
                // Create the algorithm using reflection
                hmacAlg = (HMAC)Activator.CreateInstance(request.Contract.HmacContract.Value.HashAlgorithm);
            }

            Aes aesAlgorithm = new AesCng
            {
                BlockSize = (int)request.Contract.TransformationContract.BlockSize,
                KeySize   = (int)request.Contract.TransformationContract.KeySize,
                Mode      = request.Contract.TransformationContract.CipherMode,
                Padding   = request.Contract.TransformationContract.PaddingMode
            };

            var @params = new object[] { 1024 * 1024 * 1024, aesAlgorithm };

            var encryptor =
                (SymmetricCryptoManager)Activator.CreateInstance(request.Contract.TransformationContract.CryptoManager,
                                                                 @params);


            byte[] key = keyDevice.GetBytes((int)request.Contract.TransformationContract.KeySize / 8);

            Externals.ZeroMemory(byteHandle.AddrOfPinnedObject(), ((byte[])byteHandle.Target).Length);

            byteHandle.Free();

            // Create a handle to the key to allow control of it
            GCHandle keyHandle = GCHandle.Alloc(key, GCHandleType.Pinned);

            // Encrypt the data to a temporary file
            encryptor.EncryptFileBytes(this._filePath, App.This.DataTempFile, key, iv);

            ((IProgress <int>) this._progress)?.Report(90);


            byte[] hash = null;

            if (request.Contract.HmacContract != null)
            {
                // Create the signature derived from the encrypted data and key
                byte[] signature = MessageAuthenticator.CreateHmac(App.This.DataTempFile, key, hmacAlg);

                // Set the signature correctly in the CryptographicRepresentative object
                hash = signature;
            }

            HmacRepresentative?hmac = request.Contract.HmacContract.HasValue
                                        ? new HmacRepresentative(request.Contract.HmacContract.Value.HashAlgorithm, hash)
                                        : (HmacRepresentative?)null;

            KeyRepresentative?keyRepresentative = new KeyRepresentative
                                                  (
                request.Contract.InstanceKeyContract.Value.KeyAlgorithm,
                request.Contract.InstanceKeyContract.Value.PerformanceDerivative,
                salt
                                                  );

            // Delete the key from memory for security
            Externals.ZeroMemory(keyHandle.AddrOfPinnedObject(), key.Length);
            keyHandle.Free();

            var cryptographicInfo = new SymmetricCryptographicRepresentative
                                    (
                new TransformationRepresentative
                (
                    request.Contract.TransformationContract.CryptoManager,
                    iv,
                    request.Contract.TransformationContract.CipherMode,
                    request.Contract.TransformationContract.PaddingMode,
                    request.Contract.TransformationContract.KeySize,
                    request.Contract.TransformationContract.BlockSize
                ),
                keyRepresentative,
                hmac
                                    );

            // Write the CryptographicRepresentative object to a file
            cryptographicInfo.WriteHeaderToFile(this._filePath);

            ((IProgress <int>) this._progress)?.Report(98);
            FileStatics.AppendToFile(this._filePath, App.This.DataTempFile);

            ((IProgress <int>) this._progress)?.Report(100);
        }
예제 #4
0
        ///  <summary>
        ///
        ///  </summary>
        ///  <param name="cryptographicRepresentative"></param>
        /// <param name="key"></param>
        /// TODO decompose
        public void DecryptDataWithHeader([NotNull] SymmetricCryptographicRepresentative cryptographicRepresentative, byte[] key)
        {
            ((IProgress <int>) this._progress)?.Report(0);

            ((IProgress <int>) this._progress)?.Report(10);

            HMAC hmacAlg = null;

            if (cryptographicRepresentative.HmacRepresentative != null)
            {
                hmacAlg = (HMAC)Activator.CreateInstance(cryptographicRepresentative.HmacRepresentative.Value.HashAlgorithm);
            }

            var @params = new object[]
            {
                1024 * 1024 * 8, new AesCng
                {
                    BlockSize = (int)cryptographicRepresentative.TransformationModeInfo.BlockSize,
                    KeySize   = (int)cryptographicRepresentative.TransformationModeInfo.KeySize,
                    Mode      = cryptographicRepresentative.TransformationModeInfo.CipherMode,
                    Padding   = cryptographicRepresentative.TransformationModeInfo.PaddingMode
                }
            };


            var decryptor = (SymmetricCryptoManager)Activator.CreateInstance(cryptographicRepresentative.TransformationModeInfo.CryptoManager, @params);

            FileStatics.RemovePrependData(this._filePath, App.This.HeaderLessTempFile, cryptographicRepresentative.HeaderLength);

            ((IProgress <int>) this._progress)?.Report(20);

            GCHandle keyHandle = GCHandle.Alloc(key, GCHandleType.Pinned);

            var isVerified = false;

            if (cryptographicRepresentative.HmacRepresentative != null)
            {
                // Check if the file and key make the same HMAC
                isVerified = MessageAuthenticator.VerifyHmac(App.This.HeaderLessTempFile, key,
                                                             cryptographicRepresentative.HmacRepresentative.Value.HashBytes, hmacAlg);
            }

            ((IProgress <int>) this._progress)?.Report(35);

            // If that didn't succeed, the file has been tampered with
            if (cryptographicRepresentative.HmacRepresentative != null && !isVerified)
            {
                throw new UnverifiableDataException("File could not be verified - may have been tampered, or the password is incorrect");
            }

            // Try decrypting the remaining data
            try
            {
                decryptor.DecryptFileBytes(App.This.HeaderLessTempFile, App.This.DataTempFile, key, cryptographicRepresentative.TransformationModeInfo.InitializationVector);

                ((IProgress <int>) this._progress)?.Report(75);

                // Move the file to the original file location
                File.Copy(App.This.DataTempFile, this._filePath, true);

                ((IProgress <int>) this._progress)?.Report(100);
            }
            finally
            {
                // Delete the key from memory for security
                Externals.ZeroMemory(keyHandle.AddrOfPinnedObject(), key.Length);
                keyHandle.Free();
            }
        }
예제 #5
0
        ///  <summary>
        ///
        ///  </summary>
        ///  <param name="request"></param>
        /// <param name="key"></param>
        /// <param name="desiredKeyDerivationMilliseconds"></param>
        public void EncryptDataWithHeader(RequestStateRecord request, byte[] key,
                                          int desiredKeyDerivationMilliseconds)
        {
            ((IProgress <int>) this._progress)?.Report(0);

            var iv  = new byte[request.Contract.TransformationContract.InitializationVectorSizeBytes];
            var rng = new RNGCryptoServiceProvider();

            try
            {
                rng.GetBytes(iv);
            }
            catch (CryptographicException exception)
            {
                FileStatics.WriteToLogFile(exception);
                MessageBox.Show(
                    "There was an error generating secure random numbers. Please try again - check log file for more details");
            }

            ((IProgress <int>) this._progress)?.Report(25);

            HMAC hmacAlg = null;

            if (request.Contract.HmacContract != null)
            {
                // Create the algorithm using reflection
                hmacAlg = (HMAC)Activator.CreateInstance(request.Contract.HmacContract.Value.HashAlgorithm);
            }

            var @params = new object[] { 1024 * 1024 * 1024, new AesCryptoServiceProvider() };

            var encryptor =
                (SymmetricCryptoManager)Activator.CreateInstance(request.Contract.TransformationContract.CryptoManager,
                                                                 @params);

            // Create a handle to the key to allow control of it
            GCHandle keyHandle = GCHandle.Alloc(key, GCHandleType.Pinned);

            // Encrypt the data to a temporary file
            encryptor.EncryptFileBytes(this._filePath, App.This.DataTempFile, key, iv);

            ((IProgress <int>) this._progress)?.Report(90);


            byte[] hash = null;

            if (request.Contract.HmacContract != null)
            {
                // Create the signature derived from the encrypted data and key
                byte[] signature = MessageAuthenticator.CreateHmac(App.This.DataTempFile, key, hmacAlg);

                // Set the signature correctly in the CryptographicRepresentative object
                hash = signature;
            }

            HmacRepresentative?hmac = request.Contract.HmacContract != null && hash != null
                                        ? new HmacRepresentative(request.Contract.HmacContract.Value.HashAlgorithm, hash)
                                        : (HmacRepresentative?)null;

            // Delete the key from memory for security
            Externals.ZeroMemory(keyHandle.AddrOfPinnedObject(), key.Length);
            keyHandle.Free();

            var cryptographicInfo = new SymmetricCryptographicRepresentative
                                    (
                new TransformationRepresentative
                (
                    request.Contract.TransformationContract.CryptoManager,
                    iv,
                    request.Contract.TransformationContract.CipherMode,
                    request.Contract.TransformationContract.PaddingMode,
                    request.Contract.TransformationContract.KeySize,
                    request.Contract.TransformationContract.BlockSize
                ),
                null,
                hmac
                                    );

            // Write the CryptographicRepresentative object to a file
            cryptographicInfo.WriteHeaderToFile(this._filePath);

            ((IProgress <int>) this._progress)?.Report(98);

            FileStatics.AppendToFile(this._filePath, App.This.DataTempFile);

            ((IProgress <int>) this._progress)?.Report(100);
        }