Index: libabac/abac_id.c
===================================================================
--- libabac/abac_id.c	(revision 9b43fc3d618a238405947779470f1a092ba98648)
+++ libabac/abac_id.c	(revision 34e667d519aee5a2be9e323d09c0a3258eb805b1)
@@ -6,5 +6,4 @@
 #include <assert.h>
 #include <err.h>
-#include <termios.h>
 #include <time.h>
 
@@ -21,6 +20,9 @@
 #define KEY_SUFFIX  "_private.pem"
 #define CERT_SUFFIX "_ID.pem"
-/* Size of password memory allocation */
-#define PWLEN 128
+
+extern private_key_t *abac_key_private_key(abac_key_t *ptr);
+extern abac_key_t *abac_key_file_new(char *filename, chunk_t potato);
+extern abac_key_t *abac_key_chunk_new(chunk_t keyblob, chunk_t potato);
+extern chunk_t abac_key_chunk(abac_key_t *);
 
 //
@@ -28,5 +30,5 @@
 //
 struct _abac_id_t {
-    int idtype;    /* default to 'keyid' for now */
+    int idtype;    /* default to string 'keyid' for now */
 
     char *keyid; /* sha */
@@ -34,15 +36,7 @@
 
     certificate_t *cert;
-    private_key_t *key;
+    abac_key_t *key;
 
     int refcount;
-};
-
-/* Callback configuration, local */
-struct cb_opts {
-    bool use_prompt;    /* Print a prompt to stderr */
-    bool use_echo;      /* If true, turn off input echo on stdin */
-    unsigned int tries; /* Number of attempts allowed */
-    char prompt[20];    /* The prompt to display if use_echo is true */
 };
 
@@ -51,5 +45,4 @@
 // Helper functions below
 //
-
 static char *_get_keyid(certificate_t *cert) {
     // get the keyid
@@ -60,99 +53,4 @@
 }
 
