Index: creddy/generate.c
===================================================================
--- creddy/generate.c	(revision a0772a276e6895adbca67fb6f36a919f5911c332)
+++ creddy/generate.c	(revision 39fed7cfca3152c1d7385e267e7873c003b07590)
@@ -4,17 +4,17 @@
 
 #include "creddy.h"
-
-#define KEY_SUFFIX  "_private.pem"
-#define CERT_SUFFIX "_ID.pem"
-
-static private_key_t *_generate_key(char *filename);
-static void _generate_cert(char *filename, private_key_t *private, char *cn, int validity);
+#include "libcreddy.h"
 
 void generate_main(options_t *opts) {
+    int ret, fd;
+    creddy_id_t *id;
+    char *filename;
+    FILE *out;
+
     printf("Generating key, this will take a while. Create entropy!\n");
     printf("    - move the mouse\n");
     printf("    - generate disk activity (run find)\n");
 
-    int ret = creddy_generate(opts->cn, opts->validity);
+    ret = creddy_id_generate(&id, opts->cn, opts->validity);
 
     if (ret == CREDDY_GENERATE_INVALID_CN) {
@@ -26,177 +26,26 @@
         usage(opts);
     }
-}
+    // in both above cases: usage(opts) exits
 
-int creddy_generate(char *cn, int validity) {
-    private_key_t *key;
-    chunk_t encoding;
+    //
+    // success!
+    //
 
-    if (cn == NULL || !clean_name(cn))
-        return CREDDY_GENERATE_INVALID_CN;
+    // write the cert
+    filename = creddy_id_cert_filename(id);
+    out = fopen(filename, "w");
+    creddy_id_write_cert(id, out);
+    fclose(out);
+    free(filename);
 
-    if (validity < 0)
-        return CREDDY_GENERATE_INVALID_VALIDITY;
-
-    int cn_len = strlen(cn);
-
-    // key output filename: "${cn}_private.pem"
-    char *filename = xmalloc(cn_len + sizeof(KEY_SUFFIX));
-    memcpy(filename, cn, cn_len);
-
-    memcpy(filename + cn_len, KEY_SUFFIX, sizeof(KEY_SUFFIX));
-    key = _generate_key(filename);
-
-    // cert filename: ${cn}_ID.pem
-    memcpy(filename + cn_len, CERT_SUFFIX, sizeof(CERT_SUFFIX));
-    _generate_cert(filename, key, cn, validity);
-
-    free(filename);
-    DESTROY_IF(key);
-
-    return CREDDY_SUCCESS;
-}
-
-static private_key_t *_generate_key(char *filename) {
-    private_key_t *key;
-    int ret;
-    chunk_t encoding;
-
-    // generate the key
-    key = lib->creds->create(
-        lib->creds,
-        CRED_PRIVATE_KEY, KEY_RSA,
-        BUILD_KEY_SIZE, 2048,
-        BUILD_END
-    );
-    if (key == NULL)
-        errx(1, "Key generation failed");
-
-    // get the key encoding
-    ret = key->get_encoding(key, KEY_PRIV_PEM, &encoding);
-    if (!ret)
-        errx(1, "Couldn't encode private key");
-
-    // write it to a file (with mode 600)
-    int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+    // write the key
+    filename = creddy_id_privkey_filename(id);
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); // mode 600
     if (fd < 0)
-        err(1, "Couldn't open %s for writing private key", filename);
-
-    ret = write(fd, encoding.ptr, encoding.len);
-    if (ret < encoding.len)
-        errx(1, "Couldn't write all the bytes of the private key");
-
-    close(fd);
-
-    free(encoding.ptr);
-
-    return key;
-}
-
-static char *_create_dn(char *cn) {
-
-#define DN "cn="
-
-    char *dn = xmalloc(sizeof(DN) + strlen(cn));
-    memcpy(dn, DN, sizeof(DN));
-    strcat(dn, cn);
-
-    return dn;
-}
-
-#define BYTES_PER_LINE 64
-
-// thx libstrongswan
-static void _encode_base64(char *filename, chunk_t encoding) {
-    int start;
-
-    chunk_t b64 = chunk_to_base64(encoding, NULL);
-
-    FILE *out = fopen(filename, "w");
-    if (out == NULL)
-        err(1, "couldn't open %s for writing", filename);
-
-    fprintf(out, "-----BEGIN CERTIFICATE-----\n");
-
-    for (start = 0; start < b64.len; start += BYTES_PER_LINE) {
-        int left = b64.len - start;
-        int len = left < BYTES_PER_LINE ? left : BYTES_PER_LINE;
-        fwrite(b64.ptr + start, len, 1, out);
-        fprintf(out, "\n");
-    }
-
-    fprintf(out, "-----END CERTIFICATE-----\n");
+        err(1, "Can't open private key file %s", filename);
+    out = fdopen(fd, "w");
+    creddy_id_write_privkey(id, out);
     fclose(out);
 
-    free(b64.ptr);
+    creddy_id_free(id);
 }
-
-static void _generate_cert(char *filename, private_key_t *private, char *cn, int validity) {
-    // build the DN
-    char *dn_string = _create_dn(cn);
-    identification_t *id = identification_create_from_string(dn_string);
-    if (id == NULL)
-        errx(1, "couldn't create ID from DN %s", dn_string);
-    free(dn_string);
-
-    // get the public key
-    public_key_t *public = private->get_public_key(private);
-    if (public == NULL)
-        errx(1, "couldn't get public key from private key");
-
-    // create a serial (stolen from strongswan pki)
-    rng_t *rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-    if (!rng)
-        errx(1, "no random number generator");
-
-    // random serial
-    chunk_t serial = generate_serial();
-
-    // validity period
-    time_t not_before = time(NULL);
-    time_t not_after = not_before + validity * 24 * 60 * 60;
-
-    // create!
-    certificate_t *cert = lib->creds->create(lib->creds,
-        CRED_CERTIFICATE, CERT_X509,
-        BUILD_SIGNING_KEY, private,
-        BUILD_PUBLIC_KEY, public,
-        BUILD_SUBJECT, id,
-        BUILD_NOT_BEFORE_TIME, not_before,
-        BUILD_NOT_AFTER_TIME, not_after,
-        BUILD_SERIAL, serial,
-        BUILD_DIGEST_ALG, HASH_SHA1,
-        BUILD_X509_FLAG, X509_CA,
-        BUILD_PATHLEN, X509_NO_PATH_LEN_CONSTRAINT,
-        BUILD_END
-    );
-    if (cert == NULL)
-        errx(1, "couldn't build cert :(");
-
-    chunk_t encoding = cert->get_encoding(cert);
-
-    // sigh
-    _encode_base64(filename, encoding);
-
-    DESTROY_IF(id);
-    DESTROY_IF(cert);
-    DESTROY_IF(public);
-    free(encoding.ptr);
-    free(serial.ptr);
-}
-
-chunk_t generate_serial() {
-    chunk_t serial = chunk_empty;
-
-    // create a serial (stolen from strongswan pki)
-    rng_t *rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-    if (!rng)
-        errx(1, "no random number generator");
-
-    rng->allocate_bytes(rng, 8, &serial);
-    while (serial.ptr[0] == 0)
-        // don't get leading 0's
-        rng->get_bytes(rng, 1, serial.ptr);
-    rng->destroy(rng);
-
-    return serial;
-}
