Пример #1
0
        public void Given_NewEntryWhenEntryAlreadyExists_When_InsertNewEntryAndOverwriteNotChosen_Then_Exception()
        {
            // Arrange
            const string newEntryName    = "password";
            var          newKey          = new PlainTextKey();
            var          encryptedData   = new List <byte[]>();
            var          categoryToAddTo = new Category()
            {
                Name    = "Dev",
                Entries = new List <Entry>()
                {
                    new Entry()
                    {
                        Name = newEntryName,
                    }
                }
            };
            var dat = new EnvCryptDat()
            {
                Categories = new[] { categoryToAddTo }
            };

            // Act
            Action act = () => dat.AddEntry(categoryToAddTo.Name, newEntryName, newKey, encryptedData, false);

            // Assert
            act.ShouldThrow <EnvCryptException>();
        }
Пример #2
0
        public TExtRep Map(EnvCryptDat fromDatPoco)
        {
            Contract.Requires <ArgumentNullException>(fromDatPoco != null, "fromDatPoco");
            Contract.Requires <EnvCryptException>(fromDatPoco.Categories != null);
            Contract.Requires <EnvCryptException>(Contract.ForAll(fromDatPoco.Categories,
                                                                  c => !string.IsNullOrWhiteSpace(c.Name)));

            /*
             * There must be list of Entires (if 0 Entries then it is not emitted in the TExtRep object).
             * Each entry must have a Name but may not have other things that the
             * plaintext key doesn't need to have, such as the key name and hash.
             */
            Contract.Requires <EnvCryptException>(Contract.ForAll(fromDatPoco.Categories,
                                                                  c => c.Entries != null));
            Contract.Requires <EnvCryptException>(Contract.ForAll(fromDatPoco.Categories,
                                                                  c => Contract.ForAll(
                                                                      c.Entries, e => e.EncryptedValue != null)));
            Contract.Requires <EnvCryptException>(Contract.ForAll(fromDatPoco.Categories, c => Contract.ForAll(
                                                                      c.Entries, e => e.Name != null)));
            Contract.Requires <EnvCryptException>(Contract.ForAll(fromDatPoco.Categories,
                                                                  c => Contract.ForAll(
                                                                      c.Entries, e => Contract.ForAll(e.EncryptedValue, bytes => bytes != null))));

            Contract.Ensures(Contract.Result <TExtRep>() != null);

            return(default(TExtRep));
        }
Пример #3
0
 public void LogDecryption(TWorkflowOptions withWorkflowOptions, EnvCryptDat ecDat, IList <TKey> usingLoadedKeys, IList <EntriesDecrypterResult <TKey> > results)
 {
     Contract.Requires <ArgumentNullException>(withWorkflowOptions != null, "withWorkflowOptions");
     Contract.Requires <ArgumentNullException>(ecDat != null, "ecDat");
     Contract.Requires <ArgumentNullException>(usingLoadedKeys != null, "usingLoadedKeys");
     Contract.Requires <EnvCryptException>(Contract.ForAll(usingLoadedKeys, k => k != null), "no loaded keys can be null");
     Contract.Requires <ArgumentNullException>(results != null, "results");
     Contract.Requires <EnvCryptException>(Contract.ForAll(results, r => r != null), "no results can be null");
 }
Пример #4
0
        public void Given_CategoryExists_When_RemoveEntry_Then_CorrectEntryRemoved()
        {
            // Arrange
            const string categoryToRemove = "Family Guy";
            const string entryToRemove    = "brian";
            var          dat = new EnvCryptDat()
            {
                Categories = new[]
                {
                    new Category()
                    {
                        Name    = categoryToRemove,
                        Entries = new List <Entry>()
                        {
                            new Entry()
                            {
                                Name    = "bart",
                                KeyName = "bart"
                            },
                            new Entry()
                            {
                                Name    = entryToRemove,
                                KeyName = entryToRemove
                            }
                        }
                    },
                    new Category()
                    {
                        Name    = "some other entry",
                        Entries = new List <Entry>()
                        {
                            new Entry()
                            {
                                Name    = entryToRemove,
                                KeyName = entryToRemove
                            }
                        }
                    }
                }
            };

            // Act
            var hasBeenFound = dat.RemoveEntry(categoryToRemove, entryToRemove);

            // Assert
            hasBeenFound.Should().BeTrue("entry exists in the DAT POCO");
            dat.Categories.Should().HaveCount(2);
            dat.Categories[0].Entries.Should().HaveCount(1);
            dat.Categories[1].Entries.Should().HaveCount(1);
            dat.Categories[0].Name.Should().Be(categoryToRemove, "there is still an entry in the category so the category should remain");
            dat.Categories[0].Entries[0].Name.Should().NotBe(entryToRemove);
        }
