Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: LDAP over SSL from servlet

303 views
Skip to first unread message

shoedeep

unread,
Mar 9, 2005, 2:00:13 PM3/9/05
to
Hi Susan ,
Correct me if i am wrong ,as I understand iManager is a plugin
to work with the LDAP server installation on the specific machine and not
a standlaone application which can be installed on any machine to connect
to any LDAP server . I have only access to LDAP server using a client
browser to view the object structure . I do not have any access to the
server itself to integrate the plugin .
In this situation I can get the .der file/certificate only from the server
admin and then run then run the keytool utility .
Please let me know if my observation is correct I have already contacted
LDAP server adming to provide me with certificate /path.

Please let me know of your views
Thanks


Susan Perrin wrote:

> Hi,

> You could use ConsoleOne or iManager to look at the ldap server object/ssl
> settings to look at the name of the certificate eDirectory is using
> (probably SSL CertificateDNS - servername). Then you can bring up that
> certificate object, under Certificates/Trusted Root use export to export it
> to a .der file.

> Then you can manually run keytool

> keytool -import -file myCert.der -alias myName -keystore .sslkey

> or you could just run TLSTrustManager sample at
>
http://developer.novell.com/ndk/doc/samplecode/jldap_sample/security/TLSTrustManager.java.html
> which will create a keystore file for you based on the dynamic cert exchange
> with the server.

> Then the question is where tomcat will look for the file. I believe it uses
> a default file called .keystore location specific to platform and install.

> I hope this helps.

> Thank you
> Susan


@novell.com Susan Perrin

unread,
Mar 9, 2005, 2:15:10 PM3/9/05
to
Hi,

If I understand your response, if you don't have iManager pieces installed
on the eDirectory server, you can't use it as an admin tool. If you do, it
can be run remotely from a browser. ConsoleOne can be run from any client
but it requires Novell client software be installed.

But if for whatever reason you don't have access to management tools for
eDirectory, that's why I suggested the TLSTrustManager sample which will
dynamically read the server's certificate and output a keystore file for you
without having to export it using C1 or iManager. The sample is a useful
tool.

Thank you
Susan


shoedeep

unread,
Mar 9, 2005, 4:34:33 PM3/9/05
to
Hi ,
Thanks for your response . I can not configure iManager as I dont have
admin credentials available . For TLSTrustManager I will need keyStorePath
and keyStorePassword . I am trying to figure out if there is already
existing keystore for the certificate
Thanks

@novell.com Susan Perrin

unread,
Mar 9, 2005, 4:42:55 PM3/9/05
to
Hi,

If you don't already have a keystore, TLSTrustManager will create it with
the path/file and password you enter.

You don't need to be admin, just run it as anonymous, for example:

java -classpath .;c:\novell\ndk\ndssdk\java\lib_debug\ldap.jar
TLSTrustManager nldap.com 636 "" "" mynewstore novell

I believe tomcat uses .keystore file with password changeit. But this is a
way to test.

Thank you
Susan


shoedeep

unread,
Mar 10, 2005, 2:54:28 PM3/10/05
to
Hi ,
This is what i am getting as error. Does it mean SSL port is some
other port , or SSL port is not enable or I am missing something . I have
masked the server name for security reason
------------------------------------------------------------------------------
C:\Novell\ndk\samples\jldap_sample\security>java TLSTrustManager
XXXX.XXXX.edu:636 "" "" mynewstore novell
LDAP Error: LDAPException: Unable to connect to server XXXX.XXXX.edu:636
(91) Connect Error
java.net.ConnectException: Connection timed out: connect

C:\Novell\ndk\samples\jldap_sample\security>java TLSTrustManager XXXX.XXXX.edu
"" "" mynewstore novell
LDAP Error: LDAPException: Unable to connect to server XXXX.XXXX.edu:636
(91) Connect Error
java.net.ConnectException: Connection timed out: connect
------------------------------------------------------------------------------
Please do let me know

Thanks in advance .
Sonika Gupta

Susan Perrin wrote:

> Hi,

> If you don't already have a keystore, TLSTrustManager will create it with
> the path/file and password you enter.

> You don't need to be admin, just run it as anonymous, for example:

> java -classpath .;c:novellndkndssdkjavalib_debugldap.jar

@novell.com Susan Perrin

unread,
Mar 10, 2005, 3:50:14 PM3/10/05
to
Hi

The sample is written so that the port is a separate parameter, so instead
of

