Skip to content

Commit

Permalink
feat(NODE-5549): add ability to provide crl file
Browse files Browse the repository at this point in the history
  • Loading branch information
durran committed Aug 22, 2023
1 parent a0955bd commit ca1efd8
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 12 deletions.
2 changes: 0 additions & 2 deletions .evergreen/config.in.yml
Original file line number Diff line number Diff line change
Expand Up @@ -636,8 +636,6 @@ functions:
export PROJECT_DIRECTORY="$(pwd)"
export NODE_LTS_VERSION=${NODE_LTS_VERSION}
export DRIVERS_TOOLS="${DRIVERS_TOOLS}"
export SSL_CA_FILE="${SSL_CA_FILE}"
export SSL_KEY_FILE="${SSL_KEY_FILE}"
export MONGODB_URI="${MONGODB_URI}"
bash ${PROJECT_DIRECTORY}/.evergreen/run-tls-tests.sh
Expand Down
2 changes: 0 additions & 2 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -589,8 +589,6 @@ functions:
export PROJECT_DIRECTORY="$(pwd)"
export NODE_LTS_VERSION=${NODE_LTS_VERSION}
export DRIVERS_TOOLS="${DRIVERS_TOOLS}"
export SSL_CA_FILE="${SSL_CA_FILE}"
export SSL_KEY_FILE="${SSL_KEY_FILE}"
export MONGODB_URI="${MONGODB_URI}"
bash ${PROJECT_DIRECTORY}/.evergreen/run-tls-tests.sh
Expand Down
5 changes: 3 additions & 2 deletions .evergreen/run-tls-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ set -o errexit # Exit the script with error if any of the commands fail

source "${PROJECT_DIRECTORY}/.evergreen/init-node-and-npm-env.sh"

export SSL_KEY_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/client.pem"
export SSL_CA_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/ca.pem"
export TLS_KEY_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/client.pem"
export TLS_CA_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/ca.pem"
export TLS_CRL_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/crl.pem"

