CryptoManagerSync.java revision 5a92d951296cae7ad72e45f84c92d40a6d41ad40
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * CDDL HEADER START
3371be256ea01dd6e09b2d28c64b495c3d43e32bMark de Reeper *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The contents of this file are subject to the terms of the
3371be256ea01dd6e09b2d28c64b495c3d43e32bMark de Reeper * Common Development and Distribution License, Version 1.0 only
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (the "License"). You may not use this file except in compliance
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * with the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
3371be256ea01dd6e09b2d28c64b495c3d43e32bMark de Reeper * or http://forgerock.org/license/CDDLv1.0.html.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing permissions
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL HEADER in each
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * file and include the License file at legal-notices/CDDLv1_0.txt.
3371be256ea01dd6e09b2d28c64b495c3d43e32bMark de Reeper * If applicable, add the following below this CDDL HEADER, with the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * fields enclosed by brackets "[]" replaced with your own identifying
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * information:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Portions Copyright [yyyy] [name of copyright owner]
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * CDDL HEADER END
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
3371be256ea01dd6e09b2d28c64b495c3d43e32bMark de Reeper * Copyright 2008-2010 Sun Microsystems, Inc.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Portions Copyright 2014-2015 ForgeRock AS
3371be256ea01dd6e09b2d28c64b495c3d43e32bMark de Reeper */
fdd3077db2228482076ca7f288c80761f311ea0eMark de Reeperpackage org.opends.server.crypto;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport static org.opends.messages.CoreMessages.*;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport static org.opends.server.api.plugin.PluginType.*;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport static org.opends.server.config.ConfigConstants.*;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport static org.opends.server.core.DirectoryServer.*;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport static org.opends.server.protocols.internal.InternalClientConnection.*;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport static org.opends.server.protocols.internal.Requests.*;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport static org.opends.server.util.ServerConstants.*;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport static org.opends.server.util.StaticUtils.*;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.EnumSet;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.HashMap;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.LinkedHashMap;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.List;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Map;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.forgerock.i18n.LocalizableMessage;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.forgerock.i18n.slf4j.LocalizedLogger;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.forgerock.opendj.ldap.ResultCode;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.forgerock.opendj.ldap.SearchScope;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.admin.ads.ADSContext;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.api.Backend;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.api.BackendInitializationListener;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.api.plugin.InternalDirectoryServerPlugin;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.api.plugin.PluginResult.PostResponse;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.config.ConfigConstants;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.controls.EntryChangeNotificationControl;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.controls.PersistentSearchChangeType;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.core.AddOperation;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.core.DeleteOperation;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.core.DirectoryServer;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.protocols.internal.InternalClientConnection;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.protocols.internal.InternalSearchOperation;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.protocols.internal.SearchRequest;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.protocols.ldap.LDAPControl;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.Attribute;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.AttributeType;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.Control;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.CryptoManagerException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.DN;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.DirectoryException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.Entry;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.InitializationException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.ObjectClass;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.RDN;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.SearchFilter;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.SearchResultEntry;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.operation.PostResponseAddOperation;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.operation.PostResponseDeleteOperation;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.operation.PostResponseModifyOperation;
fdd3077db2228482076ca7f288c80761f311ea0eMark de Reeper
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This class defines an object that synchronizes certificates from the admin
fdd3077db2228482076ca7f288c80761f311ea0eMark de Reeper * data branch into the trust store backend, and synchronizes secret-key entries
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * from the admin data branch to the crypto manager secret-key cache.
fdd3077db2228482076ca7f288c80761f311ea0eMark de Reeper */
fdd3077db2228482076ca7f288c80761f311ea0eMark de Reeperpublic class CryptoManagerSync extends InternalDirectoryServerPlugin
fdd3077db2228482076ca7f288c80761f311ea0eMark de Reeper implements BackendInitializationListener
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /** The debug log tracer for this object. */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /** The DN of the administration suffix. */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private DN adminSuffixDN;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /** The DN of the instance keys container within the admin suffix. */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private DN instanceKeysDN;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /** The DN of the secret keys container within the admin suffix. */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private DN secretKeysDN;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /** The DN of the trust store root. */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private DN trustStoreRootDN;
fdd3077db2228482076ca7f288c80761f311ea0eMark de Reeper
fdd3077db2228482076ca7f288c80761f311ea0eMark de Reeper /** The attribute type that is used to specify a server instance certificate. */
fdd3077db2228482076ca7f288c80761f311ea0eMark de Reeper private final AttributeType attrCert;
fdd3077db2228482076ca7f288c80761f311ea0eMark de Reeper
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /** The attribute type that holds a server certificate identifier. */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private final AttributeType attrAlias;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /** The attribute type that holds the time a key was compromised. */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private final AttributeType attrCompromisedTime;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /** A filter on object class to select key entries. */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private SearchFilter keySearchFilter;
/** The instance key objectclass. */
private final ObjectClass ocInstanceKey;
/** The cipher key objectclass. */
private final ObjectClass ocCipherKey;
/** The mac key objectclass. */
private final ObjectClass ocMacKey;
/** Dummy configuration DN. */
private static final String CONFIG_DN = "cn=Crypto Manager Sync,cn=config";
/**
* Creates a new instance of this trust store synchronization thread.
*
* @throws InitializationException in case an exception occurs during
* initialization, such as a failure to publish the instance-key-pair
* public-key-certificate in ADS.
*/
public CryptoManagerSync() throws InitializationException
{
super(toDN(CONFIG_DN), EnumSet.of(
// No implementation required for modify_dn operations
// FIXME: Technically it is possible to perform a subtree modDN
// in this case however such subtree modDN would essentially be
// moving configuration branches which should not happen.
POST_RESPONSE_ADD, POST_RESPONSE_MODIFY, POST_RESPONSE_DELETE),
true);
try {
CryptoManagerImpl.publishInstanceKeyEntryInADS();
}
catch (CryptoManagerException ex) {
throw new InitializationException(ex.getMessageObject());
}
DirectoryServer.registerBackendInitializationListener(this);
try
{
adminSuffixDN = DN.valueOf(ADSContext.getAdministrationSuffixDN());
instanceKeysDN = adminSuffixDN.child(DN.valueOf("cn=instance keys"));
secretKeysDN = adminSuffixDN.child(DN.valueOf("cn=secret keys"));
trustStoreRootDN = DN.valueOf(ConfigConstants.DN_TRUST_STORE_ROOT);
keySearchFilter =
SearchFilter.createFilterFromString("(|" +
"(objectclass=" + OC_CRYPTO_INSTANCE_KEY + ")" +
"(objectclass=" + OC_CRYPTO_CIPHER_KEY + ")" +
"(objectclass=" + OC_CRYPTO_MAC_KEY + ")" +
")");
}
catch (DirectoryException e)
{
}
ocInstanceKey = DirectoryServer.getObjectClass(OC_CRYPTO_INSTANCE_KEY, true);
ocCipherKey = DirectoryServer.getObjectClass(OC_CRYPTO_CIPHER_KEY, true);
ocMacKey = DirectoryServer.getObjectClass(OC_CRYPTO_MAC_KEY, true);
attrCert = getAttributeTypeOrDefault(ATTR_CRYPTO_PUBLIC_KEY_CERTIFICATE);
attrAlias = getAttributeTypeOrDefault(ATTR_CRYPTO_KEY_ID);
attrCompromisedTime = getAttributeTypeOrDefault(ATTR_CRYPTO_KEY_COMPROMISED_TIME);
if (DirectoryServer.getBackendWithBaseDN(adminSuffixDN) != null)
{
searchAdminSuffix();
}
DirectoryServer.registerInternalPlugin(this);
}
private static DN toDN(final String dn) throws InitializationException
{
try
{
return DN.valueOf(dn);
}
catch (DirectoryException e)
{
throw new RuntimeException(e);
}
}
private void searchAdminSuffix()
{
SearchRequest request = newSearchRequest(adminSuffixDN, SearchScope.WHOLE_SUBTREE, keySearchFilter);
InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
ResultCode resultCode = searchOperation.getResultCode();
if (resultCode != ResultCode.SUCCESS)
{
logger.debug(INFO_TRUSTSTORESYNC_ADMIN_SUFFIX_SEARCH_FAILED, adminSuffixDN,
searchOperation.getErrorMessage());
}
for (SearchResultEntry searchEntry : searchOperation.getSearchEntries())
{
try
{
handleInternalSearchEntry(searchEntry);
}
catch (DirectoryException e)
{
logger.traceException(e);
logger.error(ERR_TRUSTSTORESYNC_EXCEPTION, stackTraceToSingleLineString(e));
}
}
}
/** {@inheritDoc} */
@Override
public void performBackendPreInitializationProcessing(Backend<?> backend)
{
DN[] baseDNs = backend.getBaseDNs();
if (baseDNs != null)
{
for (DN baseDN : baseDNs)
{
if (baseDN.equals(adminSuffixDN))
{
searchAdminSuffix();
}
}
}
}
/** {@inheritDoc} */
@Override
public void performBackendPostFinalizationProcessing(Backend<?> backend)
{
// No implementation required.
}
@Override
public void performBackendPostInitializationProcessing(Backend<?> backend) {
// Nothing to do.
}
@Override
public void performBackendPreFinalizationProcessing(Backend<?> backend) {
// Nothing to do.
}
private void handleInternalSearchEntry(SearchResultEntry searchEntry)
throws DirectoryException
{
if (searchEntry.hasObjectClass(ocInstanceKey))
{
handleInstanceKeySearchEntry(searchEntry);
}
else
{
try
{
if (searchEntry.hasObjectClass(ocCipherKey))
{
DirectoryServer.getCryptoManager().importCipherKeyEntry(searchEntry);
}
else if (searchEntry.hasObjectClass(ocMacKey))
{
DirectoryServer.getCryptoManager().importMacKeyEntry(searchEntry);
}
}
catch (CryptoManagerException e)
{
throw new DirectoryException(
DirectoryServer.getServerErrorResultCode(), e);
}
}
}
private void handleInstanceKeySearchEntry(SearchResultEntry searchEntry)
throws DirectoryException
{
RDN srcRDN = searchEntry.getName().rdn();
// Only process the entry if it has the expected form of RDN.
if (!srcRDN.isMultiValued() &&
srcRDN.getAttributeType(0).equals(attrAlias))
{
DN dstDN = trustStoreRootDN.child(srcRDN);
// Extract any change notification control.
EntryChangeNotificationControl ecn = null;
List<Control> controls = searchEntry.getControls();
try
{
for (Control c : controls)
{
if (OID_ENTRY_CHANGE_NOTIFICATION.equals(c.getOID()))
{
if (c instanceof LDAPControl)
{
ecn = EntryChangeNotificationControl.DECODER.decode(c
.isCritical(), ((LDAPControl) c).getValue());
}
else
{
ecn = (EntryChangeNotificationControl)c;
}
}
}
}
catch (DirectoryException e)
{
// ignore
}
// Get any existing local trust store entry.
Entry dstEntry = DirectoryServer.getEntry(dstDN);
if (ecn != null &&
ecn.getChangeType() == PersistentSearchChangeType.DELETE)
{
// entry was deleted so remove it from the local trust store
if (dstEntry != null)
{
deleteEntry(dstDN);
}
}
else if (searchEntry.hasAttribute(attrCompromisedTime))
{
// key was compromised so remove it from the local trust store
if (dstEntry != null)
{
deleteEntry(dstDN);
}
}
else if (dstEntry == null)
{
// The entry was added
addEntry(searchEntry, dstDN);
}
else
{
// The entry was modified
modifyEntry(searchEntry, dstEntry);
}
}
}
/**
* Modify an entry in the local trust store if it differs from an entry in
* the ADS branch.
* @param srcEntry The instance key entry in the ADS branch.
* @param dstEntry The local trust store entry.
*/
private void modifyEntry(Entry srcEntry, Entry dstEntry)
{
List<Attribute> srcList = srcEntry.getAttribute(attrCert);
List<Attribute> dstList = dstEntry.getAttribute(attrCert);
// Check for changes to the certificate value.
boolean differ = false;
if (srcList == null)
{
if (dstList != null)
{
differ = true;
}
}
else if (dstList == null
|| srcList.size() != dstList.size()
|| !srcList.equals(dstList))
{
differ = true;
}
if (differ)
{
// The trust store backend does not implement modify so we need to
// delete then add.
DN dstDN = dstEntry.getName();
deleteEntry(dstDN);
addEntry(srcEntry, dstDN);
}
}
/**
* Delete an entry from the local trust store.
* @param dstDN The DN of the entry to be deleted in the local trust store.
*/
private static void deleteEntry(DN dstDN)
{
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
DeleteOperation delOperation = conn.processDelete(dstDN);
if (delOperation.getResultCode() != ResultCode.SUCCESS)
{
logger.debug(INFO_TRUSTSTORESYNC_DELETE_FAILED, dstDN, delOperation.getErrorMessage());
}
}
/**
* Add an entry to the local trust store.
* @param srcEntry The instance key entry in the ADS branch.
* @param dstDN The DN of the entry to be added in the local trust store.
*/
private void addEntry(Entry srcEntry, DN dstDN)
{
Map<ObjectClass, String> ocMap = new LinkedHashMap<>(2);
ocMap.put(DirectoryServer.getTopObjectClass(), OC_TOP);
ocMap.put(ocInstanceKey, OC_CRYPTO_INSTANCE_KEY);
Map<AttributeType, List<Attribute>> userAttrs = new HashMap<>();
List<Attribute> attrList;
attrList = srcEntry.getAttribute(attrAlias);
if (attrList != null)
{
userAttrs.put(attrAlias, attrList);
}
attrList = srcEntry.getAttribute(attrCert);
if (attrList != null)
{
userAttrs.put(attrCert, attrList);
}
Entry addEntry = new Entry(dstDN, ocMap, userAttrs, null);
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
AddOperation addOperation = conn.processAdd(addEntry);
if (addOperation.getResultCode() != ResultCode.SUCCESS)
{
logger.debug(INFO_TRUSTSTORESYNC_ADD_FAILED, dstDN, addOperation.getErrorMessage());
}
}
/** {@inheritDoc} */
@Override
public PostResponse doPostResponse(PostResponseAddOperation op)
{
if (op.getResultCode() != ResultCode.SUCCESS)
{
return PostResponse.continueOperationProcessing();
}
final Entry entry = op.getEntryToAdd();
final DN entryDN = op.getEntryDN();
if (entryDN.isDescendantOf(instanceKeysDN))
{
handleInstanceKeyAddOperation(entry);
}
else if (entryDN.isDescendantOf(secretKeysDN))
{
try
{
if (entry.hasObjectClass(ocCipherKey))
{
DirectoryServer.getCryptoManager().importCipherKeyEntry(entry);
}
else if (entry.hasObjectClass(ocMacKey))
{
DirectoryServer.getCryptoManager().importMacKeyEntry(entry);
}
}
catch (CryptoManagerException e)
{
logger.error(LocalizableMessage.raw(
"Failed to import key entry: %s", e.getMessage()));
}
}
return PostResponse.continueOperationProcessing();
}
private void handleInstanceKeyAddOperation(Entry entry)
{
RDN srcRDN = entry.getName().rdn();
// Only process the entry if it has the expected form of RDN.
if (!srcRDN.isMultiValued() &&
srcRDN.getAttributeType(0).equals(attrAlias))
{
DN dstDN = trustStoreRootDN.child(srcRDN);
if (!entry.hasAttribute(attrCompromisedTime))
{
addEntry(entry, dstDN);
}
}
}
/** {@inheritDoc} */
@Override
public PostResponse doPostResponse(PostResponseDeleteOperation op)
{
if (op.getResultCode() != ResultCode.SUCCESS
|| !op.getEntryDN().isDescendantOf(instanceKeysDN))
{
return PostResponse.continueOperationProcessing();
}
RDN srcRDN = op.getEntryToDelete().getName().rdn();
// Only process the entry if it has the expected form of RDN.
// FIXME: Technically it is possible to perform a subtree in
// this case however such subtree delete would essentially be
// removing configuration branches which should not happen.
if (!srcRDN.isMultiValued() &&
srcRDN.getAttributeType(0).equals(attrAlias))
{
DN destDN = trustStoreRootDN.child(srcRDN);
deleteEntry(destDN);
}
return PostResponse.continueOperationProcessing();
}
/** {@inheritDoc} */
@Override
public PostResponse doPostResponse(PostResponseModifyOperation op)
{
if (op.getResultCode() != ResultCode.SUCCESS)
{
return PostResponse.continueOperationProcessing();
}
final Entry newEntry = op.getModifiedEntry();
final DN entryDN = op.getEntryDN();
if (entryDN.isDescendantOf(instanceKeysDN))
{
handleInstanceKeyModifyOperation(newEntry);
}
else if (entryDN.isDescendantOf(secretKeysDN))
{
try
{
if (newEntry.hasObjectClass(ocCipherKey))
{
DirectoryServer.getCryptoManager().importCipherKeyEntry(newEntry);
}
else if (newEntry.hasObjectClass(ocMacKey))
{
DirectoryServer.getCryptoManager().importMacKeyEntry(newEntry);
}
}
catch (CryptoManagerException e)
{
logger.error(LocalizableMessage.raw(
"Failed to import modified key entry: %s", e.getMessage()));
}
}
return PostResponse.continueOperationProcessing();
}
private void handleInstanceKeyModifyOperation(Entry newEntry)
{
RDN srcRDN = newEntry.getName().rdn();
// Only process the entry if it has the expected form of RDN.
if (!srcRDN.isMultiValued() &&
srcRDN.getAttributeType(0).equals(attrAlias))
{
DN dstDN = trustStoreRootDN.child(srcRDN);
// Get any existing local trust store entry.
Entry dstEntry = null;
try
{
dstEntry = DirectoryServer.getEntry(dstDN);
}
catch (DirectoryException e)
{
// ignore
}
if (newEntry.hasAttribute(attrCompromisedTime))
{
// The key was compromised so we should remove it from the local
// trust store.
if (dstEntry != null)
{
deleteEntry(dstDN);
}
}
else if (dstEntry == null)
{
addEntry(newEntry, dstDN);
}
else
{
modifyEntry(newEntry, dstEntry);
}
}
}
}