source: java/net/deterlab/abac/Identity.java @ f63aa1b

abac0-leakabac0-meicompt_changesgec13mei-idmei-rt0-nmei_rt0mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2tvf-new-xml
Last change on this file since f63aa1b was 3a52bed, checked in by Ted Faber <faber@…>, 13 years ago

Allow IDs to generate new certs.

  • Property mode set to 100644
File size: 6.0 KB
Line 
1package net.deterlab.abac;
2
3import java.io.*;
4
5import java.util.*;
6import java.security.*;
7import java.security.cert.*;
8import javax.security.auth.x500.*;
9
10import java.math.BigInteger;
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;
17import org.bouncycastle.jce.provider.X509CertificateObject;
18import org.bouncycastle.openssl.PEMReader;
19import org.bouncycastle.openssl.PEMWriter;
20
21public class Identity implements Comparable {
22    private X509CertificateObject m_cert;
23    private String m_keyid;
24    private String m_cn;
25
26    /**
27     *  Initialize internals from PEM cert in a reader.  Use a PEMReader to get
28     *  the certificate, and call init(cert) on it.
29     */
30    protected void init(Reader r) throws 
31        CertificateException, NoSuchAlgorithmException,InvalidKeyException,
32        NoSuchProviderException, SignatureException, IOException {
33            PEMReader pr = new PEMReader(r);
34            Object c = pr.readObject();
35
36            if (c instanceof X509CertificateObject) 
37                init((X509CertificateObject)c);
38            else 
39                throw new CertificateException("Not an identity certificate");
40    }
41
42    /**
43     *  Initialize internals from cert.  Confirm it is self signed,  and then
44     *  the keyid and common name.  There's some work to get this stuff, but
45     *  it's all an incantation of getting the right classes to get the right
46     *  data.  Looks more complex than it is.
47     */
48    protected void init(X509CertificateObject c) throws
49        CertificateException, NoSuchAlgorithmException,InvalidKeyException,
50        NoSuchProviderException, SignatureException, IOException {
51            m_cert = (X509CertificateObject) c;
52            m_cert.verify(m_cert.getPublicKey());
53            // Cert is valid, fill in the CN and keyid
54            m_keyid = extractKeyID(m_cert.getPublicKey());
55            m_cn = m_cert.getSubjectDN().getName();
56            /// XXX: better parse
57            if (m_cn.startsWith("CN=")) m_cn = m_cn.substring(3);
58    }
59
60    /**
61     * Construct from a string, used as a CN
62     */
63    public Identity(String cn) throws
64            CertificateException, NoSuchAlgorithmException,InvalidKeyException,
65            NoSuchProviderException, SignatureException, IOException {
66        KeyPair kp = KeyPairGenerator.getInstance("RSA").genKeyPair();
67        X509V1CertificateGenerator gen = new X509V1CertificateGenerator();
68
69        gen.setIssuerDN(new X500Principal("CN=" + cn));
70        gen.setSubjectDN(new X500Principal("CN=" + cn));
71        gen.setNotAfter(new Date(System.currentTimeMillis() 
72                    + 3600 * 1000 * 24 * 365));
73        gen.setNotBefore(new Date(System.currentTimeMillis()));
74        gen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
75        gen.setPublicKey(kp.getPublic());
76        gen.setSignatureAlgorithm("SHA256WithRSAEncryption");
77        X509CertificateObject a = (X509CertificateObject) gen.generate(kp.getPrivate());
78        init(a);
79    }
80
81
82
83    /**
84     * Construct from a file, containing a self-signed PEM certificate.
85     */
86    public Identity(File file) throws 
87        CertificateException, NoSuchAlgorithmException,InvalidKeyException,
88        NoSuchProviderException, SignatureException, FileNotFoundException,
89        IOException { init(new FileReader(file)); }
90
91    /**
92     * Construct from a reader, containing a self-signed PEM certificate.
93     */
94    public Identity(Reader r) throws 
95        CertificateException, NoSuchAlgorithmException,InvalidKeyException,
96        NoSuchProviderException, SignatureException, IOException { init(r); }
97
98    /**
99     * Construct from an InputStream, containing a self-signed PEM certificate.
100     */
101    public Identity(InputStream s) throws 
102        CertificateException, NoSuchAlgorithmException,InvalidKeyException,
103        NoSuchProviderException, SignatureException, IOException { 
104            init(new InputStreamReader(s));
105        }
106
107    /**
108     * Construct from an X509CertificateObject, if you parsed one somewhere
109     * else.
110     */
111    public Identity(X509CertificateObject cert) throws 
112        CertificateException, NoSuchAlgorithmException,InvalidKeyException,
113        NoSuchProviderException, SignatureException, FileNotFoundException,
114        IOException { init(cert); }
115
116
117    /**
118     * Write the PEM cert to the given writer.
119     */
120    public void write(Writer w) throws IOException {
121        PEMWriter pw = new PEMWriter(w);
122
123        pw.writeObject(m_cert);
124        pw.flush();
125    }
126
127    /**
128     * Write the PEM cert to a file with the given name.
129     */
130    public void write(String fn) throws IOException, FileNotFoundException {
131        write(new FileWriter(fn));
132    }
133
134    /**
135     * Write the PEM cert to the given file.
136     */
137    public void write(File fn) throws IOException, FileNotFoundException {
138        write(new FileWriter(fn));
139    }
140
141    /**
142     * Write the PEM cert to the given OutputStream.
143     */
144    public void write(OutputStream s) 
145        throws IOException, FileNotFoundException {
146        write(new OutputStreamWriter(s));
147    }
148
149    /**
150     * Get to the SHA1 hash of the key.
151     */
152    public static String extractKeyID(PublicKey k) {
153        ASN1Sequence seq = null;
154        try {
155            seq = (ASN1Sequence) new ASN1InputStream(
156                    k.getEncoded()).readObject();
157        }
158        catch (IOException ie) {
159            // Badly formatted key??
160            return null;
161        }
162        SubjectPublicKeyInfo ki = new SubjectPublicKeyInfo(seq);
163        SubjectKeyIdentifier id = 
164            SubjectKeyIdentifier.createSHA1KeyIdentifier(ki);
165
166        // Now format it into a string for keeps
167        Formatter fmt = new Formatter(new StringWriter());
168        for (byte b: id.getKeyIdentifier())
169            fmt.format("%02x", b);
170        return fmt.out().toString();
171    }
172
173    // Accessors
174    public String getKeyID() { return m_keyid; }
175    public String getName() { return m_cn; }
176    public String toString() { return m_keyid + " (" + m_cn + ")"; }
177    public boolean equals(Object o) { 
178        if ( o == null ) return false;
179        else if ( ! (o instanceof Identity) ) return false;
180        else return getKeyID().equals(((Identity)o).getKeyID());
181    }
182    public int compareTo(Object o) { 
183        if ( ! (o instanceof Identity) ) return 1;
184        else return getKeyID().compareTo(((Identity)o).getKeyID());
185    }
186    public X509CertificateObject getCertificate() { return m_cert; }
187
188};
Note: See TracBrowser for help on using the repository browser.