Пример #5
0
 public IList <EntriesDecrypterResult <TKey> > Decrypt(
     TKey usingKey,
     EnvCryptDat inDat,
     CategoryEntryPair categoryEntryPair,
     bool throwExceptionIfEntryNotFound = true,
     bool throwIfDecryptingKeyNotFound  = true,
     bool throwIfKeyCannotDecrypt       = true)
 {
     Contract.Requires <ArgumentNullException>(usingKey != null, "usingKey");
     Contract.Requires <ArgumentNullException>(inDat != null, "inDat");
     //
     return(this.Decrypt(new[] { usingKey }, inDat, new[] { categoryEntryPair }, throwExceptionIfEntryNotFound,
                         throwIfDecryptingKeyNotFound, throwIfKeyCannotDecrypt));
 }
Пример #6
0
 public IList <EntriesDecrypterResult <TKey> > Decrypt(
     IList <TKey> usingKeys,
     EnvCryptDat inDat,
     CategoryEntryPair categoryEntryPair,
     bool throwExceptionIfEntryNotFound = true,
     bool throwIfDecryptingKeyNotFound  = true,
     bool throwIfKeyCannotDecrypt       = true)
 {
     Contract.Requires <ArgumentNullException>(usingKeys != null, "usingKeys");
     Contract.Requires <ArgumentException>(usingKeys.Any(), "usingKeys");
     Contract.Requires <EnvCryptException>(Contract.ForAll(usingKeys, k => k != null), "all keys in the list can be null");
     Contract.Requires <ArgumentNullException>(inDat != null, "inDat");
     //
     return(this.Decrypt(usingKeys, inDat, new[] { categoryEntryPair }, throwExceptionIfEntryNotFound,
                         throwIfDecryptingKeyNotFound, throwIfKeyCannotDecrypt));
 }
        public void Given_POCOWithPlainText_When_Mapped_Then_EncryptionInXMLNotSet()
        {
            // Arrange
            var datPoco = new EnvCryptDat()
            {
                Categories = new[]
                {
                    new Category()
                    {
                        Name    = "Production",
                        Entries = new[]
                        {
                            new Entry()
                            {
                                Name = "database URL",
                                EncryptionAlgorithm = EnvCryptAlgoEnum.PlainText,
                                EncryptedValue      = new[]
                                {
                                    new byte[1],
                                }
                            },
                        }
                    }
                }
            };

            var strConverterMock = new Mock <IEncryptedDetailsPersistConverter>();

            //      Array of length 1 returns "1", length 2 returns "2"...
            strConverterMock.Setup(c => c.Encode(It.IsAny <byte[]>(), It.IsAny <EnvCryptAlgoEnum>()))
            .Returns <byte[], EnvCryptAlgoEnum>((b, _) => b.Length.ToString());

            // Act
            var mapper = new DatToXmlMapper(strConverterMock.Object);
            var res    = mapper.Map(datPoco);

            // Assert
            res.Items.Should().NotBeNull();
            res.Items.Should().HaveCount(1);
            res.Items[0].Entry.Should().NotBeNull();
            res.Items[0].Entry.Should().HaveCount(1);

            res.Items[0].Entry[0].Name.Should().Be("database URL");
            res.Items[0].Entry[0].Decryption.Should().BeNull();
            res.Items[0].Entry[0].EncryptedValue.Should().HaveCount(1);
            res.Items[0].Entry[0].EncryptedValue[0].Value.Should().Be("1");
        }
Пример #8
0
        public void Given_EntryExistsAndIsTheOnlyEntryInCategory_When_RemoveEntry_Then_CategoryRemoved()
        {
            // Arrange
            const string categoryToRemove = "Family Guy";
            const string entryToRemove    = "brian";
            var          dat = new EnvCryptDat()
            {
                Categories = new List <Category>()
                {
                    new Category()
                    {
                        Name    = categoryToRemove,
                        Entries = new List <Entry>()
                        {
                            new Entry()
                            {
                                Name    = entryToRemove,
                                KeyName = entryToRemove
                            }
                        }
                    },
                    new Category()
                    {
                        Name    = "some other entry",
                        Entries = new List <Entry>()
                        {
                            new Entry()
                            {
                                Name    = entryToRemove,
                                KeyName = entryToRemove
                            }
                        }
                    }
                }
            };

            // Act
            var hasBeenFound = dat.RemoveEntry(categoryToRemove, entryToRemove);

            // Assert
            hasBeenFound.Should().BeTrue("entry exists in the DAT POCO");
            dat.Categories.Should().HaveCount(1);
            dat.Categories[0].Name.Should()
            .NotBe(categoryToRemove, "category was empty after removal of {0} entry so should be removed",
                   entryToRemove);
        }
