directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r896130 - in /directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl: LdapsIT.java LdapsUpdateCertificateIT.java StartTlsConfidentialityIT.java StartTlsIT.java StartTlsUpdateCertificateIT.java
Date Tue, 05 Jan 2010 17:11:29 GMT
Author: elecharny
Date: Tue Jan  5 17:11:29 2010
New Revision: 896130

URL: http://svn.apache.org/viewvc?rev=896130&view=rev
Log:
Split the Ldaps and StartTls tests to avoid some bad interaction between them

Added:
    directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/LdapsUpdateCertificateIT.java
    directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsConfidentialityIT.java
    directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsUpdateCertificateIT.java
Modified:
    directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/LdapsIT.java
    directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsIT.java

Modified: directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/LdapsIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/LdapsIT.java?rev=896130&r1=896129&r2=896130&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/LdapsIT.java (original)
+++ directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/LdapsIT.java Tue Jan  5 17:11:29 2010
@@ -20,28 +20,21 @@
 package org.apache.directory.server.ssl;
 
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
-import java.security.cert.X509Certificate;
 import java.util.Hashtable;
 
 import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
-import javax.naming.directory.BasicAttribute;
-import javax.naming.directory.BasicAttributes;
 import javax.naming.directory.DirContext;
 import javax.naming.directory.InitialDirContext;
-import javax.naming.directory.ModificationItem;
 
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.annotations.SaslMechanism;
-import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.annotations.CreateDS;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
-import org.apache.directory.server.core.security.TlsKeyGenerator;
 import org.apache.directory.server.ldap.handlers.bind.cramMD5.CramMd5MechanismHandler;
 import org.apache.directory.server.ldap.handlers.bind.digestMD5.DigestMd5MechanismHandler;
 import org.apache.directory.server.ldap.handlers.bind.gssapi.GssapiMechanismHandler;
@@ -50,7 +43,7 @@
 import org.apache.directory.server.ldap.handlers.extended.StoredProcedureExtendedOperationHandler;
 import org.apache.directory.server.operations.bind.BogusNtlmProvider;
 import org.apache.directory.shared.ldap.constants.SupportedSaslMechanisms;
-import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.util.AttributeUtils;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -63,6 +56,7 @@
  * @version $Rev: 642496 $
  */
 @RunWith ( FrameworkRunner.class ) 
+@CreateDS( allowAnonAccess=true, name="LdapsIT-class")
 @CreateLdapServer ( 
     transports = 
     {
@@ -91,9 +85,9 @@
     
     
     /**
-     * Create an entry for a person.
+     * Create a secure connection on ou=system.
      */
-    public DirContext getSecureConnection() throws Exception
+    private DirContext getSecureConnectionSystem() throws Exception
     {
         Hashtable<String, String> env = new Hashtable<String, String>();
         env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
@@ -112,72 +106,18 @@
      * @throws NamingException cannot create person
      */
     @Test
-    public void testLdapS() throws Exception
+    public void testLdaps() throws Exception
     {
         // Create a person
-        Attributes attributes = new BasicAttributes( true );
-        Attribute attribute = new BasicAttribute( "objectClass" );
-        attribute.add( "top" );
-        attribute.add( "person" );
-        attributes.put( attribute );
-        attributes.put( "cn", "The Person" );
-        attributes.put( "sn", "Person" );
-        attributes.put( "description", "this is a person" );
-        DirContext ctx = getSecureConnection();
+        Attributes attributes = AttributeUtils.createAttributes( 
+            "objectClass: top",
+            "objectClass: person",
+            "cn: The Person",
+            "sn: Person",
+            "description: this is a person" );
+        DirContext ctx = getSecureConnectionSystem();
         DirContext person = ctx.createSubcontext( RDN, attributes );
 
         assertNotNull( person );
     }
-
-    /**
-     * Test for DIRSERVER-1373.
-     */
-    @Test
-    public void testUpdateCertificate() throws Exception
-    {
-        // create a secure connection
-        Hashtable<String, String> env = new Hashtable<String, String>();
-        env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
-        env.put( "java.naming.provider.url", "ldaps://localhost:" + ldapServer.getPortSSL() );
-        env.put( "java.naming.ldap.factory.socket", SSLSocketFactory.class.getName() );
-        env.put( "java.naming.security.principal", "uid=admin,ou=system" );
-        env.put( "java.naming.security.credentials", "secret" );
-        env.put( "java.naming.security.authentication", "simple" );
-        InitialDirContext ctx = new InitialDirContext( env );
-
-        // create a new certificate
-        String newIssuerDN = "cn=new_issuer_dn";
-        String newSubjectDN = "cn=new_subject_dn";
-        ServerEntry entry = ldapServer.getDirectoryService().getAdminSession().lookup(
-            new LdapDN( "uid=admin,ou=system" ) );
-        TlsKeyGenerator.addKeyPair( entry, newIssuerDN, newSubjectDN, "RSA" );
-
-        // now update the certificate (over the wire)
-        ModificationItem[] mods = new ModificationItem[3];
-        mods[0] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
-            TlsKeyGenerator.PRIVATE_KEY_AT, entry.get( TlsKeyGenerator.PRIVATE_KEY_AT ).getBytes() ) );
-        mods[1] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
-            TlsKeyGenerator.PUBLIC_KEY_AT, entry.get( TlsKeyGenerator.PUBLIC_KEY_AT ).getBytes() ) );
-        mods[2] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
-            TlsKeyGenerator.USER_CERTIFICATE_AT, entry.get( TlsKeyGenerator.USER_CERTIFICATE_AT ).getBytes() ) );
-        ctx.modifyAttributes( "uid=admin,ou=system", mods );
-        ctx.close();
-
-        ldapServer.reloadSslContext();
-        
-        // create a secure connection
-        ctx = new InitialDirContext( env );
-
-        // check the received certificate, it must contain the updated server certificate
-        X509Certificate[] lastReceivedServerCertificates = BogusTrustManagerFactory.lastReceivedServerCertificates;
-        assertNotNull( lastReceivedServerCertificates );
-        assertEquals( 1, lastReceivedServerCertificates.length );
-        String issuerDN = lastReceivedServerCertificates[0].getIssuerDN().getName();
-        String subjectDN = lastReceivedServerCertificates[0].getSubjectDN().getName();
-        // converting the values to lowercase is required cause the certificate is
-        // having attribute names in capital letters e.c the above newIssuerDN will be present as CN=new_issuer_dn
-        assertEquals( "Expected the new certificate with the new issuer", newIssuerDN.toLowerCase(), issuerDN.toLowerCase() );
-        assertEquals( "Expected the new certificate with the new subject", newSubjectDN.toLowerCase(), subjectDN.toLowerCase() );
-    }
-
 }

