[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[iaik-ssl] the SSLClient example



Hi, I've tried to use your SSLClient example provided in the iSaSiLk
documentation.
I've made some minor changes in order to compile it.
At runtime I have this ouptut:

--------
add Provider IAIK...

Ok, verificato.
creato il key and certificate.
Connect to thunder.polito.it:8443

InputRecord locked.
OutputRecord locked.
starting handshake.
send client_hello...
v3ClientHello, version: 3.0
received server_hello...
Server doesn't want to resume a previous session.
CipherSuite selected by server: SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
CompressionMethod selected by server: NULL
received Certificate...
Exception during handshaking: java.lang.ClassCastException:
java.lang.Object
Fatal SSL handshake error!
----------

I use a personal certificate exported from Netscape Navigator and I read
it in a PKCS12 object.

It seems that something happens during the startHandshake method... but
I don't have any clue.

I've sent in attachment the files SSLClient.java and
SampleClientTrustDecider.java

Could anybody help me, please?

Riccardo Conturbia
import java.io.*;
import java.net.*;
import java.security.*;
// import java.security.cert.X509Certificate;

import iaik.x509.X509Certificate;
import iaik.security.ssl.*;
import iaik.security.provider.IAIK;
import iaik.security.rsa.*;
import iaik.pkcs.*;

// Demo SSL implementation.

public class SSLClient
{
   static PrintWriter writer = null;
   static BufferedReader reader = null;
   
   public static void proxyConnect(String host, int port) throws IOException
   {
      String request = new String("CONNECT " + host + ":" + port + " HTTP/1.0");
      writer.println(request);
      writer.println();               
      writer.flush();
      // legge e stampa le risposte del proxy
      String line;
      do
      {
         line = reader.readLine();
         System.out.println("Proxy sends: " + line);
      } 
      while (line.length() > 0);
      System.out.println();
   }
   
   public static void main(String arg[]) throws IOException
   {
      BufferedReader key = new BufferedReader(new InputStreamReader(System.in));
      
      String serverName = null;
      int serverPort = 433;
      String proxyName = null;
      int proxyPort = 9999;
      
      System.out.println("add Provider IAIK...\n");
      IAIK.addAsProvider();
      
      if (arg.length >= 1)
         serverName = arg[0];
      else
      {
         System.out.println("Usage: server host:port [proxy:port]\nYou can try: ssl3.netscape.com:433\n");
         System.exit(0);
      }
      
      int p = serverName.indexOf(58);
      if (p > 0)
      {
         serverPort = Integer.decode(serverName.substring(p+1)).intValue();
         serverName = serverName.substring(0, p);
      }
      
      // legge il nome del proxy e la sua porta
      if (arg.length >= 2)
      {
         proxyName = arg[1];
         
         p = proxyName.indexOf(58);
         if (p > 0)
         {
            proxyPort = Integer.decode(proxyName.substring(p+1)).intValue();
            proxyName = proxyName.substring(0, p);
         }  
      }
      
      SSLSocket s = null;
      SSLClientContext context = new SSLClientContext();
      
      CipherSuite[] cs = new CipherSuite[10];
      cs[3] = CipherSuite.SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA;
      cs[4] = CipherSuite.SSL_DH_anon_EXPORT_WITH_RC4_40_MD5;
      cs[5] = CipherSuite.SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA;
      cs[6] = CipherSuite.SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA;
      cs[7] = CipherSuite.SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA;
      cs[8] = CipherSuite.SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA;
      cs[0] = CipherSuite.SSL_RSA_EXPORT_WITH_DES40_CBC_SHA;
      cs[1] = CipherSuite.SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5;
      cs[2] = CipherSuite.SSL_RSA_EXPORT_WITH_RC4_40_MD5;
      cs[9] = CipherSuite.SSL_NULL_WITH_NULL_NULL;

      
      context.setEnabledCipherSuites(cs);
      
      SampleClientTrustDecider trustDecider = new SampleClientTrustDecider(true);
      
      context.setTrustDecider(trustDecider);
      
      System.out.print("Connect to " + serverName + ":" + serverPort);
      
      if (proxyName != null)
         System.out.print(" via" + proxyName + ":" + proxyPort);
      
      System.out.println("\n");
      
      try
      {
         if (proxyName == null)
         {
            s = new SSLSocket(serverName, serverPort, context);
            s.setDebugStream(System.out);
            reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
            writer = new PrintWriter(s.getOutputStream());
         }
         else
         {
            s = new SSLSocket(proxyName, proxyPort, context);
            s.setDebugStream(System.out);
            
            s.setAutoHandshake(false);
            reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
            writer = new PrintWriter(s.getOutputStream());
            
            proxyConnect(serverName, serverPort);
            
            s.startHandshake();
         }
         
         System.out.println("\nConnection established...\n");
         System.out.println("Active cipher suite: " + s.getActiveCipherSuite().getName());
         System.out.println("Active compression method: " + s.getActiveCompressionMethod().getName());
         System.out.println("\nServer certificate chain:");
         X509Certificate[] chain = (iaik.x509.X509Certificate[])s.getPeerCertificateChain();
         for (int i = 0; i < chain.length; i++)
            System.out.println("Certificate " + i + ": " + chain[i].getSubjectDN());
         System.out.println();
         
         String request = new String("GET / HTTP/1.0");
         System.out.println("Send request for server homepage...");
         writer.println(request);
         writer.println();
         writer.flush();
         
         String line;
         do
         {
            line = reader.readLine();
            System.out.println("Server sends: " + line);
         }
         while (line != null);
         
         s.close();
      }
      catch (UnknownHostException ex)
      {
         System.out.println("UnknownHostException: " + ex.getMessage());
      }
      catch (IOException ex)
      {
         System.out.println(ex.getMessage());
      }
      catch (Exception ex)
      {
         System.out.println("Exception: " + ex.getMessage());
      }  
      
      key.readLine();
   }
}
import java.security.*;
import java.io.*;
//import java.security.cert.X509Certificate;

import iaik.x509.X509Certificate;
import iaik.security.ssl.*;
import iaik.asn1.*;
import iaik.asn1.structures.Name;
import iaik.security.rsa.*;
import iaik.security.dsa.*;
import iaik.security.dh.*;
import iaik.pkcs.*;
import iaik.utils.KeyAndCertificate;
import iaik.pkcs.pkcs8.EncryptedPrivateKeyInfo;
import iaik.pkcs.pkcs8.PrivateKeyInfo;
import iaik.pkcs.pkcs12.*;

public class SampleClientTrustDecider implements ClientTrustDecider
{
   private X509Certificate[] rsa_cert;
   private iaik.security.rsa.RSAPrivateKey rsa_private_key;
   private PrivateKey private_key;
   boolean debug;

   char[] password = "riccardo".toCharArray();
   
   public SampleClientTrustDecider(boolean printDebugInfo)
   {
      debug = printDebugInfo;
      try
      {
         KeyAndCertificate kac;
         EncryptedPrivateKeyInfo epki;
         
         PKCS12 pkcs12 = new PKCS12(new FileInputStream("cert.pfx"));
         pkcs12.decrypt(password);
         
         if (pkcs12.verify(password)) System.out.println("Ok, verificato.");
         else System.out.println("Ahio... non e' verificato...");
         
         CertificateBag[] cb;
         cb = pkcs12.getCertificateBags();
         
         X509Certificate[] cert;
         cert = CertificateBag.getCertificates(cb);
         
         KeyBag kb;
         kb = pkcs12.getKeyBag();

         kac = new KeyAndCertificate(kb.getPrivateKey(), cert);
         System.out.println("creato il key and certificate.");
                  
         rsa_private_key = (iaik.security.rsa.RSAPrivateKey)kac.getPrivateKey();
         rsa_cert = kac.getCertificateChain();
                           
      }
      catch (iaik.pkcs.PKCSParsingException e)
      {
         System.out.println("Problemi con il parsing: " + e.getMessage());
      }
      catch (iaik.pkcs.PKCSException e)
      {
         System.out.println("Problemi..." + e.getMessage());
      }
      catch (IOException ex)
      {
         System.out.println("IOException: " + ex.getMessage());
      }
   }
   
   public boolean verifyCertificateChain(X509Certificate[] chain)
   {
      int len = chain.length;
      
      try
      {
         chain[len-1].verify(chain[len-1].getPublicKey()); // top level
         for (int i = len-1; i<0; i--)
            chain[i-1].verify(chain[i].getPublicKey());
      }
      catch (Exception ex)
      {
         return false;
      }
      return true;
   }
   
   public boolean isTrustedPeer(SSLCertificate certificate)
   {
      X509Certificate[] certChain = (iaik.x509.X509Certificate[])certificate.getCertificateChain();
      debug("Server certificate chain");
      for (int i=0; i<certChain.length; i++)
         debug(certChain[i].getSubjectDN().toString());
      
      return verifyCertificateChain(certChain);
   }
   
   public iaik.security.ssl.SSLCertificate getCertificate(byte[] certificateTypes, iaik.java.security.Principal[] certificateAuthorities,
                                        String keyExchangeAlgorithm)
   {
      debug("Key exchange algorithm: " + keyExchangeAlgorithm);
      
      debug("Server accepts the following CAs:");
      for (int i=0; i<certificateAuthorities.length; i++)
         debug (certificateAuthorities[i].toString());
      
      debug("Server request the following certificate types:");
      for (int i=0; i<certificateTypes.length; i++)
      {
         switch (certificateTypes[i])
         {
            case ClientTrustDecider.rsa_sign:
               debug("rsa_sign");
               break;
            case ClientTrustDecider.dss_sign:
               debug("dss_sign");
               break;
            case ClientTrustDecider.rsa_fixed_dh:
               debug("rsa_fixed_dh");
               break;
            case ClientTrustDecider.rsa_ephemeral_dh:
               debug("rsa_ephemeral_dh");
               break;
            case ClientTrustDecider.dss_ephemeral_dh:
               debug("dss_ephemeral_dh");
               break;
            case ClientTrustDecider.fortezza_dms:
               debug("fortezza_dms");
               break;
         }
      }
      
      
      if (keyExchangeAlgorithm.startsWith("RSA") || keyExchangeAlgorithm.startsWith("DHE_RSA"))
      {
         debug("return RSA certificate...");
         private_key = (java.security.PrivateKey)rsa_private_key;
         return new SSLCertificate(rsa_cert);
      }
      
      return null;
   }
   
   public iaik.java.security.PrivateKey getPrivateKey()
   {
      return (iaik.java.security.PrivateKey)private_key;
   }
   
   private void debug(String s)
   {
      if (debug) System.out.println(s);
   }
   
}