Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
secder.h File Reference
#include <time.h>
#include "plarena.h"
#include "prlong.h"
#include "seccomon.h"
#include "secdert.h"
#include "prtime.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define CERT_GeneralizedTime2FormattedAscii   CERT_UTCTime2FormattedAscii

Functions

SEC_BEGIN_PROTOS SECStatus DER_Encode (PRArenaPool *arena, SECItem *dest, DERTemplate *t, void *src)
SECStatus DER_Lengths (SECItem *item, int *header_len_p, uint32 *contents_len_p)
unsigned char * DER_StoreHeader (unsigned char *to, unsigned int code, uint32 encodingLen)
int DER_LengthLength (uint32 len)
SECStatus DER_SetInteger (PRArenaPool *arena, SECItem *dst, int32 src)
SECStatus DER_SetUInteger (PRArenaPool *arena, SECItem *dst, uint32 src)
long DER_GetInteger (SECItem *src)
unsigned long DER_GetUInteger (SECItem *src)
SECStatus DER_TimeToUTCTime (SECItem *result, int64 time)
SECStatus DER_TimeToUTCTimeArena (PRArenaPool *arenaOpt, SECItem *dst, int64 gmttime)
SECStatus DER_AsciiToTime (int64 *result, const char *string)
SECStatus DER_UTCTimeToTime (int64 *result, const SECItem *time)
char * DER_UTCTimeToAscii (SECItem *utcTime)
char * DER_UTCDayToAscii (SECItem *utctime)
char * DER_GeneralizedDayToAscii (SECItem *gentime)
char * DER_TimeChoiceDayToAscii (SECItem *timechoice)
SECStatus DER_TimeToGeneralizedTime (SECItem *dst, int64 gmttime)
SECStatus DER_TimeToGeneralizedTimeArena (PRArenaPool *arenaOpt, SECItem *dst, int64 gmttime)
SECStatus DER_GeneralizedTimeToTime (int64 *dst, const SECItem *time)
char * CERT_UTCTime2FormattedAscii (int64 utcTime, char *format)
char * CERT_GenTime2FormattedAscii (int64 genTime, char *format)
SECStatus DER_DecodeTimeChoice (PRTime *output, const SECItem *input)
SECStatus DER_EncodeTimeChoice (PRArenaPool *arena, SECItem *output, PRTime input)

Define Documentation

Definition at line 184 of file secder.h.


Function Documentation

char* CERT_GenTime2FormattedAscii ( int64  genTime,
char *  format 
)

Definition at line 185 of file sectime.c.

{
    PRExplodedTime printableTime; 
    char *timeString;
   
    /* Decompose time into components */
    PR_ExplodeTime(genTime, PR_GMTParameters, &printableTime);
    
    timeString = (char *)PORT_Alloc(100);

    if ( timeString ) {
        PR_FormatTime( timeString, 100, format, &printableTime );
    }
    
    return (timeString);
}

Here is the caller graph for this function:

char* CERT_UTCTime2FormattedAscii ( int64  utcTime,
char *  format 
)

Definition at line 168 of file sectime.c.

{
    PRExplodedTime printableTime; 
    char *timeString;
   
    /* Converse time to local time and decompose it into components */
    PR_ExplodeTime(utcTime, PR_LocalTimeParameters, &printableTime);
    
    timeString = (char *)PORT_Alloc(100);

    if ( timeString ) {
        PR_FormatTime( timeString, 100, format, &printableTime );
    }
    
    return (timeString);
}

Here is the caller graph for this function:

SECStatus DER_AsciiToTime ( int64 result,
const char *  string 
)

Definition at line 145 of file dertime.c.

