<commit_before>package org.bouncycastle.crypto.tls;

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

public abstract class AbstractTlsServer implements TlsServer {

    protected TlsCipherFactory cipherFactory;

    protected TlsServerContext context;

    protected ProtocolVersion clientVersion;
    protected Hashtable clientExtensions;

    protected ProtocolVersion serverVersion;
    protected int selectedCipherSuite;
    protected short selectedCompressionMethod;
    protected Hashtable serverExtensions;

    public AbstractTlsServer() {
        this(new DefaultTlsCipherFactory());
    }

    public AbstractTlsServer(TlsCipherFactory cipherFactory) {
        this.cipherFactory = cipherFactory;
    }

    protected abstract int[] getCipherSuites();

    protected short[] getCompressionMethods() {
        return new short[] { CompressionMethod.NULL };
    }

    protected ProtocolVersion getMaximumVersion() {
        return ProtocolVersion.TLSv11;
    }

    protected ProtocolVersion getMinimumVersion() {
        return ProtocolVersion.TLSv10;
    }

    public void init(TlsServerContext context) {
        this.context = context;
    }

    public void notifyClientVersion(ProtocolVersion clientVersion) throws IOException {
        this.clientVersion = clientVersion;
    }

    public void notifyOfferedCipherSuites(int[] offeredCipherSuites) throws IOException {
        int[] cipherSuites = getCipherSuites();
        for (int i = 0; i < cipherSuites.length; ++i) {
            if (TlsProtocol.arrayContains(offeredCipherSuites, cipherSuites[i])) {
                this.selectedCipherSuite = cipherSuites[i];
                return;
            }
        }
        throw new TlsFatalAlert(AlertDescription.handshake_failure);
    }

    public void notifyOfferedCompressionMethods(short[] offeredCompressionMethods)
        throws IOException {
        short[] compressionMethods = getCompressionMethods();
        for (int i = 0; i < compressionMethods.length; ++i) {
            if (TlsProtocol.arrayContains(offeredCompressionMethods, compressionMethods[i])) {
                this.selectedCompressionMethod = compressionMethods[i];
                return;
            }
        }
        throw new TlsFatalAlert(AlertDescription.handshake_failure);
    }

    public void notifySecureRenegotiation(boolean secureRenegotiation) throws IOException {
        if (!secureRenegotiation) {
            /*
             * RFC 5746 3.6. In this case, some servers may want to terminate the handshake instead
             * of continuing; see Section 4.3 for discussion.
             */
            throw new TlsFatalAlert(AlertDescription.handshake_failure);
        }
    }

    public void processClientExtensions(Hashtable clientExtensions) throws IOException {
        this.clientExtensions = clientExtensions;
    }

    public ProtocolVersion getServerVersion() throws IOException {
        if (getMinimumVersion().isEqualOrEarlierVersionOf(clientVersion)) {
            ProtocolVersion maximumVersion = getMaximumVersion();
            if (clientVersion.isEqualOrEarlierVersionOf(maximumVersion)) {
                return serverVersion = clientVersion;
            }
            if (clientVersion.isLaterVersionOf(maximumVersion)) {
                return serverVersion = maximumVersion;
            }
        }
        throw new TlsFatalAlert(AlertDescription.protocol_version);
    }

    public int getSelectedCipherSuite() throws IOException {
        return selectedCipherSuite;
    }

    public short getSelectedCompressionMethod() throws IOException {
        return selectedCompressionMethod;
    }

    // Hashtable is (Integer -> byte[])
    public Hashtable getServerExtensions() throws IOException {
        if (TlsECCUtils.isECCCipherSuite(this.selectedCipherSuite)) {

            /*
             * TODO RFC 4429 5.1. A server that receives a ClientHello containing one or both of
             * these extensions MUST use the client's enumerated capabilities to guide its selection
             * of an appropriate cipher suite. One of the proposed ECC cipher suites must be
             * negotiated only if the server can successfully complete the handshake while using the
             * curves and point formats supported by the client [...].
             */
            this.serverExtensions = new Hashtable();
            TlsECCUtils.addSupportedPointFormatsExtension(serverExtensions, new short[] {
                ECPointFormat.uncompressed, ECPointFormat.ansiX962_compressed_char2,
                ECPointFormat.ansiX962_compressed_prime });
            return serverExtensions;
        }

        return null;
    }

    public Vector getServerSupplementalData() throws IOException {
        return null;
    }
<commit_msg>Defer selection of cipher suite and compression method<commit_after>package org.bouncycastle.crypto.tls;

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

public abstract class AbstractTlsServer implements TlsServer {

    protected TlsCipherFactory cipherFactory;

