26
26
import java .io .IOException ;
27
27
import java .net .URI ;
28
28
import java .security .GeneralSecurityException ;
29
+ import java .security .NoSuchAlgorithmException ;
29
30
30
31
import org .neo4j .driver .AuthToken ;
31
32
import org .neo4j .driver .AuthTokens ;
50
51
import org .neo4j .driver .internal .retry .ExponentialBackoffRetryLogic ;
51
52
import org .neo4j .driver .internal .retry .RetryLogic ;
52
53
import org .neo4j .driver .internal .retry .RetrySettings ;
53
- import org .neo4j .driver .internal .security .SecurityPlanImpl ;
54
54
import org .neo4j .driver .internal .security .SecurityPlan ;
55
+ import org .neo4j .driver .internal .security .SecurityPlanImpl ;
55
56
import org .neo4j .driver .internal .spi .ConnectionPool ;
56
57
import org .neo4j .driver .internal .spi .ConnectionProvider ;
57
58
import org .neo4j .driver .internal .util .Clock ;
67
68
public class DriverFactory
68
69
{
69
70
public static final String BOLT_URI_SCHEME = "bolt" ;
71
+ public static final String BOLT_HIGH_TRUST_URI_SCHEME = "bolt+s" ;
72
+ public static final String BOLT_LOW_TRUST_URI_SCHEME = "bolt+ssc" ;
70
73
public static final String BOLT_ROUTING_URI_SCHEME = "neo4j" ;
74
+ public static final String BOLT_ROUTING_HIGH_TRUST_URI_SCHEME = "neo4j+s" ;
75
+ public static final String BOLT_ROUTING_LOW_TRUST_URI_SCHEME = "neo4j+ssc" ;
76
+
71
77
72
78
public final Driver newInstance ( URI uri , AuthToken authToken , RoutingSettings routingSettings ,
73
79
RetrySettings retrySettings , Config config )
@@ -103,7 +109,7 @@ public final Driver newInstance ( URI uri, AuthToken authToken, RoutingSettings
103
109
}
104
110
else
105
111
{
106
- securityPlan = createSecurityPlan ( address , config );
112
+ securityPlan = createSecurityPlan ( uri , config );
107
113
}
108
114
109
115
InternalLoggerFactory .setDefaultFactory ( new NettyLogging ( config .logging () ) );
@@ -148,17 +154,22 @@ protected ChannelConnector createConnector( ConnectionSettings settings, Securit
148
154
}
149
155
150
156
private InternalDriver createDriver ( URI uri , SecurityPlan securityPlan , BoltServerAddress address , ConnectionPool connectionPool ,
151
- EventExecutorGroup eventExecutorGroup , RoutingSettings routingSettings , RetryLogic retryLogic , MetricsProvider metricsProvider , Config config )
157
+ EventExecutorGroup eventExecutorGroup , RoutingSettings routingSettings , RetryLogic retryLogic ,
158
+ MetricsProvider metricsProvider , Config config )
152
159
{
153
160
try
154
161
{
155
162
String scheme = uri .getScheme ().toLowerCase ();
156
163
switch ( scheme )
157
164
{
158
165
case BOLT_URI_SCHEME :
166
+ case BOLT_LOW_TRUST_URI_SCHEME :
167
+ case BOLT_HIGH_TRUST_URI_SCHEME :
159
168
assertNoRoutingContext ( uri , routingSettings );
160
169
return createDirectDriver ( securityPlan , address , connectionPool , retryLogic , metricsProvider , config );
161
170
case BOLT_ROUTING_URI_SCHEME :
171
+ case BOLT_ROUTING_LOW_TRUST_URI_SCHEME :
172
+ case BOLT_ROUTING_HIGH_TRUST_URI_SCHEME :
162
173
return createRoutingDriver ( securityPlan , address , connectionPool , eventExecutorGroup , routingSettings , retryLogic , metricsProvider , config );
163
174
default :
164
175
throw new ClientException ( format ( "Unsupported URI scheme: %s" , scheme ) );
@@ -287,11 +298,11 @@ protected Bootstrap createBootstrap( EventLoopGroup eventLoopGroup )
287
298
return BootstrapFactory .newBootstrap ( eventLoopGroup );
288
299
}
289
300
290
- private static SecurityPlan createSecurityPlan ( BoltServerAddress address , Config config )
301
+ private static SecurityPlan createSecurityPlan ( URI uri , Config config )
291
302
{
292
303
try
293
304
{
294
- return createSecurityPlanImpl ( config );
305
+ return createSecurityPlanImpl ( config , uri );
295
306
}
296
307
catch ( GeneralSecurityException | IOException ex )
297
308
{
@@ -301,31 +312,50 @@ private static SecurityPlan createSecurityPlan( BoltServerAddress address, Confi
301
312
302
313
/*
303
314
* Establish a complete SecurityPlan based on the details provided for
304
- * driver construction.
315
+ * driver construction based off the scheme and configured properties .
305
316
*/
306
- private static SecurityPlan createSecurityPlanImpl ( Config config )
317
+ private static SecurityPlan createSecurityPlanImpl ( Config config , URI uri )
307
318
throws GeneralSecurityException , IOException
308
319
{
309
- if ( config .encrypted () )
320
+ String scheme = uri .getScheme ().toLowerCase ();
321
+
322
+ if ( scheme .equals ( BOLT_URI_SCHEME ) || scheme .equals ( BOLT_ROUTING_URI_SCHEME ) )
310
323
{
311
- Config .TrustStrategy trustStrategy = config .trustStrategy ();
312
- boolean hostnameVerificationEnabled = trustStrategy .isHostnameVerificationEnabled ();
313
- switch ( trustStrategy .strategy () )
324
+ if ( config .encrypted () )
314
325
{
315
- case TRUST_CUSTOM_CA_SIGNED_CERTIFICATES :
316
- return SecurityPlanImpl .forCustomCASignedCertificates ( trustStrategy .certFile (), hostnameVerificationEnabled );
317
- case TRUST_SYSTEM_CA_SIGNED_CERTIFICATES :
318
- return SecurityPlanImpl .forSystemCASignedCertificates ( hostnameVerificationEnabled );
319
- case TRUST_ALL_CERTIFICATES :
320
- return SecurityPlanImpl .forAllCertificates ( hostnameVerificationEnabled );
321
- default :
322
- throw new ClientException (
323
- "Unknown TLS authentication strategy: " + trustStrategy .strategy ().name () );
326
+ Config .TrustStrategy trustStrategy = config .trustStrategy ();
327
+ boolean hostnameVerificationEnabled = trustStrategy .isHostnameVerificationEnabled ();
328
+ switch ( trustStrategy .strategy () )
329
+ {
330
+ case TRUST_CUSTOM_CA_SIGNED_CERTIFICATES :
331
+ return SecurityPlanImpl .forCustomCASignedCertificates ( trustStrategy .certFile (), hostnameVerificationEnabled );
332
+ case TRUST_SYSTEM_CA_SIGNED_CERTIFICATES :
333
+ return SecurityPlanImpl .forSystemCASignedCertificates ( hostnameVerificationEnabled );
334
+ case TRUST_ALL_CERTIFICATES :
335
+ return SecurityPlanImpl .forAllCertificates ( hostnameVerificationEnabled );
336
+ default :
337
+ throw new ClientException (
338
+ "Unknown TLS authentication strategy: " + trustStrategy .strategy ().name () );
339
+ }
340
+ }
341
+ else
342
+ {
343
+ return insecure ();
324
344
}
325
345
}
326
346
else
327
347
{
328
- return insecure ();
348
+ switch ( scheme )
349
+ {
350
+ case BOLT_HIGH_TRUST_URI_SCHEME :
351
+ case BOLT_ROUTING_HIGH_TRUST_URI_SCHEME :
352
+ return configureHighTrustSecurityPlan ( config , scheme );
353
+ case BOLT_LOW_TRUST_URI_SCHEME :
354
+ case BOLT_ROUTING_LOW_TRUST_URI_SCHEME :
355
+ return configureLowTrustSecurityPlan ( config , scheme );
356
+ default :
357
+ throw new ClientException ( format ( "Unsupported URI scheme: %s" , scheme ) );
358
+ }
329
359
}
330
360
}
331
361
@@ -350,4 +380,46 @@ private static void closeConnectionPoolAndSuppressError( ConnectionPool connecti
350
380
addSuppressed ( mainError , closeError );
351
381
}
352
382
}
383
+
384
+ private static SecurityPlan configureHighTrustSecurityPlan ( Config config , String scheme ) throws NoSuchAlgorithmException
385
+ {
386
+ if ( config .isEncryptedUserConfigured () && !config .encrypted () )
387
+ {
388
+ throw new IllegalArgumentException ( "Encryption must be enabled for scheme: " + scheme );
389
+ }
390
+ else if ( config .isTrustStrategyUserConfigured () &&
391
+ ( config .trustStrategy ().strategy ().equals ( Config .TrustStrategy .Strategy .TRUST_ALL_CERTIFICATES ) ||
392
+ config .trustStrategy ().strategy ().equals ( Config .TrustStrategy .Strategy .TRUST_CUSTOM_CA_SIGNED_CERTIFICATES )))
393
+ {
394
+ throw new IllegalArgumentException ( "Scheme: " + scheme + " must use a higher level of trust configuration" );
395
+ }
396
+
397
+ return SecurityPlanImpl .forSystemCASignedCertificates ( config .trustStrategy ().isHostnameVerificationEnabled () );
398
+ }
399
+
400
+ private static SecurityPlan configureLowTrustSecurityPlan ( Config config , String scheme ) throws GeneralSecurityException , IOException
401
+ {
402
+ if ( config .isEncryptedUserConfigured () && !config .encrypted () )
403
+ {
404
+ throw new IllegalArgumentException ( "Encryption must be enabled for scheme: " + scheme );
405
+ }
406
+ else if ( config .isTrustStrategyUserConfigured () &&
407
+ config .trustStrategy ().strategy ().equals ( Config .TrustStrategy .Strategy .TRUST_SYSTEM_CA_SIGNED_CERTIFICATES ) )
408
+ {
409
+ throw new IllegalArgumentException ( "Scheme: " + scheme + " must use a lower level of trust configuration" );
410
+ }
411
+ {
412
+ if ( !config .isTrustStrategyUserConfigured () ||
413
+ (config .isTrustStrategyUserConfigured () && config .trustStrategy ().strategy ().equals ( Config .TrustStrategy .Strategy .TRUST_ALL_CERTIFICATES )) )
414
+
415
+ {
416
+ return SecurityPlanImpl .forAllCertificates ( config .trustStrategy ().isHostnameVerificationEnabled () );
417
+ }
418
+ else
419
+ {
420
+ return SecurityPlanImpl .forCustomCASignedCertificates ( config .trustStrategy ().certFile (),
421
+ config .trustStrategy ().isHostnameVerificationEnabled () );
422
+ }
423
+ }
424
+ }
353
425
}
0 commit comments