or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

content-streaming.mdhttp-clients.mdhttp-messages.mdindex.mdmetrics.mdservice-discovery.mdtls-configuration.md

tls-configuration.mddocs/

0

# TLS and SSL Configuration

1

2

Comprehensive TLS/SSL configuration providers for client authentication and server certificate validation. Includes file-based and system property-based key manager providers, supporting various keystore formats and authentication scenarios.

3

4

## Capabilities

5

6

### TlsKeyManagersProvider

7

8

Functional interface for providing KeyManagers used in client TLS authentication. Implementations supply the key managers that contain client certificates and private keys.

9

10

```java { .api }

11

/**

12

* Provider for KeyManagers used in client TLS authentication.

13

* KeyManagers contain the client certificates and private keys used

14

* for mutual TLS authentication with servers.

15

*/

16

@FunctionalInterface

17

public interface TlsKeyManagersProvider {

18

/**

19

* Provide key managers for TLS client authentication

20

* @return Array of KeyManagers, or null if no client authentication is needed

21

*/

22

KeyManager[] keyManagers();

23

24

/**

25

* Provider that returns null (no client authentication)

26

* @return TlsKeyManagersProvider that provides no key managers

27

*/

28

static TlsKeyManagersProvider noneProvider();

29

}

30

```

31

32

**Usage Example:**

33

34

```java

35

// Custom key manager provider

36

TlsKeyManagersProvider customProvider = () -> {

37

try {

38

KeyStore keyStore = loadClientKeyStore();

39

KeyManagerFactory factory = KeyManagerFactory.getInstance("SunX509");

40

factory.init(keyStore, "keystore-password".toCharArray());

41

return factory.getKeyManagers();

42

} catch (Exception e) {

43

throw new RuntimeException("Failed to load client key managers", e);

44

}

45

};

46

47

// No client authentication

48

TlsKeyManagersProvider noAuth = TlsKeyManagersProvider.noneProvider();

49

50

// Using with HTTP client builder

51

MyHttpClient.Builder builder = MyHttpClient.builder()

52

.tlsKeyManagersProvider(customProvider);

53

```

54

55

### FileStoreTlsKeyManagersProvider

56

57

Provider that loads key managers from a file-based keystore. Supports various keystore formats including JKS, PKCS12, and others.

58

59

```java { .api }

60

/**

61

* Loads key managers from a file-based key store.

62

* Supports standard Java keystore formats (JKS, PKCS12, etc.).

63

*/

64

public final class FileStoreTlsKeyManagersProvider extends AbstractFileStoreTlsKeyManagersProvider {

65

/**

66

* Load key managers from the configured keystore file

67

* @return Array of KeyManagers loaded from the file store

68

*/

69

@Override

70

public KeyManager[] keyManagers();

71

72

/**

73

* Create a file store provider from keystore file

74

* @param path Path to the keystore file

75

* @param type Keystore type (e.g., "JKS", "PKCS12")

76

* @param password Password for the keystore

77

* @return FileStoreTlsKeyManagersProvider instance

78

*/

79

public static FileStoreTlsKeyManagersProvider create(Path path, String type, String password);

80

}

81

```

82

83

**Usage Examples:**

84

85

```java

86

// Load from JKS keystore

87

FileStoreTlsKeyManagersProvider jksProvider = FileStoreTlsKeyManagersProvider.create(

88

Paths.get("/path/to/client.jks"),

89

"JKS",

90

"keystore-password"

91

);

92

93

// Load from PKCS12 keystore

94

FileStoreTlsKeyManagersProvider p12Provider = FileStoreTlsKeyManagersProvider.create(

95

Paths.get("/path/to/client.p12"),

96

"PKCS12",

97

"keystore-password"

98

);

99

100

// Using with HTTP client

101

SdkHttpClient client = httpClientBuilder

102

.tlsKeyManagersProvider(jksProvider)

103

.build();

104

105

// Load from environment-specified location

106

String keystorePath = System.getenv("CLIENT_KEYSTORE_PATH");

107

String keystorePass = System.getenv("CLIENT_KEYSTORE_PASSWORD");

108

109

if (keystorePath != null && keystorePass != null) {

110

FileStoreTlsKeyManagersProvider envProvider = FileStoreTlsKeyManagersProvider.create(

111

Paths.get(keystorePath),

112

"PKCS12", // or detect from file extension

113

keystorePass

114

);

115

clientBuilder.tlsKeyManagersProvider(envProvider);

116

}

117

```

