Index: libabac/abac.h
===================================================================
--- libabac/abac.h	(revision 9f78e4c5cf0cff152f251f1b3b25329716e9c319)
+++ libabac/abac.h	(revision e50f807d08d2317f946f7886c04a062102b5e485)
@@ -79,4 +79,5 @@
 char *abac_role_string(abac_role_t *role);
 char *abac_role_linked_role(abac_role_t *role);
+char *abac_role_linking_role(abac_role_t *role);
 char *abac_role_role_name(abac_role_t *role);
 char *abac_role_principal(abac_role_t *role);
@@ -203,4 +204,14 @@
 int abac_attribute_write_file(abac_attribute_t *attr, const char *fname);
 
+/*
+ * Return the number of tail strings
+ */
+int abac_attribute_get_ntails(abac_attribute_t *a);
+
+/*
+ * Return the nth tail string or NULL if it is undefined
+ */
+char *abac_attribute_get_tail_n(abac_attribute_t *a, int n);
+
 // get chunked cert
 // returns 0 if the cert isn't baked
Index: libabac/abac_attribute.c
===================================================================
--- libabac/abac_attribute.c	(revision 9f78e4c5cf0cff152f251f1b3b25329716e9c319)
+++ libabac/abac_attribute.c	(revision e50f807d08d2317f946f7886c04a062102b5e485)
@@ -148,17 +148,23 @@
     return attr->head_string;
 }
+
 /*
-void abac_attribute_set_tail(abac_attribute_t *attr, char *string)
-{
-    assert(attr);
-    attr->tail_string=string;
-}
-
-char *abac_attribute_get_tail(abac_attribute_t *attr)
-{
-    assert(attr);
-    return attr->tail_string;
-}
-*/
+ * Return the number of tail strings
+ */
+int abac_attribute_get_ntails(abac_attribute_t *attr) {
+    assert(attr);
+    return attr->ntails;
+}
+
+/*
+ * Return the nth tail string or NULL if it is undefined
+ */
+
+char *abac_attribute_get_tail_n(abac_attribute_t *attr, int n) {
+    assert(attr);
+    if ( n < 0 || n > attr->ntails) return NULL;
+    return attr->tail_strings[n];
+}
+
 
 /* A.b->C, return copy of a A */
@@ -232,11 +238,9 @@
         return 0; 
 
-    char *role_string = abac_attribute_role_string(attr);
-
 /* Make an new GENI abac credential with the rt0 rule that expires secs from
  * now.  cert is the PEM encoded X.509 of the issuer's certificate as a string.
  * certlen is the length of cert.  Returns the XML. Caller is responsible for
  * freeing it. */
-    char *attr_cert=my_make_credential(role_string, attr->validity, (char *)id_chunk.ptr, id_chunk.len);
+    char *attr_cert=make_credential(attr, attr->validity, (char *)id_chunk.ptr, id_chunk.len);
 
     if (attr_cert == NULL)
@@ -246,5 +250,5 @@
     attr->cert.len = strlen(attr_cert);
 
-    free(role_string);
+    /* free(role_string); */
     return 1;
 }
@@ -316,5 +320,5 @@
     char *rt0=NULL;
 
-    char **rt0s=my_read_credential((void *)id_certs,filename, &xml);
+    char **rt0s=read_credential((void *)id_certs,filename, &xml);
     if(rt0s == NULL) return alist;
     if(xml == NULL || strlen(xml)==0) return alist;
Index: libabac/abac_role.c
===================================================================
--- libabac/abac_role.c	(revision 9f78e4c5cf0cff152f251f1b3b25329716e9c319)
+++ libabac/abac_role.c	(revision e50f807d08d2317f946f7886c04a062102b5e485)
@@ -353,4 +353,13 @@
 
 /**
+ * Returns the linkinged part of a linking role. For instance, if the role is
+ * A.r1.r2, this returns r1.
+ */
+char *abac_role_linking_role(abac_role_t *role) {
+    assert(role != NULL);
+    return role->linked_role;
+}
+
+/**
  * Returns the principal part of a role. The stuff before the first dot.
  */
Index: libabac/abac_xml.c
===================================================================
--- libabac/abac_xml.c	(revision 9f78e4c5cf0cff152f251f1b3b25329716e9c319)
+++ libabac/abac_xml.c	(revision e50f807d08d2317f946f7886c04a062102b5e485)
@@ -27,4 +27,7 @@
 
 #include <openssl/sha.h>
