mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noel Rouvignac
22.44.2014 1345ac0dfae9a555abb7b74ed48452d9bc92b8c3
opends/src/server/org/opends/server/backends/TrustStoreBackend.java
@@ -22,12 +22,10 @@
 *
 *
 *      Copyright 2007-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011 ForgeRock AS
 *      Portions Copyright 2011-2014 ForgeRock AS
 */
package org.opends.server.backends;
import static org.opends.messages.BackendMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -48,12 +46,13 @@
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Random;
import java.util.SortedSet;
import java.util.Set;
import javax.naming.ldap.Rdn;
import javax.net.ssl.KeyManager;
@@ -62,7 +61,6 @@
import javax.net.ssl.TrustManagerFactory;
import org.opends.messages.Message;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.TrustStoreBackendCfg;
import org.opends.server.api.Backend;
@@ -76,18 +74,16 @@
import org.opends.server.loggers.ErrorLogger;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.*;
import org.opends.server.types.FilePermission;
import org.opends.server.util.CertificateManager;
import org.opends.server.util.SetupUtils;
import org.opends.server.util.Validator;
/**
 * This class defines a backend used to provide an LDAP view of public keys
 * stored in a key store.
 */
public class TrustStoreBackend
     extends Backend
public class TrustStoreBackend extends Backend<TrustStoreBackendCfg>
       implements ConfigurationChangeListener<TrustStoreBackendCfg>
{
  /**
@@ -97,34 +93,28 @@
  // The current configuration state.
  /** The current configuration state. */
  private TrustStoreBackendCfg configuration;
  // The DN for the base entry.
  /** The DN for the base entry. */
  private DN baseDN;
  // The set of base DNs for this backend.
  /** The set of base DNs for this backend. */
  private DN[] baseDNs;
  // The base entry.
  /** The base entry. */
  private Entry baseEntry;
  // The set of supported controls for this backend.
  private HashSet<String> supportedControls;
  // The set of supported features for this backend.
  private HashSet<String> supportedFeatures;
  // The PIN needed to access the trust store backing file.
  /** The PIN needed to access the trust store backing file. */
  private char[] trustStorePIN;
  // The path to the trust store backing file.
  /** The path to the trust store backing file. */
  private String trustStoreFile;
  // The type of trust store backing file to use.
  /** The type of trust store backing file to use. */
  private String trustStoreType;
  // The certificate manager for the trust store.
  /** The certificate manager for the trust store. */
  private CertificateManager certificateManager;
@@ -141,26 +131,16 @@
    // Perform all initialization in initializeBackend.
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void configureBackend(Configuration config) throws ConfigException
  /** {@inheritDoc} */
  @Override
  public void configureBackend(TrustStoreBackendCfg config) throws ConfigException
  {
    Validator.ensureNotNull(config);
    Validator.ensureTrue(config instanceof TrustStoreBackendCfg);
    configuration = (TrustStoreBackendCfg)config;
    configuration = config;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void initializeBackend()
         throws ConfigException, InitializationException
  {
@@ -278,12 +258,7 @@
            }
            finally
            {
              try
              {
                br.close();
              } catch (Exception e) {
                // ignore
              }
              close(br);
            }
            if (pinStr == null)
@@ -366,11 +341,6 @@
                                opAttrs);
    // Define empty sets for the supported controls and features.
    supportedControls = new HashSet<String>(0);
    supportedFeatures = new HashSet<String>(0);
    // Register this as a change listener.
    configuration.addTrustStoreChangeListener(this);
@@ -393,12 +363,8 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void finalizeBackend()
  {
    configuration.addTrustStoreChangeListener(this);
@@ -416,23 +382,15 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public DN[] getBaseDNs()
  {
    return baseDNs;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public long getEntryCount()
  {
    int numEntries = 1;
@@ -456,45 +414,31 @@
    return numEntries;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean isLocal()
  {
    // For the purposes of this method, this is a local backend.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    // All searches in this backend will always be considered indexed.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public Entry getEntry(DN entryDN)
         throws DirectoryException
  /** {@inheritDoc} */
  @Override
  public Entry getEntry(DN entryDN) throws DirectoryException
  {
    // If the requested entry was null, then throw an exception.
    if (entryDN == null)
    {
      Message message = ERR_TRUSTSTORE_GET_ENTRY_NULL.get();
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
                                   message);
          ERR_BACKEND_GET_ENTRY_NULL.get(getBackendID()));
    }
@@ -508,11 +452,7 @@
    // See if the requested entry was one level below the backend base entry.
    // If so, then it must point to a trust store entry.
    DN parentDN = entryDN.getParentDNInSuffix();
    if (parentDN == null)
    {
      return null;
    }
    else if (parentDN.equals(baseDN))
    if (parentDN != null && parentDN.equals(baseDN))
    {
      try
      {
@@ -520,13 +460,13 @@
      }
      catch (DirectoryException e)
      {
        return null;
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.VERBOSE, e);
        }
      }
    }
    else
    {
      return null;
    }
    return null;
  }
@@ -618,12 +558,8 @@
    return e;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void addEntry(Entry entry, AddOperation addOperation)
         throws DirectoryException
  {
@@ -657,12 +593,8 @@
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
         throws DirectoryException
  {
@@ -684,39 +616,27 @@
    deleteCertificate(entryDN);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void replaceEntry(Entry oldEntry, Entry newEntry,
      ModifyOperation modifyOperation) throws DirectoryException
  {
    Message message = ERR_TRUSTSTORE_MODIFY_NOT_SUPPORTED.get();
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
        ERR_BACKEND_MODIFY_NOT_SUPPORTED.get(String.valueOf(oldEntry.getDN()), getBackendID()));
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void renameEntry(DN currentDN, Entry entry,
                          ModifyDNOperation modifyDNOperation)
         throws DirectoryException
  {
    Message message = ERR_TRUSTSTORE_MODIFY_DN_NOT_SUPPORTED.get();
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
        ERR_BACKEND_MODIFY_DN_NOT_SUPPORTED.get(String.valueOf(currentDN), getBackendID()));
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void search(SearchOperation searchOperation)
         throws DirectoryException
  {
@@ -732,13 +652,10 @@
    SearchFilter filter = searchOperation.getFilter();
    if (this.baseDN.equals(baseDN))
    {
      if ((scope == SearchScope.BASE_OBJECT) ||
          (scope == SearchScope.WHOLE_SUBTREE))
      if ((scope == SearchScope.BASE_OBJECT || scope == SearchScope.WHOLE_SUBTREE)
          && filter.matchesEntry(baseEntry))
      {
        if (filter.matchesEntry(baseEntry))
        {
          searchOperation.returnEntry(baseEntry, null);
        }
        searchOperation.returnEntry(baseEntry, null);
      }
      String[] aliases = null;
@@ -759,7 +676,7 @@
        aliases = new String[0];
      }
      if ((scope != SearchScope.BASE_OBJECT) && (! (aliases.length == 0) ))
      if (scope != SearchScope.BASE_OBJECT && aliases.length != 0)
      {
        AttributeType certAliasType =
             DirectoryServer.getAttributeType(ATTR_CRYPTO_KEY_ID, true);
@@ -795,13 +712,10 @@
    {
      Entry certEntry = getCertEntry(baseDN);
      if ((scope == SearchScope.BASE_OBJECT) ||
          (scope == SearchScope.WHOLE_SUBTREE))
      if ((scope == SearchScope.BASE_OBJECT || scope == SearchScope.WHOLE_SUBTREE)
          && filter.matchesEntry(certEntry))
      {
        if (filter.matchesEntry(certEntry))
        {
          searchOperation.returnEntry(certEntry, null);
        }
        searchOperation.returnEntry(certEntry, null);
      }
    }
    else
@@ -811,165 +725,104 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  /** {@inheritDoc} */
  @Override
  public Set<String> getSupportedControls()
  {
    return supportedControls;
    return Collections.emptySet();
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  /** {@inheritDoc} */
  @Override
  public Set<String> getSupportedFeatures()
  {
    return supportedFeatures;
    return Collections.emptySet();
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean supportsLDIFExport()
  {
    // We do not support LDIF exports.
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void exportLDIF(LDIFExportConfig exportConfig)
         throws DirectoryException
  {
    Message message = ERR_TRUSTSTORE_IMPORT_AND_EXPORT_NOT_SUPPORTED.get();
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
        ERR_BACKEND_IMPORT_AND_EXPORT_NOT_SUPPORTED.get(getBackendID()));
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean supportsLDIFImport()
  {
    // This backend does not support LDIF imports.
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public LDIFImportResult importLDIF(LDIFImportConfig importConfig)
         throws DirectoryException
  {
    // This backend does not support LDIF imports.
    Message message = ERR_TRUSTSTORE_IMPORT_AND_EXPORT_NOT_SUPPORTED.get();
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
        ERR_BACKEND_IMPORT_AND_EXPORT_NOT_SUPPORTED.get(getBackendID()));
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean supportsBackup()
  {
    // This backend does not provide a backup/restore mechanism.
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
    // This backend does not provide a backup/restore mechanism.
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void createBackup(BackupConfig backupConfig)
       throws DirectoryException
  {
    // This backend does not provide a backup/restore mechanism.
    Message message = ERR_TRUSTSTORE_BACKUP_AND_RESTORE_NOT_SUPPORTED.get();
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
        ERR_BACKEND_BACKUP_AND_RESTORE_NOT_SUPPORTED.get(getBackendID()));
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void removeBackup(BackupDirectory backupDirectory,
                           String backupID)
         throws DirectoryException
  {
    // This backend does not provide a backup/restore mechanism.
    Message message = ERR_TRUSTSTORE_BACKUP_AND_RESTORE_NOT_SUPPORTED.get();
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
        ERR_BACKEND_BACKUP_AND_RESTORE_NOT_SUPPORTED.get(getBackendID()));
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean supportsRestore()
  {
    // This backend does not provide a backup/restore mechanism.
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void restoreBackup(RestoreConfig restoreConfig)
         throws DirectoryException
  {
    // This backend does not provide a backup/restore mechanism.
    Message message = ERR_TRUSTSTORE_BACKUP_AND_RESTORE_NOT_SUPPORTED.get();
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
        ERR_BACKEND_BACKUP_AND_RESTORE_NOT_SUPPORTED.get(getBackendID()));
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public ConditionResult hasSubordinates(DN entryDN)
      throws DirectoryException
  {
@@ -977,12 +830,8 @@
        ERR_HAS_SUBORDINATES_NOT_SUPPORTED.get());
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public long numSubordinates(DN entryDN, boolean subtree)
      throws DirectoryException
  {
@@ -990,11 +839,8 @@
        ERR_NUM_SUBORDINATES_NOT_SUPPORTED.get());
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public boolean isConfigurationChangeAcceptable(
       TrustStoreBackendCfg configuration, List<Message> unacceptableReasons)
  {
@@ -1057,32 +903,26 @@
    // If there is a PIN property, then make sure the corresponding
    // property is set.
    String pinProp = configuration.getTrustStorePinProperty();
    if (pinProp != null)
    if (pinProp != null && System.getProperty(pinProp) == null)
    {
      if (System.getProperty(pinProp) == null)
      {
        Message message = ERR_TRUSTSTORE_PIN_PROPERTY_NOT_SET.get(
                String.valueOf(pinProp),
                String.valueOf(cfgEntryDN));
        unacceptableReasons.add(message);
        configAcceptable = false;
      }
      Message message = ERR_TRUSTSTORE_PIN_PROPERTY_NOT_SET.get(
          String.valueOf(pinProp),
          String.valueOf(cfgEntryDN));
      unacceptableReasons.add(message);
      configAcceptable = false;
    }
    // If there is a PIN environment variable, then make sure the corresponding
    // environment variable is set.
    String pinEnVar = configuration.getTrustStorePinEnvironmentVariable();
    if (pinEnVar != null)
    if (pinEnVar != null && System.getenv(pinEnVar) == null)
    {
      if (System.getenv(pinEnVar) == null)
      {
        Message message = ERR_TRUSTSTORE_PIN_ENVAR_NOT_SET.get(
                String.valueOf(pinEnVar),
                String.valueOf(cfgEntryDN));
        unacceptableReasons.add(message);
        configAcceptable = false;
      }
      Message message = ERR_TRUSTSTORE_PIN_ENVAR_NOT_SET.get(
          String.valueOf(pinEnVar),
          String.valueOf(cfgEntryDN));
      unacceptableReasons.add(message);
      configAcceptable = false;
    }
@@ -1112,12 +952,7 @@
        }
        finally
        {
          try
          {
            br.close();
          } catch (Exception e) {
            // ignore
          }
          close(br);
        }
        if (pinStr == null)
@@ -1135,11 +970,8 @@
    return configAcceptable;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public ConfigChangeResult applyConfigurationChange(TrustStoreBackendCfg cfg)
  {
    ResultCode        resultCode          = ResultCode.SUCCESS;
@@ -1261,12 +1093,7 @@
            }
            finally
            {
              try
              {
                br.close();
              } catch (Exception e) {
                // ignore
              }
              close(br);
            }
            if (pinStr == null)
@@ -1389,14 +1216,7 @@
    }
    finally
    {
      if (inputStream != null)
      {
        try
        {
          inputStream.close();
        }
        catch (Exception e){}
      }
      close(inputStream);
    }
@@ -1460,14 +1280,7 @@
    }
    finally
    {
      if (inputStream != null)
      {
        try
        {
          inputStream.close();
        }
        catch (Exception e){}
      }
      close(inputStream);
    }
@@ -1477,14 +1290,7 @@
      TrustManagerFactory trustManagerFactory =
           TrustManagerFactory.getInstance(trustManagerAlgorithm);
      trustManagerFactory.init(trustStore);
      TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
//    TrustManager[] newTrustManagers = new TrustManager[trustManagers.length];
//    for (int i=0; i < trustManagers.length; i++)
//    {
//      newTrustManagers[i] = new ExpirationCheckTrustManager(
//                                     (X509TrustManager) trustManagers[i]);
//    }
      return trustManagers;
      return trustManagerFactory.getTrustManagers();
    }
    catch (Exception e)
    {
@@ -1539,14 +1345,7 @@
    }
    finally
    {
      if (inputStream != null)
      {
        try
        {
          inputStream.close();
        }
        catch (Exception e){}
      }
      close(inputStream);
    }
    try
@@ -1799,7 +1598,7 @@
      d = next % 10;
      if (d < 0)
      {
        d = d * (-1);
        d = d * -1;
      }
      generatedChar = (char) (d+48);
      break;
@@ -1808,16 +1607,16 @@
      d = next % 26;
      if (d < 0)
      {
        d = d * (-1);
        d = d * -1;
      }
      generatedChar =  (char) (d + 97);
      break;
    default:
      // Will return a capital letter
      d = (next % 26);
      d = next % 26;
      if (d < 0)
      {
        d = d * (-1);
        d = d * -1;
      }
      generatedChar = (char) (d + 65) ;
    }
@@ -1827,7 +1626,7 @@
  private static int getRandomInt(Random random,int modulo)
  {
    return (random.nextInt() & modulo);
    return random.nextInt() & modulo;
  }
  /**
@@ -1904,11 +1703,7 @@
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void preloadEntryCache() throws UnsupportedOperationException {
    throw new UnsupportedOperationException("Operation not supported.");