1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43:
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57:
58:
61: public class GnuPrivateKeyring
62: extends BaseKeyring
63: implements IPrivateKeyring
64: {
65: private static final Logger log = Logger.getLogger(GnuPrivateKeyring.class.getName());
66: public static final int USAGE = Registry.GKR_PRIVATE_KEYS
67: | Registry.GKR_PUBLIC_CREDENTIALS;
68: protected String mac;
69: protected int maclen;
70: protected String cipher;
71: protected String mode;
72: protected int keylen;
73:
74: public GnuPrivateKeyring(String mac, int maclen, String cipher, String mode,
75: int keylen)
76: {
77: keyring = new PasswordAuthenticatedEntry(mac, maclen, new Properties());
78: keyring2 = new CompressedEntry(new Properties());
79: keyring.add(keyring2);
80: this.mac = mac;
81: this.maclen = maclen;
82: this.cipher = cipher;
83: this.mode = mode;
84: this.keylen = keylen;
85: }
86:
87: public GnuPrivateKeyring()
88: {
89: this("HMAC-SHA-1", 20, "AES", "OFB", 16);
90: }
91:
92: public boolean containsPrivateKey(String alias)
93: {
94: if (Configuration.DEBUG)
95: log.entering(this.getClass().getName(), "containsPrivateKey", alias);
96: boolean result = false;
97: if (containsAlias(alias))
98: for (Iterator it = get(alias).iterator(); it.hasNext();)
99: if (it.next() instanceof PasswordAuthenticatedEntry)
100: {
101: result = true;
102: break;
103: }
104: if (Configuration.DEBUG)
105: log.exiting(this.getClass().getName(), "containsPrivateKey",
106: Boolean.valueOf(result));
107: return result;
108: }
109:
110: public Key getPrivateKey(String alias, char[] password)
111: throws UnrecoverableKeyException
112: {
113: if (Configuration.DEBUG)
114: log.entering(this.getClass().getName(), "getPrivateKey", alias);
115: Key result = null;
116: if (containsAlias(alias))
117: {
118: PasswordAuthenticatedEntry e1 = null;
119: for (Iterator it = get(alias).iterator(); it.hasNext();)
120: {
121: Entry e = (Entry) it.next();
122: if (Configuration.DEBUG)
123: log.finest("Entry: " + e);
124: if (e instanceof PasswordAuthenticatedEntry)
125: {
126: e1 = (PasswordAuthenticatedEntry) e;
127: break;
128: }
129: }
130: if (Configuration.DEBUG)
131: log.fine("e1 = " + e1);
132: if (e1 != null)
133: {
134: try
135: {
136: e1.verify(password);
137: }
138: catch (Exception e)
139: {
140: if (Configuration.DEBUG)
141: log.throwing(this.getClass().getName(), "getPrivateKey", e);
142: throw new UnrecoverableKeyException("authentication failed");
143: }
144: PasswordEncryptedEntry e2 = null;
145: for (Iterator it = e1.getEntries().iterator(); it.hasNext();)
146: {
147: Entry e = (Entry) it.next();
148: if (e instanceof PasswordEncryptedEntry)
149: {
150: e2 = (PasswordEncryptedEntry) e;
151: break;
152: }
153: }
154: if (e2 != null)
155: {
156: try
157: {
158: e2.decrypt(password);
159: }
160: catch (Exception e)
161: {
162: log.throwing(this.getClass().getName(), "getPrivateKey", e);
163: throw new UnrecoverableKeyException("decryption failed");
164: }
165: for (Iterator it = e2.get(alias).iterator(); it.hasNext();)
166: {
167: Entry e = (Entry) it.next();
168: if (e instanceof PrivateKeyEntry)
169: {
170: result = ((PrivateKeyEntry) e).getKey();
171: break;
172: }
173: }
174: }
175: }
176: }
177: if (Configuration.DEBUG)
178: log.exiting(this.getClass().getName(), "getPrivateKey",
179: result == null ? "null" : result.getClass().getName());
180: return result;
181: }
182:
183: public void putPrivateKey(String alias, Key key, char[] password)
184: {
185: if (Configuration.DEBUG)
186: log.entering(this.getClass().getName(), "putPrivateKey",
187: new Object[] { alias, key.getClass().getName() });
188: if (! containsPrivateKey(alias))
189: {
190: alias = fixAlias(alias);
191: Properties p = new Properties();
192: p.put("alias", alias);
193: PrivateKeyEntry pke = new PrivateKeyEntry(key, new Date(), p);
194: if (Configuration.DEBUG)
195: log.fine("About to encrypt the key...");
196: PasswordEncryptedEntry enc;
197: enc = new PasswordEncryptedEntry(cipher, mode, keylen, new Properties());
198: enc.add(pke);
199: try
200: {
201: enc.encode(null, password);
202: }
203: catch (IOException x)
204: {
205: if (Configuration.DEBUG)
206: log.log(Level.FINE, "Exception while encrypting the key. "
207: + "Rethrow as IllegalArgumentException", x);
208: throw new IllegalArgumentException(x.toString());
209: }
210: if (Configuration.DEBUG)
211: log.fine("About to authenticate the encrypted key...");
212: PasswordAuthenticatedEntry auth;
213: auth = new PasswordAuthenticatedEntry(mac, maclen, new Properties());
214: auth.add(enc);
215: try
216: {
217: auth.encode(null, password);
218: }
219: catch (IOException x)
220: {
221: if (Configuration.DEBUG)
222: log.log(Level.FINE, "Exception while authenticating the encrypted "
223: + "key. Rethrow as IllegalArgumentException", x);
224: throw new IllegalArgumentException(x.toString());
225: }
226: keyring.add(auth);
227: }
228: else if (Configuration.DEBUG)
229: log.fine("Keyring already contains alias: " + alias);
230: if (Configuration.DEBUG)
231: log.exiting(this.getClass().getName(), "putPrivateKey");
232: }
233:
234: public boolean containsPublicKey(String alias)
235: {
236: if (Configuration.DEBUG)
237: log.entering(this.getClass().getName(), "containsPublicKey", alias);
238: boolean result = false;
239: if (containsAlias(alias))
240: for (Iterator it = get(alias).iterator(); it.hasNext();)
241: if (it.next() instanceof PublicKeyEntry)
242: {
243: result = true;
244: break;
245: }
246: if (Configuration.DEBUG)
247: log.exiting(this.getClass().getName(), "containsPublicKey",
248: Boolean.valueOf(result));
249: return result;
250: }
251:
252: public PublicKey getPublicKey(String alias)
253: {
254: if (Configuration.DEBUG)
255: log.entering(this.getClass().getName(), "getPublicKey", alias);
256: PublicKey result = null;
257: if (containsAlias(alias))
258: for (Iterator it = get(alias).iterator(); it.hasNext();)
259: {
260: Entry e = (Entry) it.next();
261: if (e instanceof PublicKeyEntry)
262: {
263: result = ((PublicKeyEntry) e).getKey();
264: break;
265: }
266: }
267: if (Configuration.DEBUG)
268: log.exiting(this.getClass().getName(), "getPublicKey",
269: result == null ? "null" : result.getClass().getName());
270: return result;
271: }
272:
273: public void putPublicKey(String alias, PublicKey key)
274: {
275: if (Configuration.DEBUG)
276: log.entering(this.getClass().getName(), "putPublicKey",
277: new Object[] { alias, key.getClass().getName() });
278: if (! containsPublicKey(alias))
279: {
280: Properties p = new Properties();
281: p.put("alias", fixAlias(alias));
282: add(new PublicKeyEntry(key, new Date(), p));
283: }
284: else if (Configuration.DEBUG)
285: log.fine("Keyring already contains alias: " + alias);
286: if (Configuration.DEBUG)
287: log.exiting(this.getClass().getName(), "putPublicKey");
288: }
289:
290: public boolean containsCertPath(String alias)
291: {
292: if (Configuration.DEBUG)
293: log.entering(this.getClass().getName(), "containsCertPath", alias);
294: boolean result = false;
295: if (containsAlias(alias))
296: for (Iterator it = get(alias).iterator(); it.hasNext();)
297: if (it.next() instanceof CertPathEntry)
298: {
299: result = true;
300: break;
301: }
302: if (Configuration.DEBUG)
303: log.exiting(this.getClass().getName(), "containsCertPath",
304: Boolean.valueOf(result));
305: return result;
306: }
307:
308: public Certificate[] getCertPath(String alias)
309: {
310: if (Configuration.DEBUG)
311: log.entering(this.getClass().getName(), "getCertPath", alias);
312: Certificate[] result = null;
313: if (containsAlias(alias))
314: for (Iterator it = get(alias).iterator(); it.hasNext();)
315: {
316: Entry e = (Entry) it.next();
317: if (e instanceof CertPathEntry)
318: {
319: result = ((CertPathEntry) e).getCertPath();
320: break;
321: }
322: }
323: if (Configuration.DEBUG)
324: log.exiting(this.getClass().getName(), "getCertPath", result);
325: return result;
326: }
327:
328: public void putCertPath(String alias, Certificate[] path)
329: {
330: if (Configuration.DEBUG)
331: log.entering(this.getClass().getName(), "putCertPath",
332: new Object[] { alias, path });
333: if (! containsCertPath(alias))
334: {
335: Properties p = new Properties();
336: p.put("alias", fixAlias(alias));
337: add(new CertPathEntry(path, new Date(), p));
338: }
339: else if (Configuration.DEBUG)
340: log.fine("Keyring already contains alias: " + alias);
341: if (Configuration.DEBUG)
342: log.exiting(this.getClass().getName(), "putCertPath");
343: }
344:
345: protected void load(InputStream in, char[] password) throws IOException
346: {
347: if (Configuration.DEBUG)
348: log.entering(this.getClass().getName(), "load");
349: if (in.read() != USAGE)
350: throw new MalformedKeyringException("incompatible keyring usage");
351: if (in.read() != PasswordAuthenticatedEntry.TYPE)
352: throw new MalformedKeyringException(
353: "expecting password-authenticated entry tag");
354: keyring = PasswordAuthenticatedEntry.decode(new DataInputStream(in), password);
355: if (Configuration.DEBUG)
356: log.exiting(this.getClass().getName(), "load");
357: }
358:
359: protected void store(OutputStream out, char[] password) throws IOException
360: {
361: if (Configuration.DEBUG)
362: log.entering(this.getClass().getName(), "store");
363: out.write(USAGE);
364: keyring.encode(new DataOutputStream(out), password);
365: if (Configuration.DEBUG)
366: log.exiting(this.getClass().getName(), "store");
367: }
368: }