From 7d27b07f5294984490b0a134c212b1b00f06fced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Gro=CC=88bler?= Date: Sat, 16 Sep 2017 16:03:45 +0200 Subject: [PATCH] added option to request, require and verify client certificates --- docs/options.md | 20 +++++++++++--------- docs/ssl-tls.md | 9 +++++---- lib/server.js | 3 ++- lib/server.spec.js | 10 ++++++---- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/docs/options.md b/docs/options.md index 566e351..2815222 100644 --- a/docs/options.md +++ b/docs/options.md @@ -11,6 +11,7 @@ const options = { 'listen': 'myservice.example.com:50051', 'rootProtoPath': '../protos', 'rootCert': '/path/to/root/cert', + 'checkClientCert': true, 'certChain': '/path/to/cert/chain', 'privateKey': '/path/to/private/key', }; @@ -19,14 +20,15 @@ const app = new Condor(options); All the options are not required. Their default values are: -| Option | Description | Default | -|---------------|----------------------------------------------------------|---------------| -| listen | The hostname and port the server will listen into | 0.0.0.0:50051 | -| host | The hostname. *Valid only if `listen` is not set* | 0.0.0.0 | -| port | The port. *Valid only if `listen` is not set* | 50051 | -| rootProtoPath | Root path of the proto files | | -| rootCert | Path to the root cert file | | -| certChain | Path to the cert chain file | | -| privateKey | Path to the private key file | | +| Option | Description | Default | +|-----------------|----------------------------------------------------------------------------------------|---------------| +| listen | The hostname and port the server will listen into | 0.0.0.0:50051 | +| host | The hostname. *Valid only if `listen` is not set* | 0.0.0.0 | +| port | The port. *Valid only if `listen` is not set* | 50051 | +| rootProtoPath | Root path of the proto files | | +| rootCert | Path to the root cert file | | +| checkClientCert | Indicates that the server should request, require and verify the client's certificates | false | +| certChain | Path to the cert chain file | | +| privateKey | Path to the private key file | | Next: [Related modules and middleware](related-modules-and-middleware.md) diff --git a/docs/ssl-tls.md b/docs/ssl-tls.md index 86510ce..7bbcac8 100644 --- a/docs/ssl-tls.md +++ b/docs/ssl-tls.md @@ -8,13 +8,14 @@ layout: default GRPC has some built-in mechanisms for server [authentication](http://www.grpc.io/docs/guides/auth.html). To enable SSL you just have to pass the host and the paths to the certificate files. - + ```js const options= { 'listen': 'myservice.example.com:50051', // required - 'rootCert': '/path/to/root/cert', // optional - 'certChain': '/path/to/cert/chain', // required - 'privateKey': '/path/to/private/key', // required + 'rootCert': '/path/to/root/cert', // optional + 'checkClientCert': false, // optional + 'certChain': '/path/to/cert/chain', // required + 'privateKey': '/path/to/private/key', // required }; app = new Condor(options); ``` diff --git a/lib/server.js b/lib/server.js index 6ea96d1..54a15d3 100644 --- a/lib/server.js +++ b/lib/server.js @@ -10,6 +10,7 @@ module.exports = class { constructor(builder, options) { const defaultOptions = { 'listen': '0.0.0.0:50051', + 'checkClientCert': false, }; this._validateBuilder(builder); @@ -124,7 +125,7 @@ module.exports = class { 'cert_chain': this._getFileBuffer(options.certChain), 'private_key': this._getFileBuffer(options.privateKey), }, - ]); + ], options.checkClientCert); } _getFileBuffer(path) { diff --git a/lib/server.spec.js b/lib/server.spec.js index 1f1ccb8..e4c62ab 100644 --- a/lib/server.spec.js +++ b/lib/server.spec.js @@ -33,7 +33,7 @@ describe('Server:', () => { describe('getOptions()', () => { describe('when server was initialized without options', () => { it('should return the default options', () => { - const defaultOptions = {'listen': '0.0.0.0:50051'}; + const defaultOptions = {'listen': '0.0.0.0:50051', 'checkClientCert': false}; expect(server.getOptions()).toEqual(defaultOptions); }); }); @@ -45,13 +45,13 @@ describe('Server:', () => { }); it('should return the options merged with the default options', () => { - const expectedOptions = {'listen': '1.1.1.1:3000'}; + const expectedOptions = {'listen': '1.1.1.1:3000', 'checkClientCert': false}; expect(server.getOptions()).toEqual(expectedOptions); }); describe('when two servers are created', () => { it('should reset default options', () => { - const expectedOptions = {'listen': '0.0.0.0:50051'}; + const expectedOptions = {'listen': '0.0.0.0:50051', 'checkClientCert': false}; server = new Server(builder); expect(server.getOptions()).toEqual(expectedOptions); }); @@ -93,6 +93,7 @@ describe('Server:', () => { it('should create ssl creds', () => { const expectedOptions = { 'listen': '0.0.0.0:50051', + 'checkClientCert': false, 'certChain': 'spec/ssl/server.crt', 'privateKey': 'spec/ssl/server.key', }; @@ -122,6 +123,7 @@ describe('Server:', () => { describe('when ssl options are files paths', () => { const expectedOptions = { 'listen': '0.0.0.0:50051', + 'checkClientCert': false, 'certChain': 'spec/ssl/server.crt', 'privateKey': 'spec/ssl/server.key', }; @@ -231,7 +233,7 @@ describe('Server:', () => { 'cert_chain': new Buffer('cert_chain'), 'private_key': new Buffer('private_key'), }, - ]); + ], false); server = new Server(builder, { 'cert_chain': '/path/to/cert/chain.crt', 'private_key': '/path/to/private/key.key',