+
+#include "abac.h"
+#include "abac_util.h"
 
 extern int abac_verifier_load_id_chars(void *, char*); 
@@ -62,9 +65,110 @@
 #define VERSIONLEN 256
 
-/* Call perror on str and exit */
-static void fatal(const char *str) {
-    perror(str);
-    exit(20);
-}
+/* XML template for a new RT0 credential.  Fill in the RT0 to store (XML
+ * escaped) and the expiration time (formated using strftime_format and
+ * strftime). */
+#define template_v10 "<signed-credential>\n"\
+"    <credential xml:id=\"ref0\">\n"\
+"	<type>abac</type>\n"\
+"	<version>1.0</version>\n"\
+"	<expires>%s</expires>\n"\
+"	<rt0>%s</rt0>\n"\
+"    </credential>\n"\
+"    <signatures>\n"\
+"	<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\">\n"\
+"	    <SignedInfo>\n"\
+"		<CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/>\n"\
+"		<SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/>\n"\
+"		<Reference URI=\"#ref0\">\n"\
+"		    <Transforms>\n"\
+"			<Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/>\n"\
+"		    </Transforms>\n"\
+"		    <DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>\n"\
+"		    <DigestValue/>\n"\
+"		</Reference>\n"\
+"	    </SignedInfo>\n"\
+"	    <SignatureValue/>\n"\
+"	    <KeyInfo>\n"\
+"	      <KeyValue/>\n"\
+"		<X509Data>\n"\
+"		    <X509Certificate/>\n"\
+"		    <X509SubjectName/>\n"\
+"		    <X509IssuerSerial/>\n"\
+"		</X509Data>\n"\
+"	    </KeyInfo>\n"\
+"	</Signature>\n"\
+"    </signatures>\n"\
+"</signed-credential>"
+
+/* XML template for a new RT0 credential.  Fill in the RT0 to store (XML
+ * escaped) and the expiration time (formated using strftime_format and
+ * strftime). */
+#define template_v11 "<signed-credential>\n"\
+"    <credential xml:id=\"ref0\">\n"\
+"	<type>abac</type>\n"\
+"	<serial/>\n"\
+"	<owner_gid/>\n"\
+"	<target_gid/>\n"\
+"	<uuid/>\n"\
+"	<expires>%s</expires>\n"\
+"	<rt0>\n"\
+"	    <version>1.1</version>\n"\
+"	    %s\n"\
+"	</rt0>\n"\
+"    </credential>\n"\
+"    <signatures>\n"\
+"	<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\">\n"\
+"	    <SignedInfo>\n"\
+"		<CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/>\n"\
+"		<SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/>\n"\
+"		<Reference URI=\"#ref0\">\n"\
+"		    <Transforms>\n"\
+"			<Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/>\n"\
+"		    </Transforms>\n"\
+"		    <DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>\n"\
+"		    <DigestValue/>\n"\
+"		</Reference>\n"\
+"	    </SignedInfo>\n"\
+"	    <SignatureValue/>\n"\
+"	    <KeyInfo>\n"\
+"	      <KeyValue/>\n"\
+"		<X509Data>\n"\
+"		    <X509Certificate/>\n"\
+"		    <X509SubjectName/>\n"\
+"		    <X509IssuerSerial/>\n"\
+"		</X509Data>\n"\
+"	    </KeyInfo>\n"\
+"	</Signature>\n"\
+"    </signatures>\n"\
+"</signed-credential>"
+
+xmlChar *encode_rt0_xml_v10(abac_attribute_t *);
+xmlChar *encode_rt0_xml_v11(abac_attribute_t *);
+xmlChar **parse_rt0_xml_v10(xmlNodePtr);
+xmlChar **parse_rt0_xml_v11(xmlNodePtr);
+
+typedef struct {
+    char *version;
+    xmlChar *(*rt0_to_xml)(abac_attribute_t *);
+    xmlChar **(*xml_to_rt0)(xmlNodePtr);
+    char *out_template;
+} GENI_xml_processing_t;
+
+GENI_xml_processing_t xml_proc[] = {
+    { "1.0", encode_rt0_xml_v10, parse_rt0_xml_v10, template_v10},
+    { "1.1", encode_rt0_xml_v11, parse_rt0_xml_v11, template_v11},
+    { NULL, NULL, NULL},
+};
+
+GENI_xml_processing_t *get_xml_processing(char *ver) {
+    int i ;
+
+    for (i = 0; xml_proc[i].version; i++) {
+	if (!strcmp(xml_proc[i].version, ver))
+	    return &xml_proc[i];
+    }
+    return NULL;
+}
+
 
 /* Hex dump the contents of buf (length len) to stderr.  For debugging */
