/** * TLS-Attacker - A Modular Penetration Testing Framework for TLS * * Copyright 2014-2016 Ruhr University Bochum / Hackmanit GmbH * * Licensed under Apache License 2.0 * http://www.apache.org/licenses/LICENSE-2.0 */ package de.rub.nds.tlsattacker.tls.protocol; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import de.rub.nds.tlsattacker.tls.exceptions.ConfigurationException; import de.rub.nds.tlsattacker.tls.workflow.TlsContext; /** * @author Juraj Somorovsky <juraj.somorovsky@rub.de> * @param <Message> */ public abstract class ProtocolMessageHandler<Message extends ProtocolMessage> { /** * tls context */ protected final TlsContext tlsContext; /** * handled protocol message */ protected Message protocolMessage; /** * type of the protocol message class */ protected Class<? extends Message> correctProtocolMessageClass; /** * * @param tlsContext */ public ProtocolMessageHandler(TlsContext tlsContext) { // ProtocolController protocolController = // ProtocolController.getInstance(); this.tlsContext = tlsContext; if (tlsContext == null) { throw new ConfigurationException("TLS Context is not configured yet"); } } /** * Prepare message for sending. This method invokes before and after method * hooks. * * @return message in bytes */ public byte[] prepareMessage() { beforePrepareMessageAction(); byte[] ret = prepareMessageAction(); ret = afterPrepareMessageAction(ret); return ret; } /** * Parse incoming message bytes and return a pointer to the last processed * byte + 1. This pointer is then used by further protocol message handler. * This method invokes before and after method hooks. * * @param message * @param pointer * @return pointer to the next protocol message in the byte array, if any * message following, i.e. lastProcessedBytePointer + 1 */ public int parseMessage(byte[] message, int pointer) { byte[] hookedMessage; hookedMessage = beforeParseMessageAction(message, pointer); int ret = parseMessageAction(hookedMessage, pointer); ret = afterParseMessageAction(ret); return ret; } /** * Prepare message for sending * * @return message in bytes */ protected abstract byte[] prepareMessageAction(); /** * Parse incoming message bytes and return a pointer to the last processed * byte. This pointer is then used by further protocol message handler. * * @param message * @param pointer * @return */ protected abstract int parseMessageAction(byte[] message, int pointer); /** * Implementation hook, which allows the handlers to invoke specific methods * before the prepareMessageAction is executed */ protected void beforePrepareMessageAction() { } /** * Implementation hook, which allows the handlers to invoke specific methods * after the prepareMessageAction is executed */ protected byte[] afterPrepareMessageAction(byte[] ret) { return ret; } /** * Implementation hook, which allows the handlers to invoke specific methods * before the parseMessageAction is executed * * @param message * @param pointer * @return */ protected byte[] beforeParseMessageAction(byte[] message, int pointer) { return message; } /** * Implementation hook, which allows the handlers to invoke specific methods * after the parseMessageAction is executed * * @param ret * @return */ protected int afterParseMessageAction(int ret) { return ret; } /** * Checks the protocol message * * @param protocolMessage * @return */ public boolean isCorrectProtocolMessage(ProtocolMessage protocolMessage) { if (protocolMessage == null) { return false; } else { return protocolMessage.getClass().equals(correctProtocolMessageClass); } } /** * This method is used to initialize new protocol message in a case we are * handling a dynamic message exchange or an unexpected message is received * and we have to initialize it. */ public void initializeProtocolMessage() { try { Constructor<? extends Message> c = correctProtocolMessageClass.getConstructor(); Message pm = c.newInstance(); this.protocolMessage = pm; } catch (SecurityException | IllegalAccessException | IllegalArgumentException | InstantiationException | InvocationTargetException | NoSuchMethodException ex) { throw new ConfigurationException(ex.getLocalizedMessage(), ex); } } /** * @return newly initialized protocol message used by this handler */ public Message getProtocolMessage() { return this.protocolMessage; } /** * @param protocolMessage */ @SuppressWarnings("unchecked") public void setProtocolMessage(ProtocolMessage protocolMessage) { this.protocolMessage = (Message) protocolMessage; } }