Added: directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/LdapsUpdateCertificateIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/LdapsUpdateCertificateIT.java?rev=896130&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/LdapsUpdateCertificateIT.java (added)
+++ directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/LdapsUpdateCertificateIT.java Tue Jan  5 17:11:29 2010
@@ -0,0 +1,155 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.ssl;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.security.cert.X509Certificate;
+import java.util.Hashtable;
+
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.ModificationItem;
+
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.annotations.SaslMechanism;
+import org.apache.directory.server.core.annotations.CreateDS;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.apache.directory.server.core.security.TlsKeyGenerator;
+import org.apache.directory.server.ldap.handlers.bind.cramMD5.CramMd5MechanismHandler;
+import org.apache.directory.server.ldap.handlers.bind.digestMD5.DigestMd5MechanismHandler;
+import org.apache.directory.server.ldap.handlers.bind.gssapi.GssapiMechanismHandler;
+import org.apache.directory.server.ldap.handlers.bind.ntlm.NtlmMechanismHandler;
+import org.apache.directory.server.ldap.handlers.bind.plain.PlainMechanismHandler;
+import org.apache.directory.server.ldap.handlers.extended.StoredProcedureExtendedOperationHandler;
+import org.apache.directory.server.operations.bind.BogusNtlmProvider;
+import org.apache.directory.shared.ldap.constants.SupportedSaslMechanisms;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Test case to verify DIREVE-216.  Starts up the server binds via SUN JNDI provider
+ * to perform add modify operations on entries.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 642496 $
+ */
+@RunWith ( FrameworkRunner.class ) 
+@CreateDS( allowAnonAccess=true, name="LdapsUpdateCertificateIT-class")
+@CreateLdapServer ( 
+    transports = 
+    {
+        @CreateTransport( protocol = "LDAP" ),
+        @CreateTransport( protocol = "LDAPS" )
+    },
+    saslHost="localhost",
+    saslMechanisms = 
+    {
+        @SaslMechanism( name=SupportedSaslMechanisms.PLAIN, implClass=PlainMechanismHandler.class ),
+        @SaslMechanism( name=SupportedSaslMechanisms.CRAM_MD5, implClass=CramMd5MechanismHandler.class),
+        @SaslMechanism( name=SupportedSaslMechanisms.DIGEST_MD5, implClass=DigestMd5MechanismHandler.class),
+        @SaslMechanism( name=SupportedSaslMechanisms.GSSAPI, implClass=GssapiMechanismHandler.class),
+        @SaslMechanism( name=SupportedSaslMechanisms.NTLM, implClass=NtlmMechanismHandler.class),
+        @SaslMechanism( name=SupportedSaslMechanisms.GSS_SPNEGO, implClass=NtlmMechanismHandler.class)
+    },
+    extendedOpHandlers = 
+    {
+        StoredProcedureExtendedOperationHandler.class
+    },
+    ntlmProvider=BogusNtlmProvider.class
+    )
+public class LdapsUpdateCertificateIT extends AbstractLdapTestUnit
+{
+    /**
+     * Create an entry for a person.
+     */
+    public DirContext getSecureConnection() throws Exception
+    {
+        Hashtable<String, String> env = new Hashtable<String, String>();
+        env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
+        env.put( "java.naming.provider.url", "ldap://localhost:" + ldapServer.getPortSSL() + "/ou=system" );
+        env.put( "java.naming.ldap.factory.socket", SSLSocketFactory.class.getName() );
+        env.put( "java.naming.security.principal", "uid=admin,ou=system" );
+        env.put( "java.naming.security.credentials", "secret" );
+        env.put( "java.naming.security.authentication", "simple" );
+        return new InitialDirContext( env );
+    }
+
+
+    /**
+     * Test for DIRSERVER-1373.
+     */
+    @Test
+    public void testUpdateCertificate() throws Exception
+    {
+        // create a secure connection
+        Hashtable<String, String> env = new Hashtable<String, String>();
+        env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
+        env.put( "java.naming.provider.url", "ldaps://localhost:" + ldapServer.getPortSSL() );
+        env.put( "java.naming.ldap.factory.socket", SSLSocketFactory.class.getName() );
+        env.put( "java.naming.security.principal", "uid=admin,ou=system" );
+        env.put( "java.naming.security.credentials", "secret" );
+        env.put( "java.naming.security.authentication", "simple" );
+        InitialDirContext ctx = new InitialDirContext( env );
+
+        // create a new certificate
+        String newIssuerDN = "cn=new_issuer_dn";
+        String newSubjectDN = "cn=new_subject_dn";
+        ServerEntry entry = ldapServer.getDirectoryService().getAdminSession().lookup(
+            new LdapDN( "uid=admin,ou=system" ) );
+        TlsKeyGenerator.addKeyPair( entry, newIssuerDN, newSubjectDN, "RSA" );
+
+        // now update the certificate (over the wire)
+        ModificationItem[] mods = new ModificationItem[3];
+        mods[0] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
+            TlsKeyGenerator.PRIVATE_KEY_AT, entry.get( TlsKeyGenerator.PRIVATE_KEY_AT ).getBytes() ) );
+        mods[1] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
+            TlsKeyGenerator.PUBLIC_KEY_AT, entry.get( TlsKeyGenerator.PUBLIC_KEY_AT ).getBytes() ) );
+        mods[2] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
+            TlsKeyGenerator.USER_CERTIFICATE_AT, entry.get( TlsKeyGenerator.USER_CERTIFICATE_AT ).getBytes() ) );
+        ctx.modifyAttributes( "uid=admin,ou=system", mods );
+        ctx.close();
+
+        ldapServer.reloadSslContext();
+        
+        // create a secure connection
+        ctx = new InitialDirContext( env );
+
+        // check the received certificate, it must contain the updated server certificate
+        X509Certificate[] lastReceivedServerCertificates = BogusTrustManagerFactory.lastReceivedServerCertificates;
+        assertNotNull( lastReceivedServerCertificates );
+        assertEquals( 1, lastReceivedServerCertificates.length );
+        String issuerDN = lastReceivedServerCertificates[0].getIssuerDN().getName();
+        String subjectDN = lastReceivedServerCertificates[0].getSubjectDN().getName();
+        // converting the values to lowercase is required cause the certificate is
+        // having attribute names in capital letters e.c the above newIssuerDN will be present as CN=new_issuer_dn
+        assertEquals( "Expected the new certificate with the new issuer", newIssuerDN.toLowerCase(), issuerDN.toLowerCase() );
+        assertEquals( "Expected the new certificate with the new subject", newSubjectDN.toLowerCase(), subjectDN.toLowerCase() );
+    }
+
+}

