or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

buffer-management.mdconnection-management.mdcontent-streaming.mdcore-io.mdindex.mdselector-management.mdssl-support.md

ssl-support.mddocs/

0

# SSL/TLS Support

1

2

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

3

4

## Capabilities

5

6

### SslConnection

7

8

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

9

10

```java { .api }

11

/**

12

* SSL/TLS connection wrapper providing encryption layer

13

*/

14

class SslConnection extends AbstractConnection implements Connection.UpgradeTo {

15

public SslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine sslEngine);

16

public SslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine sslEngine, boolean useInputDirectByteBuffers, boolean useOutputDirectByteBuffers);

17

18

// SSL engine access

19

public SSLEngine getSSLEngine();

20

21

// SSL session information

22

public String getProtocol();

23

public String getCipherSuite();

24

public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException;

25

public Principal getPeerPrincipal() throws SSLPeerUnverifiedException;

26

public Principal getLocalPrincipal();

27

28

// Connection state

29

public boolean isHandshaking();

30

public boolean isHandshakeComplete();

31

public boolean isOpen();

32

33

// Buffer configuration

34

public boolean isUseInputDirectByteBuffers();

35

public boolean isUseOutputDirectByteBuffers();

36

public void setUseInputDirectByteBuffers(boolean useInputDirectByteBuffers);

37

public void setUseOutputDirectByteBuffers(boolean useOutputDirectByteBuffers);

38

39

// Renegotiation

40

public void beginHandshake() throws SSLException;

41

public CompletableFuture<Void> handshake();

42

43

// Lifecycle

44

public void onOpen();

45

public void onClose(Throwable cause);

46

public void onFillable();

47

public boolean onIdleExpired(TimeoutException timeoutException);

48

49

// Connection upgrade support

50

public void onUpgradeTo(ByteBuffer prefilled);

51

52

// Statistics

53

public long getBytesIn();

54

public long getBytesOut();

55

public long getEncryptedBytesIn();

56

public long getEncryptedBytesOut();

57

}

58

```

59

60

**Usage Examples:**

61

62

```java

63

// Create SSL connection

64

SSLEngine sslEngine = sslContextFactory.newSSLEngine("example.com", 443);

65

sslEngine.setUseClientMode(true);

66

sslEngine.setWantClientAuth(false);

67

68

SslConnection sslConnection = new SslConnection(

69

byteBufferPool,

70

executor,

71

tcpEndPoint,

72

sslEngine

73

);

74

75

// Configure buffer usage (direct buffers can be more efficient for SSL)

76

sslConnection.setUseInputDirectByteBuffers(true);

77

sslConnection.setUseOutputDirectByteBuffers(true);

78

79

// Perform handshake

80

CompletableFuture<Void> handshakeFuture = sslConnection.handshake();

81

handshakeFuture.thenRun(() -> {

82

System.out.println("SSL handshake completed");

83

System.out.println("Protocol: " + sslConnection.getProtocol());

84

System.out.println("Cipher suite: " + sslConnection.getCipherSuite());

85

86

try {

87

Certificate[] peerCerts = sslConnection.getPeerCertificates();

88

System.out.println("Peer certificate count: " + peerCerts.length);

89

} catch (SSLPeerUnverifiedException e) {

90

System.out.println("Peer certificate not verified");

91

}

92

}).exceptionally(throwable -> {

93

System.err.println("SSL handshake failed: " + throwable.getMessage());

94

return null;

95

});

96

97

// Monitor SSL traffic

98

Timer timer = new Timer();

99

timer.scheduleAtFixedRate(new TimerTask() {

100

@Override

101

public void run() {

102

System.out.printf("SSL Traffic - Plain: %d/%d bytes, Encrypted: %d/%d bytes%n",

103

sslConnection.getBytesIn(), sslConnection.getBytesOut(),

104

sslConnection.getEncryptedBytesIn(), sslConnection.getEncryptedBytesOut());

105

}

106

}, 0, 10000);

107

108

// Manual renegotiation

109

if (sslConnection.isHandshakeComplete() && !sslConnection.isHandshaking()) {

110

try {

111

sslConnection.beginHandshake();

112

System.out.println("SSL renegotiation initiated");

113

} catch (SSLException e) {

114

System.err.println("Failed to initiate renegotiation: " + e.getMessage());

115

}

116

}

117

```

118

119

### SslClientConnectionFactory

120

121

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

122

123

