| opends/resource/config/config.ldif | ●●●●● patch | view | raw | blame | history | |
| opends/src/messages/messages/backend.properties | ●●●●● patch | view | raw | blame | history | |
| opends/src/messages/messages/extension.properties | ●●●●● patch | view | raw | blame | history | |
| opends/src/server/org/opends/server/backends/TrustStoreBackend.java | ●●●●● patch | view | raw | blame | history | |
| opends/src/server/org/opends/server/extensions/GetSymmetricKeyExtendedOperation.java | ●●●●● patch | view | raw | blame | history | |
| opends/src/server/org/opends/server/util/ServerConstants.java | ●●●●● patch | view | raw | blame | history | |
| opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/GetSymmetricKeyExtendedOperationTestCase.java | ●●●●● patch | view | raw | blame | history |
opends/resource/config/config.ldif
@@ -539,6 +539,13 @@ ds-cfg-extended-operation-handler-class: org.opends.server.extensions.StartTLSExtendedOperation ds-cfg-extended-operation-handler-enabled: true dn: cn=Get Symmetric Key,cn=Extended Operations,cn=config objectClass: top objectClass: ds-cfg-extended-operation-handler cn: Get Symmetric Key ds-cfg-extended-operation-handler-class: org.opends.server.extensions.GetSymmetricKeyExtendedOperation ds-cfg-extended-operation-handler-enabled: true dn: cn=Who Am I,cn=Extended Operations,cn=config objectClass: top objectClass: ds-cfg-extended-operation-handler opends/src/messages/messages/backend.properties
@@ -1030,3 +1030,5 @@ does not exist MILD_ERR_LDIF_BACKEND_NUM_SUBORDINATES_NO_SUCH_ENTRY_366=The target entry %s \ does not exist SEVERE_ERR_TRUSTSTORE_ERROR_READING_KEY_367=Error reading key %s from key \ store %s: %s opends/src/messages/messages/extension.properties
@@ -1589,3 +1589,12 @@ encrypt a value using password storage scheme %s: %s SEVERE_ERR_PWSCHEME_CANNOT_DECRYPT_560=An error occurred while trying to \ decrypt a value using password storage scheme %s: %s MILD_ERR_GET_SYMMETRIC_KEY_NO_VALUE_561=Cannot decode the provided \ symmetric key extended operation because it does not have a value MILD_ERR_GET_SYMMETRIC_KEY_INVALID_TYPE_562=Cannot decode the provided \ symmetric key extended operation because the value sequence has an element \ with an invalid type of %s MILD_ERR_GET_SYMMETRIC_KEY_ASN1_DECODE_EXCEPTION_563=Cannot decode the \ provided symmetric key extended request: %s MILD_ERR_GET_SYMMETRIC_KEY_DECODE_EXCEPTION_564=An unexpected error occurred \ while attempting to decode the symmetric key extended request sequence: %s opends/src/server/org/opends/server/backends/TrustStoreBackend.java
@@ -39,6 +39,7 @@ import java.util.*; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.Key; import org.opends.server.api.Backend; import org.opends.server.config.ConfigException; @@ -1425,6 +1426,63 @@ } /** * 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. */ public Key getKey(String alias) throws DirectoryException { KeyStore trustStore; try { trustStore = KeyStore.getInstance(trustStoreType); FileInputStream inputStream = new FileInputStream(getFileForPath(trustStoreFile)); trustStore.load(inputStream, trustStorePIN); inputStream.close(); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_TRUSTSTORE_CANNOT_LOAD.get( trustStoreFile, getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); } try { return trustStore.getKey(alias, trustStorePIN); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_TRUSTSTORE_ERROR_READING_KEY.get( alias, trustStoreFile, getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); } } private void addCertificate(Entry entry) throws DirectoryException { opends/src/server/org/opends/server/extensions/GetSymmetricKeyExtendedOperation.java
New file @@ -0,0 +1,266 @@ /* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 * * * Portions Copyright 2007 Sun Microsystems, Inc. */ package org.opends.server.extensions; import org.opends.server.admin.std.server.ExtendedOperationHandlerCfg; import org.opends.server.api.ExtendedOperationHandler; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.loggers.debug.DebugLogger; import org.opends.server.types.*; import org.opends.server.config.ConfigException; import org.opends.server.core.DirectoryServer; import org.opends.server.core.ExtendedOperation; import org.opends.server.protocols.asn1.ASN1Sequence; import org.opends.server.protocols.asn1.ASN1Element; import org.opends.server.protocols.asn1.ASN1Exception; import org.opends.server.protocols.asn1.ASN1OctetString; import org.opends.server.util.StaticUtils; import org.opends.server.util.ServerConstants; import org.opends.messages.Message; import static org.opends.messages.ExtensionMessages.*; import java.util.Set; import java.util.HashSet; import java.util.ArrayList; /** * This class implements the get symmetric key extended operation, an OpenDS * proprietary extension used for distribution of symmetric keys amongst * servers. */ public class GetSymmetricKeyExtendedOperation extends ExtendedOperationHandler<ExtendedOperationHandlerCfg> { /** * The tracer object for the debug logger. */ private static final DebugTracer TRACER = DebugLogger.getTracer(); /** * The BER type value for the symmetric key element of the operation value. */ public static final byte TYPE_SYMMETRIC_KEY_ELEMENT = (byte) 0x80; /** * The BER type value for the instance key ID element of the operation value. */ public static final byte TYPE_INSTANCE_KEY_ID_ELEMENT = (byte) 0x81; // The default set of supported control OIDs for this extended operation. private Set<String> supportedControlOIDs = new HashSet<String>(0); /** * Create an instance of this symmetric key extended operation. All * initialization should be performed in the * <CODE>initializeExtendedOperationHandler</CODE> method. */ public GetSymmetricKeyExtendedOperation() { super(); } /** * {@inheritDoc} */ public void initializeExtendedOperationHandler( ExtendedOperationHandlerCfg config) throws ConfigException, InitializationException { supportedControlOIDs = new HashSet<String>(); DirectoryServer.registerSupportedExtension( ServerConstants.OID_GET_SYMMETRIC_KEY_EXTENDED_OP, this); registerControlsAndFeatures(); } /** * Performs any finalization that may be necessary for this extended * operation handler. By default, no finalization is performed. */ public void finalizeExtendedOperationHandler() { DirectoryServer.deregisterSupportedExtension( ServerConstants.OID_GET_SYMMETRIC_KEY_EXTENDED_OP); deregisterControlsAndFeatures(); } /** * {@inheritDoc} */ @Override() public Set<String> getSupportedControls() { return supportedControlOIDs; } /** * Processes the provided extended operation. * * @param operation The extended operation to be processed. */ public void processExtendedOperation(ExtendedOperation operation) { // Initialize the variables associated with components that may be included // in the request. byte[] requestSymmetricKey = null; byte[] instanceKeyID = null; // Parse the encoded request, if there is one. ByteString requestValue = operation.getRequestValue(); if (requestValue == null) { // The request must always have a value. Message message = ERR_GET_SYMMETRIC_KEY_NO_VALUE.get(); operation.appendErrorMessage(message); return; } try { ASN1Sequence valueSequence = ASN1Sequence.decodeAsSequence(requestValue.value()); for (ASN1Element e : valueSequence.elements()) { switch (e.getType()) { case TYPE_SYMMETRIC_KEY_ELEMENT: requestSymmetricKey = ASN1OctetString.decodeAsOctetString(e).value(); break; case TYPE_INSTANCE_KEY_ID_ELEMENT: instanceKeyID = ASN1OctetString.decodeAsOctetString(e).value(); break; default: Message message = ERR_GET_SYMMETRIC_KEY_INVALID_TYPE.get( StaticUtils.byteToHex(e.getType())); operation.appendErrorMessage(message); return; } } } catch (ASN1Exception ae) { if (DebugLogger.debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, ae); } Message message = ERR_GET_SYMMETRIC_KEY_ASN1_DECODE_EXCEPTION.get( ae.getMessage()); operation.appendErrorMessage(message); return; } catch (Exception e) { if (DebugLogger.debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } operation.setResultCode(ResultCode.PROTOCOL_ERROR); Message message = ERR_GET_SYMMETRIC_KEY_DECODE_EXCEPTION.get( StaticUtils.getExceptionMessage(e)); operation.appendErrorMessage(message); return; } CryptoManager cm = DirectoryServer.getCryptoManager(); try { byte[] responseSymmetricKey = cm.rewrapSymmetricKeyAttribute( requestSymmetricKey, instanceKeyID); operation.setResponseOID( ServerConstants.OID_GET_SYMMETRIC_KEY_EXTENDED_OP); operation.setResponseValue(new ASN1OctetString(responseSymmetricKey)); operation.setResultCode(ResultCode.SUCCESS); } catch (CryptoManager.CryptoManagerException e) { operation.setResultCode(DirectoryServer.getServerErrorResultCode()); operation.appendErrorMessage(e.getMessageObject()); } } /** * Encodes the provided information into an ASN.1 octet string suitable for * use as the value for this extended operation. * * @param symmetricKey The wrapped key to use for this request control. * @param instanceKeyID The requesting server instance key ID to use for * this request control. * * @return An ASN.1 octet string containing the encoded request value. */ public static ASN1OctetString encodeRequestValue( byte[] symmetricKey, byte[] instanceKeyID) { ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2); ASN1OctetString symmetricKeyElement = new ASN1OctetString(TYPE_SYMMETRIC_KEY_ELEMENT, symmetricKey); elements.add(symmetricKeyElement); ASN1OctetString instanceKeyIDElement = new ASN1OctetString(TYPE_INSTANCE_KEY_ID_ELEMENT, instanceKeyID); elements.add(instanceKeyIDElement); ASN1Sequence valueSequence = new ASN1Sequence(elements); return new ASN1OctetString(valueSequence.encode()); } } opends/src/server/org/opends/server/util/ServerConstants.java
@@ -775,6 +775,14 @@ /** * The request OID for the get symmetric key extended operation. */ public static final String OID_GET_SYMMETRIC_KEY_EXTENDED_OP = "1.3.6.1.4.1.26027.1.6.3"; /** * The name of the standard "ldapSubentry" objectclass (which is a special * type of objectclass that makes a kind of "operational" entry), formatted * in camel case. opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/GetSymmetricKeyExtendedOperationTestCase.java
New file @@ -0,0 +1,111 @@ /* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 * * * Portions Copyright 2007 Sun Microsystems, Inc. */ package org.opends.server.extensions; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.opends.server.TestCaseUtils; import org.opends.server.types.ResultCode; import org.opends.server.types.CryptoManager; import org.opends.server.core.ExtendedOperation; import org.opends.server.core.DirectoryServer; import org.opends.server.util.ServerConstants; import org.opends.server.protocols.asn1.ASN1OctetString; import org.opends.server.protocols.internal.InternalClientConnection; import static org.testng.Assert.*; import static org.testng.Assert.assertEquals; import java.util.Arrays; /** * A set of test cases for the symmetric key extended operation. */ public class GetSymmetricKeyExtendedOperationTestCase extends ExtensionsTestCase { /** * Ensures that the Directory Server is running. * * @throws Exception If an unexpected problem occurs. */ @BeforeClass() public void startServer() throws Exception { TestCaseUtils.startServer(); } @Test public void testValidRequest() throws Exception { CryptoManager cm = DirectoryServer.getCryptoManager(); // TODO use a proper symmetric key value byte[] symmetricKey = cm.getInstanceKeyID(); byte[] instanceKeyID = cm.getInstanceKeyID(); ASN1OctetString requestValue = GetSymmetricKeyExtendedOperation.encodeRequestValue( symmetricKey, instanceKeyID); InternalClientConnection internalConnection = InternalClientConnection.getRootConnection(); ExtendedOperation extendedOperation = internalConnection.processExtendedOperation( ServerConstants.OID_GET_SYMMETRIC_KEY_EXTENDED_OP, requestValue); assertEquals(extendedOperation.getResultCode(), ResultCode.SUCCESS); assertTrue(Arrays.equals( extendedOperation.getResponseValue().value(), symmetricKey)); } @Test public void testInvalidRequest() throws Exception { CryptoManager cm = DirectoryServer.getCryptoManager(); // byte[] symmetricKey = new byte[1]; // FIXME causes ArrayOutOfBounds! byte[] symmetricKey = new byte[16]; byte[] instanceKeyID = cm.getInstanceKeyID(); ASN1OctetString requestValue = GetSymmetricKeyExtendedOperation.encodeRequestValue( symmetricKey, instanceKeyID); InternalClientConnection internalConnection = InternalClientConnection.getRootConnection(); ExtendedOperation extendedOperation = internalConnection.processExtendedOperation( ServerConstants.OID_GET_SYMMETRIC_KEY_EXTENDED_OP, requestValue); assertFalse(extendedOperation.getResultCode() == ResultCode.SUCCESS); } }