Пример #1
0
 public void EncryptedDataBytes()
 {
     var encryptedData = new EncryptedData(Encoding.UTF8.GetBytes(TestString));
     var encryptedDataString = encryptedData.ToString();
     var decryptedTestStringBytes = EncryptedData.DecryptDataAsBytes(encryptedData.Key, encryptedDataString);
     Assert.AreEqual(TestString, Encoding.UTF8.GetString(decryptedTestStringBytes));
 }
Пример #2
0
 public void EncryptedDataString()
 {
     var encryptedData = new EncryptedData(TestString);
     var encryptedDataString = encryptedData.ToString();
     var decryptedTestString = EncryptedData.DecryptData(encryptedData.Key, encryptedDataString);
     Assert.AreEqual(TestString, decryptedTestString);
 }
Пример #3
0
        public static SecretShare[] SplitKey(Crypto.EncryptedData encryptedData)
        {
            var keySplitIndex = (int)Math.Round((double)encryptedData.Key.Length / 2);

            var split1 = encryptedData.Key.Substring(0, keySplitIndex);
            var split2 = encryptedData.Key.Substring(keySplitIndex);

            var encryptedDataString = encryptedData.ToString();

            return(new[]
            {
                new SecretShare {
                    Type = SecretShareType.StringSplit, EncryptedData = encryptedDataString, SharedSecret = split1
                },
                new SecretShare {
                    Type = SecretShareType.StringSplit, EncryptedData = encryptedDataString, SharedSecret = split2
                },
            });
        }
Пример #4
0
        private void ProcessShares(int databaseId)
        {
            if (_processingSecretShares)
                return;

            var serverAccount = GetServerAccount();

            if (serverAccount.LinkedDeviceCryptoKeyId == 0)
                return;

            var apiClient = GetApiClient();
            var database = Model.Databases.Get(databaseId);
            var linkedClientCryptoKey = Model.CryptoKeys.Get(serverAccount.LinkedDeviceCryptoKeyId);
            
            _processingSecretShares = true;
            Task.Run(() => 
            {
                bool moreToProcess;
                do
                {
                    moreToProcess = false;
                    var entries = Model.DatabasesEntries.Find(new DatabaseEntry { DatabaseId = databaseId });
                    var entriesToSend = new List<DatabaseEntry>();
                    var entriesDataToSend = new List<DatabaseEntryData>();
                    foreach (var entry in entries)
                    {
                        var entryData = Model.DatabasesEntriesData.Get(entry.DatabaseEntryDataId);
                        if (entryData.PasswordShared)
                            continue;

                        if (entryData.Password == "")
                            continue;

                        if (entriesToSend.Count > 50)
                        {
                            moreToProcess = true;
                            break;
                        }

                        entriesToSend.Add(entry);
                        entriesDataToSend.Add(entryData);
                    }

                    if (entriesToSend.Count == 0)
                    {
                        _processingSecretShares = false;
                        return;
                    }

                    var entrySecretsToSend = new List<DeviceToDeviceMessages.NewSecretItem>();
                    var entriesEncryptedPassword = new List<EncryptedData>();
                    for (var i = 0; i < entriesToSend.Count; i++)
                    {
                        var entry = entriesToSend[i];
                        var entryData = entriesDataToSend[i];

                        var encryptedPassword = new EncryptedData(entryData.Password);
                        var newSecretIdentifier = Guid.NewGuid().ToString();

                        entrySecretsToSend.Add(new DeviceToDeviceMessages.NewSecretItem
                        {
                            EntryIdentifier = entry.Identifier,
                            SecretIdentifier = newSecretIdentifier,
                            Secret = encryptedPassword.Key
                        });

                        entriesEncryptedPassword.Add(encryptedPassword);
                    }

                    var message = new DeviceToDeviceMessages.NewSecret
                    {
                        LinkIdentifier = database.Identifier,
                        Secrets = entrySecretsToSend
                    };
                    var request = new SendLinkedDeviceMessage
                    {
                        SecondsValidFor = 120
                    };
                    request.SetMessage(message, linkedClientCryptoKey.PublicKeyPem);

                    SendLinkedDeviceMessage.ResponseParams response;
                    try
                    {
                        response = request.GetResponse(apiClient);
                    }
                    catch (RequestException)
                    {
                        // Try again later
                        _processingSecretShares = false;
                        return;
                    }

                    var processedSuccess = ProcessSharesCheckReceived(response.MessageIdentifier);
                    if (!processedSuccess)
                    {
                        _processingSecretShares = false;
                        return;
                    }

                    for (var i = 0; i < entriesToSend.Count; i++)
                    {
                        var entry = entriesToSend[i];
                        var entryData = entriesDataToSend[i];
                        var entrySecret = entrySecretsToSend[i];
                        var entryEncryptedPassword = entriesEncryptedPassword[i];

                        var originalSecretIdentifier = entryData.PasswordSharedIdentifier;
                        var newSecretIdentifier = entrySecret.SecretIdentifier;

                        Model.DatabasesEntriesData.Update(entryData.Id, new DatabaseEntryData
                        {
                            Password = "",
                            PasswordShared = true,
                            PasswordSharedIdentifier = newSecretIdentifier,
                            PasswordEncryptedData = entryEncryptedPassword.ToString()
                        });
                        Model.DatabasesEntriesDataSync.Create(new DatabaseEntryDataSync { DatabaseEntryId = entry.Id });

                        if (!string.IsNullOrEmpty(originalSecretIdentifier))
                        {
                            // Tell the device the previous secret can be deleted.

                            var deleteSecretMessage = new DeviceToDeviceMessages.DeleteSecret
                            {
                                SecretIdentifier = originalSecretIdentifier
                            };

                            var deleteSecretRequest = new SendLinkedDeviceMessage();
                            deleteSecretRequest.SetMessage(deleteSecretMessage, linkedClientCryptoKey.PublicKeyPem);

                            try
                            {
                                deleteSecretRequest.GetResponse(apiClient);
                            }
                            catch (RequestException)
                            {
                                // Errr, probably should retry this another time, but lots of effort for little gain.
                                // I'll come back to it later.
                            }
                        }
                    }

                } while (moreToProcess);

                _processingSecretShares = false;

                RestartSyncLoop();
            });
        }