Source Code Cross Referenced for JDKKeyStore.java in  » Security » Bouncy-Castle » org » bouncycastle » jce » provider » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Security » Bouncy Castle » org.bouncycastle.jce.provider 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.bouncycastle.jce.provider;
002:
003:        import java.io.ByteArrayInputStream;
004:        import java.io.ByteArrayOutputStream;
005:        import java.io.DataInputStream;
006:        import java.io.DataOutputStream;
007:        import java.io.IOException;
008:        import java.io.InputStream;
009:        import java.io.OutputStream;
010:        import java.security.*;
011:        import java.security.cert.Certificate;
012:        import java.security.cert.CertificateEncodingException;
013:        import java.security.cert.CertificateException;
014:        import java.security.cert.CertificateFactory;
015:        import java.security.spec.KeySpec;
016:        import java.security.spec.PKCS8EncodedKeySpec;
017:        import java.security.spec.X509EncodedKeySpec;
018:        import java.util.Date;
019:        import java.util.Enumeration;
020:        import java.util.Hashtable;
021:
022:        import javax.crypto.Cipher;
023:        import javax.crypto.CipherInputStream;
024:        import javax.crypto.CipherOutputStream;
025:        import javax.crypto.SecretKeyFactory;
026:        import javax.crypto.spec.PBEKeySpec;
027:        import javax.crypto.spec.PBEParameterSpec;
028:        import javax.crypto.spec.SecretKeySpec;
029:
030:        import org.bouncycastle.crypto.Digest;
031:        import org.bouncycastle.crypto.PBEParametersGenerator;
032:        import org.bouncycastle.crypto.digests.SHA1Digest;
033:        import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
034:        import org.bouncycastle.crypto.io.DigestInputStream;
035:        import org.bouncycastle.crypto.io.DigestOutputStream;
036:        import org.bouncycastle.crypto.io.MacInputStream;
037:        import org.bouncycastle.crypto.io.MacOutputStream;
038:        import org.bouncycastle.crypto.macs.HMac;
039:        import org.bouncycastle.jce.interfaces.BCKeyStore;
040:
041:        public class JDKKeyStore extends KeyStoreSpi implements  BCKeyStore {
042:            private static final int STORE_VERSION = 1;
043:
044:            private static final int STORE_SALT_SIZE = 20;
045:            private static final String STORE_CIPHER = "PBEWithSHAAndTwofish-CBC";
046:
047:            private static final int KEY_SALT_SIZE = 20;
048:            private static final int MIN_ITERATIONS = 1024;
049:
050:            private static final String KEY_CIPHER = "PBEWithSHAAnd3-KeyTripleDES-CBC";
051:
052:            //
053:            // generic object types
054:            //
055:            static final int NULL = 0;
056:            static final int CERTIFICATE = 1;
057:            static final int KEY = 2;
058:            static final int SECRET = 3;
059:            static final int SEALED = 4;
060:
061:            //
062:            // key types
063:            //
064:            static final int KEY_PRIVATE = 0;
065:            static final int KEY_PUBLIC = 1;
066:            static final int KEY_SECRET = 2;
067:
068:            protected Hashtable table = new Hashtable();
069:
070:            protected SecureRandom random = new SecureRandom();
071:
072:            public JDKKeyStore() {
073:            }
074:
075:            private class StoreEntry {
076:                int type;
077:                String alias;
078:                Object obj;
079:                Certificate[] certChain;
080:                Date date = new Date();
081:
082:                StoreEntry(String alias, Certificate obj) {
083:                    this .type = CERTIFICATE;
084:                    this .alias = alias;
085:                    this .obj = obj;
086:                    this .certChain = null;
087:                }
088:
089:                StoreEntry(String alias, Key obj, Certificate[] certChain) {
090:                    this .type = KEY;
091:                    this .alias = alias;
092:                    this .obj = obj;
093:                    this .certChain = certChain;
094:                }
095:
096:                StoreEntry(String alias, byte[] obj, Certificate[] certChain) {
097:                    this .type = SECRET;
098:                    this .alias = alias;
099:                    this .obj = obj;
100:                    this .certChain = certChain;
101:                }
102:
103:                StoreEntry(String alias, Key key, char[] password,
104:                        Certificate[] certChain) throws Exception {
105:                    this .type = SEALED;
106:                    this .alias = alias;
107:                    this .certChain = certChain;
108:
109:                    byte[] salt = new byte[KEY_SALT_SIZE];
110:
111:                    random.setSeed(System.currentTimeMillis());
112:                    random.nextBytes(salt);
113:
114:                    int iterationCount = MIN_ITERATIONS
115:                            + (random.nextInt() & 0x3ff);
116:
117:                    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
118:                    DataOutputStream dOut = new DataOutputStream(bOut);
119:
120:                    dOut.writeInt(salt.length);
121:                    dOut.write(salt);
122:                    dOut.writeInt(iterationCount);
123:
124:                    Cipher cipher = makePBECipher(KEY_CIPHER,
125:                            Cipher.ENCRYPT_MODE, password, salt, iterationCount);
126:                    CipherOutputStream cOut = new CipherOutputStream(dOut,
127:                            cipher);
128:
129:                    dOut = new DataOutputStream(cOut);
130:
131:                    encodeKey(key, dOut);
132:
133:                    dOut.close();
134:
135:                    obj = bOut.toByteArray();
136:                }
137:
138:                StoreEntry(String alias, Date date, int type, Object obj) {
139:                    this .alias = alias;
140:                    this .date = date;
141:                    this .type = type;
142:                    this .obj = obj;
143:                }
144:
145:                StoreEntry(String alias, Date date, int type, Object obj,
146:                        Certificate[] certChain) {
147:                    this .alias = alias;
148:                    this .date = date;
149:                    this .type = type;
150:                    this .obj = obj;
151:                    this .certChain = certChain;
152:                }
153:
154:                int getType() {
155:                    return type;
156:                }
157:
158:                String getAlias() {
159:                    return alias;
160:                }
161:
162:                Object getObject() {
163:                    return obj;
164:                }
165:
166:                Object getObject(char[] password)
167:                        throws NoSuchAlgorithmException,
168:                        UnrecoverableKeyException {
169:                    if (password == null || password.length == 0) {
170:                        if (obj instanceof  Key) {
171:                            return obj;
172:                        }
173:                    }
174:
175:                    if (type == SEALED) {
176:                        ByteArrayInputStream bIn = new ByteArrayInputStream(
177:                                (byte[]) obj);
178:                        DataInputStream dIn = new DataInputStream(bIn);
179:
180:                        try {
181:                            byte[] salt = new byte[dIn.readInt()];
182:
183:                            dIn.readFully(salt);
184:
185:                            int iterationCount = dIn.readInt();
186:
187:                            Cipher cipher = makePBECipher(KEY_CIPHER,
188:                                    Cipher.DECRYPT_MODE, password, salt,
189:                                    iterationCount);
190:
191:                            CipherInputStream cIn = new CipherInputStream(dIn,
192:                                    cipher);
193:
194:                            try {
195:                                return decodeKey(new DataInputStream(cIn));
196:                            } catch (Exception x) {
197:                                bIn = new ByteArrayInputStream((byte[]) obj);
198:                                dIn = new DataInputStream(bIn);
199:
200:                                salt = new byte[dIn.readInt()];
201:
202:                                dIn.readFully(salt);
203:
204:                                iterationCount = dIn.readInt();
205:
206:                                cipher = makePBECipher("Broken" + KEY_CIPHER,
207:                                        Cipher.DECRYPT_MODE, password, salt,
208:                                        iterationCount);
209:
210:                                cIn = new CipherInputStream(dIn, cipher);
211:
212:                                Key k = null;
213:
214:                                try {
215:                                    k = decodeKey(new DataInputStream(cIn));
216:                                } catch (Exception y) {
217:                                    bIn = new ByteArrayInputStream((byte[]) obj);
218:                                    dIn = new DataInputStream(bIn);
219:
220:                                    salt = new byte[dIn.readInt()];
221:
222:                                    dIn.readFully(salt);
223:
224:                                    iterationCount = dIn.readInt();
225:
226:                                    cipher = makePBECipher("Old" + KEY_CIPHER,
227:                                            Cipher.DECRYPT_MODE, password,
228:                                            salt, iterationCount);
229:
230:                                    cIn = new CipherInputStream(dIn, cipher);
231:
232:                                    k = decodeKey(new DataInputStream(cIn));
233:                                }
234:
235:                                //
236:                                // reencrypt key with correct cipher.
237:                                //
238:                                if (k != null) {
239:                                    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
240:                                    DataOutputStream dOut = new DataOutputStream(
241:                                            bOut);
242:
243:                                    dOut.writeInt(salt.length);
244:                                    dOut.write(salt);
245:                                    dOut.writeInt(iterationCount);
246:
247:                                    Cipher out = makePBECipher(KEY_CIPHER,
248:                                            Cipher.ENCRYPT_MODE, password,
249:                                            salt, iterationCount);
250:                                    CipherOutputStream cOut = new CipherOutputStream(
251:                                            dOut, out);
252:
253:                                    dOut = new DataOutputStream(cOut);
254:
255:                                    encodeKey(k, dOut);
256:
257:                                    dOut.close();
258:
259:                                    obj = bOut.toByteArray();
260:
261:                                    return k;
262:                                } else {
263:                                    throw new UnrecoverableKeyException(
264:                                            "no match");
265:                                }
266:                            }
267:                        } catch (Exception e) {
268:                            throw new UnrecoverableKeyException("no match");
269:                        }
270:                    } else {
271:                        throw new RuntimeException("forget something!");
272:                        // TODO
273:                        // if we get to here key was saved as byte data, which
274:                        // according to the docs means it must be a private key
275:                        // in EncryptedPrivateKeyInfo (PKCS8 format), later...
276:                        //
277:                    }
278:                }
279:
280:                Certificate[] getCertificateChain() {
281:                    return certChain;
282:                }
283:
284:                Date getDate() {
285:                    return date;
286:                }
287:            }
288:
289:            private void encodeCertificate(Certificate cert,
290:                    DataOutputStream dOut) throws IOException {
291:                try {
292:                    byte[] cEnc = cert.getEncoded();
293:
294:                    dOut.writeUTF(cert.getType());
295:                    dOut.writeInt(cEnc.length);
296:                    dOut.write(cEnc);
297:                } catch (CertificateEncodingException ex) {
298:                    throw new IOException(ex.toString());
299:                }
300:            }
301:
302:            private Certificate decodeCertificate(DataInputStream dIn)
303:                    throws IOException {
304:                String type = dIn.readUTF();
305:                byte[] cEnc = new byte[dIn.readInt()];
306:
307:                dIn.readFully(cEnc);
308:
309:                try {
310:                    CertificateFactory cFact = CertificateFactory.getInstance(
311:                            type, "BC");
312:                    ByteArrayInputStream bIn = new ByteArrayInputStream(cEnc);
313:
314:                    return cFact.generateCertificate(bIn);
315:                } catch (NoSuchProviderException ex) {
316:                    throw new IOException(ex.toString());
317:                } catch (CertificateException ex) {
318:                    throw new IOException(ex.toString());
319:                }
320:            }
321:
322:            private void encodeKey(Key key, DataOutputStream dOut)
323:                    throws IOException {
324:                byte[] enc = key.getEncoded();
325:
326:                if (key instanceof  PrivateKey) {
327:                    dOut.write(KEY_PRIVATE);
328:                } else if (key instanceof  PublicKey) {
329:                    dOut.write(KEY_PUBLIC);
330:                } else {
331:                    dOut.write(KEY_SECRET);
332:                }
333:
334:                dOut.writeUTF(key.getFormat());
335:                dOut.writeUTF(key.getAlgorithm());
336:                dOut.writeInt(enc.length);
337:                dOut.write(enc);
338:            }
339:
340:            private Key decodeKey(DataInputStream dIn) throws IOException {
341:                int keyType = dIn.read();
342:                String format = dIn.readUTF();
343:                String algorithm = dIn.readUTF();
344:                byte[] enc = new byte[dIn.readInt()];
345:                KeySpec spec;
346:
347:                dIn.readFully(enc);
348:
349:                if (format.equals("PKCS#8") || format.equals("PKCS8")) {
350:                    spec = new PKCS8EncodedKeySpec(enc);
351:                } else if (format.equals("X.509") || format.equals("X509")) {
352:                    spec = new X509EncodedKeySpec(enc);
353:                } else if (format.equals("RAW")) {
354:                    return new SecretKeySpec(enc, algorithm);
355:                } else {
356:                    throw new IOException("Key format " + format
357:                            + " not recognised!");
358:                }
359:
360:                try {
361:                    switch (keyType) {
362:                    case KEY_PRIVATE:
363:                        return KeyFactory.getInstance(algorithm, "BC")
364:                                .generatePrivate(spec);
365:                    case KEY_PUBLIC:
366:                        return KeyFactory.getInstance(algorithm, "BC")
367:                                .generatePublic(spec);
368:                    case KEY_SECRET:
369:                        return SecretKeyFactory.getInstance(algorithm, "BC")
370:                                .generateSecret(spec);
371:                    default:
372:                        throw new IOException("Key type " + keyType
373:                                + " not recognised!");
374:                    }
375:                } catch (Exception e) {
376:                    throw new IOException("Exception creating key: "
377:                            + e.toString());
378:                }
379:            }
380:
381:            protected Cipher makePBECipher(String algorithm, int mode,
382:                    char[] password, byte[] salt, int iterationCount)
383:                    throws IOException {
384:                try {
385:                    PBEKeySpec pbeSpec = new PBEKeySpec(password);
386:                    SecretKeyFactory keyFact = SecretKeyFactory.getInstance(
387:                            algorithm, "BC");
388:                    PBEParameterSpec defParams = new PBEParameterSpec(salt,
389:                            iterationCount);
390:
391:                    Cipher cipher = Cipher.getInstance(algorithm, "BC");
392:
393:                    cipher.init(mode, keyFact.generateSecret(pbeSpec),
394:                            defParams);
395:
396:                    return cipher;
397:                } catch (Exception e) {
398:                    throw new IOException(
399:                            "Error initialising store of key store: " + e);
400:                }
401:            }
402:
403:            public void setRandom(SecureRandom rand) {
404:                this .random = rand;
405:            }
406:
407:            public Enumeration engineAliases() {
408:                return table.keys();
409:            }
410:
411:            public boolean engineContainsAlias(String alias) {
412:                return (table.get(alias) != null);
413:            }
414:
415:            public void engineDeleteEntry(String alias)
416:                    throws KeyStoreException {
417:                Object entry = table.get(alias);
418:
419:                if (entry == null) {
420:                    throw new KeyStoreException("no such entry as " + alias);
421:                }
422:
423:                table.remove(alias);
424:            }
425:
426:            public Certificate engineGetCertificate(String alias) {
427:                StoreEntry entry = (StoreEntry) table.get(alias);
428:
429:                if (entry != null) {
430:                    if (entry.getType() == CERTIFICATE) {
431:                        return (Certificate) entry.getObject();
432:                    } else {
433:                        Certificate[] chain = entry.getCertificateChain();
434:
435:                        if (chain != null) {
436:                            return chain[0];
437:                        }
438:                    }
439:                }
440:
441:                return null;
442:            }
443:
444:            public String engineGetCertificateAlias(Certificate cert) {
445:                Enumeration e = table.elements();
446:                while (e.hasMoreElements()) {
447:                    StoreEntry entry = (StoreEntry) e.nextElement();
448:
449:                    if (entry.getObject() instanceof  Certificate) {
450:                        Certificate c = (Certificate) entry.getObject();
451:
452:                        if (c.equals(cert)) {
453:                            return entry.getAlias();
454:                        }
455:                    } else {
456:                        Certificate[] chain = entry.getCertificateChain();
457:
458:                        if (chain != null && chain[0].equals(cert)) {
459:                            return entry.getAlias();
460:                        }
461:                    }
462:                }
463:
464:                return null;
465:            }
466:
467:            public Certificate[] engineGetCertificateChain(String alias) {
468:                StoreEntry entry = (StoreEntry) table.get(alias);
469:
470:                if (entry != null) {
471:                    return entry.getCertificateChain();
472:                }
473:
474:                return null;
475:            }
476:
477:            public Date engineGetCreationDate(String alias) {
478:                StoreEntry entry = (StoreEntry) table.get(alias);
479:
480:                if (entry != null) {
481:                    return entry.getDate();
482:                }
483:
484:                return null;
485:            }
486:
487:            public Key engineGetKey(String alias, char[] password)
488:                    throws NoSuchAlgorithmException, UnrecoverableKeyException {
489:                StoreEntry entry = (StoreEntry) table.get(alias);
490:
491:                if (entry == null || entry.getType() == CERTIFICATE) {
492:                    return null;
493:                }
494:
495:                return (Key) entry.getObject(password);
496:            }
497:
498:            public boolean engineIsCertificateEntry(String alias) {
499:                StoreEntry entry = (StoreEntry) table.get(alias);
500:
501:                if (entry != null && entry.getType() == CERTIFICATE) {
502:                    return true;
503:                }
504:
505:                return false;
506:            }
507:
508:            public boolean engineIsKeyEntry(String alias) {
509:                StoreEntry entry = (StoreEntry) table.get(alias);
510:
511:                if (entry != null && entry.getType() != CERTIFICATE) {
512:                    return true;
513:                }
514:
515:                return false;
516:            }
517:
518:            public void engineSetCertificateEntry(String alias, Certificate cert)
519:                    throws KeyStoreException {
520:                StoreEntry entry = (StoreEntry) table.get(alias);
521:
522:                if (entry != null && entry.getType() != CERTIFICATE) {
523:                    throw new KeyStoreException(
524:                            "key store already has a key entry with alias "
525:                                    + alias);
526:                }
527:
528:                table.put(alias, new StoreEntry(alias, cert));
529:            }
530:
531:            public void engineSetKeyEntry(String alias, byte[] key,
532:                    Certificate[] chain) throws KeyStoreException {
533:                table.put(alias, new StoreEntry(alias, key, chain));
534:            }
535:
536:            public void engineSetKeyEntry(String alias, Key key,
537:                    char[] password, Certificate[] chain)
538:                    throws KeyStoreException {
539:                if ((key instanceof  PrivateKey) && (chain == null)) {
540:                    throw new KeyStoreException(
541:                            "no certificate chain for private key");
542:                }
543:
544:                try {
545:                    table.put(alias,
546:                            new StoreEntry(alias, key, password, chain));
547:                } catch (Exception e) {
548:                    throw new KeyStoreException(e.toString());
549:                }
550:            }
551:
552:            public int engineSize() {
553:                return table.size();
554:            }
555:
556:            protected boolean isSameAs(byte[] one, byte[] two) {
557:                if (one.length != two.length) {
558:                    return false;
559:                }
560:
561:                for (int i = 0; i != one.length; i++) {
562:                    if (one[i] != two[i]) {
563:                        return false;
564:                    }
565:                }
566:
567:                return true;
568:            }
569:
570:            protected void loadStore(InputStream in) throws IOException {
571:                DataInputStream dIn = new DataInputStream(in);
572:                int type = dIn.read();
573:
574:                while (type > NULL) {
575:                    String alias = dIn.readUTF();
576:                    Date date = new Date(dIn.readLong());
577:                    int chainLength = dIn.readInt();
578:                    Certificate[] chain = null;
579:
580:                    if (chainLength != 0) {
581:                        chain = new Certificate[chainLength];
582:
583:                        for (int i = 0; i != chainLength; i++) {
584:                            chain[i] = decodeCertificate(dIn);
585:                        }
586:                    }
587:
588:                    switch (type) {
589:                    case CERTIFICATE:
590:                        Certificate cert = decodeCertificate(dIn);
591:
592:                        table.put(alias, new StoreEntry(alias, date,
593:                                CERTIFICATE, cert));
594:                        break;
595:                    case KEY:
596:                        Key key = decodeKey(dIn);
597:                        table.put(alias, new StoreEntry(alias, date, KEY, key,
598:                                chain));
599:                        break;
600:                    case SECRET:
601:                    case SEALED:
602:                        byte[] b = new byte[dIn.readInt()];
603:
604:                        dIn.readFully(b);
605:                        table.put(alias, new StoreEntry(alias, date, type, b,
606:                                chain));
607:                        break;
608:                    default:
609:                        throw new RuntimeException(
610:                                "Unknown object type in store.");
611:                    }
612:
613:                    type = dIn.read();
614:                }
615:            }
616:
617:            protected void saveStore(OutputStream out) throws IOException {
618:                Enumeration e = table.elements();
619:                DataOutputStream dOut = new DataOutputStream(out);
620:
621:                while (e.hasMoreElements()) {
622:                    StoreEntry entry = (StoreEntry) e.nextElement();
623:
624:                    dOut.write(entry.getType());
625:                    dOut.writeUTF(entry.getAlias());
626:                    dOut.writeLong(entry.getDate().getTime());
627:
628:                    Certificate[] chain = entry.getCertificateChain();
629:                    if (chain == null) {
630:                        dOut.writeInt(0);
631:                    } else {
632:                        dOut.writeInt(chain.length);
633:                        for (int i = 0; i != chain.length; i++) {
634:                            encodeCertificate(chain[i], dOut);
635:                        }
636:                    }
637:
638:                    switch (entry.getType()) {
639:                    case CERTIFICATE:
640:                        encodeCertificate((Certificate) entry.getObject(), dOut);
641:                        break;
642:                    case KEY:
643:                        encodeKey((Key) entry.getObject(), dOut);
644:                        break;
645:                    case SEALED:
646:                    case SECRET:
647:                        byte[] b = (byte[]) entry.getObject();
648:
649:                        dOut.writeInt(b.length);
650:                        dOut.write(b);
651:                        break;
652:                    default:
653:                        throw new RuntimeException(
654:                                "Unknown object type in store.");
655:                    }
656:                }
657:
658:                dOut.write(NULL);
659:            }
660:
661:            public void engineLoad(InputStream stream, char[] password)
662:                    throws IOException {
663:                table.clear();
664:
665:                if (stream == null) // just initialising
666:                {
667:                    return;
668:                }
669:
670:                DataInputStream dIn = new DataInputStream(stream);
671:                int version = dIn.readInt();
672:
673:                if (version != STORE_VERSION) {
674:                    if (version != 0) {
675:                        throw new IOException("Wrong version of key store.");
676:                    }
677:                }
678:
679:                byte[] salt = new byte[dIn.readInt()];
680:
681:                dIn.readFully(salt);
682:
683:                int iterationCount = dIn.readInt();
684:
685:                HMac hMac = new HMac(new SHA1Digest());
686:                MacInputStream mIn = new MacInputStream(dIn, hMac);
687:                PBEParametersGenerator pbeGen = new PKCS12ParametersGenerator(
688:                        new SHA1Digest());
689:                byte[] passKey = PBEParametersGenerator
690:                        .PKCS12PasswordToBytes(password);
691:
692:                pbeGen.init(passKey, salt, iterationCount);
693:
694:                hMac.init(pbeGen
695:                        .generateDerivedMacParameters(hMac.getMacSize()));
696:
697:                for (int i = 0; i != passKey.length; i++) {
698:                    passKey[i] = 0;
699:                }
700:
701:                loadStore(mIn);
702:
703:                byte[] mac = new byte[hMac.getMacSize()];
704:                byte[] oldMac = new byte[hMac.getMacSize()];
705:
706:                hMac.doFinal(mac, 0);
707:
708:                for (int i = 0; i != oldMac.length; i++) {
709:                    oldMac[i] = (byte) dIn.read();
710:                }
711:
712:                //
713:                // we only do an integrity check if the password is provided.
714:                //
715:                if ((password != null && password.length != 0)
716:                        && !isSameAs(mac, oldMac)) {
717:                    table.clear();
718:                    throw new IOException("KeyStore integrity check failed.");
719:                }
720:            }
721:
722:            public void engineStore(OutputStream stream, char[] password)
723:                    throws IOException {
724:                DataOutputStream dOut = new DataOutputStream(stream);
725:                byte[] salt = new byte[STORE_SALT_SIZE];
726:                int iterationCount = MIN_ITERATIONS
727:                        + (random.nextInt() & 0x3ff);
728:
729:                random.nextBytes(salt);
730:
731:                dOut.writeInt(STORE_VERSION);
732:                dOut.writeInt(salt.length);
733:                dOut.write(salt);
734:                dOut.writeInt(iterationCount);
735:
736:                HMac hMac = new HMac(new SHA1Digest());
737:                MacOutputStream mOut = new MacOutputStream(dOut, hMac);
738:                PBEParametersGenerator pbeGen = new PKCS12ParametersGenerator(
739:                        new SHA1Digest());
740:                byte[] passKey = PBEParametersGenerator
741:                        .PKCS12PasswordToBytes(password);
742:
743:                pbeGen.init(passKey, salt, iterationCount);
744:
745:                hMac.init(pbeGen
746:                        .generateDerivedMacParameters(hMac.getMacSize()));
747:
748:                for (int i = 0; i != passKey.length; i++) {
749:                    passKey[i] = 0;
750:                }
751:
752:                saveStore(mOut);
753:
754:                byte[] mac = new byte[hMac.getMacSize()];
755:
756:                hMac.doFinal(mac, 0);
757:
758:                dOut.write(mac);
759:
760:                dOut.close();
761:            }
762:
763:            /**
764:             * the BouncyCastle store. This wont work with the key tool as the
765:             * store is stored encrypteed on disk, so the password is mandatory,
766:             * however if you hard drive is in a bad part of town and you absolutely,
767:             * positively, don't want nobody peeking at your things, this is the
768:             * one to use, no problem! After all in a Bouncy Castle nothing can
769:             * touch you.
770:             *
771:             * Also referred to by the alias UBER.
772:             */
773:            public static class BouncyCastleStore extends JDKKeyStore {
774:                public void engineLoad(InputStream stream, char[] password)
775:                        throws IOException {
776:                    table.clear();
777:
778:                    if (stream == null) // just initialising
779:                    {
780:                        return;
781:                    }
782:
783:                    Cipher cipher;
784:                    DataInputStream dIn = new DataInputStream(stream);
785:                    int version = dIn.readInt();
786:
787:                    if (version != STORE_VERSION) {
788:                        if (version != 0) {
789:                            throw new IOException("Wrong version of key store.");
790:                        }
791:                    }
792:
793:                    byte[] salt = new byte[dIn.readInt()];
794:
795:                    if (salt.length != STORE_SALT_SIZE) {
796:                        throw new IOException("Key store corrupted.");
797:                    }
798:
799:                    dIn.readFully(salt);
800:
801:                    int iterationCount = dIn.readInt();
802:
803:                    if ((iterationCount < 0)
804:                            || (iterationCount > 4 * MIN_ITERATIONS)) {
805:                        throw new IOException("Key store corrupted.");
806:                    }
807:
808:                    if (version == 0) {
809:                        cipher = this .makePBECipher("Old" + STORE_CIPHER,
810:                                Cipher.DECRYPT_MODE, password, salt,
811:                                iterationCount);
812:                    } else {
813:                        cipher = this .makePBECipher(STORE_CIPHER,
814:                                Cipher.DECRYPT_MODE, password, salt,
815:                                iterationCount);
816:                    }
817:
818:                    CipherInputStream cIn = new CipherInputStream(dIn, cipher);
819:
820:                    DigestInputStream dgIn = new DigestInputStream(cIn,
821:                            new SHA1Digest());
822:
823:                    this .loadStore(dgIn);
824:
825:                    Digest dig = dgIn.getDigest();
826:                    int digSize = dig.getDigestSize();
827:                    byte[] hash = new byte[digSize];
828:                    byte[] oldHash = new byte[digSize];
829:
830:                    dig.doFinal(hash, 0);
831:
832:                    for (int i = 0; i != digSize; i++) {
833:                        oldHash[i] = (byte) cIn.read();
834:                    }
835:
836:                    if (!this .isSameAs(hash, oldHash)) {
837:                        table.clear();
838:                        throw new IOException(
839:                                "KeyStore integrity check failed.");
840:                    }
841:                }
842:
843:                public void engineStore(OutputStream stream, char[] password)
844:                        throws IOException {
845:                    Cipher cipher;
846:                    DataOutputStream dOut = new DataOutputStream(stream);
847:                    byte[] salt = new byte[STORE_SALT_SIZE];
848:                    int iterationCount = MIN_ITERATIONS
849:                            + (random.nextInt() & 0x3ff);
850:
851:                    random.nextBytes(salt);
852:
853:                    dOut.writeInt(STORE_VERSION);
854:                    dOut.writeInt(salt.length);
855:                    dOut.write(salt);
856:                    dOut.writeInt(iterationCount);
857:
858:                    cipher = this 
859:                            .makePBECipher(STORE_CIPHER, Cipher.ENCRYPT_MODE,
860:                                    password, salt, iterationCount);
861:
862:                    CipherOutputStream cOut = new CipherOutputStream(dOut,
863:                            cipher);
864:                    DigestOutputStream dgOut = new DigestOutputStream(cOut,
865:                            new SHA1Digest());
866:
867:                    this .saveStore(dgOut);
868:
869:                    Digest dig = dgOut.getDigest();
870:                    byte[] hash = new byte[dig.getDigestSize()];
871:
872:                    dig.doFinal(hash, 0);
873:
874:                    cOut.write(hash);
875:
876:                    cOut.close();
877:                }
878:            }
879:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.