Unable to send a response packet to client browser - Openssl

This is a discussion on Unable to send a response packet to client browser - Openssl ; 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 ...

+ Reply to Thread
Results 1 to 3 of 3

Thread: Unable to send a response packet to client browser

  1. Unable to send a response packet to client browser

    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
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #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 Hello.. Main Page..
    \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 majordomo@openssl.org


  2. Re: Unable to send a response packet to client browser

    Uh, what is the actual behavior? Have you attempted to debug it with
    openssl s_client? Have you attempted to figure out what a real
    webserver, such as Apache, does with the same input?

    This is not a general "we will debug your code for you" list, but we
    can point you in the directions to look for the solutions.

    I would also suggest that you read the relevant HTTP standards to
    understand just what each of the headers you're sending means. It
    would also probably be a good thing to avoid sending a false Server
    header, and most clients won't allow IPs as server canonical-names
    when there are certificates involved (since there is no means of
    specifying an IP as a canonical name in the certificate).

    -Kyle H

    On Thu, Jun 19, 2008 at 5:39 AM, lakshmi prasanna wrote:
    > 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
    > #include
    > #include
    > #include
    > #include
    > #include
    > #include
    > #include
    > #include
    >
    > #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 Hello.. Main Page..
    > \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 majordomo@openssl.org
    >

    __________________________________________________ ____________________
    OpenSSL Project http://www.openssl.org
    User Support Mailing List openssl-users@openssl.org
    Automated List Manager majordomo@openssl.org


  3. RE: Unable to send a response packet to client browser


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


    Umm, this doesn't look like an HTTP protocol implementation. This looks like
    code to read 1,024 bytes. Who says an HTTP request is exactly 1,024 bytes?


    > 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;
    > }


    This doesn't write all the data. It keeps writing the beginning of the data
    as many times as needed to send a number of bytes equal to the total length
    of the data. That doesn't seem to make much sense.

    DS


    __________________________________________________ ____________________
    OpenSSL Project http://www.openssl.org
    User Support Mailing List openssl-users@openssl.org
    Automated List Manager majordomo@openssl.org


+ Reply to Thread