Troubleshooting SSL Handshake Failures in OpenSSL: Resolving SSL23_WRITE Errors for Modern Systems


2 views

When working with OpenSSL 1.0.1 on Ubuntu 12.04, you might encounter the frustrating SSL23_WRITE:ssl handshake failure error while perfectly working connections succeed on older OpenSSL versions (0.9.8 series). This typically indicates a protocol or cipher suite mismatch between client and server.

First, let's gather more information about the server's SSL configuration:

openssl s_client -connect myhost.com:443 -showcerts -debug

For more detailed protocol testing:

openssl s_client -connect myhost.com:443 -tls1
openssl s_client -connect myhost.com:443 -ssl3

The issue often stems from:

  • Server requiring obsolete protocols (SSLv2/SSLv3) disabled in newer OpenSSL
  • Incompatible cipher suites between client and server
  • Missing intermediate certificates
  • Strict SNI requirements

Option 1: Force specific protocol version

openssl s_client -connect myhost.com:443 -tls1

Option 2: Enable legacy protocols (if absolutely necessary)

openssl s_client -connect myhost.com:443 -ssl3 -no_tls1

Option 3: Specify cipher suites

openssl s_client -connect myhost.com:443 \
-cipher 'ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA'

To capture the complete handshake process:

openssl s_client -connect myhost.com:443 -msg

For certificate chain verification:

openssl s_client -connect myhost.com:443 -CApath /etc/ssl/certs -verify 2

When implementing SSL connections in code, you might need to adjust SSL context options:

// C example using OpenSSL
SSL_CTX *ctx = SSL_CTX_new(SSLv23_method());
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);

For Python applications:

import ssl
context = ssl.create_default_context()
context.protocol = ssl.PROTOCOL_TLSv1

Check your system's OpenSSL configuration file (typically /etc/ssl/openssl.cnf) for any restrictive settings. You might need to modify the @SECLEVEL or cipher string settings.


When encountering the SSL routines:SSL23_WRITE:ssl handshake failure error with OpenSSL 1.0.1, we're seeing a protocol negotiation failure between client and server. This typically occurs when:

  • Protocol version mismatch exists
  • Cipher suite incompatibility emerges
  • Server-side SSL/TLS configuration is restrictive

First, let's verify the exact protocol versions supported by your server:

openssl s_client -connect myhost.com:443 -tls1
openssl s_client -connect myhost.com:443 -tls1_1
openssl s_client -connect myhost.com:443 -tls1_2

From my experience debugging similar issues, these are the most likely culprits:

  1. Legacy Protocol Support: OpenSSL 1.0.1 has stricter protocol enforcement
  2. Cipher Suite Mismatch: Newer OpenSSL versions disable weak ciphers by default
  3. SNI Requirements: Modern servers often require Server Name Indication

Solution 1: Force Protocol Version

openssl s_client -connect myhost.com:443 -tls1 -servername myhost.com

Solution 2: Enable Debug Output

openssl s_client -connect myhost.com:443 -debug -msg

Solution 3: Specify Cipher Suite

openssl s_client -connect myhost.com:443 -cipher "ECDHE-RSA-AES256-GCM-SHA384"

For programmatic connections, consider modifying your SSL context:

SSL_CTX *ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
SSL_CTX_set_ciphersuites(ctx, "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256");

If you control the server, verify your SSL configuration:

openssl s_server -cert server.pem -key server.key -accept 443 -www

Check modern compatibility using:

openssl ciphers -v 'HIGH:!aNULL:!MD5'

After applying fixes, verify with:

openssl s_client -connect myhost.com:443 -tlsextdebug -status

This should give you detailed information about the successful handshake parameters.