in kmscng/main/bridge.cc [330:397]
absl::Status EnumKeys(__in NCRYPT_PROV_HANDLE hProvider,
__in_opt LPCWSTR pszScope,
__deref_out NCryptKeyName** ppKeyName,
__inout PVOID* ppEnumState, __in DWORD dwFlags,
__in_opt std::string test_config_path) {
LOG_IF(INFO, std::getenv(kVerboseLoggingEnvVariable))
<< "EnumKeys invoked\n"
<< "Provider: " << hProvider << "\n"
<< "Flags: " << dwFlags << "\n\n";
ASSIGN_OR_RETURN(Provider * prov, ValidateProviderHandle(hProvider));
if (pszScope) {
return NewInvalidArgumentError("pszScope should be null",
NTE_INVALID_PARAMETER, SOURCE_LOCATION);
}
if (!ppKeyName) {
return NewInvalidArgumentError("ppKeyName cannot be null",
NTE_INVALID_PARAMETER, SOURCE_LOCATION);
}
dwFlags = dwFlags & ~NCRYPT_SILENT_FLAG;
dwFlags = dwFlags & ~NCRYPT_MACHINE_KEY_FLAG;
if (dwFlags != 0) {
return NewInvalidArgumentError(
absl::StrFormat("unsupported flag specified: %u", dwFlags),
NTE_BAD_FLAGS, SOURCE_LOCATION);
}
EnumState* enum_state;
ProviderConfig config;
// Generate CKV list if this is the first call to EnumKeys.
if (!*ppEnumState) {
// If test_config_path exists, load config from there. This is only used
// for internal testing.
if (!test_config_path.empty()) {
ASSIGN_OR_RETURN(config, LoadConfigFromFile(test_config_path));
} else {
// Load config from well-known system path.
ASSIGN_OR_RETURN(config,
LoadConfigFromFile("C:\\Windows\\KMSCNG\\config.yaml"));
}
// Load CKV list from config file.
ASSIGN_OR_RETURN(std::vector<HeapAllocatedKeyDetails> ckv_list,
BuildCkvList(hProvider, config));
*ppEnumState = new EnumState{
.key_details = ckv_list,
.current = 0,
};
enum_state = reinterpret_cast<EnumState*>(*ppEnumState);
} else {
// Check ppEnumState value to make sure it's a valid vector index.
enum_state = reinterpret_cast<EnumState*>(*ppEnumState);
if (enum_state->current > enum_state->key_details.size()) {
return NewInvalidArgumentError(
absl::StrFormat("unrecognized ppEnumState value: %u",
enum_state->current),
NTE_INVALID_PARAMETER, SOURCE_LOCATION);
}
}
if (enum_state->current == enum_state->key_details.size()) {
return NewInvalidArgumentError(
absl::StrFormat("end of enumeration reached: %u", enum_state->current),
NTE_NO_MORE_ITEMS, SOURCE_LOCATION);
}
*ppKeyName =
enum_state->key_details[enum_state->current].NewNCryptKeyName().release();
enum_state->current += 1;
return absl::OkStatus();
}