diff --git a/src/plugins/data_source/README.md b/src/plugins/data_source/README.md index ccd50a272d16..6faa0a618f69 100755 --- a/src/plugins/data_source/README.md +++ b/src/plugins/data_source/README.md @@ -79,7 +79,7 @@ a. Envelope encryption - has multiple benefits including strong protection on da b. Key derivation algorithm - HKDF with SHA-384, which “helps you avoid accidental reuse of a data encryption key and reduces the risk of overusing a data key.” -c. Signature algorithm - ECDSA with P-384 and SHA-384. Under multiple data source case, data source indices stored on OpenSearch can be modified / replaced by attacker. With ECDSA signature, ciphertext decryption will fail if it’s getting pullted. No one will be able to create another signature that verifies with the public key because the private key has been dropped. +c. Signature algorithm - ECDSA with P-384 and SHA-384. Under multiple data source case, data source documents stored on OpenSearch can be modified / replaced by attacker. With ECDSA signature, ciphertext decryption will fail if it’s getting pullted. No one will be able to create another signature that verifies with the public key because the private key has been dropped. --- diff --git a/src/plugins/data_source/config.ts b/src/plugins/data_source/config.ts index d7579026c6e2..f2fd79fade9a 100644 --- a/src/plugins/data_source/config.ts +++ b/src/plugins/data_source/config.ts @@ -8,7 +8,7 @@ import { fileAppenderSchema } from './audit_config'; const KEY_NAME_MIN_LENGTH: number = 1; const KEY_NAME_MAX_LENGTH: number = 100; -// Wrapping key size shoule be 32 bytes, as used in envelope encryption algorithms. +// Wrapping key size should be 32 bytes, as used in envelope encryption algorithms. const WRAPPING_KEY_SIZE: number = 32; export const configSchema = schema.object({ diff --git a/src/plugins/data_source/server/client/configure_client.ts b/src/plugins/data_source/server/client/configure_client.ts index b84cc53c36cf..7a13ae33bf92 100644 --- a/src/plugins/data_source/server/client/configure_client.ts +++ b/src/plugins/data_source/server/client/configure_client.ts @@ -58,10 +58,9 @@ export const getCredential = async ( const { decryptedText, encryptionContext } = await cryptography .decodeAndDecrypt(password) - .catch(() => { - throw new Error( - 'Encrypted "auth.credentials.password" contaminated. Please delete and create another data source.' - ); + .catch((err: any) => { + // Re-throw as DataSourceConfigError + throw new DataSourceConfigError('Unable to decrypt "auth.credentials.password".', err); }); if (encryptionContext!.endpoint !== endpoint) { diff --git a/src/plugins/data_source/server/cryptography_service.test.ts b/src/plugins/data_source/server/cryptography_service.test.ts index 4aa6b62a1326..783a4f951393 100644 --- a/src/plugins/data_source/server/cryptography_service.test.ts +++ b/src/plugins/data_source/server/cryptography_service.test.ts @@ -33,7 +33,7 @@ describe('Cryptography Service', () => { }, } as DataSourcePluginConfigType; - const expectedErrorMsg = `Wrapping key size shoule be 32 bytes, as used in envelope encryption. Current wrapping key size: '${config.encryption.wrappingKey.length}' bytes`; + const expectedErrorMsg = `Wrapping key size should be 32 bytes, as used in envelope encryption. Current wrapping key size: '${config.encryption.wrappingKey.length}' bytes`; expect(() => { service.setup(config); diff --git a/src/plugins/data_source/server/cryptography_service.ts b/src/plugins/data_source/server/cryptography_service.ts index 410d95164932..a2fcc0dfe301 100644 --- a/src/plugins/data_source/server/cryptography_service.ts +++ b/src/plugins/data_source/server/cryptography_service.ts @@ -9,9 +9,7 @@ import { RawAesKeyringNode, RawAesWrappingSuiteIdentifier, } from '@aws-crypto/client-node'; - import { Logger } from '../../../../src/core/server'; - import { DataSourcePluginConfigType } from '../config'; export const ENCODING_STRATEGY: BufferEncoding = 'base64'; @@ -44,7 +42,7 @@ export class CryptographyService { const { wrappingKeyName, wrappingKeyNamespace, wrappingKey } = config.encryption; if (wrappingKey.length !== WRAPPING_KEY_SIZE) { - const wrappingKeySizeMismatchMsg = `Wrapping key size shoule be 32 bytes, as used in envelope encryption. Current wrapping key size: '${wrappingKey.length}' bytes`; + const wrappingKeySizeMismatchMsg = `Wrapping key size should be 32 bytes, as used in envelope encryption. Current wrapping key size: '${wrappingKey.length}' bytes`; this.logger.error(wrappingKeySizeMismatchMsg); throw new Error(wrappingKeySizeMismatchMsg); } diff --git a/src/plugins/data_source/server/plugin.ts b/src/plugins/data_source/server/plugin.ts index 9b2095a535a9..2a3d02be6838 100644 --- a/src/plugins/data_source/server/plugin.ts +++ b/src/plugins/data_source/server/plugin.ts @@ -20,7 +20,6 @@ import { } from '../../../../src/core/server'; import { DataSourcePluginConfigType } from '../config'; import { LoggingAuditor } from './audit/logging_auditor'; - import { CryptographyService, CryptographyServiceSetup } from './cryptography_service'; import { DataSourceService, DataSourceServiceSetup } from './data_source_service'; import { DataSourceSavedObjectsClientWrapper, dataSource } from './saved_objects'; diff --git a/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.ts b/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.ts index 2184f5b6925c..90c984949e83 100644 --- a/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.ts +++ b/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.ts @@ -15,12 +15,9 @@ import { SavedObjectsUpdateOptions, SavedObjectsUpdateResponse, } from 'opensearch-dashboards/server'; - import { Logger, SavedObjectsErrorHelpers } from '../../../../../src/core/server'; - import { DATA_SOURCE_SAVED_OBJECT_TYPE } from '../../common'; import { AuthType } from '../../common/data_sources'; - import { EncryptionContext, CryptographyServiceSetup } from '../cryptography_service'; /** @@ -296,8 +293,10 @@ export class DataSourceSavedObjectsClientWrapper { }); attributes = savedObject.attributes; } catch (err: any) { - // this.logger.error(err); - throw err; + const errMsg = `Fail to fetch existing data source for dataSourceId [${id}]`; + this.logger.error(errMsg); + this.logger.error(err); + throw SavedObjectsErrorHelpers.decorateBadRequestError(err, errMsg); } if (!attributes) { @@ -350,10 +349,11 @@ export class DataSourceSavedObjectsClientWrapper { const { encryptionContext } = await this.cryptography .decodeAndDecrypt(password) - .catch(() => { - throw SavedObjectsErrorHelpers.createBadRequestError( - 'Update failed due to deprecated data source: encrypted "auth.credentials.password" contaminated. Please delete and create another data source.' - ); + .catch((err: any) => { + const errMsg = `Fail to update existing data source for dataSourceId [${id}]: unable to decrypt "auth.credentials.password"`; + this.logger.error(errMsg); + this.logger.error(err); + throw SavedObjectsErrorHelpers.decorateBadRequestError(err, errMsg); }); if (encryptionContext.endpoint !== endpoint) {