CP.hs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  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. data Algo = Sha3_512Ed25519 deriving (Eq, Ord, Bounded, Enum)
  12. instance Show Algo where
  13. show Sha3_512Ed25519 = "SHA3_512-ED25519"
  14. instance Read.Read Algo where
  15. readsPrec _ str = catMaybes $ map (tryRead str) [minBound..maxBound]
  16. where
  17. tryRead input test = let
  18. txt = show test
  19. firstIn = take (length txt) input
  20. lastIn = drop (length txt) input
  21. in if firstIn == txt then Just (test, lastIn) else Nothing
  22. data SCP = SCPSha3_512Ed25519 ByteString Ed25519.PublicKey
  23. | SAll
  24. revocationHeader :: String
  25. revocationHeader = "CP-Revoked"
  26. publicHeader :: String
  27. publicHeader = "CP-Grant-All"
  28. algoHeader :: String
  29. algoHeader = "CP-Algorithm"
  30. sharedKeyHeader :: String
  31. sharedKeyHeader = "CP-Shared-Key"
  32. idHeader :: String
  33. idHeader = "CP-Id"
  34. sFromHeaders :: Resc.PlainHeaders -> Maybe SCP
  35. sFromHeaders hh = let
  36. shh = Resc.sealed hh
  37. pbc = fromMaybe False $ Resc.getBooleanHeader shh publicHeader
  38. revoked = fromMaybe False $ Resc.getBooleanHeader shh revocationHeader
  39. in
  40. if revoked then Nothing
  41. else
  42. if pbc then Just SAll
  43. else do
  44. algo <- Resc.getReadHeader shh algoHeader
  45. sh' <- Resc.getBase64Header shh sharedKeyHeader
  46. sh <- maybeCryptoError . Ed25519.publicKey $ sh'
  47. cid <- Resc.getBase64Header shh idHeader
  48. case algo of
  49. Sha3_512Ed25519 -> pure $ SCPSha3_512Ed25519 cid sh