summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2016-08-17 15:52:08 -0400
committerJoey Hess <joeyh@joeyh.name>2016-08-17 15:52:08 -0400
commit19e3dc5541a74fe1c323c629bdf214b8690640e5 (patch)
treed4c16b9bb027887e9b7ea323997d30e00ba9ebdb
parented8d1ed03c3520ccd4b3c775817bef122457f224 (diff)
downloadkeysafe-19e3dc5541a74fe1c323c629bdf214b8690640e5.tar.gz
save restored secret key to gpg or file
-rw-r--r--Gpg.hs12
-rw-r--r--SecretKey.hs26
-rw-r--r--Storage/Local.hs2
-rw-r--r--keysafe.cabal1
-rw-r--r--keysafe.hs10
5 files changed, 43 insertions, 8 deletions
diff --git a/Gpg.hs b/Gpg.hs
index cbb7991..f8651e3 100644
--- a/Gpg.hs
+++ b/Gpg.hs
@@ -55,3 +55,15 @@ getSecretKey (KeyId kid) = do
_ -> error "gpg --export-secret-key failed"
where
ps = ["--batch", "--export-secret-key", BU8.toString kid]
+
+writeSecretKey :: SecretKey -> IO ()
+writeSecretKey (SecretKey b) = do
+ (Just hin, _, _, ph) <- createProcess (proc "gpg" ps)
+ { std_in = CreatePipe }
+ B.hPut hin b
+ exitcode <- waitForProcess ph
+ case exitcode of
+ ExitSuccess -> return ()
+ _ -> error "gpg --import failed"
+ where
+ ps = ["--batch", "--import"]
diff --git a/SecretKey.hs b/SecretKey.hs
new file mode 100644
index 0000000..45d9680
--- /dev/null
+++ b/SecretKey.hs
@@ -0,0 +1,26 @@
+{- Copyright 2016 Joey Hess <id@joeyh.name>
+ -
+ - Licensed under the GNU AGPL version 3 or higher.
+ -}
+
+module SecretKey where
+
+import Types
+import qualified Gpg
+import qualified Data.ByteString as B
+import System.IO
+import System.Posix.IO
+
+getSecretKey :: SecretKeySource -> IO SecretKey
+getSecretKey (GpgKey kid) = Gpg.getSecretKey kid
+getSecretKey (KeyFile f) = SecretKey <$> B.readFile f
+
+-- | Can throw exception if the secret key already exists.
+writeSecretKey :: SecretKeySource -> SecretKey -> IO ()
+writeSecretKey (GpgKey _) secretkey = Gpg.writeSecretKey secretkey
+writeSecretKey (KeyFile f) (SecretKey b) = do
+ fd <- openFd f WriteOnly (Just 0o666)
+ (defaultFileFlags { exclusive = True } )
+ h <- fdToHandle fd
+ B.hPut h b
+ hClose h
diff --git a/Storage/Local.hs b/Storage/Local.hs
index 57ba530..82a7fd0 100644
--- a/Storage/Local.hs
+++ b/Storage/Local.hs
@@ -41,7 +41,7 @@ store i s = onError (StoreFailure . show) $ do
then return StoreAlreadyExists
else do
let tmp = dest ++ ".tmp"
- fd <- openFd tmp WriteOnly (Just 0o600)
+ fd <- openFd tmp WriteOnly (Just 0o400)
(defaultFileFlags { exclusive = True } )
h <- fdToHandle fd
B.hPut h (toByteString s)
diff --git a/keysafe.cabal b/keysafe.cabal
index dd06d3a..7f27178 100644
--- a/keysafe.cabal
+++ b/keysafe.cabal
@@ -61,6 +61,7 @@ Executable keysafe
Entropy
ExpensiveHash
Gpg
+ SecretKey
Serialization
Shard
Storage
diff --git a/keysafe.hs b/keysafe.hs
index 4666dd3..efdd068 100644
--- a/keysafe.hs
+++ b/keysafe.hs
@@ -15,6 +15,7 @@ import Encryption
import Entropy
import ExpensiveHash
import Cost
+import SecretKey
import Shard
import Storage
import qualified Gpg
@@ -61,10 +62,6 @@ dispatch cmdline ui tunables = do
go CmdLine.Benchmark _ =
benchmarkTunables tunables
-getSecretKey :: SecretKeySource -> IO SecretKey
-getSecretKey (GpgKey kid) = Gpg.getSecretKey kid
-getSecretKey (KeyFile f) = SecretKey <$> B.readFile f
-
backup :: Storage -> UI -> Tunables -> SecretKeySource -> SecretKey -> IO ()
backup storage ui tunables secretkeysource secretkey = do
username <- userName
@@ -166,10 +163,9 @@ restore storage ui secretkeydest = do
(decryptdesc cost) $ \setpercent -> do
case decrypt candidatekeys esk of
Nothing -> showError ui "Decryption failed! Unknown why it would fail at this point."
- Just (SecretKey secretkey) -> do
+ Just secretkey -> do
setpercent 100
- -- TODO save
- print secretkey
+ writeSecretKey secretkeydest secretkey
showInfo ui "Success" "Your secret key successfully restored!"
where
-- TODO: derive by probing to find objects