I have software that uses a documented API for the RSA authentication agent. This is a product that runs as a service on client computers in a domain and locally localizes users by exchanging data with RSA Authentication Manager, which is installed centrally.
Authentication publicly documented API-interface here: Agent Authentication API 8.1.1 for C developers guide . However, the documents do not look right, and I do not have access to the RSA header files - they are not public; only PDF documentation is available for download without paying $$ for RSA. If someone has access to the current header files, can you confirm if the documentation is out of date?
The function signatures indicated in the API docs seem to be incorrect - in fact, I am absolutely convinced that they are erroneous on x64 machines. For example, the latest PDF documentation shows the following:
int WINAPI AceSetUserData(SDI_HANDLE hdl, unsigned int userData)
int WINAPI AceGetUserData(SDI_HANDLE hdl, unsigned int *pUserData)
The documentation states several times that the value "userData" is a 32-bit quantity, for example, in the documentation for AceInit, AceSetUserDataand AceGetUserData. Relevant excerpt from documents for AceGetUserData:
This function is synchronous, and the caller must point to a 32-bit storage area (i.e., an unsigned int) as the second argument, into which the user data value will be copied.
This is clearly wrong - from some experiments, if you pass a pointer to the center of the buffer filled with 0xff AceGetUserData, of course, writes out a 64-bit value, not a 32-bit amount.
aceclnt.dll 8.1.3.563; " API 8.1 SP1", 7.3.1 .
, ... , - ( , !), -, RSA, .
#include <assert.h>
#include <stdlib.h>
#include <stdint.h>
#ifdef WIN32
#include <Windows.h>
#include <tchar.h>
#define SDAPI WINAPI
#else
#define SDAPI
#endif
typedef int SDI_HANDLE;
typedef uint32_t SD_BOOL;
typedef void (SDAPI* AceCallback)(SDI_HANDLE);
#define ACE_SUCCESS 1
#define ACE_PROCESSING 150
typedef SD_BOOL (SDAPI* AceInitializeEx_proto)(const char*, char*, uint32_t);
typedef int (SDAPI* AceInit_proto)(SDI_HANDLE*, void*, AceCallback);
typedef int (SDAPI* AceClose_proto)(SDI_HANDLE, AceCallback);
typedef int (SDAPI* AceGetUserData_proto)(SDI_HANDLE, void*);
typedef int (SDAPI* AceSetUserData_proto)(SDI_HANDLE, void*);
struct Api {
AceInitializeEx_proto AceInitializeEx;
AceInit_proto AceInit;
AceClose_proto AceClose;
AceGetUserData_proto AceGetUserData;
AceSetUserData_proto AceSetUserData;
} api;
static void api_init(struct Api* api) {
HMODULE dll = LoadLibrary(_T("aceclnt.dll"));
api->AceInitializeEx = (AceInitializeEx_proto)GetProcAddress(dll, "AceInitializeEx");
api->AceInit = (AceInit_proto)GetProcAddress(dll, "AceInit");
api->AceClose = (AceClose_proto)GetProcAddress(dll, "AceClose");
api->AceGetUserData = (AceGetUserData_proto)GetProcAddress(dll, "AceGetUserData");
api->AceSetUserData = (AceSetUserData_proto)GetProcAddress(dll, "AceSetUserData");
int success = api->AceInitializeEx("C:\\my\\conf\\directory", 0, 0);
assert(success);
}
static void demoFunction(SDI_HANDLE handle) {
union {
unsigned char testBuffer[sizeof(void *) * 3];
void *forceAlignment;
} u;
memset(u.testBuffer, 0xA5, sizeof u.testBuffer);
int err = api.AceGetUserData(handle, (void*)(u.testBuffer + sizeof(void*)));
assert(err == ACE_SUCCESS);
fputs("DEBUG: testBuffer =", stderr);
for (size_t i = 0; i < sizeof(u.testBuffer); i++) {
if (i % 4 == 0)
putc(' ', stderr);
fprintf(stderr, "%02x", u.testBuffer[i]);
}
fputc('\n', stderr);
}
static void SDAPI demoCallback(SDI_HANDLE h) {
fprintf(stderr, "Callback invoked, handle = %p\n", (void*)h);
}
int main(int argc, const char** argv)
{
api_init(&api);
SDI_HANDLE h;
int err = api.AceInit(&h, 0, &demoCallback);
assert(err == ACE_PROCESSING);
demoFunction(h);
api.AceClose(h, 0);
return 0;
}