/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2007-2010 Sun Microsystems, Inc.
* Portions Copyright 2011-2014 ForgeRock AS
*/
/**
* This class defines a backend used to provide an LDAP view of public keys
* stored in a key store.
*/
implements ConfigurationChangeListener<TrustStoreBackendCfg>
{
/**
* The tracer object for the debug logger.
*/
/** The current configuration state. */
/** The DN for the base entry. */
/** The set of base DNs for this backend. */
/** The base entry. */
/** The PIN needed to access the trust store backing file. */
private char[] trustStorePIN;
/** The path to the trust store backing file. */
/** The type of trust store backing file to use. */
/** The certificate manager for the trust store. */
/**
* Creates a new backend. All backend
* implementations must implement a default constructor that use
* <CODE>super()</CODE> to invoke this constructor.
*/
public TrustStoreBackend()
{
super();
// Perform all initialization in initializeBackend.
}
/** {@inheritDoc} */
{
}
/** {@inheritDoc} */
public void initializeBackend()
{
// Create the set of base DNs that we will handle. In this case, it's just
// the DN of the base trust store entry.
{
throw new InitializationException(message);
}
// Get the path to the trust store file.
// Get the trust store type. If none is specified, then use the default
// type.
if (trustStoreType == null)
{
}
try
{
}
catch (KeyStoreException kse)
{
if (debugEnabled())
{
}
throw new InitializationException(message);
}
// Get the PIN needed to access the contents of the trust store file. We
// will offer several places to look for the PIN, and we will do so in the
// following order:
// - In a specified Java property
// - In a specified environment variable
// - In a specified file on the server filesystem.
// - As the value of a configuration attribute.
// In any case, the PIN must be in the clear. If no PIN is provided, then
// it will be assumed that none is required to access the information in the
// trust store.
if (pinProperty == null)
{
{
if (pinFilePath == null)
{
{
// This should be an Error. Otherwise, programs fails.
// Is there a Unit Test?
}
else
{
}
}
else
{
{
try
{
// Generate a PIN.
// Store the PIN in the pin file.
}
catch (Exception e)
{
throw new InitializationException(message);
}
}
else
{
try
{
}
catch (IOException ioe)
{
}
finally
{
}
{
throw new InitializationException(message);
}
else
{
}
}
}
}
else
{
{
throw new InitializationException(message);
}
else
{
}
}
}
else
{
{
throw new InitializationException(message);
}
else
{
}
}
// Create a certificate manager.
new String(trustStorePIN));
// Generate a self-signed certificate, if there is none.
// Construct the trust store base entry.
for (int i=0; i < numAVAs; i++)
{
}
opAttrs);
// Register this as a change listener.
// Register the trust store base as a private suffix.
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
throw new InitializationException(message, e);
}
}
/** {@inheritDoc} */
public void finalizeBackend()
{
super.finalizeBackend();
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
}
}
/** {@inheritDoc} */
{
return baseDNs;
}
/** {@inheritDoc} */
public long getEntryCount()
{
int numEntries = 1;
try
{
{
}
}
catch (KeyStoreException e)
{
if (debugEnabled())
{
}
}
return numEntries;
}
/** {@inheritDoc} */
public boolean isLocal()
{
// For the purposes of this method, this is a local backend.
return true;
}
/** {@inheritDoc} */
{
// All searches in this backend will always be considered indexed.
return true;
}
/** {@inheritDoc} */
{
// If the requested entry was null, then throw an exception.
{
}
// If the requested entry was the backend base entry, then retrieve it.
{
}
// See if the requested entry was one level below the backend base entry.
// If so, then it must point to a trust store entry.
{
try
{
return getCertEntry(entryDN);
}
catch (DirectoryException e)
{
if (debugEnabled())
{
}
}
}
return null;
}
/**
* Generates an entry for a certificate based on the provided DN. The
* DN must contain an RDN component that specifies the alias of the
* certificate, and that certificate alias must exist in the key store.
*
* @param entryDN The DN of the certificate to retrieve.
*
* @return The requested certificate entry.
*
* @throws DirectoryException If the specified alias does not exist, or if
* the DN does not specify any alias.
*/
throws DirectoryException
{
// Make sure that the DN specifies a certificate alias.
AttributeType t =
if (v == null)
{
}
try
{
{
}
}
catch (Exception e)
{
if (debugEnabled())
{
}
}
// Construct the certificate entry to return.
true);
return e;
}
/** {@inheritDoc} */
throws DirectoryException
{
{
}
{
}
{
}
else
{
}
}
/** {@inheritDoc} */
throws DirectoryException
{
{
}
{
}
}
/** {@inheritDoc} */
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
throws DirectoryException
{
// Get the base entry for the search, if possible. If it doesn't exist,
// then this will throw an exception.
// Look at the base DN and see if it's the trust store base DN, or a
// trust store entry DN.
{
{
}
try
{
}
catch (KeyStoreException e)
{
if (debugEnabled())
{
}
}
{
}
{
{
alias);
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
continue;
}
{
}
}
}
}
{
{
}
}
else
{
}
}
/** {@inheritDoc} */
{
return Collections.emptySet();
}
/** {@inheritDoc} */
{
return Collections.emptySet();
}
/** {@inheritDoc} */
public boolean supportsLDIFExport()
{
return false;
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
public boolean supportsLDIFImport()
{
return false;
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
public boolean supportsBackup()
{
return false;
}
/** {@inheritDoc} */
{
return false;
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
public boolean supportsRestore()
{
return false;
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
public boolean isConfigurationChangeAcceptable(
{
boolean configAcceptable = true;
// Get the path to the trust store file.
try
{
{
configAcceptable = false;
}
}
catch (Exception e)
{
if (debugEnabled())
{
}
getExceptionMessage(e)));
configAcceptable = false;
}
// Check to see if the trust store type is acceptable.
{
try
{
}
catch (KeyStoreException kse)
{
if (debugEnabled())
{
}
configAcceptable = false;
}
}
// If there is a PIN property, then make sure the corresponding
// property is set.
{
configAcceptable = false;
}
// If there is a PIN environment variable, then make sure the corresponding
// environment variable is set.
{
configAcceptable = false;
}
// If there is a PIN file, then make sure the file is readable if it exists.
{
if (f.exists())
{
try
{
}
catch (IOException ioe)
{
configAcceptable = false;
}
finally
{
}
{
configAcceptable = false;
}
}
}
return configAcceptable;
}
/** {@inheritDoc} */
{
boolean adminActionRequired = false;
// Get the path to the trust store file.
{
}
// Get the trust store type. If none is specified, then use the default
// type.
if (newTrustStoreType == null)
{
}
try
{
}
catch (KeyStoreException kse)
{
if (debugEnabled())
{
}
}
// Get the PIN needed to access the contents of the trust store file. We
// will offer several places to look for the PIN, and we will do so in the
// following order:
// - In a specified Java property
// - In a specified environment variable
// - In a specified file on the server filesystem.
// - As the value of a configuration attribute.
// In any case, the PIN must be in the clear. If no PIN is provided, then
// it will be assumed that none is required to access the information in the
// trust store.
if (newPINProperty == null)
{
if (newPINEnVar == null)
{
if (newPINFile == null)
{
{
}
else
{
}
}
else
{
{
try
{
// Generate a PIN.
// Store the PIN in the pin file.
}
catch (Exception e)
{
}
}
else
{
try
{
}
catch (IOException ioe)
{
}
finally
{
}
{
}
else
{
}
}
}
}
else
{
{
}
else
{
}
}
}
else
{
{
}
else
{
}
}
{
configuration = cfg;
new String(trustStorePIN));
}
}
/**
* Create a new child DN from a given parent DN. The child RDN is formed
* from a given attribute type and string value.
* @param parentDN The DN of the parent.
* @param rdnAttrType The attribute type of the RDN.
* @param rdnStringValue The string value of the RDN.
* @return A new child DN.
*/
{
}
/**
* Retrieves a set of <CODE>KeyManager</CODE> objects that may be used for
* interactions requiring access to a key manager.
*
* @return A set of <CODE>KeyManager</CODE> objects that may be used for
* interactions requiring access to a key manager.
*
* @throws DirectoryException If a problem occurs while attempting to obtain
* the set of key managers.
*/
throws DirectoryException
{
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
message, e);
}
finally
{
}
try
{
return keyManagerFactory.getKeyManagers();
}
catch (Exception e)
{
if (debugEnabled())
{
}
message, e);
}
}
/**
* Retrieves a set of {@code TrustManager} objects that may be used
* for interactions requiring access to a trust manager.
*
* @return A set of {@code TrustManager} objects that may be used
* for interactions requiring access to a trust manager.
*
* @throws DirectoryException If a problem occurs while attempting
* to obtain the set of trust managers.
*/
throws DirectoryException
{
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
message, e);
}
finally
{
}
try
{
return trustManagerFactory.getTrustManagers();
}
catch (Exception e)
{
if (debugEnabled())
{
}
message, e);
}
}
/**
* Returns the key associated with the given alias, using the trust
* store pin to recover it.
*
* @param alias The alias name.
*
* @return The requested key, or null if the given alias does not exist
* or does not identify a key-related entry.
*
* @throws DirectoryException If an error occurs while retrieving the key.
*/
throws DirectoryException
{
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
message, e);
}
finally
{
}
try
{
}
catch (Exception e)
{
if (debugEnabled())
{
}
message, e);
}
}
throws DirectoryException
{
// Make sure that the DN specifies a certificate alias.
AttributeType t =
if (v == null)
{
}
try
{
{
message);
}
{
try
{
}
catch (Exception e)
{
throw new DirectoryException(
}
}
else
{
{
throw new DirectoryException(
}
{
throw new DirectoryException(
}
if (!i.hasNext())
{
throw new DirectoryException(
}
if (i.hasNext())
{
throw new DirectoryException(
}
try
{
try
{
try
{
}
finally
{
}
}
finally
{
}
}
catch (IOException e)
{
certAlias, getExceptionMessage(e));
throw new DirectoryException(
}
}
}
catch (Exception e)
{
throw new DirectoryException(
}
}
throws DirectoryException
{
// Make sure that the DN specifies a certificate alias.
AttributeType t =
if (v == null)
{
}
try
{
{
message);
}
}
catch (Exception e)
{
throw new DirectoryException(
}
}
/**
* Returns the validity period to be used to generate the ADS certificate.
* @return The validity period to be used to generate the ADS certificate.
*/
private static int getADSCertificateValidity()
{
return 20 * 365;
}
/**
* Returns the Subject DN to be used to generate the ADS certificate.
* @return The Subject DN to be used to generate the ADS certificate.
* @throws java.net.UnknownHostException If the server host name could not be
* determined.
*/
throws UnknownHostException
{
}
/**
* Create a randomly generated password for a certificate keystore.
* @return A randomly generated password for a certificate keystore.
*/
private static char[] createKeystorePassword() {
int pwdLength = 50;
}
return pwd;
}
{
char generatedChar;
int d;
switch (type)
{
case 0:
// Will return a digit
d = next % 10;
if (d < 0)
{
d = d * -1;
}
generatedChar = (char) (d+48);
break;
case 1:
// Will return a lower case letter
d = next % 26;
if (d < 0)
{
d = d * -1;
}
generatedChar = (char) (d + 97);
break;
default:
// Will return a capital letter
d = next % 26;
if (d < 0)
{
d = d * -1;
}
generatedChar = (char) (d + 65) ;
}
return generatedChar;
}
{
}
/**
* Creates a PIN file on the specified path.
* @param path the path where the PIN file will be created.
* @param pin The PIN to store in the file.
* @throws IOException if something goes wrong.
*/
throws IOException
{
if(FilePermission.canSetPermissions()) {
try {
new FilePermission(0600)))
{
// Log a warning that the permissions were not set.
}
} catch(DirectoryException e) {
// Log a warning that the permissions were not set.
}
}
}
/**
* Generates a self-signed certificate with well-known alias if there is none.
* @throws InitializationException If an error occurs while interacting with
* the key store.
*/
private void generateInstanceCertificateIfAbsent()
throws InitializationException
{
try
{
{
return;
}
}
catch (Exception e)
{
throw new InitializationException(message, e);
}
try
{
}
catch (Exception e)
{
throw new InitializationException(message, e);
}
}
/** {@inheritDoc} */
throw new UnsupportedOperationException("Operation not supported.");
}
}