All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.tls.AbstractTlsKeyExchange Maven / Gradle / Ivy

Go to download

The Bouncy Castle Java APIs for the TLS, including a JSSE provider. The APIs are designed primarily to be used in conjunction with the BC FIPS provider. The APIs may also be used with other providers although if being used in a FIPS context it is the responsibility of the user to ensure that any other providers used are FIPS certified and used appropriately.

There is a newer version: 2.0.19
Show newest version
package org.bouncycastle.tls;

import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;

/**
 * Base class for supporting a TLS key exchange implementation.
 */
public abstract class AbstractTlsKeyExchange
    implements TlsKeyExchange
{
    protected int keyExchange;
    protected Vector supportedSignatureAlgorithms;

    protected TlsContext context;

    protected AbstractTlsKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms)
    {
        this.keyExchange = keyExchange;
        this.supportedSignatureAlgorithms = supportedSignatureAlgorithms;
    }

    protected void checkServerCertSigAlg(Certificate serverCertificate) throws IOException
    {
        if (supportedSignatureAlgorithms == null)
        {
            /*
             * TODO RFC 2246 7.4.2. Unless otherwise specified, the signing algorithm for the
             * certificate must be the same as the algorithm for the certificate key.
             */
        }
        else
        {
            /*
             * TODO RFC 5246 7.4.2. If the client provided a "signature_algorithms" extension, then
             * all certificates provided by the server MUST be signed by a hash/signature algorithm
             * pair that appears in that extension.
             */
        }
    }

    protected DigitallySigned parseSignature(InputStream input) throws IOException
    {
        DigitallySigned signature = DigitallySigned.parse(context, input);
        SignatureAndHashAlgorithm signatureAlgorithm = signature.getAlgorithm();
        if (signatureAlgorithm != null)
        {
            TlsUtils.verifySupportedSignatureAlgorithm(supportedSignatureAlgorithms, signatureAlgorithm);
        }
        return signature;
    }

    public void init(TlsContext context)
    {
        this.context = context;

        ProtocolVersion clientVersion = context.getClientVersion();

        if (TlsUtils.isSignatureAlgorithmsExtensionAllowed(clientVersion))
        {
            /*
             * RFC 5246 7.4.1.4.1. If the client does not send the signature_algorithms extension,
             * the server MUST do the following:
             * 
             * - If the negotiated key exchange algorithm is one of (RSA, DHE_RSA, DH_RSA, RSA_PSK,
             * ECDH_RSA, ECDHE_RSA), behave as if client had sent the value {sha1,rsa}.
             * 
             * - If the negotiated key exchange algorithm is one of (DHE_DSS, DH_DSS), behave as if
             * the client had sent the value {sha1,dsa}.
             * 
             * - If the negotiated key exchange algorithm is one of (ECDH_ECDSA, ECDHE_ECDSA),
             * behave as if the client had sent value {sha1,ecdsa}.
             */
            if (this.supportedSignatureAlgorithms == null)
            {
                switch (keyExchange)
                {
                case KeyExchangeAlgorithm.DH_DSS:
                case KeyExchangeAlgorithm.DHE_DSS:
                case KeyExchangeAlgorithm.SRP_DSS:
                {
                    this.supportedSignatureAlgorithms = TlsUtils.getDefaultDSSSignatureAlgorithms();
                    break;
                }

                case KeyExchangeAlgorithm.ECDH_ECDSA:
                case KeyExchangeAlgorithm.ECDHE_ECDSA:
                {
                    this.supportedSignatureAlgorithms = TlsUtils.getDefaultECDSASignatureAlgorithms();
                    break;
                }

                case KeyExchangeAlgorithm.DH_RSA:
                case KeyExchangeAlgorithm.DHE_RSA:
                case KeyExchangeAlgorithm.ECDH_RSA:
                case KeyExchangeAlgorithm.ECDHE_RSA:
                case KeyExchangeAlgorithm.RSA:
                case KeyExchangeAlgorithm.RSA_PSK:
                case KeyExchangeAlgorithm.SRP_RSA:
                {
                    this.supportedSignatureAlgorithms = TlsUtils.getDefaultRSASignatureAlgorithms();
                    break;
                }

                case KeyExchangeAlgorithm.DHE_PSK:
                case KeyExchangeAlgorithm.ECDHE_PSK:
                case KeyExchangeAlgorithm.PSK:
                case KeyExchangeAlgorithm.SRP:
                    break;

                default:
                    throw new IllegalStateException("unsupported key exchange algorithm");
                }
            }
        }
        else if (this.supportedSignatureAlgorithms != null)
        {
            throw new IllegalStateException("supported_signature_algorithms not allowed for " + clientVersion);
        }
    }

    public void processServerCertificate(Certificate serverCertificate) throws IOException
    {
        throw new TlsFatalAlert(AlertDescription.internal_error);
    }

    public void processServerCredentials(TlsCredentials serverCredentials)
        throws IOException
    {
        // TODO[tls-ops] Process the server certificate differently on the server side 
        processServerCertificate(serverCredentials.getCertificate());
    }

    public boolean requiresServerKeyExchange()
    {
        return false;
    }

    public byte[] generateServerKeyExchange()
        throws IOException
    {
        if (requiresServerKeyExchange())
        {
            throw new TlsFatalAlert(AlertDescription.internal_error);
        }
        return null;
    }

    public void skipServerKeyExchange()
        throws IOException
    {
        if (requiresServerKeyExchange())
        {
            throw new TlsFatalAlert(AlertDescription.unexpected_message);
        }
    }

    public void processServerKeyExchange(InputStream input)
        throws IOException
    {
        if (!requiresServerKeyExchange())
        {
            throw new TlsFatalAlert(AlertDescription.unexpected_message);
        }
    }

    public short[] getClientCertificateTypes()
    {
        return null;
    }

    public void skipClientCredentials()
        throws IOException
    {
        if (TlsUtils.isStaticKeyAgreement(keyExchange))
        {
            throw new TlsFatalAlert(AlertDescription.unexpected_message);
        }
    }

    public void processClientCertificate(Certificate clientCertificate)
        throws IOException
    {
    }

    public void processClientKeyExchange(InputStream input)
        throws IOException
    {
        // Key exchange implementation MUST support client key exchange
        throw new TlsFatalAlert(AlertDescription.internal_error);
    }

    public boolean requiresCertificateVerify()
    {
        return !TlsUtils.isStaticKeyAgreement(keyExchange);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy