Here are some of the things that I've found out the hard way.
Since writing the applications, I got hold of a copy of the book "Network Security with OpenSSL" by John Viega, Matt Messier and Pravir Chandra. I think if I'd had this to start with it would have saved me a lot of time - it has example code and documentation on the "openssl" utility that is much better than the current online stuff. The book is available from Amazon.
A lot of things I've done wrong resulted in the error no shared cipher, which seems to be a bit of a catch-all.
openssl> req -x509 -new -out nickcert.pem -config myconfig.cnf -keyout nickkey.pemNote that the documentation for "req(1)" says that if the "-key" option is not used, then an RSA key will be generated. The commands I've used to get a certificate with DSA key (thus allowing DSS ciphers) is:
openssl> dsaparam -genkey -out nickdsaparam.pem 128 openssl> gendsa -out nickdsakey.pem -des3 nickdsaparam.pem (asks for pw) openssl> req -x509 -new -out nickdsacert.pem -config myconfig.cnf -key nickdsakey.pemIt seems like java's "keytool" utility is the other way round - i.e. by default you get DSA key encryption, and you use "-keyalg" to specify RSA if you want it.
However, another thing that causes the handshake to occur is Socket.getSession(), which you might use to get info on, say, what ciphers are enabled. If the handshake fails in this case, you don't get an SSLException, and if you subsequently try and do I/O to the socket you'll get a IOException.
You can look at SSLSession.getCipherSuite() which will be SSL_NULL_WITH_NULL_NULL in this case.
The way that OpenSSL decides to trust a certificate is that it looks in its verify path to find a chain of certificates which must include one for the issuer (a certificate for the subject isn't good enough). I.e. it follows the chain and requires that the chain ends with a self-signed certificate.