summaryrefslogtreecommitdiffhomepage
path: root/keysafe.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2016-09-14 16:42:26 -0400
committerJoey Hess <joeyh@joeyh.name>2016-09-14 16:59:20 -0400
commita41cbda751d515032859d72656fda3d219300ecb (patch)
treefdc5324c56e0b67b6e74826cd6b8cd742984ecf0 /keysafe.hs
parenta68caf8b54b9d37deeaeddc6a28394d1587f1dc5 (diff)
downloadkeysafe-a41cbda751d515032859d72656fda3d219300ecb.tar.gz
Store information about backed up keys in ~/.keysafe/backup.log
This can be deleted by the user at any time, but it's useful in case a server is known to be compromised, or a problem is found with keysafe's implementation that makes a backup insecure. This commit was sponsored by Nick Daly on Patreon.
Diffstat (limited to 'keysafe.hs')
-rw-r--r--keysafe.hs26
1 files changed, 15 insertions, 11 deletions
diff --git a/keysafe.hs b/keysafe.hs
index 1abab5f..1eb52bd 100644
--- a/keysafe.hs
+++ b/keysafe.hs
@@ -19,6 +19,7 @@ import Cost
import SecretKey
import Share
import Storage
+import BackupRecord
import HTTP.Server
import qualified Gpg
import Data.Maybe
@@ -96,10 +97,10 @@ backup cmdline storagelocations ui tunables secretkeysource secretkey = do
<$> promptName ui "Enter other name"
othernamedesc Nothing validateName
let name = Name (theirname <> " " <> othername)
- kek <- promptkek name
+ (kek, passwordentropy) <- promptpassword name
let sis = shareIdents tunables name secretkeysource
let cost = getCreationCost kek <> getCreationCost sis
- (r, queued) <- withProgressIncremental ui "Encrypting and storing data"
+ (r, queued, locs) <- withProgressIncremental ui "Encrypting and storing data"
(encryptdesc cost cores) $ \addpercent -> do
let esk = encrypt tunables kek secretkey
shares <- genShares esk tunables
@@ -107,10 +108,13 @@ backup cmdline storagelocations ui tunables secretkeysource secretkey = do
_ <- sis `seq` addpercent 25
let step = 50 `div` sum (map S.size shares)
storeShares storagelocations sis shares (addpercent step)
+ backuprecord <- mkBackupRecord (mapMaybe getServer locs) secretkeysource passwordentropy
case r of
- StoreSuccess
- | queued -> showInfo ui "Backup queued" "Some data was not sucessfully uploaded to servers, and has been queued for later upload. Run keysafe --uploadqueued at a later point to finish the backup."
- | otherwise -> showInfo ui "Backup success" "Your secret key was successfully encrypted and backed up."
+ StoreSuccess -> do
+ storeBackupRecord backuprecord
+ if queued
+ then showInfo ui "Backup queued" "Some data was not sucessfully uploaded to servers, and has been queued for later upload. Run keysafe --uploadqueued at a later point to finish the backup."
+ else showInfo ui "Backup success" "Your secret key was successfully encrypted and backed up."
StoreFailure s -> showError ui ("There was a problem storing your encrypted secret key: " ++ s)
StoreAlreadyExists -> do
showError ui $ unlines
@@ -118,20 +122,20 @@ backup cmdline storagelocations ui tunables secretkeysource secretkey = do
, "Please try again with a different name."
]
go theirname
- promptkek name = do
+ promptpassword name = do
password <- fromMaybe (error "Aborting on no password")
<$> promptPassword ui True "Enter password" passworddesc
kek <- genKeyEncryptionKey tunables name password
username <- userName
let badwords = concatMap namewords [name, username]
+ let passwordentropy = calcPasswordEntropy password badwords
let crackcost = estimateAttackCost spotAWS $
- estimateBruteforceOf kek $
- passwordEntropy password badwords
+ estimateBruteforceOf kek passwordentropy
let mincost = Dollars 100000
if crackcost < mincost
then do
showError ui $ "Weak password! It would cost only " ++ show crackcost ++ " to crack the password. Please think of a better one. More words would be good.."
- promptkek name
+ promptpassword name
else do
(thisyear, _, _) <- toGregorian . utctDay
<$> getCurrentTime
@@ -139,8 +143,8 @@ backup cmdline storagelocations ui tunables secretkeysource secretkey = do
(crackdesc crackcost thisyear)
"Is your password strong enough?"
if ok
- then return kek
- else promptkek name
+ then return (kek, passwordentropy)
+ else promptpassword name
namewords (Name nb) = words (BU8.toString nb)
keydesc = case secretkeysource of
GpgKey _ -> "gpg secret key"