Index: java/net/deterlab/abac/Credential.java
===================================================================
--- java/net/deterlab/abac/Credential.java	(revision 61f21c5edc41e5de819dd3b8a28651883c5685f1)
+++ java/net/deterlab/abac/Credential.java	(revision 7b33c9b584e09381bd205bd0aee336833e7c4c81)
@@ -23,22 +23,12 @@
  * @version 1.3
  */
-public class Credential implements Comparable {
-    /** The ASN1 OID for an IETF attribute. */
-    protected static String attrOID = "1.3.6.1.5.5.7.10.4";
-    /** The ASN1 OID for AuthorityKeyIdentifier. */
-    protected static String authKeyOID = "2.5.29.35";
-
+public abstract class Credential implements Comparable {
     /** The role at the head */
     protected Role m_head
     /** The role at the tail */;
     protected Role m_tail;
-    /** The certificate representing this credential */
-    protected X509V2AttributeCertificate ac;
     /** The identity that issued the certificate */
     protected Identity id;
 
-    /** Make sure BouncyCastle is loaded */
-    static { Context.loadBouncyCastle(); } 
-
     /**
      * Create an empty Credential.
@@ -46,5 +36,4 @@
     public Credential() {
 	m_head = m_tail = null;
-	ac = null;
 	id = null;
     }
@@ -60,79 +49,5 @@
         m_head = head;
         m_tail = tail;
-	ac = null; 
 	id = null;
-    }
-
-    /**
-     * Do the credential extraction from an input stream.  This parses the
-     * certificate from the input stream and saves it. The contents must be
-     * validated and parsed later.
-     * @param stream the InputStream to read the certificate from.
-     * @throws IOException if the stream is unparsable
-     */
-    protected void read_certificate(InputStream stream) 
-	    throws IOException {
-	ac = new X509V2AttributeCertificate(stream);
-    }
-
-    /**
-     * Initialize a credential from parsed certificate.  Validiate it against
-     * the given identities and parse out the roles.  Note that catching
-     * java.security.GeneralSecurityException catches most of the exceptions
-     * this throws.
-     * @param ids a Collection of Identities to use in validating the cert
-     * @throws CertificateException if the certificate is badly formatted
-     * @throws InvalidKeyException if none of the Identities can validate the
-     *				    certificate
-     * @throws NoSuchAlgorithmException if the credential uses an unknown
-     *				    signature algorithm
-     * @throws NoSuchProviderException if the provider of the signature
-     *				    algorithm is unavailable
-     * @throws SignatureException if the signature check fails
-     */
-    protected void init(Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException {
-	for (Identity i: ids) {
-	    try {
-		ac.verify(i.getCertificate().getPublicKey(), "BC");
-		id = i;
-		break;
-	    }
-	    catch (InvalidKeyException e) { }
-	}
-	if (id == null) throw new InvalidKeyException("Unknown identity");
-
-        load_roles();
-
-	if (!id.getKeyID().equals(m_head.principal()))
-	    throw new InvalidKeyException("Unknown identity");
-    }
-
-    /**
-     * Parse a credential from an InputStream and initialize the role from it.
-     * Combine read_credential(stream) and init(ids).  Note that catching
-     * java.security.GeneralSecurityException catches most of the exceptions
-     * this throws.
-     * @param stream the InputStream to read the certificate from.
-     * @param ids a Collection of Identities to use in validating the cert
-     * @throws CertificateException if the certificate is badly formatted
-     * @throws InvalidKeyException if none of the Identities can validate the
-     *				    certificate
-     * @throws NoSuchAlgorithmException if the credential uses an unknown
-     *				    signature algorithm
-     * @throws NoSuchProviderException if the provider of the signature
-     *				    algorithm is unavailable
-     * @throws SignatureException if the signature check fails
-     * @throws IOException if the certificate is unparsable.
-     */
-    protected void init(InputStream stream, Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException, IOException {
-	read_certificate(stream);
-	if (ac == null) throw new IOException("Unknown Format");
-	init(ids);
     }
 
@@ -157,5 +72,5 @@
      */
     public Credential(String filename, Collection<Identity> ids) 
-	throws Exception { init(new FileInputStream(filename), ids); }
+	throws Exception { this(); }
 
     /**
@@ -182,5 +97,5 @@
 		NoSuchAlgorithmException, NoSuchProviderException,
 		SignatureException, StreamParsingException, IOException {
-	init(new FileInputStream(file), ids);
+	 this();
     }
 
@@ -207,31 +122,5 @@
 		NoSuchAlgorithmException, NoSuchProviderException,
 		SignatureException, StreamParsingException, IOException {
-	init(s, ids);
-    }
-
-    /**
-     * Create a credential from an X509V2AttributeCertificate object.  Throws
-     * an exception if the certificate doesn't parse into an ABAC credential,
-     * or cannot be validated.  Note that catching
-     * java.security.GeneralSecurityException catches most of the exceptions
-     * this throws.
-     * @param c the X509V2AttributeCertificate to create from
-     * @param ids a Collection of Identities to use in validating the cert
-     * @throws CertificateException if the certificate is badly formatted
-     * @throws InvalidKeyException if none of the Identities can validate the
-     *				    certificate
-     * @throws NoSuchAlgorithmException if the credential uses an unknown
-     *				    signature algorithm
-     * @throws NoSuchProviderException if the provider of the signature
-     *				    algorithm is unavailable
-     * @throws SignatureException if the signature check fails
-     * @throws IOException if the certificate is unparsable.
-     */
-    public Credential(X509V2AttributeCertificate c, Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException, IOException {
-	ac = c;
-	init(ids);
+	 this();
     }
 
@@ -252,62 +141,8 @@
      * @throws SignatureException if the signature creation fails
      */
-    public void make_cert(Identity i) 
+    public abstract void make_cert(Identity i) 
 	    throws IOException, CertificateEncodingException,
 	       NoSuchProviderException, NoSuchAlgorithmException,
-	       SignatureException, InvalidKeyException {
-	PrivateKey key = i.getKeyPair().getPrivate();
-	SubjectPublicKeyInfo pki = Context.extractSubjectPublicKeyInfo(
-		i.getKeyPair().getPublic());
-	X509V2AttributeCertificateGenerator gen = 
-	    new X509V2AttributeCertificateGenerator();
-
-	gen.setIssuer(new AttributeCertificateIssuer(
-		    new X500Principal("CN="+m_head.principal())));
-	gen.setHolder(new AttributeCertificateHolder(
-		    new X500Principal("CN="+m_head.principal())));
-	gen.setNotAfter(new Date(System.currentTimeMillis() 
-		    + (3600L * 1000L * 24L * 365L)));
-	gen.setNotBefore(new Date(System.currentTimeMillis()));
-	gen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
-	gen.addAttribute(new X509Attribute(attrOID, 
-		    new DERSequence(
-			new DERSequence(
-			    new DERUTF8String(toString())))));
-	gen.setSignatureAlgorithm("SHA256WithRSAEncryption");
-
-	// Creddy expects an authority key identifier.
-	gen.addExtension(authKeyOID, false, 
-		new AuthorityKeyIdentifier(pki));
-	// Create the cert.
-	ac = (X509V2AttributeCertificate) gen.generate(key, "BC");
-	id = i;
-    }
-
-    /**
-     * Load the roles off the attribute cert. Throws a RuntimeException if
-     * there's something wrong with the cert.
-     */
-    private void load_roles() {
-        String roles = null;
-        try {
-            X509Attribute attr = ac.getAttributes()[0];
-
-            DERSequence    java     = (DERSequence)attr.getValues()[0];
-            DERSequence    fucking  = (DERSequence)java.getObjectAt(0);
-            DERUTF8String  sucks    = (DERUTF8String)fucking.getObjectAt(0);
-
-            roles = sucks.getString();
-        }
-        catch (Exception e) {
-            throw new RuntimeException("Badly formatted certificate");
-        }
-
-        String[] parts = roles.split("\\s*<--?\\s*");
-        if (parts.length != 2)
-            throw new RuntimeException("Invalid attribute: " + roles);
-
-        m_head = new Role(parts[0]);
-        m_tail = new Role(parts[1]);
-    }
+	       SignatureException, InvalidKeyException;
 
     /**
@@ -357,10 +192,4 @@
 
     /**
-     * Gets the cert associated with this credential (if any).
-     * @return the attribute cert associated with this credential (if any).
-     */
-    public X509V2AttributeCertificate cert() { return ac; }
-
-    /**
      * Turn the credential into string form. The format is head &lt;- tail. For
      * example: A.r1 &lt;- B.r2.r3.  Principal names are key identifiers.
@@ -388,9 +217,5 @@
      * @throws IOException if there is an error writing.
      */
-    public void write(OutputStream s) throws IOException {
-	if (ac != null ) 
-	    s.write(ac.getEncoded());
-	s.flush();
-    }
+    public abstract void write(OutputStream s) throws IOException;
 
     /**
@@ -400,7 +225,6 @@
      * @throws IOException if there is an error writing.
      */
-    public void write(String fn) throws IOException, FileNotFoundException {
-	write(new FileOutputStream(fn));
-    }
+    public abstract void write(String fn) 
+	throws IOException, FileNotFoundException;
 
     /**
@@ -409,5 +233,5 @@
      * @return true if this Credential has a certificate associated.
      */
-    public boolean hasCertificate() { return ac != null; }
+    public abstract boolean hasCertificate();
 
     /**
@@ -422,10 +246,3 @@
      */
     public X509Certificate issuerCert() { return id.getCertificate(); }
-    /**
-     * Return the X509V2AttributeCertificate that underlys the Credential
-     * @return the X509V2AttributeCertificate that underlys the Credential.
-     */
-    public X509V2AttributeCertificate attributeCert() { return ac; }
-
-
 }
Index: java/net/deterlab/abac/GENICredential.java
===================================================================
--- java/net/deterlab/abac/GENICredential.java	(revision 61f21c5edc41e5de819dd3b8a28651883c5685f1)
+++ java/net/deterlab/abac/GENICredential.java	(revision 7b33c9b584e09381bd205bd0aee336833e7c4c81)
@@ -39,13 +39,6 @@
  */
 public class GENICredential extends Credential implements Comparable {
-    /** The role at the head */
-    protected Role m_head
-    /** The role at the tail */;
-    protected Role m_tail;
     /** The signed XML representing this credential */
     protected Document doc;
-    /** The identity that issued the certificate */
-    protected Identity id;
-
 
     /**
@@ -571,73 +564,8 @@
 
     /**
-     * Two credentials are the same if their roles are the same.
-     * @param o an Object to compare
-     * @return true if the Credentials have the Roles 
-     */
-    public boolean equals(Object o) {
-	if ( o instanceof Credential ) {
-	    Credential c = (Credential) o;
-
-	    if (m_head == null || m_tail == null ) return false;
-	    else return (m_head.equals(c.head()) && m_tail.equals(c.tail()));
-	}
-	else return false;
-    }
-
-    /**
-     * Allow credentials to be compared.  They are ordered by their Roles, head
-     * then tail.
-     * @param o an Object to compare
-     * @return -1 if this Credential is before, 0 if they are the same, and 1
-     *		    if this Credential is after the given object.
-     */
-    public int compareTo(Object o) {
-	if (o instanceof Credential) {
-	    Credential c = (Credential) o;
-
-	    if (head().equals(c.head())) return tail().compareTo(c.tail());
-	    else return head().compareTo(c.head());
-	}
-	else return 1;
-    }
-
-
-    /**
-     * Get the head role from the credential.
-     * @return the Role in the head
-     */
-    public Role head() { return m_head; }
-
-    /**
-     * Get the tail role from the credential
-     * @return the Role in the tail
-     */
-    public Role tail() { return m_tail; }
-
-    /**
      * Gets the cert associated with this credential (if any).
      * @return the attribute cert associated with this credential (if any).
      */
     public Document GENIcert() { return doc; }
-
-    /**
-     * Turn the credential into string form. The format is head &lt;- tail. For
-     * example: A.r1 &lt;- B.r2.r3.  Principal names are key identifiers.
-     * @return the string form
-     */
-    public String toString() {
-        return m_head + " <- " + m_tail;
-    }
-
-    /**
-     * Turn the credential into string form. The format is head &lt;- tail. For
-     * example: A.r1 &lt;- B.r2.r3.  Principal names are shortened to menmonics
-     * if the Context knows the identity.
-     * @param c the Context to translate names in
-     * @return the string form
-     */
-    public String simpleString(Context c) {
-	return m_head.simpleString(c) + " <- " + m_tail.simpleString(c);
-    }
 
     /**
@@ -663,9 +591,8 @@
 	}
     }
-
     /**
      * Output the signed GENI ABAC certificate associated with this
-     * Credential to the filename given.
-     * @param fn a String containing the output filename
+     * Credential to the OutputStream.
+     * @param fn a String, the file name on which to write
      * @throws IOException if there is an error writing.
      */
@@ -681,21 +608,3 @@
     public boolean hasCertificate() { return doc != null; }
 
-    /**
-     * Return the Identity that issued the underlying certificate.  A jabac
-     * extension.
-     * @return the Identity that issued the underlying certificate.
-     */
-    public Identity issuer() { return id; }
-    /**
-     * Return the X509Certificate that issued the underlying certificate.
-     * @return the X509Certificate that issued the underlying certificate.
-     */
-    public X509Certificate issuerCert() { return id.getCertificate(); }
-    /**
-     * Return the X509V2AttributeCertificate that underlys the Credential
-     * @return the X509V2AttributeCertificate that underlys the Credential.
-    public X509V2AttributeCertificate attributeCert() { return ac; }
-     */
-
-
 }
Index: java/net/deterlab/abac/X509Credential.java
===================================================================
--- java/net/deterlab/abac/X509Credential.java	(revision 61f21c5edc41e5de819dd3b8a28651883c5685f1)
+++ java/net/deterlab/abac/X509Credential.java	(revision 7b33c9b584e09381bd205bd0aee336833e7c4c81)
@@ -28,13 +28,6 @@
     /** The ASN1 OID for AuthorityKeyIdentifier. */
     protected static String authKeyOID = "2.5.29.35";
-
-    /** The role at the head */
-    protected Role m_head
-    /** The role at the tail */;
-    protected Role m_tail;
     /** The certificate representing this credential */
     protected X509V2AttributeCertificate ac;
-    /** The identity that issued the certificate */
-    protected Identity id;
 
     /** Make sure BouncyCastle is loaded */
@@ -293,9 +286,9 @@
             X509Attribute attr = ac.getAttributes()[0];
 
-            DERSequence    java     = (DERSequence)attr.getValues()[0];
-            DERSequence    fucking  = (DERSequence)java.getObjectAt(0);
-            DERUTF8String  sucks    = (DERUTF8String)fucking.getObjectAt(0);
-
-            roles = sucks.getString();
+            DERSequence    t1     = (DERSequence)attr.getValues()[0];
+            DERSequence    t2  = (DERSequence)t1.getObjectAt(0);
+            DERUTF8String  t3    = (DERUTF8String)t2.getObjectAt(0);
+
+            roles = t3.getString();
         }
         catch (Exception e) {
@@ -312,73 +305,8 @@
 
     /**
-     * Two credentials are the same if their roles are the same.
-     * @param o an Object to compare
-     * @return true if the Credentials have the Roles 
-     */
-    public boolean equals(Object o) {
-	if ( o instanceof Credential ) {
-	    Credential c = (Credential) o;
-
-	    if (m_head == null || m_tail == null ) return false;
-	    else return (m_head.equals(c.head()) && m_tail.equals(c.tail()));
-	}
-	else return false;
-    }
-
-    /**
-     * Allow credentials to be compared.  They are ordered by their Roles, head
-     * then tail.
-     * @param o an Object to compare
-     * @return -1 if this Credential is before, 0 if they are the same, and 1
-     *		    if this Credential is after the given object.
-     */
-    public int compareTo(Object o) {
-	if (o instanceof Credential) {
-	    Credential c = (Credential) o;
-
-	    if (head().equals(c.head())) return tail().compareTo(c.tail());
-	    else return head().compareTo(c.head());
-	}
-	else return 1;
-    }
-
-
-    /**
-     * Get the head role from the credential.
-     * @return the Role in the head
-     */
-    public Role head() { return m_head; }
-
-    /**
-     * Get the tail role from the credential
-     * @return the Role in the tail
-     */
-    public Role tail() { return m_tail; }
-
-    /**
      * Gets the cert associated with this credential (if any).
      * @return the attribute cert associated with this credential (if any).
      */
     public X509V2AttributeCertificate cert() { return ac; }
-
-    /**
-     * Turn the credential into string form. The format is head &lt;- tail. For
-     * example: A.r1 &lt;- B.r2.r3.  Principal names are key identifiers.
-     * @return the string form
-     */
-    public String toString() {
-        return m_head + " <- " + m_tail;
-    }
-
-    /**
-     * Turn the credential into string form. The format is head &lt;- tail. For
-     * example: A.r1 &lt;- B.r2.r3.  Principal names are shortened to menmonics
-     * if the Context knows the identity.
-     * @param c the Context to translate names in
-     * @return the string form
-     */
-    public String simpleString(Context c) {
-	return m_head.simpleString(c) + " <- " + m_tail.simpleString(c);
-    }
 
     /**
@@ -412,15 +340,4 @@
 
     /**
-     * Return the Identity that issued the underlying certificate.  A jabac
-     * extension.
-     * @return the Identity that issued the underlying certificate.
-     */
-    public Identity issuer() { return id; }
-    /**
-     * Return the X509Certificate that issued the underlying certificate.
-     * @return the X509Certificate that issued the underlying certificate.
-     */
-    public X509Certificate issuerCert() { return id.getCertificate(); }
-    /**
      * Return the X509V2AttributeCertificate that underlys the Credential
      * @return the X509V2AttributeCertificate that underlys the Credential.
