packages feed

keysafe 0.20170303 → 0.20170811

raw patch · 10 files changed

+32/−135 lines, 10 filesdep ~MonadRandomdep ~aesondep ~directory

Dependency ranges changed: MonadRandom, aeson, directory, http-client, optparse-applicative, servant, servant-client, servant-server

Files

CHANGELOG view
@@ -1,3 +1,9 @@+keysafe (0.20170811) unstable; urgency=medium++  * Updated to http-client 0.5.3, servant 0.11, and stackage lts-9.0.++ -- Joey Hess <id@joeyh.name>  Fri, 11 Aug 2017 18:57:15 -0400+ keysafe (0.20170303) unstable; urgency=medium    * Updated to use raaz-0.1.1.
CmdLine.hs view
@@ -14,6 +14,7 @@ import Tunables import qualified Gpg import Options.Applicative+import Data.Monoid import qualified Data.ByteString.UTF8 as BU8 import qualified Data.Text as T import System.Directory
Encryption.hs view
@@ -20,7 +20,6 @@ import qualified Data.Text.Encoding as E import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as B8-import qualified Data.ByteString.UTF8 as BU8 import Text.Read  type AesKey = Raaz.KEY256@@ -202,7 +201,10 @@  -- | Encoded, so that it does not contain any NULs. sha :: B.ByteString -> B.ByteString-sha = BU8.fromString . Raaz.showBase16 . Raaz.sha256+sha = Raaz.toByteString . enc . Raaz.sha256+  where+	enc :: Raaz.Encodable a => a -> Raaz.Base16+	enc = Raaz.encode  padBytes :: Int -> B.ByteString -> B.ByteString padBytes n b = b <> padding
HTTP/Client.hs view
@@ -15,11 +15,8 @@ import Servant.Client import Data.Proxy import Network.HTTP.Client hiding (port, host, Proxy)-import Network.HTTP.Client.Internal (Connection, makeConnection)-import Control.Monad.Trans.Except (ExceptT, runExceptT)+import Network.HTTP.Client.Internal (Connection) import Control.Exception-import qualified Network.Socket-import Network.Socket.ByteString (sendAll, recv) import Network.Socks5 import qualified Data.ByteString.UTF8 as BU8 import Data.List@@ -28,10 +25,10 @@ httpAPI :: Proxy HttpAPI httpAPI = Proxy -motd :: Manager -> BaseUrl -> ClientM Motd-getObject :: StorableObjectIdent -> Maybe ProofOfWork -> Manager -> BaseUrl -> ClientM (POWGuarded StorableObject)-putObject :: StorableObjectIdent -> Maybe ProofOfWork -> StorableObject -> Manager -> BaseUrl -> ClientM (POWGuarded StoreResult)-countObjects :: Maybe ProofOfWork -> Manager -> BaseUrl -> ClientM (POWGuarded CountResult)+motd :: ClientM Motd+getObject :: StorableObjectIdent -> Maybe ProofOfWork -> ClientM (POWGuarded StorableObject)+putObject :: StorableObjectIdent -> Maybe ProofOfWork -> StorableObject -> ClientM (POWGuarded StoreResult)+countObjects :: Maybe ProofOfWork -> ClientM (POWGuarded CountResult) motd :<|> getObject :<|> putObject :<|> countObjects = client httpAPI  tryA :: IO a -> IO (Either SomeException a)@@ -43,7 +40,7 @@ 	-> (String -> a) 	-> (r -> a) 	-> p-	-> (Maybe ProofOfWork -> Manager -> BaseUrl -> ExceptT ServantError IO (POWGuarded r))+	-> (Maybe ProofOfWork -> ClientM (POWGuarded r)) 	-> IO a serverRequest srv onerr onsuccess p a = do 	r <- tryA $ go Nothing maxProofOfWork@@ -69,7 +66,7 @@ -- comparing IP addresses (which are masked somewhat by using tor). serverRequest' 	:: Server-	-> (Manager -> BaseUrl -> ExceptT ServantError IO r)+	-> (ClientM r) 	-> IO (Either String r) serverRequest' srv a = go Nothing (serverUrls srv)   where@@ -77,7 +74,7 @@ 		maybe "no known address" (\err -> "server failure: " ++ show err) lasterr 	go _ (url:urls) = do 		manager <- torableManager-		res <- runExceptT $ a manager url+		res <- runClientM a (ClientEnv manager url) 		case res of 			Left err -> go (Just err) urls 			Right r -> return (Right r)@@ -103,12 +100,6 @@ 	torsockconf = defaultSocksConf "127.0.0.1" torsocksport 	socksdomain = SocksAddrDomainName (BU8.fromString onionaddress) 	socksaddr = SocksAddress socksdomain (fromIntegral p)--socketConnection :: Network.Socket.Socket -> Int -> IO Connection-socketConnection socket chunksize = makeConnection-	(recv socket chunksize)-	(sendAll socket)-	(Network.Socket.close socket)  serverUrls :: Server -> [BaseUrl] serverUrls srv = map go (serverAddress srv)
HTTP/ProofOfWork.hs view
@@ -16,7 +16,7 @@ import GHC.Generics import qualified Data.Text as T import qualified Data.ByteString as B-import Data.Text.Encoding (encodeUtf8)+import Data.Text.Encoding (decodeUtf8, encodeUtf8) import Raaz.Core.Encode import qualified Raaz import Data.BloomFilter.Hash@@ -109,7 +109,7 @@ mkRequeestID' :: RequestIDSecret -> RandomSalt -> RequestID mkRequeestID' (RequestIDSecret key) salt = 	let hmac = Raaz.hmacSha256 key (encodeUtf8 $ fromRandomSalt salt)-	in RequestID salt (T.pack (showBase16 hmac))+	in RequestID salt $ decodeUtf8 $ Raaz.toByteString (Raaz.encode hmac :: Base16)  validRequestID :: RequestIDSecret -> RequestID -> Bool validRequestID secret rid =
HTTP/Server.hs view
@@ -18,6 +18,7 @@ import Storage.Local import Serialization () import Servant+import Network.Wai (Application) import Network.Wai.Handler.Warp import Control.Monad.IO.Class import Control.Concurrent
Makefile view
@@ -34,7 +34,7 @@ 		$(BUILDER) build $(BUILDEROPTIONS); \ 	fi 	if [ "$(BUILDER)" = stack ]; then \-		ln -sf $$(find .stack-work/ -name keysafe -type f | grep build/keysafe/keysafe | tail -n 1) keysafe; \+		ln -sf $$(stack path --dist-dir)/build/keysafe/keysafe keysafe; \ 	else \ 		ln -sf dist/build/keysafe/keysafe keysafe; \ 	fi
Storage.hs view
@@ -73,9 +73,6 @@ -- -- If a server is not currently accessible, it will be queued locally. -- If any uploads are queued, returns True.------ TODO: Add shuffling and queueing/chaffing to prevent--- correlation of related shares. storeShares :: StorageLocations -> ShareIdents -> [S.Set Share] -> UpdateProgress -> IO (StoreResult, Bool, [Storage]) storeShares (StorageLocations locs) allsis shares updateprogress = do 	((r, anyqueued), usedlocs) <- go allsis shares [] False
− TODO
@@ -1,100 +0,0 @@-Soon:--* Finish vetting 2 servers to Recommended.-* Set up --check-servers in a cron job, so I know when servers are down.-* Remove gpg key passohrase from gpg keys that keysafe backs up.-  The reason for this is that the user may well forget their gpg key-  passphrase, and it's *weird* to restore a key with keysafe's password-  and then have it passphrase protected.-  The gpg key passphrase is intended only to keep a key from being used-  for a short period of time (a week or so) when the device holding it -  is known to have been compromised, so the key can be revoked.-  This doesn't really apply to keys backed up with keysafe -- if they get-  compromised somehow, the user won't know, and cracking the gpg passphrase-  should be almost trivial to an attacker who was able to break keysafe's-  password.-  paperkey can remove gpg key passphrases. Is there any better way?-  It might make sense for keysafe to prompt for a new gpg passphrase-  when restoring.--Later:--* The attack cost display can lead to a false sense of security if the user-  takes it as gospel. It needs to be clear that it's an estimate. This and-  other parts of the keysafe UI need usability testing.-* Make --gui password entry fields longer, so user does not feel they need-  to make password short. (zenity may not allow configuring this)-* improve restore progress bar points (update after every hash try)-* If we retrieved enough shares successfully, but decrypt failed, must-  be a wrong password, so prompt for re-entry and retry with those shares.-* --no-jargon which makes the UI avoid terms like "secret key" and "crack-  password". Do usability testing!-* --key-value=$N which eliminates the question about password value,-  and rejects passwords that would cost less than $N to crack at current-  rates. This should add a combo box to the password entry form in the-  GUI to let the user adjust the $N there.-* In backup, only upload to N-1 servers immediately, and delay the rest-  for up to several days, with some uploads of chaff, to prevent-  collaborating evil servers from correlating related shards.-* Add some random padding to http requests and responses, to make it-  harder for traffic analysis to tell that given TOR traffic is-  keysafe traffic.--Wishlist:--* Custom GUI, instead of zenity. Allows:-  - Fewer screens by consolidating multiple prompts.-  - Check same password entered second time and don't allow continuing-    if not.-  - Password strengh display, and don't allow continuing if password is too-    weak.-* Keep secret keys in locked memory until they're encrypted.-  (Raaz makes this possible to do.)-  Would be nice, but not super-important, since gpg secret keys-  are passphrase protected anyway..-* Don't require --totalshares and --neededshares on restore when unusual-  values were used for backup. --  The difficulty is that the number of needed shares cannot be determined by-  looking at shares, and guessing it wrong will result in combining-  too few shares yielding garbage, which it will take up to an hour to-  try to decrypt, before it can tell that more shares are needed.--  This could be dealt with by including the number of needed shares in the-  serialization of Share, but then an attacker could use it to partition-  shares from servers. If only one person uses --neededshares=5,-  the attacker can guess that all their shares go together.--  What about including the number of needed shares in the name? Since that's-  hashed, it's not visible to an attacker. Keysafe would need to try names-  with 2 shares, then 3, etc, and once it found shares, it would know the-  number needed. It should also be possible to avoid breaking backwards-  compatability, by only including the number of shares in the name when-  it's not the standard number. To avoid needing to re-run argon2 for each-  try, the argon2 hash of the name could be calculated first, and then the-  number of needed shares appended before the final sha256 hash is-  generated.-  -  If an attacker is able to guess the name, and a nonstandard number of-  shares was used, the attacker could upload other objects where they would-  be found before the real objects. This could be used to prevent-  restore from working. (It also makes a malicious data attack (as described-  in https://keysafe.branchable.com/details/) possible by attackers who do not-  control the servers.--Encryption tunables changes:--* Argon2d is more resistent to GPU/ASIC attack optimisation.-  Switching from Argon2i would require new tunables, and delay restores-  (of keys backed up using the old tunables, and when the user provides the-  wrong name) by ~10 minutes, so deferred for now-  until there's some other reason to change the tunables.-* The ShareIdents derivation currently appends a number and sha256 hashes-  to generate a stream of values. Ben M points out that HMAC is a more-  typical way to do such a thing. Even better, a HKDF-Expand-  (RFC5869) can generate a stream which can then be chunked up into values.  -  Either of these would avoid a full pre-image attack on SHA-2 breaking-  keysafe. Of course, such an SHA-2 attack would be a general security-  disaster. HKDF may prove more robust in the face of partial SHA-2 breaks.-  Deferred for now until tthere's some other reason to change keysafe's-  tunables.
keysafe.cabal view
@@ -1,5 +1,5 @@ Name: keysafe-Version: 0.20170303+Version: 0.20170811 Cabal-Version: >= 1.8 Maintainer: Joey Hess <joey@kitenet.net> Author: Joey Hess@@ -19,7 +19,6 @@ License-File: AGPL Extra-Source-Files:   CHANGELOG-  TODO   INSTALL   keysafe.1   keysafe.service@@ -52,18 +51,18 @@     , unix == 2.7.*     , filepath == 1.4.*     , split == 0.2.*-    , directory == 1.2.*+    , directory (>= 1.2 && < 1.4)     , process (>= 1.2 && < 1.5)-    , optparse-applicative == 0.12.*+    , optparse-applicative (>= 0.12 && < 0.14)     , readline == 1.0.*     , zxcvbn-c == 1.0.*-    , servant (>= 0.7 && < 0.9)-    , servant-server (>= 0.7 && < 0.9)-    , servant-client (>= 0.7 && < 0.9)-    , aeson == 0.11.*+    , servant (>= 0.7 && < 0.12)+    , servant-server (>= 0.7 && < 0.12)+    , servant-client (>= 0.7 && < 0.12)+    , aeson (>= 0.11 && < 1.2)     , wai == 3.2.*     , warp == 3.2.*-    , http-client == 0.4.*+    , http-client (>= 0.5.3 && < 0.6)     , transformers (>= 0.4 && < 0.6)     , stm == 2.4.*     , socks == 0.5.*@@ -79,7 +78,7 @@     , unix-compat == 0.4.*     , exceptions == 0.8.*     , random-shuffle == 0.0.*-    , MonadRandom == 0.4.*+    , MonadRandom (>= 0.4 && < 0.6)   Other-Modules:     AutoStart     BackupLog