import Test.QuickCheck
import qualified Test.HUnit as Unit
import Test.HUnit ((~:), (~=?))
import Text.Printf
import Data.ASN1.Raw
import Data.ASN1.DER (ASN1(..))
import qualified Data.ASN1.DER as DER
import Data.Binary.Get
import Data.Binary.Put
import Data.Word
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
mkSeq l = Value Universal 0x10 (Constructed l)
mkBool t = Value Universal 0x1 (Primitive $ B.pack [ if t then 0x1 else 0x0 ])
mkInt t = Value Universal 0x2 (Primitive $ B.pack [ t ])
famous_oids :: [[Integer]]
famous_oids =
[ [2,1,2]
, [1,38,53]
, [2,24,840,24042,530,530]
, [0,20,84,249,59342,53295392,325993252935]
, [1,2,840,113549,1,1,1]
]
instance Arbitrary Value where
arbitrary = elements [
mkSeq [],
mkSeq [ mkBool True, mkInt 124 ],
mkSeq [ mkSeq [ mkBool True, mkInt 124 ], mkSeq [] ]
]
coarbitrary (Value _ tn _) = variant tn
instance Arbitrary ASN1 where
arbitrary = elements (
[Boolean False,Boolean True,Null,EOC]
++ map IntVal ([0..512] ++ [10241024..10242048])
++ map OID famous_oids
)
getVal = either (const (Value Application (-1) (Constructed []))) id . runGetErr getValue
putVal = runPut . putValue
decodeASN1 = either (const EOC) id . DER.decodeASN1
prop_getput_value_id :: Value -> Bool
prop_getput_value_id v = (getVal . putVal) v == v
prop_getput_asn1_id :: ASN1 -> Bool
prop_getput_asn1_id v = (DER.decodeASN1 . DER.encodeASN1) v == Right v
tests =
[ ("get.put value/id", test prop_getput_value_id)
, ("get.put DER.ASN1/id", test prop_getput_asn1_id)
]
quickCheckMain = mapM_ (\(s,a) -> printf "%-25s: " s >> a) tests
value_units :: [ (String, Value, [Word8]) ]
value_units = [
("empty Sequence", mkSeq [], [ 0x30, 0x0 ]),
("long Sequence", mkSeq (replicate 50 (mkBool True)), [ 0x30, 0x81, 150 ] ++ (concat $ replicate 50 [ 0x01, 0x1, 0x1 ]))
]
asn1_units :: [ (String, ASN1) ]
asn1_units =
map (\oid -> ("OID " ++ show oid, OID oid)) famous_oids ++
[]
utests :: [Unit.Test]
utests =
map (\ (s, v, r) -> ("put " ++ s) ~: s ~: r ~=? (L.unpack $ putVal v)) value_units ++
map (\ (s, v, r) -> ("get " ++ s) ~: s ~: v ~=? (getVal $ L.pack r)) value_units ++
map (\ (s, v) -> ("decode/encode=id") ~: s ~: v ~=? (decodeASN1 . DER.encodeASN1) v) asn1_units
main = do
Unit.runTestTT (Unit.TestList utests)
quickCheckMain