module Crypto.Store.CMS.PEM
( readCMSFile
, readCMSFileFromMemory
, berToContentInfo
, pemToContentInfo
, writeCMSFile
, writeCMSFileToMemory
, contentInfoToDER
, contentInfoToPEM
) where
import qualified Data.ByteString as B
import Data.Maybe (catMaybes)
import Crypto.Store.CMS.Info
import Crypto.Store.CMS.Util
import Crypto.Store.Error
import Crypto.Store.PEM
readCMSFile :: FilePath -> IO [ContentInfo]
readCMSFile :: String -> IO [ContentInfo]
readCMSFile String
path = [PEM] -> [ContentInfo]
accumulate ([PEM] -> [ContentInfo]) -> IO [PEM] -> IO [ContentInfo]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO [PEM]
readPEMs String
path
readCMSFileFromMemory :: B.ByteString -> [ContentInfo]
readCMSFileFromMemory :: ByteString -> [ContentInfo]
readCMSFileFromMemory = (String -> [ContentInfo])
-> ([PEM] -> [ContentInfo]) -> Either String [PEM] -> [ContentInfo]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ([ContentInfo] -> String -> [ContentInfo]
forall a b. a -> b -> a
const []) [PEM] -> [ContentInfo]
accumulate (Either String [PEM] -> [ContentInfo])
-> (ByteString -> Either String [PEM])
-> ByteString
-> [ContentInfo]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either String [PEM]
pemParseBS
accumulate :: [PEM] -> [ContentInfo]
accumulate :: [PEM] -> [ContentInfo]
accumulate = [Maybe ContentInfo] -> [ContentInfo]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe ContentInfo] -> [ContentInfo])
-> ([PEM] -> [Maybe ContentInfo]) -> [PEM] -> [ContentInfo]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PEM -> [Maybe ContentInfo] -> [Maybe ContentInfo])
-> [Maybe ContentInfo] -> [PEM] -> [Maybe ContentInfo]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (([Maybe ContentInfo] -> PEM -> [Maybe ContentInfo])
-> PEM -> [Maybe ContentInfo] -> [Maybe ContentInfo]
forall a b c. (a -> b -> c) -> b -> a -> c
flip [Maybe ContentInfo] -> PEM -> [Maybe ContentInfo]
pemToContentInfo) []
berToContentInfo :: B.ByteString -> Either StoreError ContentInfo
berToContentInfo :: ByteString -> Either StoreError ContentInfo
berToContentInfo = ByteString -> Either StoreError ContentInfo
forall obj.
ParseASN1Object [ASN1Event] obj =>
ByteString -> Either StoreError obj
decodeASN1Object
pemToContentInfo :: [Maybe ContentInfo] -> PEM -> [Maybe ContentInfo]
pemToContentInfo :: [Maybe ContentInfo] -> PEM -> [Maybe ContentInfo]
pemToContentInfo [Maybe ContentInfo]
acc PEM
pem
| PEM -> String
pemName PEM
pem String -> [String] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
names = ByteString -> [Maybe ContentInfo]
decode (PEM -> ByteString
pemContent PEM
pem)
| Bool
otherwise = Maybe ContentInfo
forall a. Maybe a
Nothing Maybe ContentInfo -> [Maybe ContentInfo] -> [Maybe ContentInfo]
forall a. a -> [a] -> [a]
: [Maybe ContentInfo]
acc
where
names :: [String]
names = [ String
"CMS", String
"PKCS7" ]
decode :: ByteString -> [Maybe ContentInfo]
decode ByteString
bs =
case ByteString -> Either StoreError ContentInfo
berToContentInfo ByteString
bs of
Left StoreError
_ -> Maybe ContentInfo
forall a. Maybe a
Nothing Maybe ContentInfo -> [Maybe ContentInfo] -> [Maybe ContentInfo]
forall a. a -> [a] -> [a]
: [Maybe ContentInfo]
acc
Right ContentInfo
info -> ContentInfo -> Maybe ContentInfo
forall a. a -> Maybe a
Just ContentInfo
info Maybe ContentInfo -> [Maybe ContentInfo] -> [Maybe ContentInfo]
forall a. a -> [a] -> [a]
: [Maybe ContentInfo]
acc
writeCMSFile :: FilePath -> [ContentInfo] -> IO ()
writeCMSFile :: String -> [ContentInfo] -> IO ()
writeCMSFile String
path = String -> ByteString -> IO ()
B.writeFile String
path (ByteString -> IO ())
-> ([ContentInfo] -> ByteString) -> [ContentInfo] -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ContentInfo] -> ByteString
writeCMSFileToMemory
writeCMSFileToMemory :: [ContentInfo] -> B.ByteString
writeCMSFileToMemory :: [ContentInfo] -> ByteString
writeCMSFileToMemory = [PEM] -> ByteString
pemsWriteBS ([PEM] -> ByteString)
-> ([ContentInfo] -> [PEM]) -> [ContentInfo] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ContentInfo -> PEM) -> [ContentInfo] -> [PEM]
forall a b. (a -> b) -> [a] -> [b]
map ContentInfo -> PEM
contentInfoToPEM
contentInfoToDER :: ContentInfo -> B.ByteString
contentInfoToDER :: ContentInfo -> ByteString
contentInfoToDER = ContentInfo -> ByteString
forall obj. ProduceASN1Object ASN1P obj => obj -> ByteString
encodeASN1Object
contentInfoToPEM :: ContentInfo -> PEM
contentInfoToPEM :: ContentInfo -> PEM
contentInfoToPEM ContentInfo
info = PEM { pemName :: String
pemName = String
"CMS", pemHeader :: [(String, ByteString)]
pemHeader = [], pemContent :: ByteString
pemContent = ByteString
bs}
where bs :: ByteString
bs = ContentInfo -> ByteString
contentInfoToDER ContentInfo
info