118

119

### SystemPropertyTlsKeyManagersProvider

120

121

Provider that loads key managers from standard JSSE system properties. Uses the same properties that the JVM uses for default SSL context configuration.

122

123

```java { .api }

124

/**

125

* Loads key managers from standard JSSE system properties.

126

* Uses javax.net.ssl.keyStore, javax.net.ssl.keyStorePassword,

127

* and javax.net.ssl.keyStoreType system properties.

128

*/

129

public final class SystemPropertyTlsKeyManagersProvider extends AbstractFileStoreTlsKeyManagersProvider {

130

/**

131

* Load key managers from system properties

132

* @return Array of KeyManagers loaded from system property configuration

133

*/

134

@Override

135

public KeyManager[] keyManagers();

136

137

/**

138

* Create a system property provider

139

* @return SystemPropertyTlsKeyManagersProvider instance

140

*/

141

public static SystemPropertyTlsKeyManagersProvider create();

142

}

143

```

144

145

**Usage Example:**

146

147

```java

148

// Using system properties

149

SystemPropertyTlsKeyManagersProvider sysProvider = SystemPropertyTlsKeyManagersProvider.create();

150

151

// The provider will read these system properties:

152

// -Djavax.net.ssl.keyStore=/path/to/client.jks

153

// -Djavax.net.ssl.keyStorePassword=password

154

// -Djavax.net.ssl.keyStoreType=JKS

155

156

// Using with HTTP client

157

SdkHttpClient client = httpClientBuilder

158

.tlsKeyManagersProvider(sysProvider)

159

.build();

160

161

// Command line example:

162

// java -Djavax.net.ssl.keyStore=/etc/ssl/client.p12 \

163

// -Djavax.net.ssl.keyStorePassword=secret \

164

// -Djavax.net.ssl.keyStoreType=PKCS12 \

165

// MyApplication

166

```

167

168

### TlsTrustManagersProvider

169

170

Functional interface for providing TrustManagers used in server certificate validation. Implementations supply trust managers that validate server certificates.

171

172

```java { .api }

173

/**

174

* Provider for TrustManagers used in server certificate validation.

175

* TrustManagers determine which server certificates to trust during

176

* TLS handshake.

177

*/

178

@FunctionalInterface

179

public interface TlsTrustManagersProvider {

180

/**

181

* Provide trust managers for server certificate validation

182

* @return Array of TrustManagers, or null to use system default trust store

183

*/

184

TrustManager[] trustManagers();

185

}

186

```

187

188

**Usage Examples:**

189

190

```java

191

// Custom trust store

192

TlsTrustManagersProvider customTrust = () -> {

193

try {

194

KeyStore trustStore = loadCustomTrustStore();

195

TrustManagerFactory factory = TrustManagerFactory.getInstance("SunX509");

196

factory.init(trustStore);

197

return factory.getTrustManagers();

198

} catch (Exception e) {

199

throw new RuntimeException("Failed to load trust managers", e);

200

}

201

};

202

203

// Trust all certificates (DANGEROUS - for testing only)

204

TlsTrustManagersProvider trustAll = () -> new TrustManager[] {

205

new X509TrustManager() {

206

@Override

207

public void checkClientTrusted(X509Certificate[] chain, String authType) {

208

// Accept all

209

}

210

211

@Override

212

public void checkServerTrusted(X509Certificate[] chain, String authType) {

213

// Accept all

214

}

215

216

@Override

217

public X509Certificate[] getAcceptedIssuers() {

218

return new X509Certificate[0];

219

}

220

}

221

};

222

223

// System default trust store

224

TlsTrustManagersProvider systemDefault = () -> null; // Uses system default

225

```

