예제 #1
0
        private bool ValidateInternal(string columnName)
        {
            IDataStore privateKeyDataStore;

            switch (columnName)
            {
            case nameof(PrivateKeyFileName):
                if (String.IsNullOrEmpty(PrivateKeyFileName))
                {
                    return(false);
                }
                privateKeyDataStore = New <IDataStore>(PrivateKeyFileName);
                return(privateKeyDataStore.IsAvailable);

            case nameof(PasswordText):
                if (!ValidateInternal(nameof(PrivateKeyFileName)))
                {
                    return(false);
                }
                privateKeyDataStore = New <IDataStore>(PrivateKeyFileName);

                if (String.IsNullOrEmpty(PasswordText))
                {
                    return(false);
                }
                LogOnIdentity identity = new LogOnIdentity(PasswordText);

                EncryptedProperties properties = EncryptedProperties.Create(privateKeyDataStore, identity);
                return(properties.IsValid);

            default:
                throw new ArgumentException("Cannot validate property.", columnName);
            }
        }
        private static string EncryptPrivateKey(UserKeyPair keys, Passphrase passphrase)
        {
            if (keys.KeyPair.PrivateKey == null)
            {
                return(String.Empty);
            }

            byte[] privateKeyPemBytes = Encoding.UTF8.GetBytes(keys.KeyPair.PrivateKey.ToString());

            if (passphrase == Passphrase.Empty)
            {
                byte[] encryptedPrivateKeyBytes = New <IProtectedData>().Protect(privateKeyPemBytes, null);
                return(Convert.ToBase64String(encryptedPrivateKeyBytes));
            }

            StringBuilder encryptedPrivateKey = new StringBuilder();

            using (StringWriter writer = new StringWriter(encryptedPrivateKey))
            {
                using (Stream stream = new MemoryStream(privateKeyPemBytes))
                {
                    EncryptionParameters encryptionParameters = new EncryptionParameters(Resolve.CryptoFactory.Preferred.CryptoId, passphrase);
                    EncryptedProperties  properties           = new EncryptedProperties("private-key.pem");
                    using (MemoryStream encryptedStream = new MemoryStream())
                    {
                        AxCryptFile.Encrypt(stream, encryptedStream, properties, encryptionParameters, AxCryptOptions.EncryptWithCompression, new ProgressContext());
                        writer.Write(Convert.ToBase64String(encryptedStream.ToArray()));
                    }
                }
            }
            return(encryptedPrivateKey.ToString());
        }
