From 3646578ae7e29230d7b05a5487ad12990b2ae688 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 26 Feb 2013 16:33:05 +0000 Subject: [PATCH] Demo code for SSL_CONF API Two example programs one for command line argument processing and one for configuration file processing. --- demos/bio/Makefile | 10 +++- demos/bio/README | 3 + demos/bio/client-arg.c | 115 ++++++++++++++++++++++++++++++++++++ demos/bio/client-conf.c | 125 ++++++++++++++++++++++++++++++++++++++++ demos/bio/connect.cnf | 9 +++ 5 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 demos/bio/client-arg.c create mode 100644 demos/bio/client-conf.c create mode 100644 demos/bio/connect.cnf diff --git a/demos/bio/Makefile b/demos/bio/Makefile index 4351540532..f8c8f03517 100644 --- a/demos/bio/Makefile +++ b/demos/bio/Makefile @@ -1,7 +1,7 @@ CC=cc CFLAGS= -g -I../../include -LIBS= -L../.. ../../libssl.a ../../libcrypto.a -EXAMPLES=saccept sconnect +LIBS= -L../.. ../../libssl.a ../../libcrypto.a -ldl +EXAMPLES=saccept sconnect client-arg client-conf all: $(EXAMPLES) @@ -11,6 +11,12 @@ saccept: saccept.o sconnect: sconnect.o $(CC) -o sconnect sconnect.o $(LIBS) +client-arg: client-arg.o + $(CC) -o client-arg client-arg.o $(LIBS) + +client-conf: client-conf.o + $(CC) -o client-conf client-conf.o $(LIBS) + clean: rm -f $(EXAMPLES) *.o diff --git a/demos/bio/README b/demos/bio/README index 0b24e5b80c..fab5789959 100644 --- a/demos/bio/README +++ b/demos/bio/README @@ -1,3 +1,6 @@ This directory contains some simple examples of the use of BIO's to simplify socket programming. +The client-conf and client-arg include examples of how to use the SSL_CONF +API for configuration file or command line processing. + diff --git a/demos/bio/client-arg.c b/demos/bio/client-arg.c new file mode 100644 index 0000000000..f0cb9aba90 --- /dev/null +++ b/demos/bio/client-arg.c @@ -0,0 +1,115 @@ +#include +#include + +int main(int argc, char **argv) + { + BIO *sbio = NULL, *out = NULL; + int len; + char tmpbuf[1024]; + SSL_CTX *ctx; + SSL_CONF_CTX *cctx; + SSL *ssl; + char **args = argv + 1; + const char *connect_str = "localhost:4433"; + int nargs = argc - 1; + + ERR_load_crypto_strings(); + ERR_load_SSL_strings(); + SSL_library_init(); + + ctx = SSL_CTX_new(SSLv23_client_method()); + cctx = SSL_CONF_CTX_new(); + SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); + SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); + while(*args && **args == '-') + { + int rv; + /* Parse standard arguments */ + rv = SSL_CONF_cmd_argv(cctx, &nargs, &args); + if (rv == -3) + { + fprintf(stderr, "Missing argument for %s\n", *args); + goto end; + } + if (rv < 0) + { + fprintf(stderr, "Error in command %s\n", *args); + ERR_print_errors_fp(stderr); + goto end; + } + /* If rv > 0 we processed something so proceed to next arg */ + if (rv > 0) + continue; + /* Otherwise application specific argument processing */ + if (!strcmp(*args, "-connect")) + { + connect_str = args[1]; + if (connect_str == NULL) + { + fprintf(stderr, "Missing -connect argument\n"); + goto end; + } + args += 2; + nargs -= 2; + continue; + } + else + { + fprintf(stderr, "Unknown argument %s\n", *args); + goto end; + } + } + + /* We'd normally set some stuff like the verify paths and + * mode here because as things stand this will connect to + * any server whose certificate is signed by any CA. + */ + + sbio = BIO_new_ssl_connect(ctx); + + BIO_get_ssl(sbio, &ssl); + + if(!ssl) + { + fprintf(stderr, "Can't locate SSL pointer\n"); + goto end; + } + + /* Don't want any retries */ + SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + + /* We might want to do other things with ssl here */ + + BIO_set_conn_hostname(sbio, connect_str); + + out = BIO_new_fp(stdout, BIO_NOCLOSE); + if(BIO_do_connect(sbio) <= 0) + { + fprintf(stderr, "Error connecting to server\n"); + ERR_print_errors_fp(stderr); + goto end; + } + + if(BIO_do_handshake(sbio) <= 0) + { + fprintf(stderr, "Error establishing SSL connection\n"); + ERR_print_errors_fp(stderr); + goto end; + } + + /* Could examine ssl here to get connection info */ + + BIO_puts(sbio, "GET / HTTP/1.0\n\n"); + for(;;) + { + len = BIO_read(sbio, tmpbuf, 1024); + if(len <= 0) break; + BIO_write(out, tmpbuf, len); + } + end: + SSL_CONF_CTX_free(cctx); + BIO_free_all(sbio); + BIO_free(out); + return 0; + } + diff --git a/demos/bio/client-conf.c b/demos/bio/client-conf.c new file mode 100644 index 0000000000..6cef222fa3 --- /dev/null +++ b/demos/bio/client-conf.c @@ -0,0 +1,125 @@ +#include +#include +#include + +int main(int argc, char **argv) + { + BIO *sbio = NULL, *out = NULL; + int i, len, rv; + char tmpbuf[1024]; + SSL_CTX *ctx = NULL; + SSL_CONF_CTX *cctx = NULL; + SSL *ssl = NULL; + CONF *conf = NULL; + STACK_OF(CONF_VALUE) *sect = NULL; + CONF_VALUE *cnf; + const char *connect_str = "localhost:4433"; + long errline = -1; + + ERR_load_crypto_strings(); + ERR_load_SSL_strings(); + SSL_library_init(); + + conf = NCONF_new(NULL); + + if (NCONF_load(conf, "connect.cnf", &errline) <= 0) + { + if (errline <= 0) + fprintf(stderr, "Error processing config file\n"); + else + fprintf(stderr, "Error on line %ld\n", errline); + goto end; + } + + sect = NCONF_get_section(conf, "default"); + + if (sect == NULL) + { + fprintf(stderr, "Error retrieving default section\n"); + goto end; + } + + ctx = SSL_CTX_new(SSLv23_client_method()); + cctx = SSL_CONF_CTX_new(); + SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); + SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); + SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); + for (i = 0; i < sk_CONF_VALUE_num(sect); i++) + { + cnf = sk_CONF_VALUE_value(sect, i); + rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value); + if (rv > 0) + continue; + if (rv != -2) + { + fprintf(stderr, "Error processing %s = %s\n", + cnf->name, cnf->value); + ERR_print_errors_fp(stderr); + goto end; + } + if (!strcmp(cnf->name, "Connect")) + { + connect_str = cnf->value; + } + else + { + fprintf(stderr, "Unknown configuration option %s\n", + cnf->name); + goto end; + } + } + + /* We'd normally set some stuff like the verify paths and + * mode here because as things stand this will connect to + * any server whose certificate is signed by any CA. + */ + + sbio = BIO_new_ssl_connect(ctx); + + BIO_get_ssl(sbio, &ssl); + + if(!ssl) + { + fprintf(stderr, "Can't locate SSL pointer\n"); + goto end; + } + + /* Don't want any retries */ + SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + + /* We might want to do other things with ssl here */ + + BIO_set_conn_hostname(sbio, connect_str); + + out = BIO_new_fp(stdout, BIO_NOCLOSE); + if(BIO_do_connect(sbio) <= 0) + { + fprintf(stderr, "Error connecting to server\n"); + ERR_print_errors_fp(stderr); + goto end; + } + + if(BIO_do_handshake(sbio) <= 0) + { + fprintf(stderr, "Error establishing SSL connection\n"); + ERR_print_errors_fp(stderr); + goto end; + } + + /* Could examine ssl here to get connection info */ + + BIO_puts(sbio, "GET / HTTP/1.0\n\n"); + for(;;) + { + len = BIO_read(sbio, tmpbuf, 1024); + if(len <= 0) break; + BIO_write(out, tmpbuf, len); + } + end: + SSL_CONF_CTX_free(cctx); + BIO_free_all(sbio); + BIO_free(out); + NCONF_free(conf); + return 0; + } + diff --git a/demos/bio/connect.cnf b/demos/bio/connect.cnf new file mode 100644 index 0000000000..4dee03c373 --- /dev/null +++ b/demos/bio/connect.cnf @@ -0,0 +1,9 @@ +# Example configuration file +# Connects to the default port of s_server +Connect = localhost:4433 +# Disable TLS v1.2 for test. +# Protocol = ALL, -TLSv1.2 +# Only support 3 curves +Curves = P-521:P-384:P-256 +# Restricted signature algorithms +SignatureAlgorithms = RSA+SHA512:ECDSA+SHA512 -- 2.34.1