/** * 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.modifiablevariable.ModifiableVariableFactory; import de.rub.nds.tlsattacker.modifiablevariable.ModifiableVariableProperty; import de.rub.nds.tlsattacker.modifiablevariable.bytearray.ModifiableByteArray; import de.rub.nds.tlsattacker.modifiablevariable.integer.ModifiableInteger; import de.rub.nds.tlsattacker.tls.constants.ConnectionEnd; import de.rub.nds.tlsattacker.tls.constants.CipherSuite; import de.rub.nds.tlsattacker.tls.constants.CompressionMethod; import de.rub.nds.tlsattacker.tls.constants.HandshakeMessageType; import de.rub.nds.tlsattacker.tls.constants.ProtocolVersion; import de.rub.nds.tlsattacker.util.ArrayConverter; import java.util.Date; import java.util.LinkedList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlElements; import javax.xml.bind.annotation.XmlRootElement; /** * * @author Juraj Somorovsky <juraj.somorovsky@rub.de> * @author Philip Riese <philip.riese@rub.de> */ @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) // @XmlType(propOrder = {"compressionLength", "cipherSuiteLength"}) public class ClientHelloMessage extends HelloMessage { /** * List of supported compression methods */ @XmlElementWrapper @XmlElements(value = { @XmlElement(type = CompressionMethod.class, name = "CompressionMethod") }) private List<CompressionMethod> supportedCompressionMethods = new LinkedList<>(); /** * List of supported ciphersuites */ @XmlElementWrapper @XmlElements(value = { @XmlElement(type = CipherSuite.class, name = "CipherSuite") }) private List<CipherSuite> supportedCipherSuites = new LinkedList<>(); /** * compression length */ @ModifiableVariableProperty(type = ModifiableVariableProperty.Type.LENGTH) ModifiableInteger compressionLength; /** * cipher suite byte length */ @ModifiableVariableProperty(type = ModifiableVariableProperty.Type.LENGTH) ModifiableInteger cipherSuiteLength; /** * array of supported ciphersuites */ @ModifiableVariableProperty(type = ModifiableVariableProperty.Type.TLS_CONSTANT) ModifiableByteArray cipherSuites; /** * array of supported compressions */ @ModifiableVariableProperty(type = ModifiableVariableProperty.Type.TLS_CONSTANT) ModifiableByteArray compressions; /** * array of all extension bytes to forward them as MitM */ byte[] extensionBytes; public ClientHelloMessage() { super(HandshakeMessageType.CLIENT_HELLO); this.messageIssuer = ConnectionEnd.CLIENT; } public ClientHelloMessage(ConnectionEnd messageIssuer) { super(HandshakeMessageType.CLIENT_HELLO); this.messageIssuer = messageIssuer; } public ModifiableInteger getCompressionLength() { return compressionLength; } public ModifiableInteger getCipherSuiteLength() { return cipherSuiteLength; } public ModifiableByteArray getCipherSuites() { return cipherSuites; } public ModifiableByteArray getCompressions() { return compressions; } public void setCompressionLength(ModifiableInteger compressionLength) { this.compressionLength = compressionLength; } public void setCipherSuiteLength(ModifiableInteger cipherSuiteLength) { this.cipherSuiteLength = cipherSuiteLength; } public void setCipherSuites(ModifiableByteArray cipherSuites) { this.cipherSuites = cipherSuites; } public void setCompressions(ModifiableByteArray compressions) { this.compressions = compressions; } public void setCompressionLength(int compressionLength) { this.compressionLength = ModifiableVariableFactory.safelySetValue(this.compressionLength, compressionLength); } public void setCipherSuiteLength(int cipherSuiteLength) { this.cipherSuiteLength = ModifiableVariableFactory.safelySetValue(this.cipherSuiteLength, cipherSuiteLength); } public void setCipherSuites(byte[] array) { this.cipherSuites = ModifiableVariableFactory.safelySetValue(cipherSuites, array); } public void setCompressions(byte[] array) { this.compressions = ModifiableVariableFactory.safelySetValue(compressions, array); } public void setSupportedCompressionMethods(List<CompressionMethod> supportedCompressionMethods) { this.supportedCompressionMethods = supportedCompressionMethods; } public void setSupportedCipherSuites(List<CipherSuite> supportedCipherSuites) { this.supportedCipherSuites = supportedCipherSuites; } public List<CompressionMethod> getSupportedCompressionMethods() { return supportedCompressionMethods; } public byte[] getExtensionBytes() { return extensionBytes; } public void setExtensionBytes(byte[] extensionBytes) { this.extensionBytes = extensionBytes; } public List<CipherSuite> getSupportedCipherSuites() { return supportedCipherSuites; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(super.toString()).append("\n Protocol Version: ") .append(ProtocolVersion.getProtocolVersion(protocolVersion.getValue())) .append("\n Client Unix Time: ") .append(new Date(ArrayConverter.bytesToLong(unixTime.getValue()) * 1000)).append("\n Client Random: ") .append(ArrayConverter.bytesToHexString(random.getValue())).append("\n Session ID: ") .append(ArrayConverter.bytesToHexString(sessionId.getValue())).append("\n Supported Cipher Suites: ") .append(ArrayConverter.bytesToHexString(cipherSuites.getValue())) .append("\n Supported Compression Methods: ") .append(ArrayConverter.bytesToHexString(compressions.getValue())).append("\n Extensions: "); // Some ExtensionsTypes are not supported yet, so avoiding the // NULLPointerException needs to be done /** * for (ExtensionMessage e : extensions) { sb.append(e.toString()); } */ return sb.toString(); } }