source: java/net/deterlab/abac/Identity.java @ 1b88de8

abac0-leakabac0-meicompt_changesgec13mei-idmei-rt0-nmei_rt0mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2tvf-new-xml
Last change on this file since 1b88de8 was e36ea1d, checked in by Ted Faber <faber@…>, 14 years ago

Initial javadocs

  • Property mode set to 100644
File size: 13.2 KB
RevLine 
[9725efb]1package net.deterlab.abac;
2
3import java.io.*;
4
5import java.util.*;
6import java.security.*;
7import java.security.cert.*;
[3a52bed]8import javax.security.auth.x500.*;
[9725efb]9
[3a52bed]10import java.math.BigInteger;
[9725efb]11
12import org.bouncycastle.asn1.*;
13import org.bouncycastle.asn1.util.*;
14import org.bouncycastle.asn1.x509.*;
15import org.bouncycastle.x509.*;
16import org.bouncycastle.jce.provider.X509AttrCertParser;
[84f0e7a]17// import org.bouncycastle.jce.provider.X509CertificateObject;
[9725efb]18import org.bouncycastle.openssl.PEMReader;
[1a7e6d3]19import org.bouncycastle.openssl.PEMWriter;
[9725efb]20
[e36ea1d]21/**
22 * An ABAC identity.  An X509 Certificate-encoded public key.  The key
23 * identifier is used as the name of the Identity.  This whole class is
24 * something of a jabac extension.
25 * @author <a href="http://abac.deterlab.net">ISI ABAC team</a>
26 * @version 1.3
27 */
[5cf72cc]28public class Identity implements Comparable {
[e36ea1d]29    /** The underlying X509 certificate. */
30    protected X509Certificate cert;
31    /** The public key id used as this principal's name */
32    protected String keyid;
33    /** The common name in the certificate, used as a mnemonic */
34    protected String cn;
35    /** The keypair, if any, used to sign for this Identity */
36    protected KeyPair kp;
[9725efb]37
[1a7e6d3]38    /**
[e36ea1d]39     * Initialize from PEM cert in a reader.  Use a PEMReader to get
40     * the certificate, and call init(cert) on it.
41     * @param r a Reader containing the certificate
42     * @throws CertificateException if the certificate is badly formatted
43     * @throws InvalidKeyException if none of the Identities can validate the
44     *                              certificate
45     * @throws NoSuchAlgorithmException if the credential uses an unknown
46     *                              signature algorithm
47     * @throws NoSuchProviderException if the provider of the signature
48     *                              algorithm is unavailable
49     * @throws SignatureException if the signature check fails
50     * @throws IOException if the certificate is unparsable.
[1a7e6d3]51     */
[8a14e37]52    protected void init(Reader r) throws 
[42ca4b8]53            CertificateException, NoSuchAlgorithmException,InvalidKeyException,
54            NoSuchProviderException, SignatureException, IOException {
55        PEMReader pr = new PEMReader(r);
56        Object c = null;
57
58        while ( ( c= pr.readObject()) != null ){
59
[84f0e7a]60            if (c instanceof X509Certificate) {
[0595372]61                if ( cn == null ) 
[84f0e7a]62                    init((X509Certificate)c);
[42ca4b8]63                else
64                    throw new CertificateException("Two certs in one file");
65            }
66            else if (c instanceof KeyPair) setKeyPair((KeyPair)c);
[8a14e37]67            else 
[42ca4b8]68                throw new CertificateException(
69                        "Not an identity certificate");
70        }
[8a14e37]71    }
72
73    /**
[e36ea1d]74     * Initialize internals from cert.  Confirm it is self signed,  and then
75     * the keyid and common name.  There's some work to get this stuff, but
76     * it's all an incantation of getting the right classes to get the right
77     * data.  Looks more complex than it is.
78     * @param c an X509Certificate to init from
79     * @throws CertificateException if the certificate is badly formatted
80     * @throws InvalidKeyException if none of the Identities can validate the
81     *                              certificate
82     * @throws NoSuchAlgorithmException if the credential uses an unknown
83     *                              signature algorithm
84     * @throws NoSuchProviderException if the provider of the signature
85     *                              algorithm is unavailable
86     * @throws SignatureException if the signature check fails
87     * @throws IOException if the certificate is unparsable.
[8a14e37]88     */
[84f0e7a]89    protected void init(X509Certificate c) throws
[8a14e37]90        CertificateException, NoSuchAlgorithmException,InvalidKeyException,
91        NoSuchProviderException, SignatureException, IOException {
[0595372]92            cert = (X509Certificate) c;
93            cert.verify(cert.getPublicKey());
[8a14e37]94            // Cert is valid, fill in the CN and keyid
[0595372]95            keyid = Context.extractKeyID(cert.getPublicKey());
96            cn = cert.getSubjectDN().getName();
[8a14e37]97            /// XXX: better parse
[0595372]98            if (cn.startsWith("CN=")) cn = cn.substring(3);
[9725efb]99    }
100
[1a7e6d3]101    /**
[e36ea1d]102     * Construct from a string, used as a CN.  Keys are generated.
103     * @param cn a String containing the menomnic name
104     * @throws IOException reading or writing problems
105     * @throws CertificateEncodingException Problem creating certificate
106     * @throws InvalidKeyException if none of the Identities can sign the
107     *                              certificate
108     * @throws NoSuchAlgorithmException if the credential uses an unknown
109     *                              signature algorithm
110     * @throws NoSuchProviderException if the provider of the signature
111     *                              algorithm is unavailable
112     * @throws SignatureException if the signature creation fails
[1a7e6d3]113     */
[3a52bed]114    public Identity(String cn) throws
115            CertificateException, NoSuchAlgorithmException,InvalidKeyException,
116            NoSuchProviderException, SignatureException, IOException {
117        X509V1CertificateGenerator gen = new X509V1CertificateGenerator();
[42ca4b8]118        kp = KeyPairGenerator.getInstance("RSA").genKeyPair();
[3a52bed]119
120        gen.setIssuerDN(new X500Principal("CN=" + cn));
121        gen.setSubjectDN(new X500Principal("CN=" + cn));
122        gen.setNotAfter(new Date(System.currentTimeMillis() 
123                    + 3600 * 1000 * 24 * 365));
124        gen.setNotBefore(new Date(System.currentTimeMillis()));
125        gen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
126        gen.setPublicKey(kp.getPublic());
127        gen.setSignatureAlgorithm("SHA256WithRSAEncryption");
[84f0e7a]128        X509Certificate a = (X509Certificate) gen.generate(kp.getPrivate());
[3a52bed]129        init(a);
130    }
131
[9725efb]132
133
[1a7e6d3]134    /**
135     * Construct from a file, containing a self-signed PEM certificate.
[e36ea1d]136     * @param file the File to read
137     * @throws CertificateException if the certificate is badly formatted
138     * @throws InvalidKeyException if none of the Identities can validate the
139     *                              certificate
140     * @throws NoSuchAlgorithmException if the credential uses an unknown
141     *                              signature algorithm
142     * @throws NoSuchProviderException if the provider of the signature
143     *                              algorithm is unavailable
144     * @throws SignatureException if the signature check fails
145     * @throws IOException if the certificate is unparsable.
[1a7e6d3]146     */
[9725efb]147    public Identity(File file) throws 
148        CertificateException, NoSuchAlgorithmException,InvalidKeyException,
149        NoSuchProviderException, SignatureException, FileNotFoundException,
[42ca4b8]150        IOException { 
151            kp = null;
152            init(new FileReader(file));
153        }
[1a7e6d3]154
155    /**
[e36ea1d]156     * Construct from a reader containing a self-signed PEM certificate.
157     * @param r the Reader containing the certificate
158     * @throws CertificateException if the certificate is badly formatted
159     * @throws InvalidKeyException if none of the Identities can validate the
160     *                              certificate
161     * @throws NoSuchAlgorithmException if the credential uses an unknown
162     *                              signature algorithm
163     * @throws NoSuchProviderException if the provider of the signature
164     *                              algorithm is unavailable
165     * @throws SignatureException if the signature check fails
166     * @throws IOException if the certificate is unparsable.
[1a7e6d3]167     */
168    public Identity(Reader r) throws 
169        CertificateException, NoSuchAlgorithmException,InvalidKeyException,
[42ca4b8]170        NoSuchProviderException, SignatureException, IOException {
171            kp = null;
172            init(r);
173        }
[1a7e6d3]174
175    /**
[e36ea1d]176     * Construct from an InputStream containing a self-signed PEM certificate.
177     * @param s the InputStream containing the certificate
178     * @throws CertificateException if the certificate is badly formatted
179     * @throws InvalidKeyException if none of the Identities can validate the
180     *                              certificate
181     * @throws NoSuchAlgorithmException if the credential uses an unknown
182     *                              signature algorithm
183     * @throws NoSuchProviderException if the provider of the signature
184     *                              algorithm is unavailable
185     * @throws SignatureException if the signature check fails
186     * @throws IOException if the certificate is unparsable.
[1a7e6d3]187     */
188    public Identity(InputStream s) throws 
189        CertificateException, NoSuchAlgorithmException,InvalidKeyException,
190        NoSuchProviderException, SignatureException, IOException { 
[42ca4b8]191            kp = null;
[1a7e6d3]192            init(new InputStreamReader(s));
193        }
194
[8a14e37]195    /**
[e36ea1d]196     * Construct from an X509Certificate
197     * @param cert an X509Certificate to init from
198     * @throws CertificateException if the certificate is badly formatted
199     * @throws InvalidKeyException if none of the Identities can validate the
200     *                              certificate
201     * @throws NoSuchAlgorithmException if the credential uses an unknown
202     *                              signature algorithm
203     * @throws NoSuchProviderException if the provider of the signature
204     *                              algorithm is unavailable
205     * @throws SignatureException if the signature check fails
206     * @throws IOException if the certificate is unparsable.
[8a14e37]207     */
[84f0e7a]208    public Identity(X509Certificate cert) throws 
[8a14e37]209        CertificateException, NoSuchAlgorithmException,InvalidKeyException,
210        NoSuchProviderException, SignatureException, FileNotFoundException,
[42ca4b8]211        IOException { 
212            kp = null;
213            init(cert);
214        }
[8a14e37]215
[8a93b41]216    /**
217     * Write the PEM key to the given writer.
[e36ea1d]218     * @param w the Writer
219     * @return true if the Identity had a keypair and wrote the key
220     * @throws IOException if writing fails
[8a93b41]221     */
222    public boolean writePrivateKey(Writer w) throws IOException {
223        if (kp != null ) {
224            PEMWriter pw = new PEMWriter(w);
225
226            pw.writeObject(kp.getPrivate());
227            pw.flush();
228            return true;
229        }
230        else return false;
231    }
232
233    /**
234     * Write the PEM key to a file with the given name.
235     */
236    public boolean writePrivateKey(String fn) 
237            throws IOException, FileNotFoundException {
238        return writePrivateKey(new FileWriter(fn));
239    }
240
241    /**
242     * Write the PEM key to the given file.
[e36ea1d]243     * @param fn a String with the output file name
244     * @return true if the Identity had a keypair and wrote the key
245     * @throws IOException if writing fails
[8a93b41]246     */
247    public boolean writePrivateKey(File fn) 
248            throws IOException, FileNotFoundException {
249        return writePrivateKey(new FileWriter(fn));
250    }
251
252    /**
253     * Write the PEM key to the given OutputStream.
[e36ea1d]254     * @param s an OutputStream to write on
255     * @return true if the Identity had a keypair and wrote the key
256     * @throws IOException if writing fails
[8a93b41]257     */
258    public boolean writePrivateKey(OutputStream s) 
259            throws IOException, FileNotFoundException {
260        return writePrivateKey(new OutputStreamWriter(s));
261    }
262
[1a7e6d3]263
264    /**
265     * Write the PEM cert to the given writer.
[e36ea1d]266     * @param w a Writer to write on
267     * @throws IOException if writing fails
[1a7e6d3]268     */
269    public void write(Writer w) throws IOException {
270        PEMWriter pw = new PEMWriter(w);
271
[0595372]272        pw.writeObject(cert);
[5cf72cc]273        pw.flush();
[1a7e6d3]274    }
275
276    /**
277     * Write the PEM cert to a file with the given name.
278     */
279    public void write(String fn) throws IOException, FileNotFoundException {
280        write(new FileWriter(fn));
281    }
282
283    /**
284     * Write the PEM cert to the given file.
[e36ea1d]285     * @param fn a String with the output file name
286     * @throws IOException if writing fails
[1a7e6d3]287     */
288    public void write(File fn) throws IOException, FileNotFoundException {
289        write(new FileWriter(fn));
290    }
291
292    /**
293     * Write the PEM cert to the given OutputStream.
[e36ea1d]294     * @param s an OutputStream to write on
295     * @throws IOException if writing fails
[1a7e6d3]296     */
297    public void write(OutputStream s) 
298        throws IOException, FileNotFoundException {
299        write(new OutputStreamWriter(s));
300    }
[9725efb]301
[e9360e2]302
[e36ea1d]303    /**
304     * Return the Identity's KeyID
305     * @return the Identity's KeyID
306     */
[0595372]307    public String getKeyID() { return keyid; }
[e36ea1d]308    /**
309     * Return the Identity's mnemonic name
310     * @return the Identity's mnemonic name
311     */
[0595372]312    public String getName() { return cn; }
[e36ea1d]313    /**
314     * Return the Identity's X509 Certificate
315     * @return the Identity's X509 Certificate
316     */
317    public X509Certificate getCertificate() { return cert; }
318    /**
319     * Return a simple string rep of the Identity.
320     * @return a simple string rep of the Identity.
321     */
[42ca4b8]322    public String toString() { 
[0595372]323        String s = keyid + " (" + cn ;
[42ca4b8]324
[0595372]325        if (keyid != null ) s += " [keyed]";
[42ca4b8]326        s += ")";
327        return s;
328    }
329    /**
330     * Associate a keypair with this Identity.  If the ID has a certificate,
331     * make sure that the keypair matches it.  If not throw an
332     * IllegalArgumentException.
[e36ea1d]333     * @param k the KeyPair to connect
334     * @throws IllegalArgumentException if the keypair does not
335     *                              match the pubkey in the X509 certificate
[42ca4b8]336     */
337    public void setKeyPair(KeyPair k) {
[0595372]338        if (keyid != null) {
339            String kid = Context.extractKeyID(k.getPublic());
[42ca4b8]340
[0595372]341            if ( kid != null && kid.equals(keyid)) kp = k;
[42ca4b8]342            else 
343                throw new IllegalArgumentException(
344                        "Keypair does not match certificate");
345        }
346        else kp = k;
347    }
[e36ea1d]348
349    /**
350     * Return the keypair associated with this Identity (if any)
351     * @return the keypair associated with this Identity (if any)
352     */
[42ca4b8]353    public KeyPair getKeyPair() { return kp; }
[e36ea1d]354
355    /**
356     * Equality test.  Two Identities are equal if their key ID's match.
357     * @return true if the two key ID's are equal.
358     */
[5cf72cc]359    public boolean equals(Object o) { 
360        if ( o == null ) return false;
361        else if ( ! (o instanceof Identity) ) return false;
362        else return getKeyID().equals(((Identity)o).getKeyID());
363    }
[e36ea1d]364    /**
365     * Allow Identities to be compared.  They are ordered by their key ID's.
366     * @param o an Object to compare
367     * @return -1 if this Identity is before, 0 if they are the same, and 1
368     *              if this Identity is after the given object.
369     */
[5cf72cc]370    public int compareTo(Object o) { 
371        if ( ! (o instanceof Identity) ) return 1;
372        else return getKeyID().compareTo(((Identity)o).getKeyID());
373    }
[1a7e6d3]374
[9725efb]375};
Note: See TracBrowser for help on using the repository browser.