83 lines
2.8 KiB
Plaintext
83 lines
2.8 KiB
Plaintext
module App.DKIM where
|
|
|
|
import Data.Maybe (Maybe(..))
|
|
|
|
import Data.Codec.Argonaut (JsonCodec)
|
|
import Data.Codec.Argonaut as CA
|
|
import Data.Codec.Argonaut.Record as CAR
|
|
|
|
type PublicKey = String
|
|
|
|
type DKIM
|
|
= { v :: Maybe Version -- v= "DKIM1", entirely optional (for now, even ignored).
|
|
, k :: Maybe SignatureAlgorithm -- k= Key type (optional, default is "rsa").
|
|
, h :: Maybe HashingAlgorithm -- h= hash algorigthm (optional, "sha1" or "sha256" from RFC6376)
|
|
, p :: PublicKey -- p= Public-key data (base64; REQUIRED).
|
|
-- The syntax and semantics of this tag value before being
|
|
-- encoded in base64 are defined by the "k=" tag.
|
|
, n :: Maybe String -- n= Notes that might be of interest to a human (optional)
|
|
}
|
|
|
|
codec :: JsonCodec DKIM
|
|
codec = CA.object "DKIM"
|
|
(CAR.record
|
|
{ v: CAR.optional codecVersion
|
|
, k: CAR.optional codecSignatureAlgorithm
|
|
, h: CAR.optional codecHashingAlgorithm
|
|
, p: CA.string
|
|
, n: CAR.optional CA.string
|
|
})
|
|
|
|
-- RFC6376 section 3.6.2.1
|
|
-- All DKIM keys are stored in a subdomain named "_domainkey". Given a
|
|
-- DKIM-Signature field with a "d=" tag of "example.com" and an "s=" tag
|
|
-- of "foo.bar", the DNS query will be for
|
|
-- "foo.bar._domainkey.example.com".
|
|
|
|
data HashingAlgorithm = SHA1 | SHA256
|
|
|
|
-- | Codec for just encoding a single value of type `HashingAlgorithm`.
|
|
codecHashingAlgorithm :: CA.JsonCodec HashingAlgorithm
|
|
codecHashingAlgorithm = CA.prismaticCodec "HashingAlgorithm" str_to_hashing_algorithm show_hashing_algorithm CA.string
|
|
|
|
str_to_hashing_algorithm :: String -> Maybe HashingAlgorithm
|
|
str_to_hashing_algorithm = case _ of
|
|
"sha1" -> Just SHA1
|
|
"sha256" -> Just SHA256
|
|
_ -> Nothing
|
|
|
|
show_hashing_algorithm :: HashingAlgorithm -> String
|
|
show_hashing_algorithm = case _ of
|
|
SHA1 -> "sha1"
|
|
SHA256 -> "sha256"
|
|
|
|
data SignatureAlgorithm = RSA
|
|
|
|
-- | Codec for just encoding a single value of type `SignatureAlgorithm`.
|
|
codecSignatureAlgorithm :: CA.JsonCodec SignatureAlgorithm
|
|
codecSignatureAlgorithm = CA.prismaticCodec "SignatureAlgorithm" str_to_signature_algorithm show_signature_algorithm CA.string
|
|
|
|
str_to_signature_algorithm :: String -> Maybe SignatureAlgorithm
|
|
str_to_signature_algorithm = case _ of
|
|
"rsa" -> Just RSA
|
|
_ -> Nothing
|
|
|
|
show_signature_algorithm :: SignatureAlgorithm -> String
|
|
show_signature_algorithm = case _ of
|
|
RSA -> "rsa"
|
|
|
|
data Version = DKIM1
|
|
|
|
-- | Codec for just encoding a single value of type `Version`.
|
|
codecVersion :: CA.JsonCodec Version
|
|
codecVersion = CA.prismaticCodec "Version" str_to_version show_version CA.string
|
|
|
|
str_to_version :: String -> Maybe Version
|
|
str_to_version = case _ of
|
|
"dkim1" -> Just DKIM1
|
|
_ -> Nothing
|
|
|
|
show_version :: Version -> String
|
|
show_version = case _ of
|
|
DKIM1 -> "dkim1"
|