{
    long year, month, mday, hour, minute, second, hourOff, minOff, days;
    int64 result, tmp1, tmp2;

    if (string == NULL) {
       goto loser;
    }
    
    /* Verify time is formatted properly and capture information */
    second = 0;
    hourOff = 0;
    minOff = 0;
    CAPTURE(year,string+0,loser);
    if (year < 50) {
       /* ASSUME that year # is in the 2000's, not the 1900's */
       year += 100;
    }
    CAPTURE(month,string+2,loser);
    if ((month == 0) || (month > 12)) goto loser;
    CAPTURE(mday,string+4,loser);
    if ((mday == 0) || (mday > 31)) goto loser;
    CAPTURE(hour,string+6,loser);
    if (hour > 23) goto loser;
    CAPTURE(minute,string+8,loser);
    if (minute > 59) goto loser;
    if (ISDIGIT(string[10])) {
       CAPTURE(second,string+10,loser);
       if (second > 59) goto loser;
       string += 2;
    }
    if (string[10] == '+') {
       CAPTURE(hourOff,string+11,loser);
       if (hourOff > 23) goto loser;
       CAPTURE(minOff,string+13,loser);
       if (minOff > 59) goto loser;
    } else if (string[10] == '-') {
       CAPTURE(hourOff,string+11,loser);
       if (hourOff > 23) goto loser;
       hourOff = -hourOff;
       CAPTURE(minOff,string+13,loser);
       if (minOff > 59) goto loser;
       minOff = -minOff;
    } else if (string[10] != 'Z') {
       goto loser;
    }
    
    
    /* Convert pieces back into a single value year  */
    LL_I2L(tmp1, (year-70L));
    LL_I2L(tmp2, SECYEAR);
    LL_MUL(result, tmp1, tmp2);
    
    LL_I2L(tmp1, ( (mday-1L)*SECDAY + hour*SECHOUR + minute*SECMIN -
                hourOff*SECHOUR - minOff*SECMIN + second ) );
    LL_ADD(result, result, tmp1);

    /*
    ** Have to specially handle the day in the month and the year, to
    ** take into account leap days. The return time value is in
    ** seconds since January 1st, 12:00am 1970, so start examining
    ** the time after that. We can't represent a time before that.
    */

    /* Using two digit years, we can only represent dates from 1970
       to 2069. As a result, we cannot run into the leap year rule
       that states that 1700, 2100, etc. are not leap years (but 2000
       is). In other words, there are no years in the span of time
       that we can represent that are == 0 mod 4 but are not leap
       years. Whew.
       */

    days = monthToDayInYear[month-1];
    days += (year - 68)/4;

    if (((year % 4) == 0) && (month < 3)) {
       days--;
    }
   
    LL_I2L(tmp1, (days * SECDAY) );
    LL_ADD(result, result, tmp1 );

    /* convert to micro seconds */
    LL_I2L(tmp1, PR_USEC_PER_SEC);
    LL_MUL(result, result, tmp1);

    *dst = result;
    return SECSuccess;

  loser:
    PORT_SetError(SEC_ERROR_INVALID_TIME);
    return SECFailure;
       
}
SECStatus DER_DecodeTimeChoice ( PRTime output,
const SECItem *  input 
)

Definition at line 238 of file sectime.c.

{
    switch (input->type) {
        case siGeneralizedTime:
            return DER_GeneralizedTimeToTime(output, input);

        case siUTCTime:
            return DER_UTCTimeToTime(output, input);

        default:
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            PORT_Assert(0);
            return SECFailure;
    }
}

Here is the caller graph for this function:

SEC_BEGIN_PROTOS SECStatus DER_Encode ( PRArenaPool arena,
SECItem *  dest,
DERTemplate *  t,
void src 
)

Definition at line 475 of file derenc.c.

