Project

General

Profile

HaskellMaybeChecks » History » Version 1

Grigoriy Volkov, 01/22/2019 04:11 PM

1 1 Grigoriy Volkov
Using Maybe Monad for checks
2
3
<pre>
4
{-# LANGUAGE LambdaCase, RecordWildCards #-}
5
6
import Data.Maybe (isJust, mapMaybe)
7
import Data.List (nub)
8
9
data Group = X25519 | Secp384
10
           deriving (Eq)
11
12
data KeyShareData = KeyShareClientHello [Group]
13
                  | KeyShareHelloRetryRequest Group
14
15
data Ext = SupportedGroups [Group]
16
         | KeyShares KeyShareData
17
18
check :: [Ext] -> [Ext] -> Bool
19
check eCH eHRR = isJust $ do
20
  sgCH <- exactlyOne $ mapMaybe (\case SupportedGroups gs -> Just gs; _ -> Nothing) eCH
21
  continueIf $ nub sgCH == sgCH -- no duplicates allowed
22
  ksCH <- (\case KeyShareClientHello gs -> Just gs; _ -> Nothing) =<<
23
    exactlyOne (mapMaybe (\case KeyShares ks -> Just ks; _ -> Nothing) eCH)
24
  ksHRR <- (\case KeyShareHelloRetryRequest g -> Just g; _ -> Nothing) =<<
25
    exactlyOne (mapMaybe (\case KeyShares ks -> Just ks; _ -> Nothing) eHRR)
26
  continueIf $ nub ksCH == ksCH -- no duplicates allowed
27
  continueIf $ ksHRR `elem` sgCH -- group must be supported
28
  continueIf $ ksHRR `notElem` ksCH -- key share must not have been already sent
29
30
exactlyOne :: [a] -> Maybe a
31
exactlyOne [x] = Just x
32
exactlyOne _ = Nothing
33
34
continueIf :: Bool -> Maybe ()
35
continueIf True = Just ()
36
continueIf False = Nothing
37
</pre>