```java { .api }

124

/**

125

* Creates SSL client connections

126

*/

127

class SslClientConnectionFactory implements ClientConnectionFactory {

128

public SslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory);

129

public SslClientConnectionFactory(SslContextFactory.Client sslContextFactory, String nextProtocol);

130

131

public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException;

132

public Connection customize(Connection connection, Map<String, Object> context);

133

134

// Configuration

135

public SslContextFactory.Client getSslContextFactory();

136

public ClientConnectionFactory getClientConnectionFactory();

137

public String getNextProtocol();

138

139

// Direct buffer configuration

140

public boolean isDirectBuffersForEncryption();

141

public void setDirectBuffersForEncryption(boolean direct);

142

public boolean isDirectBuffersForDecryption();

143

public void setDirectBuffersForDecryption(boolean direct);

144

}

145

```

146

147

**Usage Examples:**

148

149

```java

150

// SSL context factory configuration

151

SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();

152

sslContextFactory.setTrustAll(false); // Verify server certificates

153

sslContextFactory.setEndpointIdentificationAlgorithm("HTTPS"); // Enable hostname verification

154

sslContextFactory.setProtocol("TLS"); // Use TLS protocol

155

sslContextFactory.setIncludeCipherSuites("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384");

156

sslContextFactory.setExcludeCipherSuites("SSL_RSA_WITH_DES_CBC_SHA");

157

158

// HTTP/1.1 over SSL

159

ClientConnectionFactory http11Factory = new HttpClientConnectionFactory();

160

SslClientConnectionFactory sslFactory = new SslClientConnectionFactory(sslContextFactory, http11Factory);

161

162

// Direct SSL factory for specific protocol

163

SslClientConnectionFactory directSslFactory = new SslClientConnectionFactory(sslContextFactory, "http/1.1");

164

165

// Configure direct buffers for better performance

166

sslFactory.setDirectBuffersForEncryption(true);

167

sslFactory.setDirectBuffersForDecryption(true);

168

169

// Create SSL connection

170

Map<String, Object> context = new HashMap<>();

171

context.put(ClientConnectionFactory.CLIENT_CONTEXT_KEY, httpClient);

172

context.put(SslClientConnectionFactory.SSL_CONTEXT_FACTORY_CONTEXT_KEY, sslContextFactory);

173

174

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

175

176

// Chain multiple factories for protocol layering

177

ClientConnectionFactory http2Factory = new HTTP2ClientConnectionFactory();

178

SslClientConnectionFactory http2SslFactory = new SslClientConnectionFactory(sslContextFactory, http2Factory);

179

180

// ALPN negotiation factory

181

ALPNClientConnectionFactory alpnFactory = new ALPNClientConnectionFactory(

182

executor, http2SslFactory, "h2", "http/1.1");

183

SslClientConnectionFactory alpnSslFactory = new SslClientConnectionFactory(sslContextFactory, alpnFactory);

184

```

185

186

### SslHandshakeListener

187

188

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

189

190

```java { .api }

191

/**

192

* Listener for SSL handshake events

193

*/

194

interface SslHandshakeListener extends EventListener {

195

/** Called when SSL handshake succeeds */

196

default void handshakeSucceeded(Event event) {}

197

198

/** Called when SSL handshake fails */

199

default void handshakeFailed(Event event, Throwable failure) {}

200

201

class Event {

202

private final SSLEngine sslEngine;

203

204

public Event(SSLEngine sslEngine);

205

206

public SSLEngine getSSLEngine();

207

public String getProtocol();

208

public String getCipherSuite();

209

public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException;

210

public Principal getPeerPrincipal() throws SSLPeerUnverifiedException;

211

public Principal getLocalPrincipal();

212

}

213

}

214

```

215

216

**Usage Examples:**

217

218

