equal
deleted
inserted
replaced
1 /* |
1 /* |
2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
36 import java.security.KeyStoreSpi; |
36 import java.security.KeyStoreSpi; |
37 import java.security.KeyStoreException; |
37 import java.security.KeyStoreException; |
38 import java.security.UnrecoverableKeyException; |
38 import java.security.UnrecoverableKeyException; |
39 import java.security.cert.Certificate; |
39 import java.security.cert.Certificate; |
40 import java.security.cert.CertificateFactory; |
40 import java.security.cert.CertificateFactory; |
41 import java.security.cert.X509Certificate; |
|
42 import java.security.cert.CertificateException; |
41 import java.security.cert.CertificateException; |
43 import java.security.spec.InvalidKeySpecException; |
|
44 import javax.crypto.SealedObject; |
42 import javax.crypto.SealedObject; |
45 |
43 |
46 /** |
44 /** |
47 * This class provides the keystore implementation referred to as "jceks". |
45 * This class provides the keystore implementation referred to as "jceks". |
48 * This implementation strongly protects the keystore private keys using |
46 * This implementation strongly protects the keystore private keys using |
85 |
83 |
86 /** |
84 /** |
87 * Private keys and certificates are stored in a hashtable. |
85 * Private keys and certificates are stored in a hashtable. |
88 * Hash entries are keyed by alias names. |
86 * Hash entries are keyed by alias names. |
89 */ |
87 */ |
90 private Hashtable entries = new Hashtable(); |
88 private Hashtable<String, Object> entries = new Hashtable<String, Object>(); |
91 |
89 |
92 /** |
90 /** |
93 * Returns the key associated with the given alias, using the given |
91 * Returns the key associated with the given alias, using the given |
94 * password to recover it. |
92 * password to recover it. |
95 * |
93 * |
154 |
152 |
155 Object entry = entries.get(alias.toLowerCase()); |
153 Object entry = entries.get(alias.toLowerCase()); |
156 |
154 |
157 if ((entry instanceof PrivateKeyEntry) |
155 if ((entry instanceof PrivateKeyEntry) |
158 && (((PrivateKeyEntry)entry).chain != null)) { |
156 && (((PrivateKeyEntry)entry).chain != null)) { |
159 chain = (Certificate[])((PrivateKeyEntry)entry).chain.clone(); |
157 chain = ((PrivateKeyEntry)entry).chain.clone(); |
160 } |
158 } |
161 |
159 |
162 return chain; |
160 return chain; |
163 } |
161 } |
164 |
162 |
260 entry.protectedKey = keyProtector.protect((PrivateKey)key); |
258 entry.protectedKey = keyProtector.protect((PrivateKey)key); |
261 |
259 |
262 // clone the chain |
260 // clone the chain |
263 if ((chain != null) && |
261 if ((chain != null) && |
264 (chain.length !=0)) { |
262 (chain.length !=0)) { |
265 entry.chain = (Certificate[])chain.clone(); |
263 entry.chain = chain.clone(); |
266 } else { |
264 } else { |
267 entry.chain = null; |
265 entry.chain = null; |
268 } |
266 } |
269 |
267 |
270 // store the entry |
268 // store the entry |
314 // We assume it's a private key, because there is no standard |
312 // We assume it's a private key, because there is no standard |
315 // (ASN.1) encoding format for wrapped secret keys |
313 // (ASN.1) encoding format for wrapped secret keys |
316 PrivateKeyEntry entry = new PrivateKeyEntry(); |
314 PrivateKeyEntry entry = new PrivateKeyEntry(); |
317 entry.date = new Date(); |
315 entry.date = new Date(); |
318 |
316 |
319 entry.protectedKey = (byte[])key.clone(); |
317 entry.protectedKey = key.clone(); |
320 if ((chain != null) && |
318 if ((chain != null) && |
321 (chain.length != 0)) { |
319 (chain.length != 0)) { |
322 entry.chain = (Certificate[])chain.clone(); |
320 entry.chain = chain.clone(); |
323 } else { |
321 } else { |
324 entry.chain = null; |
322 entry.chain = null; |
325 } |
323 } |
326 |
324 |
327 entries.put(alias.toLowerCase(), entry); |
325 entries.put(alias.toLowerCase(), entry); |
382 /** |
380 /** |
383 * Lists all the alias names of this keystore. |
381 * Lists all the alias names of this keystore. |
384 * |
382 * |
385 * @return enumeration of the alias names |
383 * @return enumeration of the alias names |
386 */ |
384 */ |
387 public Enumeration engineAliases() { |
385 public Enumeration<String> engineAliases() { |
388 return entries.keys(); |
386 return entries.keys(); |
389 } |
387 } |
390 |
388 |
391 /** |
389 /** |
392 * Checks if the given alias exists in this keystore. |
390 * Checks if the given alias exists in this keystore. |
460 * or null if no such entry exists in this keystore. |
458 * or null if no such entry exists in this keystore. |
461 */ |
459 */ |
462 public String engineGetCertificateAlias(Certificate cert) { |
460 public String engineGetCertificateAlias(Certificate cert) { |
463 Certificate certElem; |
461 Certificate certElem; |
464 |
462 |
465 Enumeration e = entries.keys(); |
463 Enumeration<String> e = entries.keys(); |
466 while (e.hasMoreElements()) { |
464 while (e.hasMoreElements()) { |
467 String alias = (String)e.nextElement(); |
465 String alias = e.nextElement(); |
468 Object entry = entries.get(alias); |
466 Object entry = entries.get(alias); |
469 if (entry instanceof TrustedCertEntry) { |
467 if (entry instanceof TrustedCertEntry) { |
470 certElem = ((TrustedCertEntry)entry).cert; |
468 certElem = ((TrustedCertEntry)entry).cert; |
471 } else if ((entry instanceof PrivateKeyEntry) && |
469 } else if ((entry instanceof PrivateKeyEntry) && |
472 (((PrivateKeyEntry)entry).chain != null)) { |
470 (((PrivateKeyEntry)entry).chain != null)) { |
558 dos.writeInt(JCEKS_MAGIC); |
556 dos.writeInt(JCEKS_MAGIC); |
559 dos.writeInt(VERSION_2); // always write the latest version |
557 dos.writeInt(VERSION_2); // always write the latest version |
560 |
558 |
561 dos.writeInt(entries.size()); |
559 dos.writeInt(entries.size()); |
562 |
560 |
563 Enumeration e = entries.keys(); |
561 Enumeration<String> e = entries.keys(); |
564 while (e.hasMoreElements()) { |
562 while (e.hasMoreElements()) { |
565 |
563 |
566 String alias = (String)e.nextElement(); |
564 String alias = e.nextElement(); |
567 Object entry = entries.get(alias); |
565 Object entry = entries.get(alias); |
568 |
566 |
569 if (entry instanceof PrivateKeyEntry) { |
567 if (entry instanceof PrivateKeyEntry) { |
570 |
568 |
571 PrivateKeyEntry pentry = (PrivateKeyEntry)entry; |
569 PrivateKeyEntry pentry = (PrivateKeyEntry)entry; |
675 { |
673 { |
676 synchronized(entries) { |
674 synchronized(entries) { |
677 DataInputStream dis; |
675 DataInputStream dis; |
678 MessageDigest md = null; |
676 MessageDigest md = null; |
679 CertificateFactory cf = null; |
677 CertificateFactory cf = null; |
680 Hashtable cfs = null; |
678 Hashtable<String, CertificateFactory> cfs = null; |
681 ByteArrayInputStream bais = null; |
679 ByteArrayInputStream bais = null; |
682 byte[] encoded = null; |
680 byte[] encoded = null; |
683 |
681 |
684 if (stream == null) |
682 if (stream == null) |
685 return; |
683 return; |
711 |
709 |
712 if (xVersion == VERSION_1) { |
710 if (xVersion == VERSION_1) { |
713 cf = CertificateFactory.getInstance("X509"); |
711 cf = CertificateFactory.getInstance("X509"); |
714 } else { |
712 } else { |
715 // version 2 |
713 // version 2 |
716 cfs = new Hashtable(3); |
714 cfs = new Hashtable<String, CertificateFactory>(3); |
717 } |
715 } |
718 |
716 |
719 entries.clear(); |
717 entries.clear(); |
720 int count = dis.readInt(); |
718 int count = dis.readInt(); |
721 |
719 |
759 // certificate factory of that type (reuse |
757 // certificate factory of that type (reuse |
760 // existing factory if possible) |
758 // existing factory if possible) |
761 String certType = dis.readUTF(); |
759 String certType = dis.readUTF(); |
762 if (cfs.containsKey(certType)) { |
760 if (cfs.containsKey(certType)) { |
763 // reuse certificate factory |
761 // reuse certificate factory |
764 cf = (CertificateFactory)cfs.get(certType); |
762 cf = cfs.get(certType); |
765 } else { |
763 } else { |
766 // create new certificate factory |
764 // create new certificate factory |
767 cf = CertificateFactory.getInstance( |
765 cf = CertificateFactory.getInstance( |
768 certType); |
766 certType); |
769 // store the certificate factory so we can |
767 // store the certificate factory so we can |
801 // certificate factory of that type (reuse |
799 // certificate factory of that type (reuse |
802 // existing factory if possible) |
800 // existing factory if possible) |
803 String certType = dis.readUTF(); |
801 String certType = dis.readUTF(); |
804 if (cfs.containsKey(certType)) { |
802 if (cfs.containsKey(certType)) { |
805 // reuse certificate factory |
803 // reuse certificate factory |
806 cf = (CertificateFactory)cfs.get(certType); |
804 cf = cfs.get(certType); |
807 } else { |
805 } else { |
808 // create new certificate factory |
806 // create new certificate factory |
809 cf = CertificateFactory.getInstance(certType); |
807 cf = CertificateFactory.getInstance(certType); |
810 // store the certificate factory so we can |
808 // store the certificate factory so we can |
811 // reuse it later |
809 // reuse it later |