> 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]