diff options
author | djm <> | 2010-10-01 22:59:01 +0000 |
---|---|---|
committer | djm <> | 2010-10-01 22:59:01 +0000 |
commit | fe047d8b632246cb2db3234a0a4f32e5c318857b (patch) | |
tree | 939b752540947d33507b3acc48d76a8bfb7c3dc3 /src/lib/libcrypto/o_time.c | |
parent | 2ea67f4aa254b09ded62e6e14fc893bbe6381579 (diff) | |
download | openbsd-fe047d8b632246cb2db3234a0a4f32e5c318857b.tar.gz openbsd-fe047d8b632246cb2db3234a0a4f32e5c318857b.tar.bz2 openbsd-fe047d8b632246cb2db3234a0a4f32e5c318857b.zip |
resolve conflicts, fix local changes
Diffstat (limited to 'src/lib/libcrypto/o_time.c')
-rw-r--r-- | src/lib/libcrypto/o_time.c | 153 |
1 files changed, 151 insertions, 2 deletions
diff --git a/src/lib/libcrypto/o_time.c b/src/lib/libcrypto/o_time.c index e29091d650..eecbdd19f0 100644 --- a/src/lib/libcrypto/o_time.c +++ b/src/lib/libcrypto/o_time.c | |||
@@ -2,6 +2,9 @@ | |||
2 | /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL | 2 | /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL |
3 | * project 2001. | 3 | * project 2001. |
4 | */ | 4 | */ |
5 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
6 | * project 2008. | ||
7 | */ | ||
5 | /* ==================================================================== | 8 | /* ==================================================================== |
6 | * Copyright (c) 2001 The OpenSSL Project. All rights reserved. | 9 | * Copyright (c) 2001 The OpenSSL Project. All rights reserved. |
7 | * | 10 | * |
@@ -73,7 +76,7 @@ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) | |||
73 | { | 76 | { |
74 | struct tm *ts = NULL; | 77 | struct tm *ts = NULL; |
75 | 78 | ||
76 | #if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && !defined(__CYGWIN32__) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS) | 79 | #if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS) |
77 | /* should return &data, but doesn't on some systems, | 80 | /* should return &data, but doesn't on some systems, |
78 | so we don't even look at the return value */ | 81 | so we don't even look at the return value */ |
79 | gmtime_r(timer,result); | 82 | gmtime_r(timer,result); |
@@ -214,4 +217,150 @@ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) | |||
214 | } | 217 | } |
215 | #endif | 218 | #endif |
216 | return ts; | 219 | return ts; |
217 | } | 220 | } |
221 | |||
222 | /* Take a tm structure and add an offset to it. This avoids any OS issues | ||
223 | * with restricted date types and overflows which cause the year 2038 | ||
224 | * problem. | ||
225 | */ | ||
226 | |||
227 | #define SECS_PER_DAY (24 * 60 * 60) | ||
228 | |||
229 | static long date_to_julian(int y, int m, int d); | ||
230 | static void julian_to_date(long jd, int *y, int *m, int *d); | ||
231 | |||
232 | int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) | ||
233 | { | ||
234 | int offset_hms, offset_day; | ||
235 | long time_jd; | ||
236 | int time_year, time_month, time_day; | ||
237 | /* split offset into days and day seconds */ | ||
238 | offset_day = offset_sec / SECS_PER_DAY; | ||
239 | /* Avoid sign issues with % operator */ | ||
240 | offset_hms = offset_sec - (offset_day * SECS_PER_DAY); | ||
241 | offset_day += off_day; | ||
242 | /* Add current time seconds to offset */ | ||
243 | offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; | ||
244 | /* Adjust day seconds if overflow */ | ||
245 | if (offset_hms >= SECS_PER_DAY) | ||
246 | { | ||
247 | offset_day++; | ||
248 | offset_hms -= SECS_PER_DAY; | ||
249 | } | ||
250 | else if (offset_hms < 0) | ||
251 | { | ||
252 | offset_day--; | ||
253 | offset_hms += SECS_PER_DAY; | ||
254 | } | ||
255 | |||
256 | /* Convert date of time structure into a Julian day number. | ||
257 | */ | ||
258 | |||
259 | time_year = tm->tm_year + 1900; | ||
260 | time_month = tm->tm_mon + 1; | ||
261 | time_day = tm->tm_mday; | ||
262 | |||
263 | time_jd = date_to_julian(time_year, time_month, time_day); | ||
264 | |||
265 | /* Work out Julian day of new date */ | ||
266 | time_jd += offset_day; | ||
267 | |||
268 | if (time_jd < 0) | ||
269 | return 0; | ||
270 | |||
271 | /* Convert Julian day back to date */ | ||
272 | |||
273 | julian_to_date(time_jd, &time_year, &time_month, &time_day); | ||
274 | |||
275 | if (time_year < 1900 || time_year > 9999) | ||
276 | return 0; | ||
277 | |||
278 | /* Update tm structure */ | ||
279 | |||
280 | tm->tm_year = time_year - 1900; | ||
281 | tm->tm_mon = time_month - 1; | ||
282 | tm->tm_mday = time_day; | ||
283 | |||
284 | tm->tm_hour = offset_hms / 3600; | ||
285 | tm->tm_min = (offset_hms / 60) % 60; | ||
286 | tm->tm_sec = offset_hms % 60; | ||
287 | |||
288 | return 1; | ||
289 | |||
290 | } | ||
291 | |||
292 | /* Convert date to and from julian day | ||
293 | * Uses Fliegel & Van Flandern algorithm | ||
294 | */ | ||
295 | static long date_to_julian(int y, int m, int d) | ||
296 | { | ||
297 | return (1461 * (y + 4800 + (m - 14) / 12)) / 4 + | ||
298 | (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 - | ||
299 | (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + | ||
300 | d - 32075; | ||
301 | } | ||
302 | |||
303 | static void julian_to_date(long jd, int *y, int *m, int *d) | ||
304 | { | ||
305 | long L = jd + 68569; | ||
306 | long n = (4 * L) / 146097; | ||
307 | long i, j; | ||
308 | |||
309 | L = L - (146097 * n + 3) / 4; | ||
310 | i = (4000 * (L + 1)) / 1461001; | ||
311 | L = L - (1461 * i) / 4 + 31; | ||
312 | j = (80 * L) / 2447; | ||
313 | *d = L - (2447 * j) / 80; | ||
314 | L = j / 11; | ||
315 | *m = j + 2 - (12 * L); | ||
316 | *y = 100 * (n - 49) + i + L; | ||
317 | } | ||
318 | |||
319 | #ifdef OPENSSL_TIME_TEST | ||
320 | |||
321 | #include <stdio.h> | ||
322 | |||
323 | /* Time checking test code. Check times are identical for a wide range of | ||
324 | * offsets. This should be run on a machine with 64 bit time_t or it will | ||
325 | * trigger the very errors the routines fix. | ||
326 | */ | ||
327 | |||
328 | int main(int argc, char **argv) | ||
329 | { | ||
330 | long offset; | ||
331 | for (offset = 0; offset < 1000000; offset++) | ||
332 | { | ||
333 | check_time(offset); | ||
334 | check_time(-offset); | ||
335 | check_time(offset * 1000); | ||
336 | check_time(-offset * 1000); | ||
337 | } | ||
338 | } | ||
339 | |||
340 | int check_time(long offset) | ||
341 | { | ||
342 | struct tm tm1, tm2; | ||
343 | time_t t1, t2; | ||
344 | time(&t1); | ||
345 | t2 = t1 + offset; | ||
346 | OPENSSL_gmtime(&t2, &tm2); | ||
347 | OPENSSL_gmtime(&t1, &tm1); | ||
348 | OPENSSL_gmtime_adj(&tm1, 0, offset); | ||
349 | if ((tm1.tm_year == tm2.tm_year) && | ||
350 | (tm1.tm_mon == tm2.tm_mon) && | ||
351 | (tm1.tm_mday == tm2.tm_mday) && | ||
352 | (tm1.tm_hour == tm2.tm_hour) && | ||
353 | (tm1.tm_min == tm2.tm_min) && | ||
354 | (tm1.tm_sec == tm2.tm_sec)) | ||
355 | return 1; | ||
356 | fprintf(stderr, "TIME ERROR!!\n"); | ||
357 | fprintf(stderr, "Time1: %d/%d/%d, %d:%02d:%02d\n", | ||
358 | tm2.tm_mday, tm2.tm_mon + 1, tm2.tm_year + 1900, | ||
359 | tm2.tm_hour, tm2.tm_min, tm2.tm_sec); | ||
360 | fprintf(stderr, "Time2: %d/%d/%d, %d:%02d:%02d\n", | ||
361 | tm1.tm_mday, tm1.tm_mon + 1, tm1.tm_year + 1900, | ||
362 | tm1.tm_hour, tm1.tm_min, tm1.tm_sec); | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | #endif | ||