javax.net.ssl Sockets and OKing self-signed certificates

Discussion in 'Java' started by Richard Maher, Sep 6, 2007.

  1. Hi,

    I would dearly love a server with a "self-signed certificate" to be
    accessible by my javax.net.ssl.startHandshake() but it seems to consistently
    crap-out with a failure :-( Look I've only ever tested the client code
    (please see below) with a https server (just to see if everything was
    kosher) and it maybe something I'm doing wrong. I just couldn't find
    anything in the handshake listener that controlled self-cert.

    So, is my code crap? or is there a bit I need to toggle to get the behaviour
    I require?

    Please help if you can.

    Cheers Richard Maher

    import java.io.BufferedOutputStream;
    import java.io.BufferedInputStream;
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.net.SocketTimeoutException;
    import java.lang.System;
    import javax.net.ssl.SSLSocket;
    import javax.net.ssl.SSLSocketFactory;

    public class Tier3Socket
    {
    public static final
    String T3ID="T3$";
    public static final
    int USERSIZ=40;
    public static final
    int T3IDBUFSIZ=48;
    public static final
    int CREDBUFSIZ=80;
    public static final
    int CONTIMOUT=3000;

    public byte [] t3IdBuf;
    public byte [] readBuf;
    public byte [] writeBuf;

    private String host;
    private int port;
    private int maxBufSiz;
    private int bytesIn;
    private String hostCharSet;
    private Socket t3Sock;
    private SSLSocketFactory sockFactory;
    private BufferedInputStream in;
    private BufferedOutputStream out;
    private byte [] outUser;
    private byte [] outPwd;
    private byte [] credBuf;
    private String inMsg;
    private String stringOut;
    private boolean sslReqd;

    Tier3Socket (String host, int port, int maxBufSiz, String hostCharSet,
    boolean sslReqd)
    {
    this.host = host;
    this.port = port;
    this.maxBufSiz = maxBufSiz;
    this.hostCharSet = hostCharSet;
    this.bytesIn = 0;
    this.sslReqd = sslReqd;

    t3IdBuf = new byte[T3IDBUFSIZ];
    readBuf = new byte[maxBufSiz];

    if (sslReqd)
    sockFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
    }

    public void open() throws UnknownHostException, IOException
    {
    if (sslReqd)
    t3Sock = (SSLSocket)sockFactory.createSocket();
    else
    t3Sock = new Socket();

    t3Sock.setKeepAlive(true);
    t3Sock.setReuseAddress(true);
    t3Sock.setTcpNoDelay(true);
    t3Sock.connect(new InetSocketAddress(host,port), CONTIMOUT);

    in = new BufferedInputStream (t3Sock.getInputStream() ,maxBufSiz);
    out = new BufferedOutputStream (t3Sock.getOutputStream(),maxBufSiz);

    if (sslReqd)
    {
    ((SSLSocket)t3Sock).setUseClientMode(true);

    try {((SSLSocket)t3Sock).startHandshake();}
    catch (IOException e)
    {
    System.out.println("Failed SSL Handshake");
    throw new IOException("Can't SSL on Socket");
    }
    }
    }

    public void handShake(String username, String password) throws IOException
    {
    credBuf = new byte[CREDBUFSIZ];

    outUser = username.getBytes(hostCharSet);
    System.arraycopy(outUser, 0, credBuf, 0, outUser.length);

    outPwd = password.getBytes(hostCharSet);
    System.arraycopy(outPwd, 0, credBuf, USERSIZ, outPwd.length);

    out.write(credBuf, 0, CREDBUFSIZ);
    out.flush();

    if (in.read(t3IdBuf) < t3IdBuf.length)
    {
    System.out.println("Read < " + Integer.toString(t3IdBuf.length) + "
    bytes");
    throw new IOException();
    }

    inMsg = new String(t3IdBuf, 0, 3, hostCharSet);

    if (!inMsg.equals(T3ID))
    {
    throw new IOException();
    }
    }

    public void sendUrgentData (int oob) throws IOException
    {
    t3Sock.sendUrgentData(oob);
    }

    public void setTimeout(int msecs) throws UnknownHostException, IOException
    {
    t3Sock.setSoTimeout(msecs);
    }

    public void close () throws IOException
    {
    if (t3Sock != null && !t3Sock.isClosed())
    {
    try {t3Sock.close();}
    catch (Exception e)
    {e.printStackTrace();}
    }
    }

    public void buffMessage (String message) throws IOException
    {
    byte [] msg = message.getBytes(hostCharSet);

    out.write(msg);
    }

    public void sendMessage (String message) throws IOException
    {
    byte [] msg = message.getBytes(hostCharSet);

    out.write(msg);
    flush();
    }

    public void flush () throws IOException
    {
    out.flush();
    }

    public int readMessage () throws IOException
    {
    return readMessage(readBuf.length);
    }

    public int readMessage (int bytes) throws IOException
    {
    try
    {
    bytesIn = in.read(readBuf, 0, bytes);
    }
    catch (SocketTimeoutException e)
    {
    return 0;
    }

    return bytesIn;
    }

    public String getString () throws ArrayIndexOutOfBoundsException
    {
    return getString(0, bytesIn);
    }

    public String getString (int offset, int length) throws
    ArrayIndexOutOfBoundsException
    {
    if ((offset + length) > bytesIn)
    {
    throw new ArrayIndexOutOfBoundsException();
    }
    try
    {
    stringOut = new String(readBuf, offset, length, hostCharSet);
    }
    catch (Exception e)
    {
    return null;
    }

    return stringOut;
    }

    }
     
    Richard Maher, Sep 6, 2007
    #1
    1. Advertising

  2. Richard Maher

    Rogan Dawes Guest

    Richard Maher wrote:
    > Hi,
    >
    > I would dearly love a server with a "self-signed certificate" to be
    > accessible by my javax.net.ssl.startHandshake() but it seems to consistently
    > crap-out with a failure :-( Look I've only ever tested the client code
    > (please see below) with a https server (just to see if everything was
    > kosher) and it maybe something I'm doing wrong. I just couldn't find
    > anything in the handshake listener that controlled self-cert.
    >
    > So, is my code crap? or is there a bit I need to toggle to get the behaviour
    > I require?
    >
    > Please help if you can.
    >
    > Cheers Richard Maher
    >


    [snip code]

    Take a look at http://dawes.za.net/rogan/PKCS11Test.java

    While it refers to PKCS#11 in the name, it also includes a number of
    techniques necessary to deal with your question too.

    In particular, see the method configureHTTPSUrlConnection where I create
    a new X509TrustManager.

    Hope this helps.

    Rogan
     
    Rogan Dawes, Sep 6, 2007
    #2
    1. Advertising

  3. Hi Rogan,

    "Rogan Dawes" <> wrote in message
    news:...
    > Richard Maher wrote:
    > > Hi,
    > >
    > > I would dearly love a server with a "self-signed certificate" to be
    > > accessible by my javax.net.ssl.startHandshake() but it seems to

    consistently
    > > crap-out with a failure :-( Look I've only ever tested the client code
    > > (please see below) with a https server (just to see if everything was
    > > kosher) and it maybe something I'm doing wrong. I just couldn't find
    > > anything in the handshake listener that controlled self-cert.
    > >
    > > So, is my code crap? or is there a bit I need to toggle to get the

    behaviour
    > > I require?
    > >
    > > Please help if you can.
    > >
    > > Cheers Richard Maher
    > >

    >
    > [snip code]
    >
    > Take a look at http://dawes.za.net/rogan/PKCS11Test.java
    >
    > While it refers to PKCS#11 in the name, it also includes a number of
    > techniques necessary to deal with your question too.
    >
    > In particular, see the method configureHTTPSUrlConnection where I create
    > a new X509TrustManager.
    >
    > Hope this helps.
    >
    > Rogan


    Thanks for the reply.

    It looks like your new trust manager just lets everything through. Is there
    a way to trap which connections are fully-certified and which are
    self-certifying?

    Cheers Richard Maher
     
    Richard Maher, Sep 9, 2007
    #3
  4. Richard Maher

    Rogan Dawes Guest

    Richard Maher wrote:
    > Hi Rogan,
    >
    >> [snip code]
    >>
    >> Take a look at http://dawes.za.net/rogan/PKCS11Test.java
    >>
    >> While it refers to PKCS#11 in the name, it also includes a number of
    >> techniques necessary to deal with your question too.
    >>
    >> In particular, see the method configureHTTPSUrlConnection where I create
    >> a new X509TrustManager.
    >>
    >> Hope this helps.
    >>
    >> Rogan

    >
    > Thanks for the reply.
    >
    > It looks like your new trust manager just lets everything through. Is there
    > a way to trap which connections are fully-certified and which are
    > self-certifying?
    >
    > Cheers Richard Maher
    >
    >


    Well, you need to decide what your rules are, and implement a suitable
    TrustManager. The typical way to approach this is:

    a) Add the certificate of the self-signer to your JRE trust store, and
    allow the default TrustManager to check against that cert. That would
    allow connections from that particular self-signer to pass.

    b) Create your own TrustManager that checks to see whether your rules
    apply, and return cleanly, otherwise throwing an exception. (I forget
    what the correct exception is, the JavaDoc is your friend :) )

    Hope this helped.

    Rogan
     
    Rogan Dawes, Sep 10, 2007
    #4
  5. Thanks.

    "Rogan Dawes" <> wrote in message
    news:...
    > Richard Maher wrote:
    > > Hi Rogan,
    > >
    > >> [snip code]
    > >>
    > >> Take a look at http://dawes.za.net/rogan/PKCS11Test.java
    > >>
    > >> While it refers to PKCS#11 in the name, it also includes a number of
    > >> techniques necessary to deal with your question too.
    > >>
    > >> In particular, see the method configureHTTPSUrlConnection where I

    create
    > >> a new X509TrustManager.
    > >>
    > >> Hope this helps.
    > >>
    > >> Rogan

    > >
    > > Thanks for the reply.
    > >
    > > It looks like your new trust manager just lets everything through. Is

    there
    > > a way to trap which connections are fully-certified and which are
    > > self-certifying?
    > >
    > > Cheers Richard Maher
    > >
    > >

    >
    > Well, you need to decide what your rules are, and implement a suitable
    > TrustManager. The typical way to approach this is:
    >
    > a) Add the certificate of the self-signer to your JRE trust store, and
    > allow the default TrustManager to check against that cert. That would
    > allow connections from that particular self-signer to pass.
    >
    > b) Create your own TrustManager that checks to see whether your rules
    > apply, and return cleanly, otherwise throwing an exception. (I forget
    > what the correct exception is, the JavaDoc is your friend :) )
    >
    > Hope this helped.
    >
    > Rogan
     
    Richard Maher, Sep 11, 2007
    #5
  6. Richard Maher

    Rogan Dawes Guest

    Richard Maher wrote:
    > Hi Rogan,
    >
    >> Well, you need to decide what your rules are, and implement a suitable
    >> TrustManager. The typical way to approach this is:
    >>
    >> a) Add the certificate of the self-signer to your JRE trust store, and
    >> allow the default TrustManager to check against that cert. That would
    >> allow connections from that particular self-signer to pass.

    >
    > I've used the following command in an attempt to register the register the
    > self-signing server in my client's JRE Trust Store: -
    >
    > keytool -import -alias gein.vistech.net -trustcacerts -file d:\temp\gein.cer
    >
    > But am still having no joy with the code that I previously posted :-(
    >
    > I can't say my code is perfect but it does work connecting to a https server
    > (at least for the handshake). Any ideas?
    >
    > Cheers Richard Maher
    >
    > PS. Here is the trace: -
    >
    > Trace level set to 5: all ... completed.
    > liveconnect: Invoking JS method: document
    > liveconnect: Invoking JS method: URL


    Urk! Applets!

    Sorry, I have no clue about applets.

    Rogan
     
    Rogan Dawes, Sep 17, 2007
    #6
  7. Hi Rogan,

    > Sorry, I have no clue about applets.


    You don't know what you're missing - They're the Mutt's Nuts!

    In ended up (thanks to the inestigative efforst of my brilliant friend
    Graham Burley) to be as simple as specifying the correct default Truststore
    location on the Keytool command line as in: -

    keytool -importcert -alias gein -file d:\temp\gein.cer -keystore
    ...\lib\security\cacerts

    Now the code in the OP works as advertised. Thanks for your help.

    Cheers Richard Maher

    "Rogan Dawes" <> wrote in message
    news:...
    > Richard Maher wrote:
    > > Hi Rogan,
    > >
    > >> Well, you need to decide what your rules are, and implement a suitable
    > >> TrustManager. The typical way to approach this is:
    > >>
    > >> a) Add the certificate of the self-signer to your JRE trust store, and
    > >> allow the default TrustManager to check against that cert. That would
    > >> allow connections from that particular self-signer to pass.

    > >
    > > I've used the following command in an attempt to register the register

    the
    > > self-signing server in my client's JRE Trust Store: -
    > >
    > > keytool -import -alias gein.vistech.net -trustcacerts -file

    d:\temp\gein.cer
    > >
    > > But am still having no joy with the code that I previously posted :-(
    > >
    > > I can't say my code is perfect but it does work connecting to a https

    server
    > > (at least for the handshake). Any ideas?
    > >
    > > Cheers Richard Maher
    > >
    > > PS. Here is the trace: -
    > >
    > > Trace level set to 5: all ... completed.
    > > liveconnect: Invoking JS method: document
    > > liveconnect: Invoking JS method: URL

    >
    > Urk! Applets!
    >
    > Sorry, I have no clue about applets.
    >
    > Rogan
     
    Richard Maher, Sep 18, 2007
    #7
  8. Richard Maher

    Roedy Green Guest

    On Tue, 18 Sep 2007 08:13:38 +0800, "Richard Maher"
    <> wrote, quoted or indirectly quoted
    someone who said :

    >In ended up (thanks to the inestigative efforst of my brilliant friend
    >Graham Burley) to be as simple as specifying the correct default Truststore
    >location on the Keytool command line as in: -
    >
    >keytool -importcert -alias gein -file d:\temp\gein.cer -keystore
    >..\lib\security\cacerts


    By that di you mean adding -keystore ..\lib\security\cacerts ??
    If you leave it off, keytool puts certs in .keystore.

    See http://mindprod.com/jgloss/cacerts.html
    http://mindprod.com/jgloss/keystore.html
    http://mindprod.com/jgloss/keytool.html
    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Sep 28, 2007
    #8
  9. Richard Maher

    Roedy Green Guest

    Roedy Green, Sep 28, 2007
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andrew Thompson
    Replies:
    63
    Views:
    1,730
    Darren
    Sep 20, 2005
  2. n33470

    Are SSL certificates and x.509 certificates the same?

    n33470, Dec 14, 2005, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    188
    n33470
    Dec 14, 2005
  3. Jon Lim
    Replies:
    0
    Views:
    155
    Jon Lim
    Nov 21, 2005
  4. Neumann
    Replies:
    0
    Views:
    105
    Neumann
    Aug 11, 2006
  5. Richard Maher
    Replies:
    2
    Views:
    124
    Richard Maher
    Sep 6, 2007
Loading...

Share This Page