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.

431 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1996
  6. //
  7. // File: ossconv.cpp
  8. //
  9. // Contents: Conversion APIs to/from OSS ASN.1 data structures
  10. //
  11. // Functions: OssConvToObjectIdentifier
  12. // OssConvFromObjectIdentifier
  13. // OssConvToUTCTime
  14. // OssConvFromUTCTime
  15. // OssConvToGeneralizedTime
  16. // OssConvFromGeneralizedTime
  17. // OssConvToChoiceOfTime
  18. // OssConvFromChoiceOfTime
  19. // OssConvToAttribute
  20. // OssConvToAlgorithmIdentifier
  21. // OssConvFromAlgorithmIdentifier
  22. //
  23. //
  24. // Notes: According to the <draft-ietf-pkix-ipki-part1-04.txt> :
  25. // For UTCTime. Where YY is greater than 50, the year shall
  26. // be interpreted as 19YY. Where YY is less than or equal to
  27. // 50, the year shall be interpreted as 20YY.
  28. //
  29. // History: 28-Mar-96 philh created
  30. // 03-May-96 kevinr merged from wincrmsg
  31. //
  32. //--------------------------------------------------------------------------
  33. #include "global.hxx"
  34. #include <dbgdef.h>
  35. #include "badstrfunctions.h"
  36. ////////////////////////////////////////////////////////////////////////////////
  37. ///////////////////////////////////////////////////////////////////////////////
  38. // These are the old 4.0 versions of these routines.
  39. #define atol StrToInt
  40. char * __cdecl _ltoa(long l, char * psz, int) {wnsprintf(psz, 10, "%d", l); return psz; }
  41. /////////////////////////////////////////////////////////////////////////////////
  42. /////////////////////////////////////////////////////////////////////////////////
  43. //
  44. // UTCTime in X.509 certs are represented using a 2-digit year
  45. // field (yuk! but true).
  46. //
  47. // According to IETF draft, YY years greater than this are
  48. // to be interpreted as 19YY; YY years less than this are 20YY. Sigh.
  49. //
  50. #define MAGICYEAR 50
  51. #define YEARFIRST 1951
  52. #define YEARLAST 2050
  53. #define YEARFIRSTGENERALIZED 2050
  54. inline BOOL my_isdigit( char ch)
  55. {
  56. return (ch >= '0') && (ch <= '9');
  57. }
  58. //+-------------------------------------------------------------------------
  59. // Convert the ascii string ("1.2.9999") to OSS's Object Identifier
  60. // represented as an array of unsigned longs.
  61. //
  62. // Returns TRUE for a successful conversion.
  63. //--------------------------------------------------------------------------
  64. BOOL
  65. WINAPI
  66. OssConvToObjectIdentifier(
  67. IN LPCSTR pszObjId,
  68. IN OUT unsigned short *pCount,
  69. OUT unsigned long rgulValue[]
  70. )
  71. {
  72. BOOL fResult = TRUE;
  73. unsigned short c = 0;
  74. LPSTR psz = (LPSTR) pszObjId;
  75. char ch;
  76. if (psz) {
  77. unsigned short cMax = *pCount;
  78. unsigned long *pul = rgulValue;
  79. while ((ch = *psz) != '\0' && c++ < cMax) {
  80. *pul++ = (unsigned long)atol(psz);
  81. while (my_isdigit(ch = *psz++))
  82. ;
  83. if (ch != '.')
  84. break;
  85. }
  86. if (ch != '\0')
  87. fResult = FALSE;
  88. }
  89. *pCount = c;
  90. return fResult;
  91. }
  92. //+-------------------------------------------------------------------------
  93. // Convert from OSS's Object Identifier represented as an array of
  94. // unsigned longs to an ascii string ("1.2.9999").
  95. //
  96. // Returns TRUE for a successful conversion
  97. //--------------------------------------------------------------------------
  98. BOOL
  99. WINAPI
  100. OssConvFromObjectIdentifier(
  101. IN unsigned short Count,
  102. IN unsigned long rgulValue[],
  103. OUT LPSTR pszObjId,
  104. IN OUT DWORD *pcbObjId
  105. )
  106. {
  107. BOOL fResult = TRUE;
  108. LONG lRemain;
  109. if (pszObjId == NULL)
  110. *pcbObjId = 0;
  111. lRemain = (LONG) *pcbObjId;
  112. if (Count == 0) {
  113. if (--lRemain > 0)
  114. pszObjId++;
  115. } else {
  116. char rgch[36];
  117. LONG lData;
  118. unsigned long *pul = rgulValue;
  119. for (; Count > 0; Count--, pul++) {
  120. _ltoa(*pul, rgch, 10);
  121. lData = strlen(rgch);
  122. lRemain -= lData + 1;
  123. if (lRemain >= 0) {
  124. if (lData > 0) {
  125. memcpy(pszObjId, rgch, lData);
  126. pszObjId += lData;
  127. }
  128. *pszObjId++ = '.';
  129. }
  130. }
  131. }
  132. if (lRemain >= 0) {
  133. *(pszObjId -1) = '\0';
  134. *pcbObjId = *pcbObjId - (DWORD) lRemain;
  135. } else {
  136. *pcbObjId = *pcbObjId + (DWORD) -lRemain;
  137. if (pszObjId) {
  138. SetLastError((DWORD) ERROR_MORE_DATA);
  139. fResult = FALSE;
  140. }
  141. }
  142. return fResult;
  143. }
  144. //+-------------------------------------------------------------------------
  145. // Adjust FILETIME for timezone.
  146. //
  147. // Returns FALSE iff conversion failed.
  148. //--------------------------------------------------------------------------
  149. static BOOL AdjustFileTime(
  150. IN OUT LPFILETIME pFileTime,
  151. IN short mindiff,
  152. IN ossBoolean utc
  153. )
  154. {
  155. if (utc || mindiff == 0)
  156. return TRUE;
  157. BOOL fResult;
  158. SYSTEMTIME stmDiff;
  159. FILETIME ftmDiff;
  160. short absmindiff;
  161. memset(&stmDiff, 0, sizeof(stmDiff));
  162. // Note: FILETIME is 100 nanoseconds interval since January 1, 1601
  163. stmDiff.wYear = 1601;
  164. stmDiff.wMonth = 1;
  165. stmDiff.wDay = 1;
  166. absmindiff = mindiff > 0 ? mindiff : -mindiff;
  167. stmDiff.wHour = absmindiff / 60;
  168. stmDiff.wMinute = absmindiff % 60;
  169. if (stmDiff.wHour >= 24) {
  170. stmDiff.wDay += stmDiff.wHour / 24;
  171. stmDiff.wHour %= 24;
  172. }
  173. if ((fResult = SystemTimeToFileTime(&stmDiff, &ftmDiff))) {
  174. if (mindiff > 0)
  175. *((_int64 *) pFileTime) += *((_int64 *) &ftmDiff);
  176. else
  177. *((_int64 *) pFileTime) -= *((_int64 *) &ftmDiff);
  178. }
  179. return fResult;
  180. }
  181. //+-------------------------------------------------------------------------
  182. // Convert FILETIME to OSS's UTCTime.
  183. //
  184. // Returns TRUE for a successful conversion
  185. //--------------------------------------------------------------------------
  186. BOOL
  187. WINAPI
  188. OssConvToUTCTime(
  189. IN LPFILETIME pFileTime,
  190. OUT UTCTime *pOssTime
  191. )
  192. {
  193. BOOL fRet;
  194. SYSTEMTIME t;
  195. memset(pOssTime, 0, sizeof(*pOssTime));
  196. if (!FileTimeToSystemTime(pFileTime, &t))
  197. goto FileTimeToSystemTimeError;
  198. if (t.wYear < YEARFIRST || t.wYear > YEARLAST)
  199. goto YearRangeError;
  200. pOssTime->year = t.wYear % 100;
  201. pOssTime->month = t.wMonth;
  202. pOssTime->day = t.wDay;
  203. pOssTime->hour = t.wHour;
  204. pOssTime->minute = t.wMinute;
  205. pOssTime->second = t.wSecond;
  206. pOssTime->utc = TRUE;
  207. fRet = TRUE;
  208. CommonReturn:
  209. return fRet;
  210. ErrorReturn:
  211. fRet = FALSE;
  212. goto CommonReturn;
  213. TRACE_ERROR(FileTimeToSystemTimeError)
  214. TRACE_ERROR(YearRangeError)
  215. }
  216. //+-------------------------------------------------------------------------
  217. // Convert from OSS's UTCTime to FILETIME.
  218. //
  219. // Returns TRUE for a successful conversion
  220. //--------------------------------------------------------------------------
  221. BOOL
  222. WINAPI
  223. OssConvFromUTCTime(
  224. IN UTCTime *pOssTime,
  225. OUT LPFILETIME pFileTime
  226. )
  227. {
  228. BOOL fRet;
  229. SYSTEMTIME t;
  230. memset(&t, 0, sizeof(t));
  231. t.wYear = pOssTime->year > MAGICYEAR ?
  232. (1900 + pOssTime->year) : (2000 + pOssTime->year);
  233. t.wMonth = pOssTime->month;
  234. t.wDay = pOssTime->day;
  235. t.wHour = pOssTime->hour;
  236. t.wMinute = pOssTime->minute;
  237. t.wSecond = pOssTime->second;
  238. if (!SystemTimeToFileTime(&t, pFileTime))
  239. goto SystemTimeToFileTimeError;
  240. fRet = AdjustFileTime(
  241. pFileTime,
  242. pOssTime->mindiff,
  243. pOssTime->utc
  244. );
  245. CommonReturn:
  246. return fRet;
  247. ErrorReturn:
  248. fRet = FALSE;
  249. goto CommonReturn;
  250. TRACE_ERROR(SystemTimeToFileTimeError)
  251. }
  252. //+-------------------------------------------------------------------------
  253. // Convert FILETIME to OSS's GeneralizedTime.
  254. //
  255. // Returns TRUE for a successful conversion
  256. //--------------------------------------------------------------------------
  257. BOOL
  258. WINAPI
  259. OssConvToGeneralizedTime(
  260. IN LPFILETIME pFileTime,
  261. OUT GeneralizedTime *pOssTime
  262. )
  263. {
  264. BOOL fRet;
  265. SYSTEMTIME t;
  266. memset(pOssTime, 0, sizeof(*pOssTime));
  267. if (!FileTimeToSystemTime(pFileTime, &t))
  268. goto FileTimeToSystemTimeError;
  269. pOssTime->year = t.wYear;
  270. pOssTime->month = t.wMonth;
  271. pOssTime->day = t.wDay;
  272. pOssTime->hour = t.wHour;
  273. pOssTime->minute = t.wMinute;
  274. pOssTime->second = t.wSecond;
  275. pOssTime->millisec = t.wMilliseconds;
  276. pOssTime->utc = TRUE;
  277. fRet = TRUE;
  278. CommonReturn:
  279. return fRet;
  280. ErrorReturn:
  281. fRet = FALSE;
  282. goto CommonReturn;
  283. TRACE_ERROR(FileTimeToSystemTimeError)
  284. }
  285. //+-------------------------------------------------------------------------
  286. // Convert from OSS's GeneralizedTime to FILETIME.
  287. //
  288. // Returns TRUE for a successful conversion
  289. //--------------------------------------------------------------------------
  290. BOOL
  291. WINAPI
  292. OssConvFromGeneralizedTime(
  293. IN GeneralizedTime *pOssTime,
  294. OUT LPFILETIME pFileTime
  295. )
  296. {
  297. BOOL fRet;
  298. SYSTEMTIME t;
  299. memset(&t, 0, sizeof(t));
  300. t.wYear = pOssTime->year;
  301. t.wMonth = pOssTime->month;
  302. t.wDay = pOssTime->day;
  303. t.wHour = pOssTime->hour;
  304. t.wMinute = pOssTime->minute;
  305. t.wSecond = pOssTime->second;
  306. t.wMilliseconds = pOssTime->millisec;
  307. if (!SystemTimeToFileTime(&t, pFileTime))
  308. goto SystemTimeToFileTimeError;
  309. fRet = AdjustFileTime(
  310. pFileTime,
  311. pOssTime->mindiff,
  312. pOssTime->utc
  313. );
  314. CommonReturn:
  315. return fRet;
  316. ErrorReturn:
  317. fRet = FALSE;
  318. goto CommonReturn;
  319. TRACE_ERROR(SystemTimeToFileTimeError)
  320. }
  321. //+-------------------------------------------------------------------------
  322. // Convert FILETIME to OSS's UTCTime or GeneralizedTime.
  323. //
  324. // If 1950 < FILETIME < 2005, then UTCTime is chosen. Otherwise,
  325. // GeneralizedTime is chosen. GeneralizedTime values shall not include
  326. // fractional seconds.
  327. //
  328. // Returns TRUE for a successful conversion
  329. //
  330. // Note, in asn1hdr.h, UTCTime has same typedef as GeneralizedTime.
  331. //--------------------------------------------------------------------------
  332. BOOL
  333. WINAPI
  334. OssConvToChoiceOfTime(
  335. IN LPFILETIME pFileTime,
  336. OUT WORD *pwChoice,
  337. OUT GeneralizedTime *pOssTime
  338. )
  339. {
  340. BOOL fRet;
  341. SYSTEMTIME t;
  342. memset(pOssTime, 0, sizeof(*pOssTime));
  343. if (!FileTimeToSystemTime(pFileTime, &t))
  344. goto FileTimeToSystemTimeError;
  345. if (t.wYear < YEARFIRST || t.wYear >= YEARFIRSTGENERALIZED) {
  346. *pwChoice = OSS_GENERALIZED_TIME_CHOICE;
  347. pOssTime->year = t.wYear;
  348. } else {
  349. *pwChoice = OSS_UTC_TIME_CHOICE;
  350. pOssTime->year = t.wYear % 100;
  351. }
  352. pOssTime->month = t.wMonth;
  353. pOssTime->day = t.wDay;
  354. pOssTime->hour = t.wHour;
  355. pOssTime->minute = t.wMinute;
  356. pOssTime->second = t.wSecond;
  357. pOssTime->utc = TRUE;
  358. fRet = TRUE;
  359. CommonReturn:
  360. return fRet;
  361. ErrorReturn:
  362. fRet = FALSE;
  363. *pwChoice = 0;
  364. goto CommonReturn;
  365. TRACE_ERROR(FileTimeToSystemTimeError)
  366. }
  367. //+-------------------------------------------------------------------------
  368. // Convert from OSS's UTCTime or GeneralizedTime to FILETIME.
  369. //
  370. // Returns TRUE for a successful conversion.
  371. //
  372. // Note, in asn1hdr.h, UTCTime has same typedef as GeneralizedTime.
  373. //--------------------------------------------------------------------------
  374. BOOL
  375. WINAPI
  376. OssConvFromChoiceOfTime(
  377. IN WORD wChoice,
  378. IN GeneralizedTime *pOssTime,
  379. OUT LPFILETIME pFileTime
  380. )
  381. {
  382. if (OSS_UTC_TIME_CHOICE == wChoice)
  383. return OssConvFromUTCTime(pOssTime, pFileTime);
  384. else
  385. return OssConvFromGeneralizedTime(pOssTime, pFileTime);
  386. }