An Introduction to OpenSSL Programming, Part II of II
Automatic rehandshake support is built into SSL_read(), so the client doesn't have to do anything explicit to enable rehandshake. However, this doesn't necessarily mean that arbitrary clients will work. In particular, the client must be prepared to handle the SSL_ERROR_WANT_READ return value from SSL_read(). Ordinarily, if the client is using blocking I/O--as we are in wclient2--SSL_read() would never return this error. However, it's required if rehandshaking occurs.
To see why this is, imagine that your client uses select() to determine when there is data available from the server. When select() returns, you call SSL_read(). If the server is requesting rehandshake, however, the data will be a HelloRequest message. SSL_read() consumes the message and performs the handshake. There's no guarantee that there will be any more data available on the socket, so SSL_read() needs to return without any data--hence the SSL_ERROR_WANT_READ return value.
Our original wclient program, despite functioning properly in every other respect, broke utterly when dealing with rehandshake, thereby proving once again that if you haven't tested some feature, it almost certainly doesn't work. The fix in wclient2 is to change the read loop that is shown in Listing 5.
Listing 5. New Client Read Loop with Rehandshake Support
48 /* Now read the server's response, assuming
49 that it's terminated by a close */
50 while(1){
51 r=SSL_read(ssl,buf,BUFSIZZ);
52 switch(SSL_get_error(ssl,r)){
53 case SSL_ERROR_NONE:
54 len=r;
55 break;
56 case SSL_ERROR_WANT_READ:
57 continue;
58 case SSL_ERROR_ZERO_RETURN:
59 goto shutdown;
60 case SSL_ERROR_SYSCALL:
61 fprintf(stderr,
62 "SSL Error: Premature close\n");
63 goto done;
64 default:
65 berr_exit("SSL read problem");
66 }
67
68 fwrite(buf,1,len,stdout);
69 }
Since this is an HTTP client and it's already written the request, there's no need to wonder if there is data coming from the server. The next traffic on the wire will always be the server's response. Thus, we don't need to select() on the socket. If we get SSL_ERROR_WANT_READ, we just go back to the top of the loop and call SSL_read() again.
When using client authentication it's important to understand what it does and doesn't provide. So far, all the server knows is that the client possessed the private key corresponding to some valid certificate. In some cases this might be enough, but in most cases the server wants to know who the client is in order to make authorization decisions.
Checking the client's certificate is roughly similar to the check_cert() function we used to check the server's identity. The server would extract the client's name from the certificate and check it against some access control list. If the name is on the list, the client will be accorded the appropriate privileges. Otherwise, access will be denied.
SSL offers a multiplicity of cryptographic algorithms. Since they are not equally strong and fast, users often want to choose one algorithm over another. By default, OpenSSL supports a broad variety of ciphers; however, it provides an API for restricting the cipher that it will negotiate. We expose this functionality in wclient2 and wserver2 with the -a flag.
To use the -a flag, the user provides a colon-separated list of ciphers, as in -a RC4-SHA:DEC-CBC3-SHA:DES-CBC- SHA. This string is then passed to OpenSSL via the SSL_CTX_set_cipher_list() function, as shown in Listing 6.
Listing 6. Setting the Cipher List
126 /* Set our cipher list */
127 if(ciphers){
128 SSL_CTX_set_cipher_list(ctx,ciphers);
129 }
You can get a list of all the algorithms that OpenSSL supports using the openssl command. Try openssl ciphers. Also, you might want to try using the -a flag with both client and server. Verify for yourself that if you use the same cipher (or have the same one on both lists) things work and, otherwise, the connection fails.
Our wclient program is just about the most trivial client program possible because the I/O semantics are so simple. The client always writes everything it has to write, and then reads everything that the server has to read. Reads and writes are never interlaced, and the client just stops and waits for data from the server. This works fine for simple applications, but there are many situations in which it's unacceptable. One such application is a remote login client.
A remote login client such as Telnet or ssh needs to process at least two sources of input: the keyboard and the network. Input from the keyboard and the server can appear asynchronously. That is to say they can appear in any order. This means that the read/write type I/O discipline that we had in wclient is fundamentally inadequate.
It's easy to see this. Consider an I/O discipline analogous to the one we used in wclient, represented by the pseudo-code in Listing 7.
Listing 7. A Broken Client I/O Discipline
1 while(1){
2 read(keyboard,buffer);
3 write(server,buffer);
4 read(server,buffer);
5 write(screen,buffer);
6 }
Consider the case in which you're remotely logged into some machine and request a directory listing. Your request is a single line (ls on UNIX boxes) but the response is a large number of lines. In general, these lines will be written in more than one write. Thus, it may very well take more than one read in order to read them from the server. However, if we use the I/O discipline in Listing 7, we'll run into a problem.
We read the command from the user and the first chunk of the server's response, but after that we get deadlocked. The client is waiting in line 2 for the user to type something, but the user is waiting for the rest of the directory listing. We're deadlocked. In order to break the deadlock, we need some way to know when either the keyboard or the network is ready to read. We can then service that source of input and keep from deadlocking. Conveniently, Linux provides us with a call that does exactly that-- select(2). select() is the standard tool for doing multiplexed I/O. It lets you determine whether any of a set of sockets is ready to read or write. If you're not familiar with it already, read the man page or consult Richard Stevens's fine book Advanced Programming in the UNIX Environment (Addison-Wesley 1992).
Unfortunately, although select() is a common UNIX idiom, its use with OpenSSL is far from clean and requires understanding of some subtleties of SSL. In order to demonstrate them, we present a new program, sclient. sclient is a simple model of an SSLized remote access client. It connects to the server and then transfers anything typed at the keyboard to the server, and anything sent from the server to the screen.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- seo services in india
2 hours 58 min ago - For KDE install kio-mtp
2 hours 59 min ago - Evernote is much more...
4 hours 59 min ago - Reply to comment | Linux Journal
13 hours 44 min ago - Dynamic DNS
14 hours 18 min ago - Reply to comment | Linux Journal
15 hours 17 min ago - Reply to comment | Linux Journal
16 hours 7 min ago - Not free anymore
20 hours 9 min ago - Great
23 hours 56 min ago - Reply to comment | Linux Journal
1 day 4 min ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?



Comments
Block socket with SSL_MODE_AUTO_RETRY
If I use block socket with SSL_MODE_AUTO_RETRY
The flag SSL_MODE_AUTO_RETRY will cause read/write operations to only return after the handshake and successful completion.
Do I have to handle the retrying in SSL_Read and SSL_Write? Isn't it easier to do this way? I know it hurts throughput a little, but is it a big deal?