/**
* 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.workflow;
import de.rub.nds.tlsattacker.modifiablevariable.HoldsModifiableVariable;
import de.rub.nds.tlsattacker.tls.constants.AlgorithmResolver;
import de.rub.nds.tlsattacker.tls.constants.ConnectionEnd;
import de.rub.nds.tlsattacker.tls.constants.ProtocolVersion;
import de.rub.nds.tlsattacker.tls.crypto.TlsMessageDigest;
import de.rub.nds.tlsattacker.tls.exceptions.CryptoException;
import de.rub.nds.tlsattacker.tls.protocol.ProtocolMessageTypeHolder;
import de.rub.nds.tlsattacker.tls.constants.CipherSuite;
import de.rub.nds.tlsattacker.tls.constants.CompressionMethod;
import de.rub.nds.tlsattacker.tls.constants.DigestAlgorithm;
import de.rub.nds.tlsattacker.tls.constants.HandshakeByteLength;
import de.rub.nds.tlsattacker.tls.constants.SignatureAlgorithm;
import de.rub.nds.tlsattacker.tls.constants.SignatureAndHashAlgorithm;
import de.rub.nds.tlsattacker.tls.record.RecordHandler;
import de.rub.nds.tlsattacker.util.ArrayConverter;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedList;
import java.util.List;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.crypto.tls.ServerDHParams;
import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
import org.bouncycastle.jce.provider.X509CertificateObject;
/**
*
* @author Juraj Somorovsky <juraj.somorovsky@rub.de>
* @author Philip Riese <philip.riese@rub.de>
*/
public class TlsContext {
/**
* SSL/TLS protocol version
*/
private ProtocolVersion protocolVersion = ProtocolVersion.TLS12;
/**
* Indicates if we are executing a server or client
*/
private ConnectionEnd myConnectionEnd = ConnectionEnd.CLIENT;
/**
* master secret established during the handshake
*/
private byte[] masterSecret = new byte[HandshakeByteLength.MASTER_SECRET];
/**
* premaster secret established during the handshake
*/
private byte[] preMasterSecret = new byte[HandshakeByteLength.PREMASTER_SECRET];
/**
* client random, including unix time
*/
private byte[] clientRandom = new byte[HandshakeByteLength.RANDOM + HandshakeByteLength.UNIX_TIME];
/**
* server random, including unix time
*/
private byte[] serverRandom = new byte[HandshakeByteLength.RANDOM + HandshakeByteLength.UNIX_TIME];
/**
* selected cipher suite
*/
private CipherSuite selectedCipherSuite = CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA;
/**
* compression algorithm
*/
private CompressionMethod compressionMethod;
/**
* session ID
*/
private byte[] sessionID = new byte[HandshakeByteLength.RANDOM + HandshakeByteLength.UNIX_TIME];
/**
* server certificate parsed from the server certificate message
*/
private Certificate serverCertificate;
/**
* client certificate parsed from the client certificate message
*/
private Certificate clientCertificate;
/**
* server certificate from the server certificate message, in a nice x509
* form
*/
private X509CertificateObject x509ServerCertificateObject;
/**
* client certificate from the client certificate message, in a nice x509
* form
*/
private X509CertificateObject x509ClientCertificateObject;
/**
* EC context containing information about public/private key agreements,
* curves, and point formats
*/
private TlsECContext ecContext;
/**
* Server DH parameters
*/
private ServerDHParams serverDHParameters;
/**
* Server DH Private Key
*/
private DHPrivateKeyParameters serverDHPrivateKeyParameters;
/**
* workflow trace containing all the messages exchanged during the
* communication
*/
@HoldsModifiableVariable
private WorkflowTrace workflowTrace;
/**
* List of preconfigured protocol messages by the workflow configuration
* factory. In case the real message order of sent messages was modified,
* one can compare it to the preconfigured order and find differences.
*/
private List<ProtocolMessageTypeHolder> preconfiguredProtocolMessages;
/**
* keystore for storing client / server certificates
*/
private KeyStore keyStore;
/**
* alias for the used key in the keystore
*/
private String alias;
/**
* key store password
*/
private String password;
/**
* host to connect
*/
private String host;
/**
* Client Authentication YES or NO
*/
private boolean clientAuthentication = false;
/**
* SessionResumptionWorkflow
*/
private boolean sessionResumption = false;
/**
* RenegotiationWorkflow
*/
private boolean renegotiation = false;
/**
* Man_in_the_Middle_Workflow
*/
private boolean mitm = false;
private TlsMessageDigest digest;
private LinkedList<SignatureAndHashAlgorithm> supportedSignatureAndHashAlgorithms;
private RecordHandler recordHandler;
/**
* DTLS Cookie
*/
private byte[] dtlsHandshakeCookie = new byte[0];
public TlsContext() {
digest = new TlsMessageDigest();
ecContext = new TlsECContext();
}
public TlsContext(ProtocolVersion pv) {
this();
protocolVersion = pv;
}
public void initiliazeTlsMessageDigest() {
try {
DigestAlgorithm algorithm = AlgorithmResolver.getDigestAlgorithm(protocolVersion, selectedCipherSuite);
digest.initializeDigestAlgorithm(algorithm);
} catch (NoSuchAlgorithmException ex) {
throw new CryptoException(ex);
}
}
public byte[] getMasterSecret() {
return masterSecret;
}
public byte[] getServerClientRandom() {
return ArrayConverter.concatenate(serverRandom, clientRandom);
}
public CipherSuite getSelectedCipherSuite() {
return selectedCipherSuite;
}
public void setMasterSecret(byte[] masterSecret) {
this.masterSecret = masterSecret;
}
public void setSelectedCipherSuite(CipherSuite selectedCipherSuite) {
this.selectedCipherSuite = selectedCipherSuite;
}
public byte[] getClientServerRandom() {
return ArrayConverter.concatenate(clientRandom, serverRandom);
}
public byte[] getPreMasterSecret() {
return preMasterSecret;
}
public void setPreMasterSecret(byte[] preMasterSecret) {
this.preMasterSecret = preMasterSecret;
}
public ProtocolVersion getProtocolVersion() {
return protocolVersion;
}
public void setProtocolVersion(ProtocolVersion protocolVersion) {
this.protocolVersion = protocolVersion;
}
public ConnectionEnd getMyConnectionEnd() {
return myConnectionEnd;
}
public ConnectionEnd getMyConnectionPeer() {
return myConnectionEnd == ConnectionEnd.CLIENT ? ConnectionEnd.SERVER : ConnectionEnd.CLIENT;
}
public void setMyConnectionEnd(ConnectionEnd myConnectionEnd) {
this.myConnectionEnd = myConnectionEnd;
}
public byte[] getClientRandom() {
return clientRandom;
}
public void setClientRandom(byte[] clientRandom) {
this.clientRandom = clientRandom;
}
public byte[] getServerRandom() {
return serverRandom;
}
public void setServerRandom(byte[] serverRandom) {
this.serverRandom = serverRandom;
}
public CompressionMethod getCompressionMethod() {
return compressionMethod;
}
public void setCompressionMethod(CompressionMethod compressionMethod) {
this.compressionMethod = compressionMethod;
}
public byte[] getSessionID() {
return sessionID;
}
public void setSessionID(byte[] sessionID) {
this.sessionID = sessionID;
}
public WorkflowTrace getWorkflowTrace() {
return workflowTrace;
}
public void setWorkflowTrace(WorkflowTrace workflowTrace) {
this.workflowTrace = workflowTrace;
}
public TlsECContext getEcContext() {
return ecContext;
}
public void setEcContext(TlsECContext ecContext) {
this.ecContext = ecContext;
}
public Certificate getServerCertificate() {
return serverCertificate;
}
public void setServerCertificate(Certificate serverCertificate) {
this.serverCertificate = serverCertificate;
}
public Certificate getClientCertificate() {
return clientCertificate;
}
public void setClientCertificate(Certificate clientCertificate) {
this.clientCertificate = clientCertificate;
}
public X509CertificateObject getX509ServerCertificateObject() {
return x509ServerCertificateObject;
}
public void setX509ServerCertificateObject(X509CertificateObject x509ServerCertificateObject) {
this.x509ServerCertificateObject = x509ServerCertificateObject;
}
public X509CertificateObject getX509ClientCertificateObject() {
return x509ClientCertificateObject;
}
public void setX509ClientCertificateObject(X509CertificateObject x509ClientCertificateObject) {
this.x509ClientCertificateObject = x509ClientCertificateObject;
}
public ServerDHParams getServerDHParameters() {
return serverDHParameters;
}
public void setServerDHParameters(ServerDHParams serverDHParameters) {
this.serverDHParameters = serverDHParameters;
}
public DHPrivateKeyParameters getServerDHPrivateKeyParameters() {
return serverDHPrivateKeyParameters;
}
public void setServerDHPrivateKeyParameters(DHPrivateKeyParameters serverDHPrivateKeyParameters) {
this.serverDHPrivateKeyParameters = serverDHPrivateKeyParameters;
}
public List<ProtocolMessageTypeHolder> getPreconfiguredProtocolMessages() {
return preconfiguredProtocolMessages;
}
public void setPreconfiguredProtocolMessages(List<ProtocolMessageTypeHolder> preconfiguredProtocolMessages) {
this.preconfiguredProtocolMessages = preconfiguredProtocolMessages;
}
public KeyStore getKeyStore() {
return keyStore;
}
public void setKeyStore(KeyStore keyStore) {
this.keyStore = keyStore;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public TlsMessageDigest getDigest() {
return digest;
}
public LinkedList<SignatureAndHashAlgorithm> getSupportedSignatureAndHashAlgorithms() {
return supportedSignatureAndHashAlgorithms;
}
public LinkedList<SignatureAndHashAlgorithm> getSupportedSignatureAndHashAlgorithmsForRSA() {
LinkedList<SignatureAndHashAlgorithm> rsaAlgorithms = new LinkedList<>();
for (SignatureAndHashAlgorithm alg : supportedSignatureAndHashAlgorithms) {
if (alg.getSignatureAlgorithm() == SignatureAlgorithm.RSA) {
rsaAlgorithms.add(alg);
}
}
return rsaAlgorithms;
}
public LinkedList<SignatureAndHashAlgorithm> getSupportedSignatureAndHashAlgorithmsForEC() {
LinkedList<SignatureAndHashAlgorithm> ecAlgorithms = new LinkedList<>();
for (SignatureAndHashAlgorithm alg : supportedSignatureAndHashAlgorithms) {
if (alg.getSignatureAlgorithm() == SignatureAlgorithm.ECDSA) {
ecAlgorithms.add(alg);
}
}
return ecAlgorithms;
}
public void setSupportedSignatureAndHashAlgorithms(
LinkedList<SignatureAndHashAlgorithm> supportedSignatureAndHashAlgorithms) {
this.supportedSignatureAndHashAlgorithms = supportedSignatureAndHashAlgorithms;
}
public void setDtlsHandshakeCookie(byte[] cookie) {
this.dtlsHandshakeCookie = cookie;
}
public byte[] getDtlsHandshakeCookie() {
return dtlsHandshakeCookie;
}
public RecordHandler getRecordHandler() {
return recordHandler;
}
public void setRecordHandler(RecordHandler recordHandler) {
this.recordHandler = recordHandler;
}
public boolean isClientAuthentication() {
return clientAuthentication;
}
public void setClientAuthentication(boolean status) {
this.clientAuthentication = status;
}
public boolean isSessionResumption() {
return sessionResumption;
}
public void setSessionResumption(boolean sessionResumption) {
this.sessionResumption = sessionResumption;
}
public boolean isRenegotiation() {
return renegotiation;
}
public void setRenegotiation(boolean renegotiation) {
this.renegotiation = renegotiation;
}
public boolean isMitMAttack() {
return mitm;
}
public void setMitMAttack(boolean mitm) {
this.mitm = mitm;
}
}