{
    unsigned int contents_len, header_len;

    src = (void **)((char *)src + dtemplate->offset);

    /*
     * First figure out how long the encoding will be. Do this by
     * traversing the template from top to bottom and accumulating
     * the length of each leaf item.
     */
    contents_len = contents_length (dtemplate, src);
    header_len = header_length (dtemplate, contents_len);

    dest->len = contents_len + header_len;

    /* Allocate storage to hold the encoding */
    dest->data = (unsigned char*) PORT_ArenaAlloc(arena, dest->len);
    if (dest->data == NULL) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return SECFailure;
    }

    /* Now encode into the buffer */
    (void) der_encode (dest->data, dtemplate, src);

    return SECSuccess;
}
SECStatus DER_EncodeTimeChoice ( PRArenaPool arena,
SECItem *  output,
PRTime  input 
)

Definition at line 257 of file sectime.c.

{
    if (LL_CMP(input, >, January1st2050)) {
        return DER_TimeToGeneralizedTimeArena(arena, output, input);
    } else {
        return DER_TimeToUTCTimeArena(arena, output, input);
    }
}

Here is the caller graph for this function:

char* DER_GeneralizedDayToAscii ( SECItem *  gentime)

Definition at line 85 of file sectime.c.

{
    return (DecodeGeneralizedTime2FormattedAscii (gentime, "%a %b %d, %Y"));
}

Here is the caller graph for this function:

SECStatus DER_GeneralizedTimeToTime ( int64 dst,
const SECItem *  time 
)

Definition at line 330 of file dertime.c.

{
    PRExplodedTime genTime;
    const char *string;
    long hourOff, minOff;
    uint16 century;
    char localBuf[20];

    /* Minimum valid GeneralizedTime is ccyymmddhhmmZ       which is 13 bytes.
    ** Maximum valid GeneralizedTime is ccyymmddhhmmss+0000 which is 19 bytes.
    ** 20 should be large enough for all valid encoded times. 
    */
    if (!time || !time->data || time->len < 13)
        goto loser;
    if (time->len >= sizeof localBuf) {
        string = (const char *)time->data;
    } else {
       memset(localBuf, 0, sizeof localBuf);
        memcpy(localBuf, time->data, time->len);
       string = (const char *)localBuf;
    }

    memset(&genTime, 0, sizeof genTime);

    /* Verify time is formatted properly and capture information */
    hourOff = 0;
    minOff = 0;

    CAPTURE(century, string+0, loser);
    century *= 100;
    CAPTURE(genTime.tm_year,string+2,loser);
    genTime.tm_year += century;

    CAPTURE(genTime.tm_month,string+4,loser);
    if ((genTime.tm_month == 0) || (genTime.tm_month > 12)) goto loser;

    /* NSPR month base is 0 */
    --genTime.tm_month;
    
    CAPTURE(genTime.tm_mday,string+6,loser);
    if ((genTime.tm_mday == 0) || (genTime.tm_mday > 31)) goto loser;
    
    CAPTURE(genTime.tm_hour,string+8,loser);
    if (genTime.tm_hour > 23) goto loser;
    
    CAPTURE(genTime.tm_min,string+10,loser);
    if (genTime.tm_min > 59) goto loser;
    
    if (ISDIGIT(string[12])) {
       CAPTURE(genTime.tm_sec,string+12,loser);
       if (genTime.tm_sec > 59) goto loser;
       string += 2;
    }
    if (string[12] == '+') {
       CAPTURE(hourOff,string+13,loser);
       if (hourOff > 23) goto loser;
       CAPTURE(minOff,string+15,loser);
       if (minOff > 59) goto loser;
    } else if (string[12] == '-') {
       CAPTURE(hourOff,string+13,loser);
       if (hourOff > 23) goto loser;
       hourOff = -hourOff;
       CAPTURE(minOff,string+15,loser);
       if (minOff > 59) goto loser;
       minOff = -minOff;
    } else if (string[12] != 'Z') {
       goto loser;
    }

    /* Since the values of hourOff and minOff are small, there will
       be no loss of data by the conversion to int8 */
    /* Convert the GMT offset to seconds and save it it genTime
       for the implode time process */
    genTime.tm_params.tp_gmt_offset = (PRInt32)((hourOff * 60L + minOff) * 60L);
    *dst = PR_ImplodeTime (&genTime);
    return SECSuccess;

  loser:
    PORT_SetError(SEC_ERROR_INVALID_TIME);
    return SECFailure;
       
}
long DER_GetInteger ( SECItem *  src)

