OER support for UTCTime and GeneralizedTime, also fuzz-testing
diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c
index dee267d..02d79a7 100644
--- a/skeletons/GeneralizedTime.c
+++ b/skeletons/GeneralizedTime.c
@@ -176,7 +176,7 @@
 asn_TYPE_operation_t asn_OP_GeneralizedTime = {
 	OCTET_STRING_free,
 	GeneralizedTime_print,
-	OCTET_STRING_compare,   /* Does not normalize time zones! */
+	GeneralizedTime_compare,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
 	GeneralizedTime_encode_der,
 	OCTET_STRING_decode_xer_utf8,
@@ -185,8 +185,8 @@
 	0,
 	0,
 #else
-	0,
-	0,
+	OCTET_STRING_decode_oer,
+	OCTET_STRING_encode_oer,
 #endif  /* ASN_DISABLE_OER_SUPPORT */
 #ifdef	ASN_DISABLE_PER_SUPPORT
 	0,
@@ -739,7 +739,7 @@
 
     (void)constraints;
 
-    if(max_length < sizeof("yyyymmddhhmmss")) {
+    if(max_length < sizeof("yyyymmddhhmmss") && !*sptr) {
         return result_skipped;
     }
 
@@ -754,3 +754,55 @@
 
     return result_ok;
 }
+
+int
+GeneralizedTime_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
+                        const void *bptr) {
+    const GeneralizedTime_t *a = aptr;
+    const GeneralizedTime_t *b = bptr;
+
+    (void)td;
+
+    if(a && b) {
+        int afrac_value, afrac_digits;
+        int bfrac_value, bfrac_digits;
+        time_t at = asn_GT2time_frac(a, &afrac_value, &afrac_digits, 0, 0);
+        time_t bt = asn_GT2time_frac(b, &bfrac_value, &bfrac_digits, 0, 0);
+        if(at < bt) {
+            return -1;
+        } else if(at > bt) {
+            return 1;
+        } else if(afrac_digits == bfrac_digits) {
+            if(afrac_value == bfrac_value) {
+                return 0;
+            }
+            if(afrac_value < bfrac_value) {
+                return -1;
+            } else {
+                return 1;
+            }
+        } else if(afrac_digits == 0) {
+            return -1;
+        } else if(bfrac_digits == 0) {
+            return 1;
+        } else {
+            double afrac = (double)afrac_value / afrac_digits;
+            double bfrac = (double)bfrac_value / bfrac_digits;
+            if(afrac < bfrac) {
+                return -1;
+            } else if(afrac > bfrac) {
+                return 1;
+            } else {
+                return 0;
+            }
+        }
+    } else if(!a && !b) {
+        return 0;
+    } else if(!a) {
+        return -1;
+    } else {
+        return 1;
+    }
+
+}
+
diff --git a/skeletons/GeneralizedTime.h b/skeletons/GeneralizedTime.h
index 84ee481..92f0029 100644
--- a/skeletons/GeneralizedTime.h
+++ b/skeletons/GeneralizedTime.h
@@ -17,13 +17,13 @@
 extern asn_TYPE_operation_t asn_OP_GeneralizedTime;
 
 asn_struct_print_f GeneralizedTime_print;
+asn_struct_compare_f GeneralizedTime_compare;
 asn_constr_check_f GeneralizedTime_constraint;
 der_type_encoder_f GeneralizedTime_encode_der;
 xer_type_encoder_f GeneralizedTime_encode_xer;
 asn_random_fill_f  GeneralizedTime_random_fill;
 
 #define GeneralizedTime_free           OCTET_STRING_free
-#define GeneralizedTime_compare        OCTET_STRING_compare
 #define GeneralizedTime_decode_ber     OCTET_STRING_decode_ber
 #define GeneralizedTime_decode_xer     OCTET_STRING_decode_xer_utf8
 #define GeneralizedTime_decode_uper    OCTET_STRING_decode_uper
diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c
index 55c7506..8ff9d92 100644
--- a/skeletons/UTCTime.c
+++ b/skeletons/UTCTime.c
@@ -31,7 +31,7 @@
 asn_TYPE_operation_t asn_OP_UTCTime = {
 	OCTET_STRING_free,
 	UTCTime_print,
-	OCTET_STRING_compare,   /* Does not deal with time zones. */
+	UTCTime_compare,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
 	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
 	OCTET_STRING_decode_xer_utf8,
@@ -40,8 +40,8 @@
 	0,
 	0,
 #else
-	0,
-	0,
+	OCTET_STRING_decode_oer,
+	OCTET_STRING_encode_oer,
 #endif  /* ASN_DISABLE_OER_SUPPORT */
 #ifdef	ASN_DISABLE_PER_SUPPORT
 	0,
@@ -109,7 +109,7 @@
 			ASN__ENCODE_FAILED;
 
 		/* Fractions are not allowed in UTCTime */
-		ut = asn_time2GT(0, 0, 1);
+		ut = asn_time2UT(0, &tm, 1);
 		if(!ut) ASN__ENCODE_FAILED;
 
 		rv = OCTET_STRING_encode_xer_utf8(td, sptr, ilevel, flags,
@@ -210,7 +210,7 @@
 
     (void)constraints;
 
-    if(max_length < sizeof("yymmddhhmmss")) {
+    if(max_length < sizeof("yymmddhhmmss") && !*sptr) {
         return result_skipped;
     }
 
@@ -225,3 +225,31 @@
 
     return result_ok;
 }
+
+int
+UTCTime_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
+                        const void *bptr) {
+    const GeneralizedTime_t *a = aptr;
+    const GeneralizedTime_t *b = bptr;
+
+    (void)td;
+
+    if(a && b) {
+        time_t at = asn_UT2time(a, 0, 0);
+        time_t bt = asn_UT2time(b, 0, 0);
+        if(at < bt) {
+            return -1;
+        } else if(at > bt) {
+            return 1;
+        } else {
+            return 0;
+        }
+    } else if(!a && !b) {
+        return 0;
+    } else if(!a) {
+        return -1;
+    } else {
+        return 1;
+    }
+}
+
diff --git a/skeletons/UTCTime.h b/skeletons/UTCTime.h
index 629bf06..23234fa 100644
--- a/skeletons/UTCTime.h
+++ b/skeletons/UTCTime.h
@@ -17,12 +17,12 @@
 extern asn_TYPE_operation_t asn_OP_UTCTime;
 
 asn_struct_print_f UTCTime_print;
+asn_struct_compare_f UTCTime_compare;
 asn_constr_check_f UTCTime_constraint;
 xer_type_encoder_f UTCTime_encode_xer;
 asn_random_fill_f  UTCTime_random_fill;
 
 #define UTCTime_free         OCTET_STRING_free
-#define UTCTime_compare      OCTET_STRING_compare
 #define UTCTime_decode_ber   OCTET_STRING_decode_ber
 #define UTCTime_encode_der   OCTET_STRING_encode_der
 #define UTCTime_decode_xer   OCTET_STRING_decode_xer_utf8