226

227

## Configuration Patterns

228

229

### Mutual TLS Authentication

230

231

Complete setup for mutual TLS (client certificate authentication):

232

233

```java

234

// Load client certificate and private key

235

FileStoreTlsKeyManagersProvider keyProvider = FileStoreTlsKeyManagersProvider.create(

236

Paths.get("/etc/ssl/private/client.p12"),

237

"PKCS12",

238

System.getenv("CLIENT_CERT_PASSWORD")

239

);

240

241

// Load custom CA certificates for server validation

242

TlsTrustManagersProvider trustProvider = () -> {

243

try {

244

KeyStore trustStore = KeyStore.getInstance("JKS");

245

try (InputStream is = Files.newInputStream(Paths.get("/etc/ssl/ca-bundle.jks"))) {

246

trustStore.load(is, "truststore-password".toCharArray());

247

}

248

249

TrustManagerFactory factory = TrustManagerFactory.getInstance("SunX509");

250

factory.init(trustStore);

251

return factory.getTrustManagers();

252

} catch (Exception e) {

253

throw new RuntimeException("Failed to load trust store", e);

254

}

255

};

256

257

// Configure HTTP client with mutual TLS

258

SdkHttpClient client = httpClientBuilder

259

.tlsKeyManagersProvider(keyProvider)

260

.tlsTrustManagersProvider(trustProvider)

261

.build();

262

```

263

264

### Environment-Based Configuration

265

266

Configuration that adapts to deployment environment:

267

268

```java

269

public static TlsKeyManagersProvider createKeyManagerProvider() {

270

// Try system properties first

271

if (System.getProperty("javax.net.ssl.keyStore") != null) {

272

return SystemPropertyTlsKeyManagersProvider.create();

273

}

274

275

// Try environment variables

276

String keystorePath = System.getenv("TLS_KEYSTORE_PATH");

277

String keystorePassword = System.getenv("TLS_KEYSTORE_PASSWORD");

278

String keystoreType = System.getenv("TLS_KEYSTORE_TYPE");

279

280

if (keystorePath != null && keystorePassword != null) {

281

return FileStoreTlsKeyManagersProvider.create(

282

Paths.get(keystorePath),

283

keystoreType != null ? keystoreType : "PKCS12",

284

keystorePassword

285

);

286

}

287

288

// No client authentication

289

return TlsKeyManagersProvider.noneProvider();

290

}

291

292

public static TlsTrustManagersProvider createTrustManagerProvider() {

293

String trustStorePath = System.getenv("TLS_TRUSTSTORE_PATH");

294

String trustStorePassword = System.getenv("TLS_TRUSTSTORE_PASSWORD");

295

296

if (trustStorePath != null) {

297

return () -> {

298

try {

299

KeyStore trustStore = KeyStore.getInstance("JKS");

300

try (InputStream is = Files.newInputStream(Paths.get(trustStorePath))) {

301

trustStore.load(is, trustStorePassword != null ?

302

trustStorePassword.toCharArray() : null);

303

}

304

305

TrustManagerFactory factory = TrustManagerFactory.getInstance("SunX509");

306

factory.init(trustStore);

307

return factory.getTrustManagers();

308

} catch (Exception e) {

309

throw new RuntimeException("Failed to load custom trust store", e);

310

}

311

};

312

}

313

314

// Use system default

315

return () -> null;

316

}

317

```

318

319

### Certificate Validation Strategies

320

321

Different approaches to server certificate validation:

322

323

