/**
* 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.handshake;
import de.rub.nds.tlsattacker.tls.constants.ProtocolVersion;
import de.rub.nds.tlsattacker.tls.protocol.ProtocolMessageHandler;
import de.rub.nds.tlsattacker.tls.workflow.TlsContext;
import de.rub.nds.tlsattacker.util.ArrayConverter;
/**
* @author Juraj Somorovsky - juraj.somorovsky@rub.de
* @author Florian Pfützenreuter <florian.pfuetzenreuter@rub.de>
* @param <ProtocolMessage>
*/
public abstract class HandshakeMessageHandler<ProtocolMessage extends HandshakeMessage> extends
ProtocolMessageHandler<ProtocolMessage> {
private byte[] dtlsAllMessageBytes;
public HandshakeMessageHandler(TlsContext tlsContext) {
super(tlsContext);
}
@Override
protected byte[] beforeParseMessageAction(byte[] message, int pointer) {
if (tlsContext.getProtocolVersion() == ProtocolVersion.DTLS12) {
return prepareDtlsHandshakeMessageParse(message, pointer);
}
return message;
}
/**
* Implementation hook used after the prepareMessageAction: the content of
* the parsed protocol message is parsed and the digest value is updated
*
* @param messageBytes
* @return
*/
@Override
protected byte[] afterPrepareMessageAction(byte[] messageBytes) {
if (tlsContext.getProtocolVersion() == ProtocolVersion.DTLS12) {
protocolMessage.setCompleteResultingMessage(finishDtlsHandshakeMessagePrepare(messageBytes));
}
byte[] pm = protocolMessage.getCompleteResultingMessage().getValue();
if (protocolMessage.getIncludeInDigest()) {
tlsContext.getDigest().update(pm);
}
return pm;
}
/**
* Implementation hook used after the parseMessageAction: the content of the
* parsed protocol message is parsed and the digest value is updated
*
* @param ret
* @return
*/
@Override
protected int afterParseMessageAction(int ret) {
if (tlsContext.getProtocolVersion() == ProtocolVersion.DTLS12) {
protocolMessage.setCompleteResultingMessage(dtlsAllMessageBytes);
ret += 8;
}
byte[] pm = protocolMessage.getCompleteResultingMessage().getValue();
if (protocolMessage.getIncludeInDigest()) {
tlsContext.getDigest().update(pm);
}
return ret;
}
private byte[] prepareDtlsHandshakeMessageParse(byte[] message, int pointer) {
dtlsAllMessageBytes = message;
byte[] parsePmBytes;
protocolMessage.setMessageSeq((message[pointer + 4] << 8) + (message[pointer + 5] & 0xFF));
protocolMessage.setFragmentOffset((message[pointer + 6] << 16) + (message[pointer + 7] << 8)
+ (message[pointer + 8] & 0xFF));
protocolMessage.setFragmentLength((message[pointer + 9] << 16) + (message[pointer + 10] << 8)
+ (message[pointer + 11] & 0xFF));
parsePmBytes = new byte[message.length - 8];
System.arraycopy(message, 0, parsePmBytes, 0, pointer);
System.arraycopy(message, pointer, parsePmBytes, pointer, 4);
System.arraycopy(message, pointer + 12, parsePmBytes, pointer + 4, message.length - pointer - 12);
return parsePmBytes;
}
private byte[] finishDtlsHandshakeMessagePrepare(byte[] messageBytes) {
protocolMessage.setFragmentLength(messageBytes.length - 4);
byte[] preparePmBytes = new byte[messageBytes.length + 8];
System.arraycopy(messageBytes, 0, preparePmBytes, 0, 4);
System.arraycopy(ArrayConverter.intToBytes(protocolMessage.getMessageSeq().getValue(), 2), 0, preparePmBytes,
4, 2);
System.arraycopy(ArrayConverter.intToBytes(protocolMessage.getFragmentOffset().getValue(), 3), 0,
preparePmBytes, 6, 3);
System.arraycopy(ArrayConverter.intToBytes(protocolMessage.getFragmentLength().getValue(), 3), 0,
preparePmBytes, 9, 3);
System.arraycopy(messageBytes, 4, preparePmBytes, 12, messageBytes.length - 4);
return preparePmBytes;
}
}