summaryrefslogtreecommitdiff
path: root/lib/Kiki.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2016-08-29 01:15:25 -0400
committerjoe <joe@jerkface.net>2016-08-29 01:15:25 -0400
commit1eff837423de69ece2a85430a7ad433b7c1a504a (patch)
treec2c7d6e83e9589de72b29924f6cb2354107d0d0e /lib/Kiki.hs
parent7a579e7b82a2f5707af77f4a7101ce72e57635ac (diff)
Better gpg-agent support.
Diffstat (limited to 'lib/Kiki.hs')
-rw-r--r--lib/Kiki.hs47
1 files changed, 34 insertions, 13 deletions
diff --git a/lib/Kiki.hs b/lib/Kiki.hs
index 25c98e2..c042540 100644
--- a/lib/Kiki.hs
+++ b/lib/Kiki.hs
@@ -2,9 +2,10 @@
2{-# LANGUAGE OverloadedStrings #-} 2{-# LANGUAGE OverloadedStrings #-}
3module Kiki where 3module Kiki where
4 4
5import Control.Exception
6import Control.Applicative 5import Control.Applicative
7import Control.Arrow 6import Control.Arrow
7import Control.Concurrent
8import Control.Exception
8import Control.Monad 9import Control.Monad
9import Data.ASN1.BinaryEncoding 10import Data.ASN1.BinaryEncoding
10import Data.ASN1.Encoding 11import Data.ASN1.Encoding
@@ -22,6 +23,7 @@ import System.FilePath.Posix
22import System.IO 23import System.IO
23import System.IO.Temp 24import System.IO.Temp
24import System.IO.Error 25import System.IO.Error
26import System.Posix.IO as Posix (createPipe)
25import System.Posix.User 27import System.Posix.User
26import System.Process 28import System.Process
27import System.Posix.Files 29import System.Posix.Files
@@ -37,6 +39,7 @@ import qualified Data.ByteString.Lazy.Char8 as Char8
37import qualified Data.Map.Strict as Map 39import qualified Data.Map.Strict as Map
38import qualified SSHKey as SSH 40import qualified SSHKey as SSH
39 41
42import GnuPGAgent (Query(..))
40import CommandLine 43import CommandLine
41import KeyRing 44import KeyRing
42import DotLock 45import DotLock
@@ -138,9 +141,9 @@ importAndRefresh root cmn = do
138 141
139 let passfd = cap_passfd cmn 142 let passfd = cap_passfd cmn
140 143
141 pwds <- 144 (torgen,pwds) <-
142 if gotsec 145 if gotsec
143 then return [] 146 then return (Generate 0 $ GenRSA $ 1024 `div` 8, [])
144 else do 147 else do
145 {- ssh-keygen to create master key... 148 {- ssh-keygen to create master key...
146 let mkpath = home ++ "/master-key" 149 let mkpath = home ++ "/master-key"
@@ -154,36 +157,47 @@ importAndRefresh root cmn = do
154 HomeSec 157 HomeSec
155 ( encode $ Message [mk { is_subkey = False }] ) 158 ( encode $ Message [mk { is_subkey = False }] )
156 -} 159 -}
157 master_un <- (\k -> k { is_subkey = False }) <$> generateKey (GenRSA $ 4096 `div` 8 ) 160 master_un <- (\k -> MappedPacket (k { is_subkey = False }) Map.empty) <$> generateKey (GenRSA $ 4096 `div` 8 )
161 tor_un <- generateKey (GenRSA $ 1024 `div` 8 )
162 (read_tor,write_tor) <- Posix.createPipe
163 do rs <- writeKeyToFile (streaminfo { typ = PEMFile, access = Sec, spill = KF_Match "tor", fill = KF_All }) (FileDesc write_tor) tor_un
164 -- outputReport $ map (first show) rs
165 return ()
158 let default_cipher = (CAST5 {- AES128 -}, IteratedSaltedS2K SHA1 4073382889203176146 7864320) 166 let default_cipher = (CAST5 {- AES128 -}, IteratedSaltedS2K SHA1 4073382889203176146 7864320)
159 ctx = InputFileContext secring pubring 167 ctx = InputFileContext secring pubring
168 main_passwds = withAgent $ do pfd <- maybeToList passfd
169 return $ PassphraseSpec Nothing Nothing pfd
160 passwordop = KeyRingOperation 170 passwordop = KeyRingOperation
161 { opFiles = Map.empty 171 { opFiles = Map.empty
162 -- TODO: ask agent for new passphrase 172 -- TODO: ask agent for new passphrase
163 , opPassphrases = do pfd <- maybeToList passfd 173 , opPassphrases = main_passwds
164 return $ PassphraseSpec Nothing Nothing pfd
165 , opHome = homespec 174 , opHome = homespec
166 , opTransforms = [] 175 , opTransforms = []
167 } 176 }
168 transcoder <- makeMemoizingDecrypter passwordop ctx Map.empty 177 let uidentry = Map.singleton (keykey $ packet master_un)
169 master0 <- transcoder default_cipher $ MappedPacket master_un Map.empty 178 $ master_un { packet = Query (packet master_un)
179 (torUIDFromKey tor_un)
180 Nothing
181 }
182 transcoder <- makeMemoizingDecrypter passwordop ctx (Just master_un, uidentry)
183 master0 <- transcoder default_cipher master_un
170 case master0 of 184 case master0 of
171 KikiSuccess master -> do 185 KikiSuccess master -> do
172 mkdirFor secring 186 mkdirFor secring
173 writeInputFileL ctx 187 writeInputFileL ctx
174 HomeSec 188 HomeSec
175 $ encode $ Message [master { is_subkey = False}] 189 $ encode $ Message [master]
176 putStrLn "Wrote master key" 190 putStrLn "Wrote master key"
177 return [PassphraseMemoizer transcoder] 191 return (FileDesc read_tor, [PassphraseMemoizer transcoder])
178 er -> do 192 er -> do
179 hPutStrLn stderr ("warning: " ++ errorString er) 193 hPutStrLn stderr ("warning: " ++ errorString er)
180 hPutStrLn stderr "warning: keys will not be encrypted."; 194 hPutStrLn stderr "warning: keys will not be encrypted.";
181 mkdirFor secring 195 mkdirFor secring
182 writeInputFileL ctx 196 writeInputFileL ctx
183 HomeSec 197 HomeSec
184 $ encode $ Message [master_un { is_subkey = False}] 198 $ encode $ Message [packet master_un]
185 putStrLn "Wrote master key" 199 putStrLn "Wrote master key"
186 return [] 200 return (Generate 0 (GenRSA $ 1024 `div` 8 ), [])
187 gotpub <- doesFileExist pubring 201 gotpub <- doesFileExist pubring
188 when (not gotpub) $ do 202 when (not gotpub) $ do
189 mkdirFor pubring 203 mkdirFor pubring
@@ -233,7 +247,14 @@ importAndRefresh root cmn = do
233 { opFiles = Map.fromList $ 247 { opFiles = Map.fromList $
234 [ ( HomeSec, buildStreamInfo KF_All KeyRingFile ) 248 [ ( HomeSec, buildStreamInfo KF_All KeyRingFile )
235 , ( HomePub, (buildStreamInfo KF_All KeyRingFile) { access = Pub } ) 249 , ( HomePub, (buildStreamInfo KF_All KeyRingFile) { access = Pub } )
236 , ( Generate 0 (GenRSA (1024 `div` 8)), strm { spill = KF_Match "tor" }) 250 , ( torgen , case torgen of
251 FileDesc _ -> StreamInfo { typ = PEMFile
252 , fill = KF_Match "tor"
253 , spill = KF_Match "tor"
254 , access = Sec
255 , initializer = NoCreate
256 , transforms = [] }
257 _ -> strm { spill = KF_Match "tor" })
237 , ( Generate 1 (GenRSA (1024 `div` 8)), strm { spill = KF_Match "ipsec" }) 258 , ( Generate 1 (GenRSA (1024 `div` 8)), strm { spill = KF_Match "ipsec" })
238 , ( ArgFile sshcpath, (peminfo 2048 "ssh-client") ) 259 , ( ArgFile sshcpath, (peminfo 2048 "ssh-client") )
239 , ( ArgFile sshspath, (peminfo 2048 "ssh-server") ) 260 , ( ArgFile sshspath, (peminfo 2048 "ssh-server") )