mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-14 00:12:06 +01:00
More cleanup and better error reporting
This commit is contained in:
parent
5f0c56f5b3
commit
a85d72f635
5 changed files with 48 additions and 15 deletions
|
@ -6,6 +6,9 @@ package org.pgpainless.decryption_verification.syntax_check;
|
|||
|
||||
import org.pgpainless.exception.MalformedOpenPgpMessageException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This class describes the syntax for OpenPGP messages as specified by rfc4880.
|
||||
*
|
||||
|
@ -19,7 +22,7 @@ import org.pgpainless.exception.MalformedOpenPgpMessageException;
|
|||
public class OpenPgpMessageSyntax implements Syntax {
|
||||
|
||||
@Override
|
||||
public Transition transition(State from, InputSymbol input, StackSymbol stackItem)
|
||||
public @Nonnull Transition transition(@Nonnull State from, @Nonnull InputSymbol input, @Nullable StackSymbol stackItem)
|
||||
throws MalformedOpenPgpMessageException {
|
||||
switch (from) {
|
||||
case OpenPgpMessage:
|
||||
|
@ -37,7 +40,7 @@ public class OpenPgpMessageSyntax implements Syntax {
|
|||
throw new MalformedOpenPgpMessageException(from, input, stackItem);
|
||||
}
|
||||
|
||||
Transition fromOpenPgpMessage(InputSymbol input, StackSymbol stackItem)
|
||||
Transition fromOpenPgpMessage(@Nonnull InputSymbol input, @Nullable StackSymbol stackItem)
|
||||
throws MalformedOpenPgpMessageException {
|
||||
if (stackItem != StackSymbol.msg) {
|
||||
throw new MalformedOpenPgpMessageException(State.OpenPgpMessage, input, stackItem);
|
||||
|
@ -65,7 +68,7 @@ public class OpenPgpMessageSyntax implements Syntax {
|
|||
}
|
||||
}
|
||||
|
||||
Transition fromLiteralMessage(InputSymbol input, StackSymbol stackItem)
|
||||
Transition fromLiteralMessage(@Nonnull InputSymbol input, @Nullable StackSymbol stackItem)
|
||||
throws MalformedOpenPgpMessageException {
|
||||
switch (input) {
|
||||
case Signature:
|
||||
|
@ -84,7 +87,7 @@ public class OpenPgpMessageSyntax implements Syntax {
|
|||
throw new MalformedOpenPgpMessageException(State.LiteralMessage, input, stackItem);
|
||||
}
|
||||
|
||||
Transition fromCompressedMessage(InputSymbol input, StackSymbol stackItem)
|
||||
Transition fromCompressedMessage(@Nonnull InputSymbol input, @Nullable StackSymbol stackItem)
|
||||
throws MalformedOpenPgpMessageException {
|
||||
switch (input) {
|
||||
case Signature:
|
||||
|
@ -103,7 +106,7 @@ public class OpenPgpMessageSyntax implements Syntax {
|
|||
throw new MalformedOpenPgpMessageException(State.CompressedMessage, input, stackItem);
|
||||
}
|
||||
|
||||
Transition fromEncryptedMessage(InputSymbol input, StackSymbol stackItem)
|
||||
Transition fromEncryptedMessage(@Nonnull InputSymbol input, @Nullable StackSymbol stackItem)
|
||||
throws MalformedOpenPgpMessageException {
|
||||
switch (input) {
|
||||
case Signature:
|
||||
|
@ -122,7 +125,7 @@ public class OpenPgpMessageSyntax implements Syntax {
|
|||
throw new MalformedOpenPgpMessageException(State.EncryptedMessage, input, stackItem);
|
||||
}
|
||||
|
||||
Transition fromValid(InputSymbol input, StackSymbol stackItem)
|
||||
Transition fromValid(@Nonnull InputSymbol input, @Nullable StackSymbol stackItem)
|
||||
throws MalformedOpenPgpMessageException {
|
||||
// There is no applicable transition rule out of Valid
|
||||
throw new MalformedOpenPgpMessageException(State.Valid, input, stackItem);
|
||||
|
|
|
@ -20,10 +20,13 @@ public class PDA {
|
|||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(PDA.class);
|
||||
|
||||
// right now we implement what rfc4880 specifies.
|
||||
// TODO: Consider implementing what we proposed here:
|
||||
// https://mailarchive.ietf.org/arch/msg/openpgp/uepOF6XpSegMO4c59tt9e5H1i4g/
|
||||
private final Syntax syntax = new OpenPgpMessageSyntax();
|
||||
private final Stack<StackSymbol> stack = new Stack<>();
|
||||
private final List<InputSymbol> inputs = new ArrayList<>(); // keep track of inputs for debugging / error reporting
|
||||
private final List<InputSymbol> inputs = new ArrayList<>(); // Track inputs for debugging / error reporting
|
||||
private State state;
|
||||
private Syntax syntax = new OpenPgpMessageSyntax();
|
||||
|
||||
public PDA() {
|
||||
state = State.OpenPgpMessage;
|
||||
|
@ -32,16 +35,20 @@ public class PDA {
|
|||
}
|
||||
|
||||
public void next(InputSymbol input) throws MalformedOpenPgpMessageException {
|
||||
StackSymbol stackSymbol = popStack();
|
||||
try {
|
||||
Transition transition = syntax.transition(state, input, popStack());
|
||||
inputs.add(input);
|
||||
Transition transition = syntax.transition(state, input, stackSymbol);
|
||||
state = transition.getNewState();
|
||||
for (StackSymbol item : transition.getPushedItems()) {
|
||||
pushStack(item);
|
||||
}
|
||||
inputs.add(input);
|
||||
} catch (MalformedOpenPgpMessageException e) {
|
||||
MalformedOpenPgpMessageException wrapped = new MalformedOpenPgpMessageException("Malformed message: After reading stream " + Arrays.toString(inputs.toArray()) +
|
||||
", token '" + input + "' is unexpected and illegal.", e);
|
||||
MalformedOpenPgpMessageException wrapped = new MalformedOpenPgpMessageException(
|
||||
"Malformed message: After reading stream " + Arrays.toString(inputs.toArray()) +
|
||||
", token '" + input + "' is not allowed." +
|
||||
"\nNo transition from state '" + state + "' with stack " + Arrays.toString(stack.toArray()) +
|
||||
(stackSymbol != null ? "||'" + stackSymbol + "'." : "."), e);
|
||||
LOGGER.debug("Invalid input '" + input + "'", wrapped);
|
||||
throw wrapped;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ package org.pgpainless.decryption_verification.syntax_check;
|
|||
|
||||
import org.pgpainless.exception.MalformedOpenPgpMessageException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This interface can be used to define a custom syntax for the {@link PDA}.
|
||||
*/
|
||||
|
@ -25,6 +28,6 @@ public interface Syntax {
|
|||
* @return applicable transition rule containing the new state and pushed stack symbols
|
||||
* @throws MalformedOpenPgpMessageException if there is no applicable transition rule (the input symbol is illegal)
|
||||
*/
|
||||
Transition transition(State from, InputSymbol input, StackSymbol stackItem)
|
||||
@Nonnull Transition transition(@Nonnull State from, @Nonnull InputSymbol input, @Nullable StackSymbol stackItem)
|
||||
throws MalformedOpenPgpMessageException;
|
||||
}
|
||||
|
|
|
@ -4,24 +4,44 @@
|
|||
|
||||
package org.pgpainless.decryption_verification.syntax_check;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Result of applying a transition rule.
|
||||
* Transition rules can be described by implementing the {@link Syntax} interface.
|
||||
*/
|
||||
public class Transition {
|
||||
|
||||
private final List<StackSymbol> pushedItems = new ArrayList<>();
|
||||
private final State newState;
|
||||
|
||||
public Transition(State newState, StackSymbol... pushedItems) {
|
||||
public Transition(@Nonnull State newState, @Nonnull StackSymbol... pushedItems) {
|
||||
this.newState = newState;
|
||||
this.pushedItems.addAll(Arrays.asList(pushedItems));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the new {@link State} that is reached by applying the transition.
|
||||
*
|
||||
* @return new state
|
||||
*/
|
||||
@Nonnull
|
||||
public State getNewState() {
|
||||
return newState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of {@link StackSymbol StackSymbols} that are pushed onto the stack
|
||||
* by applying the transition.
|
||||
* The list contains items in the order in which they are pushed onto the stack.
|
||||
* The list may be empty.
|
||||
*
|
||||
* @return list of items to be pushed onto the stack
|
||||
*/
|
||||
@Nonnull
|
||||
public List<StackSymbol> getPushedItems() {
|
||||
return new ArrayList<>(pushedItems);
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ public class PDATest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testEncryptedMessageWithAppendedStandalongSigIsNotValid() {
|
||||
public void testEncryptedMessageWithAppendedStandaloneSigIsNotValid() {
|
||||
PDA check = new PDA();
|
||||
check.next(InputSymbol.EncryptedData);
|
||||
assertThrows(MalformedOpenPgpMessageException.class,
|
||||
|
|
Loading…
Reference in a new issue