@@ -619,4 +723,151 @@
     else return 0;                                                    
 }  
+
+/*
+ * If n has a child that is an element named name, return a pointer to it,
+ * other wise return NULL.
+ */
+static xmlNodePtr get_direct_child(xmlNodePtr n, xmlChar *name) {
+    xmlNodePtr c = NULL;
+
+    if ( !n ) return NULL;
+
+    for (c = n->children; c; c = c->next) {
+	if ( c->type != XML_ELEMENT_NODE ) 
+	    continue;
+	if ( !strcmp((char *) c->name, (char *) name)) 
+	    return c;
+    }
+    return NULL;
+}
+
+xmlChar **parse_rt0_xml_v10(xmlNodePtr n) {
+    xmlChar *txt;
+    xmlChar **rv = NULL;
+
+    /* read the RT0 and return it */
+    if ( !(txt = get_element_content(n)) ) return NULL;
+
+    if ( !(rv = malloc(2 * sizeof(xmlChar *)))) return NULL;
+    if (!(rv[0] = malloc(strlen((char *) txt)+1))) {
+	free(rv);
+	return NULL;
+    }
+    strcpy((char *) rv[0], (char *) txt);
+    rv[1] = NULL;
+    return rv;
+}
+
+static int role_len(xmlChar *rn) {
+    xmlChar *p;
+    int len = 0;
+
+    for (p = rn; *p; p++) 
+	if ( !isspace(*p) ) len++;
+    return len;
+}
+
+static int term_len(xmlNodePtr n) {
+    int len = 0;
+    xmlNodePtr c = NULL;/* Scratch */
+
+    for (c = n->children; c; c = c->next) {
+	if ( c->type != XML_ELEMENT_NODE ) 
+	    continue;
+	if ( !strcmp((char *) c->name, "ABACprincipal")) {
+	    xmlNodePtr k = get_direct_child(c, "keyid");
+	    if ( !k ) return -1;
+	    len += role_len(get_element_content(k));
+	} else if (!strcmp((char *) c->name, "role")) {
+	    len += role_len(get_element_content(c)) +1;
+	} else if (!strcmp((char *) c->name, "linking_role")) {
+	    len += role_len(get_element_content(c)) +1;
+	}
+    }
+    return len;
+}
+
+
+static xmlChar *role_copy(xmlChar *rn, xmlChar *dest) {
+    while (*rn) {
+	if (!isspace(*rn)) *dest++ = *rn;
+	rn++;
+    }
+    return dest;
+}
+
+static xmlChar *term_copy(xmlNodePtr n, xmlChar *dest) {
+    xmlNodePtr p = get_direct_child(n, "ABACprincipal");
+
+    if ( !p ) return NULL;
+    if ( !(p = get_direct_child(p, "keyid"))) return NULL;
+    if ( !(dest = role_copy(get_element_content(p), dest))) return NULL;
+    if ( (p = get_direct_child(n, "linking_role"))) {
+	*dest++ = '.';
+	if ( !(dest = role_copy(get_element_content(p), dest))) return NULL;
+    }
+    if ( (p = get_direct_child(n, "role"))) {
+	*dest++ = '.';
+	if ( !(dest = role_copy(get_element_content(p), dest))) return NULL;
+    }
+    return dest;
+}
+
+static xmlChar *append_and_move(xmlChar *d, xmlChar *a, int sz) {
+    strncat((char *) d, (char *) a, sz);
+    return d + sz;
+}
+
+xmlChar **parse_rt0_xml_v11(xmlNodePtr n) {
+    int len = 3;    /* Length of the RT0 string we're building initially 3 for
+		       the <- and end-of-string */
+    int heads = 0;  /* number of tails so far */
+    int tails = 0;  /* number of tails so far */
+    xmlNodePtr c = NULL;/* Scratch */
+    xmlChar **rv = NULL;
+    xmlChar *d = NULL;
+
+    if ( !n ) return NULL;
+
+    for (c = n->children; c; c = c->next) {
+	if ( c->type != XML_ELEMENT_NODE ) 
+	    continue;
+	if ( !strcmp((char *) c->name, "head") ) {
+	    len += term_len(c);
+	    heads ++;
+	} else if (!strcmp((char *) c->name, "tail")) {
+	    len += term_len(c);
+	    /* if more than one tail, add space for " & " */
+	    if ( tails++) len += 3; 
+	}
+    }
+    if ( heads != 1 || tails < 1) return NULL;
+    if ( !(rv = malloc(2 * sizeof(xmlChar *)))) return NULL;
+    if (!(rv[0] = malloc(len)) ) {
+	free(rv);
+	return NULL;
+    }
+    d = rv[0];
+    if ( !( c = get_direct_child(n, "head"))) goto fail;
+    if ( !(d = term_copy(c, d))) goto fail;
+    d = append_and_move(d, "<-", 2);
+    tails = 0;
+    for (c = n->children; c; c = c->next) {
+	if ( c->type != XML_ELEMENT_NODE ) 
+	    continue;
+	if ( !strcmp((char *) c->name, "tail") ) {
+	    /* if more than one tail, add " & " */
+	    if ( tails++) 
+		d = append_and_move(d, " & ", 3);
+	    if ( !(d = term_copy(c, d))) goto fail;
+	}
+    }
+    return rv;
+
+fail:
+    free(rv[0]);
+    free(rv);
+    return NULL;
+} 
 /*
  * Parse an ABAC credential (that has had its signature checked.  Make sure it
@@ -634,4 +885,5 @@
     xmlChar *txt;		/* rt0 content */
     xmlChar **rv = NULL;	/* return value */
