/** * 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.dtls.protocol.handshake; import java.util.Arrays; import de.rub.nds.tlsattacker.tls.constants.HandshakeByteLength; import de.rub.nds.tlsattacker.tls.constants.HandshakeMessageType; import de.rub.nds.tlsattacker.tls.constants.ProtocolVersion; import de.rub.nds.tlsattacker.tls.constants.RecordByteLength; import de.rub.nds.tlsattacker.tls.exceptions.InvalidMessageTypeException; import de.rub.nds.tlsattacker.tls.protocol.handshake.HandshakeMessageHandler; import de.rub.nds.tlsattacker.tls.workflow.TlsContext; import de.rub.nds.tlsattacker.util.ArrayConverter; /** * @author Florian Pfützenreuter <florian.pfuetzenreuter@rub.de> * @param <HandshakeMessage> */ public class HelloVerifyRequestHandler<Message extends HelloVerifyRequestMessage> extends HandshakeMessageHandler<Message> { @SuppressWarnings("unchecked") public HelloVerifyRequestHandler(TlsContext tlsContext) { super(tlsContext); this.correctProtocolMessageClass = (Class<? extends Message>) HelloVerifyRequestMessage.class; } @Override public byte[] prepareMessageAction() { byte[] content; protocolMessage.setProtocolVersion(tlsContext.getProtocolVersion().getValue()); // TODO: Calculate cookie via HMAC byte[] cookie = new byte[3]; cookie[0] = (byte) 11; cookie[1] = (byte) 22; cookie[2] = (byte) 33; tlsContext.setDtlsHandshakeCookie(cookie); protocolMessage.setCookie(cookie); protocolMessage.setCookieLength((byte) cookie.length); content = ArrayConverter.concatenate(protocolMessage.getProtocolVersion().getValue(), new byte[] { protocolMessage.getCookieLength().getValue() }, protocolMessage.getCookie().getValue()); protocolMessage.setLength(content.length); protocolMessage.setCompleteResultingMessage(ArrayConverter.concatenate( new byte[] { HandshakeMessageType.HELLO_VERIFY_REQUEST.getValue() }, ArrayConverter.intToBytes(protocolMessage.getLength().getValue(), 3), content)); return protocolMessage.getCompleteResultingMessage().getValue(); } @Override public int parseMessageAction(byte[] message, int pointer) { if (message[pointer] != HandshakeMessageType.HELLO_VERIFY_REQUEST.getValue()) { throw new InvalidMessageTypeException("This is not a client verify message"); } protocolMessage.setType(message[pointer]); int currentPointer = pointer + HandshakeByteLength.MESSAGE_TYPE; int nextPointer = currentPointer + HandshakeByteLength.MESSAGE_TYPE_LENGTH; int length = ArrayConverter.bytesToInt(Arrays.copyOfRange(message, currentPointer, nextPointer)); protocolMessage.setLength(length); currentPointer = nextPointer; nextPointer = currentPointer + RecordByteLength.PROTOCOL_VERSION; ProtocolVersion serverProtocolVersion = ProtocolVersion.getProtocolVersion(Arrays.copyOfRange(message, currentPointer, nextPointer)); protocolMessage.setProtocolVersion(serverProtocolVersion.getValue()); currentPointer = nextPointer; nextPointer += HandshakeByteLength.DTLS_HANDSHAKE_COOKIE_LENGTH; int cookieLength = ArrayConverter.bytesToInt(Arrays.copyOfRange(message, currentPointer, nextPointer)); byte[] cookie; currentPointer = nextPointer; nextPointer += cookieLength; cookie = Arrays.copyOfRange(message, currentPointer, nextPointer); protocolMessage.setCookie(cookie); protocolMessage.setCookieLength((byte) cookie.length); tlsContext.setDtlsHandshakeCookie(cookie); return nextPointer; } }