Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/demos/bio/server-arg.c
34868 views
1
/*
2
* Copyright 2013-2017 The OpenSSL Project Authors. All Rights Reserved.
3
*
4
* Licensed under the Apache License 2.0 (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
/*
11
* 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
14
*/
15
16
#include <stdio.h>
17
#include <string.h>
18
#include <signal.h>
19
#include <stdlib.h>
20
#include <openssl/err.h>
21
#include <openssl/ssl.h>
22
23
int main(int argc, char *argv[])
24
{
25
char *port = "*:4433";
26
BIO *ssl_bio, *tmp;
27
SSL_CTX *ctx;
28
SSL_CONF_CTX *cctx;
29
char buf[512];
30
BIO *in = NULL;
31
int ret = EXIT_FAILURE, i;
32
char **args = argv + 1;
33
int nargs = argc - 1;
34
35
ctx = SSL_CTX_new(TLS_server_method());
36
37
cctx = SSL_CONF_CTX_new();
38
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
39
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
40
SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
41
while (*args && **args == '-') {
42
int rv;
43
/* Parse standard arguments */
44
rv = SSL_CONF_cmd_argv(cctx, &nargs, &args);
45
if (rv == -3) {
46
fprintf(stderr, "Missing argument for %s\n", *args);
47
goto err;
48
}
49
if (rv < 0) {
50
fprintf(stderr, "Error in command %s\n", *args);
51
ERR_print_errors_fp(stderr);
52
goto err;
53
}
54
/* If rv > 0 we processed something so proceed to next arg */
55
if (rv > 0)
56
continue;
57
/* Otherwise application specific argument processing */
58
if (strcmp(*args, "-port") == 0) {
59
port = args[1];
60
if (port == NULL) {
61
fprintf(stderr, "Missing -port argument\n");
62
goto err;
63
}
64
args += 2;
65
nargs -= 2;
66
continue;
67
} else {
68
fprintf(stderr, "Unknown argument %s\n", *args);
69
goto err;
70
}
71
}
72
73
if (!SSL_CONF_CTX_finish(cctx)) {
74
fprintf(stderr, "Finish error\n");
75
ERR_print_errors_fp(stderr);
76
goto err;
77
}
78
#ifdef ITERATE_CERTS
79
/*
80
* Demo of how to iterate over all certificates in an SSL_CTX structure.
81
*/
82
{
83
X509 *x;
84
int rv;
85
rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST);
86
while (rv) {
87
X509 *x = SSL_CTX_get0_certificate(ctx);
88
X509_NAME_print_ex_fp(stdout, X509_get_subject_name(x), 0,
89
XN_FLAG_ONELINE);
90
printf("\n");
91
rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT);
92
}
93
fflush(stdout);
94
}
95
#endif
96
/* Setup server side SSL bio */
97
ssl_bio = BIO_new_ssl(ctx, 0);
98
99
if ((in = BIO_new_accept(port)) == NULL)
100
goto err;
101
102
/*
103
* This means that when a new connection is accepted on 'in', The ssl_bio
104
* will be 'duplicated' and have the new socket BIO push into it.
105
* Basically it means the SSL BIO will be automatically setup
106
*/
107
BIO_set_accept_bios(in, ssl_bio);
108
109
again:
110
/*
111
* The first call will setup the accept socket, and the second will get a
112
* socket. In this loop, the first actual accept will occur in the
113
* BIO_read() function.
114
*/
115
116
if (BIO_do_accept(in) <= 0)
117
goto err;
118
119
for (;;) {
120
i = BIO_read(in, buf, 512);
121
if (i == 0) {
122
/*
123
* If we have finished, remove the underlying BIO stack so the
124
* next time we call any function for this BIO, it will attempt
125
* to do an accept
126
*/
127
printf("Done\n");
128
tmp = BIO_pop(in);
129
BIO_free_all(tmp);
130
goto again;
131
}
132
if (i < 0)
133
goto err;
134
fwrite(buf, 1, i, stdout);
135
fflush(stdout);
136
}
137
138
ret = EXIT_SUCCESS;
139
err:
140
if (ret != EXIT_SUCCESS)
141
ERR_print_errors_fp(stderr);
142
BIO_free(in);
143
return ret;
144
}
145
146