source: java/net/deterlab/abac/Credential.java @ 1a80501

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

Some cleanup

  • Property mode set to 100644
File size: 7.0 KB
RevLine 
[31b67d5]1package net.deterlab.abac;
2
[7ef13e3]3import java.io.*;
[281158a]4import java.math.*;
[7ef13e3]5
6import java.util.*;
[5cf72cc]7import java.util.zip.*;
[7ef13e3]8import java.security.*;
9import java.security.cert.*;
10
[9725efb]11import net.deterlab.abac.Identity;
[90f939f]12
13import org.bouncycastle.asn1.*;
[e9360e2]14import org.bouncycastle.asn1.x509.*;
[90f939f]15import org.bouncycastle.x509.*;
[281158a]16import org.bouncycastle.jce.X509Principal;
[90f939f]17import org.bouncycastle.jce.provider.X509AttrCertParser;
[7ef13e3]18import org.bouncycastle.jce.provider.X509CertificateObject;
19import org.bouncycastle.openssl.PEMReader;
[90f939f]20
[281158a]21import java.security.PrivateKey;
22
[88e139a]23public class Credential implements Comparable {
[9725efb]24    protected static Vector<Identity> s_ids = new Vector<Identity>();
[281158a]25    protected static String attrOID = "1.3.6.1.5.5.7.10.4";
[e9360e2]26    protected static String authKeyOID = "2.5.29.35";
[9394f1f]27
[0595372]28    private Role m_head;
29    private Role m_tail;
30    private X509V2AttributeCertificate ac;
31    private Identity id;
32
[9394f1f]33    /**
34     * A dummy credential.
35     */
36    public Credential() {
37        m_head = m_tail = null;
[0595372]38        ac = null;
39        id = null;
[9394f1f]40    }
[31b67d5]41    /**
42     * Create a credential from a head and tail role. This is only for testing.
43     * In a real implementation the Credential must be loaded from an X.509
44     * attribute cert.
45     */
46    public Credential(Role head, Role tail) {
47        m_head = head;
48        m_tail = tail;
[0595372]49        ac = null; 
50        id = null;
[31b67d5]51    }
52
[90f939f]53    /**
[7ef13e3]54     * Do the credential initialization from a filename.
[90f939f]55     */
[84f0e7a]56    protected void read_certificate(InputStream stream) 
57            throws Exception {
[90f939f]58        X509AttrCertParser parser = new X509AttrCertParser();
[1a7e6d3]59        parser.engineInit(stream);
[0595372]60        ac = (X509V2AttributeCertificate)parser.engineRead();
[84f0e7a]61    }
[7ef13e3]62
[be05757]63
[84f0e7a]64    protected void init(InputStream stream, Collection<Identity> ids) 
65            throws Exception {
66        read_certificate(stream);
[0595372]67        if (ac == null) throw new IOException("Unknown Format");
[84f0e7a]68        init(ids);
69    }
70
71    protected void init(Collection<Identity> ids) 
[0595372]72            throws CertificateException, InvalidKeyException, 
73                NoSuchAlgorithmException, NoSuchProviderException,
74                SignatureException {
75        for (Identity i: ids) {
[7ef13e3]76            try {
[0595372]77                ac.verify(i.getCertificate().getPublicKey(), "BC");
78                id = i;
[7ef13e3]79                break;
80            }
[9725efb]81            catch (InvalidKeyException e) { }
[7ef13e3]82        }
[0595372]83        if (id == null) throw new InvalidKeyException("Unknown identity");
[90f939f]84
85        load_roles();
[281158a]86
[0595372]87        if (!id.getKeyID().equals(m_head.issuer_part()))
[281158a]88            throw new InvalidKeyException("Unknown identity");
[90f939f]89    }
[7ef13e3]90    /**
91     * Create a credential from an attribute cert. Throws an exception if the
92     * cert file can't be opened or if there's a format problem with the cert.
93     */
[84f0e7a]94    public Credential(String filename, Collection<Identity> ids) 
95        throws Exception { init(new FileInputStream(filename), ids); }
[7ef13e3]96
97    /**
98     * Create a credential from an attribute cert. Throws an exception if the
99     * cert file can't be opened or if there's a format problem with the cert.
100     */
[84f0e7a]101    public Credential(File file, Collection<Identity> ids) 
102        throws Exception { init(new FileInputStream(file), ids); }
[1a7e6d3]103
104    /**
105     * Create a credential from an InputStream.
106     */
[84f0e7a]107    public Credential(InputStream s, Collection<Identity> ids) 
108        throws Exception { init(s, ids); }
109
110    public Credential(X509V2AttributeCertificate c, Collection<Identity> ids) 
111        throws Exception {
[0595372]112        ac = c;
[84f0e7a]113        init(ids);
[7ef13e3]114    }
115
[84f0e7a]116
[e9360e2]117    /**
118     * Create a certificate from this credential issued by the given identity.
119     * This is just grungy credential generation work.
120     */
121    public void make_cert(Identity i) {
122        PrivateKey key = i.getKeyPair().getPrivate();
[0595372]123        SubjectPublicKeyInfo pki = Context.extractSubjectPublicKeyInfo(
[e9360e2]124                i.getKeyPair().getPublic());
[281158a]125        X509V2AttributeCertificateGenerator gen = 
126            new X509V2AttributeCertificateGenerator();
127
128        gen.setIssuer(new AttributeCertificateIssuer(
129                    new X509Principal("CN="+m_head.issuer_part())));
130        gen.setHolder(new AttributeCertificateHolder(
131                    new X509Principal("CN="+m_head.issuer_part())));
132        gen.setNotAfter(new Date(System.currentTimeMillis() 
133                    + 3600 * 1000 * 24 * 365));
134        gen.setNotBefore(new Date(System.currentTimeMillis()));
135        gen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
136        gen.addAttribute(new X509Attribute(attrOID, 
137                    new DERSequence(
138                        new DERSequence(
139                            new DERUTF8String(toString())))));
140        gen.setSignatureAlgorithm("SHA256WithRSAEncryption");
141
142        try { 
[e9360e2]143            // Creddy expects an authority key identifier.
144            gen.addExtension(authKeyOID, false, 
145                    new AuthorityKeyIdentifier(pki));
146            // Create the cert.
[0595372]147            ac = (X509V2AttributeCertificate) gen.generate(key, "BC");
[281158a]148        }
149        catch (Exception e) { 
150            System.err.println(e);
151        }
152    }
[7ef13e3]153
[90f939f]154    /**
155     * Load the roles off the attribute cert. Throws a RuntimeException if
156     * there's something wrong with the cert.
157     */
158    private void load_roles() throws RuntimeException {
159        String roles = null;
160        try {
[0595372]161            X509Attribute attr = ac.getAttributes()[0];
[90f939f]162
163            DERSequence    java     = (DERSequence)attr.getValues()[0];
164            DERSequence    fucking  = (DERSequence)java.getObjectAt(0);
165            DERUTF8String  sucks    = (DERUTF8String)fucking.getObjectAt(0);
166
167            roles = sucks.getString();
168        }
169        catch (Exception e) {
[0595372]170            throw new RuntimeException("Badly formatted certificate");
[90f939f]171        }
172
173        String[] parts = roles.split("\\s*<--?\\s*");
174        if (parts.length != 2)
175            throw new RuntimeException("Invalid attribute: " + roles);
176
177        m_head = new Role(parts[0]);
178        m_tail = new Role(parts[1]);
179    }
180
[cfcdcb4b]181    /**
182     * Two credentials are the same if their roles are the same.
183     */
184    public boolean equals(Object o) {
185        if ( o instanceof Credential ) {
186            Credential c = (Credential) o;
187
188            if (m_head == null || m_tail == null ) return false;
189            else return (m_head.equals(c.head()) && m_tail.equals(c.tail()));
190        }
191        else return false;
192    }
193
[88e139a]194    public int compareTo(Object o) {
195        if (o instanceof Credential) {
196            Credential c = (Credential) o;
197
198            if (head().equals(c.head())) return tail().compareTo(c.tail());
199            else return head().compareTo(c.head());
200        }
201        else return 1;
202    }
203
204
[31b67d5]205    /**
206     * Get the head role from the credential.
207     */
[0595372]208    public Role head() { return m_head; }
[31b67d5]209
210    /**
211     * Get the tail role from the credential
212     */
[0595372]213    public Role tail() { return m_tail; }
[31b67d5]214
[90f939f]215    /**
216     * Gets the cert associated with this credential (if any).
217     */
[0595372]218    public X509V2AttributeCertificate cert() { return ac; }
[90f939f]219
[31b67d5]220    /**
221     * Turn the credential into string form. The format is head &lt;- tail. For
222     * example: A.r1 &lt;- B.r2.r3.
223     */
224    public String toString() {
225        return m_head + " <- " + m_tail;
226    }
227
[84f0e7a]228    public String simpleString(Context c) {
229        return m_head.simpleString(c) + " <- " + m_tail.simpleString(c);
[de63a31]230    }
231
[1a7e6d3]232    public void write(OutputStream s) throws IOException {
[0595372]233        s.write(ac.getEncoded());
[e9360e2]234        s.flush();
[1a7e6d3]235    }
236
237    public void write(String fn) throws IOException, FileNotFoundException {
238        write(new FileOutputStream(fn));
239    }
240
[0595372]241    public boolean hasCertificate() { return ac != null; }
[5cf72cc]242
[0595372]243    public Identity getID() { return id; }
[90f939f]244
[7ef13e3]245
[31b67d5]246}
Note: See TracBrowser for help on using the repository browser.