Use OpenSSL authentication mechanism to complete version control

Source: Internet
Author: User
Tags ssl connection

OpenSSL has powerful functions, such as seamless Io filtering, secure sockets, and data encryption and decryption, in fact, the certificate authentication function of OpenSSL can implement the version control function of the C/S Mode Program. The most important thing is that the certificate will be transmitted during the SSL handshake, many fields in the certificate can be customized. The server can obtain the client information by viewing the client certificate. On the contrary, the client can also obtain the server information through the server certificate, many people think this is a bit complicated. To achieve information intercommunication, you do not need to use SSL handshakes. The standard socket can be used. However, the purpose of using SSL is to make the communication more confidential, or, the process of using SSL is clear, and the handshake process of OpenSSL is very clear. We have considered a lot of things that we may not consider, and OpenSSL APIs are very rich, we can easily get enough information in a safe, stable environment!

The simplest version control is to use a global variable on the control end. This variable can be of the int type, and each bit of it represents a function, during program initialization, the server performs an SSL handshake with the client as the control end, during which the server passes the certificate to the control end, the control end can obtain the global version control variable based on the content of the server certificate, and then parse the variable to obtain the functions that the program can use, or the process can be reversed, the client passes the certificate to the server. The server verifies the client certificate to determine which services are provided or performs two-way authentication between the server and the client. The following is an actual example. First, let's take a look at the server's rough code:

# Include "stdafx. H"

# Include "server_verify.h"

DWORD winapi verifyproc (lpvoid lpparam );

Int isvalidcert (char * strcertpath) // this function is used as a callback function to implement an internal authentication policy. Here we only provide a simple example.

{

X509 * server_cert = NULL;

Char * STR;

Bio * pbio = bio_new_file (const char *) strcertpath, "R ");

If (pbio = NULL)

