From 381417089a9352490866107ee06d2c5e56be0296 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Fri, 18 Oct 2013 16:28:38 +0100 Subject: [PATCH] Add demo for SSL server using SSL_CONF. (cherry picked from commit ebd14bfce9ef6b4bf41129a329823130d1002f42) --- demos/bio/accept.cnf | 12 ++++ demos/bio/client-arg.c | 7 ++ demos/bio/client-conf.c | 7 ++ demos/bio/server-arg.c | 135 +++++++++++++++++++++++++++++++++++++ demos/bio/server-conf.c | 143 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 304 insertions(+) create mode 100644 demos/bio/accept.cnf create mode 100644 demos/bio/server-arg.c create mode 100644 demos/bio/server-conf.c diff --git a/demos/bio/accept.cnf b/demos/bio/accept.cnf new file mode 100644 index 0000000000..c1a0343a05 --- /dev/null +++ b/demos/bio/accept.cnf @@ -0,0 +1,12 @@ +# Example configuration file +# Connects to the default port of s_server +Port = localhost:4433 +# Disable TLS v1.2 for test. +# Protocol = ALL, -TLSv1.2 +# Only support 3 curves +Curves = P-521:P-384:P-256 +ECDHParameters = Automatic +# Restricted signature algorithms +SignatureAlgorithms = RSA+SHA512:ECDSA+SHA512 +Certificate=server.pem +PrivateKey=server.pem diff --git a/demos/bio/client-arg.c b/demos/bio/client-arg.c index f0cb9aba90..cca7a1ed06 100644 --- a/demos/bio/client-arg.c +++ b/demos/bio/client-arg.c @@ -60,6 +60,13 @@ int main(int argc, char **argv) } } + if (!SSL_CONF_CTX_finish(cctx)) + { + fprintf(stderr, "Finish error\n"); + ERR_print_errors_fp(stderr); + goto err; + } + /* 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. diff --git a/demos/bio/client-conf.c b/demos/bio/client-conf.c index 6cef222fa3..191615a9ac 100644 --- a/demos/bio/client-conf.c +++ b/demos/bio/client-conf.c @@ -68,6 +68,13 @@ int main(int argc, char **argv) goto end; } } + + if (!SSL_CONF_CTX_finish(cctx)) + { + fprintf(stderr, "Finish error\n"); + ERR_print_errors_fp(stderr); + goto err; + } /* We'd normally set some stuff like the verify paths and * mode here because as things stand this will connect to diff --git a/demos/bio/server-arg.c b/demos/bio/server-arg.c new file mode 100644 index 0000000000..cf8e86b754 --- /dev/null +++ b/demos/bio/server-arg.c @@ -0,0 +1,135 @@ +/* NOCW */ +/* demos/bio/saccept.c */ + +/* A minimal program to server an SSL connection. + * It uses blocking. + * saccept host:port + * host is the interface IP to use. If any interface, use *:port + * The default it *:4433 + * + * cc -I../../include saccept.c -L../.. -lssl -lcrypto + */ + +#include +#include +#include +#include + + +int main(int argc, char *argv[]) + { + char *port = "*:4433"; + BIO *ssl_bio,*tmp; + SSL_CTX *ctx; + SSL_CONF_CTX *cctx; + char buf[512]; + BIO *in=NULL; + int ret=1,i; + char **args = argv + 1; + int nargs = argc - 1; + + SSL_load_error_strings(); + + /* Add ciphers and message digests */ + OpenSSL_add_ssl_algorithms(); + + ctx=SSL_CTX_new(SSLv23_server_method()); + + cctx = SSL_CONF_CTX_new(); + SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); + SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); + 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 err; + } + if (rv < 0) + { + fprintf(stderr, "Error in command %s\n", *args); + ERR_print_errors_fp(stderr); + goto err; + } + /* If rv > 0 we processed something so proceed to next arg */ + if (rv > 0) + continue; + /* Otherwise application specific argument processing */ + if (!strcmp(*args, "-port")) + { + port = args[1]; + if (port == NULL) + { + fprintf(stderr, "Missing -port argument\n"); + goto err; + } + args += 2; + nargs -= 2; + continue; + } + else + { + fprintf(stderr, "Unknown argument %s\n", *args); + goto err; + } + } + + if (!SSL_CONF_CTX_finish(cctx)) + { + fprintf(stderr, "Finish error\n"); + ERR_print_errors_fp(stderr); + goto err; + } + + /* Setup server side SSL bio */ + ssl_bio=BIO_new_ssl(ctx,0); + + if ((in=BIO_new_accept(port)) == NULL) goto err; + + /* This means that when a new connection is acceptede on 'in', + * The ssl_bio will be 'dupilcated' and have the new socket + * BIO push into it. Basically it means the SSL BIO will be + * automatically setup */ + BIO_set_accept_bios(in,ssl_bio); + +again: + /* The first call will setup the accept socket, and the second + * will get a socket. In this loop, the first actual accept + * will occur in the BIO_read() function. */ + + if (BIO_do_accept(in) <= 0) goto err; + + for (;;) + { + i=BIO_read(in,buf,512); + if (i == 0) + { + /* If we have finished, remove the underlying + * BIO stack so the next time we call any function + * for this BIO, it will attempt to do an + * accept */ + printf("Done\n"); + tmp=BIO_pop(in); + BIO_free_all(tmp); + goto again; + } + if (i < 0) goto err; + fwrite(buf,1,i,stdout); + fflush(stdout); + } + + ret=0; +err: + if (ret) + { + ERR_print_errors_fp(stderr); + } + if (in != NULL) BIO_free(in); + exit(ret); + return(!ret); + } + diff --git a/demos/bio/server-conf.c b/demos/bio/server-conf.c new file mode 100644 index 0000000000..d520a1bbb8 --- /dev/null +++ b/demos/bio/server-conf.c @@ -0,0 +1,143 @@ +/* NOCW */ +/* demos/bio/saccept.c */ + +/* A minimal program to server an SSL connection. + * It uses blocking. + * saccept host:port + * host is the interface IP to use. If any interface, use *:port + * The default it *:4433 + * + * cc -I../../include saccept.c -L../.. -lssl -lcrypto + */ + +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) + { + char *port = "*:4433"; + BIO *in=NULL; + BIO *ssl_bio,*tmp; + SSL_CTX *ctx; + SSL_CONF_CTX *cctx = NULL; + CONF *conf = NULL; + STACK_OF(CONF_VALUE) *sect = NULL; + CONF_VALUE *cnf; + long errline = -1; + char buf[512]; + int ret=1,i; + + SSL_load_error_strings(); + + /* Add ciphers and message digests */ + OpenSSL_add_ssl_algorithms(); + + conf = NCONF_new(NULL); + + if (NCONF_load(conf, "accept.cnf", &errline) <= 0) + { + if (errline <= 0) + fprintf(stderr, "Error processing config file\n"); + else + fprintf(stderr, "Error on line %ld\n", errline); + goto err; + } + + sect = NCONF_get_section(conf, "default"); + + if (sect == NULL) + { + fprintf(stderr, "Error retrieving default section\n"); + goto err; + } + + ctx=SSL_CTX_new(SSLv23_server_method()); + cctx = SSL_CONF_CTX_new(); + SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); + SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); + 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++) + { + int rv; + 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 err; + } + if (!strcmp(cnf->name, "Port")) + { + port = cnf->value; + } + else + { + fprintf(stderr, "Unknown configuration option %s\n", + cnf->name); + goto err; + } + } + + if (!SSL_CONF_CTX_finish(cctx)) + { + fprintf(stderr, "Finish error\n"); + ERR_print_errors_fp(stderr); + goto err; + } + + /* Setup server side SSL bio */ + ssl_bio=BIO_new_ssl(ctx,0); + + if ((in=BIO_new_accept(port)) == NULL) goto err; + + /* This means that when a new connection is acceptede on 'in', + * The ssl_bio will be 'dupilcated' and have the new socket + * BIO push into it. Basically it means the SSL BIO will be + * automatically setup */ + BIO_set_accept_bios(in,ssl_bio); + +again: + /* The first call will setup the accept socket, and the second + * will get a socket. In this loop, the first actual accept + * will occur in the BIO_read() function. */ + + if (BIO_do_accept(in) <= 0) goto err; + + for (;;) + { + i=BIO_read(in,buf,512); + if (i == 0) + { + /* If we have finished, remove the underlying + * BIO stack so the next time we call any function + * for this BIO, it will attempt to do an + * accept */ + printf("Done\n"); + tmp=BIO_pop(in); + BIO_free_all(tmp); + goto again; + } + if (i < 0) goto err; + fwrite(buf,1,i,stdout); + fflush(stdout); + } + + ret=0; +err: + if (ret) + { + ERR_print_errors_fp(stderr); + } + if (in != NULL) BIO_free(in); + exit(ret); + return(!ret); + } + -- 2.40.0