Use OpenSSL to establish SSL Secure Communication (C/S)

Source: Internet
Author: User
Tags openssl library ssl connection htons

/*************************************** **************************************** ***********
* 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>.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.