diff options
Diffstat (limited to 'lib/Kiki.hs')
-rw-r--r-- | lib/Kiki.hs | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/lib/Kiki.hs b/lib/Kiki.hs index 9513b0f..f89aad2 100644 --- a/lib/Kiki.hs +++ b/lib/Kiki.hs | |||
@@ -1,7 +1,8 @@ | |||
1 | {-# LANGUAGE NamedFieldPuns #-} | 1 | {-# LANGUAGE LambdaCase #-} |
2 | {-# LANGUAGE RecordWildCards #-} | 2 | {-# LANGUAGE NamedFieldPuns #-} |
3 | {-# LANGUAGE ViewPatterns #-} | ||
4 | {-# LANGUAGE OverloadedStrings #-} | 3 | {-# LANGUAGE OverloadedStrings #-} |
4 | {-# LANGUAGE RecordWildCards #-} | ||
5 | {-# LANGUAGE ViewPatterns #-} | ||
5 | module Kiki | 6 | module Kiki |
6 | ( module Kiki | 7 | ( module Kiki |
7 | , setVerifyFlag | 8 | , setVerifyFlag |
@@ -48,9 +49,11 @@ import qualified SSHKey as SSH | |||
48 | import CommandLine | 49 | import CommandLine |
49 | import DotLock | 50 | import DotLock |
50 | import GnuPGAgent (Query (..)) | 51 | import GnuPGAgent (Query (..)) |
52 | import qualified IntMapClass as I | ||
51 | import KeyRing hiding (pemFromPacket) | 53 | import KeyRing hiding (pemFromPacket) |
52 | import KeyDB | 54 | import KeyDB |
53 | import KeyRing.BuildKeyDB (gpgipv6addr, Hostnames, allNames) | 55 | import KeyRing.BuildKeyDB (gpgipv6addr, Hostnames, allNames) |
56 | import TimeUtil | ||
54 | 57 | ||
55 | withAgent :: [PassphraseSpec] -> [PassphraseSpec] | 58 | withAgent :: [PassphraseSpec] -> [PassphraseSpec] |
56 | withAgent [] = [PassphraseAgent] | 59 | withAgent [] = [PassphraseAgent] |
@@ -763,6 +766,48 @@ verifyFile isHomeless cap keyrings filename = do | |||
763 | _ -> do | 766 | _ -> do |
764 | hPutStrLn stderr "Unsupported file format." | 767 | hPutStrLn stderr "Unsupported file format." |
765 | 768 | ||
769 | signFile :: Bool -> CommonArgsParsed -> [FilePath] -> String -> FilePath -> IO () | ||
770 | signFile isHomeless cap keyrings keyid filename = do | ||
771 | let mop = minimalOp isHomeless cap | ||
772 | KikiResult r report <- runKeyRing mop | ||
773 | { opFiles = opFiles mop | ||
774 | `Map.union` Map.fromList | ||
775 | [ (ArgFile f, strm { access = Sec }) | f <- keyrings ] | ||
776 | } | ||
777 | case r of | ||
778 | KikiSuccess rt -> go rt | ||
779 | err -> hPutStrLn stderr $ errorString err | ||
780 | where | ||
781 | go :: KeyRingRuntime -> IO () | ||
782 | go rt = do | ||
783 | tm <- modificationTime <$> getFileStatus filename | ||
784 | bs <- L.readFile filename | ||
785 | let hashed = [] -- TODO: FingerprintPacket | ||
786 | unhashed = [IssuerPacket keyid] | ||
787 | lit = LiteralDataPacket | ||
788 | { format = 'b' -- b:binary, t:text, u:utf8 | ||
789 | , filename = filename | ||
790 | , timestamp = fromTime tm -- seconds since Jan 1, 1970 UTC | ||
791 | , content = bs | ||
792 | } | ||
793 | hash = SHA512 | ||
794 | matchkey fp mp = matchpr fp (packet mp) == fp | ||
795 | case smallprGrip keyid of | ||
796 | Nothing -> hPutStrLn stderr "Bad keygrip." | ||
797 | Just grip -> do | ||
798 | let keydata = lookupByGrip grip (rtKeyDB rt) | ||
799 | case keydata of | ||
800 | [] -> hPutStrLn stderr "No matching key." | ||
801 | (k,_):_ -> rtPassphrases rt (Unencrypted,S2K 100 "") k >>= \case | ||
802 | KikiSuccess un -> do | ||
803 | mb <- pgpSign (Message [un]) (DataSignature lit []) hash keyid | ||
804 | case mb of | ||
805 | Nothing -> hPutStrLn stderr "Failed to make signature." | ||
806 | Just o -> do | ||
807 | putStrLn $ "Using "++show (fingerprint un)++" to write " <> filename <> ".sig" | ||
808 | let sigs = map (\sig -> sig { unhashed_subpackets = unhashed }) (signatures_over o) | ||
809 | L.writeFile (filename <> ".sig") $ L.concat $ map encode sigs | ||
810 | err -> hPutStrLn stderr $ errorString err | ||
766 | 811 | ||
767 | parsePackets :: L.ByteString -> Either String [Packet] | 812 | parsePackets :: L.ByteString -> Either String [Packet] |
768 | parsePackets bs = case decodeOrFail bs of | 813 | parsePackets bs = case decodeOrFail bs of |