-
Notifications
You must be signed in to change notification settings - Fork 147
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce Client Certificate configuration (#1183)
⚠️ This API is released as preview.⚠️ This feature is NodeJS only. Browser should configure the client certificate in the system certificates. The ClientCertificate is a mechanism to support mutual TLS as a second factor for authentication. The driver's certificate will not be used to authenticate a user on the DBMS, but only to authenticate the driver as a trusted client to the DBMS. Another authentication mechanism is still required to authenticate the user. The configuration is done by using the driver configuration, the property name is `clientCertificate` and this a object with the following properties: * `certfile`: The path to client certificate file. This is can configured as list of paths. * `keyfile`: The path to key file. This can also be configured as a list of paths, an object contain `path` and `password` or a list of objects contain `path` and `password`. * `password` (optional): The client key password. See [node documentation](https://nodejs.org/api/tls.html#tlscreatesecurecontextoptions) for understanding how password, certs and keys work together. Configuration example: ```javascript import neo4j from 'neo4j-driver' const driver = neo4j.driver('neo4j+s://myhost:7687', MY_CREDENTIALS, { clientCertificate: { certfile: '/path/to/cert/file.cert', keyfile: '/path/to/cert/file.pem', password: 'the_key_password' // optional } }) // then use your driver as usual. ``` ### Client Certificate Provider and Certificate Rotation In case of the certificate needs to be changed, the driver offers an api for change client certificates without creating a new driver instance. The change is done by inform an `ClientCertificateProvider` instead of a `ClientCertificate` in the driver configuration. `ClientCertificateProvider` is a public interface which can be implemented by user. However, the driver offers an implementation of this interface for working with certificate rotation scenarios. ```javascript import neo4j from 'neo4j-driver' const initialClientCertificate: { certfile: '/path/to/cert/file.cert', keyfile: '/path/to/cert/file.pem', password: 'the_key_password' // optional } const clientCertificateProvider = neo4j.clientCertificateProviders.rotating({ initialCertificate: initialClientCertificate }) const driver = neo4j.driver('neo4j+s://myhost:7687', MY_CREDENTIALS, { clientCertificate: clientCertificateProvider }) // use the driver as usual // then you have new certificate which will replace the old one clientCertificateProvider.updateCertificate({ certfile: '/path/to/cert/new_file.cert', keyfile: '/path/to/cert/new_file.pem', password: 'the_new_key_password' // optional }) // New connections will be created using the new certificate. // however, older connections will not be closed if they still working. ```⚠️ This feature is NodeJS only. Browser should configure the client certificate in the system certificates.⚠️ This API is released as preview.
- Loading branch information
Showing
56 changed files
with
1,944 additions
and
72 deletions.
There are no files selected for viewing
21 changes: 21 additions & 0 deletions
21
packages/bolt-connection/src/channel/browser/browser-client-certificates-loader.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/** | ||
* Copyright (c) "Neo4j" | ||
* Neo4j Sweden AB [https://neo4j.com] | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
export default { | ||
async load (clientCertificate) { | ||
return clientCertificate | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
packages/bolt-connection/src/channel/deno/deno-client-certificates-loader.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/** | ||
* Copyright (c) "Neo4j" | ||
* Neo4j Sweden AB [https://neo4j.com] | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
export default { | ||
async load (clientCertificate) { | ||
return clientCertificate | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
packages/bolt-connection/src/channel/node/node-client-certificates-loader.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/** | ||
* Copyright (c) "Neo4j" | ||
* Neo4j Sweden AB [https://neo4j.com] | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import fs from 'fs' | ||
|
||
function readFile (file) { | ||
return new Promise((resolve, reject) => fs.readFile(file, (err, data) => { | ||
if (err) { | ||
return reject(err) | ||
} | ||
return resolve(data) | ||
})) | ||
} | ||
|
||
function loadCert (fileOrFiles) { | ||
if (Array.isArray(fileOrFiles)) { | ||
return Promise.all(fileOrFiles.map(loadCert)) | ||
} | ||
return readFile(fileOrFiles) | ||
} | ||
|
||
function loadKey (fileOrFiles) { | ||
if (Array.isArray(fileOrFiles)) { | ||
return Promise.all(fileOrFiles.map(loadKey)) | ||
} | ||
|
||
if (typeof fileOrFiles === 'string') { | ||
return readFile(fileOrFiles) | ||
} | ||
|
||
return readFile(fileOrFiles.path) | ||
.then(pem => ({ | ||
pem, | ||
passphrase: fileOrFiles.password | ||
})) | ||
} | ||
|
||
export default { | ||
async load (clientCertificate) { | ||
const certPromise = loadCert(clientCertificate.certfile) | ||
const keyPromise = loadKey(clientCertificate.keyfile) | ||
|
||
const [cert, key] = await Promise.all([certPromise, keyPromise]) | ||
|
||
return { | ||
cert, | ||
key, | ||
passphrase: clientCertificate.password | ||
} | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
packages/bolt-connection/src/connection-provider/client-certificate-holder.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* Copyright (c) "Neo4j" | ||
* Neo4j Sweden AB [https://neo4j.com] | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import { ClientCertificatesLoader } from '../channel' | ||
|
||
export default class ClientCertificateHolder { | ||
constructor ({ clientCertificateProvider, loader }) { | ||
this._clientCertificateProvider = clientCertificateProvider | ||
this._loader = loader || ClientCertificatesLoader | ||
this._clientCertificate = null | ||
} | ||
|
||
async getClientCertificate () { | ||
if (this._clientCertificateProvider != null && | ||
(this._clientCertificate == null || await this._clientCertificateProvider.hasUpdate())) { | ||
this._clientCertificate = Promise.resolve(this._clientCertificateProvider.getClientCertificate()) | ||
.then(this._loader.load) | ||
.then(clientCertificate => { | ||
this._clientCertificate = clientCertificate | ||
return this._clientCertificate | ||
}) | ||
.catch(error => { | ||
this._clientCertificate = null | ||
throw error | ||
}) | ||
} | ||
|
||
return this._clientCertificate | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.