Index: java/net/deterlab/abac/ABACException.java
===================================================================
--- java/net/deterlab/abac/ABACException.java	(revision 44896b58622fc4afa61c046f2ff5da0de5722006)
+++ java/net/deterlab/abac/ABACException.java	(revision 44896b58622fc4afa61c046f2ff5da0de5722006)
@@ -0,0 +1,32 @@
+package net.deterlab.abac;
+
+/**
+ * Superclass for all jabac Exceptions passed to the user.  All these
+ * exceptions include a cause from the underlying library that caused them when
+ * possible.
+ * @author <a href="http://abac.deterlab.net">ISI ABAC team</a>
+ * @version 1.3
+ */
+public class ABACException extends Exception  {
+    /**
+     * Constructs a new ABACException.
+     */
+    public ABACException() { super(); }
+    /**
+     * Constructs a new ABACException with a detail message.
+     * @param m a String the detail message
+     */
+    public ABACException(String m) { super(m); }
+    /**
+     * Constructs a new ABACException with a detail message and a cause.
+     * @param m a String the detail message
+     * @param c a Throwable the cause
+     */
+    public ABACException(String m, Throwable c) { super(m, c); }
+    /**
+     * Constructs a new ABACException with a cause.
+     * @param c a Throwable the cause
+     */
+    public ABACException(Throwable c) { super(c); }
+}
+
Index: java/net/deterlab/abac/BadSignatureException.java
===================================================================
--- java/net/deterlab/abac/BadSignatureException.java	(revision 44896b58622fc4afa61c046f2ff5da0de5722006)
+++ java/net/deterlab/abac/BadSignatureException.java	(revision 44896b58622fc4afa61c046f2ff5da0de5722006)
@@ -0,0 +1,31 @@
+package net.deterlab.abac;
+
+/**
+ * A Bad Signature was found on an ID or Credential.  All these exceptions
+ * include a cause from the underlying library that caused them when possible.
+ * @author <a href="http://abac.deterlab.net">ISI ABAC team</a>
+ * @version 1.3
+ */
+public class BadSignatureException extends ABACException  {
+    /**
+     * Constructs a new BadSignatureException.
+     */
+    public BadSignatureException() { super(); }
+    /**
+     * Constructs a new BadSignatureException with a detail message.
+     * @param m a String the detail message
+     */
+    public BadSignatureException(String m) { super(m); }
+    /**
+     * Constructs a new BadSignatureException with a detail message and a cause.
+     * @param m a String the detail message
+     * @param c a Throwable the cause
+     */
+    public BadSignatureException(String m, Throwable c) { super(m, c); }
+    /**
+     * Constructs a new BadSignatureException with a cause.
+     * @param c a Throwable the cause
+     */
+    public BadSignatureException(Throwable c) { super(c); }
+}
+
Index: java/net/deterlab/abac/CertInvalidException.java
===================================================================
--- java/net/deterlab/abac/CertInvalidException.java	(revision 44896b58622fc4afa61c046f2ff5da0de5722006)
+++ java/net/deterlab/abac/CertInvalidException.java	(revision 44896b58622fc4afa61c046f2ff5da0de5722006)
@@ -0,0 +1,33 @@
+package net.deterlab.abac;
+
+/**
+ * A Certificate (ID or Credential) was invalid for a reason other than bad
+ * signature or missing issuer, usually something that is not a certificate at
+ * all was parsed.  All these exceptions include a cause from the underlying
+ * library that caused them when possible.
+ * @author <a href="http://abac.deterlab.net">ISI ABAC team</a>
+ * @version 1.3
+ */
+public class CertInvalidException extends ABACException  {
+    /**
+     * Constructs a new CertInvalidException.
+     */
+    public CertInvalidException() { super(); }
+    /**
+     * Constructs a new CertInvalidException with a detail message.
+     * @param m a String the detail message
+     */
+    public CertInvalidException(String m) { super(m); }
+    /**
+     * Constructs a new CertInvalidException with a detail message and a cause.
+     * @param m a String the detail message
+     * @param c a Throwable the cause
+     */
+    public CertInvalidException(String m, Throwable c) { super(m, c); }
+    /**
+     * Constructs a new CertInvalidException with a cause.
+     * @param c a Throwable the cause
+     */
+    public CertInvalidException(Throwable c) { super(c); }
+}
+
Index: java/net/deterlab/abac/Credential.java
===================================================================
--- java/net/deterlab/abac/Credential.java	(revision 7b33c9b584e09381bd205bd0aee336833e7c4c81)
+++ java/net/deterlab/abac/Credential.java	(revision 44896b58622fc4afa61c046f2ff5da0de5722006)
@@ -60,17 +60,11 @@
      * @param filename a String containing the filename to read
      * @param ids a Collection of Identities to use in validating the cert
