1
2 package jsdsi.util;
3
4 import java.io.FileReader;
5 import java.io.IOException;
6 import java.io.LineNumberReader;
7 import java.math.BigInteger;
8 import java.net.URI;
9 import java.security.InvalidAlgorithmParameterException;
10 import java.security.NoSuchAlgorithmException;
11 import java.security.cert.CollectionCertStoreParameters;
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.Map;
16 import java.util.Set;
17 import java.util.StringTokenizer;
18
19 import jsdsi.AuthCert;
20 import jsdsi.Cert;
21 import jsdsi.Certificate;
22 import jsdsi.Hash;
23 import jsdsi.Name;
24 import jsdsi.NameCert;
25 import jsdsi.Principal;
26 import jsdsi.RSAPublicKey;
27 import jsdsi.Signature;
28 import jsdsi.StringTag;
29 import jsdsi.Subject;
30 import jsdsi.Tag;
31 import jsdsi.certstore.CertificateDAO;
32 import jsdsi.certstore.InMemoryCertificateDAO;
33 import jsdsi.certstore.JsdsiCertStoreParameters;
34
35 /***
36 * <p>
37 * <strong>NOTE: </strong> This class is purely used for testing purposes and creates invalid
38 * certificates with fake signatures.
39 * </p>
40 * <p>
41 * Creates a set of certificates from a flat text file for testing. Each certificate appears on its
42 * own line. Blank lines are allowed, but comments are not.
43 * <p>
44 * Name certs are specified as follows: <br>
45 * <code>ISSUER name -> SUBJECT [names...]</code>
46 * <p>
47 * For example, <br>
48 * <code>ALICE friends -> BOB</code><br>
49 * <code>BOB my-friends -> BOB sister</code><br>
50 * <code>BOB sister -> CAROL</code>
51 * <p>
52 * Note that we use uppercase for keys and lowercase for names for clarity, but this is not
53 * required. However, lines are case-sensitive, so <code>"BOB"</code> is different from
54 * <code>"Bob"</code>.
55 * <p>
56 * Auth certs are specified as follows: <br>
57 * <code>ISSUER [!|+]tag -> SUBJECT [names...]</code><br>
58 * where ! means the permission <code>"tag"</code> cannot be delegated, while
59 * <code>"+"</code> means that it can.
60 * <p>
61 * For example, <br>
62 * <code>ALICE !read -> BOB</code><br>
63 * <code>BOB +write -> BOB my-friends</code>
64 *
65 * @author Sameer Ajmani
66 * @author Sean Radford
67 * @version $Revision: 1.2.2.2 $ $Date: 2005/11/08 03:12:52 $
68 */
69 public class Loader {
70
71 /***
72 * The CertificateDAO this Loader should use for its CertStore
73 */
74 private CertificateDAO dao;
75
76 /***
77 * The keys.
78 */
79 private Map keys = new HashMap();
80
81 /***
82 * The certs.
83 */
84 private Set certSet = new HashSet();
85
86 /***
87 * The names.
88 */
89 private Set nameSet = new HashSet();
90
91 /***
92 * Thes tags.
93 */
94 private Set tagSet = new HashSet();
95
96 /***
97 * The cert store.
98 */
99 private java.security.cert.CertStore store;
100
101 /***
102 * Creates a new <code>Loader</code> from a given filename.
103 *
104 * @param filename filename to read the certificates from.
105 * @param dao to use for the CertStore
106 * @throws IOException if an error occurs reading the file <code>filename</code>.
107 */
108 public Loader(String filename, CertificateDAO dao) throws IOException {
109 Set certs = new HashSet();
110 LineNumberReader in = new LineNumberReader(new FileReader(filename));
111 in.setLineNumber(1);
112 for (String line = in.readLine(); line != null; line = in.readLine()) {
113 StringTokenizer t = new StringTokenizer(line);
114 if (t.countTokens() == 0) {
115 continue; // skip empty lines
116 }
117 if (t.countTokens() < 4) {
118 throw new IOException("bad input on line " + in.getLineNumber() + ": " + line);
119 }
120 Principal issuer = getPrincipal(t.nextToken());
121 String name = t.nextToken();
122 String arrow = t.nextToken();
123 if (!arrow.equals("->")) {
124 throw new IOException("bad arrow on line " + in.getLineNumber() + ": " + line);
125 }
126 Principal sub = getPrincipal(t.nextToken());
127 String[] names = new String[t.countTokens()];
128 for (int i = 0; i < names.length; i++) {
129 names[i] = t.nextToken();
130 }
131 Subject subject = (names.length > 0) ? (Subject) new Name(sub,
132 names) : (Subject) sub;
133
134 // create a fake certificate with a fake signature
135 Cert c;
136 if (name.startsWith("!") || name.startsWith("+")) {
137 // this is an auth cert
138 Tag tag = new StringTag(name.substring(1));
139 tagSet.add(tag);
140 c = new AuthCert(issuer,
141 subject,
142 null, null, null, tag, name.startsWith("+"));
143 // propagate?
144 } else {
145 // this is a name cert
146 nameSet.add(new Name(issuer, name));
147 c = new NameCert(issuer, subject, null, null, null, name);
148 }
149 certSet.add(c);
150 Signature s = new Signature(issuer,
151 new Hash("md5",
152 "HASH-VALUE".getBytes(), null),
153 "rsa-pkcs1-md5",
154 "SIGNATURE-VALUE".getBytes());
155 try {
156 certs.add(new Certificate(c, s));
157 } catch (java.security.cert.CertificateException e) {
158 throw new Error(e);
159 }
160 }
161 try {
162 store = java.security.cert.CertStore.getInstance("SPKI",
163 new JsdsiCertStoreParameters(
164 dao, certs));
165 } catch (InvalidAlgorithmParameterException e) {
166 throw new Error(e);
167 } catch (NoSuchAlgorithmException e) {
168 throw new Error(e);
169 }
170 }
171
172 /***
173 * Returns the cert store of this <code>Loader</code>.
174 *
175 * @return the cert store of this <code>Loader</code>.
176 */
177 public java.security.cert.CertStore getCertStore() {
178 return store;
179 }
180
181 /***
182 * Returns the keys of this <code>Loader</code>.
183 *
184 * @return the keys of this <code>Loader</code>.
185 */
186 public Collection getKeys() {
187 return keys.values();
188 }
189
190 /***
191 * Returns the certs of this <code>Loader</code>.
192 *
193 * @return the certs of this <code>Loader</code>.
194 */
195 public Set getCerts() {
196 return certSet;
197 }
198
199 /***
200 * Returns the names of this <code>Loader</code>.
201 *
202 * @return the names of this <code>Loader</code>.
203 */
204 public Set getNames() {
205 return nameSet;
206 }
207
208 /***
209 * Returns the tags of this <code>Loader</code>.
210 *
211 * @return the tags of this <code>Loader</code>.
212 */
213 public Set getTags() {
214 return tagSet;
215 }
216
217 /***
218 * For a given string: looks if the key is already saved in the loader or creates a new one from
219 * the bytes stored in the given key (assuming <code>MD5/RSA/PKCS#1</code> format).
220 *
221 * @param id key to add to the keys of this <code>Loader</code> if not already stored (assumes
222 * <code>MD5/RSA/PKCS#1</code> format).
223 * @return either the key already stored or the new key added to the keys.
224 */
225 private Principal getPrincipal(String id) {
226 RSAPublicKey k = (RSAPublicKey) keys.get(id);
227 if (k == null) {
228 k = new RSAPublicKey(new BigInteger(id.getBytes()),
229 new BigInteger(new byte[] { 0x03 }),
230 "MD5/RSA/PKCS#1", (URI[]) null);
231 keys.put(id, k);
232 }
233 return k;
234 }
235 }
This page was automatically generated by Maven