예제 #3
0
        private static bool EncryptionChangeNecessary(LogOnIdentity identity, EncryptedProperties encryptedProperties, EncryptionParameters encryptionParameters)
        {
            if (encryptedProperties.DecryptionParameter == null)
            {
                return(false);
            }

            if (encryptedProperties.DecryptionParameter.Passphrase != identity.Passphrase)
            {
                return(true);
            }

            if (encryptedProperties.SharedKeyHolders.Count() != encryptionParameters.PublicKeys.Count())
            {
                return(true);
            }

            foreach (UserPublicKey userPublicKey in encryptionParameters.PublicKeys)
            {
                if (!encryptedProperties.SharedKeyHolders.Contains(userPublicKey))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #4
0
        public static void Encrypt(Stream sourceStream, Stream destinationStream, EncryptedProperties properties, EncryptionParameters encryptionParameters, AxCryptOptions options, IProgressContext progress)
        {
            if (sourceStream == null)
            {
                throw new ArgumentNullException("sourceStream");
            }
            if (destinationStream == null)
            {
                throw new ArgumentNullException("destinationStream");
            }
            if (properties == null)
            {
                throw new ArgumentNullException("properties");
            }
            if (encryptionParameters == null)
            {
                throw new ArgumentNullException("encryptionParameters");
            }
            if (progress == null)
            {
                throw new ArgumentNullException("progress");
            }

            using (IAxCryptDocument document = New <AxCryptFactory>().CreateDocument(encryptionParameters))
            {
                document.FileName          = properties.FileMetaData.FileName;
                document.CreationTimeUtc   = properties.FileMetaData.CreationTimeUtc;
                document.LastAccessTimeUtc = properties.FileMetaData.LastAccessTimeUtc;
                document.LastWriteTimeUtc  = properties.FileMetaData.LastWriteTimeUtc;

                document.EncryptTo(sourceStream, destinationStream, options);
            }
        }
예제 #5
0
        public async Task EncryptAsync(Stream clearIn, Stream encryptedOut, string fileName)
        {
            EncryptionParameters parameters = new EncryptionParameters(_cryptoId, _passphrase);
            await parameters.AddAsync(_publicKeys);

            EncryptedProperties properties = new EncryptedProperties(fileName);

            AxCryptFile.Encrypt(clearIn, encryptedOut, properties, parameters, _options, new ProgressContext());
        }
 private void ResetState(Passphrase passphrase)
 {
     DocumentHeaders   = new V1DocumentHeaders(passphrase);
     PassphraseIsValid = false;
     Properties        = EncryptedProperties.Create(this);
     if (_hmacStream != null)
     {
         _hmacStream.Dispose();
         _hmacStream = null;
     }
 }
예제 #7
0
        private static byte[] GetSaveDataForKeys(UserKeyPair keys, string originalFileName, Passphrase passphrase)
        {
            string json = Resolve.Serializer.Serialize(keys);

            using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
            {
                EncryptionParameters encryptionParameters = new EncryptionParameters(Resolve.CryptoFactory.Preferred.CryptoId, passphrase);
                EncryptedProperties  properties           = new EncryptedProperties(originalFileName);
                using (MemoryStream exportStream = new MemoryStream())
                {
                    AxCryptFile.Encrypt(stream, exportStream, properties, encryptionParameters, AxCryptOptions.EncryptWithCompression, new ProgressContext());
                    return(exportStream.ToArray());
                }
            }
        }
        private static bool InfoFromDecryptedDocument(IDataStore sourceFileInfo, FileOperationEventArgs e)
        {
            EncryptedProperties properties = New <AxCryptFile>().CreateEncryptedProperties(sourceFileInfo, e.LogOnIdentity);

            if (!properties.IsValid)
            {
                return(false);
            }

            e.CryptoId = properties.DecryptionParameter.CryptoId;
            IDataStore destination = New <IDataStore>(Resolve.Portable.Path().Combine(Resolve.Portable.Path().GetDirectoryName(sourceFileInfo.FullName), properties.FileMetaData.FileName));

            e.SaveFileFullName = destination.FullName;
            e.AxCryptFile      = sourceFileInfo;
            return(true);
        }
예제 #9
0
        private static async Task <IEnumerable <Tuple <string, EncryptedProperties> > > ListValidAsync(IEnumerable <string> fileNames, LogOnIdentity defaultIdentity)
        {
            List <Tuple <string, EncryptedProperties> > files = new List <Tuple <string, EncryptedProperties> >();

            foreach (string file in fileNames)
            {
                LogOnIdentity       decryptionIdentity = FindDecryptionIdentity(file, defaultIdentity);
                EncryptedProperties properties         = await EncryptedPropertiesAsync(New <IDataStore>(file), decryptionIdentity);

                if (properties.IsValid)
                {
                    files.Add(new Tuple <string, EncryptedProperties>(file, properties));
                }
            }

            return(files);
        }
예제 #10
0
        /// <summary>
        /// Tries to load a key pair from the serialized byte array.
        /// </summary>
        /// <param name="value">The bytes.</param>
        /// <param name="passphrase">The passphrase.</param>
        /// <param name="keyPair">The key pair.</param>
        /// <returns>True if the pair was successfully loaded, and set in the keyPair parameter.</returns>
        public static bool TryLoad(byte[] value, Passphrase passphrase, out UserKeyPair keyPair)
        {
            using (MemoryStream encryptedStream = new MemoryStream(value))
            {
                using (MemoryStream decryptedStream = new MemoryStream())
                {
                    EncryptedProperties properties = New <AxCryptFile>().Decrypt(encryptedStream, decryptedStream, new DecryptionParameter[] { new DecryptionParameter(passphrase, Resolve.CryptoFactory.Preferred.CryptoId) });
                    if (!properties.IsValid)
                    {
                        keyPair = null;
                        return(false);
                    }

                    string json = Encoding.UTF8.GetString(decryptedStream.ToArray(), 0, (int)decryptedStream.Length);
                    keyPair = Resolve.Serializer.Deserialize <UserKeyPair>(json);
                    return(true);
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Loads an AxCrypt file from the specified reader. After this, the reader is positioned to
        /// read encrypted data.
        /// </summary>
        /// <param name="passphrase">The passphrase.</param>
        /// <param name="cryptoId">The crypto identifier.</param>
        /// <param name="reader">The reader.</param>
        /// <param name="headers">The headers.</param>
        /// <returns>
        /// True if the key was valid, false if it was wrong.
        /// </returns>
        private bool Load(Passphrase passphrase, Guid cryptoId, AxCryptReader reader, Headers headers)
        {
            ResetState();
            if (cryptoId == new V1Aes128CryptoFactory().CryptoId)
            {
                return(PassphraseIsValid);
            }

            _reader       = reader;
            CryptoFactory = Resolve.CryptoFactory.Create(cryptoId);
            V2KeyWrapHeaderBlock keyWrap = headers.FindHeaderBlock <V2KeyWrapHeaderBlock>();
            IDerivedKey          key     = CryptoFactory.RestoreDerivedKey(passphrase, keyWrap.DerivationSalt, keyWrap.DerivationIterations);

            keyWrap.SetDerivedKey(CryptoFactory, key);
            DocumentHeaders   = new V2DocumentHeaders(keyWrap);
            PassphraseIsValid = DocumentHeaders.Load(headers);
            Properties        = EncryptedProperties.Create(this);

            return(PassphraseIsValid);
        }
        public Task Process(IEntity entity)
        {
            var properties = EncryptedProperties.GetOrDefault(entity.GetType());

            if (properties.None())
            {
                return(Task.CompletedTask);
            }

            foreach (var property in properties)
            {
                var clean = (string)property.GetValue(entity);
                if (clean.HasValue())
                {
                    property.SetValue(entity, Security.Encryption.Encrypt(clean, EncryptionKey));
                }
            }

            return(Task.CompletedTask);
        }
예제 #13
0
        public static void RestoreRandomRename(this IDataStore dataStore, LogOnIdentity identity)
        {
            EncryptedProperties encryptedProperties = EncryptedProperties.Create(dataStore, identity);

            if (!encryptedProperties.IsValid)
            {
                return;
            }

            string destinationFilePath = Resolve.Portable.Path().Combine(Resolve.Portable.Path().GetDirectoryName(dataStore.FullName), encryptedProperties.FileMetaData.FileName.CreateEncryptedName());

            if (string.Equals(dataStore.FullName, destinationFilePath, StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            using (FileLock lockedSave = destinationFilePath.CreateUniqueFile())
            {
                dataStore.MoveTo(lockedSave.DataStore.FullName);
            }
        }
예제 #14
0
        /// <summary>
        /// Loads an AxCrypt file from the specified reader. After this, the reader is positioned to
        /// read encrypted data.
        /// </summary>
        /// <param name="inputStream">The stream to read from. Will be disposed when this instance is disposed.</param>
        /// <returns>True if the key was valid, false if it was wrong.</returns>
        private bool Load(Passphrase passphrase, AxCryptReader reader, Headers headers)
        {
            _reader = reader;
            ResetState(passphrase);
            PassphraseIsValid = DocumentHeaders.Load(headers);
            if (!PassphraseIsValid)
            {
                return(false);
            }

            _hmacStream = new V1HmacStream(DocumentHeaders.HmacSubkey.Key);
            foreach (HeaderBlock header in DocumentHeaders.Headers.HeaderBlocks)
            {
                if (header.HeaderBlockType != HeaderBlockType.Preamble)
                {
                    header.Write(_hmacStream);
                }
            }

            Properties = EncryptedProperties.Create(this);
            return(true);
        }
예제 #15
0
        public bool Load(IAsymmetricPrivateKey privateKey, Guid cryptoId, Headers headers)
        {
            if (headers == null)
            {
                throw new ArgumentNullException("headers");
            }

            ResetState();

            CryptoFactory = Resolve.CryptoFactory.Create(cryptoId);

            IEnumerable <V2AsymmetricKeyWrapHeaderBlock> keyWraps = headers.HeaderBlocks.OfType <V2AsymmetricKeyWrapHeaderBlock>();

            foreach (V2AsymmetricKeyWrapHeaderBlock keyWrap in keyWraps)
            {
                keyWrap.SetPrivateKey(CryptoFactory, privateKey);
                if (keyWrap.Crypto(0) == null)
                {
                    continue;
                }

                DocumentHeaders = new V2DocumentHeaders(keyWrap);
                if (!DocumentHeaders.Load(headers))
                {
                    throw new InvalidOperationException("If the master key was decrypted with the private key, the load should not be able to fail.");
                }

                V2AlgorithmVerifierEncryptedHeaderBlock algorithmVerifier = DocumentHeaders.Headers.FindHeaderBlock <V2AlgorithmVerifierEncryptedHeaderBlock>();
                PassphraseIsValid = algorithmVerifier != null && algorithmVerifier.IsVerified;
                if (PassphraseIsValid)
                {
                    Properties = EncryptedProperties.Create(this);
                    return(true);
                }
            }
            return(false);
        }
예제 #16
0
 private void ResetState()
 {
     PassphraseIsValid = false;
     DocumentHeaders   = null;
     Properties        = EncryptedProperties.Create(this);
 }
예제 #17
0
 /// <summary>
 /// Creates encrypted properties for an encrypted file.
 /// </summary>
 /// <param name="dataStore">The data store.</param>
 /// <param name="identity">The identity.</param>
 /// <returns>The EncrypedProperties, if possible.</returns>
 public virtual EncryptedProperties CreateEncryptedProperties(IDataStore dataStore, LogOnIdentity identity)
 {
     return(EncryptedProperties.Create(dataStore, identity));
 }
예제 #18
0
        public async Task ChangeEncryptionAsync(IDataStore from, LogOnIdentity identity, EncryptionParameters encryptionParameters, IProgressContext progress)
        {
            if (!from.IsEncrypted())
            {
                return;
            }

            using (CancellationTokenSource tokenSource = new CancellationTokenSource())
            {
                if (IsFileInUse(from))
                {
                    throw new FileOperationException("File is in use, cannot write to it.", from.FullName, Abstractions.ErrorStatus.FileLocked, null);
                }

                using (PipelineStream pipeline = new PipelineStream(tokenSource.Token))
                {
                    EncryptedProperties encryptedProperties = EncryptedProperties.Create(from, identity);
                    if (!EncryptionChangeNecessary(identity, encryptedProperties, encryptionParameters))
                    {
                        return;
                    }

                    using (FileLock fileLock = New <FileLocker>().Acquire(from))
                    {
                        Task decryption = Task.Run(() =>
                        {
                            Decrypt(from, pipeline, identity);
                            pipeline.Complete();
                        }).ContinueWith((t) => { if (t.IsFaulted)
                                                 {
                                                     tokenSource.Cancel();
                                                 }
                                        }, tokenSource.Token, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Current);

                        Task encryption = Task.Run(async() =>
                        {
                            bool isWriteProteced = from.IsWriteProtected;
                            if (isWriteProteced)
                            {
                                from.IsWriteProtected = false;
                            }
                            await EncryptToFileWithBackupAsync(fileLock, (Stream s) =>
                            {
                                Encrypt(pipeline, s, encryptedProperties, encryptionParameters, AxCryptOptions.EncryptWithCompression, progress);
                                return(Constant.CompletedTask);
                            }, progress);
                            from.IsWriteProtected = isWriteProteced;
                        }).ContinueWith((t) => { if (t.IsFaulted)
                                                 {
                                                     tokenSource.Cancel();
                                                 }
                                        }, tokenSource.Token, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Current);

                        try
                        {
                            Task.WaitAll(decryption, encryption);
                        }
                        catch (AggregateException ae)
                        {
                            New <IReport>().Exception(ae);
                            IEnumerable <Exception> exceptions = ae.InnerExceptions.Where(ex1 => ex1.GetType() != typeof(OperationCanceledException));
                            if (!exceptions.Any())
                            {
                                return;
                            }

                            IEnumerable <Exception> axCryptExceptions = exceptions.Where(ex2 => ex2 is AxCryptException);
                            if (axCryptExceptions.Any())
                            {
                                ExceptionDispatchInfo.Capture(axCryptExceptions.First()).Throw();
                            }

                            Exception ex = exceptions.First();
                            throw new InternalErrorException(ex.Message, Abstractions.ErrorStatus.Exception, ex);
                        }
                    }
                }
            }
        }
예제 #19
0
 private static async Task <EncryptedProperties> EncryptedPropertiesAsync(IDataStore dataStore, LogOnIdentity decryptionIdentity)
 {
     return(await Task.Run(() => EncryptedProperties.Create(dataStore, decryptionIdentity)));
 }