Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/security/KeyStore.java
38829 views
1
/*
2
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
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
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package java.security;
27
28
import java.io.*;
29
import java.net.URI;
30
import java.security.cert.Certificate;
31
import java.security.cert.X509Certificate;
32
import java.security.cert.CertificateException;
33
import java.security.spec.AlgorithmParameterSpec;
34
import java.util.*;
35
import javax.crypto.SecretKey;
36
37
import javax.security.auth.DestroyFailedException;
38
import javax.security.auth.callback.*;
39
40
import sun.security.util.Debug;
41
42
/**
43
* This class represents a storage facility for cryptographic
44
* keys and certificates.
45
*
46
* <p> A {@code KeyStore} manages different types of entries.
47
* Each type of entry implements the {@code KeyStore.Entry} interface.
48
* Three basic {@code KeyStore.Entry} implementations are provided:
49
*
50
* <ul>
51
* <li><b>KeyStore.PrivateKeyEntry</b>
52
* <p> This type of entry holds a cryptographic {@code PrivateKey},
53
* which is optionally stored in a protected format to prevent
54
* unauthorized access. It is also accompanied by a certificate chain
55
* for the corresponding public key.
56
*
57
* <p> Private keys and certificate chains are used by a given entity for
58
* self-authentication. Applications for this authentication include software
59
* distribution organizations which sign JAR files as part of releasing
60
* and/or licensing software.
61
*
62
* <li><b>KeyStore.SecretKeyEntry</b>
63
* <p> This type of entry holds a cryptographic {@code SecretKey},
64
* which is optionally stored in a protected format to prevent
65
* unauthorized access.
66
*
67
* <li><b>KeyStore.TrustedCertificateEntry</b>
68
* <p> This type of entry contains a single public key {@code Certificate}
69
* belonging to another party. It is called a <i>trusted certificate</i>
70
* because the keystore owner trusts that the public key in the certificate
71
* indeed belongs to the identity identified by the <i>subject</i> (owner)
72
* of the certificate.
73
*
74
* <p>This type of entry can be used to authenticate other parties.
75
* </ul>
76
*
77
* <p> Each entry in a keystore is identified by an "alias" string. In the
78
* case of private keys and their associated certificate chains, these strings
79
* distinguish among the different ways in which the entity may authenticate
80
* itself. For example, the entity may authenticate itself using different
81
* certificate authorities, or using different public key algorithms.
82
*
83
* <p> Whether aliases are case sensitive is implementation dependent. In order
84
* to avoid problems, it is recommended not to use aliases in a KeyStore that
85
* only differ in case.
86
*
87
* <p> Whether keystores are persistent, and the mechanisms used by the
88
* keystore if it is persistent, are not specified here. This allows
89
* use of a variety of techniques for protecting sensitive (e.g., private or
90
* secret) keys. Smart cards or other integrated cryptographic engines
91
* (SafeKeyper) are one option, and simpler mechanisms such as files may also
92
* be used (in a variety of formats).
93
*
94
* <p> Typical ways to request a KeyStore object include
95
* relying on the default type and providing a specific keystore type.
96
*
97
* <ul>
98
* <li>To rely on the default type:
99
* <pre>
100
* KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
101
* </pre>
102
* The system will return a keystore implementation for the default type.
103
*
104
* <li>To provide a specific keystore type:
105
* <pre>
106
* KeyStore ks = KeyStore.getInstance("JKS");
107
* </pre>
108
* The system will return the most preferred implementation of the
109
* specified keystore type available in the environment. <p>
110
* </ul>
111
*
112
* <p> Before a keystore can be accessed, it must be
113
* {@link #load(java.io.InputStream, char[]) loaded}.
114
* <pre>
115
* KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
116
*
117
* // get user password and file input stream
118
* char[] password = getPassword();
119
*
120
* try (FileInputStream fis = new FileInputStream("keyStoreName")) {
121
* ks.load(fis, password);
122
* }
123
* </pre>
124
*
125
* To create an empty keystore using the above {@code load} method,
126
* pass {@code null} as the {@code InputStream} argument.
127
*
128
* <p> Once the keystore has been loaded, it is possible
129
* to read existing entries from the keystore, or to write new entries
130
* into the keystore:
131
* <pre>
132
* KeyStore.ProtectionParameter protParam =
133
* new KeyStore.PasswordProtection(password);
134
*
135
* // get my private key
136
* KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
137
* ks.getEntry("privateKeyAlias", protParam);
138
* PrivateKey myPrivateKey = pkEntry.getPrivateKey();
139
*
140
* // save my secret key
141
* javax.crypto.SecretKey mySecretKey;
142
* KeyStore.SecretKeyEntry skEntry =
143
* new KeyStore.SecretKeyEntry(mySecretKey);
144
* ks.setEntry("secretKeyAlias", skEntry, protParam);
145
*
146
* // store away the keystore
147
* try (FileOutputStream fos = new FileOutputStream("newKeyStoreName")) {
148
* ks.store(fos, password);
149
* }
150
* </pre>
151
*
152
* Note that although the same password may be used to
153
* load the keystore, to protect the private key entry,
154
* to protect the secret key entry, and to store the keystore
155
* (as is shown in the sample code above),
156
* different passwords or other protection parameters
157
* may also be used.
158
*
159
* <p> Every implementation of the Java platform is required to support
160
* the following standard {@code KeyStore} type:
161
* <ul>
162
* <li>{@code PKCS12}</li>
163
* </ul>
164
* This type is described in the <a href=
165
* "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
166
* KeyStore section</a> of the
167
* Java Cryptography Architecture Standard Algorithm Name Documentation.
168
* Consult the release documentation for your implementation to see if any
169
* other types are supported.
170
*
171
* @author Jan Luehe
172
*
173
* @see java.security.PrivateKey
174
* @see javax.crypto.SecretKey
175
* @see java.security.cert.Certificate
176
*
177
* @since 1.2
178
*/
179
180
public class KeyStore {
181
182
private static final Debug pdebug =
183
Debug.getInstance("provider", "Provider");
184
private static final boolean skipDebug =
185
Debug.isOn("engine=") && !Debug.isOn("keystore");
186
187
/*
188
* Constant to lookup in the Security properties file to determine
189
* the default keystore type.
190
* In the Security properties file, the default keystore type is given as:
191
* <pre>
192
* keystore.type=jks
193
* </pre>
194
*/
195
private static final String KEYSTORE_TYPE = "keystore.type";
196
197
// The keystore type
198
private String type;
199
200
// The provider
201
private Provider provider;
202
203
// The provider implementation
204
private KeyStoreSpi keyStoreSpi;
205
206
// Has this keystore been initialized (loaded)?
207
private boolean initialized = false;
208
209
/**
210
* A marker interface for {@code KeyStore}
211
* {@link #load(KeyStore.LoadStoreParameter) load}
212
* and
213
* {@link #store(KeyStore.LoadStoreParameter) store}
214
* parameters.
215
*
216
* @since 1.5
217
*/
218
public static interface LoadStoreParameter {
219
/**
220
* Gets the parameter used to protect keystore data.
221
*
222
* @return the parameter used to protect keystore data, or null
223
*/
224
public ProtectionParameter getProtectionParameter();
225
}
226
227
/**
228
* A marker interface for keystore protection parameters.
229
*
230
* <p> The information stored in a {@code ProtectionParameter}
231
* object protects the contents of a keystore.
232
* For example, protection parameters may be used to check
233
* the integrity of keystore data, or to protect the
234
* confidentiality of sensitive keystore data
235
* (such as a {@code PrivateKey}).
236
*
237
* @since 1.5
238
*/
239
public static interface ProtectionParameter { }
240
241
/**
242
* A password-based implementation of {@code ProtectionParameter}.
243
*
244
* @since 1.5
245
*/
246
public static class PasswordProtection implements
247
ProtectionParameter, javax.security.auth.Destroyable {
248
249
private final char[] password;
250
private final String protectionAlgorithm;
251
private final AlgorithmParameterSpec protectionParameters;
252
private volatile boolean destroyed = false;
253
254
/**
255
* Creates a password parameter.
256
*
257
* <p> The specified {@code password} is cloned before it is stored
258
* in the new {@code PasswordProtection} object.
259
*
260
* @param password the password, which may be {@code null}
261
*/
262
public PasswordProtection(char[] password) {
263
this.password = (password == null) ? null : password.clone();
264
this.protectionAlgorithm = null;
265
this.protectionParameters = null;
266
}
267
268
/**
269
* Creates a password parameter and specifies the protection algorithm
270
* and associated parameters to use when encrypting a keystore entry.
271
* <p>
272
* The specified {@code password} is cloned before it is stored in the
273
* new {@code PasswordProtection} object.
274
*
275
* @param password the password, which may be {@code null}
276
* @param protectionAlgorithm the encryption algorithm name, for
277
* example, {@code PBEWithHmacSHA256AndAES_256}.
278
* See the Cipher section in the <a href=
279
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
280
* Java Cryptography Architecture Standard Algorithm Name
281
* Documentation</a>
282
* for information about standard encryption algorithm names.
283
* @param protectionParameters the encryption algorithm parameter
284
* specification, which may be {@code null}
285
* @exception NullPointerException if {@code protectionAlgorithm} is
286
* {@code null}
287
*
288
* @since 1.8
289
*/
290
public PasswordProtection(char[] password, String protectionAlgorithm,
291
AlgorithmParameterSpec protectionParameters) {
292
if (protectionAlgorithm == null) {
293
throw new NullPointerException("invalid null input");
294
}
295
this.password = (password == null) ? null : password.clone();
296
this.protectionAlgorithm = protectionAlgorithm;
297
this.protectionParameters = protectionParameters;
298
}
299
300
/**
301
* Gets the name of the protection algorithm.
302
* If none was set then the keystore provider will use its default
303
* protection algorithm. The name of the default protection algorithm
304
* for a given keystore type is set using the
305
* {@code 'keystore.<type>.keyProtectionAlgorithm'} security property.
306
* For example, the
307
* {@code keystore.PKCS12.keyProtectionAlgorithm} property stores the
308
* name of the default key protection algorithm used for PKCS12
309
* keystores. If the security property is not set, an
310
* implementation-specific algorithm will be used.
311
*
312
* @return the algorithm name, or {@code null} if none was set
313
*
314
* @since 1.8
315
*/
316
public String getProtectionAlgorithm() {
317
return protectionAlgorithm;
318
}
319
320
/**
321
* Gets the parameters supplied for the protection algorithm.
322
*
323
* @return the algorithm parameter specification, or {@code null},
324
* if none was set
325
*
326
* @since 1.8
327
*/
328
public AlgorithmParameterSpec getProtectionParameters() {
329
return protectionParameters;
330
}
331
332
/**
333
* Gets the password.
334
*
335
* <p>Note that this method returns a reference to the password.
336
* If a clone of the array is created it is the caller's
337
* responsibility to zero out the password information
338
* after it is no longer needed.
339
*
340
* @see #destroy()
341
* @return the password, which may be {@code null}
342
* @exception IllegalStateException if the password has
343
* been cleared (destroyed)
344
*/
345
public synchronized char[] getPassword() {
346
if (destroyed) {
347
throw new IllegalStateException("password has been cleared");
348
}
349
return password;
350
}
351
352
/**
353
* Clears the password.
354
*
355
* @exception DestroyFailedException if this method was unable
356
* to clear the password
357
*/
358
public synchronized void destroy() throws DestroyFailedException {
359
destroyed = true;
360
if (password != null) {
361
Arrays.fill(password, ' ');
362
}
363
}
364
365
/**
366
* Determines if password has been cleared.
367
*
368
* @return true if the password has been cleared, false otherwise
369
*/
370
public synchronized boolean isDestroyed() {
371
return destroyed;
372
}
373
}
374
375
/**
376
* A ProtectionParameter encapsulating a CallbackHandler.
377
*
378
* @since 1.5
379
*/
380
public static class CallbackHandlerProtection
381
implements ProtectionParameter {
382
383
private final CallbackHandler handler;
384
385
/**
386
* Constructs a new CallbackHandlerProtection from a
387
* CallbackHandler.
388
*
389
* @param handler the CallbackHandler
390
* @exception NullPointerException if handler is null
391
*/
392
public CallbackHandlerProtection(CallbackHandler handler) {
393
if (handler == null) {
394
throw new NullPointerException("handler must not be null");
395
}
396
this.handler = handler;
397
}
398
399
/**
400
* Returns the CallbackHandler.
401
*
402
* @return the CallbackHandler.
403
*/
404
public CallbackHandler getCallbackHandler() {
405
return handler;
406
}
407
408
}
409
410
/**
411
* A marker interface for {@code KeyStore} entry types.
412
*
413
* @since 1.5
414
*/
415
public static interface Entry {
416
417
/**
418
* Retrieves the attributes associated with an entry.
419
* <p>
420
* The default implementation returns an empty {@code Set}.
421
*
422
* @return an unmodifiable {@code Set} of attributes, possibly empty
423
*
424
* @since 1.8
425
*/
426
public default Set<Attribute> getAttributes() {
427
return Collections.<Attribute>emptySet();
428
}
429
430
/**
431
* An attribute associated with a keystore entry.
432
* It comprises a name and one or more values.
433
*
434
* @since 1.8
435
*/
436
public interface Attribute {
437
/**
438
* Returns the attribute's name.
439
*
440
* @return the attribute name
441
*/
442
public String getName();
443
444
/**
445
* Returns the attribute's value.
446
* Multi-valued attributes encode their values as a single string.
447
*
448
* @return the attribute value
449
*/
450
public String getValue();
451
}
452
}
453
454
/**
455
* A {@code KeyStore} entry that holds a {@code PrivateKey}
456
* and corresponding certificate chain.
457
*
458
* @since 1.5
459
*/
460
public static final class PrivateKeyEntry implements Entry {
461
462
private final PrivateKey privKey;
463
private final Certificate[] chain;
464
private final Set<Attribute> attributes;
465
466
/**
467
* Constructs a {@code PrivateKeyEntry} with a
468
* {@code PrivateKey} and corresponding certificate chain.
469
*
470
* <p> The specified {@code chain} is cloned before it is stored
471
* in the new {@code PrivateKeyEntry} object.
472
*
473
* @param privateKey the {@code PrivateKey}
474
* @param chain an array of {@code Certificate}s
475
* representing the certificate chain.
476
* The chain must be ordered and contain a
477
* {@code Certificate} at index 0
478
* corresponding to the private key.
479
*
480
* @exception NullPointerException if
481
* {@code privateKey} or {@code chain}
482
* is {@code null}
483
* @exception IllegalArgumentException if the specified chain has a
484
* length of 0, if the specified chain does not contain
485
* {@code Certificate}s of the same type,
486
* or if the {@code PrivateKey} algorithm
487
* does not match the algorithm of the {@code PublicKey}
488
* in the end entity {@code Certificate} (at index 0)
489
*/
490
public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain) {
491
this(privateKey, chain, Collections.<Attribute>emptySet());
492
}
493
494
/**
495
* Constructs a {@code PrivateKeyEntry} with a {@code PrivateKey} and
496
* corresponding certificate chain and associated entry attributes.
497
*
498
* <p> The specified {@code chain} and {@code attributes} are cloned
499
* before they are stored in the new {@code PrivateKeyEntry} object.
500
*
501
* @param privateKey the {@code PrivateKey}
502
* @param chain an array of {@code Certificate}s
503
* representing the certificate chain.
504
* The chain must be ordered and contain a
505
* {@code Certificate} at index 0
506
* corresponding to the private key.
507
* @param attributes the attributes
508
*
509
* @exception NullPointerException if {@code privateKey}, {@code chain}
510
* or {@code attributes} is {@code null}
511
* @exception IllegalArgumentException if the specified chain has a
512
* length of 0, if the specified chain does not contain
513
* {@code Certificate}s of the same type,
514
* or if the {@code PrivateKey} algorithm
515
* does not match the algorithm of the {@code PublicKey}
516
* in the end entity {@code Certificate} (at index 0)
517
*
518
* @since 1.8
519
*/
520
public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain,
521
Set<Attribute> attributes) {
522
523
if (privateKey == null || chain == null || attributes == null) {
524
throw new NullPointerException("invalid null input");
525
}
526
if (chain.length == 0) {
527
throw new IllegalArgumentException
528
("invalid zero-length input chain");
529
}
530
531
Certificate[] clonedChain = chain.clone();
532
String certType = clonedChain[0].getType();
533
for (int i = 1; i < clonedChain.length; i++) {
534
if (!certType.equals(clonedChain[i].getType())) {
535
throw new IllegalArgumentException
536
("chain does not contain certificates " +
537
"of the same type");
538
}
539
}
540
if (!privateKey.getAlgorithm().equals
541
(clonedChain[0].getPublicKey().getAlgorithm())) {
542
throw new IllegalArgumentException
543
("private key algorithm does not match " +
544
"algorithm of public key in end entity " +
545
"certificate (at index 0)");
546
}
547
this.privKey = privateKey;
548
549
if (clonedChain[0] instanceof X509Certificate &&
550
!(clonedChain instanceof X509Certificate[])) {
551
552
this.chain = new X509Certificate[clonedChain.length];
553
System.arraycopy(clonedChain, 0,
554
this.chain, 0, clonedChain.length);
555
} else {
556
this.chain = clonedChain;
557
}
558
559
this.attributes =
560
Collections.unmodifiableSet(new HashSet<>(attributes));
561
}
562
563
/**
564
* Gets the {@code PrivateKey} from this entry.
565
*
566
* @return the {@code PrivateKey} from this entry
567
*/
568
public PrivateKey getPrivateKey() {
569
return privKey;
570
}
571
572
/**
573
* Gets the {@code Certificate} chain from this entry.
574
*
575
* <p> The stored chain is cloned before being returned.
576
*
577
* @return an array of {@code Certificate}s corresponding
578
* to the certificate chain for the public key.
579
* If the certificates are of type X.509,
580
* the runtime type of the returned array is
581
* {@code X509Certificate[]}.
582
*/
583
public Certificate[] getCertificateChain() {
584
return chain.clone();
585
}
586
587
/**
588
* Gets the end entity {@code Certificate}
589
* from the certificate chain in this entry.
590
*
591
* @return the end entity {@code Certificate} (at index 0)
592
* from the certificate chain in this entry.
593
* If the certificate is of type X.509,
594
* the runtime type of the returned certificate is
595
* {@code X509Certificate}.
596
*/
597
public Certificate getCertificate() {
598
return chain[0];
599
}
600
601
/**
602
* Retrieves the attributes associated with an entry.
603
* <p>
604
*
605
* @return an unmodifiable {@code Set} of attributes, possibly empty
606
*
607
* @since 1.8
608
*/
609
@Override
610
public Set<Attribute> getAttributes() {
611
return attributes;
612
}
613
614
/**
615
* Returns a string representation of this PrivateKeyEntry.
616
* @return a string representation of this PrivateKeyEntry.
617
*/
618
public String toString() {
619
StringBuilder sb = new StringBuilder();
620
sb.append("Private key entry and certificate chain with "
621
+ chain.length + " elements:\r\n");
622
for (Certificate cert : chain) {
623
sb.append(cert);
624
sb.append("\r\n");
625
}
626
return sb.toString();
627
}
628
629
}
630
631
/**
632
* A {@code KeyStore} entry that holds a {@code SecretKey}.
633
*
634
* @since 1.5
635
*/
636
public static final class SecretKeyEntry implements Entry {
637
638
private final SecretKey sKey;
639
private final Set<Attribute> attributes;
640
641
/**
642
* Constructs a {@code SecretKeyEntry} with a
643
* {@code SecretKey}.
644
*
645
* @param secretKey the {@code SecretKey}
646
*
647
* @exception NullPointerException if {@code secretKey}
648
* is {@code null}
649
*/
650
public SecretKeyEntry(SecretKey secretKey) {
651
if (secretKey == null) {
652
throw new NullPointerException("invalid null input");
653
}
654
this.sKey = secretKey;
655
this.attributes = Collections.<Attribute>emptySet();
656
}
657
658
/**
659
* Constructs a {@code SecretKeyEntry} with a {@code SecretKey} and
660
* associated entry attributes.
661
*
662
* <p> The specified {@code attributes} is cloned before it is stored
663
* in the new {@code SecretKeyEntry} object.
664
*
665
* @param secretKey the {@code SecretKey}
666
* @param attributes the attributes
667
*
668
* @exception NullPointerException if {@code secretKey} or
669
* {@code attributes} is {@code null}
670
*
671
* @since 1.8
672
*/
673
public SecretKeyEntry(SecretKey secretKey, Set<Attribute> attributes) {
674
675
if (secretKey == null || attributes == null) {
676
throw new NullPointerException("invalid null input");
677
}
678
this.sKey = secretKey;
679
this.attributes =
680
Collections.unmodifiableSet(new HashSet<>(attributes));
681
}
682
683
/**
684
* Gets the {@code SecretKey} from this entry.
685
*
686
* @return the {@code SecretKey} from this entry
687
*/
688
public SecretKey getSecretKey() {
689
return sKey;
690
}
691
692
/**
693
* Retrieves the attributes associated with an entry.
694
* <p>
695
*
696
* @return an unmodifiable {@code Set} of attributes, possibly empty
697
*
698
* @since 1.8
699
*/
700
@Override
701
public Set<Attribute> getAttributes() {
702
return attributes;
703
}
704
705
/**
706
* Returns a string representation of this SecretKeyEntry.
707
* @return a string representation of this SecretKeyEntry.
708
*/
709
public String toString() {
710
return "Secret key entry with algorithm " + sKey.getAlgorithm();
711
}
712
}
713
714
/**
715
* A {@code KeyStore} entry that holds a trusted
716
* {@code Certificate}.
717
*
718
* @since 1.5
719
*/
720
public static final class TrustedCertificateEntry implements Entry {
721
722
private final Certificate cert;
723
private final Set<Attribute> attributes;
724
725
/**
726
* Constructs a {@code TrustedCertificateEntry} with a
727
* trusted {@code Certificate}.
728
*
729
* @param trustedCert the trusted {@code Certificate}
730
*
731
* @exception NullPointerException if
732
* {@code trustedCert} is {@code null}
733
*/
734
public TrustedCertificateEntry(Certificate trustedCert) {
735
if (trustedCert == null) {
736
throw new NullPointerException("invalid null input");
737
}
738
this.cert = trustedCert;
739
this.attributes = Collections.<Attribute>emptySet();
740
}
741
742
/**
743
* Constructs a {@code TrustedCertificateEntry} with a
744
* trusted {@code Certificate} and associated entry attributes.
745
*
746
* <p> The specified {@code attributes} is cloned before it is stored
747
* in the new {@code TrustedCertificateEntry} object.
748
*
749
* @param trustedCert the trusted {@code Certificate}
750
* @param attributes the attributes
751
*
752
* @exception NullPointerException if {@code trustedCert} or
753
* {@code attributes} is {@code null}
754
*
755
* @since 1.8
756
*/
757
public TrustedCertificateEntry(Certificate trustedCert,
758
Set<Attribute> attributes) {
759
if (trustedCert == null || attributes == null) {
760
throw new NullPointerException("invalid null input");
761
}
762
this.cert = trustedCert;
763
this.attributes =
764
Collections.unmodifiableSet(new HashSet<>(attributes));
765
}
766
767
/**
768
* Gets the trusted {@code Certficate} from this entry.
769
*
770
* @return the trusted {@code Certificate} from this entry
771
*/
772
public Certificate getTrustedCertificate() {
773
return cert;
774
}
775
776
/**
777
* Retrieves the attributes associated with an entry.
778
* <p>
779
*
780
* @return an unmodifiable {@code Set} of attributes, possibly empty
781
*
782
* @since 1.8
783
*/
784
@Override
785
public Set<Attribute> getAttributes() {
786
return attributes;
787
}
788
789
/**
790
* Returns a string representation of this TrustedCertificateEntry.
791
* @return a string representation of this TrustedCertificateEntry.
792
*/
793
public String toString() {
794
return "Trusted certificate entry:\r\n" + cert.toString();
795
}
796
}
797
798
/**
799
* Creates a KeyStore object of the given type, and encapsulates the given
800
* provider implementation (SPI object) in it.
801
*
802
* @param keyStoreSpi the provider implementation.
803
* @param provider the provider.
804
* @param type the keystore type.
805
*/
806
protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type)
807
{
808
this.keyStoreSpi = keyStoreSpi;
809
this.provider = provider;
810
this.type = type;
811
812
if (!skipDebug && pdebug != null) {
813
pdebug.println("KeyStore." + type.toUpperCase() + " type from: " +
814
this.provider.getName());
815
}
816
}
817
818
/**
819
* Returns a keystore object of the specified type.
820
*
821
* <p> This method traverses the list of registered security Providers,
822
* starting with the most preferred Provider.
823
* A new KeyStore object encapsulating the
824
* KeyStoreSpi implementation from the first
825
* Provider that supports the specified type is returned.
826
*
827
* <p> Note that the list of registered providers may be retrieved via
828
* the {@link Security#getProviders() Security.getProviders()} method.
829
*
830
* @param type the type of keystore.
831
* See the KeyStore section in the <a href=
832
* "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
833
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
834
* for information about standard keystore types.
835
*
836
* @return a keystore object of the specified type.
837
*
838
* @exception KeyStoreException if no Provider supports a
839
* KeyStoreSpi implementation for the
840
* specified type.
841
*
842
* @see Provider
843
*/
844
public static KeyStore getInstance(String type)
845
throws KeyStoreException
846
{
847
try {
848
Object[] objs = Security.getImpl(type, "KeyStore", (String)null);
849
return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
850
} catch (NoSuchAlgorithmException nsae) {
851
throw new KeyStoreException(type + " not found", nsae);
852
} catch (NoSuchProviderException nspe) {
853
throw new KeyStoreException(type + " not found", nspe);
854
}
855
}
856
857
/**
858
* Returns a keystore object of the specified type.
859
*
860
* <p> A new KeyStore object encapsulating the
861
* KeyStoreSpi implementation from the specified provider
862
* is returned. The specified provider must be registered
863
* in the security provider list.
864
*
865
* <p> Note that the list of registered providers may be retrieved via
866
* the {@link Security#getProviders() Security.getProviders()} method.
867
*
868
* @param type the type of keystore.
869
* See the KeyStore section in the <a href=
870
* "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
871
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
872
* for information about standard keystore types.
873
*
874
* @param provider the name of the provider.
875
*
876
* @return a keystore object of the specified type.
877
*
878
* @exception KeyStoreException if a KeyStoreSpi
879
* implementation for the specified type is not
880
* available from the specified provider.
881
*
882
* @exception NoSuchProviderException if the specified provider is not
883
* registered in the security provider list.
884
*
885
* @exception IllegalArgumentException if the provider name is null
886
* or empty.
887
*
888
* @see Provider
889
*/
890
public static KeyStore getInstance(String type, String provider)
891
throws KeyStoreException, NoSuchProviderException
892
{
893
if (provider == null || provider.length() == 0)
894
throw new IllegalArgumentException("missing provider");
895
try {
896
Object[] objs = Security.getImpl(type, "KeyStore", provider);
897
return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
898
} catch (NoSuchAlgorithmException nsae) {
899
throw new KeyStoreException(type + " not found", nsae);
900
}
901
}
902
903
/**
904
* Returns a keystore object of the specified type.
905
*
906
* <p> A new KeyStore object encapsulating the
907
* KeyStoreSpi implementation from the specified Provider
908
* object is returned. Note that the specified Provider object
909
* does not have to be registered in the provider list.
910
*
911
* @param type the type of keystore.
912
* See the KeyStore section in the <a href=
913
* "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
914
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
915
* for information about standard keystore types.
916
*
917
* @param provider the provider.
918
*
919
* @return a keystore object of the specified type.
920
*
921
* @exception KeyStoreException if KeyStoreSpi
922
* implementation for the specified type is not available
923
* from the specified Provider object.
924
*
925
* @exception IllegalArgumentException if the specified provider is null.
926
*
927
* @see Provider
928
*
929
* @since 1.4
930
*/
931
public static KeyStore getInstance(String type, Provider provider)
932
throws KeyStoreException
933
{
934
if (provider == null)
935
throw new IllegalArgumentException("missing provider");
936
try {
937
Object[] objs = Security.getImpl(type, "KeyStore", provider);
938
return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
939
} catch (NoSuchAlgorithmException nsae) {
940
throw new KeyStoreException(type + " not found", nsae);
941
}
942
}
943
944
/**
945
* Returns the default keystore type as specified by the
946
* {@code keystore.type} security property, or the string
947
* {@literal "jks"} (acronym for {@literal "Java keystore"})
948
* if no such property exists.
949
*
950
* <p>The default keystore type can be used by applications that do not
951
* want to use a hard-coded keystore type when calling one of the
952
* {@code getInstance} methods, and want to provide a default keystore
953
* type in case a user does not specify its own.
954
*
955
* <p>The default keystore type can be changed by setting the value of the
956
* {@code keystore.type} security property to the desired keystore type.
957
*
958
* @return the default keystore type as specified by the
959
* {@code keystore.type} security property, or the string {@literal "jks"}
960
* if no such property exists.
961
* @see java.security.Security security properties
962
*/
963
public final static String getDefaultType() {
964
String kstype;
965
kstype = AccessController.doPrivileged(new PrivilegedAction<String>() {
966
public String run() {
967
return Security.getProperty(KEYSTORE_TYPE);
968
}
969
});
970
if (kstype == null) {
971
kstype = "jks";
972
}
973
return kstype;
974
}
975
976
/**
977
* Returns the provider of this keystore.
978
*
979
* @return the provider of this keystore.
980
*/
981
public final Provider getProvider()
982
{
983
return this.provider;
984
}
985
986
/**
987
* Returns the type of this keystore.
988
*
989
* @return the type of this keystore.
990
*/
991
public final String getType()
992
{
993
return this.type;
994
}
995
996
/**
997
* Returns the key associated with the given alias, using the given
998
* password to recover it. The key must have been associated with
999
* the alias by a call to {@code setKeyEntry},
1000
* or by a call to {@code setEntry} with a
1001
* {@code PrivateKeyEntry} or {@code SecretKeyEntry}.
1002
*
1003
* @param alias the alias name
1004
* @param password the password for recovering the key
1005
*
1006
* @return the requested key, or null if the given alias does not exist
1007
* or does not identify a key-related entry.
1008
*
1009
* @exception KeyStoreException if the keystore has not been initialized
1010
* (loaded).
1011
* @exception NoSuchAlgorithmException if the algorithm for recovering the
1012
* key cannot be found
1013
* @exception UnrecoverableKeyException if the key cannot be recovered
1014
* (e.g., the given password is wrong).
1015
*/
1016
public final Key getKey(String alias, char[] password)
1017
throws KeyStoreException, NoSuchAlgorithmException,
1018
UnrecoverableKeyException
1019
{
1020
if (!initialized) {
1021
throw new KeyStoreException("Uninitialized keystore");
1022
}
1023
return keyStoreSpi.engineGetKey(alias, password);
1024
}
1025
1026
/**
1027
* Returns the certificate chain associated with the given alias.
1028
* The certificate chain must have been associated with the alias
1029
* by a call to {@code setKeyEntry},
1030
* or by a call to {@code setEntry} with a
1031
* {@code PrivateKeyEntry}.
1032
*
1033
* @param alias the alias name
1034
*
1035
* @return the certificate chain (ordered with the user's certificate first
1036
* followed by zero or more certificate authorities), or null if the given alias
1037
* does not exist or does not contain a certificate chain
1038
*
1039
* @exception KeyStoreException if the keystore has not been initialized
1040
* (loaded).
1041
*/
1042
public final Certificate[] getCertificateChain(String alias)
1043
throws KeyStoreException
1044
{
1045
if (!initialized) {
1046
throw new KeyStoreException("Uninitialized keystore");
1047
}
1048
return keyStoreSpi.engineGetCertificateChain(alias);
1049
}
1050
1051
/**
1052
* Returns the certificate associated with the given alias.
1053
*
1054
* <p> If the given alias name identifies an entry
1055
* created by a call to {@code setCertificateEntry},
1056
* or created by a call to {@code setEntry} with a
1057
* {@code TrustedCertificateEntry},
1058
* then the trusted certificate contained in that entry is returned.
1059
*
1060
* <p> If the given alias name identifies an entry
1061
* created by a call to {@code setKeyEntry},
1062
* or created by a call to {@code setEntry} with a
1063
* {@code PrivateKeyEntry},
1064
* then the first element of the certificate chain in that entry
1065
* is returned.
1066
*
1067
* @param alias the alias name
1068
*
1069
* @return the certificate, or null if the given alias does not exist or
1070
* does not contain a certificate.
1071
*
1072
* @exception KeyStoreException if the keystore has not been initialized
1073
* (loaded).
1074
*/
1075
public final Certificate getCertificate(String alias)
1076
throws KeyStoreException
1077
{
1078
if (!initialized) {
1079
throw new KeyStoreException("Uninitialized keystore");
1080
}
1081
return keyStoreSpi.engineGetCertificate(alias);
1082
}
1083
1084
/**
1085
* Returns the creation date of the entry identified by the given alias.
1086
*
1087
* @param alias the alias name
1088
*
1089
* @return the creation date of this entry, or null if the given alias does
1090
* not exist
1091
*
1092
* @exception KeyStoreException if the keystore has not been initialized
1093
* (loaded).
1094
*/
1095
public final Date getCreationDate(String alias)
1096
throws KeyStoreException
1097
{
1098
if (!initialized) {
1099
throw new KeyStoreException("Uninitialized keystore");
1100
}
1101
return keyStoreSpi.engineGetCreationDate(alias);
1102
}
1103
1104
/**
1105
* Assigns the given key to the given alias, protecting it with the given
1106
* password.
1107
*
1108
* <p>If the given key is of type {@code java.security.PrivateKey},
1109
* it must be accompanied by a certificate chain certifying the
1110
* corresponding public key.
1111
*
1112
* <p>If the given alias already exists, the keystore information
1113
* associated with it is overridden by the given key (and possibly
1114
* certificate chain).
1115
*
1116
* @param alias the alias name
1117
* @param key the key to be associated with the alias
1118
* @param password the password to protect the key
1119
* @param chain the certificate chain for the corresponding public
1120
* key (only required if the given key is of type
1121
* {@code java.security.PrivateKey}).
1122
*
1123
* @exception KeyStoreException if the keystore has not been initialized
1124
* (loaded), the given key cannot be protected, or this operation fails
1125
* for some other reason
1126
*/
1127
public final void setKeyEntry(String alias, Key key, char[] password,
1128
Certificate[] chain)
1129
throws KeyStoreException
1130
{
1131
if (!initialized) {
1132
throw new KeyStoreException("Uninitialized keystore");
1133
}
1134
if ((key instanceof PrivateKey) &&
1135
(chain == null || chain.length == 0)) {
1136
throw new IllegalArgumentException("Private key must be "
1137
+ "accompanied by certificate "
1138
+ "chain");
1139
}
1140
keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
1141
}
1142
1143
/**
1144
* Assigns the given key (that has already been protected) to the given
1145
* alias.
1146
*
1147
* <p>If the protected key is of type
1148
* {@code java.security.PrivateKey}, it must be accompanied by a
1149
* certificate chain certifying the corresponding public key. If the
1150
* underlying keystore implementation is of type {@code jks},
1151
* {@code key} must be encoded as an
1152
* {@code EncryptedPrivateKeyInfo} as defined in the PKCS #8 standard.
1153
*
1154
* <p>If the given alias already exists, the keystore information
1155
* associated with it is overridden by the given key (and possibly
1156
* certificate chain).
1157
*
1158
* @param alias the alias name
1159
* @param key the key (in protected format) to be associated with the alias
1160
* @param chain the certificate chain for the corresponding public
1161
* key (only useful if the protected key is of type
1162
* {@code java.security.PrivateKey}).
1163
*
1164
* @exception KeyStoreException if the keystore has not been initialized
1165
* (loaded), or if this operation fails for some other reason.
1166
*/
1167
public final void setKeyEntry(String alias, byte[] key,
1168
Certificate[] chain)
1169
throws KeyStoreException
1170
{
1171
if (!initialized) {
1172
throw new KeyStoreException("Uninitialized keystore");
1173
}
1174
keyStoreSpi.engineSetKeyEntry(alias, key, chain);
1175
}
1176
1177
/**
1178
* Assigns the given trusted certificate to the given alias.
1179
*
1180
* <p> If the given alias identifies an existing entry
1181
* created by a call to {@code setCertificateEntry},
1182
* or created by a call to {@code setEntry} with a
1183
* {@code TrustedCertificateEntry},
1184
* the trusted certificate in the existing entry
1185
* is overridden by the given certificate.
1186
*
1187
* @param alias the alias name
1188
* @param cert the certificate
1189
*
1190
* @exception KeyStoreException if the keystore has not been initialized,
1191
* or the given alias already exists and does not identify an
1192
* entry containing a trusted certificate,
1193
* or this operation fails for some other reason.
1194
*/
1195
public final void setCertificateEntry(String alias, Certificate cert)
1196
throws KeyStoreException
1197
{
1198
if (!initialized) {
1199
throw new KeyStoreException("Uninitialized keystore");
1200
}
1201
keyStoreSpi.engineSetCertificateEntry(alias, cert);
1202
}
1203
1204
/**
1205
* Deletes the entry identified by the given alias from this keystore.
1206
*
1207
* @param alias the alias name
1208
*
1209
* @exception KeyStoreException if the keystore has not been initialized,
1210
* or if the entry cannot be removed.
1211
*/
1212
public final void deleteEntry(String alias)
1213
throws KeyStoreException
1214
{
1215
if (!initialized) {
1216
throw new KeyStoreException("Uninitialized keystore");
1217
}
1218
keyStoreSpi.engineDeleteEntry(alias);
1219
}
1220
1221
/**
1222
* Lists all the alias names of this keystore.
1223
*
1224
* @return enumeration of the alias names
1225
*
1226
* @exception KeyStoreException if the keystore has not been initialized
1227
* (loaded).
1228
*/
1229
public final Enumeration<String> aliases()
1230
throws KeyStoreException
1231
{
1232
if (!initialized) {
1233
throw new KeyStoreException("Uninitialized keystore");
1234
}
1235
return keyStoreSpi.engineAliases();
1236
}
1237
1238
/**
1239
* Checks if the given alias exists in this keystore.
1240
*
1241
* @param alias the alias name
1242
*
1243
* @return true if the alias exists, false otherwise
1244
*
1245
* @exception KeyStoreException if the keystore has not been initialized
1246
* (loaded).
1247
*/
1248
public final boolean containsAlias(String alias)
1249
throws KeyStoreException
1250
{
1251
if (!initialized) {
1252
throw new KeyStoreException("Uninitialized keystore");
1253
}
1254
return keyStoreSpi.engineContainsAlias(alias);
1255
}
1256
1257
/**
1258
* Retrieves the number of entries in this keystore.
1259
*
1260
* @return the number of entries in this keystore
1261
*
1262
* @exception KeyStoreException if the keystore has not been initialized
1263
* (loaded).
1264
*/
1265
public final int size()
1266
throws KeyStoreException
1267
{
1268
if (!initialized) {
1269
throw new KeyStoreException("Uninitialized keystore");
1270
}
1271
return keyStoreSpi.engineSize();
1272
}
1273
1274
/**
1275
* Returns true if the entry identified by the given alias
1276
* was created by a call to {@code setKeyEntry},
1277
* or created by a call to {@code setEntry} with a
1278
* {@code PrivateKeyEntry} or a {@code SecretKeyEntry}.
1279
*
1280
* @param alias the alias for the keystore entry to be checked
1281
*
1282
* @return true if the entry identified by the given alias is a
1283
* key-related entry, false otherwise.
1284
*
1285
* @exception KeyStoreException if the keystore has not been initialized
1286
* (loaded).
1287
*/
1288
public final boolean isKeyEntry(String alias)
1289
throws KeyStoreException
1290
{
1291
if (!initialized) {
1292
throw new KeyStoreException("Uninitialized keystore");
1293
}
1294
return keyStoreSpi.engineIsKeyEntry(alias);
1295
}
1296
1297
/**
1298
* Returns true if the entry identified by the given alias
1299
* was created by a call to {@code setCertificateEntry},
1300
* or created by a call to {@code setEntry} with a
1301
* {@code TrustedCertificateEntry}.
1302
*
1303
* @param alias the alias for the keystore entry to be checked
1304
*
1305
* @return true if the entry identified by the given alias contains a
1306
* trusted certificate, false otherwise.
1307
*
1308
* @exception KeyStoreException if the keystore has not been initialized
1309
* (loaded).
1310
*/
1311
public final boolean isCertificateEntry(String alias)
1312
throws KeyStoreException
1313
{
1314
if (!initialized) {
1315
throw new KeyStoreException("Uninitialized keystore");
1316
}
1317
return keyStoreSpi.engineIsCertificateEntry(alias);
1318
}
1319
1320
/**
1321
* Returns the (alias) name of the first keystore entry whose certificate
1322
* matches the given certificate.
1323
*
1324
* <p> This method attempts to match the given certificate with each
1325
* keystore entry. If the entry being considered was
1326
* created by a call to {@code setCertificateEntry},
1327
* or created by a call to {@code setEntry} with a
1328
* {@code TrustedCertificateEntry},
1329
* then the given certificate is compared to that entry's certificate.
1330
*
1331
* <p> If the entry being considered was
1332
* created by a call to {@code setKeyEntry},
1333
* or created by a call to {@code setEntry} with a
1334
* {@code PrivateKeyEntry},
1335
* then the given certificate is compared to the first
1336
* element of that entry's certificate chain.
1337
*
1338
* @param cert the certificate to match with.
1339
*
1340
* @return the alias name of the first entry with a matching certificate,
1341
* or null if no such entry exists in this keystore.
1342
*
1343
* @exception KeyStoreException if the keystore has not been initialized
1344
* (loaded).
1345
*/
1346
public final String getCertificateAlias(Certificate cert)
1347
throws KeyStoreException
1348
{
1349
if (!initialized) {
1350
throw new KeyStoreException("Uninitialized keystore");
1351
}
1352
return keyStoreSpi.engineGetCertificateAlias(cert);
1353
}
1354
1355
/**
1356
* Stores this keystore to the given output stream, and protects its
1357
* integrity with the given password.
1358
*
1359
* @param stream the output stream to which this keystore is written.
1360
* @param password the password to generate the keystore integrity check
1361
*
1362
* @exception KeyStoreException if the keystore has not been initialized
1363
* (loaded).
1364
* @exception IOException if there was an I/O problem with data
1365
* @exception NoSuchAlgorithmException if the appropriate data integrity
1366
* algorithm could not be found
1367
* @exception CertificateException if any of the certificates included in
1368
* the keystore data could not be stored
1369
*/
1370
public final void store(OutputStream stream, char[] password)
1371
throws KeyStoreException, IOException, NoSuchAlgorithmException,
1372
CertificateException
1373
{
1374
if (!initialized) {
1375
throw new KeyStoreException("Uninitialized keystore");
1376
}
1377
keyStoreSpi.engineStore(stream, password);
1378
}
1379
1380
/**
1381
* Stores this keystore using the given {@code LoadStoreParameter}.
1382
*
1383
* @param param the {@code LoadStoreParameter}
1384
* that specifies how to store the keystore,
1385
* which may be {@code null}
1386
*
1387
* @exception IllegalArgumentException if the given
1388
* {@code LoadStoreParameter}
1389
* input is not recognized
1390
* @exception KeyStoreException if the keystore has not been initialized
1391
* (loaded)
1392
* @exception IOException if there was an I/O problem with data
1393
* @exception NoSuchAlgorithmException if the appropriate data integrity
1394
* algorithm could not be found
1395
* @exception CertificateException if any of the certificates included in
1396
* the keystore data could not be stored
1397
*
1398
* @since 1.5
1399
*/
1400
public final void store(LoadStoreParameter param)
1401
throws KeyStoreException, IOException,
1402
NoSuchAlgorithmException, CertificateException {
1403
if (!initialized) {
1404
throw new KeyStoreException("Uninitialized keystore");
1405
}
1406
keyStoreSpi.engineStore(param);
1407
}
1408
1409
/**
1410
* Loads this KeyStore from the given input stream.
1411
*
1412
* <p>A password may be given to unlock the keystore
1413
* (e.g. the keystore resides on a hardware token device),
1414
* or to check the integrity of the keystore data.
1415
* If a password is not given for integrity checking,
1416
* then integrity checking is not performed.
1417
*
1418
* <p>In order to create an empty keystore, or if the keystore cannot
1419
* be initialized from a stream, pass {@code null}
1420
* as the {@code stream} argument.
1421
*
1422
* <p> Note that if this keystore has already been loaded, it is
1423
* reinitialized and loaded again from the given input stream.
1424
*
1425
* @param stream the input stream from which the keystore is loaded,
1426
* or {@code null}
1427
* @param password the password used to check the integrity of
1428
* the keystore, the password used to unlock the keystore,
1429
* or {@code null}
1430
*
1431
* @exception IOException if there is an I/O or format problem with the
1432
* keystore data, if a password is required but not given,
1433
* or if the given password was incorrect. If the error is due to a
1434
* wrong password, the {@link Throwable#getCause cause} of the
1435
* {@code IOException} should be an
1436
* {@code UnrecoverableKeyException}
1437
* @exception NoSuchAlgorithmException if the algorithm used to check
1438
* the integrity of the keystore cannot be found
1439
* @exception CertificateException if any of the certificates in the
1440
* keystore could not be loaded
1441
*/
1442
public final void load(InputStream stream, char[] password)
1443
throws IOException, NoSuchAlgorithmException, CertificateException
1444
{
1445
keyStoreSpi.engineLoad(stream, password);
1446
initialized = true;
1447
}
1448
1449
/**
1450
* Loads this keystore using the given {@code LoadStoreParameter}.
1451
*
1452
* <p> Note that if this KeyStore has already been loaded, it is
1453
* reinitialized and loaded again from the given parameter.
1454
*
1455
* @param param the {@code LoadStoreParameter}
1456
* that specifies how to load the keystore,
1457
* which may be {@code null}
1458
*
1459
* @exception IllegalArgumentException if the given
1460
* {@code LoadStoreParameter}
1461
* input is not recognized
1462
* @exception IOException if there is an I/O or format problem with the
1463
* keystore data. If the error is due to an incorrect
1464
* {@code ProtectionParameter} (e.g. wrong password)
1465
* the {@link Throwable#getCause cause} of the
1466
* {@code IOException} should be an
1467
* {@code UnrecoverableKeyException}
1468
* @exception NoSuchAlgorithmException if the algorithm used to check
1469
* the integrity of the keystore cannot be found
1470
* @exception CertificateException if any of the certificates in the
1471
* keystore could not be loaded
1472
*
1473
* @since 1.5
1474
*/
1475
public final void load(LoadStoreParameter param)
1476
throws IOException, NoSuchAlgorithmException,
1477
CertificateException {
1478
1479
keyStoreSpi.engineLoad(param);
1480
initialized = true;
1481
}
1482
1483
/**
1484
* Gets a keystore {@code Entry} for the specified alias
1485
* with the specified protection parameter.
1486
*
1487
* @param alias get the keystore {@code Entry} for this alias
1488
* @param protParam the {@code ProtectionParameter}
1489
* used to protect the {@code Entry},
1490
* which may be {@code null}
1491
*
1492
* @return the keystore {@code Entry} for the specified alias,
1493
* or {@code null} if there is no such entry
1494
*
1495
* @exception NullPointerException if
1496
* {@code alias} is {@code null}
1497
* @exception NoSuchAlgorithmException if the algorithm for recovering the
1498
* entry cannot be found
1499
* @exception UnrecoverableEntryException if the specified
1500
* {@code protParam} were insufficient or invalid
1501
* @exception UnrecoverableKeyException if the entry is a
1502
* {@code PrivateKeyEntry} or {@code SecretKeyEntry}
1503
* and the specified {@code protParam} does not contain
1504
* the information needed to recover the key (e.g. wrong password)
1505
* @exception KeyStoreException if the keystore has not been initialized
1506
* (loaded).
1507
* @see #setEntry(String, KeyStore.Entry, KeyStore.ProtectionParameter)
1508
*
1509
* @since 1.5
1510
*/
1511
public final Entry getEntry(String alias, ProtectionParameter protParam)
1512
throws NoSuchAlgorithmException, UnrecoverableEntryException,
1513
KeyStoreException {
1514
1515
if (alias == null) {
1516
throw new NullPointerException("invalid null input");
1517
}
1518
if (!initialized) {
1519
throw new KeyStoreException("Uninitialized keystore");
1520
}
1521
return keyStoreSpi.engineGetEntry(alias, protParam);
1522
}
1523
1524
/**
1525
* Saves a keystore {@code Entry} under the specified alias.
1526
* The protection parameter is used to protect the
1527
* {@code Entry}.
1528
*
1529
* <p> If an entry already exists for the specified alias,
1530
* it is overridden.
1531
*
1532
* @param alias save the keystore {@code Entry} under this alias
1533
* @param entry the {@code Entry} to save
1534
* @param protParam the {@code ProtectionParameter}
1535
* used to protect the {@code Entry},
1536
* which may be {@code null}
1537
*
1538
* @exception NullPointerException if
1539
* {@code alias} or {@code entry}
1540
* is {@code null}
1541
* @exception KeyStoreException if the keystore has not been initialized
1542
* (loaded), or if this operation fails for some other reason
1543
*
1544
* @see #getEntry(String, KeyStore.ProtectionParameter)
1545
*
1546
* @since 1.5
1547
*/
1548
public final void setEntry(String alias, Entry entry,
1549
ProtectionParameter protParam)
1550
throws KeyStoreException {
1551
if (alias == null || entry == null) {
1552
throw new NullPointerException("invalid null input");
1553
}
1554
if (!initialized) {
1555
throw new KeyStoreException("Uninitialized keystore");
1556
}
1557
keyStoreSpi.engineSetEntry(alias, entry, protParam);
1558
}
1559
1560
/**
1561
* Determines if the keystore {@code Entry} for the specified
1562
* {@code alias} is an instance or subclass of the specified
1563
* {@code entryClass}.
1564
*
1565
* @param alias the alias name
1566
* @param entryClass the entry class
1567
*
1568
* @return true if the keystore {@code Entry} for the specified
1569
* {@code alias} is an instance or subclass of the
1570
* specified {@code entryClass}, false otherwise
1571
*
1572
* @exception NullPointerException if
1573
* {@code alias} or {@code entryClass}
1574
* is {@code null}
1575
* @exception KeyStoreException if the keystore has not been
1576
* initialized (loaded)
1577
*
1578
* @since 1.5
1579
*/
1580
public final boolean
1581
entryInstanceOf(String alias,
1582
Class<? extends KeyStore.Entry> entryClass)
1583
throws KeyStoreException
1584
{
1585
1586
if (alias == null || entryClass == null) {
1587
throw new NullPointerException("invalid null input");
1588
}
1589
if (!initialized) {
1590
throw new KeyStoreException("Uninitialized keystore");
1591
}
1592
return keyStoreSpi.engineEntryInstanceOf(alias, entryClass);
1593
}
1594
1595
/**
1596
* A description of a to-be-instantiated KeyStore object.
1597
*
1598
* <p>An instance of this class encapsulates the information needed to
1599
* instantiate and initialize a KeyStore object. That process is
1600
* triggered when the {@linkplain #getKeyStore} method is called.
1601
*
1602
* <p>This makes it possible to decouple configuration from KeyStore
1603
* object creation and e.g. delay a password prompt until it is
1604
* needed.
1605
*
1606
* @see KeyStore
1607
* @see javax.net.ssl.KeyStoreBuilderParameters
1608
* @since 1.5
1609
*/
1610
public static abstract class Builder {
1611
1612
// maximum times to try the callbackhandler if the password is wrong
1613
static final int MAX_CALLBACK_TRIES = 3;
1614
1615
/**
1616
* Construct a new Builder.
1617
*/
1618
protected Builder() {
1619
// empty
1620
}
1621
1622
/**
1623
* Returns the KeyStore described by this object.
1624
*
1625
* @return the {@code KeyStore} described by this object
1626
* @exception KeyStoreException if an error occurred during the
1627
* operation, for example if the KeyStore could not be
1628
* instantiated or loaded
1629
*/
1630
public abstract KeyStore getKeyStore() throws KeyStoreException;
1631
1632
/**
1633
* Returns the ProtectionParameters that should be used to obtain
1634
* the {@link KeyStore.Entry Entry} with the given alias.
1635
* The {@code getKeyStore} method must be invoked before this
1636
* method may be called.
1637
*
1638
* @return the ProtectionParameters that should be used to obtain
1639
* the {@link KeyStore.Entry Entry} with the given alias.
1640
* @param alias the alias of the KeyStore entry
1641
* @throws NullPointerException if alias is null
1642
* @throws KeyStoreException if an error occurred during the
1643
* operation
1644
* @throws IllegalStateException if the getKeyStore method has
1645
* not been invoked prior to calling this method
1646
*/
1647
public abstract ProtectionParameter getProtectionParameter(String alias)
1648
throws KeyStoreException;
1649
1650
/**
1651
* Returns a new Builder that encapsulates the given KeyStore.
1652
* The {@linkplain #getKeyStore} method of the returned object
1653
* will return {@code keyStore}, the {@linkplain
1654
* #getProtectionParameter getProtectionParameter()} method will
1655
* return {@code protectionParameters}.
1656
*
1657
* <p> This is useful if an existing KeyStore object needs to be
1658
* used with Builder-based APIs.
1659
*
1660
* @return a new Builder object
1661
* @param keyStore the KeyStore to be encapsulated
1662
* @param protectionParameter the ProtectionParameter used to
1663
* protect the KeyStore entries
1664
* @throws NullPointerException if keyStore or
1665
* protectionParameters is null
1666
* @throws IllegalArgumentException if the keyStore has not been
1667
* initialized
1668
*/
1669
public static Builder newInstance(final KeyStore keyStore,
1670
final ProtectionParameter protectionParameter) {
1671
if ((keyStore == null) || (protectionParameter == null)) {
1672
throw new NullPointerException();
1673
}
1674
if (keyStore.initialized == false) {
1675
throw new IllegalArgumentException("KeyStore not initialized");
1676
}
1677
return new Builder() {
1678
private volatile boolean getCalled;
1679
1680
public KeyStore getKeyStore() {
1681
getCalled = true;
1682
return keyStore;
1683
}
1684
1685
public ProtectionParameter getProtectionParameter(String alias)
1686
{
1687
if (alias == null) {
1688
throw new NullPointerException();
1689
}
1690
if (getCalled == false) {
1691
throw new IllegalStateException
1692
("getKeyStore() must be called first");
1693
}
1694
return protectionParameter;
1695
}
1696
};
1697
}
1698
1699
/**
1700
* Returns a new Builder object.
1701
*
1702
* <p>The first call to the {@link #getKeyStore} method on the returned
1703
* builder will create a KeyStore of type {@code type} and call
1704
* its {@link KeyStore#load load()} method.
1705
* The {@code inputStream} argument is constructed from
1706
* {@code file}.
1707
* If {@code protection} is a
1708
* {@code PasswordProtection}, the password is obtained by
1709
* calling the {@code getPassword} method.
1710
* Otherwise, if {@code protection} is a
1711
* {@code CallbackHandlerProtection}, the password is obtained
1712
* by invoking the CallbackHandler.
1713
*
1714
* <p>Subsequent calls to {@link #getKeyStore} return the same object
1715
* as the initial call. If the initial call to failed with a
1716
* KeyStoreException, subsequent calls also throw a
1717
* KeyStoreException.
1718
*
1719
* <p>The KeyStore is instantiated from {@code provider} if
1720
* non-null. Otherwise, all installed providers are searched.
1721
*
1722
* <p>Calls to {@link #getProtectionParameter getProtectionParameter()}
1723
* will return a {@link KeyStore.PasswordProtection PasswordProtection}
1724
* object encapsulating the password that was used to invoke the
1725
* {@code load} method.
1726
*
1727
* <p><em>Note</em> that the {@link #getKeyStore} method is executed
1728
* within the {@link AccessControlContext} of the code invoking this
1729
* method.
1730
*
1731
* @return a new Builder object
1732
* @param type the type of KeyStore to be constructed
1733
* @param provider the provider from which the KeyStore is to
1734
* be instantiated (or null)
1735
* @param file the File that contains the KeyStore data
1736
* @param protection the ProtectionParameter securing the KeyStore data
1737
* @throws NullPointerException if type, file or protection is null
1738
* @throws IllegalArgumentException if protection is not an instance
1739
* of either PasswordProtection or CallbackHandlerProtection; or
1740
* if file does not exist or does not refer to a normal file
1741
*/
1742
public static Builder newInstance(String type, Provider provider,
1743
File file, ProtectionParameter protection) {
1744
if ((type == null) || (file == null) || (protection == null)) {
1745
throw new NullPointerException();
1746
}
1747
if ((protection instanceof PasswordProtection == false) &&
1748
(protection instanceof CallbackHandlerProtection == false)) {
1749
throw new IllegalArgumentException
1750
("Protection must be PasswordProtection or " +
1751
"CallbackHandlerProtection");
1752
}
1753
if (file.isFile() == false) {
1754
throw new IllegalArgumentException
1755
("File does not exist or it does not refer " +
1756
"to a normal file: " + file);
1757
}
1758
return new FileBuilder(type, provider, file, protection,
1759
AccessController.getContext());
1760
}
1761
1762
private static final class FileBuilder extends Builder {
1763
1764
private final String type;
1765
private final Provider provider;
1766
private final File file;
1767
private ProtectionParameter protection;
1768
private ProtectionParameter keyProtection;
1769
private final AccessControlContext context;
1770
1771
private KeyStore keyStore;
1772
1773
private Throwable oldException;
1774
1775
FileBuilder(String type, Provider provider, File file,
1776
ProtectionParameter protection,
1777
AccessControlContext context) {
1778
this.type = type;
1779
this.provider = provider;
1780
this.file = file;
1781
this.protection = protection;
1782
this.context = context;
1783
}
1784
1785
public synchronized KeyStore getKeyStore() throws KeyStoreException
1786
{
1787
if (keyStore != null) {
1788
return keyStore;
1789
}
1790
if (oldException != null) {
1791
throw new KeyStoreException
1792
("Previous KeyStore instantiation failed",
1793
oldException);
1794
}
1795
PrivilegedExceptionAction<KeyStore> action =
1796
new PrivilegedExceptionAction<KeyStore>() {
1797
public KeyStore run() throws Exception {
1798
if (protection instanceof CallbackHandlerProtection == false) {
1799
return run0();
1800
}
1801
// when using a CallbackHandler,
1802
// reprompt if the password is wrong
1803
int tries = 0;
1804
while (true) {
1805
tries++;
1806
try {
1807
return run0();
1808
} catch (IOException e) {
1809
if ((tries < MAX_CALLBACK_TRIES)
1810
&& (e.getCause() instanceof UnrecoverableKeyException)) {
1811
continue;
1812
}
1813
throw e;
1814
}
1815
}
1816
}
1817
public KeyStore run0() throws Exception {
1818
KeyStore ks;
1819
if (provider == null) {
1820
ks = KeyStore.getInstance(type);
1821
} else {
1822
ks = KeyStore.getInstance(type, provider);
1823
}
1824
InputStream in = null;
1825
char[] password = null;
1826
try {
1827
in = new FileInputStream(file);
1828
if (protection instanceof PasswordProtection) {
1829
password =
1830
((PasswordProtection)protection).getPassword();
1831
keyProtection = protection;
1832
} else {
1833
CallbackHandler handler =
1834
((CallbackHandlerProtection)protection)
1835
.getCallbackHandler();
1836
PasswordCallback callback = new PasswordCallback
1837
("Password for keystore " + file.getName(),
1838
false);
1839
handler.handle(new Callback[] {callback});
1840
password = callback.getPassword();
1841
if (password == null) {
1842
throw new KeyStoreException("No password" +
1843
" provided");
1844
}
1845
callback.clearPassword();
1846
keyProtection = new PasswordProtection(password);
1847
}
1848
ks.load(in, password);
1849
return ks;
1850
} finally {
1851
if (in != null) {
1852
in.close();
1853
}
1854
}
1855
}
1856
};
1857
try {
1858
keyStore = AccessController.doPrivileged(action, context);
1859
return keyStore;
1860
} catch (PrivilegedActionException e) {
1861
oldException = e.getCause();
1862
throw new KeyStoreException
1863
("KeyStore instantiation failed", oldException);
1864
}
1865
}
1866
1867
public synchronized ProtectionParameter
1868
getProtectionParameter(String alias) {
1869
if (alias == null) {
1870
throw new NullPointerException();
1871
}
1872
if (keyStore == null) {
1873
throw new IllegalStateException
1874
("getKeyStore() must be called first");
1875
}
1876
return keyProtection;
1877
}
1878
}
1879
1880
/**
1881
* Returns a new Builder object.
1882
*
1883
* <p>Each call to the {@link #getKeyStore} method on the returned
1884
* builder will return a new KeyStore object of type {@code type}.
1885
* Its {@link KeyStore#load(KeyStore.LoadStoreParameter) load()}
1886
* method is invoked using a
1887
* {@code LoadStoreParameter} that encapsulates
1888
* {@code protection}.
1889
*
1890
* <p>The KeyStore is instantiated from {@code provider} if
1891
* non-null. Otherwise, all installed providers are searched.
1892
*
1893
* <p>Calls to {@link #getProtectionParameter getProtectionParameter()}
1894
* will return {@code protection}.
1895
*
1896
* <p><em>Note</em> that the {@link #getKeyStore} method is executed
1897
* within the {@link AccessControlContext} of the code invoking this
1898
* method.
1899
*
1900
* @return a new Builder object
1901
* @param type the type of KeyStore to be constructed
1902
* @param provider the provider from which the KeyStore is to
1903
* be instantiated (or null)
1904
* @param protection the ProtectionParameter securing the Keystore
1905
* @throws NullPointerException if type or protection is null
1906
*/
1907
public static Builder newInstance(final String type,
1908
final Provider provider, final ProtectionParameter protection) {
1909
if ((type == null) || (protection == null)) {
1910
throw new NullPointerException();
1911
}
1912
final AccessControlContext context = AccessController.getContext();
1913
return new Builder() {
1914
private volatile boolean getCalled;
1915
private IOException oldException;
1916
1917
private final PrivilegedExceptionAction<KeyStore> action
1918
= new PrivilegedExceptionAction<KeyStore>() {
1919
1920
public KeyStore run() throws Exception {
1921
KeyStore ks;
1922
if (provider == null) {
1923
ks = KeyStore.getInstance(type);
1924
} else {
1925
ks = KeyStore.getInstance(type, provider);
1926
}
1927
LoadStoreParameter param = new SimpleLoadStoreParameter(protection);
1928
if (protection instanceof CallbackHandlerProtection == false) {
1929
ks.load(param);
1930
} else {
1931
// when using a CallbackHandler,
1932
// reprompt if the password is wrong
1933
int tries = 0;
1934
while (true) {
1935
tries++;
1936
try {
1937
ks.load(param);
1938
break;
1939
} catch (IOException e) {
1940
if (e.getCause() instanceof UnrecoverableKeyException) {
1941
if (tries < MAX_CALLBACK_TRIES) {
1942
continue;
1943
} else {
1944
oldException = e;
1945
}
1946
}
1947
throw e;
1948
}
1949
}
1950
}
1951
getCalled = true;
1952
return ks;
1953
}
1954
};
1955
1956
public synchronized KeyStore getKeyStore()
1957
throws KeyStoreException {
1958
if (oldException != null) {
1959
throw new KeyStoreException
1960
("Previous KeyStore instantiation failed",
1961
oldException);
1962
}
1963
try {
1964
return AccessController.doPrivileged(action, context);
1965
} catch (PrivilegedActionException e) {
1966
Throwable cause = e.getCause();
1967
throw new KeyStoreException
1968
("KeyStore instantiation failed", cause);
1969
}
1970
}
1971
1972
public ProtectionParameter getProtectionParameter(String alias)
1973
{
1974
if (alias == null) {
1975
throw new NullPointerException();
1976
}
1977
if (getCalled == false) {
1978
throw new IllegalStateException
1979
("getKeyStore() must be called first");
1980
}
1981
return protection;
1982
}
1983
};
1984
}
1985
1986
}
1987
1988
static class SimpleLoadStoreParameter implements LoadStoreParameter {
1989
1990
private final ProtectionParameter protection;
1991
1992
SimpleLoadStoreParameter(ProtectionParameter protection) {
1993
this.protection = protection;
1994
}
1995
1996
public ProtectionParameter getProtectionParameter() {
1997
return protection;
1998
}
1999
}
2000
2001
}
2002
2003