diff options
author | Joey Hess <joeyh@joeyh.name> | 2016-08-17 15:52:08 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2016-08-17 15:52:08 -0400 |
commit | 19e3dc5541a74fe1c323c629bdf214b8690640e5 (patch) | |
tree | d4c16b9bb027887e9b7ea323997d30e00ba9ebdb | |
parent | ed8d1ed03c3520ccd4b3c775817bef122457f224 (diff) | |
download | keysafe-19e3dc5541a74fe1c323c629bdf214b8690640e5.tar.gz |
save restored secret key to gpg or file
-rw-r--r-- | Gpg.hs | 12 | ||||
-rw-r--r-- | SecretKey.hs | 26 | ||||
-rw-r--r-- | Storage/Local.hs | 2 | ||||
-rw-r--r-- | keysafe.cabal | 1 | ||||
-rw-r--r-- | keysafe.hs | 10 |
5 files changed, 43 insertions, 8 deletions
@@ -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 @@ -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 |