blob: 6056969fe9e83a4a56a125df5567d44bab54ad69 [file] [log] [blame]
Matt Caswell0f113f32015-01-22 03:40:55 +00001/*
Rich Salz9e200682016-05-18 09:16:36 -04002 * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10/*
Matt Caswell0f113f32015-01-22 03:40:55 +000011 * A minimal program to serve an SSL connection. It uses blocking. It use the
12 * SSL_CONF API with the command line. cc -I../../include server-arg.c
13 * -L../.. -lssl -lcrypto -ldl
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +010014 */
15
16#include <stdio.h>
Richard Levitte16c6dee2016-09-09 00:58:21 +020017#include <string.h>
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +010018#include <signal.h>
19#include <openssl/err.h>
20#include <openssl/ssl.h>
21
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +010022int main(int argc, char *argv[])
Matt Caswell0f113f32015-01-22 03:40:55 +000023{
24 char *port = "*:4433";
25 BIO *ssl_bio, *tmp;
26 SSL_CTX *ctx;
27 SSL_CONF_CTX *cctx;
28 char buf[512];
29 BIO *in = NULL;
30 int ret = 1, i;
31 char **args = argv + 1;
32 int nargs = argc - 1;
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +010033
Matt Caswell32ec4152015-03-27 23:01:51 +000034 ctx = SSL_CTX_new(TLS_server_method());
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +010035
Matt Caswell0f113f32015-01-22 03:40:55 +000036 cctx = SSL_CONF_CTX_new();
37 SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
38 SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
39 SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
40 while (*args && **args == '-') {
41 int rv;
42 /* Parse standard arguments */
43 rv = SSL_CONF_cmd_argv(cctx, &nargs, &args);
44 if (rv == -3) {
45 fprintf(stderr, "Missing argument for %s\n", *args);
46 goto err;
47 }
48 if (rv < 0) {
49 fprintf(stderr, "Error in command %s\n", *args);
50 ERR_print_errors_fp(stderr);
51 goto err;
52 }
53 /* If rv > 0 we processed something so proceed to next arg */
54 if (rv > 0)
55 continue;
56 /* Otherwise application specific argument processing */
Rich Salz86885c22015-05-06 14:56:14 -040057 if (strcmp(*args, "-port") == 0) {
Matt Caswell0f113f32015-01-22 03:40:55 +000058 port = args[1];
59 if (port == NULL) {
60 fprintf(stderr, "Missing -port argument\n");
61 goto err;
62 }
63 args += 2;
64 nargs -= 2;
65 continue;
66 } else {
67 fprintf(stderr, "Unknown argument %s\n", *args);
68 goto err;
69 }
70 }
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +010071
Matt Caswell0f113f32015-01-22 03:40:55 +000072 if (!SSL_CONF_CTX_finish(cctx)) {
73 fprintf(stderr, "Finish error\n");
74 ERR_print_errors_fp(stderr);
75 goto err;
76 }
Rich Salz7aa0b022015-02-02 11:08:16 -050077#ifdef ITERATE_CERTS
Matt Caswell0f113f32015-01-22 03:40:55 +000078 /*
79 * Demo of how to iterate over all certificates in an SSL_CTX structure.
80 */
81 {
82 X509 *x;
83 int rv;
84 rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST);
85 while (rv) {
86 X509 *x = SSL_CTX_get0_certificate(ctx);
87 X509_NAME_print_ex_fp(stdout, X509_get_subject_name(x), 0,
88 XN_FLAG_ONELINE);
89 printf("\n");
90 rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT);
91 }
92 fflush(stdout);
93 }
Dr. Stephen Henson0f788192014-02-02 02:51:30 +000094#endif
Matt Caswell0f113f32015-01-22 03:40:55 +000095 /* Setup server side SSL bio */
96 ssl_bio = BIO_new_ssl(ctx, 0);
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +010097
Matt Caswell0f113f32015-01-22 03:40:55 +000098 if ((in = BIO_new_accept(port)) == NULL)
99 goto err;
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +0100100
Matt Caswell0f113f32015-01-22 03:40:55 +0000101 /*
102 * This means that when a new connection is accepted on 'in', The ssl_bio
103 * will be 'duplicated' and have the new socket BIO push into it.
104 * Basically it means the SSL BIO will be automatically setup
105 */
106 BIO_set_accept_bios(in, ssl_bio);
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +0100107
Matt Caswell0f113f32015-01-22 03:40:55 +0000108 again:
109 /*
110 * The first call will setup the accept socket, and the second will get a
111 * socket. In this loop, the first actual accept will occur in the
112 * BIO_read() function.
113 */
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +0100114
Matt Caswell0f113f32015-01-22 03:40:55 +0000115 if (BIO_do_accept(in) <= 0)
116 goto err;
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +0100117
Matt Caswell0f113f32015-01-22 03:40:55 +0000118 for (;;) {
119 i = BIO_read(in, buf, 512);
120 if (i == 0) {
121 /*
122 * If we have finished, remove the underlying BIO stack so the
123 * next time we call any function for this BIO, it will attempt
124 * to do an accept
125 */
126 printf("Done\n");
127 tmp = BIO_pop(in);
128 BIO_free_all(tmp);
129 goto again;
130 }
131 if (i < 0)
132 goto err;
133 fwrite(buf, 1, i, stdout);
134 fflush(stdout);
135 }
Dr. Stephen Hensonebd14bf2013-10-18 16:28:38 +0100136
Matt Caswell0f113f32015-01-22 03:40:55 +0000137 ret = 0;
138 err:
139 if (ret) {
140 ERR_print_errors_fp(stderr);
141 }
Rich Salzca3a82c2015-03-25 11:31:18 -0400142 BIO_free(in);
Matt Caswell0f113f32015-01-22 03:40:55 +0000143 exit(ret);
144 return (!ret);
145}