Пример #9
0
        private static bool SearchForCategory(this EnvCryptDat inDatPoco,
                                              string withCategoryName, out Category foundCategory)
        {
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(withCategoryName), "withCategoryName");
            Contract.Ensures(Contract.Result <bool>() ?
                             Contract.ValueAtReturn(out foundCategory) != null :
                             Contract.ValueAtReturn(out foundCategory) == default(Category));
            //
            for (uint catI = 0; catI < inDatPoco.Categories.Count; catI++)
            {
                var currentCategory = inDatPoco.Categories[(int)catI];
                if (currentCategory.Name == withCategoryName)
                {
                    foundCategory = currentCategory;
                    return(true);
                }
            }

            foundCategory = default(Category);
            return(false);
        }
Пример #10
0
        public void Save(EnvCryptDat data, DatToFileSaverOptions fileSaverOptions)
        {
            if (fileSaverOptions == null ||
                string.IsNullOrWhiteSpace(fileSaverOptions.DestinationFilePath))
            {
                throw new ArgumentException("destination file path cannot be empty");
            }

            var xmlPoco = _pocoToXmlMapper.Map(data);
            var xmlStr  = _serializationUtils.Serialize(xmlPoco);

            var fileWriterOptions = new StringToFileWriterOptions()
            {
                Contents = xmlStr,
                Encoding = _serializationUtils.GetUsedEncoding(),
                Path     = fileSaverOptions.DestinationFilePath,
                OverwriteIfFileExists = true
            };

            _fileWriter.Write(fileWriterOptions);
        }
Пример #11
0
        public void Given_NewEntryWhenEntryAlreadyExists_When_InsertNewEntryAndOverwriteChosen_Then_ExistingEntryReplaced()
        {
            // Arrange
            const string newEntryName    = "password";
            var          newKey          = new PlainTextKey();
            var          encryptedData   = new List <byte[]>();
            var          categoryToAddTo = new Category()
            {
                Name    = "Dev",
                Entries = new List <Entry>()
                {
                    new Entry()
                    {
                        Name                = newEntryName,
                        EncryptedValue      = new List <byte[]>(),
                        EncryptionAlgorithm = EnvCryptAlgoEnum.Aes,
                        KeyHash             = 123,
                        KeyName             = "this key's details will be overwritten"
                    }
                }
            };
            var dat = new EnvCryptDat()
            {
                Categories = new List <Category>()
                {
                    categoryToAddTo
                }
            };

            // Act
            dat.AddEntry(categoryToAddTo.Name, newEntryName, newKey, encryptedData, true);

            // Assert
            dat.Categories.Should().HaveCount(1);
            dat.Categories[0].Should().NotBeNull();
            dat.Categories[0].Entries.Should().HaveCount(1);
            dat.Categories[0].Entries[0].Name.Should().Be(newEntryName);
            dat.Categories[0].Entries[0].EncryptedValue.Should().Equal(encryptedData);
            dat.Categories[0].Entries[0].EncryptionAlgorithm.Should().Be(EnvCryptAlgoEnum.PlainText);
        }
Пример #12
0
        public void Given_CategoryExists_When_SearchForEntry_Then_EntryFound()
        {
            // Arrange
            const string categoryName = "The Simpsons";
            const string entryName    = "Bart";
            var          dat          = new EnvCryptDat()
            {
                Categories = new[]
                {
                    new Category()
                    {
                        Name    = categoryName,
                        Entries = new []
                        {
                            new Entry()
                            {
                                Name    = "bart",
                                KeyName = "bart"
                            },
                            new Entry()
                            {
                                Name    = entryName,
                                KeyName = entryName
                            }
                        }
                    }
                }
            };

            // Act
            Entry foundEntry;
            var   hasBeenFound = dat.SearchForEntry(categoryName, entryName, out foundEntry);

            // Assert
            hasBeenFound.Should().BeTrue("entry exists in the DAT POCO");
            foundEntry.Name.Should().Be(entryName);
            foundEntry.KeyName.Should().Be(entryName);
        }
Пример #13
0
        public static bool SearchForEntry(this EnvCryptDat inDatPoco,
                                          string withCategoryName, string withEntryName, out Entry foundEntry)
        {
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(withCategoryName), "withCategoryName");
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(withEntryName), "withEntryName");
            Contract.Ensures(Contract.Result <bool>() ?
                             Contract.ValueAtReturn(out foundEntry) != null :
                             Contract.ValueAtReturn(out foundEntry) == default(Entry));
            //
            Category foundCategory;

            if (inDatPoco.SearchForCategory(withCategoryName, out foundCategory))
            {
                Entry entry;
                if (foundCategory.SearchForEntry(withEntryName, out entry))
                {
                    foundEntry = entry;
                    return(true);
                }
            }
            foundEntry = null;
            return(false);
        }
