module Crypto.Store.CMS.PEM
( readCMSFile
, readCMSFileFromMemory
, pemToContentInfo
, writeCMSFile
, writeCMSFileToMemory
, contentInfoToPEM
) where
import Data.ASN1.BinaryEncoding
import Data.ASN1.Encoding
import qualified Data.ByteString as B
import Data.Maybe (catMaybes)
import Crypto.Store.CMS.Info
import Crypto.Store.CMS.Util
import Crypto.Store.PEM
readCMSFile :: FilePath -> IO [ContentInfo]
readCMSFile path = accumulate <$> readPEMs path
readCMSFileFromMemory :: B.ByteString -> [ContentInfo]
readCMSFileFromMemory = either (const []) accumulate . pemParseBS
accumulate :: [PEM] -> [ContentInfo]
accumulate = catMaybes . foldr (flip pemToContentInfo) []
pemToContentInfo :: [Maybe ContentInfo] -> PEM -> [Maybe ContentInfo]
pemToContentInfo acc pem
| pemName pem `elem` names = decode (pemContent pem)
| otherwise = Nothing : acc
where
names = [ "CMS", "PKCS7" ]
decode bs =
case decodeASN1Repr' BER bs of
Left _ -> Nothing : acc
Right asn1 ->
case fromASN1Repr asn1 of
Right (info, []) -> Just info : acc
_ -> Nothing : acc
writeCMSFile :: FilePath -> [ContentInfo] -> IO ()
writeCMSFile path = B.writeFile path . writeCMSFileToMemory
writeCMSFileToMemory :: [ContentInfo] -> B.ByteString
writeCMSFileToMemory = pemsWriteBS . map contentInfoToPEM
contentInfoToPEM :: ContentInfo -> PEM
contentInfoToPEM info = PEM { pemName = "CMS", pemHeader = [], pemContent = bs}
where bs = encodeASN1Object info