```java

219

// SSL handshake monitoring

220

SslHandshakeListener handshakeMonitor = new SslHandshakeListener() {

221

@Override

222

public void handshakeSucceeded(Event event) {

223

System.out.println("SSL handshake succeeded:");

224

System.out.println(" Protocol: " + event.getProtocol());

225

System.out.println(" Cipher: " + event.getCipherSuite());

226

227

try {

228

Certificate[] certs = event.getPeerCertificates();

229

if (certs.length > 0 && certs[0] instanceof X509Certificate) {

230

X509Certificate x509 = (X509Certificate) certs[0];

231

System.out.println(" Subject: " + x509.getSubjectDN());

232

System.out.println(" Issuer: " + x509.getIssuerDN());

233

System.out.println(" Valid until: " + x509.getNotAfter());

234

}

235

} catch (SSLPeerUnverifiedException e) {

236

System.out.println(" Peer not verified: " + e.getMessage());

237

}

238

}

239

240

@Override

241

public void handshakeFailed(Event event, Throwable failure) {

242

System.err.println("SSL handshake failed: " + failure.getMessage());

243

if (failure instanceof SSLException) {

244

SSLException sslEx = (SSLException) failure;

245

System.err.println("SSL error details: " + sslEx.toString());

246

}

247

}

248

};

249

250

// Add listener to SSL context factory

251

sslContextFactory.addEventListener(handshakeMonitor);

252

253

// Certificate validation listener

254

SslHandshakeListener certValidator = new SslHandshakeListener() {

255

@Override

256

public void handshakeSucceeded(Event event) {

257

try {

258

Certificate[] certs = event.getPeerCertificates();

259

validateCertificateChain(certs);

260

} catch (Exception e) {

261

System.err.println("Certificate validation failed: " + e.getMessage());

262

}

263

}

264

265

private void validateCertificateChain(Certificate[] certs) throws Exception {

266

// Custom certificate validation logic

267

if (certs.length == 0) {

268

throw new SSLException("No certificates provided");

269

}

270

271

X509Certificate serverCert = (X509Certificate) certs[0];

272

273

// Check certificate validity period

274

serverCert.checkValidity();

275

276

// Check certificate purpose

277

List<String> extKeyUsage = serverCert.getExtendedKeyUsage();

278

if (extKeyUsage != null && !extKeyUsage.contains("1.3.6.1.5.5.7.3.1")) { // Server authentication

279

throw new SSLException("Certificate not valid for server authentication");

280

}

281

282

System.out.println("Certificate validation passed");

283

}

284

};

285

```

286

287

### ALPNProcessor

288

289

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

290

291

```java { .api }

292

/**

293

* Interface for ALPN (Application Layer Protocol Negotiation) processing

294

*/

295

interface ALPNProcessor {

296

/**

297

* Process ALPN negotiation result

298

* @param sslEngine the SSL engine

299

* @param protocols list of protocols offered by client

300

* @param selected the protocol selected by server

301

*/

302

void process(SSLEngine sslEngine, List<String> protocols, String selected);

303

304

// Server-side ALPN processor

305

abstract class Server implements ALPNProcessor {

306

/** Select protocol from client's list */

307

public abstract String select(List<String> protocols);

308

309

public void process(SSLEngine sslEngine, List<String> protocols, String selected);

310

}

311

312

// Client-side ALPN processor

313

abstract class Client implements ALPNProcessor {

314

private final List<String> protocols;

315

316

protected Client(String... protocols);

317

318

/** Handle selected protocol */

319

public abstract void selected(String protocol);

320

321

public List<String> getProtocols();

322

public void process(SSLEngine sslEngine, List<String> protocols, String selected);

323

}

324

}

325

```

326

327

**ALPN Usage Examples:**

328

329

```java

330

// Server-side ALPN processor

331

ALPNProcessor.Server serverALPN = new ALPNProcessor.Server() {

332

@Override

333

public String select(List<String> protocols) {

334

System.out.println("Client offered protocols: " + protocols);

335

336

// Prefer HTTP/2, fallback to HTTP/1.1

337

if (protocols.contains("h2")) {

338

return "h2";

339

} else if (protocols.contains("http/1.1")) {

340

return "http/1.1";

341

}

342

return null; // No supported protocol

343

}

344

345

@Override

346

public void process(SSLEngine sslEngine, List<String> protocols, String selected) {

347

System.out.println("Selected protocol: " + selected);

348

super.process(sslEngine, protocols, selected);

349

}

350

};

351

352

// Client-side ALPN processor

353

ALPNProcessor.Client clientALPN = new ALPNProcessor.Client("h2", "http/1.1") {

354

@Override

355

public void selected(String protocol) {

356

System.out.println("Server selected protocol: " + protocol);

357

358

switch (protocol) {

359

case "h2":

360

// Configure for HTTP/2

361

configureHTTP2();

362

break;

363

case "http/1.1":

364

// Configure for HTTP/1.1

365

configureHTTP11();

366

break;

367

default:

368

System.err.println("Unexpected protocol selected: " + protocol);

369

}

370

}

371

372

private void configureHTTP2() {

373

System.out.println("Initializing HTTP/2 configuration");

374

// HTTP/2 specific setup

375

}

376

377

private void configureHTTP11() {

378

System.out.println("Initializing HTTP/1.1 configuration");

379

// HTTP/1.1 specific setup

380

}

381

};

382

383

// Register ALPN processors with SSL context factory

384

sslContextFactory.addBean(serverALPN); // Server side

385

sslContextFactory.addBean(clientALPN); // Client side

386

387

// Custom ALPN processor for protocol-specific handling

388

ALPNProcessor customProcessor = new ALPNProcessor() {

389

@Override

390

public void process(SSLEngine sslEngine, List<String> protocols, String selected) {

391

System.out.println("ALPN negotiation completed");

392

System.out.println("Offered: " + protocols);

393

System.out.println("Selected: " + selected);

394

395

// Store selected protocol for later use

396

sslEngine.setHandshakeApplicationProtocolSelector((sslEngine1, protocols1) -> {

397

// Custom protocol selection logic

398

return selectCustomProtocol(protocols1);

399

});

400

}

401

402

private String selectCustomProtocol(List<String> protocols) {

403

// Custom protocol selection algorithm

404

for (String protocol : protocols) {

405

if (protocol.startsWith("custom-")) {

406

return protocol;

407

}

408

}

409

return protocols.isEmpty() ? null : protocols.get(0);

410

}

411

};

412

```

