RSA BSAFE Cert-C

Certificate Components for C

Crypto-C 6.2.1 Developer's Guide
Search

timeutil.c

Routines used for obtaining and displaying times such as validity start date.

/* $Id: timeutil.c,v 1.4 2004/03/02 05:18:38 gsingh Exp $ */
/* timeutil.c
** Copyright (c) 1999-2003, RSA Security Inc.
**
** This file is used to demonstrate how to interface to an RSA Security
** licensed development product.  You have a royalty-free right to use,
** modify, reproduce and distribute this demonstration file (including
** any modified version), provided that you agree that RSA Security has
** no warranty, implied or otherwise, or liability for this demonstration
** file or any modified version.
**
** This file contains routines used for obtaining and displaying times, such
** as the validity start date, for example.  Displays time in UTC time zone
** and input expected to be UTC, not local, time.
*/

#include "timeutil.h"

#ifdef _MSC_VER
# pragma warning (disable: 171) /* invalid type conversion (often of very similar ptrs) */
#endif

void RSA_PrintUint4Time (char *label, UINT4 time)
{
  time_t t = (time_t)time;
  struct tm *tmPtr = NULL;

  if (label != NULL)
    RSA_PrintMessage ("%s\n", label);

  tmPtr = gmtime (&t);

  if (tmPtr != NULL)
    RSA_PrintMessage ("  [UTC] %s", asctime (tmPtr));
  else {
    RSA_PrintMessage ("  Date exceeds [UTC] Tuesday January 19 ");
    RSA_PrintMessage ("03:14:07 2038\n  ");
    RSA_PrintMessage ("gmtime() in timeutil.c cannot process value\n");
  }
}  /* end RSA_PrintUint4Time */
  
int RSA_GetInputToUint4Time (UINT4 *time, char *prompt)
{
  int status = 0;

  char timeString[RSA_DEMO_MAX_LINE_LEN];
  int sec = 0, min = 0, hr = 0, date = 0, month = 0, year = 0;
  struct tm timeStruct, *tempStruct;

  time_t currentTime = 0, gmTime = 0, offset = 0, temp = 0;

  *time = 0;
  
  for (;;) {
    RSA_PrintMessage (prompt);
    RSA_PrintMessage (" (YYYY/MM/DD/hh:mm:ss, or blank for current time):\n");
    status = RSA_GetCommand (timeString, sizeof (timeString), NULL);
    if (status != 0)
      goto CLEANUP;

    if (T_strlen (timeString) == 0) {
      T_time (time);
      break;
    }
    else {
      status = sscanf (timeString, "%d/%d/%d/%d:%d:%d", &year, &month, &date,
                       &hr, &min, &sec);
      if (status < 6) {
        RSA_PrintMessage ("Invalid format for date.  Try again.\n");
        continue;
      }
      status = 0;

      month--;  /* users will give months from 1-12, but mktime expects 0-11 */
      year = year - 1900;  /* mktime expects years since 1900 */

      T_time ((UINT4 *)&currentTime);
      tempStruct = localtime (&currentTime);
      /*  Must match current local conditions  */
      timeStruct.tm_isdst = tempStruct->tm_isdst;  

      timeStruct.tm_sec = sec;
      timeStruct.tm_min = min;
      timeStruct.tm_hour = hr;
      timeStruct.tm_mday = date;
      timeStruct.tm_mon = month;
      timeStruct.tm_year = year;

      /* We are assuming that the user enters a UTC time.  Since mktime
       * converts to local time, we use offset to "undo" the unnecessary
       * conversion.
       */
      if ((*time = (UINT4)mktime (&timeStruct)) == -1)
        RSA_PrintMessage ("Error converting user input.  Perhaps the year is \
out of the range of the\ntime() function.  Try again.\n");
      else {
        temp = currentTime;  /* since gmtime seems to clobber temp... */
        gmTime = mktime (gmtime (&temp));
        offset = gmTime - currentTime;
     
        *time = *time - offset;
        break;
      }
    }
  }
  
  RSA_PrintUint4Time (NULL, *time);
  
CLEANUP:
  if (status != 0)
    RSA_PrintError ("RSA_GetInputToUint4Time", status);
  
  return status;
}  /* end RSA_GetInputToUint4Time */

int RSA_Uint4ToGeneralizedTime (GENERALIZED_TIME *genTime, UINT4 *uintTime)
{
  int status = 0;
  
  time_t time = (time_t)*uintTime;
  struct tm *timeStruct;

  timeStruct = gmtime (&time);

  genTime->year = (unsigned short)(timeStruct->tm_year + 1900);
  genTime->month = (unsigned short)(timeStruct->tm_mon + 1);
  genTime->day = (unsigned short)timeStruct->tm_mday;
  genTime->hour = (unsigned short)timeStruct->tm_hour;
  genTime->minute = (unsigned short)timeStruct->tm_min;
  genTime->second = (unsigned short)(timeStruct->tm_sec % 60);
  genTime->microSecond = 0;
  genTime->timeZone = 0;  /* we require uintTime to be UTC */
  
  return status;
}  /* end RSA_Uint4ToGeneralizedTime */

void RSA_PrintGeneralizedTime (char *label, GENERALIZED_TIME *genTime)
{
  if (label != NULL)
    RSA_PrintMessage ("%s\n", label);

  RSA_PrintMessage ("  %u %u/%u %u:%u:%u ", genTime->year, genTime->month,
                    genTime->day, genTime->hour, genTime->minute,
                    genTime->second);
  RSA_PrintMessage ("(%u microseconds) ", genTime->microSecond);

  if (genTime->timeZone == 0)
    RSA_PrintMessage ("UTC\n");
  else {
    RSA_PrintMessage ("\n  %d minutes moving westward between UTC and local");
    RSA_PrintMessage ("time\n");
  }
}  /* end RSA_PrintGeneralizedTime */

int RSA_GetInputToGeneralizedTime (GENERALIZED_TIME *genTime, char *prompt)
{
  int status = 0;
  UINT4 time = 0;

  T_memset ((POINTER)genTime, 0, sizeof (*genTime));

  status = RSA_GetInputToUint4Time (&time, prompt);
  if (status != 0)
    goto CLEANUP;

  status = RSA_Uint4ToGeneralizedTime (genTime, &time);

CLEANUP:
  if (status != 0)
    RSA_PrintError ("RSA_GetInputToGeneralizedTime", status);

  return status;
}  /* end RSA_GetInputToGeneralizedTime */

Copyright (c) 1999-2005 RSA Security Inc. All rights reserved. 067-001001-2720-001-000 - 2.7.2