better error handling in ASN.1 message parser

This commit is contained in:
Trolli Schmittlauch 2020-05-08 11:23:36 +02:00
parent 6dc9650da5
commit 28254a9f83

View file

@ -284,12 +284,17 @@ encodeMessage
parseMessage :: ParseASN1 FediChordMessage
parseMessage = do
begin <- getNext
case begin of
Start Sequence -> return ()
x -> throwParseError $ "unexpected ASN.1 element " ++ show x
-- request and response messages are distiguishable by their structure,
-- see ASN.1 schema
first <- getNext
case first of
Enumerated a -> parseRequest . toEnum . fromIntegral $ a
IntVal i -> parseResponse i
other -> throwParseError $ "unexpected first ASN1 element: " ++ show other
parseRequest :: Action -> ParseASN1 FediChordMessage
parseRequest action = do
@ -304,6 +309,11 @@ parseRequest action = do
Leave -> parseLeaveRequest
Stabilise -> parseStabiliseRequest
Ping -> parsePingRequest
-- consume sequence end
end <- getNext
case end of
End Sequence -> return ()
x -> throwParseError $ "unexpected ASN.1 element " ++ show x
return $ Request requestID sender parts part action payload
@ -320,35 +330,48 @@ parseResponse responseTo = do
Leave -> parseLeaveResponse
Stabilise -> parseStabiliseResponse
Ping -> parsePingResponse
-- consume sequence end
end <- getNext
case end of
End Sequence -> return ()
x -> throwParseError $ "unexpected ASN.1 element " ++ show x
return $ Response responseTo senderID parts part action payload
parseInteger :: ParseASN1 Integer
parseInteger = do
IntVal parsed <- getNext
return parsed
i <- getNext
case i of
IntVal parsed -> return parsed
x -> throwParseError $ "Expected IntVal but got " ++ show x
parseEnum :: Enum a => ParseASN1 a
parseEnum = do
Enumerated en <- getNext
return $ toEnum . fromIntegral $ en
e <- getNext
case e of
Enumerated en -> return $ toEnum . fromIntegral $ en
x -> throwParseError $ "Expected Enumerated but got " ++ show x
parseString :: ParseASN1 String
parseString = do
ASN1String toBeParsed <- getNext
maybe (throwParseError "string parsing failed") return $ asn1CharacterToString toBeParsed
s <- getNext
case s of
ASN1String toBeParsed -> maybe (throwParseError "string parsing failed") return $ asn1CharacterToString toBeParsed
x -> throwParseError $ "Expected a ASN1String but got " ++ show x
parseOctets :: ParseASN1 BS.ByteString
parseOctets = do
OctetString bs <- getNext
return bs
os <- getNext
case os of
OctetString bs -> return bs
x -> throwParseError $ "Expected an OctetString but got " ++ show x
parseNull :: ParseASN1 ()
parseNull = do
-- ToDo: figure out how this fails on wrong inputs,
-- maybe a case distinction + throwParseError is better?
Null <- getNext
return ()
n <- getNext
case n of
Null -> return ()
x -> throwParseError $ "Expected Null but got " ++ show x
parseNodeState :: ParseASN1 NodeState
parseNodeState = do