Skip to content

Instantly share code, notes, and snippets.

@sevaa
Last active March 24, 2025 23:24
Show Gist options
  • Save sevaa/836f5ac7da881462821f2a687ca46a7b to your computer and use it in GitHub Desktop.
Save sevaa/836f5ac7da881462821f2a687ca46a7b to your computer and use it in GitHub Desktop.
CertEnrollUI API
; To build the import library, run one of the following with this file under the Development Command prompt:
; lib /def:CertEnrollUI.def /out:CertEnrollUI.lib /machine:x64
; The /machine switch can also be x86, arm, or arm64
LIBRARY CertEnrollUI
EXPORTS
CreateUIObject @200
#pragma once
enum EnrollmentUIFlags
{
UIF_NONE = 0,
UIF_DISABLESELECTION = 1,
UIF_BASICMODE = 2,
UIF_EOBO = 4,
UIF_CUSTOMREQUEST = 8,
UIF_AUTOENROLL = 16
};
enum TextPageId
{
TPI_Welcome = 0,
TPI_EverythingIsOK = 1
};
enum UserAction
{
UA_None = 0,
UA_OK = 1,
UA_Cancel = 2
};
enum TemplateSelectionPageId
{
TSPI_Enroll = 0,
TSPI_Enrolling = 1,
TSPI_Enrolled = 2,
TSPI_Failed = 3,
TSPI_Backup = 4,
TSPI_Backingup = 5,
TSPI_BackupSucceeded = 6,
TSPI_FailedToBackup = 7,
TSPI_SavingCert = 8,
TSPI_SavedCert = 9,
TSPI_FailedToCreateCert = 10,
TSPI_CreateCert = 11,
TSPI_InstallCert = 12,
TSPI_InstallingCert = 13,
TSPI_InstalledCert = 14,
TSPI_FailedToInstallCert = 15,
TSPI_OfflineRequest = 16,
TSPI_SavingRequest = 17,
TSPI_SavedRequest = 18,
TSPI_FailedToCreateRequest = 19
};
enum EnrollmentQueryStatus
{
QueryOK = 1,
QueryError = 2,
QueryUnknown = 4,
QuerySuperseded = 8,
QueryEnrollRequired = 32
};
// A replacement for ATL::CSimpleArray
template<class T>
struct CSimpleArray
{
T* p;
int Size, AllocSize;
};
struct POLICY_SERVER_GROUP
{
BSTR bstrCEPId;
BSTR bstrFriendlyName;
bool fSelected;
bool fGroupPolicy;
bool fAutoEnrollment;
bool fDefault;
// It's an array of smart pointers, but an array of dumb pointers would be binary compatible
CSimpleArray<IX509PolicyServerUrl*> arrPtrCEP;
};
struct FAILED_POLICY_SERVER
{
BSTR bstrCEPId;
BSTR bstrErrorStr;
};
class IX509Enrollments : public IDispatch
{
public:
STDMETHOD(get_ItemByIndex)(long i, IX509Enrollment** ppo) = 0;
STDMETHOD(get_Count)(long* n) = 0;
STDMETHOD(get__NewEnum)(IUnknown**) = 0;
STDMETHOD(Add)(IX509Enrollment*) = 0;
STDMETHOD(Remove)(long) = 0;
STDMETHOD(Clear)(void) = 0;
STDMETHOD(get_ItemByTemplateName)(wchar_t*, IX509Enrollment**) = 0;
STDMETHOD(get_Item)(long, tagVARIANT*) = 0;
STDMETHOD(p_SetErrorInfo)(HRESULT, const wchar_t*, const wchar_t*) = 0;
};
class ICertificateEnrollmentUI
{
public:
virtual long Run(HWND hWnd, EnrollmentUIFlags Flags) = 0;
virtual long ShowCEPSelectionPage(CSimpleArray<POLICY_SERVER_GROUP>*, enum X509CertificateEnrollmentContext, bool, bool, enum UserAction* userAction) = 0;
virtual long ShowTemplateSelectionPage(IX509Enrollments*, CSimpleArray<FAILED_POLICY_SERVER>*, enum TemplateSelectionPageId, enum UserAction* userAction) = 0;
virtual long ShowTextPage(enum TextPageId, enum UserAction* userAction) = 0;
virtual int ShowErrorPage(LPCWSTR) = 0;
virtual __int64 SelectUser(LPWSTR*, enum UserAction* userAction) = 0;
virtual __int64 SelectEACert(struct _CERT_CONTEXT const**, enum UserAction* userAction) = 0;
virtual __int64 SelectCustomRequestTemplate(LPWSTR *, unsigned __int64, int *SelectedTemplate, enum X509RequestType*, bool *SuppressDefault, bool *CNGRequest, enum UserAction* userAction) = 0;
virtual void Delete(void) = 0;
virtual __int64 UpdateProgress(double, struct IX509Enrollment*, enum UserAction* userAction) = 0;
virtual int WaitForSmartCard(LPWSTR*, enum UserAction* userAction) = 0;
virtual int SaveRequest(_CRYPTOAPI_BLOB*, enum UserAction* userAction) = 0;
virtual HWND GetHWND(void) = 0;
};
extern "C" extern HRESULT WINAPI CreateUIObject(ICertificateEnrollmentUI **ppUI);
@sevaa
Copy link
Author

sevaa commented Mar 24, 2025

Companion gist for this blog post. The undocumented API of the Windows' CertEnrollUI.dll, the one that lets you display and drive the certificate enrollment wizard. A sample of this API usage is another gist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment