/**
* 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.modifiablevariable;
import de.rub.nds.tlsattacker.modifiablevariable.biginteger.BigIntegerAddModification;
import de.rub.nds.tlsattacker.modifiablevariable.biginteger.BigIntegerExplicitValueModification;
import de.rub.nds.tlsattacker.modifiablevariable.biginteger.BigIntegerShiftLeftModification;
import de.rub.nds.tlsattacker.modifiablevariable.biginteger.BigIntegerShiftRightModification;
import de.rub.nds.tlsattacker.modifiablevariable.biginteger.BigIntegerSubtractModification;
import de.rub.nds.tlsattacker.modifiablevariable.biginteger.BigIntegerXorModification;
import de.rub.nds.tlsattacker.modifiablevariable.bytearray.ByteArrayDeleteModification;
import de.rub.nds.tlsattacker.modifiablevariable.bytearray.ByteArrayDuplicateModification;
import de.rub.nds.tlsattacker.modifiablevariable.bytearray.ByteArrayExplicitValueModification;
import de.rub.nds.tlsattacker.modifiablevariable.bytearray.ByteArrayInsertModification;
import de.rub.nds.tlsattacker.modifiablevariable.bytearray.ByteArrayShuffleModification;
import de.rub.nds.tlsattacker.modifiablevariable.bytearray.ByteArrayXorModification;
import de.rub.nds.tlsattacker.modifiablevariable.filter.AccessModificationFilter;
import de.rub.nds.tlsattacker.modifiablevariable.integer.IntegerAddModification;
import de.rub.nds.tlsattacker.modifiablevariable.integer.IntegerExplicitValueModification;
import de.rub.nds.tlsattacker.modifiablevariable.integer.IntegerShiftLeftModification;
import de.rub.nds.tlsattacker.modifiablevariable.integer.IntegerShiftRightModification;
import de.rub.nds.tlsattacker.modifiablevariable.integer.IntegerSubtractModification;
import de.rub.nds.tlsattacker.modifiablevariable.integer.IntegerXorModification;
import de.rub.nds.tlsattacker.modifiablevariable.singlebyte.ByteAddModification;
import de.rub.nds.tlsattacker.modifiablevariable.singlebyte.ByteExplicitValueModification;
import de.rub.nds.tlsattacker.modifiablevariable.singlebyte.ByteSubtractModification;
import de.rub.nds.tlsattacker.modifiablevariable.singlebyte.ByteXorModification;
import de.rub.nds.tlsattacker.util.ArrayConverter;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* @author Juraj Somorovsky - juraj.somorovsky@rub.de
* @author Christian Mainka - christian.mainka@rub.de
* @param <E>
*/
@XmlRootElement
@XmlTransient
@XmlSeeAlso({AccessModificationFilter.class, BigIntegerAddModification.class,
BigIntegerExplicitValueModification.class, BigIntegerSubtractModification.class,
BigIntegerXorModification.class, BigIntegerShiftLeftModification.class, BigIntegerShiftRightModification.class,
IntegerAddModification.class, IntegerExplicitValueModification.class, IntegerSubtractModification.class,
IntegerXorModification.class, IntegerShiftLeftModification.class, IntegerShiftRightModification.class,
ByteArrayDeleteModification.class, ByteArrayExplicitValueModification.class, ByteArrayInsertModification.class,
ByteArrayXorModification.class, ByteArrayDuplicateModification.class, ByteArrayShuffleModification.class,
ByteAddModification.class, ByteExplicitValueModification.class,
ByteSubtractModification.class, ByteXorModification.class})
public abstract class VariableModification<E> {
private static final Logger LOGGER = LogManager.getLogger(VariableModification.class);
/**
* post modification for next modification executed on the given variable
*/
private VariableModification<E> postModification = null;
/**
* In specific cases it is possible to filter out some modifications based
* on given rules. ModificationFilter is responsible for validating if the
* modification can be executed.
*/
private ModificationFilter modificationFilter = null;
/**
* Get the value of postModification
*
* @return the value of postModification
*/
// http://stackoverflow.com/questions/5122296/jaxb-not-unmarshalling-xml-any-element-to-jaxbelement
@XmlAnyElement(lax = true)
final public VariableModification<E> getPostModification() {
return postModification;
}
/**
* Set the value of postModification
*
* @param postModification new value of postModification
*/
final public void setPostModification(VariableModification<E> postModification) {
this.postModification = postModification;
}
public E modify(E input) {
E modifiedValue = modifyImplementationHook(input);
if (postModification != null) {
modifiedValue = postModification.modify(modifiedValue);
}
if ((modificationFilter == null) || (modificationFilter.filterModification() == false)) {
debug(modifiedValue);
return modifiedValue;
} else {
return input;
}
}
protected abstract E modifyImplementationHook(E input);
/**
* Debugging modified variables. Getting stack trace can be time consuming,
* thus we use isDebugEnabled() function
*
* @param value
*/
protected void debug(E value) {
if (LOGGER.isDebugEnabled()) {
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
int index = 0;
for (int i = 0; i < stack.length; i++) {
if (stack[i].toString().contains("ModifiableVariable.getValue")) {
index = i + 1;
}
}
String valueString;
if (value.getClass().getSimpleName().equals("byte[]")) {
valueString = ArrayConverter.bytesToHexString((byte[]) value);
} else {
valueString = value.toString();
}
LOGGER.debug("Using {} in function:\n {}\n New value: {}", this.getClass().getSimpleName(), stack[index],
valueString);
}
}
public ModificationFilter getModificationFilter() {
return modificationFilter;
}
public void setModificationFilter(ModificationFilter modificationFilter) {
this.modificationFilter = modificationFilter;
}
}