David, Sorry for the lack of information, let me try to fill in the blanks.
We're using Perl (IO::Socket::SSL) on the sending side to establish a secure socket to a C agent on the receiving side. The C agent uses native OpenSSL APIs. On the Perl side, we create a TCP socket and then do a startSSL afterwards. The same exact code works fine with Perl running on Windows going to a C agent on Windows. If fails when Perl is running on Solaris going to the same C agent on Windows. This same Perl SSL code on Solaris works fine going to a Java server on Solaris. # Start the SSL handshake if (defined($self->{'_sslconf'})) { $self->{'_Socket'} = BfSSLSocket::startSSL($self->{'_Socket'}, $AddrIsIpv6, $self->{'_sslconf'}) if ($self->{'_Socket'}); } The above startSSL method basically comes down to this, which works on Windows. print "SSL connection to agent.\n"; $sock = IO::Socket::SSL->start_SSL($sock, 'SSL_version' => $ssl_ver, 'SSL_cipher_list' => $ssl_cipher_list, 'SSL_verify_mode' => hex $ssl_verify_mode, 'SSL_use_cert' => $use_cert, 'SSL_key_file' => $key_location, 'SSL_passwd_cb' => sub{return $key_pass}, 'SSL_cert_file' => $cert_location, 'SSL_ca_file' => $ca_location, 'SSL_startHandshake' => 0 ) || die "Encountered an SSL handshake problem: ".IO::Socket::SSL::errstr(); $sock->connect_SSL; On the Agent side, there's a dispatch process which receives requests and spawns a new Agent when it gets the connection. It hands the socket over to the new Agent process which then starts SSL. Once the SSL handshake is successful, it goes into the main loop which starts read/writes. } else if (NULL != start_SSL() || SS_OK == ssl_state) { agent_main_loop(); stop_SSL(); } void *start_SSL(void) { char err_buf[1024]; const char *sbuf=NULL; int err=0, rc=0; X509* client_cert; BFTRACE("In start_SSL"); /* Specify the context configuration options */ ssl_state = init_CTX(); /* You cannot send a hello in the middle of an SSL handshake. Defer the SSL hello until the end. Send the TCP hello now, if the state is SS_OK. */ switch (ssl_state) { case SS_OK: send_hello(CODE_HELLO); return NULL; default: break; /* Continue to do the SSL handshake. */ } BFTRACE("Calling SSL_new"); /* Create a new SSL context */ ssl = SSL_new(ctx); if (NULL == ssl) { sbuf = ERR_error_string(err, err_buf); send_msg("SSL", "SSLErrorNoSSL", "s", sbuf); ssl_state = SS_FAILED; return NULL; } /* hRemote is the duplicate file descriptor from the dispatch thread. */ SSL_set_fd(ssl, hRemote); SSL_set_accept_state(ssl); BFTRACE("Calling SSL_accept."); rc = SSL_accept(ssl); sprintf(err_buf, "SSL_accept rc=%d (1 is good, 0 is handshake failure, <0 is fatal)", rc); BFTRACE(err_buf); if (rc <= 0) { err = SSL_get_error(ssl, rc); sprintf(err_buf, "Error code: %d", err); BFTRACE(err_buf); ERR_error_string_n(ERR_get_error(), err_buf, sizeof(err_buf)); BFTRACE(err_buf); switch (err) { case SSL_ERROR_NONE: sprintf(err_buf, "No error reported."); BFTRACE(err_buf); break; case SSL_ERROR_WANT_WRITE: sprintf(err_buf, "Error: SSL_ERROR_WANT_WRITE"); BFTRACE(err_buf); break; case SSL_ERROR_WANT_READ: sprintf(err_buf, "Error: SSL_ERROR_WANT_READ"); BFTRACE(err_buf); break; case SSL_ERROR_WANT_X509_LOOKUP: sprintf(err_buf, "Error: SSL_ERROR_WANT_X509_LOOKUP"); BFTRACE(err_buf); break; case SSL_ERROR_SYSCALL: sprintf(err_buf, "Error: SSL_ERROR_SYSCALL, errlist: %s", sys_errlist[errno]); BFTRACE(err_buf); break; case SSL_ERROR_SSL: sprintf(err_buf, "Error: SSL_ERROR_SSL"); BFTRACE(err_buf); break; case SSL_ERROR_ZERO_RETURN: sprintf(err_buf, "Error: SSL_ERROR_ZERO_RETURN"); BFTRACE(err_buf); break; } ssl_state = SS_FAILED; SSL_free(ssl); return NULL; } sbuf = SSL_get_cipher_name(ssl); if (sbuf != NULL) { sprintf(err_buf, "Cipher chosen: %s", sbuf); BFTRACE(err_buf); } client_cert = SSL_get_peer_certificate (ssl); if (client_cert != NULL) { sbuf = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0); sprintf(err_buf, "Client certificate: %s", sbuf); BFTRACE(err_buf); } switch (ssl_state) { case SS_OK: BFTRACE("ssl_state = SS_OK"); send_hello(CODE_HELLO); return NULL; case SS_SECURE: BFTRACE("ssl_state = SS_SECURE"); send_hello(CODE_SECURE_HELLO); break; case SS_CERTIFIED: BFTRACE("ssl_state = SS_CERTIFIED"); send_hello(CODE_CERTIFIED_HELLO); break; default: return NULL; } return ssl; } Here's what we should see from the first READ on the sending side: SSL_ca_file: ./keystore/buildForgeCA.pem SSL_cert_file: ./keystore/buildForgeCert.pem SSL_key_file: ./keystore/buildForgeKey.pem SSL_verify_mode: 0x01 SSL_version: TLSv1 SSL_cipher_list: ALL SSL_use_cert: 1 Making as SSL connection using socket IO::Socket::INET=GLOB(0x1faf924). SSL connection to agent. DEBUG: .../IO/Socket/SSL.pm:1387: new ctx 32890752 DEBUG: .../IO/Socket/SSL.pm:880: dont start handshake: IO::Socket::SSL=GLOB(0x1f af924) DEBUG: .../IO/Socket/SSL.pm:284: ssl handshake not started DEBUG: .../IO/Socket/SSL.pm:327: Net::SSLeay::connect -> 1 DEBUG: .../IO/Socket/SSL.pm:382: ssl handshake done Socket is of type: ref(IO::Socket::SSL=GLOB(0x1faf924)) READ:202 HELLO TLS - BuildForge Agent v_VERSION_ However, what comes across here is encrypted data instead. Looks like I'm missing all this debug statements from the failing trace.. This is taken from a successful trace on Windows. Note the "dont start handshake, then ssl handshake done after DEBUG: .../IO/Socket/SSL.pm:1387: new ctx 32890752 DEBUG: .../IO/Socket/SSL.pm:880: dont start handshake: IO::Socket::SSL=GLOB(0x1f af924) DEBUG: .../IO/Socket/SSL.pm:284: ssl handshake not started DEBUG: .../IO/Socket/SSL.pm:327: Net::SSLeay::connect -> 1 DEBUG: .../IO/Socket/SSL.pm:382: ssl handshake done Socket is of type: ref(IO::Socket::SSL=GLOB(0x1faf924)) Hmm.. It appears that this call to IO::Socket::SSL is bombing out somewhere as it's not starting the handshake at all. The "connect_SSL" should begin that as shown above. $sock = IO::Socket::SSL->start_SSL($sock, 'SSL_version' => $ssl_ver, 'SSL_cipher_list' => $ssl_cipher_list, 'SSL_verify_mode' => hex $ssl_verify_mode, 'SSL_use_cert' => $use_cert, 'SSL_key_file' => $key_location, 'SSL_passwd_cb' => sub{return $key_pass}, 'SSL_cert_file' => $cert_location, 'SSL_ca_file' => $ca_location, 'SSL_startHandshake' => 0 ) || die "Encountered an SSL handshake problem: ".IO::Socket::SSL::errstr(); $sock->connect_SSL; In the failing state, there's no debug output, although there should be as I have debug enabled there the same way via eval "use IO::Socket::SSL qw($debug $inetValue)";. Here's the failing trace again. Making as SSL connection using socket IO::Socket::INET=GLOB(0x29bd6a0). SSL connection to agent. Socket is of type: ref(IO::Socket::SSL=GLOB(0x29bd6a0)) READ: ReadyLine: . Agent Connecting... READ:^V^C^AJ^BF^C^AI^Q╣ In fact, I can see on the same system when it connects successfully to Java, that the debug prints out for the same code (although I do a 'SSL_startHandshake' => 1 in that case as Java is ready to accept SSL immediately where as the Agent is not due to the dispatch process). Making as SSL connection using socket GLOB(0x29d4fc8). SSL connection to services. DEBUG: .../IO/Socket/SSL.pm:1387: new ctx 3028608 DEBUG: .../IO/Socket/SSL.pm:872: start handshake DEBUG: .../IO/Socket/SSL.pm:284: ssl handshake not started DEBUG: .../IO/Socket/SSL.pm:327: Net::SSLeay::connect -> 1 DEBUG: .../IO/Socket/SSL.pm:382: ssl handshake done Socket is of type: ref(IO::Socket::SSL=GLOB(0x29d4fc8)) Any ideas? I will try changing 'SSL_startHandshake' => 1, w/o the $sock->connect_SSL, but that didn't work from Windows -> Windows in this environment. It just seems like even the general start_SSL code is not getting invoked although it's definately going through that path. Regards, Pete David Schwartz wrote: > > >> So I can now see the Solaris side. It appears it gets >> "gibberish", probably >> encrypted data. Does anyone know why it would appear that the socket is >> not decrypting the data? This same code works fine on a Windows system. >> >> SSL_ca_file: /opt/bf-567/Platform/keystore/CA.pem >> SSL_cert_file: /opt/bf-567/Platform/keystore/Cert.pem >> SSL_key_file: /opt/bf-567/Platform/keystore/Key.pem >> SSL_verify_mode: 0x01 >> SSL_version: TLSv1 >> SSL_cipher_list: ALL >> SSL_use_cert: 1 >> Making as SSL connection using socket IO::Socket::INET=GLOB(0x29bdfe8). >> SSL connection to agent. >> Socket is of type: ref(IO::Socket::SSL=GLOB(0x29bdfe8)) >> READ: >> ReadyLine: . >> Agent Connecting... >> READ: <gibberish on the wire> > > Well, we're kind of back to square one trying to help you, since we're > looking someplace else entirely now. You really haven't given us any idea > what your application is actually doing or what these log entries mean. > > If the 'READ' entries are displaying raw socket data as text, then it's > logical that they would make no apparent sense. If it's decrypt SSL > output, > then that you're getting any output at all means that your code thinks the > SSL negotation completed successfully, which is inconsistent with what I > think you were seeing on the other side (accept failing, therefore no data > could have been exchanged). > > My best guess is that your 'READ' lines are in fact showing raw socket > data, > so it's not surprising it looks like gibberish. That you expected it to be > decrypted data suggests that there's some disconnect between what your > code > is doing and what you expect it to be doing. > > It's hard to tell without more details. > > DS > > > ______________________________________________________________________ > OpenSSL Project http://www.openssl.org > User Support Mailing List openssl-users@openssl.org > Automated List Manager [EMAIL PROTECTED] > > -- View this message in context: http://www.nabble.com/SSL_ERROR_SYSCALL%2C-errlist%3A-No-such-file-or-directory-tp20329506p20344466.html Sent from the OpenSSL - User mailing list archive at Nabble.com. ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]