Index: creddy/attr.c
===================================================================
--- creddy/attr.c	(revision 8231b92a3085fb87141108c14c428ac8df831002)
+++ creddy/attr.c	(revision 00d21a1ab04feed2d7d1b9de476bc8a52caa2f1d)
@@ -27,4 +27,5 @@
 char *_get_role_encoding(creddy_attribute_t *attr);
 
+// validity is measured in seconds (as of 0.2.0)
 int creddy_attribute_create(creddy_attribute_t **ret, creddy_id_t *issuer, char *role, int validity) {
     if (creddy_id_privkey(issuer) == NULL)
@@ -107,5 +108,5 @@
     // create attribute cert
     time_t not_before = time(NULL);
-    time_t not_after = not_before + attr->validity * 24 * 60 * 60;
+    time_t not_after = not_before + attr->validity;
     chunk_t serial = creddy_generate_serial();
 
Index: creddy/attribute.c
===================================================================
--- creddy/attribute.c	(revision 8231b92a3085fb87141108c14c428ac8df831002)
+++ creddy/attribute.c	(revision 00d21a1ab04feed2d7d1b9de476bc8a52caa2f1d)
@@ -39,5 +39,5 @@
         errx(1, "Invalid role name: %s", opts->role);
     if (ret == CREDDY_ATTRIBUTE_INVALID_VALIDITY)
-        errx(1, "Invalid validity: must be >= 1 day");
+        errx(1, "Invalid validity: must be >= 1 second");
 
     for (i = 0; i < opts->num_subjects; ++i) {
Index: creddy/creddy.c
===================================================================
--- creddy/creddy.c	(revision 8231b92a3085fb87141108c14c428ac8df831002)
+++ creddy/creddy.c	(revision 00d21a1ab04feed2d7d1b9de476bc8a52caa2f1d)
@@ -1,3 +1,4 @@
 #include <assert.h>
+#include <errno.h>
 #include <getopt.h>
 #include <stdio.h>
@@ -58,4 +59,5 @@
     int ret;
     options_t options = { 0, };
+    char *validity_str = NULL;
 
     subjects = xmalloc(sizeof(subject_t) * 2);
@@ -118,5 +120,5 @@
                 break;
             case OPT_VALIDITY: // also an attribute option
-                options.validity = atoi(optarg);
+                validity_str = xstrdup(optarg);
                 break;
 
@@ -167,4 +169,58 @@
             printf("I don't understand %s\n", argv[optind]);
         usage(&options);
+    }
+
+    // parse the validity
+    if (validity_str != NULL) {
+        char suffix = 'd'; // default suffix is days
+        int multiplier;
+
+        int len = strlen(validity_str);
+        assert(len > 0);
+
+        // get the suffix char if it's alphabetical
+        if (isalpha(validity_str[len - 1])) {
+            suffix = validity_str[len - 1];
+
+            // truncate
+            validity_str[len - 1] = '\0';
+            --len;
+
+            // make sure it's not only a suffix
+            if (len == 0) {
+                printf("Invalid validity\n");
+                usage(&options);
+            }
+        }
+
+        // convert the suffix to a multiplier
+        switch(suffix) {
+            case 's': multiplier =        1; break;
+            case 'm': multiplier =       60; break;
+            case 'h': multiplier =     3600; break;
+            case 'd': multiplier =    86400; break;
+            case 'y': multiplier = 31536000; break;
+            default:
+                printf("Invalid suffix, must be s m h d y\n");
+                usage(&options);
+        }
+
+        // ascii to int
+        char *end;
+        options.validity = strtol(validity_str, &end, 10);
+        if (errno != 0 || end - validity_str < len) {
+            printf("Invalid validity\n");
+            usage(&options);
+        }
+
+        if (options.validity <= 0) {
+            printf("Invalid validity: must be > 0\n");
+            usage(&options);
+        }
+
+        // multiply!
+        options.validity *= multiplier;
+
+        free(validity_str);
     }
 
@@ -196,5 +252,5 @@
     switch (options.mode) {
         case MODE_GENERATE:
-            if (options.validity == 0) options.validity = 1080;
+            if (options.validity == 0) options.validity = 1080 * 86400;
             generate_main(&options);
             break;
@@ -205,5 +261,5 @@
 
         case MODE_ATTRIBUTE:
-            if (options.validity == 0) options.validity = 365;
+            if (options.validity == 0) options.validity = 365 * 86400;
             attribute_main(&options);
             break;
@@ -235,8 +291,11 @@
     if (opts->mode == MODE_GENERATE)
         printf(
-            "Usage: creddy --generate --cn <name> [ --validity <days> ] [ --out <dir> ]\n"
+            "Usage: creddy --generate --cn <name> [ --validity <time> ] [ --out <dir> ]\n"
             "    cert will be in ${name}_ID.der, private key in ${name}_private.pem\n"
             "    files output to dir if specified\n"
             "    default validity: 1080 days\n"
+            "\n"
+            "    time is specified with optional suffix: s m h d y\n"
+            "    defaults to days if unspecified\n"
         );
 
@@ -258,8 +317,11 @@
             "                [ --subject-cert <cert> | --subject-id <sha1> \\\n"
             "                    [ --subject-role <role> ]  ... ] \\\n"
-            "                [ --validity <days> ] --out <file>\n"
+            "                [ --validity <time> ] --out <file>\n"
             "    default validity: 365 days\n"
             "    provide exactly one of --subject-cert / --subject-id\n"
             "    give multiple --subject-{cert,id} / --subject-role pairs for intersection\n"
+            "\n"
+            "    time is specified with optional suffix: s m h d y\n"
+            "    defaults to days if unspecified\n"
         );
 
Index: creddy/id.c
===================================================================
--- creddy/id.c	(revision 8231b92a3085fb87141108c14c428ac8df831002)
+++ creddy/id.c	(revision 00d21a1ab04feed2d7d1b9de476bc8a52caa2f1d)
@@ -112,4 +112,6 @@
 /**
  * Generate an ID with the specified CN and validity.
+ * 
+ * validity is measured in seconds (as of 0.2.0)
  */
 int creddy_id_generate(creddy_id_t **ret, char *cn, int validity) {
@@ -402,4 +404,6 @@
 /**
  * Generate certificate.
+ *
+ * validity is measured in seconds (as of 0.2.0)
  */
 static certificate_t *_generate_cert(private_key_t *private, char *cn, int validity) {
@@ -428,5 +432,5 @@
     // validity period
     time_t not_before = time(NULL);
-    time_t not_after = not_before + validity * 24 * 60 * 60;
+    time_t not_after = not_before + validity;
 
     // create!
