Skip to content

Commit aaf956f

Browse files
committed
Merge branch '1.0' into 1.1
# Conflicts: # src/v1/internal/ch-node.js # src/v1/internal/ch-websocket.js # src/v1/internal/connector.js # test/v1/tck/steps/tlssteps.js
2 parents de58703 + b4da125 commit aaf956f

File tree

7 files changed

+125
-16
lines changed

7 files changed

+125
-16
lines changed

src/v1/driver.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,18 @@ let USER_AGENT = "neo4j-javascript/" + VERSION;
197197
* // This means that by default, connections "just work" while still giving you
198198
* // good encrypted protection.
199199
* //
200-
* // TRUST_SIGNED_CERTIFICATES is the classic approach to trust verification -
200+
* // TRUST_CUSTOM_CA_SIGNED_CERTIFICATES is the classic approach to trust verification -
201201
* // whenever we establish an encrypted connection, we ensure the host is using
202202
* // an encryption certificate that is in, or is signed by, a certificate listed
203203
* // as trusted. In the web bundle, this list of trusted certificates is maintained
204204
* // by the web browser. In NodeJS, you configure the list with the next config option.
205-
* trust: "TRUST_ON_FIRST_USE" | "TRUST_SIGNED_CERTIFICATES",
205+
* //
206+
* // TRUST_SYSTEM_CA_SIGNED_CERTIFICATES meand that you trust whatever certificates
207+
* // are in the default certificate chain of th
208+
* trust: "TRUST_ON_FIRST_USE" | "TRUST_SIGNED_CERTIFICATES" | TRUST_CUSTOM_CA_SIGNED_CERTIFICATES | TRUST_SYSTEM_CA_SIGNED_CERTIFICATES,
206209
*
207210
* // List of one or more paths to trusted encryption certificates. This only
208-
* // works in the NodeJS bundle, and only matters if you use "TRUST_SIGNED_CERTIFICATES".
211+
* // works in the NodeJS bundle, and only matters if you use "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES".
209212
* // The certificate files should be in regular X.509 PEM format.
210213
* // For instance, ['./trusted.pem']
211214
* trustedCertificates: [],

src/v1/internal/ch-node.js

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,17 @@ function storeFingerprint( serverId, knownHostsPath, fingerprint, cb ) {
105105
}
106106