Added: directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsConfidentialityIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsConfidentialityIT.java?rev=896130&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsConfidentialityIT.java (added)
+++ directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsConfidentialityIT.java Tue Jan  5 17:11:29 2010
@@ -0,0 +1,298 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.ssl;
+
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import javax.naming.AuthenticationNotSupportedException;
+import javax.naming.Context;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapContext;
+import javax.naming.ldap.StartTlsRequest;
+import javax.naming.ldap.StartTlsResponse;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.annotations.CreateDS;
+import org.apache.directory.server.core.entry.ClonedServerEntry;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.apache.directory.server.integ.ServerIntegrationUtils;
+import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Test case to verify proper operation of confidentiality requirements as 
+ * specified in https://issues.apache.org/jira/browse/DIRSERVER-1189.  
+ * 
+ * Starts up the server binds via SUN JNDI provider to perform various 
+ * operations on entries which should be rejected when a TLS secured 
+ * connection is not established.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 639006 $
+ */
+@RunWith ( FrameworkRunner.class ) 
+@CreateDS( allowAnonAccess=true, name="StartTlsConfidentialityIT-class")
+@CreateLdapServer ( 
+    transports = 
+    {
+        @CreateTransport( protocol = "LDAP" ),
+        @CreateTransport( protocol = "LDAPS" )
+    },
+    extendedOpHandlers={ StartTlsHandler.class }
+    )
+public class StartTlsConfidentialityIT extends AbstractLdapTestUnit
+{
+    private static final Logger LOG = LoggerFactory.getLogger( StartTlsConfidentialityIT.class );
+    private static final String[] CERT_IDS = new String[] { "userCertificate" };
+    private File ksFile;
+
+    
+    boolean oldConfidentialityRequiredValue;
+    
+    
+    /**
+     * Sets up the key store and installs the self signed certificate for the 
+     * server (created on first startup) which is to be used by the StartTLS 
+     * JDNDI client that will connect.  The key store is created from scratch
+     * programmatically and whipped on each run.  The certificate is acquired 
+     * by pulling down the bytes for administrator's userCertificate from 
+     * uid=admin,ou=system.  We use sysRoot direct context instead of one over
+     * the wire since the server is configured to prevent connections without
+     * TLS secured connections.
+     */
+    @Before
+    public void installKeyStoreWithCertificate() throws Exception
+    {
+        if ( ksFile != null && ksFile.exists() )
+        {
+            ksFile.delete();
+        }
+        
+        ksFile = File.createTempFile( "testStore", "ks" );
+        CoreSession session = ldapServer.getDirectoryService().getAdminSession();
+        ClonedServerEntry entry = session.lookup( new LdapDN( "uid=admin,ou=system" ), CERT_IDS );
+        byte[] userCertificate = entry.get( CERT_IDS[0] ).getBytes();
+        assertNotNull( userCertificate );
+
+        ByteArrayInputStream in = new ByteArrayInputStream( userCertificate );
+        CertificateFactory factory = CertificateFactory.getInstance( "X.509" );
+        Certificate cert = factory.generateCertificate( in );
+        KeyStore ks = KeyStore.getInstance( KeyStore.getDefaultType() );
+        ks.load( null, null );
+        ks.setCertificateEntry( "apacheds", cert );
+        ks.store( new FileOutputStream( ksFile ), "changeit".toCharArray() );
+        LOG.debug( "Keystore file installed: {}", ksFile.getAbsolutePath() );
+        
+        oldConfidentialityRequiredValue = ldapServer.isConfidentialityRequired();
+    }
+    
+    
+    /**
+     * Just deletes the generated key store file.
+     */
+    @After
+    public void deleteKeyStore() throws Exception
+    {
+        if ( ksFile != null && ksFile.exists() )
+        {
+            ksFile.delete();
+        }
+        
+        LOG.debug( "Keystore file deleted: {}", ksFile.getAbsolutePath() );
+        ldapServer.setConfidentialityRequired( oldConfidentialityRequiredValue );
+    }
+    
+
+    private LdapContext getSecuredContext() throws Exception
+    {
+        System.setProperty ( "javax.net.ssl.trustStore", ksFile.getAbsolutePath() );
+        System.setProperty ( "javax.net.ssl.keyStore", ksFile.getAbsolutePath() );
+        System.setProperty ( "javax.net.ssl.keyStorePassword", "changeit" );
+        LOG.debug( "testStartTls() test starting ... " );
+        
+        // Set up environment for creating initial context
+        Hashtable<String, Object> env = new Hashtable<String,Object>();
+        env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
+        
+        // Must use the name of the server that is found in its certificate?
+        env.put( Context.PROVIDER_URL, "ldap://localhost:" + ldapServer.getPort() );
+
+        // Create initial context
+        LOG.debug( "About to get initial context" );
+        LdapContext ctx = new InitialLdapContext( env, null );
+
+        // Start TLS
+        LOG.debug( "About send startTls extended operation" );
+        StartTlsResponse tls = ( StartTlsResponse ) ctx.extendedOperation( new StartTlsRequest() );
+        LOG.debug( "Extended operation issued" );
+        tls.setHostnameVerifier( new HostnameVerifier() {
+            public boolean verify( String hostname, SSLSession session )
+            {
+                return true;
+            } 
+        } );
+        LOG.debug( "TLS negotion about to begin" );
+        tls.negotiate();
+        return ctx;
+    }
+    
+
+    /**
+     * Checks to make sure insecure binds fail while secure binds succeed.
+     */
+    @Test
+    public void testConfidentiality() throws Exception
+    {
+        ldapServer.setConfidentialityRequired( true );
+
+        // -------------------------------------------------------------------
+        // Unsecured bind should fail
+        // -------------------------------------------------------------------
+
+        try
+        {
+            ServerIntegrationUtils.getWiredContext( ldapServer );
+            fail( "Should not get here due to violation of confidentiality requirements" );
+        }
+        catch( AuthenticationNotSupportedException e )
+        {
+        }
+        
+        // -------------------------------------------------------------------
+        // get anonymous connection with StartTLS (no bind request sent)
+        // -------------------------------------------------------------------
+
+        LdapContext ctx = getSecuredContext();
+        assertNotNull( ctx );
+        
+        // -------------------------------------------------------------------
+        // upgrade connection via bind request (same physical connection - TLS)
+        // -------------------------------------------------------------------
+
+        ctx.addToEnvironment( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
+        ctx.addToEnvironment( Context.SECURITY_CREDENTIALS, "secret" );
+        ctx.addToEnvironment( Context.SECURITY_AUTHENTICATION, "simple" );
+        ctx.reconnect( null );
+        
+        // -------------------------------------------------------------------
+        // do a search and confirm
+        // -------------------------------------------------------------------
+
+        NamingEnumeration<SearchResult> results = ctx.search( "ou=system", "(objectClass=*)", new SearchControls() );
+        Set<String> names = new HashSet<String>();
+        while( results.hasMore() )
+        {
+            names.add( results.next().getName() );
+        }
+        results.close();
+        assertTrue( names.contains( "prefNodeName=sysPrefRoot" ) );
+        assertTrue( names.contains( "ou=users" ) );
+        assertTrue( names.contains( "ou=configuration" ) );
+        assertTrue( names.contains( "uid=admin" ) );
+        assertTrue( names.contains( "ou=groups" ) );
+        
+        // -------------------------------------------------------------------
+        // do add and confirm
+        // -------------------------------------------------------------------
+
+        Attributes attrs = new BasicAttributes( "objectClass", "person", true );
+        attrs.put( "sn", "foo" );
+        attrs.put( "cn", "foo bar" );
+        ctx.createSubcontext( "cn=foo bar,ou=system", attrs );
+        assertNotNull( ctx.lookup( "cn=foo bar,ou=system" ) );
+        
+        // -------------------------------------------------------------------
+        // do modify and confirm
+        // -------------------------------------------------------------------
+
+        ModificationItem[] mods = new ModificationItem[] {
+                new ModificationItem( DirContext.ADD_ATTRIBUTE, new BasicAttribute( "cn", "fbar" ) )
+        };
+        ctx.modifyAttributes( "cn=foo bar,ou=system", mods );
+        Attributes reread = ( Attributes ) ctx.getAttributes( "cn=foo bar,ou=system" );
+        assertTrue( reread.get( "cn" ).contains( "fbar" ) );
+        
+        // -------------------------------------------------------------------
+        // do rename and confirm 
+        // -------------------------------------------------------------------
+
+        ctx.rename( "cn=foo bar,ou=system", "cn=fbar,ou=system" );
+        try
+        {
+            ctx.getAttributes( "cn=foo bar,ou=system" );
+            fail( "old name of renamed entry should not be found" );
+        }
+        catch ( NameNotFoundException e )
+        {
+        }
+        reread = ( Attributes ) ctx.getAttributes( "cn=fbar,ou=system" );
+        assertTrue( reread.get( "cn" ).contains( "fbar" ) );
+        
+        // -------------------------------------------------------------------
+        // do delete and confirm
+        // -------------------------------------------------------------------
+
+        ctx.destroySubcontext( "cn=fbar,ou=system" );
+        try
+        {
+            ctx.getAttributes( "cn=fbar,ou=system" );
+            fail( "deleted entry should not be found" );
+        }
+        catch ( NameNotFoundException e )
+        {
+        }
+        
+        ctx.close();
+    }
+}

Modified: directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsIT.java?rev=896130&r1=896129&r2=896130&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsIT.java (original)
+++ directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsIT.java Tue Jan  5 17:11:29 2010
@@ -22,8 +22,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -31,22 +29,12 @@
 import java.security.KeyStore;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
-import java.util.Set;
 
-import javax.naming.AuthenticationNotSupportedException;
 import javax.naming.Context;
-import javax.naming.NameNotFoundException;
 import javax.naming.NamingEnumeration;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.BasicAttribute;
-import javax.naming.directory.BasicAttributes;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.ModificationItem;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 import javax.naming.ldap.InitialLdapContext;
@@ -59,12 +47,10 @@
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.annotations.CreateDS;
 import org.apache.directory.server.core.entry.ClonedServerEntry;
-import org.apache.directory.server.core.entry.ServerEntry;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
-import org.apache.directory.server.core.security.TlsKeyGenerator;
-import org.apache.directory.server.integ.ServerIntegrationUtils;
 import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
 import org.apache.directory.shared.ldap.name.LdapDN;
 import org.junit.After;
@@ -87,6 +73,7 @@
  * @version $Rev: 639006 $
  */
 @RunWith ( FrameworkRunner.class ) 
+@CreateDS( allowAnonAccess=true, name="StartTlsIT-class")
 @CreateLdapServer ( 
     transports = 
     {
@@ -160,149 +147,6 @@
     }
     
 
-    private LdapContext getSecuredContext() throws Exception
-    {
-        System.setProperty ( "javax.net.ssl.trustStore", ksFile.getAbsolutePath() );
-        System.setProperty ( "javax.net.ssl.keyStore", ksFile.getAbsolutePath() );
-        System.setProperty ( "javax.net.ssl.keyStorePassword", "changeit" );
-        LOG.debug( "testStartTls() test starting ... " );
-        
-        // Set up environment for creating initial context
-        Hashtable<String, Object> env = new Hashtable<String,Object>();
-        env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
-        
-        // Must use the name of the server that is found in its certificate?
-        env.put( Context.PROVIDER_URL, "ldap://localhost:" + ldapServer.getPort() );
-
-        // Create initial context
-        LOG.debug( "About to get initial context" );
-        LdapContext ctx = new InitialLdapContext( env, null );
-
-        // Start TLS
-        LOG.debug( "About send startTls extended operation" );
-        StartTlsResponse tls = ( StartTlsResponse ) ctx.extendedOperation( new StartTlsRequest() );
-        LOG.debug( "Extended operation issued" );
-        tls.setHostnameVerifier( new HostnameVerifier() {
-            public boolean verify( String hostname, SSLSession session )
-            {
-                return true;
-            } 
-        } );
-        LOG.debug( "TLS negotion about to begin" );
-        tls.negotiate();
-        return ctx;
-    }
-    
-
-    /**
-     * Checks to make sure insecure binds fail while secure binds succeed.
-     */
-    @Test
-    public void testConfidentiality() throws Exception
-    {
-        ldapServer.setConfidentialityRequired( true );
-
-        // -------------------------------------------------------------------
-        // Unsecured bind should fail
-        // -------------------------------------------------------------------
-
-        try
-        {
-            ServerIntegrationUtils.getWiredContext( ldapServer );
-            fail( "Should not get here due to violation of confidentiality requirements" );
-        }
-        catch( AuthenticationNotSupportedException e )
-        {
-        }
-        
-        // -------------------------------------------------------------------
-        // get anonymous connection with StartTLS (no bind request sent)
-        // -------------------------------------------------------------------
-
-        LdapContext ctx = getSecuredContext();
-        assertNotNull( ctx );
-        
-        // -------------------------------------------------------------------
-        // upgrade connection via bind request (same physical connection - TLS)
-        // -------------------------------------------------------------------
-
-        ctx.addToEnvironment( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
-        ctx.addToEnvironment( Context.SECURITY_CREDENTIALS, "secret" );
-        ctx.addToEnvironment( Context.SECURITY_AUTHENTICATION, "simple" );
-        ctx.reconnect( null );
-        
-        // -------------------------------------------------------------------
-        // do a search and confirm
-        // -------------------------------------------------------------------
-
-        NamingEnumeration<SearchResult> results = ctx.search( "ou=system", "(objectClass=*)", new SearchControls() );
-        Set<String> names = new HashSet<String>();
-        while( results.hasMore() )
-        {
-            names.add( results.next().getName() );
-        }
-        results.close();
-        assertTrue( names.contains( "prefNodeName=sysPrefRoot" ) );
-        assertTrue( names.contains( "ou=users" ) );
-        assertTrue( names.contains( "ou=configuration" ) );
-        assertTrue( names.contains( "uid=admin" ) );
-        assertTrue( names.contains( "ou=groups" ) );
-        
-        // -------------------------------------------------------------------
-        // do add and confirm
-        // -------------------------------------------------------------------
-
-        Attributes attrs = new BasicAttributes( "objectClass", "person", true );
-        attrs.put( "sn", "foo" );
-        attrs.put( "cn", "foo bar" );
-        ctx.createSubcontext( "cn=foo bar,ou=system", attrs );
-        assertNotNull( ctx.lookup( "cn=foo bar,ou=system" ) );
-        
-        // -------------------------------------------------------------------
-        // do modify and confirm
-        // -------------------------------------------------------------------
-
-        ModificationItem[] mods = new ModificationItem[] {
-                new ModificationItem( DirContext.ADD_ATTRIBUTE, new BasicAttribute( "cn", "fbar" ) )
-        };
-        ctx.modifyAttributes( "cn=foo bar,ou=system", mods );
-        Attributes reread = ( Attributes ) ctx.getAttributes( "cn=foo bar,ou=system" );
-        assertTrue( reread.get( "cn" ).contains( "fbar" ) );
-        
-        // -------------------------------------------------------------------
-        // do rename and confirm 
-        // -------------------------------------------------------------------
-
-        ctx.rename( "cn=foo bar,ou=system", "cn=fbar,ou=system" );
-        try
-        {
-            ctx.getAttributes( "cn=foo bar,ou=system" );
-            fail( "old name of renamed entry should not be found" );
-        }
-        catch ( NameNotFoundException e )
-        {
-        }
-        reread = ( Attributes ) ctx.getAttributes( "cn=fbar,ou=system" );
-        assertTrue( reread.get( "cn" ).contains( "fbar" ) );
-        
-        // -------------------------------------------------------------------
-        // do delete and confirm
-        // -------------------------------------------------------------------
-
-        ctx.destroySubcontext( "cn=fbar,ou=system" );
-        try
-        {
-            ctx.getAttributes( "cn=fbar,ou=system" );
-            fail( "deleted entry should not be found" );
-        }
-        catch ( NameNotFoundException e )
-        {
-        }
-        
-        ctx.close();
-    }
-
-
     private void search( int ii, LdapContext securedContext ) throws Exception
     {
         SearchControls controls = new SearchControls();
@@ -397,69 +241,4 @@
             ctx.close();
         }
     }
-    
-    /**
-     * Test for DIRSERVER-1373.
-     */
-    @Test
-    public void testUpdateCertificate() throws Exception
-    {
-        // create a secure connection
-        Hashtable<String, String> env = new Hashtable<String, String>();
-        env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
-        env.put( "java.naming.provider.url", "ldap://localhost:" + ldapServer.getPort() );
-        env.put( "java.naming.security.principal", "uid=admin,ou=system" );
-        env.put( "java.naming.security.credentials", "secret" );
-        env.put( "java.naming.security.authentication", "simple" );
-        LdapContext ctx = new InitialLdapContext( env, null );
-        StartTlsResponse tls = ( StartTlsResponse ) ctx.extendedOperation( new StartTlsRequest() );
-        tls.setHostnameVerifier( new HostnameVerifier() {
-            public boolean verify( String hostname, SSLSession session )
-            {
-                return true;
-            } 
-        } );
-        tls.negotiate( BogusSSLContextFactory.getInstance( false ).getSocketFactory() );
-
-        // create a new certificate
-        String newIssuerDN = "cn=new_issuer_dn";
-        String newSubjectDN = "cn=new_subject_dn";
-        ServerEntry entry = ldapServer.getDirectoryService().getAdminSession().lookup(
-            new LdapDN( "uid=admin,ou=system" ) );
-        TlsKeyGenerator.addKeyPair( entry, newIssuerDN, newSubjectDN, "RSA" );
-
-        // now update the certificate (over the wire)
-        ModificationItem[] mods = new ModificationItem[3];
-        mods[0] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
-            TlsKeyGenerator.PRIVATE_KEY_AT, entry.get( TlsKeyGenerator.PRIVATE_KEY_AT ).getBytes() ) );
-        mods[1] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
-            TlsKeyGenerator.PUBLIC_KEY_AT, entry.get( TlsKeyGenerator.PUBLIC_KEY_AT ).getBytes() ) );
-        mods[2] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
-            TlsKeyGenerator.USER_CERTIFICATE_AT, entry.get( TlsKeyGenerator.USER_CERTIFICATE_AT ).getBytes() ) );
-        ctx.modifyAttributes( "uid=admin,ou=system", mods );
-        ctx.close();
-
-        ldapServer.reloadSslContext();
-        
-        // create a new secure connection
-        ctx = new InitialLdapContext( env, null );
-        tls = ( StartTlsResponse ) ctx.extendedOperation( new StartTlsRequest() );
-        tls.setHostnameVerifier( new HostnameVerifier() {
-            public boolean verify( String hostname, SSLSession session )
-            {
-                return true;
-            } 
-        } );
-        tls.negotiate( BogusSSLContextFactory.getInstance( false ).getSocketFactory() );
-
-        // check the received certificate, it must contain the updated server certificate
-        X509Certificate[] lastReceivedServerCertificates = BogusTrustManagerFactory.lastReceivedServerCertificates;
-        assertNotNull( lastReceivedServerCertificates );
-        assertEquals( 1, lastReceivedServerCertificates.length );
-        String issuerDN = lastReceivedServerCertificates[0].getIssuerDN().getName();
-        String subjectDN = lastReceivedServerCertificates[0].getSubjectDN().getName();
-        assertEquals( "Expected the new certificate with the new issuer", newIssuerDN.toLowerCase(), issuerDN.toLowerCase() );
-        assertEquals( "Expected the new certificate with the new subject", newSubjectDN.toLowerCase(), subjectDN.toLowerCase() );
-    }
-
 }

