1 /*
2 * The NeuClear Project and it's libraries are
3 * (c) 2002-2004 Antilles Software Ventures SA
4 * For more information see: http://neuclear.org
5 *
6 * This library is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 * Lesser General Public License for more details.
10 *
11 * You should have received a copy of the GNU Lesser General Public
12 * License along with this library; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 */
15 /*
16 $Id: SQLSigner.java,v 1.3 2004/07/21 23:07:16 pelle Exp $
17 $Log: SQLSigner.java,v $
18 Revision 1.3 2004/07/21 23:07:16 pelle
19 Updated the Signer interface with a new generateKey() method, which doesn't take any parameters.
20 It stores the generated key using the Base32 encoded SHA1 digest as it's alias.
21
22 Revision 1.2 2004/05/13 23:55:32 pelle
23 Updated Deneb Shahs SQLSigner
24 Also added his unit tests
25
26 Revision 1.1 2004/04/22 13:09:25 pelle
27 Added Deneb Shah's SQLSigner (deneb shah <deneb007@yahoo.com>)
28 Which stores private keys encrypted in a database and uses Hibernate.
29 */
30 package org.neuclear.commons.crypto.signers;
31
32 import org.neuclear.commons.LowLevelException;
33 import org.neuclear.commons.crypto.CryptoException;
34 import org.neuclear.commons.crypto.CryptoTools;
35 import org.neuclear.commons.crypto.passphraseagents.AlwaysTheSamePassphraseAgent;
36 import org.neuclear.commons.crypto.passphraseagents.InteractiveAgent;
37 import org.neuclear.commons.crypto.passphraseagents.PassPhraseAgent;
38 import org.neuclear.commons.crypto.passphraseagents.UserCancellationException;
39 import org.neuclear.commons.crypto.signers.hibernate.SQLStore;
40 import org.neuclear.commons.crypto.signers.hibernate.SQLStoreAccess;
41
42 import java.security.*;
43 import java.security.interfaces.DSAPublicKey;
44 import java.security.interfaces.RSAPublicKey;
45 import java.util.Iterator;
46
47 /***
48 * @author DESHAH
49 * <p/>
50 * To change the template for this generated type comment go to
51 * Window>Preferences>Java>Code Generation>Code and Comments
52 */
53 public class SQLSigner implements BrowsableSigner {
54 SQLStoreAccess access;
55 PassPhraseAgent agent;
56
57 /* (non-Javadoc)
58 * @see org.neuclear.commons.crypto.signers.BrowsableSigner#iterator()
59 *
60 * this will
61 * -- encrypt the private key with the CryptoTool
62 * -- create a SQLStore to store it
63 * -- use SQLAccess to store the key
64 */
65 public SQLSigner(String passphrase) {
66 access = new SQLStoreAccess();
67 agent = new AlwaysTheSamePassphraseAgent(passphrase);
68 }
69
70 public SQLSigner() {
71 this("neuclear");
72 }
73
74 /*
75 * This method should return an iterator list of all username
76 *
77 * Question ?
78 * -- why Iterator List ? why not any other dataStructure like String[]
79 *
80 * @see org.neuclear.commons.crypto.signers.BrowsableSigner#iterator()
81 */
82 public Iterator iterator() throws KeyStoreException {
83 return access.getAllUserName();
84 }
85
86 /* (non-Javadoc)
87 * @see org.neuclear.commons.crypto.signers.BrowsableSigner#sign(byte[], org.neuclear.commons.crypto.signers.SetPublicKeyCallBack)
88 *
89 * dont know what to do with this method yet
90 */
91 public byte[] sign(byte[] data, SetPublicKeyCallBack callback)
92 throws UserCancellationException {
93 return ((InteractiveAgent) agent).sign(this, data, callback);
94 }
95
96 /* (non-Javadoc)
97 * @see org.neuclear.commons.crypto.signers.BrowsableSigner#sign(java.lang.String, char[], byte[], org.neuclear.commons.crypto.signers.SetPublicKeyCallBack)
98 *
99 * This should sign the data with the privateKey
100 * and return the data
101 * -- get key from SQLStore using SQLStoreAccess for a given alias
102 * -- sign and return the data using CryptoTool
103 *
104 */
105 public byte[] sign(String alias,
106 char[] passphrase,
107 byte[] data,
108 SetPublicKeyCallBack callback)
109 throws InvalidPassphraseException {
110 try {
111 PrivateKey prvKey = getKey(alias, passphrase);
112 byte[] bytes = CryptoTools.sign(prvKey, data);
113 if (callback != null)
114 callback.setPublicKey(getPublicKey(alias));
115 return bytes;
116 } catch (UnrecoverableKeyException e) {
117 throw new InvalidPassphraseException(alias);
118 } catch (NoSuchAlgorithmException e) {
119 throw new LowLevelException(e);
120 } catch (KeyStoreException e) {
121 // Could try to reload it here but I wont for now
122 throw new LowLevelException(e);
123 } catch (CryptoException e) {
124 throw new LowLevelException(e);
125 }
126
127 }
128
129 /***
130 * This method will get the private key from the SQLStore
131 * -- Use SQLStore to get the private key
132 * -- unwrap the private key using CryptoTool with the passphrase
133 * -- return the decrypted privateKey
134 *
135 * @param name
136 * @param passphrase
137 * @return
138 * @throws UnrecoverableKeyException
139 * @throws NonExistingSignerException
140 * @throws NoSuchAlgorithmException
141 * @throws KeyStoreException
142 */
143 private PrivateKey getKey(final String name, final char[] passphrase) throws UnrecoverableKeyException, NonExistingSignerException, NoSuchAlgorithmException, KeyStoreException {
144 try {
145 SQLStoreAccess access = new SQLStoreAccess();
146 final byte[] arrWrappedPvtKey = access.getEncryptedPrivateKey(name);
147
148 if (arrWrappedPvtKey == null)
149 throw new NonExistingSignerException("No keys for: " + name);
150
151 final PrivateKey key = CryptoTools.unWrapRSAKey(passphrase, arrWrappedPvtKey);
152
153 if (key == null)
154 throw new NonExistingSignerException("No keys for: " + name);
155
156 return key;
157 } catch (ClassCastException e) {
158 throw new NonExistingSignerException("Incorrect Key type found");
159 } catch (CryptoException e) {
160 throw new NonExistingSignerException("Incorrect Key type found");
161 }
162
163
164 }
165
166 /*
167 * This method will generate a keyp pair and store it in the DB
168 * -- use Crypto Tools to generate a keypair
169 * -- get public key
170 * -- get Private key
171 * -- store it in the table using SQLStore
172 *
173 * (non-Javadoc)
174 * @see org.neuclear.commons.crypto.signers.BrowsableSigner#createKeyPair(java.lang.String, char[])
175 */
176 public void createKeyPair(String alias, char[] passphrase)
177 throws CryptoException {
178 try {
179
180 // for now it is RSA, later make it generic
181 KeyPair kp = CryptoTools.createTinyRSAKeyPair();
182 PrivateKey pvtKey = kp.getPrivate();
183 PublicKey pubKey = kp.getPublic();
184
185 byte[] encodedPublicKey = pubKey.getEncoded();
186 byte[] wrappedPrivateKey = CryptoTools.wrapKey(passphrase, pvtKey);
187
188 SQLStore store = new SQLStore(alias, wrappedPrivateKey, encodedPublicKey);
189
190 SQLStoreAccess access = new SQLStoreAccess();
191 access.add(store);
192
193 } catch (Exception e) {
194 throw new CryptoException("Aint Create Key -- under age");
195 }
196
197 }
198
199 /* (non-Javadoc)
200 * @see org.neuclear.commons.crypto.signers.Signer#sign(java.lang.String, byte[])
201 */
202 public byte[] sign(String name, byte[] data)
203 throws UserCancellationException, NonExistingSignerException {
204 return sign(name, data, false);
205 }
206
207 public final byte[] sign(final String name, final byte[] data, boolean incorrect) throws UserCancellationException, NonExistingSignerException {
208 try {
209 final char[] pass = getPassPhrase(name, incorrect);
210 return CryptoTools.sign(getKey(name, pass), data);
211 } catch (UnrecoverableKeyException e) {
212 System.err.println("Incorrect Passphrase Attemt on: " + name);
213 return sign(name, data, true);
214 } catch (NoSuchAlgorithmException e) {
215 throw new LowLevelException(e);
216 } catch (KeyStoreException e) {
217 // Could try to reload it here but I wont for now
218 throw new LowLevelException(e);
219 } catch (CryptoException e) {
220 throw new LowLevelException(e);
221 }
222 }
223
224 private char[] getPassPhrase(final String name, boolean incorrect) throws UserCancellationException {
225 if (incorrect && (agent instanceof InteractiveAgent))
226 ((InteractiveAgent) agent).getPassPhrase(name, true);
227 return agent.getPassPhrase(name);
228 }
229
230 /*
231 * This method will return true if the username is present in the db
232 *
233 * (non-Javadoc)
234 * @see org.neuclear.commons.crypto.signers.Signer#canSignFor(java.lang.String)
235 */
236 public boolean canSignFor(String name) {
237 SQLStoreAccess access = new SQLStoreAccess();
238 SQLStore store = access.verifyAlias(name);
239 if (store == null) {
240 return false;
241 }
242
243 return true;
244 }
245
246 /* (non-Javadoc)
247 * @see org.neuclear.commons.crypto.signers.Signer#getKeyType(java.lang.String)
248 */
249 public int getKeyType(String name) {
250
251 try {
252 if (canSignFor(name)) {
253 final PublicKey pk = getPublicKey(name);
254 if (pk instanceof RSAPublicKey)
255 return KEY_RSA;
256 if (pk instanceof DSAPublicKey)
257 return KEY_DSA;
258 return KEY_OTHER;
259 }
260 } catch (NonExistingSignerException e) {
261 return KEY_NONE;
262 }
263
264 return KEY_NONE;
265 }
266
267 /* (non-Javadoc)
268 * @see org.neuclear.commons.crypto.signers.Signer#generateKey(java.lang.String)
269 */
270 public PublicKey generateKey(String alias) throws UserCancellationException {
271 try {
272 // for now it is RSA, later make it generic
273 KeyPair kp = CryptoTools.createTinyRSAKeyPair();
274 PrivateKey pvtKey = kp.getPrivate();
275 PublicKey pubKey = kp.getPublic();
276
277 byte[] encodedPublicKey = pubKey.getEncoded();
278 byte[] wrappedPrivateKey = CryptoTools.wrapKey(agent.getPassPhrase(alias), pvtKey);
279
280 SQLStore store = new SQLStore(alias, wrappedPrivateKey, encodedPublicKey);
281
282 SQLStoreAccess access = new SQLStoreAccess();
283 access.add(store);
284
285 return pubKey;
286 } catch (CryptoException e) {
287 throw new UserCancellationException("[SQLSigner] [generateKey] -- " + e.getMessage());
288 } catch (NoSuchAlgorithmException e) {
289 throw new UserCancellationException("[SQLSigner] [generateKey] -- " + e.getMessage());
290 }
291 }
292
293 public PublicKey generateKey() throws UserCancellationException {
294 try {
295 // for now it is RSA, later make it generic
296 KeyPair kp = CryptoTools.createTinyRSAKeyPair();
297 PrivateKey pvtKey = kp.getPrivate();
298 PublicKey pubKey = kp.getPublic();
299
300 byte[] encodedPublicKey = pubKey.getEncoded();
301 String alias = CryptoTools.encodeBase32(CryptoTools.digest(encodedPublicKey));
302
303 byte[] wrappedPrivateKey = CryptoTools.wrapKey(agent.getPassPhrase(alias), pvtKey);
304
305 SQLStore store = new SQLStore(alias, wrappedPrivateKey, encodedPublicKey);
306
307 SQLStoreAccess access = new SQLStoreAccess();
308 access.add(store);
309
310 return pubKey;
311 } catch (CryptoException e) {
312 throw new UserCancellationException("[SQLSigner] [generateKey] -- " + e.getMessage());
313 } catch (NoSuchAlgorithmException e) {
314 throw new UserCancellationException("[SQLSigner] [generateKey] -- " + e.getMessage());
315 }
316 }
317
318 /* (non-Javadoc)
319 * @see org.neuclear.commons.crypto.signers.Signer#save()
320 */
321 public void save() throws UserCancellationException {
322 // TODO Auto-generated method stub
323 }
324
325 /* (non-Javadoc)
326 * @see org.neuclear.commons.crypto.signers.PublicKeySource#getPublicKey(java.lang.String)
327 */
328 public PublicKey getPublicKey(String name)
329 throws NonExistingSignerException {
330 try {
331 SQLStore store = access.verifyAlias(name);
332 byte[] arrPubKey = store.getPublicKey();
333 return CryptoTools.getPublicKeyFromBase64(new String(arrPubKey));
334 } catch (CryptoException e) {
335 throw new NonExistingSignerException("[SQLSigner] [getPublicKey] -- " + e.getMessage());
336 }
337 }
338
339 public static void main(String[] args) {
340 }
341 }
This page was automatically generated by Maven