Skip to content

Commit f270e01

Browse files
Merge remote-tracking branch 'origin/w/8.1/improvement/ARSN-481-kmip-errors' into w/8.2/improvement/ARSN-481-kmip-errors
2 parents a01688c + f109dba commit f270e01

File tree

7 files changed

+370
-127
lines changed

7 files changed

+370
-127
lines changed

lib/errors/arsenalErrors.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,3 +1070,15 @@ export const QuotaExceeded: ErrorFormat = {
10701070
code: 429,
10711071
description: 'The quota set for the resource is exceeded.',
10721072
};
1073+
1074+
// -------------------- KMS --------------------
1075+
// Most other KMS Exception can't be converted to from KMIP
1076+
const NotFoundException: ErrorFormat = {
1077+
code: 400, // Not 404 because it's the KMS (Encrypt/Decrypt) that fails, not the object API
1078+
description: 'The request was rejected because the specified entity or resource could not be found.'
1079+
};
1080+
1081+
/** need typescript@5.6 for string literal export
1082+
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-6.html#support-for-arbitrary-module-identifiers
1083+
*/
1084+
module.exports['KMS.NotFoundException'] = NotFoundException;

lib/network/kmip/Client.ts

Lines changed: 56 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import KMIP from '.';
77
import * as werelogs from 'werelogs';
88
import { arsenalErrorKMIP } from '../utils';
99
import { KMSInterface } from '../KMSInterface';
10+
import { errorInstances } from '../../errors';
11+
import { kmipMsg } from './errorMapping';
1012

