Index: libabac/abac.h
===================================================================
--- libabac/abac.h	(revision 7e3f5e29f503573b501f5c9f1222d71c262d6018)
+++ libabac/abac.h	(revision 9e063cb3a3c18c17cd43f2173ada363498198dca)
@@ -94,4 +94,8 @@
 // returns one of ABAC_SUCCESS or ABAC_GENERATE_* (see top)
 int abac_id_generate(abac_id_t **ret, char *cn, long validity);
+
+// generate an ID using supplied private key
+// returns one of ABAC_SUCCESS or ABAC_GENERATE_* (see top)
+int abac_id_generate_with_key(abac_id_t **ret, char *cn, long validity, char *keyfile);
 
 // get the SHA1 keyid, pointer is valid for the lifetime of the object
@@ -207,5 +211,5 @@
 ABAC_LIST_T *abac_attribute_certs_from_chunk(abac_chunk_t);
 
-// get the attribute role string
+	// get the attribute role string
 char *abac_attribute_role_string(abac_attribute_t *attr);
 
@@ -223,4 +227,9 @@
 int abac_attribute_still_valid(abac_attribute_t *attr);
 
+/* 
+ * Return code for libabac
+ */
+#define ABAC_RC_SUCCESS                0
+#define ABAC_RC_FAILURE                1
 
 /*
Index: libabac/abac_attribute.c
===================================================================
--- libabac/abac_attribute.c	(revision 7e3f5e29f503573b501f5c9f1222d71c262d6018)
+++ libabac/abac_attribute.c	(revision 9e063cb3a3c18c17cd43f2173ada363498198dca)
@@ -284,5 +284,5 @@
     attr->role =abac_xstrdup(tmp+1);
 
-    attr->cert.ptr=(unsigned char *)xml;
+    attr->cert.ptr=(unsigned char *)abac_xstrdup(xml);
     attr->cert.len=strlen(xml);
 
Index: libabac/abac_id.c
===================================================================
--- libabac/abac_id.c	(revision 7e3f5e29f503573b501f5c9f1222d71c262d6018)
+++ libabac/abac_id.c	(revision 9e063cb3a3c18c17cd43f2173ada363498198dca)
@@ -80,16 +80,20 @@
 }
 
-/**
- * Load private key for a cert.
- */
-int abac_id_privkey_from_file(abac_id_t *id, char *filename) {
-    assert(id != NULL);
-
+static EVP_PKEY *_load_privkey_from_file(char *filename)
+{
     FILE *fp=fopen(filename,"r");
-    if(fp==NULL) return ABAC_FAILURE;
-
+    if(fp==NULL) return NULL;
     EVP_PKEY *key=abac_load_privkey_from_fp(fp);
     fclose(fp);
-
+    return key;
+}
+
+/**
+ * Load private key for a cert.
+ */
+int abac_id_privkey_from_file(abac_id_t *id, char *filename) {
+    assert(id != NULL);
+
+    EVP_PKEY *key=_load_privkey_from_file(filename);
     if (key == NULL) return ABAC_FAILURE;
 
@@ -127,4 +131,28 @@
     id->keyid = abac_get_keyid(id->cert);
 
+    id->refcount = 1;
+
+    *ret = id;
+    return ABAC_SUCCESS;
+}
+
+/**
+ * Generate an ID with the specified CN and validity.
+ *
+ * validity is measured in seconds (as of 0.2.0)
+ */
+int abac_id_generate_with_key(abac_id_t **ret, char *cn, long validity, char *keyfile) {
+    if (cn == NULL || !abac_clean_name(cn))
+        return ABAC_GENERATE_INVALID_CN;
+
+    if (validity < 0)
+        return ABAC_GENERATE_INVALID_VALIDITY;
+
+    abac_id_t *id = abac_xmalloc(sizeof(abac_id_t));
+
+    id->cn = abac_xstrdup(cn);
+    id->key = _load_privkey_from_file(keyfile);
+    id->cert = abac_generate_cert(id->key, cn, validity);
+    id->keyid = abac_get_keyid(id->cert);
     id->refcount = 1;
 
Index: libabac/abac_openssl.c
===================================================================
--- libabac/abac_openssl.c	(revision 7e3f5e29f503573b501f5c9f1222d71c262d6018)
+++ libabac/abac_openssl.c	(revision 9e063cb3a3c18c17cd43f2173ada363498198dca)
@@ -465,5 +465,5 @@
 X509 *abac_generate_cert(EVP_PKEY *pkey, char *cn, long validity) {
 
-    /* must have a privkey before generating an ID cert?? */
+    /* must have a privkey before generating an ID cert */
     assert(pkey);
     X509 *cert=NULL;
@@ -571,5 +571,5 @@
 
 /* check whether the cert is still valid or not and also extract what its 
-   not_before and not_after field */
+   not_before and not_after field, 0 is okay, 1 is not */
 int abac_check_validity(X509 *cert, struct tm *not_before, struct tm *not_after) {
     assert(cert);
@@ -583,7 +583,7 @@
 
     ret=_convert_time(not_before, notBefore);
-    if(ret==0) return 0;
+    if(ret==0) return 1;
     ret=_convert_time(not_after, notAfter);
-    if(ret==0) return 0;
+    if(ret==0) return 1;
 
     if((X509_cmp_current_time(notBefore) >=0) ||
Index: libabac/abac_xml.c
===================================================================
--- libabac/abac_xml.c	(revision 7e3f5e29f503573b501f5c9f1222d71c262d6018)
+++ libabac/abac_xml.c	(revision 9e063cb3a3c18c17cd43f2173ada363498198dca)
@@ -1,4 +1,6 @@
 
 /* abac_xml.c, specifically for GENI */
+
+/* in xml, rc in general is, 1 is good, 0 or -1 is bad */
 
 #define _GNU_SOURCE
@@ -56,5 +58,5 @@
 
 /* Call perror on str and exit */
-void fatal(const char *str) {
+static void fatal(const char *str) {
     perror(str);
     exit(20);
@@ -62,5 +64,5 @@
 
 /* Hex dump the contents of buf (length len) to stderr.  For debugging */
-void dump_it(xmlChar *buf, int len) {
+static void dump_it(xmlChar *buf, int len) {
     int i;
 
@@ -74,5 +76,5 @@
  * 2 * SHA_DIGEST_LENGTH +1 bytes long).  The caller is responsible for
  * allocating and deallocating each of them. */
-void sha1_to_text(xmlChar *keyid, xmlChar *text) {
+static void sha1_to_text(xmlChar *keyid, xmlChar *text) {
     int i = 0;
 
@@ -85,5 +87,5 @@
  * node passed in.  Node must point to an XML_ELEMENT node.  the return value
  * is still part of node's XML document, so treat it as read only. */
-xmlChar *get_element_content(xmlNodePtr node) {
+static xmlChar *get_element_content(xmlNodePtr node) {
     xmlNodePtr text = NULL;
 
@@ -99,5 +101,5 @@
  * is allocated and its length is returned in len.  Any values for buf and len
  * are ignored and overwritten. */
-int get_base64_field(xmlNodePtr node, xmlChar *field, 
+static int get_base64_field(xmlNodePtr node, xmlChar *field, 
 	xmlChar **buf, int *len) {
     xmlChar *txt = NULL;
@@ -130,5 +132,5 @@
  * usually used.  The length of the constructed header is returned. This is
  * used in creating a key hash from key data.*/
-int make_asn1_header(char h, size_t len, xmlChar *buf) {
+static int make_asn1_header(char h, size_t len, xmlChar *buf) {
     if ( len > 0x00ffffff) {
 	buf[0] = h;
@@ -170,5 +172,5 @@
  * keyid must be at least SHA_DIGEST_LENGTH bytes long, and the caller is
  * responsible for it. This routine returns 1 on success and 0 on failure. */
-int get_keyid_from_keyinfo(xmlDocPtr doc, xmlChar *keyid) {
+static int get_keyid_from_keyinfo(xmlDocPtr doc, xmlChar *keyid) {
     xmlNodePtr root = NULL; /* XML document root */
     xmlNodePtr node = NULL; /* Scratch XML node */
@@ -247,5 +249,5 @@
  * Takes a pointer to the XML document to check.  Similar to the examples at
  * http://www.aleksey.com/xmlsec/api/xmlsec-examples.html */
-int check_signature(xmlDocPtr doc) {
+static int check_signature(xmlDocPtr doc) {
     xmlNodePtr root = NULL;	    /* Root XML node */
     xmlNodePtr node = NULL;	    /* Scratch XML node */
@@ -317,5 +319,5 @@
  * n.  If expires is earlier, return false, else true.  If n is null, compare
  * it to the current time. */
-int check_GENI_expires(xmlChar *expires, struct tm *n) {
+static int check_GENI_expires(xmlChar *expires, struct tm *n) {
     struct tm tv;   /* Parsed expires field */
     time_t now;	    /* Now in seconds since the epoch */
@@ -340,5 +342,5 @@
  * rules.  Then add the privilege specific rules. On failure ***carray and its
  * contents are freed and *nc is set to zero.*/
-void add_privilege_credential_string(xmlChar *text_keyid, xmlChar *text_owner, 
+static void add_privilege_credential_string(xmlChar *text_keyid, xmlChar *text_owner, 
 	xmlChar *text_target, xmlChar *priv, int delegate, xmlChar ***carray,
 	int *nc) {
@@ -418,5 +420,5 @@
  * return value is an array of strings, zero-terminated (like argv) that holds
  * the RT0 strings.  It is NULL on failure. */
-xmlChar **parse_privilege(xmlDocPtr doc) {
+static xmlChar **parse_privilege(xmlDocPtr doc) {
     xmlNodePtr root = NULL;	/* XML root node */
     xmlNodePtr node = NULL;	/* XML scratch node */
@@ -533,5 +535,5 @@
 /* Compare the version string (major.minor) to the major and minor numbers, and
  * return true if the version string is >= the major minor pair. */
-int check_GENI_abac_version(xmlChar *version, int major, int minor) {
+static int check_GENI_abac_version(xmlChar *version, int major, int minor) {
     xmlChar lversion[VERSIONLEN];   /* Buffer to parse version in */
     xmlChar *lp = &lversion[0];	    /* strsep needs a pointer it can modify */
@@ -623,5 +625,5 @@
  * NULL. Demultiplexed to parse_privilege or parse_abac to do the parsing and
  * uses check_signature to confirm the sig. */
-xmlChar **read_credential(char *infile, xmlChar **xml) {
+static xmlChar **read_credential(char *infile, xmlChar **xml) {
     xmlDocPtr doc = xmlParseFile(infile);   /* Parse the document */
     xmlNodePtr node = NULL;		    /* XML scratch node */
@@ -660,58 +662,4 @@
 }
 
-char **my_read_credential(char *infile, char **xml) {
-    return (char **)read_credential(infile, (xmlChar **)xml);
-}
-
-
-/* Straight off http://www.aleksey.com/xmlsec/api/xmlsec-examples.html .
- * Voodoo.  But call it. */
-int init_xmlsec() {
-    /* Init xmlsec library */
-    if(xmlSecInit() < 0) {
-        fprintf(stderr, "Error: xmlsec initialization failed.\n");
-        return(-1);
-    }
-
-    /* Check loaded library version */
-    if(xmlSecCheckVersion() != 1) {
-        fprintf(stderr,
-		"Error: loaded xmlsec library version is not compatible.\n");
-        return(-1);
-    }
-
-    /* Load default crypto engine if we are supporting dynamic
-     * loading for xmlsec-crypto libraries. Use the crypto library
-     * name ("openssl", "nss", etc.) to load corresponding 
-     * xmlsec-crypto library.
-     */
-#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
-    if(xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
-        fprintf(stderr, "Error: unable to load default xmlsec-crypto library. "
-		"Make sure\n" 
-		"that you have it installed and check shared libraries path\n"
-		"(LD_LIBRARY_PATH) envornment variable.\n");
-        return(-1);     
-    }
-#endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */
-
-    /* Init crypto library */
-    if(xmlSecCryptoAppInit(NULL) < 0) {
-        fprintf(stderr, "Error: crypto initialization failed.\n");
-        return(-1);
-    }
-
-    /* Init xmlsec-crypto library */
-    if(xmlSecCryptoInit() < 0) {
-        fprintf(stderr, "Error: xmlsec-crypto initialization failed.\n");
-        return(-1);
-    }
-    return 0;
-}
-
-int deinit_xmlsec() {
-  /* no op for now */
-    return 0;
-}
 
 /* from Ted's writer */
@@ -766,5 +714,5 @@
  * using xmlFree().
  */
-xmlChar *minimal_xml_escaping(xmlChar *str) {
+static xmlChar *minimal_xml_escaping(xmlChar *str) {
     /* A quickie translation table with the character to escape, the output
      * string and the length of the output in it. The table is initialized with
@@ -821,5 +769,5 @@
  * certlen is the length of cert.  Returns the XML. Caller is responsible for
  * freeing it. */
-char *make_credential(xmlChar *rt0, int secs, xmlSecByte *cert, 
+static char *make_credential(xmlChar *rt0, int secs, xmlSecByte *cert, 
 	xmlSecSize certlen) {
     xmlDocPtr doc = NULL;	/* parsed XML document */
@@ -894,10 +842,4 @@
 }
 
-char *my_make_credential(char* rt0, int secs, char* cert, int certlen)
-{
-    return make_credential((xmlChar *)rt0, secs, (xmlSecByte *)cert, (xmlSecSize)certlen);
-}
-
-
 #define CERTSIZE 4096
 /* Read a file into a the dynamically allocated array buf.  Whatever was in buf
@@ -905,5 +847,5 @@
  * buf contains as much of the contents of filename as possible and len is the
  * length of it.  The caller must free() buf. buf is zero terminated.*/
-void read_cert(char *filename, char **buf, int *len) {
+static void read_cert(char *filename, char **buf, int *len) {
     FILE *cert = NULL;
     char *nbuf = NULL;
@@ -946,5 +888,68 @@
 
 
-/******** helper functions **************************/
+/******** helper functions used by libabac **********************/
+
+/* Straight off http://www.aleksey.com/xmlsec/api/xmlsec-examples.html .
+ * Voodoo.  But call it. */
+int init_xmlsec() {
+    /* Init xmlsec library */
+    if(xmlSecInit() < 0) {
+        fprintf(stderr, "Error: xmlsec initialization failed.\n");
+        return(-1);
+    }
+
+    /* Check loaded library version */
+    if(xmlSecCheckVersion() != 1) {
+        fprintf(stderr,
+		"Error: loaded xmlsec library version is not compatible.\n");
+        return(-1);
+    }
+
+    /* Load default crypto engine if we are supporting dynamic
+     * loading for xmlsec-crypto libraries. Use the crypto library
+     * name ("openssl", "nss", etc.) to load corresponding 
+     * xmlsec-crypto library.
+     */
+#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
+    if(xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
+        fprintf(stderr, "Error: unable to load default xmlsec-crypto library. "
+		"Make sure\n" 
+		"that you have it installed and check shared libraries path\n"
+		"(LD_LIBRARY_PATH) envornment variable.\n");
+        return(-1);     
+    }
+#endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */
+
+    /* Init crypto library */
+    if(xmlSecCryptoAppInit(NULL) < 0) {
+        fprintf(stderr, "Error: crypto initialization failed.\n");
+        return(-1);
+    }
+
+    /* Init xmlsec-crypto library */
+    if(xmlSecCryptoInit() < 0) {
+        fprintf(stderr, "Error: xmlsec-crypto initialization failed.\n");
+        return(-1);
+    }
+    return 0;
+}
+
+int deinit_xmlsec() {
+  /* no op for now */
+    return 0;
+}
+
+
+/* to cast the parameters */
+char **my_read_credential(char *infile, char **xml) {
+    return (char **)read_credential(infile, (xmlChar **)xml);
+}
+
+char *my_make_credential(char* rt0, int secs, char* cert, int certlen)
+{
+    return make_credential((xmlChar *)rt0, secs, (xmlSecByte *)cert, (xmlSecSize)certlen);
+}
+
+/* parse the xml blob and extract keyid */ 
 char *get_keyid_from_xml(char *xml) {
     xmlDocPtr doc=xmlParseMemory(xml,strlen(xml));
@@ -963,5 +968,7 @@
 }
 
-/* validity time in xml from current time */
+/* parse xml and get the expected expiration time and returns 
+ * (expiration time-current time)
+ */
 long get_validity_from_xml(char *xml) {
     xmlDocPtr doc=xmlParseMemory(xml,strlen(xml));
@@ -991,4 +998,5 @@
 }
 
+/* parse xml structure and extract the attribute rules */
 char **get_rt0_from_xml(char *xml) {
     xmlDocPtr doc=xmlParseMemory(xml,strlen(xml));
@@ -1022,2 +1030,4 @@
     return (char **)rv;
 }
+
+
