-
Notifications
You must be signed in to change notification settings - Fork 79
chore(ci): add FIPS e2e and smoke tests MONGOSH-1222 #1298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
01c9daf
3bcc3a5
bd01d4d
e093335
63d0214
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
/* eslint-disable no-console */ | ||
/* eslint-disable no-console, @typescript-eslint/no-non-null-assertion, chai-friendly/no-unused-expressions */ | ||
import { spawn } from 'child_process'; | ||
import assert from 'assert'; | ||
import { once } from 'events'; | ||
import { redactURICredentials } from '@mongosh/history'; | ||
import fleSmokeTestScript from './smoke-tests-fle'; | ||
import { buildInfo } from './build-info'; | ||
|
||
/** | ||
* Run smoke tests on an executable, e.g. | ||
|
@@ -20,11 +21,23 @@ export async function runSmokeTests(smokeTestServer: string | undefined, executa | |
assert(!!smokeTestServer, 'Make sure MONGOSH_SMOKE_TEST_SERVER is set in CI'); | ||
} | ||
|
||
for (const { input, output, testArgs } of [{ | ||
const skipFipsWithOpenSSL3 = process.env.MONGOSH_SMOKE_TEST_OS_SKIP_FIPS_WITH_OPENSSL3 && buildInfo().opensslVersion.startsWith('3.'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Had to add this option since the docker images that provide a OpenSSL-3-capable OS don’t provide FIPS support in a usable way. That’s okay – we are being clear here about the fact that what we provide is shared OpenSSL support and the ability to put OpenSSL in FIPS mode. Making sure that their local OpenSSL works in FIPS mode is the user’s responsibility. |
||
const expectFipsSupport = !!process.env.MONGOSH_SMOKE_TEST_OS_HAS_FIPS_SUPPORT && buildInfo().sharedOpenssl; | ||
console.log('FIPS support required to pass?', { skipFipsWithOpenSSL3, expectFipsSupport }); | ||
|
||
for (const { input, output, testArgs, includeStderr } of [{ | ||
input: 'print("He" + "llo" + " Wor" + "ld!")', | ||
output: /Hello World!/, | ||
includeStderr: false, | ||
testArgs: ['--nodb'], | ||
}].concat(smokeTestServer ? [{ | ||
}].concat(skipFipsWithOpenSSL3 ? [] : [{ | ||
input: 'crypto.createHash("md5").update("hello").digest("hex")', | ||
output: expectFipsSupport ? | ||
/disabled for FIPS/i : | ||
/disabled for FIPS|Could not enable FIPS mode/i, | ||
includeStderr: true, | ||
testArgs: ['--tlsFIPSMode', '--nodb'] | ||
}]).concat(smokeTestServer ? [{ | ||
input: ` | ||
const dbname = "testdb_simplesmoke" + new Date().getTime(); | ||
use(dbname); | ||
|
@@ -34,13 +47,15 @@ export async function runSmokeTests(smokeTestServer: string | undefined, executa | |
} | ||
db.dropDatabase();`, | ||
output: /Test succeeded/, | ||
includeStderr: false, | ||
testArgs: [smokeTestServer as string] | ||
}, { | ||
input: fleSmokeTestScript, | ||
output: /Test succeeded|Test skipped/, | ||
includeStderr: false, | ||
testArgs: [smokeTestServer as string] | ||
}] : [])) { | ||
await runSmokeTest(executable, [...args, ...testArgs], input, output); | ||
await runSmokeTest(executable, [...args, ...testArgs], input, output, includeStderr); | ||
} | ||
console.log('all tests passed'); | ||
} | ||
|
@@ -53,16 +68,18 @@ export async function runSmokeTests(smokeTestServer: string | undefined, executa | |
* @param input stdin contents of the executable | ||
* @param output Expected contents of stdout | ||
*/ | ||
async function runSmokeTest(executable: string, args: string[], input: string, output: RegExp): Promise<void> { | ||
async function runSmokeTest(executable: string, args: string[], input: string, output: RegExp, includeStderr?: boolean): Promise<void> { | ||
const proc = spawn(executable, [...args], { | ||
stdio: ['pipe', 'pipe', 'inherit'] | ||
stdio: ['pipe', 'pipe', includeStderr ? 'pipe' : 'inherit'] | ||
}); | ||
let stdout = ''; | ||
proc.stdout.setEncoding('utf8').on('data', (chunk) => { stdout += chunk; }); | ||
proc.stdin.end(input); | ||
await once(proc.stdout, 'end'); | ||
let stderr = ''; | ||
proc.stdout!.setEncoding('utf8').on('data', (chunk) => { stdout += chunk; }); | ||
proc.stderr?.setEncoding('utf8').on('data', (chunk) => { stderr += chunk; }); | ||
proc.stdin!.end(input); | ||
await once(proc.stdout!, 'end'); | ||
try { | ||
assert.match(stdout, output); | ||
assert.match(includeStderr ? `${stdout}\n${stderr}` : stdout, output); | ||
console.error({ status: 'success', input, output, stdout, executable, args: args.map(arg => redactURICredentials(arg)) }); | ||
} catch (err: any) { | ||
console.error({ status: 'failure', input, output, stdout, executable, args: args.map(arg => redactURICredentials(arg)) }); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,6 @@ ADD ${artifact_url} /tmp | |
ADD node_modules /usr/share/mongodb-crypt-library-version/node_modules | ||
RUN yum repolist | ||
RUN yum install -y /tmp/*mongosh*.rpm | ||
RUN /usr/bin/mongosh --version | ||
RUN /usr/bin/mongosh --build-info | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just so that we can see the openssl config values more easily for debugging |
||
RUN env MONGOSH_RUN_NODE_SCRIPT=1 mongosh /usr/share/mongodb-crypt-library-version/node_modules/.bin/mongodb-crypt-library-version /usr/lib64/mongosh_crypt_v1.so | grep -Eq '^mongo_(crypt|csfle)_v1-' | ||
ENTRYPOINT [ "mongosh" ] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -133,9 +133,14 @@ To recreate the certificates follow the steps outlined below. | |
openssl ca -create_serial -config ca.cnf -in client.csr -out client.pem -days 99999 | ||
``` | ||
This will also generate a `<FINGERPRINT>.pem` file which can be removed. | ||
4. Create a bundle with client key and certificate to use for connecting: | ||
4. Create an encrypted client key file from the existing unencrypted one: | ||
``` | ||
openssl pkcs8 -topk8 -in client.key -v2 aes-256-cbc -out client.encrypted.key -passout pass:p4ssw0rd | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would have never figured this one There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mcasimir To be clear, my knowledge here also only comes from StackOverflow 😉 https://superuser.com/questions/1664393/are-private-keys-generated-by-openssl-when-fips-mode-is-disabled-usable-when-fip |
||
``` | ||
5. Create bundles with client key and certificate to use for connecting: | ||
``` | ||
cat client.pem client.key > client.bundle.pem | ||
cat client.pem client.encrypted.key > client.bundle.encrypted.pem | ||
``` | ||
|
||
## Create Client Certificate not from CA | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only variant where FIPS support worked out of the box. For other OSes, I guess the docker tests have to be enough (although I was pleasantly surprised to see that FIPS support works even for their docker images).