CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-eclipse-jetty--jetty-io

Core I/O components for Eclipse Jetty providing essential I/O utilities, buffer management, and network connection handling

Pending
Overview
Eval results
Files

ssl-support.mddocs/

SSL/TLS Support

Jetty IO provides comprehensive SSL/TLS support including secure connections, handshake management, and Application Layer Protocol Negotiation (ALPN) for modern protocol negotiation.

Capabilities

SslConnection

SSL/TLS connection wrapper that provides encryption layer over an existing EndPoint.

/**
 * SSL/TLS connection wrapper providing encryption layer
 */
class SslConnection extends AbstractConnection implements Connection.UpgradeTo {
    public SslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine sslEngine);
    public SslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine sslEngine, boolean useInputDirectByteBuffers, boolean useOutputDirectByteBuffers);
    
    // SSL engine access
    public SSLEngine getSSLEngine();
    
    // SSL session information
    public String getProtocol();
    public String getCipherSuite();
    public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException;
    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException;
    public Principal getLocalPrincipal();
    
    // Connection state
    public boolean isHandshaking();
    public boolean isHandshakeComplete();
    public boolean isOpen();
    
    // Buffer configuration
    public boolean isUseInputDirectByteBuffers();
    public boolean isUseOutputDirectByteBuffers();
    public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers);
    public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers);
    
    // Renegotiation
    public void beginHandshake() throws SSLException;
    public CompletableFuture<Void> handshake();
    
    // Lifecycle
    public void onOpen();
    public void onClose(Throwable cause);
    public void onFillable();
    public boolean onIdleExpired(TimeoutException timeoutException);
    
    // Connection upgrade support
    public void onUpgradeTo(ByteBuffer prefilled);
    
    // Statistics
    public long getBytesIn();
    public long getBytesOut();
    public long getEncryptedBytesIn();
    public long getEncryptedBytesOut();
}

Usage Examples:

// Create SSL connection
SSLEngine sslEngine = sslContextFactory.newSSLEngine("example.com", 443);
sslEngine.setUseClientMode(true);
sslEngine.setWantClientAuth(false);

SslConnection sslConnection = new SslConnection(
    byteBufferPool, 
    executor, 
    tcpEndPoint, 
    sslEngine
);

// Configure buffer usage (direct buffers can be more efficient for SSL)
sslConnection.setUseInputDirectByteBuffers(true);
sslConnection.setUseOutputDirectByteBuffers(true);

// Perform handshake
CompletableFuture<Void> handshakeFuture = sslConnection.handshake();
handshakeFuture.thenRun(() -> {
    System.out.println("SSL handshake completed");
    System.out.println("Protocol: " + sslConnection.getProtocol());
    System.out.println("Cipher suite: " + sslConnection.getCipherSuite());
    
    try {
        Certificate[] peerCerts = sslConnection.getPeerCertificates();
        System.out.println("Peer certificate count: " + peerCerts.length);
    } catch (SSLPeerUnverifiedException e) {
        System.out.println("Peer certificate not verified");
    }
}).exceptionally(throwable -> {
    System.err.println("SSL handshake failed: " + throwable.getMessage());
    return null;
});

// Monitor SSL traffic
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        System.out.printf("SSL Traffic - Plain: %d/%d bytes, Encrypted: %d/%d bytes%n",
            sslConnection.getBytesIn(), sslConnection.getBytesOut(),
            sslConnection.getEncryptedBytesIn(), sslConnection.getEncryptedBytesOut());
    }
}, 0, 10000);

// Manual renegotiation
if (sslConnection.isHandshakeComplete() && !sslConnection.isHandshaking()) {
    try {
        sslConnection.beginHandshake();
        System.out.println("SSL renegotiation initiated");
    } catch (SSLException e) {
        System.err.println("Failed to initiate renegotiation: " + e.getMessage());
    }
}

SslClientConnectionFactory

Factory for creating SSL client connections with automatic SSL context configuration.

/**
 * Creates SSL client connections
 */
