1 /*
2 * Copyright 2002 Massachusetts Institute of Technology
3 *
4 * Permission to use, copy, modify, and distribute this program for any
5 * purpose and without fee is hereby granted, provided that this
6 * copyright and permission notice appear on all copies and supporting
7 * documentation, the name of M.I.T. not be used in advertising or
8 * publicity pertaining to distribution of the program without specific
9 * prior permission, and notice be given in supporting documentation that
10 * copying and distribution is by permission of M.I.T. M.I.T. makes no
11 * representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 */
14 package jsdsi;
15
16 import java.io.FileReader;
17 import java.io.IOException;
18 import java.io.LineNumberReader;
19 import java.math.BigInteger;
20 import java.net.URI;
21 import java.security.InvalidAlgorithmParameterException;
22 import java.security.NoSuchAlgorithmException;
23 import java.security.cert.CollectionCertStoreParameters;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.StringTokenizer;
30
31 /***
32 * <p>Creates a set of certificates from a flat text file for testing.
33 * Each certificate appears on its own line. Blank lines are allowed,
34 * but comments are not.
35 *
36 * <p>Name certs are specified as follows:
37 * <br><code>ISSUER name -> SUBJECT [names...]</code>
38 *
39 * <p>For example,
40 * <br><code>ALICE friends -> BOB</code>
41 * <br><code>BOB my-friends -> BOB sister</code>
42 * <br><code>BOB sister -> CAROL</code>
43 *
44 * <p>Note that we use uppercase for keys and lowercase for names for
45 * clarity, but this is not required. However, lines are
46 * case-sensitive, so <code>"BOB"</code> is different from
47 * <code>"Bob"</code>.
48 *
49 * <p>Auth certs are specified as follows:
50 * <br><code>ISSUER [!|+]tag -> SUBJECT [names...]</code>
51 * <br>where ! means the permission <code>"tag"</code> cannot be
52 * delegated, while <code>"+"</code>
53 * means that it can.
54 *
55 * <p>For example,
56 * <br><code>ALICE !read -> BOB</code>
57 * <br><code>BOB +write -> BOB my-friends</code>
58 *
59 * @author Sameer Ajmani
60 * @author Sean Radford
61 * @version $Revision: 1.3 $ $Date: 2004/03/09 23:03:43 $
62 */
63 public class Loader {
64 /***
65 * The keys.
66 */
67 private Map keys = new HashMap();
68
69 /***
70 * The certs.
71 */
72 private Set certSet = new HashSet();
73
74 /***
75 * The names.
76 */
77 private Set nameSet = new HashSet();
78
79 /***
80 * Thes tags.
81 */
82 private Set tagSet = new HashSet();
83
84 /***
85 * The cert store.
86 */
87 private java.security.cert.CertStore store;
88
89 /***
90 * Creates a new <code>Loader</code> from a given filename.
91 *
92 * @param filename filename to read the certificates from.
93 * @throws IOException if an error occurs reading the file
94 * <code>filename</code>.
95 */
96 public Loader(String filename) throws IOException {
97 Set certs = new HashSet();
98 LineNumberReader in = new LineNumberReader(new FileReader(filename));
99 in.setLineNumber(1);
100 for (String line = in.readLine(); line != null; line = in.readLine()) {
101 StringTokenizer t = new StringTokenizer(line);
102 if (t.countTokens() == 0) {
103 continue; // skip empty lines
104 }
105 if (t.countTokens() < 4) {
106 throw new IOException(
107 "bad input on line " + in.getLineNumber() + ": " + line);
108 }
109 Principal issuer = getPrincipal(t.nextToken());
110 String name = t.nextToken();
111 String arrow = t.nextToken();
112 if (!arrow.equals("->")) {
113 throw new IOException(
114 "bad arrow on line " + in.getLineNumber() + ": " + line);
115 }
116 Principal sub = getPrincipal(t.nextToken());
117 String[] names = new String[t.countTokens()];
118 for (int i = 0; i < names.length; i++) {
119 names[i] = t.nextToken();
120 }
121 Subject subject =
122 (names.length > 0)
123 ? (Subject) new Name(sub, names)
124 : (Subject) sub;
125
126 // create a fake certificate with a fake signature
127 Cert c;
128 if (name.startsWith("!") || name.startsWith("+")) {
129 // this is an auth cert
130 Tag tag = new StringTag(name.substring(1));
131 tagSet.add(tag);
132 c =
133 new AuthCert(
134 issuer,
135 subject,
136 null,
137 null,
138 null,
139 tag,
140 name.startsWith("+"));
141 // propagate?
142 } else {
143 // this is a name cert
144 nameSet.add(new Name(issuer, name));
145 c = new NameCert(issuer, subject, null, null, null, name);
146 }
147 certSet.add(c);
148 Signature s =
149 new Signature(
150 issuer,
151 new Hash("md5", "HASH-VALUE".getBytes(), null),
152 "rsa-pkcs1-md5",
153 "SIGNATURE-VALUE".getBytes());
154 try {
155 certs.add(new Certificate(c, s));
156 } catch (java.security.cert.CertificateException e) {
157 throw new Error(e);
158 }
159 }
160 try {
161 store =
162 java.security.cert.CertStore.getInstance(
163 "SPKI",
164 new CollectionCertStoreParameters(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
219 * or creates a new one from the bytes stored in the given key (assuming
220 * <code>MD5/RSA/PKCS#1</code> format).
221 *
222 * @param id key to add to the keys of this <code>Loader</code> if not
223 * already stored (assumes <code>MD5/RSA/PKCS#1</code> format).
224 * @return either the key already stored or the new key added to the keys.
225 */
226 private Principal getPrincipal(String id) {
227 RSAPublicKey k = (RSAPublicKey) keys.get(id);
228 if (k == null) {
229 k =
230 new RSAPublicKey(
231 new BigInteger(id.getBytes()),
232 new BigInteger(new byte[] { 0x03 }),
233 "MD5/RSA/PKCS#1",
234 (URI[])null);
235 keys.put(id, k);
236 }
237 return k;
238 }
239 }
This page was automatically generated by Maven