{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
module Network.AWS.CloudFront.SignedCookies.Crypto
(
readPrivateKeyPemFile
, sign
, PrivateKey
, ByteString
) where
import Network.AWS.CloudFront.SignedCookies.Crypto.Internal
import Network.AWS.CloudFront.SignedCookies.Types
import Data.ASN1.BinaryEncoding (DER (DER))
import Data.ASN1.Encoding (decodeASN1')
import Data.ASN1.Error (ASN1Error)
import Data.ASN1.Types (ASN1)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import Crypto.PubKey.RSA (PrivateKey)
import qualified Crypto.PubKey.RSA.PKCS15 as RSA
import Crypto.Hash.Algorithms (SHA1 (SHA1))
import qualified Data.PEM as PEM
import qualified Data.Text as Text
sign
:: PrivateKey
-> ByteString
-> IO ByteString
sign key bs =
RSA.signSafer (Just SHA1) key bs >>= either (fail . show) pure
readPrivateKeyPemFile
:: PemFilePath
-> IO PrivateKey
readPrivateKeyPemFile (PemFilePath path) = do
lbs <- BS.readFile (Text.unpack path)
pemSections <- either fail pure (PEM.pemParseBS lbs)
pemBs <- PEM.pemContent <$> case pemSections of
[x] -> pure x
xs ->
let msg = "Expected exactly 1 PEM section but found " ++
show @Int (length xs)
in fail msg
asn1s :: [ASN1] <- either (fail . show) pure (decodeASN1' DER pemBs)
either fail pure (rsaPrivateKeyFromASN1 asn1s)