+    GENI_xml_processing_t *proc = NULL; /* Specialization for version number */
     int ncred = 0;		/* number of creds in rv */
     int i = 0;			/* Scratch (used only in fail:)  */
@@ -647,26 +899,27 @@
     if ( !(node = xmlSecFindNode(root, (xmlChar *) GENI_credential, NULL)))
 	goto fail;
-    if ( !(expires = xmlSecFindNode(node, (xmlChar *) GENI_expires, NULL)))
-	goto fail;
-    if ( !(rt0 = xmlSecFindNode(node, (xmlChar *) GENI_rt0, NULL)))
-	goto fail;
-    if ( !(version = xmlSecFindNode(node, (xmlChar *) GENI_version, NULL)))
-	goto fail;
-
-    /* Check the version and expiration */
-    if ( !check_GENI_abac_version(get_element_content(version), 1, 0)) 
+    if ( !(expires = get_direct_child(node, (xmlChar *) GENI_expires)))
 	goto fail;
     if ( !check_GENI_expires(get_element_content(expires), NULL))
 	goto fail;
 
+    if ( !(rt0 = get_direct_child(node, (xmlChar *) GENI_rt0))) 
+	goto fail;
+    /* There are two places to look for a version.  The credential node and the
+     * rt0 node that is a child of the credential node.  The version element is
+     * only under the credential in the misdefined GENI abac v1.0. */
+    if ( !(version = get_direct_child(node, (xmlChar *) GENI_version))) {
+	if ( !(version = get_direct_child(rt0, (xmlChar *) GENI_version))) 
+	    goto fail;
+    }
+
+    /* Pick parsing specialization based on the version.  If we can't resolve a
+     * processor, this is an unknown version. */
+    if ( !(proc = get_xml_processing(get_element_content(version))))
+	goto fail;
+
     /* read the RT0 and return it */
-    if ( !(txt = get_element_content(rt0)) ) goto fail;
-
-    if ( !(rv = malloc(2 * sizeof(xmlChar *)))) goto fail;
-    if (!(rv[0] = malloc(strlen((char *) txt)+1))) goto fail;
-    ncred++;
-
-    strcpy((char *) rv[0], (char *) txt);
-    rv[1] = NULL;
+    if ( !(rv = proc->xml_to_rt0(rt0)) ) goto fail;
+    ncred=1;
 
     /* extract issuer pem and insert */
@@ -690,5 +943,7 @@
  * NULL. Demultiplexed to parse_privilege or parse_abac to do the parsing and
  * uses check_signature to confirm the sig. */
