Building.Open.Source.Network.Security.Tools.Components.And.Techniques [Electronic resources] نسخه متنی

This is a Digital Library

With over 100,000 free electronic resource in Persian, Arabic and English

Building.Open.Source.Network.Security.Tools.Components.And.Techniques [Electronic resources] - نسخه متنی

Mike D. Schiffman

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Encryption

Encryption represents a powerful technique for protecting network communications. Through the proper use of encryption over networks, we can secure sensitive data while in transit and protect control channels from compromise. First, we can use encryption to authenticate the party with whom we communicate over the network through the use of public key signatures or shared private keys. Second, we can hide the data communicated from all but the intended recipients when encrypted appropriately. Proper authentication, integrity of communication, and confidentiality of communication goes a long way toward achieving our objective of a functionally secure network. In essence, it immunizes our networks from many of the maladies that could plague it.


Encryption across the Network


We fully realize the utility of encryption, while considerable in a local context as we saw in Chapter 7, when we implement it across the network. We can build secure communications channels for data as well as commands by using this technique. As we saw in Chapter 7, we can use the OpenSSL component to build all sorts of wondrous encryption constructs, including SSL-based communications. SSL is so useful because it is a set of protocols that the Internet Engineering Task Force (IETF) has standardized, and almost every Web browser and Web server available supports it. You can also use SSL independently of the Web, making it even more powerful.

The following code comes from a real system that securely sends XML-formatted information over a network. The hardest part of using the OpenSSL library to create an SSL session is the initialization of the library and the context structure used to manage the session and its attributes. The code shown includes all the basic elements of initializing the library, setting up the session context, loading the client public key certificate, and sending data securely over SSL:


#include "rand.h"
#include "pkcsl2.h"
#include "ssl.h"
/* global variables for SSL implementation */
static BIO *bio = NULL, *bio_out= NULL, *bio_err= NULL;
static SSL *ssl = NULL;
static SSL_CTX *ssl_ctx= NULL;
static X509 *x509= NULL;
int HTTPSCoiranlnit(const char *clientCert, const char *password)
{
char randbuf[60];

Start by initializing the library and creating basic input/output descriptors:


/* initialize the library */
SSL_library_init();
/* Create a BIO for stdout and stderr */
bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

Next, we load the OpenSSL error text strings so that any errors will be reported with a higher verbosity:


SSL_load_error_strings();

Create the SSL context structure operating in the default SSL version 3 in SSL version 2 header mode in order to maximize the number of servers to which we can connect:


if ((ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
{
return (0);
}

OpenSSL has reasonable documentation, but there is little discussion about how, when, and where to initialize the random number generator in the OpenSSL library. This factor is a critical aspect of using OpenSSL successfully—one that we must handle with rare in order to achieve the expected level of security that SSL provides. The following code reads enough data from the best system-supplied entropy source to fill randbuf:


fread(randbuf, 1, sizeof(randbuf), fopenf"/dev/srand", "r"));
RAND_seed((const void*)randbuf, sizeof(randbuf));

Enable all of the vendor bug compatibility options and set the cipher list, which you should choose carefully to meet the security needs of your application:


SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL);
SSL_CTX_set_cipher_list(ssl_ctx, "DEFAULT:!EXP");
Create a new SSL structure:
if ((ssl = SSL_new(ssl_ctx)) == NULL)
{
return (0);
}

An SSL exists, but which side of the protocol are we doing? If we call SSL_connect () or SSL_accept (), the side of the connection is implied. In this case, however, we will call SSL_do_handshake (), which requires the "client/server side" flag to be set. SSL_set_connect_state () sets the SSL connection to do the connect side of the protocol on the SSL_do_hand-shake () (SSL_set_accept_state () would set it up to perform a server-side accept):


SSL_set_connect_state(ssl);

Set up the verification callback, which is where you will put your code to check the validity of the certificate provided by the other side of the SSL connection (this action is important to protect against a number of issues, including man-in-the-middle and DNS redirection attacks):


SSL_set_verify(ssl, SSL_VERIFY_NONE, verification_callback);

Next, load the Public Key Cryptography Standard Number 12 (PKCS#12) client certificate:


if (clientCert)
{
FILE *pkcs12fp = NULL;
PKCS12 *pkcs12 = NULL;
EVP_PKEY *pkey = NULL;
X509 *cert = NULL;
/* initialize the PKCS12 library crypto stuff */
PKCS12_PBE_add();
/* PKCS#12 cert handling here */
if ((pkcs12fp = fopen(clientCert, "r")) == NULL)
{
return (0);
}
/* read the PKCS12 structure in from disk */
if ((pkcs12 = d2i_PKCS12_fp(pkcs12fp, NULL)) == NULL)
{
fclose(pkcs12fp);
return (0);
}
/* use password to decrypt client cert */
if (PKCS12_parse(pkcsl2, password, &pkey, &cert, NULL) == 0)
{
fclose(pkcs12fp);
PKCS12_free(pkcsl2);
return (0);
}

Bind the client certificate and private key from the PKCS#12 structure to the SSL session for future use:


if (SSL_use_certificate(ssl, cert) == 1)
{
if (!SSL_use_PrivateKey(ssl, pkey))
{
fclose(pkcs12fp);
PKCS12_free(pkcs12);
return (0);
}
else if (!SSL_check_private_key(ssl))
{
fclose(pkcs12fp);
PKCS12_free(pkcs12);
return (0);
}
}
/* clean up */
fclose(pkcs12fp);
PKCS12_free(pkcs12);
}
/* always reset the SSL state machine */
SSL_set_connect_state(ssl);
return (1);
}

After you complete this initialization, you can use the following code snippet to connect to the server and send encrypted data over the network. The function takes three arguments: a pointer to the data to send, the size of the data in bytes, and an ASCII string specifying the host name and port, separated with a colon, to which we will send the data:


int send_data(void *user_data, unsigned int size, char *host_port)
{
int result = 0;
BIO bio;

Create a BIO instance that is a socket connection to the server with which we want to communicate. This connection is not actually created until the SSL handshake is initiated:


bio = BIO_new_connect(host_port);
if (bio == NULL)
{
return (ERR_UNKNOWN);
}
SSL_set_bio(ssl, bio, bio);
while (!done)
{

Here is where we initiate the state machine and begin the connection process to the other end:


i = S S L_do_hands hake(ssl);
switch (SSL_get_error(ssl, i))
{

If SSL_get_error () returns SSL_ERROR_NONE, we are done with connection establishment and can proceed to write the data:


case SSL_ERROR_NONE:
done = 1;
break;

If SSL_get_error () returns SSL_ERROR_SSL or SSL_ERROR_SYSCALL, there was an unrecoverable error in the handshaking process. Return with the proper error code:


case SSL_ERROR_SYSCALL:
case SSL_ERROR_SSL:
return (ERR_NO_CONNECTION);

If SSL_get_error () returns SSL_ERROR_ZERO_RETURN, a read() or write () system call failed-usually because the socket closed for some reason. In any event, the protocol failed:


case SSL_ERROR_ZERO_RETURN:
return (ERR_BROKEN_CONNECTION);

If SSL_get_error () returns any of the following, we keep at it:


case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_CONNECT:
default:
break;
}
}

If we get here, it is time to write data through our newly built SSL tunnel:


result = SSL_write(ssl, user_data, size);
if (result <= 0)
{
return (ERR_WRITE_FAILED);
}
}

/ 135