Definition at line 211 of file dersubr.c.

{
    long ival = 0;
    unsigned len = it->len;
    unsigned char *cp = it->data;
    unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1);
    unsigned long ofloinit;

    if (*cp & 0x80)
       ival = -1L;
    ofloinit = ival & overflow;

    while (len) {
       if ((ival & overflow) != ofloinit) {
           PORT_SetError(SEC_ERROR_BAD_DER);
           if (ival < 0) {
              return LONG_MIN;
           }
           return LONG_MAX;
       }
       ival = ival << 8;
       ival |= *cp++;
       --len;
    }
    return ival;
}
unsigned long DER_GetUInteger ( SECItem *  src)

Definition at line 243 of file dersubr.c.

{
    unsigned long ival = 0;
    unsigned len = it->len;
    unsigned char *cp = it->data;
    unsigned long overflow = 0xffUL << ((sizeof(ival) - 1) * 8);

    /* Cannot put a negative value into an unsigned container. */
    if (*cp & 0x80) {
       PORT_SetError(SEC_ERROR_BAD_DER);
       return 0;
    }

    while (len) {
       if (ival & overflow) {
           PORT_SetError(SEC_ERROR_BAD_DER);
           return ULONG_MAX;
       }
       ival = ival << 8;
       ival |= *cp++;
       --len;
    }
    return ival;
}

Definition at line 42 of file dersubr.c.

{
    if (len > 127) {
       if (len > 255) {
           if (len > 65535L) {
              if (len > 16777215L) {
                  return 5;
              } else {
                  return 4;
              }
           } else {
              return 3;
           }
       } else {
           return 2;
       }
    } else {
       return 1;
    }
}
SECStatus DER_Lengths ( SECItem *  item,
int header_len_p,
uint32 contents_len_p 
)

Definition at line 217 of file derdec.c.

{
    return(der_capture(item->data, &item->data[item->len], header_len_p,
                     contents_len_p));
}
SECStatus DER_SetInteger ( PRArenaPool arena,
SECItem *  dst,
int32  src 
)

Definition at line 111 of file dersubr.c.

{
    unsigned char bb[4];
    unsigned len;

    bb[0] = (unsigned char) (i >> 24);
    bb[1] = (unsigned char) (i >> 16);
    bb[2] = (unsigned char) (i >> 8);
    bb[3] = (unsigned char) (i);

    /*
    ** Small integers are encoded in a single byte. Larger integers
    ** require progressively more space.
    */
    if (i < -128) {
       if (i < -32768L) {
           if (i < -8388608L) {
              len = 4;
           } else {
              len = 3;
           }
       } else {
           len = 2;
       }
    } else if (i > 127) {
       if (i > 32767L) {
           if (i > 8388607L) {
              len = 4;
           } else {
              len = 3;
           }
       } else {
           len = 2;
       }
    } else {
       len = 1;
    }
    it->data = (unsigned char*) PORT_ArenaAlloc(arena, len);
    if (!it->data) {
       return SECFailure;
    }
    it->len = len;
    PORT_Memcpy(it->data, bb + (4 - len), len);
    return SECSuccess;
}
SECStatus DER_SetUInteger ( PRArenaPool arena,
SECItem *  dst,
uint32  src 
)

Definition at line 162 of file dersubr.c.

