/*
 * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.security.mscapi;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.AccessController;
import java.security.InvalidKeyException;
import java.security.KeyStoreSpi;
import java.security.KeyStoreException;
import java.security.UnrecoverableKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecurityPermission;
import java.security.cert.X509Certificate;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.interfaces.RSAPrivateCrtKey;
import java.util.*;

import sun.security.action.GetPropertyAction;

Implementation of key store for Windows using the Microsoft Crypto API.
Since:1.6
/** * Implementation of key store for Windows using the Microsoft Crypto API. * * @since 1.6 */
abstract class KeyStore extends KeyStoreSpi { public static final class MY extends KeyStore { public MY() { super("MY"); } } public static final class ROOT extends KeyStore { public ROOT() { super("ROOT"); } } class KeyEntry { private Key privateKey; private X509Certificate certChain[]; private String alias; KeyEntry(Key key, X509Certificate[] chain) { this(null, key, chain); } KeyEntry(String alias, Key key, X509Certificate[] chain) { this.privateKey = key; this.certChain = chain; /* * The default alias for both entry types is derived from a * hash value intrinsic to the first certificate in the chain. */ if (alias == null) { this.alias = Integer.toString(chain[0].hashCode()); } else { this.alias = alias; } }
Gets the alias for the keystore entry.
/** * Gets the alias for the keystore entry. */
String getAlias() { return alias; }
Sets the alias for the keystore entry.
/** * Sets the alias for the keystore entry. */
void setAlias(String alias) { // TODO - set friendly name prop in cert store this.alias = alias; }
Gets the private key for the keystore entry.
/** * Gets the private key for the keystore entry. */
Key getPrivateKey() { return privateKey; }
Sets the private key for the keystore entry.
/** * Sets the private key for the keystore entry. */
void setPrivateKey(RSAPrivateCrtKey key) throws InvalidKeyException, KeyStoreException { byte[] modulusBytes = key.getModulus().toByteArray(); // Adjust key length due to sign bit int keyBitLength = (modulusBytes[0] == 0) ? (modulusBytes.length - 1) * 8 : modulusBytes.length * 8; byte[] keyBlob = generatePrivateKeyBlob( keyBitLength, modulusBytes, key.getPublicExponent().toByteArray(), key.getPrivateExponent().toByteArray(), key.getPrimeP().toByteArray(), key.getPrimeQ().toByteArray(), key.getPrimeExponentP().toByteArray(), key.getPrimeExponentQ().toByteArray(), key.getCrtCoefficient().toByteArray()); privateKey = storePrivateKey(Objects.requireNonNull(keyBlob), "{" + UUID.randomUUID().toString() + "}", keyBitLength); }
Gets the certificate chain for the keystore entry.
/** * Gets the certificate chain for the keystore entry. */
X509Certificate[] getCertificateChain() { return certChain; }
Sets the certificate chain for the keystore entry.
/** * Sets the certificate chain for the keystore entry. */
void setCertificateChain(X509Certificate[] chain) throws CertificateException, KeyStoreException { for (int i = 0; i < chain.length; i++) { byte[] encoding = chain[i].getEncoded(); if (i == 0 && privateKey != null) { storeCertificate(getName(), alias, encoding, encoding.length, privateKey.getHCryptProvider(), privateKey.getHCryptKey()); } else { storeCertificate(getName(), alias, encoding, encoding.length, 0L, 0L); // no private key to attach } } certChain = chain; } }; /* * An X.509 certificate factory. * Used to create an X.509 certificate from its DER-encoding. */ private CertificateFactory certificateFactory = null; /* * Compatibility mode: for applications that assume keystores are * stream-based this mode tolerates (but ignores) a non-null stream * or password parameter when passed to the load or store methods. * The mode is enabled by default. */ private static final String KEYSTORE_COMPATIBILITY_MODE_PROP = "sun.security.mscapi.keyStoreCompatibilityMode"; private final boolean keyStoreCompatibilityMode; /* * The keystore entries. * Keys in the map are unique aliases (thus can differ from * KeyEntry.getAlias()) */ private Map<String,KeyEntry> entries = new HashMap<>(); /* * The keystore name. * Case is not significant. */ private final String storeName; KeyStore(String storeName) { // Get the compatibility mode String prop = AccessController.doPrivileged( new GetPropertyAction(KEYSTORE_COMPATIBILITY_MODE_PROP)); if ("false".equalsIgnoreCase(prop)) { keyStoreCompatibilityMode = false; } else { keyStoreCompatibilityMode = true; } this.storeName = storeName; }
Returns the key associated with the given alias.

A compatibility mode is supported for applications that assume a password must be supplied. It permits (but ignores) a non-null password. The mode is enabled by default. Set the sun.security.mscapi.keyStoreCompatibilityMode system property to false to disable compatibility mode and reject a non-null password.

Params:
  • alias – the alias name
  • password – the password, which should be null
Throws:
Returns:the requested key, or null if the given alias does not exist or does not identify a key entry.
/** * Returns the key associated with the given alias. * <p> * A compatibility mode is supported for applications that assume * a password must be supplied. It permits (but ignores) a non-null * <code>password</code>. The mode is enabled by default. * Set the * <code>sun.security.mscapi.keyStoreCompatibilityMode</code> * system property to <code>false</code> to disable compatibility mode * and reject a non-null <code>password</code>. * * @param alias the alias name * @param password the password, which should be <code>null</code> * * @return the requested key, or null if the given alias does not exist * or does not identify a <i>key entry</i>. * * @exception NoSuchAlgorithmException if the algorithm for recovering the * key cannot be found, * or if compatibility mode is disabled and <code>password</code> is * non-null. * @exception UnrecoverableKeyException if the key cannot be recovered. */
public java.security.Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { if (alias == null) { return null; } if (password != null && !keyStoreCompatibilityMode) { throw new UnrecoverableKeyException("Password must be null"); } if (engineIsKeyEntry(alias) == false) return null; KeyEntry entry = entries.get(alias); return (entry == null) ? null : entry.getPrivateKey(); }
Returns the certificate chain associated with the given alias.
Params:
  • alias – the alias name
Returns:the certificate chain (ordered with the user's certificate first and the root certificate authority last), or null if the given alias does not exist or does not contain a certificate chain (i.e., the given alias identifies either a trusted certificate entry or a key entry without a certificate chain).
/** * Returns the certificate chain associated with the given alias. * * @param alias the alias name * * @return the certificate chain (ordered with the user's certificate first * and the root certificate authority last), or null if the given alias * does not exist or does not contain a certificate chain (i.e., the given * alias identifies either a <i>trusted certificate entry</i> or a * <i>key entry</i> without a certificate chain). */
public Certificate[] engineGetCertificateChain(String alias) { if (alias == null) { return null; } KeyEntry entry = entries.get(alias); X509Certificate[] certChain = (entry == null) ? null : entry.getCertificateChain(); return (certChain == null) ? null : certChain.clone(); }
Returns the certificate associated with the given alias.

If the given alias name identifies a trusted certificate entry, the certificate associated with that entry is returned. If the given alias name identifies a key entry, the first element of the certificate chain of that entry is returned, or null if that entry does not have a certificate chain.

Params:
  • alias – the alias name
Returns:the certificate, or null if the given alias does not exist or does not contain a certificate.
/** * Returns the certificate associated with the given alias. * * <p>If the given alias name identifies a * <i>trusted certificate entry</i>, the certificate associated with that * entry is returned. If the given alias name identifies a * <i>key entry</i>, the first element of the certificate chain of that * entry is returned, or null if that entry does not have a certificate * chain. * * @param alias the alias name * * @return the certificate, or null if the given alias does not exist or * does not contain a certificate. */
public Certificate engineGetCertificate(String alias) { if (alias == null) { return null; } KeyEntry entry = entries.get(alias); X509Certificate[] certChain = (entry == null) ? null : entry.getCertificateChain(); return (certChain == null || certChain.length == 0) ? null : certChain[0]; }
Returns the creation date of the entry identified by the given alias.
Params:
  • alias – the alias name
Returns:the creation date of this entry, or null if the given alias does not exist
/** * Returns the creation date of the entry identified by the given alias. * * @param alias the alias name * * @return the creation date of this entry, or null if the given alias does * not exist */
public Date engineGetCreationDate(String alias) { if (alias == null) { return null; } return new Date(); }
Stores the given private key and associated certificate chain in the keystore.

The given java.security.PrivateKey key must be accompanied by a certificate chain certifying the corresponding public key.

If the given alias already exists, the keystore information associated with it is overridden by the given key and certificate chain. Otherwise, a new entry is created.

A compatibility mode is supported for applications that assume a password must be supplied. It permits (but ignores) a non-null password. The mode is enabled by default. Set the sun.security.mscapi.keyStoreCompatibilityMode system property to false to disable compatibility mode and reject a non-null password.

Params:
  • alias – the alias name
  • key – the private key to be associated with the alias
  • password – the password, which should be null
  • chain – the certificate chain for the corresponding public key (only required if the given key is of type java.security.PrivateKey).
Throws:
  • KeyStoreException – if the given key is not a private key, cannot be protected, or if compatibility mode is disabled and password is non-null, or if this operation fails for some other reason.
/** * Stores the given private key and associated certificate chain in the * keystore. * * <p>The given java.security.PrivateKey <code>key</code> must * be accompanied by a certificate chain certifying the * corresponding public key. * * <p>If the given alias already exists, the keystore information * associated with it is overridden by the given key and certificate * chain. Otherwise, a new entry is created. * * <p> * A compatibility mode is supported for applications that assume * a password must be supplied. It permits (but ignores) a non-null * <code>password</code>. The mode is enabled by default. * Set the * <code>sun.security.mscapi.keyStoreCompatibilityMode</code> * system property to <code>false</code> to disable compatibility mode * and reject a non-null <code>password</code>. * * @param alias the alias name * @param key the private key to be associated with the alias * @param password the password, which should be <code>null</code> * @param chain the certificate chain for the corresponding public * key (only required if the given key is of type * <code>java.security.PrivateKey</code>). * * @exception KeyStoreException if the given key is not a private key, * cannot be protected, or if compatibility mode is disabled and * <code>password</code> is non-null, or if this operation fails for * some other reason. */
public void engineSetKeyEntry(String alias, java.security.Key key, char[] password, Certificate[] chain) throws KeyStoreException { if (alias == null) { throw new KeyStoreException("alias must not be null"); } if (password != null && !keyStoreCompatibilityMode) { throw new KeyStoreException("Password must be null"); } if (key instanceof RSAPrivateCrtKey) { KeyEntry entry = entries.get(alias); X509Certificate[] xchain; if (chain != null) { if (chain instanceof X509Certificate[]) { xchain = (X509Certificate[]) chain; } else { xchain = new X509Certificate[chain.length]; System.arraycopy(chain, 0, xchain, 0, chain.length); } } else { xchain = null; } if (entry == null) { entry = //TODO new KeyEntry(alias, key, (X509Certificate[]) chain); new KeyEntry(alias, null, xchain); storeWithUniqueAlias(alias, entry); } entry.setAlias(alias); try { entry.setPrivateKey((RSAPrivateCrtKey) key); entry.setCertificateChain(xchain); } catch (CertificateException ce) { throw new KeyStoreException(ce); } catch (InvalidKeyException ike) { throw new KeyStoreException(ike); } } else { throw new UnsupportedOperationException( "Cannot assign the key to the given alias."); } }
Assigns the given key (that has already been protected) to the given alias.

If the protected key is of type java.security.PrivateKey, it must be accompanied by a certificate chain certifying the corresponding public key. If the underlying keystore implementation is of type jks, key must be encoded as an EncryptedPrivateKeyInfo as defined in the PKCS #8 standard.

If the given alias already exists, the keystore information associated with it is overridden by the given key (and possibly certificate chain).

Params:
  • alias – the alias name
  • key – the key (in protected format) to be associated with the alias
  • chain – the certificate chain for the corresponding public key (only useful if the protected key is of type java.security.PrivateKey).
Throws:
/** * Assigns the given key (that has already been protected) to the given * alias. * * <p>If the protected key is of type * <code>java.security.PrivateKey</code>, it must be accompanied by a * certificate chain certifying the corresponding public key. If the * underlying keystore implementation is of type <code>jks</code>, * <code>key</code> must be encoded as an * <code>EncryptedPrivateKeyInfo</code> as defined in the PKCS #8 standard. * * <p>If the given alias already exists, the keystore information * associated with it is overridden by the given key (and possibly * certificate chain). * * @param alias the alias name * @param key the key (in protected format) to be associated with the alias * @param chain the certificate chain for the corresponding public * key (only useful if the protected key is of type * <code>java.security.PrivateKey</code>). * * @exception KeyStoreException if this operation fails. */
public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException { throw new UnsupportedOperationException( "Cannot assign the encoded key to the given alias."); }
Assigns the given certificate to the given alias.

If the given alias already exists in this keystore and identifies a trusted certificate entry, the certificate associated with it is overridden by the given certificate.

Params:
  • alias – the alias name
  • cert – the certificate
Throws:
  • KeyStoreException – if the given alias already exists and does not identify a trusted certificate entry, or this operation fails for some other reason.
/** * Assigns the given certificate to the given alias. * * <p>If the given alias already exists in this keystore and identifies a * <i>trusted certificate entry</i>, the certificate associated with it is * overridden by the given certificate. * * @param alias the alias name * @param cert the certificate * * @exception KeyStoreException if the given alias already exists and does * not identify a <i>trusted certificate entry</i>, or this operation * fails for some other reason. */
public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException { if (alias == null) { throw new KeyStoreException("alias must not be null"); } if (cert instanceof X509Certificate) { // TODO - build CryptoAPI chain? X509Certificate[] chain = new X509Certificate[]{ (X509Certificate) cert }; KeyEntry entry = entries.get(alias); if (entry == null) { entry = new KeyEntry(alias, null, chain); storeWithUniqueAlias(alias, entry); } if (entry.getPrivateKey() == null) { // trusted-cert entry entry.setAlias(alias); try { entry.setCertificateChain(chain); } catch (CertificateException ce) { throw new KeyStoreException(ce); } } } else { throw new UnsupportedOperationException( "Cannot assign the certificate to the given alias."); } }
Deletes the entry identified by the given alias from this keystore.
Params:
  • alias – the alias name
Throws:
/** * Deletes the entry identified by the given alias from this keystore. * * @param alias the alias name * * @exception KeyStoreException if the entry cannot be removed. */
public void engineDeleteEntry(String alias) throws KeyStoreException { if (alias == null) { throw new KeyStoreException("alias must not be null"); } KeyEntry entry = entries.remove(alias); if (entry != null) { // Get end-entity certificate and remove from system cert store X509Certificate[] certChain = entry.getCertificateChain(); if (certChain != null) { try { byte[] encoding = certChain[0].getEncoded(); removeCertificate(getName(), entry.getAlias(), encoding, encoding.length); } catch (CertificateException e) { throw new KeyStoreException("Cannot remove entry: ", e); } } Key privateKey = entry.getPrivateKey(); if (privateKey != null) { destroyKeyContainer( Key.getContainerName(privateKey.getHCryptProvider())); } } }
Lists all the alias names of this keystore.
Returns:enumeration of the alias names
/** * Lists all the alias names of this keystore. * * @return enumeration of the alias names */
public Enumeration<String> engineAliases() { final Iterator<String> iter = entries.keySet().iterator(); return new Enumeration<String>() { public boolean hasMoreElements() { return iter.hasNext(); } public String nextElement() { return iter.next(); } }; }
Checks if the given alias exists in this keystore.
Params:
  • alias – the alias name
Returns:true if the alias exists, false otherwise
/** * Checks if the given alias exists in this keystore. * * @param alias the alias name * * @return true if the alias exists, false otherwise */
public boolean engineContainsAlias(String alias) { return entries.containsKey(alias); }
Retrieves the number of entries in this keystore.
Returns:the number of entries in this keystore
/** * Retrieves the number of entries in this keystore. * * @return the number of entries in this keystore */
public int engineSize() { return entries.size(); }
Returns true if the entry identified by the given alias is a key entry, and false otherwise.
Returns:true if the entry identified by the given alias is a key entry, false otherwise.
/** * Returns true if the entry identified by the given alias is a * <i>key entry</i>, and false otherwise. * * @return true if the entry identified by the given alias is a * <i>key entry</i>, false otherwise. */
public boolean engineIsKeyEntry(String alias) { if (alias == null) { return false; } KeyEntry entry = entries.get(alias); return entry != null && entry.getPrivateKey() != null; }
Returns true if the entry identified by the given alias is a trusted certificate entry, and false otherwise.
Returns:true if the entry identified by the given alias is a trusted certificate entry, false otherwise.
/** * Returns true if the entry identified by the given alias is a * <i>trusted certificate entry</i>, and false otherwise. * * @return true if the entry identified by the given alias is a * <i>trusted certificate entry</i>, false otherwise. */
public boolean engineIsCertificateEntry(String alias) { if (alias == null) { return false; } KeyEntry entry = entries.get(alias); return entry != null && entry.getPrivateKey() == null; }
Returns the (alias) name of the first keystore entry whose certificate matches the given certificate.

This method attempts to match the given certificate with each keystore entry. If the entry being considered is a trusted certificate entry, the given certificate is compared to that entry's certificate. If the entry being considered is a key entry, the given certificate is compared to the first element of that entry's certificate chain (if a chain exists).

Params:
  • cert – the certificate to match with.
Returns:the (alias) name of the first entry with matching certificate, or null if no such entry exists in this keystore.
/** * Returns the (alias) name of the first keystore entry whose certificate * matches the given certificate. * * <p>This method attempts to match the given certificate with each * keystore entry. If the entry being considered * is a <i>trusted certificate entry</i>, the given certificate is * compared to that entry's certificate. If the entry being considered is * a <i>key entry</i>, the given certificate is compared to the first * element of that entry's certificate chain (if a chain exists). * * @param cert the certificate to match with. * * @return the (alias) name of the first entry with matching certificate, * or null if no such entry exists in this keystore. */
public String engineGetCertificateAlias(Certificate cert) { for (Map.Entry<String,KeyEntry> mapEntry : entries.entrySet()) { KeyEntry entry = mapEntry.getValue(); if (entry.certChain != null && entry.certChain[0].equals(cert)) { return entry.getAlias(); } } return null; }
engineStore is currently a no-op. Entries are stored during engineSetEntry. A compatibility mode is supported for applications that assume keystores are stream-based. It permits (but ignores) a non-null stream or password. The mode is enabled by default. Set the sun.security.mscapi.keyStoreCompatibilityMode system property to false to disable compatibility mode and reject a non-null stream or password.
Params:
  • stream – the output stream, which should be null
  • password – the password, which should be null
Throws:
  • IOException – if compatibility mode is disabled and either parameter is non-null.
/** * engineStore is currently a no-op. * Entries are stored during engineSetEntry. * * A compatibility mode is supported for applications that assume * keystores are stream-based. It permits (but ignores) a non-null * <code>stream</code> or <code>password</code>. * The mode is enabled by default. * Set the * <code>sun.security.mscapi.keyStoreCompatibilityMode</code> * system property to <code>false</code> to disable compatibility mode * and reject a non-null <code>stream</code> or <code>password</code>. * * @param stream the output stream, which should be <code>null</code> * @param password the password, which should be <code>null</code> * * @exception IOException if compatibility mode is disabled and either * parameter is non-null. */
public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { if (stream != null && !keyStoreCompatibilityMode) { throw new IOException("Keystore output stream must be null"); } if (password != null && !keyStoreCompatibilityMode) { throw new IOException("Keystore password must be null"); } }
Loads the keystore. A compatibility mode is supported for applications that assume keystores are stream-based. It permits (but ignores) a non-null stream or password. The mode is enabled by default. Set the sun.security.mscapi.keyStoreCompatibilityMode system property to false to disable compatibility mode and reject a non-null stream or password.
Params:
  • stream – the input stream, which should be null.
  • password – the password, which should be null.
Throws:
  • IOException – if there is an I/O or format problem with the keystore data. Or if compatibility mode is disabled and either parameter is non-null.
  • NoSuchAlgorithmException – if the algorithm used to check the integrity of the keystore cannot be found
  • CertificateException – if any of the certificates in the keystore could not be loaded
  • SecurityException – if the security check for SecurityPermission("authProvider.name") does not pass, where name is the value returned by this provider's getName method.
/** * Loads the keystore. * * A compatibility mode is supported for applications that assume * keystores are stream-based. It permits (but ignores) a non-null * <code>stream</code> or <code>password</code>. * The mode is enabled by default. * Set the * <code>sun.security.mscapi.keyStoreCompatibilityMode</code> * system property to <code>false</code> to disable compatibility mode * and reject a non-null <code>stream</code> or <code>password</code>. * * @param stream the input stream, which should be <code>null</code>. * @param password the password, which should be <code>null</code>. * * @exception IOException if there is an I/O or format problem with the * keystore data. Or if compatibility mode is disabled and either * parameter is non-null. * @exception NoSuchAlgorithmException if the algorithm used to check * the integrity of the keystore cannot be found * @exception CertificateException if any of the certificates in the * keystore could not be loaded * @exception SecurityException if the security check for * <code>SecurityPermission("authProvider.<i>name</i>")</code> does not * pass, where <i>name</i> is the value returned by * this provider's <code>getName</code> method. */
public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { if (stream != null && !keyStoreCompatibilityMode) { throw new IOException("Keystore input stream must be null"); } if (password != null && !keyStoreCompatibilityMode) { throw new IOException("Keystore password must be null"); } /* * Use the same security check as AuthProvider.login */ SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new SecurityPermission( "authProvider.SunMSCAPI")); } // Clear all key entries entries.clear(); try { // Load keys and/or certificate chains loadKeysOrCertificateChains(getName()); } catch (KeyStoreException e) { throw new IOException(e); } }
Stores the given entry into the map, making sure the alias, used as the key is unique. If the same alias already exists, it tries to append a suffix (1), (2), etc to it until it finds a unique value.
/** * Stores the given entry into the map, making sure * the alias, used as the key is unique. * If the same alias already exists, it tries to append * a suffix (1), (2), etc to it until it finds a unique * value. */
private void storeWithUniqueAlias(String alias, KeyEntry entry) { String uniqAlias = alias; int uniqNum = 1; while (true) { KeyEntry val = entries.get(uniqAlias); if (val == null) { val = entries.put(uniqAlias, entry); } if (val == null) { break; } uniqAlias = alias + " (" + (uniqNum++) + ")"; } }
Generates a certificate chain from the collection of certificates and stores the result into a key entry. This method is called by native code in libsunmscapi.
/** * Generates a certificate chain from the collection of * certificates and stores the result into a key entry. * This method is called by native code in libsunmscapi. */
private void generateCertificateChain(String alias, Collection<? extends Certificate> certCollection) { try { X509Certificate[] certChain = new X509Certificate[certCollection.size()]; int i = 0; for (Iterator<? extends Certificate> iter = certCollection.iterator(); iter.hasNext(); i++) { certChain[i] = (X509Certificate) iter.next(); } storeWithUniqueAlias(alias, new KeyEntry(alias, null, certChain)); } catch (Throwable e) { // Ignore the exception and skip this entry // If e is thrown, remember to deal with it in // native code. } }
Generates RSA key and certificate chain from the private key handle, collection of certificates and stores the result into key entries. This method is called by native code in libsunmscapi.
/** * Generates RSA key and certificate chain from the private key handle, * collection of certificates and stores the result into key entries. * This method is called by native code in libsunmscapi. */
private void generateRSAKeyAndCertificateChain(String alias, long hCryptProv, long hCryptKey, int keyLength, Collection<? extends Certificate> certCollection) { try { X509Certificate[] certChain = new X509Certificate[certCollection.size()]; int i = 0; for (Iterator<? extends Certificate> iter = certCollection.iterator(); iter.hasNext(); i++) { certChain[i] = (X509Certificate) iter.next(); } storeWithUniqueAlias(alias, new KeyEntry(alias, new RSAPrivateKey(hCryptProv, hCryptKey, keyLength), certChain)); } catch (Throwable e) { // Ignore the exception and skip this entry // If e is thrown, remember to deal with it in // native code. } }
Generates certificates from byte data and stores into cert collection. This method is called by native code in libsunmscapi.
Params:
  • data – Byte data.
  • certCollection – Collection of certificates.
/** * Generates certificates from byte data and stores into cert collection. * This method is called by native code in libsunmscapi. * * @param data Byte data. * @param certCollection Collection of certificates. */
private void generateCertificate(byte[] data, Collection<Certificate> certCollection) { try { ByteArrayInputStream bis = new ByteArrayInputStream(data); // Obtain certificate factory if (certificateFactory == null) { certificateFactory = CertificateFactory.getInstance("X.509", "SUN"); } // Generate certificate Collection<? extends Certificate> c = certificateFactory.generateCertificates(bis); certCollection.addAll(c); } catch (CertificateException e) { // Ignore the exception and skip this certificate // If e is thrown, remember to deal with it in // native code. } catch (Throwable te) { // Ignore the exception and skip this certificate // If e is thrown, remember to deal with it in // native code. } }
Returns the name of the keystore.
/** * Returns the name of the keystore. */
private String getName() { return storeName; }
Load keys and/or certificates from keystore into Collection.
Params:
  • name – Name of keystore.
  • entries – Collection of key/certificate.
/** * Load keys and/or certificates from keystore into Collection. * * @param name Name of keystore. * @param entries Collection of key/certificate. */
private native void loadKeysOrCertificateChains(String name) throws KeyStoreException;
Stores a DER-encoded certificate into the certificate store
Params:
  • name – Name of the keystore.
  • alias – Name of the certificate.
  • encoding – DER-encoded certificate.
/** * Stores a DER-encoded certificate into the certificate store * * @param name Name of the keystore. * @param alias Name of the certificate. * @param encoding DER-encoded certificate. */
private native void storeCertificate(String name, String alias, byte[] encoding, int encodingLength, long hCryptProvider, long hCryptKey) throws CertificateException, KeyStoreException;
Removes the certificate from the certificate store
Params:
  • name – Name of the keystore.
  • alias – Name of the certificate.
  • encoding – DER-encoded certificate.
/** * Removes the certificate from the certificate store * * @param name Name of the keystore. * @param alias Name of the certificate. * @param encoding DER-encoded certificate. */
private native void removeCertificate(String name, String alias, byte[] encoding, int encodingLength) throws CertificateException, KeyStoreException;
Destroys the key container.
Params:
  • keyContainerName – The name of the key container.
/** * Destroys the key container. * * @param keyContainerName The name of the key container. */
private native void destroyKeyContainer(String keyContainerName) throws KeyStoreException;
Generates a private-key BLOB from a key's components.
/** * Generates a private-key BLOB from a key's components. */
private native byte[] generatePrivateKeyBlob( int keyBitLength, byte[] modulus, byte[] publicExponent, byte[] privateExponent, byte[] primeP, byte[] primeQ, byte[] exponentP, byte[] exponentQ, byte[] crtCoefficient) throws InvalidKeyException; private native RSAPrivateKey storePrivateKey(byte[] keyBlob, String keyContainerName, int keySize) throws KeyStoreException; }