90 lines
20 KiB
JavaScript
90 lines
20 KiB
JavaScript
|
|
"use strict";
|
||
|
|
|
||
|
|
Object.defineProperty(exports, "__esModule", {
|
||
|
|
value: true
|
||
|
|
});
|
||
|
|
exports.getParameterEncryptionMetadata = void 0;
|
||
|
|
var _types = require("./types");
|
||
|
|
var _cekEntry = require("./cek-entry");
|
||
|
|
var _keyCrypto = require("./key-crypto");
|
||
|
|
var _dataType = require("../data-type");
|
||
|
|
var _request = _interopRequireDefault(require("../request"));
|
||
|
|
var _rpcrequestPayload = _interopRequireDefault(require("../rpcrequest-payload"));
|
||
|
|
var _packet = require("../packet");
|
||
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
|
// This code is based on the `mssql-jdbc` library published under the conditions of MIT license.
|
||
|
|
// Copyright (c) 2019 Microsoft Corporation
|
||
|
|
|
||
|
|
const getParameterEncryptionMetadata = (connection, request, callback) => {
|
||
|
|
if (request.cryptoMetadataLoaded === true) {
|
||
|
|
return callback();
|
||
|
|
}
|
||
|
|
const metadataRequest = new _request.default('sp_describe_parameter_encryption', error => {
|
||
|
|
if (error) {
|
||
|
|
return callback(error);
|
||
|
|
}
|
||
|
|
const decryptSymmetricKeyPromises = [];
|
||
|
|
const cekList = [];
|
||
|
|
let paramCount = 0;
|
||
|
|
for (const columns of resultRows) {
|
||
|
|
try {
|
||
|
|
const isFirstRecordSet = columns.some(col => (col && col.metadata && col.metadata.colName) === 'database_id');
|
||
|
|
if (isFirstRecordSet === true) {
|
||
|
|
const currentOrdinal = columns[_types.DescribeParameterEncryptionResultSet1.KeyOrdinal].value;
|
||
|
|
let cekEntry;
|
||
|
|
if (!cekList[currentOrdinal]) {
|
||
|
|
cekEntry = new _cekEntry.CEKEntry(currentOrdinal);
|
||
|
|
cekList[cekEntry.ordinal] = cekEntry;
|
||
|
|
} else {
|
||
|
|
cekEntry = cekList[currentOrdinal];
|
||
|
|
}
|
||
|
|
cekEntry.add(columns[_types.DescribeParameterEncryptionResultSet1.EncryptedKey].value, columns[_types.DescribeParameterEncryptionResultSet1.DbId].value, columns[_types.DescribeParameterEncryptionResultSet1.KeyId].value, columns[_types.DescribeParameterEncryptionResultSet1.KeyVersion].value, columns[_types.DescribeParameterEncryptionResultSet1.KeyMdVersion].value, columns[_types.DescribeParameterEncryptionResultSet1.KeyPath].value, columns[_types.DescribeParameterEncryptionResultSet1.ProviderName].value, columns[_types.DescribeParameterEncryptionResultSet1.KeyEncryptionAlgorithm].value);
|
||
|
|
} else {
|
||
|
|
paramCount++;
|
||
|
|
const paramName = columns[_types.DescribeParameterEncryptionResultSet2.ParameterName].value;
|
||
|
|
const paramIndex = request.parameters.findIndex(param => paramName === `@${param.name}`);
|
||
|
|
const cekOrdinal = columns[_types.DescribeParameterEncryptionResultSet2.ColumnEncryptionKeyOrdinal].value;
|
||
|
|
const cekEntry = cekList[cekOrdinal];
|
||
|
|
if (cekEntry && cekList.length < cekOrdinal) {
|
||
|
|
return callback(new Error(`Internal error. The referenced column encryption key ordinal "${cekOrdinal}" is missing in the encryption metadata returned by sp_describe_parameter_encryption. Max ordinal is "${cekList.length}".`));
|
||
|
|
}
|
||
|
|
const encType = columns[_types.DescribeParameterEncryptionResultSet2.ColumnEncrytionType].value;
|
||
|
|
if (_types.SQLServerEncryptionType.PlainText !== encType) {
|
||
|
|
request.parameters[paramIndex].cryptoMetadata = {
|
||
|
|
cekEntry: cekEntry,
|
||
|
|
ordinal: cekOrdinal,
|
||
|
|
cipherAlgorithmId: columns[_types.DescribeParameterEncryptionResultSet2.ColumnEncryptionAlgorithm].value,
|
||
|
|
encryptionType: encType,
|
||
|
|
normalizationRuleVersion: Buffer.from([columns[_types.DescribeParameterEncryptionResultSet2.NormalizationRuleVersion].value])
|
||
|
|
};
|
||
|
|
decryptSymmetricKeyPromises.push((0, _keyCrypto.decryptSymmetricKey)(request.parameters[paramIndex].cryptoMetadata, connection.config.options));
|
||
|
|
} else if (request.parameters[paramIndex].forceEncrypt === true) {
|
||
|
|
return callback(new Error(`Cannot execute statement or procedure ${request.sqlTextOrProcedure} because Force Encryption was set as true for parameter ${paramIndex + 1} and the database expects this parameter to be sent as plaintext. This may be due to a configuration error.`));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch {
|
||
|
|
return callback(new Error(`Internal error. Unable to parse parameter encryption metadata in statement or procedure "${request.sqlTextOrProcedure}"`));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (paramCount !== request.parameters.length) {
|
||
|
|
return callback(new Error(`Internal error. Metadata for some parameters in statement or procedure "${request.sqlTextOrProcedure}" is missing in the resultset returned by sp_describe_parameter_encryption.`));
|
||
|
|
}
|
||
|
|
return Promise.all(decryptSymmetricKeyPromises).then(() => {
|
||
|
|
request.cryptoMetadataLoaded = true;
|
||
|
|
process.nextTick(callback);
|
||
|
|
}, error => {
|
||
|
|
process.nextTick(callback, error);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
metadataRequest.addParameter('tsql', _dataType.typeByName.NVarChar, request.sqlTextOrProcedure);
|
||
|
|
if (request.parameters.length) {
|
||
|
|
metadataRequest.addParameter('params', _dataType.typeByName.NVarChar, metadataRequest.makeParamsParameter(request.parameters));
|
||
|
|
}
|
||
|
|
const resultRows = [];
|
||
|
|
metadataRequest.on('row', columns => {
|
||
|
|
resultRows.push(columns);
|
||
|
|
});
|
||
|
|
connection.makeRequest(metadataRequest, _packet.TYPE.RPC_REQUEST, new _rpcrequestPayload.default(metadataRequest.sqlTextOrProcedure, metadataRequest.parameters, connection.currentTransactionDescriptor(), connection.config.options, connection.databaseCollation));
|
||
|
|
};
|
||
|
|
exports.getParameterEncryptionMetadata = getParameterEncryptionMetadata;
|
||
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdHlwZXMiLCJyZXF1aXJlIiwiX2Nla0VudHJ5IiwiX2tleUNyeXB0byIsIl9kYXRhVHlwZSIsIl9yZXF1ZXN0IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9ycGNyZXF1ZXN0UGF5bG9hZCIsIl9wYWNrZXQiLCJvYmoiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImdldFBhcmFtZXRlckVuY3J5cHRpb25NZXRhZGF0YSIsImNvbm5lY3Rpb24iLCJyZXF1ZXN0IiwiY2FsbGJhY2siLCJjcnlwdG9NZXRhZGF0YUxvYWRlZCIsIm1ldGFkYXRhUmVxdWVzdCIsIlJlcXVlc3QiLCJlcnJvciIsImRlY3J5cHRTeW1tZXRyaWNLZXlQcm9taXNlcyIsImNla0xpc3QiLCJwYXJhbUNvdW50IiwiY29sdW1ucyIsInJlc3VsdFJvd3MiLCJpc0ZpcnN0UmVjb3JkU2V0Iiwic29tZSIsImNvbCIsIm1ldGFkYXRhIiwiY29sTmFtZSIsImN1cnJlbnRPcmRpbmFsIiwiRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MSIsIktleU9yZGluYWwiLCJ2YWx1ZSIsImNla0VudHJ5IiwiQ0VLRW50cnkiLCJvcmRpbmFsIiwiYWRkIiwiRW5jcnlwdGVkS2V5IiwiRGJJZCIsIktleUlkIiwiS2V5VmVyc2lvbiIsIktleU1kVmVyc2lvbiIsIktleVBhdGgiLCJQcm92aWRlck5hbWUiLCJLZXlFbmNyeXB0aW9uQWxnb3JpdGhtIiwicGFyYW1OYW1lIiwiRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MiIsIlBhcmFtZXRlck5hbWUiLCJwYXJhbUluZGV4IiwicGFyYW1ldGVycyIsImZpbmRJbmRleCIsInBhcmFtIiwibmFtZSIsImNla09yZGluYWwiLCJDb2x1bW5FbmNyeXB0aW9uS2V5T3JkaW5hbCIsImxlbmd0aCIsIkVycm9yIiwiZW5jVHlwZSIsIkNvbHVtbkVuY3J5dGlvblR5cGUiLCJTUUxTZXJ2ZXJFbmNyeXB0aW9uVHlwZSIsIlBsYWluVGV4dCIsImNyeXB0b01ldGFkYXRhIiwiY2lwaGVyQWxnb3JpdGhtSWQiLCJDb2x1bW5FbmNyeXB0aW9uQWxnb3JpdGhtIiwiZW5jcnlwdGlvblR5cGUiLCJub3JtYWxpemF0aW9uUnVsZVZlcnNpb24iLCJCdWZmZXIiLCJmcm9tIiwiTm9ybWFsaXphdGlvblJ1bGVWZXJzaW9uIiwicHVzaCIsImRlY3J5cHRTeW1tZXRyaWNLZXkiLCJjb25maWciLCJvcHRpb25zIiwiZm9yY2VFbmNyeXB0Iiwic3FsVGV4dE9yUHJvY2VkdXJlIiwiUHJvbWlzZSIsImFsbCIsInRoZW4iLCJwcm9jZXNzIiwibmV4dFRpY2siLCJhZGRQYXJhbWV0ZXIiLCJUWVBFUyIsIk5WYXJDaGFyIiwibWFrZVBhcmFtc1BhcmFtZXRlciIsIm9uIiwibWFrZVJlcXVlc3QiLCJUWVBFIiwiUlBDX1JFUVVFU1QiLCJScGNSZXF1ZXN0UGF5bG9hZCIsImN1cnJlbnRUcmFuc2FjdGlvbkRlc2NyaXB0b3IiLCJkYXRhYmFzZUNvbGxhdGlvbiIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvYWx3YXlzLWVuY3J5cHRlZC9nZXQtcGFyYW1ldGVyLWVuY3J5cHRpb24tbWV0YWRhdGEudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gVGhpcyBjb2RlIGlzIGJhc2VkIG9uIHRoZSBgbXNzcWwtamRiY2AgbGlicmFyeSBwdWJsaXNoZWQgdW5kZXIgdGhlIGNvbmRpdGlvbnMgb2YgTUlUIGxpY2Vuc2UuXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTkgTWljcm9zb2Z0IENvcnBvcmF0aW9uXG5cbmltcG9ydCB7IFNRTFNlcnZlckVuY3J5cHRpb25UeXBlLCB0eXBlIENyeXB0b01ldGFkYXRhLCBEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQxLCBEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQyIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBDRUtFbnRyeSB9IGZyb20gJy4vY2VrLWVudHJ5JztcbmltcG9ydCB7IGRlY3J5cHRTeW1tZXRyaWNLZXkgfSBmcm9tICcuL2tleS1jcnlwdG8nO1xuaW1wb3J0IHsgdHlwZUJ5TmFtZSBhcyBUWVBFUywgdHlwZSBQYXJhbWV0ZXIgfSBmcm9tICcuLi9kYXRhLXR5cGUnO1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vcmVxdWVzdCc7XG5pbXBvcnQgQ29ubmVjdGlvbiBmcm9tICcuLi9jb25uZWN0aW9uJztcbmltcG9ydCBScGNSZXF1ZXN0UGF5bG9hZCBmcm9tICcuLi9ycGNyZXF1ZXN0LXBheWxvYWQnO1xuaW1wb3J0IHsgVFlQRSB9IGZyb20gJy4uL3BhY2tldCc7XG5cbmV4cG9ydCBjb25zdCBnZXRQYXJhbWV0ZXJFbmNyeXB0aW9uTWV0YWRhdGEgPSAoY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgcmVxdWVzdDogUmVxdWVzdCwgY2FsbGJhY2s6IChlcnJvcj86IEVycm9yKSA9PiB2b2lkKSA9PiB7XG4gIGlmIChyZXF1ZXN0LmNyeXB0b01ldGFkYXRhTG9hZGVkID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gIH1cblxuICBjb25zdCBtZXRhZGF0YVJlcXVlc3QgPSBuZXcgUmVxdWVzdCgnc3BfZGVzY3JpYmVfcGFyYW1ldGVyX2VuY3J5cHRpb24nLCAoZXJyb3IpID0+IHtcbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjayhlcnJvcik7XG4gICAgfVxuXG4gICAgY29uc3QgZGVjcnlwdFN5bW1ldHJpY0tleVByb21pc2VzOiBQcm9taXNlPHZvaWQ+W10gPSBbXTtcbiAgICBjb25zdCBjZWtMaXN0OiBDRUtFbnRyeVtdID0gW107XG4gICAgbGV0IHBhcmFtQ291bnQgPSAwO1xuXG4gICAgZm9yIChjb25zdCBjb2x1bW5zIG9mIHJlc3VsdFJvd3MpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGlzRmlyc3RSZWNvcmRTZXQgPSBjb2x1bW5zLnNvbWUoKGNvbDogYW55KSA9PiAoY29sICYmIGNvbC5tZXRhZGF0YSAmJiBjb2wubWV0YWRhdGEuY29sTmFtZSkgPT09ICdkYXRhYmFzZV9pZCcpO1xuICAgICAgICBpZiAoaXNGaXJzdFJlY29yZFNldCA9PT0gdHJ1ZSkge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRPcmRpbmFsID0gY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQxLktleU9yZGluYWxdLnZhbHVlO1xuICAgICAgICAgIGxldCBjZWtFbnRyeTogQ0VLRW50cnk7XG4gICAgICAgICAgaWYgKCFjZWtMaXN0W2N1cnJlbnRPcmRpbmFsXSkge1xuICAgICAgICAgICAgY2VrRW50cnkgPSBuZXcgQ0VLRW50cnkoY3VycmVudE9yZGluYWwpO1xuICA
|