From fd89dd25ca024493dcfd3b5b295749058f74065b Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Fri, 10 Nov 2017 18:20:55 +0100 Subject: [PATCH 1/3] Use DAuth instead of botan for password hashing. Fixes #7 --- dub.json | 6 +---- source/calendarwebapp/authenticator.d | 4 +-- source/calendarwebapp/configuration.d | 8 ++---- source/calendarwebapp/passhash.d | 38 ++++++++++++--------------- test/calendarwebapp/testpasshash.d | 25 +++++++----------- 5 files changed, 31 insertions(+), 50 deletions(-) diff --git a/dub.json b/dub.json index 74add46..c732017 100644 --- a/dub.json +++ b/dub.json @@ -4,14 +4,10 @@ "Johannes Loher" ], "dependencies": { - "botan": "~>1.12.9", + "dauth": "~>0.6.3", "vibe-d": "~>0.8.1", - "vibe-d:tls": "~>0.8.1", "poodinis": "~>8.0.1" }, - "subConfigurations": { - "vibe-d:tls": "botan" - }, "description": "A simple webapplication to edit and view calendar entries", "copyright": "Copyright © 2017, Johannes Loher", "license": "MIT", diff --git a/source/calendarwebapp/authenticator.d b/source/calendarwebapp/authenticator.d index 5f79986..a15c380 100644 --- a/source/calendarwebapp/authenticator.d +++ b/source/calendarwebapp/authenticator.d @@ -28,8 +28,6 @@ private: public: Nullable!AuthInfo checkUser(string username, string password) @safe { - import botan.passhash.bcrypt : checkBcrypt; - auto result = users.findOne(["username" : username]); /* checkHash should be called using vibe.core.concurrency.async to avoid blocking, but https://github.com/vibe-d/vibe.d/issues/1521 is @@ -37,6 +35,8 @@ public: if (result != Bson(null)) { auto authInfo = result.deserializeBson!AuthInfo; + import vibe.core.log : logInfo; + logInfo(passwordHasher.generateHash(password)); if (passwordHasher.checkHash(password, authInfo.passwordHash)) { return authInfo.nullable; diff --git a/source/calendarwebapp/configuration.d b/source/calendarwebapp/configuration.d index 21a5465..7a5ec87 100644 --- a/source/calendarwebapp/configuration.d +++ b/source/calendarwebapp/configuration.d @@ -1,12 +1,9 @@ module calendarwebapp.configuration; -import botan.rng.auto_rng : AutoSeededRNG; -import botan.rng.rng : RandomNumberGenerator; - import calendarwebapp.authenticator : Authenticator, MongoDBAuthenticator; import calendarwebapp.calendarwebapp : CalendarWebapp; import calendarwebapp.event : EventStore, MongoDBEventStore; -import calendarwebapp.passhash : BcryptPasswordHasher, PasswordHasher; +import calendarwebapp.passhash : PasswordHasher, SHA256PasswordHasher; import poodinis; @@ -23,8 +20,7 @@ public: container.register!MongoClient.existingInstance(mongoClient); container.register!(EventStore, MongoDBEventStore!()); container.register!(Authenticator, MongoDBAuthenticator!()); - container.register!(PasswordHasher, BcryptPasswordHasher); - container.register!(RandomNumberGenerator, AutoSeededRNG); + container.register!(PasswordHasher, SHA256PasswordHasher); container.register!CalendarWebapp; container.register!(ValueInjector!string, StringInjector); container.register!(ValueInjector!MongoCollection, MongoCollectionInjector); diff --git a/source/calendarwebapp/passhash.d b/source/calendarwebapp/passhash.d index 7dbc4b2..c1b3e82 100644 --- a/source/calendarwebapp/passhash.d +++ b/source/calendarwebapp/passhash.d @@ -4,30 +4,10 @@ import poodinis; interface PasswordHasher { - string generateHash(in string password) @safe; + string generateHash(in string password) const @safe; bool checkHash(in string password, in string hash) const @safe; } -class BcryptPasswordHasher : PasswordHasher -{ - import botan.passhash.bcrypt : checkBcrypt, generateBcrypt; - import botan.rng.rng : RandomNumberGenerator; - - string generateHash(in string password) @safe - { - return (() @trusted => generateBcrypt(password, rng, cost))(); - } - - bool checkHash(in string password, in string hash) const @safe - { - return (()@trusted => checkBcrypt(password, hash))(); - } - -private: - @Autowire RandomNumberGenerator rng; - enum cost = 10; -} - class StubPasswordHasher : PasswordHasher { string generateHash(in string password) const @safe pure nothrow @@ -40,3 +20,19 @@ class StubPasswordHasher : PasswordHasher return password == hash; } } + +class SHA256PasswordHasher : PasswordHasher +{ + import dauth; + import std.digest.sha : SHA256; + + string generateHash(in string password) const @safe + { + return (() @trusted => password.dupPassword.makeHash!SHA256.toCryptString)(); + } + + bool checkHash(in string password, in string hash) const @safe + { + return (() @trusted => isSameHash(password.dupPassword, parseHash(hash)))(); + } +} diff --git a/test/calendarwebapp/testpasshash.d b/test/calendarwebapp/testpasshash.d index 6282db5..1bcea57 100644 --- a/test/calendarwebapp/testpasshash.d +++ b/test/calendarwebapp/testpasshash.d @@ -4,24 +4,8 @@ import calendarwebapp.passhash; import poodinis; -//import unit_threaded.should; import unit_threaded; -@("BcryptPasswordHasher") -@Values("", "test", "langesKompliziertesPasswort") -@system unittest -{ - import botan.rng.rng : RandomNumberGenerator; - import botan.rng.auto_rng : AutoSeededRNG; - auto container = new shared DependencyContainer; - container.register!(RandomNumberGenerator, AutoSeededRNG); - container.register!(PasswordHasher, BcryptPasswordHasher); - - auto hasher = container.resolve!PasswordHasher; - immutable testPassword = getValue!string; - hasher.checkHash(testPassword, hasher.generateHash(testPassword)).shouldBeTrue; -} - @("StubPasswordHasher") @Values("", "test", "langesKompliziertesPasswort") @safe unittest @@ -30,3 +14,12 @@ import unit_threaded; immutable testPassword = getValue!string; hasher.checkHash(testPassword, hasher.generateHash(testPassword)).shouldBeTrue; } + +@("SHA256PasswordHasher") +@Values("", "test", "langesKompliziertesPasswort") +@safe unittest +{ + immutable hasher = new SHA256PasswordHasher; + immutable testPassword = getValue!string; + hasher.checkHash(testPassword, hasher.generateHash(testPassword)).shouldBeTrue; +} From 37fda7abc8aa14cb67ed343e49f461982f47c4d7 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Fri, 10 Nov 2017 18:31:47 +0100 Subject: [PATCH 2/3] a little cleanup --- source/calendarwebapp/passhash.d | 4 +--- test/calendarwebapp/testpasshash.d | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/source/calendarwebapp/passhash.d b/source/calendarwebapp/passhash.d index c1b3e82..30c4829 100644 --- a/source/calendarwebapp/passhash.d +++ b/source/calendarwebapp/passhash.d @@ -1,7 +1,5 @@ module calendarwebapp.passhash; -import poodinis; - interface PasswordHasher { string generateHash(in string password) const @safe; @@ -23,7 +21,7 @@ class StubPasswordHasher : PasswordHasher class SHA256PasswordHasher : PasswordHasher { - import dauth; + import dauth : dupPassword, isSameHash, makeHash, parseHash; import std.digest.sha : SHA256; string generateHash(in string password) const @safe diff --git a/test/calendarwebapp/testpasshash.d b/test/calendarwebapp/testpasshash.d index 1bcea57..d292bb1 100644 --- a/test/calendarwebapp/testpasshash.d +++ b/test/calendarwebapp/testpasshash.d @@ -2,8 +2,6 @@ module test.calendarwebapp.testpasshash; import calendarwebapp.passhash; -import poodinis; - import unit_threaded; @("StubPasswordHasher") From 84206e28818114243476b39b0ede4ea9c5d2bcf6 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Mon, 20 Nov 2017 22:36:16 +0100 Subject: [PATCH 3/3] some small fixups --- source/calendarwebapp/authenticator.d | 2 -- source/calendarwebapp/configuration.d | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/source/calendarwebapp/authenticator.d b/source/calendarwebapp/authenticator.d index 4ab0b5b..0322398 100644 --- a/source/calendarwebapp/authenticator.d +++ b/source/calendarwebapp/authenticator.d @@ -37,8 +37,6 @@ public: if (result != Bson(null)) { auto authInfo = result.deserializeBson!AuthInfo; - import vibe.core.log : logInfo; - logInfo(passwordHasher.generateHash(password)); if (passwordHasher.checkHash(password, authInfo.passwordHash)) { return authInfo.nullable; diff --git a/source/calendarwebapp/configuration.d b/source/calendarwebapp/configuration.d index ffb162d..1ef363d 100644 --- a/source/calendarwebapp/configuration.d +++ b/source/calendarwebapp/configuration.d @@ -20,7 +20,7 @@ public: override void registerDependencies(shared(DependencyContainer) container) { auto mongoClient = connectMongoDB("localhost"); - auto pool = new MySQLPool("localhost", "root", "Ilemm3Kzj", "CalendarWebapp"); + auto pool = new MySQLPool("localhost", "username", "password", "CalendarWebapp"); container.register!MySQLPool.existingInstance(pool); container.register!MongoClient.existingInstance(mongoClient); container.register!(EventStore, MySQLEventStore);