Leaked source code of windows server 2003
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.

474 lines
15 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1996
  6. //
  7. // File: toidfunc.cpp
  8. //
  9. // Contents: OID Function Tests: Register, Unregister or Enum
  10. //
  11. // See Usage() for a list of test options.
  12. //
  13. //
  14. // Functions: main
  15. //
  16. // History: 24-Nov-96 philh created
  17. //--------------------------------------------------------------------------
  18. #include <windows.h>
  19. #include <assert.h>
  20. #include "wincrypt.h"
  21. #include "certtest.h"
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <memory.h>
  26. #include <time.h>
  27. static void Usage(void)
  28. {
  29. printf("Usage: toidfunc [options] <TestName>\n");
  30. printf("Options are:\n");
  31. printf(" -h - This message\n");
  32. printf(" -o<OID string> - For example, -o1.2.3.4\n");
  33. printf(" -o%s - Default Dlls\n", CRYPT_DEFAULT_OID);
  34. printf(" -O<OID number> - For example, -O1000\n");
  35. printf(" -f<FuncName> - For example, -fCryptDllEncodeObject\n");
  36. printf(" -F<FuncName Override> - For example, -FMyEncodeObject\n");
  37. printf(" -e<EncodeType Number> - For example, -e1 (X509_ASN)\n");
  38. printf(" -i<index number> - Default Dlls index\n");
  39. printf(" -d<Dll filename> - For example, -dsetx509.dll\n");
  40. printf(" -G<Group number> - For example, -G7\n");
  41. printf(" -v[RegType] <name> <data> - Registry value\n");
  42. printf("\n");
  43. printf("TestNames (case insensitive):\n");
  44. printf(" Enum options: [-o|-O] [-f] [-e], defaults to any\n");
  45. printf(" Register options: -o|-O -f [-F] [-e] [-d] [-v] [-v] ...\n");
  46. printf(" Unregister options: -o|-O -f [-e]\n");
  47. printf(" EnumInfo options: [-G], defaults to all groups\n");
  48. printf("\n");
  49. printf(" Register options: -o%s -f [-i] -d [-v] [-v] ...\n",
  50. CRYPT_DEFAULT_OID);
  51. printf(" Unregister options: -o%s -f -d\n", CRYPT_DEFAULT_OID);
  52. printf("\n");
  53. printf("Defaults:\n");
  54. printf(" -e%d (X509_ASN_ENCODING)\n", X509_ASN_ENCODING);
  55. printf(" -i0x%x\n", CRYPT_REGISTER_LAST_INDEX);
  56. printf("\n");
  57. printf("RegTypes: REG_SZ | REG_EXPAND_SZ | REG_DWORD\n");
  58. printf("\n");
  59. printf("OID number range: 1 .. 0xFFFF\n");
  60. printf("\n");
  61. printf("-v option: the next two arguments contain Registry Value name and data\n");
  62. printf(" For example, -vREG_SZ FuncName MyDllDecodeObject\n");
  63. printf("\n");
  64. }
  65. static DWORD ToRegType(
  66. IN LPCSTR pszOption,
  67. IN LPCSTR pszRegType
  68. )
  69. {
  70. DWORD RegType;
  71. if (NULL == pszRegType || '\0' == *pszRegType ||
  72. 0 == _stricmp("REG_SZ", pszRegType))
  73. RegType = REG_SZ;
  74. else if (0 == _stricmp("REG_EXPAND_SZ", pszRegType))
  75. RegType = REG_EXPAND_SZ;
  76. else if (0 == _stricmp("REG_DWORD", pszRegType))
  77. RegType = REG_DWORD;
  78. else if (0 == _stricmp("REG_MULTI_SZ", pszRegType))
  79. RegType = REG_MULTI_SZ;
  80. else {
  81. printf("Option (%s) : has an invalid RegType: %s\n",
  82. pszOption, pszRegType);
  83. RegType = REG_NONE;
  84. }
  85. return RegType;
  86. }
  87. static LPCSTR FromRegType(
  88. IN DWORD dwType
  89. )
  90. {
  91. LPCSTR pszType;
  92. switch (dwType) {
  93. case REG_DWORD:
  94. pszType = "REG_DWORD";
  95. break;
  96. case REG_SZ:
  97. pszType = "REG_SZ";
  98. break;
  99. case REG_EXPAND_SZ:
  100. pszType = "REG_EXPAND_SZ";
  101. break;
  102. case REG_MULTI_SZ:
  103. pszType = "REG_MULTI_SZ";
  104. break;
  105. case REG_BINARY:
  106. pszType = "REG_BINARY";
  107. break;
  108. default:
  109. pszType = "REG_????";
  110. }
  111. return pszType;
  112. }
  113. #define ENUM_ARG "EnumCallback arg"
  114. static BOOL WINAPI EnumCallback(
  115. IN DWORD dwEncodingType,
  116. IN LPCSTR pszFuncName,
  117. IN LPCSTR pszOID,
  118. IN DWORD cValue,
  119. IN const DWORD rgdwValueType[],
  120. IN LPCWSTR const rgpwszValueName[],
  121. IN const BYTE * const rgpbValueData[],
  122. IN const DWORD rgcbValueData[],
  123. IN void *pvArg
  124. )
  125. {
  126. BOOL fResult = TRUE;
  127. if (NULL == pvArg || 0 != strcmp(ENUM_ARG, (LPCSTR) pvArg)) {
  128. fResult = FALSE;
  129. printf("CryptEnumOIDFunction failed: invalid pvArg passed to callback\n");
  130. }
  131. printf(" EncodingType %d\\%s\\%s\n", dwEncodingType, pszFuncName, pszOID);
  132. for (DWORD i = 0; i < cValue; i++) {
  133. DWORD dwType = rgdwValueType[i];
  134. if (REG_MULTI_SZ == dwType) {
  135. DWORD j;
  136. DWORD cch;
  137. LPWSTR pwszData = (LPWSTR) rgpbValueData[i];
  138. for (j = 0; 0 != (cch = wcslen(pwszData));
  139. j++, pwszData += cch + 1) {
  140. printf(" %S[%d] : %S\n", rgpwszValueName[i], j, pwszData);
  141. }
  142. } else if (REG_BINARY == dwType) {
  143. printf(" %S (REG_BINARY) :\n", rgpwszValueName[i]);
  144. PrintBytes(" ", (BYTE *) rgpbValueData[i], rgcbValueData[i]);
  145. } else {
  146. printf(" %S : ", rgpwszValueName[i]);
  147. if (rgpbValueData[i] && rgcbValueData[i]) {
  148. switch (dwType) {
  149. case REG_DWORD:
  150. {
  151. DWORD dwData = *((DWORD *) rgpbValueData[i]);
  152. printf("0x%x (%d)", dwData, dwData);
  153. }
  154. break;
  155. case REG_SZ:
  156. case REG_EXPAND_SZ:
  157. printf("%S", rgpbValueData[i]);
  158. break;
  159. default:
  160. printf("UNEXPECTED VALUE TYPE");
  161. }
  162. if (REG_SZ != dwType)
  163. printf(" (%s)", FromRegType(dwType));
  164. } else
  165. printf("EMPTY");
  166. printf("\n");
  167. }
  168. }
  169. return fResult;
  170. }
  171. static BOOL WINAPI EnumInfoCallback(
  172. IN PCCRYPT_OID_INFO pInfo,
  173. IN void *pvArg
  174. )
  175. {
  176. BOOL fResult = TRUE;
  177. DWORD cExtra;
  178. DWORD *pdwExtra;
  179. DWORD i;
  180. if (NULL == pvArg || 0 != strcmp(ENUM_ARG, (LPCSTR) pvArg)) {
  181. fResult = FALSE;
  182. printf("CryptEnumOIDInfo failed: invalid pvArg passed to callback\n");
  183. }
  184. printf(" Group: %d OID: %s Name: %S Algid: 0x%x",
  185. pInfo->dwGroupId, pInfo->pszOID, pInfo->pwszName, pInfo->Algid);
  186. cExtra = pInfo->ExtraInfo.cbData / sizeof(DWORD);
  187. pdwExtra = (DWORD *) pInfo->ExtraInfo.pbData;
  188. for (i = 0; i < cExtra; i++)
  189. printf(" Extra[%d]: %d (0x%x)", i, pdwExtra[i], pdwExtra[i]);
  190. printf("\n");
  191. return fResult;
  192. }
  193. int _cdecl main(int argc, char * argv[])
  194. {
  195. int status;
  196. LPSTR pszTestName = NULL;
  197. LPSTR pszOID = NULL;
  198. LPSTR pszFuncName = NULL;
  199. LPSTR pszOverrideFuncName = NULL;
  200. DWORD dwEncodingType = X509_ASN_ENCODING;
  201. BOOL fEncodingType = FALSE;
  202. LPWSTR pwszDllFile = NULL;
  203. DWORD dwDllIndex = CRYPT_REGISTER_LAST_INDEX;
  204. DWORD dwGroupId = 0;
  205. #define MAX_VALUE_COUNT 16
  206. DWORD cValue = 0;
  207. DWORD rgdwValueType[MAX_VALUE_COUNT];
  208. LPWSTR rgpwszValueName[MAX_VALUE_COUNT];
  209. BYTE *rgpbValueData[MAX_VALUE_COUNT];
  210. DWORD rgcbValueData[MAX_VALUE_COUNT];
  211. DWORD rgdwValueData[MAX_VALUE_COUNT];
  212. DWORD RegType;
  213. DWORD i;
  214. while (--argc>0) {
  215. if (**++argv == '-')
  216. {
  217. switch(argv[0][1])
  218. {
  219. case 'o':
  220. pszOID = argv[0]+2;
  221. break;
  222. case 'O':
  223. {
  224. DWORD dwOID = strtoul(argv[0]+2, NULL, 0);
  225. if (dwOID == 0 || dwOID > 0xFFFF) {
  226. printf(
  227. "Option (-O) : OID constant (%d,0x%x) out of range\n",
  228. dwOID, dwOID);
  229. goto BadUsage;
  230. }
  231. pszOID = (LPSTR)(ULONG_PTR) dwOID;
  232. }
  233. break;
  234. case 'f':
  235. pszFuncName = argv[0]+2;
  236. break;
  237. case 'F':
  238. pszOverrideFuncName = argv[0]+2;
  239. break;
  240. case 'e':
  241. dwEncodingType = strtoul(argv[0]+2, NULL, 0);
  242. fEncodingType = TRUE;
  243. break;
  244. case 'i':
  245. dwDllIndex = strtoul(argv[0]+2, NULL, 0);
  246. break;
  247. case 'd':
  248. pwszDllFile = AllocAndSzToWsz(argv[0]+2);
  249. break;
  250. case 'v':
  251. if (argc < 3 || argv[1][0] == '-' || argv[2][0] == '-') {
  252. printf("Option (-v) : missing name and data arguments\n");
  253. goto BadUsage;
  254. }
  255. if (cValue >= MAX_VALUE_COUNT) {
  256. printf("Exceeded maximum value count of %d\n",
  257. MAX_VALUE_COUNT);
  258. goto BadUsage;
  259. }
  260. if (REG_NONE == (RegType = ToRegType("-v", argv[0] + 2)))
  261. goto BadUsage;
  262. rgdwValueType[cValue] = RegType;
  263. rgpwszValueName[cValue] = AllocAndSzToWsz(argv[1]);
  264. if (REG_DWORD == RegType) {
  265. rgdwValueData[cValue] = strtoul(argv[2], NULL, 0);
  266. rgpbValueData[cValue] =
  267. (BYTE *) &rgdwValueData[cValue];
  268. rgcbValueData[cValue] = sizeof(DWORD);
  269. } else {
  270. LPWSTR pwsz = AllocAndSzToWsz(argv[2]);
  271. if (pwsz) {
  272. rgpbValueData[cValue] = (BYTE *) pwsz;
  273. rgcbValueData[cValue] =
  274. (wcslen(pwsz) + 1) * sizeof(WCHAR);
  275. } else {
  276. rgpbValueData[cValue] = NULL;
  277. rgcbValueData[cValue] = 0;
  278. }
  279. }
  280. cValue++;
  281. argc -= 2;
  282. argv += 2;
  283. break;
  284. case 'G':
  285. dwGroupId = strtoul(argv[0]+2, NULL, 0);
  286. break;
  287. case 'h':
  288. default:
  289. goto BadUsage;
  290. }
  291. } else {
  292. if (pszTestName) {
  293. printf("Multiple TestNames:: %s %s\n", pszTestName, argv[0]);
  294. goto BadUsage;
  295. }
  296. pszTestName = argv[0];
  297. }
  298. }
  299. if (pszTestName == NULL) {
  300. printf("Missing TestName\n");
  301. goto BadUsage;
  302. }
  303. printf("command line: %s\n", GetCommandLine());
  304. if (0 == _stricmp("Register", pszTestName)) {
  305. if (pszOID == NULL) {
  306. printf("Register Test:: missing OID option (-o) or (-O)\n");
  307. goto BadUsage;
  308. }
  309. if (pszFuncName == NULL) {
  310. printf("Register Test:: missing function name option (-f)\n");
  311. goto BadUsage;
  312. }
  313. if ((DWORD_PTR) pszOID > 0xFFFF &&
  314. 0 == _stricmp(CRYPT_DEFAULT_OID, pszOID)) {
  315. if (pwszDllFile == NULL) {
  316. printf("Register Test:: missing dll option (-d)\n");
  317. goto BadUsage;
  318. }
  319. if (!CryptRegisterDefaultOIDFunction(
  320. dwEncodingType,
  321. pszFuncName,
  322. dwDllIndex,
  323. pwszDllFile
  324. )) {
  325. PrintLastError("CryptRegisterDefaultOIDFunction");
  326. goto ErrorReturn;
  327. }
  328. } else {
  329. if (!CryptRegisterOIDFunction(
  330. dwEncodingType,
  331. pszFuncName,
  332. pszOID,
  333. pwszDllFile,
  334. pszOverrideFuncName
  335. )) {
  336. PrintLastError("CryptRegisterOIDFunction");
  337. goto ErrorReturn;
  338. }
  339. }
  340. for (i = 0; i < cValue; i++) {
  341. if (!CryptSetOIDFunctionValue(
  342. dwEncodingType,
  343. pszFuncName,
  344. pszOID,
  345. rgpwszValueName[i],
  346. rgdwValueType[i],
  347. rgpbValueData[i],
  348. rgcbValueData[i]
  349. )) {
  350. PrintLastError("CryptSetOIDFunctionValue");
  351. goto ErrorReturn;
  352. }
  353. }
  354. printf("Successful Register\n");
  355. } else if (0 == _stricmp("Unregister", pszTestName)) {
  356. if (pszOID == NULL) {
  357. printf("Unregister test:: missing OID option (-o) or (-O)\n");
  358. goto BadUsage;
  359. }
  360. if (pszFuncName == NULL) {
  361. printf("Unregister test:: missing function name option (-f)\n");
  362. goto BadUsage;
  363. }
  364. if ((DWORD_PTR) pszOID > 0xFFFF &&
  365. 0 == _stricmp(CRYPT_DEFAULT_OID, pszOID)) {
  366. if (pwszDllFile == NULL) {
  367. printf("Unregister Test:: missing dll option (-d)\n");
  368. goto BadUsage;
  369. }
  370. if (!CryptUnregisterDefaultOIDFunction(
  371. dwEncodingType,
  372. pszFuncName,
  373. pwszDllFile
  374. )) {
  375. PrintLastError("CryptUnregisterDefaultOIDFunction");
  376. goto ErrorReturn;
  377. }
  378. } else {
  379. if (!CryptUnregisterOIDFunction(
  380. dwEncodingType,
  381. pszFuncName,
  382. pszOID
  383. )) {
  384. PrintLastError("CryptUnregisterOIDFunction");
  385. goto ErrorReturn;
  386. }
  387. }
  388. printf("Successful Unregister\n");
  389. } else if (0 == _stricmp("Enum", pszTestName)) {
  390. if (!CryptEnumOIDFunction(
  391. fEncodingType ? dwEncodingType : CRYPT_MATCH_ANY_ENCODING_TYPE,
  392. pszFuncName,
  393. pszOID,
  394. 0, // dwFlags
  395. ENUM_ARG,
  396. EnumCallback
  397. )) {
  398. PrintLastError("CryptEnumOIDFunction");
  399. goto ErrorReturn;
  400. } else
  401. printf("Successful Enum\n");
  402. } else if (0 == _stricmp("EnumInfo", pszTestName)) {
  403. if (!CryptEnumOIDInfo(
  404. dwGroupId,
  405. 0, // dwFlags
  406. ENUM_ARG,
  407. EnumInfoCallback
  408. )) {
  409. PrintLastError("CryptEnumOIDInfo");
  410. goto ErrorReturn;
  411. } else
  412. printf("Successful EnumInfo\n");
  413. } else {
  414. printf("Invalid TestName: %s\n", pszTestName);
  415. goto BadUsage;
  416. }
  417. status = 0;
  418. CommonReturn:
  419. if (pwszDllFile)
  420. TestFree(pwszDllFile);
  421. while(cValue--) {
  422. if (rgdwValueType[cValue] != REG_DWORD && rgpbValueData[cValue])
  423. TestFree(rgpbValueData[cValue]);
  424. if (rgpwszValueName[cValue])
  425. TestFree(rgpwszValueName[cValue]);
  426. }
  427. return status;
  428. BadUsage:
  429. Usage();
  430. status = 0;
  431. goto CommonReturn;
  432. ErrorReturn:
  433. printf("Failed\n");
  434. status = -1;
  435. goto CommonReturn;
  436. }