Hi,

I tried to implement a simple HTTPS server using openssl.
The Server establishes an SSL connection, receives input and searches
the input for GET string. If string is found it is supposed to send a
"static" response to the client.
The client here can be any browser.

I am able to establish the connection with client, read request
containing GET string. But the response could not be sent to the
client.

Please point the error in my program. Below is the server code:

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/x509v3.h>

#define CADIR NULL
#define CAFILE "cacert.pem"
#define CERTFILE "mycert.pem"
#define KEYFILE "myprivkey.pem"

#define int_error(msg) handle_error(__FILE__, __LINE__, msg)

int seed_prng(int bytes)
{
        if( !RAND_load_file("/dev/random", bytes))
                return 0;
        return 1;
}
void handle_error(const char *file, int lineno, const char *msg)
{
         fprintf(stderr, "** %s:%i %s\n", file, lineno, msg);
         ERR_print_errors_fp(stderr);
         exit(-1);
}

int verify_callback(int ok, X509_STORE_CTX *store)
{
        char data[256];
        if (!ok)
        {
                X509 *cert = X509_STORE_CTX_get_current_cert(store);
                int depth = X509_STORE_CTX_get_error_depth(store);
                int err = X509_STORE_CTX_get_error(store);
                fprintf(stderr, "-Error with certificate at depth: %i\n",
                                depth);
                X509_NAME_oneline(X509_get_issuer_name(cert), data, 256);
                fprintf(stderr, " issuer = %s\n", data);
                X509_NAME_oneline(X509_get_subject_name(cert), data, 256);
                fprintf(stderr, " subject = %s\n", data);
                fprintf(stderr, " err %i:%s\n", err,
                X509_verify_cert_error_string(err));
        }
        return ok;
}

SSL_CTX *set_server_context(void)
{
        SSL_CTX *ctx;
        ctx = SSL_CTX_new(SSLv23_method());
        if (SSL_CTX_load_verify_locations(ctx, CAFILE, CADIR) != 1)
                int_error("Error loading CA file and/or directory");
        if (SSL_CTX_set_default_verify_paths(ctx) != 1)
               int_error("Error loading default CA file and/or directory");
        ctx = SSL_CTX_new(SSLv23_method());
        if(SSL_CTX_use_certificate_chain_file(ctx, CERTFILE) != 1)
                int_error("Error loading server certificate from file");
        if(SSL_CTX_use_PrivateKey_file(ctx, KEYFILE,SSL_FILETYPE_PEM) != 1)
                int_error("Error loading private key from file");
        SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE, verify_callback);
//      SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER, verify_callback);
        SSL_CTX_set_verify_depth(ctx, 4);
        return ctx;
}

void init_OpenSSL(void)
{
        if(! SSL_library_init())
        {
                fprintf(stderr, "** OpenSSL initialization failed!\n");
                exit(-1);
        }
        SSL_load_error_strings();
}


int processClient(SSL *client_conn)
{

        int err, nread, nwrite, werr,i=1;
        char buf[1024];

        do
        {
                for (nread = 0; nread < sizeof(buf); nread += err)
                {
                        err = SSL_read(client_conn, buf + nread, sizeof(buf) -  
nread);
                        if (err <= 0)
                                break;
                }

                printf ("String Read = %s\n", buf);

                if (strstr(buf,"GET"))
                {
                        printf("GET Found\n");
                        strcpy(buf, "HTTP/1.1 200 OK\r\nServer:
Microsoft-IIS/5.0\r\nContent-Location:
http://172.16.1.75/index.htm\r\nDate: Thu, 19 Jun 2008 10:07:37
GMT\r\nContent-Type: text/html\r\nAccept-Ranges:
bytes\r\nLast-Modified: Tue, 27 May 2008 12:22:48
GMT\r\nContent-Length: 47\r\n\r\n<html><body> Hello.. Main Page..
</body></html>\r\n");
                        for ( nwrite = 0; nwrite <= strlen(buf) ; )
                        {
                                
                                werr = SSL_write(client_conn,buf,strlen(buf));
                                printf ("Loop = %d", i++);
                                        if (werr <= 0 )
                                        {
                                                printf ("Write Error \n");
                                                continue;
                                        }
                                        nwrite += werr;
                        }
                                if (werr>0)
                                {
                                        printf ("Written HTML Page to 
socket\n");
                                //      break;
                                }
                                break;
                        }
                }
                while (err > 0);
        printf("Exited While loop and closing the ssl client connection\n");
        return (SSL_get_shutdown(client_conn) & SSL_RECEIVED_SHUTDOWN) ? 1 : 0;


}

int main (int argc, char **argv)
{

        int listenSock, clientSock, iRet;
        struct sockaddr_in serverAddr, clientAddr;
        int clientLength;
        BIO *clientBIO;
        SSL *ssl_client_conn;
        SSL_CTX *ctx;

        long ret_seed;
        
        init_OpenSSL();
        
        ret_seed=seed_prng(1024);
        if(!ret_seed)
                int_error("Error while seeding the prng");

        ctx = set_server_context();
        
        clientLength = sizeof(clientAddr);
        listenSock=socket(AF_INET,SOCK_STREAM,0);
        bzero(&serverAddr,sizeof(serverAddr));
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_addr.s_addr=htonl(INADDR_ANY);
        serverAddr.sin_port=htons(443);
        
        bind(listenSock,(struct sockaddr *)&serverAddr,sizeof(serverAddr));
        listen(listenSock,1024);
        
        for(;;)
        {
                clientSock = accept ( listenSock, (struct sockaddr*) 
&clientAddr,
&(clientLength) );
                printf ("Accepted connection from client \n");
                ssl_client_conn = SSL_new(ctx);
                clientBIO = BIO_new_socket(clientSock, BIO_CLOSE);
                SSL_set_bio(ssl_client_conn, clientBIO, clientBIO);

                if ( SSL_accept(ssl_client_conn) != 1 )
                {
                        printf("Error accepting ssl connection\n");
                        close (listenSock);
                        SSL_CTX_free(ctx);
                        exit (0);
                }
                if (processClient(ssl_client_conn))
                        printf ("Client Connection closed without errors\n");
        //      SSL_free(ssl_client_conn);
        //      BIO_free(clientBIO);
        }
        
        SSL_CTX_free (ctx);
        close (listenSock);
        
        
        
}


-- 
thanks,
Lakshmi Prasanna
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to