source: java/net/deterlab/abac/GENIPrivCredential.java @ 2405adf

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

Check expiration

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