source: java/net/deterlab/abac/Credential.java @ 281158a

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

Write credentials

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