Skip to content
Snippets Groups Projects
Unverified Commit f2661507 authored by Jean-Paul Calderone's avatar Jean-Paul Calderone
Browse files

Put bounds checking on redeemCounter

parent f0867b77
No related branches found
No related tags found
1 merge request!53Accept counter in redemption request
...@@ -73,6 +73,8 @@ data Result ...@@ -73,6 +73,8 @@ data Result
= Unpaid -- ^ A voucher has not been paid for. = Unpaid -- ^ A voucher has not been paid for.
| DoubleSpend -- ^ A voucher has already been redeemed. | DoubleSpend -- ^ A voucher has already been redeemed.
| OtherFailure Text -- ^ Some other unrecognized failure mode. | OtherFailure Text -- ^ Some other unrecognized failure mode.
-- | Given counter was not in the expected range
| CounterOutOfBounds Integer Integer Integer
| Succeeded PublicKey [Signature] Proof | Succeeded PublicKey [Signature] Proof
deriving (Show, Eq) deriving (Show, Eq)
...@@ -104,6 +106,13 @@ instance ToJSON Result where ...@@ -104,6 +106,13 @@ instance ToJSON Result where
[ "success" .= False [ "success" .= False
, "reason" .= ("double-spend" :: Text) , "reason" .= ("double-spend" :: Text)
] ]
toJSON (CounterOutOfBounds min max received) = object
[ "success" .= False
, "reason" .= ("counter-out-of-bounds" :: Text)
, "min" .= min
, "max" .= max
, "received" .= received
]
toJSON (OtherFailure description) = object toJSON (OtherFailure description) = object
[ "success" .= False [ "success" .= False
, "reason" .= description , "reason" .= description
...@@ -131,6 +140,11 @@ instance FromJSON Result where ...@@ -131,6 +140,11 @@ instance FromJSON Result where
then return DoubleSpend then return DoubleSpend
else return $ OtherFailure reason else return $ OtherFailure reason
-- | Limit the value for the counter value supplied during a voucher
-- redemption attempt. A counter in the range [0..maxCounter) is allowed.
maxCounter :: Integer
maxCounter = 16
type RedemptionAPI = ReqBody '[JSON] Redeem :> Post '[JSON] Result type RedemptionAPI = ReqBody '[JSON] Redeem :> Post '[JSON] Result
jsonErr400 reason = err400 jsonErr400 reason = err400
...@@ -145,21 +159,24 @@ redemptionServer = redeem ...@@ -145,21 +159,24 @@ redemptionServer = redeem
-- voucher and return signatures. Return a failure if this is not possible -- voucher and return signatures. Return a failure if this is not possible
-- (eg because the voucher was already redeemed). -- (eg because the voucher was already redeemed).
redeem :: VoucherDatabase d => Issuer -> d -> Redeem -> Handler Result redeem :: VoucherDatabase d => Issuer -> d -> Redeem -> Handler Result
redeem issue database (Redeem voucher tokens) = do redeem issue database (Redeem voucher tokens counter) =
let fingerprint = fingerprintFromTokens tokens if counter < 0 || counter >= maxCounter then
result <- liftIO $ PaymentServer.Persistence.redeemVoucher database voucher fingerprint throwError $ jsonErr400 (CounterOutOfBounds 0 maxCounter counter)
case result of else do
Left NotPaid -> do let fingerprint = fingerprintFromTokens tokens
throwError $ jsonErr400 Unpaid result <- liftIO $ PaymentServer.Persistence.redeemVoucher database voucher fingerprint
Left AlreadyRedeemed -> do case result of
throwError $ jsonErr400 DoubleSpend Left NotPaid -> do
Right () -> do throwError $ jsonErr400 Unpaid
let result = issue tokens Left AlreadyRedeemed -> do
case result of throwError $ jsonErr400 DoubleSpend
Left reason -> do Right () -> do
throwError $ jsonErr400 $ OtherFailure reason let result = issue tokens
Right (ChallengeBypass key signatures proof) -> case result of
return $ Succeeded key signatures proof Left reason -> do
throwError $ jsonErr400 $ OtherFailure reason
Right (ChallengeBypass key signatures proof) ->
return $ Succeeded key signatures proof
-- | Compute a cryptographic hash (fingerprint) of a list of tokens which can -- | Compute a cryptographic hash (fingerprint) of a list of tokens which can
-- be used as an identifier for this exact sequence of tokens. -- be used as an identifier for this exact sequence of tokens.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment