Skip to content

Commit 44bbd6e

Browse files
authored
feat(NODE-3777): add csfle kmip support (#3070)
1 parent f5c76f3 commit 44bbd6e

27 files changed

+5652
-67
lines changed

.evergreen/config.yml

Lines changed: 62 additions & 14 deletions
Large diffs are not rendered by default.

.evergreen/config.yml.in

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@ functions:
119119
${PREPARE_SHELL}
120120
DRIVERS_TOOLS="${DRIVERS_TOOLS}" bash ${DRIVERS_TOOLS}/.evergreen/atlas_data_lake/run-mongohouse-local.sh
121121

122+
"bootstrap kms servers":
123+
- command: subprocess.exec
124+
params:
125+
background: true
126+
working_dir: src
127+
binary: bash
128+
args:
129+
- .evergreen/run-kms-servers.sh
130+
env:
131+
DRIVERS_TOOLS: ${DRIVERS_TOOLS}
122132
"run tests":
123133
- command: shell.exec
124134
type: test
@@ -133,6 +143,8 @@ functions:
133143
export AWS_ACCESS_KEY_ID='${AWS_ACCESS_KEY_ID}'
134144
export AWS_SECRET_ACCESS_KEY='${AWS_SECRET_ACCESS_KEY}'
135145
export AWS_DEFAULT_REGION='us-east-1'
146+
export KMIP_TLS_CA_FILE="${DRIVERS_TOOLS}/.evergreen/x509gen/ca.pem"
147+
export KMIP_TLS_CERT_FILE="${DRIVERS_TOOLS}/.evergreen/x509gen/client.pem"
136148
EOT
137149
fi
138150
- command: shell.exec
@@ -193,8 +205,7 @@ functions:
193205
- command: shell.exec
194206
params:
195207
script: |
196-
DRIVERS_TOOLS=${DRIVERS_TOOLS} MONGODB_URI=${MONGODB_URI} \
197-
bash ${DRIVERS_TOOLS}/.evergreen/run-load-balancer.sh start
208+
MONGODB_URI=${MONGODB_URI} bash ${DRIVERS_TOOLS}/.evergreen/run-load-balancer.sh start
198209
- command: expansions.update
199210
params:
200211
file: lb-expansion.yml
@@ -203,7 +214,6 @@ functions:
203214
- command: shell.exec
204215
params:
205216
script: |
206-
DRIVERS_TOOLS=${DRIVERS_TOOLS} MONGODB_URI=${MONGODB_URI} \
207217
bash ${DRIVERS_TOOLS}/.evergreen/run-load-balancer.sh stop
208218

209219
"run-lb-tests":

.evergreen/generate_evergreen_tasks.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ function makeTask({ mongoVersion, topology, tags = [], auth = 'auth' }) {
6262
AUTH: auth
6363
}
6464
},
65+
{ func: 'bootstrap kms servers' },
6566
{ func: 'run tests' }
6667
]
6768
};
@@ -96,6 +97,7 @@ BASE_TASKS.push({
9697
AUTH: 'auth'
9798
}
9899
},
100+
{ func: 'bootstrap kms servers' },
99101
{
100102
func: 'run tests',
101103
vars: {
@@ -163,6 +165,7 @@ TASKS.push(
163165
TOPOLOGY: 'replica_set'
164166
}
165167
},
168+
{ func: 'bootstrap kms servers' },
166169
{ func: 'run socks5 tests' }
167170
]
168171
},
@@ -637,7 +640,6 @@ BUILD_VARIANTS.push({
637640
});
638641

