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