Пример #14
0
        public void Given_NewEntryInNonExistantCategory_When_InsertNewEntry_Then_EntryInserted()
        {
            // Arrange
            var dat = new EnvCryptDat()
            {
                Categories = new List <Category>()       // Start off with no categories (thus no entries)
            };

            const string newEntryName  = "password";
            var          newKey        = new PlainTextKey();
            var          encryptedData = new List <byte[]>();

            // Act
            dat.AddEntry("UAT", newEntryName, newKey, encryptedData);

            // Assert
            dat.Categories.Should().HaveCount(1);
            dat.Categories[0].Name.Should().Be("UAT");
            dat.Categories[0].Should().NotBeNull();
            dat.Categories[0].Entries.Should().HaveCount(1);
            dat.Categories[0].Entries[0].Name.Should().Be(newEntryName);
            dat.Categories[0].Entries[0].EncryptedValue.Should().Equal(encryptedData);
            dat.Categories[0].Entries[0].EncryptionAlgorithm.Should().Be(EnvCryptAlgoEnum.PlainText);
        }
Пример #15
0
        public void Given_AesEntries_When_DecryptWithAudit_Then_FilesWrittenWithCorrectContent()
        {
            // Arrange
            //      Generate random key
            const string keyName   = "key to test audit";
            var          aesKeyGen = new AesKeyGenerator();
            var          aesKey    = aesKeyGen.GetNewKey(new AesKeyGenerationOptions()
            {
                KeySize    = GenerateAesKeyBuilder.DefaultAesKeySize,
                NewKeyName = keyName
            });
            var keyLoaderMock = new Mock <IKeyLoader <AesKey, KeyFromFileDetails> >(MockBehavior.Strict);

            keyLoaderMock.Setup(l => l.Load(It.IsAny <KeyFromFileDetails>()))
            .Returns(aesKey);

            IUserStringConverter converter    = new Utf16LittleEndianUserStringConverter();
            const string         categoryName = "my category";
            const string         entryName1   = "my entry";
            const string         entryName2   = "my entry2";
            var datPoco = new EnvCryptDat()
            {
                Categories = new[]
                {
                    new Category()
                    {
                        Name    = categoryName,
                        Entries = new[]
                        {
                            new Entry()
                            {
                                Name                = entryName1,
                                EncryptedValue      = new[] { new byte[1] }, // not important for this test
                                EncryptionAlgorithm = aesKey.Algorithm,
                                KeyName             = aesKey.Name,
                                KeyHash             = aesKey.GetHashCode()
                            },
                            new Entry()
                            {
                                Name                = entryName2,
                                EncryptedValue      = new[] { new byte[1] }, // not important for this test
                                EncryptionAlgorithm = aesKey.Algorithm,
                                KeyName             = aesKey.Name,
                                KeyHash             = aesKey.GetHashCode()
                            }
                        }
                    }
                }
            };
            var datLoaderMock = new Mock <IDatLoader <DatFromFileLoaderOptions> >();

            datLoaderMock.Setup(l => l.Load(It.IsAny <DatFromFileLoaderOptions>()))
            .Returns(datPoco);

            var encryptionAlgoMock = new Mock <ISegmentEncryptionAlgo <AesKey> >();

            encryptionAlgoMock.Setup(a => a.Decrypt(It.IsAny <IList <byte[]> >(), aesKey))
            .Returns(converter.Encode("not important for this test"));

            var processName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);

            var utcNow       = new DateTime(2015, 01, 01);
            var dateTimeMock = new Mock <IMyDateTime>();

            dateTimeMock.Setup(t => t.UtcNow()).Returns(utcNow);
            var fileInfoFactoryMock = new Mock <IMyFileInfoFactory>();
            var fileInfoMock        = new Mock <IMyFileInfo>();

            fileInfoMock.Setup(f => f.CreationTimeUtc)
            .Returns(utcNow.AddDays(-2));
            fileInfoFactoryMock.Setup(f => f.GetNewInstance(It.Is <string>(s => s.Contains(processName))))
            .Returns <string>(s => new MyFileInfo(s));
            fileInfoFactoryMock.Setup(f => f.GetNewInstance(It.IsRegex(@".+deleteme")))
            .Returns(fileInfoMock.Object);


            using (var tempDir = new TempDir())
            {
                var loggerConfig = new ToFileAuditLoggerConfig()
                {
                    LogDirectory = tempDir.TempDirectory,
                    NumberOfDaysSinceCreationToKeep = 1
                };
                var auditLogger = new ToFileAuditLogger <AesKey, DecryptEntryWorkflowOptions>(
                    loggerConfig, new MyDirectory(), new MyFile(),
                    dateTimeMock.Object,
                    new OldLogCleaner(loggerConfig, new MyDirectory(), new MyFile(), fileInfoFactoryMock.Object));


                // Act
                var deleteFile1Path = Path.Combine(tempDir.TempDirectory, ".deleteme.log");
                File.WriteAllText(deleteFile1Path, "somerandomtext");
                var deleteFile2Path = Path.Combine(tempDir.TempDirectory, "asd.deleteme.log");
                File.WriteAllText(deleteFile2Path, "somerandomtext2");
                const string datFilePath = @"C:\my dat file";
                new DecryptAesEntryWorkflowBuilder()
                .WithAesSegmentEncryptionAlgo(encryptionAlgoMock.Object)
                .WithKeyLoader(keyLoaderMock.Object)
                .WithDatLoader(datLoaderMock.Object)
                .WithAuditLogger(auditLogger)
                .Build().Run(new DecryptEntryWorkflowOptions()
                {
                    CategoryEntryPair = new[]
                    {
                        new CategoryEntryPair(categoryName, entryName1),
                        new CategoryEntryPair(categoryName, entryName2)
                    },
                    DatFilePath  = datFilePath,
                    KeyFilePaths = new[]
                    {
                        "null"
                    }
                });


                // Assert
                File.Exists(deleteFile1Path).Should().BeFalse();
                File.Exists(deleteFile2Path).Should().BeFalse();

                var expectedFilePath = Path.Combine(tempDir.TempDirectory, string.Format(loggerConfig.FileNameFormat,
                                                                                         utcNow.ToString(ToFileAuditLogger <AesKey, DecryptEntryWorkflowOptions> .DateTimeFormatInFileName),
                                                                                         processName) + loggerConfig.LogFileExtension);

                File.Exists(expectedFilePath)
                .Should().BeTrue();
                var lines = File.ReadAllLines(expectedFilePath);
                lines.Should().HaveCount(5);
                lines[1].Should().Be(datFilePath);
                lines[3].Should().Be(categoryName + "\t" + entryName1 + "\t" + keyName + "\t" + EnvCryptAlgoEnum.Aes);
                lines[4].Should().Be(categoryName + "\t" + entryName2 + "\t" + keyName + "\t" + EnvCryptAlgoEnum.Aes);
            }
        }
