mirror of
https://github.com/crosspoint-reader/crosspoint-reader.git
synced 2026-08-13 14:21:57 -07:00
49 lines
1.6 KiB
C++
49 lines
1.6 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <string_view>
|
|
|
|
#include "lib/Serialization/CredentialIntegrity.h"
|
|
|
|
namespace {
|
|
|
|
std::string decodeBase64(const std::string_view encoded) {
|
|
static constexpr std::string_view alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
std::string decoded;
|
|
decoded.reserve(encoded.size() * 3 / 4);
|
|
|
|
uint32_t accumulator = 0;
|
|
unsigned bits = 0;
|
|
for (const char ch : encoded) {
|
|
if (ch == '=') break;
|
|
const size_t value = alphabet.find(ch);
|
|
if (value == std::string_view::npos) return {};
|
|
accumulator = (accumulator << 6U) | static_cast<uint32_t>(value);
|
|
bits += 6;
|
|
if (bits >= 8) {
|
|
bits -= 8;
|
|
decoded.push_back(static_cast<char>((accumulator >> bits) & 0xFFU));
|
|
}
|
|
}
|
|
return decoded;
|
|
}
|
|
|
|
TEST(CredentialIntegrity, RejectsSameLengthBase64Corruption) {
|
|
const std::string encoded = "cGFzc3dvcmQ="; // "password"
|
|
const std::string plaintext = decodeBase64(encoded);
|
|
const uint32_t expectedCrc32 = credential_integrity::crc32(plaintext);
|
|
|
|
std::string corrupted = encoded;
|
|
corrupted[2] = corrupted[2] == 'A' ? 'B' : 'A';
|
|
const std::string corruptedPlaintext = decodeBase64(corrupted);
|
|
|
|
ASSERT_EQ(corrupted.size(), encoded.size());
|
|
ASSERT_EQ(corruptedPlaintext.size(), plaintext.size());
|
|
ASSERT_NE(corruptedPlaintext, plaintext);
|
|
EXPECT_TRUE(credential_integrity::validate(plaintext, plaintext.size(), expectedCrc32));
|
|
EXPECT_FALSE(credential_integrity::validate(corruptedPlaintext, plaintext.size(), expectedCrc32));
|
|
}
|
|
|
|
} // namespace
|