/*************************************** **************************************** ***********
* SSL/TLS client Win32 (based on demos/CLI. cpp)
* The dynamic Connection Library libeay32.dll and ssleay. dll must be used,
* Add ws2_32.lib libeay32.lib ssleay32.lib to setting,
* The above library files can be found in the out32dll directory after OpenSSL is compiled,
* For the required certificate files, see <generate a certificate file using OpenSSL> Generate a certificate file by yourself */
**************************************** **************************************** **********/
# Include <stdio. h>
# Include <stdlib. h>
# Include <memory. h>
# Include <errno. h>
# Include <sys/types. h>
# Include <winsock2.h>
# Include "OpenSSL/RSA. H"
# Include "OpenSSL/crypto. H"
# Include "OpenSSL/x509.h"
# Include "OpenSSL/PEM. H"
# Include "OpenSSL/SSL. H"
# Include "OpenSSL/err. H"
# Include "OpenSSL/Rand. H"
/* All required parameter information is provided here in the form of # define */
# Define certf "client. CRT"/* client certificate (requires ca signature )*/
# Define keyf "client. Key"/* private key of the client (encrypted storage is recommended )*/
# Define cacert "ca. CRT"/* CA certificate */
# Define Port 1111/* server port */
# Define server_addr "127.0.0.1"/* IP address of the Service segment */
// Check for errors
# Define chk_null (x) if (x) = NULL) {exit (-1 );}
# Define chk_err (ERR, S) if (ERR) =-1) {perror (s); exit (-2 );}
# Define chk_ssl (ERR) if (ERR) =-1) {err_print_errors_fp (stderr); exit (-3 );}
Int main (void)
{
Int err;
Int SD;
Struct sockaddr_in SA;
Ssl_ctx * CTX;
SSL * SSL;
X509 * server_cert;
Char * STR;
Char Buf [4096];
Ssl_method * meth;
Int seed_int [100];/* store random sequence */
Wsadata;
// Obtain the socket version (2.2)
If (wsastartup (makeword (2, 2), & wsadata )! = 0)
{
Printf ("wsastartup () fail: % d/N", getlasterror ());
Return-1;
}
Openssl_add_ssl_algorithms ();/* initialize and load the algorithm */
Ssl_load_error_strings ();/* load error information to prepare for printing debugging information */
Meth = tlsv1_client_method ();/* specify the protocol used here (SSLv2/SSLv3/tlsv1 */
CTX = ssl_ctx_new (METH );
Chk_null (CTX );
Ssl_ctx_set_verify (CTX, ssl_verify_peer, null);/* Verify the peer */
Ssl_ctx_load_verify_locations (CTX, cacert, null);/* If verified, place the CA certificate */
// Load your own certificate client. CRT
If (ssl_ctx_use_certificate_file (CTX, certf, ssl_filetype_pem) <= 0)
{
Err_print_errors_fp (stderr );
Exit (-2 );
}
// Load your own key file client. Key
If (ssl_ctx_use_privatekey_file (CTX, keyf, ssl_filetype_pem) <= 0)
{
Err_print_errors_fp (stderr );
Exit (-3 );
}
// Verify that the key is paired with the certificate
If (! Ssl_ctx_check_private_key (CTX ))
{
Printf ("private key does not match the certificate Public Key/N ");
Exit (-4 );
}
/* Create a random number generation mechanism, required by the Win32 platform */
Srand (unsigned) Time (null); // seed by Time
For (INT I = 0; I <100; I ++)
{
Seed_int [I] = rand ();
}
Rand_seed (seed_int, sizeof (seed_int ));
/* The following is the normal TCP socket establishment process .............................. */
Printf ("begin TCP socket.../N ");
SD = socket (af_inet, sock_stream, 0); chk_err (SD, "socket ");
Memset (& SA, '/0', sizeof (SA ));
SA. sin_family = af_inet;
SA. sin_addr.s_addr = inet_addr (server_addr);/* Server IP */
SA. sin_port = htons (port);/* server port number */
Err = connect (SD, (struct sockaddr *) & SA, sizeof (SA ));
Chk_err (ERR, "Connect ");
/* The TCP connection has been established and the SSL handshake process starts ..........................*/
Printf ("begin SSL negotiation N ");
SSL = ssl_new (CTX); // create an SSL
Chk_null (SSL );
Ssl_set_fd (SSL, SD); // associate SSL with socket
Err = ssl_connect (SSL); // use SSL to connect to the server
Chk_ssl (ERR );
/* Print information of all encryption algorithms (optional )*/
Printf ("SSL connection using % Sn", ssl_get_cipher (SSL ));
/* Obtain the server certificate and print some information (optional )*/
Server_cert = ssl_get_peer_certificate (SSL );
Chk_null (server_cert );
Printf ("server certificate:/N ");
STR = x509_name_oneline (x509_get_subject_name (server_cert), 0, 0 );
Chk_null (STR );
Printf ("t subject: % Sn", STR );
Free (STR );
STR = x509_name_oneline (x509_get_issuer_name (server_cert), 0, 0 );
Chk_null (STR );
Printf ("t issuer: % Sn", STR );
Free (STR );
X509_free (server_cert);/* release the certificate if not required */
/* Start data exchange. Use ssl_write and ssl_read to replace write and read */
Printf ("begin SSL data exchangen ");
// Send a message
Err = ssl_write (SSL, "Hello world! ", Strlen (" Hello world! "));
Chk_ssl (ERR );
// Receives the message
Err = ssl_read (SSL, Buf, sizeof (BUF)-1 );
Chk_ssl (ERR );
Buf [err] = '/0 ';
Printf ("got % d chars: '% s' N", err, Buf );
Ssl_shutdown (SSL);/* Send SSL/TLS close_notify */
/* Close the work */
Shutdown (SD, 2 );
Ssl_free (SSL );
Ssl_ctx_free (CTX );
Return 0;
}
/*************************************** **************************************** ********
* SSL/TLS server Win32 (based on demos/server. cpp)
* The dynamic Connection Library libeay32.dll and ssleay. dll must be used,
* Add ws2_32.lib libeay32.lib ssleay32.lib to setting,
* The above library files can be found in the out32dll directory after OpenSSL is compiled,
* For the required certificate files, see <generate a certificate file using OpenSSL>.
**************************************** **************************************** *******/
# Include <stdio. h>
# Include <stdlib. h>
# Include <memory. h>
# Include <errno. h>
# Include <sys/types. h>
# Include <winsock2.h>
# Include "OpenSSL/RSA. H"
# Include "OpenSSL/crypto. H"
# Include "OpenSSL/x509.h"
# Include "OpenSSL/PEM. H"
# Include "OpenSSL/SSL. H"
# Include "OpenSSL/err. H"
/* All required parameter information is provided here in the form of # define */
# Define certf "server. CRT"/* server certificate (CA signature required )*/
# Define keyf "server. Key"/* private key of the server (encrypted storage is recommended )*/
# Define cacert "ca. CRT"/* CA certificate */
# Define Port 1111/* prepare the bound port */
# Define chk_null (x) if (x) = NULL) {exit (1 );}
# Define chk_err (ERR, S) if (ERR) =-1) {perror (s); exit (1 );}
# Define chk_ssl (ERR) if (ERR) =-1) {err_print_errors_fp (stderr); exit (2 );}
Int main ()
{
Int err;
Int listen_sd;
Int SD;
Struct sockaddr_in sa_serv;
Struct sockaddr_in sa_cli;
Int client_len;
Ssl_ctx * CTX;
SSL * SSL;
X509 * client_cert;
Char * STR;
Char Buf [4096];
Ssl_method * meth;
Wsadata;
If (wsastartup (makeword (2, 2), & wsadata )! = 0)
{
Printf ("wsastartup () fail: % DN", getlasterror ());
Return-1;
}
Ssl_load_error_strings ();/* prepare for printing debugging information */
Openssl_add_ssl_algorithms ();/* initialize and load the algorithm */
Meth = tlsv1_server_method ();/* specify the protocol used here (SSLv2/SSLv3/tlsv1 */
CTX = ssl_ctx_new (METH );
Chk_null (CTX );
Ssl_ctx_set_verify (CTX, ssl_verify_peer, null);/* Verify or not */
Ssl_ctx_load_verify_locations (CTX, cacert, null);/* If verified, place the CA certificate */
// Load your certificate file
If (ssl_ctx_use_certificate_file (CTX, certf, ssl_filetype_pem) <= 0)
{
Err_print_errors_fp (stderr );
Exit (3 );
}
// Load your own key file
If (ssl_ctx_use_privatekey_file (CTX, keyf, ssl_filetype_pem) <= 0)
{
Err_print_errors_fp (stderr );
Exit (4 );
}
// Verify
If (! Ssl_ctx_check_private_key (CTX ))
{
Printf ("private key does not match the certificate Public Key/N ");
Exit (5 );
}
// Select secure communication protocol
Ssl_ctx_set_cipher_list (CTX, "RC4-MD5 ");
/* Start the normal TCP socket process ................................. */
Printf ("begin TCP socket.../N ");
Listen_sd = socket (af_inet, sock_stream, 0 );
Chk_err (listen_sd, "socket ");
Memset (& sa_serv, '/0', sizeof (sa_serv ));
Sa_serv.sin_family = af_inet;
Sa_serv.sin_addr.s_addr = inaddr_any;
Sa_serv.sin_port = htons (port );
Err = BIND (listen_sd, (struct sockaddr *) & sa_serv,
Sizeof (sa_serv ));
Chk_err (ERR, "bind ");
/* Accept TCP links */
Err = listen (listen_sd, 5 );
Chk_err (ERR, "listen ");
Client_len = sizeof (sa_cli );
SD = accept (listen_sd, (struct sockaddr *) & sa_cli, & client_len );
Chk_err (SD, "accept ");
Closesocket (listen_sd );
Printf ("connection from % lx, port % x/N ",
Sa_cli.sin_addr.s_addr, sa_cli.sin_port );
/* The TCP connection has been established to perform the SSL process on the server ......................*/
Printf ("begin server side SSL/N ");
SSL = ssl_new (CTX );
Chk_null (SSL );
Ssl_set_fd (SSL, SD );
Err = ssl_accept (SSL );
Printf ("ssl_accept finishedn ");
Chk_ssl (ERR );
/* Print information of all encryption algorithms (optional )*/
Printf ("SSL connection using % s/n", ssl_get_cipher (SSL ));
/* Obtain the client certificate and print some information (optional )*/
Client_cert = ssl_get_peer_certificate (SSL );
If (client_cert! = NULL)
{
Printf ("client certificate:/N ");
STR = x509_name_oneline (x509_get_subject_name (client_cert), 0, 0 );
Chk_null (STR );
Printf ("t subject: % s/n", STR );
Free (STR );
STR = x509_name_oneline (x509_get_issuer_name (client_cert), 0, 0 );
Chk_null (STR );
Printf ("t issuer: % s/n", STR );
Free (STR );
X509_free (client_cert);/* release the certificate if not required */
}
Else
{
Printf ("client does not have certificate./N ");
}
/* Start data exchange. Use ssl_write and ssl_read to replace write and read */
Err = ssl_read (SSL, Buf, sizeof (BUF)-1 );
Chk_ssl (ERR );
Buf [err] = '/0 ';
Printf ("got % d chars: '% s'/N", err, Buf );
Err = ssl_write (SSL, "I hear you.", strlen ("I hear you ."));
Chk_ssl (ERR );
/* Close the work */
Shutdown (SD, 2 );
Ssl_free (SSL );
Ssl_ctx_free (CTX );
Return 0;
}
// Download the OpenSSL library. For more information, see <compile and install the OpenSSL library>;
// Use the OpenSSL library to generate a certificate file. For more information, see <generate a certificate file using OpenSSL>.
// Common APIs <APIs frequently used to write SSL communication programs using OpenSSL>.