Пример #16
0
        public EnvCryptEncryptedData Map(EnvCryptDat fromDatPoco)
        {
            var xmlCategories = new List <EnvCryptEncryptedDataCategory>(fromDatPoco.Categories.Count);

            for (uint catI = 0; catI < fromDatPoco.Categories.Count; catI++)
            {
                // For each caegory
                var xmlCategoryToAdd = new EnvCryptEncryptedDataCategory();
                var currentCategory  = fromDatPoco.Categories[(int)catI];
                if (currentCategory == null || !currentCategory.Entries.Any())
                {
                    // Don't add it to the XML if there is nothing in the category
                    continue;
                }
                xmlCategoryToAdd.Name = currentCategory.Name;

                var xmlCategoryEntries = new List <EnvCryptEncryptedDataCategoryEntry>(currentCategory.Entries.Count);
                // For each entry in the category
                for (uint entryI = 0; entryI < currentCategory.Entries.Count; entryI++)
                {
                    var xmlEntryToAdd = new EnvCryptEncryptedDataCategoryEntry();
                    xmlCategoryEntries.Add(xmlEntryToAdd);
                    var currentEntry = currentCategory.Entries[(int)entryI];

                    /*
                     * If there are no encrypted values or all segments are empty,
                     * then don't add the entry at all.
                     */
                    if (currentEntry.EncryptedValue == null ||
                        !currentEntry.EncryptedValue.Any() ||
                        currentEntry.EncryptedValue.Count(b => b.Any()) == 0)
                    {
                        continue;
                    }

                    xmlEntryToAdd.Name = currentEntry.Name;

                    // Add encrypted values
                    {
                        var xmlEncryptedValues = new List <EnvCryptEncryptedDataCategoryEntryEncryptedValue>();
                        for (uint valueI = 0; valueI < currentEntry.EncryptedValue.Count; valueI++)
                        {
                            var currentValueAsByteArr = currentEntry.EncryptedValue[(int)valueI];
                            if (currentValueAsByteArr == null || !currentValueAsByteArr.Any())
                            {
                                continue;
                            }

                            /*
                             * Note: There is no check here for 'empty' array items
                             * because the default byte value of 0 could be valid.
                             */

                            xmlEncryptedValues.Add(new EnvCryptEncryptedDataCategoryEntryEncryptedValue()
                            {
                                Value = _strConverter.Encode(currentValueAsByteArr, currentEntry.EncryptionAlgorithm)
                            });
                        }
                        xmlEntryToAdd.EncryptedValue = xmlEncryptedValues.ToArray();
                    }

                    // Don't add Decryption element at all if plaintext, but still add values (above)
                    if (currentEntry.EncryptionAlgorithm == EnvCryptAlgoEnum.PlainText)
                    {
                        xmlEntryToAdd.Decryption = null;
                        continue;
                    }

                    // Only add entry to XML if one exists
                    if (currentEntry.KeyName != null)
                    {
                        xmlEntryToAdd.Decryption = new EnvCryptEncryptedDataCategoryEntryDecryption()
                        {
                            KeyName = currentEntry.KeyName,
                            Algo    = currentEntry.EncryptionAlgorithm.ToString(),
                            Hash    = currentEntry.KeyHash,
                        };
                    }
                }

                // Add our prepared Entries
                xmlCategoryToAdd.Entry = xmlCategoryEntries.ToArray();

                xmlCategories.Add(xmlCategoryToAdd);
            }

            // Add out prepared Categories
            return(new EnvCryptEncryptedData()
            {
                Items = xmlCategories.ToArray()
            });
        }
        private static DecryptGenericWorkflowOptions TwoDifferentAlgosExceptionTestSetup(out Mock <IDatLoader <DatFromFileLoaderOptions> > datLoaderMock)
        {
            var options = new DecryptGenericWorkflowOptions()
            {
                DatFilePath       = @"X:\tmp\generic.dat",
                CategoryEntryPair = new List <CategoryEntryPair>()
                {
                    new CategoryEntryPair("prod", "password"),
                    new CategoryEntryPair("uat", "password"),
                    new CategoryEntryPair("dev", "username"),
                }
            };

            var dat = new EnvCryptDat()
            {
                Categories = new[]
                {
                    new Category()
                    {
                        Name    = options.CategoryEntryPair[0].Category,
                        Entries = new[]
                        {
                            new Entry()
                            {
                                Name = options.CategoryEntryPair[0].Entry,
                                EncryptionAlgorithm = EnvCryptAlgoEnum.Rsa
                            }
                        }
                    },
                    new Category()
                    {
                        Name    = options.CategoryEntryPair[1].Category,
                        Entries = new[]
                        {
                            new Entry()
                            {
                                Name = options.CategoryEntryPair[1].Entry,
                                EncryptionAlgorithm = EnvCryptAlgoEnum.Aes
                            }
                        }
                    },
                    new Category()
                    {
                        Name    = options.CategoryEntryPair[2].Category,
                        Entries = new[]
                        {
                            new Entry()
                            {
                                Name = options.CategoryEntryPair[2].Entry,
                                EncryptionAlgorithm = EnvCryptAlgoEnum.PlainText
                            }
                        }
                    }
                }
            };


            datLoaderMock = new Mock <IDatLoader <DatFromFileLoaderOptions> >(MockBehavior.Strict);
            datLoaderMock.Setup(l => l.Load(It.Is <DatFromFileLoaderOptions>(o => o.DatFilePath == options.DatFilePath)))
            .Returns(dat);

            return(options);
        }