class SslClientConnectionFactory implements ClientConnectionFactory {
    public SslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory);
    public SslClientConnectionFactory(SslContextFactory.Client sslContextFactory, String nextProtocol);
    
    public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException;
    public Connection customize(Connection connection, Map<String, Object> context);
    
    // Configuration
    public SslContextFactory.Client getSslContextFactory();
    public ClientConnectionFactory getClientConnectionFactory();
    public String getNextProtocol();
    
    // Direct buffer configuration
    public boolean isDirectBuffersForEncryption();
    public void setDirectBuffersForEncryption(boolean direct);
    public boolean isDirectBuffersForDecryption();
    public void setDirectBuffersForDecryption(boolean direct);
}

Usage Examples:

// SSL context factory configuration
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
sslContextFactory.setTrustAll(false); // Verify server certificates
sslContextFactory.setEndpointIdentificationAlgorithm("HTTPS"); // Enable hostname verification
sslContextFactory.setProtocol("TLS"); // Use TLS protocol
sslContextFactory.setIncludeCipherSuites("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384");
sslContextFactory.setExcludeCipherSuites("SSL_RSA_WITH_DES_CBC_SHA");

// HTTP/1.1 over SSL
ClientConnectionFactory http11Factory = new HttpClientConnectionFactory();
SslClientConnectionFactory sslFactory = new SslClientConnectionFactory(sslContextFactory, http11Factory);

// Direct SSL factory for specific protocol
SslClientConnectionFactory directSslFactory = new SslClientConnectionFactory(sslContextFactory, "http/1.1");

// Configure direct buffers for better performance
sslFactory.setDirectBuffersForEncryption(true);
sslFactory.setDirectBuffersForDecryption(true);

// Create SSL connection
Map<String, Object> context = new HashMap<>();
context.put(ClientConnectionFactory.CLIENT_CONTEXT_KEY, httpClient);
context.put(SslClientConnectionFactory.SSL_CONTEXT_FACTORY_CONTEXT_KEY, sslContextFactory);

Connection sslConnection = sslFactory.newConnection(tcpEndPoint, context);

// Chain multiple factories for protocol layering
ClientConnectionFactory http2Factory = new HTTP2ClientConnectionFactory();
SslClientConnectionFactory http2SslFactory = new SslClientConnectionFactory(sslContextFactory, http2Factory);

// ALPN negotiation factory
ALPNClientConnectionFactory alpnFactory = new ALPNClientConnectionFactory(
    executor, http2SslFactory, "h2", "http/1.1");
SslClientConnectionFactory alpnSslFactory = new SslClientConnectionFactory(sslContextFactory, alpnFactory);

SslHandshakeListener

Event listener for monitoring SSL/TLS handshake process and outcomes.

/**
 * Listener for SSL handshake events
 */
interface SslHandshakeListener extends EventListener {
    /** Called when SSL handshake succeeds */
    default void handshakeSucceeded(Event event) {}
    
    /** Called when SSL handshake fails */
    default void handshakeFailed(Event event, Throwable failure) {}
    
    class Event {
        private final SSLEngine sslEngine;
        
        public Event(SSLEngine sslEngine);
        
        public SSLEngine getSSLEngine();
        public String getProtocol();
        public String getCipherSuite();
        public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException;
        public Principal getPeerPrincipal() throws SSLPeerUnverifiedException;
        public Principal getLocalPrincipal();
    }
}

Usage Examples:

// SSL handshake monitoring
SslHandshakeListener handshakeMonitor = new SslHandshakeListener() {
    @Override
    public void handshakeSucceeded(Event event) {
        System.out.println("SSL handshake succeeded:");
        System.out.println("  Protocol: " + event.getProtocol());
        System.out.println("  Cipher: " + event.getCipherSuite());
        
        try {
            Certificate[] certs = event.getPeerCertificates();
            if (certs.length > 0 && certs[0] instanceof X509Certificate) {
                X509Certificate x509 = (X509Certificate) certs[0];
                System.out.println("  Subject: " + x509.getSubjectDN());
                System.out.println("  Issuer: " + x509.getIssuerDN());
                System.out.println("  Valid until: " + x509.getNotAfter());
            }
        } catch (SSLPeerUnverifiedException e) {
            System.out.println("  Peer not verified: " + e.getMessage());
        }
    }
    
    @Override
    public void handshakeFailed(Event event, Throwable failure) {
        System.err.println("SSL handshake failed: " + failure.getMessage());
        if (failure instanceof SSLException) {
            SSLException sslEx = (SSLException) failure;
            System.err.println("SSL error details: " + sslEx.toString());
        }
    }
};

