/** * 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 java.util.Arrays; import de.rub.nds.tlsattacker.tls.constants.AlgorithmResolver; import de.rub.nds.tlsattacker.tls.constants.CipherSuite; import de.rub.nds.tlsattacker.tls.constants.HandshakeByteLength; import de.rub.nds.tlsattacker.tls.constants.HandshakeMessageType; import de.rub.nds.tlsattacker.tls.constants.KeyExchangeAlgorithm; import de.rub.nds.tlsattacker.tls.exceptions.InvalidMessageTypeException; import de.rub.nds.tlsattacker.tls.workflow.TlsContext; import de.rub.nds.tlsattacker.util.ArrayConverter; /** * * @author Juraj Somorovsky <juraj.somorovsky@rub.de> * @author Philip Riese <philip.riese@rub.de> * @param <HandshakeMessage> */ public abstract class ClientKeyExchangeHandler<Message extends ClientKeyExchangeMessage> extends HandshakeMessageHandler<Message> { KeyExchangeAlgorithm keyExchangeAlgorithm; public ClientKeyExchangeHandler(TlsContext tlsContext) { super(tlsContext); } @Override public byte[] prepareMessageAction() { protocolMessage.setType(HandshakeMessageType.CLIENT_KEY_EXCHANGE.getValue()); CipherSuite selectedCipherSuite = tlsContext.getSelectedCipherSuite(); KeyExchangeAlgorithm keyExchange = AlgorithmResolver.getKeyExchangeAlgorithm(selectedCipherSuite); if (keyExchange != keyExchangeAlgorithm) { throw new UnsupportedOperationException("The selected key exchange algorithm (" + keyExchange + ") is not supported yet"); } byte[] result = this.prepareKeyExchangeMessage(); protocolMessage.setLength(result.length); long header = (protocolMessage.getType().getValue() << 24) + protocolMessage.getLength().getValue(); protocolMessage.setCompleteResultingMessage(ArrayConverter.concatenate( ArrayConverter.longToUint32Bytes(header), result)); return protocolMessage.getCompleteResultingMessage().getValue(); } @Override public int parseMessageAction(byte[] message, int pointer) { if (message[pointer] != HandshakeMessageType.CLIENT_KEY_EXCHANGE.getValue()) { throw new InvalidMessageTypeException("This is not a Client key exchange 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; int resultPointer = this.parseKeyExchangeMessage(message, currentPointer); currentPointer = resultPointer; protocolMessage.setCompleteResultingMessage(Arrays.copyOfRange(message, pointer, currentPointer)); return currentPointer; } abstract byte[] prepareKeyExchangeMessage(); abstract int parseKeyExchangeMessage(byte[] message, int pointer); }