/**
   * Tests whether the Who Am I? extended operation with an internal authenticated connection
   * succeeds with new setting of "ds-cfg-reject-unauthenticated-requests".
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test
  public void testAuthWAINewCfg() throws Exception {
    try {
      DirectoryServer.setRejectUnauthenticatedRequests(true);

      InternalClientConnection conn = InternalClientConnection.getRootConnection();
      ExtendedOperation extOp = conn.processExtendedOperation(OID_WHO_AM_I_REQUEST, null);
      assertEquals(extOp.getResultCode(), ResultCode.SUCCESS);
      assertNotNull(extOp.getResponseValue());
    } finally {
      DirectoryServer.setRejectUnauthenticatedRequests(false);
    }
  }
  @Test()
  public void testInvalidRequest() throws Exception {
    CryptoManagerImpl cm = DirectoryServer.getCryptoManager();

    String symmetricKey = "1";
    String instanceKeyID = cm.getInstanceKeyID();

    ByteString 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);
  }
  @Test(enabled = true)
  public void testValidRequest() throws Exception {
    final CryptoManagerImpl cm = DirectoryServer.getCryptoManager();
    final String secretMessage = "zyxwvutsrqponmlkjihgfedcba";
    final String cipherTransformationName = "AES/CBC/PKCS5Padding";
    final int cipherKeyLength = 128;

    CryptoManagerImpl.publishInstanceKeyEntryInADS();

    // Initial encryption ensures a cipher key entry is in ADS.
    cm.encrypt(cipherTransformationName, cipherKeyLength, secretMessage.getBytes());

    // Retrieve all uncompromised cipher key entries corresponding to the
    // specified transformation and key length.
    final String baseDNStr // TODO: is this DN defined elsewhere as a constant?
        = "cn=secret keys," + ADSContext.getAdministrationSuffixDN();
    final DN baseDN = DN.decode(baseDNStr);
    final String FILTER_OC_INSTANCE_KEY =
        new StringBuilder("(objectclass=")
            .append(ConfigConstants.OC_CRYPTO_CIPHER_KEY)
            .append(")")
            .toString();
    final String FILTER_NOT_COMPROMISED =
        new StringBuilder("(!(")
            .append(ConfigConstants.ATTR_CRYPTO_KEY_COMPROMISED_TIME)
            .append("=*))")
            .toString();
    final String FILTER_CIPHER_TRANSFORMATION_NAME =
        new StringBuilder("(")
            .append(ConfigConstants.ATTR_CRYPTO_CIPHER_TRANSFORMATION_NAME)
            .append("=")
            .append(cipherTransformationName)
            .append(")")
            .toString();
    final String FILTER_CIPHER_KEY_LENGTH =
        new StringBuilder("(")
            .append(ConfigConstants.ATTR_CRYPTO_KEY_LENGTH_BITS)
            .append("=")
            .append(String.valueOf(cipherKeyLength))
            .append(")")
            .toString();
    final String searchFilter =
        new StringBuilder("(&")
            .append(FILTER_OC_INSTANCE_KEY)
            .append(FILTER_NOT_COMPROMISED)
            .append(FILTER_CIPHER_TRANSFORMATION_NAME)
            .append(FILTER_CIPHER_KEY_LENGTH)
            .append(")")
            .toString();
    final LinkedHashSet<String> requestedAttributes = new LinkedHashSet<String>();
    requestedAttributes.add(ConfigConstants.ATTR_CRYPTO_SYMMETRIC_KEY);
    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);
    assertTrue(0 < searchOp.getSearchEntries().size());

    final InternalClientConnection internalConnection =
        InternalClientConnection.getRootConnection();
    final String instanceKeyID = cm.getInstanceKeyID();
    final AttributeType attrSymmetricKey =
        DirectoryServer.getAttributeType(ConfigConstants.ATTR_CRYPTO_SYMMETRIC_KEY);
    for (Entry e : searchOp.getSearchEntries()) {
      final String symmetricKeyAttributeValue =
          e.getAttributeValue(attrSymmetricKey, DirectoryStringSyntax.DECODER);
      final ByteString requestValue =
          GetSymmetricKeyExtendedOperation.encodeRequestValue(
              symmetricKeyAttributeValue, instanceKeyID);
      final ExtendedOperation extendedOperation =
          internalConnection.processExtendedOperation(
              ServerConstants.OID_GET_SYMMETRIC_KEY_EXTENDED_OP, requestValue);
      assertEquals(extendedOperation.getResultCode(), ResultCode.SUCCESS);
      // The key should be re-wrapped, and hence have a different binary
      // representation....
      final String responseValue = extendedOperation.getResponseValue().toString();
      assertFalse(symmetricKeyAttributeValue.equals(responseValue));
      // ... but the keyIDs should be equal (ideally, the validity of
      // the returned value would be checked by decoding the
      // returned ds-cfg-symmetric-key attribute value; however, there
      // is no non-private method to call.
      assertEquals(responseValue.split(":")[0], symmetricKeyAttributeValue.split(":")[0]);
    }
  }