package net.deterlab.abac;
import java.io.*;
import java.math.*;
import java.util.*;
import java.security.*;
import java.security.cert.*;
import javax.security.auth.x500.*;
import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.x509.*;
import org.bouncycastle.x509.*;
import org.bouncycastle.x509.util.*;
import org.bouncycastle.openssl.*;
/**
* An ABAC credential, with or without an underlying certificate that
* represents it. These are edges in proof graphs and can be constructed from
* their constituent Roles.
* @author ISI ABAC team
* @version 1.3
*/
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 identity that issued the certificate */
protected Identity id;
/**
* Create an empty Credential.
*/
public Credential() {
m_head = m_tail = null;
id = null;
}
/**
* Create a credential from a head and tail role. This credential has no
* underlying certificate, and cannot be exported or used in real proofs.
* make_cert can create a certificate for a credential initialized this
* way.
* @param head the Role at the head of the credential
* @param tail the Role at the tail of the credential
*/
public Credential(Role head, Role tail) {
m_head = head;
m_tail = tail;
id = null;
}
/**
* Create a credential from an attribute cert in a file. Throws an
* exception if the cert file can't be opened or if there's a format
* problem with the cert. Note that catching
* java.security.GeneralSecurityException catches most of the exceptions
* this throws.
* @param filename a String containing the filename to read
* @param ids a Collection of Identities to use in validating the cert
* @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 Credential(String filename, Collection ids)
throws ABACException { this(); }
/**
* Create a credential from an attribute cert in a file. Throws an
* exception if the cert file can't be opened or if there's a format
* problem with the cert. Note that catching
* java.security.GeneralSecurityException catches most of the exceptions
* this throws.
* @param file the File to read
* @param ids a Collection of Identities to use in validating the cert
* @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 Credential(File file, Collection ids)
throws ABACException {
this();
}
/**
* Create a credential from an InputStream. Throws an exception if the
* stream can't be parsed or if there's a format problem with the cert.
* Note that catching java.security.GeneralSecurityException catches most
* of the exceptions this throws.
* @param s the InputStream to read
* @param ids a Collection of Identities to use in validating the cert
* @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 Credential(InputStream s, Collection ids)
throws ABACException {
this();
}
/**
* Create a certificate from this credential issued by the given identity.
* Note that catching java.security.GeneralSecurityException catches most
* of the exceptions this throws.
* @param i the Identity that will issue the certificate
* @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 ABACException;
/**
* 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; }
/**
* Turn the credential into string form. The format is head <- tail. For
* example: A.r1 <- 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 <- tail. For
* example: A.r1 <- 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);
}
/**
* Output the DER formatted attribute certificate associated with this
* Credential to the OutputStream.
* @param s the OutputStream on which to write
* @throws IOException if there is an error writing.
*/
public abstract void write(OutputStream s) throws IOException;
/**
* Output the DER formatted attribute certificate associated with this
* Credential to the filename given.
* @param fn a String containing the output filename
* @throws IOException if there is an error writing.
*/
public abstract void write(String fn)
throws IOException, FileNotFoundException;
/**
* Return true if this Credential has a certificate associated. A jabac
* extension.
* @return true if this Credential has a certificate associated.
*/
public abstract boolean hasCertificate();
/**
* 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 a CredentialParser that never parses a credential. Credentials
* that can be parsed must override this. Called indirectly by
* CredentialFactory.registerClass().
* @return a CredentialParser for this kind of credential.
*/
static public CredentialParser getCredentialParser() {
return new CredentialParser() {
public Credential[] parseCredential(InputStream s,
Collection ids) {
return null;
}
};
}
}