0
# SSL Security
1
2
SSL context factories for secure communication with support for custom keystores and truststores. The SSL framework provides flexible certificate management and secure connection establishment for client applications.
3
4
## Capabilities
5
6
### AbstractSslContextFactory
7
8
Abstract base class for SSL context creation with keystore and truststore support.
9
10
```java { .api }
11
/**
12
* Abstract base class for SSL context creation with keystore and truststore support
13
*/
14
public abstract class AbstractSslContextFactory {
15
/**
16
* Default socket algorithm constant
17
*/
18
public static final String SOCKET_ALGORITHM = "SSL";
19
20
/**
21
* Protected constructor for SSL context factory
22
* @param trustStore the truststore containing trusted certificates
23
* @param trustStorePassword password for the truststore
24
* @param keyStore the keystore containing client certificates and private keys
25
* @param keyStorePassword password for the keystore
26
*/
27
protected AbstractSslContextFactory(KeyStore trustStore, String trustStorePassword,
28
KeyStore keyStore, String keyStorePassword);
29
30
/**
31
* Gets the keystore
32
* @return the keystore used by this factory
33
*/
34
public KeyStore getKeyStore();
35
36
/**
37
* Gets the truststore
38
* @return the truststore used by this factory
39
*/
40
public KeyStore getTrustStore();
41
42
/**
43
* Gets keystore password length
44
* @return length of the keystore password (for security validation)
45
*/
46
public int getKeyStorePasswordLength();
47
48
/**
49
* Gets truststore password length
50
* @return length of the truststore password (for security validation)
51
*/
52
public int getTrustStorePasswordLength();
53
54
/**
55
* Creates SSL context
56
* @return configured SSLContext ready for use
57
* @throws ClientSslSocketFactoryException if SSL context creation fails
58
*/
59
public SSLContext getSSLContext() throws ClientSslSocketFactoryException;
60
}
61
```
62
63
### URLSslContextFactory
64
65
SSL context factory that loads keystores from URLs.
66
67
```java { .api }
68
/**
69
* SSL context factory that loads keystores from URLs
70
*/
71
public class URLSslContextFactory extends AbstractSslContextFactory {
72
/**
73
* Creates SSL context factory loading keystores from URLs
74
* @param trustStoreUrl URL to the truststore file
75
* @param trustStorePassword password for the truststore
76
* @param keyStoreUrl URL to the keystore file
77
* @param keyStorePassword password for the keystore
78
* @throws ClientSslSocketFactoryException if keystore loading fails
79
*/
80
public URLSslContextFactory(URL trustStoreUrl, String trustStorePassword,
81
URL keyStoreUrl, String keyStorePassword)
82
throws ClientSslSocketFactoryException;
83
84
/**
85
* String representation of the factory
86
* @return string describing this SSL factory configuration
87
*/
88
public String toString();
89
}
90
```
91
92
**Usage Examples:**
93
94
```java
95
import com.netflix.client.ssl.*;
96
import javax.net.ssl.SSLContext;
97
import java.net.URL;
98
import java.security.KeyStore;
99
100
// Creating SSL context factory from URLs
101
try {
102
URL trustStoreUrl = new URL("file:///path/to/truststore.jks");
103
URL keyStoreUrl = new URL("file:///path/to/keystore.jks");
104
105
URLSslContextFactory factory = new URLSslContextFactory(
106
trustStoreUrl, "truststore-password",
107
keyStoreUrl, "keystore-password"
108
);
109
110
SSLContext sslContext = factory.getSSLContext();
111
112
// Use SSL context for secure connections
113
configureHttpsClient(sslContext);
114
115
} catch (ClientSslSocketFactoryException e) {
116
logger.error("Failed to create SSL context", e);
117
// Fall back to default SSL configuration
118
}
119
120
// Loading from classpath resources
121
URL trustStoreUrl = getClass().getResource("/ssl/truststore.jks");
122
URL keyStoreUrl = getClass().getResource("/ssl/client-keystore.jks");
123
124
URLSslContextFactory factory = new URLSslContextFactory(
125
trustStoreUrl, System.getProperty("ssl.truststore.password"),
126
keyStoreUrl, System.getProperty("ssl.keystore.password")
127
);
128
```
129
130
### Custom SSL Context Factory Implementation
131
132
```java
133
/**
134
* Example custom SSL context factory for specific certificate management needs
135
*/
136
public class CustomSslContextFactory extends AbstractSslContextFactory {
137
private final String certificateAlias;
138
139
public CustomSslContextFactory(KeyStore trustStore, String trustStorePassword,
140
KeyStore keyStore, String keyStorePassword,
141
String certificateAlias) {
142
super(trustStore, trustStorePassword, keyStore, keyStorePassword);
143
this.certificateAlias = certificateAlias;
144
}
145
146
@Override
147
public SSLContext getSSLContext() throws ClientSslSocketFactoryException {
148
try {
149
// Create SSL context with custom certificate selection
150
SSLContext context = SSLContext.getInstance("TLS");
151
152
// Initialize with custom key manager that uses specific certificate alias
153
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
154
kmf.init(getKeyStore(), getKeyStorePassword().toCharArray());
155
156
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
157
tmf.init(getTrustStore());
158
159
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
160
161
return context;
162
163
} catch (Exception e) {
164
throw new ClientSslSocketFactoryException("Failed to create custom SSL context", e);
165
}
166
}
167
168
private String getKeyStorePassword() {
169
// Custom password retrieval logic
170
return System.getProperty("client.keystore.password");
171
}
172
}
173
```
174
175
### SSL Configuration Patterns
176
177
```java
178
/**
179
* SSL configuration manager for different environments
180
*/
181
public class SslConfigurationManager {
182
private static final Logger logger = LoggerFactory.getLogger(SslConfigurationManager.class);
183
184
/**
185
* Creates SSL context factory for production environment
186
*/
187
public static AbstractSslContextFactory createProductionFactory()
188
throws ClientSslSocketFactoryException {
189
try {
190
// Load from secure configuration
191
URL trustStoreUrl = new URL(System.getProperty("ssl.truststore.url"));
192
URL keyStoreUrl = new URL(System.getProperty("ssl.keystore.url"));
193
194
String trustStorePassword = System.getProperty("ssl.truststore.password");
195
String keyStorePassword = System.getProperty("ssl.keystore.password");
196
197
return new URLSslContextFactory(trustStoreUrl, trustStorePassword,
198
keyStoreUrl, keyStorePassword);
199
200
} catch (Exception e) {
201
throw new ClientSslSocketFactoryException("Failed to create production SSL factory", e);
202
}
203
}
204
205
/**
206
* Creates SSL context factory for development environment
207
*/
208
public static AbstractSslContextFactory createDevelopmentFactory()
209
throws ClientSslSocketFactoryException {
210
try {
211
// Load from classpath for development
212
URL trustStoreUrl = SslConfigurationManager.class.getResource("/ssl/dev-truststore.jks");
213
URL keyStoreUrl = SslConfigurationManager.class.getResource("/ssl/dev-keystore.jks");
214
215
return new URLSslContextFactory(trustStoreUrl, "dev-password",
216
keyStoreUrl, "dev-password");
217
218
} catch (Exception e) {
219
throw new ClientSslSocketFactoryException("Failed to create development SSL factory", e);
220
}
221
}
222
223
/**
224
* Creates SSL context factory with validation
225
*/
226
public static AbstractSslContextFactory createValidatedFactory(
227
URL trustStoreUrl, String trustStorePassword,
228
URL keyStoreUrl, String keyStorePassword) throws ClientSslSocketFactoryException {
229
230
// Validate inputs
231
if (trustStoreUrl == null || keyStoreUrl == null) {
232
throw new ClientSslSocketFactoryException("SSL store URLs cannot be null", null);
233
}
234
235
if (trustStorePassword == null || keyStorePassword == null) {
236
throw new ClientSslSocketFactoryException("SSL store passwords cannot be null", null);
237
}
238
239
// Validate password strength (basic check)
240
if (trustStorePassword.length() < 6 || keyStorePassword.length() < 6) {
241
logger.warn("SSL store passwords are weak (less than 6 characters)");
242
}
243
244
URLSslContextFactory factory = new URLSslContextFactory(
245
trustStoreUrl, trustStorePassword,
246
keyStoreUrl, keyStorePassword
247
);
248
249
// Validate that SSL context can be created
250
SSLContext context = factory.getSSLContext();
251
logger.info("SSL context created successfully: {}", factory.toString());
252
253
return factory;
254
}
255
}
256
```
257
258
### Integration with Client Configuration
259
260
```java
261
/**
262
* Client with SSL support integration
263
*/
264
public class SecureClient {
265
private final SSLContext sslContext;
266
private final IClientConfig config;
267
268
public SecureClient(IClientConfig config) throws ClientSslSocketFactoryException {
269
this.config = config;
270
this.sslContext = createSslContext(config);
271
}
272
273
private SSLContext createSslContext(IClientConfig config) throws ClientSslSocketFactoryException {
274
try {
275
// Get SSL configuration from client config
276
String trustStoreLocation = config.get(CommonClientConfigKey.TrustStore);
277
String trustStorePassword = config.get(CommonClientConfigKey.TrustStorePassword);
278
String keyStoreLocation = config.get(CommonClientConfigKey.KeyStore);
279
String keyStorePassword = config.get(CommonClientConfigKey.KeyStorePassword);
280
281
if (trustStoreLocation != null && keyStoreLocation != null) {
282
// Create factory from configuration
283
URL trustStoreUrl = new URL(trustStoreLocation);
284
URL keyStoreUrl = new URL(keyStoreLocation);
285
286
URLSslContextFactory factory = new URLSslContextFactory(
287
trustStoreUrl, trustStorePassword,
288
keyStoreUrl, keyStorePassword
289
);
290
291
return factory.getSSLContext();
292
} else {
293
// Use default SSL context
294
return SSLContext.getDefault();
295
}
296
297
} catch (Exception e) {
298
throw new ClientSslSocketFactoryException("Failed to create SSL context from configuration", e);
299
}
300
}
301
302
public void executeSecureRequest(ClientRequest request) throws Exception {
303
// Use SSL context for secure communication
304
if (request.getUri().getScheme().equals("https")) {
305
// Configure HTTPS connection with SSL context
306
configureHttpsConnection(sslContext);
307
}
308
309
// Execute request
310
}
311
312
private void configureHttpsConnection(SSLContext sslContext) {
313
// Configure HTTPS connection to use the SSL context
314
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
315
}
316
}
317
```
318
319
### SSL Troubleshooting and Validation
320
321
```java
322
/**
323
* SSL diagnostic utilities
324
*/
325
public class SslDiagnostics {
326
private static final Logger logger = LoggerFactory.getLogger(SslDiagnostics.class);
327
328
/**
329
* Validates SSL factory configuration
330
*/
331
public static void validateSslFactory(AbstractSslContextFactory factory) {
332
try {
333
logger.info("Validating SSL factory: {}", factory.toString());
334
335
// Check keystore
336
KeyStore keyStore = factory.getKeyStore();
337
if (keyStore != null) {
338
logger.info("Keystore loaded with {} entries", keyStore.size());
339
logKeyStoreAliases(keyStore);
340
} else {
341
logger.warn("No keystore configured");
342
}
343
344
// Check truststore
345
KeyStore trustStore = factory.getTrustStore();
346
if (trustStore != null) {
347
logger.info("Truststore loaded with {} entries", trustStore.size());
348
logTrustStoreAliases(trustStore);
349
} else {
350
logger.warn("No truststore configured");
351
}
352
353
// Validate password lengths
354
int keyStorePasswordLength = factory.getKeyStorePasswordLength();
355
int trustStorePasswordLength = factory.getTrustStorePasswordLength();
356
357
logger.info("Keystore password length: {}", keyStorePasswordLength);
358
logger.info("Truststore password length: {}", trustStorePasswordLength);
359
360
// Test SSL context creation
361
SSLContext context = factory.getSSLContext();
362
logger.info("SSL context created successfully: {}", context.getProtocol());
363
364
} catch (Exception e) {
365
logger.error("SSL factory validation failed", e);
366
}
367
}
368
369
private static void logKeyStoreAliases(KeyStore keyStore) {
370
try {
371
Enumeration<String> aliases = keyStore.aliases();
372
while (aliases.hasMoreElements()) {
373
String alias = aliases.nextElement();
374
boolean isKey = keyStore.isKeyEntry(alias);
375
boolean isCert = keyStore.isCertificateEntry(alias);
376
logger.debug("Keystore alias: {} (key: {}, cert: {})", alias, isKey, isCert);
377
}
378
} catch (Exception e) {
379
logger.warn("Could not enumerate keystore aliases", e);
380
}
381
}
382
383
private static void logTrustStoreAliases(KeyStore trustStore) {
384
try {
385
Enumeration<String> aliases = trustStore.aliases();
386
while (aliases.hasMoreElements()) {
387
String alias = aliases.nextElement();
388
logger.debug("Truststore alias: {}", alias);
389
}
390
} catch (Exception e) {
391
logger.warn("Could not enumerate truststore aliases", e);
392
}
393
}
394
}