\ timestamp, got " ++ show ts_bad)
(ts_bad ==? BasicTypes.Bad "Too old/too new timestamp or clock skew")
+-- | Tests that a ConfdReply can be properly encoded, signed and parsed using
+-- the proper salt, but fails parsing with the wrong salt.
+prop_rep_salt :: Hash.HashKey -- ^ The hash key
+ -> Confd.ConfdReply -- ^ A Confd reply
+ -> Property
+prop_rep_salt hmac reply =
+ forAll arbitrary $ \salt1 ->
+ forAll (arbitrary `suchThat` (/= salt1)) $ \salt2 ->
+ let innerMsg = J.encode reply
+ msg = J.encode $ Confd.Utils.signMessage hmac salt1 innerMsg
+ in
+ Confd.Utils.parseReply hmac msg salt1 ==? BasicTypes.Ok (innerMsg, reply)
+ .&&. Confd.Utils.parseReply hmac msg salt2 ==?
+ BasicTypes.Bad "The received salt differs from the expected salt"
+
-- | Tests that signing with a different key fails detects failure
-- correctly.
prop_bad_key :: String -- ^ Salt
testSuite "Confd/Utils"
[ 'prop_req_sign
+ , 'prop_rep_salt
, 'prop_bad_key
]
( getClusterHmac
, parseSignedMessage
, parseRequest
+ , parseReply
, signMessage
, getCurrentTime
) where
else Bad "HMAC verification failed"
return (salt, msg, parsedMsg)
--- | Message parsing. This can either result in a good, valid message,
--- or fail in the Result monad.
+-- | Message parsing. This can either result in a good, valid request
+-- message, or fail in the Result monad.
parseRequest :: HashKey -> String -> Integer
-> Result (String, ConfdRequest)
parseRequest hmac msg curtime = do
then fail "Too old/too new timestamp or clock skew"
else return (origmsg, request)
+-- | Message parsing. This can either result in a good, valid reply
+-- message, or fail in the Result monad.
+-- It also checks that the salt in the message corresponds to the one
+-- that is expected
+parseReply :: HashKey -> String -> String -> Result (String, ConfdReply)
+parseReply hmac msg expSalt = do
+ (salt, origmsg, reply) <- parseSignedMessage hmac msg
+ if salt /= expSalt
+ then fail "The received salt differs from the expected salt"
+ else return (origmsg, reply)
+
-- | Signs a message with a given key and salt.
signMessage :: HashKey -> String -> String -> SignedMessage
signMessage key salt msg =