-static xmlChar **read_credential(void *ctxt_id_certs, char *infile, xmlChar **xml) {
+char **read_credential(void *ctxt_id_certs, char *infile, 
+	char **in_xml) {
+    xmlChar **xml = in_xml;		    /* Cast */
     xmlDocPtr doc = xmlParseFile(infile);   /* Parse the document */
     xmlNodePtr node = NULL;		    /* XML scratch node */
@@ -724,5 +979,5 @@
 fail:
     xmlFreeDoc(doc);
-    return rv;
+    return (char **) rv;
 }
 
@@ -734,41 +989,4 @@
 /* Maximum version len */
 #define VERSIONLEN 256
-
-/* XML template for a new RT0 credential.  Fill in the RT0 to store (XML
- * escaped) and the expiration time (formated using strftime_format and
- * strftime). */
-xmlChar *template = (xmlChar *) (
-"<signed-credential>\n"
-"    <credential xml:id=\"ref0\">\n"
-"	<type>abac</type>\n"
-"	<version>1.0</version>\n"
-"	<expires>%s</expires>\n"
-"	<rt0>%s</rt0>\n"
-"    </credential>\n"
-"    <signatures>\n"
-"	<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\">\n"
-"	    <SignedInfo>\n"
-"		<CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/>\n"
-"		<SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/>\n"
-"		<Reference URI=\"#ref0\">\n"
-"		    <Transforms>\n"
-"			<Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/>\n"
-"		    </Transforms>\n"
-"		    <DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>\n"
-"		    <DigestValue/>\n"
-"		</Reference>\n"
-"	    </SignedInfo>\n"
-"	    <SignatureValue/>\n"
-"	    <KeyInfo>\n"
-"	      <KeyValue/>\n"
-"		<X509Data>\n"
-"		    <X509Certificate/>\n"
-"		    <X509SubjectName/>\n"
-"		    <X509IssuerSerial/>\n"
-"		</X509Data>\n"
-"	    </KeyInfo>\n"
-"	</Signature>\n"
-"    </signatures>\n"
-"</signed-credential>");
 
 char *strftime_fmt = "%FT%TZ";
@@ -830,15 +1048,114 @@
 }
 
+xmlChar *encode_rt0_xml_v10(abac_attribute_t *a) {
+    return minimal_xml_escaping(abac_attribute_role_string(a));
+}
+
+static char *head_template = 
+"<head>\n"
+"   <ABACprincipal><keyid>%s</keyid></ABACprincipal>\n"
+"   <role>%s</role>\n"
+"</head>\n";
+
+static char *tail_template[] = {
+"<tail>\n"
+"   <ABACprincipal><keyid>%s</keyid></ABACprincipal>\n"
+"</tail>\n",
+"<tail>\n"
+"   <ABACprincipal><keyid>%s</keyid></ABACprincipal>\n"
+"   <role>%s</role>\n"
+"</tail>\n",
+"<tail>\n"
+"   <ABACprincipal><keyid>%s</keyid></ABACprincipal>\n"
+"   <role>%s</role>\n"
+"   <linking_role>%s</linking_role>\n"
+"</tail>\n",
+};
+
+xmlChar *encode_rt0_xml_v11(abac_attribute_t *a) {
+    int htlen = strlen(head_template);
+    int ttlen = strlen(tail_template[2]);
+    int sz = strlen(abac_attribute_get_head(a)) + htlen;
+    int ntails = abac_attribute_get_ntails(a);
+    char *princ_role[2];
+    char *copy = abac_xstrdup(abac_attribute_get_head(a));
+    int npr = 2;
+    char *tmp = NULL;
+    char *rv = NULL;
+    int i;
+
+    for ( i = 0 ; i < ntails; i++)
+	sz += strlen(abac_attribute_get_tail_n(a, i)) + ttlen;
+
+    if ( !(rv = (char *) xmlMalloc(sz)) ) goto fail;
+    if ( !(tmp = (char *) xmlMalloc(sz)) ) goto fail;
+
+    abac_split(copy, ".", princ_role, &npr);
+    if ( npr != 2) 
+	goto fail;
+
+    sz -= snprintf(rv, sz, head_template, princ_role[0], princ_role[1]);
+
+    for ( i = 0 ; i < ntails; i++) {
+	abac_role_t *r = abac_role_from_string(abac_attribute_get_tail_n(a,i));
+	int ts;
+
+	if ( !r )
+	    goto fail;
+
+	if ( abac_role_is_principal(r)) {
+	    char *p = minimal_xml_escaping(abac_role_principal(r));
+
+	    ts = snprintf(tmp, sz, tail_template[0], p);
+	    free(p);
+	} else if (abac_role_is_role(r)) {
+	    char *p = minimal_xml_escaping(abac_role_principal(r));
+	    char *ro = minimal_xml_escaping(abac_role_role_name(r));
+
+	    ts = snprintf(tmp, sz, tail_template[1], p, ro);
+	    free(p);
+	    free(ro);
+	} else if (abac_role_is_linking(r)) {
+	    char *p = minimal_xml_escaping(abac_role_principal(r));
+	    char *ro = minimal_xml_escaping(abac_role_role_name(r));
+	    char *li = minimal_xml_escaping(abac_role_linking_role(r));
+
+	    ts = snprintf(tmp, sz, tail_template[2], p, ro, li);
+	    free(p);
+	    free(ro);
+	    free(li);
+	}
+
+	free(r);
+
+	if ( ts < 0 ) 
+	    goto fail;
+
+	strncat(rv, tmp, sz);
+	sz -= ts;
+    }
+    free(tmp);
+    return (xmlChar *) rv;
+
+fail:
+    if (rv ) free(rv);
+    if (tmp) free(tmp);
+    return NULL;
+}
+
 /* Make an new GENI abac credential with the rt0 rule that expires secs from
  * now.  cert is the PEM encoded X.509 of the issuer's certificate as a string.
  * certlen is the length of cert.  Returns the XML. Caller is responsible for
  * freeing it. */
