SERVER-108185 Assert encryptedTokens is the correct length for text s… (#39240)
GitOrigin-RevId: b00a4e468eccb33b841278e192b9d823804db2de
This commit is contained in:
parent
5cc52b5a90
commit
df068ab24f
@ -459,6 +459,20 @@ public:
|
||||
static constexpr std::size_t kCipherLengthESCAndLeafFlag = kCipherLengthESCOnly + 1;
|
||||
static constexpr std::size_t kCipherLengthESCAndMsize = kCipherLengthESCOnly + 3;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Assert that _encryptedTokens is of the expected length for text search.
|
||||
*/
|
||||
void assertIsValidForTextSearch() const {
|
||||
uassert(ErrorCodes::BadValue,
|
||||
fmt::format("Invalid length for EncryptedStateCollectionTokensV2 for text "
|
||||
"search: Expected {}, got {}",
|
||||
kCipherLengthESCAndMsize,
|
||||
_encryptedTokens.size()),
|
||||
_encryptedTokens.size() == kCipherLengthESCAndMsize);
|
||||
}
|
||||
|
||||
private:
|
||||
static void assertLength(std::size_t sz) {
|
||||
uassert(ErrorCodes::BadValue,
|
||||
fmt::format("Invalid length for EncryptedStateCollectionTokensV2, expected {}, "
|
||||
|
||||
@ -927,17 +927,22 @@ void processFieldsForInsert(FLEQueryInterface* queryImpl,
|
||||
}
|
||||
} else if (payload.isTextSearchPayload()) {
|
||||
const auto& tsts = payload.payload.getTextSearchTokenSets().get();
|
||||
ecocDocuments.push_back(tsts.getExactTokenSet().getEncryptedTokens().generateDocument(
|
||||
payload.fieldPathName));
|
||||
auto exactSet = tsts.getExactTokenSet();
|
||||
exactSet.getEncryptedTokens().assertIsValidForTextSearch();
|
||||
ecocDocuments.push_back(
|
||||
exactSet.getEncryptedTokens().generateDocument(payload.fieldPathName));
|
||||
for (const auto& ts : tsts.getSubstringTokenSets()) {
|
||||
ts.getEncryptedTokens().assertIsValidForTextSearch();
|
||||
ecocDocuments.push_back(
|
||||
ts.getEncryptedTokens().generateDocument(payload.fieldPathName));
|
||||
}
|
||||
for (const auto& ts : tsts.getSuffixTokenSets()) {
|
||||
ts.getEncryptedTokens().assertIsValidForTextSearch();
|
||||
ecocDocuments.push_back(
|
||||
ts.getEncryptedTokens().generateDocument(payload.fieldPathName));
|
||||
}
|
||||
for (const auto& ts : tsts.getPrefixTokenSets()) {
|
||||
ts.getEncryptedTokens().assertIsValidForTextSearch();
|
||||
ecocDocuments.push_back(
|
||||
ts.getEncryptedTokens().generateDocument(payload.fieldPathName));
|
||||
}
|
||||
|
||||
@ -2350,5 +2350,79 @@ TEST_F(QETextSearchCrudTest, BasicPrefixAndSuffixMultipleInserts) {
|
||||
{"aaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaa"}});
|
||||
}
|
||||
|
||||
// Test insert update payloads containing text search token sets ('b') with embedded encryptedTokens
|
||||
// of invalid length in the exact/substring/prefix/suffix token sets are rejected.
|
||||
TEST_F(QETextSearchCrudTest, InsertPayloadHasInvalidExactEncryptedTokensForTextSearch) {
|
||||
addSchema({.type = QueryTypeEnum::SubstringPreview,
|
||||
.lb = 2,
|
||||
.ub = 10,
|
||||
.mlen = 400,
|
||||
.casef = false,
|
||||
.diacf = false});
|
||||
auto doc = BSON(kTestFieldName << "abcdef");
|
||||
auto element = doc.firstElement();
|
||||
auto buf = generatePlaceholder(element);
|
||||
auto efc = getEFC();
|
||||
|
||||
BSONObjBuilder builder;
|
||||
builder.append("_id", 1);
|
||||
builder.append("counter", 1);
|
||||
builder.append("plainText", "sample");
|
||||
builder.append(transformElementForInsertUpdate(element, buf, efc).firstElement());
|
||||
auto result = builder.obj();
|
||||
|
||||
auto serverPayload = EDCServerCollection::getEncryptedFieldInfo(result);
|
||||
ASSERT_EQ(serverPayload.size(), 1);
|
||||
auto& exactSet = serverPayload[0].payload.getTextSearchTokenSets().value().getExactTokenSet();
|
||||
exactSet.setEncryptedTokens(
|
||||
StateCollectionTokensV2(ESCDerivedFromDataTokenAndContentionFactorToken(
|
||||
exactSet.getEscDerivedToken().asPrfBlock()),
|
||||
boost::none,
|
||||
boost::none /* msize */)
|
||||
.encrypt({{}}));
|
||||
ASSERT_THROWS_CODE_AND_WHAT(
|
||||
processInsert(_queryImpl.get(), _edcNs, serverPayload, efc, 0, result, false),
|
||||
DBException,
|
||||
ErrorCodes::BadValue,
|
||||
"Invalid length for EncryptedStateCollectionTokensV2 for text "
|
||||
"search: Expected 51, got 48");
|
||||
}
|
||||
|
||||
TEST_F(QETextSearchCrudTest, InsertPayloadHasInvalidSubstringEncryptedTokensForTextSearch) {
|
||||
addSchema({.type = QueryTypeEnum::SubstringPreview,
|
||||
.lb = 2,
|
||||
.ub = 10,
|
||||
.mlen = 400,
|
||||
.casef = false,
|
||||
.diacf = false});
|
||||
auto doc = BSON(kTestFieldName << "abcdef");
|
||||
auto element = doc.firstElement();
|
||||
auto buf = generatePlaceholder(element);
|
||||
auto efc = getEFC();
|
||||
|
||||
BSONObjBuilder builder;
|
||||
builder.append("_id", 1);
|
||||
builder.append("counter", 1);
|
||||
builder.append("plainText", "sample");
|
||||
builder.append(transformElementForInsertUpdate(element, buf, efc).firstElement());
|
||||
auto result = builder.obj();
|
||||
|
||||
auto serverPayload = EDCServerCollection::getEncryptedFieldInfo(result);
|
||||
ASSERT_EQ(serverPayload.size(), 1);
|
||||
auto& ts =
|
||||
serverPayload[0].payload.getTextSearchTokenSets().value().getSubstringTokenSets().back();
|
||||
ts.setEncryptedTokens(StateCollectionTokensV2(ESCDerivedFromDataTokenAndContentionFactorToken(
|
||||
ts.getEscDerivedToken().asPrfBlock()),
|
||||
boost::none,
|
||||
boost::none /* msize */)
|
||||
.encrypt({{}}));
|
||||
ASSERT_THROWS_CODE_AND_WHAT(
|
||||
processInsert(_queryImpl.get(), _edcNs, serverPayload, efc, 0, result, false),
|
||||
DBException,
|
||||
ErrorCodes::BadValue,
|
||||
"Invalid length for EncryptedStateCollectionTokensV2 for text "
|
||||
"search: Expected 51, got 48");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mongo
|
||||
|
||||
Loading…
Reference in New Issue
Block a user