1113
const CRYPTOGRAPHIC_OBJECT_TYPE = 'Symmetric Key';
1214
const CRYPTOGRAPHIC_ALGORITHM = 'AES';
@@ -67,13 +69,12 @@ function _negotiateProtocolVersion(client: any, logger: werelogs.Logger, cb: any
6769
KMIP.Integer('Protocol Version Major', 1),
6870
KMIP.Integer('Protocol Version Minor', 2),
6971
]),
70-
], (err, response) => {
72+
], (error, response) => {
7173
const kmipLog = {
7274
host: client.host,
7375
latencyMs: Date.now() - startDate
7476
};
75-
if (err) {
76-
const error = arsenalErrorKMIP(err);
77+
if (error) {
7778
logger.error('KMIP::negotiateProtocolVersion',
7879
{ error, kmip: kmipLog,
7980
vendorIdentification: client.vendorIdentification });
@@ -107,13 +108,12 @@ function _mapExtensions(client: any, logger: werelogs.Logger, cb: any) {
107108
const startDate = Date.now();
108109
return client.kmip.request(logger, 'Query', [
109110
KMIP.Enumeration('Query Function', 'Query Extension Map'),
110-
], (err, response) => {
111+
], (error, response) => {
111112
const kmipLog = {
112113
host: client.host,
113114
latencyMs: Date.now() - startDate
114115
};
115-
if (err) {
116-
const error = arsenalErrorKMIP(err);
116+
if (error) {
117117
logger.error('KMIP::mapExtensions',
118118
{ error, kmip: kmipLog,
119119
vendorIdentification: client.vendorIdentification });
@@ -145,13 +145,12 @@ function _queryServerInformation(client: any, logger: werelogs.Logger, cb: any)
145145
const startDate = Date.now();
146146
client.kmip.request(logger, 'Query', [
147147
KMIP.Enumeration('Query Function', 'Query Server Information'),
148-
], (err, response) => {
148+
], (error, response) => {
149149
const kmipLog = {
150150
host: client.host,
151151
latencyMs: Date.now() - startDate
152152
};
153-
if (err) {
154-
const error = arsenalErrorKMIP(err);
153+
if (error) {
155154
logger.warn('KMIP::queryServerInformation',
156155
{ error, kmip: kmipLog });
157156
/* no error returned, caller can keep going */
@@ -186,13 +185,12 @@ function _queryOperationsAndObjects(client: any, logger: werelogs.Logger, cb: an
186185
return client.kmip.request(logger, 'Query', [
187186
KMIP.Enumeration('Query Function', 'Query Operations'),
188187
KMIP.Enumeration('Query Function', 'Query Objects'),
189-
], (err, response) => {
188+
], (error, response) => {
190189
const kmipLog = {
191190
host: client.host,
192191
latencyMs: Date.now() - startDate
193192
};
194-
if (err) {
195-
const error = arsenalErrorKMIP(err);
193+
if (error) {
196194
logger.error('KMIP::queryOperationsAndObjects',
197195
{ error, kmip: kmipLog,
198196
vendorIdentification: client.vendorIdentification });
@@ -322,6 +320,21 @@ export default class Client implements KMSInterface {
322320
}
323321

324322

323+
_checkUniqueIdentifier(keyIdentifier: string, response: any, operation: string, logger: werelogs.Logger) {
324+
const uniqueIdentifier = response.lookup(searchFilter.uniqueIdentifier)[0];
325+
if (uniqueIdentifier !== keyIdentifier) {
326+
// Retryable
327+
const error = errorInstances.InternalError.customizeDescription(
328+
kmipMsg(operation, keyIdentifier,
329+
'Server did not return the expected identifier')
330+
);
331+
logger.error(`KMIP::${operation}`,
332+
{ error, uniqueIdentifier, keyIdentifier });
333+
return error;
334+
}
335+
return null;
336+
}
337+
325338
/**
326339
* Activate a cryptographic key managed by the server,
327340
* for a specific bucket. This is a required action to perform after
@@ -333,25 +346,16 @@ export default class Client implements KMSInterface {
333346
_activateBucketKey(keyIdentifier: string, logger: werelogs.Logger, cb: any) {
334347
return this.kmip.request(logger, 'Activate', [
335348
KMIP.TextString('Unique Identifier', keyIdentifier),
336-
], (err, response) => {
337-
if (err) {
338-
const error = arsenalErrorKMIP(err);
349+
], (error, response) => {
350+
if (error) {
339351
logger.error('KMIP::_activateBucketKey',
340352
{ error,
341353
serverInformation: this.serverInformation });
342354
return cb(error);
343355
}
344-
const uniqueIdentifier =
345-
response.lookup(searchFilter.uniqueIdentifier)[0];
346-
if (uniqueIdentifier !== keyIdentifier) {
347-
const error = arsenalErrorKMIP(
348-
'Server did not return the expected identifier');
349-
logger.error('KMIP::cipherDataKey',
350-
{ error, uniqueIdentifier });
351-
return cb(error);
352-
}
353-
return cb(null, keyIdentifier);
354-
});
356+
const keyErr = this._checkUniqueIdentifier(keyIdentifier, response, 'Activate', logger);
357+
return cb(keyErr, keyIdentifier);
358+
}, keyIdentifier);
355359
}
356360

357361
/**
@@ -386,9 +390,8 @@ export default class Client implements KMSInterface {
386390
return this.kmip.request(logger, 'Create', [
387391
KMIP.Enumeration('Object Type', CRYPTOGRAPHIC_OBJECT_TYPE),
388392
KMIP.Structure('Template-Attribute', attributes),
389-
], (err, response) => {
390-
if (err) {
391-
const error = arsenalErrorKMIP(err);
393+
], (error, response) => {
394+
if (error) {
392395
logger.error('KMIP::createBucketKey',
393396
{ error,
394397
serverInformation: this.serverInformation });
@@ -399,8 +402,11 @@ export default class Client implements KMSInterface {
399402
const uniqueIdentifier =
400403
response.lookup(searchFilter.uniqueIdentifier)[0];
401404
if (createdObjectType !== CRYPTOGRAPHIC_OBJECT_TYPE) {
402-
const error = arsenalErrorKMIP(
403-
'Server created an object of wrong type');
405+
// Retryable
406+
const error = errorInstances.InternalError.customizeDescription(
407+
kmipMsg('Create', bucketName,
408+
'Server created an object of wrong type')
409+
);
404410
logger.error('KMIP::createBucketKey',
405411
{ error, createdObjectType });
406412
return cb(error);
@@ -409,7 +415,7 @@ export default class Client implements KMSInterface {
409415
return this._activateBucketKey(uniqueIdentifier, logger, cb);
410416
}
411417
return cb(null, uniqueIdentifier);
412-
});
418+
}, bucketName);
413419
}
414420

415421
/**
@@ -430,25 +436,16 @@ export default class Client implements KMSInterface {
430436
KMIP.TextString('Revocation Message',
431437
'About to be deleted'),
432438
]),
433-
], (err, response) => {
434-
if (err) {
435-
const error = arsenalErrorKMIP(err);
439+
], (error, response) => {
440+
if (error) {
436441
logger.error('KMIP::_revokeBucketKey',
437442
{ error,
438443
serverInformation: this.serverInformation });
439444
return cb(error);
440445
}
441-
const uniqueIdentifier =
442-
response.lookup(searchFilter.uniqueIdentifier)[0];
443-
if (uniqueIdentifier !== bucketKeyId) {
444-
const error = arsenalErrorKMIP(
445-
'Server did not return the expected identifier');
446-
logger.error('KMIP::_revokeBucketKey',
447-
{ error, uniqueIdentifier });
448-
return cb(error);
449-
}
450-
return cb();
451-
});
446+
const keyErr = this._checkUniqueIdentifier(bucketKeyId, response, 'Revoke', logger);
447+
return cb(keyErr);
448+
}, bucketKeyId);
452449
}
453450

454451
/**
@@ -476,17 +473,9 @@ export default class Client implements KMSInterface {
476473
serverInformation: this.serverInformation });
477474
return cb(error);
478475
}
479-
const uniqueIdentifier =
480-
response.lookup(searchFilter.uniqueIdentifier)[0];
481-
if (uniqueIdentifier !== bucketKeyId) {
482-
const error = arsenalErrorKMIP(
483-
'Server did not return the expected identifier');
484-
logger.error('KMIP::destroyBucketKey',
485-
{ error, uniqueIdentifier });
486-
return cb(error);
487-
}
488-
return cb();
489-
});
476+
const keyErr = this._checkUniqueIdentifier(bucketKeyId, response, 'Destroy', logger);
477+
return cb(keyErr);
478+
}, bucketKeyId);
490479
});
491480
}
492481

@@ -518,26 +507,17 @@ export default class Client implements KMSInterface {
518507
]),
519508
KMIP.ByteString('Data', plainTextDataKey),
520509
KMIP.ByteString('IV/Counter/Nonce', CRYPTOGRAPHIC_DEFAULT_IV),
521-
], (err, response) => {
522-
if (err) {
523-
const error = arsenalErrorKMIP(err);
510+
], (error, response) => {
511+
if (error) {
524512
logger.error('KMIP::cipherDataKey',
525513
{ error,
526514
serverInformation: this.serverInformation });
527515
return cb(error);
528516
}
529-
const uniqueIdentifier =
530-
response.lookup(searchFilter.uniqueIdentifier)[0];
517+
const keyErr = this._checkUniqueIdentifier(masterKeyId, response, 'Encrypt', logger);
531518
const data = response.lookup(searchFilter.data)[0];
532-
if (uniqueIdentifier !== masterKeyId) {
533-
const error = arsenalErrorKMIP(
534-
'Server did not return the expected identifier');
535-
logger.error('KMIP::cipherDataKey',
536-
{ error, uniqueIdentifier });
537-
return cb(error);
538-
}
539-
return cb(null, data);
540-
});
519+
return cb(keyErr, data);
520+
}, masterKeyId);
541521
}
542522

543523
/**
@@ -568,26 +548,17 @@ export default class Client implements KMSInterface {
568548
]),
569549
KMIP.ByteString('Data', cipheredDataKey),
570550
KMIP.ByteString('IV/Counter/Nonce', CRYPTOGRAPHIC_DEFAULT_IV),
571-
], (err, response) => {
572-
if (err) {
573-
const error = arsenalErrorKMIP(err);
551+
], (error, response) => {
552+
if (error) {
574553
logger.error('KMIP::decipherDataKey',
575554
{ error,
576555
serverInformation: this.serverInformation });
577556
return cb(error);
578557
}
579-
const uniqueIdentifier =
580-
response.lookup(searchFilter.uniqueIdentifier)[0];
558+
const keyErr = this._checkUniqueIdentifier(masterKeyId, response, 'Decrypt', logger);
581559
const data = response.lookup(searchFilter.data)[0];
582-
if (uniqueIdentifier !== masterKeyId) {
583-
const error = arsenalErrorKMIP(
584-
'Server did not return the right identifier');
585-
logger.error('KMIP::decipherDataKey',
586-
{ error, uniqueIdentifier });
587-
return cb(error);
588-
}
589-
return cb(null, data);
590-
});
560+
return cb(keyErr, data);
561+
}, masterKeyId);
591562
}
592563

593564
healthcheck(logger, cb) {

0 commit comments

Comments
 (0)