diff options
author | joe <joe@jerkface.net> | 2014-08-04 19:25:43 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2014-08-04 19:25:43 -0400 |
commit | f75dc8570a347896093a88e482780d6969488cbf (patch) | |
tree | a6eccd7558d6cef4c72927e605563ee51a4d378d | |
parent | d546f22c6ee3d88eca6b01b4e7debae56cfda649 (diff) |
Refactored ssh key blob serialization into independent module.
-rw-r--r-- | SSHKey.hs | 51 | ||||
-rw-r--r-- | kiki.hs | 37 |
2 files changed, 57 insertions, 31 deletions
diff --git a/SSHKey.hs b/SSHKey.hs new file mode 100644 index 0000000..6e92e43 --- /dev/null +++ b/SSHKey.hs | |||
@@ -0,0 +1,51 @@ | |||
1 | {-# LANGUAGE OverloadedStrings #-} | ||
2 | module SSHKey where | ||
3 | |||
4 | import qualified Data.ByteString.Lazy.Char8 as L8 | ||
5 | import qualified Data.ByteString.Lazy as L | ||
6 | import qualified Codec.Binary.Base64 as Base64 | ||
7 | import Data.Binary.Get ( runGet ) | ||
8 | import Data.Binary.Put ( putWord32be, runPut, putByteString ) | ||
9 | import Data.Binary ( get, put ) | ||
10 | import Data.Monoid ( (<>) ) | ||
11 | import Data.Maybe ( fromMaybe, listToMaybe ) | ||
12 | import Data.Char ( isSpace ) | ||
13 | import Control.Monad ( guard ) | ||
14 | import LengthPrefixedBE | ||
15 | |||
16 | type Key = (Integer,Integer) | ||
17 | |||
18 | keyblob :: Key -> L.ByteString | ||
19 | keyblob (n,e) = "ssh-rsa " <> blob | ||
20 | where | ||
21 | bs = sshrsa e n | ||
22 | blob = L8.pack $ Base64.encode (L.unpack bs) | ||
23 | |||
24 | sshrsa :: Integer -> Integer -> L.ByteString | ||
25 | sshrsa e n = runPut $ do | ||
26 | putWord32be 7 | ||
27 | putByteString "ssh-rsa" | ||
28 | put (LengthPrefixedBE e) | ||
29 | put (LengthPrefixedBE n) | ||
30 | |||
31 | blobkey :: L8.ByteString -> Key | ||
32 | blobkey bs = fromMaybe er $ do | ||
33 | let (pre,bs1) = L8.splitAt 7 bs | ||
34 | guard $ pre == "ssh-rsa" | ||
35 | let (sp,bs2) = L8.span isSpace bs1 | ||
36 | guard $ not (L8.null sp) | ||
37 | bs3 <- listToMaybe $ L8.words bs2 | ||
38 | qq <- L.pack `fmap` Base64.decode (L8.unpack bs3) | ||
39 | decode_sshrsa qq | ||
40 | where | ||
41 | er = error "Unsupported key format" | ||
42 | |||
43 | decode_sshrsa :: L8.ByteString -> Maybe Key | ||
44 | decode_sshrsa bs = do | ||
45 | let (pre,bs1) = L8.splitAt 11 bs | ||
46 | guard $ pre == runPut (putWord32be 7 >> putByteString "ssh-rsa") | ||
47 | let rsakey = flip runGet bs1 $ do | ||
48 | LengthPrefixedBE e <- get | ||
49 | LengthPrefixedBE n <- get | ||
50 | return (n,e) | ||
51 | return rsakey | ||
@@ -36,8 +36,6 @@ import qualified Data.ByteString.Lazy as L | |||
36 | import qualified Data.ByteString.Lazy.Char8 as Char8 | 36 | import qualified Data.ByteString.Lazy.Char8 as Char8 |
37 | import qualified Data.Map as Map | 37 | import qualified Data.Map as Map |
38 | import Control.Arrow (first,second) | 38 | import Control.Arrow (first,second) |
39 | import Data.Binary.Get (runGet) | ||
40 | import Data.Binary.Put (putWord32be,runPut,putByteString) | ||
41 | import Data.Time.Clock.POSIX ( posixSecondsToUTCTime ) | 39 | import Data.Time.Clock.POSIX ( posixSecondsToUTCTime ) |
42 | import Data.Monoid ( (<>) ) | 40 | import Data.Monoid ( (<>) ) |
43 | 41 | ||
@@ -45,12 +43,12 @@ import Data.OpenPGP.Util (verify,fingerprint) | |||
45 | import ScanningParser | 43 | import ScanningParser |
46 | import PEM | 44 | import PEM |
47 | import DotLock | 45 | import DotLock |
48 | import LengthPrefixedBE | ||
49 | import KeyRing | 46 | import KeyRing |
50 | import Base58 | 47 | import Base58 |
51 | import qualified CryptoCoins | 48 | import qualified CryptoCoins |
52 | -- import Chroot | 49 | -- import Chroot |
53 | import ProcessUtils | 50 | import ProcessUtils |
51 | import qualified SSHKey as SSH | ||
54 | 52 | ||
55 | -- {-# ANN module ("HLint: ignore Eta reduce"::String) #-} | 53 | -- {-# ANN module ("HLint: ignore Eta reduce"::String) #-} |
56 | -- {-# ANN module ("HLint: ignore Use camelCase"::String) #-} | 54 | -- {-# ANN module ("HLint: ignore Use camelCase"::String) #-} |
@@ -114,22 +112,6 @@ import ProcessUtils | |||
114 | 112 | ||
115 | warn str = hPutStrLn stderr str | 113 | warn str = hPutStrLn stderr str |
116 | 114 | ||
117 | sshrsa :: Integer -> Integer -> Char8.ByteString | ||
118 | sshrsa e n = runPut $ do | ||
119 | putWord32be 7 | ||
120 | putByteString "ssh-rsa" | ||
121 | put (LengthPrefixedBE e) | ||
122 | put (LengthPrefixedBE n) | ||
123 | |||
124 | decode_sshrsa :: Char8.ByteString -> Maybe RSAPublicKey | ||
125 | decode_sshrsa bs = do | ||
126 | let (pre,bs1) = Char8.splitAt 11 bs | ||
127 | guard $ pre == runPut (putWord32be 7 >> putByteString "ssh-rsa") | ||
128 | let rsakey = flip runGet bs1 $ do | ||
129 | LengthPrefixedBE e <- get | ||
130 | LengthPrefixedBE n <- get | ||
131 | return $ RSAKey (MPI n) (MPI e) | ||
132 | return rsakey | ||
133 | 115 | ||
134 | isCertificationSig (CertificationSignature {}) = True | 116 | isCertificationSig (CertificationSignature {}) = True |
135 | isCertificationSig _ = True | 117 | isCertificationSig _ = True |
@@ -240,16 +222,9 @@ modifyUID other = other | |||
240 | -} | 222 | -} |
241 | 223 | ||
242 | readPublicKey :: Char8.ByteString -> RSAPublicKey | 224 | readPublicKey :: Char8.ByteString -> RSAPublicKey |
243 | readPublicKey bs = fromMaybe er $ do | 225 | readPublicKey bs = RSAKey (MPI n) (MPI e) |
244 | let (pre,bs1) = Char8.splitAt 7 bs | ||
245 | guard $ pre == "ssh-rsa" | ||
246 | let (sp,bs2) = Char8.span isSpace bs1 | ||
247 | guard $ not (Char8.null sp) | ||
248 | bs3 <- listToMaybe $ Char8.words bs2 | ||
249 | qq <- L.pack `fmap` Base64.decode (Char8.unpack bs3) | ||
250 | decode_sshrsa qq | ||
251 | where | 226 | where |
252 | er = error "Unsupported key format" | 227 | (n,e) = SSH.blobkey bs |
253 | 228 | ||
254 | -- | Returns the given list with its last element modified. | 229 | -- | Returns the given list with its last element modified. |
255 | toLast :: (x -> x) -> [x] -> [x] | 230 | toLast :: (x -> x) -> [x] -> [x] |
@@ -312,9 +287,9 @@ show_ssh' keyspec wkgrip db = do | |||
312 | (selectPublicKey s db) | 287 | (selectPublicKey s db) |
313 | $ \k -> do | 288 | $ \k -> do |
314 | let Just (RSAKey (MPI n) (MPI e)) = rsaKeyFromPacket k | 289 | let Just (RSAKey (MPI n) (MPI e)) = rsaKeyFromPacket k |
315 | bs = sshrsa e n | 290 | bs = SSH.keyblob (n,e) |
316 | blob = Base64.encode (L.unpack bs) | 291 | blob = Char8.unpack bs |
317 | return $ "ssh-rsa " ++ blob | 292 | return blob |
318 | 293 | ||
319 | show_id keyspec wkgrip db = do | 294 | show_id keyspec wkgrip db = do |
320 | let s = parseSpec "" keyspec | 295 | let s = parseSpec "" keyspec |