Improved Certificate Handling (fixed problem with Certificate validation)

This commit is contained in:
Philipp Crocoll
2013-12-12 10:24:24 +01:00
parent ee8348e688
commit b320477a64
22 changed files with 1265 additions and 869 deletions

View File

@@ -18,9 +18,9 @@ namespace Kp2aUnitTests
{
TestRunner runner = new TestRunner();
// Run all tests from this assembly
runner.AddTests(Assembly.GetExecutingAssembly());
//runner.AddTests(new List<Type> { typeof(TestSynchronizeCachedDatabase) });
//runner.AddTests(typeof(TestSaveDbCached).GetMethod("TestLoadEditSaveWhenModified"));
//runner.AddTests(Assembly.GetExecutingAssembly());
//runner.AddTests(new List<Type> { typeof(TestSynchronizeCachedDatabase)});
runner.AddTests(typeof(TestLoadDb).GetMethod("LoadErrorWithCertificateTrustFailure"));
//runner.AddTests(new List<Type> { typeof(TestSaveDb) });
//runner.AddTests(new List<Type> { typeof(TestCachingFileStorage) });

View File

@@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.18051
// Laufzeitversion:4.0.30319.34003
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.

View File

@@ -66,7 +66,7 @@ namespace Kp2aUnitTests
var app = CreateTestKp2aApp();
app.CreateNewDatabase();
bool loadSuccesful = false;
LoadDb task = new LoadDb(app, new IOConnectionInfo() { Path = filename }, null, password, keyfile, new ActionOnFinish((success, message) =>
LoadDb task = new LoadDb(app, new IOConnectionInfo() { Path = filename }, null, CreateKey(password, keyfile), keyfile, new ActionOnFinish((success, message) =>
{
if (!success)
Kp2aLog.Log(message);
@@ -80,7 +80,20 @@ namespace Kp2aUnitTests
Assert.IsTrue(loadSuccesful);
return app;
}
protected static CompositeKey CreateKey(string password, string keyfile)
{
CompositeKey key = new CompositeKey();
key.AddUserKey(new KcpPassword(password));
if (!String.IsNullOrEmpty(keyfile))
key.AddUserKey(new KcpKeyFile(keyfile));
return key;
}
protected static CompositeKey CreateKey(string password)
{
CompositeKey key = new CompositeKey();
key.AddUserKey(new KcpPassword(password));
return key;
}
protected virtual TestKp2aApp CreateTestKp2aApp()
{
TestKp2aApp app = new TestKp2aApp();

View File

@@ -14,6 +14,12 @@ namespace Kp2aUnitTests
[TestClass]
class TestCachingFileStorage: TestBase
{
[TestInitialize]
public void InitTests()
{
TestFileStorage.Offline = false;
}
private TestFileStorage _testFileStorage;
private CachingFileStorage _fileStorage;
private static readonly string CachingTestFile = DefaultDirectory + "cachingTestFile.txt";
@@ -37,7 +43,7 @@ namespace Kp2aUnitTests
Assert.AreEqual(MemoryStreamToString(fileContents), _defaultCacheFileContents);
//let the base file storage go offline:
_testFileStorage.Offline = true;
TestFileStorage.Offline = true;
//now try to read the file again:
MemoryStream fileContents2 = ReadToMemoryStream(_fileStorage, CachingTestFile);
@@ -98,7 +104,7 @@ namespace Kp2aUnitTests
_testCacheSupervisor.AssertSingleCall(TestCacheSupervisor.UpdatedCachedFileOnLoadId);
//let the base file storage go offline:
_testFileStorage.Offline = true;
TestFileStorage.Offline = true;
//write something to the cache:
string newContent = "new content";
@@ -116,7 +122,7 @@ namespace Kp2aUnitTests
Assert.AreEqual(MemoryStreamToString(fileContents2), newContent);
//now go online and read again. This should trigger a sync and the modified data must be returned
_testFileStorage.Offline = false;
TestFileStorage.Offline = false;
MemoryStream fileContents3 = ReadToMemoryStream(_fileStorage, CachingTestFile);
Assert.AreEqual(MemoryStreamToString(fileContents3), newContent);
@@ -141,7 +147,7 @@ namespace Kp2aUnitTests
_testCacheSupervisor.AssertSingleCall(TestCacheSupervisor.UpdatedCachedFileOnLoadId);
//let the base file storage go offline:
_testFileStorage.Offline = true;
TestFileStorage.Offline = true;
//write something to the cache:
string newLocalContent = "new local content";
@@ -153,7 +159,7 @@ namespace Kp2aUnitTests
File.WriteAllText(CachingTestFile, "new remote content");
//go online again:
_testFileStorage.Offline = false;
TestFileStorage.Offline = false;
//now try to read the file again:
MemoryStream fileContents2 = ReadToMemoryStream(_fileStorage, CachingTestFile);
@@ -231,7 +237,7 @@ namespace Kp2aUnitTests
private void SetupFileStorage()
{
_testFileStorage = new TestFileStorage();
_testFileStorage = new TestFileStorage(new TestKp2aApp());
_testCacheSupervisor = new TestCacheSupervisor();
//_fileStorage = new CachingFileStorage(_testFileStorage, Application.Context.CacheDir.Path, _testCacheSupervisor);
_fileStorage = new CachingFileStorage(_testFileStorage, "/mnt/sdcard/kp2atest_cache", _testCacheSupervisor);

View File

@@ -1,16 +1,23 @@
using System;
using System.Collections.Generic;
using System.IO;
using Android.Content;
using Android.OS;
using KeePassLib.Serialization;
using keepass2android;
using keepass2android.Io;
namespace Kp2aUnitTests
{
internal class TestFileStorage: IFileStorage
{
private BuiltInFileStorage _builtIn = new BuiltInFileStorage();
public TestFileStorage(IKp2aApp app)
{
_builtIn = new BuiltInFileStorage(app);
}
private BuiltInFileStorage _builtIn;
public bool Offline { get; set; }
public static bool Offline { get; set; }
public IEnumerable<string> SupportedProtocols { get { yield return "test"; } }
@@ -96,6 +103,11 @@ namespace Kp2aUnitTests
return _builtIn.RequiresCredentials(ioc);
}
public void CreateDirectory(IOConnectionInfo ioc, string newDirName)
{
throw new NotImplementedException();
}
public void CreateDirectory(IOConnectionInfo ioc)
{
throw new NotImplementedException();
@@ -110,5 +122,66 @@ namespace Kp2aUnitTests
{
throw new NotImplementedException();
}
public bool RequiresSetup(IOConnectionInfo ioConnection)
{
return false;
}
public string IocToPath(IOConnectionInfo ioc)
{
return ioc.Path;
}
public void StartSelectFile(IFileStorageSetupInitiatorActivity activity, bool isForSave, int requestCode, string protocolId)
{
throw new NotImplementedException();
}
public void PrepareFileUsage(IFileStorageSetupInitiatorActivity activity, IOConnectionInfo ioc, int requestCode,
bool alwaysReturnSuccess)
{
throw new NotImplementedException();
}
public void OnCreate(IFileStorageSetupActivity activity, Bundle savedInstanceState)
{
throw new NotImplementedException();
}
public void OnResume(IFileStorageSetupActivity activity)
{
throw new NotImplementedException();
}
public void OnStart(IFileStorageSetupActivity activity)
{
throw new NotImplementedException();
}
public void OnActivityResult(IFileStorageSetupActivity activity, int requestCode, int resultCode, Intent data)
{
throw new NotImplementedException();
}
public string GetDisplayName(IOConnectionInfo ioc)
{
return ioc.Path;
}
public string CreateFilePath(string parent, string newFilename)
{
throw new NotImplementedException();
}
public IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
{
throw new NotImplementedException();
}
public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Security;
using Android.App;
using Android.Content;
using Android.OS;
using KeePassLib.Keys;
using KeePassLib.Serialization;
using keepass2android;
using keepass2android.Io;
@@ -30,18 +32,27 @@ namespace Kp2aUnitTests
}
public virtual TestFileStorage TestFileStorage
{
get
{
if (_testFileStorage != null)
return _testFileStorage;
return (TestFileStorage) FileStorage;
}
set { _testFileStorage = value; }
}
public void LockDatabase(bool allowQuickUnlock = true)
{
throw new NotImplementedException();
}
public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, string password, string keyFile,
public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey,
ProgressDialogStatusLogger statusLogger)
{
_db.LoadData(this, ioConnectionInfo, memoryStream, password, statusLogger);
_db.LoadData(this, ioConnectionInfo, memoryStream, compKey, statusLogger);
}
public Database GetDb()
{
return _db;
@@ -128,10 +139,11 @@ namespace Kp2aUnitTests
public bool TriggerReloadCalled;
private TestFileStorage _testFileStorage;
public TestKp2aApp()
{
FileStorage = new BuiltInFileStorage();
FileStorage = new BuiltInFileStorage(this);
}
public void TriggerReload(Context ctx)
@@ -139,6 +151,16 @@ namespace Kp2aUnitTests
TriggerReloadCalled = true;
}
public bool OnServerCertificateError(int sslPolicyErrors)
{
ServerCertificateErrorCalled = true;
return ServerCertificateErrorResponse;
}
public bool ServerCertificateErrorResponse { get; set; }
protected bool ServerCertificateErrorCalled { get; set; }
public void SetYesNoCancelResult(YesNoCancelResult yesNoCancelResult)
{
_yesNoCancelResult = yesNoCancelResult;

View File

@@ -1,9 +1,7 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using Android.App;
using Android.OS;
using KeePassLib.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using keepass2android;
@@ -21,8 +19,10 @@ namespace Kp2aUnitTests
IKp2aApp app = new TestKp2aApp();
app.CreateNewDatabase();
bool loadSuccesful = false;
LoadDb task = new LoadDb(app, new IOConnectionInfo() { Path = TestDbDirectory+filenameWithoutDir }, null,
password, keyfile, new ActionOnFinish((success, message) =>
var key = CreateKey(password, keyfile);
LoadDb task = new LoadDb(app, new IOConnectionInfo { Path = TestDbDirectory+filenameWithoutDir }, null,
key, keyfile, new ActionOnFinish((success, message) =>
{
if (!success)
Android.Util.Log.Debug("KP2ATest", "error loading db: " + message);
@@ -40,6 +40,8 @@ namespace Kp2aUnitTests
Assert.AreEqual(2,app.GetDb().KpDatabase.RootGroup.Entries.Count());
}
[TestMethod]
public void TestLoadWithPasswordOnly()
@@ -74,11 +76,12 @@ namespace Kp2aUnitTests
public void LoadFromRemoteWithDomain()
{
var ioc = RemoteDomainIoc; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public!
IKp2aApp app = new TestKp2aApp();
var app = new TestKp2aApp();
app.ServerCertificateErrorResponse = true; //accept invalid cert
app.CreateNewDatabase();
bool loadSuccesful = false;
LoadDb task = new LoadDb(app, ioc, null, "a", null, new ActionOnFinish((success, message) =>
LoadDb task = new LoadDb(app, ioc, null, CreateKey("a"), null, new ActionOnFinish((success, message) =>
{
if (!success)
Android.Util.Log.Debug("KP2ATest", "error loading db: " + message);
@@ -95,14 +98,69 @@ namespace Kp2aUnitTests
}
[TestMethod]
public void LoadFromRemote1and1()
public void LoadErrorWithCertificateTrustFailure()
{
var ioc = RemoteCertFailureIoc; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public!
var app = new TestKp2aApp();
app.ServerCertificateErrorResponse = false;
app.CreateNewDatabase();
bool loadSuccesful = false;
string theMessage = "";
LoadDb task = new LoadDb(app, ioc, null, CreateKey("test"), null, new ActionOnFinish((success, message) =>
{
if (!success)
Android.Util.Log.Debug("KP2ATest", "error loading db: " + message);
loadSuccesful = success;
theMessage = message;
})
);
ProgressTask pt = new ProgressTask(app, Application.Context, task);
Android.Util.Log.Debug("KP2ATest", "Running ProgressTask");
pt.Run();
pt.JoinWorkerThread();
Android.Util.Log.Debug("KP2ATest", "PT.run finished");
Assert.IsFalse(loadSuccesful, "database should not be loaded because invalid certificates are not accepted");
Assert.AreEqual(theMessage, UiStringKey.ErrorOcurred +" "+UiStringKey.CertificateFailure);
}
[TestMethod]
public void LoadWithAcceptedCertificateTrustFailure()
{
var ioc = RemoteCertFailureIoc; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public!
var app = new TestKp2aApp();
app.ServerCertificateErrorResponse = true;
app.CreateNewDatabase();
bool loadSuccesful = false;
LoadDb task = new LoadDb(app, ioc, null, CreateKey("test"), null, new ActionOnFinish((success, message) =>
{
if (!success)
Android.Util.Log.Debug("KP2ATest", "error loading db: " + message);
loadSuccesful = success;
})
);
ProgressTask pt = new ProgressTask(app, Application.Context, task);
Android.Util.Log.Debug("KP2ATest", "Running ProgressTask");
pt.Run();
pt.JoinWorkerThread();
Android.Util.Log.Debug("KP2ATest", "PT.run finished");
Assert.IsTrue(loadSuccesful, "database should be loaded because invalid certificates are accepted");
}
[TestMethod]
public void LoadFromRemote1And1()
{
var ioc = RemoteIoc1and1; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public!
IKp2aApp app = new TestKp2aApp();
app.CreateNewDatabase();
bool loadSuccesful = false;
LoadDb task = new LoadDb(app, ioc, null, "test", null, new ActionOnFinish((success, message) =>
LoadDb task = new LoadDb(app, ioc, null, CreateKey("test"), null, new ActionOnFinish((success, message) =>
{
if (!success)
Android.Util.Log.Debug("KP2ATest", "error loading db: " + message);
@@ -120,7 +178,7 @@ namespace Kp2aUnitTests
[TestMethod]
public void LoadFromRemote1and1NonExisting()
public void LoadFromRemote1And1NonExisting()
{
var ioc = RemoteIoc1and1NonExisting; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public!
IKp2aApp app = new TestKp2aApp();
@@ -128,7 +186,7 @@ namespace Kp2aUnitTests
bool loadSuccesful = false;
bool gotError = false;
LoadDb task = new LoadDb(app, ioc, null, "test", null, new ActionOnFinish((success, message) =>
LoadDb task = new LoadDb(app, ioc, null, CreateKey("test"), null, new ActionOnFinish((success, message) =>
{
if (!success)
{
@@ -148,7 +206,7 @@ namespace Kp2aUnitTests
}
[TestMethod]
public void LoadFromRemote1and1WrongCredentials()
public void LoadFromRemote1And1WrongCredentials()
{
var ioc = RemoteIoc1and1WrongCredentials; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public!
IKp2aApp app = new TestKp2aApp();
@@ -156,7 +214,7 @@ namespace Kp2aUnitTests
bool loadSuccesful = false;
bool gotError = false;
LoadDb task = new LoadDb(app, ioc, null, "test", null, new ActionOnFinish((success, message) =>
LoadDb task = new LoadDb(app, ioc, null, CreateKey("test"), null, new ActionOnFinish((success, message) =>
{
if (!success)
{
@@ -179,7 +237,7 @@ namespace Kp2aUnitTests
[TestMethod]
public void FileNotFoundExceptionWithWebDav()
{
var fileStorage = new BuiltInFileStorage();
var fileStorage = new BuiltInFileStorage(new TestKp2aApp());
//should work:
using (var stream = fileStorage.OpenFileForRead(RemoteIoc1and1))

View File

@@ -22,12 +22,12 @@ namespace Kp2aUnitTests
class TestSaveDbCached: TestBase
{
private TestCacheSupervisor _testCacheSupervisor = new TestCacheSupervisor();
private TestFileStorage _testFileStorage = new TestFileStorage();
protected override TestKp2aApp CreateTestKp2aApp()
{
TestKp2aApp app = base.CreateTestKp2aApp();
app.FileStorage = new CachingFileStorage(_testFileStorage, "/mnt/sdcard/kp2atest/cache/", _testCacheSupervisor);
app.FileStorage = new CachingFileStorage(new TestFileStorage(app), "/mnt/sdcard/kp2atest/cache/", _testCacheSupervisor);
return app;
}

View File

@@ -19,13 +19,20 @@ namespace Kp2aUnitTests
[TestClass]
internal class TestSynchronizeCachedDatabase : TestBase
{
[TestInitialize]
public void InitTests()
{
TestFileStorage.Offline = false;
}
private TestCacheSupervisor _testCacheSupervisor = new TestCacheSupervisor();
private TestFileStorage _testFileStorage = new TestFileStorage();
protected override TestKp2aApp CreateTestKp2aApp()
{
TestKp2aApp app = base.CreateTestKp2aApp();
app.FileStorage = new CachingFileStorage(_testFileStorage, "/mnt/sdcard/kp2atest/cache/", _testCacheSupervisor);
app.TestFileStorage = new TestFileStorage(app);
app.FileStorage = new CachingFileStorage(app.TestFileStorage, "/mnt/sdcard/kp2atest/cache/", _testCacheSupervisor);
return app;
}
@@ -58,7 +65,7 @@ namespace Kp2aUnitTests
Assert.AreEqual(resultMessage, app.GetResourceString(UiStringKey.FilesInSync));
//go offline:
_testFileStorage.Offline = true;
TestFileStorage.Offline = true;
//sync when offline (->error)
Synchronize(app, out wasSuccessful, out resultMessage);
@@ -73,7 +80,7 @@ namespace Kp2aUnitTests
_testCacheSupervisor.AssertSingleCall(TestCacheSupervisor.CouldntSaveToRemoteId);
//go online again:
_testFileStorage.Offline = false;
TestFileStorage.Offline = false;
//sync with local changes only (-> upload):
Synchronize(app, out wasSuccessful, out resultMessage);
@@ -81,10 +88,10 @@ namespace Kp2aUnitTests
Assert.AreEqual(resultMessage, app.GetResourceString(UiStringKey.SynchronizedDatabaseSuccessfully));
//ensure both files are identical and up to date now:
_testFileStorage.Offline = true;
TestFileStorage.Offline = true;
var appOfflineLoaded = LoadDatabase(DefaultFilename, DefaultPassword, DefaultKeyfile);
_testCacheSupervisor.AssertSingleCall(TestCacheSupervisor.CouldntOpenFromRemoteId);
_testFileStorage.Offline = false;
TestFileStorage.Offline = false;
var appRemoteLoaded = LoadDatabase(DefaultFilename, DefaultPassword, DefaultKeyfile);
_testCacheSupervisor.AssertSingleCall(TestCacheSupervisor.LoadedFromRemoteInSyncId);
@@ -92,6 +99,8 @@ namespace Kp2aUnitTests
AssertDatabasesAreEqual(app.GetDb().KpDatabase, appRemoteLoaded.GetDb().KpDatabase);
}
[TestMethod]
public void TestSyncWhenRemoteDeleted()
{
@@ -133,11 +142,11 @@ namespace Kp2aUnitTests
_testCacheSupervisor.AssertSingleCall(TestCacheSupervisor.LoadedFromRemoteInSyncId);
var app2 = LoadDatabase(DefaultFilename, DefaultPassword, DefaultKeyfile);
app2.FileStorage = _testFileStorage; //give app2 direct access to the remote file
app2.FileStorage = app.TestFileStorage; //give app2 direct access to the remote file
_testCacheSupervisor.AssertSingleCall(TestCacheSupervisor.LoadedFromRemoteInSyncId);
//go offline:
_testFileStorage.Offline = true;
TestFileStorage.Offline = true;
string resultMessage;
@@ -153,7 +162,7 @@ namespace Kp2aUnitTests
_testCacheSupervisor.AssertSingleCall(TestCacheSupervisor.CouldntSaveToRemoteId);
//go online again:
_testFileStorage.Offline = false;
TestFileStorage.Offline = false;
//...and remote only for "app2":
SaveDatabase(app2);