You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2008/03/19 21:47:45 UTC

svn commit: r639006 - in /directory: apacheds/branches/bigbang/core/ apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/ apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/ apacheds/branch...

Author: akarasulu
Date: Wed Mar 19 13:47:36 2008
New Revision: 639006

URL: http://svn.apache.org/viewvc?rev=639006&view=rev
Log:
Adding zero conf StartTLS extended operation and zero conf LDAPS feature ...
 
 o Uses DIT for KeyStore
   - special schema elements added to apache schema to specifically handle the
     server keys and certificates which are assigned to the administrative user
   - special KeyStore implementation used
 o Generates key on first start to automatically enable StartTLS with zero conf
 o Uses BouncyCastle to generate self signed certificate on first start
 o LDAPS feature modified to use same DIT based KeyStore and the same self
   signed certificate and RSA keys generated or replaced by administrator
 o Reduced configuration without need to include KeyStore file path and passwd
 o Administrators can now update the keys and certificates directly from the DIT


Added:
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/CoreKeyStoreSpi.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/TlsKeyGenerator.java
    directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/
    directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/TlsKeyGeneratorTest.java
    directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/StartTlsHandler.java
    directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/StartTlsITest.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DummySSLSocketFactory.java
Modified:
    directory/apacheds/branches/bigbang/core/pom.xml
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
    directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexus.java
    directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java
    directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/ssl/LdapsInitializer.java
    directory/apacheds/branches/bigbang/schema-bootstrap/src/main/schema/apache.schema
    directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java
    directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/StoredProcedureExecutionITest.java
    directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/LdapsITest.java
    directory/apacheds/branches/bigbang/server-xml/src/main/resources/server.xml
    directory/installers/branches/bigbang/apacheds-noarch/   (props changed)
    directory/installers/branches/bigbang/apacheds-noarch/log4j.properties
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixTransformer.java
    directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DirectoryClassUtils.java

Modified: directory/apacheds/branches/bigbang/core/pom.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/pom.xml?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/pom.xml (original)
+++ directory/apacheds/branches/bigbang/core/pom.xml Wed Mar 19 13:47:36 2008
@@ -100,6 +100,12 @@
       <version>${pom.version}</version>
       <scope>test</scope>
     </dependency>
+
+    <dependency>
+      <groupId>bouncycastle</groupId>
+      <artifactId>bcprov-jdk15</artifactId>
+    </dependency>
+
   </dependencies>
 
   <build>

Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java Wed Mar 19 13:47:36 2008
@@ -61,6 +61,7 @@
 import org.apache.directory.server.core.schema.SchemaOperationControl;
 import org.apache.directory.server.core.schema.SchemaPartitionDao;
 import org.apache.directory.server.core.schema.SchemaService;
+import org.apache.directory.server.core.security.TlsKeyGenerator;
 import org.apache.directory.server.core.subtree.SubentryInterceptor;
 import org.apache.directory.server.core.trigger.TriggerInterceptor;
 import org.apache.directory.server.schema.SerializableComparator;
@@ -992,6 +993,7 @@
             serverEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
             serverEntry.put( SchemaConstants.DISPLAY_NAME_AT, "Directory Superuser" );
 