{

Return 0;
}
Server_cert = pem_read_bio_x509 (pbio, null );
If (server_cert = NULL)
{
Return 0;
}
STR = x509_name_oneline (x509_get_subject_name (server_cert), 0, 0 );
If (STR = NULL)
{
X509_free (server_cert );
Return 0;
}
Char * sub = strstr (STR, "cn = ");
Int Len = 0;
For (LEN = 0; (char) * (sub + Len )! = '/'; Len ++ );
Sub [Len] = 0;
Sub = sub + 3;
Int sublen = strlen (sub );
For (; (char) * (sub + sublen )! = ')'; Sublen --);
If (sublen {
X509_free (server_cert );
Return 0;
}
For (LEN = sublen-1 ;'('! = * (Sub + Len) & Len! = 0; Len --);
If (LEN {

X509_free (server_cert );
Return 0;

}

Sub [sublen-1] = 0;

Sub = sub + Len + 1;

// Obtain the version information in the SSL Certificate

Int nversion = atoi (sub );

Openssl_free (STR );
X509_free (server_cert );
Return 1;
}
Cserververify: cserververify (void)
{
G_hlistenthread = NULL;
M_soserver = invalid_socket;
M_serverip = _ T ("");
M_bexit = false;
}
Int cserververify: startlisten (const char * lpszserverip, int nport, hwnd hmsgrevwnd)
{
M_serverip = (cstring) lpszserverip;
M_port = nport;
M_meth = sslv23_server_method ();
M_ctx = ssl_ctx_new (m_meth );
Char szfilepath [_ max_path];
: Getmodulefilenamea (null, szfilepath, sizeof (szfilepath ));
... // Obtain the full path of the Certificate file in szfilepath
If (ssl_ctx_use_certificate_file (m_ctx, szfilepath, ssl_filetype_pem )! = 1 ){
... // Error handling of Version Information
}
Int server_id; // This server_id represents the logic verified by the server itself. To verify the client certificate, your certificate must pass the verification first.
If (! Isvalidcert_server [ID] (szfilepath) // verify whether the certificate is legal. The legal certificate must comply with the company's authentication policies
{
... // Handle invalid Certificate Errors
}
... // The full path to the key file in szfilepath
If (ssl_ctx_use_privatekey_file (m_ctx, szfilepath, ssl_filetype_pem )! = 1 ){
... // Handle errors that do not match the key file and Certificate
}
M_soserver = socket (af_inet, sock_stream, ipproto_tcp );
... // Handle errors caused by socket Creation
... // Socket parameter settings, using IOCTL
... // Socket binding, bind
... // Socket listening, using listen
DWORD dwthreadid = 0;
G_hlistenthread = createthread (null, 0, verifyproc, (lpvoid) This, 0, & dwthreadid );
Return (INT) m_soserver;
}
Int cserververify: stoplisten ()
{
... // Stop the authentication service thread and reset the socket
Return 0;
}
SSL * initnewsslsession (socket SD, cserververify * pserver)
{
SSL * SSL = NULL;
Int err;
SSL = ssl_new (pserver-> m_ctx );
... // When an error occurs, set SSL to null and return SSL
Ssl_set_fd (SSL, SD );
Err = ssl_accept (SSL );
... // Set SSL to null when an error occurs
Return SSL;
}
DWORD winapi verifyproc (lpvoid lpparam)
{
Cserververify * pserver = (cserververify *) lpparam;
Socket soserver = pserver-> m_soserver;
Fd_set fsread;
Fd_zero (& fsread );
Fd_set (soserver, & fsread );
While (! Pserver-> m_bexit)
{
Int nselectres = select (0, & fsread, null );
... // Select error handling
If (fd_isset (soserver, & fsread ))
{
Struct sockaddr_in saddrclient;
Size_t szaddress = sizeof (saddrclient );
Socket clientsd = accept (soserver, (sockaddr *) & saddrclient, (int *) & szaddress );
... // Accept error handling
Int mode = 0;
Ioctlsocket (clientsd, fionbio, (u_long far *) & mode );
SSL * SSL = initnewsslsession (clientsd, pserver );
Int client_id; // This ID indicates the authentication policy ID. Obtained through the standard socket Recv, client verification is required immediately
// The following callback function for implementing the authentication policy should be called. When each client connects to the server, it will tell the server which authentication policy to use. All authentication policies are registered on the server.
If (! Isvalidcert_server [client_id] (...)
{
... // The certificate cannot be processed out of date. For example, if a message is sent to the client, it is notified that the client is about to be unavailable.
}
If (SSL) // because only this SSL is required to recognize the service, there is no need to exist after authentication is completed, so release
{
... // Release SSL, disable Client socket
}
}
}
Return 2009;
}
The client code is as follows:
# Include "stdafx. H"
# Include "client_verify.h"
# Pragma comment (Lib, "libeay32 ")
# Pragma comment (Lib, "ssleay32 ")
Unsigned int g_icertcode = 0; // global authentication information, Version Control Reference Field
Int getcertcode (SSL * SSL)
{
X509 * server_cert = NULL;
Char * STR;
Server_cert = ssl_get_peer_certificate (SSL );
If (server_cert = NULL)
{
Return 0;
}
STR = x509_name_oneline (x509_get_subject_name (server_cert), 0, 0 );
... // Null Pointer Error Handling
Char * sub = strstr (STR, "cn = ");
Int Len = 0;
For (LEN = 0; (char) * (sub + Len )! = '/'; Len ++ );
Sub [Len] = 0;
Sub = sub + 3;
Int sublen = strlen (sub );
For (; (char) * (sub + sublen )! = ')'; Sublen --);
If (sublen {
X509_free (server_cert );
Return 0;
}
For (LEN = sublen-1 ;'('! = * (Sub + Len) & Len! = 0; Len --);
If (LEN {
X509_free (server_cert );
Return 0;
}
Sub [sublen-1] = 0;
Sub = sub + Len + 1;
G_icertcode = atoi (sub); // obtain the global version control information, which is the ultimate goal.
Openssl_free (STR );
X509_free (server_cert );
Return 1;
}
Cclientverify: cclientverify (void)
{
Ssleay_add_ssl_algorithms ();
Ssl_load_error_strings ();
M_soclient = invalid_socket;
M_clientssl = NULL;
M_clientmeth = sslv23_client_method ();
}
Socket cclientverify: connecttoserver (sockaddr_in sdserver)
{
Socket soclient = socket (af_inet, sock_stream, ipproto_tcp );
... // Handle socket creation errors
If (connect (soclient, (sockaddr *) & sdserver, sizeof (sdserver) = socket_error)
... // Standard socket connection error handling
M_clientmeth = sslv23_client_method ();
M_clientctx = ssl_ctx_new (m_clientmeth );
... // Obtain the full path of the root certificate
Int Re = ssl_ctx_load_verify_locations (m_clientctx, szfilepath ,".");
... // Get error handling for root certificate, for example, root certificate does not exist
SSL * SSL = ssl_new (m_clientctx );
Ssl_set_fd (SSL, soclient );
Int err = ssl_connect (SSL );
... // Handle SSL connection errors
Int vres = ssl_get_verify_result (SSL );
If (vres! = X509_v_ OK)
{
... // Handle errors that fail SSL verification, such as exiting the process
}
If (! Getcertcode (SSL) // This function should also be a callback function, which is determined through negotiation between the server and the client.
{
... // Handle errors that fail custom verification, such as exiting the process
}
... // Save SSL and other user-defined operations
Return soclient;
}

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.