// Add listener to SSL context factory
sslContextFactory.addEventListener(handshakeMonitor);

// Certificate validation listener
SslHandshakeListener certValidator = new SslHandshakeListener() {
    @Override
    public void handshakeSucceeded(Event event) {
        try {
            Certificate[] certs = event.getPeerCertificates();
            validateCertificateChain(certs);
        } catch (Exception e) {
            System.err.println("Certificate validation failed: " + e.getMessage());
        }
    }
    
    private void validateCertificateChain(Certificate[] certs) throws Exception {
        // Custom certificate validation logic
        if (certs.length == 0) {
            throw new SSLException("No certificates provided");
        }
        
        X509Certificate serverCert = (X509Certificate) certs[0];
        
        // Check certificate validity period
        serverCert.checkValidity();
        
        // Check certificate purpose
        List<String> extKeyUsage = serverCert.getExtendedKeyUsage();
        if (extKeyUsage != null && !extKeyUsage.contains("1.3.6.1.5.5.7.3.1")) { // Server authentication
            throw new SSLException("Certificate not valid for server authentication");
        }
        
        System.out.println("Certificate validation passed");
    }
};

ALPNProcessor

Interface for handling Application Layer Protocol Negotiation (ALPN) during SSL handshake.

/**
 * Interface for ALPN (Application Layer Protocol Negotiation) processing
 */
interface ALPNProcessor {
    /** 
     * Process ALPN negotiation result
     * @param sslEngine the SSL engine
     * @param protocols list of protocols offered by client
     * @param selected the protocol selected by server
     */
    void process(SSLEngine sslEngine, List<String> protocols, String selected);
    
    // Server-side ALPN processor
    abstract class Server implements ALPNProcessor {
        /** Select protocol from client's list */
        public abstract String select(List<String> protocols);
        
        public void process(SSLEngine sslEngine, List<String> protocols, String selected);
    }
    
    // Client-side ALPN processor  
    abstract class Client implements ALPNProcessor {
        private final List<String> protocols;
        
        protected Client(String... protocols);
        
        /** Handle selected protocol */
        public abstract void selected(String protocol);
        
        public List<String> getProtocols();
        public void process(SSLEngine sslEngine, List<String> protocols, String selected);
    }
}

ALPN Usage Examples:

// Server-side ALPN processor
ALPNProcessor.Server serverALPN = new ALPNProcessor.Server() {
    @Override
    public String select(List<String> protocols) {
        System.out.println("Client offered protocols: " + protocols);
        
        // Prefer HTTP/2, fallback to HTTP/1.1
        if (protocols.contains("h2")) {
            return "h2";
        } else if (protocols.contains("http/1.1")) {
            return "http/1.1";
        }
        return null; // No supported protocol
    }
    
    @Override
    public void process(SSLEngine sslEngine, List<String> protocols, String selected) {
        System.out.println("Selected protocol: " + selected);
        super.process(sslEngine, protocols, selected);
    }
};

// Client-side ALPN processor
ALPNProcessor.Client clientALPN = new ALPNProcessor.Client("h2", "http/1.1") {
    @Override
    public void selected(String protocol) {
        System.out.println("Server selected protocol: " + protocol);
        
        switch (protocol) {
            case "h2":
                // Configure for HTTP/2
                configureHTTP2();
                break;
            case "http/1.1":
                // Configure for HTTP/1.1
                configureHTTP11();
                break;
            default:
                System.err.println("Unexpected protocol selected: " + protocol);
        }
    }
    
    private void configureHTTP2() {
        System.out.println("Initializing HTTP/2 configuration");
        // HTTP/2 specific setup
    }
    
    private void configureHTTP11() {
        System.out.println("Initializing HTTP/1.1 configuration");
        // HTTP/1.1 specific setup
    }
};

// Register ALPN processors with SSL context factory
sslContextFactory.addBean(serverALPN); // Server side
sslContextFactory.addBean(clientALPN); // Client side

