summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Base58.hs25
-rw-r--r--Compat.hs54
-rw-r--r--DNSKey.hs2
-rw-r--r--KeyRing.hs21
-rw-r--r--TimeUtil.hs7
-rw-r--r--kiki.cabal30
-rw-r--r--kiki.hs52
7 files changed, 155 insertions, 36 deletions
diff --git a/Base58.hs b/Base58.hs
index de35b01..3c1a113 100644
--- a/Base58.hs
+++ b/Base58.hs
@@ -1,6 +1,12 @@
1{-# LANGUAGE CPP #-}
1module Base58 where 2module Base58 where
2 3
4#if !defined(VERSION_cryptonite)
3import qualified Crypto.Hash.SHA256 as SHA256 5import qualified Crypto.Hash.SHA256 as SHA256
6#else
7import Crypto.Hash
8import Data.ByteArray (convert)
9#endif
4import qualified Data.ByteString as S 10import qualified Data.ByteString as S
5import Data.Maybe 11import Data.Maybe
6import Data.List 12import Data.List
@@ -28,7 +34,12 @@ base58_decode str = do
28 34
29 let (rcksum,rpayload) = splitAt 4 $ rbytes 35 let (rcksum,rpayload) = splitAt 4 $ rbytes
30 a_payload = reverse rpayload 36 a_payload = reverse rpayload
37#if !defined(VERSION_cryptonite)
31 hash_result = S.take 4 . SHA256.hash . SHA256.hash . S.pack $ a_payload 38 hash_result = S.take 4 . SHA256.hash . SHA256.hash . S.pack $ a_payload
39#else
40 hash_result = S.take 4 . convert $ digest
41 where digest = hash (S.pack a_payload) :: Digest SHA256
42#endif
32 expected_hash = S.pack $ reverse rcksum 43 expected_hash = S.pack $ reverse rcksum
33 (network_id,payload) = splitAt 1 a_payload 44 (network_id,payload) = splitAt 1 a_payload
34 45
@@ -37,11 +48,17 @@ base58_decode str = do
37 return (network_id,payload) 48 return (network_id,payload)
38 49
39base58_encode :: S.ByteString -> String 50base58_encode :: S.ByteString -> String
40base58_encode hash = replicate zcount '1' ++ map (base58chars !!) (reverse rdigits) 51base58_encode hsh = replicate zcount '1' ++ map (base58chars !!) (reverse rdigits)
41 where 52 where
42 zcount = S.length . S.takeWhile (==0) $ hash 53 zcount = S.length . S.takeWhile (==0) $ hsh
43 cksum = S.take 4 . SHA256.hash . SHA256.hash $ hash 54#if !defined(VERSION_cryptonite)
44 n = foldl' (\a b->a*256+b) 0 . map asInteger $ concatMap S.unpack [hash, cksum] 55 cksum = S.take 4 . SHA256.hash . SHA256.hash $ hsh
56#else
57 cksum = S.take 4 (convert digest2 :: S.ByteString)
58 where digest2 = hash ( convert digest1 :: S.ByteString) :: Digest SHA256
59 digest1 = hash hsh :: Digest SHA256
60#endif
61 n = foldl' (\a b->a*256+b) 0 . map asInteger $ concatMap S.unpack [hsh, cksum]
45 asInteger x = fromIntegral x :: Integer 62 asInteger x = fromIntegral x :: Integer
46 rdigits = unfoldr getdigit n 63 rdigits = unfoldr getdigit n
47 where 64 where
diff --git a/Compat.hs b/Compat.hs
new file mode 100644
index 0000000..43f62c0
--- /dev/null
+++ b/Compat.hs
@@ -0,0 +1,54 @@
1module Compat where
2
3import Data.Bits
4import Data.Word
5import Data.ASN1.Types
6import Data.ASN1.Encoding
7import Data.ASN1.BinaryEncoding
8import Crypto.PubKey.RSA as RSA
9
10instance ASN1Object PublicKey where
11 toASN1 pubKey = \xs -> Start Sequence
12 : IntVal (public_n pubKey)
13 : IntVal (public_e pubKey)
14 : End Sequence
15 : xs
16 fromASN1 (Start Sequence:IntVal smodulus:IntVal pubexp:End Sequence:xs) =
17 Right (PublicKey { public_size = calculate_modulus modulus 1
18 , public_n = modulus
19 , public_e = pubexp
20 }
21 , xs)
22 where calculate_modulus n i = if (2 ^ (i * 8)) > n then i else calculate_modulus n (i+1)
23 -- some bad implementation will not serialize ASN.1 integer properly, leading
24 -- to negative modulus. if that's the case, we correct it.
25 modulus = toPositive smodulus
26 fromASN1 ( Start Sequence
27 : IntVal 0
28 : Start Sequence
29 : OID [1, 2, 840, 113549, 1, 1, 1]
30 : Null
31 : End Sequence
32 : OctetString bs
33 : xs
34 ) = let inner = either strError fromASN1 $ decodeASN1' BER bs
35 strError = Left .
36 ("fromASN1: RSA.PublicKey: " ++) . show
37 in either Left (\(k, _) -> Right (k, xs)) inner
38 fromASN1 _ =
39 Left "fromASN1: RSA.PublicKey: unexpected format"
40
41
42toPositive :: Integer -> Integer
43toPositive int
44 | int < 0 = uintOfBytes $ bytesOfInt int
45 | otherwise = int
46 where uintOfBytes = foldl (\acc n -> (acc `shiftL` 8) + fromIntegral n) 0
47 bytesOfInt :: Integer -> [Word8]
48 bytesOfInt n = if testBit (head nints) 7 then nints else 0xff : nints
49 where nints = reverse $ plusOne $ reverse $ map complement $ bytesOfUInt (abs n)
50 plusOne [] = [1]
51 plusOne (x:xs) = if x == 0xff then 0 : plusOne xs else (x+1) : xs
52 bytesOfUInt x = reverse (list x)
53 where list i = if i <= 0xff then [fromIntegral i] else (fromIntegral i .&. 0xff) : list (i `shiftR` 8)
54
diff --git a/DNSKey.hs b/DNSKey.hs
index 38d336d..5c71c16 100644
--- a/DNSKey.hs
+++ b/DNSKey.hs
@@ -50,6 +50,7 @@ i2bs_unsized 0 = B.singleton 0
50i2bs_unsized i = B.reverse $ B.unfoldr (\i' -> if i' <= 0 then Nothing else Just (fromIntegral i', (i' `shiftR` 8))) i 50i2bs_unsized i = B.reverse $ B.unfoldr (\i' -> if i' <= 0 then Nothing else Just (fromIntegral i', (i' `shiftR` 8))) i
51{-# INLINE i2bs_unsized #-} 51{-# INLINE i2bs_unsized #-}
52 52
53{-
53main = do 54main = do
54 bs <- L.getContents 55 bs <- L.getContents
55 let rsa = runGet (getRSA (fromIntegral $ L.length bs)) bs 56 let rsa = runGet (getRSA (fromIntegral $ L.length bs)) bs
@@ -57,3 +58,4 @@ main = do
57 rsa' = runGet (getRSA (fromIntegral $ L.length bs)) bs' 58 rsa' = runGet (getRSA (fromIntegral $ L.length bs)) bs'
58 print rsa 59 print rsa
59 print rsa' 60 print rsa'
61-}
diff --git a/KeyRing.hs b/KeyRing.hs
index 776ded3..50702ae 100644
--- a/KeyRing.hs
+++ b/KeyRing.hs
@@ -133,10 +133,16 @@ import qualified Data.ByteString.Lazy as L ( unpack, null, readFile, writeFile
133 , ByteString, toChunks, hGetContents, hPut, concat, fromChunks, splitAt 133 , ByteString, toChunks, hGetContents, hPut, concat, fromChunks, splitAt
134 , index ) 134 , index )
135import qualified Data.ByteString as S ( ByteString, unpack, splitAt, concat, cons, spanEnd, hGetContents, readFile, breakSubstring, drop, length, null, putStr ) 135import qualified Data.ByteString as S ( ByteString, unpack, splitAt, concat, cons, spanEnd, hGetContents, readFile, breakSubstring, drop, length, null, putStr )
136import qualified Crypto.Types.PubKey.ECC as ECC
137import qualified Codec.Binary.Base32 as Base32 136import qualified Codec.Binary.Base32 as Base32
138import qualified Codec.Binary.Base64 as Base64 137import qualified Codec.Binary.Base64 as Base64
138#if !defined(VERSION_cryptonite)
139import qualified Crypto.Hash.SHA1 as SHA1 139import qualified Crypto.Hash.SHA1 as SHA1
140import qualified Crypto.Types.PubKey.ECC as ECC
141#else
142import qualified Crypto.Hash as Vincent
143import Data.ByteArray (convert)
144import qualified Crypto.PubKey.ECC.Types as ECC
145#endif
140import qualified Data.X509 as X509 146import qualified Data.X509 as X509
141import qualified Crypto.PubKey.RSA as RSA 147import qualified Crypto.PubKey.RSA as RSA
142import qualified Codec.Compression.GZip as GZip 148import qualified Codec.Compression.GZip as GZip
@@ -173,8 +179,7 @@ import Debug.Trace
173#endif 179#endif
174import Network.Socket -- (SockAddr) 180import Network.Socket -- (SockAddr)
175import qualified Data.ByteString.Lazy.Char8 as Char8 181import qualified Data.ByteString.Lazy.Char8 as Char8
176 182import Compat
177
178 183
179import TimeUtil 184import TimeUtil
180import PEM 185import PEM
@@ -1441,7 +1446,14 @@ torhash :: Packet -> String
1441torhash key = fromMaybe "" $ derToBase32 <$> derRSA key 1446torhash key = fromMaybe "" $ derToBase32 <$> derRSA key
1442 1447
1443derToBase32 :: ByteString -> String 1448derToBase32 :: ByteString -> String
1449#if !defined(VERSION_cryptonite)
1444derToBase32 = map toLower . Base32.encode . S.unpack . SHA1.hashlazy 1450derToBase32 = map toLower . Base32.encode . S.unpack . SHA1.hashlazy
1451#else
1452derToBase32 = map toLower . Base32.encode . S.unpack . sha1
1453 where
1454 sha1 :: L.ByteString -> S.ByteString
1455 sha1 x = convert (Vincent.hashlazy x :: Vincent.Digest Vincent.SHA1)
1456#endif
1445 1457
1446derRSA :: Packet -> Maybe ByteString 1458derRSA :: Packet -> Maybe ByteString
1447derRSA rsa = do 1459derRSA rsa = do
@@ -1480,6 +1492,8 @@ spemCert _ = Nothing
1480toStrict :: L.ByteString -> S.ByteString 1492toStrict :: L.ByteString -> S.ByteString
1481toStrict = foldr1 (<>) . L.toChunks 1493toStrict = foldr1 (<>) . L.toChunks
1482 1494
1495-- No instance for (ASN1Object RSA.PublicKey)
1496
1483parseCertBlob comp bs = do 1497parseCertBlob comp bs = do
1484 asn1 <- either (const Nothing) Just 1498 asn1 <- either (const Nothing) Just
1485 $ decodeASN1 DER bs 1499 $ decodeASN1 DER bs
@@ -1936,6 +1950,7 @@ writePEM typ dta = pem
1936 [ ["-----BEGIN " <> typ <> "-----"] 1950 [ ["-----BEGIN " <> typ <> "-----"]
1937 , split64s dta 1951 , split64s dta
1938 , ["-----END " <> typ <> "-----"] ] 1952 , ["-----END " <> typ <> "-----"] ]
1953 split64s :: String -> [String]
1939 split64s "" = [] 1954 split64s "" = []
1940 split64s dta = line : split64s rest where (line,rest) = splitAt 64 dta 1955 split64s dta = line : split64s rest where (line,rest) = splitAt 64 dta
1941 1956
diff --git a/TimeUtil.hs b/TimeUtil.hs
index 9035e50..879bc32 100644
--- a/TimeUtil.hs
+++ b/TimeUtil.hs
@@ -1,5 +1,6 @@
1{-# LANGUAGE OverloadedStrings #-} 1{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE ViewPatterns #-} 2{-# LANGUAGE ViewPatterns #-}
3{-# LANGUAGE CPP #-}
3module TimeUtil 4module TimeUtil
4 ( now 5 ( now
5 , IsTime(..) 6 , IsTime(..)
@@ -14,8 +15,10 @@ import Data.Time.LocalTime
14import Data.Time.Format 15import Data.Time.Format
15import Data.Time.Clock 16import Data.Time.Clock
16import Data.Time.Clock.POSIX 17import Data.Time.Clock.POSIX
17import System.Locale 18#if !MIN_VERSION_time(1,5,0)
18import Data.String 19import System.Locale (defaultTimeLocale)
20#endif
21import Data.String
19import Control.Applicative 22import Control.Applicative
20import Data.Maybe 23import Data.Maybe
21import Data.Char 24import Data.Char
diff --git a/kiki.cabal b/kiki.cabal
index 450a3ab..e301d7f 100644
--- a/kiki.cabal
+++ b/kiki.cabal
@@ -11,21 +11,28 @@ Maintainer: Joseph Crayne <oh.hello.joe@gmail.com>
11--Homepage: TODO 11--Homepage: TODO
12build-type: Simple 12build-type: Simple
13 13
14Flag cryptonite
15 Description: Use newer cryptonite-based x509 version 1.6 and higher
16 Default: True
17
14Executable kiki 18Executable kiki
15 Main-is: kiki.hs 19 Main-is: kiki.hs
16 -- base >=4.6 due to use of readEither in KikiD.Message 20 -- base >=4.6 due to use of readEither in KikiD.Message
17 Build-Depends: base >=4.6.0.0, 21 Build-Depends: base >=4.6.0.0,
18 directory -any, 22 directory -any,
19 openpgp-util -any, 23 openpgp-util -any,
20 crypto-pubkey (>=0.2.3), cryptohash -any, 24 asn1-types -any, asn1-encoding -any,
21 crypto-pubkey-types -any,
22 x509 (< 1.6), asn1-types -any, asn1-encoding -any,
23 dataenc -any, text -any, pretty -any, pretty-show -any, 25 dataenc -any, text -any, pretty -any, pretty-show -any,
24 bytestring -any, openpgp (>=0.6.1.1), binary -any, 26 bytestring -any, binary -any,
25 unix, time, 27 unix, time,
26 containers -any, process -any, filepath -any, 28 containers -any, process -any, filepath -any,
27 network -any, old-locale -any, zlib -any, 29 network -any, old-locale -any, zlib -any,
28 hourglass -any 30 hourglass -any
31 if !flag(cryptonite)
32 Build-Depends: crypto-pubkey >=0.2.3, cryptohash -any,
33 crypto-pubkey-types -any, x509 <1.6
34 else
35 Build-Depends: cryptonite, x509 >=1.6, memory
29 ghc-options: -O2 -fwarn-unused-binds -fwarn-unused-imports 36 ghc-options: -O2 -fwarn-unused-binds -fwarn-unused-imports
30 c-sources: dotlock.c 37 c-sources: dotlock.c
31 38
@@ -33,20 +40,5 @@ Executable hosts
33 Main-is: hosts.hs 40 Main-is: hosts.hs
34 c-sources: dotlock.c 41 c-sources: dotlock.c
35 42
36Executable kikid
37 Main-is: kikid.hs
38 Build-Depends: base -any,
39 --kiki >=0.0.3,
40 hdaemonize >= 0.5,
41 hsyslog -any,
42 async >= 2.0.0,
43 stm-chans >= 2.0.0,
44 network >= 2.4 && < 3.0,
45 monad-loops -any,
46 HTTP -any,
47 stm >= 2.3,
48 cereal -any,
49 bytes -any
50
51library 43library
52 exposed-modules: KeyRing 44 exposed-modules: KeyRing
diff --git a/kiki.hs b/kiki.hs
index 2d926a8..316da90 100644
--- a/kiki.hs
+++ b/kiki.hs
@@ -29,8 +29,14 @@ import System.Environment
29import System.Exit 29import System.Exit
30import System.IO (hPutStrLn,stderr) 30import System.IO (hPutStrLn,stderr)
31import qualified Codec.Binary.Base64 as Base64 31import qualified Codec.Binary.Base64 as Base64
32import qualified Crypto.Hash.RIPEMD160 as RIPEMD160 32#if !defined(VERSION_cryptonite)
33-- import qualified Crypto.Hash.RIPEMD160 as RIPEMD160
33import qualified Crypto.Hash.SHA256 as SHA256 34import qualified Crypto.Hash.SHA256 as SHA256
35#else
36import Crypto.Hash.Algorithms (RIPEMD160(..))
37import Crypto.Hash
38import Data.ByteArray (convert)
39#endif
34import qualified Data.ByteString as S 40import qualified Data.ByteString as S
35import qualified Data.ByteString.Lazy as L 41import qualified Data.ByteString.Lazy as L
36import qualified Data.ByteString.Lazy.Char8 as Char8 42import qualified Data.ByteString.Lazy.Char8 as Char8
@@ -38,6 +44,7 @@ import qualified Data.Map as Map
38import Control.Arrow (first,second) 44import Control.Arrow (first,second)
39import Data.Time.Clock.POSIX ( posixSecondsToUTCTime ) 45import Data.Time.Clock.POSIX ( posixSecondsToUTCTime )
40import Data.Monoid ( (<>) ) 46import Data.Monoid ( (<>) )
47import Data.Binary.Put
41 48
42import Data.OpenPGP.Util (verify,fingerprint) 49import Data.OpenPGP.Util (verify,fingerprint)
43import ScanningParser 50import ScanningParser
@@ -50,6 +57,7 @@ import qualified CryptoCoins
50import ProcessUtils 57import ProcessUtils
51import qualified SSHKey as SSH 58import qualified SSHKey as SSH
52import Text.Printf 59import Text.Printf
60import qualified DNSKey as DNS
53 61
54-- {-# ANN module ("HLint: ignore Eta reduce"::String) #-} 62-- {-# ANN module ("HLint: ignore Eta reduce"::String) #-}
55-- {-# ANN module ("HLint: ignore Use camelCase"::String) #-} 63-- {-# ANN module ("HLint: ignore Use camelCase"::String) #-}
@@ -279,13 +287,15 @@ show_whose_key input_key db =
279 (_:_) -> error "ambiguous" 287 (_:_) -> error "ambiguous"
280 [] -> return () 288 [] -> return ()
281 289
282show_pem keyspec wkgrip db = either warn putStrLn $ show_pem' keyspec wkgrip db 290show_dns keyspec wkgrip db = either warn putStrLn $ show_pem' keyspec wkgrip db dnsPresentationFromPacket
283 291
284show_pem' keyspec wkgrip db = do 292show_pem keyspec wkgrip db = either warn putStrLn $ show_pem' keyspec wkgrip db pemFromPacket
293
294show_pem' keyspec wkgrip db keyfmt = do
285 let s = parseSpec wkgrip keyspec 295 let s = parseSpec wkgrip keyspec
286 flip (maybe . Left $ keyspec ++ ": not found") 296 flip (maybe . Left $ keyspec ++ ": not found")
287 (selectPublicKey s db) 297 (selectPublicKey s db)
288 pemFromPacket 298 keyfmt
289 299
290pemFromPacket k = do 300pemFromPacket k = do
291 let rsa = pkcs8 . fromJust $ rsaKeyFromPacket k 301 let rsa = pkcs8 . fromJust $ rsaKeyFromPacket k
@@ -294,6 +304,15 @@ pemFromPacket k = do
294 return $ 304 return $
295 writePEM "PUBLIC KEY" qq -- ("TODO "++show keyspec) 305 writePEM "PUBLIC KEY" qq -- ("TODO "++show keyspec)
296 306
307dnsPresentationFromPacket k = do
308 let RSAKey (MPI n) (MPI e) = fromJust $ rsaKeyFromPacket k
309 dnskey = DNS.RSA n e
310 bin = runPut (DNS.putRSA dnskey)
311 qq = Base64.encode (L.unpack bin)
312 return $
313 writePEM "FIXME PUBLIC KEY" qq -- ("TODO "++show keyspec)
314
315
297show_ssh keyspec wkgrip db = either warn putStrLn $ show_ssh' keyspec wkgrip db 316show_ssh keyspec wkgrip db = either warn putStrLn $ show_ssh' keyspec wkgrip db
298 317
299show_ssh' keyspec wkgrip db = do 318show_ssh' keyspec wkgrip db = do
@@ -331,6 +350,8 @@ show_torhash pubkey _ = do
331 asn1 <- either (const Nothing) (Just) e 350 asn1 <- either (const Nothing) (Just) e
332 k <- either (const Nothing) (Just . fst) (fromASN1 asn1) 351 k <- either (const Nothing) (Just . fst) (fromASN1 asn1)
333 return $ f (packetFromPublicRSAKey undefined) k 352 return $ f (packetFromPublicRSAKey undefined) k
353
354 addy :: String -> String
334 addy hsh = take 16 hsh ++ ".onion " ++ hsh 355 addy hsh = take 16 hsh ++ ".onion " ++ hsh
335 pkcs1 = fmap ( parsekey (\f (RSAKey n e) -> f n e) . pemBlob ) 356 pkcs1 = fmap ( parsekey (\f (RSAKey n e) -> f n e) . pemBlob )
336 $ pemParser (Just "RSA PUBLIC KEY") 357 $ pemParser (Just "RSA PUBLIC KEY")
@@ -421,8 +442,14 @@ bitcoinAddress network_id k = address
421 Just (MPI x) = lookup 'x' (key k) 442 Just (MPI x) = lookup 'x' (key k)
422 Just (MPI y) = lookup 'y' (key k) 443 Just (MPI y) = lookup 'y' (key k)
423 pub = cannonical_eckey x y 444 pub = cannonical_eckey x y
424 hash = S.cons network_id . RIPEMD160.hash . SHA256.hash . S.pack $ pub 445#if !defined(VERSION_cryptonite)
425 address = base58_encode hash 446 hsh = S.cons network_id . RIPEMD160.hash . SHA256.hash . S.pack $ pub
447#else
448 hsh = S.cons network_id . ripemd160 . sha256 . S.pack $ pub
449 sha256 x = convert (Crypto.Hash.hash x :: Digest SHA256) :: S.ByteString
450 ripemd160 x = convert (Crypto.Hash.hash x :: Digest RIPEMD160) :: S.ByteString
451#endif
452 address = base58_encode hsh
426 453
427whoseKey :: RSAPublicKey -> KeyDB -> [KeyData] 454whoseKey :: RSAPublicKey -> KeyDB -> [KeyData]
428whoseKey rsakey db = filter matchkey (Map.elems db) 455whoseKey rsakey db = filter matchkey (Map.elems db)
@@ -484,6 +511,11 @@ kiki_usage bExport bImport bSecret cmd = putStr $
484 ," Shows the fingerprint and UIDs of the key that owns the one that" 511 ," Shows the fingerprint and UIDs of the key that owns the one that"
485 ," is input on stdin in ssh-rsa format." 512 ," is input on stdin in ssh-rsa format."
486 ,"" 513 ,""
514 ," --dns SPEC"
515 ," Outputs the DNSKEY presentation format (RFC3110) of the public key"
516 ," corresponding to SPEC."
517 ," (See 'kiki help spec' for more information.)"
518 ,""
487 ," --pem SPEC" 519 ," --pem SPEC"
488 ," Outputs the PKCS #8 public key corresponding to SPEC." 520 ," Outputs the PKCS #8 public key corresponding to SPEC."
489 ," (See 'kiki help spec' for more information.)" 521 ," (See 'kiki help spec' for more information.)"
@@ -1130,6 +1162,7 @@ kiki "show" args = do
1130 , ("--whose-key",0) 1162 , ("--whose-key",0)
1131 , ("--key",1) 1163 , ("--key",1)
1132 , ("--pem",1) 1164 , ("--pem",1)
1165 , ("--dns",1)
1133 , ("--ssh",1) 1166 , ("--ssh",1)
1134 , ("--wip",1) 1167 , ("--wip",1)
1135 , ("--cert",1) 1168 , ("--cert",1)
@@ -1180,6 +1213,7 @@ kiki "show" args = do
1180 ,("--whose-key", const $ show_whose_key input_key) 1213 ,("--whose-key", const $ show_whose_key input_key)
1181 ,("--key",\[x] -> show_id x $ fromMaybe "" grip) 1214 ,("--key",\[x] -> show_id x $ fromMaybe "" grip)
1182 ,("--pem",\[x] -> show_pem x $ fromMaybe "" grip) 1215 ,("--pem",\[x] -> show_pem x $ fromMaybe "" grip)
1216 ,("--dns",\[x] -> show_dns x $ fromMaybe "" grip)
1183 ,("--ssh",\[x] -> show_ssh x $ fromMaybe "" grip) 1217 ,("--ssh",\[x] -> show_ssh x $ fromMaybe "" grip)
1184 ,("--wip",\[x] -> show_wip x $ fromMaybe "" grip) 1218 ,("--wip",\[x] -> show_wip x $ fromMaybe "" grip)
1185 ,("--cert",\[x] -> show_cert x $ fromMaybe "" grip) 1219 ,("--cert",\[x] -> show_cert x $ fromMaybe "" grip)
@@ -1253,6 +1287,7 @@ kiki "merge" args = do
1253 w:xs -> w:map (drop 1) xs 1287 w:xs -> w:map (drop 1) xs
1254 [] -> [] 1288 [] -> []
1255 (goods,bads) = partition acceptable ws 1289 (goods,bads) = partition acceptable ws
1290 acceptable :: String -> Bool
1256 acceptable "spill" = True 1291 acceptable "spill" = True
1257 acceptable "fill" = True 1292 acceptable "fill" = True
1258 acceptable "sync" = True 1293 acceptable "sync" = True
@@ -1496,7 +1531,7 @@ kiki "init-key" args = do
1496 goti <- doesFileExist (ipsecpathpub) 1531 goti <- doesFileExist (ipsecpathpub)
1497 when (not goti) $ do 1532 when (not goti) $ do
1498 either warn (writeFile $ ipsecpathpub) 1533 either warn (writeFile $ ipsecpathpub)
1499 $ show_pem' "strongswan" grip (rtKeyDB rt) 1534 $ show_pem' "strongswan" grip (rtKeyDB rt) pemFromPacket
1500 else return () 1535 else return ()
1501 1536
1502 1537
@@ -1585,7 +1620,8 @@ interp vars raw = es >>= interp1
1585 where 1620 where
1586 gs = groupBy (\_ c -> c/='%') raw 1621 gs = groupBy (\_ c -> c/='%') raw
1587 es = dropWhile null $ gobbleEscapes ("":gs) 1622 es = dropWhile null $ gobbleEscapes ("":gs)
1588 where gobbleEscapes (a:"%":b:bs) = (a++b) : gobbleEscapes bs 1623 where gobbleEscapes :: [String] -> [String]
1624 gobbleEscapes (a:"%":b:bs) = (a++b) : gobbleEscapes bs
1589 gobbleEscapes (g:gs) = g : gobbleEscapes gs 1625 gobbleEscapes (g:gs) = g : gobbleEscapes gs
1590 gobbleEscapes [] = [] 1626 gobbleEscapes [] = []
1591 interp1 ('%':'(':str) = fromMaybe "" (Map.lookup key vars) ++ drop 1 rest 1627 interp1 ('%':'(':str) = fromMaybe "" (Map.lookup key vars) ++ drop 1 rest