diff options
author | joe <joe@blackbird> | 2014-01-06 20:58:46 -0500 |
---|---|---|
committer | joe <joe@blackbird> | 2014-01-06 20:58:46 -0500 |
commit | f6e2f03b31f3c9760cb4e1251218fb9372527c96 (patch) | |
tree | 38b6bebfb071637356f2f31bc46ecb79aa16e242 | |
parent | 3257807aabc1d12b657cbd47d87de3c69ca6da1d (diff) |
--show-whose-key option to search who owns the given ssh key.
-rw-r--r-- | kiki.hs | 56 |
1 files changed, 55 insertions, 1 deletions
@@ -79,6 +79,7 @@ import qualified Hosts | |||
79 | import Network.Socket -- (SockAddr) | 79 | import Network.Socket -- (SockAddr) |
80 | import LengthPrefixedBE | 80 | import LengthPrefixedBE |
81 | import Data.Binary.Put (putWord32be,runPut,putByteString) | 81 | import Data.Binary.Put (putWord32be,runPut,putByteString) |
82 | import 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 | ||
108 | data RSAPublicKey = RSAKey MPI MPI deriving Show | 109 | data RSAPublicKey = RSAKey MPI MPI deriving (Eq,Show) |
109 | data PKCS8_RSAPublicKey = RSAKey8 MPI MPI deriving Show | 110 | data PKCS8_RSAPublicKey = RSAKey8 MPI MPI deriving Show |
110 | 111 | ||
111 | pkcs8 (RSAKey n e) = RSAKey8 n e | 112 | pkcs8 (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 | ||
230 | decode_sshrsa :: Char8.ByteString -> Maybe RSAPublicKey | ||
231 | decode_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 | |||
229 | rsaKeyFromPacket :: Packet -> Maybe RSAPublicKey | 242 | rsaKeyFromPacket :: Packet -> Maybe RSAPublicKey |
230 | rsaKeyFromPacket p@(PublicKeyPacket {}) = do | 243 | rsaKeyFromPacket 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 | } |
965 | readKeyFromFile is_public fmt filename = error ("unimplemented key type: "++fmt) | 978 | readKeyFromFile is_public fmt filename = error ("unimplemented key type: "++fmt) |
966 | 979 | ||
980 | readPublicKey :: Char8.ByteString -> RSAPublicKey | ||
981 | readPublicKey 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 | {- |
968 | getPassphrase cmd = | 993 | getPassphrase 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 | ||
1437 | show_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 | |||
1412 | show_pem keyspec wkgrip db = do | 1447 | show_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 | ||
2140 | whoseKey :: RSAPublicKey -> KeyDB -> [KeyData] | ||
2141 | whoseKey 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 | |||
2105 | kiki_usage = do | 2149 | kiki_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) |