0

My question is about cryptoAPI interface.

Look, CertEnumSystemStoreLocation() is a function to enumerate all certificate store locations available in system. It returns (using callback) enumerated location as wide string (LPCWSTR).

CertEnumSystemStore() enumerates stores by the given location. It takes integer constant for location (DWORD) as argument.

I tried to enumerate locations and the result was a list of strings, that semantically is equal to the list of DWORD location constants from CryptoAPI import module.

And my question is: what should i do to translate wide string representation of store location to DWORD constant? Is there a cryptoAPI function (or, at least, commonly used method) for it?

MrCat
  • 107
  • 2

2 Answers2

2

It looks like the dwFlags passed to your CertEnumSystemStoreLocationCallback callback function actually gives you the store location constant, although this is incredibly badly documented.

The example shown here for Listing System and Physical Stores handles the dwFlags value in its callback like this:

dwFlags &= CERT_SYSTEM_STORE_MASK;
dwFlags |= pEnumArg->dwFlags & ~CERT_SYSTEM_STORE_LOCATION_MASK;
CertEnumSystemStore(dwFlags, ...);

So I think if you do that masking you'll be left with the location constant in dwFlags equivalent to the string passed in the pvszStoreLocation parameter.

Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79
1

The dwFlags argument passed to the CertEnumSystemStoreLocationCallback callback function contains the store location encoded in the bits CERT_SYSTEM_STORE_LOCATION_MASK. Shifting those to the right by CERT_SYSTEM_STORE_LOCATION_SHIFT turns it into the numeric store ID.

The following code retrieves the list of store locations alongside the numeric store IDs:

Structure for communication:

#include <SDKDDKVer.h>
#include <windows.h>
#include <wincrypt.h>
#pragma comment(lib, "Crypt32.lib")

#include <vector>
#include <string>
#include <iostream>

struct Location {
    DWORD StoreId;
    std::wstring Name;
};
typedef std::vector<Location> StoreLocationsContainer;

Callback:

BOOL WINAPI CertEnumSystemStoreLocationCallback( LPCWSTR pvszStoreLocations,
                                                 DWORD dwFlags,
                                                 void* pvReserved,
                                                 void* pvArg
                                                 ) {
    StoreLocationsContainer& locations = *reinterpret_cast<StoreLocationsContainer*>( pvArg );
    DWORD StoreId = ( dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK )
                    >> CERT_SYSTEM_STORE_LOCATION_SHIFT;
    Location location = { StoreId, std::wstring( pvszStoreLocations ) };
    locations.push_back( location );
    return TRUE;
}

Implementation:

StoreLocationsContainer GetStoreLocations() {
    StoreLocationsContainer locations;
    if ( !::CertEnumSystemStoreLocation( 0x0,
                                         &locations,
                                         CertEnumSystemStoreLocationCallback ) ) {
        throw std::runtime_error( "CertEnumSystemStoreLocation" );
    }
    return locations;
}

For completeness, here is the remaining code to dump all stores across all locations:

BOOL WINAPI CertEnumSystemStoreCallback( const void* pvSystemStore,
                                         DWORD dwFlags,
                                         PCERT_SYSTEM_STORE_INFO pStoreInfo,
                                         void* pvReserved,
                                         void* pvArg ) {
    std::wcout << L"  " << static_cast<const wchar_t*>( pvSystemStore ) << std::endl;
    return TRUE;
}

void PrintStores( const StoreLocationsContainer& locations ) {
    for ( const Location& loc : locations ) {
        std::wcout << loc.Name << std::endl;
        DWORD dwFlags = ( loc.StoreId << CERT_SYSTEM_STORE_LOCATION_SHIFT )
                        & CERT_SYSTEM_STORE_LOCATION_MASK;
        ::CertEnumSystemStore( dwFlags, nullptr, nullptr, CertEnumSystemStoreCallback );
    }
}

int main() {
    StoreLocationsContainer locations = GetStoreLocations();
    PrintStores( locations );

    return 0;
}
IInspectable
  • 46,945
  • 8
  • 85
  • 181