[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