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
Line 
1package net.deterlab.abac;
2
3import java.io.*;
4import java.math.*;
5
6import java.util.*;
7import java.security.*;
8import java.security.cert.*;
9
10import net.deterlab.abac.Identity;
11
12import org.bouncycastle.asn1.*;
13import org.bouncycastle.x509.*;
14import org.bouncycastle.jce.X509Principal;
15import org.bouncycastle.jce.provider.X509AttrCertParser;
16import org.bouncycastle.jce.provider.X509CertificateObject;
17import org.bouncycastle.openssl.PEMReader;
18
19import org.bouncycastle.asn1.util.ASN1Dump;
20
21import java.security.PrivateKey;
22
23public class Credential {
24    protected static Vector<Identity> s_ids = new Vector<Identity>();
25    protected static String attrOID = "1.3.6.1.5.5.7.10.4";
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    }
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;
43        m_ac = null; 
44        m_id = null;
45    }
46
47    /**
48     * Do the credential initialization from a filename.
49     */
50    protected void init(InputStream stream) throws Exception {
51        X509AttrCertParser parser = new X509AttrCertParser();
52        parser.engineInit(stream);
53        m_ac = (X509V2AttributeCertificate)parser.engineRead();
54        m_id = null;
55
56        for (Identity id: s_ids) {
57            try {
58                m_ac.verify(id.getCertificate().getPublicKey(), "BC");
59                m_id = id;
60                break;
61            }
62            catch (InvalidKeyException e) { }
63        }
64        if (m_id == null) throw new InvalidKeyException("Unknown identity");
65
66        load_roles();
67
68        if (!m_id.getKeyID().equals(m_head.issuer_part()))
69            throw new InvalidKeyException("Unknown identity");
70    }
71
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 {
77        init(new FileInputStream(filename));
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 {
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);
93    }
94
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    }
120
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
130            //System.err.println(ASN1Dump.dumpAsString(attr));
131
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
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
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
177    /**
178     * Gets the cert associated with this credential (if any).
179     */
180    public X509V2AttributeCertificate cert() {
181        return m_ac;
182    }
183
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
192    public String simpleString() {
193        return m_head.simpleString() + " <- " + m_tail.simpleString();
194    }
195
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
204    public boolean hasCertificate() { return m_ac != null; }
205
206    private Role m_head, m_tail;
207
208    private X509V2AttributeCertificate m_ac;
209    private Identity m_id;
210
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    }
216    public static Collection<Identity> identities() { return s_ids; }
217}
Note: See TracBrowser for help on using the repository browser.