3
3
import org .dcache .oncrpc4j .rpc .net .IpProtocolType ;
4
4
import org .dcache .oncrpc4j .xdr .XdrString ;
5
5
6
+ import java .io .EOFException ;
6
7
import java .io .IOException ;
7
8
import java .math .BigInteger ;
8
9
import java .security .GeneralSecurityException ;
9
10
import java .security .KeyPair ;
10
11
import java .security .KeyPairGenerator ;
11
12
import java .security .KeyStore ;
13
+ import java .security .PrivateKey ;
12
14
import java .security .SecureRandom ;
13
15
import java .security .Security ;
14
16
import java .security .cert .Certificate ;
15
17
import java .util .Date ;
16
18
import java .util .concurrent .TimeUnit ;
17
19
import javax .net .ssl .KeyManagerFactory ;
18
20
import javax .net .ssl .SSLContext ;
21
+ import javax .net .ssl .SSLParameters ;
19
22
import javax .net .ssl .TrustManagerFactory ;
20
23
21
24
import org .bouncycastle .asn1 .x500 .X500Name ;
@@ -49,7 +52,8 @@ public class ClientServerTLSTest {
49
52
private OncRpcSvc svc ;
50
53
private OncRpcSvc clnt ;
51
54
private RpcCall clntCall ;
52
- private SSLContext sslContext ;
55
+ private SSLContext sslServerContext ;
56
+ private SSLContext sslClientContext ;
53
57
54
58
private RpcDispatchable echo = (RpcCall call ) -> {
55
59
switch (call .getProcedure ()) {
@@ -88,7 +92,15 @@ public static void setupClass() {
88
92
89
93
@ Before
90
94
public void setUp () throws Exception {
91
- sslContext = createSslContext ();
95
+
96
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator .getInstance ("RSA" , "BC" );
97
+ keyPairGenerator .initialize (2048 , new SecureRandom ());
98
+ KeyPair keyPair = keyPairGenerator .generateKeyPair ();
99
+
100
+ Certificate certificate = generateSelfSignedCert (keyPair );
101
+
102
+ sslServerContext = createServerSslContext (certificate , keyPair .getPrivate ());
103
+ sslClientContext = createClientSslContext (certificate );
92
104
}
93
105
94
106
@ After
@@ -112,7 +124,7 @@ public void shouldCallCorrectProcedure() throws IOException {
112
124
.withSelectorThreadPoolSize (1 )
113
125
.withWorkerThreadPoolSize (1 )
114
126
.withRpcService (new OncRpcProgram (PROGNUM , PROGVER ), echo )
115
- .withSSLContext (sslContext )
127
+ .withSSLContext (sslServerContext )
116
128
.withServiceName ("svc" )
117
129
.build ();
118
130
svc .start ();
@@ -125,7 +137,7 @@ public void shouldCallCorrectProcedure() throws IOException {
125
137
.withSelectorThreadPoolSize (1 )
126
138
.withWorkerThreadPoolSize (1 )
127
139
.withRpcService (new OncRpcProgram (PROGNUM , PROGVER ), upper )
128
- .withSSLContext (sslContext )
140
+ .withSSLContext (sslClientContext )
129
141
.withServiceName ("clnt" )
130
142
.build ();
131
143
clnt .start ();
@@ -153,7 +165,7 @@ public void shouldTriggerClientCallback() throws IOException {
153
165
.withSelectorThreadPoolSize (1 )
154
166
.withWorkerThreadPoolSize (1 )
155
167
.withRpcService (new OncRpcProgram (PROGNUM , PROGVER ), echo )
156
- .withSSLContext (sslContext )
168
+ .withSSLContext (sslServerContext )
157
169
.withServiceName ("svc" )
158
170
.build ();
159
171
svc .start ();
@@ -166,7 +178,7 @@ public void shouldTriggerClientCallback() throws IOException {
166
178
.withSelectorThreadPoolSize (1 )
167
179
.withWorkerThreadPoolSize (1 )
168
180
.withRpcService (new OncRpcProgram (PROGNUM , PROGVER ), upper )
169
- .withSSLContext (sslContext )
181
+ .withSSLContext (sslClientContext )
170
182
.withServiceName ("clnt" )
171
183
.build ();
172
184
clnt .start ();
@@ -194,7 +206,7 @@ public void shouldStartTLSHandshake() throws IOException {
194
206
.withSelectorThreadPoolSize (1 )
195
207
.withWorkerThreadPoolSize (1 )
196
208
.withRpcService (new OncRpcProgram (PROGNUM , PROGVER ), echo )
197
- .withSSLContext (sslContext )
209
+ .withSSLContext (sslServerContext )
198
210
.withStartTLS ()
199
211
.withServiceName ("svc" )
200
212
.build ();
@@ -207,7 +219,7 @@ public void shouldStartTLSHandshake() throws IOException {
207
219
.withWorkerThreadIoStrategy ()
208
220
.withSelectorThreadPoolSize (1 )
209
221
.withWorkerThreadPoolSize (1 )
210
- .withSSLContext (sslContext )
222
+ .withSSLContext (sslClientContext )
211
223
.withStartTLS ()
212
224
.withServiceName ("clnt" )
213
225
.build ();
@@ -239,7 +251,7 @@ public void shouldFailWhenNoTLSOnClient() throws IOException {
239
251
.withSelectorThreadPoolSize (1 )
240
252
.withWorkerThreadPoolSize (1 )
241
253
.withRpcService (new OncRpcProgram (PROGNUM , PROGVER ), echo )
242
- .withSSLContext (sslContext )
254
+ .withSSLContext (sslServerContext )
243
255
.withStartTLS ()
244
256
.withServiceName ("svc" )
245
257
.build ();
@@ -275,7 +287,7 @@ public void shouldFailSecondStartTLS() throws IOException {
275
287
.withSelectorThreadPoolSize (1 )
276
288
.withWorkerThreadPoolSize (1 )
277
289
.withRpcService (new OncRpcProgram (PROGNUM , PROGVER ), echo )
278
- .withSSLContext (sslContext )
290
+ .withSSLContext (sslServerContext )
279
291
.withStartTLS ()
280
292
.withServiceName ("svc" )
281
293
.build ();
@@ -288,7 +300,7 @@ public void shouldFailSecondStartTLS() throws IOException {
288
300
.withWorkerThreadIoStrategy ()
289
301
.withSelectorThreadPoolSize (1 )
290
302
.withWorkerThreadPoolSize (1 )
291
- .withSSLContext (sslContext )
303
+ .withSSLContext (sslClientContext )
292
304
.withStartTLS ()
293
305
.withServiceName ("clnt" )
294
306
.build ();
@@ -324,7 +336,7 @@ public void shouldRejectStartTlsWhenNotConfigured() throws IOException {
324
336
.withWorkerThreadIoStrategy ()
325
337
.withSelectorThreadPoolSize (1 )
326
338
.withWorkerThreadPoolSize (1 )
327
- .withSSLContext (sslContext )
339
+ .withSSLContext (sslClientContext )
328
340
.withStartTLS ()
329
341
.withServiceName ("clnt" )
330
342
.build ();
@@ -336,21 +348,81 @@ public void shouldRejectStartTlsWhenNotConfigured() throws IOException {
336
348
clntCall .call (0 , XdrVoid .XDR_VOID , XdrVoid .XDR_VOID , new RpcAuthTypeTls ());
337
349
}
338
350
339
- public static SSLContext createSslContext () throws Exception {
351
+
352
+ @ Test (expected = EOFException .class ) // rfc8446#section-6.2
353
+ public void shouldRejectTlsWhenClientCertRequired () throws IOException , Exception {
354
+
355
+ SSLParameters parameters = new SSLParameters ();
356
+ parameters .setNeedClientAuth (true );
357
+
358
+ svc = new OncRpcSvcBuilder ()
359
+ .withoutAutoPublish ()
360
+ .withTCP ()
361
+ .withWorkerThreadIoStrategy ()
362
+ .withBindAddress ("127.0.0.1" )
363
+ .withSelectorThreadPoolSize (1 )
364
+ .withWorkerThreadPoolSize (1 )
365
+ .withRpcService (new OncRpcProgram (PROGNUM , PROGVER ), echo )
366
+ .withSSLContext (sslServerContext )
367
+ .withSSLParameters (parameters )
368
+ .withServiceName ("svc" )
369
+ .build ();
370
+ svc .start ();
371
+
372
+ clnt = new OncRpcSvcBuilder ()
373
+ .withoutAutoPublish ()
374
+ .withTCP ()
375
+ .withClientMode ()
376
+ .withWorkerThreadIoStrategy ()
377
+ .withSelectorThreadPoolSize (1 )
378
+ .withWorkerThreadPoolSize (1 )
379
+ .withRpcService (new OncRpcProgram (PROGNUM , PROGVER ), upper )
380
+ .withSSLContext (sslClientContext )
381
+ .withServiceName ("clnt" )
382
+ .build ();
383
+ clnt .start ();
384
+
385
+ RpcTransport t = clnt .connect (svc .getInetSocketAddress (IpProtocolType .TCP ));
386
+ clntCall = new RpcCall (PROGNUM , PROGVER , new RpcAuthTypeNone (), t );
387
+
388
+ XdrString s = new XdrString ("hello" );
389
+ XdrString reply = new XdrString ();
390
+ clntCall .call (ECHO , s , reply );
391
+ }
392
+
393
+ public static SSLContext createClientSslContext (Certificate certificate ) throws Exception {
340
394
341
395
char [] password = "password" .toCharArray ();
342
396
397
+ // create emtpy keystore and put certificates into it
398
+ KeyStore keyStore = createEmptyKeystore ();
399
+ keyStore .setEntry ("chain" , new KeyStore .TrustedCertificateEntry (certificate ),null );
343
400
344
- KeyPairGenerator keyPairGenerator = KeyPairGenerator .getInstance ("RSA" , "BC" );
345
- keyPairGenerator .initialize (2048 , new SecureRandom ());
346
- KeyPair keyPair = keyPairGenerator .generateKeyPair ();
401
+ KeyManagerFactory keyManagerFactory
402
+ = KeyManagerFactory .getInstance (KeyManagerFactory .getDefaultAlgorithm ());
403
+ keyManagerFactory .init (keyStore , password );
404
+
405
+ TrustManagerFactory trustManagerFactory
406
+ = TrustManagerFactory .getInstance (TrustManagerFactory .getDefaultAlgorithm ());
407
+ trustManagerFactory .init (keyStore );
408
+
409
+ SSLContext sslContext = SSLContext .getInstance ("TLS" );
410
+ sslContext .init (keyManagerFactory .getKeyManagers (),
411
+ trustManagerFactory .getTrustManagers (),
412
+ new SecureRandom ());
413
+
414
+ return sslContext ;
415
+ }
416
+
417
+ public static SSLContext createServerSslContext (Certificate certificate , PrivateKey privateKey ) throws Exception {
418
+
419
+ char [] password = "password" .toCharArray ();
347
420
348
- Certificate certificate = generateSelfSignedCert (keyPair );
349
421
Certificate [] certificateChain = {certificate };
350
422
351
423
// create emtpy keystore and put certificates into it
352
424
KeyStore keyStore = createEmptyKeystore ();
353
- keyStore .setKeyEntry ("private" , keyPair . getPrivate () , password , certificateChain );
425
+ keyStore .setKeyEntry ("private" , privateKey , password , certificateChain );
354
426
keyStore .setCertificateEntry ("cert" , certificate );
355
427
356
428
KeyManagerFactory keyManagerFactory
0 commit comments