crypto-pubkey-openssh (empty) → 0.0.0
raw patch · 4 files changed
+133/−0 lines, 4 filesdep +attoparsecdep +basedep +base64-bytestringsetup-changed
Dependencies added: attoparsec, base, base64-bytestring, bytestring, cereal, crypto-pubkey-types
Files
- LICENSE +20/−0
- Setup.hs +3/−0
- crypto-pubkey-openssh.cabal +33/−0
- src/Crypto/PubKey/OpenSsh.hs +77/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2013 Fedor Gogolev++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,3 @@+import Distribution.Simple++main = defaultMain
+ crypto-pubkey-openssh.cabal view
@@ -0,0 +1,33 @@+Name: crypto-pubkey-openssh+Version: 0.0.0+Synopsis: OpenSSH public keys parser+Description: OpenSSH public keys parser+License: MIT+License-file: LICENSE+Copyright: Fedor Gogolev <knsd@knsd.net>+Author: Fedor Gogolev <knsd@knsd.net>+Maintainer: Fedor Gogolev <knsd@knsd.net>+Homepage: https://github.com/knsd/crypto-pubkey-openssh+Bug-reports: https://github.com/knsd/crypto-pubkey-openssh/issues+Category: Cryptography, Parsing+Stability: Alpha+Build-type: Simple+Cabal-version: >= 1.12+Tested-with: GHC == 7.6.*++Library+ Hs-source-dirs: src+ Ghc-options: -Wall -fno-warn-orphans+ Default-language: Haskell2010+ Build-depends: base == 4.6.*+ , bytestring == 0.10.*+ , base64-bytestring == 1.0.*+ , cereal == 0.3.*+ , attoparsec == 0.10.*+ , crypto-pubkey-types == 0.2.*++ Exposed-modules: Crypto.PubKey.OpenSsh++Source-repository head+ Type: git+ Location: https://github.com/knsd/crypto-pubkey-openssh
+ src/Crypto/PubKey/OpenSsh.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE OverloadedStrings #-}++module Crypto.PubKey.OpenSsh+ ( OpenSshPublicKey(..)+ , openSshPublicKeyParser+ , parseOpenSshPublicKey+ ) where++import Prelude hiding (take)++import Control.Monad (void, replicateM)+import Data.ByteString.Char8 (ByteString)++import Data.Attoparsec.ByteString.Char8 (Parser, parseOnly, take, space,+ isSpace, takeTill)+import Data.Serialize (Get, getBytes, runGet, getWord32be, getWord8)+import qualified Data.ByteString.Base64 as Base64+import qualified Crypto.Types.PubKey.DSA as DSA+import qualified Crypto.Types.PubKey.RSA as RSA++data OpenSshPublicKey = OpenSshPublicKeyRsa RSA.PublicKey+ | OpenSshPublicKeyDsa DSA.PublicKey+ deriving (Eq, Show)++data OpenSshPublicKeyType = OpenSshPublicKeyTypeRsa+ | OpenSshPublicKeyTypeDsa+ deriving (Eq, Show)++typeSize :: Int+typeSize = 7++readType :: Monad m => ByteString -> m OpenSshPublicKeyType+readType "ssh-rsa" = return OpenSshPublicKeyTypeRsa+readType "ssh-dss" = return OpenSshPublicKeyTypeDsa+readType _ = fail "Invalid key type"++calculateSize :: Integer -> Int+calculateSize = go 1+ where+ go i n | 2 ^ (i * 8) > n = i+ | otherwise = go (i + 1) n++getInteger :: Get Integer+getInteger = do+ size <- fmap fromIntegral getWord32be+ ints <- fmap reverse $ replicateM size $ fmap toInteger getWord8+ return $ fst $ flip foldl1 (zip ints ([0..] :: [Integer])) $+ \(a, _) (c, p) -> (c * (256 ^ p) + a, p)++getOpenSshPublicKey :: Get OpenSshPublicKey+getOpenSshPublicKey = do+ size <- fmap fromIntegral $ getWord32be+ getBytes size >>= readType >>= \typ -> case typ of+ OpenSshPublicKeyTypeRsa -> parseRsa+ OpenSshPublicKeyTypeDsa -> parseDsa+ where+ parseRsa = do + e <- getInteger+ n <- getInteger+ return $ OpenSshPublicKeyRsa $ RSA.PublicKey (calculateSize n) n e+ parseDsa = do+ p <- getInteger+ q <- getInteger+ g <- getInteger+ y <- getInteger+ return $ OpenSshPublicKeyDsa $ DSA.PublicKey (p, g, q) y++openSshPublicKeyParser :: Parser OpenSshPublicKey+openSshPublicKeyParser = do+ _typ <- readType =<< take typeSize+ void space+ b64 <- takeTill isSpace+ binary <- either fail return $ Base64.decode b64+ either fail return $ runGet getOpenSshPublicKey binary++parseOpenSshPublicKey :: ByteString -> Either String OpenSshPublicKey+parseOpenSshPublicKey = parseOnly openSshPublicKeyParser