// Custom ALPN processor for protocol-specific handling
ALPNProcessor customProcessor = new ALPNProcessor() {
    @Override
    public void process(SSLEngine sslEngine, List<String> protocols, String selected) {
        System.out.println("ALPN negotiation completed");
        System.out.println("Offered: " + protocols);
        System.out.println("Selected: " + selected);
        
        // Store selected protocol for later use
        sslEngine.setHandshakeApplicationProtocolSelector((sslEngine1, protocols1) -> {
            // Custom protocol selection logic
            return selectCustomProtocol(protocols1);
        });
    }
    
    private String selectCustomProtocol(List<String> protocols) {
        // Custom protocol selection algorithm
        for (String protocol : protocols) {
            if (protocol.startsWith("custom-")) {
                return protocol;
            }
        }
        return protocols.isEmpty() ? null : protocols.get(0);
    }
};

SSL Configuration Best Practices

/**
 * SSL context factory configuration examples
 */
class SSLConfigurationExamples {
    public static SslContextFactory.Client createSecureClient() {
        SslContextFactory.Client factory = new SslContextFactory.Client();
        
        // Security settings
        factory.setTrustAll(false); // Always verify certificates
        factory.setEndpointIdentificationAlgorithm("HTTPS"); // Enable hostname verification
        factory.setRenegotiationAllowed(false); // Disable renegotiation for security
        
        // Protocol configuration
        factory.setProtocol("TLS");
        factory.setIncludeProtocols("TLSv1.2", "TLSv1.3");
        factory.setExcludeProtocols("SSLv2", "SSLv3", "TLSv1", "TLSv1.1");
        
        // Cipher suite configuration
        factory.setIncludeCipherSuites(
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
            "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
        );
        factory.setExcludeCipherSuites(
            ".*_DES_.*", ".*_RC4_.*", ".*_MD5$", ".*_SHA$"
        );
        
        return factory;
    }
    
    public static SslContextFactory.Server createSecureServer(Path keystorePath, String keystorePassword) {
        SslContextFactory.Server factory = new SslContextFactory.Server();
        
        // Keystore configuration
        factory.setKeyStorePath(keystorePath.toString());
        factory.setKeyStorePassword(keystorePassword);
        factory.setKeyStoreType("PKCS12");
        
        // Client authentication
        factory.setWantClientAuth(true); // Request client certificates
        factory.setNeedClientAuth(false); // But don't require them
        
        // Security settings
        factory.setRenegotiationAllowed(false);
        factory.setSessionCachingEnabled(true);
        factory.setSessionTimeout(3600); // 1 hour session timeout
        
        // Protocol and cipher configuration (same as client)
        factory.setProtocol("TLS");
        factory.setIncludeProtocols("TLSv1.2", "TLSv1.3");
        // ... cipher suites as above
        
        return factory;
    }
}

Configuration Usage:

// Secure client configuration
SslContextFactory.Client clientSSL = SSLConfigurationExamples.createSecureClient();

// Custom truststore for client
clientSSL.setTrustStorePath("/path/to/truststore.p12");
clientSSL.setTrustStorePassword("truststore-password");
clientSSL.setTrustStoreType("PKCS12");

// Client certificate authentication
clientSSL.setKeyStorePath("/path/to/client-keystore.p12");
clientSSL.setKeyStorePassword("client-keystore-password");

// SNI (Server Name Indication) configuration
clientSSL.setSNIMatchers(
    new SNIMatcher(StandardConstants.SNI_HOST_NAME) {
        @Override
        public boolean matches(SNIServerName serverName) {
            return serverName.getAsciiName().endsWith(".example.com");
        }
    }
);

// Start SSL context factory
clientSSL.start();

// Create SSL connection factory
ClientConnectionFactory httpFactory = new HttpClientConnectionFactory();
SslClientConnectionFactory sslFactory = new SslClientConnectionFactory(clientSSL, httpFactory);

Install with Tessl CLI

npx tessl i tessl/maven-org-eclipse-jetty--jetty-io

docs

buffer-management.md

connection-management.md

content-streaming.md

core-io.md

index.md

selector-management.md

ssl-support.md

tile.json