11/*
2- Copyright (c) 2017 Darren Smith
2+ Copyright (c) 2017 Darren Smith
33
4- ssl_examples is free software; you can redistribute it and/or modify
5- it under the terms of the MIT license. See LICENSE for details.
4+ ssl_examples is free software; you can redistribute it and/or modify
5+ it under the terms of the MIT license. See LICENSE for details.
66*/
77
88#include <openssl/bio.h>
@@ -63,6 +63,9 @@ struct ssl_client
6363 char * encrypt_buf ;
6464 size_t encrypt_len ;
6565
66+ /* Store the previous state string */
67+ const char * last_state ;
68+
6669 /* Method to invoke when unencrypted bytes are available. */
6770 void (* io_on_read )(char * buf , size_t len );
6871} client ;
@@ -71,6 +74,7 @@ struct ssl_client
7174 * handshake. */
7275enum ssl_mode { SSLMODE_SERVER , SSLMODE_CLIENT };
7376
77+
7478void ssl_client_init (struct ssl_client * p ,
7579 int fd ,
7680 enum ssl_mode mode )
@@ -93,21 +97,25 @@ void ssl_client_init(struct ssl_client *p,
9397 p -> io_on_read = print_unencrypted_data ;
9498}
9599
100+
96101void ssl_client_cleanup (struct ssl_client * p )
97102{
98103 SSL_free (p -> ssl ); /* free the SSL object and its BIO's */
99104 free (p -> write_buf );
100105 free (p -> encrypt_buf );
101106}
102107
108+
103109int ssl_client_want_write (struct ssl_client * cp ) {
104110 return (cp -> write_len > 0 );
105111}
106112
113+
107114/* Obtain the return value of an SSL operation and convert into a simplified
108115 * error code, which is easier to examine for failure. */
109116enum sslstatus { SSLSTATUS_OK , SSLSTATUS_WANT_IO , SSLSTATUS_FAIL };
110117
118+
111119static enum sslstatus get_sslstatus (SSL * ssl , int n )
112120{
113121 switch (SSL_get_error (ssl , n ))
@@ -124,6 +132,7 @@ static enum sslstatus get_sslstatus(SSL* ssl, int n)
124132 }
125133}
126134
135+
127136/* Handle request to send unencrypted data to the SSL. All we do here is just
128137 * queue the data into the encrypt_buf for later processing by the SSL
129138 * object. */
@@ -134,6 +143,7 @@ void send_unencrypted_bytes(const char *buf, size_t len)
134143 client .encrypt_len += len ;
135144}
136145
146+
137147/* Queue encrypted bytes. Should only be used when the SSL object has requested a
138148 * write operation. */
139149void queue_encrypted_bytes (const char * buf , size_t len )
@@ -143,12 +153,38 @@ void queue_encrypted_bytes(const char *buf, size_t len)
143153 client .write_len += len ;
144154}
145155
156+
157+ void print_ssl_state ()
158+ {
159+ const char * current_state = SSL_state_string_long (client .ssl );
160+ if (current_state != client .last_state ) {
161+ if (current_state )
162+ printf ("SSL-STATE: %s\n" , current_state );
163+ client .last_state = current_state ;
164+ }
165+ }
166+
167+
168+ void print_ssl_error ()
169+ {
170+ BIO * bio = BIO_new (BIO_s_mem ());
171+ ERR_print_errors (bio );
172+ char * buf ;
173+ size_t len = BIO_get_mem_data (bio , & buf );
174+ if (len > 0 )
175+ printf ("SSL-ERROR: %s" , buf );
176+ BIO_free (bio );
177+ }
178+
179+
146180enum sslstatus do_ssl_handshake ()
147181{
148182 char buf [DEFAULT_BUF_SIZE ];
149183 enum sslstatus status ;
150184
185+ print_ssl_state ();
151186 int n = SSL_do_handshake (client .ssl );
187+ print_ssl_state ();
152188 status = get_sslstatus (client .ssl , n );
153189
154190 /* Did SSL request to write bytes? */
@@ -259,6 +295,7 @@ int do_encrypt()
259295 return 0 ;
260296}
261297
298+
262299/* Read bytes from stdin and queue for later encryption. */
263300void do_stdin_read ()
264301{
@@ -268,6 +305,7 @@ void do_stdin_read()
268305 send_unencrypted_bytes (buf , (size_t )n );
269306}
270307
308+
271309/* Read encrypted bytes from socket. */
272310int do_sock_read ()
273311{
@@ -280,6 +318,7 @@ int do_sock_read()
280318 return -1 ;
281319}
282320
321+
283322/* Write encrypted bytes to the socket. */
284323int do_sock_write ()
285324{
@@ -295,19 +334,21 @@ int do_sock_write()
295334 return -1 ;
296335}
297336
337+
298338void ssl_init (const char * certfile , const char * keyfile )
299339{
300- printf ("initialising SSL\n" );
301-
302340 /* SSL library initialisation */
341+
303342 SSL_library_init ();
304343 OpenSSL_add_all_algorithms ();
305344 SSL_load_error_strings ();
306- ERR_load_BIO_strings ();
345+ #if OPENSSL_VERSION_MAJOR < 3
346+ ERR_load_BIO_strings (); // deprecated since OpenSSL 3.0
347+ #endif
307348 ERR_load_crypto_strings ();
308349
309350 /* create the SSL server context */
310- ctx = SSL_CTX_new (SSLv23_method ());
351+ ctx = SSL_CTX_new (TLS_method ());
311352 if (!ctx )
312353 die ("SSL_CTX_new()" );
313354
@@ -326,6 +367,7 @@ void ssl_init(const char * certfile, const char* keyfile)
326367 printf ("certificate and private key loaded and verified\n" );
327368 }
328369
370+
329371 /* Recommended to avoid SSLv2 & SSLv3 */
330372 SSL_CTX_set_options (ctx , SSL_OP_ALL |SSL_OP_NO_SSLv2 |SSL_OP_NO_SSLv3 );
331373}
0 commit comments