packages feed

crypto-pubkey-openssh 0.2.6 → 0.2.7

raw patch · 5 files changed

+230/−26 lines, 5 filesdep ~QuickCheckdep ~asn1-encodingdep ~asn1-typesPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: QuickCheck, asn1-encoding, asn1-types, attoparsec, base, base64-bytestring, bytestring, cereal, crypto-pubkey-types, deepseq, filepath, pem, process, tasty, tasty-quickcheck, temporary

API changes (from Hackage documentation)

Files

+ README.md view
@@ -0,0 +1,19 @@+crypto-pubkey-openssh [![Build Status](https://secure.travis-ci.org/knsd/crypto-pubkey-openssh.png)](http://travis-ci.org/knsd/crypto-pubkey-openssh)+=====================++OpenSSH keys decoder/encoder, example.++```haskell+import System.Environment (getArgs)+import qualified Data.ByteString as B++import Crypto.PubKey.OpenSsh (decodePrivate)++main :: IO ()+main = do+    fname <- fmap head getArgs+    content <- B.readFile fname+    case decodePrivate content of+        Left e -> error e+        Right key -> print key+```
crypto-pubkey-openssh.cabal view
@@ -1,5 +1,5 @@ Name:               crypto-pubkey-openssh-Version:            0.2.6+Version:            0.2.7 Synopsis:           OpenSSH keys decoder/encoder Description:        OpenSSH keys decoder/encoder License:            MIT@@ -17,6 +17,9 @@ Cabal-version:      >= 1.12 Tested-with:        GHC == 7.6.* +Extra-source-files:+  README.md+ Flag OpenSsh   Description:      Test with ssh-keygen   Default:          False@@ -25,15 +28,15 @@   Hs-source-dirs:   src   Ghc-options:      -Wall -fno-warn-orphans   Default-language: Haskell2010-  Build-depends:    base                       == 4.7.*  || == 4.6.*  || == 4.5.*-                  , bytestring                 == 0.10.* || == 0.9.*-                  , base64-bytestring          == 1.0.*-                  , cereal                     == 0.4.*-                  , attoparsec                 >= 0.10-                  , crypto-pubkey-types        == 0.4.*-                  , pem                        == 0.2.*-                  , asn1-types                 == 0.2.*-                  , asn1-encoding              == 0.8.*+  Build-depends:    base                       >= 4.5 && < 5+                  , bytestring+                  , base64-bytestring+                  , cereal+                  , attoparsec+                  , crypto-pubkey-types+                  , pem+                  , asn1-types+                  , asn1-encoding    Exposed-modules:  Crypto.PubKey.OpenSsh   Other-modules:    Crypto.PubKey.OpenSsh.Types@@ -49,23 +52,27 @@   if flag(OpenSsh)     cpp-options: -DOPENSSH -  Build-depends:    base                       == 4.7.*  || == 4.6.*  || == 4.5.*-                  , bytestring                 == 0.10.* || == 0.9.*-                  , base64-bytestring          == 1.0.*-                  , cereal                     == 0.4.*-                  , attoparsec                 >= 0.10-                  , crypto-pubkey-types        == 0.4.*-                  , pem                        == 0.2.*-                  , asn1-types                 == 0.2.*-                  , asn1-encoding              == 0.8.*+  Build-depends:    base                       >= 4.5 && < 5+                  , bytestring+                  , base64-bytestring+                  , cereal+                  , attoparsec+                  , crypto-pubkey-types+                  , pem+                  , asn1-types+                  , asn1-encoding -                  , tasty                      == 0.8.*-                  , tasty-quickcheck           == 0.8.*-                  , QuickCheck                 >= 2.6-                  , temporary                  == 1.2.*  || == 1.1.*-                  , process                    == 1.2.*-                  , filepath                   == 1.3.*-                  , deepseq                    == 1.3.*+                  , tasty+                  , tasty-quickcheck+                  , QuickCheck+                  , temporary+                  , process+                  , filepath+                  , deepseq++  Other-modules:    Crypto.PubKey.OpenSsh.Encode.Tests+                    Crypto.PubKey.OpenSsh.Decode.Tests+                    SshKeygen  Source-repository head   Type:             git
+ tests/Crypto/PubKey/OpenSsh/Decode/Tests.hs view
@@ -0,0 +1,87 @@+{-# LANGUAGE OverloadedStrings #-}+module Crypto.PubKey.OpenSsh.Decode.Tests+    ( tests+    ) where++import Test.Tasty (TestTree, testGroup)+import Test.Tasty.QuickCheck (testProperty, once)++import Crypto.PubKey.OpenSsh.Decode (decodePublic, decodePrivate)+import Data.ByteString.Char8 ()++testDecodeRSAPublic :: Bool+testDecodeRSAPublic =+    case decodePublic rsaPub of+        Left _  -> False+        Right _ -> True+ where+  rsaPub = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCtuy+p1/IHUtofNeUg6Ex2Sc3f0B+97VsfAq65pyKvAAqAtZpR96Vr35hbaNEb+j3fpAXjrxouM87q5KksWD+0qFWNhDv7rBg6ENQJNLf5lfssiFacrVv1/SG2UP8VDkCMxpJyzcHE5ajmSzcjEFoerRudV2g05PPlw4fNyuhVaMQjNUejg+17CUPS8e7TxUoRvnVuBVSMezMn11n81djakzuit7nXj1L7WVqNHtAlbstK2aDdCB3yBOtOwBQVwvFwQfHpQ8hwrYoKAXPw3YTd9sPTtJ0qz0cZH89t7redHABRhOWdf7+cm0LpubqwWvv0SLlFRMwefoMsGcnJ6E7P tommd@Vodka"++testDecodeRSAPrivate :: Bool+testDecodeRSAPrivate =+    case decodePrivate rsaPriv of+        Left _  -> False+        Right _ -> True+ where+ rsaPriv = "-----BEGIN RSA PRIVATE KEY-----\n\+\MIIEpAIBAAKCAQEAw6s7oDCoXjEkrLDRVZDyWLVaiqxZyOTA33TyGSELv9ZiQzkr\n\+\ti+AOyuTWkmZjHYdLDWBYYQvwEjufzneHvNLw87/1zsQrd6ZPUwEOkh0RqG9mxoV\n\+\JFgpruzKoG6BNgnUti/S9idErit+XEx9ff8bmmjawdC10czAdL3zCpZaEXw4JAwC\n\+\sgQB1J1/Mw4cnzMqKyxPtSPZjhiZZ6y2bVCfNfnOZ9dvIDa/unEWlFSDPjX0+zSM\n\+\mjRzDoE04jtoAI0v3iynZ26kea+YU4oni2MQ7EL4Y1CmLAWm4/9APhf3Xt0EJOIt\n\+\Ngv1j2468+8WF5aTEitb8D2ZRFYPiLWMaJlhGwIDAQABAoIBAQCWAPXLDsJkw4P8\n\+\J+mzkVVZEF8DJLIIQuZh6MOY5C6fuPjH1FJgbvX9ZqCmfPoMJpiixboUSkRZQxAj\n\+\1Pcl/xq8WDrmg897m8UaquYq0FTjuScketBudnAuPDXy3ASOqua5bNxr/Rq383wB\n\+\wloKd8Jvk6bxItHgrvl0BhMGsNEHyT36SXmc7HsgCzifuXMo5E3uqTGP/+wLWCRy\n\+\NO+AqStSjQbQZtLVOvNdQYknv+uqm/m5LyO1Vi2pPl0vEgpwiq4C/8W+YT2ya3dz\n\+\QfG+Fsewu5WDdHTBgTN4F/p2tgG6Zg+fdfRkF2NNwJXiGb1TTmR1IMZtzqDQ5mys\n\+\dk40xuAxAoGBAOTMhUpINw2rSaduEWAxnSAZFMAIozKBOJD1Q2+kYbYMHPOPN+CN\n\+\NCUrWpEiFa+vM+BIrQsG6M7Nb9VmefOKuS7vetIUYWsJ2hO8oX2+8ZiPcBwU3izX\n\+\wAoGq0yeUaG4yGZUrkP2Gfm+jUdj/AoGOnG9pd/CYDevVNnOSyWko8RVAoGBANru\n\+\Zupv8fIXDcnqYGBAbHpBQkojAzccBHxyE/4BUJlFIZWDAMem50op49SsF6gKrxtO\n\+\IvXb1+58axGza84F7cXmQgR0nV8AXMzBlI31HyvftMv8Yb1h+oXbjCFI99lMz6/F\n\+\jkCSzoiLGo0NAEmqRb4TThSjj8vfiw+zxsllQH+vAoGAFmKcN+RQ3pl/n035jTvN\n\+\b7KEgTVXIj3aVvRoIKgolzMgMgQ1J1cpXuma9tAq5wFxReRWadnHNVSMOIjKLbXI\n\+\4Hq1vZAY5+wS1hOCiVcBNDf0dArmoeSJ+XElmV10ByqZEMoAMs4FRJYMJIv3wNNT\n\+\LIWtkPLnjwssdhLk703oZ/ECgYB/4JCsjwa7aUvcjNIOZpL2NfgKZbkTD4JvThLv\n\+\YsU5QXAEbKif9ZVTdHRnXL3Uoaj2QgWZpffSjUnc5PgrNrtTxNL610K0ovmRf+DN\n\+\qkey0NBB9gEBJaG3Xi3To1Nh0cPd337fqOCKUPYJPXbVkGd8Rrpsw7zSUJhha5jJ\n\+\OiMacQKBgQCxDCTOUqDksmXkDutXi/f/dMIwfMXaNuTc3ectyaBC05+0B10uLfnv\n\+\7jurNd89OFTHsu7CLfbwDzu+Q+GWTWemUk2ieq9z0Ct5aIzjxoALNnKiu5pH1YDH\n\+\Mf6ApFppkCpTkQ0sEERn0zH/hNQct1cwflfQi7JN+3GGax7oySmQRQ==\n\+\-----END RSA PRIVATE KEY-----"++testDecodeDSAPublic :: Bool+testDecodeDSAPublic =+    case decodePublic dsaPub of+        Left _  -> False+        Right _ -> True+ where+  dsaPub = "ssh-dss AAAAB3NzaC1kc3MAAACBALco1Yeq0uPETFRf72VbmH+sMttQMbs1GRF+9vbkI7GJZtaRCE2+jtVSiFXDBm4Yuxf+pqvdQ6Jl1X/zuED/YzN2GIVhHMzy12KQ27E8B63vIP/hhLaYv7Tw00yE7HzxBrbx4rfdkPguam0Mjzqhck4cwVKsKhuSinaGTwqMF+KRAAAAFQCziBsxBGOF2YDzsXnBs+Jv0p2GewAAAIEAiCaFUZcLEO5WTAi/lQNo42ZyXP2rl1jeugPVCtDSWhSEHU1EIJcmmCx//ofaOz/X2uJAv15ZjLY8xZW41N2wHA64mhjaXzBBUeVqAOgoYW8dQOo2XNFmU7idWsYxhsUUknWDf9A6v4blUgQNHn1u8c4Y3xcfCEHfZB6om6XA7aAAAACAI3H1hNNXWzd5Fuqpj1ZeUKFAOfFbYeD3XBIKwwMPdrVZW/PMJ3s+Ic90V0paKBA0+Sgvg+EHWK213+zEp29+lL50Nne7jh//smQ0zBKMiRre7iZ+rEDM4nWZOM3vzClfgilTDkkQ4TCjz7yMm21ZqApt+Lq5uNOK6DJB4PszCwI= tommd@Vodka"++testDecodeDSAPrivate :: Bool+testDecodeDSAPrivate =+    case decodePrivate dsaPriv of+        Left _  -> False+        Right _ -> True+ where+  dsaPriv = "-----BEGIN DSA PRIVATE KEY-----\n\+\MIIBuwIBAAKBgQC3KNWHqtLjxExUX+9lW5h/rDLbUDG7NRkRfvb25COxiWbWkQhN\n\+\vo7VUohVwwZuGLsX/qar3UOiZdV/87hA/2MzdhiFYRzM8tdikNuxPAet7yD/4YS2\n\+\mL+08NNMhOx88Qa28eK33ZD4LmptDI86oXJOHMFSrCobkop2hk8KjBfikQIVALOI\n\+\GzEEY4XZgPOxecGz4m/SnYZ7AoGBAIgmhVGXCxDuVkwIv5UDaONmclz9q5dY3roD\n\+\1QrQ0loUhB1NRCCXJpgsf/6H2js/19riQL9eWYy2PMWVuNTdsBwOuJoY2l8wQVHl\n\+\agDoKGFvHUDqNlzRZlO4nVrGMYbFFJJ1g3/QOr+G5VIEDR59bvHOGN8XHwhB32Qe\n\+\qJulwO2gAoGAI3H1hNNXWzd5Fuqpj1ZeUKFAOfFbYeD3XBIKwwMPdrVZW/PMJ3s+\n\+\Ic90V0paKBA0+Sgvg+EHWK213+zEp29+lL50Nne7jh//smQ0zBKMiRre7iZ+rEDM\n\+\4nWZOM3vzClfgilTDkkQ4TCjz7yMm21ZqApt+Lq5uNOK6DJB4PszCwICFAG6JRA/\n\+\iyaf5dPPUem5PxQeKx1b\n\+\-----END DSA PRIVATE KEY-----"++tests :: TestTree+tests = testGroup "Crypto.PubKey.OpenSsh.Decode.Tests"+    [ testProperty "Decode Public RSA" $ once testDecodeRSAPublic+    , testProperty "Decode Private RSA" $ once testDecodeRSAPrivate+    , testProperty "Decode Public DSA" $ once testDecodeDSAPublic+    , testProperty "Decode Private DSA" $ once testDecodeDSAPrivate+    ]
+ tests/Crypto/PubKey/OpenSsh/Encode/Tests.hs view
@@ -0,0 +1,20 @@+module Crypto.PubKey.OpenSsh.Encode.Tests+    ( tests+    ) where++import Control.DeepSeq (deepseq)+import Data.Word (Word8)++import Test.Tasty (TestTree, testGroup)+import Test.Tasty.QuickCheck (testProperty)++import Crypto.PubKey.OpenSsh.Encode (fixZeroByte)++-- | In version 0.2.0 `fixZeroByte` function fails with empty input+testFixZeroByte :: [Word8] -> Bool+testFixZeroByte i = fixZeroByte i `deepseq` True++tests :: TestTree+tests = testGroup "Crypto.PubKey.OpenSsh.Encode.Tests"+    [ testProperty "regression test testFixZeroByte" testFixZeroByte+    ]
+ tests/SshKeygen.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE TypeSynonymInstances #-}++module SshKeygen where++import Data.Monoid ((<>))+import System.FilePath.Posix ((</>), (<.>))+import System.Process (runCommand, waitForProcess)+import System.IO.Temp (withSystemTempDirectory)+import qualified Data.ByteString.Char8 as SB++import Test.Tasty (TestTree, testGroup)+import Test.Tasty.QuickCheck (Property, Arbitrary(..), elements, suchThat, testProperty)+import Test.QuickCheck.Monadic (monadicIO, run, assert)++import Crypto.PubKey.OpenSsh.Types (OpenSshKeyType(..), OpenSshPublicKey(..),+                                    OpenSshPrivateKey(..))+import Crypto.PubKey.OpenSsh (encodePublic, decodePublic,+                              encodePrivate, decodePrivate)++import qualified Crypto.PubKey.OpenSsh.Encode.Tests++type StrictByteString = SB.ByteString+type PrivateKey = StrictByteString+type PublicKey = StrictByteString++instance Arbitrary OpenSshKeyType where+    arbitrary = elements [OpenSshKeyTypeRsa, OpenSshKeyTypeDsa]++openSshKeys :: OpenSshKeyType -> IO (PrivateKey, PublicKey)+openSshKeys t = withSystemTempDirectory base $ \dir -> do+    let path = dir </> typ+    let run = "ssh-keygen -t " <> typ <> " -N \"\" -f " <> path+    waitForProcess =<< runCommand run+    priv <- SB.readFile $ path+    pub <- fmap SB.init $ SB.readFile $ path <.> "pub"+    return (priv, pub)+  where+    base = "crypto-pubkey-openssh-tests"+    typ = case t of+        OpenSshKeyTypeRsa -> "rsa"+        OpenSshKeyTypeDsa -> "dsa"++testWithOpenSsh :: OpenSshKeyType -> Property+testWithOpenSsh t = monadicIO $ do+    (priv, pub) <- run $ openSshKeys t+    assert $ checkPublic (decodePublic pub) pub+    assert $ checkPrivate (decodePrivate priv) priv+  where+    checkPublic = case t of+        OpenSshKeyTypeRsa -> \r b -> case r of+            Right k@(OpenSshPublicKeyRsa _ _) ->+                encodePublic k == b+            _                                 -> False+        OpenSshKeyTypeDsa -> \r b -> case r of+            Right k@(OpenSshPublicKeyDsa _ _) ->+                encodePublic k == b+            _                                 -> False+    checkPrivate = case t of+        OpenSshKeyTypeRsa -> \r b -> case r of+            Right k@(OpenSshPrivateKeyRsa _) ->+                encodePrivate k == b+            _                                 -> False+        OpenSshKeyTypeDsa -> \r b -> case r of+            Right k@(OpenSshPrivateKeyDsa _ _) ->+                encodePrivate k == b+            _                                 -> False++tests :: TestTree+tests = testGroup "SshKeygen"+    [ testProperty "decode/encode" $ testWithOpenSsh+    ]