Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
7.9 KiB

  1. #include <windows.h>
  2. #include <wincrypt.h>
  3. #include <autoenr.h>
  4. #include <cryptui.h>
  5. #define MY_TEST_REG_ENTRY "Software\\Microsoft\\Cryptography\\AutoEnroll"
  6. #define PST_EVENT_INIT "PS_SERVICE_STARTED"
  7. /*BOOL SmallTest(DWORD dw)
  8. {
  9. HKEY hRegKey = 0;
  10. DWORD dwDisposition;
  11. BOOL fRet = FALSE;
  12. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CURRENT_USER, MY_TEST_REG_ENTRY,
  13. 0, NULL, REG_OPTION_NON_VOLATILE,
  14. KEY_ALL_ACCESS, NULL, &hRegKey,
  15. &dwDisposition))
  16. goto Ret;
  17. if (ERROR_SUCCESS != RegSetValueEx(hRegKey, "AutoEnrollTest", 0,
  18. REG_BINARY, (BYTE*)&dw, sizeof(dw)))
  19. goto Ret;
  20. fRet = TRUE;
  21. Ret:
  22. if (hRegKey)
  23. RegCloseKey(hRegKey);
  24. SetLastError(dw);
  25. return fRet;
  26. }*/
  27. void AutoEnrollErrorLogging(DWORD dwErr)
  28. {
  29. return;
  30. // UNDONE - log the error along with some useful message
  31. //SmallTest(dwErr);
  32. }
  33. #define FAST_BUFF_LEN 256
  34. BOOL EnrollForACert(
  35. IN BOOL fMachineEnrollment,
  36. IN BOOL fRenewalRequired,
  37. IN PAUTO_ENROLL_INFO pInfo
  38. )
  39. {
  40. CRYPTUI_WIZ_CERT_REQUEST_INFO CertRequestInfo;
  41. CRYPTUI_WIZ_CERT_REQUEST_PVK_NEW NewKeyInfo;
  42. CRYPTUI_WIZ_CERT_TYPE CertType;
  43. CRYPT_KEY_PROV_INFO ProviderInfo;
  44. PCCERT_CONTEXT pCertContext = NULL;
  45. PCCERT_CONTEXT pCert = NULL;
  46. DWORD dwCAStatus;
  47. DWORD dwAcquireFlags = 0;
  48. LPWSTR pwszProvName = NULL;
  49. WCHAR rgwszMachineName[MAX_COMPUTERNAME_LENGTH + 1];
  50. DWORD cMachineName = MAX_COMPUTERNAME_LENGTH + 1;
  51. CRYPT_DATA_BLOB CryptData;
  52. DWORD dwErr = 0;
  53. BOOL fRet = FALSE;
  54. memset(&CertRequestInfo, 0, sizeof(CertRequestInfo));
  55. memset(&NewKeyInfo, 0, sizeof(NewKeyInfo));
  56. memset(&ProviderInfo, 0, sizeof(ProviderInfo));
  57. memset(&rgwszMachineName, 0, sizeof(rgwszMachineName));
  58. memset(&CryptData, 0, sizeof(CryptData));
  59. memset(&CertType, 0, sizeof(CertType));
  60. if (fMachineEnrollment)
  61. {
  62. dwAcquireFlags = CRYPT_MACHINE_KEYSET;
  63. if (0 == GetComputerNameW(rgwszMachineName,
  64. &cMachineName))
  65. {
  66. goto Ret;
  67. }
  68. CertRequestInfo.pwszMachineName = rgwszMachineName;
  69. }
  70. // set up the provider info
  71. ProviderInfo.dwProvType = pInfo->dwProvType;
  72. ProviderInfo.pwszProvName = NULL; // The wizard will choose one based
  73. // on the cert type
  74. // set the acquire context flags
  75. // UNDONE - need to add silent flag
  76. ProviderInfo.dwFlags = dwAcquireFlags;
  77. // set the key specification
  78. ProviderInfo.dwKeySpec = pInfo->dwKeySpec;
  79. // set up the new key info
  80. NewKeyInfo.dwSize = sizeof(NewKeyInfo);
  81. NewKeyInfo.pKeyProvInfo = &ProviderInfo;
  82. // set the flags to be passed when calling CryptGenKey
  83. NewKeyInfo.dwGenKeyFlags = pInfo->dwGenKeyFlags;
  84. // set the request info
  85. CertRequestInfo.dwSize = sizeof(CertRequestInfo);
  86. // UNDONE - if cert exists then check if expired (if so do renewal)
  87. if (pInfo->fRenewal)
  88. {
  89. CertRequestInfo.dwPurpose = CRYPTUI_WIZ_CERT_RENEW;
  90. CertRequestInfo.pRenewCertContext = pInfo->pOldCert;
  91. }
  92. else
  93. {
  94. CertRequestInfo.dwPurpose = CRYPTUI_WIZ_CERT_ENROLL;
  95. CertRequestInfo.pRenewCertContext = NULL;
  96. }
  97. // UNDONE - for now always gen a new key, later may allow using existing key
  98. // for things like renewal
  99. CertRequestInfo.dwPvkChoice = CRYPTUI_WIZ_CERT_REQUEST_PVK_CHOICE_NEW;
  100. CertRequestInfo.pPvkNew = &NewKeyInfo;
  101. // destination cert store is the MY store (!!!! hard coded !!!!)
  102. CertRequestInfo.pwszDesStore = L"MY";
  103. // set algorithm for hashing
  104. CertRequestInfo.pszHashAlg = NULL;
  105. // set the cert type
  106. CertRequestInfo.dwCertChoice = CRYPTUI_WIZ_CERT_REQUEST_CERT_TYPE;
  107. CertType.dwSize = sizeof(CertType);
  108. CertType.cCertType = 1;
  109. CertType.rgwszCertType = &pInfo->pwszCertType;
  110. CertRequestInfo.pCertType = &CertType;
  111. // set the requested cert extensions
  112. CertRequestInfo.pCertRequestExtensions = &pInfo->CertExtensions;
  113. // set post option
  114. CertRequestInfo.dwPostOption = 0;
  115. // set the Cert Server machine and authority
  116. CertRequestInfo.pwszCALocation = pInfo->pwszCAMachine;
  117. CertRequestInfo.pwszCAName = pInfo->pwszCAAuthority;
  118. // certify and create a key at the same time
  119. if (!CryptUIWizCertRequest(CRYPTUI_WIZ_NO_UI, 0, NULL,
  120. &CertRequestInfo, &pCertContext,
  121. &dwCAStatus))
  122. {
  123. AutoEnrollErrorLogging(GetLastError());
  124. goto Ret;
  125. }
  126. if (CRYPTUI_WIZ_CERT_REQUEST_STATUS_SUCCEEDED == dwCAStatus)
  127. {
  128. BYTE aHash[20];
  129. CRYPT_HASH_BLOB blobHash;
  130. blobHash.pbData = aHash;
  131. blobHash.cbData = sizeof(aHash);
  132. CryptData.cbData = (wcslen(pInfo->pwszAutoEnrollmentID) + 1) * sizeof(WCHAR);
  133. CryptData.pbData = (BYTE*)pInfo->pwszAutoEnrollmentID;
  134. // We need to get the real certificate of the store, as the one
  135. // passed back is self contained.
  136. if(!CertGetCertificateContextProperty(pCertContext,
  137. CERT_SHA1_HASH_PROP_ID,
  138. blobHash.pbData,
  139. &blobHash.cbData))
  140. {
  141. AutoEnrollErrorLogging(GetLastError());
  142. goto Ret;
  143. }
  144. pCert = CertFindCertificateInStore(pInfo->hMYStore,
  145. pCertContext->dwCertEncodingType,
  146. 0,
  147. CERT_FIND_SHA1_HASH,
  148. &blobHash,
  149. NULL);
  150. if(pCert == NULL)
  151. {
  152. AutoEnrollErrorLogging(GetLastError());
  153. goto Ret;
  154. }
  155. // place the auto enrollment property on the cert
  156. if (!CertSetCertificateContextProperty(pCert,
  157. CERT_AUTO_ENROLL_PROP_ID, 0, &CryptData))
  158. {
  159. AutoEnrollErrorLogging(GetLastError());
  160. goto Ret;
  161. }
  162. }
  163. // UNDONE - request did not return cert so take appropriate action
  164. // else
  165. // {
  166. // goto Ret;
  167. // }
  168. fRet = TRUE;
  169. Ret:
  170. if (pCertContext)
  171. CertFreeCertificateContext(pCertContext);
  172. if (pCert)
  173. CertFreeCertificateContext(pCert);
  174. if (pwszProvName)
  175. LocalFree(pwszProvName);
  176. return fRet;
  177. }
  178. //+---------------------------------------------------------------------------
  179. //
  180. // Function: ProvAutoEnrollment
  181. //
  182. // Synopsis: Entry point for the default MS auto enrollment client provider.
  183. //
  184. // Arguments:
  185. // fMachineEnrollment - TRUE if machine is enrolling, FALSE if user
  186. //
  187. // pInfo - information needed to enroll (see AUTO_ENROLL_INFO struct
  188. // in autoenrl.h)
  189. //
  190. // History: 01-12-98 jeffspel Created
  191. //
  192. // Notes:
  193. //
  194. //----------------------------------------------------------------------------
  195. BOOL ProvAutoEnrollment(
  196. IN BOOL fMachineEnrollment,
  197. IN PAUTO_ENROLL_INFO pInfo
  198. )
  199. {
  200. BOOL fRenewalRequired = FALSE;
  201. BOOL fRet = FALSE;
  202. // enroll for a cert
  203. if (!EnrollForACert(fMachineEnrollment, fRenewalRequired, pInfo))
  204. goto Ret;
  205. fRet = TRUE;
  206. Ret:
  207. return fRet;
  208. }
  209. BOOLEAN
  210. DllInitialize(
  211. IN PVOID hmod,
  212. IN ULONG Reason,
  213. IN PCONTEXT Context
  214. )
  215. {
  216. return( TRUE );
  217. }