npm run check:tls
3 changes: 3 additions & 0 deletions src/connection_string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,9 @@ export const OPTIONS = {
tlsCAFile: {
type: 'string'
},
tlsCRLFile: {
type: 'string'
},
tlsCertificateKeyFile: {
type: 'string'
},
Expand Down
9 changes: 7 additions & 2 deletions src/mongo_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ export interface MongoClientOptions extends BSONSerializeOptions, SupportedNodeC
tlsCertificateKeyFilePassword?: string;
/** Specifies the location of a local .pem file that contains the root certificate chain from the Certificate Authority. This file is used to validate the certificate presented by the mongod/mongos instance. */
tlsCAFile?: string;
/** Specifies the location of a local CRL .pem file that contains the client revokation list. */
tlsCRLFile?: string;
/** Bypasses validation of the certificates presented by the mongod/mongos instance */
tlsAllowInvalidCertificates?: boolean;
/** Disables hostname validation of the certificate presented by the mongod/mongos instance. */
Expand Down Expand Up @@ -437,6 +439,9 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
if (typeof options.tlsCAFile === 'string') {
options.ca ??= await fs.readFile(options.tlsCAFile);
}
if (typeof options.tlsCRLFile === 'string') {
options.crl ??= await fs.readFile(options.tlsCRLFile);
}
if (typeof options.tlsCertificateKeyFile === 'string') {
if (!options.key || !options.cert) {
const contents = await fs.readFile(options.tlsCertificateKeyFile);
Expand Down Expand Up @@ -790,7 +795,7 @@ export interface MongoOptions
* | nodejs native option | driver spec equivalent option name | driver option type |
* |:----------------------|:----------------------------------------------|:-------------------|
* | `ca` | `tlsCAFile` | `string` |
* | `crl` | N/A | `string` |
* | `crl` | `tlsCRLFile` | `string` |
* | `cert` | `tlsCertificateKeyFile` | `string` |
* | `key` | `tlsCertificateKeyFile` | `string` |
* | `passphrase` | `tlsCertificateKeyFilePassword` | `string` |
Expand All @@ -814,8 +819,8 @@ export interface MongoOptions
* `cert` and `key` fields will be undefined.
*/
tls: boolean;

tlsCAFile?: string;
tlsCRLFile?: string;
tlsCertificateKeyFile?: string;

/** @internal */
Expand Down
32 changes: 28 additions & 4 deletions test/manual/tls_support.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ import {
MongoServerSelectionError
} from '../mongodb';

const REQUIRED_ENV = ['MONGODB_URI', 'SSL_KEY_FILE', 'SSL_CA_FILE'];
const REQUIRED_ENV = ['MONGODB_URI', 'TLS_KEY_FILE', 'TLS_CA_FILE', 'TLS_CRL_FILE'];

describe('TLS Support', function () {
for (const key of REQUIRED_ENV) {
if (process.env[key] == null) {
throw new Error(`skipping SSL tests, ${key} environment variable is not defined`);
throw new Error(`skipping TLS tests, ${key} environment variable is not defined`);
}
}

const CONNECTION_STRING = process.env.MONGODB_URI as string;
const TLS_CERT_KEY_FILE = process.env.SSL_KEY_FILE as string;
const TLS_CA_FILE = process.env.SSL_CA_FILE as string;
const TLS_CERT_KEY_FILE = process.env.TLS_KEY_FILE as string;
const TLS_CA_FILE = process.env.TLS_CA_FILE as string;
const TLS_CRL_FILE = process.env.TLS_CRL_FILE as string;
const tlsSettings = {
tls: true,
tlsCertificateKeyFile: TLS_CERT_KEY_FILE,
Expand Down Expand Up @@ -114,6 +115,29 @@ describe('TLS Support', function () {
});
});

context('when providing tlsCRLFile', () => {
context('when the file will revoke the certificate', () => {
let client: MongoClient;
beforeEach(() => {
client = new MongoClient(CONNECTION_STRING, {
tls: true,
tlsCAFile: TLS_CA_FILE,
tlsCRLFile: TLS_CRL_FILE,
serverSelectionTimeoutMS: 5000,
connectTimeoutMS: 5000
});
});
afterEach(async () => {
await client?.close();
});

it('throws a MongoServerSelectionError', async () => {
const err = await client.connect().catch(e => e);
expect(err).to.be.instanceOf(MongoServerSelectionError);
});
});
});

context('when tlsCertificateKeyFile is provided, but tlsCAFile is missing', () => {
let client: MongoClient;
beforeEach(() => {
Expand Down
7 changes: 7 additions & 0 deletions test/unit/connection_string.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,13 @@ describe('Connection String', function () {
});
});

context('when providing tlsCRLFile', function () {
it('sets the tlsCRLFile option', function () {
const options = parseOptions('mongodb://localhost/?tls=true&tlsCRLFile=path/to/crl.pem');
expect(options.tlsCRLFile).to.equal('path/to/crl.pem');
});
});

context('when both tls and ssl options are provided', function () {
context('when the options are provided in the URI', function () {
context('when the options are equal', function () {
Expand Down
2 changes: 2 additions & 0 deletions test/unit/mongo_client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('MongoOptions', function () {
const options = parseOptions('mongodb://localhost:27017/?ssl=true', {
tlsCertificateKeyFile: filename,
tlsCAFile: filename,
tlsCRLFile: filename,
tlsCertificateKeyFilePassword: 'tlsCertificateKeyFilePassword'
});
fs.unlinkSync(filename);
Expand All @@ -61,6 +62,7 @@ describe('MongoOptions', function () {
expect(options).to.not.have.property('cert');
expect(options).to.have.property('tlsCertificateKeyFile', filename);
expect(options).to.have.property('tlsCAFile', filename);
expect(options).to.have.property('tlsCRLFile', filename);
expect(options).has.property('passphrase', 'tlsCertificateKeyFilePassword');
expect(options).has.property('tls', true);
});
Expand Down

0 comments on commit ca1efd8

Please sign in to comment.