diff --git a/Data/ASN1/BitArray.hs b/Data/ASN1/BitArray.hs
new file mode 100644
--- /dev/null
+++ b/Data/ASN1/BitArray.hs
@@ -0,0 +1,35 @@
+module Data.ASN1.BitArray
+	( BitArray(..)
+	, bitArrayLength
+	, bitArrayGetBit
+	, bitArrayGetData
+	, toBitArray
+	) where
+
+import Data.Bits
+import Data.Word
+import qualified Data.ByteString.Lazy as L
+
+-- | represent a bitarray / bitmap
+data BitArray = BitArray Word64 L.ByteString
+	deriving (Show,Eq)
+
+-- | returns the length of bits in this bitarray
+bitArrayLength :: BitArray -> Word64
+bitArrayLength (BitArray l _) = l
+
+-- | get the nth bits
+bitArrayGetBit :: BitArray -> Word64 -> Bool
+bitArrayGetBit (BitArray l d) n
+	| n >= l    = error ("array bit out of bounds: requesting bit " ++ show n ++ " but only got " ++ show l ++ " bits")
+	| otherwise = flip testBit (7-fromIntegral bitn) $ L.index d (fromIntegral offset)
+		where (offset, bitn) = n `divMod` 8
+
+-- | get padded bytestring of the bitarray
+bitArrayGetData :: BitArray -> L.ByteString
+bitArrayGetData (BitArray _ d) = d
+
+-- | number of bit to skip at the end (padding)
+toBitArray :: L.ByteString -> Int -> BitArray
+toBitArray l toSkip =
+	BitArray (fromIntegral (L.length l * 8 - fromIntegral toSkip)) l
diff --git a/Data/ASN1/Prim.hs b/Data/ASN1/Prim.hs
--- a/Data/ASN1/Prim.hs
+++ b/Data/ASN1/Prim.hs
@@ -57,6 +57,7 @@
 import Data.ASN1.Internal
 import Data.ASN1.Raw
 import Data.ASN1.Stream
+import Data.ASN1.BitArray
 import Data.Bits
 import Data.Word
 import Data.List (unfoldr)
@@ -87,7 +88,7 @@
 encodeHeader :: Bool -> ASN1Length -> ASN1 -> ASN1Header
 encodeHeader pc len (Boolean _)                = ASN1Header Universal 0x1 pc len
 encodeHeader pc len (IntVal _)                 = ASN1Header Universal 0x2 pc len
-encodeHeader pc len (BitString _ _)            = ASN1Header Universal 0x3 pc len
+encodeHeader pc len (BitString _)              = ASN1Header Universal 0x3 pc len
 encodeHeader pc len (OctetString _)            = ASN1Header Universal 0x4 pc len
 encodeHeader pc len Null                       = ASN1Header Universal 0x5 pc len
 encodeHeader pc len (OID _)                    = ASN1Header Universal 0x6 pc len
@@ -119,7 +120,7 @@
 encodePrimitiveData :: ASN1 -> ByteString
 encodePrimitiveData (Boolean b)         = B.singleton (if b then 0xff else 0)
 encodePrimitiveData (IntVal i)          = putInteger i
-encodePrimitiveData (BitString i bits)  = putBitString i bits
+encodePrimitiveData (BitString bits)    = putBitString bits
 encodePrimitiveData (OctetString b)     = putString b
 encodePrimitiveData Null                = B.empty
 encodePrimitiveData (OID oid)           = putOID oid
@@ -253,7 +254,7 @@
 	let toSkip' = if toSkip >= 48 && toSkip <= 48 + 7 then toSkip - (fromIntegral $ ord '0') else toSkip in
 	let xs = B.tail s in
 	if toSkip' >= 0 && toSkip' <= 7
