source: java/net/deterlab/abac/GENICredentialv1_0.java @ c1736fe

abac0-leakabac0-meitvf-new-xml
Last change on this file since c1736fe was c1736fe, checked in by Ted Faber <faber@…>, 11 years ago

Nicer class structure for GENI credentials

  • Property mode set to 100644
File size: 8.0 KB
Line 
1package net.deterlab.abac;
2
3import java.io.*;
4import java.math.*;
5import java.text.*;
6
7import java.util.*;
8
9import java.security.*;
10import java.security.cert.*;
11
12import javax.xml.parsers.*;
13import javax.xml.transform.*;
14import javax.xml.transform.dom.*;
15import javax.xml.transform.stream.*;
16
17import javax.xml.crypto.*;
18import javax.xml.crypto.dsig.*;
19import javax.xml.crypto.dsig.dom.*;
20import javax.xml.crypto.dsig.keyinfo.*;
21import javax.xml.crypto.dsig.spec.*;
22
23import org.xml.sax.*;
24import org.w3c.dom.*;
25
26/**
27 * An ABAC credential formatted as a soon-to-be deprecated  abac-type version
28 * 1.0 GENI credential.
29 * @author <a href="http://abac.deterlab.net">ISI ABAC team</a>
30 * @version 1.4
31 */
32public class GENICredentialv1_0 extends GENICredential implements Comparable {
33    /**
34     * Create an empty Credential.
35     */
36    public GENICredentialv1_0() {
37        super();
38    }
39    /**
40     * Create a credential from a head and tail role.  This credential has no
41     * underlying certificate, and cannot be exported or used in real proofs.
42     * make_cert can create a certificate for a credential initialized this
43     * way.
44     * @param head the Role at the head of the credential
45     * @param tail the Role at the tail of the credential
46     */
47    public GENICredentialv1_0(Role head, Role tail) {
48        super(head, tail);
49    }
50
51    /**
52     * Create a credential from an attribute cert in a file. Throws an
53     * exception if the cert file can't be opened or if there's a format
54     * problem with the cert.  Note that catching
55     * java.security.GeneralSecurityException catches most of the exceptions
56     * this throws.
57     * @param filename a String containing the filename to read
58     * @param ids a Collection of Identities to use in validating the cert
59     * @throws CertInvalidException if the stream is unparsable
60     * @throws MissingIssuerException if none of the Identities can validate the
61     *                              certificate
62     * @throws BadSignatureException if the signature check fails
63     */
64    GENICredentialv1_0(String filename, Collection<Identity> ids) 
65        throws ABACException { 
66        super(filename, ids);
67    }
68
69    /**
70     * Create a credential from an attribute cert in a file. Throws an
71     * exception if the cert file can't be opened or if there's a format
72     * problem with the cert.  Note that catching
73     * java.security.GeneralSecurityException catches most of the exceptions
74     * this throws.
75     * @param file the File to read
76     * @param ids a Collection of Identities to use in validating the cert
77     * @throws CertInvalidException if the stream is unparsable
78     * @throws MissingIssuerException if none of the Identities can validate the
79     *                              certificate
80     * @throws BadSignatureException if the signature check fails
81     */
82    GENICredentialv1_0(File file, Collection<Identity> ids) 
83            throws ABACException {
84        super(file, ids);
85    }
86
87    /**
88     * Create a credential from an InputStream.  Throws an exception if the
89     * stream can't be parsed or if there's a format problem with the cert.
90     * Note that catching java.security.GeneralSecurityException catches most
91     * of the exceptions this throws.
92     * @param s the InputStream to read
93     * @param ids a Collection of Identities to use in validating the cert
94     * @throws CertInvalidException if the stream is unparsable
95     * @throws MissingIssuerException if none of the Identities can validate the
96     *                              certificate
97     * @throws BadSignatureException if the signature check fails
98     */
99    GENICredentialv1_0(InputStream s, Collection<Identity> ids) 
100            throws ABACException { 
101        super(s, ids);
102    }
103
104    /**
105     * Encode the abac credential's XML and set the validity.  This is straight
106     * line code that directly builds the credential.
107     * @param validity a long holding the number of seconds that the credential
108     * is valid for.
109     * @return a Node, the place to attach signatures
110     * @throws ABACException if any of the XML construction fails
111     */
112    protected Node make_rt0_content(long validity) throws ABACException {
113        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
114        DocumentBuilder db = null;
115        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
116        StringBuffer expBuf = new StringBuffer();
117
118        /* This is a weirdness to cope with the GENI format.  They have a naked
119         * xml:id specifier without any namespace declarations in the
120         * credential.  Notice that this is the opposite of the setting used in
121         * init to read a credential. */
122        dbf.setNamespaceAware(false);
123
124        if ( dbf == null ) 
125            throw new ABACException("Cannot get DocumentBuilderFactory!?");
126
127        try {
128            db = dbf.newDocumentBuilder();
129        }
130        catch (ParserConfigurationException pe) {
131            throw new ABACException("Cannot get DocumentBuilder!?" + 
132                    pe.getMessage(), pe);
133        }
134
135        doc = db.newDocument();
136        if ( doc == null ) 
137            throw new ABACException("No Document");
138
139        Element root = doc.createElement("signed-credential"); 
140        Element cred = doc.createElement("credential");
141        Element sig = doc.createElement("signatures");
142        Element e = doc.createElement("type");
143        Node text = doc.createTextNode("abac");
144
145        doc.appendChild(root);
146
147        cred.setAttribute("xml:id", "ref0");
148        /* So that the signing code can find the section to sign */
149        cred.setIdAttribute("xml:id", true);
150
151        root.appendChild(cred);
152        e.appendChild(text);
153        cred.appendChild(e);
154
155        m_expiration = new Date(System.currentTimeMillis() + 
156                (1000L * validity ));
157        df.setTimeZone(new SimpleTimeZone(0, "Z"));
158        df.format(m_expiration, expBuf, new FieldPosition(0));
159        e = doc.createElement("expires");
160        text = doc.createTextNode(expBuf.toString());
161        e.appendChild(text);
162        cred.appendChild(e);
163
164        e = doc.createElement("version");
165        text = doc.createTextNode("1.0");
166        e.appendChild(text);
167        cred.appendChild(e);
168
169        e = doc.createElement("rt0");
170        text = doc.createTextNode(m_head + "<-" + m_tail);
171        e.appendChild(text);
172        cred.appendChild(e);
173
174        root.appendChild(sig);
175        return sig;
176    }
177
178    /**
179     * Load the roles off the attribute cert.
180     * @throws CertInvalidException if the certificate is badly formatted
181     */
182    protected void load_roles() throws CertInvalidException {
183        if ( doc == null ) 
184            throw new CertInvalidException("No credential");
185
186        NodeList nodes = doc.getElementsByTagName("type");
187        Node node = null;
188        String roles = null;
189
190        if (nodes == null || nodes.getLength() != 1) 
191            throw new CertInvalidException("More than one type element?");
192
193        node = nodes.item(0);
194        if ( node == null ) 
195            throw new CertInvalidException("bad rt0 element?");
196
197        if ( !"abac".equals(node.getTextContent()) ) 
198            throw new CertInvalidException("Not an abac type credential");
199
200        nodes = doc.getElementsByTagName("rt0");
201        if (nodes == null || nodes.getLength() != 1) 
202            throw new CertInvalidException("More than one rt0 element?");
203
204        node = nodes.item(0);
205
206        if ( node == null ) 
207            throw new CertInvalidException("bad rt0 element?");
208
209        if ( (roles = node.getTextContent()) == null ) 
210            throw new CertInvalidException("bad rt0 element (no text)?");
211
212        String[] parts = roles.split("\\s*<--?\\s*");
213        if (parts.length != 2)
214            throw new CertInvalidException("Invalid attribute: " + roles);
215
216        m_head = new Role(parts[0]);
217        m_tail = new Role(parts[1]);
218    }
219
220    /**
221     * Return a CredentialCredentialFactorySpecialization for GENICredentials.
222     * Used by the CredentialFactory to parse and generate these kind of
223     * credentials.  It basically wraps constuctor calls.
224     * @return a CredentialFactorySpecialization for this kind of credential.
225     */
226    static public CredentialFactorySpecialization
227            getCredentialFactorySpecialization() {
228        return new CredentialFactorySpecialization() {
229            public Credential[] parseCredential(InputStream is, 
230                    Collection<Identity> ids) throws ABACException {
231                return new Credential[] { new GENICredentialv1_0(is, ids) }; 
232            }
233            public Credential generateCredential(Role head, Role tail) {
234                return new GENICredentialv1_0(head, tail);
235            }
236        };
237    }
238}
Note: See TracBrowser for help on using the repository browser.