summaryrefslogtreecommitdiff
path: root/SSHKey.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2014-08-04 19:25:43 -0400
committerjoe <joe@jerkface.net>2014-08-04 19:25:43 -0400
commitf75dc8570a347896093a88e482780d6969488cbf (patch)
treea6eccd7558d6cef4c72927e605563ee51a4d378d /SSHKey.hs
parentd546f22c6ee3d88eca6b01b4e7debae56cfda649 (diff)
Refactored ssh key blob serialization into independent module.
Diffstat (limited to 'SSHKey.hs')
-rw-r--r--SSHKey.hs51
1 files changed, 51 insertions, 0 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 #-}
2module SSHKey where
3
4import qualified Data.ByteString.Lazy.Char8 as L8
5import qualified Data.ByteString.Lazy as L
6import qualified Codec.Binary.Base64 as Base64
7import Data.Binary.Get ( runGet )
8import Data.Binary.Put ( putWord32be, runPut, putByteString )
9import Data.Binary ( get, put )
10import Data.Monoid ( (<>) )
11import Data.Maybe ( fromMaybe, listToMaybe )
12import Data.Char ( isSpace )
13import Control.Monad ( guard )
14import LengthPrefixedBE
15
16type Key = (Integer,Integer)
17
18keyblob :: Key -> L.ByteString
19keyblob (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
31blobkey :: L8.ByteString -> Key
32blobkey 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