-static char *make_credential(xmlChar *rt0, int secs, xmlSecByte *cert, 
-	xmlSecSize certlen) {
+char *make_credential(abac_attribute_t *attr, int secs, char *in_cert, 
+	int in_certlen) {
+    xmlSecByte *cert = (xmlSecByte *) in_cert; /* Cast of certificate */
+    xmlSecSize certlen = (xmlSecSize) in_certlen; /* Cast of len */
     xmlDocPtr doc = NULL;	/* parsed XML document */
     xmlNodePtr root = NULL;	/* Root of the document */
     xmlNodePtr signNode = NULL;	/* <Signature> element */
     xmlSecDSigCtxPtr dsigCtx = NULL;  /* Signing context */
-    xmlChar *rt0_escaped = minimal_xml_escaping(rt0); /* RT0, escaped */
+    /*xmlChar *rt0_escaped = minimal_xml_escaping(rt0); /* RT0, escaped */
+    xmlChar *rt0_xml = NULL;	/* attr's RT0 as xml */
     xmlChar *rv = NULL;		/* return value */
     time_t exp;			/* expriation time (seconds since epoch) */
@@ -848,8 +1165,12 @@
     int len = 0;		/* length of the populated template (temp) */
 
-    if ( !rt0_escaped) goto fail;
+    GENI_xml_processing_t *proc = get_xml_processing("1.1");
+
+    if ( !proc ) goto fail;
+    if ( !(rt0_xml = proc->rt0_to_xml(attr))) goto fail;
 
     /* Calculate the length of the populated template and allocate it */
-    len = strlen((char *) template)+EXPIRESLEN+strlen((char *) rt0_escaped)+1;
+    len = strlen((char *) proc->out_template)+EXPIRESLEN+
+	strlen((char *) rt0_xml)+1;
 
     if ( !(temp = malloc(len)) )
@@ -865,5 +1186,5 @@
 
     /* Populate template with  expiration and escaped rt0 */
-    snprintf(temp, len, (char *) template, estr, (char *) rt0_escaped);
+    snprintf(temp, len, proc->out_template, estr, (char *) rt0_xml);
 
     /* parse the populated template */
@@ -902,5 +1223,5 @@
 	xmlSecDSigCtxDestroy(dsigCtx);
     if ( doc) xmlFreeDoc(doc);
-    if (rt0_escaped) xmlFree(rt0_escaped);
+    if (rt0_xml) xmlFree(rt0_xml);
     if ( temp) free(temp);
     return (char *) rv;
@@ -1012,14 +1333,4 @@
 }
 
-
-/* to cast the parameters */
-char **my_read_credential(void *ctxt_id_certs, char *infile, char **xml) {
-    return (char **)read_credential(ctxt_id_certs, 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 */ 
Index: libabac/abac_xml.h
===================================================================
--- libabac/abac_xml.h	(revision 9f78e4c5cf0cff152f251f1b3b25329716e9c319)
+++ libabac/abac_xml.h	(revision e50f807d08d2317f946f7886c04a062102b5e485)
@@ -4,10 +4,11 @@
 
 extern void read_cert(char *filename, char **buf, int *len);
-extern char *my_make_credential(char* rt0, int secs, char* cert, int certlen);
+extern char *make_credential(abac_attribute_t* rt0, int secs, char* cert, 
+	int certlen);
 extern void fatal(const char *str);
 
 extern int init_xmlsec();
 extern int deinit_xmlsec();
-extern char **my_read_credential(void *id_certs, char *infile, char **xml);
+extern char **read_credential(void *id_certs, char *infile, char **xml);
 
 extern char **get_rt0_from_xml(void *id_certs,char *xml);
