mirror of
https://github.com/openssl/openssl.git
synced 2025-01-30 14:01:55 +08:00
Added Simple SSL Echo Client/Server to demos.
Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/17260)
This commit is contained in:
parent
cb629550cd
commit
801c638c50
@ -50,3 +50,6 @@ signature:
|
||||
EVP_Signature_demo.c Compute and verify a signature from multiple buffers
|
||||
rsa_pss_direct.c Compute and verify an RSA-PSS signature from a hash
|
||||
rsa_pss_hash.c Compute and verify an RSA-PSS signature over a buffer
|
||||
|
||||
sslecho:
|
||||
main.c Simple SSL echo client/server.
|
||||
|
20
demos/sslecho/A-SSL-Docs.txt
Normal file
20
demos/sslecho/A-SSL-Docs.txt
Normal file
@ -0,0 +1,20 @@
|
||||
Useful Links:
|
||||
|
||||
OpenSSL API Documentation: https://www.openssl.org/docs
|
||||
|
||||
Github: https://github.com/openssl/openssl
|
||||
|
||||
OpenSSL Wiki: https://wiki.openssl.org/index.php/Main_Page
|
||||
|
||||
Original Simple Server: https://wiki.openssl.org/index.php/Simple_TLS_Server
|
||||
|
||||
---------------------------------------------------------------
|
||||
|
||||
Generate self signed cert and key 'pem' files (good for 10 years):
|
||||
|
||||
openssl req -newkey rsa:4096 -x509 -sha256 -days 3650 -nodes -out cert.pem -keyout key.pem
|
||||
|
||||
You can just hit carriage returns to accept the default values, except for "Common Name"; you
|
||||
should enter 'localhost', or an actual hostname.
|
||||
|
||||
The same keys can be used for both communicating instances; same or different machines.
|
26
demos/sslecho/README.md
Normal file
26
demos/sslecho/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
OpenSSL Simple Echo Client/Server
|
||||
=================================
|
||||
|
||||
This project implements a simple echo client/server.
|
||||
|
||||
It is a console application, with command line parameters determining the mode
|
||||
of operation (client or server). Start it with no parameters to see usage.
|
||||
|
||||
The server code was adapted from the Simple TLS Server on the OpenSSL Wiki.
|
||||
The server code was modified to perform the echo function, and client code
|
||||
was added to open a connection with the server and to send keyboard input
|
||||
to the server.
|
||||
|
||||
The new client code illustrates that:
|
||||
|
||||
- Connection to the SSL server starts as a standard TCP 'connect'.
|
||||
- Once connected with TCP, the client 'upgrades' to SSL using
|
||||
SSL_connect().
|
||||
- When the SSL connection completes, data is sent and received using
|
||||
SSL_write() and SSL_read().
|
||||
- Pretty simple.
|
||||
|
||||
The cert.pem and key.pem files included are self signed certificates with the
|
||||
"Common Name" of 'localhost'.
|
||||
|
||||
Best to create the 'pem' files using an actual hostname.
|
32
demos/sslecho/cert.pem
Normal file
32
demos/sslecho/cert.pem
Normal file
@ -0,0 +1,32 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFkzCCA3ugAwIBAgIUQJ8FQFwuVg1UlnIBam0+liL0RSQwDQYJKoZIhvcNAQEL
|
||||
BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X
|
||||
DTIyMDIwMjE0MzgzNloXDTMyMDEzMTE0MzgzNlowWTELMAkGA1UEBhMCQVUxEzAR
|
||||
BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5
|
||||
IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
|
||||
MIICCgKCAgEAyPZfTbR9lVvpHxIGRzpYb1gYFjPZ7yTXYZVKEqQLVxw/O2L32ufa
|
||||
lODiYJr/pKu9++9T+JrmRnonYlyl0uFta3w4rMY9PzHsT7jIZJByoFdraNz1SnxF
|
||||
1UaHjzF9fjIA0/n/ZGVJDZCCYulpcVkpW14oNG4tTW5IefYUH3GxmPZ5godhWEla
|
||||
6OXl3+9xkGd5yXq1O4VZbsekcVcZlznuq7blmvs3UrjrEZ5xgmCd8kNzy/E9APKY
|
||||
SSGx87/U9yyiz5GAphgSNTqAfEWqpzouMv+hUm/J5NuZCXbOPYbE7zfDDauspYiY
|
||||
/wdGty9ZvDy5g+fFz8sZig1OWuHqvU8QGoIfVRCxjhX3+p0/KshGDBWjLHek+8Wh
|
||||
IZHmuf1LgT+gOzN3dxxVEcphSiJX0eZ/OhBelowrdabEycm2WAk3qs/tUDMbWh6V
|
||||
VSH22ODLX/cBrSAY2sk2EU8Mz5Mbm6gFTcJhqOBgVn5g8/3QCAhFG3xq/2LKZ+za
|
||||
itAKbaeQqyAw5G/+oc7mKCjUqSKE92n6FKZRsJrB+vfy3AQYyqJevHcIf2nbBimX
|
||||
vb4/rDed/gvSOVGIXIUiUlFHgg8DoVZqMrfJ+y/xwr+Ya+AX8n6J8EB2It3W4EEf
|
||||
nmosupBcZPb6U2VrtpEe/199nPj2ZXQHGLLQfw8lYjvZDghCFiP0o8cCAwEAAaNT
|
||||
MFEwHQYDVR0OBBYEFDClIPCiAkevl1qh188Ycjz5IZ/DMB8GA1UdIwQYMBaAFDCl
|
||||
IPCiAkevl1qh188Ycjz5IZ/DMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
|
||||
BQADggIBAGQm27D74xUm1X99GbDQpgJenUIu+Bszk8qXCsPfyyQZy4H6+70uXlkC
|
||||
ASf/keQjrPzrco3rBelbtlCGqqWhsCznVplrjNIntBAkLD0fU3z92SjsMvHEcBDa
|
||||
Nu6aXExN9gv85EBJHNnj16hqjo8Mk+ydNQ8BtcnZa4zi7GdVh29KbPuEzeoyRnXP
|
||||
xh5yHUj5Bs6hEUbirhm1WLEK8bvfWykfEJiGOQO8MHAeYK1uPFXDmswgTwJFzZyA
|
||||
6LSXYbmGOnCM8yAmVXHMnXXCKd+DQFyQ0KrXDiixyTinYFtrONBkNNt/7SnCjJt5
|
||||
H3LRTNuoZvvGmaS7GxbIMemBjLdrigKicVZunEPGFRTEL7K+spmSMnpAiITStxjR
|
||||
70wHEe3M9IUbJximKaxvMhXhP0VSPJGOzgG304A2MqMS7UPBDzD/pz5c7gn7ILfM
|
||||
LcxzStnQcbTqqmdpNVlMv31YpOk5nel5RY3UmwKbQkix6UAo/CJmC1Q3yLU8uG5O
|
||||
6j7vS8t0wOYcVTAA845JU8C7V5yy6UeCB9F2oGDgVwCe6U8bzTIoCDnkzIKO7LlS
|
||||
734KP+fNK9LatNzpPQWW+1SK4XEZBNLOMePwu560GLVzPgr9ji0z83E+0yAcWrAO
|
||||
4gKT+/h3Ep1Ut73daskFAvNJFFt/5Rm+xZECHrxRkXqW1AN/2eXX
|
||||
-----END CERTIFICATE-----
|
52
demos/sslecho/key.pem
Normal file
52
demos/sslecho/key.pem
Normal file
@ -0,0 +1,52 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDI9l9NtH2VW+kf
|
||||
EgZHOlhvWBgWM9nvJNdhlUoSpAtXHD87Yvfa59qU4OJgmv+kq73771P4muZGeidi
|
||||
XKXS4W1rfDisxj0/MexPuMhkkHKgV2to3PVKfEXVRoePMX1+MgDT+f9kZUkNkIJi
|
||||
6WlxWSlbXig0bi1Nbkh59hQfcbGY9nmCh2FYSVro5eXf73GQZ3nJerU7hVlux6Rx
|
||||
VxmXOe6rtuWa+zdSuOsRnnGCYJ3yQ3PL8T0A8phJIbHzv9T3LKLPkYCmGBI1OoB8
|
||||
RaqnOi4y/6FSb8nk25kJds49hsTvN8MNq6yliJj/B0a3L1m8PLmD58XPyxmKDU5a
|
||||
4eq9TxAagh9VELGOFff6nT8qyEYMFaMsd6T7xaEhkea5/UuBP6A7M3d3HFURymFK
|
||||
IlfR5n86EF6WjCt1psTJybZYCTeqz+1QMxtaHpVVIfbY4Mtf9wGtIBjayTYRTwzP
|
||||
kxubqAVNwmGo4GBWfmDz/dAICEUbfGr/Yspn7NqK0Aptp5CrIDDkb/6hzuYoKNSp
|
||||
IoT3afoUplGwmsH69/LcBBjKol68dwh/adsGKZe9vj+sN53+C9I5UYhchSJSUUeC
|
||||
DwOhVmoyt8n7L/HCv5hr4BfyfonwQHYi3dbgQR+eaiy6kFxk9vpTZWu2kR7/X32c
|
||||
+PZldAcYstB/DyViO9kOCEIWI/SjxwIDAQABAoICAH51SpODOGN8ar36gajgtjWa
|
||||
oc2W41TxQfdOEkaYo+o1BDVCmeVOcOWufcV8w9HDoNGgUJ7oGm/O/mmPE2oYINq6
|
||||
WI+gT3os2B9yj+d4Xik32YcrQ8+TU/5ZW4RoCCgZHxxE/MkYU1gNz36ekpOZH8U3
|
||||
AuW7Txaih0j36MHAsZknwF67Ai6kOmjEAltgOX49Hw4CAXlq+FQVnQ0VWi0nb2Du
|
||||
vp0/6BhN9N4pbhQ06C9C8uMq8tBd2CZs5aYU2NaRaAJl9SaPjyWfoqqQzEpe+iNt
|
||||
aP6PCeTRqwOhlzZwUAyYck1v8jxYMK6KzZ0IVtd0/uhaOMgBbhjJNr1J3IUz81Ud
|
||||
gwmU7UrifjtcGiMHNmHnIAJNcbm9sY27EvsyEHz3zf90VQL8wLpYflX9kX5v8soi
|
||||
WPv6On+u7ARKofHfQKmP1BfJoGY651uyI1vqdpwUds9iQk3dZWUuBf1WRzywH4t/
|
||||
Vwz/h9cEW1Pd42cjukRCoPE1kLc9vHBUEADaaQG7Y5avuLIfDFzXEmwf9YokGRcy
|
||||
ULUikhhFgiL4bOiQ4cj0/c3CLFAM98iq+z1pTlGFy5msjgUTg3ouUUbbPTaxaMS5
|
||||
yVeXelleQADdpj25MTGatBkGW4WC3DYopvvSy+DZ6XarJ6gYm+/cV+eoXddQYLUd
|
||||
RAQqnQFqVPUIy2rlVuQBAoIBAQDlKILSqQNPZqou6lFgo4tbFLpzUFVAnmrEUhuJ
|
||||
3v9ppseKncolZ3pcr10VwIzuQZliLLvUiZ8aB+TzMeuIRBm1PkXMpSRhPsVb2bGb
|
||||
QrTzzPafB8uwVwvr3YzYeRXbpdabU9UpuQMk+lD+GEx5DfowdYJMtdIBOeQdjROi
|
||||
7JZnHPfNwNheEakJpCgPbulQRfrXx4Fd+npWQprcvCYhg8vnqCHrGazy5g/2dnYF
|
||||
NW7L2CNHdM74SJKl8gY/YcfEQSFcir6SFWUGPOiHsVdpKX9K0his6DoiV8QPH/S0
|
||||
RIKZuNIuOmiO8ATblYksrh8UuOQWi2kywE3bF3neMmNgwoRBAoIBAQDggGL0C9Ij
|
||||
n+DHlkHujbziEwe1pLVSb4x2q5KmZwA4VWDGLARbK2ypx6/LJDsUCwK6ZFHh89DU
|
||||
eW9Ze6fXMi8Fiv1N1DfawIu9+bU3BG5boiQMdAgYzSCUhwojo3KiIpvbzXCmSQd9
|
||||
1lJkbwxQFo2GuYZIX+QLyONhGBA1JdF0kBzIrrQWmza+wNj1emftFptZlwAW1+wm
|
||||
KvZyzAZl3/5fj5/9oAMxlH489edbgRMF/cOmzpB4fIAkbzmvU97xXOzKWX+nPA6D
|
||||
BTVkkruqESpq2pf06gGnlbCC5Tcf1QS+On+/LGr1frr/aeouRy8xHv5xgVCRcyh+
|
||||
nLwOP6W/KYYHAoIBAQCXgjtMkJYxrw0hy6ZWIIsIgyHrD9fty0+H0UmH1DpGXhBb
|
||||
44s9Q7cxBHik4xPKivCgajcdhIf+q+2BpSW2iF/+5tc7QIxXBytxWPMGVgpRjtgX
|
||||
uQ3A3yxwm6B9l0EOYg0L0VeEKGCd2CoodWRKPSWHWIn3sdbRHLdnmli7RXUDY7Gr
|
||||
Ba+IMmDykOgzm/8CJeJ9O9iai/rKgWrmOjdzvTHZTd5vFCC2z8kKCLRrKTLB73sT
|
||||
yXT1zvW2Zdgfm8R6Sx2Fk+3/o8mRYD/VRzklvFv+2f2ahEe7YQ+teFFPxmQawomk
|
||||
KtXqe2Ka07lIIy9FgiC7jxzUgzR2gIUAlYwC81iBAoIBAC30Oc0oykf+hv1z1WUm
|
||||
YD6KlK5q267XJJJ6BlfHh7UATQHjqrSay/Bo7qQPc4RjyJgsxtIQnXOQs+lGNZII
|
||||
NLXWwIj44sIFXdVyUtTDNG/PXb+q1Kl2+69LgRjQcTudB/hTMjbnhgANKepjDMss
|
||||
AqZMPZ98+WosIdcTHOY0Ko7InQu7LyPde7RKN17wQmu2j/Ajx6HlavJZIv9Wogyi
|
||||
cChRdvdslJrGgZyq3UPOxP0Z972iVNJE8doDZnRsH5uaYOH+tfGein3pSAehPYbP
|
||||
YrZirm40pEgQjQQONV1vtjvWL6YLSo2b9l0n6ga1DYTpij3jsYFEaEqafKgSATSD
|
||||
JGsCggEAVnGMMovIgEADUAiwQzlYb5/gUjRJOetFpPW8R/3CZqFt3FTprNH0Q7Jb
|
||||
be3PJCLONqYE8K84n66Ro5I/58oVcJ5QwCwZCmZ+Kk4u7j0RYR9kkpR6gWShSpfw
|
||||
CkrSVNz0zn3l8GxIs11YO+ztBQG82StU+7PTZH9KGEQhytO3km+txC3EXih7Fn7R
|
||||
Vb2rJ+2v6aSGjH+1n/GFP8YxKAxYk7jPwI5s4YMrn6TQPt4tgr4I0f7DDjjlVLEg
|
||||
LMixBvYHG/8fXWtldf6Wwhl6UJ5G0LA4KxXRAJ68RX8cQNLG7mv66xogbLEMnrJr
|
||||
DDFU5HazFnn1G0/rg2SnKHTRLV2E9g==
|
||||
-----END PRIVATE KEY-----
|
340
demos/sslecho/main.c
Normal file
340
demos/sslecho/main.c
Normal file
@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
static const int server_port = 4433;
|
||||
|
||||
typedef unsigned char bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
/*
|
||||
* This flag won't be useful until both accept/read (TCP & SSL) methods
|
||||
* can be called with a timeout. TBD.
|
||||
*/
|
||||
static volatile bool server_running = true;
|
||||
|
||||
int create_socket(bool isServer)
|
||||
{
|
||||
int s;
|
||||
int optval = 1;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
perror("Unable to create socket");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (isServer) {
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(server_port);
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
/* Reuse the address; good for quick restarts */
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))
|
||||
< 0) {
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (bind(s, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
|
||||
perror("Unable to bind");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (listen(s, 1) < 0) {
|
||||
perror("Unable to listen");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
SSL_CTX* create_context(bool isServer)
|
||||
{
|
||||
const SSL_METHOD *method;
|
||||
SSL_CTX *ctx;
|
||||
|
||||
if (isServer)
|
||||
method = TLS_server_method();
|
||||
else
|
||||
method = TLS_client_method();
|
||||
|
||||
ctx = SSL_CTX_new(method);
|
||||
if (ctx == NULL) {
|
||||
perror("Unable to create SSL context");
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void configure_server_context(SSL_CTX *ctx)
|
||||
{
|
||||
/* Set the key and cert */
|
||||
if (SSL_CTX_use_certificate_chain_file(ctx, "cert.pem") <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_PrivateKey_file(ctx, "key.pem", SSL_FILETYPE_PEM) <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void configure_client_context(SSL_CTX *ctx)
|
||||
{
|
||||
/*
|
||||
* Configure the client to abort the handshake if certificate verification
|
||||
* fails
|
||||
*/
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
/*
|
||||
* In a real application you would probably just use the default system certificate trust store and call:
|
||||
* SSL_CTX_set_default_verify_paths(ctx);
|
||||
* In this demo though we are using a self-signed certificate, so the client must trust it directly.
|
||||
*/
|
||||
if (!SSL_CTX_load_verify_locations(ctx, "cert.pem", NULL)) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
printf("Usage: sslecho s\n");
|
||||
printf(" --or--\n");
|
||||
printf(" sslecho c ip\n");
|
||||
printf(" c=client, s=server, ip=dotted ip of server\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool isServer;
|
||||
int result;
|
||||
|
||||
SSL_CTX *ssl_ctx = NULL;
|
||||
SSL *ssl = NULL;
|
||||
|
||||
int server_skt = -1;
|
||||
int client_skt = -1;
|
||||
|
||||
char txbuf[128];
|
||||
size_t txcap = sizeof(txbuf);
|
||||
int txlen;
|
||||
|
||||
char rxbuf[128];
|
||||
size_t rxcap = sizeof(rxbuf);
|
||||
int rxlen;
|
||||
|
||||
char *rem_server_ip = NULL;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
unsigned int addr_len = sizeof(addr);
|
||||
|
||||
/* Splash */
|
||||
printf("\nsslecho : Simple Echo Client/Server (OpenSSL 3.0.1-dev) : %s : %s\n\n", __DATE__,
|
||||
__TIME__);
|
||||
|
||||
/* Need to know if client or server */
|
||||
if (argc < 2) {
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
isServer = (argv[1][0] == 's') ? true : false;
|
||||
/* If client get remote server address (could be 127.0.0.1) */
|
||||
if (!isServer) {
|
||||
if (argc != 3) {
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
rem_server_ip = argv[2];
|
||||
}
|
||||
|
||||
/* Create context used by both client and server */
|
||||
ssl_ctx = create_context(isServer);
|
||||
|
||||
/* If server */
|
||||
if (isServer) {
|
||||
|
||||
printf("We are the server on port: %d\n\n", server_port);
|
||||
|
||||
/* Configure server context with appropriate key files */
|
||||
configure_server_context(ssl_ctx);
|
||||
|
||||
/* Create server socket; will bind with server port and listen */
|
||||
server_skt = create_socket(true);
|
||||
|
||||
/*
|
||||
* Loop to accept clients.
|
||||
* Need to implement timeouts on TCP & SSL connect/read functions
|
||||
* before we can catch a CTRL-C and kill the server.
|
||||
*/
|
||||
while (server_running) {
|
||||
/* Wait for TCP connection from client */
|
||||
client_skt = accept(server_skt, (struct sockaddr*) &addr,
|
||||
&addr_len);
|
||||
if (client_skt < 0) {
|
||||
perror("Unable to accept");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("Client TCP connection accepted\n");
|
||||
|
||||
/* Create server SSL structure using newly accepted client socket */
|
||||
ssl = SSL_new(ssl_ctx);
|
||||
SSL_set_fd(ssl, client_skt);
|
||||
|
||||
/* Wait for SSL connection from the client */
|
||||
if (SSL_accept(ssl) <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
server_running = false;
|
||||
} else {
|
||||
|
||||
printf("Client SSL connection accepted\n\n");
|
||||
|
||||
/* Echo loop */
|
||||
while (true) {
|
||||
/* Get message from client; will fail if client closes connection */
|
||||
if ((rxlen = SSL_read(ssl, rxbuf, rxcap)) <= 0) {
|
||||
if (rxlen == 0) {
|
||||
printf("Client closed connection\n");
|
||||
}
|
||||
ERR_print_errors_fp(stderr);
|
||||
break;
|
||||
}
|
||||
/* Insure null terminated input */
|
||||
rxbuf[rxlen] = 0;
|
||||
/* Look for kill switch */
|
||||
if (strcmp(rxbuf, "kill\n") == 0) {
|
||||
/* Terminate...with extreme prejudice */
|
||||
printf("Server received 'kill' command\n");
|
||||
server_running = false;
|
||||
break;
|
||||
}
|
||||
/* Show received message */
|
||||
printf("Received: %s", rxbuf);
|
||||
/* Echo it back */
|
||||
if (SSL_write(ssl, rxbuf, rxlen) <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (server_running) {
|
||||
/* Cleanup for next client */
|
||||
SSL_shutdown(ssl);
|
||||
SSL_free(ssl);
|
||||
close(client_skt);
|
||||
}
|
||||
}
|
||||
printf("Server exiting...\n");
|
||||
}
|
||||
/* Else client */
|
||||
else {
|
||||
|
||||
printf("We are the client\n\n");
|
||||
|
||||
/* Configure client context so we verify the server correctly */
|
||||
configure_client_context(ssl_ctx);
|
||||
|
||||
/* Create "bare" socket */
|
||||
client_skt = create_socket(false);
|
||||
/* Set up connect address */
|
||||
addr.sin_family = AF_INET;
|
||||
inet_pton(AF_INET, rem_server_ip, &addr.sin_addr.s_addr);
|
||||
addr.sin_port = htons(server_port);
|
||||
/* Do TCP connect with server */
|
||||
if (connect(client_skt, (struct sockaddr*) &addr, sizeof(addr)) != 0) {
|
||||
perror("Unable to TCP connect to server");
|
||||
goto exit;
|
||||
} else {
|
||||
printf("TCP connection to server successful\n");
|
||||
}
|
||||
|
||||
/* Create client SSL structure using dedicated client socket */
|
||||
ssl = SSL_new(ssl_ctx);
|
||||
SSL_set_fd(ssl, client_skt);
|
||||
/* Set host name for SNI */
|
||||
SSL_set_tlsext_host_name(ssl, rem_server_ip);
|
||||
/* Configure server hostname check */
|
||||
SSL_set1_host(ssl, rem_server_ip);
|
||||
|
||||
/* Now do SSL connect with server */
|
||||
if (SSL_connect(ssl) == 1) {
|
||||
|
||||
printf("SSL connection to server successful\n\n");
|
||||
|
||||
/* Loop to send input from keyboard */
|
||||
while (true) {
|
||||
/* Get a line of input */
|
||||
txlen = getline(&txbuf, &txcap, stdin);
|
||||
/* Exit loop if just a carriage return */
|
||||
if (txbuf[0] == '\n') {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Send it to the server */
|
||||
if ((result = SSL_write(ssl, txbuf, txlen)) <= 0) {
|
||||
printf("Server closed connection\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Wait for the echo */
|
||||
rxlen = SSL_read(ssl, rxbuf, rxcap);
|
||||
if (rxlen <= 0) {
|
||||
printf("Server closed connection\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
break;
|
||||
} else {
|
||||
/* Show it */
|
||||
rxbuf[rxlen] = 0;
|
||||
printf("Received: %s", rxbuf);
|
||||
}
|
||||
}
|
||||
printf("Client exiting...\n");
|
||||
} else {
|
||||
|
||||
printf("SSL connection to server failed\n\n");
|
||||
|
||||
ERR_print_errors_fp(stderr);
|
||||
}
|
||||
}
|
||||
exit:
|
||||
/* Close up */
|
||||
if (ssl != NULL) {
|
||||
SSL_shutdown(ssl);
|
||||
SSL_free(ssl);
|
||||
}
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
|
||||
if (client_skt != -1)
|
||||
close(client_skt);
|
||||
if (server_skt != -1)
|
||||
close(server_skt);
|
||||
|
||||
OPENSSL_free(txbuf);
|
||||
OPENSSL_free(rxbuf);
|
||||
|
||||
printf("sslecho exiting\n");
|
||||
|
||||
return 0;
|
||||
}
|
12
demos/sslecho/makefile
Normal file
12
demos/sslecho/makefile
Normal file
@ -0,0 +1,12 @@
|
||||
PROG ?= sslecho
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
# Debug version.
|
||||
#
|
||||
$(PROG): main.c
|
||||
|
||||
$(CC) -O0 -g3 -W -Wall -I../../include -L../../ -o $(PROG) main.c -lssl -lcrypto
|
||||
|
||||
clean:
|
||||
rm -rf $(PROG) *.o *.obj
|
Loading…
Reference in New Issue
Block a user