Net::SSLeay::OO - OO Calling Method for Net::SSLeay
use Net::SSLeay::OO; use Net::SSLeay::OO::Constants qw(OP_ALL OP_NO_TLSv2); my $ctx = Net::SSLeay::OO::Context->new; $ctx->set_options(OP_ALL & OP_NO_TLSv2); $ctx->load_verify_locations("", "/etc/ssl/certs"); # get a socket/stream somehow my $socket = IO::Socket::INET->new(...); # create a new SSL object, and attach it to the socket my $ssl = Net::SSLeay::OO::SSL->new(ctx => $ctx); $ssl->set_fd($socket); # initiate the SSL connection $ssl->connect; # exchange data ... be sure to read the man page my $wrote = $ssl->write($data, $size); my $bytes_read = $ssl->read(\$buf, $size); # close... $ssl->shutdown; $socket->shutdown(1);
This set of modules adds an OO calling convention to the Net::SSLeay module. It steers away from overly abstracting things, or adding new behaviour, instead just making the existing functionality easier to use.
What does this approach win you over Net::SSLeay?
For a start, you get a blessed object rather than an integer to work with, so you know what you are dealing with. All of the functions which were callable with
Net::SSLeay::foo($ssl, @args) will then be callable as plain
The OpenSSL functions use a C-style namespace convention, where functions are prefixed by the type of the object that they operate on. OpenSSL has several types of objects, such as a "Context" (this is a bit like a bunch of pre-defined connection settings), and various classes relating to X509, sessions, etc.
This module splits up the functions which Net::SSLeay binds into Perl based on the naming convention, then sets up wrappers for them so that you can just call methods on objects.
If an error is raised by the OpenSSL library, an exception is immediately raised (trappable via
eval) which pretty-prints into something presented a little less cryptic than OpenSSL's
:-delimited error string format.
This is currently more of a promise than a reality; but eventually each of the access methods for the various objects will be able to know their lifetime in a robust fashion, so you should get less segfaults. Eg, some SSL functions don't return object references which are guaranteed to last very long, so if you wait too long before getting properties from them you will get a segfault.
On the flip side, what does this approach win you over other simpler APIs such as IO::Socket::SSL? Well, I guess it comes down to "Make things as simple as possible, but no simpler".
Most SSL socket libraries tend to try to hide complexity from you, but there really are things that you should consider; such as, shouldn't you be validating the other end of your SSL connection has a valid certificate? Which SSL versions do you wish to allow?
IO::Socket::SSL lets you specify a lot of this stuff, but it's not a very earnest implementation; it's just treated as a few extra options passed to the constructor, a bit of magic at socket setup time, and then hope that this will be enough. The support for verifying client certificates didn't even work when I tested it.
On the other hand, using the OpenSSL API fully means you are taken through the stages of setup piece by piece. You can easily do things like check that your SSL configuration (eg server certificate) is valid before you start daemonize or start accepting real sockets.
I'll try to keep the documentation as complete as possible - there's nothing more annoying than thin wrapper libraries which don't help much people trying to use them. But in general, most functions available in the OpenSSL manual will be available.
This is a brief overview of the packages in this module, so that you know where to start.
The context object represents an individual configuration of the OpenSSL library. Normally, you'll create one of these as you verify the configuration of your program - eg for a server, setting the CA certificates directory, and setting various other bits and bobs.
You have one of these per connection, and when you create one it is tied to a Context object, taking defaults from the Context object. Many settings can be made either on the Context object or the SSL object. Once you have created this object, you attach it to a filehandle/socket and then call either
connect, depending on which SSL role you are playing in the connection.
This module allows you to explicitly import SSLeay/OpenSSL constants for passing to various API methods, so that you don't have to specify the complete namespace to them.
This class represents an error from OpenSSL, actually a stack of errors. These are raised and printed pretty transparently, but if you want to pick apart the details of the error you can do so. There is no corresponding C struct, but the
ERR_* man pages (try
man -k ERR_) handle the integers that OpenSSL passes around internally as error codes.
This class represents a certificate. You can't create these with this module, because of a lack of bindings in Net::SSLeay, but various things will return them.
Retrieving things like the "issuer name" from X509 certificates returns one of these objects; you can then call
->oneline on it, or print it to your requirements, to get a usable string.
This class represents a certificate store. This would normally represent a local directory with certificates in it. Currently the only way to get one of these is with "get_cert_store" in Net::SSLeay::OO::Context.
This is a type of object that you get back during certificate verification. You probably don't need to use this class unless you want certificate verification to fail based on custom rules during the actual handshake.
This seems to represent an actual SSL session; ie, after
connect has succeeded. This is a pretty uninteresting class. About all you can do with it is pull out or alter the time the SSL session was established, and session timeouts.
This is the internal class which splits up the functions in Net::SSLeay into class-specific packages.
These classes are currently all TO-DO. All I've done is earmarked these packages in Net::SSLeay::OO::Functions as recipients for the corresponding Net::SSLeay functions. There's not a lot of boilerplate that has to be implemented to make them work, take a look at some of the implementations of some of the X509 classes to see how short it can be. If you make them work, with a test suite, send them to me and I'll include them in this distribution.
Source code is available from Catalyst:
Please see the file SubmittingPatches for information on preferred submission format.
Suggested avenues for support:
Copyright 2009, NZ Registry Services. This module is licensed under the Artistic License v2.0, which permits relicensing under other Free Software licenses.
This software is not free; it is encumbered by various restrictions stemming from OpenSSL and Net::SSLeay. The bizarre copyright of Net::SSLeay states to be "under the same terms as OpenSSL", which is something of a GPL/Artistic/Perl license idiom. What it means is, if you make software based on Net::SSLeay, you have to acknowledge the OpenSSL team as below, even if you use it with a free rewrite of OpenSSL, or something. If you did that, the Net::SSLeay license will effectively compel you to lie. But that's pretty unlikely so let's just cut straight to the clauses.
This module and sub-classes which abstract the interface is almost certainly covered by these clauses:
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * firstname.lastname@example.org. * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project.
If you write a program which uses SSL sockets, and then you advertise it, even if SSL is like a small tick-box item and hardly relevant to the message you are putting across, heed the following license term:
* 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"