+            TlsKeyGenerator.addKeyPair( serverEntry );
             partitionNexus.add( new AddOperationContext( registries, PartitionNexus.getAdminName(), serverEntry ) );
         }
 

Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexus.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexus.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexus.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexus.java Wed Mar 19 13:47:36 2008
@@ -57,7 +57,7 @@
 public abstract class PartitionNexus implements Partition
 {
     /** the admin super user uid */
-    public final static String ADMIN_UID = "admin";
+    public static final String ADMIN_UID = "admin";
     
     /** the initial admin passwd set on startup */
     public static final String ADMIN_PASSWORD_STRING = "secret";

Added: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/CoreKeyStoreSpi.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/CoreKeyStoreSpi.java?rev=639006&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/CoreKeyStoreSpi.java (added)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/CoreKeyStoreSpi.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,332 @@
+/*
+ *   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.core.security;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.authn.LdapPrincipal;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.entry.ServerEntryUtils;
+import org.apache.directory.server.core.partition.PartitionNexus;
+import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.util.SingletonEnumeration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A read only key store facility designed specifically for TLS/CA operations.
+ * It is only intended for accessing the 'apacheds' private/public key pairs
+ * as well as the self signed certificate.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class CoreKeyStoreSpi extends KeyStoreSpi
+{
+    private static final String APACHEDS_ALIAS = "apacheds";
+
+    private static final Logger LOG = LoggerFactory.getLogger( CoreKeyStoreSpi.class );
+    
+    private DirectoryService directoryService;
+    
+
+    /**
+     * Creates a new instance of LocalKeyStore.
+     */
+    public CoreKeyStoreSpi( DirectoryService directoryService )
+    {
+        LOG.debug( "Constructor called." );
+        this.directoryService = directoryService;
+    }
+
+
+    private ServerEntry getTlsEntry() throws NamingException
+    {
+        LdapDN adminDn = PartitionNexus.getAdminName();
+        LdapPrincipal principal = new LdapPrincipal( adminDn, AuthenticationLevel.SIMPLE );
+        Attributes attrs = directoryService.getJndiContext( principal ).getAttributes( adminDn );
+        return ServerEntryUtils.toServerEntry( attrs, adminDn, directoryService.getRegistries() );
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineAliases()
+     */
+    @Override
+    public Enumeration<String> engineAliases()
+    {
+        LOG.debug( "engineAliases() called." );
+        return new SingletonEnumeration<String>( APACHEDS_ALIAS );
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineContainsAlias(java.lang.String)
+     */
+    @Override
+    public boolean engineContainsAlias( String alias )
+    {
+        LOG.debug( "engineContainsAlias({}) called.", alias );
+        
+        if ( alias.equalsIgnoreCase( APACHEDS_ALIAS ) )
+        {
+            return true;
+        }
+        
+        return false;
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineDeleteEntry(java.lang.String)
+     */
+    @Override
+    public void engineDeleteEntry( String alias ) throws KeyStoreException
+    {
+        LOG.debug( "engineDeleteEntry({}) called.", alias );
+        throw new UnsupportedOperationException();
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineGetCertificate(java.lang.String)
+     */
+    @Override
+    public Certificate engineGetCertificate( String alias )
+    {
+        LOG.debug( "engineGetCertificate({}) called.", alias );
+        if ( alias.equalsIgnoreCase( APACHEDS_ALIAS ) )
+        {
+            try
+            {
+                ServerEntry entry = getTlsEntry();
+                return TlsKeyGenerator.getCertificate( entry );
+            }
+            catch ( NamingException e )
+            {
+                LOG.error( "Failed to access certificate in DIT.", e );
+            }
+        }
+        
+        return null;
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineGetCertificateAlias(java.security.cert.Certificate)
+     */
+    @Override
+    public String engineGetCertificateAlias( Certificate cert )
+    {
+        LOG.debug( "engineGetCertificateAlias({}) called.", cert );
+        
+        if ( cert instanceof X509Certificate )
+        {
+            LOG.debug( "Certificate in alias request is X.509 based." );
+            X509Certificate xcert = ( X509Certificate ) cert;
+            if ( xcert.getSubjectDN().toString().equals( TlsKeyGenerator.CERTIFICATE_PRINCIPAL_DN ) )
+            {
+                return APACHEDS_ALIAS;
+            }
+        }
+        
+        try
+        {
+            ServerEntry entry = getTlsEntry();
+            if ( ArrayUtils.isEquals( cert.getEncoded(), entry.get( TlsKeyGenerator.USER_CERTIFICATE_AT ).getBytes() ) )
+            {
+                return APACHEDS_ALIAS;
+            }
+        }
+        catch ( Exception e )
+        {
+            LOG.error( "Failed on attempt to compare certificate bytes to determine alias.", e );
+        }
+        
+        return null;
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineGetCertificateChain(java.lang.String)
+     */
+    @Override
+    public Certificate[] engineGetCertificateChain( String alias )
+    {
+        LOG.debug( "engineGetCertificateChain({}) called.", alias );
+        try
+        {
+            ServerEntry entry = getTlsEntry();
+            LOG.debug( "Entry:\n{}", entry );
+            return new Certificate[] { TlsKeyGenerator.getCertificate( entry ) };
+        }
+        catch ( Exception e )
+        {
+            LOG.error( "Failed on attempt to compare certificate bytes to determine alias.", e );
+        }
+        
+        return new Certificate[0];
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineGetCreationDate(java.lang.String)
+     */
+    @Override
+    public Date engineGetCreationDate( String alias )
+    {
+        LOG.debug( "engineGetCreationDate({}) called.", alias );
+        return new Date();
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineGetKey(java.lang.String, char[])
+     */
+    @Override
+    public Key engineGetKey( String alias, char[] password ) throws NoSuchAlgorithmException, UnrecoverableKeyException
+    {
+        LOG.debug( "engineGetKey({}, {}) called.", alias, password );
+        
+        try
+        {
+            ServerEntry entry = getTlsEntry();
+            KeyPair keyPair = TlsKeyGenerator.getKeyPair( entry );
+            return keyPair.getPrivate();
+        }
+        catch ( Exception e )
+        {
+            LOG.error( "Failed on attempt to extract key.", e );
+        }
+        
+        return null;
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineIsCertificateEntry(java.lang.String)
+     */
+    @Override
+    public boolean engineIsCertificateEntry( String alias )
+    {
+        LOG.debug( "engineIsCertificateEntry({}) called.", alias );
+        return false;
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineIsKeyEntry(java.lang.String)
+     */
+    @Override
+    public boolean engineIsKeyEntry( String alias )
+    {
+        LOG.debug( "engineIsKeyEntry({}) called.", alias );
+        return true;
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineLoad(java.io.InputStream, char[])
+     */
+    @Override
+    public void engineLoad( InputStream stream, char[] password ) throws IOException, NoSuchAlgorithmException,
+        CertificateException
+    {
+        LOG.debug( "engineLoad({}, {}) called.", stream, password );
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineSetCertificateEntry(java.lang.String, java.security.cert.Certificate)
+     */
+    @Override
+    public void engineSetCertificateEntry( String alias, Certificate cert ) throws KeyStoreException
+    {
+        LOG.debug( "engineSetCertificateEntry({}, {}) called.", alias, cert );
+        throw new NotImplementedException();
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineSetKeyEntry(java.lang.String, byte[], java.security.cert.Certificate[])
+     */
+    @Override
+    public void engineSetKeyEntry( String alias, byte[] key, Certificate[] chain ) throws KeyStoreException
+    {
+        LOG.debug( "engineSetKeyEntry({}, key, {}) called.", alias, chain );
+        throw new NotImplementedException();
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineSetKeyEntry(java.lang.String, java.security.Key, char[], java.security.cert.Certificate[])
+     */
+    @Override
+    public void engineSetKeyEntry( String alias, Key key, char[] password, Certificate[] chain )
+        throws KeyStoreException
+    {
+        LOG.debug( "engineSetKeyEntry({}, key, {}, chain) called.", alias, new String( password ) );
+        throw new NotImplementedException();
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineSize()
+     */
+    @Override
+    public int engineSize()
+    {
+        LOG.debug( "engineSize() called." );
+        return 1;
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.security.KeyStoreSpi#engineStore(java.io.OutputStream, char[])
+     */
+    @Override
+    public void engineStore( OutputStream stream, char[] password ) throws IOException, NoSuchAlgorithmException,
+        CertificateException
+    {
+        LOG.debug( "engineStore(stream, {}) called.", new String( password ) );
+    }
+}

Added: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/TlsKeyGenerator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/TlsKeyGenerator.java?rev=639006&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/TlsKeyGenerator.java (added)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/TlsKeyGenerator.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,264 @@
+/*
+ *   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.core.security;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Security;
+import java.util.Date;
+
+import javax.naming.NamingException;
+import javax.security.auth.x500.X500Principal;
+
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.EncodedKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+import org.apache.directory.server.core.entry.ServerAttribute;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.x509.X509V1CertificateGenerator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Generates the default RSA key pair for the server.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class TlsKeyGenerator
+{
+    private static final Logger LOG = LoggerFactory.getLogger( TlsKeyGenerator.class );
+    
+    public static final String TLS_KEY_INFO_OC = "tlsKeyInfo";
+    public static final String PRIVATE_KEY_AT = "privateKey";
+    public static final String PUBLIC_KEY_AT = "publicKey";
+    public static final String KEY_ALGORITHM_AT = "keyAlgorithm";
+    public static final String PRIVATE_KEY_FORMAT_AT = "privateKeyFormat";
+    public static final String PUBLIC_KEY_FORMAT_AT = "publicKeyFormat";
+    public static final String USER_CERTIFICATE_AT = "userCertificate";
+
+    public static final String CERTIFICATE_PRINCIPAL_DN =
+        "CN=ApacheDS, OU=Directory, O=ASF, C=US";
+    private static final String ALGORITHM = "RSA";
+    private static final int KEY_SIZE = 1024;
+    private static final long YEAR_MILLIS = 365*24*3600*1000;
+    
+
+    static
+    {
+        Security.addProvider( new BouncyCastleProvider() );
+    }
+
+    
+    /**
+     * Gets the certificate associated with the self signed TLS private/public 
+     * key pair.
+     *
+     * @param entry the TLS key/cert entry
+     * @return the X509 certificate associated with that entry
+     * @throws NamingException if there are problems accessing or decoding
+     */
+    public static X509Certificate getCertificate( ServerEntry entry ) throws NamingException
+    {
+        X509Certificate cert = null;
+        CertificateFactory certFactory = null;
+        
+        try
+        {
+            certFactory = CertificateFactory.getInstance( "X.509", "BC" );
+        }
+        catch ( Exception e )
+        {
+            NamingException ne = new NamingException( "Failed to get BC Certificate factory for algorithm: X.509" );
+            ne.setRootCause( e );
+            throw ne;
+        }
+
+        byte[] certBytes = entry.get( USER_CERTIFICATE_AT ).getBytes();
+        InputStream in = new ByteArrayInputStream( certBytes );
+
+        try
+        {
+            cert = ( X509Certificate ) certFactory.generateCertificate( in );
+        }
+        catch ( CertificateException e )
+        {
+            NamingException ne = new NamingException( "Bad certificate format." );
+            ne.setRootCause( e );
+            throw ne;
+        }
+        
+        return cert;
+    }
+    
+    
+    /**
+     * Extracts the public private key pair from the tlsKeyInfo entry.
+     *
+     * @param entry an entry of the tlsKeyInfo objectClass
+     * @return the private and public key pair
+     * @throws NamingException if there are format or access issues
+     */
+    public static KeyPair getKeyPair( ServerEntry entry ) throws NamingException
+    {
+        PublicKey publicKey = null;
+        PrivateKey privateKey = null;
+        
+        KeyFactory keyFactory = null;
+        try
+        {
+            keyFactory = KeyFactory.getInstance( ALGORITHM );
+        }
+        catch ( Exception e )
+        {
+            NamingException ne = new NamingException( "Failed to get key factory for algorithm: " + ALGORITHM );
+            ne.setRootCause( e );
+            throw ne;
+        }
+        
+        EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec( entry.get( PRIVATE_KEY_AT ).getBytes() );
+        try
+        {
+            privateKey = keyFactory.generatePrivate( privateKeySpec );
+        }
+        catch ( Exception e )
+        {
+            NamingException ne = new NamingException( "Bad private key format." );
+            ne.setRootCause( e );
+            throw ne;
+        }
+    
+        EncodedKeySpec publicKeySpec = new X509EncodedKeySpec( entry.get( PUBLIC_KEY_AT ).getBytes() );
+        try
+        {
+            publicKey = keyFactory.generatePublic( publicKeySpec );
+        }
+        catch ( InvalidKeySpecException e )
+        {
+            NamingException ne = new NamingException( "Bad public key format." );
+            ne.setRootCause( e );
+            throw ne;
+        }
+        
+        return new KeyPair( publicKey, privateKey );
+    }
+    
+
+    /**
+     * Adds a private key pair along with a self signed certificate to an 
+     * entry making sure it contains the objectClasses and attributes needed
+     * to support the additions.  This function is intended for creating a TLS
+     * key value pair and self signed certificate for use by the server to 
+     * authenticate itself during SSL handshakes in the course of establishing
+     * an LDAPS connection or a secure LDAP connection using StartTLS. Usually
+     * this information is added to the administrator user's entry so the 
+     * administrator (effectively the server) can manage these security 
+     * concerns.
+     * 
+     * @param entry the entry to add security attributes to
+     * @throws NamingException on problems generating the content in the entry
+     */
+    public static void addKeyPair( ServerEntry entry ) throws NamingException
+    {
+        ServerAttribute objectClass = entry.get( SchemaConstants.OBJECT_CLASS_AT );
+        if ( objectClass == null )
+        {
+            entry.put( SchemaConstants.OBJECT_CLASS_AT, TLS_KEY_INFO_OC, SchemaConstants.INET_ORG_PERSON_OC );
+        }
+        else
+        {
+            objectClass.add( TLS_KEY_INFO_OC, SchemaConstants.INET_ORG_PERSON_OC );
+        }
+        
+        KeyPairGenerator generator = null;
+        try
+        {
+            generator = KeyPairGenerator.getInstance( ALGORITHM );
+        }
+        catch ( NoSuchAlgorithmException e )
+        {
+            NamingException ne = new NamingException( "Cannot generate key pair for TLS" );
+            ne.setRootCause( e );
+            throw ne;
+        }
+
+        generator.initialize( KEY_SIZE );
+        KeyPair keypair = generator.genKeyPair();
+        entry.put( KEY_ALGORITHM_AT, ALGORITHM );
+        
+        // Generate the private key attributes 
+        PrivateKey privateKey = keypair.getPrivate();
+        entry.put( PRIVATE_KEY_AT, privateKey.getEncoded() );
+        entry.put( PRIVATE_KEY_FORMAT_AT, privateKey.getFormat() );
+        LOG.debug( "PrivateKey: {}", privateKey );
+        
+        PublicKey publicKey = keypair.getPublic();
+        entry.put( PUBLIC_KEY_AT, publicKey.getEncoded() );
+        entry.put( PUBLIC_KEY_FORMAT_AT, publicKey.getFormat() );
+        LOG.debug( "PublicKey: {}", publicKey );
+        
+        // Generate the self-signed certificate
+        Date startDate = new Date(); 
+        Date expiryDate = new Date( System.currentTimeMillis() + YEAR_MILLIS ); 
+        BigInteger serialNumber = BigInteger.valueOf( System.currentTimeMillis() );
+
+        X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
+        X500Principal dnName = new X500Principal( CERTIFICATE_PRINCIPAL_DN );
+
+        certGen.setSerialNumber( serialNumber );
+        certGen.setIssuerDN( dnName );
+        certGen.setNotBefore( startDate );
+        certGen.setNotAfter( expiryDate );
+        certGen.setSubjectDN( dnName );
+        certGen.setPublicKey( publicKey );
+        certGen.setSignatureAlgorithm( "SHA1With" + ALGORITHM );
+
+        try
+        {
+            X509Certificate cert = certGen.generate( privateKey, "BC" );
+            entry.put( USER_CERTIFICATE_AT, cert.getEncoded() );
+            LOG.debug( "X509 Certificate: {}", cert );
+        }
+        catch ( Exception e )
+        {
+            NamingException ne = new NamingException( "Cannot generate self signed certificate." );
+            ne.setRootCause( e );
+            throw ne;
+        }
+        
+        LOG.info( "Keys and self signed certificate successfully generated." );
+    }
+}

Added: directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/TlsKeyGeneratorTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/TlsKeyGeneratorTest.java?rev=639006&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/TlsKeyGeneratorTest.java (added)
+++ directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/TlsKeyGeneratorTest.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,111 @@
+/*
+ *   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.core.security;
+
+
+import static org.junit.Assert.*;
+
+import java.io.FileInputStream;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.server.core.entry.DefaultServerEntry;
+import org.apache.directory.server.schema.bootstrap.ApacheSchema;
+import org.apache.directory.server.schema.bootstrap.ApachemetaSchema;
+import org.apache.directory.server.schema.bootstrap.BootstrapSchemaLoader;
+import org.apache.directory.server.schema.bootstrap.CoreSchema;
+import org.apache.directory.server.schema.bootstrap.CosineSchema;
+import org.apache.directory.server.schema.bootstrap.InetorgpersonSchema;
+import org.apache.directory.server.schema.bootstrap.Schema;
+import org.apache.directory.server.schema.bootstrap.SystemSchema;
+import org.apache.directory.server.schema.registries.DefaultOidRegistry;
+import org.apache.directory.server.schema.registries.DefaultRegistries;
+import org.apache.directory.server.schema.registries.OidRegistry;
+import org.apache.directory.server.schema.registries.Registries;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Test for the TlsKeyGenerator class.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class TlsKeyGeneratorTest
+{
+    private static final Logger LOG = LoggerFactory.getLogger( TlsKeyGeneratorTest.class );
+    private static BootstrapSchemaLoader loader;
+    private static Registries registries;
+    private static OidRegistry oidRegistry;
+    
+
+    /**
+     * Initialize the registries once for the whole test suite
+     */
+    @BeforeClass
+    public static void setup() throws NamingException
+    {
+        loader = new BootstrapSchemaLoader();
+        oidRegistry = new DefaultOidRegistry();
+        registries = new DefaultRegistries( "bootstrap", loader, oidRegistry );
+        
+        // load essential bootstrap schemas 
+        Set<Schema> bootstrapSchemas = new HashSet<Schema>();
+        bootstrapSchemas.add( new ApachemetaSchema() );
+        bootstrapSchemas.add( new ApacheSchema() );
+        bootstrapSchemas.add( new CoreSchema() );
+        bootstrapSchemas.add( new SystemSchema() );
+        bootstrapSchemas.add( new InetorgpersonSchema() );
+        bootstrapSchemas.add( new CosineSchema() );
+        loader.loadWithDependencies( bootstrapSchemas, registries );
+        
+    }
+    
+    
+    /**
+     * Test method for all methods in one.
+     */
+    @Test
+    public void testAll() throws NamingException
+    {
+        DefaultServerEntry entry = new DefaultServerEntry( registries, new LdapDN() );
+        TlsKeyGenerator.addKeyPair( entry );
+        LOG.debug( "Entry: {}", entry );
+        assertTrue( entry.contains( SchemaConstants.OBJECT_CLASS_AT, TlsKeyGenerator.TLS_KEY_INFO_OC ) );
+        
+        KeyPair keyPair = TlsKeyGenerator.getKeyPair( entry );
+        assertNotNull( keyPair );
+        
+        X509Certificate cert = TlsKeyGenerator.getCertificate( entry );
+        assertNotNull( cert );
+    }
+}

Modified: directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java (original)
+++ directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java Wed Mar 19 13:47:36 2008
@@ -20,9 +20,11 @@
 package org.apache.directory.server.ldap;
 
 
-import java.io.File;
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.Security;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -38,6 +40,7 @@
 
 import org.apache.directory.server.core.DirectoryService;
 import org.apache.directory.server.core.partition.PartitionNexus;
+import org.apache.directory.server.core.security.CoreKeyStoreSpi;
 import org.apache.directory.server.ldap.support.AbandonHandler;
 import org.apache.directory.server.ldap.support.AddHandler;
 import org.apache.directory.server.ldap.support.BindHandler;
@@ -60,7 +63,6 @@
 import org.apache.directory.server.ldap.support.UnbindHandler;
 import org.apache.directory.server.ldap.support.ssl.LdapsInitializer;
 import org.apache.directory.server.protocol.shared.DirectoryBackedService;
-import org.apache.directory.server.protocol.shared.ServiceConfigurationException;
 import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
 import org.apache.directory.shared.asn1.codec.Asn1CodecDecoder;
 import org.apache.directory.shared.asn1.codec.Asn1CodecEncoder;
@@ -166,13 +168,6 @@
     /** Whether to allow anonymous access. */
     private boolean allowAnonymousAccess = true; // allow by default
 
-    /** The path to the certificate file. */
-    private File ldapsCertificateFile = new File( "server-work" + File.separator + "certificates" + File.separator
-        + "server.cert" );
-
-    /** The certificate password. */
-    private String ldapsCertificatePassword = "changeit";
-
     /** The extended operation handlers. */
     private final Collection<ExtendedOperationHandler> extendedOperationHandlers = new ArrayList<ExtendedOperationHandler>();
 
@@ -321,9 +316,19 @@
         
         if ( isEnableLdaps() )
         {
-            char[] certPasswordChars = getLdapsCertificatePassword().toCharArray();
-            String storePath = getLdapsCertificateFile().getPath();
-            chain = LdapsInitializer.init( certPasswordChars, storePath );
+            Provider provider = Security.getProvider( "SUN" );
+            LOG.debug( "provider = {}", provider );
+            CoreKeyStoreSpi coreKeyStoreSpi = new CoreKeyStoreSpi( getDirectoryService() );
+            KeyStore keyStore = new KeyStore( coreKeyStoreSpi, provider, "JKS" ) {};
+            try
+            {
+                keyStore.load( null, null );
+            }
+            catch ( Exception e )
+            {
+                // nothing really happens with this keystore
+            }
+            chain = LdapsInitializer.init( keyStore );
         }
         else
         {
@@ -475,6 +480,10 @@
      */
     public void addExtendedOperationHandler( ExtendedOperationHandler eoh )
     {
+        if ( extendedHandler == null )
+        {
+            setExtendedHandler( new DefaultExtendedHandler() );
+        }
         extendedHandler.addHandler( eoh );
     }
 
@@ -537,64 +546,6 @@
     public void setEnableLdaps( boolean enableLdaps )
     {
         this.enableLdaps = enableLdaps;
-    }
-
-
-    /**
-     * Returns the path of the X509 (or JKS) certificate file for LDAPS.
-     * The default value is <tt>"&lt;WORKDIR&gt;/certificates/server.cert"</tt>.
-     *
-     * @return The LDAPS certificate file.
-     */
-    public File getLdapsCertificateFile()
-    {
-        return ldapsCertificateFile;
-    }
-
-
-    /**
-     * Sets the path of the SunX509 certificate file (either PKCS12 or JKS format)
-     * for LDAPS.
-     *
-     * @param ldapsCertificateFile The path to the SunX509 certificate.
-     */
-    public void setLdapsCertificateFile( File ldapsCertificateFile )
-    {
-        if ( ldapsCertificateFile == null )
-        {
-            throw new ServiceConfigurationException( "LdapsCertificateFile cannot be null." );
-        }
-        this.ldapsCertificateFile = ldapsCertificateFile;
-    }
-
-
-    /**
-     * Returns the password which is used to load the the SunX509 certificate file
-     * (either PKCS12 or JKS format).
-     * The default value is <tt>"changeit"</tt>.  This is the same value with what
-     * <a href="http://jakarta.apache.org/tomcat/">Apache Jakarta Tomcat</a> uses by
-     * default.
-     *
-     * @return The LDAPS certificate password.
-     */
-    public String getLdapsCertificatePassword()
-    {
-        return ldapsCertificatePassword;
-    }
-
-
-    /**
-     * Sets the password which is used to load the LDAPS certificate file.
-     *
-     * @param ldapsCertificatePassword The certificate password.
-     */
-    public void setLdapsCertificatePassword( String ldapsCertificatePassword )
-    {
-        if ( ldapsCertificatePassword == null )
-        {
-            throw new ServiceConfigurationException( "LdapsCertificatePassword cannot be null." );
-        }
-        this.ldapsCertificatePassword = ldapsCertificatePassword;
     }
 
 

Added: directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/StartTlsHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/StartTlsHandler.java?rev=639006&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/StartTlsHandler.java (added)
+++ directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/StartTlsHandler.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,197 @@
+/*
+ *   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.ldap.support.extended;
+
+
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.directory.server.core.security.CoreKeyStoreSpi;
+import org.apache.directory.server.ldap.ExtendedOperationHandler;
+import org.apache.directory.server.ldap.LdapServer;
+import org.apache.directory.server.ldap.SessionRegistry;
+import org.apache.directory.shared.ldap.message.ExtendedRequest;
+import org.apache.directory.shared.ldap.message.ExtendedResponse;
+import org.apache.directory.shared.ldap.message.ExtendedResponseImpl;
+import org.apache.directory.shared.ldap.message.LdapResult;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.filter.SSLFilter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Handler for the StartTLS extended operation.
+ *
+ * @org.apache.xbean.XBean
+ * @see <a href="http://www.ietf.org/rfc/rfc2830.txt">RFC 2830</a>
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class StartTlsHandler implements ExtendedOperationHandler
+{
+    public static final String EXTENSION_OID = "1.3.6.1.4.1.1466.20037";
+
+    private static final Set<String> EXTENSION_OIDS;
+    private static final Logger LOG = LoggerFactory.getLogger( StartTlsHandler.class );
+    
+    private SSLContext sslContext;
+
+    
+    static
+    {
+        Set<String> set = new HashSet<String>( 3 );
+        set.add( EXTENSION_OID );
+        EXTENSION_OIDS = Collections.unmodifiableSet( set );
+    }
+    
+
+    public void handleExtendedOperation( IoSession session, SessionRegistry registry, ExtendedRequest req ) throws Exception
+    {
+        LOG.info( "Handling StartTLS request." );
+        
+        IoFilterChain chain = session.getFilterChain();
+        SSLFilter sslFilter = ( SSLFilter ) chain.get( "sslFilter" );
+        if( sslFilter == null )
+        {
+            sslFilter = new SSLFilter( sslContext );
+            chain.addFirst( "sslFilter", sslFilter );
+        }
+        else
+        {
+            sslFilter.startSSL( session );
+        }
+        
+        ExtendedResponse res = new ExtendedResponseImpl( req.getMessageId() );
+        LdapResult result = res.getLdapResult();
+        result.setResultCode( ResultCodeEnum.SUCCESS );
+        res.setResponseName( EXTENSION_OID );
+        res.setResponse( new byte[ 0 ] );
+
+        // Send a response.
+        session.setAttribute( SSLFilter.DISABLE_ENCRYPTION_ONCE );
+        session.write( res );
+    }
+    
+    
+    class ServerX509TrustManager implements X509TrustManager
+    {
+        public void checkClientTrusted( X509Certificate[] chain, String authType ) throws CertificateException
+        {
+            LOG.debug( "checkClientTrusted() called" );
+        }
+
+        public void checkServerTrusted( X509Certificate[] chain, String authType ) throws CertificateException
+        {
+            LOG.debug( "checkServerTrusted() called" );
+        }
+
+        public X509Certificate[] getAcceptedIssuers()
+        {
+            LOG.debug( "getAcceptedIssuers() called" );
+            return new X509Certificate[0];
+        }
+    }
+
+
+    public final Set<String> getExtensionOids()
+    {
+        return EXTENSION_OIDS;
+    }
+
+
+    public final String getOid()
+    {
+        return EXTENSION_OID;
+    }
+
+    
+    public void setLdapProvider( LdapServer ldapServer )
+    {
+        LOG.debug( "Setting LDAP Service" );
+        Provider provider = Security.getProvider( "SUN" );
+        LOG.debug( "provider = {}", provider );
+        CoreKeyStoreSpi coreKeyStoreSpi = new CoreKeyStoreSpi( ldapServer.getDirectoryService() );
+        KeyStore keyStore = new KeyStore( coreKeyStoreSpi, provider, "JKS" ) {};
+
+        try
+        {
+            keyStore.load( null, null );
+        }
+        catch ( Exception e1 )
+        {
+            throw new RuntimeException( "Failed on keystore load which should never really happen." );
+        }
+        
+        KeyManagerFactory keyManagerFactory = null;
+        try
+        {
+            keyManagerFactory = KeyManagerFactory.getInstance( "SunX509" );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( "Failed to create KeyManagerFactory", e );
+        }
+        
+        try
+        {
+            keyManagerFactory.init( keyStore, null );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( "Failed to initialize KeyManagerFactory", e );
+        }
+        
+        try
+        {
+            sslContext = SSLContext.getInstance( "TLS" );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( "Failed to create SSLContext", e );
+        }
+        
+        try
+        {
+            sslContext.init( keyManagerFactory.getKeyManagers(), 
+                new TrustManager[] { new ServerX509TrustManager() }, 
+                new SecureRandom() );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( "Failed to initialize SSLContext", e );
+        }
+    }
+}

Modified: directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/ssl/LdapsInitializer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/ssl/LdapsInitializer.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/ssl/LdapsInitializer.java (original)
+++ directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/ssl/LdapsInitializer.java Wed Mar 19 13:47:36 2008
@@ -20,14 +20,9 @@
 package org.apache.directory.server.ldap.support.ssl;
 
 
-import java.io.FileInputStream;
-import java.io.IOException;
 import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
 import java.security.Security;
-import java.security.cert.CertificateException;
 
 import javax.naming.NamingException;
 import javax.net.ssl.KeyManagerFactory;
@@ -49,26 +44,8 @@
  */
 public class LdapsInitializer
 {
-    public static IoFilterChainBuilder init( char[] certPasswordChars, String storePath ) throws NamingException
+    public static IoFilterChainBuilder init( KeyStore ks ) throws NamingException
     {
-        KeyStore ks = null;
-        try
-        {
-            ks = loadKeyStore( storePath, "PKCS12" );
-        }
-        catch ( Exception e )
-        {
-            try
-            {
-                ks = loadKeyStore( storePath, "JKS" );
-            }
-            catch ( Exception e2 )
-            {
-                throw ( NamingException ) new NamingException( "Failed to load a certificate: " + storePath )
-                    .initCause( e );
-            }
-        }
-
         SSLContext sslCtx;
         try
         {
@@ -79,7 +56,7 @@
                 algorithm = "SunX509";
             }
             KeyManagerFactory kmf = KeyManagerFactory.getInstance( algorithm );
-            kmf.init( ks, certPasswordChars );
+            kmf.init( ks, null );
 
             // Initialize the SSLContext to work with our key managers.
             sslCtx = SSLContext.getInstance( "TLS" );
@@ -94,33 +71,5 @@
         DefaultIoFilterChainBuilder chain = new DefaultIoFilterChainBuilder();
         chain.addLast( "SSL", new SSLFilter( sslCtx ) );
         return chain;
-    }
-
-
-    private static KeyStore loadKeyStore( String storePath, String storeType ) throws KeyStoreException, IOException,
-        CertificateException, NoSuchAlgorithmException
-    {
-        FileInputStream in = null;
-        // Create keystore
-        KeyStore ks = KeyStore.getInstance( storeType );
-        try
-        {
-            in = new FileInputStream( storePath );
-            ks.load( in, null );
-            return ks;
-        }
-        finally
-        {
-            if ( in != null )
-            {
-                try
-                {
-                    in.close();
-                }
-                catch ( IOException ignored )
-                {
-                }
-            }
-        }
     }
 }

Modified: directory/apacheds/branches/bigbang/schema-bootstrap/src/main/schema/apache.schema
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/schema-bootstrap/src/main/schema/apache.schema?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/schema-bootstrap/src/main/schema/apache.schema (original)
+++ directory/apacheds/branches/bigbang/schema-bootstrap/src/main/schema/apache.schema Wed Mar 19 13:47:36 2008
@@ -421,3 +421,46 @@
 # END Schema Subentry Modification Attribute Schema 
 # =================================================
 
+# =============================================
+# SSL/TLS Key Management for LDAPS and StartTLS  
+# =============================================
+
+attributetype ( 1.3.6.1.4.1.18060.0.4.1.2.38
+    NAME 'privateKeyFormat'
+    DESC 'The format of the private key used for TLS'
+    EQUALITY caseExactIA5Match
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.18060.0.4.1.2.41
+    NAME 'publicKeyFormat'
+    DESC 'The format of the public key used for TLS'
+    EQUALITY caseExactIA5Match
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.18060.0.4.1.2.39
+    NAME 'keyAlgorithm'
+    DESC 'The algorithm used for the key/pair used by the server for TLS'
+    EQUALITY caseExactIA5Match
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.18060.0.4.1.2.40
+    NAME 'privateKey'
+    DESC 'The private key material used for TLS'
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.18060.0.4.1.2.42
+    NAME 'publicKey'
+    DESC 'The public key material used for TLS'
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE )
+
+objectclass ( 1.3.6.1.4.1.18060.0.4.1.3.11
+    NAME 'tlsKeyInfo'
+    SUP top
+    AUXILIARY
+    MUST ( privateKeyFormat $ keyAlgorithm $ privateKey $
+           publicKeyFormat $ publicKey ) )
+
+# =================================================
+# END SSL/TLS Key Management for LDAPS and StartTLS 
+# =================================================
+    
\ No newline at end of file

Modified: directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java (original)
+++ directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java Wed Mar 19 13:47:36 2008
@@ -28,6 +28,8 @@
 import org.apache.directory.server.core.DirectoryService;
 import org.apache.directory.server.core.jndi.CoreContextFactory;
 import org.apache.directory.server.ldap.LdapServer;
+import org.apache.directory.server.ldap.support.extended.StartTlsHandler;
+import org.apache.directory.server.ldap.support.extended.StoredProcedureExtendedOperationHandler;
 import org.apache.directory.server.protocol.shared.SocketAcceptor;
 import org.apache.directory.shared.ldap.exception.LdapConfigurationException;
 import org.apache.directory.shared.ldap.ldif.LdifEntry;
@@ -235,6 +237,8 @@
         directoryService.startup();
 
         configureLdapServer();
+        ldapServer.addExtendedOperationHandler( new StartTlsHandler() );
+        ldapServer.addExtendedOperationHandler( new StoredProcedureExtendedOperationHandler() );
         ldapServer.start();
         setContexts( ServerDNConstants.ADMIN_SYSTEM_DN, "secret" );
     }

Modified: directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/StoredProcedureExecutionITest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/StoredProcedureExecutionITest.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/StoredProcedureExecutionITest.java (original)
+++ directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/StoredProcedureExecutionITest.java Wed Mar 19 13:47:36 2008
@@ -58,9 +58,8 @@
     
     @Before public void setUp() throws Exception
     {
-
         super.setUp();
-
+        
         Hashtable<String, Object> env = new Hashtable<String, Object>();
         env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
         env.put( "java.naming.provider.url", "ldap://localhost:" + port + "/ou=system" );
@@ -73,6 +72,7 @@
         spContainer.get( "objectClass" ).add( "organizationalUnit" );
         spContainer.put( "ou", "Stored Procedures" );
         spCtx = ( LdapContext ) ctx.createSubcontext( "ou=Stored Procedures", spContainer );
+        assertNotNull( spCtx );
         
         // Initialize OIDs maps for normalization
         oids = new HashMap<String, OidNormalizer>();

Modified: directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/LdapsITest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/LdapsITest.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/LdapsITest.java (original)
+++ directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/LdapsITest.java Wed Mar 19 13:47:36 2008
@@ -30,9 +30,6 @@
 import javax.naming.directory.Attributes;
 import javax.naming.directory.DirContext;
 import javax.naming.directory.InitialDirContext;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.IOException;
 import java.util.Hashtable;
 
 
@@ -77,34 +74,6 @@
     protected void configureLdapServer()
     {
         ldapServer.setEnableLdaps( true );
-        ldapServer.setLdapsCertificatePassword( "boguspw" );
-//        ldapServer.setIpPort( ldapsPort );
-
-        // Copy the bogus certificate to the certificates directory.
-        InputStream in = getClass().getResourceAsStream( "/bogus.cert" );
-        ldapServer.getLdapsCertificateFile().getParentFile().mkdirs();
-
-        try
-        {
-            FileOutputStream out = new FileOutputStream( ldapServer.getLdapsCertificateFile() );
-
-            for ( ;; )
-            {
-                int c = in.read();
-                if ( c < 0 )
-                {
-                    break;
-                }
-                out.write( c );
-            }
-
-            in.close();
-            out.close();
-        } catch ( IOException e )
-        {
-            throw new RuntimeException( e );
-        }
-
     }
 
     /**

Added: directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/StartTlsITest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/StartTlsITest.java?rev=639006&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/StartTlsITest.java (added)
+++ directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/StartTlsITest.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,85 @@
+/*
+ *   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 java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.directory.Attributes;
+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.unit.AbstractServerTest;
+import org.apache.directory.shared.ldap.util.DummySSLSocketFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Test case for StartTls.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class StartTlsITest extends AbstractServerTest
+{
+    private static final Logger LOG = LoggerFactory.getLogger( StartTlsITest.class );
+    
+    
+    public void testStartTls() throws Exception
+    {
+//        // 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" );
+//        env.put( "java.naming.ldap.factory.socket", DummySSLSocketFactory.class.getName() );
+//        
+//        // Must use the name of the server that is found in its certificate
+//        env.put( Context.PROVIDER_URL, "ldap://localhost:" + port );
+//
+//        // Create initial context
+//        LOG.error( "About to get initial context" );
+//        LdapContext ctx = new InitialLdapContext( env, null );
+//
+//        // Start TLS
+//        LOG.error( "About send startTls extended operation" );
+//        StartTlsResponse tls = ( StartTlsResponse ) ctx.extendedOperation( new StartTlsRequest() );
+//        LOG.error( "Extended operation issued" );
+//        tls.setHostnameVerifier( new HostnameVerifier() {
+//            public boolean verify( String hostname, SSLSession session )
+//            {
+//                return true;
+//            } 
+//        } );
+//        LOG.error( "TLS negotion about to begin" );
+//        SSLSession session = tls.negotiate( new DummySSLSocketFactory() );
+//        
+//        ctx.addToEnvironment( "java.naming.security.principal", "uid=admin,ou=system" );
+//        ctx.addToEnvironment( "java.naming.security.credentials", "secret" );
+//        ctx.addToEnvironment( "java.naming.security.authentication", "simple" );
+//
+//        Attributes attrs = ctx.getAttributes( "ou=system" ); 
+//        System.out.println( attrs.toString() );
+    }
+}

Modified: directory/apacheds/branches/bigbang/server-xml/src/main/resources/server.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-xml/src/main/resources/server.xml?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-xml/src/main/resources/server.xml (original)
+++ directory/apacheds/branches/bigbang/server-xml/src/main/resources/server.xml Wed Mar 19 13:47:36 2008
@@ -134,10 +134,9 @@
   </dnsServer>
 -->
 
-<!-- no certificate  -->
   <ldapServer id="ldapsServer"
-          enabled="false"
-              ipPort="60636"
+              enabled="true"
+              ipPort="10636"
               enableLdaps="true">
     <directoryService>#directoryService</directoryService>
     <socketAcceptor>#socketAcceptor</socketAcceptor>
@@ -177,7 +176,7 @@
 
     <!-- the collection of extended operation handlers to install           -->
     <extendedOperationHandlers>
-      <!--startTlsHandler/-->
+      <startTlsHandler/>
       <gracefulShutdownHandler/>
       <launchDiagnosticUiHandler/>
       <!-- The Stored Procedure Extended Operation is not stable yet and it may cause security risks.-->

Propchange: directory/installers/branches/bigbang/apacheds-noarch/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Mar 19 13:47:36 2008
@@ -1,4 +1,5 @@
 server.xml
+*.log.*
 work
 META-INF
 server-work

Modified: directory/installers/branches/bigbang/apacheds-noarch/log4j.properties
URL: http://svn.apache.org/viewvc/directory/installers/branches/bigbang/apacheds-noarch/log4j.properties?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/installers/branches/bigbang/apacheds-noarch/log4j.properties (original)
+++ directory/installers/branches/bigbang/apacheds-noarch/log4j.properties Wed Mar 19 13:47:36 2008
@@ -40,4 +40,5 @@
 # Remove me when the unbind problem has gone away:
 # https://issues.apache.org/jira/browse/DIRSERVER-1047
 log4j.logger.org.apache.directory.server.ldap.support.UnbindHandler=OFF
+log4j.logger.org.apache.directory.server.schema.registries=WARN
 

Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixTransformer.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixTransformer.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixTransformer.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixTransformer.java Wed Mar 19 13:47:36 2008
@@ -302,7 +302,7 @@
     private Message transformExtendedRequest( LdapMessage twixMessage, int messageId )
     {
         ExtendedRequest extendedRequest = twixMessage.getExtendedRequest();
-        ExtendedRequestImpl snickersMessage = null;
+        ExtendedRequestImpl snickersMessage;
 
         if ( extendedRequest.getRequestName().equals( GracefulShutdownRequest.EXTENSION_OID ) )
         {

Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DirectoryClassUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DirectoryClassUtils.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DirectoryClassUtils.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DirectoryClassUtils.java Wed Mar 19 13:47:36 2008
@@ -20,6 +20,9 @@
 
 package org.apache.directory.shared.ldap.util;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.lang.reflect.Method;
 import java.util.Arrays;
 
@@ -29,9 +32,10 @@
  */
 public class DirectoryClassUtils
 {
+    private static final Logger LOG = LoggerFactory.getLogger( DirectoryClassUtils.class );
     
     /**
-     * A replacement for {@link java.lang.Class.getMethod} with extended capability.
+     * A replacement for {@link java.lang.Class#getMethod} with extended capability.
      * 
      * <p>
      * This method returns parameter-list assignment-compatible method as well as
@@ -41,13 +45,31 @@
      * @param candidateMethodName Name of the method been looked for.
      * @param candidateParameterTypes Types of the parameters in the signature of the method being loooked for.
      * @return The Method found.
-     * @throws NoSuchMethodException
+     * @throws NoSuchMethodException when the method cannot be found
      */
     public static Method getAssignmentCompatibleMethod( Class<?> clazz,
                                                         String candidateMethodName,
                                                         Class<?>[] candidateParameterTypes
                                                       ) throws NoSuchMethodException
     {
+        if ( LOG.isDebugEnabled() )
+        {
+            StringBuilder buf = new StringBuilder();
+            buf.append( "call to getAssignmentCompatibleMethod(): \n\tclazz = " );
+            buf.append( clazz.getName() );
+            buf.append( "\n\tcandidateMethodName = " );
+            buf.append( candidateMethodName );
+            buf.append( "\n\tcandidateParameterTypes = " );
+
+            for ( Class<?> argClass : candidateParameterTypes )
+            {
+                buf.append( "\n\t\t" );
+                buf.append( argClass.getName() );
+            }
+
+            LOG.debug( buf.toString() );
+        }
+
         try
         {
             // Look for exactly the same signature.
@@ -58,9 +80,12 @@
                 return exactMethod;
             }
         }
-        catch ( SecurityException e ) { }
-        catch ( NoSuchMethodException e ) { }
-        
+        catch ( Exception e )
+        {
+            LOG.info( "Could not find accessible exact match for candidateMethod {}", candidateMethodName, e );
+        }
+
+
         /**
          * Look for the assignment-compatible signature.
          */
@@ -103,6 +128,7 @@
             return methods[ mx ];
         }
         
-        throw new NoSuchMethodException( clazz.getName() + "." + candidateMethodName + "(" + Arrays.toString( candidateParameterTypes ) + ")" );
+        throw new NoSuchMethodException( clazz.getName() + "." + candidateMethodName
+            + "(" + Arrays.toString( candidateParameterTypes ) + ")" );
     }
 }

Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DummySSLSocketFactory.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DummySSLSocketFactory.java?rev=639006&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DummySSLSocketFactory.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DummySSLSocketFactory.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,213 @@
+/*
+ *  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.shared.ldap.util;
+
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+
+/**
+ * A SSLSocketFactory that accepts every certificat without validation.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DummySSLSocketFactory extends SSLSocketFactory
+{
+
+    /** The default instance. */
+    private static SocketFactory instance;
+
+
+    /**
+     * Gets the default instance.
+     * 
+     * Note: This method is invoked from the JNDI framework when 
+     * creating a ldaps:// connection.
+     * 
+     * @return the default instance
+     */
+    public static SocketFactory getDefault()
+    {
+        if ( instance == null )
+        {
+            instance = new DummySSLSocketFactory();
+        }
+        return instance;
+    }
+
+    /** The delegate. */
+    private SSLSocketFactory delegate;
+
+
+    /**
+     * Creates a new instance of DummySSLSocketFactory.
+     */
+    public DummySSLSocketFactory()
+    {
+        try
+        {
+            TrustManager tm = new X509TrustManager()
+            {
+                public X509Certificate[] getAcceptedIssuers()
+                {
+                    return new X509Certificate[0];
+                }
+
+
+                public void checkClientTrusted( X509Certificate[] arg0, String arg1 ) throws CertificateException
+                {
+                }
+
+
+                public void checkServerTrusted( X509Certificate[] arg0, String arg1 ) throws CertificateException
+                {
+                }
+            };
+            TrustManager[] tma =
+                { tm };
+            SSLContext sc = SSLContext.getInstance( "TLS" ); //$NON-NLS-1$
+            sc.init( null, tma, new SecureRandom() );
+            delegate = sc.getSocketFactory();
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+        }
+    }
+
+
+    /**
+     * @see javax.net.ssl.SSLSocketFactory#getDefaultCipherSuites()
+     */
+    public String[] getDefaultCipherSuites()
+    {
+        return delegate.getDefaultCipherSuites();
+    }
+
+
+    /**
+     * @see javax.net.ssl.SSLSocketFactory#getSupportedCipherSuites()
+     */
+    public String[] getSupportedCipherSuites()
+    {
+        return delegate.getSupportedCipherSuites();
+    }
+
+
+    /**
+     * @see javax.net.ssl.SSLSocketFactory#createSocket(java.net.Socket, java.lang.String, int, boolean)
+     */
+    public Socket createSocket( Socket arg0, String arg1, int arg2, boolean arg3 ) throws IOException
+    {
+        try
+        {
+            return delegate.createSocket( arg0, arg1, arg2, arg3 );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.lang.String, int)
+     */
+    public Socket createSocket( String arg0, int arg1 ) throws IOException, UnknownHostException
+    {
+        try
+        {
+            return delegate.createSocket( arg0, arg1 );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.net.InetAddress, int)
+     */
+    public Socket createSocket( InetAddress arg0, int arg1 ) throws IOException
+    {
+        try
+        {
+            return delegate.createSocket( arg0, arg1 );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.lang.String, int, java.net.InetAddress, int)
+     */
+    public Socket createSocket( String arg0, int arg1, InetAddress arg2, int arg3 ) throws IOException,
+        UnknownHostException
+    {
+        try
+        {
+            return delegate.createSocket( arg0, arg1, arg2, arg3 );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.net.InetAddress, int, java.net.InetAddress, int)
+     */
+    public Socket createSocket( InetAddress arg0, int arg1, InetAddress arg2, int arg3 ) throws IOException
+    {
+        try
+        {
+            return delegate.createSocket( arg0, arg1, arg2, arg3 );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+}