    protected TlsServerContext context;

    protected ProtocolVersion clientVersion;
    protected int[] offeredCipherSuites;
    protected short[] offeredCompressionMethods;
    protected Hashtable clientExtensions;

    protected ProtocolVersion serverVersion;
    protected int selectedCipherSuite;
    protected short selectedCompressionMethod;
    protected Hashtable serverExtensions;

    public AbstractTlsServer() {
        this(new DefaultTlsCipherFactory());
    }

    public AbstractTlsServer(TlsCipherFactory cipherFactory) {
        this.cipherFactory = cipherFactory;
    }

    protected abstract int[] getCipherSuites();

    protected short[] getCompressionMethods() {
        return new short[] { CompressionMethod.NULL };
    }

    protected ProtocolVersion getMaximumVersion() {
        return ProtocolVersion.TLSv11;
    }

    protected ProtocolVersion getMinimumVersion() {
        return ProtocolVersion.TLSv10;
    }

    public void init(TlsServerContext context) {
        this.context = context;
    }

    public void notifyClientVersion(ProtocolVersion clientVersion) throws IOException {
        this.clientVersion = clientVersion;
    }

    public void notifyOfferedCipherSuites(int[] offeredCipherSuites) throws IOException {
        this.offeredCipherSuites = offeredCipherSuites;
    }

    public void notifyOfferedCompressionMethods(short[] offeredCompressionMethods)
        throws IOException {
        this.offeredCompressionMethods = offeredCompressionMethods;
    }

    public void notifySecureRenegotiation(boolean secureRenegotiation) throws IOException {
        if (!secureRenegotiation) {
            /*
             * RFC 5746 3.6. In this case, some servers may want to terminate the handshake instead
             * of continuing; see Section 4.3 for discussion.
             */
            throw new TlsFatalAlert(AlertDescription.handshake_failure);
        }
    }

    public void processClientExtensions(Hashtable clientExtensions) throws IOException {
        this.clientExtensions = clientExtensions;
    }

    public ProtocolVersion getServerVersion() throws IOException {
        if (getMinimumVersion().isEqualOrEarlierVersionOf(clientVersion)) {
            ProtocolVersion maximumVersion = getMaximumVersion();
            if (clientVersion.isEqualOrEarlierVersionOf(maximumVersion)) {
                return serverVersion = clientVersion;
            }
            if (clientVersion.isLaterVersionOf(maximumVersion)) {
                return serverVersion = maximumVersion;
            }
        }
        throw new TlsFatalAlert(AlertDescription.protocol_version);
    }

    public int getSelectedCipherSuite() throws IOException {
        int[] cipherSuites = getCipherSuites();
        for (int i = 0; i < cipherSuites.length; ++i) {
            if (TlsProtocol.arrayContains(this.offeredCipherSuites, cipherSuites[i])) {
                return this.selectedCipherSuite = cipherSuites[i];
            }
        }
        throw new TlsFatalAlert(AlertDescription.handshake_failure);
    }

    public short getSelectedCompressionMethod() throws IOException {
        short[] compressionMethods = getCompressionMethods();
        for (int i = 0; i < compressionMethods.length; ++i) {
            if (TlsProtocol.arrayContains(offeredCompressionMethods, compressionMethods[i])) {
                return this.selectedCompressionMethod = compressionMethods[i];
            }
        }
        throw new TlsFatalAlert(AlertDescription.handshake_failure);
    }

    // Hashtable is (Integer -> byte[])
    public Hashtable getServerExtensions() throws IOException {
        if (TlsECCUtils.isECCCipherSuite(this.selectedCipherSuite)) {

            /*
             * TODO RFC 4429 5.1. A server that receives a ClientHello containing one or both of
             * these extensions MUST use the client's enumerated capabilities to guide its selection
             * of an appropriate cipher suite. One of the proposed ECC cipher suites must be
             * negotiated only if the server can successfully complete the handshake while using the
             * curves and point formats supported by the client [...].
             */
            this.serverExtensions = new Hashtable();
            TlsECCUtils.addSupportedPointFormatsExtension(serverExtensions, new short[] {
                ECPointFormat.uncompressed, ECPointFormat.ansiX962_compressed_char2,
                ECPointFormat.ansiX962_compressed_prime });
            return serverExtensions;
        }

        return null;
    }

    public Vector getServerSupplementalData() throws IOException {
        return null;
    }

{'fraction_non_alphanumeric': 0.06564932404752151, 'fraction_numerical': 0.005530520278574355, 'mean_word_length': 2.8099882949668356, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4229795', 'n_tokens_mistral': 2479, 'n_tokens_neox': 2332, 'n_words': 619}