-     * @throws StreamParsingException if the stream is unparsable
-     * @throws CertificateException if the certificate is badly formatted
-     * @throws InvalidKeyException if none of the Identities can validate the
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException 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.
+     * @throws BadSignatureException if the signature check fails
      */
     public Credential(String filename, Collection<Identity> ids) 
-	throws Exception { this(); }
+	throws ABACException { this(); }
 
     /**
@@ -82,19 +76,11 @@
      * @param file the File to read
      * @param ids a Collection of Identities to use in validating the cert
-     * @throws StreamParsingException if the stream is unparsable
-     * @throws CertificateException if the certificate is badly formatted
-     * @throws InvalidKeyException if none of the Identities can validate the
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException 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.
+     * @throws BadSignatureException if the signature check fails
      */
     public Credential(File file, Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException, StreamParsingException, IOException {
+	    throws ABACException {
 	 this();
     }
@@ -107,19 +93,11 @@
      * @param s the InputStream to read
      * @param ids a Collection of Identities to use in validating the cert
-     * @throws StreamParsingException if the stream is unparsable
-     * @throws CertificateException if the certificate is badly formatted
-     * @throws InvalidKeyException if none of the Identities can validate the
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException 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.
+     * @throws BadSignatureException if the signature check fails
      */
     public Credential(InputStream s, Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException, StreamParsingException, IOException {
+	    throws ABACException {
 	 this();
     }
@@ -131,18 +109,10 @@
      * of the exceptions this throws.
      * @param i the Identity that will issue the certificate
-     * @throws IOException reading or writing problems
-     * @throws CertificateEncodingException Problem creating certificate
-     * @throws InvalidKeyException if none of the Identities can sign 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 creation fails
+     * @throws ABACException for Credential-specific errors
+     * @throws MissingIssuerException the identity is invalid
+     * @throws BadSignatureException if the signature creation fails
      */
     public abstract void make_cert(Identity i) 
-	    throws IOException, CertificateEncodingException,
-	       NoSuchProviderException, NoSuchAlgorithmException,
-	       SignatureException, InvalidKeyException;
+	    throws ABACException;
 
     /**
Index: java/net/deterlab/abac/GENICredential.java
===================================================================
--- java/net/deterlab/abac/GENICredential.java	(revision 7b33c9b584e09381bd205bd0aee336833e7c4c81)
+++ java/net/deterlab/abac/GENICredential.java	(revision 44896b58622fc4afa61c046f2ff5da0de5722006)
@@ -141,11 +141,11 @@
 	}
 	catch (IllegalArgumentException ie) {
-	    throw new IOException("null stream");
+	    throw new IOException("null stream", ie);
 	}
 	catch (SAXException se) {
-	    throw new IOException(se.getMessage());
+	    throw new IOException(se.getMessage(), se);
 	}
 	catch (Exception e) {
-	    throw new IOException(e.getMessage());
+	    throw new IOException(e.getMessage(), e);
 	}
 
@@ -200,8 +200,9 @@
      * @param n a Node pointing to a Signature section
      * @return an Identity constructed frm the X509 Certificate
-     * @throws SignatureException if the Identity cannot be created from the
+     * @throws MissingIssuerException if the Identity cannot be created from the
      * certificate.
      */
-    static protected Identity getIdentity(Node n) throws SignatureException {
+    static protected Identity getIdentity(Node n) 
+	throws MissingIssuerException {
 	Identity rv = null;
 	Node nn = getChildByName(n, "KeyInfo");
@@ -219,5 +220,5 @@
 	} 
 	catch (Exception e) {
-	    throw new SignatureException(e.getMessage());
+	    throw new MissingIssuerException(e.getMessage(), e);
 	}
     }
@@ -229,17 +230,11 @@
      * 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
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException 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 BadSignatureException if the signature check fails
      */
     protected void init(Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException {
+	    throws ABACException {
 
 	XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
@@ -252,5 +247,5 @@
 
 	    if (nl.getLength() == 0) 
-		throw new SignatureException("Cannot find Signature element");
+		throw new CertInvalidException("Cannot find Signature element");
 
 	    setIDAttrs(doc);
@@ -258,12 +253,12 @@
 		    nl.item(0));
 	    if ( valContext == null )
-		throw new SignatureException("No context");
+		throw new ABACException("No validation context!?");
 
 	    signature = fac.unmarshalXMLSignature(valContext);
 	    if (signature == null) 
-		throw new SignatureException("No sig");
+		throw new BadSignatureException("Cannot unmarshal signature");
 
 	    if (!signature.validate(valContext))
-		throw new SignatureException("bad signature");
+		throw new BadSignatureException("bad signature");
 
 	    load_roles();
@@ -274,8 +269,12 @@
 
 	    if (!id.getKeyID().equals(m_head.principal()))
-		throw new InvalidKeyException("Unknown identity");
+		throw new MissingIssuerException("Issuer ID and left hand " +
+			"side principal disagree");
+	}
+	catch (ABACException ae) {
+	    throw ae;
 	}
 	catch (Exception e) {
-	    throw new SignatureException(e.getMessage());
+	    throw new BadSignatureException(e.getMessage(), e);
 	}
     }
@@ -288,20 +287,18 @@
      * @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
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException 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.
+     * @throws BadSignatureException if the signature check fails
      */
     protected void init(InputStream stream, Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException, IOException {
-	read_certificate(stream);
-	if (doc == null) throw new IOException("Unknown Format");
+	    throws ABACException {
+	 try {
+	    read_certificate(stream);
+	 }
+	 catch (IOException e) {
+	     throw new CertInvalidException("Cannot parse cert", e);
+	 }
+	if (doc == null) throw new CertInvalidException("Unknown Format");
 	init(ids);
     }
@@ -315,17 +312,18 @@
      * @param filename a String containing the filename to read
      * @param ids a Collection of Identities to use in validating the cert
-     * @throws StreamParsingException if the stream is unparsable
-     * @throws CertificateException if the certificate is badly formatted
-     * @throws InvalidKeyException if none of the Identities can validate the
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException 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.
+     * @throws BadSignatureException if the signature check fails
      */
     public GENICredential(String filename, Collection<Identity> ids) 
-	throws Exception { init(new FileInputStream(filename), ids); }
+	throws ABACException { 
+	try {
+	    init(new FileInputStream(filename), ids);
+	}
+	catch (FileNotFoundException e) {
+	    throw new CertInvalidException("Bad filename", e);
+	}
+    }
 
     /**
@@ -337,20 +335,17 @@
      * @param file the File to read
      * @param ids a Collection of Identities to use in validating the cert
-     * @throws StreamParsingException if the stream is unparsable
-     * @throws CertificateException if the certificate is badly formatted
-     * @throws InvalidKeyException if none of the Identities can validate the
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException 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.
+     * @throws BadSignatureException if the signature check fails
      */
     public GENICredential(File file, Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException, StreamParsingException, IOException {
-	init(new FileInputStream(file), ids);
+	    throws ABACException {
+	try {
+	    init(new FileInputStream(file), ids);
+	}
+	catch (FileNotFoundException e) {
+	    throw new CertInvalidException("Bad filename", e);
+	}
     }
 
@@ -362,21 +357,11 @@
      * @param s the InputStream to read
      * @param ids a Collection of Identities to use in validating the cert
-     * @throws StreamParsingException if the stream is unparsable
-     * @throws CertificateException if the certificate is badly formatted
-     * @throws InvalidKeyException if none of the Identities can validate the
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException 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.
+     * @throws BadSignatureException if the signature check fails
      */
     public GENICredential(InputStream s, Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException, StreamParsingException, IOException {
-	init(s, ids);
-    }
+	    throws ABACException { init(s, ids); }
 
     /**
@@ -384,7 +369,7 @@
      * 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 {
+     * @throws ABACException if any of the XML construction fails
+     */
+    protected Node make_rt0_content() throws ABACException {
 	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 	DocumentBuilder db = null;
@@ -399,5 +384,5 @@
 
 	if ( dbf == null ) 
-	    throw new IOException("Cannot get DocumentBuilderFactory!?");
+	    throw new ABACException("Cannot get DocumentBuilderFactory!?");
 
 	try {
@@ -405,11 +390,11 @@
 	}
 	catch (ParserConfigurationException pe) {
-	    throw new IOException("Cannot get DocumentBuilder!?" + 
-		    pe.getMessage());
+	    throw new ABACException("Cannot get DocumentBuilder!?" + 
+		    pe.getMessage(), pe);
 	}
 
 	doc = db.newDocument();
 	if ( doc == null ) 
-	    throw new IOException("No Document");
+	    throw new ABACException("No Document");
 
 	Element root = doc.createElement("signed-credential"); 
@@ -454,21 +439,12 @@
     /**
      * Create a certificate from this credential issued by the given identity.
-     * Note that catching java.security.GeneralSecurityException catches most
-     * of the exceptions this throws.
+     * This is the signed XML ABAC credential.
      * @param i the Identity that will issue the certificate
-     * @throws IOException reading or writing problems
-     * @throws CertificateEncodingException Problem creating certificate
-     * @throws InvalidKeyException if none of the Identities can sign 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 creation fails
+     * @throws ABACException if xml creation fails
+     * @throws MissingIssuerException if the issuer is bad
+     * @throws BadSignatureException if the signature creation fails
      */
     public void make_cert(Identity i) 
-	    throws IOException, CertificateEncodingException,
-	       NoSuchProviderException, NoSuchAlgorithmException,
-	       SignatureException, InvalidKeyException {
+	    throws ABACException {
 	X509Certificate cert = i.getCertificate();
 	KeyPair kp = i.getKeyPair();
@@ -476,11 +452,11 @@
 	PrivateKey privKey = null;
 	if ( cert == null ) 
-	    throw new IOException("No credential in identity?");
+	    throw new MissingIssuerException("No credential in identity?");
 	if ( kp == null ) 
-	    throw new IOException("No keypair in identity?");
+	    throw new MissingIssuerException("No keypair in identity?");
 
 	pubKey = kp.getPublic();
 	if ((privKey = kp.getPrivate()) == null ) 
-	    throw new IOException("No private ket in identity");
+	    throw new MissingIssuerException("No private ket in identity");
 
 	XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
@@ -499,6 +475,6 @@
 	} 
 	catch (KeyException ke) {
-	    throw new InvalidKeyException("Unsupported key format " + 
-		    ke.getMessage());
+	    throw new ABACException("Unsupported key format " + 
+		    ke.getMessage(), ke);
 	}
 
@@ -528,16 +504,16 @@
 	}
 	catch (Exception me) {
-	    throw new SignatureException(me.getMessage());
-	}
-
-    }
-
-    /**
-     * Load the roles off the attribute cert. Throws a RuntimeException if
-     * there's something wrong with the cert.
-     */
-    private void load_roles() {
+	    throw new BadSignatureException(me.getMessage(), me);
+	}
+
+    }
+
+    /**
+     * Load the roles off the attribute cert.
+     * @throws CertInvalidException if the certificate is badly formatted
+     */
+    private void load_roles() throws CertInvalidException {
 	if ( doc == null ) 
-            throw new RuntimeException("No credential");
+            throw new CertInvalidException("No credential");
 
         String roles = null;
@@ -545,17 +521,17 @@
 
 	if (nodes == null || nodes.getLength() != 1) 
-            throw new RuntimeException("More than one rt0 element?");
+            throw new CertInvalidException("More than one rt0 element?");
 
 	Node node = nodes.item(0);
 
 	if ( node == null ) 
-            throw new RuntimeException("bad rt0 element?");
+            throw new CertInvalidException("bad rt0 element?");
 
 	if ( (roles = node.getTextContent()) == null ) 
-            throw new RuntimeException("bad rt0 element (no text)?");
+            throw new CertInvalidException("bad rt0 element (no text)?");
 
         String[] parts = roles.split("\\s*<--?\\s*");
         if (parts.length != 2)
-            throw new RuntimeException("Invalid attribute: " + roles);
+            throw new CertInvalidException("Invalid attribute: " + roles);
 
         m_head = new Role(parts[0]);
@@ -588,5 +564,5 @@
 	} 
 	catch (Exception e) {
-	    throw new IOException(e.getMessage());
+	    throw new IOException(e.getMessage(), e);
 	}
     }
@@ -596,4 +572,5 @@
      * @param fn a String, the file name on which to write
      * @throws IOException if there is an error writing.
+     * @throws FileNotFoundExeption if the file path is bogus
      */
     public void write(String fn) throws IOException, FileNotFoundException {
Index: java/net/deterlab/abac/MissingIssuerException.java
===================================================================
--- java/net/deterlab/abac/MissingIssuerException.java	(revision 44896b58622fc4afa61c046f2ff5da0de5722006)
+++ java/net/deterlab/abac/MissingIssuerException.java	(revision 44896b58622fc4afa61c046f2ff5da0de5722006)
@@ -0,0 +1,32 @@
+package net.deterlab.abac;
+
+/**
+ * An attempt to validate a credential failed because no issuer was found.  All
+ * these exceptions include a cause from the underlying library that caused
+ * them when possible.
+ * @author <a href="http://abac.deterlab.net">ISI ABAC team</a>
+ * @version 1.3
+ */
+public class MissingIssuerException extends ABACException  {
+    /**
+     * Constructs a new MissingIssuerException.
+     */
+    public MissingIssuerException() { super(); }
+    /**
+     * Constructs a new MissingIssuerException with a detail message.
+     * @param m a String the detail message
+     */
+    public MissingIssuerException(String m) { super(m); }
+    /**
+     * Constructs a new MissingIssuerException with a detail message and a cause.
+     * @param m a String the detail message
+     * @param c a Throwable the cause
+     */
+    public MissingIssuerException(String m, Throwable c) { super(m, c); }
+    /**
+     * Constructs a new MissingIssuerException with a cause.
+     * @param c a Throwable the cause
+     */
+    public MissingIssuerException(Throwable c) { super(c); }
+}
+
Index: java/net/deterlab/abac/X509Credential.java
===================================================================
--- java/net/deterlab/abac/X509Credential.java	(revision 7b33c9b584e09381bd205bd0aee336833e7c4c81)
+++ java/net/deterlab/abac/X509Credential.java	(revision 44896b58622fc4afa61c046f2ff5da0de5722006)
@@ -75,17 +75,11 @@
      * 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
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException if none of the Identities can validate the
+     *				    certificate
+     * @throws BadSignatureException if the signature check fails
      */
     protected void init(Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException {
+	    throws ABACException {
 	for (Identity i: ids) {
 	    try {
@@ -94,12 +88,12 @@
 		break;
 	    }
-	    catch (InvalidKeyException e) { }
-	}
-	if (id == null) throw new InvalidKeyException("Unknown identity");
+	    catch (GeneralSecurityException e) { }
+	}
+	if (id == null) throw new MissingIssuerException("Unknown identity");
 
         load_roles();
 
 	if (!id.getKeyID().equals(m_head.principal()))
-	    throw new InvalidKeyException("Unknown identity");
+	    throw new MissingIssuerException("Unknown identity");
     }
 
@@ -111,20 +105,18 @@
      * @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.
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException if none of the Identities can validate the
+     *				    certificate
+     * @throws BadSignatureException if the signature check fails
      */
     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");
+	    throws ABACException {
+	try {
+	    read_certificate(stream);
+	}
+	catch (IOException e) {
+	    throw new CertInvalidException(e.getMessage(), e);
+	}
+	if (ac == null) throw new CertInvalidException("Unknown Format");
 	init(ids);
     }
@@ -138,17 +130,18 @@
      * @param filename a String containing the filename to read
      * @param ids a Collection of Identities to use in validating the cert
-     * @throws StreamParsingException if the stream is unparsable
-     * @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.
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException if none of the Identities can validate the
+     *				    certificate
+     * @throws BadSignatureException if the signature check fails
      */
     public X509Credential(String filename, Collection<Identity> ids) 
-	throws Exception { init(new FileInputStream(filename), ids); }
+	throws ABACException { 
+	try {
+	    init(new FileInputStream(filename), ids); 
+	}
+	catch (FileNotFoundException e) {
+	    throw new CertInvalidException("Bad filename", e);
+	}
+    }
 
     /**
@@ -160,20 +153,17 @@
      * @param file the File to read
      * @param ids a Collection of Identities to use in validating the cert
-     * @throws StreamParsingException if the stream is unparsable
-     * @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.
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException if none of the Identities can validate the
+     *				    certificate
+     * @throws BadSignatureException if the signature check fails
      */
     public X509Credential(File file, Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException, StreamParsingException, IOException {
-	init(new FileInputStream(file), ids);
+	    throws ABACException {
+	try {
+	    init(new FileInputStream(file), ids);
+	}
+	catch (FileNotFoundException e) {
+	    throw new CertInvalidException("Bad filename", e);
+	}
     }
 
@@ -185,21 +175,11 @@
      * @param s the InputStream to read
      * @param ids a Collection of Identities to use in validating the cert
-     * @throws StreamParsingException if the stream is unparsable
-     * @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.
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException if none of the Identities can validate the
+     *				    certificate
+     * @throws BadSignatureException if the signature check fails
      */
     public X509Credential(InputStream s, Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException, StreamParsingException, IOException {
-	init(s, ids);
-    }
+	    throws ABACException { init(s, ids); }
 
     /**
@@ -211,18 +191,12 @@
      * @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 X509Credential(X509V2AttributeCertificate c, Collection<Identity> ids) 
-	    throws CertificateException, InvalidKeyException, 
-		NoSuchAlgorithmException, NoSuchProviderException,
-		SignatureException, IOException {
+     * @throws CertInvalidException if the stream is unparsable
+     * @throws MissingIssuerException if none of the Identities can validate the
+     *				    certificate
+     * @throws BadSignatureException if the signature check fails
+     */
+    public X509Credential(X509V2AttributeCertificate c, 
+	    Collection<Identity> ids) 
+	    throws ABACException {
 	ac = c;
 	init(ids);
@@ -235,18 +209,10 @@
      * of the exceptions this throws.
      * @param i the Identity that will issue the certificate
-     * @throws IOException reading or writing problems
-     * @throws CertificateEncodingException Problem creating certificate
-     * @throws InvalidKeyException if none of the Identities can sign 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 creation fails
+     * @throws ABACException if xml creation fails
+     * @throws MissingIssuerException if the issuer is bad
+     * @throws BadSignatureException if the signature creation fails
      */
     public void make_cert(Identity i) 
-	    throws IOException, CertificateEncodingException,
-	       NoSuchProviderException, NoSuchAlgorithmException,
-	       SignatureException, InvalidKeyException {
+	    throws ABACException {
 	PrivateKey key = i.getKeyPair().getPrivate();
 	SubjectPublicKeyInfo pki = Context.extractSubjectPublicKeyInfo(
@@ -255,31 +221,36 @@
 	    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(
+	try {
+	    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 DERUTF8String(toString())))));
-	gen.setSignatureAlgorithm("SHA256WithRSAEncryption");
-
-	// Creddy expects an authority key identifier.
-	gen.addExtension(authKeyOID, false, 
-		new AuthorityKeyIdentifier(pki));
+			    new DERSequence(
+				new DERUTF8String(toString())))));
+	    gen.setSignatureAlgorithm("SHA256WithRSAEncryption");
+
+	    // Creddy expects an authority key identifier.
+	    gen.addExtension(authKeyOID, false, 
+		    new AuthorityKeyIdentifier(pki));
+	    ac = (X509V2AttributeCertificate) gen.generate(key, "BC");
+	}
+	catch (Exception e) {
+	    throw new ABACException("Cannot encode cert", e);
+	}
 	// 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() {
+     * Load the roles off the attribute cert. 
+     * @throws CertInvalidException if the certificate is badly formatted
+     */
+    private void load_roles() throws CertInvalidException {
         String roles = null;
         try {
@@ -293,10 +264,10 @@
         }
         catch (Exception e) {
-            throw new RuntimeException("Badly formatted certificate");
+            throw new CertInvalidException("Badly formatted certificate");
         }
 
         String[] parts = roles.split("\\s*<--?\\s*");
         if (parts.length != 2)
-            throw new RuntimeException("Invalid attribute: " + roles);
+            throw new CertInvalidException("Invalid attribute: " + roles);
 
         m_head = new Role(parts[0]);
