#ifndef __CERT_REQUESTER_CONTEXT_H__ #define __CERT_REQUESTER_CONTEXT_H__ 1 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // CLASS CertRequesterContext. // // The CertRequesterContext class is used to encapsulate any details of the certificate enrollment // implementation which are dependent upon the context in which the program is running. // Currently, there are two supported contexts: // // 1) LocalContext. This is used when the program runs under the current user's context, // on the local machine. // // 2) KeySvcContext. This is used when some other context must be specified through // keysvc. // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ class CertRequesterContext { public: //------------------------------------------------------------------------- // Builds a list of the CSPs supported in this context. // (Different machines may have different CSP lists). // // Requires: // * This CertRequesterContext was created with a valid CERT_WIZARD_INFO pointer. // // Modifies: // * The following fields of the internal CERT_WIZARD_INFO pointer: // dwCSPCount : contains the number of valid CSPs. // rgdwProviderType : contains a dwCSPCount-element array of the provider types available. // This field should be freed with WizardFree(). // rgwszProvider : contains a dwCSPCount-element array of the provider names available. // This field, and each array element should be freed with WizardFree(). // // Use GetWizardInfo() to retrieve a pointer to the updated CERT_WIZARD_INFO. // // Returns: // * S_OK if successful, failure code otherwise. // //-------------------------------------------------------------------------- virtual HRESULT BuildCSPList() = 0; //--------------------------------------------------------------------------- // Checks if this context has sufficient access to use the specified cert type // in enrollment. // // Requires: // * This CertRequesterContext was created with a valid CERT_WIZARD_INFO pointer. // // Modifies: // Nothing // // Returns: // * Returns TRUE if this context has the permission to access the specified cert type. // Returns FALSE if not, or if an error occurs. // //-------------------------------------------------------------------------- virtual BOOL CheckAccessPermission(IN HCERTTYPE hCertType) = 0; //--------------------------------------------------------------------------- // Checks if this context has sufficient access to use the specified CA in enrollment. // // Requires: // * This CertRequesterContext was created with a valid CERT_WIZARD_INFO pointer. // // Modifies: // Nothing // // Returns: // * Returns TRUE if this context has the permission to access the specified CA. // Returns FALSE if not, or if an error occurs. // //-------------------------------------------------------------------------- virtual BOOL CheckCAPermission(IN HCAINFO hCAInfo) = 0; //----------------------------------------------------------------------- // Gets the name of the default CSP on the local machine, based on the provider // type specified by the internal CERT_WIZARD_INFO pointer. // // Requires: // * This CertRequesterContext was created with a valid CERT_WIZARD_INFO pointer. // // Modifies: // * The following fields of the internal CERT_WIZARD_INFO pointer: // pwszProvider : contains the name of the default provider, for the specified // provider type, on this machine. Use WizardFree to free the memory // associated with this field. HOWEVER, check the out parameter to // ensure that memory for this field was actually allocated. // // Use GetWizardInfo() to retrieve a pointer to the updated CERT_WIZARD_INFO. // // Returns: // S_OK if successful, an error code otherwise. // If memory was allocated to store the default CSP's name, returns TRUE into // the OUT parameter, FALSE otherwise. // // If the dwProviderType field of the interal wizard pointer is not set, OR // both the dwProviderType and pwszProvider fields are set, then the function // does not attempt to find a default CSP, and returns successfully without allocating // any memory. // //------------------------------------------------------------------------ virtual HRESULT GetDefaultCSP(OUT BOOL *pfAllocateCSP) = 0; //---------------------------------------------------------------------- // // Enrolls for a certificate, or renews a certificate, based on the // supplied parameters. // // Parameters: // * pdwStatus : Status of the request. One of the CRYPTUI_WIZ_CERT_REQUEST_STATUS_* // defines in cryptui.h. // * pResult : For certificate request creation, returns a pointer to an opaque // data blob which can be used as a parameter to SubmitRequest(). // Otherwise, returns a PCCERT_CONTEXT representing the // enrolled/renewed certificate. // // Requires: // Modifies: // Returns: // S_OK if the operation completed without an error, returns a standard error // code otherwise. Note that a return value of S_OK does not // guarantee that a certificate was issued: check that the pdwStatus parameter. // //---------------------------------------------------------------------- virtual HRESULT Enroll(OUT DWORD *pdwStatus, OUT HANDLE *pResult) = 0; //---------------------------------------------------------------------- // Performs context-specific initialization. This should always be called after // the context is created. // // Requires: // * This CertRequesterContext was created with a valid CERT_WIZARD_INFO pointer. // // Modifies: // Implementation-specific (see implementation documentation). // // Returns: // S_OK if the initialization succeeded. // //---------------------------------------------------------------------- virtual HRESULT Initialize() = 0; virtual HRESULT QueryRequestStatus(IN HANDLE hRequest, OUT CRYPTUI_WIZ_QUERY_CERT_REQUEST_INFO *pQueryInfo) = 0; virtual ~CertRequesterContext(); static HRESULT MakeDefaultCertRequesterContext(OUT CertRequesterContext **ppRequesterContext); static HRESULT MakeCertRequesterContext(IN LPCWSTR pwszAccountName, IN LPCWSTR pwszMachineName, IN DWORD dwCertOpenStoreFlags, IN CERT_WIZARD_INFO *pCertWizardInfo, OUT CertRequesterContext **ppRequesterContext, OUT UINT *pIDSText); UINT GetErrorString() { return m_idsText; } CERT_WIZARD_INFO * GetWizardInfo() { return m_pCertWizardInfo; } protected: CertRequesterContext(CERT_WIZARD_INFO * pCertWizardInfo) : m_pCertWizardInfo(pCertWizardInfo) { } CERT_WIZARD_INFO * m_pCertWizardInfo; UINT m_idsText; private: CertRequesterContext(); }; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // LocalContext. // // This class provides an implementation of the CertRequestContext interface // which runs under the current user's context on the local machine. // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ class LocalContext : public CertRequesterContext { friend class CertRequesterContext; public: //---------------------------------------------------------------------- // See CertRequesterContext::BuildCSPList(). //---------------------------------------------------------------------- virtual HRESULT BuildCSPList(); //---------------------------------------------------------------------- // See CertRequesterContext::CheckAccessPermission(HCERTTYPE). //---------------------------------------------------------------------- virtual BOOL CheckAccessPermission(HCERTTYPE hCertType); //---------------------------------------------------------------------- // See CertRequesterContext::BuildCSPList(BOOL *). //---------------------------------------------------------------------- virtual HRESULT GetDefaultCSP(BOOL *pfAllocateCSP); //---------------------------------------------------------------------- // See CertRequesterContext::BuildCSPList(HCAINFO). //---------------------------------------------------------------------- virtual BOOL CheckCAPermission(HCAINFO hCAInfo); virtual HRESULT Enroll(OUT DWORD *pdwStatus, OUT HANDLE *pResult); virtual HRESULT QueryRequestStatus(IN HANDLE hRequest, OUT CRYPTUI_WIZ_QUERY_CERT_REQUEST_INFO *pQueryInfo); //---------------------------------------------------------------------- // Always returns S_OK. //---------------------------------------------------------------------- virtual HRESULT Initialize(); private: HANDLE GetClientIdentity(); LocalContext(); LocalContext(CERT_WIZARD_INFO * pCertWizardInfo) : CertRequesterContext(pCertWizardInfo) { if (NULL != m_pCertWizardInfo) { m_pCertWizardInfo->fLocal = TRUE; } } }; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // KeySvcContext. // // This class provides an implementation of the CertRequestContext interface // using key svc. // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ class KeySvcContext : public CertRequesterContext { friend class CertRequesterContext; public: //---------------------------------------------------------------------- // See CertRequesterContext::BuildCSPList(). //---------------------------------------------------------------------- virtual HRESULT BuildCSPList(); //---------------------------------------------------------------------- // See CertRequesterContext::CheckAccessPermission(HCERTTYPE). //---------------------------------------------------------------------- virtual BOOL CheckAccessPermission(HCERTTYPE hCertType); //---------------------------------------------------------------------- // See CertRequesterContext::BuildCSPList(BOOL *). //---------------------------------------------------------------------- virtual HRESULT GetDefaultCSP(BOOL *pfAllocateCSP); //---------------------------------------------------------------------- // See CertRequesterContext::BuildCSPList(HCAINFO). //---------------------------------------------------------------------- virtual BOOL CheckCAPermission(HCAINFO hCAInfo); virtual HRESULT Enroll(OUT DWORD *pdwStatus, OUT HANDLE *pResult) = 0; virtual HRESULT QueryRequestStatus(IN HANDLE hRequest, OUT CRYPTUI_WIZ_QUERY_CERT_REQUEST_INFO *pQueryInfo); //---------------------------------------------------------------------- // Requires: // * This CertRequesterContext was created with a valid CERT_WIZARD_INFO pointer. // * This CertRequesterContext has been initialized with a call to Initialize(). // // Modifies: // * The following fields of the internal CERT_WIZARD_INFO pointer: // awszAllowedCertTypes : contains an array of cert types which this context // has permission to enroll for. This field, and each // array element, must be freed with WizardFree(). // awszValidCA : contains an array of CAs which this context has // permission to enroll from. This field, and each array // element, must be freed with WizardFree(). // Returns: // S_OK if initialization succeeded, an error code otherwise. // //---------------------------------------------------------------------- virtual HRESULT Initialize(); virtual ~KeySvcContext() { // free the list of allowed CertTypes // These may be allocate by the KeySvcContext's Initialize() method. if(NULL != m_pCertWizardInfo->awszAllowedCertTypes) { WizardFree(m_pCertWizardInfo->awszAllowedCertTypes); } if(NULL != m_pCertWizardInfo->awszValidCA) { WizardFree(m_pCertWizardInfo->awszValidCA); } } protected: KeySvcContext(CERT_WIZARD_INFO * pCertWizardInfo) : CertRequesterContext(pCertWizardInfo) { if (NULL != m_pCertWizardInfo) { m_pCertWizardInfo->fLocal = FALSE; m_pCertWizardInfo->awszAllowedCertTypes = NULL; m_pCertWizardInfo->awszValidCA = NULL; } } HRESULT ToCertContext(IN CERT_BLOB *pPKCS7Blob, IN CERT_BLOB *pHashBlob, OUT DWORD *pdwStatus, OUT PCCERT_CONTEXT *ppCertContext); private: KeySvcContext(); }; class WhistlerMachineContext : public KeySvcContext { friend class CertRequesterContext; virtual HRESULT Enroll(OUT DWORD *pdwStatus, OUT HANDLE *ppCertContext); private: WhistlerMachineContext(CERT_WIZARD_INFO * pCertWizardInfo) : KeySvcContext(pCertWizardInfo) { } HRESULT CreateRequest(IN KEYSVCC_HANDLE hKeyService, IN LPSTR pszMachineName, IN LPWSTR pwszCALocation, IN LPWSTR pwszCAName, IN PCERT_REQUEST_PVK_NEW pKeyNew, IN CERT_BLOB *pCert, IN PCERT_REQUEST_PVK_NEW pRenewKey, IN LPWSTR pszHashAlg, IN PCERT_ENROLL_INFO pRequestInfo, OUT HANDLE *phRequest); HRESULT SubmitRequest(IN KEYSVCC_HANDLE hKeyService, IN LPSTR pszMachineName, IN LPWSTR pwszCALocation, IN LPWSTR pwszCAName, IN HANDLE hRequest, OUT PCCERT_CONTEXT *ppCertContext, OUT DWORD *pdwStatus); void FreeRequest(IN KEYSVCC_HANDLE hKeyService, IN LPSTR pszMachineName, IN HANDLE hRequest); }; #endif // #ifndef __CERT_REQUESTER_CONTEXT_H__