Hi, I am writing a specialized HTTPS server for Windows. The server and browser are on the same machine, with the browser requesting a resource via localhost (e.g., "https://localhost:2649/someResource").
When using Netscape 6.2 (a Mozilla 0.9.4 branch), the SSL_read in the snippet below works fine. When using IE 5.01 SP2, SSL_read returns 0, with SSL_get_error returning SSL_ERR_SYSCALL (logic of SSL_get_error just falls completely through to this default return value). I'm at a complete loss on this one, so any help would be greatly appreciated. I have tried the following: o Using both the static and dynamic OpenSSL libraries o Identified the call stack: SSL_read ssl3_read ssl3_read_internal ssl3_read_bytes ssl3_get_record ssl3_read_n BIO_read sock_read (pointed to by b->method->bread) readsocket (<-- failure point??: returns 0 bytes read, but why only for IE?) o Tried using the BIO_new / BIO_new_socket approach instead of SSL_set_fd with the same result o Ensured non-SSL communications are ok by setting the do_ssl constant to false (see snippet below) o Tried the SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER option with no success Here's my environment: o Windows NT 4, build 4.00.1381 (SP3?) o IE 5, build 5.00.3314.2101 (5.01 SP2) o Microsoft Visual C++ 6.0 o Non-MFC console application, linked to multithreaded DLL runtime o 128 MB RAM Thanks, Jim Sample code: #include <winsock2.h> #include <string> #include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/crypto.h> using namespace std; int main() { WSADATA d; int err = WSAStartup(0x0101, &d); const bool do_ssl = true; SOCKET _sockfd; int _port; SSL_CTX* _ssl_ctx; SSL* _ssl; int rc; int nrecv; if (err != 0) return err; if (do_ssl) { SSL_library_init(); SSL_load_error_strings(); _ssl_ctx = SSL_CTX_new( SSLv23_server_method() ); if ( SSL_CTX_use_certificate_file( _ssl_ctx, ".\\localhost.crt", SSL_FILETYPE_PEM ) == 0 ) return -1; if ( SSL_CTX_use_PrivateKey_file( _ssl_ctx, ".\\localhost.key", SSL_FILETYPE_PEM ) == 0 ) return -1; if ( SSL_CTX_check_private_key( _ssl_ctx ) == 0 ) return -1; } struct protoent *ppe; struct sockaddr_in sin; int type = SOCK_STREAM; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; _port = 2649; if ((sin.sin_port = htons((u_short)_port)) == 0) return -1; if ((ppe = getprotobyname("tcp")) == NULL) return -1; _sockfd = socket(PF_INET, type, ppe->p_proto); if (_sockfd < 0) return -1; if (bind(_sockfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { return -1; } if ((type = SOCK_STREAM) && (listen(_sockfd, 5) < 0)) { return -1; } sockaddr cliaddr; int clilen = sizeof(cliaddr); fd_set fds; clilen = sizeof(cliaddr); FD_ZERO(&fds); FD_SET(_sockfd, &fds); SOCKET clisockfd; clisockfd = ::accept(_sockfd, &cliaddr, &clilen); if (clisockfd < 0) return -1; if (do_ssl) { _ssl = SSL_new(_ssl_ctx); SSL_set_options(_ssl, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); SSL_set_fd(_ssl, clisockfd); while ( !SSL_is_init_finished(_ssl) ) { if ( (rc = SSL_accept(_ssl)) <= 0 ) { if ( SSL_get_error(_ssl, rc) == SSL_ERROR_ZERO_RETURN ) return -1; else if ( SSL_get_error(_ssl, rc) == SSL_ERROR_SYSCALL ) { if (errno == EINTR) continue; return -1; } else return -1; } } } /* * Reading Request-Line from socket */ static char prevChar = '\0'; char currChar = '\0'; string currLine; for ( ; ; ) { if (do_ssl) { int ret = SSL_read( _ssl, &currChar, 1); // returns 0, currChar is null string int wsaen = WSAGetLastError(); int geno = SSL_get_error(_ssl, ret); // returns SSL_ERR_SYSCALL int egeno = ERR_get_error(); if (ret == 0) ERR_print_errors_fp(stdout); } else { nrecv = ::recv(clisockfd, &currChar, 1, 0); // Regular sockets rc = WSAGetLastError(); } if (currChar == 0) break; // Ignore LF if it follows a CR, for CRLF end-of-line if ((currChar == '\n') && (prevChar == '\r')) continue; // Found end-of-line if ((currChar == '\r') || (currChar == '\n')) break; currLine = currLine + currChar; } strcpy(&prevChar, &currChar); /* * Cleanup */ if (do_ssl) { SSL_shutdown( _ssl ); SSL_free( _ssl ); SSL_CTX_free( _ssl_ctx ); } ::shutdown(_sockfd, SD_SEND); char tmp; while( ::recv(_sockfd, &tmp, 1, 0) > 0 ); if (::closesocket(_sockfd) != 0) return -1; _sockfd = 0; WSACleanup(); return 0; } ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]