KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > ui > cli > KeyStoreContainer


1 /**
2  *
3  */

4 package org.ejbca.ui.cli;
5
6 import java.io.BufferedInputStream JavaDoc;
7 import java.io.BufferedOutputStream JavaDoc;
8 import java.io.BufferedReader JavaDoc;
9 import java.io.ByteArrayInputStream JavaDoc;
10 import java.io.ByteArrayOutputStream JavaDoc;
11 import java.io.IOException JavaDoc;
12 import java.io.InputStream JavaDoc;
13 import java.io.InputStreamReader JavaDoc;
14 import java.io.OutputStream JavaDoc;
15 import java.lang.reflect.InvocationTargetException JavaDoc;
16 import java.math.BigInteger JavaDoc;
17 import java.security.InvalidKeyException JavaDoc;
18 import java.security.Key JavaDoc;
19 import java.security.KeyPair JavaDoc;
20 import java.security.KeyPairGenerator JavaDoc;
21 import java.security.KeyStore JavaDoc;
22 import java.security.KeyStoreException JavaDoc;
23 import java.security.NoSuchAlgorithmException JavaDoc;
24 import java.security.NoSuchProviderException JavaDoc;
25 import java.security.Provider JavaDoc;
26 import java.security.Security JavaDoc;
27 import java.security.SignatureException JavaDoc;
28 import java.security.UnrecoverableKeyException JavaDoc;
29 import java.security.cert.Certificate JavaDoc;
30 import java.security.cert.CertificateException JavaDoc;
31 import java.security.cert.X509Certificate JavaDoc;
32 import java.util.Collection JavaDoc;
33 import java.util.Date JavaDoc;
34 import java.util.Enumeration JavaDoc;
35 import java.util.Iterator JavaDoc;
36
37 import javax.security.auth.x500.X500Principal JavaDoc;
38
39 import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
40 import org.bouncycastle.cms.CMSEnvelopedDataParser;
41 import org.bouncycastle.cms.CMSEnvelopedDataStreamGenerator;
42 import org.bouncycastle.cms.CMSTypedStream;
43 import org.bouncycastle.cms.RecipientInformation;
44 import org.bouncycastle.cms.RecipientInformationStore;
45 import org.bouncycastle.jce.provider.BouncyCastleProvider;
46 import org.bouncycastle.x509.X509V3CertificateGenerator;
47
48 public class KeyStoreContainer {
49     private void setPassWord(boolean isKeystoreException) throws IOException JavaDoc {
50         System.err.println((isKeystoreException ? "Setting key entry in keystore" : "Loading keystore")+". Give password of inserted card in slot:");
51         final char result[] = passwordReader.readPassword();
52         if ( isKeystoreException )
53             this.passPhraseGetSetEntry = result;
54         else
55             this.passPhraseLoadSave = result;
56     }
57     private final KeyStore JavaDoc keyStore;
58     private final String JavaDoc providerName;
59     private final String JavaDoc ecryptProviderName;
60     private final PasswordReader passwordReader;
61     private char passPhraseLoadSave[] = null;
62     private char passPhraseGetSetEntry[] = null;
63     public KeyStoreContainer(final String JavaDoc keyStoreType,
64                              final String JavaDoc providerClassName,
65                              final String JavaDoc encryptProviderClassName,
66                              final String JavaDoc sStoreID) throws NoSuchAlgorithmException JavaDoc, CertificateException JavaDoc, KeyStoreException JavaDoc, NoSuchProviderException JavaDoc, IOException JavaDoc, IllegalArgumentException JavaDoc, SecurityException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc, InvocationTargetException JavaDoc, NoSuchMethodException JavaDoc, ClassNotFoundException JavaDoc {
67         this( keyStoreType,
68               providerClassName,
69               encryptProviderClassName,
70               sStoreID,
71               null );
72     }
73     public KeyStoreContainer(final String JavaDoc keyStoreType,
74                              final String JavaDoc providerClassName,
75                              final String JavaDoc encryptProviderClassName,
76                              final String JavaDoc sStoreID,
77                              final PasswordReader _passwordReader) throws NoSuchAlgorithmException JavaDoc, CertificateException JavaDoc, KeyStoreException JavaDoc, NoSuchProviderException JavaDoc, IOException JavaDoc, IllegalArgumentException JavaDoc, SecurityException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc, InvocationTargetException JavaDoc, NoSuchMethodException JavaDoc, ClassNotFoundException JavaDoc {
78         final byte storeID[] = sStoreID!=null ? sStoreID.getBytes():null;
79         Security.addProvider( new BouncyCastleProvider() );
80         this.providerName = getProviderName(providerClassName);
81         this.ecryptProviderName = getProviderName(encryptProviderClassName);
82         this.passwordReader = _passwordReader!=null ? _passwordReader : new DefaultPasswordReader();
83         System.err.println("Creating KeyStore of type "+keyStoreType+" with provider "+this.providerName+(storeID!=null ? (" with ID "+new String JavaDoc(storeID)) : "")+'.');
84         this.keyStore = KeyStore.getInstance(keyStoreType, this.providerName);
85         try {
86             load(storeID);
87         } catch( IOException JavaDoc e ) {
88             setPassWord(false);
89             load(storeID);
90         }
91     }
92     public interface PasswordReader {
93         char[] readPassword() throws IOException JavaDoc;
94     }
95     private class DefaultPasswordReader implements PasswordReader {
96         public char[] readPassword() throws IOException JavaDoc {
97             return new BufferedReader JavaDoc(new InputStreamReader JavaDoc(System.in)).readLine().toCharArray();
98         }
99     }
100     String JavaDoc getProviderName() {
101         return this.providerName;
102     }
103     private void load(byte storeID[]) throws NoSuchAlgorithmException JavaDoc, CertificateException JavaDoc, IOException JavaDoc {
104         this.keyStore.load(storeID!=null ? new ByteArrayInputStream JavaDoc(storeID):null, this.passPhraseLoadSave);
105     }
106     public byte[] storeKeyStore() throws KeyStoreException JavaDoc, NoSuchAlgorithmException JavaDoc, CertificateException JavaDoc, IOException JavaDoc {
107         System.err.println("Next line will contain the identity identifying the keystore:");
108         ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
109         this.keyStore.store(baos, this.passPhraseLoadSave);
110         System.out.print(new String JavaDoc(baos.toByteArray()));
111         System.out.flush();
112         System.err.println();
113         return baos.toByteArray();
114     }
115     public KeyStore JavaDoc getKeyStore() {
116         return this.keyStore;
117     }
118     void setKeyEntry(String JavaDoc alias, Key JavaDoc key, Certificate JavaDoc chain[]) throws IOException JavaDoc, KeyStoreException JavaDoc {
119         try {
120             this.keyStore.setKeyEntry(alias, key, this.passPhraseGetSetEntry, chain);
121         } catch (KeyStoreException JavaDoc e) {
122             setPassWord(true);
123             this.keyStore.setKeyEntry(alias, key, this.passPhraseGetSetEntry, chain);
124         }
125     }
126     void deleteAlias(String JavaDoc alias) throws KeyStoreException JavaDoc {
127         this.keyStore.deleteEntry(alias);
128         System.err.println("Deleting certificate with alias "+alias+'.');
129     }
130     public byte[] delete(final String JavaDoc alias) throws Exception JavaDoc {
131         if ( alias!=null )
132             deleteAlias(alias);
133         else {
134             Enumeration JavaDoc e = this.keyStore.aliases();
135             while( e.hasMoreElements() )
136                 deleteAlias( (String JavaDoc) e.nextElement() );
137         }
138         return storeKeyStore();
139     }
140     public Key JavaDoc getKey(String JavaDoc alias) throws KeyStoreException JavaDoc, NoSuchAlgorithmException JavaDoc, UnrecoverableKeyException JavaDoc, IOException JavaDoc {
141         try {
142             return this.keyStore.getKey(alias, this.passPhraseGetSetEntry);
143         } catch (UnrecoverableKeyException JavaDoc e1) {
144             setPassWord(true);
145             return this.keyStore.getKey(alias, this.passPhraseGetSetEntry );
146         }
147     }
148     private String JavaDoc getProviderName( String JavaDoc className ) throws IllegalArgumentException JavaDoc, SecurityException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc, InvocationTargetException JavaDoc, NoSuchMethodException JavaDoc, ClassNotFoundException JavaDoc {
149         Provider JavaDoc provider = (Provider JavaDoc)Class.forName(className).getConstructor(new Class JavaDoc[0]).newInstance(new Object JavaDoc[0]);
150         Security.addProvider(provider);
151         return provider.getName();
152     }
153     private X509Certificate JavaDoc getSelfCertificate (String JavaDoc myname,
154                                                 long validity,
155                                                 String JavaDoc sigAlg,
156                                                 KeyPair JavaDoc keyPair) throws CertificateException JavaDoc, InvalidKeyException JavaDoc, SignatureException JavaDoc, NoSuchAlgorithmException JavaDoc, NoSuchProviderException JavaDoc {
157         final long currentTime = new Date JavaDoc().getTime();
158         final Date JavaDoc firstDate = new Date JavaDoc(currentTime-24*60*60*1000);
159         final Date JavaDoc lastDate = new Date JavaDoc(currentTime + validity * 1000);
160         X509V3CertificateGenerator cg = new X509V3CertificateGenerator();
161         // Add all mandatory attributes
162
cg.setSerialNumber(BigInteger.valueOf(firstDate.getTime()));
163         cg.setSignatureAlgorithm(sigAlg);
164         cg.setSubjectDN(new X500Principal JavaDoc(myname));
165         cg.setPublicKey(keyPair.getPublic());
166         cg.setNotBefore(firstDate);
167         cg.setNotAfter(lastDate);
168         cg.setIssuerDN(new X500Principal JavaDoc(myname));
169         return cg.generate(keyPair.getPrivate(), this.providerName);
170     }
171     private KeyPair JavaDoc generate( final String JavaDoc provider,
172                               final String JavaDoc algName,
173                               final int size) throws NoSuchAlgorithmException JavaDoc, NoSuchProviderException JavaDoc {
174         KeyPairGenerator JavaDoc kpg = KeyPairGenerator.getInstance(algName, provider);
175         kpg.initialize(size);
176         return kpg.generateKeyPair();
177     }
178     public byte[] generate( final int keySize,
179                             final String JavaDoc keyEntryName) throws Exception JavaDoc {
180         // Generate the RSA Keypair
181
final String JavaDoc keyAlgName = "RSA";
182         final String JavaDoc sigAlgName = "SHA1withRSA";
183         final KeyPair JavaDoc keyPair = generate(this.providerName, keyAlgName, keySize);
184         X509Certificate JavaDoc[] chain = new X509Certificate JavaDoc[1];
185         chain[0] = getSelfCertificate("CN=some guy, L=around, C=US",
186                                       (long)30*24*60*60*365, sigAlgName, keyPair);
187         System.err.println("Creating certificate with entry "+keyEntryName+'.');
188         setKeyEntry(keyEntryName, keyPair.getPrivate(), chain);
189         return storeKeyStore();
190     }
191     public char[] getPassPhraseGetSetEntry() {
192         return passPhraseGetSetEntry;
193     }
194     public char[] getPassPhraseLoadSave() {
195         return passPhraseLoadSave;
196     }
197     static void move(final String JavaDoc providerClassName,
198                      final String JavaDoc encryptProviderClassName,
199                      final String JavaDoc keyStoreType,
200                      final String JavaDoc fromID,
201                      final String JavaDoc toID) throws IllegalArgumentException JavaDoc, SecurityException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc, InvocationTargetException JavaDoc, NoSuchMethodException JavaDoc, ClassNotFoundException JavaDoc, NoSuchAlgorithmException JavaDoc, CertificateException JavaDoc, KeyStoreException JavaDoc, NoSuchProviderException JavaDoc, IOException JavaDoc, UnrecoverableKeyException JavaDoc {
202         KeyStoreContainer fromKS = new KeyStoreContainer(keyStoreType, providerClassName, encryptProviderClassName, fromID);
203         KeyStoreContainer toKS = new KeyStoreContainer(keyStoreType, providerClassName, encryptProviderClassName, toID);
204         Enumeration JavaDoc e = fromKS.getKeyStore().aliases();
205         while( e.hasMoreElements() ) {
206             String JavaDoc alias = (String JavaDoc) e.nextElement();
207             if (fromKS.getKeyStore().isKeyEntry(alias)) {
208                 Key JavaDoc key=fromKS.getKey(alias);
209                 Certificate JavaDoc chain[] = fromKS.getKeyStore().getCertificateChain(alias);
210                 toKS.setKeyEntry(alias, key, chain);
211             }
212             fromKS.deleteAlias( alias );
213         }
214         fromKS.storeKeyStore();
215         toKS.storeKeyStore();
216     }
217     abstract private class CodeStream {
218         void code(InputStream JavaDoc is, OutputStream JavaDoc os, String JavaDoc alias) throws Exception JavaDoc {
219             doCoding(is, os, alias);
220             os.flush();
221         }
222         abstract void doCoding(final InputStream JavaDoc is, OutputStream JavaDoc os, String JavaDoc alias) throws Exception JavaDoc;
223     }
224     private class EncryptStream extends CodeStream {
225         void doCoding(final InputStream JavaDoc is, OutputStream JavaDoc os, String JavaDoc alias) throws Exception JavaDoc {
226             final int bufferSize = 32*1024;
227             final InputStream JavaDoc bis = new BufferedInputStream JavaDoc(is, bufferSize);
228             final OutputStream JavaDoc bos = new BufferedOutputStream JavaDoc(os, bufferSize);
229             final CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator();
230             final Certificate JavaDoc cert = keyStore.getCertificate(alias);
231             if ( cert==null )
232                 throw new ErrorAdminCommandException("Certificate alias "+alias+" not found in keystore.");
233             edGen.addKeyTransRecipient(cert.getPublicKey(), "hej".getBytes() );
234             OutputStream JavaDoc out = edGen.open(bos, CMSEnvelopedDataGenerator.AES128_CBC, "BC");
235             byte[] buf = new byte[bufferSize];
236             while (true) {
237                 int len = bis.read(buf);
238                 if ( len<0 )
239                     break;
240                 out.write(buf,0, len);
241             }
242             out.close();
243             bos.close();
244             os.close();
245         }
246     }
247     private class DecryptStream extends CodeStream {
248         void doCoding(final InputStream JavaDoc is, OutputStream JavaDoc os, String JavaDoc alias) throws Exception JavaDoc {
249             final int bufferSize = 32*1024;
250             final InputStream JavaDoc bis = new BufferedInputStream JavaDoc(is, bufferSize);
251             final OutputStream JavaDoc bos = new BufferedOutputStream JavaDoc(os, bufferSize);
252             CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(bis);
253             RecipientInformationStore recipients = ep.getRecipientInfos();
254             Collection JavaDoc c = recipients.getRecipients();
255             Iterator JavaDoc it = c.iterator();
256             if (it.hasNext()) {
257                 RecipientInformation recipient = (RecipientInformation)it.next();
258                 Key JavaDoc key = getKey(alias);
259                 if ( key==null )
260                     throw new ErrorAdminCommandException("Key alias "+alias+" not found in keystore.");
261                 CMSTypedStream recData = recipient.getContentStream(key, KeyStoreContainer.this.ecryptProviderName);
262                 InputStream JavaDoc ris = recData.getContentStream();
263                 byte[] buf = new byte[bufferSize];
264                 while (true) {
265                     int len = ris.read(buf);
266                     if ( len<0 )
267                         break;
268                     bos.write(buf,0, len);
269                 }
270             }
271             bos.close();
272             os.close();
273         }
274     }
275     public void decrypt(InputStream JavaDoc is, OutputStream JavaDoc os, String JavaDoc alias) throws Exception JavaDoc {
276         new DecryptStream().code(is, os, alias);
277     }
278     public void encrypt(InputStream JavaDoc is, OutputStream JavaDoc os, String JavaDoc alias) throws Exception JavaDoc {
279         new EncryptStream().code(is, os, alias);
280     }
281 }
Popular Tags