-static chunk_t _passphrase_callback(void *user, int try) {
-    /* Get a password from stdin and return it as a chunk_t.  If too many tries
-     * have occurred or there is any other problem, return an empty chunk_t,
-     * which libstrongswan takes as giving up.  The chunk is alloated here
-     * (inside getline), and presumably freed by libstrongswan. User points to
-     * a cb_opts struct, which affects this routine in the obvious ways.
-     */
-    /* Configuration options */
-    struct cb_opts *opts = (struct cb_opts *) user;
-    chunk_t rv = chunk_empty;   /* Return value, starts empty */
-
-    if (try -1 < opts->tries ) {
-        struct termios t;   /* Terminal settings */
-        size_t len = 0;     /* Length of string from getline */
-        tcflag_t orig = 0;  /* Holds the original local flags (echo in here) */
-
-        if (!opts->use_echo) {
-            /* Use tc{get,set}attr to turn echo off and restore the intial
-             * echo settings */
-            if (!tcgetattr(0, &t)) {
-                orig = t.c_lflag;
-
-                t.c_lflag &= ~ECHO;
-                if ( tcsetattr(0, TCSANOW, &t) ) {
-                    perror("Cannot turn off echo");
-                    return rv;
-                }
-            }
-            else {
-                perror("Cannot turn get attributes to off echo");
-                return rv;
-            }
-        }
-        if (opts->use_prompt) printf("%s", opts->prompt);
-
-        /* Because rv.ptr starts as NULL, getline allocates memory.  The size
-         * of the allocation returns in rv.len and the size of the string
-         * (including newline and NUL) is in len.  */
-        if ((rv.ptr = (u_char *) malloc(rv.len = PWLEN))) {
-            if ( fgets(rv.ptr, rv.len, stdin) ) {
-                /* Readjust the chunk_t's len field to the size of the string
-                 * w/o the newline or NUL */
-                /* would prefer strnlen, but no such luck in FBSD7 or earlier*/
-                size_t len = strlen(rv.ptr);
-
-                if (rv.ptr[len-2] == '\n') rv.len = len-2;
-                else rv.len = len -1;
-            }
-            else {
-                /* Read failed.  Deallocate and clear rv */
-                free(rv.ptr);
-                rv = chunk_empty;
-            }
-        }
-        else {
-            /* Failed malloc.  Restore rv to empty and return it */
-            perror("malloc");
-            rv = chunk_empty;
-            return rv;
-        }
-
-        if (!opts->use_echo ) {
-            /* Pop echo beck to its original setting. */
-            t.c_lflag = orig;
-
-            if ( tcsetattr(0, TCSANOW, &t) )
-                perror("Cannot restore echo setting?");
-
-            if (opts->use_prompt) printf("\n");
-        }
-    }
-    else fprintf(stderr, "Too many tries (%d)", try-1);
-    return rv;
-}
-
-/**
- * Generate a private key.
- */
-static private_key_t *_generate_key(void) {
-    private_key_t *key;
-    libabac_init();
-
-    // 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");
-
-    return key;
-}
-
 static char *_create_dn(char *cn) {
 
@@ -171,5 +69,5 @@
  * validity is measured in seconds (as of 0.2.0)
  */
-static certificate_t *_generate_cert(private_key_t *private, char *cn, int validity) {
+static certificate_t *_generate_cert(abac_key_t *keyptr, char *cn, int validity) {
     // build the DN
     char *dn_string = _create_dn(cn);
@@ -182,5 +80,11 @@
 
     // get the public key
+    private_key_t *private = abac_key_private_key(keyptr);
+
+    if(private == NULL)
+        errx(1, "couldn't create ID without private key");
+
     public_key_t *public = private->get_public_key(private);
+
     if (public == NULL)
         errx(1, "couldn't get public key from private key");
@@ -209,7 +113,5 @@
         BUILD_DIGEST_ALG, HASH_SHA1,
         BUILD_X509_FLAG, X509_CA,
-/*
-        BUILD_PATHLEN, X509_NO_PATH_LEN_CONSTRAINT,
-*/
+        BUILD_PATHLEN, X509_NO_CONSTRAINT,
         BUILD_END
     );
@@ -219,4 +121,5 @@
     DESTROY_IF(id);
     DESTROY_IF(public);
+    DESTROY_IF(private);
     free(serial.ptr);
 
@@ -337,4 +240,11 @@
 private_key_t *abac_id_privkey(abac_id_t *id) {
     assert(id != NULL);
+    if(id->key !=0)
+        return abac_key_private_key(id->key);
+    return NULL;
+}
+
+abac_key_t *abac_id_keyptr(abac_id_t *id)
+{
     return id->key;
 }
@@ -365,21 +275,7 @@
  * Returns false if there's no private key loaded
  */
-int abac_id_write_privkey(abac_id_t *id, FILE *out) {
-    int ret;
-    chunk_t encoding;
-
-    assert(id != NULL);
-
-    if (id->key == NULL)
-        return 0;
-
-    ret = id->key->get_encoding(id->key, PRIVKEY_PEM, &encoding);
-    if (!ret)
-        errx(1, "Couldn't encode private key");
-
-    fwrite(encoding.ptr, encoding.len, 1, out);
-
-    free(encoding.ptr);
-    return 1;
+int abac_id_write_privkey(abac_id_t *id, FILE *out)
+{
+    return abac_key_write_privkey(id->key, out);
 }
 
@@ -400,12 +296,23 @@
  * Get a PEM-encoded chunk representing the private key 
  */
-abac_chunk_t abac_id_privkey_chunk(abac_id_t *id) {
-    assert(id->cert);
-
-    chunk_t encoding = chunk_empty;
-    int rc= id->key->get_encoding(id->key, PRIVKEY_PEM, &encoding);
-    abac_chunk_t ret = { encoding.ptr, encoding.len };
-
+abac_chunk_t abac_id_privkey_chunk(abac_id_t *id) 
+{
+    chunk_t tmp=chunk_empty;
+    if(id->key) {
+         tmp=abac_key_chunk(id->key);
+    }
+    if(debug)
+        printf("abac_id_privkey_chunk tmp ptr, loc(%d)(%d)\n", (int)tmp.ptr, tmp.len);
+
+    abac_chunk_t ret= {tmp.ptr, tmp.len}; 
+    if(debug)
+        printf("abac_id_privkey_chunk ptr, loc(%d)(%d)\n", (int)ret.ptr, ret.len);
     return ret;
+}
+
+void abac_id_print_key_chunk(abac_id_t *id)
+{
+   if(id->key)
+       print_abac_key("abac_id_print_key_chunk",id->key);
 }
 
@@ -427,7 +334,10 @@
         return;
 
+    if(debug)
+        printf("making abac_id_free call on (%s)!!!\n", id->cn);
     // free once the reference count reaches 0
     DESTROY_IF(id->cert);
-    DESTROY_IF(id->key);
+
+    if(id->key) abac_key_free(id->key);
 
     free(id->keyid);
@@ -437,39 +347,4 @@
 
 /****************************************************************/
-/**
- * Load private key for a cert.
- */
-int abac_id_load_privkey_file(abac_id_t *id, char *filename) {
-    assert(id != NULL);
-
-    // load signer key
-    private_key_t *key = lib->creds->create(lib->creds,
-        CRED_PRIVATE_KEY, KEY_RSA,
-        BUILD_FROM_FILE, filename,
-        BUILD_END
-    );
-    if (key == NULL)
-        return 0;
-
-    id->key = key;
-    return 1;
-}
-
-int abac_id_load_privkey_chunk(abac_id_t *id, chunk_t chunk) {
-    assert(id != NULL);
-
-    // load signer key
-    private_key_t *key = lib->creds->create(lib->creds,
-        CRED_PRIVATE_KEY, KEY_RSA,
-        BUILD_BLOB_PEM, chunk,
-        BUILD_END
-    );
-    if (key == NULL)
-        return 0;
-
-    id->key = key;
-    return 1;
-}
-
 /**
  * Default private key filename. Value must be freed by caller.
@@ -499,6 +374,4 @@
     return filename;
 }
-
-
 
 /****************************************************************/
@@ -598,5 +471,6 @@
  * validity is measured in seconds (as of 0.2.0)
  */
-int abac_id_generate(abac_id_t **ret, char *cn, int validity) {
+int abac_id_generate(abac_id_t **ret, char *cn, int validity)
+{
     if (cn == NULL || !abac_validate_clean_name(cn))
         return ABAC_ID_GENERATE_INVALID_CN;
@@ -615,5 +489,5 @@
     id->idtype = e_KEYID;
     id->cn = tmp;
-    id->key = _generate_key();
+    id->key = abac_key_generate();
     id->cert = _generate_cert(id->key, cn, validity);
     id->keyid = _get_keyid(id->cert);
@@ -625,3 +499,78 @@
 }
 
-/*****************************************************************/
+
+/**
+ * Generate an ID with the specified CN and validity and a passphrase.
+ *
+ * validity is measured in seconds (as of 0.2.0)
+ */
+int abac_id_generate_with_key(abac_id_t **ret, char *cn, int validity, char *filename, char *pfile) {
+    if (cn == NULL || !abac_validate_clean_name(cn))
+        return ABAC_ID_GENERATE_INVALID_CN;
+
+    if(debug) {
+        printf("abac_id_generate: generating id with cn(%s) and privkey(%s)",
+                                                    cn, filename);
+        if(pfile) printf("pfile(%s)\n",pfile);
+            else printf("\n");
+    }
+
+    if (validity < 0)
+        return ABAC_ID_GENERATE_INVALID_VALIDITY;
+
+    if (validity == 0) validity = 1080 * 86400;
+
+    chunk_t pp=chunk_empty;
+    if(pfile && strlen(pfile)!=0) {
+        if(!file_exist(pfile))
+            errx(1, "passphrase file does not exist!!\n");
+        pp=extract_potato(filename,pfile);
+    }
+
+    abac_id_t *id = abac_xmalloc(sizeof(abac_id_t));
+    char *tmp=NULL;
+    asprintf(&tmp,"p%s",cn);
+    id->idtype = e_KEYID;
+    id->cn = tmp;
+    id->key = abac_key_file_new(filename,pp);
+    id->cert = _generate_cert(id->key, cn, validity);
+    id->keyid = _get_keyid(id->cert);
+
+    id->refcount = 1;
+
+    *ret = id;
+    return ABAC_ID_SUCCESS;
+}
+
+int abac_id_load_privkey_file(abac_id_t *ptr, char *keyfile)
+{
+    assert(ptr);
+    ptr->key=abac_key_file_new(keyfile, chunk_empty);
+    return 1;
+}
+
+int abac_id_load_enc_privkey_file(abac_id_t *ptr, char *keyfile, char *pfile)
+{
+    assert(ptr);
+    chunk_t pp=extract_potato(keyfile,pfile);
+    ptr->key=abac_key_file_new(keyfile, pp);
+    return 1;
+}
+
+int abac_id_load_privkey_chunk(abac_id_t *ptr, chunk_t keychunk)
+{
+    assert(ptr);
+    ptr->key=abac_key_chunk_new(keychunk, chunk_empty);
+    if(debug)
+        print_abac_key("after abac_id_load_privkey_chunk", ptr->key);
+    return 1;
+}
+
+int abac_id_load_enc_privkey_chunk(abac_id_t *ptr, chunk_t keychunk, char *pfile)
+{
+    assert(ptr);
+    chunk_t pp=extract_potato(NULL,pfile);
+    ptr->key=abac_key_chunk_new(keychunk, pp);
+    return 1;
+}
+
