org.bouncycastle.tls.TlsECDHKeyExchange Maven / Gradle / Ivy
package org.bouncycastle.tls;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.bouncycastle.tls.crypto.TlsCertificate;
import org.bouncycastle.tls.crypto.TlsCertificateRole;
import org.bouncycastle.tls.crypto.TlsSecret;
/**
* (D)TLS ECDH key exchange (see RFC 4492).
*/
public class TlsECDHKeyExchange
extends AbstractTlsKeyExchange
{
private static int checkKeyExchange(int keyExchange)
{
switch (keyExchange)
{
case KeyExchangeAlgorithm.ECDH_ECDSA:
case KeyExchangeAlgorithm.ECDH_RSA:
return keyExchange;
default:
throw new IllegalArgumentException("unsupported key exchange algorithm");
}
}
protected TlsCredentialedAgreement agreementCredentials;
protected TlsCertificate ecdhPeerCertificate;
public TlsECDHKeyExchange(int keyExchange)
{
super(checkKeyExchange(keyExchange));
}
public void skipServerCredentials() throws IOException
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
public void processServerCredentials(TlsCredentials serverCredentials) throws IOException
{
this.agreementCredentials = TlsUtils.requireAgreementCredentials(serverCredentials);
}
public void processServerCertificate(Certificate serverCertificate) throws IOException
{
this.ecdhPeerCertificate = serverCertificate.getCertificateAt(0).checkUsageInRole(TlsCertificateRole.ECDH);
}
public short[] getClientCertificateTypes()
{
/*
* RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with
* ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because
* the use of a long-term ECDH client key would jeopardize the forward secrecy property of
* these algorithms.
*/
return new short[]{ ClientCertificateType.ecdsa_fixed_ecdh, ClientCertificateType.rsa_fixed_ecdh };
}
public void skipClientCredentials() throws IOException
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
public void processClientCredentials(TlsCredentials clientCredentials) throws IOException
{
this.agreementCredentials = TlsUtils.requireAgreementCredentials(clientCredentials);
}
public void generateClientKeyExchange(OutputStream output) throws IOException
{
// In this case, the Client Key Exchange message will be sent, but will be empty.
}
public void processClientCertificate(Certificate clientCertificate) throws IOException
{
this.ecdhPeerCertificate = clientCertificate.getCertificateAt(0).checkUsageInRole(TlsCertificateRole.ECDH);
}
public void processClientKeyExchange(InputStream input) throws IOException
{
// For ecdsa_fixed_ecdh and rsa_fixed_ecdh, the key arrived in the client certificate
}
public boolean requiresCertificateVerify()
{
return false;
}
public TlsSecret generatePreMasterSecret() throws IOException
{
return agreementCredentials.generateAgreement(ecdhPeerCertificate);
}
}