639642
const oneOffFuncs = [
640-
{ func: 'run custom csfle tests' },
641643
{ func: 'run custom snappy tests' },
642644
{
643645
func: 'run bson-ext test',
@@ -669,6 +671,28 @@ const oneOffFuncAsTasks = oneOffFuncs.map(oneOffFunc => ({
669671
]
670672
}));
671673

674+
oneOffFuncAsTasks.push({
675+
name: 'run-custom-csfle-tests',
676+
tags: ['run-custom-dependency-tests'],
677+
commands: [
678+
{
679+
func: 'install dependencies',
680+
vars: {
681+
NODE_LTS_NAME: LOWEST_LTS
682+
}
683+
},
684+
{
685+
func: 'bootstrap mongo-orchestration',
686+
vars: {
687+
VERSION: 'latest',
688+
TOPOLOGY: 'server'
689+
}
690+
},
691+
{ func: 'bootstrap kms servers' },
692+
{ func: 'run custom csfle tests' }
693+
]
694+
});
695+
672696
// TODO NODE-3897 - generate combined coverage report
673697
const coverageTask = {
674698
name: 'download and merge coverage'.split(' ').join('-'),

.evergreen/run-bson-ext-test.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ fi
2323
# run tests
2424
echo "Running $AUTH tests over $SSL, connecting to $MONGODB_URI"
2525

26+
npm install mongodb-client-encryption@">=2.0.0-beta.3"
2627
npm install bson-ext
2728

2829
export MONGODB_API_VERSION=${MONGODB_API_VERSION}

.evergreen/run-custom-csfle-tests.sh

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ popd # ../csfle-deps-tmp
6363
cp -R ../csfle-deps-tmp/libmongocrypt/bindings/node node_modules/mongodb-client-encryption
6464

6565
export MONGODB_URI=${MONGODB_URI}
66+
export KMIP_TLS_CA_FILE="${DRIVERS_TOOLS}/.evergreen/x509gen/ca.pem"
67+
export KMIP_TLS_CERT_FILE="${DRIVERS_TOOLS}/.evergreen/x509gen/client.pem"
6668
set +o errexit # We want to run both test suites even if the first fails
6769
npm run check:csfle
6870
DRIVER_CSFLE_TEST_RESULT=$?
@@ -103,8 +105,3 @@ if [ $DRIVER_CSFLE_TEST_RESULT -ne 0 ]; then
103105
echo "Driver tests failed, look above for results"
104106
exit 1
105107
fi
106-
107-
echo "Test legacy version of FLE bindings"
108-
rm -rf node_modules/mongodb-client-encryption
109-
npm install mongodb-client-encryption@"^1.2.7"
110-
npm run check:csfle

.evergreen/run-kms-servers.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
cd ${DRIVERS_TOOLS}/.evergreen/csfle
2+
. ./activate_venv.sh
3+
# by default it always runs on port 5698
4+
./kmstlsvenv/bin/python3 -u kms_kmip_server.py &
5+
./kmstlsvenv/bin/python3 -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/expired.pem --port 8000 &
6+
./kmstlsvenv/bin/python3 -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/wrong-host.pem --port 8001 &
7+
./kmstlsvenv/bin/python3 -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/server.pem --port 8002 --require_client_cert &

.evergreen/run-tests.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ if [[ -z "${CLIENT_ENCRYPTION}" ]]; then
4141
unset AWS_ACCESS_KEY_ID;
4242
unset AWS_SECRET_ACCESS_KEY;
4343
else
44-
npm install mongodb-client-encryption@">=2.0.0-beta.0"
4544
pip install --upgrade boto3
46-
4745
# Get access to the AWS temporary credentials:
4846
echo "adding temporary AWS credentials to environment"
4947
# CSFLE_AWS_TEMP_ACCESS_KEY_ID, CSFLE_AWS_TEMP_SECRET_ACCESS_KEY, CSFLE_AWS_TEMP_SESSION_TOKEN
5048
. $DRIVERS_TOOLS/.evergreen/csfle/set-temp-creds.sh
5149
fi
5250

51+
npm install mongodb-client-encryption@">=2.0.0-beta.3"
52+
5353
AUTH=$AUTH SINGLE_MONGOS_LB_URI=${SINGLE_MONGOS_LB_URI} MULTI_MONGOS_LB_URI=${MULTI_MONGOS_LB_URI} MONGODB_API_VERSION=${MONGODB_API_VERSION} MONGODB_UNIFIED_TOPOLOGY=${UNIFIED} MONGODB_URI=${MONGODB_URI} LOAD_BALANCER=${LOAD_BALANCER} npm run ${TEST_NPM_SCRIPT}

src/deps.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,28 @@ export const AutoEncryptionLoggerLevel = Object.freeze({
174174
export type AutoEncryptionLoggerLevel =
175175
typeof AutoEncryptionLoggerLevel[keyof typeof AutoEncryptionLoggerLevel];
176176

177+
/** @public */
178+
export interface AutoEncryptionTlsOptions {
179+
/**
180+
* Specifies the location of a local .pem file that contains
181+
* either the client's TLS/SSL certificate and key or only the
182+
* client's TLS/SSL key when tlsCertificateFile is used to
183+
* provide the certificate.
184+
*/
185+
tlsCertificateKeyFile?: string;
186+
/**
187+
* Specifies the password to de-crypt the tlsCertificateKeyFile.
188+
*/
189+
tlsCertificateKeyFilePassword?: string;
190+
/**
191+
* Specifies the location of a local .pem file that contains the
192+
* root certificate chain from the Certificate Authority.
193+
* This file is used to validate the certificate presented by the
194+
* KMS provider.
195+
*/
196+
tlsCAFile?: string;
197+
}
198+
177199
/** @public */
178200
export interface AutoEncryptionOptions {
179201
/** @internal */
@@ -234,6 +256,17 @@ export interface AutoEncryptionOptions {
234256
*/
235257
endpoint?: string | undefined;
236258
};
259+
/**
260+
* Configuration options for using 'kmip' as your KMS provider
261+
*/
262+
kmip?: {
263+
/**
264+
* The output endpoint string.
265+
* The endpoint consists of a hostname and port separated by a colon.
266+
* E.g. "example.com:123". A port is always present.
267+
*/
268+
endpoint?: string;
269+
};
237270
};
238271
/**
239272
* A map of namespaces to a local JSON schema for encryption
@@ -264,6 +297,14 @@ export interface AutoEncryptionOptions {
264297
mongocryptdSpawnArgs?: string[];
265298
};
266299
proxyOptions?: ProxyOptions;
300+
/** The TLS options to use connecting to the KMS provider */
301+
tlsOptions?: {
302+
aws?: AutoEncryptionTlsOptions;
303+
local?: AutoEncryptionTlsOptions;
304+
azure?: AutoEncryptionTlsOptions;
305+
gcp?: AutoEncryptionTlsOptions;
306+
kmip?: AutoEncryptionTlsOptions;
307+
};
267308
}
268309

269310
/** @public */

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ export type {
229229
export type { InternalAbstractCursorOptions } from './cursor/abstract_cursor';
230230
export type { AggregationCursorOptions } from './cursor/aggregation_cursor';
231231
export type { DbOptions, DbPrivate } from './db';
232-
export type { AutoEncrypter, AutoEncryptionOptions } from './deps';
232+
export type { AutoEncrypter, AutoEncryptionOptions, AutoEncryptionTlsOptions } from './deps';
233233
export type { Encrypter, EncrypterOptions } from './encrypter';
234234
export type { AnyError, ErrorDescription, MongoNetworkErrorOptions } from './error';
235235
export type { Explain, ExplainOptions, ExplainVerbosityLike } from './explain';

test/integration/client-side-encryption/client_side_encryption.corpus.spec.test.js

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ describe('Client Side Encryption Corpus', function () {
2929
'base64'
3030
)
3131
};
32+
kmsProviders.kmip = {
33+
endpoint: 'localhost:5698'
34+
};
3235

3336
// TODO: build this into EJSON
3437
// TODO: make a custom chai assertion for this
@@ -55,6 +58,7 @@ describe('Client Side Encryption Corpus', function () {
5558
const corpusKeyLocal = loadCorpusData('corpus-key-local.json');
5659
const corpusKeyAws = loadCorpusData('corpus-key-aws.json');
5760
const corpusKeyAzure = loadCorpusData('corpus-key-azure.json');
61+
const corpusKeyKmip = loadCorpusData('corpus-key-kmip.json');
5862
const corpusKeyGcp = loadCorpusData('corpus-key-gcp.json');
5963
const corpusAll = filterImportedObject(loadCorpusData('corpus.json'));
6064
const corpusEncryptedExpectedAll = filterImportedObject(loadCorpusData('corpus-encrypted.json'));
@@ -74,20 +78,23 @@ describe('Client Side Encryption Corpus', function () {
7478
['local', corpusKeyLocal._id],
7579
['aws', corpusKeyAws._id],
7680
['azure', corpusKeyAzure._id],
77-
['gcp', corpusKeyGcp._id]
81+
['gcp', corpusKeyGcp._id],
82+
['kmip', corpusKeyKmip._id]
7883
]);
7984
const keyAltNameMap = new Map([
8085
['local', 'local'],
8186
['aws', 'aws'],
8287
['azure', 'azure'],
83-
['gcp', 'gcp']
88+
['gcp', 'gcp'],
89+
['kmip', 'kmip']
8490
]);
8591
const copyOverValues = new Set([
8692
'_id',
8793
'altname_aws',
8894
'altname_local',
8995
'altname_azure',
90-
'altname_gcp'
96+
'altname_gcp',
97+
'altname_kmip'
9198
]);
9299

93100
let client;
@@ -153,7 +160,13 @@ describe('Client Side Encryption Corpus', function () {
153160
.catch(() => {})
154161
.then(() => keyDb.collection(keyVaultCollName))
155162
.then(keyColl =>
156-
keyColl.insertMany([corpusKeyLocal, corpusKeyAws, corpusKeyAzure, corpusKeyGcp])
163+
keyColl.insertMany([
164+
corpusKeyLocal,
165+
corpusKeyAws,
166+
corpusKeyAzure,
167+
corpusKeyGcp,
168+
corpusKeyKmip
169+
])
157170
);
158171
});
159172
});
@@ -195,9 +208,16 @@ describe('Client Side Encryption Corpus', function () {
195208
// .. code:: javascript
196209
// Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk
197210
// Configure both objects with ``keyVaultNamespace`` set to ``keyvault.datakeys``.
211+
const tlsOptions = {
212+
kmip: {
213+
tlsCAFile: process.env.KMIP_TLS_CA_FILE,
214+
tlsCertificateKeyFile: process.env.KMIP_TLS_CERT_FILE
215+
}
216+
};
198217
const autoEncryption = {
199218
keyVaultNamespace,
200-
kmsProviders
219+
kmsProviders,
220+
tlsOptions
201221
};
202222
if (useClientSideSchema) {
203223
autoEncryption.schemaMap = {
@@ -210,7 +230,8 @@ describe('Client Side Encryption Corpus', function () {
210230
clientEncryption = new mongodbClientEncryption.ClientEncryption(client, {
211231
bson: BSON,
212232
keyVaultNamespace,
213-
kmsProviders
233+
kmsProviders,
234+
tlsOptions
214235
});
215236
});
216237
});

0 commit comments

Comments
 (0)