mitigate timing attack to determine if queue exists (#117)

* mitigate timing attack to determine if queue exists

* remove timing for authenticated SEND command

Co-authored-by: Efim Poberezkin <8711996+efim-poberezkin@users.noreply.github.com>
This commit is contained in:
Evgeny Poberezkin
2021-05-01 22:07:25 +01:00
committed by GitHub
parent 829c198e5f
commit 633b3a4bda
4 changed files with 43 additions and 15 deletions
+1 -1
View File
@@ -251,7 +251,7 @@ tGet fromParty th = liftIO (tGetParse th) >>= decodeParseValidate
Cmd SBroker _
| B.null queueId -> Left $ CMD NO_QUEUE
| otherwise -> Right cmd
-- NEW must NOT have signature or queue ID
-- NEW must have signature but NOT queue ID
Cmd SRecipient (NEW _)
| B.null signature -> Left $ CMD NO_AUTH
| not (B.null queueId) -> Left $ CMD HAS_AUTH
+14 -12
View File
@@ -108,25 +108,27 @@ verifyTransmission (sig, t@(corrId, queueId, cmd)) = do
(corrId,queueId,) <$> case cmd of
Cmd SBroker _ -> return $ smpErr INTERNAL -- it can only be client command, because `fromClient` was used
Cmd SRecipient (NEW k) -> return $ verifySignature k
Cmd SRecipient _ -> withQueueRec SRecipient $ verifySignature . recipientKey
Cmd SSender (SEND _) -> withQueueRec SSender $ verifySend sig . senderKey
Cmd SRecipient _ -> verifyCmd SRecipient $ verifySignature . recipientKey
Cmd SSender (SEND _) -> verifyCmd SSender $ verifySend sig . senderKey
Cmd SSender PING -> return cmd
where
withQueueRec :: SParty (p :: Party) -> (QueueRec -> Cmd) -> m Cmd
withQueueRec party f = do
verifyCmd :: SParty p -> (QueueRec -> Cmd) -> m Cmd
verifyCmd party f = do
(aKey, _) <- asks serverKeyPair -- any public key can be used to mitigate timing attack
st <- asks queueStore
qr <- atomically $ getQueue st party queueId
return $ either smpErr f qr
q <- atomically $ getQueue st party queueId
pure $ either (const $ fakeVerify aKey) f q
fakeVerify :: C.PublicKey -> Cmd
fakeVerify aKey = if verify aKey then authErr else authErr
verifySend :: C.Signature -> Maybe SenderPublicKey -> Cmd
verifySend "" = maybe cmd (const authErr)
verifySend _ = maybe authErr verifySignature
verifySignature :: C.PublicKey -> Cmd
verifySignature key =
if C.verify key sig (serializeTransmission t)
then cmd
else authErr
smpErr e = Cmd SBroker $ ERR e
verifySignature key = if verify key then cmd else authErr
verify :: C.PublicKey -> Bool
verify key = C.verify key sig (serializeTransmission t)
smpErr :: ErrorType -> Cmd
smpErr = Cmd SBroker . ERR
authErr = smpErr AUTH
client :: forall m. (MonadUnliftIO m, MonadReader Env m) => Client -> Server -> m ()