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

david_page
02.15.2007 29496a268e4c8bc20ac711bcef619e87c514f888
issue 466 (partial)
secret key re-wrapping (extended operation support)
4 files modified
194 ■■■■ changed files
opends/src/ads/org/opends/admin/ads/ADSContext.java 51 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/schema/BinarySyntax.java 26 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/CryptoManager.java 115 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/GetSymmetricKeyExtendedOperationTestCase.java 2 ●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ADSContext.java
@@ -57,6 +57,9 @@
import javax.naming.ldap.Control;
import javax.naming.ldap.LdapContext;
import org.opends.server.types.CryptoManager;
import org.opends.server.config.ConfigConstants;
/**
 * Class used to update and read the contents of the Administration Data.
 */
@@ -169,13 +172,15 @@
    /**
     * The unique name of the instance key public-key certificate.
     */
    INSTANCE_KEY_ID("ds-cfg-key-id", ADSPropertySyntax.STRING),
    INSTANCE_KEY_ID(ConfigConstants.ATTR_CRYPTO_KEY_ID,
            ADSPropertySyntax.STRING),
    /**
     * The instance key-pair public-key certificate. Note: This attribute
     * belongs to an instance key entry, separate from the server entry and
     * named by the ds-cfg-key-id attribute from the server entry.
     */
    INSTANCE_PUBLIC_KEY_CERTIFICATE("ds-cfg-public-key-certificate"/*;binary*/,
    INSTANCE_PUBLIC_KEY_CERTIFICATE(
            ConfigConstants.ATTR_CRYPTO_PUBLIC_KEY_CERTIFICATE/*binary*/,
            ADSPropertySyntax.CERTIFICATE_BINARY);
    private String attrName;
@@ -431,7 +436,7 @@
      throw new ADSContextException(
          ADSContextException.ErrorType.ALREADY_REGISTERED);
    }
    catch (NamingException x)
    catch (Exception x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
@@ -476,7 +481,7 @@
      throw new ADSContextException(
          ADSContextException.ErrorType.NOT_YET_REGISTERED);
    }
    catch (NamingException x)
    catch (Exception x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
@@ -2048,7 +2053,7 @@
   Returns the parent entry of the server key entries in ADS.
   @return the parent entry of the server key entries in ADS.
   */
  private static String getInstanceKeysContainerDN()
  public static String getInstanceKeysContainerDN()
  {
    return "cn=instance keys," + getAdministrationSuffixDN();
  }
@@ -2064,11 +2069,14 @@
   the instance key entry belongs.
   @param serverEntryDn The server's ADS entry DN.
   @throws NamingException In case some JNDI operation fails.
   @throws CryptoManager.CryptoManagerException In case there is a problem
   getting the instance public key certificate ID.
   */
  private void registerInstanceKeyCertificate(
          Map<ServerProperty, Object> serverProperties,
          LdapName serverEntryDn) throws NamingException
  {
          LdapName serverEntryDn)
          throws NamingException,
          CryptoManager.CryptoManagerException {
    assert serverProperties.containsKey(
                                ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE);
    if (! serverProperties.containsKey(
@@ -2117,7 +2125,9 @@
    else {
      /* create key ID, if it was not supplied in serverProperties */
      if (null == keyID) {
        keyID = java.util.UUID.randomUUID().toString();
        keyID = CryptoManager.getInstanceKeyID(
                (byte[])serverProperties.get(
                        ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE));
        keyAttrs.put(new BasicAttribute(
                ServerProperty.INSTANCE_KEY_ID.getAttributeName(), keyID));
      }
@@ -2142,18 +2152,29 @@
   public-key certificate entries in ADS.
   @return The set of valid (i.e., not tagged as compromised) instance key-pair
   public-key certificate entries in ADS represented as a Map from ds-cfg-key-id
   value to ds-cfg-public-key-certificate;binary value Note that the collection
   value to ds-cfg-public-key-certificate;binary value. Note that the collection
   might be empty.
   @throws ADSContextException in case of problems with the entry search.
   @see org.opends.server.types.CryptoManager#getTrustedCertificates
   */
  public Map<String,byte[]> getTrustedCertificates()
          throws ADSContextException
  {
    Map<String, byte[]> keyEntryMap = new HashMap<String, byte[]>();
    final Map<String, byte[]> certificateMap = new HashMap<String, byte[]>();
    final String baseDNStr = getInstanceKeysContainerDN();
    try {
      final LdapName baseDN = new LdapName(getInstanceKeysContainerDN());
      final String searchFilter =
       "(&(objectclass=ds-cfg-instance-key)(!(ds-cfg-key-compromised-time=*)))";
      final LdapName baseDN = new LdapName(baseDNStr);
      final String FILTER_OC_INSTANCE_KEY
           = new StringBuilder("(objectclass=")
           .append(ConfigConstants.OC_CRYPTO_INSTANCE_KEY)
           .append(")").toString();
      final String FILTER_NOT_COMPROMISED = new StringBuilder("(!(")
              .append(ConfigConstants.ATTR_CRYPTO_KEY_COMPROMISED_TIME)
              .append("=*))").toString();
      final String searchFilter = new StringBuilder("(&")
              .append(FILTER_OC_INSTANCE_KEY)
              .append(FILTER_NOT_COMPROMISED)
              .append(")").toString();
      final SearchControls searchControls = new SearchControls();
      searchControls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
      final String attrIDs[]= {
@@ -2169,13 +2190,13 @@
        final Attribute keyIDAttr = attrs.get(attrIDs[0]);
        final Attribute keyCertAttr = attrs.get(attrIDs[1]);
        if (null == keyIDAttr || null == keyCertAttr) continue; // schema viol.
        keyEntryMap.put((String)keyIDAttr.get(), (byte[])keyCertAttr.get());
        certificateMap.put((String)keyIDAttr.get(), (byte[])keyCertAttr.get());
      }
    }
    catch (NamingException x) {
      throw new ADSContextException(
              ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return keyEntryMap;
    return certificateMap;
  }
}
opends/src/server/org/opends/server/schema/BinarySyntax.java
@@ -29,14 +29,12 @@
import org.opends.server.admin.std.server.AttributeSyntaxCfg;
import org.opends.server.api.ApproximateMatchingRule;
import org.opends.server.api.AttributeSyntax;
import org.opends.server.api.EqualityMatchingRule;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.api.SubstringMatchingRule;
import org.opends.server.api.*;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.ByteString;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DirectoryException;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.messages.SchemaMessages.*;
@@ -65,6 +63,24 @@
  /**
   * A {@code byte[]} attribute value decoder for this syntax.
   */
  public static final AttributeValueDecoder<byte[]> DECODER =
    new AttributeValueDecoder<byte[]>()
  {
    /**
     * {@inheritDoc}
     */
    public byte[] decode(AttributeValue value) throws DirectoryException {
      // Make sure that the value is valid.
      value.getNormalizedValue();
      return value.getValueBytes();
    }
  };
  /**
   * Creates a new instance of this syntax.  Note that the only thing that
   * should be done here is to invoke the default constructor for the
   * superclass.  All initialization should be performed in the
opends/src/server/org/opends/server/types/CryptoManager.java
@@ -68,6 +68,8 @@
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.schema.DirectoryStringSyntax;
import org.opends.server.schema.IntegerSyntax;
import org.opends.server.schema.BinarySyntax;
import org.opends.admin.ads.ADSContext;
/**
 * This class provides the interface to the Directory Server
@@ -91,6 +93,18 @@
   */
  private static final DebugTracer TRACER = getTracer();
  // Various schema element references.
  private final AttributeType attrKeyID;
  private final AttributeType attrPublicKeyCertificate;
  private final AttributeType attrTransformation;
  private final AttributeType attrMacAlgorithm;
  private final AttributeType attrSymmetricKey;
  private final AttributeType attrInitVectorLength;
  private final AttributeType attrKeyLength;
  private final AttributeType attrCompromisedTime;
  private final ObjectClass   ocCipherKey;
  private final ObjectClass   ocMacKey;
  // The secure random number generator used for key generation,
  // initialization vector PRNG seed...
  private static final SecureRandom secureRandom = new SecureRandom();
@@ -100,9 +114,6 @@
  private static final Random pseudoRandom
          = new Random(secureRandom.nextLong());
  // The preferred key wrapping transformation
  private final String preferredKeyWrappingTransformation;
  // The preferred message digest algorithm for the Directory Server.
  private final String preferredDigestAlgorithm;
@@ -126,6 +137,9 @@
  // The preferred key length for the preferred cipher.
  private final int preferredCipherTransformationKeyLengthBits;
  // The preferred key wrapping transformation
  private final String preferredKeyWrappingTransformation;
  // The name of the local certificate to use for SSL.
  private final String sslCertNickname;
@@ -138,17 +152,6 @@
  // The set of SSL cipher suites enabled or null for the default set.
  private final SortedSet<String> sslCipherSuites;
  // Various schema element references.
  private final AttributeType attrKeyID;
  private final AttributeType attrTransformation;
  private final AttributeType attrMacAlgorithm;
  private final AttributeType attrSymmetricKey;
  private final AttributeType attrInitVectorLength;
  private final AttributeType attrKeyLength;
  private final AttributeType attrCompromisedTime;
  private final ObjectClass   ocCipherKey;
  private final ObjectClass   ocMacKey;
  /**
   * Creates a new instance of this crypto manager object from a given
@@ -171,6 +174,8 @@
    // Initialize various schema references.
    attrKeyID = DirectoryServer.getAttributeType(
         ConfigConstants.ATTR_CRYPTO_KEY_ID);
    attrPublicKeyCertificate = DirectoryServer.getAttributeType(
                 ConfigConstants.ATTR_CRYPTO_PUBLIC_KEY_CERTIFICATE);
    attrTransformation = DirectoryServer.getAttributeType(
         ConfigConstants.ATTR_CRYPTO_CIPHER_TRANSFORMATION_NAME);
    attrMacAlgorithm = DirectoryServer.getAttributeType(
@@ -340,9 +345,8 @@
         final Entry e = searchOp.getSearchEntries().getFirst();
         /* attribute ds-cfg-public-key-certificate is a MUST in the
            schema */
         final List<Attribute> attrs =
            e.getAttribute(DirectoryServer.getAttributeType(
                 ConfigConstants.ATTR_CRYPTO_PUBLIC_KEY_CERTIFICATE));
         final List<Attribute> attrs
                 = e.getAttribute(attrPublicKeyCertificate);
         final Attribute a = attrs.get(0);
         final AttributeValue v = a.getValues().iterator().next();
         certificate = v.getValueBytes();
@@ -411,7 +415,7 @@
   * @throws CryptoManagerException If there is a problem computing
   * the identifier from the instance key.
   */
  public String getInstanceKeyID(byte[] instanceKeyCertificate)
  public static String getInstanceKeyID(byte[] instanceKeyCertificate)
            throws CryptoManagerException {
    MessageDigest md;
    final String mdAlgorithmName = "MD5";
@@ -430,6 +434,74 @@
  /**
   Return the set of valid (i.e., not tagged as compromised) instance
   key-pair public-key certificate entries in ADS.
   @return The set of valid (i.e., not tagged as compromised) instance
   key-pair public-key certificate entries in ADS represented as a Map
   from ds-cfg-key-id value to ds-cfg-public-key-certificate;binary
   value. Note that the collection might be empty.
   @throws CryptoManagerException  In case of a problem with the
   search operation.
   @see org.opends.admin.ads.ADSContext#getTrustedCertificates()
   */
  private Map<String, byte[]> getTrustedCertificates()
          throws CryptoManagerException {
    final Map<String, byte[]> certificateMap
            = new HashMap<String, byte[]>();
    final String baseDNStr = ADSContext.getInstanceKeysContainerDN();
    try {
      final DN baseDN = DN.decode(baseDNStr);
      final String FILTER_OC_INSTANCE_KEY
              = new StringBuilder("(objectclass=")
              .append(ConfigConstants.OC_CRYPTO_INSTANCE_KEY)
              .append(")").toString();
      final String FILTER_NOT_COMPROMISED = new StringBuilder("(!(")
             .append(ConfigConstants.ATTR_CRYPTO_KEY_COMPROMISED_TIME)
              .append("=*))").toString();
      final String searchFilter = new StringBuilder("(&")
              .append(FILTER_OC_INSTANCE_KEY)
              .append(FILTER_NOT_COMPROMISED)
              .append(")").toString();
      final LinkedHashSet<String> requestedAttributes
              = new LinkedHashSet<String>();
      requestedAttributes.add(ConfigConstants.ATTR_CRYPTO_KEY_ID);
      final String ATTR_INSTANCE_KEY_CERTIFICATE_BINARY
              = ConfigConstants.ATTR_CRYPTO_PUBLIC_KEY_CERTIFICATE
              + ";binary";
      requestedAttributes.add(ATTR_INSTANCE_KEY_CERTIFICATE_BINARY);
      final InternalClientConnection icc
              = InternalClientConnection.getRootConnection();
      InternalSearchOperation searchOp = icc.processSearch(
              baseDN,
              SearchScope.SINGLE_LEVEL,
              DereferencePolicy.NEVER_DEREF_ALIASES,
              /* size limit */ 0, /* time limit */ 0,
              /* types only */ false,
              SearchFilter.createFilterFromString(searchFilter),
              requestedAttributes);
      for (Entry e : searchOp.getSearchEntries()) {
        /* attribute ds-cfg-key-id is the RDN and attribute
           ds-cfg-public-key-certificate is a MUST in the schema */
        final String keyID = e.getAttributeValue(
                attrKeyID, DirectoryStringSyntax.DECODER);
        final byte[] certificate = e.getAttributeValue(
                attrPublicKeyCertificate, BinarySyntax.DECODER);
        certificateMap.put(keyID, certificate);
      }
    }
    catch (DirectoryException ex) {
      throw new CryptoManagerException(
              // TODO: i18n
              Message.raw("Error retrieving instance-key public key" +
                      " certificates from ADS container %s.",
                      baseDNStr), ex);
    }
    return(certificateMap);
  }
  /**
   * Encodes a ds-cfg-symmetric-key attribute value using the supplied
   * arguments.
   *
@@ -640,7 +712,12 @@
          final String symmetricKeyAttribute,
          final String requestedInstanceKeyID)
          throws CryptoManagerException {
    return symmetricKeyAttribute; // TODO: really unwrap and rewrap
    final SecretKey secretKey
            = decodeSymmetricKeyAttribute(symmetricKeyAttribute);
    final byte[] wrappingKeyCert
            = getTrustedCertificates().get(requestedInstanceKeyID);
    return encodeSymmetricKeyAttribute(
            requestedInstanceKeyID, wrappingKeyCert, secretKey);
  }
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/GetSymmetricKeyExtendedOperationTestCase.java
@@ -60,7 +60,7 @@
  @Test
  @Test(enabled=false)
  public void testValidRequest() throws Exception
  {
    CryptoManager cm = DirectoryServer.getCryptoManager();