Index: java/net/deterlab/abac/GENICredential.java
===================================================================
--- java/net/deterlab/abac/GENICredential.java	(revision 797bebe2efe124193658b4872505d50276554e78)
+++ java/net/deterlab/abac/GENICredential.java	(revision 61f21c5edc41e5de819dd3b8a28651883c5685f1)
@@ -50,5 +50,10 @@
 
     /**
-     * Keyselector implementation from the web
+     * X509KeySelector implementation from
+     * http://www.outsourcingi.com/art-271-Programming-With-the-Java-XML-Digital-Signature-API.html
+     * .
+     *
+     * Straight ahead extraction of a key from an X509 cert, but it is their
+     * code and hard to improve on.
      */
     protected class X509KeySelector extends KeySelector {
@@ -133,4 +138,7 @@
 	    throw new IOException("Cannot get DocumentBuilderFactory!?");
 	try {
+	    /* Note this setting is required to find the properly
+	     * namespace-scoped signature block in the credential.
+	     */
 	    dbf.setNamespaceAware(true);
 	    if ( (db = dbf.newDocumentBuilder()) == null ) 
@@ -380,4 +388,76 @@
 
     /**
+     * Encode the abac credential's XML.  This is straight line code that
+     * directly builds the credential.
+     * @return a Node, the place to attach signatures
+     * @throws IOException if any of the XML construction fails
+     */
+    protected Node make_rt0_content() throws IOException {
+	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+	DocumentBuilder db = null;
+	SimpleDateFormat df = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss'Z'");
+	StringBuffer expBuf = new StringBuffer();
+
+	/* This is a weirdness to cope with the GENI format.  They have a naked
+	 * xml:id specifier without any namespace declarations in the
+	 * credential.  Notice that this is the opposite of the setting used in
+	 * init to read a credential. */
+	dbf.setNamespaceAware(false);
+
+	if ( dbf == null ) 
+	    throw new IOException("Cannot get DocumentBuilderFactory!?");
+
+	try {
+	    db = dbf.newDocumentBuilder();
+	}
+	catch (ParserConfigurationException pe) {
+	    throw new IOException("Cannot get DocumentBuilder!?" + 
+		    pe.getMessage());
+	}
+
+	doc = db.newDocument();
+	if ( doc == null ) 
+	    throw new IOException("No Document");
+
+	Element root = doc.createElement("signed-credential"); 
+	Element cred = doc.createElement("credential");
+	Element sig = doc.createElement("signatures");
+	Element e = doc.createElement("type");
+	Node text = doc.createTextNode("abac");
+
+	doc.appendChild(root);
+
+	cred.setAttribute("xml:id", "ref0");
+	/* So that the signing code can find the section to sign */
+	cred.setIdAttribute("xml:id", true);
+
+	root.appendChild(cred);
+	e.appendChild(text);
+	cred.appendChild(e);
+
+	/* XXX: pass in valid time */
+	df.format(new Date(System.currentTimeMillis() 
+		    + (3600L * 1000L * 24L * 365L)), expBuf, 
+		new FieldPosition(0));
+	e = doc.createElement("expires");
+	text = doc.createTextNode(expBuf.toString());
+	e.appendChild(text);
+	cred.appendChild(e);
+
+	e = doc.createElement("version");
+	text = doc.createTextNode("1.0");
+	e.appendChild(text);
+	cred.appendChild(e);
+
+	e = doc.createElement("rt0");
+	text = doc.createTextNode(m_head + "<-" + m_tail);
+	e.appendChild(text);
+	cred.appendChild(e);
+
+	root.appendChild(sig);
+	return sig;
+    }
+
+    /**
      * Create a certificate from this credential issued by the given identity.
      * Note that catching java.security.GeneralSecurityException catches most
@@ -398,16 +478,43 @@
 	       NoSuchProviderException, NoSuchAlgorithmException,
 	       SignatureException, InvalidKeyException {
+	X509Certificate cert = i.getCertificate();
+	KeyPair kp = i.getKeyPair();
+	PublicKey pubKey = null;
+	PrivateKey privKey = null;
+	if ( cert == null ) 
+	    throw new IOException("No credential in identity?");
+	if ( kp == null ) 
+	    throw new IOException("No keypair in identity?");
+
+	pubKey = kp.getPublic();
+	if ((privKey = kp.getPrivate()) == null ) 
+	    throw new IOException("No private ket in identity");
+
+	XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
+	Reference ref = null;
+	SignedInfo si = null;
+	KeyInfoFactory kif = fac.getKeyInfoFactory();
+	List x509Content = new ArrayList();
+	List keyInfo = new ArrayList();
+	x509Content.add(cert.getSubjectX500Principal().getName());
+	x509Content.add(cert);
+	X509Data xd = kif.newX509Data(x509Content);
+	KeyValue kv = null;
+
 	try {
-	    SimpleDateFormat df = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss'Z'");
-	    StringBuffer expBuf = new StringBuffer();
-	    X509Certificate cert = i.getCertificate();
-	    KeyPair kp = i.getKeyPair();
-	    if ( cert == null ) 
-		throw new IOException("No credential in identity?");
-	    if ( kp == null ) 
-		throw new IOException("No keypair in identity?");
-
-	    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
-	    Reference ref = fac.newReference("#ref0", 
+	    kv = kif.newKeyValue(pubKey);
+	} 
+	catch (KeyException ke) {
+	    throw new InvalidKeyException("Unsupported key format " + 
+		    ke.getMessage());
+	}
+
+	Collections.addAll(keyInfo, kv, xd);
+
+	KeyInfo ki = kif.newKeyInfo(keyInfo);
+	Node sig = make_rt0_content();
+
+	try {
+	    ref = fac.newReference("#ref0", 
 		    fac.newDigestMethod(DigestMethod.SHA1, null),
 		    Collections.singletonList(
@@ -416,5 +523,5 @@
 		    null, null);
 
-	    SignedInfo si = fac.newSignedInfo(
+	    si = fac.newSignedInfo(
 		    fac.newCanonicalizationMethod(
 			CanonicalizationMethod.INCLUSIVE,
@@ -422,60 +529,11 @@
 		    fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
 		    Collections.singletonList(ref));
-	    KeyInfoFactory kif = fac.getKeyInfoFactory();
-	    List x509Content = new ArrayList();
-	    x509Content.add(cert.getSubjectX500Principal().getName());
-	    x509Content.add(cert);
-	    X509Data xd = kif.newX509Data(x509Content);
-	    KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
-
-
-	    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-	    DocumentBuilder db = null;
-
-	    if ( dbf == null ) 
-		throw new IOException("Cannot get DocumentBuilderFactory!?");
-	    if ( (db = dbf.newDocumentBuilder()) == null ) 
-		throw new IOException("Cannot get DocumentBuilder!?");
-	    doc = db.newDocument();
-	    if ( doc == null ) 
-		throw new IOException("No Document");
-	    Element root = doc.createElement("signed-credential"); 
-	    doc.appendChild(root);
-	    Element cred = doc.createElement("credential");
-	    Element sig = doc.createElement("signatures");
-	    Element e = doc.createElement("type");
-	    Node text = doc.createTextNode("abac");
-
-	    cred.setAttributeNS("xml", "id", "ref0");
-	    root.appendChild(cred);
-	    e.appendChild(text);
-	    cred.appendChild(e);
-			
-	    df.format(new Date(System.currentTimeMillis() 
-			+ (3600L * 1000L * 24L * 365L)), expBuf, 
-		    new FieldPosition(0));
-	    e = doc.createElement("expires");
-	    text = doc.createTextNode(expBuf.toString());
-	    e.appendChild(text);
-	    cred.appendChild(e);
-
-	    e = doc.createElement("version");
-	    text = doc.createTextNode("1.0");
-	    e.appendChild(text);
-	    cred.appendChild(e);
-
-	    e = doc.createElement("rt0");
-	    text = doc.createTextNode(m_head + "<-" + m_tail);
-	    e.appendChild(text);
-	    cred.appendChild(e);
-
-	    root.appendChild(sig);
-
-	    DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), sig);
+
+	    DOMSignContext dsc = new DOMSignContext(privKey, sig);
 	    XMLSignature signature = fac.newXMLSignature(si, ki);
 	    signature.sign(dsc);
 	}
-	catch (Exception e) {
-	    throw new SignatureException(e.getMessage());
+	catch (Exception me) {
+	    throw new SignatureException(me.getMessage());
 	}
 