Пример #18
0
 public void Save(EnvCryptDat data, TSaverDetails fileSaverOptions)
 {
     Contract.Requires <ArgumentNullException>(data != null, "data");
 }
Пример #19
0
        public void Given_ValidPOCO_When_Mapped_Then_CorrectXMLPOCOCreated()
        {
            // Arrange
            var datPoco = new EnvCryptDat()
            {
                Categories = new[]
                {
                    new Category()
                    {
                        Name    = "Production",
                        Entries = new[]
                        {
                            new Entry()
                            {
                                Name = "database URL",
                                EncryptionAlgorithm = EnvCryptAlgoEnum.PlainText,
                                EncryptedValue      = new[]
                                {
                                    new byte[1],
                                }
                            },
                            new Entry()
                            {
                                Name = "root password",
                                EncryptionAlgorithm = EnvCryptAlgoEnum.Rsa,
                                KeyHash             = 1,
                                KeyName             = "prod key",
                                EncryptedValue      = new[]
                                {
                                    new byte[2],
                                    new byte[3],
                                }
                            }
                        }
                    },
                    new Category()
                    {
                        Name    = "UAT",
                        Entries = new[]
                        {
                            new Entry()
                            {
                                Name = "root password",
                                EncryptionAlgorithm = EnvCryptAlgoEnum.Aes,
                                KeyHash             = 2,
                                KeyName             = "uat key",
                                EncryptedValue      = new[]
                                {
                                    new byte[4],
                                }
                            }
                        }
                    }
                }
            };

            var strConverterMock = new Mock <IEncryptedDetailsPersistConverter>();

            //      Array of length 1 returns "1", length 2 returns "2"...
            strConverterMock.Setup(c => c.Encode(It.IsAny <byte[]>(), It.IsAny <EnvCryptAlgoEnum>()))
            .Returns <byte[], EnvCryptAlgoEnum>((b, _) => b.Length.ToString());

            // Act
            var mapper = new DatToXmlMapper(strConverterMock.Object);
            var res    = mapper.Map(datPoco);

            // Assert
            res.Items.Should().NotBeNull();
            res.Items.Should().HaveCount(2, "Production & UAT categories containing sets of entries");
            res.Items[0].Name.Should().Be("Production");
            res.Items[1].Name.Should().Be("UAT");

            res.Items[0].Entry.Should().NotBeNull();
            res.Items[0].Entry.Should().HaveCount(2);
            res.Items[1].Entry.Should().NotBeNull();
            res.Items[1].Entry.Should().HaveCount(1);

            res.Items[1].Entry[0].Name.Should().Be("root password");
            res.Items[1].Entry[0].EncryptedValue.Should().HaveCount(1);
            res.Items[1].Entry[0].EncryptedValue[0].Value.Should().Be("4");

            res.Items[1].Entry[0].Decryption.Should().NotBeNull();
            res.Items[1].Entry[0].Decryption.KeyName.Should().Be("uat key");
            res.Items[1].Entry[0].Decryption.Algo.Should().Be(EnvCryptAlgoEnum.Aes.ToString());
            res.Items[1].Entry[0].Decryption.Hash.Should().Be(2);
        }
