Add demo for SSL server using SSL_CONF.
authorDr. Stephen Henson <steve@openssl.org>
Fri, 18 Oct 2013 15:28:38 +0000 (16:28 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 2 Feb 2014 23:05:15 +0000 (23:05 +0000)
(cherry picked from commit ebd14bfce9ef6b4bf41129a329823130d1002f42)

demos/bio/accept.cnf [new file with mode: 0644]
demos/bio/client-arg.c
demos/bio/client-conf.c
demos/bio/server-arg.c [new file with mode: 0644]
demos/bio/server-conf.c [new file with mode: 0644]

diff --git a/demos/bio/accept.cnf b/demos/bio/accept.cnf
new file mode 100644 (file)
index 0000000..c1a0343
--- /dev/null
@@ -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
index f0cb9aba900a00188bcfaa01df72220dcc8137bf..cca7a1ed0632cdfda6499fed1f62fd9e6ebf74dc 100644 (file)
@@ -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.
index 6cef222fa36566e035d6fe2142372273ed9acb07..191615a9ac7893ea8a2aaf0f40ee3f6fea3664d6 100644 (file)
@@ -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 (file)
index 0000000..cf8e86b
--- /dev/null
@@ -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 <stdio.h>
+#include <signal.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+
+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 (file)
index 0000000..d520a1b
--- /dev/null
@@ -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 <stdio.h>
+#include <signal.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <openssl/conf.h>
+
+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);
+       }
+