#include "tomcrypt.h"
#ifdef LTC_DER
static int _char_to_int(unsigned char x)
{
switch (x) {
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
default: return 100;
}
}
#define DECODE_V(y, max) \
y = _char_to_int(buf[x])*10 + _char_to_int(buf[x+1]); \
if (y >= max) return CRYPT_INVALID_PACKET; \
x += 2;
int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
ltc_utctime *out)
{
unsigned char buf[32] = { 0 };
unsigned long x;
int y;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen != NULL);
LTC_ARGCHK(out != NULL);
if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) {
return CRYPT_INVALID_PACKET;
}
for (x = 0; x < in[1]; x++) {
y = der_ia5_value_decode(in[x+2]);
if (y == -1) {
return CRYPT_INVALID_PACKET;
}
buf[x] = y;
}
*inlen = 2 + x;
x = 0;
DECODE_V(out->YY, 100);
DECODE_V(out->MM, 13);
DECODE_V(out->DD, 32);
DECODE_V(out->hh, 24);
DECODE_V(out->mm, 60);
out->off_dir = out->off_hh = out->off_mm = out->ss = 0;
if (buf[x] == 'Z') {
return CRYPT_OK;
} else if (buf[x] == '+' || buf[x] == '-') {
out->off_dir = (buf[x++] == '+') ? 0 : 1;
DECODE_V(out->off_hh, 24);
DECODE_V(out->off_mm, 60);
return CRYPT_OK;
}
DECODE_V(out->ss, 60);
if (buf[x] == 'Z') {
return CRYPT_OK;
} else if (buf[x] == '+' || buf[x] == '-') {
out->off_dir = (buf[x++] == '+') ? 0 : 1;
DECODE_V(out->off_hh, 24);
DECODE_V(out->off_mm, 60);
return CRYPT_OK;
} else {
return CRYPT_INVALID_PACKET;
}
}
#endif