Пример #20
0
        public void LogDecryption(TWorkflowOptions withWorkflowOptions, EnvCryptDat ecDat, IList <TKey> usingLoadedKeys,
                                  IList <EntriesDecrypterResult <TKey> > results)
        {
            try
            {
                _myDirectory.CreateDirectory(_config.LogDirectory);
            }
            catch
            {
                return;
            }

            var fileName = string.Format(_config.FileNameFormat,
                                         _myDateTime.UtcNow().ToString(DateTimeFormatInFileName),
                                         Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName));

            var    logFilePathWithoutUidOrExt = Path.Combine(_config.LogDirectory, fileName);
            var    logFilePathWithoutUid      = logFilePathWithoutUidOrExt + _config.LogFileExtension;
            string finalLogPath = null;

            /*
             * If original file exists then try to create a unique one.
             */
            if (_myFile.Exists(logFilePathWithoutUid))
            {
                if (_config.MaxTriesToGetUniqueFileName <= 0)
                {
                    return;
                }

                var foundUniqueFileName = false;
                for (int uid = 0; uid < _config.MaxTriesToGetUniqueFileName; uid++)
                {
                    finalLogPath = string.Format("{0}-{1}{2}", logFilePathWithoutUidOrExt, uid, _config.LogFileExtension);

                    if (!_myFile.Exists(finalLogPath))
                    {
                        foundUniqueFileName = true;
                        break;
                    }
                }
                if (!foundUniqueFileName)
                {
                    return;
                }
            }
            else
            {
                finalLogPath = logFilePathWithoutUid;
            }

            Contract.Assert(finalLogPath != null, "a potentially unique final log path must be found at this point");
            var content = GetLogContent(withWorkflowOptions, results);

            try
            {
                _myFile.WriteAllText(finalLogPath, content);
            }
            catch
            {
                return;
            }


            _oldLogCleaner.Run();
        }
Пример #21
0
 public EnvCryptDat Load(TOptions options)
 {
     return(_cachedResult ?? (_cachedResult = _toDecorate.Load(options)));
 }
