-- | -- Module : Crypto.Store.CMS.PEM -- License : BSD-style -- Maintainer : Olivier Chéron -- Stability : experimental -- Portability : unknown -- -- PEM serialization and deserialization of CMS 'ContentInfo'. 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 -- Reading from PEM format -- | Read content info elements from a PEM file. readCMSFile :: FilePath -> IO [ContentInfo] readCMSFile path = accumulate <$> readPEMs path -- | Read content info elements from a bytearray in PEM format. readCMSFileFromMemory :: B.ByteString -> [ContentInfo] readCMSFileFromMemory = either (const []) accumulate . pemParseBS accumulate :: [PEM] -> [ContentInfo] accumulate = catMaybes . foldr (flip pemToContentInfo) [] -- | Read a content info from a 'PEM' element and add it to the accumulator -- list. 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 -- Writing to PEM format -- | Write content info elements to a PEM file. writeCMSFile :: FilePath -> [ContentInfo] -> IO () writeCMSFile path = B.writeFile path . writeCMSFileToMemory -- | Write content info elements to a bytearray in PEM format. writeCMSFileToMemory :: [ContentInfo] -> B.ByteString writeCMSFileToMemory = pemsWriteBS . map contentInfoToPEM -- | Generate PEM for a content info. contentInfoToPEM :: ContentInfo -> PEM contentInfoToPEM info = PEM { pemName = "CMS", pemHeader = [], pemContent = bs} where bs = encodeASN1Object info