< prev index next >
src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java
Print this page
rev 13981 : imported patch 6483657-MSCAPI-provider-does-not-create-unique-alias-names
*** 1,7 ****
/*
! * Copyright (c) 2005, 2015, 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
--- 1,7 ----
/*
! * 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
*** 186,197 ****
"sun.security.mscapi.keyStoreCompatibilityMode";
private final boolean keyStoreCompatibilityMode;
/*
* The keystore entries.
*/
! private Collection<KeyEntry> entries = new ArrayList<KeyEntry>();
/*
* The keystore name.
* Case is not significant.
*/
--- 186,199 ----
"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.
*/
*** 246,262 ****
}
if (engineIsKeyEntry(alias) == false)
return null;
! for (KeyEntry entry : entries) {
! if (alias.equals(entry.getAlias())) {
! return entry.getPrivateKey();
! }
! }
!
! return null;
}
/**
* Returns the certificate chain associated with the given alias.
*
--- 248,261 ----
}
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.
*
*** 272,290 ****
{
if (alias == null) {
return null;
}
! for (KeyEntry entry : entries) {
! if (alias.equals(entry.getAlias())) {
! X509Certificate[] certChain = entry.getCertificateChain();
!
! return certChain.clone();
! }
! }
!
! return null;
}
/**
* Returns the certificate associated with the given alias.
*
--- 271,287 ----
{
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.
*
*** 304,322 ****
{
if (alias == null) {
return null;
}
! for (KeyEntry entry : entries) {
! if (alias.equals(entry.getAlias()))
! {
! X509Certificate[] certChain = entry.getCertificateChain();
! return certChain.length == 0 ? null : certChain[0];
! }
! }
!
! return null;
}
/**
* Returns the creation date of the entry identified by the given alias.
*
--- 301,317 ----
{
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.
*
*** 376,395 ****
throw new KeyStoreException("Password must be null");
}
if (key instanceof RSAPrivateCrtKey) {
! KeyEntry entry = null;
! boolean found = false;
!
! for (KeyEntry e : entries) {
! if (alias.equals(e.getAlias())) {
! found = true;
! entry = e;
! break;
! }
! }
X509Certificate[] xchain;
if (chain != null) {
if (chain instanceof X509Certificate[]) {
xchain = (X509Certificate[]) chain;
--- 371,381 ----
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;
*** 399,413 ****
}
} else {
xchain = null;
}
! if (! found) {
entry =
//TODO new KeyEntry(alias, key, (X509Certificate[]) chain);
new KeyEntry(alias, null, xchain);
! entries.add(entry);
}
entry.setAlias(alias);
try {
--- 385,399 ----
}
} 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 {
*** 482,508 ****
if (cert instanceof X509Certificate) {
// TODO - build CryptoAPI chain?
X509Certificate[] chain =
new X509Certificate[]{ (X509Certificate) cert };
! KeyEntry entry = null;
! boolean found = false;
!
! for (KeyEntry e : entries) {
! if (alias.equals(e.getAlias())) {
! found = true;
! entry = e;
! break;
! }
! }
! if (! found) {
entry =
new KeyEntry(alias, null, chain);
! entries.add(entry);
!
}
if (entry.getPrivateKey() == null) { // trusted-cert entry
entry.setAlias(alias);
try {
entry.setCertificateChain(chain);
--- 468,485 ----
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);
*** 530,589 ****
{
if (alias == null) {
throw new KeyStoreException("alias must not be null");
}
! for (KeyEntry entry : entries) {
! if (alias.equals(entry.getAlias())) {
!
// 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(), alias, 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()));
}
-
- entries.remove(entry);
- break;
- }
}
}
/**
* Lists all the alias names of this keystore.
*
* @return enumeration of the alias names
*/
public Enumeration<String> engineAliases() {
!
! final Iterator<KeyEntry> iter = entries.iterator();
return new Enumeration<String>()
{
public boolean hasMoreElements()
{
return iter.hasNext();
}
public String nextElement()
{
! KeyEntry entry = iter.next();
! return entry.getAlias();
}
};
}
/**
--- 507,558 ----
{
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.
*
* @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();
}
};
}
/**
*** 592,610 ****
* @param alias the alias name
*
* @return true if the alias exists, false otherwise
*/
public boolean engineContainsAlias(String alias) {
! for (Enumeration<String> enumerator = engineAliases();
! enumerator.hasMoreElements();)
! {
! String a = enumerator.nextElement();
!
! if (a.equals(alias))
! return true;
! }
! return false;
}
/**
* Retrieves the number of entries in this keystore.
*
--- 561,571 ----
* @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.
*
*** 625,661 ****
if (alias == null) {
return false;
}
! for (KeyEntry entry : entries) {
! if (alias.equals(entry.getAlias())) {
! return entry.getPrivateKey() != null;
! }
! }
!
! return false;
}
/**
* 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)
! {
! for (KeyEntry entry : entries) {
! if (alias.equals(entry.getAlias())) {
! return entry.getPrivateKey() == null;
! }
! }
return false;
}
/**
* 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
--- 586,616 ----
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
* <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.
*
* <p>This method attempts to match the given certificate with each
*** 668,680 ****
* @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 (KeyEntry entry : entries) {
if (entry.certChain != null && entry.certChain[0].equals(cert)) {
return entry.getAlias();
}
}
--- 623,636 ----
* @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();
}
}
*** 763,786 ****
entries.clear();
try {
// Load keys and/or certificate chains
! loadKeysOrCertificateChains(getName(), entries);
} catch (KeyStoreException e) {
throw new IOException(e);
}
}
/**
* Generates a certificate chain from the collection of
* certificates and stores the result into a key entry.
*/
private void generateCertificateChain(String alias,
! Collection<? extends Certificate> certCollection,
! Collection<KeyEntry> entries)
{
try
{
X509Certificate[] certChain =
new X509Certificate[certCollection.size()];
--- 719,761 ----
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.
+ */
+ private void storeWithUniqueAlias(String alias, KeyEntry entry) {
+ String uniqAlias = alias;
+ int uniqNum = 1;
+
+ while (true) {
+ if (entries.putIfAbsent(uniqAlias, entry) == null) {
+ break;
+ }
+ uniqAlias = alias + " (" + (uniqNum++) + ")";
+ }
+ }
+
+
+ /**
* Generates a certificate chain from the collection of
* certificates and stores the result into a key entry.
*/
private void generateCertificateChain(String alias,
! Collection<? extends Certificate> certCollection)
{
try
{
X509Certificate[] certChain =
new X509Certificate[certCollection.size()];
*** 790,803 ****
certCollection.iterator(); iter.hasNext(); i++)
{
certChain[i] = (X509Certificate) iter.next();
}
! KeyEntry entry = new KeyEntry(alias, null, certChain);
!
! // Add cert chain
! entries.add(entry);
}
catch (Throwable e)
{
// Ignore the exception and skip this entry
// TODO - throw CertificateException?
--- 765,776 ----
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
// TODO - throw CertificateException?
*** 808,819 ****
* Generates RSA key and certificate chain from the private key handle,
* collection of certificates and stores the result into key entries.
*/
private void generateRSAKeyAndCertificateChain(String alias,
long hCryptProv, long hCryptKey, int keyLength,
! Collection<? extends Certificate> certCollection,
! Collection<KeyEntry> entries)
{
try
{
X509Certificate[] certChain =
new X509Certificate[certCollection.size()];
--- 781,791 ----
* Generates RSA key and certificate chain from the private key handle,
* collection of certificates and stores the result into key entries.
*/
private void generateRSAKeyAndCertificateChain(String alias,
long hCryptProv, long hCryptKey, int keyLength,
! Collection<? extends Certificate> certCollection)
{
try
{
X509Certificate[] certChain =
new X509Certificate[certCollection.size()];
*** 823,837 ****
certCollection.iterator(); iter.hasNext(); i++)
{
certChain[i] = (X509Certificate) iter.next();
}
! KeyEntry entry = new KeyEntry(alias, new RSAPrivateKey(hCryptProv,
! hCryptKey, keyLength), certChain);
!
! // Add cert chain
! entries.add(entry);
}
catch (Throwable e)
{
// Ignore the exception and skip this entry
// TODO - throw CertificateException?
--- 795,807 ----
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
// TODO - throw CertificateException?
*** 884,895 ****
* 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,
! Collection<KeyEntry> entries) throws KeyStoreException;
/**
* Stores a DER-encoded certificate into the certificate store
*
* @param name Name of the keystore.
--- 854,865 ----
* 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
*
* @param name Name of the keystore.
< prev index next >