Пример #22
0
        public IList <EntriesDecrypterResult <TKey> > Decrypt(IList <TKey> usingKeys, EnvCryptDat inDat, IList <CategoryEntryPair> categoryEntryPairs, bool throwExceptionIfEntryNotFound = true, bool throwIfDecryptingKeyNotFound = true, bool throwIfKeyCannotDecrypt = true)
        {
            Contract.Requires <ArgumentNullException>(usingKeys != null, "usingKeys");
            Contract.Requires <ArgumentException>(usingKeys.Any(), "usingKeys");
            Contract.Requires <EnvCryptException>(Contract.ForAll(usingKeys, k => k != null), "all keys in the list can be null");
            Contract.Requires <ArgumentNullException>(inDat != null, "inDat");
            Contract.Requires <ArgumentNullException>(categoryEntryPairs != null, "entryDetails");
            Contract.Ensures(Contract.Result <IList <EntriesDecrypterResult <TKey> > >() != null);
            //
            var ret = new List <EntriesDecrypterResult <TKey> >();

            var keysToUse = new List <TKey>(usingKeys.Count);

            for (uint kI = 0; kI < usingKeys.Count; kI++)
            {
                var currentKey = usingKeys[(int)kI];
                if (!_keySuitabilityChecker.IsDecryptingKey(currentKey))
                {
                    if (throwIfKeyCannotDecrypt)
                    {
                        throw new EnvCryptException("impossible to decrypt using this {0} key. Name: {1}",
                                                    currentKey.Algorithm, currentKey.Name);
                    }
                }
                else
                {
                    keysToUse.Add(currentKey);
                }
            }

            if (!keysToUse.Any())
            {
                return(ret);
            }


            for (uint tI = 0; tI < categoryEntryPairs.Count; tI++)
            {
                var currentRequest = categoryEntryPairs[(int)tI];
                var catName        = currentRequest.Category;
                var entryName      = currentRequest.Entry;

                Entry foundEntry;
                if (inDat.SearchForEntry(catName, entryName, out foundEntry))
                {
                    EntriesDecrypterResult <TKey> toAdd = null;
                    for (uint kI = 0; kI < keysToUse.Count; kI++)
                    {
                        var currentKey = keysToUse[(int)kI];
                        if (currentKey.Name == foundEntry.KeyName &&
                            currentKey.GetHashCode() == foundEntry.KeyHash)
                        {
                            var encodedDecryptedData =
                                _segmentEncrypter.Decrypt(foundEntry.EncryptedValue, currentKey);
                            var decodedDecryptedData =
                                _userStringConverter.Decode(encodedDecryptedData);

                            toAdd = new EntriesDecrypterResult <TKey>()
                            {
                                CategoryEntryPair = currentRequest,
                                DecryptedValue    = decodedDecryptedData,
                                DecryptedUsingKey = currentKey
                            };

                            ret.Add(toAdd);
                            break;
                        }
                    }
                    if (toAdd == null)
                    {
                        // Haven't found the key to decrypt this entry
                        if (throwIfDecryptingKeyNotFound)
                        {
                            throw new EnvCryptException("cannot find suitable key to decrypt. Entry name: {0}  Category: {1}  Required Key Name: {2}  Required Key Hash: {3}", entryName, catName, foundEntry.Name, foundEntry.KeyHash);
                        }
                    }
                }
                else
                {
                    if (throwExceptionIfEntryNotFound)
                    {
                        throw new EnvCryptException("entry not found.  Entry name: {0}  Category: {1}", entryName, catName);
                    }
                }
            }

            return(ret);
        }
Пример #23
0
 public void LogDecryption(TWorkflowOptions withWorkflowOptions, EnvCryptDat ecDat, IList <TKey> usingLoadedKeys, IList <EntriesDecrypterResult <TKey> > results)
 {
 }
Пример #24
0
        public static void AddEntry(this EnvCryptDat toDatPoco,
                                    string categoryName, string entryName,
                                    KeyBase key, IList <byte[]> segments, bool overwriteIfEntryExists = false)
        {
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(categoryName), "categoryName");
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(entryName), "entryName");
            Contract.Requires <ArgumentNullException>(key != null, "key");
            Contract.Requires <ArgumentNullException>(segments != null, "segments");
            //
            var isNewEntry = true;
            var entryToAdd = new Entry();

            var isNewCategory   = true;
            var categoryToAddTo = new Category()
            {
                Name    = categoryName,
                Entries = new List <Entry>()
            };


            // Search for entries with the same name in the desired category
            {
                Category foundCategory;
                if (toDatPoco.SearchForCategory(categoryName, out foundCategory))
                {
                    isNewCategory   = false;
                    categoryToAddTo = foundCategory;
                }
            }

            if (!isNewCategory)
            {
                Entry foundEntry;
                if (categoryToAddTo.SearchForEntry(entryName, out foundEntry))
                {
                    if (overwriteIfEntryExists)
                    {
                        isNewEntry = false;
                        entryToAdd = foundEntry;
                        toDatPoco.RemoveEntry(categoryName, entryName);
                    }
                    else
                    {
                        throw new EnvCryptException(
                                  "the entry '{0}' already exists in the category '{1}' and the option to overwrite was not chosen",
                                  entryName, categoryName);
                    }
                }
            }

            entryToAdd.Name                = entryName;
            entryToAdd.KeyName             = key.Name;
            entryToAdd.KeyHash             = key.GetHashCode();
            entryToAdd.EncryptionAlgorithm = key.Algorithm;
            entryToAdd.EncryptedValue      = segments;

            categoryToAddTo.Entries.Add(entryToAdd);

            if (isNewCategory || !isNewEntry)
            {
                toDatPoco.Categories.Add(categoryToAddTo);
            }
        }