Quellcode durchsuchen

add timezone-offset support to GeneralizedTime

this also fixes a bug in the length generation
Steffen Jaeckel vor 8 Jahren
Ursprung
Commit
83780d4764

+ 4 - 1
src/headers/tomcrypt_pk.h

@@ -672,7 +672,10 @@ typedef struct {
             hh, /* hour */
             hh, /* hour */
             mm, /* minute */
             mm, /* minute */
             ss, /* second */
             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;
 } ltc_generalizedtime;
 
 
 int der_encode_generalizedtime(ltc_generalizedtime *gtime,
 int der_encode_generalizedtime(ltc_generalizedtime *gtime,

+ 10 - 1
src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c

@@ -110,7 +110,7 @@ YYYYMMDDhhmmss.[0-9]*Z
        return CRYPT_OK;
        return CRYPT_OK;
     } else if (buf[x] == '.') {
     } else if (buf[x] == '.') {
        x++;
        x++;
-       while (buf[x] != 'Z') {
+       while (buf[x] >= '0' && buf[x] <= '9') {
           unsigned fs = out->fs;
           unsigned fs = out->fs;
           if (x >= sizeof(buf)) return CRYPT_INVALID_PACKET;
           if (x >= sizeof(buf)) return CRYPT_INVALID_PACKET;
           out->fs *= 10;
           out->fs *= 10;
@@ -118,6 +118,15 @@ YYYYMMDDhhmmss.[0-9]*Z
           if (fs < out->fs) return CRYPT_OVERFLOW;
           if (fs < out->fs) return CRYPT_OVERFLOW;
           x++;
           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;
        return CRYPT_OK;
     } else {
     } else {
        return CRYPT_INVALID_PACKET;
        return CRYPT_INVALID_PACKET;

+ 8 - 1
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(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 */
     /* store length */
     out[1] = (unsigned char)(x - 2);
     out[1] = (unsigned char)(x - 2);

+ 10 - 3
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) {
    if (gtime->fs == 0) {
       /* we encode as YYYYMMDDhhmmssZ */
       /* we encode as YYYYMMDDhhmmssZ */
-      *outlen = 2 + 15;
+      *outlen = 2 + 14 + 1;
    } else {
    } else {
-      /* we encode as YYYYMMDDhhmmss.fsZ */
-      unsigned long len = 2 + 17;
+      unsigned long len = 2 + 14 + 1;
       unsigned fs = gtime->fs;
       unsigned fs = gtime->fs;
       do {
       do {
          fs /= 10;
          fs /= 10;
          len++;
          len++;
       } while(fs != 0);
       } 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;
       *outlen = len;
    }
    }