java TLSTrustManager
XXXX.XXXX.edu:636 "" "" mynewstore novell

I assume you're using:

java TLSTrustManager
XXXX.XXXX.edu 636 "" "" mynewstore novell

If ssl were disabled, I'd assume you get "connection refused" not
"connection timed out".

Can you get a non - ssl connection to XXXX.XXXX.edu? (for example,
ldapsearch -h XXXX.XXXX.edu). You don't have a DNS problem do you?

Thank you
Susan

shoedeep

unread,
Mar 10, 2005, 5:30:23 PM3/10/05
to
I tried that too and it gives the error as shown below . I looked at the
code also , it does not take port number as a parameter it seems .
------------------------------------------------------------------------------
C:\Novell\ndk\samples\jldap_sample\security>java TLSTrustManager XXXX.XXXX.edu
636 "" "" mynewstore novell
Usage: java TLSTrustManager <host name> <login dn> <password> <keystore
path><keystore password>*Note: If <keystore path> does not exist it will
be created if the untrusted certificate chain is trusted by the
user.Example: java TLSTrustManager Acme.com "cn=Admin,o=Acme" secret
my.keystore myke
ypass
---------------------------------------------------------------------------
This is the code from the TLSTrustManager.java file
-----------------------------------------------------------------------------
String ldapHost = args[0];
String loginDN = args[1];
String password = args[2];
String keyStorePath = args[3];
char[] keyStorePassword = args[4].toCharArray()
------------------------------------------------------------------------------
So I do not see the code using port number also .

I tried following java code to see if my connectivity to ldap server is
fine and it works fine giving the output .

