diff --git a/.buildkite/pipelines/fips.yml b/.buildkite/pipelines/fips.yml index f4a5b3623bbcc..e04a5ecb8f936 100644 --- a/.buildkite/pipelines/fips.yml +++ b/.buildkite/pipelines/fips.yml @@ -40,14 +40,15 @@ steps: machineType: n2-standard-2 preemptible: true - - command: .buildkite/scripts/steps/fips/smoke_test.sh - label: 'Pick Smoke Test Group Run Order' + - command: .buildkite/scripts/steps/test/pick_test_group_run_order.sh + label: 'Pick Test Group Run Order' depends_on: build timeout_in_minutes: 10 env: FTR_CONFIGS_SCRIPT: '.buildkite/scripts/steps/test/ftr_configs.sh' FTR_EXTRA_ARGS: '$FTR_EXTRA_ARGS' - LIMIT_CONFIG_TYPE: 'functional' + JEST_UNIT_SCRIPT: '.buildkite/scripts/steps/test/jest.sh' + JEST_INTEGRATION_SCRIPT: '.buildkite/scripts/steps/test/jest_integration.sh' retry: automatic: - exit_status: '*' diff --git a/.buildkite/scripts/steps/fips/smoke_test.sh b/.buildkite/scripts/steps/fips/smoke_test.sh deleted file mode 100755 index 685bb111ff81a..0000000000000 --- a/.buildkite/scripts/steps/fips/smoke_test.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# Limit the FTR configs for now to avoid running all the tests. Once we're -# ready to utilize the full FTR suite in FIPS mode, we can remove this file and -# call pick_test_group_run_order.sh directly in .buildkite/pipelines/fips.yml. -configs=( - "x-pack/test/reporting_functional/reporting_and_security.config.ts" - "x-pack/test/saved_object_api_integration/security_and_spaces/config_trial.ts" - "x-pack/test/alerting_api_integration/security_and_spaces/group1/config.ts" - "x-pack/test/alerting_api_integration/security_and_spaces/group2/config.ts" - "x-pack/test/alerting_api_integration/security_and_spaces/group3/config.ts" - "x-pack/test/alerting_api_integration/security_and_spaces/group4/config.ts" - "x-pack/test/functional/apps/saved_objects_management/config.ts" - "x-pack/test/functional/apps/user_profiles/config.ts" - "x-pack/test/functional/apps/security/config.ts" -) - -printf -v FTR_CONFIG_PATTERNS '%s,' "${configs[@]}" -FTR_CONFIG_PATTERNS="${FTR_CONFIG_PATTERNS%,}" -export FTR_CONFIG_PATTERNS - -.buildkite/scripts/steps/test/pick_test_group_run_order.sh diff --git a/.buildkite/scripts/steps/test/jest_parallel.sh b/.buildkite/scripts/steps/test/jest_parallel.sh index 2a7cf780f5787..648c3b225141d 100755 --- a/.buildkite/scripts/steps/test/jest_parallel.sh +++ b/.buildkite/scripts/steps/test/jest_parallel.sh @@ -60,7 +60,14 @@ while read -r config; do # --trace-warnings to debug # Node.js process-warning detected: # Warning: Closing file descriptor 24 on garbage collection - cmd="NODE_OPTIONS=\"--max-old-space-size=12288 --trace-warnings\" node ./scripts/jest --config=\"$config\" $parallelism --coverage=false --passWithNoTests" + cmd="NODE_OPTIONS=\"--max-old-space-size=12288 --trace-warnings" + + if [ "${KBN_ENABLE_FIPS:-}" == "true" ]; then + cmd=$cmd" --enable-fips --openssl-config=$HOME/nodejs.cnf" + fi + + cmd=$cmd"\" node ./scripts/jest --config=\"$config\" $parallelism --coverage=false --passWithNoTests" + echo "actual full command is:" echo "$cmd" echo "" diff --git a/packages/core/security/core-security-server-internal/src/security_service.test.ts b/packages/core/security/core-security-server-internal/src/security_service.test.ts index 75539e9954ac0..0ff1e59db71ec 100644 --- a/packages/core/security/core-security-server-internal/src/security_service.test.ts +++ b/packages/core/security/core-security-server-internal/src/security_service.test.ts @@ -16,17 +16,32 @@ import { loggerMock, MockedLogger } from '@kbn/logging-mocks'; import { mockCoreContext } from '@kbn/core-base-server-mocks'; import type { CoreSecurityDelegateContract } from '@kbn/core-security-server'; import { SecurityService } from './security_service'; +import { configServiceMock } from '@kbn/config-mocks'; +import { getFips } from 'crypto'; const createStubInternalContract = (): CoreSecurityDelegateContract => { return Symbol('stubContract') as unknown as CoreSecurityDelegateContract; }; -describe('SecurityService', () => { +describe('SecurityService', function () { let coreContext: ReturnType; + let configService: ReturnType; let service: SecurityService; beforeEach(() => { - coreContext = mockCoreContext.create(); + const mockConfig = { + xpack: { + security: { + experimental: { + fipsMode: { + enabled: !!getFips(), + }, + }, + }, + }, + }; + configService = configServiceMock.create({ getConfig$: mockConfig }); + coreContext = mockCoreContext.create({ configService }); service = new SecurityService(coreContext); convertSecurityApiMock.mockReset(); @@ -51,8 +66,11 @@ describe('SecurityService', () => { describe('#isEnabled', () => { it('should return boolean', () => { const { fips } = service.setup(); - - expect(fips.isEnabled()).toBe(false); + if (getFips() === 0) { + expect(fips.isEnabled()).toBe(false); + } else { + expect(fips.isEnabled()).toBe(true); + } }); }); }); diff --git a/packages/core/security/core-security-server-internal/tsconfig.json b/packages/core/security/core-security-server-internal/tsconfig.json index e1812dc77cf49..11128461daf4e 100644 --- a/packages/core/security/core-security-server-internal/tsconfig.json +++ b/packages/core/security/core-security-server-internal/tsconfig.json @@ -22,5 +22,6 @@ "@kbn/core-base-server-mocks", "@kbn/config", "@kbn/core-logging-server-mocks", + "@kbn/config-mocks", ] } diff --git a/packages/core/test-helpers/core-test-helpers-kbn-server/src/create_root.ts b/packages/core/test-helpers/core-test-helpers-kbn-server/src/create_root.ts index d2fa6850a8bf8..38dae90905cb2 100644 --- a/packages/core/test-helpers/core-test-helpers-kbn-server/src/create_root.ts +++ b/packages/core/test-helpers/core-test-helpers-kbn-server/src/create_root.ts @@ -12,10 +12,12 @@ import loadJsonFile from 'load-json-file'; import { defaultsDeep } from 'lodash'; import { BehaviorSubject } from 'rxjs'; import supertest from 'supertest'; +import { set } from '@kbn/safer-lodash-set'; import { getPackages } from '@kbn/repo-packages'; import { ToolingLog } from '@kbn/tooling-log'; import { REPO_ROOT } from '@kbn/repo-info'; +import { getFips } from 'crypto'; import { createTestEsCluster, CreateTestEsClusterOptions, @@ -75,6 +77,17 @@ export function createRootWithSettings( pkg.version = customKibanaVersion; } + /* + * Most of these integration tests expect OSS to default to true, but FIPS + * requires the security plugin to be enabled + */ + let oss = true; + if (getFips() === 1) { + set(settings, 'xpack.security.experimental.fipsMode.enabled', true); + oss = false; + delete cliArgs.oss; + } + const env = Env.createDefault( REPO_ROOT, { @@ -84,10 +97,10 @@ export function createRootWithSettings( watch: false, basePath: false, runExamples: false, - oss: true, disableOptimizer: true, cache: true, dist: false, + oss, ...cliArgs, }, repoPackages: getPackages(REPO_ROOT), @@ -255,7 +268,13 @@ export function createTestServers({ if (!adjustTimeout) { throw new Error('adjustTimeout is required in order to avoid flaky tests'); } - const license = settings.es?.license ?? 'basic'; + let license = settings.es?.license ?? 'basic'; + + if (getFips() === 1) { + // Set license to 'trial' if Node is running in FIPS mode + license = 'trial'; + } + const usersToBeAdded = settings.users ?? []; if (usersToBeAdded.length > 0) { if (license !== 'trial') { @@ -292,6 +311,7 @@ export function createTestServers({ hosts: es.getHostUrls(), username: kibanaServerTestUser.username, password: kibanaServerTestUser.password, + ...(getFips() ? kbnSettings.elasticsearch : {}), }; } diff --git a/packages/core/test-helpers/core-test-helpers-kbn-server/tsconfig.json b/packages/core/test-helpers/core-test-helpers-kbn-server/tsconfig.json index 85d14bb04ab59..65ca0ccdfca0b 100644 --- a/packages/core/test-helpers/core-test-helpers-kbn-server/tsconfig.json +++ b/packages/core/test-helpers/core-test-helpers-kbn-server/tsconfig.json @@ -20,6 +20,7 @@ "@kbn/repo-packages", "@kbn/es", "@kbn/dev-utils", + "@kbn/safer-lodash-set", ], "exclude": [ "target/**/*", diff --git a/packages/kbn-es/src/install/install_source.ts b/packages/kbn-es/src/install/install_source.ts index 244b349002829..9a7e8f166791a 100644 --- a/packages/kbn-es/src/install/install_source.ts +++ b/packages/kbn-es/src/install/install_source.ts @@ -84,7 +84,7 @@ async function sourceInfo(cwd: string, license: string, log: ToolingLog = defaul log.info('on %s at %s', chalk.bold(branch), chalk.bold(sha)); log.info('%s locally modified file(s)', chalk.bold(status.modified.length)); - const etag = crypto.createHash('md5').update(branch); // eslint-disable-line @kbn/eslint/no_unsafe_hash + const etag = crypto.createHash('sha256').update(branch); etag.update(sha); // for changed files, use last modified times in hash calculation @@ -92,7 +92,7 @@ async function sourceInfo(cwd: string, license: string, log: ToolingLog = defaul etag.update(fs.statSync(path.join(cwd, file.path)).mtime.toString()); }); - const cwdHash = crypto.createHash('md5').update(cwd).digest('hex').substr(0, 8); // eslint-disable-line @kbn/eslint/no_unsafe_hash + const cwdHash = crypto.createHash('sha256').update(cwd).digest('hex').substr(0, 8); const basename = `${branch}-${task}-${cwdHash}`; const filename = `${basename}.${ext}`; diff --git a/packages/kbn-test/src/es/test_es_cluster.ts b/packages/kbn-test/src/es/test_es_cluster.ts index 620147e1fa7ab..20c54e044e46f 100644 --- a/packages/kbn-test/src/es/test_es_cluster.ts +++ b/packages/kbn-test/src/es/test_es_cluster.ts @@ -21,6 +21,7 @@ import type { ToolingLog } from '@kbn/tooling-log'; import { REPO_ROOT } from '@kbn/repo-info'; import type { ArtifactLicense } from '@kbn/es'; import type { ServerlessOptions } from '@kbn/es/src/utils'; +import { getFips } from 'crypto'; import { CI_PARALLEL_PROCESS_PREFIX } from '../ci_parallel_process_prefix'; import { esTestConfig } from './es_test_config'; @@ -200,12 +201,15 @@ export function createTestEsCluster< const esArgs = assignArgs(defaultEsArgs, customEsArgs); + // Use 'trial' license if FIPS mode is enabled, otherwise use the provided license or default to 'basic' + const testLicense: ArtifactLicense = getFips() === 1 ? 'trial' : license ? license : 'basic'; + const config = { version: esVersion, installPath: Path.resolve(basePath, clusterName), sourcePath: Path.resolve(REPO_ROOT, '../elasticsearch'), + license: testLicense, password, - license, basePath, esArgs, resources: files, diff --git a/src/core/server/integration_tests/config/check_dynamic_config.test.ts b/src/core/server/integration_tests/config/check_dynamic_config.test.ts index 85061b876eebf..38250076385b9 100644 --- a/src/core/server/integration_tests/config/check_dynamic_config.test.ts +++ b/src/core/server/integration_tests/config/check_dynamic_config.test.ts @@ -16,128 +16,135 @@ import { request, } from '@kbn/core-test-helpers-kbn-server'; import { PLUGIN_SYSTEM_ENABLE_ALL_PLUGINS_CONFIG_PATH } from '@kbn/core-plugins-server-internal/src/constants'; - -describe('PUT /internal/core/_settings', () => { - let esServer: TestElasticsearchUtils; - let root: Root; - - const loggerName = 'my-test-logger'; - - beforeAll(async () => { - const settings = { - coreApp: { allowDynamicConfigOverrides: true }, - logging: { - loggers: [{ name: loggerName, level: 'error', appenders: ['console'] }], - }, - server: { restrictInternalApis: false }, - }; - const { startES, startKibana } = createTestServers({ - adjustTimeout: (t: number) => jest.setTimeout(t), - settings: { - kbn: settings, - }, +import { getFips } from 'crypto'; + +if (getFips() === 0) { + describe('PUT /internal/core/_settings', () => { + let esServer: TestElasticsearchUtils; + let root: Root; + + const loggerName = 'my-test-logger'; + + beforeAll(async () => { + const settings = { + coreApp: { allowDynamicConfigOverrides: true }, + logging: { + loggers: [{ name: loggerName, level: 'error', appenders: ['console'] }], + }, + server: { restrictInternalApis: false }, + }; + const { startES, startKibana } = createTestServers({ + adjustTimeout: (t: number) => jest.setTimeout(t), + settings: { + kbn: settings, + }, + }); + + esServer = await startES(); + + const kbnUtils = await startKibana(); + root = kbnUtils.root; + + // eslint-disable-next-line dot-notation + root['server'].configService.addDynamicConfigPaths('logging', ['loggers']); // just for the sake of being able to change something easy to test }); - esServer = await startES(); - - const kbnUtils = await startKibana(); - root = kbnUtils.root; - - // eslint-disable-next-line dot-notation - root['server'].configService.addDynamicConfigPaths('logging', ['loggers']); // just for the sake of being able to change something easy to test - }); + afterAll(async () => { + await root?.shutdown(); + await esServer?.stop(); + }); - afterAll(async () => { - await root?.shutdown(); - await esServer?.stop(); - }); + test('should update the log level', async () => { + const logger = root.logger.get(loggerName); + expect(logger.isLevelEnabled('info')).toBe(false); + await request + .put(root, '/internal/core/_settings') + .set('Elastic-Api-Version', '1') + .send({ 'logging.loggers': [{ name: loggerName, level: 'debug', appenders: ['console'] }] }) + .expect(200); + expect(logger.isLevelEnabled('info')).toBe(true); + }); - test('should update the log level', async () => { - const logger = root.logger.get(loggerName); - expect(logger.isLevelEnabled('info')).toBe(false); - await request - .put(root, '/internal/core/_settings') - .set('Elastic-Api-Version', '1') - .send({ 'logging.loggers': [{ name: loggerName, level: 'debug', appenders: ['console'] }] }) - .expect(200); - expect(logger.isLevelEnabled('info')).toBe(true); + test('should remove the setting', async () => { + const logger = root.logger.get(loggerName); + expect(logger.isLevelEnabled('info')).toBe(true); // still true from the previous test + await request + .put(root, '/internal/core/_settings') + .set('Elastic-Api-Version', '1') + .send({ 'logging.loggers': null }) + .expect(200); + expect(logger.isLevelEnabled('info')).toBe(false); + }); }); - test('should remove the setting', async () => { - const logger = root.logger.get(loggerName); - expect(logger.isLevelEnabled('info')).toBe(true); // still true from the previous test - await request - .put(root, '/internal/core/_settings') - .set('Elastic-Api-Version', '1') - .send({ 'logging.loggers': null }) - .expect(200); - expect(logger.isLevelEnabled('info')).toBe(false); - }); -}); - -describe('checking all opted-in dynamic config settings', () => { - let root: Root; - - beforeAll(async () => { - const settings = { - logging: { - loggers: [{ name: 'root', level: 'info', appenders: ['console'] }], - }, - server: { - restrictInternalApis: false, - }, - }; - - set(settings, PLUGIN_SYSTEM_ENABLE_ALL_PLUGINS_CONFIG_PATH, true); - - root = createRootWithCorePlugins(settings, { - basePath: false, - cache: false, - dev: true, - disableOptimizer: true, - silent: false, - dist: false, - oss: false, - runExamples: false, - watch: false, + describe('checking all opted-in dynamic config settings', () => { + let root: Root; + + beforeAll(async () => { + const settings = { + logging: { + loggers: [{ name: 'root', level: 'info', appenders: ['console'] }], + }, + server: { + restrictInternalApis: false, + }, + }; + + set(settings, PLUGIN_SYSTEM_ENABLE_ALL_PLUGINS_CONFIG_PATH, true); + + root = createRootWithCorePlugins(settings, { + basePath: false, + cache: false, + dev: true, + disableOptimizer: true, + silent: false, + dist: false, + oss: false, + runExamples: false, + watch: false, + }); + + await root.preboot(); + await root.setup(); }); - await root.preboot(); - await root.setup(); - }); + afterAll(async () => { + if (root) { + await root.shutdown(); + } + }); - afterAll(async () => { - if (root) { - await root.shutdown(); + function getListOfDynamicConfigPaths(): string[] { + // eslint-disable-next-line dot-notation + return [...root['server']['configService']['dynamicPaths'].entries()] + .flatMap(([configPath, dynamicConfigKeys]) => { + return dynamicConfigKeys.map( + (dynamicConfigKey: string) => `${configPath}.${dynamicConfigKey}` + ); + }) + .sort(); } - }); - function getListOfDynamicConfigPaths(): string[] { - // eslint-disable-next-line dot-notation - return [...root['server']['configService']['dynamicPaths'].entries()] - .flatMap(([configPath, dynamicConfigKeys]) => { - return dynamicConfigKeys.map( - (dynamicConfigKey: string) => `${configPath}.${dynamicConfigKey}` - ); - }) - .sort(); - } - - /** - * This test is meant to fail when any setting is flagged as capable - * of dynamic configuration {@link PluginConfigDescriptor.dynamicConfig}. - * - * Please, add your settings to the list with a comment of why it's required to be dynamic. - * - * The intent is to trigger a code review from the Core and Security teams to discuss potential issues. - */ - test('detecting all the settings that have opted-in for dynamic in-memory updates', () => { - expect(getListOfDynamicConfigPaths()).toStrictEqual([ - // Making testing easier by having the ability of overriding the feature flags without the need to restart - 'feature_flags.overrides', - // We need this for enriching our Perf tests with more valuable data regarding the steps of the test - // Also helpful in Cloud & Serverless testing because we can't control the labels in those offerings - 'telemetry.labels', - ]); + /** + * This test is meant to fail when any setting is flagged as capable + * of dynamic configuration {@link PluginConfigDescriptor.dynamicConfig}. + * + * Please, add your settings to the list with a comment of why it's required to be dynamic. + * + * The intent is to trigger a code review from the Core and Security teams to discuss potential issues. + */ + test('detecting all the settings that have opted-in for dynamic in-memory updates', () => { + expect(getListOfDynamicConfigPaths()).toStrictEqual([ + // Making testing easier by having the ability of overriding the feature flags without the need to restart + 'feature_flags.overrides', + // We need this for enriching our Perf tests with more valuable data regarding the steps of the test + // Also helpful in Cloud & Serverless testing because we can't control the labels in those offerings + 'telemetry.labels', + ]); + }); + }); +} else { + it('is running in FIPS mode, skipping tests since they fail due to FIPS overrides', () => { + expect(getFips()).toBe(1); }); -}); +} diff --git a/src/core/server/integration_tests/config/config_deprecation.test.ts b/src/core/server/integration_tests/config/config_deprecation.test.ts index 277a6080c377f..42425f10a4c97 100644 --- a/src/core/server/integration_tests/config/config_deprecation.test.ts +++ b/src/core/server/integration_tests/config/config_deprecation.test.ts @@ -10,6 +10,7 @@ import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { mockLoggingSystem } from './config_deprecation.test.mocks'; import { createRoot } from '@kbn/core-test-helpers-kbn-server'; +import { getFips } from 'crypto'; describe('configuration deprecations', () => { let root: ReturnType; @@ -24,13 +25,19 @@ describe('configuration deprecations', () => { } }); - it('should not log deprecation warnings for default configuration', async () => { - root = createRoot(); + if (getFips() === 0) { + it('should not log deprecation warnings for default configuration', async () => { + root = createRoot(); - await root.preboot(); - await root.setup(); + await root.preboot(); + await root.setup(); - const logs = loggingSystemMock.collect(mockLoggingSystem); - expect(logs.warn.flat()).toHaveLength(0); - }); + const logs = loggingSystemMock.collect(mockLoggingSystem); + expect(logs.warn.flat()).toHaveLength(0); + }); + } else { + it('fips is enabled and the default configuration has been overridden', () => { + expect(getFips()).toBe(1); + }); + } }); diff --git a/src/core/server/integration_tests/core_app/default_route_provider_config.test.ts b/src/core/server/integration_tests/core_app/default_route_provider_config.test.ts index 57646007a586f..a3338e7d45468 100644 --- a/src/core/server/integration_tests/core_app/default_route_provider_config.test.ts +++ b/src/core/server/integration_tests/core_app/default_route_provider_config.test.ts @@ -14,74 +14,81 @@ import { request, type TestElasticsearchUtils, } from '@kbn/core-test-helpers-kbn-server'; +import { getFips } from 'crypto'; describe('default route provider', () => { let esServer: TestElasticsearchUtils; let root: Root; - beforeAll(async () => { - const { startES } = createTestServers({ - adjustTimeout: (t: number) => jest.setTimeout(t), + if (getFips() === 0) { + beforeAll(async () => { + const { startES } = createTestServers({ + adjustTimeout: (t: number) => jest.setTimeout(t), + }); + esServer = await startES(); + root = createRootWithCorePlugins({ + server: { + basePath: '/hello', + restrictInternalApis: false, + }, + }); + + await root.preboot(); + await root.setup(); + await root.start(); }); - esServer = await startES(); - root = createRootWithCorePlugins({ - server: { - basePath: '/hello', - restrictInternalApis: false, - }, + + afterAll(async () => { + await esServer.stop(); + await root.shutdown(); }); - await root.preboot(); - await root.setup(); - await root.start(); - }); + it('redirects to the configured default route respecting basePath', async function () { + const { status, header } = await request.get(root, '/'); - afterAll(async () => { - await esServer.stop(); - await root.shutdown(); - }); + expect(status).toEqual(302); + expect(header).toMatchObject({ + location: '/hello/app/home', + }); + }); - it('redirects to the configured default route respecting basePath', async function () { - const { status, header } = await request.get(root, '/'); + it('ignores invalid values', async function () { + const invalidRoutes = [ + 'http://not-your-kibana.com', + '///example.com', + '//example.com', + ' //example.com', + ]; - expect(status).toEqual(302); - expect(header).toMatchObject({ - location: '/hello/app/home', - }); - }); + for (const url of invalidRoutes) { + await request + .post(root, '/internal/kibana/settings/defaultRoute') + .send({ value: url }) + .expect(400); + } - it('ignores invalid values', async function () { - const invalidRoutes = [ - 'http://not-your-kibana.com', - '///example.com', - '//example.com', - ' //example.com', - ]; + const { status, header } = await request.get(root, '/'); + expect(status).toEqual(302); + expect(header).toMatchObject({ + location: '/hello/app/home', + }); + }); - for (const url of invalidRoutes) { + it('consumes valid values', async function () { await request .post(root, '/internal/kibana/settings/defaultRoute') - .send({ value: url }) - .expect(400); - } + .send({ value: '/valid' }) + .expect(200); - const { status, header } = await request.get(root, '/'); - expect(status).toEqual(302); - expect(header).toMatchObject({ - location: '/hello/app/home', + const { status, header } = await request.get(root, '/'); + expect(status).toEqual(302); + expect(header).toMatchObject({ + location: '/hello/valid', + }); }); - }); - - it('consumes valid values', async function () { - await request - .post(root, '/internal/kibana/settings/defaultRoute') - .send({ value: '/valid' }) - .expect(200); - - const { status, header } = await request.get(root, '/'); - expect(status).toEqual(302); - expect(header).toMatchObject({ - location: '/hello/valid', + } else { + it('should have fips enabled, the overrides prevent these tests from working', () => { + expect(getFips()).toBe(1); }); - }); + } }); diff --git a/src/core/server/integration_tests/elasticsearch/version_compatibility.test.ts b/src/core/server/integration_tests/elasticsearch/version_compatibility.test.ts index d63895220ceb1..c2cb6fccc3cd0 100644 --- a/src/core/server/integration_tests/elasticsearch/version_compatibility.test.ts +++ b/src/core/server/integration_tests/elasticsearch/version_compatibility.test.ts @@ -17,6 +17,7 @@ import { firstValueFrom, Subject } from 'rxjs'; import { CliArgs } from '@kbn/config'; import Semver from 'semver'; import { unsafeConsole } from '@kbn/security-hardening'; +import { getFips } from 'crypto'; function nextMinor() { return Semver.inc(esTestConfig.getVersion(), 'minor') || '10.0.0'; @@ -130,9 +131,15 @@ describe('Version Compatibility', () => { ); }); - it('should ignore version mismatch when running on serverless mode and complete startup', async () => { - await expect( - startServers({ customKibanaVersion: nextMinor(), cliArgs: { serverless: true } }) - ).resolves.toBeUndefined(); - }); + if (getFips() === 0) { + it('should ignore version mismatch when running on serverless mode and complete startup', async () => { + await expect( + startServers({ customKibanaVersion: nextMinor(), cliArgs: { serverless: true } }) + ).resolves.toBeUndefined(); + }); + } else { + it('fips is enabled, serverless doesnt like the config overrides', () => { + expect(getFips()).toBe(1); + }); + } }); diff --git a/src/core/server/integration_tests/node/migrator.test.ts b/src/core/server/integration_tests/node/migrator.test.ts index cd4ab1cd8c74e..f899d7da5cde0 100644 --- a/src/core/server/integration_tests/node/migrator.test.ts +++ b/src/core/server/integration_tests/node/migrator.test.ts @@ -16,6 +16,7 @@ import { ToolingLog } from '@kbn/tooling-log'; import { createTestEsCluster, kibanaServerTestUser } from '@kbn/test'; import { observeLines } from '@kbn/stdio-dev-helpers'; import { REPO_ROOT } from '@kbn/repo-info'; +import { getFips } from 'crypto'; describe('migrator-only node', () => { const log = new ToolingLog({ writeTo: process.stdout, level: 'debug' }); @@ -30,6 +31,7 @@ describe('migrator-only node', () => { let logsSub: undefined | Rx.Subscription; try { await es.start(); + const isFipsEnabled = getFips(); proc = ChildProcess.spawn( process.execPath, @@ -42,7 +44,7 @@ describe('migrator-only node', () => { '--no-optimizer', '--no-base-path', '--no-watch', - '--oss', + isFipsEnabled ? '--xpack.security.experimental.fipsMode.enabled=true' : '--oss', ], { stdio: ['pipe', 'pipe', 'pipe'] } ); diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/multiple_es_nodes.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/multiple_es_nodes.test.ts index 490dea4c06be6..6898962077b9c 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/multiple_es_nodes.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/multiple_es_nodes.test.ts @@ -18,6 +18,7 @@ import { } from '@kbn/core-test-helpers-kbn-server'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import { Root } from '@kbn/core-root-server-internal'; +import { getFips } from 'crypto'; const LOG_FILE_PREFIX = 'migration_test_multiple_es_nodes'; @@ -114,89 +115,95 @@ describe('migration v2', () => { } }); - it('migrates saved objects normally with multiple ES nodes', async () => { - const { startES } = createTestServers({ - adjustTimeout: (t: number) => jest.setTimeout(t), - settings: { - es: { - license: 'basic', - clusterName: 'es-test-cluster', - nodes: [ - { - name: 'node-01', - // original SO (5000 total; 2500 of type `foo` + 2500 of type `bar`): - // [ - // { id: 'foo:1', type: 'foo', foo: { status: 'not_migrated_1' } }, - // { id: 'bar:1', type: 'bar', bar: { status: 'not_migrated_1' } }, - // { id: 'foo:2', type: 'foo', foo: { status: 'not_migrated_2' } }, - // { id: 'bar:2', type: 'bar', bar: { status: 'not_migrated_2' } }, - // ]; - dataArchive: Path.join(__dirname, '..', 'archives', '7.13.0_5k_so_node_01.zip'), - }, - { - name: 'node-02', - dataArchive: Path.join(__dirname, '..', 'archives', '7.13.0_5k_so_node_02.zip'), - }, - ], + if (getFips() === 0) { + it('migrates saved objects normally with multiple ES nodes', async () => { + const { startES } = createTestServers({ + adjustTimeout: (t: number) => jest.setTimeout(t), + settings: { + es: { + license: 'basic', + clusterName: 'es-test-cluster', + nodes: [ + { + name: 'node-01', + // original SO (5000 total; 2500 of type `foo` + 2500 of type `bar`): + // [ + // { id: 'foo:1', type: 'foo', foo: { status: 'not_migrated_1' } }, + // { id: 'bar:1', type: 'bar', bar: { status: 'not_migrated_1' } }, + // { id: 'foo:2', type: 'foo', foo: { status: 'not_migrated_2' } }, + // { id: 'bar:2', type: 'bar', bar: { status: 'not_migrated_2' } }, + // ]; + dataArchive: Path.join(__dirname, '..', 'archives', '7.13.0_5k_so_node_01.zip'), + }, + { + name: 'node-02', + dataArchive: Path.join(__dirname, '..', 'archives', '7.13.0_5k_so_node_02.zip'), + }, + ], + }, }, - }, - }); - - esServer = await startES(); - - root = createRoot({ - logFileName: Path.join(__dirname, `${LOG_FILE_PREFIX}.log`), - hosts: esServer.hosts, - }); - - await root.preboot(); - const setup = await root.setup(); - setup.savedObjects.registerType({ - name: 'foo', - hidden: false, - mappings: { properties: { status: { type: 'text' } } }, - namespaceType: 'agnostic', - migrations: { - '7.14.0': (doc) => { - if (doc.attributes?.status) { - doc.attributes.status = doc.attributes.status.replace('not_migrated', 'migrated'); - } - return doc; + }); + + esServer = await startES(); + + root = createRoot({ + logFileName: Path.join(__dirname, `${LOG_FILE_PREFIX}.log`), + hosts: esServer.hosts, + }); + + await root.preboot(); + const setup = await root.setup(); + setup.savedObjects.registerType({ + name: 'foo', + hidden: false, + mappings: { properties: { status: { type: 'text' } } }, + namespaceType: 'agnostic', + migrations: { + '7.14.0': (doc) => { + if (doc.attributes?.status) { + doc.attributes.status = doc.attributes.status.replace('not_migrated', 'migrated'); + } + return doc; + }, }, - }, - }); - setup.savedObjects.registerType({ - name: 'bar', - hidden: false, - mappings: { properties: { status: { type: 'text' } } }, - namespaceType: 'agnostic', - migrations: { - '7.14.0': (doc) => { - if (doc.attributes?.status) { - doc.attributes.status = doc.attributes.status.replace('not_migrated', 'migrated'); - } - return doc; + }); + setup.savedObjects.registerType({ + name: 'bar', + hidden: false, + mappings: { properties: { status: { type: 'text' } } }, + namespaceType: 'agnostic', + migrations: { + '7.14.0': (doc) => { + if (doc.attributes?.status) { + doc.attributes.status = doc.attributes.status.replace('not_migrated', 'migrated'); + } + return doc; + }, }, - }, + }); + + await root.start(); + const esClient = esServer.es.getClient(); + + const migratedFooDocs = await fetchDocs(esClient, migratedIndexAlias, 'foo'); + expect(migratedFooDocs.length).toBe(2500); + migratedFooDocs.forEach((doc, i) => { + expect(doc.id).toBe(`foo:${i}`); + expect(doc.foo.status).toBe(`migrated_${i}`); + expect(doc.typeMigrationVersion).toBe('7.14.0'); + }); + + const migratedBarDocs = await fetchDocs(esClient, migratedIndexAlias, 'bar'); + expect(migratedBarDocs.length).toBe(2500); + migratedBarDocs.forEach((doc, i) => { + expect(doc.id).toBe(`bar:${i}`); + expect(doc.bar.status).toBe(`migrated_${i}`); + expect(doc.typeMigrationVersion).toBe('7.14.0'); + }); }); - - await root.start(); - const esClient = esServer.es.getClient(); - - const migratedFooDocs = await fetchDocs(esClient, migratedIndexAlias, 'foo'); - expect(migratedFooDocs.length).toBe(2500); - migratedFooDocs.forEach((doc, i) => { - expect(doc.id).toBe(`foo:${i}`); - expect(doc.foo.status).toBe(`migrated_${i}`); - expect(doc.typeMigrationVersion).toBe('7.14.0'); - }); - - const migratedBarDocs = await fetchDocs(esClient, migratedIndexAlias, 'bar'); - expect(migratedBarDocs.length).toBe(2500); - migratedBarDocs.forEach((doc, i) => { - expect(doc.id).toBe(`bar:${i}`); - expect(doc.bar.status).toBe(`migrated_${i}`); - expect(doc.typeMigrationVersion).toBe('7.14.0'); + } else { + it('skips the test when running in FIPS mode since the data archives cause the es nodes to run with a basic license', () => { + expect(getFips()).toBe(1); }); - }); + } }); diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/read_batch_size.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/read_batch_size.test.ts index df809d8c4c173..9f970ed234d71 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/read_batch_size.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/read_batch_size.test.ts @@ -15,6 +15,7 @@ import { } from '@kbn/core-test-helpers-kbn-server'; import { clearLog, readLog, startElasticsearch } from '../kibana_migrator_test_kit'; import { delay } from '../test_utils'; +import { getFips } from 'crypto'; const logFilePath = join(__dirname, 'read_batch_size.log'); @@ -36,33 +37,39 @@ describe('migration v2 - read batch size', () => { await delay(5); // give it a few seconds... cause we always do ¯\_(ツ)_/¯ }); - it('reduces the read batchSize in half if a batch exceeds maxReadBatchSizeBytes', async () => { - root = createRoot({ maxReadBatchSizeBytes: 15000 }); - await root.preboot(); - await root.setup(); - await root.start(); + if (getFips() === 0) { + it('reduces the read batchSize in half if a batch exceeds maxReadBatchSizeBytes', async () => { + root = createRoot({ maxReadBatchSizeBytes: 15000 }); + await root.preboot(); + await root.setup(); + await root.start(); - // Check for migration steps present in the logs - logs = await readLog(logFilePath); + // Check for migration steps present in the logs + logs = await readLog(logFilePath); - expect(logs).toMatch( - /Read a batch with a response content length of \d+ bytes which exceeds migrations\.maxReadBatchSizeBytes, retrying by reducing the batch size in half to 15/ - ); - expect(logs).toMatch('[.kibana] Migration completed'); - }); + expect(logs).toMatch( + /Read a batch with a response content length of \d+ bytes which exceeds migrations\.maxReadBatchSizeBytes, retrying by reducing the batch size in half to 15/ + ); + expect(logs).toMatch('[.kibana] Migration completed'); + }); - it('does not reduce the read batchSize in half if no batches exceeded maxReadBatchSizeBytes', async () => { - root = createRoot({ maxReadBatchSizeBytes: 50000 }); - await root.preboot(); - await root.setup(); - await root.start(); + it('does not reduce the read batchSize in half if no batches exceeded maxReadBatchSizeBytes', async () => { + root = createRoot({ maxReadBatchSizeBytes: 50000 }); + await root.preboot(); + await root.setup(); + await root.start(); - // Check for migration steps present in the logs - logs = await readLog(logFilePath); + // Check for migration steps present in the logs + logs = await readLog(logFilePath); - expect(logs).not.toMatch('retrying by reducing the batch size in half to'); - expect(logs).toMatch('[.kibana] Migration completed'); - }); + expect(logs).not.toMatch('retrying by reducing the batch size in half to'); + expect(logs).toMatch('[.kibana] Migration completed'); + }); + } else { + it('cannot run tests with dataArchives that have a basic licesne in FIPS mode', () => { + expect(getFips()).toBe(1); + }); + } }); function createRoot({ maxReadBatchSizeBytes }: { maxReadBatchSizeBytes?: number }) { diff --git a/src/core/server/integration_tests/saved_objects/serverless/migrations/smoke.test.ts b/src/core/server/integration_tests/saved_objects/serverless/migrations/smoke.test.ts index e76bbd8d2d65b..27af749593e70 100644 --- a/src/core/server/integration_tests/saved_objects/serverless/migrations/smoke.test.ts +++ b/src/core/server/integration_tests/saved_objects/serverless/migrations/smoke.test.ts @@ -13,28 +13,35 @@ import { TestServerlessKibanaUtils, createTestServerlessInstances, } from '@kbn/core-test-helpers-kbn-server'; +import { getFips } from 'crypto'; -describe('Basic smoke test', () => { +describe('Basic smoke test', function () { let serverlessES: TestServerlessESUtils; let serverlessKibana: TestServerlessKibanaUtils; let root: TestServerlessKibanaUtils['root']; - beforeEach(async () => { - const { startES, startKibana } = createTestServerlessInstances({ - adjustTimeout: jest.setTimeout, + if (getFips() === 0) { + beforeEach(async () => { + const { startES, startKibana } = createTestServerlessInstances({ + adjustTimeout: jest.setTimeout, + }); + serverlessES = await startES(); + serverlessKibana = await startKibana(); + root = serverlessKibana.root; }); - serverlessES = await startES(); - serverlessKibana = await startKibana(); - root = serverlessKibana.root; - }); - afterEach(async () => { - await serverlessES?.stop(); - await serverlessKibana?.stop(); - }); + afterEach(async () => { + await serverlessES?.stop(); + await serverlessKibana?.stop(); + }); - test('it can start Kibana running against serverless ES', async () => { - const { body } = await request.get(root, '/api/status').expect(200); - expect(body).toMatchObject({ status: { overall: { level: 'available' } } }); - }); + test('it can start Kibana running against serverless ES', async () => { + const { body } = await request.get(root, '/api/status').expect(200); + expect(body).toMatchObject({ status: { overall: { level: 'available' } } }); + }); + } else { + test('FIPS is enabled, serverless doesnt like the config overrides', () => { + expect(getFips()).toBe(1); + }); + } }); diff --git a/src/dev/build/lib/integration_tests/fs.test.ts b/src/dev/build/lib/integration_tests/fs.test.ts index 2b1adac411f65..4a24da0e0b5f6 100644 --- a/src/dev/build/lib/integration_tests/fs.test.ts +++ b/src/dev/build/lib/integration_tests/fs.test.ts @@ -13,6 +13,7 @@ import { chmodSync, statSync } from 'fs'; import del from 'del'; import { mkdirp, write, read, getChildPaths, copyAll, getFileHash, untar, gunzip } from '../fs'; +import { getFips } from 'crypto'; const TMP = resolve(__dirname, '../__tmp__'); const FIXTURES = resolve(__dirname, '../__fixtures__'); @@ -266,9 +267,12 @@ describe('getFileHash()', () => { '7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730' ); }); - it('resolves with the md5 hash of a file', async () => { - expect(await getFileHash(BAR_TXT_PATH, 'md5')).toBe('c157a79031e1c40f85931829bc5fc552'); - }); + + if (getFips() !== 1) { + it('resolves with the md5 hash of a file', async () => { + expect(await getFileHash(BAR_TXT_PATH, 'md5')).toBe('c157a79031e1c40f85931829bc5fc552'); + }); + } }); describe('untar()', () => { diff --git a/src/plugins/files/server/blob_storage_service/adapters/es/integration_tests/es.test.ts b/src/plugins/files/server/blob_storage_service/adapters/es/integration_tests/es.test.ts index afbae27ec367d..ab440e60629b5 100644 --- a/src/plugins/files/server/blob_storage_service/adapters/es/integration_tests/es.test.ts +++ b/src/plugins/files/server/blob_storage_service/adapters/es/integration_tests/es.test.ts @@ -27,10 +27,13 @@ describe('Elasticsearch blob storage', () => { beforeAll(async () => { ElasticsearchBlobStorageClient.configureConcurrentTransfers(Infinity); - const { startES, startKibana } = createTestServers({ adjustTimeout: jest.setTimeout }); + + const { startES, startKibana } = createTestServers({ + adjustTimeout: jest.setTimeout, + }); manageES = await startES(); manageKbn = await startKibana(); - esClient = manageKbn.coreStart.elasticsearch.client.asInternalUser; + esClient = manageKbn.coreStart.elasticsearch.createClient('es.test').asInternalUser; }); afterAll(async () => { diff --git a/src/plugins/files/server/file_client/create_es_file_client.ts b/src/plugins/files/server/file_client/create_es_file_client.ts index ddfcfc0833e80..3302e878c3631 100644 --- a/src/plugins/files/server/file_client/create_es_file_client.ts +++ b/src/plugins/files/server/file_client/create_es_file_client.ts @@ -8,6 +8,7 @@ */ import type { Logger, ElasticsearchClient } from '@kbn/core/server'; +import { getFips } from 'crypto'; import { ElasticsearchBlobStorageClient } from '../blob_storage_service'; import { FileClientImpl } from './file_client'; import type { FileClient } from './types'; @@ -66,12 +67,18 @@ export function createEsFileClient(arg: CreateEsFileClientArgs): FileClient { maxSizeBytes, indexIsAlias, } = arg; + + let hashes: Array<'sha1' | 'sha256' | 'sha512' | 'md5'> = ['sha1', 'sha256', 'sha512']; + if (getFips() !== 1) { + hashes = ['md5', ...hashes]; + } + return new FileClientImpl( { id: NO_FILE_KIND, http: {}, maxSizeBytes, - hashes: ['md5', 'sha1', 'sha256', 'sha512'], + hashes, }, new EsIndexFilesMetadataClient(metadataIndex, elasticsearchClient, logger, indexIsAlias), new ElasticsearchBlobStorageClient( diff --git a/src/plugins/files/server/file_client/integration_tests/es_file_client.test.ts b/src/plugins/files/server/file_client/integration_tests/es_file_client.test.ts index 3492db16ee1a9..16fd2e535763b 100644 --- a/src/plugins/files/server/file_client/integration_tests/es_file_client.test.ts +++ b/src/plugins/files/server/file_client/integration_tests/es_file_client.test.ts @@ -13,6 +13,7 @@ import { TestEnvironmentUtils, setupIntegrationEnvironment } from '../../test_ut import { createEsFileClient } from '../create_es_file_client'; import { FileClient } from '../types'; import { FileMetadata } from '../../../common'; +import { getFips } from 'crypto'; describe('ES-index-backed file client', () => { let esClient: TestEnvironmentUtils['esClient']; @@ -107,13 +108,21 @@ describe('ES-index-backed file client', () => { }); await file.uploadContent(Readable.from([Buffer.from('test')])); - expect(file.toJSON().hash).toStrictEqual({ - md5: '098f6bcd4621d373cade4e832627b4f6', + let expected: Record = { sha1: 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', sha512: 'ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff', - }); + }; + + if (getFips() !== 1) { + expected = { + md5: '098f6bcd4621d373cade4e832627b4f6', + ...expected, + }; + } + + expect(file.toJSON().hash).toStrictEqual(expected); await deleteFile({ id: file.id, hasContent: true }); }); diff --git a/src/plugins/files/server/file_client/stream_transforms/file_hash_transform/file_hash_transform.test.ts b/src/plugins/files/server/file_client/stream_transforms/file_hash_transform/file_hash_transform.test.ts index f0801cf763dd0..18f0cd6184e71 100644 --- a/src/plugins/files/server/file_client/stream_transforms/file_hash_transform/file_hash_transform.test.ts +++ b/src/plugins/files/server/file_client/stream_transforms/file_hash_transform/file_hash_transform.test.ts @@ -24,6 +24,8 @@ import { BlobStorageService } from '../../../blob_storage_service'; import { InternalFileShareService } from '../../../file_share_service'; import { InternalFileService } from '../../../file_service/internal_file_service'; +import { getFips } from 'crypto'; + describe('When using the FileHashTransform', () => { let file: IFile; let fileContent: Readable; @@ -75,23 +77,25 @@ describe('When using the FileHashTransform', () => { expect(() => fileHash.getFileHash()).toThrow('File hash generation not yet complete'); }); - it.each([ - ['md5', '098f6bcd4621d373cade4e832627b4f6'], - ['sha1', 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3'], - ['sha256', '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'], - [ - 'sha512', - 'ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff', - ], - ] as Array<[SupportedFileHashAlgorithm, string]>)( - 'should generate file hash using algorithm: %s', - async (algorithm, expectedHash) => { - const fileHash = createFileHashTransform(algorithm); - await file.uploadContent(fileContent, undefined, { - transforms: [fileHash], - }); + describe('algorithms', function () { + it.each([ + ...(getFips() !== 1 ? [['md5', '098f6bcd4621d373cade4e832627b4f6']] : []), + ['sha1', 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3'], + ['sha256', '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'], + [ + 'sha512', + 'ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff', + ], + ] as Array<[SupportedFileHashAlgorithm, string]>)( + 'should generate file hash using algorithm: %s', + async (algorithm, expectedHash) => { + const fileHash = createFileHashTransform(algorithm); + await file.uploadContent(fileContent, undefined, { + transforms: [fileHash], + }); - expect(fileHash.getFileHash()).toEqual({ algorithm, value: expectedHash }); - } - ); + expect(fileHash.getFileHash()).toEqual({ algorithm, value: expectedHash }); + } + ); + }); }); diff --git a/test/functional/apps/dashboard/group5/dashboard_panel_listing.ts b/test/functional/apps/dashboard/group5/dashboard_panel_listing.ts index 1685228699fc3..abd6b1c5dd1c1 100644 --- a/test/functional/apps/dashboard/group5/dashboard_panel_listing.ts +++ b/test/functional/apps/dashboard/group5/dashboard_panel_listing.ts @@ -17,7 +17,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const dashboardAddPanel = getService('dashboardAddPanel'); - describe('dashboard panel listing', () => { + describe('dashboard panel listing', function () { + this.tags('skipFIPS'); before(async () => { await kibanaServer.savedObjects.cleanStandardList(); await kibanaServer.importExport.load( diff --git a/test/server_integration/http/ssl_with_p12/index.js b/test/server_integration/http/ssl_with_p12/index.js index b402ce548c6a1..21c09a8d7e63f 100644 --- a/test/server_integration/http/ssl_with_p12/index.js +++ b/test/server_integration/http/ssl_with_p12/index.js @@ -10,7 +10,8 @@ export default function ({ getService }) { const supertest = getService('supertest'); - describe('kibana server with ssl', () => { + describe('kibana server with ssl', function () { + this.tags('skipFIPS'); it('handles requests using ssl with a P12 keystore', async () => { await supertest.get('/').expect(302); }); diff --git a/test/server_integration/http/ssl_with_p12_intermediate/index.js b/test/server_integration/http/ssl_with_p12_intermediate/index.js index b01df762c7345..0fc4a2f793e20 100644 --- a/test/server_integration/http/ssl_with_p12_intermediate/index.js +++ b/test/server_integration/http/ssl_with_p12_intermediate/index.js @@ -10,7 +10,8 @@ export default function ({ getService }) { const supertest = getService('supertest'); - describe('kibana server with ssl', () => { + describe('kibana server with ssl', function () { + this.tags('skipFIPS'); it('handles requests using ssl with a P12 keystore that uses an intermediate CA', async () => { await supertest.get('/').expect(302); }); diff --git a/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts b/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts index a0454cb2bbc18..99559e8ce6b68 100644 --- a/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts +++ b/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts @@ -28,6 +28,7 @@ import { DEFAULT_MICROSOFT_GRAPH_API_SCOPE, DEFAULT_MICROSOFT_GRAPH_API_URL, } from '../../common'; +import { getFips } from 'crypto'; const logger = loggingSystemMock.create().get() as jest.Mocked; @@ -251,19 +252,6 @@ describe('axios connections', () => { expect(res.status).toBe(200); }); - test('it works with pfx and passphrase in SSL overrides', async () => { - const { url, server } = await createServer({ useHttps: true, requestCert: true }); - testServer = server; - - const configurationUtilities = getACUfromConfig(); - const sslOverrides = { - pfx: KIBANA_P12, - passphrase: 'storepass', - }; - const res = await request({ axios, url, logger, configurationUtilities, sslOverrides }); - expect(res.status).toBe(200); - }); - test('it fails with cert and key but no ca in SSL overrides', async () => { const { url, server } = await createServer({ useHttps: true, requestCert: true }); testServer = server; @@ -278,18 +266,33 @@ describe('axios connections', () => { await expect(fn()).rejects.toThrow('certificate'); }); - test('it fails with pfx but no passphrase in SSL overrides', async () => { - const { url, server } = await createServer({ useHttps: true, requestCert: true }); - testServer = server; + if (getFips() !== 1) { + test('it works with pfx and passphrase in SSL overrides', async () => { + const { url, server } = await createServer({ useHttps: true, requestCert: true }); + testServer = server; + + const configurationUtilities = getACUfromConfig(); + const sslOverrides = { + pfx: KIBANA_P12, + passphrase: 'storepass', + }; + const res = await request({ axios, url, logger, configurationUtilities, sslOverrides }); + expect(res.status).toBe(200); + }); - const configurationUtilities = getACUfromConfig(); - const sslOverrides = { - pfx: KIBANA_P12, - }; - const fn = async () => - await request({ axios, url, logger, configurationUtilities, sslOverrides }); - await expect(fn()).rejects.toThrow('mac verify'); - }); + test('it fails with pfx but no passphrase in SSL overrides', async () => { + const { url, server } = await createServer({ useHttps: true, requestCert: true }); + testServer = server; + + const configurationUtilities = getACUfromConfig(); + const sslOverrides = { + pfx: KIBANA_P12, + }; + const fn = async () => + await request({ axios, url, logger, configurationUtilities, sslOverrides }); + await expect(fn()).rejects.toThrow('mac verify'); + }); + } test('it fails with a client-side certificate issued by an invalid ca', async () => { const { url, server } = await createServer({ useHttps: true, requestCert: true }); diff --git a/x-pack/plugins/fleet/.storybook/smoke.test.tsx b/x-pack/plugins/fleet/.storybook/smoke.test.tsx index a3984a42a5ab2..63c1199b75aa9 100644 --- a/x-pack/plugins/fleet/.storybook/smoke.test.tsx +++ b/x-pack/plugins/fleet/.storybook/smoke.test.tsx @@ -5,22 +5,30 @@ * 2.0. */ +import { getFips } from 'crypto'; + import { mount } from 'enzyme'; import { createElement } from 'react'; import { act } from 'react-dom/test-utils'; import initStoryshots from '@storybook/addon-storyshots'; -describe('Fleet Storybook Smoke', () => { - test('Init', async () => { - await initStoryshots({ - configPath: __dirname, - framework: 'react', - test: async ({ story }) => { - const renderer = mount(createElement(story.render)); - // wait until the element will perform all renders and resolve all promises (lazy loading, especially) - await act(() => new Promise((resolve) => setTimeout(resolve, 0))); - expect(renderer.html()).not.toContain('euiErrorBoundary'); - }, +describe('Fleet Storybook Smoke', function () { + if (getFips() !== 1) { + test('Init', async () => { + await initStoryshots({ + configPath: __dirname, + framework: 'react', + test: async ({ story }) => { + const renderer = mount(createElement(story.render)); + // wait until the element will perform all renders and resolve all promises (lazy loading, especially) + await act(() => new Promise((resolve) => setTimeout(resolve, 0))); + expect(renderer.html()).not.toContain('euiErrorBoundary'); + }, + }); + }); + } else { + test('fips is enabled', function () { + expect(getFips() === 1).toEqual(true); }); - }); + } }); diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts b/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts index 9d71e15958480..714b16af5bcd2 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts @@ -152,7 +152,6 @@ export async function hashSecret(secret: string) { return `${salt}:${derivedKey.toString('hex')}`; } - async function verifySecret(hash: string, secret: string) { const [salt, key] = hash.split(':'); const derivedKey = await pbkdf2Async(secret, salt, maxIteration, keyLength, 'sha512'); diff --git a/x-pack/test/functional/apps/index_lifecycle_management/read_only_view.ts b/x-pack/test/functional/apps/index_lifecycle_management/read_only_view.ts index 030074a97b4bd..b30ee9ecee763 100644 --- a/x-pack/test/functional/apps/index_lifecycle_management/read_only_view.ts +++ b/x-pack/test/functional/apps/index_lifecycle_management/read_only_view.ts @@ -15,6 +15,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const security = getService('security'); describe('Read only view', function () { + this.tags('skipFIPS'); before(async () => { await security.testUser.setRoles(['read_ilm']);