[Net-ssleay-devel] OO Net::SSLeay API - before and after

Mike McCauley mikem at open.com.au
Wed Sep 9 07:59:16 UTC 2009


Hi Sam,

this seems reasonable to me provided it doesnt compromise the non-OO side.

Other views?



On Wednesday 09 September 2009 05:06:55 pm Sam Vilain wrote:
> Here's something I'm working on.  It's very small and simple, and so
> could potentially be included in the Net::SSLeay distribution.
>
> Code before:
>
> #!/usr/bin/perl -w
>
> use strict;
> use IO::Socket::INET;
> use IO::Socket::SSL;
> use FindBin qw($Bin);
> use IO::Select;
> use Sys::Hostname qw(hostname);
> use Data::Dumper;
>
> use Net::SSLeay qw(die_now die_if_ssl_error);
> Net::SSLeay::load_error_strings();
> Net::SSLeay::SSLeay_add_ssl_algorithms();
> Net::SSLeay::randomize();
> $Net::SSLeay::trace = 2;
>
> my $address = "localhost";
> my $port = 6700;
>
> $| = 1;
>
> if ( my $pid = fork() ) {
>     sleep 1;
>     # parent.  Connect to the child.
>     my $socket = IO::Socket::INET->new(
>         PeerAddr      => $address,
>         PeerPort      => $port,
>         Timeout => 3,
>         ) or die "socket connect failed; $!";
>
>     print "client: connected\n";
>
>     my $ctx;
>     $ctx = Net::SSLeay::CTX_new()
>         or die_now "CTX_new ($ctx) ($!)";
>     Net::SSLeay::CTX_set_default_passwd_cb($ctx, sub {'secr1t'});
>     #Net::SSLeay::set_options($ssl, &Net::SSLeay::OP_ALL)
>             #and die_if_ssl_error("ssl set options");
>     #Net::SSLeay::CTX_use_RSAPrivateKey_file
>             #($ctx, 'certs/client-key.pem',
>              #&Net::SSLeay::FILETYPE_PEM);
>     #die_if_ssl_error("private key");
>     #Net::SSLeay::CTX_use_certificate_file
>             #($ctx, 'certs/client-cert.pem',
>              #&Net::SSLeay::FILETYPE_PEM);
>     #die_if_ssl_error("certificate");
>     Net::SSLeay::set_cert_and_key(
>         $ctx, "$Bin/client-cert.pem",
>         "$Bin/client-key.pem") or die "key";
>     Net::SSLeay::CTX_load_verify_locations($ctx, '', $Bin)
>             or die_now("CTX load verify loc=`$Bin' $!");
>     Net::SSLeay::CTX_set_verify($ctx, &Net::SSLeay::VERIFY_PEER,sub{1});
>
>     my $ssl = Net::SSLeay::new($ctx);
>
>     Net::SSLeay::set_fd($ssl, fileno($socket));
>     my $res = Net::SSLeay::connect($ssl)
>         and die_if_ssl_error("ssl connect");
>     print "client: ssl open, cipher `"
>         . Net::SSLeay::get_cipher($ssl) . "'\n";
>     print "client: server cert: "
>         . Net::SSLeay::dump_peer_certificate($ssl);
>
>     $res =  Net::SSLeay::write($ssl, "Hello, SSL\n");
>     die_if_ssl_error("ssl write");
>     CORE::shutdown $socket, 1;
>     my $got = Net::SSLeay::read($ssl);
>     die_if_ssl_error("ssl read");
>     print $got;
>     Net::SSLeay::free ($ssl);
>     Net::SSLeay::CTX_free ($ctx);
>     close $socket;
>
>     print "client: waiting for child process\n";
>     wait;
> }
> elsif ( defined $pid ) {
>     $Net::SSLeay::trace = 3;
>     # child.  start the server.
>     my $sock = IO::Socket::INET->new(
>         LocalAddr => $address,
>         LocalPort => $port,
>         Listen => 2,
>         Reuse => 1,
>         Proto => "tcp",
>         ) or die $!;
>
>     print "server: listening on port $port\n";
>     my $client = $sock->accept();
>     print "server: accepted a socket\n";
>     my $ctx;
>     $ctx = Net::SSLeay::CTX_new()
>         or die_now "CTX_new ($ctx) ($!)";
>     Net::SSLeay::CTX_set_default_passwd_cb($ctx, sub {'secr1t'});
>     Net::SSLeay::set_cert_and_key(
>         $ctx, "$Bin/server-cert.pem",
>         "$Bin/server-key.pem") or die "key";
>     Net::SSLeay::CTX_load_verify_locations($ctx, '', $Bin)
>             or die_now("CTX load verify loc=`$Bin' $!");
>     Net::SSLeay::CTX_set_verify($ctx, &Net::SSLeay::VERIFY_PEER,sub{
>                 my ($ok, $ctx_store) = @_;
>                 my ($certname,$cert,$error);
>                 if ($ctx_store) {
>                         $cert =
> Net::SSLeay::X509_STORE_CTX_get_current_cert($ctx_store);
>                         $error =
> Net::SSLeay::X509_STORE_CTX_get_error($ctx_store);
>                         $certname =
> Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_issuer_name($cert)).Ne
>t::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert));
> $error &&= Net::SSLeay::ERR_error_string($error); }
>                 print
> "verify_cb->($ok,$ctx_store,$certname,$error,$cert);\n";
>         1;
>     });
>
>     my $ssl = Net::SSLeay::new($ctx);
>
>     Net::SSLeay::set_fd($ssl, fileno($client));
>     my $res = Net::SSLeay::accept($ssl)
>         and die_if_ssl_error("ssl accept");
>     print "server: ssl open, cipher `"
>         . Net::SSLeay::get_cipher($ssl) . "'\n";
>     print "server: client cert: "
>         . Net::SSLeay::dump_peer_certificate($ssl);
>     my $s = IO::Select->new;
>     $s->add($client);
>     while ( $s->can_read ) {
>         my $data;
>         my $got = Net::SSLeay::ssl_read_all($ssl, 1024);
>         if ( length($got) == 0 ) {
>             last;
>         }
>         else {
>             print "server: read $got\n";
>         }
>     }
>     Net::SSLeay::free ($ssl);
>     Net::SSLeay::CTX_free ($ctx);
>     $client->shutdown(1);
> }
> else {
>   die "fork failed; $!";
> }
>
> Code after:
>
> #!/usr/bin/perl -w
>
> use strict;
> use IO::Socket::INET;
> use FindBin qw($Bin);
> use IO::Select;
> use Sys::Hostname qw(hostname);
> use Data::Dumper;
>
> use Net::SSLeay::Context;
> use Net::SSLeay::SSL;
> use Net::SSLeay::Constants qw(OP_ALL OP_NO_SSLv2 FILETYPE_PEM VERIFY_PEER);
>
> my $address = "localhost";
> my $port = 6700;
>
> $| = 1;
>
> if ( my $pid = fork() ) {
>     sleep 1;
>     # parent.  Connect to the child.
>     my $socket = IO::Socket::INET->new(
>         PeerAddr      => $address,
>         PeerPort      => $port,
>         Timeout => 3,
>         ) or die "socket connect failed; $!";
>
>     print "client: connected\n";
>
>     my $ctx = Net::SSLeay::Context->new;
>     $ctx->set_default_passwd_cb(sub {'secr1t'});
>     $ctx->set_options(OP_ALL && OP_NO_SSLv2);
>     $ctx->use_certificate_chain_file('certs/client-cert.pem');
>     $ctx->use_RSAPrivateKey_file('certs/client-key.pem', FILETYPE_PEM);
>     $ctx->load_verify_locations('', $Bin);
>     $ctx->set_verify(VERIFY_PEER);
>
>     my $ssl = Net::SSLeay::SSL->new(ctx => $ctx);
>
>     $ssl->set_fd(fileno($socket));
>     my $res = $ssl->connect();
>     print "client: ssl open, cipher `" . $ssl->get_cipher . "'\n";
>     print "client: server cert: " . $ssl->dump_peer_certificate;
>
>     $res =  $ssl->write($ssl, "Hello, SSL\n");
>     CORE::shutdown $socket, 1;
>     my $got = $ssl->read();
>     die_if_ssl_error("ssl read");
>     print $got;
>     undef($ssl);
>     close $socket;
>
>     print "client: waiting for child process\n";
>     wait;
> }
> elsif ( defined $pid ) {
>     # child.  start the server.
>     my $sock = IO::Socket::INET->new(
>         LocalAddr => $address,
>         LocalPort => $port,
>         Listen => 2,
>         Reuse => 1,
>         Proto => "tcp",
>         ) or die $!;
>
>     print "server: listening on port $port\n";
>     my $client = $sock->accept();
>     print "server: accepted a socket\n";
>     my $ctx;
>     $ctx = Net::SSLeay::Context->new();
>     $ctx->set_default_passwd_cb(sub{'secr1t'});
>     $ctx->use_certificate_chain_file('certs/server-cert.pem');
>     $ctx->use_RSAPrivateKey_file('certs/server-key.pem', FILETYPE_PEM);
>     $ctx->load_verify_locations('', $Bin);
>     $ctx->set_verify(
>         VERIFY_PEER, sub {
>             my ($ok, $ctx_store) = @_;
>             my ($certname,$cert,$error);
>             if ($ctx_store) {
>                 $cert = $ctx_store->get_current_cert;
>                 $error = $ctx_store->get_error;
>                 $certname = $cert->get_issuer_name->oneline
>                     . $cert->get_subject_name->oneline;
>                 $error &&= $error->error_string;
>             }
>             print "verify_cb->($ok,$ctx_store,$certname,$error,$cert);\n";
>             1;
>     });
>
>     my $ssl = Net::SSLeay::SSL->new(ctx => $ctx);
>
>     $ssl->set_fd(fileno($client));
>     my $res = $ssl->accept();
>     print "server: ssl open, cipher `" . $ssl->get_cipher . "'\n";
>     print "server: client cert: " . $ssl->dump_peer_certificate;
>     my $s = IO::Select->new;
>     $s->add($client);
>     while ( $s->can_read ) {
>         my $data;
>         my $got = $ssl->ssl_read_all(1024);
>         if ( length($got) == 0 ) {
>             last;
>         }
>         else {
>             print "server: read $got\n";
>         }
>     }
>     undef($ssl);
>     $client->shutdown(1);
> }
> else {
>   die "fork failed; $!";
> }
>
> I could release this as Net::OpenSSL, but I think it would potentially
> be a nice addition to Net::SSLeay proper; especially since it's a very
> simple metaprogramming hack.
>
> Ideas/comments?
>
> Sam
>
> _______________________________________________
> Net-ssleay-devel mailing list
> Net-ssleay-devel at lists.alioth.debian.org
> http://lists.alioth.debian.org/mailman/listinfo/net-ssleay-devel



-- 
Mike McCauley                               mikem at open.com.au
Open System Consultants Pty. Ltd
9 Bulbul Place Currumbin Waters QLD 4223 Australia   http://www.open.com.au
Phone +61 7 5598-7474                       Fax   +61 7 5598-7070

Radiator: the most portable, flexible and configurable RADIUS server 
anywhere. SQL, proxy, DBM, files, LDAP, NIS+, password, NT, Emerald, 
Platypus, Freeside, TACACS+, PAM, external, Active Directory, EAP, TLS, 
TTLS, PEAP, TNC, WiMAX, RSA, Vasco, Yubikey, DIAMETER etc. Full source
on Unix, Windows, MacOSX, Solaris, VMS, NetWare etc.



More information about the Net-ssleay-devel mailing list