CP.hs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. {- |
  2. fCMTP capabilities.
  3. -}
  4. module Data.SMTP.Crypto.Types.CP where
  5. import Data.ByteString (ByteString)
  6. import qualified Crypto.PubKey.Ed25519 as Ed25519
  7. import qualified Data.SMTP.Resource as Resc
  8. import Crypto.Error (maybeCryptoError)
  9. import Data.Maybe
  10. import qualified Text.Read as Read
  11. -- | Capability algorithms
  12. data Algo = Sha3_512Ed25519 deriving (Eq, Ord, Bounded, Enum)
  13. instance Show Algo where
  14. show Sha3_512Ed25519 = "SHA3_512-ED25519"
  15. instance Read.Read Algo where
  16. readsPrec _ str = catMaybes $ map (tryRead str) [minBound..maxBound]
  17. where
  18. tryRead input test = let
  19. txt = show test
  20. firstIn = take (length txt) input
  21. lastIn = drop (length txt) input
  22. in if firstIn == txt then Just (test, lastIn) else Nothing
  23. -- | Public capabilities data
  24. data PCP = PCPSha3_512Ed25519 ByteString Ed25519.PublicKey
  25. | PAll deriving (Show)
  26. -- | The fCMTP CP revocation header: "CP-Revoked"
  27. revocationHeader :: String
  28. revocationHeader = "CP-Revoked"
  29. -- | The fCMTP header for public access: "CP-Grant-All"
  30. publicHeader :: String
  31. publicHeader = "CP-Grant-All"
  32. -- | The fCMTP CP algorithm header: "CP-Algorithm"
  33. algoHeader :: String
  34. algoHeader = "CP-Algorithm"
  35. -- | The fCMTP CP shared key header: "CP-Shared-Key"
  36. sharedKeyHeader :: String
  37. sharedKeyHeader = "CP-Shared-Key"
  38. -- | The fMCTP CP id header: "CP-Id"
  39. idHeader :: String
  40. idHeader = "CP-Id"
  41. sFromHeaders :: Resc.PlainHeaders -> Maybe PCP
  42. sFromHeaders hh = let
  43. shh = Resc.sealed hh
  44. pbc = fromMaybe False $ Resc.getBooleanHeader shh publicHeader
  45. revoked = fromMaybe False $ Resc.getBooleanHeader shh revocationHeader
  46. in
  47. if revoked then Nothing
  48. else
  49. if pbc then Just PAll
  50. else do
  51. algo <- Resc.getReadHeader shh algoHeader
  52. sh' <- Resc.getBase64urlHeader shh sharedKeyHeader
  53. sh <- maybeCryptoError . Ed25519.publicKey $ sh'
  54. cid <- Resc.getBase64urlHeader shh idHeader
  55. case algo of
  56. Sha3_512Ed25519 -> pure $ PCPSha3_512Ed25519 cid sh