```java

324

// Strict validation (production)

325

TlsTrustManagersProvider strictValidation = () -> {

326

// Use system default trust store with standard validation

327

return null;

328

};

329

330

// Custom CA validation

331

TlsTrustManagersProvider customCaValidation = () -> {

332

// Load organization-specific CA certificates

333

return loadOrganizationTrustManagers();

334

};

335

336

// Hostname verification bypass (for testing with self-signed certs)

337

TlsTrustManagersProvider lenientValidation = () -> new TrustManager[] {

338

new X509TrustManager() {

339

private final X509TrustManager defaultTrustManager = getDefaultTrustManager();

340

341

@Override

342

public void checkClientTrusted(X509Certificate[] chain, String authType)

343

throws CertificateException {

344

defaultTrustManager.checkClientTrusted(chain, authType);

345

}

346

347

@Override

348

public void checkServerTrusted(X509Certificate[] chain, String authType)

349

throws CertificateException {

350

try {

351

defaultTrustManager.checkServerTrusted(chain, authType);

352

} catch (CertificateException e) {

353

// Log warning but allow self-signed certificates in test environment

354

if (isTestEnvironment()) {

355

logger.warn("Accepting untrusted certificate in test environment", e);

356

} else {

357

throw e;

358

}

359

}

360

}

361

362

@Override

363

public X509Certificate[] getAcceptedIssuers() {

364

return defaultTrustManager.getAcceptedIssuers();

365

}

366

}

367

};

368

```

369

370

## Security Considerations

371

372

### Best Practices

373

374

1. **Never Trust All Certificates in Production**:

375

```java

376

// NEVER do this in production

377

TlsTrustManagersProvider dangerousTrustAll = () -> new TrustManager[] {

378

new X509TrustManager() {

379

public void checkClientTrusted(X509Certificate[] chain, String authType) {}

380

public void checkServerTrusted(X509Certificate[] chain, String authType) {}

381

public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }

382

}

383

};

384

```

385

386

2. **Secure Password Handling**:

387

```java

388

// Read passwords from secure sources

389

String password = System.getenv("KEYSTORE_PASSWORD"); // Environment variable

390

// Or from secure configuration service

391

// Never hardcode passwords in source code

392

```

393

394

3. **Certificate Rotation Support**:

395

```java

396

// Support certificate updates without restart

397

TlsKeyManagersProvider reloadableProvider = new TlsKeyManagersProvider() {

398

private volatile KeyManager[] cachedKeyManagers;

399

private volatile long lastLoadTime;

400

private final long reloadInterval = Duration.ofHours(1).toMillis();

401

402

@Override

403

public KeyManager[] keyManagers() {

404

long now = System.currentTimeMillis();

405

if (cachedKeyManagers == null || (now - lastLoadTime) > reloadInterval) {

406

synchronized (this) {

407

if (cachedKeyManagers == null || (now - lastLoadTime) > reloadInterval) {

408

cachedKeyManagers = loadKeyManagers();

409

lastLoadTime = now;

410

}

411

}

412

}

413

return cachedKeyManagers;

414

}

415

};

416

```

417

418

4. **Error Handling**:

419

```java

420

TlsKeyManagersProvider robustProvider = () -> {

421

try {

422

return loadKeyManagers();

423

} catch (Exception e) {

424

// Log error with sufficient detail for debugging

425

logger.error("Failed to load TLS key managers from {}", keystorePath, e);

426

427

// Decide whether to fail fast or fall back

428

if (isClientAuthRequired()) {

429

throw new RuntimeException("Client authentication required but key managers unavailable", e);

430

} else {

431

logger.warn("Proceeding without client authentication");

432

return null;

433

}

434

}

435

};

436

```

437

438

### Keystore Format Support

439

440

The SPI supports various keystore formats:

441

442

- **JKS**: Java KeyStore (legacy format)

443

- **PKCS12**: Standard format (.p12, .pfx files)

444

- **JCEKS**: Java Cryptography Extension KeyStore

445

- **BKS**: Bouncy Castle KeyStore

446

- **UBER**: Bouncy Castle UBER KeyStore

447

448

Example format detection:

449

450

```java

451

public static String detectKeystoreType(Path keystorePath) {

452

String filename = keystorePath.getFileName().toString().toLowerCase();

453

if (filename.endsWith(".p12") || filename.endsWith(".pfx")) {

454

return "PKCS12";

455

} else if (filename.endsWith(".jks")) {

456

return "JKS";

457

} else if (filename.endsWith(".jceks")) {

458

return "JCEKS";

459

} else {

460

// Default to PKCS12 for modern compatibility

461

return "PKCS12";

462

}

463

}

464

```