-		then Right $ BitString (fromIntegral toSkip') (L.fromChunks [xs])
+		then Right $ BitString $ toBitArray (L.fromChunks [xs]) (fromIntegral toSkip')
 		else Left $ ASN1Misc ("bitstring: skip number not within bound " ++ show toSkip' ++ " " ++  show s)
 
 getString :: (ByteString -> Maybe ASN1Err) -> ByteString -> Either ASN1Err L.ByteString
@@ -378,8 +379,10 @@
 putInteger :: Integer -> ByteString
 putInteger i = B.pack $ bytesOfInt i
 
-putBitString :: Int -> L.ByteString -> ByteString
-putBitString i bits = B.concat $ B.singleton (fromIntegral i) : L.toChunks bits
+putBitString :: BitArray -> ByteString
+putBitString (BitArray n bits) =
+	B.concat $ B.singleton (fromIntegral i) : L.toChunks bits
+	where i = (8 - (n `mod` 8)) .&. 0x7
 
 putString :: L.ByteString -> ByteString
 putString l = B.concat $ L.toChunks l
diff --git a/Data/ASN1/Stream.hs b/Data/ASN1/Stream.hs
--- a/Data/ASN1/Stream.hs
+++ b/Data/ASN1/Stream.hs
@@ -7,6 +7,7 @@
 	) where
 
 import Data.ASN1.Raw
+import Data.ASN1.BitArray
 import Data.ByteString (ByteString)
 import qualified Data.ByteString.Lazy as L
 
@@ -19,7 +20,7 @@
 data ASN1 =
 	  Boolean Bool
 	| IntVal Integer
-	| BitString Int L.ByteString
+	| BitString BitArray
 	| OctetString L.ByteString
 	| Null
 	| OID [Integer]
diff --git a/Data/ASN1/Types.hs b/Data/ASN1/Types.hs
--- a/Data/ASN1/Types.hs
+++ b/Data/ASN1/Types.hs
@@ -4,6 +4,7 @@
 	, toStream
 	) where
 
+import Data.ASN1.BitArray
 import qualified Data.ASN1.Stream as S
 import qualified Data.ByteString.Lazy as L
 import Data.ByteString (ByteString)
@@ -12,7 +13,7 @@
 data ASN1t =
 	  Boolean Bool
 	| IntVal Integer
-	| BitString Int L.ByteString
+	| BitString BitArray
 	| OctetString L.ByteString
 	| Null
 	| OID [Integer]
@@ -52,7 +53,7 @@
 
 ofStream (S.Boolean b : l)         = Boolean b : ofStream l
 ofStream (S.IntVal i : l)          = IntVal i : ofStream l
-ofStream (S.BitString i bits : l)  = BitString i bits : ofStream l
+ofStream (S.BitString bits : l)    = BitString bits : ofStream l
 ofStream (S.OctetString b : l)     = OctetString b : ofStream l
 ofStream (S.Null : l)              = Null : ofStream l
 ofStream (S.OID oid : l)           = OID oid : ofStream l
@@ -82,7 +83,7 @@
 		toStreamOne (Container tc tag s)  = ([S.Start (S.Container tc tag)] ++ toStream s ++ [S.End (S.Container tc tag)])
 		toStreamOne (Boolean b)         = [S.Boolean b]
 		toStreamOne (IntVal b)          = [S.IntVal b]
-		toStreamOne (BitString i b)     = [S.BitString i b]
+		toStreamOne (BitString b)       = [S.BitString b]
 		toStreamOne (OctetString b)     = [S.OctetString b]
 		toStreamOne (Null)              = [S.Null]
 		toStreamOne (OID b)             = [S.OID b]
diff --git a/Tests.hs b/Tests.hs
--- a/Tests.hs
+++ b/Tests.hs
@@ -5,6 +5,7 @@
 import Text.Printf
 
 import Data.ASN1.Raw
+import Data.ASN1.BitArray
 import Data.ASN1.Stream (ASN1(..), ASN1ConstructionType(..))
 import Data.ASN1.Prim
 import qualified Data.ASN1.Types as T (ASN1t(..))
@@ -98,6 +99,12 @@
 		ws <- replicateM len arbitrary
 		return $ T.pack ws
 
+instance Arbitrary BitArray where
+	arbitrary = do
+		bs <- arbitrary
+		--w  <- choose (0,7) :: Gen Int
+		return $ toBitArray bs 0
+
 arbitraryTime = do
 	y <- choose (1951, 2050)
 	m <- choose (0, 11)
@@ -127,7 +134,7 @@
 	arbitrary = oneof
 		[ liftM Boolean arbitrary
 		, liftM IntVal arbitrary
-		, liftM2 BitString (choose (0,7)) arbitrary
+		, liftM BitString arbitrary
 		, liftM OctetString arbitrary
 		, return Null
 		, liftM OID arbitraryOID
@@ -169,7 +176,7 @@
 	arbitrary = oneof
 		[ liftM T.Boolean arbitrary
 		, liftM T.IntVal arbitrary
-		, liftM2 T.BitString (choose (0,7)) arbitrary
+		, liftM T.BitString arbitrary
 		, liftM T.OctetString arbitrary
 		, return T.Null
 		, liftM T.OID arbitraryOID
diff --git a/asn1-data.cabal b/asn1-data.cabal
--- a/asn1-data.cabal
+++ b/asn1-data.cabal
@@ -1,5 +1,5 @@
 Name:                asn1-data
-Version:             0.5.1
+Version:             0.6.0
 Description:
     ASN1 data reader and writer in raw form with supports for high level forms of ASN1 (BER, CER and DER).
     .
@@ -34,6 +34,7 @@
                      Data.ASN1.CER
                      Data.ASN1.DER
                      Data.ASN1.Raw
+                     Data.ASN1.BitArray
                      Data.ASN1.Types
                      Data.ASN1.Stream
   other-modules:     Data.ASN1.Prim