107107
const TrustStrategy = {
108-
TRUST_SIGNED_CERTIFICATES : function( opts, onSuccess, onFailure ) {
108+
/**
109+
* @deprecated Since version 1.0. Will be deleted in a future version. TRUST_CUSTOM_CA_SIGNED_CERTIFICATES.
110+
*/
111+
TRUST_SIGNED_CERTIFICATES: function( opts, onSuccess, onFailure ) {
112+
console.log("`TRUST_SIGNED_CERTIFICATES` has been deprecated as option and will be removed in a future version of " +
113+
"the driver. Pleas use `TRUST_CUSTOM_CA_SIGNED_CERTIFICATES` instead.");
114+
return TrustStrategy.TRUST_CUSTOM_CA_SIGNED_CERTIFICATES(opts, onSuccess, onFailure);
115+
},
116+
TRUST_CUSTOM_CA_SIGNED_CERTIFICATES : function( opts, onSuccess, onFailure ) {
109117
if( !opts.trustedCertificates || opts.trustedCertificates.length == 0 ) {
110-
onFailure(newError("You are using TRUST_SIGNED_CERTIFICATES as the method " +
118+
onFailure(newError("You are using TRUST_CUSTOM_CA_SIGNED_CERTIFICATES as the method " +
111119
"to verify trust for encrypted connections, but have not configured any " +
112120
"trustedCertificates. You must specify the path to at least one trusted " +
113121
"X.509 certificate for this to work. Two other alternatives is to use " +
@@ -139,6 +147,29 @@ const TrustStrategy = {
139147
socket.on('error', onFailure);
140148
return socket;
141149
},
150+
TRUST_SYSTEM_CA_SIGNED_CERTIFICATES : function( opts, onSuccess, onFailure ) {
151+
152+
let tlsOpts = {
153+
// Because we manually check for this in the connect callback, to give
154+
// a more helpful error to the user
155+
rejectUnauthorized: false
156+
};
157+
let socket = tls.connect(opts.port, opts.host, tlsOpts, function () {
158+
if (!socket.authorized) {
159+
onFailure(newError("Server certificate is not trusted. If you trust the database you are connecting to, use " +
160+
"TRUST_CUSTOM_CA_SIGNED_CERTIFICATES and add" +
161+
" the signing certificate, or the server certificate, to the list of certificates trusted by this driver" +
162+
" using `neo4j.v1.driver(.., { trustedCertificates:['path/to/certificate.crt']}). This " +
163+
" is a security measure to protect against man-in-the-middle attacks. If you are just trying " +
164+
" Neo4j out and are not concerned about encryption, simply disable it using `encrypted=false` in the driver" +
165+
" options."));
166+
} else {
167+
onSuccess();
168+
}
169+
});
170+
socket.on('error', onFailure);
171+
return socket;
172+
},
142173
TRUST_ON_FIRST_USE : function( opts, onSuccess, onFailure ) {
143174
let tlsOpts = {
144175
// Because we manually verify the certificate against known_hosts
@@ -155,7 +186,7 @@ const TrustStrategy = {
155186
// do TOFU, and the safe approach is to fail.
156187
onFailure(newError("You are using a version of NodeJS that does not " +
157188
"support trust-on-first use encryption. You can either upgrade NodeJS to " +
158-
"a newer version, use `trust:TRUST_SIGNED_CERTIFICATES` in your driver " +
189+
"a newer version, use `trust:TRUST_CUSTOM_CA_SIGNED_CERTIFICATES` in your driver " +
159190
"config instead, or disable encryption using `encrypted:\"" + ENCRYPTION_OFF+ "\"`."));
160191
return;
161192
}
@@ -205,7 +236,7 @@ function connect( opts, onSuccess, onFailure=(()=>null) ) {
205236
return TrustStrategy[opts.trust](opts, onSuccess, onFailure);
206237
} else {
207238
onFailure(newError("Unknown trust strategy: " + opts.trust + ". Please use either " +
208-
"trust:'TRUST_SIGNED_CERTIFICATES' or trust:'TRUST_ON_FIRST_USE' in your driver " +
239+
"trust:'TRUST_CUSTOM_CA_SIGNED_CERTIFICATES' or trust:'TRUST_ON_FIRST_USE' in your driver " +
209240
"configuration. Alternatively, you can disable encryption by setting " +
210241
"`encrypted:\"" + ENCRYPTION_OFF + "\"`. There is no mechanism to use encryption without trust verification, " +
211242
"because this incurs the overhead of encryption without improving security. If " +

src/v1/internal/ch-websocket.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ class WebSocketChannel {
4646
let scheme = "ws";
4747
//Allow boolean for backwards compatibility
4848
if( opts.encrypted === true || opts.encrypted === ENCRYPTION_ON ||
49-
(opts.encrypted === ENCRYPTION_NON_LOCAL && !isLocalHost(opts.host))) {
50-
if( (!opts.trust) || opts.trust === "TRUST_SIGNED_CERTIFICATES" ) {
49+
(opts.encrypted === ENCRYPTION_NON_LOCAL && !isLocalHost(opts.host)) ||
50+
opts.trust === "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES" ) {
5151
scheme = "wss";
5252
} else {
5353
this._error = newError("The browser version of this driver only supports one trust " +
54-
"strategy, 'TRUST_SIGNED_CERTIFICATES'. "+opts.trust+" is not supported. Please " +
55-
"either use TRUST_SIGNED_CERTIFICATES or disable encryption by setting " +
54+
"strategy, 'TRUST_CUSTOM_CA_SIGNED_CERTIFICATES'. "+opts.trust+" is not supported. Please " +
55+
"either use TRUST_CUSTOM_CA_SIGNED_CERTIFICATES or disable encryption by setting " +
5656
"`encrypted:\"" + ENCRYPTION_OFF + "\"` in the driver configuration.");
5757
return;
5858
}

src/v1/internal/connector.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ function connect( url, config = {}) {
438438
// Default to using ENCRYPTION_NON_LOCAL if trust-on-first-use is available
439439
encrypted : shouldEncrypt(config.encrypted, (hasFeature("trust_on_first_use") ? ENCRYPTION_NON_LOCAL : ENCRYPTION_OFF), host(url)),
440440
// Default to using TRUST_ON_FIRST_USE if it is available
441-
trust : config.trust || (hasFeature("trust_on_first_use") ? "TRUST_ON_FIRST_USE" : "TRUST_SIGNED_CERTIFICATES"),
441+
trust : config.trust || (hasFeature("trust_on_first_use") ? "TRUST_ON_FIRST_USE" : "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES"),
442442
trustedCertificates : config.trustedCertificates || [],
443443
knownHosts : config.knownHosts
444444
}));

test/internal/tls.test.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,81 @@ describe('trust-signed-certificates', function() {
9191
});
9292
});
9393

94+
describe('trust-custom-ca-signed-certificates', function() {
95+
96+
var driver;
97+
98+
it('should reject unknown certificates', function(done) {
99+
// Assuming we only run this test on NodeJS
100+
if( !NodeChannel.available ) {
101+
done();
102+
return;
103+
}
104+
105+
// Given
106+
driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"), {
107+
encrypted: true,
108+
trust: "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES",
109+
trustedCertificates: ["test/resources/random.certificate"]
110+
});
111+
112+
// When
113+
driver.session().run( "RETURN 1").catch( function(err) {
114+
expect( err.message ).toContain( "Server certificate is not trusted" );
115+
done();
116+
});
117+
});
118+
119+
it('should accept known certificates', function(done) {
120+
// Assuming we only run this test on NodeJS with TOFU support
121+
if( !NodeChannel.available ) {
122+
done();
123+
return;
124+
}
125+
126+
// Given
127+
driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"), {
128+
encrypted: true,
129+
trust: "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES",
130+
trustedCertificates: ["build/neo4j/certificates/neo4j.cert"]
131+
});
132+
133+
// When
134+
driver.session().run( "RETURN 1").then( done );
135+
});
136+
137+
afterEach(function(){
138+
if( driver ) {
139+
driver.close();
140+
}
141+
});
142+
});
143+
144+
describe('trust-system-ca-signed-certificates', function() {
145+
146+
var driver;
147+
148+
fit('should reject unknown certificates', function(done) {
149+
// Assuming we only run this test on NodeJS
150+
if( !NodeChannel.available ) {
151+
done();
152+
return;
153+
}
154+
155+
// Given
156+
driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"), {
157+
encrypted: true,
158+
trust: "TRUST_SYSTEM_CA_SIGNED_CERTIFICATES"
159+
});
160+
161+
// When
162+
driver.session().run( "RETURN 1").catch( function(err) {
163+
expect( err.message ).toContain( "Server certificate is not trusted" );
164+
done();
165+
});
166+
});
167+
});
168+
94169
describe('trust-on-first-use', function() {
95170

96171
var driver;

test/v1/examples.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ describe('examples', function() {
357357
var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"), {
358358
// Note that trust-on-first-use is not available in the browser bundle,
359359
// in NodeJS, trust-on-first-use is the default trust mode. In the browser
360-
// it is TRUST_SIGNED_CERTIFICATES.
360+
// it is TRUST_CUSTOM_CA_SIGNED_CERTIFICATES.
361361
trust: "TRUST_ON_FIRST_USE",
362362
encrypted:"ENCRYPTION_NON_LOCAL"
363363
});
@@ -369,7 +369,7 @@ describe('examples', function() {
369369
var neo4j = neo4jv1;
370370
// tag::tls-signed[]
371371
var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"), {
372-
trust: "TRUST_SIGNED_CERTIFICATES",
372+
trust: "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES",
373373
// Configuring which certificates to trust here is only available
374374
// in NodeJS. In the browser bundle the browsers list of trusted
375375
// certificates is used, due to technical limitations in some browsers.

test/v1/tck/steps/tlssteps.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ module.exports = function () {
108108
this.Given(/^a driver configured to use a trusted certificate$/, function (callback) {
109109
this.config = {
110110
encrypted: "ENCRYPTION_ON",
111-
trust: "TRUST_SIGNED_CERTIFICATES",
111+
trust: "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES",
112112
knownHosts: this.knownHosts1,
113113
trustedCertificates: ['./test/resources/root.cert']
114114
};
@@ -133,7 +133,7 @@ module.exports = function () {
133133
//common name is not set to localhost
134134
this.config = {
135135
encrypted: "ENCRYPTION_ON",
136-
trust: "TRUST_SIGNED_CERTIFICATES",
136+
trust: "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES",
137137
knownHosts: this.knownHosts1,
138138
trustedCertificates: [util.neo4jCert]
139139
};

0 commit comments

Comments
 (0)