Home | History | Annotate | Download | only in utctime
      1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
      2  *
      3  * LibTomCrypt is a library that provides various cryptographic
      4  * algorithms in a highly modular and flexible manner.
      5  *
      6  * The library is free for all purposes without any express
      7  * guarantee it works.
      8  *
      9  * Tom St Denis, tomstdenis (at) gmail.com, http://libtomcrypt.com
     10  */
     11 #include "tomcrypt.h"
     12 
     13 /**
     14   @file der_decode_utctime.c
     15   ASN.1 DER, decode a  UTCTIME, Tom St Denis
     16 */
     17 
     18 #ifdef LTC_DER
     19 
     20 static int char_to_int(unsigned char x)
     21 {
     22    switch (x)  {
     23       case '0': return 0;
     24       case '1': return 1;
     25       case '2': return 2;
     26       case '3': return 3;
     27       case '4': return 4;
     28       case '5': return 5;
     29       case '6': return 6;
     30       case '7': return 7;
     31       case '8': return 8;
     32       case '9': return 9;
     33    }
     34    return 100;
     35 }
     36 
     37 #define DECODE_V(y, max) \
     38    y  = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \
     39    if (y >= max) return CRYPT_INVALID_PACKET;           \
     40    x += 2;
     41 
     42 /**
     43   Decodes a UTC time structure in DER format (reads all 6 valid encoding formats)
     44   @param in     Input buffer
     45   @param inlen  Length of input buffer in octets
     46   @param out    [out] Destination of UTC time structure
     47   @return CRYPT_OK   if successful
     48 */
     49 int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
     50                              ltc_utctime   *out)
     51 {
     52    unsigned char buf[32];
     53    unsigned long x;
     54    int           y;
     55 
     56    LTC_ARGCHK(in    != NULL);
     57    LTC_ARGCHK(inlen != NULL);
     58    LTC_ARGCHK(out   != NULL);
     59 
     60    /* check header */
     61    if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) {
     62       return CRYPT_INVALID_PACKET;
     63    }
     64 
     65    /* decode the string */
     66    for (x = 0; x < in[1]; x++) {
     67        y = der_ia5_value_decode(in[x+2]);
     68        if (y == -1) {
     69           return CRYPT_INVALID_PACKET;
     70        }
     71        buf[x] = y;
     72    }
     73    *inlen = 2 + x;
     74 
     75 
     76    /* possible encodings are
     77 YYMMDDhhmmZ
     78 YYMMDDhhmm+hh'mm'
     79 YYMMDDhhmm-hh'mm'
     80 YYMMDDhhmmssZ
     81 YYMMDDhhmmss+hh'mm'
     82 YYMMDDhhmmss-hh'mm'
     83 
     84     So let's do a trivial decode upto [including] mm
     85    */
     86 
     87     x = 0;
     88     DECODE_V(out->YY, 100);
     89     DECODE_V(out->MM, 13);
     90     DECODE_V(out->DD, 32);
     91     DECODE_V(out->hh, 24);
     92     DECODE_V(out->mm, 60);
     93 
     94     /* clear timezone and seconds info */
     95     out->off_dir = out->off_hh = out->off_mm = out->ss = 0;
     96 
     97     /* now is it Z, +, - or 0-9 */
     98     if (buf[x] == 'Z') {
     99        return CRYPT_OK;
    100     } else if (buf[x] == '+' || buf[x] == '-') {
    101        out->off_dir = (buf[x++] == '+') ? 0 : 1;
    102        DECODE_V(out->off_hh, 24);
    103        DECODE_V(out->off_mm, 60);
    104        return CRYPT_OK;
    105     }
    106 
    107     /* decode seconds */
    108     DECODE_V(out->ss, 60);
    109 
    110     /* now is it Z, +, - */
    111     if (buf[x] == 'Z') {
    112        return CRYPT_OK;
    113     } else if (buf[x] == '+' || buf[x] == '-') {
    114        out->off_dir = (buf[x++] == '+') ? 0 : 1;
    115        DECODE_V(out->off_hh, 24);
    116        DECODE_V(out->off_mm, 60);
    117        return CRYPT_OK;
    118     } else {
    119        return CRYPT_INVALID_PACKET;
    120     }
    121 }
    122 
    123 #endif
    124 
    125 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c,v $ */
    126 /* $Revision: 1.8 $ */
    127 /* $Date: 2006/03/31 14:15:35 $ */
    128