{-# LANGUAGE DeriveGeneric, FlexibleInstances #-} {- | Main types for debug-me - - Note that changing types in ways that change the JSON serialization - changes debug-me's wire format. -} module Types ( module Types, Val(..) ) where import Val import Memory import Json -- | Things that the developer sees. data Seen = Seen { seenData :: Val } deriving (Show, Generic) instance DataSize Seen where dataSize = dataSize . seenData -- | Things that the developer enters. data Entered = Entered { enteredData :: Val , echoData :: Val -- ^ Data that is expected to be Seen, but has not been received -- at the time this was entered. } deriving (Show, Generic) instance DataSize Entered where dataSize e = dataSize (enteredData e) + dataSize (echoData e) -- | A message in the protocol. data Message a = ActivityMessage (Activity a) | ControlMessage Control deriving (Show, Generic) instance DataSize a => DataSize (Message a) where dataSize (ActivityMessage a) = dataSize a dataSize (ControlMessage c) = dataSize c -- | An activity (either Entered or Seen) with a pointer -- to a previous Activity. -- -- The Signature is over both the data in the activity, and its pointer. data Activity a = Activity { activity :: a , prevActivity :: Maybe Hash , activitySignature :: Signature } deriving (Show, Generic) instance DataSize a => DataSize (Activity a) where dataSize a = dataSize (activity a) + maybe 0 dataSize (prevActivity a) + dataSize (activitySignature a) -- | A control message, which can be sent asynchronously. data Control = Control { control :: ControlAction , controlSignature :: Signature } deriving (Show, Generic) instance DataSize Control where dataSize c = dataSize (control c) + dataSize (controlSignature c) data ControlAction = Rejected (Activity Entered) -- ^ sent by user to indicate when an Entered value was rejected. | SessionKey PublicKey -- ^ sent by user at start, and later by developer, -- to indicate their session key | SessionKeyAccepted PublicKey -- ^ sent by the user to in response to SessionKey | SessionKeyRejected PublicKey -- ^ sent by the user to in response to SessionKey deriving (Show, Generic) instance DataSize ControlAction where dataSize (Rejected a) = dataSize a dataSize (SessionKey k) = dataSize k dataSize (SessionKeyAccepted k) = dataSize k dataSize (SessionKeyRejected k) = dataSize k data Hash = Hash { hashMethod :: HashMethod , hashValue :: Val } deriving (Show, Generic, Eq) instance DataSize Hash where dataSize (Hash { hashMethod = SHA256 }) = 64 dataSize (Hash { hashMethod = SHA3 }) = 56 -- | We use SHA256. (SHA3 is included to future proof, and because it -- improves the generated JSON.) data HashMethod = SHA256 | SHA3 deriving (Show, Generic, Eq) data Signature = Ed25519Signature Val | OtherSignature Val -- ^ Not used, but included to future-proof the JSON format. deriving (Show, Generic) instance DataSize Signature where dataSize (Ed25519Signature v) = dataSize v dataSize (OtherSignature v) = dataSize v -- | A public key used for a debug-me session. -- It may be signed with a gpg key. data PublicKey = PublicKey Val (Maybe GpgSig) deriving (Show, Generic) instance DataSize PublicKey where -- ed25519 public keys are 32 bytes dataSize (PublicKey _ ms) = 32 + maybe 0 dataSize ms -- | A signature made with a gpg key. newtype GpgSig = GpgSig Val deriving (Show, Generic) instance DataSize GpgSig where dataSize (GpgSig s) = dataSize s instance ToJSON Seen instance FromJSON Seen instance ToJSON Entered instance FromJSON Entered instance ToJSON (Activity Seen) instance FromJSON (Activity Seen) instance ToJSON (Activity Entered) instance FromJSON (Activity Entered) instance ToJSON Control instance FromJSON Control instance ToJSON Hash instance FromJSON Hash instance ToJSON HashMethod instance FromJSON HashMethod instance ToJSON PublicKey instance FromJSON PublicKey instance ToJSON GpgSig instance FromJSON GpgSig instance ToJSON (Message Seen) where toJSON = genericToJSON sumOptions toEncoding = genericToEncoding sumOptions instance FromJSON (Message Seen) where parseJSON = genericParseJSON sumOptions instance ToJSON (Message Entered) where toJSON = genericToJSON sumOptions toEncoding = genericToEncoding sumOptions instance FromJSON (Message Entered) where parseJSON = genericParseJSON sumOptions instance ToJSON Signature where toJSON = genericToJSON sumOptions toEncoding = genericToEncoding sumOptions instance FromJSON Signature where parseJSON = genericParseJSON sumOptions instance ToJSON ControlAction where toJSON = genericToJSON sumOptions toEncoding = genericToEncoding sumOptions instance FromJSON ControlAction where parseJSON = genericParseJSON sumOptions