413

414

### SSL Configuration Best Practices

415

416

```java { .api }

417

/**

418

* SSL context factory configuration examples

419

*/

420

class SSLConfigurationExamples {

421

public static SslContextFactory.Client createSecureClient() {

422

SslContextFactory.Client factory = new SslContextFactory.Client();

423

424

// Security settings

425

factory.setTrustAll(false); // Always verify certificates

426

factory.setEndpointIdentificationAlgorithm("HTTPS"); // Enable hostname verification

427

factory.setRenegotiationAllowed(false); // Disable renegotiation for security

428

429

// Protocol configuration

430

factory.setProtocol("TLS");

431

factory.setIncludeProtocols("TLSv1.2", "TLSv1.3");

432

factory.setExcludeProtocols("SSLv2", "SSLv3", "TLSv1", "TLSv1.1");

433

434

// Cipher suite configuration

435

factory.setIncludeCipherSuites(

436

"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",

437

"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",

438

"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"

439

);

440

factory.setExcludeCipherSuites(

441

".*_DES_.*", ".*_RC4_.*", ".*_MD5$", ".*_SHA$"

442

);

443

444

return factory;

445

}

446

447

public static SslContextFactory.Server createSecureServer(Path keystorePath, String keystorePassword) {

448

SslContextFactory.Server factory = new SslContextFactory.Server();

449

450

// Keystore configuration

451

factory.setKeyStorePath(keystorePath.toString());

452

factory.setKeyStorePassword(keystorePassword);

453

factory.setKeyStoreType("PKCS12");

454

455

// Client authentication

456

factory.setWantClientAuth(true); // Request client certificates

457

factory.setNeedClientAuth(false); // But don't require them

458

459

// Security settings

460

factory.setRenegotiationAllowed(false);

461

factory.setSessionCachingEnabled(true);

462

factory.setSessionTimeout(3600); // 1 hour session timeout

463

464

// Protocol and cipher configuration (same as client)

465

factory.setProtocol("TLS");

466

factory.setIncludeProtocols("TLSv1.2", "TLSv1.3");

467

// ... cipher suites as above

468

469

return factory;

470

}

471

}

472

```

473

474

**Configuration Usage:**

475

476

```java

477

// Secure client configuration

478

SslContextFactory.Client clientSSL = SSLConfigurationExamples.createSecureClient();

479

480

// Custom truststore for client

481

clientSSL.setTrustStorePath("/path/to/truststore.p12");

482

clientSSL.setTrustStorePassword("truststore-password");

483

clientSSL.setTrustStoreType("PKCS12");

484

485

// Client certificate authentication

486

clientSSL.setKeyStorePath("/path/to/client-keystore.p12");

487

clientSSL.setKeyStorePassword("client-keystore-password");

488

489

// SNI (Server Name Indication) configuration

490

clientSSL.setSNIMatchers(

491

new SNIMatcher(StandardConstants.SNI_HOST_NAME) {

492

@Override

493

public boolean matches(SNIServerName serverName) {

494

return serverName.getAsciiName().endsWith(".example.com");

495

}

496

}

497

);

498

499

// Start SSL context factory

500

clientSSL.start();

501

502

// Create SSL connection factory

503

ClientConnectionFactory httpFactory = new HttpClientConnectionFactory();

504

SslClientConnectionFactory sslFactory = new SslClientConnectionFactory(clientSSL, httpFactory);

505

```