module Dropbox.Certificates.TH
( pem
, pemFile
, x509
, x509File
) where
import Data.ByteString.Char8 (pack)
import Data.ByteString.Lazy (fromChunks)
import Data.PEM (PEM(..), pemParseBS)
import Data.Certificate.X509 (X509(..), decodeCertificate)
import Language.Haskell.TH.Quote
rightsOrFirstLeft :: [Either a b] -> Either a [b]
rightsOrFirstLeft = foldr f (Right [])
where
f (Left e) _ = Left e
f _ (Left e) = Left e
f (Right v) (Right vs) = Right (v:vs)
pem :: QuasiQuoter
pem = QuasiQuoter { quoteExp = \s -> [| parsePem s |] }
pemFile :: QuasiQuoter
pemFile = quoteFile pem
parsePem :: String -> [PEM]
parsePem s = case pemParseBS $ pack s of
Left err -> error $ "Failed to parse PEM file: " ++ err
Right x -> x
x509 :: QuasiQuoter
x509 = QuasiQuoter { quoteExp = \s -> [| decodeCert . parsePem $ s |] }
x509File :: QuasiQuoter
x509File = quoteFile x509
decodeCert :: [PEM] -> [X509]
decodeCert pems =
let es = [decodeCertificate (fromChunks [stuff]) | PEM _ _ stuff <- pems]
in case rightsOrFirstLeft es of
Left err -> error $ "Failed to decode X509 file: " ++ err
Right x509s -> x509s