package net.deterlab.abac;
import java.io.*;
import java.math.*;
import java.text.*;
import java.util.*;
import java.security.*;
import java.security.cert.*;
import javax.security.auth.x500.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.crypto.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.*;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.*;
import org.xml.sax.*;
import org.w3c.dom.*;
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 formatted as an abac-type GENI credential.
* @author ISI ABAC team
* @version 1.4
*/
public class GENIPrivCredential extends GENICredential {
/**
* Create an empty Credential.
*/
public GENIPrivCredential() {
m_head = m_tail = null;
doc = 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 GENIPrivCredential(Role head, Role tail, Document d, Identity i) {
m_head = head;
m_tail = tail;
doc = null;
id = null;
}
/**
* Create a certificate from this credential issued by the given identity.
* This is the signed XML ABAC credential.
* @param i the Identity that will issue the certificate
* @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 ABACException {
throw new ABACException("Cannot generate a GENIPrivCredential");
}
static public class GENIPrivSpecialization
extends CredentialFactorySpecialization {
protected Identity nodeToIdentity(Node n) {
String certStr = null;
if ( ( certStr = n.getTextContent()) == null ) return null;
try {
certStr = "-----BEGIN CERTIFICATE-----\n" +
certStr +
"\n-----END CERTIFICATE-----";
return new Identity(new StringReader(certStr));
}
catch (Exception e) {
return null;
}
}
protected Credential[] make_creds(Document d, Identity issuer)
throws ABACException {
Node root = null;
Node credential = null;
Node owner_gid = null;
Node target_gid = null;
Node privileges = null;
Node priv = null;
Identity owner = null;
Identity target = null;
ArrayList rv =
new ArrayList();
if ( (root = getChildByName(d, "signed-credential")) == null)
throw new CertInvalidException("No signed-credential element");
if ( (credential = getChildByName(root, "credential")) == null )
throw new CertInvalidException("No credential element");
if ( (owner_gid = getChildByName(credential, "owner_gid")) == null )
throw new CertInvalidException("No owner_gid element");
if ((target_gid = getChildByName(credential,"target_gid")) == null )
throw new CertInvalidException("No target_gid element");
if ((privileges = getChildByName(credential,"privileges")) == null )
throw new CertInvalidException("No privileges element");
if ( (owner = nodeToIdentity(owner_gid)) == null)
throw new CertInvalidException("Bad owner_gid element");
if ( (target = nodeToIdentity(target_gid)) == null)
throw new CertInvalidException("Bad target_gid element");
for (Node n = privileges.getFirstChild(); n != null;
n = n.getNextSibling()) {
if (n.getNodeType() != Node.ELEMENT_NODE ||
!"privilege".equals(n.getNodeName()))
throw new CertInvalidException(
"Child of privileges not privilege?");
Node name = null;
Node can_delegate = null;
boolean cd = false;
String cds = null;
String pname = null;
if ( (name = getChildByName(n, "name")) == null)
throw new CertInvalidException("No privilege name");
if ((can_delegate = getChildByName(n, "can_delegate")) == null)
throw new CertInvalidException("No privilege delegate");
if ( (pname = name.getTextContent()) == null)
throw new CertInvalidException("No privilege name text");
if ((cds = can_delegate.getTextContent()) == null)
throw new CertInvalidException("No delegate text");
cd = cds.equals("1") || cds.equals("true");
if ( rv.isEmpty() ) {
rv.add(new GENIPrivCredential(
new Role(issuer.getKeyID() + ".speaks_for_" +
owner.getKeyID()),
new Role(owner.getKeyID()), d, issuer));
rv.add(new GENIPrivCredential(
new Role(issuer.getKeyID() + ".speaks_for_" +
owner.getKeyID()),
new Role(owner.getKeyID() + ".speaks_for_" +
owner.getKeyID()), d, issuer));
}
rv.add(new GENIPrivCredential(
new Role(issuer.getKeyID() + "." + pname + "_" +
target.getKeyID()),
new Role(issuer.getKeyID() + ".speaks_for_" +
owner.getKeyID()), d, issuer));
if (cd ) {
rv.add(new GENIPrivCredential(
new Role(issuer.getKeyID() + "." + pname +
"_" + target.getKeyID()),
new Role(issuer.getKeyID() + ".can_delegate_"
+ pname + "_" + target.getKeyID() +
"." + pname + "_" + target.getKeyID()),
d, issuer));
rv.add(new GENIPrivCredential(
new Role(issuer.getKeyID() +
".can_delegate_" + pname),
new Role(owner.getKeyID()), d, issuer));
}
}
return rv.toArray(new Credential[rv.size()]);
}
public Credential[] parseCredential(InputStream is,
Collection ids) throws ABACException {
try {
Document d = read_certificate(is);
XMLSignatureFactory fac =
XMLSignatureFactory.getInstance("DOM");
NodeList nl = d.getElementsByTagNameNS(XMLSignature.XMLNS,
"Signature");
DOMValidateContext valContext = null;
XMLSignature signature = null;
Identity lid = null;
if (nl.getLength() == 0)
throw new CertInvalidException(
"Cannot find Signature element");
setIDAttrs(d);
valContext = new DOMValidateContext(new X509KeySelector(),
nl.item(0));
if ( valContext == null )
throw new ABACException("No validation context!?");
signature = fac.unmarshalXMLSignature(valContext);
if (signature == null)
throw new BadSignatureException(
"Cannot unmarshal signature");
if (!signature.validate(valContext))
throw new BadSignatureException("bad signature");
lid = getIdentity(nl.item(0));
if ( !ids.contains(lid) ) ids.add(lid);
return make_creds(d, lid);
}
catch (ABACException ae) {
throw ae;
}
catch (Exception e) {
throw new BadSignatureException(e.getMessage(), e);
}
}
public Credential generateCredential(Role head, Role tail) {
return null;
}
};
/**
* Return a CredentialCredentialFactorySpecialization for GENICredentials.
* Used by the CredentialFactory to parse and generate these kind of
* credentials. It basically wraps constuctor calls.
* @return a CredentialFactorySpecialization for this kind of credential.
*/
static public CredentialFactorySpecialization
getCredentialFactorySpecialization() {
return new GENIPrivSpecialization();
}
}