#include "to_wauthn_const_buff.h"
#include "turn_bluetooth.h"
+#include <cctype>
#include <cstring>
#include <iostream>
#include <mutex>
Buffer credentialRawId;
Buffer userId;
unsigned transports = WAUTHN_TRANSPORT_NONE;
+ std::vector<Buffer> excludedCredentialsIds;
std::optional<LinkedData> linkedData;
bool seenLastMCUpdateCallback;
bool seenLastGAUpdateCallback;
pubkeyCredParams.params = params;
pubkeyCredParams.size = sizeof(params) / sizeof(*params);
+ auto excluded_credentials_wcbs =
+ std::vector<wauthn_const_buffer_s>(testContents.excludedCredentialsIds.size());
+ auto excluded_credentials =
+ std::vector<wauthn_pubkey_cred_descriptor_s>(testContents.excludedCredentialsIds.size());
+ for (size_t i = 0; i < testContents.excludedCredentialsIds.size(); ++i) {
+ excluded_credentials_wcbs[i] = ToWauthnConstBuff(testContents.excludedCredentialsIds[i]);
+ excluded_credentials[i] = {
+ PCT_PUBLIC_KEY,
+ &excluded_credentials_wcbs[i],
+ testContents.transports,
+ };
+ }
+
+ wauthn_pubkey_cred_descriptors_s exclude_credentials;
+ exclude_credentials.descriptors = excluded_credentials.data();
+ exclude_credentials.size = excluded_credentials.size();
+
wauthn_pubkey_cred_creation_options_s mcOptions;
std::memset(&mcOptions, 0, sizeof(mcOptions));
mcOptions.rp = &rp;
mcOptions.user = &user;
mcOptions.pubkey_cred_params = &pubkeyCredParams;
mcOptions.timeout = 60000; // 60s
+ mcOptions.exclude_credentials = exclude_credentials.size > 0 ? &exclude_credentials : nullptr;
wauthn_mc_callbacks_s mcCallbacks;
mcCallbacks.qrcode_callback = DisplayQRCallback;
<< std::endl; // NOLINT(performance-avoid-endl)
}
+void PrintHelp(char **argv)
+{
+ std::cout
+ << "Usage: " << (argv[0] ? argv[0] : "webauthn-ble-manual-tests")
+ << " [-n] [--exclude-credential CREDENTIAL_ID]\n"
+ << "\nOptions:\n"
+ << " -n Negative test -- with invalid QR code\n"
+ << " --exclude-credential CREDENTIAL_ID Send MakeCredential request with excludeList\n"
+ " containing CREDENTIAL_ID. To exclude several\n"
+ " credentials, specify this option multiple\n"
+ " times. CREDENTIAL_ID must be a hex string. E.g.\n"
+ " 91ef2e74f47bd06a6c5c4053ab8de1f6845f460a3ded.\n";
+}
+
+std::optional<Buffer> HexStringToBuffer(std::string_view hexString)
+{
+ if (hexString.size() & 1) {
+ return std::nullopt;
+ }
+ Buffer res;
+ res.reserve(hexString.size() >> 1);
+ for (size_t i = 0; i < hexString.size(); i += 2) {
+ auto d1 = hexString[i];
+ auto d2 = hexString[i | 1];
+ if (!std::isxdigit(static_cast<unsigned char>(d1)) ||
+ !std::isxdigit(static_cast<unsigned char>(d2)))
+ return std::nullopt;
+ static constexpr auto toDec = [](char c) noexcept {
+ if ('0' <= c && c <= '9')
+ return c - '0';
+ if ('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ return c - 'A' + 10;
+ };
+ res.emplace_back((toDec(d1) << 4) | toDec(d2));
+ }
+ return res;
+}
+
} // anonymous namespace
int main(int argc, char *argv[])
{},
{},
WAUTHN_TRANSPORT_NONE,
+ {},
std::nullopt,
false,
false,
{}};
- if (argc > 2) {
- std::cout << "Usage: " << (argv[0] ? argv[0] : "webauthn-ble-manual-tests") << " [-n]\n"
- << "\nOptions:\n"
- << " -n Negative test -- with invalid QR code\n";
- return 3;
+ for (int i = 1; i < argc; ++i) {
+ auto arg = std::string_view{argv[i]};
+ if (arg == "-n")
+ testContents.negative = true;
+ else if (arg == "--exclude-credential") {
+ if (i + 1 == argc) {
+ std::cout << "--exclude-credential is missing CREDENTIAL_ID argument\n";
+ PrintHelp(argv);
+ return 3;
+ }
+ auto credentialId = HexStringToBuffer(argv[++i]);
+ if (!credentialId) {
+ std::cout << "CREDENTIAL_ID has to be a hex string\n";
+ PrintHelp(argv);
+ return 3;
+ }
+ testContents.excludedCredentialsIds.emplace_back(std::move(*credentialId));
+ } else {
+ std::cout << "Unrecognized option: " << arg << '\n';
+ PrintHelp(argv);
+ return 3;
+ }
}
- if (argc == 2 && std::string_view("-n") == argv[1])
- testContents.negative = true;
const int err = TurnBluetoothOn();
if (err != BT_ERROR_NONE) {