From 83780d4764d1c04c748b8d0446617981cccd3a2b Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 30 Mar 2017 22:48:42 +0200 Subject: [PATCH] add timezone-offset support to GeneralizedTime this also fixes a bug in the length generation --- src/headers/tomcrypt_pk.h | 5 ++++- .../generalizedtime/der_decode_generalizedtime.c | 11 ++++++++++- .../generalizedtime/der_encode_generalizedtime.c | 9 ++++++++- .../generalizedtime/der_length_generalizedtime.c | 13 ++++++++++--- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index a39f5b8..60a11a9 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -672,7 +672,10 @@ typedef struct { hh, /* hour */ mm, /* minute */ ss, /* second */ - fs; /* fractional seconds */ + fs, /* fractional seconds */ + off_dir, /* timezone offset direction 0 == +, 1 == - */ + off_hh, /* timezone offset hours */ + off_mm; /* timezone offset minutes */ } ltc_generalizedtime; int der_encode_generalizedtime(ltc_generalizedtime *gtime, diff --git a/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c index 0fd5579..1f0713e 100644 --- a/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c +++ b/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c @@ -110,7 +110,7 @@ YYYYMMDDhhmmss.[0-9]*Z return CRYPT_OK; } else if (buf[x] == '.') { x++; - while (buf[x] != 'Z') { + while (buf[x] >= '0' && buf[x] <= '9') { unsigned fs = out->fs; if (x >= sizeof(buf)) return CRYPT_INVALID_PACKET; out->fs *= 10; @@ -118,6 +118,15 @@ YYYYMMDDhhmmss.[0-9]*Z if (fs < out->fs) return CRYPT_OVERFLOW; x++; } + } + + /* now is it Z, +, - */ + 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; diff --git a/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c index 4852684..afb26c8 100644 --- a/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c +++ b/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c @@ -86,7 +86,14 @@ int der_encode_generalizedtime(ltc_generalizedtime *gtime, } out[x++] = der_ia5_char_encode(baseten[gtime->fs % 10]); } - out[x++] = der_ia5_char_encode('Z'); + + if (gtime->off_mm || gtime->off_hh) { + out[x++] = der_ia5_char_encode(gtime->off_dir ? '-' : '+'); + STORE_V(gtime->off_hh); + STORE_V(gtime->off_mm); + } else { + out[x++] = der_ia5_char_encode('Z'); + } /* store length */ out[1] = (unsigned char)(x - 2); diff --git a/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c index eff3948..e5abf9f 100644 --- a/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c +++ b/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c @@ -31,15 +31,22 @@ int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen if (gtime->fs == 0) { /* we encode as YYYYMMDDhhmmssZ */ - *outlen = 2 + 15; + *outlen = 2 + 14 + 1; } else { - /* we encode as YYYYMMDDhhmmss.fsZ */ - unsigned long len = 2 + 17; + unsigned long len = 2 + 14 + 1; unsigned fs = gtime->fs; do { fs /= 10; len++; } while(fs != 0); + if (gtime->off_hh == 0 && gtime->off_mm == 0) { + /* we encode as YYYYMMDDhhmmss.fsZ */ + len += 1; + } + else { + /* we encode as YYYYMMDDhhmmss.fs{+|-}hh'mm' */ + len += 5; + } *outlen = len; }