{
    unsigned char bb[5];
    int len;

    bb[0] = 0;
    bb[1] = (unsigned char) (ui >> 24);
    bb[2] = (unsigned char) (ui >> 16);
    bb[3] = (unsigned char) (ui >> 8);
    bb[4] = (unsigned char) (ui);

    /*
    ** Small integers are encoded in a single byte. Larger integers
    ** require progressively more space.
    */
    if (ui > 0x7f) {
       if (ui > 0x7fff) {
           if (ui > 0x7fffffL) {
              if (ui >= 0x80000000L) {
                  len = 5;
              } else {
                  len = 4;
              }
           } else {
              len = 3;
           }
       } else {
           len = 2;
       }
    } else {
       len = 1;
    }

    it->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
    if (it->data == NULL) {
       return SECFailure;
    }

    it->len = len;
    PORT_Memcpy(it->data, bb + (sizeof(bb) - len), len);

    return SECSuccess;
}
unsigned char* DER_StoreHeader ( unsigned char *  to,
unsigned int  code,
uint32  encodingLen 
)

Definition at line 64 of file dersubr.c.

{
    unsigned char b[4];

    b[0] = (unsigned char)(len >> 24);
    b[1] = (unsigned char)(len >> 16);
    b[2] = (unsigned char)(len >> 8);
    b[3] = (unsigned char)len;
    if ((code & DER_TAGNUM_MASK) == DER_SET
       || (code & DER_TAGNUM_MASK) == DER_SEQUENCE)
       code |= DER_CONSTRUCTED;
    *buf++ = code;
    if (len > 127) {
       if (len > 255) {
           if (len > 65535) {
              if (len > 16777215) {
                  *buf++ = 0x84;
                  *buf++ = b[0];
                  *buf++ = b[1];
                  *buf++ = b[2];
                  *buf++ = b[3];
              } else {
                  *buf++ = 0x83;
                  *buf++ = b[1];
                  *buf++ = b[2];
                  *buf++ = b[3];
              }
           } else {
              *buf++ = 0x82;
              *buf++ = b[2];
              *buf++ = b[3];
           }
       } else {
           *buf++ = 0x81;
           *buf++ = b[3];
       }
    } else {
       *buf++ = b[3];
    }
    return buf;
}
char* DER_TimeChoiceDayToAscii ( SECItem *  timechoice)

Definition at line 93 of file sectime.c.

