void initialize(String hostname, OpenSSLKey channelIdPrivateKey) throws IOException {
        boolean enableSessionCreation = parameters.getEnableSessionCreation();
        if (!enableSessionCreation) {
            NativeCrypto.SSL_set_session_creation_enabled(ssl, this, false);
        }

        // Allow servers to trigger renegotiation. Some inadvisable server
        // configurations cause them to attempt to renegotiate during
        // certain protocols.
        NativeCrypto.SSL_accept_renegotiations(ssl, this);

        if (isClient()) {
            NativeCrypto.SSL_set_connect_state(ssl, this);

            // Configure OCSP and CT extensions for client
            NativeCrypto.SSL_enable_ocsp_stapling(ssl, this);
            if (parameters.isCTVerificationEnabled(hostname)) {
                NativeCrypto.SSL_enable_signed_cert_timestamps(ssl, this);
            }
        } else {
            NativeCrypto.SSL_set_accept_state(ssl, this);

            // Configure OCSP for server
            if (parameters.getOCSPResponse() != null) {
                NativeCrypto.SSL_enable_ocsp_stapling(ssl, this);
            }
        }

        if (parameters.getEnabledProtocols().length == 0 && parameters.isEnabledProtocolsFiltered) {
            throw new SSLHandshakeException("No enabled protocols; "
                    + NativeCrypto.OBSOLETE_PROTOCOL_SSLV3 + ", "
                    + NativeCrypto.DEPRECATED_PROTOCOL_TLSV1
                    + " and " + NativeCrypto.DEPRECATED_PROTOCOL_TLSV1_1
                    + " are no longer supported and were filtered from the list");
        }
        NativeCrypto.setEnabledProtocols(ssl, this, parameters.enabledProtocols);
        // We only set the cipher suites if we are not using SPAKE.
        if (!parameters.isSpake()) {
            NativeCrypto.setEnabledCipherSuites(
                    ssl, this, parameters.enabledCipherSuites, parameters.enabledProtocols);
        }

        if (parameters.applicationProtocols.length > 0) {
            NativeCrypto.setApplicationProtocols(ssl, this, isClient(), parameters.applicationProtocols);
        }
        if (!isClient() && parameters.applicationProtocolSelector != null) {
            NativeCrypto.setHasApplicationProtocolSelector(ssl, this, true);
        }

        // setup server certificates and private keys.
        // clients will receive a call back to request certificates.
        if (!isClient()) {
            NativeCrypto.SSL_set_options(ssl, this, SSL_OP_CIPHER_SERVER_PREFERENCE);

            if (parameters.sctExtension != null) {
                NativeCrypto.SSL_set_signed_cert_timestamp_list(ssl, this, parameters.sctExtension);
            }

            if (parameters.ocspResponse != null) {
                NativeCrypto.SSL_set_ocsp_response(ssl, this, parameters.ocspResponse);
            }
        }

        enablePSKKeyManagerIfRequested();

        if (parameters.useSessionTickets) {
            NativeCrypto.SSL_clear_options(ssl, this, SSL_OP_NO_TICKET);
        } else {
            NativeCrypto.SSL_set_options(
                    ssl, this, NativeCrypto.SSL_get_options(ssl, this) | SSL_OP_NO_TICKET);
        }

        if (parameters.getUseSni() && AddressUtils.isValidSniHostname(hostname)) {
            NativeCrypto.SSL_set_tlsext_host_name(ssl, this, hostname);
        }

        // BEAST attack mitigation (1/n-1 record splitting for CBC cipher suites
        // with TLSv1 and SSLv3).
        NativeCrypto.SSL_set_mode(ssl, this, SSL_MODE_CBC_RECORD_SPLITTING);

        if (!parameters.isSpake()) {
            setCertificateValidation();
        }
        setTlsChannelId(channelIdPrivateKey);
    }
A utility wrapper that abstracts operations on the underlying native SSL instance.
common/src/main/java/org/conscrypt/NativeSsl.java