summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@blackbird>2014-01-06 20:58:46 -0500
committerjoe <joe@blackbird>2014-01-06 20:58:46 -0500
commitf6e2f03b31f3c9760cb4e1251218fb9372527c96 (patch)
tree38b6bebfb071637356f2f31bc46ecb79aa16e242
parent3257807aabc1d12b657cbd47d87de3c69ca6da1d (diff)
--show-whose-key option to search who owns the given ssh key.
-rw-r--r--kiki.hs56
1 files changed, 55 insertions, 1 deletions
diff --git a/kiki.hs b/kiki.hs
index 87f5db4..e79c9f3 100644
--- a/kiki.hs
+++ b/kiki.hs
@@ -79,6 +79,7 @@ import qualified Hosts
79import Network.Socket -- (SockAddr) 79import Network.Socket -- (SockAddr)
80import LengthPrefixedBE 80import LengthPrefixedBE
81import Data.Binary.Put (putWord32be,runPut,putByteString) 81import Data.Binary.Put (putWord32be,runPut,putByteString)
82import Data.Binary.Get (runGet)
82 83
83-- instance Default S.ByteString where def = S.empty 84-- instance Default S.ByteString where def = S.empty
84 85
@@ -105,7 +106,7 @@ unprefix c spec = if null (snd p) then swap p else (fst p, tail (snd p))
105 where p = break (==c) spec 106 where p = break (==c) spec
106 107
107 108
108data RSAPublicKey = RSAKey MPI MPI deriving Show 109data RSAPublicKey = RSAKey MPI MPI deriving (Eq,Show)
109data PKCS8_RSAPublicKey = RSAKey8 MPI MPI deriving Show 110data PKCS8_RSAPublicKey = RSAKey8 MPI MPI deriving Show
110 111
111pkcs8 (RSAKey n e) = RSAKey8 n e 112pkcs8 (RSAKey n e) = RSAKey8 n e
@@ -226,6 +227,18 @@ sshrsa e n = runPut $ do
226 put (LengthPrefixedBE e) 227 put (LengthPrefixedBE e)
227 put (LengthPrefixedBE n) 228 put (LengthPrefixedBE n)
228 229
230decode_sshrsa :: Char8.ByteString -> Maybe RSAPublicKey
231decode_sshrsa bs = do
232 let (pre,bs1) = Char8.splitAt 11 bs
233 v = runPut (putWord32be 7 >> putByteString "ssh-rsa")
234 guard $ pre == runPut (putWord32be 7 >> putByteString "ssh-rsa")
235 let rsakey = flip runGet bs1 $ do
236 LengthPrefixedBE e <- get
237 LengthPrefixedBE n <- get
238 return $ RSAKey (MPI n) (MPI e)
239 return rsakey
240
241
229rsaKeyFromPacket :: Packet -> Maybe RSAPublicKey 242rsaKeyFromPacket :: Packet -> Maybe RSAPublicKey
230rsaKeyFromPacket p@(PublicKeyPacket {}) = do 243rsaKeyFromPacket p@(PublicKeyPacket {}) = do
231 n <- lookup 'n' $ key p 244 n <- lookup 'n' $ key p
@@ -964,6 +977,18 @@ readKeyFromFile False "PEM" fname = do
964 } 977 }
965readKeyFromFile is_public fmt filename = error ("unimplemented key type: "++fmt) 978readKeyFromFile is_public fmt filename = error ("unimplemented key type: "++fmt)
966 979
980readPublicKey :: Char8.ByteString -> RSAPublicKey
981readPublicKey bs = maybe er id $ do
982 let (pre,bs1) = Char8.splitAt 7 bs
983 guard $ pre == "ssh-rsa"
984 let (sp,bs2) = Char8.span isSpace bs1
985 guard $ not (Char8.null sp)
986 bs3 <- listToMaybe $ Char8.words bs2
987 qq <- L.pack `fmap` Base64.decode (Char8.unpack bs3)
988 decode_sshrsa qq
989 where
990 er = error "Unsupported key format"
991
967{- 992{-
968getPassphrase cmd = 993getPassphrase cmd =
969 case passphrase_fd cmd of 994 case passphrase_fd cmd of
@@ -1409,6 +1434,16 @@ show_all db = do
1409 putStrLn $ listKeys packets 1434 putStrLn $ listKeys packets
1410 -- warn $ "END LIST "++show (length packets)++" packets." 1435 -- warn $ "END LIST "++show (length packets)++" packets."
1411 1436
1437show_whose_key input_key db = do
1438 flip (maybe $ return ()) input_key $ \input_key -> do
1439 let ks = whoseKey input_key db
1440 case ks of
1441 [KeyData k _ uids _] -> do
1442 putStrLn $ fingerprint (packet k)
1443 mapM_ putStrLn $ Map.keys uids
1444 (_:_) -> error "ambiguous"
1445 [] -> return ()
1446
1412show_pem keyspec wkgrip db = do 1447show_pem keyspec wkgrip db = do
1413 let s = parseSpec wkgrip keyspec 1448 let s = parseSpec wkgrip keyspec
1414 flip (maybe $ warn (keyspec ++ ": not found") >> return ()) 1449 flip (maybe $ warn (keyspec ++ ": not found") >> return ())
@@ -2102,6 +2137,15 @@ getHostnames (KeyData topmp _ uids subs) = (addr,(onames,othernames))
2102 . torhash ) 2137 . torhash )
2103 torkeys 2138 torkeys
2104 2139
2140whoseKey :: RSAPublicKey -> KeyDB -> [KeyData]
2141whoseKey rsakey db = filter matchkey (Map.elems db)
2142 where
2143 matchkey (KeyData k _ _ subs) =
2144 not . null . filter ismatch $ Map.elems subs
2145
2146 ismatch (SubKey mp sigs) =
2147 Just rsakey == rsaKeyFromPacket (packet mp)
2148
2105kiki_usage = do 2149kiki_usage = do
2106 putStr . unlines $ 2150 putStr . unlines $
2107 ["kiki - a pgp key editing utility" 2151 ["kiki - a pgp key editing utility"
@@ -2169,6 +2213,10 @@ kiki_usage = do
2169 ,"" 2213 ,""
2170 ," --show-all Show fingerprints and UIDs and usage tags for all known keys." 2214 ," --show-all Show fingerprints and UIDs and usage tags for all known keys."
2171 ,"" 2215 ,""
2216 ," --show-whose-key"
2217 ," Shows the fingerprint and UIDs of the key that owns the one that"
2218 ," is input on stdin in ssh-rsa format."
2219 ,""
2172 ," --show-pem SPEC" 2220 ," --show-pem SPEC"
2173 ," Outputs the PKCS #8 public key corresponding to SPEC." 2221 ," Outputs the PKCS #8 public key corresponding to SPEC."
2174 ,"" 2222 ,""
@@ -2211,6 +2259,7 @@ main = do
2211 , ("--autosign",0) 2259 , ("--autosign",0)
2212 , ("--show-wk",0) 2260 , ("--show-wk",0)
2213 , ("--show-all",0) 2261 , ("--show-all",0)
2262 , ("--show-whose-key",0)
2214 , ("--show-key",1) 2263 , ("--show-key",1)
2215 , ("--show-pem",1) 2264 , ("--show-pem",1)
2216 , ("--show-ssh",1) 2265 , ("--show-ssh",1)
@@ -2298,6 +2347,10 @@ main = do
2298 warn "syntax error" 2347 warn "syntax error"
2299 exitFailure 2348 exitFailure
2300 2349
2350 input_key <- maybe (return Nothing)
2351 (const $ fmap (Just . readPublicKey) Char8.getContents)
2352 $ Map.lookup "--show-whose-key" margs
2353
2301 let keypairs = catMaybes keypairs0 2354 let keypairs = catMaybes keypairs0
2302 btcpairs = catMaybes btcpairs0 2355 btcpairs = catMaybes btcpairs0
2303 2356
@@ -2460,6 +2513,7 @@ main = do
2460 -- On last pass, interpret --show-* commands. 2513 -- On last pass, interpret --show-* commands.
2461 let shspec = Map.fromList [("--show-wk", const $ show_wk secfile grip) 2514 let shspec = Map.fromList [("--show-wk", const $ show_wk secfile grip)
2462 ,("--show-all",const $ show_all) 2515 ,("--show-all",const $ show_all)
2516 ,("--show-whose-key", const $ show_whose_key input_key)
2463 ,("--show-key",\[x] -> show_key x $ maybe "" id grip) 2517 ,("--show-key",\[x] -> show_key x $ maybe "" id grip)
2464 ,("--show-pem",\[x] -> show_pem x $ maybe "" id grip) 2518 ,("--show-pem",\[x] -> show_pem x $ maybe "" id grip)
2465 ,("--show-ssh",\[x] -> show_ssh x $ maybe "" id grip) 2519 ,("--show-ssh",\[x] -> show_ssh x $ maybe "" id grip)