Skip to content

Commit

Permalink
Moving FIPS config comparison check to Core > Security Service setup
Browse files Browse the repository at this point in the history
  • Loading branch information
kc13greiner committed Jun 26, 2024
1 parent 50015b0 commit 2c11610
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,22 @@
* Side Public License, v 1.
*/

const mockGetFipsFn = jest.fn();
jest.mock('crypto', () => ({
randomBytes: jest.fn(),
constants: jest.requireActual('crypto').constants,
get getFips() {
return mockGetFipsFn;
},
}));

import { SecurityServiceConfigType } from '../utils';
import { isFipsEnabled } from './fips';
import { isFipsEnabled, checkFipsConfig } from './fips';
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';

describe('fips', () => {
let config: SecurityServiceConfigType;
describe('#isFipsEnabled', () => {
let config: SecurityServiceConfigType;

it('should return `true` if config.experimental.fipsMode.enabled is `true`', () => {
config = { experimental: { fipsMode: { enabled: true } } };

Expand All @@ -29,4 +38,82 @@ describe('fips', () => {
expect(isFipsEnabled(config)).toBe(false);
});
});

describe('checkFipsConfig', () => {
let mockExit: jest.SpyInstance;

beforeAll(() => {
mockExit = jest.spyOn(process, 'exit').mockImplementation((exitCode) => {
throw new Error(`Fake Exit: ${exitCode}`);
});
});

afterAll(() => {
mockExit.mockRestore();
});

it('should log an error message if FIPS mode is misconfigured - xpack.security.experimental.fipsMode.enabled true, Nodejs FIPS mode false', async () => {
config = { experimental: { fipsMode: { enabled: true } } };
const logger = loggingSystemMock.create().get();
try {
checkFipsConfig(config, logger);
} catch (e) {
expect(mockExit).toHaveBeenNthCalledWith(1, 78);
}

expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
Array [
Array [
"Configuration mismatch error. xpack.security.experimental.fipsMode.enabled is set to true and the configured Node.js environment has FIPS disabled",
],
]
`);
});

it('should log an error message if FIPS mode is misconfigured - xpack.security.experimental.fipsMode.enabled false, Nodejs FIPS mode true', async () => {
mockGetFipsFn.mockImplementationOnce(() => {
return 1;
});

config = { experimental: { fipsMode: { enabled: false } } };
const logger = loggingSystemMock.create().get();

try {
checkFipsConfig(config, logger);
} catch (e) {
expect(mockExit).toHaveBeenNthCalledWith(1, 78);
}

expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
Array [
Array [
"Configuration mismatch error. xpack.security.experimental.fipsMode.enabled is set to false and the configured Node.js environment has FIPS enabled",
],
]
`);
});

it('should log an info message if FIPS mode is properly configured - xpack.security.experimental.fipsMode.enabled true, Nodejs FIPS mode true', async () => {
mockGetFipsFn.mockImplementationOnce(() => {
return 1;
});

config = { experimental: { fipsMode: { enabled: true } } };
const logger = loggingSystemMock.create().get();

try {
checkFipsConfig(config, logger);
} catch (e) {
logger.error('Should not throw error!');
}

expect(loggingSystemMock.collect(logger).info).toMatchInlineSnapshot(`
Array [
Array [
"Kibana is running in FIPS mode.",
],
]
`);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,30 @@
* Side Public License, v 1.
*/

import type { Logger } from '@kbn/logging';
import { getFips } from 'crypto';
import { SecurityServiceConfigType } from '../utils';

export function isFipsEnabled(config: SecurityServiceConfigType): boolean {
return config?.experimental?.fipsMode?.enabled ?? false;
}

export function checkFipsConfig(config: SecurityServiceConfigType, logger: Logger) {
const isFipsConfigEnabled = isFipsEnabled(config);
const isNodeRunningWithFipsEnabled = getFips() === 1;

// Check if FIPS is enabled in either setting
if (isFipsConfigEnabled || isNodeRunningWithFipsEnabled) {
// FIPS must be enabled on both or log and error an exit Kibana
if (isFipsConfigEnabled !== isNodeRunningWithFipsEnabled) {
logger.error(
`Configuration mismatch error. xpack.security.experimental.fipsMode.enabled is set to ${isFipsConfigEnabled} and the configured Node.js environment has FIPS ${
isNodeRunningWithFipsEnabled ? 'enabled' : 'disabled'
}`
);
process.exit(78);
} else {
logger.info('Kibana is running in FIPS mode.');
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type { CoreContext, CoreService } from '@kbn/core-base-server-internal';
import type { CoreSecurityDelegateContract } from '@kbn/core-security-server';
import { Observable, Subscription } from 'rxjs';
import { Config } from '@kbn/config';
import { isFipsEnabled } from './fips/fips';
import { isFipsEnabled, checkFipsConfig } from './fips/fips';
import type {
InternalSecurityServiceSetup,
InternalSecurityServiceStart,
Expand Down Expand Up @@ -50,6 +50,8 @@ export class SecurityService
const config = this.getConfig();
const securityConfig: SecurityServiceConfigType = config.get(['xpack', 'security']);

checkFipsConfig(securityConfig, this.log);

return {
registerSecurityDelegate: (api) => {
if (this.securityApi) {
Expand Down
97 changes: 0 additions & 97 deletions x-pack/plugins/security/server/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@
* 2.0.
*/

const mockGetFipsFn = jest.fn();
jest.mock('crypto', () => ({
randomBytes: jest.fn(),
constants: jest.requireActual('crypto').constants,
get getFips() {
return mockGetFipsFn;
},
}));

jest.mock('@kbn/utils', () => ({
Expand Down Expand Up @@ -2521,96 +2517,3 @@ describe('createConfig()', () => {
});
});
});

describe('checkFipsConfig', () => {
let mockExit: jest.SpyInstance;
beforeAll(() => {
mockExit = jest.spyOn(process, 'exit').mockImplementation((exitCode) => {
throw new Error(`Fake Exit: ${exitCode}`);
});
});

afterAll(() => {
mockExit.mockRestore();
});

it('should log an error message if FIPS mode is misconfigured - xpack.security.experimental.fipsMode.enabled true, Nodejs FIPS mode false', async () => {
const logger = loggingSystemMock.create().get();

try {
createConfig(
ConfigSchema.validate({ experimental: { fipsMode: { enabled: true } } }),
logger,
{
isTLSEnabled: true,
}
);
} catch (e) {
expect(mockExit).toHaveBeenNthCalledWith(1, 78);
}

expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
Array [
Array [
"Configuration mismatch error. xpack.security.experimental.fipsMode.enabled is set to true and the configured Node.js environment has FIPS disabled",
],
]
`);
});

it('should log an error message if FIPS mode is misconfigured - xpack.security.experimental.fipsMode.enabled false, Nodejs FIPS mode true', async () => {
mockGetFipsFn.mockImplementationOnce(() => {
return 1;
});

const logger = loggingSystemMock.create().get();

try {
createConfig(
ConfigSchema.validate({ experimental: { fipsMode: { enabled: false } } }),
logger,
{
isTLSEnabled: true,
}
);
} catch (e) {
expect(mockExit).toHaveBeenNthCalledWith(1, 78);
}

expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
Array [
Array [
"Configuration mismatch error. xpack.security.experimental.fipsMode.enabled is set to false and the configured Node.js environment has FIPS enabled",
],
]
`);
});

it('should log an info message if FIPS mode is properly configured - xpack.security.experimental.fipsMode.enabled true, Nodejs FIPS mode true', async () => {
mockGetFipsFn.mockImplementationOnce(() => {
return 1;
});

const logger = loggingSystemMock.create().get();

try {
createConfig(
ConfigSchema.validate({ experimental: { fipsMode: { enabled: true } } }),
logger,
{
isTLSEnabled: true,
}
);
} catch (e) {
logger.error('Should not throw error!');
}

expect(loggingSystemMock.collect(logger).info).toMatchInlineSnapshot(`
Array [
Array [
"Kibana is running in FIPS mode.",
],
]
`);
});
});
24 changes: 1 addition & 23 deletions x-pack/plugins/security/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import crypto, { getFips } from 'crypto';
import crypto from 'crypto';
import type { Duration } from 'moment';
import path from 'path';

Expand Down Expand Up @@ -321,33 +321,11 @@ export const ConfigSchema = schema.object({
}),
});

function checkFipsConfig(config: RawConfigType, logger: Logger) {
const isFipsEnabled = config.experimental.fipsMode.enabled;
const isNodeRunningWithFipsEnabled = getFips() === 1;

// Check if FIPS is enabled in either setting
if (isFipsEnabled || isNodeRunningWithFipsEnabled) {
// FIPS must be enabled on both or log and error an exit Kibana
if (isFipsEnabled !== isNodeRunningWithFipsEnabled) {
logger.error(
`Configuration mismatch error. xpack.security.experimental.fipsMode.enabled is set to ${isFipsEnabled} and the configured Node.js environment has FIPS ${
isNodeRunningWithFipsEnabled ? 'enabled' : 'disabled'
}`
);
process.exit(78);
} else {
logger.info('Kibana is running in FIPS mode.');
}
}
}

export function createConfig(
config: RawConfigType,
logger: Logger,
{ isTLSEnabled }: { isTLSEnabled: boolean }
) {
checkFipsConfig(config, logger);

let encryptionKey = config.encryptionKey;
if (encryptionKey === undefined) {
logger.warn(
Expand Down

0 comments on commit 2c11610

Please sign in to comment.