----------------------------------------------
cn=SSGUPTA,ou=Students,ou=Labs,o=XXXXX
1
----------------------------------------------------
---------------------------------------------------
java code
-------------------------------------------
public class ListCredentials
{
public static void main(String args[])
throws LDAPException
{
LDAPConnection c=new LDAPConnection ();
LDAPSearchConstraints cons = new LDAPSearchConstraints();
cons.setTimeLimit(20000);
cons.setMaxResults(5000);

String searchFilter = "(cn=ssgupta)";
//String searchFilter = "(ou=students)";

c.connect ("XXXX.XXXX.edu", 389);

//this line to get credentials for students
LDAPSearchResults res = c.search("ou=students , ou=labs
,o=XXXXX",LDAPConnection.SCOPE_ONE, searchFilter, null,false,cons);
int i = 0 ;

while (res.hasMore())
{
i++ ;
System.out.println(res.next().getDN());
System.out.println(i);


}
c.disconnect();

}
}

-------------------------------------------------------------------------
So I guess that I am able to connect to the server properly . Only issue
is with SSL connection

Thanks
Sonika

@novell.com Susan Perrin

unread,
Mar 10, 2005, 7:04:18 PM3/10/05
to
oops, sorry. I don't know if I've got an older version or if I modified my
copy for some reason.

It looks like the shipping version at
http://developer.novell.com/ndk/doc/samplecode/jldap_sample/security/TLSTrustManager.java.html
is setting the port to LDAPConnection.DEFAULT_SSL_PORT

In that case you wouldn't use XXXX.XXXX.edu:636 you would just use
XXXX.XXXX.edu

Or use mine, because I think explicitly setting the port is a good idea,
incase it's not 636.

/***************************************************************************
****
* $Novell: TLSTrustManager.java,v 1.6 2003/08/21 11:56:19 $
* Copyright (C) 1999, 2000, 2001 Novell, Inc. All Rights Reserved.
*
* THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
* TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE
* AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS
* THIS WORK. PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO
* DEVELOPER A ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S
SAMPLE
* CODE IN ITS PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION
RIGHTS
* TO MARKET, DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF
* DEVELOPER'S PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR
* DEVELOPER'S CUSTOMERS WITH RESPECT TO THIS CODE.
*
* $name: TLSTrustManager.java
*
* $description: The TLSTrustManager.java sample shows how to set up a
JSSE
* SSL connection and implement an SSLContext trust manager
* (X509TrustManager). This trust manager is implemented as
a
* sub_class called MyTrustManager.MyTrustManager will
search
* the keystore for an entry that matches the certificate
* chain. If a match is found the chain is trusted. If no
match
* is found the user will be queried with information about
the
* unknown chain, to see if the user wants to trust it. If
* trusted the unknown chain is added to the keystore and
the
* connection succeeds. If not the connection fails.
*
* The reason that someone would implement their own trust
* manager is to allow human interaction to decide weather
a
* certificate chain should be trusted or not. The default
* trust manager in the SSLContext does not allow this.
*
* The keystore is the JSSE trusted certificate store.
*
* See:
http://java.sun.com/j2se/1.4/docs/guide/security/jsse/
* JSSERefGuide.html for information on JSSE, SSLContext,
and
* trust managers (X509TrustManager).
*
* Note:
* eDirectory 8.7 and above support TLS.
*
* This sample uses objects specific to Sun's JSSE provider.
* This provider is included with JDK1.4, otherwise you must obtain
the
* JSSE package from Sun. This sample must be used with version 1.7
or
* later of the Java LDAP NDK.
*

****************************************************************************
**/
import com.novell.ldap.LDAPJSSESecureSocketFactory;
import com.novell.ldap.LDAPConnection;
import com.novell.ldap.LDAPException;
import com.sun.net.ssl.SSLContext;
import com.sun.net.ssl.TrustManager;
import com.sun.net.ssl.X509TrustManager;
import com.sun.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.security.Security;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.io.UnsupportedEncodingException;

public class TLSTrustManager
{
public static void main( String[] args )
{
try
{
// Check for valid arguments
if (args.length != 4 && args.length != 6)
{
System.err.println("Usage: java TLSTrustManager <host
name> <port> "
+ " <login dn> <password>"
+ " <keystore path> <keystore password>");
System.err.println("*Note: If <keystore path> does not"
+ " exist it will be created if the
untrusted"
+ " certificate chain is trusted by the
user."
);
System.err.println("Example: java TLSTrustManager Acme.com
636"
+ " \"cn=Admin,o=Acme\" secret my.keystore"
+ " mykeypass");
System.exit(1);
}

String ldapHost = args[0];

int port = new Integer(args[1]).intValue();
String loginDN = args[2];
String password = args[3];
String keyStorePath = args[4];
char[] keyStorePassword = args[5].toCharArray();

//dynamically set SunJSSE as a security provider
Security.addProvider(new
com.sun.net.ssl.internal.ssl.Provider());

// Open the keystore file.
FileInputStream keyStoreIStream = null;
try
{
// Open the stream to read in the keystore.
keyStoreIStream = new FileInputStream(keyStorePath);
}
catch( FileNotFoundException e )
{
// If the path does not exist then a null stream means
// the keystore is initialized empty. If an untrusted
// certificate chain is trusted by the user, then it will be
// saved in the file pointed to by keyStorePath.
keyStoreIStream = null;
}
// Create a KeyStore Object
KeyStore keyStore =
KeyStore.getInstance(KeyStore.getDefaultType());
// Init the Keystore with the contents of the keystore file.
// If the input stream is null the keystore is initialized
empty.
keyStore.load(keyStoreIStream, keyStorePassword);

// Close keystore input stream
if(keyStoreIStream != null)
{
keyStoreIStream.close();
keyStoreIStream = null;
}

// Instantiate MyTrustManager that will handle server
certificate
// chains.
TrustManager[] tms = {new MyTrustManager(keyStore,
keyStorePath,
keyStorePassword)};

// Create context based on a TLS protocol and a SunJSSE
provider.
SSLContext context = SSLContext.getInstance("TLS", "SunJSSE");

// Initialize the SSL context with MyTrustManager.
// The first parameter - null means use the default key manager.
// The third parameter - null means use the default value
// "secure random".
context.init(null, tms, null);


// The socket factory must be set before the connection is made.
// Version 1.6 or later of the NDK must be used in order for
this
// code to compile properly.
LDAPJSSESecureSocketFactoryCC ssf =
new LDAPJSSESecureSocketFactoryCC(
context.getSocketFactory() );

// Create an LDAP connection object. Pass in the secure socket.
LDAPConnection lc = new LDAPConnection(ssf);

// Connect to the server.
lc.connect( ldapHost, port );

// Authenticate to the server
lc.bind( LDAPConnection.LDAP_V3, loginDN,
password.getBytes("UTF8") );

// At this point you are connected with a secure connection.
System.out.println( "Successful bind using TLS connection.");

// Close the connection.
lc.disconnect();
System.out.println( "Disconnect");

System.exit(0);
}
catch( UnsupportedEncodingException e ) {
System.out.println( "Error: " + e.toString() );
}
catch( LDAPException ex )
{
System.out.println( "LDAP Error: " + ex.toString() );
}
catch( Exception e )
{
System.out.println( "main Error: " + e.toString() );
System.exit(1);
}
}

// MyTrustManager
// This sub_class implements the X509TrustManager interface.
MyTrustManager
// trusts known certificate chains, and queries the user to approve
unknown
// chains. It will add trusted chains to the keystore.

private static class MyTrustManager implements X509TrustManager
{
private KeyStore keyStore;
private String keyStorePath;
private char[] keyStorePassword;


// MyTrustManager constructor. Save off keyStore object along with
// the path to the keystore (keyStorePath) and it's password
// (keyStorePassword).
public MyTrustManager(KeyStore keyStore,
String keyStorePath,
char[] keyStorePassword)
{
this.keyStore = keyStore;
this.keyStorePath = keyStorePath;
this.keyStorePassword = keyStorePassword;
}

// isClientTrusted checks to see if the chain is in the keyStore
object.
// This is done with a call to isChainTrusted.
public boolean isClientTrusted(X509Certificate[] chain)
{
return isChainTrusted(chain);
}

// isServerTrusted checks to see if the chain is in the keyStore
object.
// This is done with a call to isChainTrusted. If not it queries the
// user to see if the chain should be trusted and stored into the
// keyStore object. The keyStore is then saved in the file whose
path
// keyStorePath
public boolean isServerTrusted(X509Certificate[] chain)
{
boolean trusted = false;
try
{
// See if the chain is in the keyStore object.
trusted = isChainTrusted(chain);

// If certificate is untrusted
if(!trusted)
{
System.out.println("Untrusted Certificate chain:");
for (int i = 0; i < chain.length; i++)
{
// display certificate chain information
System.out.println("Certificate chain[" + i + "]:");
System.out.println("Subject: "
+
chain[i].getSubjectDN().toString());
System.out.println("Issuer: "
+
chain[i].getIssuerDN().toString());
}
// Ask the user if the certificate should be trusted.
System.out.print("Trust this certificate chain and"
+ " add it to the keystore? (y or n) ");
int readStatus = System.in.read();
if(readStatus == 'y'|| readStatus == 'Y')
{
// Trust the chain.
trusted = true;
// Add Chain to the keyStore.
for (int i = 0; i < chain.length; i++)
{
keyStore.setCertificateEntry
(chain[i].getIssuerDN().toString(),
chain[i]);
}
System.out.println("Certificate chain to
keystore.");
// Save keystore to file.
FileOutputStream keyStoreOStream =
new FileOutputStream(keyStorePath);
keyStore.store(keyStoreOStream, keyStorePassword);
keyStoreOStream.close();
keyStoreOStream = null;
System.out.println("Keystore saved in " +
keyStorePath);
}
else
trusted = false;
}
}
catch( Exception e )
{
System.out.println( "isServerTrusted Error: " +
e.toString() );
trusted = false;
}
return trusted;
}

// getAcceptedIssuers retrieves all of the certificates in the
keyStore
// and returns them in an X509Certificate array.
public X509Certificate[] getAcceptedIssuers()
{
X509Certificate[] X509Certs = null;
try
{
// See how many certificates are in the keystore.
int numberOfEntry = keyStore.size();
// If there are any certificates in the keystore.
if(numberOfEntry > 0)
{
// Create an array of X509Certificates
X509Certs = new X509Certificate[numberOfEntry];

// Get all of the certificate alias out of the keystore.
Enumeration aliases = keyStore.aliases();

// Retrieve all of the certificates out of the keystore
// via the alias name.
int i = 0;
while (aliases.hasMoreElements())
{
X509Certs[i] =
(X509Certificate)keyStore.
getCertificate((String)aliases.nextElement());
i++;
}

}
}
catch( Exception e )
{
System.out.println( "getAcceptedIssuers Exception: "
+ e.toString() );
X509Certs = null;
}
return X509Certs;
}

// isChainTrusted searches the keyStore for any certificate in the
// certificate chain.
private boolean isChainTrusted(X509Certificate[] chain)
{
boolean trusted = false;
try
{
// Start with the root and see if it is in the Keystore.
// The root is at the end of the chain.
for (int i = chain.length - 1; i >= 0; i-- )
{
if (keyStore.getCertificateAlias(chain[i]) != null)
{
trusted = true;
break;
}
}
}
catch( Exception e )
{
System.out.println( "isChainTrusted Exception: "
+ e.toString() );
trusted = false;
}
return trusted;
}
}
}


0 new messages