source: java/net/deterlab/abac/GENIPrivCredential.java @ 7f614c1

abac0-leakabac0-meimei-idmei-rt0-nmei_rt0tvf-new-xml
Last change on this file since 7f614c1 was 7f614c1, checked in by Ted Faber <faber@…>, 12 years ago

Add expirations to all credentials

  • Property mode set to 100644
File size: 9.0 KB
RevLine 
[dd5d4d9]1package net.deterlab.abac;
2
3import java.io.*;
4import java.math.*;
5import java.text.*;
6
7import java.util.*;
8import java.security.*;
9import java.security.cert.*;
10
11import javax.security.auth.x500.*;
12
13import javax.xml.parsers.*;
14import javax.xml.transform.*;
15import javax.xml.transform.dom.*;
16import javax.xml.transform.stream.*;
17
18import javax.xml.crypto.*;
19import javax.xml.crypto.dsig.*;
20import javax.xml.crypto.dsig.dom.*;
21import javax.xml.crypto.dsig.keyinfo.*;
22import javax.xml.crypto.dsig.spec.*;
23
24import org.xml.sax.*;
25import org.w3c.dom.*;
26
27import org.bouncycastle.asn1.*;
28import org.bouncycastle.asn1.x509.*;
29import org.bouncycastle.x509.*;
30import org.bouncycastle.x509.util.*;
31import org.bouncycastle.openssl.*;
32
33/**
34 * An ABAC credential formatted as an abac-type GENI credential.
35 * @author <a href="http://abac.deterlab.net">ISI ABAC team</a>
36 * @version 1.4
37 */
38public class GENIPrivCredential extends GENICredential {
39    /**
40     * Create an empty Credential.
41     */
42    public GENIPrivCredential() {
[7f614c1]43        super();
[dd5d4d9]44        doc = null;
45    }
46    /**
47     * Create a credential from a head and tail role.  This credential has no
48     * underlying certificate, and cannot be exported or used in real proofs.
49     * make_cert can create a certificate for a credential initialized this
50     * way.
51     * @param head the Role at the head of the credential
52     * @param tail the Role at the tail of the credential
53     */
[7f614c1]54    public GENIPrivCredential(Role head, Role tail, Document d, Identity i,
55            Date e) {
[dd5d4d9]56        m_head = head;
57        m_tail = tail;
58        doc = null; 
59        id = null;
[7f614c1]60        m_expiration = e;
[dd5d4d9]61    }
62
63    /**
64     * Create a certificate from this credential issued by the given identity.
65     * This is the signed XML ABAC credential.
66     * @param i the Identity that will issue the certificate
67     * @throws ABACException if xml creation fails
68     * @throws MissingIssuerException if the issuer is bad
69     * @throws BadSignatureException if the signature creation fails
70     */
71    public void make_cert(Identity i) 
72            throws ABACException {
73        throw new ABACException("Cannot generate a GENIPrivCredential");
74    }
75
[484bb5a]76    /**
77     * Class that parses a GENI privilege credential into multiple
78     * GENIPrivCredential objects.
79     */
[dd5d4d9]80    static public class GENIPrivSpecialization 
81            extends CredentialFactorySpecialization {
82
[484bb5a]83        /**
84         * Extract an identity from a field holding a PEM-encoded x.509
85         * certificate (for example, owner_gid).
86         * @param n a Node that has the certificate in its Text Content
87         * @return the Identity
88         */
[dd5d4d9]89        protected Identity nodeToIdentity(Node n) {
90            String certStr = null;
91
92            if ( ( certStr = n.getTextContent()) == null ) return null;
93            try {
94                certStr = "-----BEGIN CERTIFICATE-----\n" + 
95                    certStr + 
96                "\n-----END CERTIFICATE-----";
97                return new Identity(new StringReader(certStr));
98            } 
99            catch (Exception e) {
100                return null;
101            }
102        }
[484bb5a]103
104        /**
105         * Parses the credential into multiple Objects based on the permissions
106         * imbued by the credential.
107         * @param d a Document, the parsed credential
108         * @param issuer an Identity that signed the credential
109         * @return an array of GENIPrivCredentials that represent the
110         * credential
111         */
[dd5d4d9]112        protected Credential[] make_creds(Document d, Identity issuer) 
113                throws ABACException {
114            Node root = null;
115            Node credential = null;
116            Node owner_gid = null;
117            Node target_gid = null;
118            Node privileges = null;
119            Node priv = null;
120            Identity owner = null;
121            Identity target = null;
122            ArrayList<GENIPrivCredential> rv = 
123                new ArrayList<GENIPrivCredential>();
124
125
126            if ( (root = getChildByName(d, "signed-credential")) == null)
127                throw new CertInvalidException("No signed-credential element");
128            if ( (credential = getChildByName(root, "credential")) == null )
129                throw new CertInvalidException("No credential element");
130            if ( (owner_gid = getChildByName(credential, "owner_gid")) == null )
131                throw new CertInvalidException("No owner_gid element");
132            if ((target_gid = getChildByName(credential,"target_gid")) == null )
133                throw new CertInvalidException("No target_gid element");
134            if ((privileges = getChildByName(credential,"privileges")) == null )
135                throw new CertInvalidException("No privileges element");
136
[2405adf]137            Date exp = getTime(d, "expires");
138
139            if ( exp.before(new Date()))
140                throw new CertInvalidException("Certificate Expired " + exp);
141
[dd5d4d9]142            if ( (owner = nodeToIdentity(owner_gid)) == null) 
143                throw new CertInvalidException("Bad owner_gid element");
144            if ( (target = nodeToIdentity(target_gid)) == null) 
145                throw new CertInvalidException("Bad target_gid element");
146
147            for (Node n = privileges.getFirstChild(); n != null; 
148                    n = n.getNextSibling()) {
149                if (n.getNodeType() != Node.ELEMENT_NODE ||
150                        !"privilege".equals(n.getNodeName()))
151                    throw new CertInvalidException(
152                            "Child of privileges not privilege?");
153                Node name = null;
154                Node can_delegate = null;
155                boolean cd = false;
156                String cds = null;
157                String pname = null;
158
159                if ( (name = getChildByName(n, "name")) == null)
160                    throw new CertInvalidException("No privilege name");
161
162                if ((can_delegate = getChildByName(n, "can_delegate")) == null)
163                    throw new CertInvalidException("No privilege delegate");
164
165                if ( (pname = name.getTextContent()) == null)
166                    throw new CertInvalidException("No privilege name text");
[6bf703b0]167                if ((cds = can_delegate.getTextContent()) == null)
[dd5d4d9]168                    throw new CertInvalidException("No delegate text");
169                cd = cds.equals("1") || cds.equals("true");
170
[484bb5a]171                /* First privilege includes the basic speaks for defintion
172                 * for this owner */
[dd5d4d9]173                if ( rv.isEmpty() ) {
174                    rv.add(new GENIPrivCredential(
175                                new Role(issuer.getKeyID() + ".speaks_for_" +
176                                    owner.getKeyID()),
[7f614c1]177                                new Role(owner.getKeyID()), d, issuer, exp));
[dd5d4d9]178                    rv.add(new GENIPrivCredential(
179                                new Role(issuer.getKeyID() + ".speaks_for_" +
180                                    owner.getKeyID()),
181                                new Role(owner.getKeyID() + ".speaks_for_" +
[7f614c1]182                                    owner.getKeyID()), d, issuer, exp));
[dd5d4d9]183                }
[484bb5a]184
185                /* The privilege itself */
[dd5d4d9]186                rv.add(new GENIPrivCredential(
187                            new Role(issuer.getKeyID() + "." + pname + "_" +
188                                target.getKeyID()),
189                            new Role(issuer.getKeyID() + ".speaks_for_" +
[7f614c1]190                                owner.getKeyID()), d, issuer, exp));
[dd5d4d9]191                if (cd ) {
[484bb5a]192                    /* The rules for delegation, if necessary */
[dd5d4d9]193                    rv.add(new GENIPrivCredential(
194                                new Role(issuer.getKeyID() + "." + pname + 
195                                    "_" + target.getKeyID()),
196                                new Role(issuer.getKeyID() + ".can_delegate_" 
197                                    + pname + "_" + target.getKeyID() + 
198                                    "." + pname + "_" + target.getKeyID()), 
[7f614c1]199                                d, issuer, exp));
[dd5d4d9]200                    rv.add(new GENIPrivCredential(
201                                new Role(issuer.getKeyID() + 
202                                    ".can_delegate_" + pname),
[7f614c1]203                                new Role(owner.getKeyID()), d, issuer, exp));
[dd5d4d9]204                }
205            }
206            return rv.toArray(new Credential[rv.size()]);
207        }
208
[484bb5a]209        /**
210         * Parse the credential into multiple GENIPrivCredentials that encode
211         * its semantics.
212         * @param is an InputStream containing the credentals
213         * @param ids a Collection of Identities to use in validation
214         * @return an array of GENIPrivCredentials that represent the
215         * credential
216         * @throws CertInvalidException if the stream is unparsable
217         * @throws MissingIssuerException if none of the Identities can
218         *                      validate the certificate
219         * @throws BadSignatureException if the signature check fails
220         */
[dd5d4d9]221        public Credential[] parseCredential(InputStream is, 
222                Collection<Identity> ids) throws ABACException {
223            try {
224                Document d = read_certificate(is);
225                XMLSignatureFactory fac = 
226                    XMLSignatureFactory.getInstance("DOM");
227                NodeList nl = d.getElementsByTagNameNS(XMLSignature.XMLNS, 
228                        "Signature");
229                DOMValidateContext valContext = null;
230                XMLSignature signature = null;
231                Identity lid = null;
232
233
234                if (nl.getLength() == 0) 
235                    throw new CertInvalidException(
236                            "Cannot find Signature element");
237
238                setIDAttrs(d);
239                valContext = new DOMValidateContext(new X509KeySelector(),
240                        nl.item(0));
241                if ( valContext == null )
242                    throw new ABACException("No validation context!?");
243
244                signature = fac.unmarshalXMLSignature(valContext);
245                if (signature == null) 
246                    throw new BadSignatureException(
247                            "Cannot unmarshal signature");
248
249                if (!signature.validate(valContext))
250                    throw new BadSignatureException("bad signature");
251
252                lid = getIdentity(nl.item(0));
253
254                if ( !ids.contains(lid) ) ids.add(lid);
255
[6bf703b0]256                return make_creds(d, lid);
[dd5d4d9]257            }
258            catch (ABACException ae) {
259                throw ae;
260            }
261            catch (Exception e) {
262                throw new BadSignatureException(e.getMessage(), e);
263            }
264        }
265
[484bb5a]266        /**
267         * One cannot create a GENIPrivCredential to encodes a single arbitrary
268         * head and tail, so this always fails.
269         * @param head a Role to encode
270         * @param tail a Role to encode
271         */
[dd5d4d9]272        public Credential generateCredential(Role head, Role tail) {
273            return null;
274        }
275    };
276
277    /**
[484bb5a]278     * Return a CredentialCredentialFactorySpecialization for
279     * GENIPrivCredentials.  Used by the CredentialFactory to parse these kind
280     * of credentials.
[dd5d4d9]281     * @return a CredentialFactorySpecialization for this kind of credential.
282     */
283    static public CredentialFactorySpecialization
284            getCredentialFactorySpecialization() {
285        return new GENIPrivSpecialization();
286    }
287}
Note: See TracBrowser for help on using the repository browser.