{
    switch (timechoice->type) {

    case siUTCTime:
        return DER_UTCDayToAscii(timechoice);

    case siGeneralizedTime:
        return DER_GeneralizedDayToAscii(timechoice);

    default:
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
}

Here is the caller graph for this function:

SECStatus DER_TimeToGeneralizedTime ( SECItem *  dst,
int64  gmttime 
)

Definition at line 318 of file dertime.c.

{
    return DER_TimeToGeneralizedTimeArena(NULL, dst, gmttime);
}
SECStatus DER_TimeToGeneralizedTimeArena ( PRArenaPool arenaOpt,
SECItem *  dst,
int64  gmttime 
)

Definition at line 273 of file dertime.c.

{
    PRExplodedTime printableTime;
    unsigned char *d;

    if ( (gmttime<January1st1) || (gmttime>=January1st10000) ) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    dst->len = 15;
    if (arenaOpt) {
        dst->data = d = (unsigned char*) PORT_ArenaAlloc(arenaOpt, dst->len);
    } else {
        dst->data = d = (unsigned char*) PORT_Alloc(dst->len);
    }
    dst->type = siGeneralizedTime;
    if (!d) {
       return SECFailure;
    }

    /* Convert an int64 time to a printable format.  */
    PR_ExplodeTime(gmttime, PR_GMTParameters, &printableTime);

    /* The month in Generalized time is base one */
    printableTime.tm_month++;

    d[0] = (printableTime.tm_year /1000) + '0';
    d[1] = ((printableTime.tm_year % 1000) / 100) + '0';
    d[2] = ((printableTime.tm_year % 100) / 10) + '0';
    d[3] = (printableTime.tm_year % 10) + '0';
    d[4] = HIDIGIT(printableTime.tm_month);
    d[5] = LODIGIT(printableTime.tm_month);
    d[6] = HIDIGIT(printableTime.tm_mday);
    d[7] = LODIGIT(printableTime.tm_mday);
    d[8] = HIDIGIT(printableTime.tm_hour);
    d[9] = LODIGIT(printableTime.tm_hour);
    d[10] = HIDIGIT(printableTime.tm_min);
    d[11] = LODIGIT(printableTime.tm_min);
    d[12] = HIDIGIT(printableTime.tm_sec);
    d[13] = LODIGIT(printableTime.tm_sec);
    d[14] = 'Z';
    return SECSuccess;
}
SECStatus DER_TimeToUTCTime ( SECItem *  result,
int64  time 
)

Definition at line 132 of file dertime.c.

{
    return DER_TimeToUTCTimeArena(NULL, dst, gmttime);
}
SECStatus DER_TimeToUTCTimeArena ( PRArenaPool arenaOpt,
SECItem *  dst,
int64  gmttime 
)

Definition at line 84 of file dertime.c.

{
    PRExplodedTime printableTime;
    unsigned char *d;

    if ( (gmttime < January1st1950) || (gmttime >= January1st2050) ) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    dst->len = 13;
    if (arenaOpt) {
        dst->data = d = (unsigned char*) PORT_ArenaAlloc(arenaOpt, dst->len);
    } else {
        dst->data = d = (unsigned char*) PORT_Alloc(dst->len);
    }
    dst->type = siUTCTime;
    if (!d) {
       return SECFailure;
    }

    /* Convert an int64 time to a printable format.  */
    PR_ExplodeTime(gmttime, PR_GMTParameters, &printableTime);

    /* The month in UTC time is base one */
    printableTime.tm_month++;

    /* remove the century since it's added to the tm_year by the 
       PR_ExplodeTime routine, but is not needed for UTC time */
    printableTime.tm_year %= 100; 

    d[0] = HIDIGIT(printableTime.tm_year);
    d[1] = LODIGIT(printableTime.tm_year);
    d[2] = HIDIGIT(printableTime.tm_month);
    d[3] = LODIGIT(printableTime.tm_month);
    d[4] = HIDIGIT(printableTime.tm_mday);
    d[5] = LODIGIT(printableTime.tm_mday);
    d[6] = HIDIGIT(printableTime.tm_hour);
    d[7] = LODIGIT(printableTime.tm_hour);
    d[8] = HIDIGIT(printableTime.tm_min);
    d[9] = LODIGIT(printableTime.tm_min);
    d[10] = HIDIGIT(printableTime.tm_sec);
    d[11] = LODIGIT(printableTime.tm_sec);
    d[12] = 'Z';
    return SECSuccess;
}
char* DER_UTCDayToAscii ( SECItem *  utctime)

Definition at line 77 of file sectime.c.

{
    return (DecodeUTCTime2FormattedAscii (utctime, "%a %b %d, %Y"));
}

Here is the caller graph for this function:

char* DER_UTCTimeToAscii ( SECItem *  utcTime)

Definition at line 70 of file sectime.c.

{
    return (DecodeUTCTime2FormattedAscii (utcTime, "%a %b %d %H:%M:%S %Y"));
}
SECStatus DER_UTCTimeToTime ( int64 result,
const SECItem *  time 
)

Definition at line 241 of file dertime.c.

{
    const char * string;
    char localBuf[20]; 

    /* Minimum valid UTCTime is yymmddhhmmZ       which is 11 bytes. 
    ** Maximum valid UTCTime is yymmddhhmmss+0000 which is 17 bytes.
    ** 20 should be large enough for all valid encoded times. 
    */
    if (!time || !time->data || time->len < 11) {
       PORT_SetError(SEC_ERROR_INVALID_TIME);
       return SECFailure;
    }
    if (time->len >= sizeof localBuf) { 
       string = (const char *)time->data;
    } else {
       memset(localBuf, 0, sizeof localBuf);
       memcpy(localBuf, time->data, time->len);
        string = (const char *)localBuf;
    }
    return DER_AsciiToTime(dst, string);
}