Index: creddy/creddy.c
===================================================================
--- creddy/creddy.c	(revision 8231b92a3085fb87141108c14c428ac8df831002)
+++ creddy/creddy.c	(revision 7df19e3b5c2cade2d4dc044dd2ba2d25063c7da2)
@@ -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"
         );
 
