summaryrefslogtreecommitdiffstats
path: root/dirmngr/ldap-misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'dirmngr/ldap-misc.c')
-rw-r--r--dirmngr/ldap-misc.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/dirmngr/ldap-misc.c b/dirmngr/ldap-misc.c
index 42f9c7a..6e9e763 100644
--- a/dirmngr/ldap-misc.c
+++ b/dirmngr/ldap-misc.c
@@ -330,3 +330,91 @@ ldap_parse_extfilter (const char *string, int silent,
}
return err;
}
+
+
+
+/* Scan an ISO timestamp and return a Generalized Time according to
+ * RFC-4517. The only supported format is "yyyymmddThhmmss[Z]"
+ * delimited by white space, nul, a colon or a comma. Returns a
+ * malloced string or NULL for an invalid string or on memory
+ * error. */
+char *
+isotime2rfc4517 (const char *string)
+{
+ int year, month, day, hour, minu, sec;
+
+ if (!isotime_p (string))
+ {
+ errno = 0;
+ return NULL;
+ }
+
+ year = atoi_4 (string);
+ month = atoi_2 (string + 4);
+ day = atoi_2 (string + 6);
+ hour = atoi_2 (string + 9);
+ minu = atoi_2 (string + 11);
+ sec = atoi_2 (string + 13);
+
+ /* Basic checks (1600 due to the LDAP time format base) */
+ if (year < 1600 || month < 1 || month > 12 || day < 1 || day > 31
+ || hour > 23 || minu > 59 || sec > 61 )
+ {
+ errno = 0;
+ return NULL;
+ }
+
+ return gpgrt_bsprintf ("%04d%02d%02d%02d%02d%02d.0Z",
+ year, month, day, hour, minu, sec);
+}
+
+
+/* Parse an LDAP Generalized Time string and update the provided
+ * isotime buffer. On error return and error code. */
+gpg_error_t
+rfc4517toisotime (gnupg_isotime_t timebuf, const char *string)
+{
+ int i;
+ int year, month, day, hour, minu, sec;
+ const char *s;
+
+ /* Sample value: "20230823141623Z"; */
+ for (i=0, s=string; i < 10; i++, s++) /* Need yyyymmddhh */
+ if (!digitp (s))
+ return gpg_error (GPG_ERR_INV_TIME);
+ year = atoi_4 (string);
+ month = atoi_2 (string + 4);
+ day = atoi_2 (string + 6);
+ hour = atoi_2 (string + 8);
+ minu = 0;
+ sec = 0;
+ if (digitp (s) && digitp (s+1))
+ {
+ minu = atoi_2 (s);
+ s += 2;
+ if (digitp (s) && digitp (s+1))
+ {
+ sec = atoi_2 (s);
+ s += 2;
+ }
+ }
+ if (*s == '.' || *s == ',')
+ {
+ s++;
+ if (!digitp (s)) /* At least one digit of the fraction required. */
+ return gpg_error (GPG_ERR_INV_TIME);
+ s++;
+ while (digitp (s))
+ s++;
+ }
+ if (*s == 'Z' && (!s[1] || spacep (s+1)))
+ ; /* stop here. */
+ else if (*s == '-' || *s == '+')
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED); /* FIXME */
+ else
+ return gpg_error (GPG_ERR_INV_TIME);
+
+ snprintf (timebuf, sizeof (gnupg_isotime_t), "%04d%02d%02dT%02d%02d%02d",
+ year, month, day, hour, minu, sec);
+ return 0;
+}