> Hello!
> 
> Where can I find sample codes using OpenSSL. I have already installed
> OpenSSL in my FreeBSD box. I have read the documentation, but can't find
> some sample codes implementing a fully running server implementing ssl, and
> a fully running client implementing ssl.

I was quite disappointed with the examples that ship with
openssl.  They are large, feature filled and not straightforward.
I had a very hard time figuring out how to use the library
myself until a friend sent me some code he had written.  So,
I tried to put together a simple example (with emphasis on
the word "simple").  I hope this helps a little.  If you find
you need to use more features than are used in this example,
this will at least serve as a quick intro before you delve into
the provided example scripts.  Enjoy..

Tim N.

P.S.: If anyone sees anything here that I should do differently,
please feel free to send me mail.

/*
 * example.c
 *      A simple SSL example
 *
 * This program is a minimal example of using the OpenSSL library
 * with TCP connections.  It does as few operations as possible
 * in as simple a manner as possible.  Features such as non-blocking
 * operation are not used.
 *
 * A certificate must be made first:
 *
 *     PATH=$PATH:$OPENSSL/bin
 *     export PATH
 *     openssl genrsa -out cert.pem 1024
 *     openssl req -new -key cert.pem -out cert.csr
 *     openssl x509 -req -days 365 -in cert.csr -signkey cert.pem -out cert.new
 *     cat cert.new >> cert.pem
 *     rm cert.csr cert.new
 *
 * To compile:
 *
 *     cc -I$OPENSSL/include example.c -L$OPENSSL/lib -lssl -lcrypto -o example
 *
 * To run:
 *     ./example -serv 1234
 *     ./example -client 127.0.0.1 1234
 *
 * Thanks to Dug Song for example code that pointed me on my way.
 *
 *                                          Tim N.
 */

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>


#define PATH_CERT       "./cert.pem"

/* report possible failure and exit */
void
check_err(int bool, char *msg)
{
    int err;

    if(bool) {
        printf("Error with %s\n", msg);
        while((err = ERR_get_error()))
            printf("%s\n", ERR_error_string(err, 0));

        if(errno)
            perror(msg);
        exit(1);
    }
}

/* return a pointer to a static buffer with a filled in AF_INET address */
struct sockaddr *
afinet_addr(int ipaddr, int port)
{
    static struct sockaddr_in ad;

    memset(&ad, 0, sizeof ad);
    ad.sin_family = AF_INET;
    ad.sin_addr.s_addr = ipaddr;
    ad.sin_port = htons(port);
    return (struct sockaddr *)&ad;
}

/* return a tcp socket connected to ipaddr/port */
int
tcp_connect(char *host, int port)
{
    int s, ipaddr, res;

    s = socket(AF_INET, SOCK_STREAM, 0);
    check_err(s == -1, "socket");

    ipaddr = inet_addr(host);
    check_err(ipaddr == -1, "bad host");
    res = connect(s, afinet_addr(inet_addr(host), port), 
                  sizeof(struct sockaddr_in));
    check_err(res == -1, "connect");
    return s;
}

/* accept an incoming tcp connection and return a connected socket */
int
tcp_accept(int port)
{
    struct sockaddr_in ad;
    int s, s2, adlen, res;

    s = socket(AF_INET, SOCK_STREAM, 0);
    check_err(s == -1, "socket");

    adlen = sizeof(struct sockaddr_in);
    res = bind(s, afinet_addr(INADDR_ANY, port), adlen);
    check_err(res == -1, "bind");

    res = listen(s, 1);
    check_err(res == -1, "listen");

    s2 = accept(s, (struct sockaddr *)&ad, &adlen);
    check_err(s2 == -1, "accept");
    close(s);
    return s2;
}

/*
 * example server process: accept a single connection, echo out
 * a string and close the connection
 */
void
ssl_server(char *cert, int port)
{
    SSL_CTX *ctx;
    SSL *ssl;
    char *msg;
    int res;

    /* build a server context */
    ctx = SSL_CTX_new(TLSv1_server_method());
    check_err(ctx == 0, "SSL_CTX_new");

    /* read in the certificate */
    if(SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM) == 0 ||
            SSL_CTX_use_PrivateKey_file(ctx, cert, SSL_FILETYPE_PEM) == 0 ||
            SSL_CTX_check_private_key(ctx) == 0) {
        check_err(1, "load cert");
    }

    /* make a new ssl handle and attach it to an incoming connection */
    ssl = SSL_new(ctx);
    check_err(ssl == 0, "SSL_new");
    SSL_set_fd(ssl, tcp_accept(port));
    SSL_set_accept_state(ssl);

    /* write data out on the connection */
    msg = "Here is some data.";
    printf("sending:  %s\n", msg);
    res = SSL_write(ssl, msg, strlen(msg));
    check_err(res <= 0, "SSL_write");
}

/*
 * example client process: initiate a connection and echo all output
 * to standard output
 */
void
ssl_client(char *host, int port)
{
    SSL_CTX *ctx;
    SSL *ssl;
    char buf[128];
    int len;

    /* build a client context */
    ctx = SSL_CTX_new(TLSv1_client_method());
    check_err(ctx == 0, "SSL_CTX_new");

    /* make a new ssl handle and attach it to a new outgoing connection */
    ssl = SSL_new(ctx);
    check_err(ssl == 0, "SSL_new");
    SSL_set_fd(ssl, tcp_connect(host, port));
    SSL_set_connect_state(ssl);

    /* read data until EOF */
    while((len = SSL_read(ssl, buf, sizeof buf)) > 0)
        printf("client read: [%.*s]\n", len, buf);
    check_err(len < 0, "SSL_read");
}

/* very primitive example of seeding random data */
void
rand_init()
{
    int now;

    now = time(0);
    RAND_seed(&now, sizeof now);
}

int
main(int argc, char **argv)
{
    /* initialize random pool and ssl library */
    rand_init();
    SSL_library_init();
    SSL_load_error_strings();

    if(argc == 3 && strcmp(argv[1], "-serv") == 0) {
        ssl_server(PATH_CERT, atoi(argv[2]));
    } else if(argc == 4 && strcmp(argv[1], "-client") == 0) {
        ssl_client(argv[2], atoi(argv[3]));
    } else {
        printf("usage: %s -serv port | %s -client ipaddr port\n", 
               argv[0], argv[0]);
        exit(1);
    }
    return 0;
}


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to