Added: directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsUpdateCertificateIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsUpdateCertificateIT.java?rev=896130&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsUpdateCertificateIT.java (added)
+++ directory/apacheds/branches/apacheds-schema/server-integ/src/test/java/org/apache/directory/server/ssl/StartTlsUpdateCertificateIT.java Tue Jan  5 17:11:29 2010
@@ -0,0 +1,211 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.ssl;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Hashtable;
+
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapContext;
+import javax.naming.ldap.StartTlsRequest;
+import javax.naming.ldap.StartTlsResponse;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.annotations.CreateDS;
+import org.apache.directory.server.core.entry.ClonedServerEntry;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.apache.directory.server.core.security.TlsKeyGenerator;
+import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Test case to verify proper operation of confidentiality requirements as 
+ * specified in https://issues.apache.org/jira/browse/DIRSERVER-1189.  
+ * 
+ * Starts up the server binds via SUN JNDI provider to perform various 
+ * operations on entries which should be rejected when a TLS secured 
+ * connection is not established.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 639006 $
+ */
+@RunWith ( FrameworkRunner.class ) 
+@CreateDS( allowAnonAccess=true, name="StartTlsUpdateCertificateIT-class")
+@CreateLdapServer ( 
+    transports = 
+    {
+        @CreateTransport( protocol = "LDAP" ),
+        @CreateTransport( protocol = "LDAPS" )
+    },
+    extendedOpHandlers={ StartTlsHandler.class }
+    )
+public class StartTlsUpdateCertificateIT extends AbstractLdapTestUnit
+{
+    private static final Logger LOG = LoggerFactory.getLogger( StartTlsUpdateCertificateIT.class );
+    private static final String[] CERT_IDS = new String[] { "userCertificate" };
+    private File ksFile;
+
+    
+    boolean oldConfidentialityRequiredValue;
+    
+    
+    /**
+     * Sets up the key store and installs the self signed certificate for the 
+     * server (created on first startup) which is to be used by the StartTLS 
+     * JDNDI client that will connect.  The key store is created from scratch
+     * programmatically and whipped on each run.  The certificate is acquired 
+     * by pulling down the bytes for administrator's userCertificate from 
+     * uid=admin,ou=system.  We use sysRoot direct context instead of one over
+     * the wire since the server is configured to prevent connections without
+     * TLS secured connections.
+     */
+    @Before
+    public void installKeyStoreWithCertificate() throws Exception
+    {
+        if ( ksFile != null && ksFile.exists() )
+        {
+            ksFile.delete();
+        }
+        
+        ksFile = File.createTempFile( "testStore", "ks" );
+        CoreSession session = ldapServer.getDirectoryService().getAdminSession();
+        ClonedServerEntry entry = session.lookup( new LdapDN( "uid=admin,ou=system" ), CERT_IDS );
+        byte[] userCertificate = entry.get( CERT_IDS[0] ).getBytes();
+        assertNotNull( userCertificate );
+
+        ByteArrayInputStream in = new ByteArrayInputStream( userCertificate );
+        CertificateFactory factory = CertificateFactory.getInstance( "X.509" );
+        Certificate cert = factory.generateCertificate( in );
+        KeyStore ks = KeyStore.getInstance( KeyStore.getDefaultType() );
+        ks.load( null, null );
+        ks.setCertificateEntry( "apacheds", cert );
+        ks.store( new FileOutputStream( ksFile ), "changeit".toCharArray() );
+        LOG.debug( "Keystore file installed: {}", ksFile.getAbsolutePath() );
+        
+        oldConfidentialityRequiredValue = ldapServer.isConfidentialityRequired();
+    }
+    
+    
+    /**
+     * Just deletes the generated key store file.
+     */
+    @After
+    public void deleteKeyStore() throws Exception
+    {
+        if ( ksFile != null && ksFile.exists() )
+        {
+            ksFile.delete();
+        }
+        
+        LOG.debug( "Keystore file deleted: {}", ksFile.getAbsolutePath() );
+        ldapServer.setConfidentialityRequired( oldConfidentialityRequiredValue );
+    }
+    
+
+    /**
+     * Test for DIRSERVER-1373.
+     */
+    @Test
+    public void testUpdateCertificate() throws Exception
+    {
+        // create a secure connection
+        Hashtable<String, String> env = new Hashtable<String, String>();
+        env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
+        env.put( "java.naming.provider.url", "ldap://localhost:" + ldapServer.getPort() );
+        env.put( "java.naming.security.principal", "uid=admin,ou=system" );
+        env.put( "java.naming.security.credentials", "secret" );
+        env.put( "java.naming.security.authentication", "simple" );
+        LdapContext ctx = new InitialLdapContext( env, null );
+        StartTlsResponse tls = ( StartTlsResponse ) ctx.extendedOperation( new StartTlsRequest() );
+        tls.setHostnameVerifier( new HostnameVerifier() {
+            public boolean verify( String hostname, SSLSession session )
+            {
+                return true;
+            } 
+        } );
+        tls.negotiate( BogusSSLContextFactory.getInstance( false ).getSocketFactory() );
+
+        // create a new certificate
+        String newIssuerDN = "cn=new_issuer_dn";
+        String newSubjectDN = "cn=new_subject_dn";
+        ServerEntry entry = ldapServer.getDirectoryService().getAdminSession().lookup(
+            new LdapDN( "uid=admin,ou=system" ) );
+        TlsKeyGenerator.addKeyPair( entry, newIssuerDN, newSubjectDN, "RSA" );
+
+        // now update the certificate (over the wire)
+        ModificationItem[] mods = new ModificationItem[3];
+        mods[0] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
+            TlsKeyGenerator.PRIVATE_KEY_AT, entry.get( TlsKeyGenerator.PRIVATE_KEY_AT ).getBytes() ) );
+        mods[1] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
+            TlsKeyGenerator.PUBLIC_KEY_AT, entry.get( TlsKeyGenerator.PUBLIC_KEY_AT ).getBytes() ) );
+        mods[2] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(
+            TlsKeyGenerator.USER_CERTIFICATE_AT, entry.get( TlsKeyGenerator.USER_CERTIFICATE_AT ).getBytes() ) );
+        ctx.modifyAttributes( "uid=admin,ou=system", mods );
+        ctx.close();
+
+        ldapServer.reloadSslContext();
+        
+        // create a new secure connection
+        ctx = new InitialLdapContext( env, null );
+        tls = ( StartTlsResponse ) ctx.extendedOperation( new StartTlsRequest() );
+        tls.setHostnameVerifier( new HostnameVerifier() {
+            public boolean verify( String hostname, SSLSession session )
+            {
+                return true;
+            } 
+        } );
+        tls.negotiate( BogusSSLContextFactory.getInstance( false ).getSocketFactory() );
+
+        // check the received certificate, it must contain the updated server certificate
+        X509Certificate[] lastReceivedServerCertificates = BogusTrustManagerFactory.lastReceivedServerCertificates;
+        assertNotNull( lastReceivedServerCertificates );
+        assertEquals( 1, lastReceivedServerCertificates.length );
+        String issuerDN = lastReceivedServerCertificates[0].getIssuerDN().getName();
+        String subjectDN = lastReceivedServerCertificates[0].getSubjectDN().getName();
+        assertEquals( "Expected the new certificate with the new issuer", newIssuerDN.toLowerCase(), issuerDN.toLowerCase() );
+        assertEquals( "Expected the new certificate with the new subject", newSubjectDN.toLowerCase(), subjectDN.toLowerCase() );
+    }
+}



Mime
View raw message