Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/sun/security/mscapi/CKeyStore.java
32288 views
1
/*
2
* Copyright (c) 2005, 2020, 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 sun.security.mscapi;
27
28
import java.io.ByteArrayInputStream;
29
import java.io.IOException;
30
import java.io.InputStream;
31
import java.io.OutputStream;
32
import java.security.AccessController;
33
import java.security.InvalidKeyException;
34
import java.security.Key;
35
import java.security.KeyStoreSpi;
36
import java.security.KeyStoreException;
37
import java.security.PrivilegedAction;
38
import java.security.UnrecoverableKeyException;
39
import java.security.NoSuchAlgorithmException;
40
import java.security.SecurityPermission;
41
import java.security.cert.X509Certificate;
42
import java.security.cert.Certificate;
43
import java.security.cert.CertificateException;
44
import java.security.cert.CertificateFactory;
45
import java.security.interfaces.RSAPrivateCrtKey;
46
import java.util.*;
47
48
import sun.security.util.Debug;
49
50
/**
51
* Implementation of key store for Windows using the Microsoft Crypto API.
52
*
53
* @since 1.6
54
*/
55
abstract class CKeyStore extends KeyStoreSpi {
56
57
public static final class MY extends CKeyStore {
58
public MY() {
59
super("MY");
60
}
61
}
62
63
public static final class ROOT extends CKeyStore {
64
public ROOT() {
65
super("ROOT");
66
}
67
}
68
69
class KeyEntry {
70
private CKey privateKey;
71
private X509Certificate[] certChain;
72
private String alias;
73
74
KeyEntry(CKey key, X509Certificate[] chain) {
75
this(null, key, chain);
76
}
77
78
KeyEntry(String alias, CKey key, X509Certificate[] chain) {
79
this.privateKey = key;
80
this.certChain = chain;
81
/*
82
* The default alias for both entry types is derived from a
83
* hash value intrinsic to the first certificate in the chain.
84
*/
85
if (alias == null) {
86
this.alias = Integer.toString(chain[0].hashCode());
87
} else {
88
this.alias = alias;
89
}
90
}
91
92
/**
93
* Gets the alias for the keystore entry.
94
*/
95
String getAlias() {
96
return alias;
97
}
98
99
/**
100
* Sets the alias for the keystore entry.
101
*/
102
void setAlias(String alias) {
103
// TODO - set friendly name prop in cert store
104
this.alias = alias;
105
}
106
107
/**
108
* Gets the private key for the keystore entry.
109
*/
110
CKey getPrivateKey() {
111
return privateKey;
112
}
113
114
/**
115
* Sets the private key for the keystore entry.
116
*/
117
void setRSAPrivateKey(Key k)
118
throws InvalidKeyException, KeyStoreException {
119
RSAPrivateCrtKey key = (RSAPrivateCrtKey) k;
120
byte[] modulusBytes = key.getModulus().toByteArray();
121
122
// Adjust key length due to sign bit
123
int keyBitLength = (modulusBytes[0] == 0)
124
? (modulusBytes.length - 1) * 8
125
: modulusBytes.length * 8;
126
127
byte[] keyBlob = generateRSAPrivateKeyBlob(
128
keyBitLength,
129
modulusBytes,
130
key.getPublicExponent().toByteArray(),
131
key.getPrivateExponent().toByteArray(),
132
key.getPrimeP().toByteArray(),
133
key.getPrimeQ().toByteArray(),
134
key.getPrimeExponentP().toByteArray(),
135
key.getPrimeExponentQ().toByteArray(),
136
key.getCrtCoefficient().toByteArray());
137
138
privateKey = storePrivateKey("RSA", Objects.requireNonNull(keyBlob),
139
"{" + UUID.randomUUID().toString() + "}", keyBitLength);
140
}
141
142
/**
143
* Gets the certificate chain for the keystore entry.
144
*/
145
X509Certificate[] getCertificateChain() {
146
return certChain;
147
}
148
149
/**
150
* Sets the certificate chain for the keystore entry.
151
*/
152
void setCertificateChain(X509Certificate[] chain)
153
throws CertificateException, KeyStoreException {
154
for (int i = 0; i < chain.length; i++) {
155
byte[] encoding = chain[i].getEncoded();
156
if (i == 0 && privateKey != null) {
157
storeCertificate(getName(), alias, encoding,
158
encoding.length, privateKey.getHCryptProvider(),
159
privateKey.getHCryptKey());
160
161
} else {
162
storeCertificate(getName(), alias, encoding,
163
encoding.length, 0L, 0L); // no private key to attach
164
}
165
}
166
certChain = chain;
167
}
168
}
169
170
/*
171
* An X.509 certificate factory.
172
* Used to create an X.509 certificate from its DER-encoding.
173
*/
174
private CertificateFactory certificateFactory = null;
175
176
/*
177
* Compatibility mode: for applications that assume keystores are
178
* stream-based this mode tolerates (but ignores) a non-null stream
179
* or password parameter when passed to the load or store methods.
180
* The mode is enabled by default.
181
*/
182
private static final String KEYSTORE_COMPATIBILITY_MODE_PROP =
183
"sun.security.mscapi.keyStoreCompatibilityMode";
184
private final boolean keyStoreCompatibilityMode;
185
private static final Debug debug = Debug.getInstance("keystore");
186
187
/*
188
* The keystore entries.
189
* Keys in the map are unique aliases (thus can differ from
190
* KeyEntry.getAlias())
191
*/
192
private Map<String,KeyEntry> entries = new HashMap<>();
193
194
/*
195
* The keystore name.
196
* Case is not significant.
197
*/
198
private final String storeName;
199
200
CKeyStore(String storeName) {
201
// Get the compatibility mode
202
String prop = AccessController.doPrivileged(
203
(PrivilegedAction<String>) () -> System.getProperty(KEYSTORE_COMPATIBILITY_MODE_PROP));
204
205
if ("false".equalsIgnoreCase(prop)) {
206
keyStoreCompatibilityMode = false;
207
} else {
208
keyStoreCompatibilityMode = true;
209
}
210
211
this.storeName = storeName;
212
}
213
214
/**
215
* Returns the key associated with the given alias.
216
* <p>
217
* A compatibility mode is supported for applications that assume
218
* a password must be supplied. It permits (but ignores) a non-null
219
* <code>password</code>. The mode is enabled by default.
220
* Set the
221
* <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
222
* system property to <code>false</code> to disable compatibility mode
223
* and reject a non-null <code>password</code>.
224
*
225
* @param alias the alias name
226
* @param password the password, which should be <code>null</code>
227
*
228
* @return the requested key, or null if the given alias does not exist
229
* or does not identify a <i>key entry</i>.
230
*
231
* @exception NoSuchAlgorithmException if the algorithm for recovering the
232
* key cannot be found,
233
* or if compatibility mode is disabled and <code>password</code> is
234
* non-null.
235
* @exception UnrecoverableKeyException if the key cannot be recovered.
236
*/
237
public java.security.Key engineGetKey(String alias, char[] password)
238
throws NoSuchAlgorithmException, UnrecoverableKeyException {
239
if (alias == null) {
240
return null;
241
}
242
243
if (password != null && !keyStoreCompatibilityMode) {
244
throw new UnrecoverableKeyException("Password must be null");
245
}
246
247
if (engineIsKeyEntry(alias) == false)
248
return null;
249
250
KeyEntry entry = entries.get(alias);
251
return (entry == null)
252
? null
253
: entry.getPrivateKey();
254
}
255
256
/**
257
* Returns the certificate chain associated with the given alias.
258
*
259
* @param alias the alias name
260
*
261
* @return the certificate chain (ordered with the user's certificate first
262
* and the root certificate authority last), or null if the given alias
263
* does not exist or does not contain a certificate chain (i.e., the given
264
* alias identifies either a <i>trusted certificate entry</i> or a
265
* <i>key entry</i> without a certificate chain).
266
*/
267
public Certificate[] engineGetCertificateChain(String alias) {
268
if (alias == null) {
269
return null;
270
}
271
272
KeyEntry entry = entries.get(alias);
273
X509Certificate[] certChain = (entry == null)
274
? null
275
: entry.getCertificateChain();
276
return (certChain == null)
277
? null
278
: certChain.clone();
279
}
280
281
/**
282
* Returns the certificate associated with the given alias.
283
*
284
* <p>If the given alias name identifies a
285
* <i>trusted certificate entry</i>, the certificate associated with that
286
* entry is returned. If the given alias name identifies a
287
* <i>key entry</i>, the first element of the certificate chain of that
288
* entry is returned, or null if that entry does not have a certificate
289
* chain.
290
*
291
* @param alias the alias name
292
*
293
* @return the certificate, or null if the given alias does not exist or
294
* does not contain a certificate.
295
*/
296
public Certificate engineGetCertificate(String alias) {
297
if (alias == null) {
298
return null;
299
}
300
301
KeyEntry entry = entries.get(alias);
302
X509Certificate[] certChain = (entry == null)
303
? null
304
: entry.getCertificateChain();
305
return (certChain == null || certChain.length == 0)
306
? null
307
: certChain[0];
308
}
309
310
/**
311
* Returns the creation date of the entry identified by the given alias.
312
*
313
* @param alias the alias name
314
*
315
* @return the creation date of this entry, or null if the given alias does
316
* not exist
317
*/
318
public Date engineGetCreationDate(String alias) {
319
if (alias == null) {
320
return null;
321
}
322
return new Date();
323
}
324
325
/**
326
* Stores the given private key and associated certificate chain in the
327
* keystore.
328
*
329
* <p>The given java.security.PrivateKey <code>key</code> must
330
* be accompanied by a certificate chain certifying the
331
* corresponding public key.
332
*
333
* <p>If the given alias already exists, the keystore information
334
* associated with it is overridden by the given key and certificate
335
* chain. Otherwise, a new entry is created.
336
*
337
* <p>
338
* A compatibility mode is supported for applications that assume
339
* a password must be supplied. It permits (but ignores) a non-null
340
* <code>password</code>. The mode is enabled by default.
341
* Set the
342
* <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
343
* system property to <code>false</code> to disable compatibility mode
344
* and reject a non-null <code>password</code>.
345
*
346
* @param alias the alias name
347
* @param key the private key to be associated with the alias
348
* @param password the password, which should be <code>null</code>
349
* @param chain the certificate chain for the corresponding public
350
* key (only required if the given key is of type
351
* <code>java.security.PrivateKey</code>).
352
*
353
* @exception KeyStoreException if the given key is not a private key,
354
* cannot be protected, or if compatibility mode is disabled and
355
* <code>password</code> is non-null, or if this operation fails for
356
* some other reason.
357
*/
358
public void engineSetKeyEntry(String alias, java.security.Key key,
359
char[] password, Certificate[] chain) throws KeyStoreException {
360
if (alias == null) {
361
throw new KeyStoreException("alias must not be null");
362
}
363
364
if (password != null && !keyStoreCompatibilityMode) {
365
throw new KeyStoreException("Password must be null");
366
}
367
368
if (key instanceof RSAPrivateCrtKey) {
369
370
KeyEntry entry = entries.get(alias);
371
372
X509Certificate[] xchain;
373
if (chain != null) {
374
if (chain instanceof X509Certificate[]) {
375
xchain = (X509Certificate[]) chain;
376
} else {
377
xchain = new X509Certificate[chain.length];
378
System.arraycopy(chain, 0, xchain, 0, chain.length);
379
}
380
} else {
381
xchain = null;
382
}
383
384
if (entry == null) {
385
entry =
386
//TODO new KeyEntry(alias, key, (X509Certificate[]) chain);
387
new KeyEntry(alias, null, xchain);
388
storeWithUniqueAlias(alias, entry);
389
}
390
391
entry.setAlias(alias);
392
393
try {
394
entry.setRSAPrivateKey(key);
395
entry.setCertificateChain(xchain);
396
397
} catch (CertificateException ce) {
398
throw new KeyStoreException(ce);
399
400
} catch (InvalidKeyException ike) {
401
throw new KeyStoreException(ike);
402
}
403
404
} else {
405
throw new UnsupportedOperationException(
406
"Cannot assign the key to the given alias.");
407
}
408
}
409
410
/**
411
* Assigns the given key (that has already been protected) to the given
412
* alias.
413
*
414
* <p>If the protected key is of type
415
* <code>java.security.PrivateKey</code>, it must be accompanied by a
416
* certificate chain certifying the corresponding public key. If the
417
* underlying keystore implementation is of type <code>jks</code>,
418
* <code>key</code> must be encoded as an
419
* <code>EncryptedPrivateKeyInfo</code> as defined in the PKCS #8 standard.
420
*
421
* <p>If the given alias already exists, the keystore information
422
* associated with it is overridden by the given key (and possibly
423
* certificate chain).
424
*
425
* @param alias the alias name
426
* @param key the key (in protected format) to be associated with the alias
427
* @param chain the certificate chain for the corresponding public
428
* key (only useful if the protected key is of type
429
* <code>java.security.PrivateKey</code>).
430
*
431
* @exception KeyStoreException if this operation fails.
432
*/
433
public void engineSetKeyEntry(String alias, byte[] key,
434
Certificate[] chain)
435
throws KeyStoreException {
436
throw new UnsupportedOperationException(
437
"Cannot assign the encoded key to the given alias.");
438
}
439
440
/**
441
* Assigns the given certificate to the given alias.
442
*
443
* <p>If the given alias already exists in this keystore and identifies a
444
* <i>trusted certificate entry</i>, the certificate associated with it is
445
* overridden by the given certificate.
446
*
447
* @param alias the alias name
448
* @param cert the certificate
449
*
450
* @exception KeyStoreException if the given alias already exists and does
451
* not identify a <i>trusted certificate entry</i>, or this operation
452
* fails for some other reason.
453
*/
454
public void engineSetCertificateEntry(String alias, Certificate cert)
455
throws KeyStoreException {
456
if (alias == null) {
457
throw new KeyStoreException("alias must not be null");
458
}
459
460
if (cert instanceof X509Certificate) {
461
462
// TODO - build CryptoAPI chain?
463
X509Certificate[] chain =
464
new X509Certificate[]{ (X509Certificate) cert };
465
KeyEntry entry = entries.get(alias);
466
467
if (entry == null) {
468
entry =
469
new KeyEntry(alias, null, chain);
470
storeWithUniqueAlias(alias, entry);
471
}
472
473
if (entry.getPrivateKey() == null) { // trusted-cert entry
474
entry.setAlias(alias);
475
476
try {
477
entry.setCertificateChain(chain);
478
479
} catch (CertificateException ce) {
480
throw new KeyStoreException(ce);
481
}
482
}
483
484
} else {
485
throw new UnsupportedOperationException(
486
"Cannot assign the certificate to the given alias.");
487
}
488
}
489
490
/**
491
* Deletes the entry identified by the given alias from this keystore.
492
*
493
* @param alias the alias name
494
*
495
* @exception KeyStoreException if the entry cannot be removed.
496
*/
497
public void engineDeleteEntry(String alias) throws KeyStoreException {
498
if (alias == null) {
499
throw new KeyStoreException("alias must not be null");
500
}
501
502
KeyEntry entry = entries.remove(alias);
503
if (entry != null) {
504
// Get end-entity certificate and remove from system cert store
505
X509Certificate[] certChain = entry.getCertificateChain();
506
if (certChain != null && certChain.length > 0) {
507
508
try {
509
510
byte[] encoding = certChain[0].getEncoded();
511
removeCertificate(getName(), entry.getAlias(), encoding,
512
encoding.length);
513
514
} catch (CertificateException e) {
515
throw new KeyStoreException("Cannot remove entry: ", e);
516
}
517
}
518
CKey privateKey = entry.getPrivateKey();
519
if (privateKey != null) {
520
destroyKeyContainer(
521
CKey.getContainerName(privateKey.getHCryptProvider()));
522
}
523
}
524
}
525
526
/**
527
* Lists all the alias names of this keystore.
528
*
529
* @return enumeration of the alias names
530
*/
531
public Enumeration<String> engineAliases() {
532
final Iterator<String> iter = entries.keySet().iterator();
533
534
return new Enumeration<String>() {
535
public boolean hasMoreElements() {
536
return iter.hasNext();
537
}
538
539
public String nextElement() {
540
return iter.next();
541
}
542
};
543
}
544
545
/**
546
* Checks if the given alias exists in this keystore.
547
*
548
* @param alias the alias name
549
*
550
* @return true if the alias exists, false otherwise
551
*/
552
public boolean engineContainsAlias(String alias) {
553
return entries.containsKey(alias);
554
}
555
556
/**
557
* Retrieves the number of entries in this keystore.
558
*
559
* @return the number of entries in this keystore
560
*/
561
public int engineSize() {
562
return entries.size();
563
}
564
565
/**
566
* Returns true if the entry identified by the given alias is a
567
* <i>key entry</i>, and false otherwise.
568
*
569
* @return true if the entry identified by the given alias is a
570
* <i>key entry</i>, false otherwise.
571
*/
572
public boolean engineIsKeyEntry(String alias) {
573
574
if (alias == null) {
575
return false;
576
}
577
578
KeyEntry entry = entries.get(alias);
579
return entry != null && entry.getPrivateKey() != null;
580
}
581
582
/**
583
* Returns true if the entry identified by the given alias is a
584
* <i>trusted certificate entry</i>, and false otherwise.
585
*
586
* @return true if the entry identified by the given alias is a
587
* <i>trusted certificate entry</i>, false otherwise.
588
*/
589
public boolean engineIsCertificateEntry(String alias) {
590
591
if (alias == null) {
592
return false;
593
}
594
595
KeyEntry entry = entries.get(alias);
596
return entry != null && entry.getPrivateKey() == null;
597
}
598
599
/**
600
* Returns the (alias) name of the first keystore entry whose certificate
601
* matches the given certificate.
602
*
603
* <p>This method attempts to match the given certificate with each
604
* keystore entry. If the entry being considered
605
* is a <i>trusted certificate entry</i>, the given certificate is
606
* compared to that entry's certificate. If the entry being considered is
607
* a <i>key entry</i>, the given certificate is compared to the first
608
* element of that entry's certificate chain (if a chain exists).
609
*
610
* @param cert the certificate to match with.
611
*
612
* @return the (alias) name of the first entry with matching certificate,
613
* or null if no such entry exists in this keystore.
614
*/
615
public String engineGetCertificateAlias(Certificate cert) {
616
617
for (Map.Entry<String,KeyEntry> mapEntry : entries.entrySet()) {
618
KeyEntry entry = mapEntry.getValue();
619
if (entry.certChain != null &&
620
entry.certChain.length > 0 &&
621
entry.certChain[0].equals(cert)) {
622
return entry.getAlias();
623
}
624
}
625
626
return null;
627
}
628
629
/**
630
* engineStore is currently a no-op.
631
* Entries are stored during engineSetEntry.
632
*
633
* A compatibility mode is supported for applications that assume
634
* keystores are stream-based. It permits (but ignores) a non-null
635
* <code>stream</code> or <code>password</code>.
636
* The mode is enabled by default.
637
* Set the
638
* <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
639
* system property to <code>false</code> to disable compatibility mode
640
* and reject a non-null <code>stream</code> or <code>password</code>.
641
*
642
* @param stream the output stream, which should be <code>null</code>
643
* @param password the password, which should be <code>null</code>
644
*
645
* @exception IOException if compatibility mode is disabled and either
646
* parameter is non-null.
647
*/
648
public void engineStore(OutputStream stream, char[] password)
649
throws IOException, NoSuchAlgorithmException, CertificateException {
650
if (stream != null && !keyStoreCompatibilityMode) {
651
throw new IOException("Keystore output stream must be null");
652
}
653
654
if (password != null && !keyStoreCompatibilityMode) {
655
throw new IOException("Keystore password must be null");
656
}
657
}
658
659
/**
660
* Loads the keystore.
661
*
662
* A compatibility mode is supported for applications that assume
663
* keystores are stream-based. It permits (but ignores) a non-null
664
* <code>stream</code> or <code>password</code>.
665
* The mode is enabled by default.
666
* Set the
667
* <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
668
* system property to <code>false</code> to disable compatibility mode
669
* and reject a non-null <code>stream</code> or <code>password</code>.
670
*
671
* @param stream the input stream, which should be <code>null</code>.
672
* @param password the password, which should be <code>null</code>.
673
*
674
* @exception IOException if there is an I/O or format problem with the
675
* keystore data. Or if compatibility mode is disabled and either
676
* parameter is non-null.
677
* @exception NoSuchAlgorithmException if the algorithm used to check
678
* the integrity of the keystore cannot be found
679
* @exception CertificateException if any of the certificates in the
680
* keystore could not be loaded
681
* @exception SecurityException if the security check for
682
* <code>SecurityPermission("authProvider.<i>name</i>")</code> does not
683
* pass, where <i>name</i> is the value returned by
684
* this provider's <code>getName</code> method.
685
*/
686
public void engineLoad(InputStream stream, char[] password)
687
throws IOException, NoSuchAlgorithmException, CertificateException {
688
if (stream != null && !keyStoreCompatibilityMode) {
689
throw new IOException("Keystore input stream must be null");
690
}
691
692
if (password != null && !keyStoreCompatibilityMode) {
693
throw new IOException("Keystore password must be null");
694
}
695
696
/*
697
* Use the same security check as AuthProvider.login
698
*/
699
SecurityManager sm = System.getSecurityManager();
700
if (sm != null) {
701
sm.checkPermission(new SecurityPermission(
702
"authProvider.SunMSCAPI"));
703
}
704
705
// Clear all key entries
706
entries.clear();
707
708
try {
709
710
// Load keys and/or certificate chains
711
loadKeysOrCertificateChains(getName());
712
713
} catch (KeyStoreException e) {
714
throw new IOException(e);
715
}
716
717
if (debug != null) {
718
debug.println("MSCAPI keystore load: entry count: " +
719
entries.size());
720
}
721
}
722
723
/**
724
* Stores the given entry into the map, making sure
725
* the alias, used as the key is unique.
726
* If the same alias already exists, it tries to append
727
* a suffix (1), (2), etc to it until it finds a unique
728
* value.
729
*/
730
private void storeWithUniqueAlias(String alias, KeyEntry entry) {
731
String uniqAlias = alias;
732
int uniqNum = 1;
733
734
while (true) {
735
if (entries.putIfAbsent(uniqAlias, entry) == null) {
736
break;
737
}
738
uniqAlias = alias + " (" + (uniqNum++) + ")";
739
}
740
}
741
742
743
/**
744
* Generates a certificate chain from the collection of
745
* certificates and stores the result into a key entry.
746
* <p>
747
* This method is called by native codes in security.cpp.
748
*/
749
private void generateCertificateChain(String alias,
750
Collection<? extends Certificate> certCollection) {
751
try {
752
X509Certificate[] certChain =
753
new X509Certificate[certCollection.size()];
754
755
int i = 0;
756
for (Iterator<? extends Certificate> iter =
757
certCollection.iterator(); iter.hasNext(); i++) {
758
certChain[i] = (X509Certificate) iter.next();
759
}
760
761
storeWithUniqueAlias(alias,
762
new KeyEntry(alias, null, certChain));
763
} catch (Throwable e) {
764
// Ignore the exception and skip this entry
765
// TODO - throw CertificateException?
766
}
767
}
768
769
/**
770
* Generates key and certificate chain from the private key handle,
771
* collection of certificates and stores the result into key entries.
772
* <p>
773
* This method is called by native codes in security.cpp.
774
*/
775
private void generateKeyAndCertificateChain(boolean isRSA, String alias,
776
long hCryptProv, long hCryptKey, int keyLength,
777
Collection<? extends Certificate> certCollection) {
778
try {
779
X509Certificate[] certChain =
780
new X509Certificate[certCollection.size()];
781
782
int i = 0;
783
for (Iterator<? extends Certificate> iter =
784
certCollection.iterator(); iter.hasNext(); i++) {
785
certChain[i] = (X509Certificate) iter.next();
786
}
787
storeWithUniqueAlias(alias, new KeyEntry(alias,
788
CPrivateKey.of(isRSA ? "RSA" : "EC", hCryptProv, hCryptKey, keyLength),
789
certChain));
790
} catch (Throwable e) {
791
// Ignore the exception and skip this entry
792
// TODO - throw CertificateException?
793
}
794
}
795
796
/**
797
* Generates certificates from byte data and stores into cert collection.
798
* <p>
799
* This method is called by native codes in security.cpp.
800
*
801
* @param data Byte data.
802
* @param certCollection Collection of certificates.
803
*/
804
private void generateCertificate(byte[] data,
805
Collection<Certificate> certCollection) {
806
try {
807
ByteArrayInputStream bis = new ByteArrayInputStream(data);
808
809
// Obtain certificate factory
810
if (certificateFactory == null) {
811
certificateFactory = CertificateFactory.getInstance("X.509", "SUN");
812
}
813
814
// Generate certificate
815
Collection<? extends Certificate> c =
816
certificateFactory.generateCertificates(bis);
817
certCollection.addAll(c);
818
} catch (CertificateException e) {
819
// Ignore the exception and skip this certificate
820
// TODO - throw CertificateException?
821
} catch (Throwable te) {
822
// Ignore the exception and skip this certificate
823
// TODO - throw CertificateException?
824
}
825
}
826
827
/**
828
* Returns the name of the keystore.
829
*/
830
private String getName() {
831
return storeName;
832
}
833
834
/**
835
* Load keys and/or certificates from keystore into Collection.
836
*
837
* @param name Name of keystore.
838
*/
839
private native void loadKeysOrCertificateChains(String name)
840
throws KeyStoreException;
841
842
/**
843
* Stores a DER-encoded certificate into the certificate store
844
*
845
* @param name Name of the keystore.
846
* @param alias Name of the certificate.
847
* @param encoding DER-encoded certificate.
848
*/
849
private native void storeCertificate(String name, String alias,
850
byte[] encoding, int encodingLength, long hCryptProvider,
851
long hCryptKey) throws CertificateException, KeyStoreException;
852
853
/**
854
* Removes the certificate from the certificate store
855
*
856
* @param name Name of the keystore.
857
* @param alias Name of the certificate.
858
* @param encoding DER-encoded certificate.
859
*/
860
private native void removeCertificate(String name, String alias,
861
byte[] encoding, int encodingLength)
862
throws CertificateException, KeyStoreException;
863
864
/**
865
* Destroys the key container.
866
*
867
* @param keyContainerName The name of the key container.
868
*/
869
private native void destroyKeyContainer(String keyContainerName)
870
throws KeyStoreException;
871
872
/**
873
* Generates a private-key BLOB from a key's components.
874
*/
875
private native byte[] generateRSAPrivateKeyBlob(
876
int keyBitLength,
877
byte[] modulus,
878
byte[] publicExponent,
879
byte[] privateExponent,
880
byte[] primeP,
881
byte[] primeQ,
882
byte[] exponentP,
883
byte[] exponentQ,
884
byte[] crtCoefficient) throws InvalidKeyException;
885
886
private native CPrivateKey storePrivateKey(String alg, byte[] keyBlob,
887
String keyContainerName, int keySize) throws KeyStoreException;
888
}
889
890