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.

420 lines
8.7 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: crypt.cpp
  7. //
  8. // Contents: Cert Server wrapper routines
  9. //
  10. // History: 17-Oct-96 vich created
  11. //
  12. //---------------------------------------------------------------------------
  13. #include <pch.cpp>
  14. #pragma hdrstop
  15. #include <stdlib.h>
  16. #define CRYPT32_SP3_ONLY
  17. #ifdef CRYPT32_SP3_ONLY
  18. #ifdef __cplusplus
  19. extern "C" {
  20. #endif
  21. #include "keygen.h"
  22. #ifdef __cplusplus
  23. }
  24. #endif
  25. #include "crypttls.h"
  26. #include "ossconv.h"
  27. #include "ossutil.h"
  28. // All the *pInfo extra stuff needs to be aligned
  29. #define INFO_LEN_ALIGN(Len) (((Len) + 7) & ~7)
  30. HCRYPTOSSGLOBAL hOssGlobal;
  31. //+-------------------------------------------------------------------------
  32. // Function: GetPog
  33. //
  34. // Synopsis: Initialize thread local storage for the asn libs
  35. //
  36. // Returns: pointer to an initialized OssGlobal data structure
  37. //--------------------------------------------------------------------------
  38. __inline OssGlobal *
  39. GetPog(VOID)
  40. {
  41. return(I_CryptGetOssGlobal(hOssGlobal));
  42. }
  43. HRESULT
  44. HError(VOID)
  45. {
  46. HRESULT hr;
  47. hr = GetLastError();
  48. if (hr <= 0xffff)
  49. {
  50. hr = HRESULT_FROM_WIN32(hr);
  51. }
  52. if (!FAILED(hr))
  53. {
  54. // somebody failed a call without properly setting an error condition
  55. hr = E_UNEXPECTED;
  56. }
  57. return(hr);
  58. }
  59. VOID
  60. OssX509GetIA5ConvertedToUnicode(
  61. IN IA5STRING *pOss,
  62. IN DWORD dwFlags,
  63. OPTIONAL OUT LPWSTR *ppwsz,
  64. IN OUT BYTE **ppbExtra,
  65. IN OUT LONG *plRemainExtra)
  66. {
  67. OssUtilGetIA5StringConvertedToUnicode(
  68. pOss->length,
  69. pOss->value,
  70. dwFlags,
  71. ppwsz,
  72. ppbExtra,
  73. plRemainExtra);
  74. }
  75. VOID
  76. OssX509GetObjectId(
  77. IN ObjectID *pOss,
  78. IN DWORD dwFlags,
  79. OPTIONAL OUT CHAR **pInfo,
  80. IN OUT BYTE **ppbExtra,
  81. IN OUT LONG *plRemainExtra)
  82. {
  83. DWORD cb;
  84. DWORD cbExtra;
  85. char ach[MAX_PATH];
  86. LONG lRemainExtra;
  87. cb = sizeof(ach);
  88. if (!OssConvFromObjectIdentifier(pOss->count, pOss->value, ach, &cb))
  89. {
  90. goto error;
  91. }
  92. CSASSERT(strlen(ach) + 1 == cb);
  93. cbExtra = INFO_LEN_ALIGN(cb);
  94. lRemainExtra = *plRemainExtra;
  95. lRemainExtra -= cbExtra;
  96. if (0 <= lRemainExtra)
  97. {
  98. *pInfo = (char *) *ppbExtra;
  99. CopyMemory(*pInfo, ach, cb);
  100. *ppbExtra += cbExtra;
  101. }
  102. *plRemainExtra = lRemainExtra;
  103. error:
  104. ;
  105. }
  106. __inline VOID
  107. OssX509GetAlgorithmParameters(
  108. IN OpenType *pOss,
  109. IN DWORD dwFlags,
  110. OPTIONAL OUT CRYPT_OBJID_BLOB *pInfo,
  111. IN OUT BYTE **ppbExtra,
  112. IN OUT LONG *plRemainExtra)
  113. {
  114. OssUtilGetOctetString(
  115. pOss->length,
  116. (BYTE *) pOss->encoded,
  117. dwFlags,
  118. pInfo,
  119. ppbExtra,
  120. plRemainExtra);
  121. }
  122. VOID
  123. OssX509GetAlgorithm(
  124. IN AlgorithmIdentifier *pOss,
  125. IN DWORD dwFlags,
  126. OPTIONAL OUT CRYPT_ALGORITHM_IDENTIFIER *pInfo,
  127. IN OUT BYTE **ppbExtra,
  128. IN OUT LONG *plRemainExtra)
  129. {
  130. if (0 <= *plRemainExtra)
  131. {
  132. ZeroMemory((VOID *) pInfo, sizeof(*pInfo));
  133. }
  134. OssX509GetObjectId(
  135. &pOss->algorithm,
  136. dwFlags,
  137. &pInfo->pszObjId,
  138. ppbExtra,
  139. plRemainExtra);
  140. if (pOss->bit_mask & parameters_present)
  141. {
  142. OssX509GetAlgorithmParameters(
  143. &pOss->parameters,
  144. dwFlags,
  145. &pInfo->Parameters,
  146. ppbExtra,
  147. plRemainExtra);
  148. }
  149. }
  150. __inline VOID
  151. OssX509GetPublicKeyBlob(
  152. IN BITSTRING const *pOss,
  153. IN DWORD dwFlags,
  154. OPTIONAL OUT CRYPT_BIT_BLOB *pInfo,
  155. IN OUT BYTE **ppbExtra,
  156. IN OUT LONG *plRemainExtra)
  157. {
  158. OssUtilGetBitString(
  159. pOss->length,
  160. pOss->value,
  161. dwFlags,
  162. pInfo,
  163. ppbExtra,
  164. plRemainExtra);
  165. }
  166. VOID
  167. OssX509GetPublicKeyInfo(
  168. IN SubjectPublicKeyInfo *pOss,
  169. IN DWORD dwFlags,
  170. OPTIONAL OUT CERT_PUBLIC_KEY_INFO *pInfo,
  171. IN OUT BYTE **ppbExtra,
  172. IN OUT LONG *plRemainExtra)
  173. {
  174. OssX509GetAlgorithm(
  175. &pOss->algorithm,
  176. dwFlags,
  177. &pInfo->Algorithm,
  178. ppbExtra,
  179. plRemainExtra);
  180. OssX509GetPublicKeyBlob(
  181. &pOss->subjectPublicKey,
  182. dwFlags,
  183. &pInfo->PublicKey,
  184. ppbExtra,
  185. plRemainExtra);
  186. }
  187. //+-------------------------------------------------------------------------
  188. // Decode into an allocated, OSS formatted info structure
  189. //
  190. // Called by the OssX509*Decode() functions.
  191. //--------------------------------------------------------------------------
  192. __inline BOOL
  193. OssInfoDecodeAndAlloc(
  194. IN int pdunum,
  195. IN const BYTE *pbEncoded,
  196. IN DWORD cbEncoded,
  197. OUT VOID **ppOssInfo)
  198. {
  199. return(OssUtilDecodeAndAllocInfo(
  200. GetPog(),
  201. pdunum,
  202. pbEncoded,
  203. cbEncoded,
  204. ppOssInfo));
  205. }
  206. //+-------------------------------------------------------------------------
  207. // Free an allocated, OSS formatted info structure
  208. //
  209. // Called by the OssX509*Decode() functions.
  210. //--------------------------------------------------------------------------
  211. VOID
  212. OssInfoFree(
  213. IN int pdunum,
  214. IN VOID *pOssInfo)
  215. {
  216. if (NULL != pOssInfo)
  217. {
  218. DWORD dwErr = GetLastError();
  219. // TlsGetValue globbers LastError
  220. OssUtilFreeInfo(GetPog(), pdunum, pOssInfo);
  221. SetLastError(dwErr);
  222. }
  223. }
  224. //+-------------------------------------------------------------------------
  225. // KeyGen Info Decode (OSS X509)
  226. //--------------------------------------------------------------------------
  227. BOOL
  228. DecodeKeyGen(
  229. IN BYTE const *pbEncoded,
  230. IN DWORD cbEncoded,
  231. IN DWORD dwFlags,
  232. OUT VOID *pInfo,
  233. IN OUT DWORD *pcbInfo)
  234. {
  235. BOOL fResult = FALSE;
  236. HRESULT hr;
  237. SignedPublicKeyAndChallenge *pOssInfo = NULL;
  238. CERT_KEYGEN_REQUEST_INFO *pcgi;
  239. BYTE *pbExtra;
  240. LONG lRemainExtra;
  241. LONG lAlignExtra;
  242. if (pInfo == NULL)
  243. {
  244. *pcbInfo = 0;
  245. }
  246. if (0 == hOssGlobal)
  247. {
  248. hOssGlobal = I_CryptInstallOssGlobal(keygen, 0, NULL);
  249. if (0 == hOssGlobal)
  250. {
  251. goto error;
  252. }
  253. }
  254. if (!OssInfoDecodeAndAlloc(
  255. SignedPublicKeyAndChallenge_PDU,
  256. pbEncoded,
  257. cbEncoded,
  258. (VOID **) &pOssInfo))
  259. {
  260. hr = HError();
  261. printf("OssInfoDecodeAndAlloc returned %u (%x)\n", hr, hr);
  262. goto error;
  263. }
  264. lRemainExtra = (LONG) *pcbInfo - INFO_LEN_ALIGN(sizeof(*pcgi));
  265. pbExtra = NULL;
  266. // for lRemainExtra < 0, LENGTH_ONLY calculation
  267. if (0 <= lRemainExtra)
  268. {
  269. pcgi = (CERT_KEYGEN_REQUEST_INFO *) pInfo;
  270. // Default all optional fields to zero
  271. ZeroMemory((VOID *) pcgi, sizeof(*pcgi));
  272. pcgi->dwVersion = 1;
  273. pbExtra = (BYTE *) pcgi + INFO_LEN_ALIGN(sizeof(*pcgi));
  274. }
  275. OssX509GetPublicKeyInfo(
  276. &pOssInfo->publicKeyAndChallenge.spki,
  277. dwFlags,
  278. &pcgi->SubjectPublicKeyInfo,
  279. &pbExtra,
  280. &lRemainExtra);
  281. OssX509GetIA5ConvertedToUnicode(
  282. &pOssInfo->publicKeyAndChallenge.challenge,
  283. dwFlags,
  284. &pcgi->pwszChallengeString,
  285. &pbExtra,
  286. &lRemainExtra);
  287. if (0 <= lRemainExtra)
  288. {
  289. *pcbInfo = *pcbInfo - (DWORD) lRemainExtra;
  290. }
  291. else
  292. {
  293. *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra;
  294. if (NULL != pInfo)
  295. {
  296. SetLastError(HRESULT_FROM_WIN32(ERROR_MORE_DATA));
  297. goto error;
  298. }
  299. }
  300. fResult = TRUE;
  301. error:
  302. OssInfoFree(SignedPublicKeyAndChallenge_PDU, pOssInfo);
  303. if (!fResult)
  304. {
  305. *pcbInfo = 0;
  306. }
  307. return(fResult);
  308. }
  309. #endif
  310. BOOL
  311. myDecodeKeyGenRequest(
  312. IN BYTE const *pbRequest,
  313. IN DWORD cbRequest,
  314. OUT CERT_KEYGEN_REQUEST_INFO **ppKeyGenRequest,
  315. OUT DWORD *pcbKeyGenRequest)
  316. {
  317. BOOL fOk = FALSE;
  318. #ifdef CRYPT32_SP3_ONLY
  319. *ppKeyGenRequest = NULL;
  320. *pcbKeyGenRequest = 0;
  321. if (!DecodeKeyGen(
  322. pbRequest,
  323. cbRequest,
  324. 0, // dwFlags
  325. NULL,
  326. pcbKeyGenRequest))
  327. {
  328. goto error;
  329. }
  330. *ppKeyGenRequest = (CERT_KEYGEN_REQUEST_INFO *) LocalAlloc(LMEM_FIXED, *pcbKeyGenRequest);
  331. if (NULL == *ppKeyGenRequest)
  332. {
  333. _PrintError(E_OUTOFMEMORY, "LocalAlloc(KeyGenRequest)");
  334. SetLastError(E_OUTOFMEMORY);
  335. goto error;
  336. }
  337. if (!DecodeKeyGen(
  338. pbRequest,
  339. cbRequest,
  340. 0, // dwFlags
  341. *ppKeyGenRequest,
  342. pcbKeyGenRequest))
  343. {
  344. goto error;
  345. }
  346. #else
  347. if (!myDecodeObject(
  348. X509_ASN_ENCODING,
  349. X509_KEYGEN_REQUEST_TO_BE_SIGNED,
  350. pbRequest,
  351. cbRequest,
  352. (VOID **) ppKeyGenRequest,
  353. pcbKeyGenRequest))
  354. {
  355. err = myHLastError();
  356. _JumpError(err, error, "myDecodeObject");
  357. }
  358. #endif
  359. fOk = TRUE;
  360. error:
  361. return(fOk);
  362. }