Crypt-HCE_SHA-0.70/0002755000175000017500000000000010031046015013507 5ustar ericeric00000000000000Crypt-HCE_SHA-0.70/examples/0002755000175000017500000000000010031046015015325 5ustar ericeric00000000000000Crypt-HCE_SHA-0.70/examples/HOW_TO_USE0000644000175000017500000000273207754540476017061 0ustar ericeric00000000000000Server side (who you are sending your request to) use Server; $server = Server->new(Server => name_of_host_to_bind_too, Port => port_number, Queue => size_of_queue, SKey => 'shaReDSEcrET'); LOOP: while ($ready_to_read = $server->accept()) { # wait for next connection @info = $server->recv(); # @info now contains all of the data sent from the client # already de-crypted # to send info back to the client $server->send("information", "to send", "back", "to" "client"); $server->close(); } additional notes: name_of_host_to_bind_too is usually the dns name assigned to the local box or ip address port_number for port's under 1024 you must be root to open size_of_queue is the amount of backlog before a requested connection is rejected Client Side (who you are sending your request from) use Client; $client = Client->new(Server => name_of_server_to_connect_to, Port => port_number, SKey => 'shaReDSEcrET'); $client->send("information", "to", "send", "to" "the server"); @response = $client->recv(); print "response = @response\n"; additional notes: the Client module closes the connection after doing a recv. So to have more than one exchange you need to issue a Client->new for each pair, or you can modify the Client->recv code } else { close ($self->{'Socket'}); # remove this line return @response; } if you modify the code you must close the socket yourself somewhere else close ($client->{'Socket'}); Crypt-HCE_SHA-0.70/examples/Client.pm0000644000175000017500000000560007754540476017134 0ustar ericeric00000000000000package Client; use IO::Select; use IO::Socket; use strict; use Carp; use Sys::Syslog; use Crypt::HCE_SHA; my @response; my $data; sub new { my $class = shift; my $self = {}; bless $self, $class; if ((scalar(@_) % 2) != 0) { croak "incorrect number of parameters"; } while (@_) { my $key = shift(@_); my $value = shift(@_); $self->{$key} = $value; } $self->_initialize; return $self; } sub _initialize { my $self = shift; my $timeout; if (!defined($self->{'Server'})) { croak "Client not initialized properly : Server parameter missing"; } if (!defined($self->{'Port'})) { croak "Client not initialized properly : Port parameter missing"; } if (!defined($self->{'SKey'})) { croak "Client not initialized properly : SKey parameter missing"; } if (!eval {$self->{'Socket'} = IO::Socket::INET->new(PeerAddr => $self->{'Server'}, PeerPort => $self->{'Port'}, Proto => 'tcp', Reuse => 1); }) { croak "Client couldn't establish a connection to $self->{'Server'}"; } $self->{'Socket'}->autoflush(1); srand($$|time()); # poor random generator should be replaced $self->{'RKey'} = rand(100000000)+1000000; $self->{'HCE'} = Crypt::HCE_SHA->new($self->{'SKey'}, $self->{'RKey'}); print { $self->{'Socket'} } "$self->{'RKey'}\n"; } sub send { my $self = shift; my @items = @_; my ($item, $enc_item); if (defined($self->{'HCE'})) { foreach $item (@items) { # syslog('debug','Client encode: %s',$item); $enc_item = $self->{'HCE'}->hce_block_encode_mime($item); # syslog('debug','Client sending: %s', $enc_item); print { $self->{'Socket'} } "$enc_item\n; } $enc_item = $self->{'HCE'}->hce_block_encode_mime("+END_OF_LIST"); print { $self->{'Socket'} } "$enc_item\n"; } else { foreach $item (@items) { # syslog('debug','Client sending: %s',$item); print { $self->{'Socket'} } "$item\n"; } print { $self->{'Socket'} } "+END_OF_LIST\n"; } return 0; } sub recv { my $self = shift; my $fh = $self->{'Socket'}; my ($data, $dec_data); if (defined($self->{'HCE'})) { $data = ""; undef(@response); while (<$fh>) { chomp; $data = 1; # syslog('debug','Client recv: %s', $_); $dec_data = $self->{'HCE'}->hce_block_decode_mime($_); # syslog('debug','Client decode: %s', $dec_data); last if ($dec_data eq "+END_OF_LIST"); push @response, $dec_data; }; if (!defined $data) { close ($self->{'Socket'}); return $data; } else { close ($self->{'Socket'}); return @response; }; } else { $data = ""; undef(@response); while (<$fh>) { chomp; $data = 1; push @response, $_; }; if (!defined $data) { close ($self->{'Socket'}); return $data; } else { close ($self->{'Socket'}); return @response; }; } } 1; __END__ #------- POD ------ Crypt-HCE_SHA-0.70/examples/Server.pm0000644000175000017500000000710307754540476017164 0ustar ericeric00000000000000package Server; use IO::Select; use IO::Socket; use strict; use Carp; use Sys::Syslog; use Crypt::HCE_SHA; my @response; my $data; sub new { my $class = shift; my $self = {}; bless $self, $class; if ((scalar(@_) % 2) != 0) { croak "incorrect number of parameters"; } while (@_) { my $key = shift(@_); my $value = shift(@_); $self->{$key} = $value; } $self->_initialize; return $self; } sub _initialize { my $self = shift; if (!defined($self->{'Server'})) { croak "Server not initialized properly : Server parameter missing"; } if (!defined($self->{'Port'})) { croak "Server not initialized properly : Port parameter missing"; } if (!defined($self->{'Queue'})) { croak "Server not initialized properly : Queue parameter missing"; } if (!eval {$self->{'Socket'} = IO::Socket::INET->new(LocalAddr => $self->{'Server'}, LocalPort => $self->{'Port'}, Proto => 'tcp', Reuse => 1, Listen => $self->{'Queue'} ); }) { croak "Server couldn't establish a port on $self->{'Server'}"; } $self->{'Socket'}->autoflush(1); delete $self->{'HCE'}; $self->{'Select'} = IO::Select->new($self->{'Socket'}); } sub accept { my $self = shift; my ($time) = @_; # how long to wait my (@ready_to_read, $size); @ready_to_read = $self->{'Select'}->can_read($time); $size = scalar(@ready_to_read); if ($size == 1) { $self->{'Connect'} = $self->{'Socket'}->accept; $self->{'Connect'}->autoflush(1); # don't buffer return messages } else { delete $self->{'Connect'}; } return $size; } sub close { my $self = shift; $self->{'Connect'}->close; delete $self->{'Connect'}; delete $self->{'HCE'}; return 0; } sub send { my $self = shift; my @items = @_; my ($item, $enc_item); if (!defined($self->{'Connect'})) { croak "No Connection established: did you accept?"; } if (defined($self->{'HCE'})) { foreach $item (@items) { # syslog('debug','Server encode: %s',$item); $enc_item = $self->{'HCE'}->hce_block_encode_mime($item); # syslog('debug','Server sending: %s', $enc_item); print { $self->{'Connect'} } "$enc_item\n"; } $enc_item = $self->{'HCE'}->hce_block_encode_mime("+END_OF_LIST"); print { $self->{'Connect'} } "$enc_item\n"; } else { foreach $item (@items) { # syslog('debug','Server sending: %s',$item); print { $self->{'Connect'} } "$item\n"; } } return 0; } sub recv { my $self = shift; my ($data, $dec_data, $fh); if (!defined($self->{'Connect'})) { croak "No Connection established: did you accept?"; } $fh = $self->{'Connect'}; undef(@response); if (!defined($self->{'SKey'})) { while (<$fh>) { chomp; # syslog('debug','Server recv: %s', $_); tr/\n\r\t//d; last if ($_ eq '+END_OF_LIST'); push @response, $_; }; if (!defined(@response)) { return; } else { return @response; } } if (defined($self->{'HCE'})) { while (<$fh>) { chomp; # syslog('debug','Server recv: %s',$_); $dec_data = $self->{'HCE'}->hce_block_decode_mime($_); $dec_data =~ tr/\n\r\t//d; # syslog('debug','Server decode: %s', $dec_data); last if ($dec_data eq "+END_OF_LIST"); push @response, $dec_data; }; if (!defined(@response)) { return; } else { return @response; }; } else { $_ = <$fh>; # get RKey chomp; $self->{'RKey'} = $_; $self->{'HCE'} = Crypt::HCE_SHA->new($self->{'SKey'}, $self->{'RKey'}); return $self->recv(); } } 1; __END__ #------- POD ------ Crypt-HCE_SHA-0.70/META.yml0000644000175000017500000000056610031046015014765 0ustar ericeric00000000000000# http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: Crypt-HCE_SHA version: 0.70 version_from: HCE_SHA.pm installdirs: site requires: Digest::SHA1: 0 MIME::Base64: 2 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.17 Crypt-HCE_SHA-0.70/test.pl0000644000175000017500000001774010031045723015037 0ustar ericeric00000000000000# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) BEGIN { $| = 1; print "1..4\n"; } END {print "not ok 1\n" unless $loaded;} use Crypt::HCE_SHA; $loaded = 1; print "ok 1\n"; ######################### End of black magic. # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 # of the test code): $text = "This is an example of some text that is long enough to verify that the bug was fixed. So if you see this message in its entirety then I guess it worked"; $hce_sha = Crypt::HCE_SHA->new("SharedSecret", "Random01,39j309ad"); $crypted = $hce_sha->hce_block_encrypt("Encrypt this information"); $info = $hce_sha->hce_block_decrypt($crypted); if ($info eq "Encrypt this information") { print "ok 2\n"; } else { print "not ok 2\n"; } $mime_crypted = $hce_sha->hce_block_encode_mime("Encrypt and Base64 this information"); $info = $hce_sha->hce_block_decode_mime($mime_crypted); if ($info eq "Encrypt and Base64 this information") { print "ok 3\n"; } else { print "not ok 3\n"; } $pid = fork(); if ($pid < 0) { die "Couldn't fork"; } if ($pid != 0) { $server = Server->new(Server => 0, Port => 5050, SKey => "SharedSecret", Queue => 1); $cons = $server->accept(5); if ($cons == 0) { die "accept timed out"; } @info = $server->recv(); $server->send(@info); wait; } else { sleep 3; $client = Client->new(Server => localhost, Port => 5050, SKey => "SharedSecret"); $client->send($text); @info_back = $client->recv(); if ($info_back[0] eq $text) { print "ok 4\n"; } else { print "not ok 4\n"; } exit 0; } package Server; use IO::Select; use IO::Socket; use strict; use Carp; #use HCE_SHA; my @response; my $data; sub new { my $class = shift; my $self = {}; bless $self, $class; if ((scalar(@_) % 2) != 0) { croak "incorrect number of parameters"; } while (@_) { my $key = shift(@_); my $value = shift(@_); $self->{$key} = $value; } $self->_initialize; return $self; } sub _initialize { my $self = shift; if (!defined($self->{'Server'})) { croak "Server not initialized properly : Server parameter missing"; } if (!defined($self->{'Port'})) { croak "Server not initialized properly : Port parameter missing"; } if (!defined($self->{'Queue'})) { croak "Server not initialized properly : Queue parameter missing"; } if (!eval {$self->{'Socket'} = IO::Socket::INET->new(LocalAddr => $self->{'Server'}, LocalPort => $self->{'Port'}, Proto => 'tcp', Reuse => 1, Listen => $self->{'Queue'} ); }) { croak "Server couldn't establish a port on $self->{'Server'}"; } $self->{'Socket'}->autoflush(1); delete $self->{'HCE'}; $self->{'Select'} = IO::Select->new($self->{'Socket'}); } sub accept { my $self = shift; my ($time) = @_; # how long to wait my (@ready_to_read, $size); @ready_to_read = $self->{'Select'}->can_read($time); $size = scalar(@ready_to_read); if ($size == 1) { $self->{'Connect'} = $self->{'Socket'}->accept; $self->{'Connect'}->autoflush(1); # don't buffer return messages } else { delete $self->{'Connect'}; } return $size; } sub close { my $self = shift; $self->{'Connect'}->close; delete $self->{'Connect'}; delete $self->{'HCE'}; return 0; } sub send { my $self = shift; my @items = @_; my ($item, $enc_item); if (!defined($self->{'Connect'})) { croak "No Connection established: did you accept?"; } if (defined($self->{'HCE'})) { foreach $item (@items) { print "Server encode: $item\n"; $enc_item = $self->{'HCE'}->hce_block_encode_mime($item); print "Server sending: $enc_item\n"; print { $self->{'Connect'} } "$enc_item\n"; } $enc_item = $self->{'HCE'}->hce_block_encode_mime("+END_OF_LIST"); print { $self->{'Connect'} } "$enc_item\n"; } else { foreach $item (@items) { print { $self->{'Connect'} } "$item\n"; } } return 0; } sub recv { my $self = shift; my ($data, $dec_data, $fh); if (!defined($self->{'Connect'})) { croak "No Connection established: did you accept?"; } $fh = $self->{'Connect'}; undef(@response); if (!defined($self->{'SKey'})) { while (<$fh>) { chomp; print "Server recv: $_\n"; tr/\n\r\t//d; last if ($_ eq '+END_OF_LIST'); push @response, $_; }; if (!defined(@response)) { return; } else { return @response; } } if (defined($self->{'HCE'})) { while (<$fh>) { chomp; print "Server recv: $_\n"; $dec_data = $self->{'HCE'}->hce_block_decode_mime($_); $dec_data =~ tr/\n\r\t//d; print "Server decode: $dec_data\n"; last if ($dec_data eq "+END_OF_LIST"); push @response, $dec_data; }; if (!defined(@response)) { return; } else { return @response; }; } else { $_ = <$fh>; # get RKey chomp; $self->{'RKey'} = $_; $self->{'HCE'} = Crypt::HCE_SHA->new($self->{'SKey'}, $self->{'RKey'}); return $self->recv(); } } package Client; use IO::Select; use IO::Socket; use strict; use Carp; #use HCE_SHA; my @response; my $data; sub new { my $class = shift; my $self = {}; bless $self, $class; if ((scalar(@_) % 2) != 0) { croak "incorrect number of parameters"; } while (@_) { my $key = shift(@_); my $value = shift(@_); $self->{$key} = $value; } $self->_initialize; return $self; } sub _initialize { my $self = shift; my $timeout; if (!defined($self->{'Server'})) { croak "Client not initialized properly : Server parameter missing"; } if (!defined($self->{'Port'})) { croak "Client not initialized properly : Port parameter missing"; } if (!defined($self->{'SKey'})) { croak "Client not initialized properly : SKey parameter missing"; } if (!eval {$self->{'Socket'} = IO::Socket::INET->new(PeerAddr => $self->{'Server'}, PeerPort => $self->{'Port'}, Proto => 'tcp', Reuse => 1); }) { croak "Client couldn't establish a connection to $self->{'Server'}"; } $self->{'Socket'}->autoflush(1); srand($$|time()); # poor random generator should be replaced $self->{'RKey'} = rand(100000000)+1000000; $self->{'HCE'} = Crypt::HCE_SHA->new($self->{'SKey'}, $self->{'RKey'}); print { $self->{'Socket'} } "$self->{'RKey'}\n"; } sub send { my $self = shift; my @items = @_; my ($item, $enc_item); if (defined($self->{'HCE'})) { foreach $item (@items) { $enc_item = $self->{'HCE'}->hce_block_encode_mime($item); print { $self->{'Socket'} } "$enc_item\n"; } $enc_item = $self->{'HCE'}->hce_block_encode_mime("+END_OF_LIST"); print { $self->{'Socket'} } "$enc_item\n"; } else { foreach $item (@items) { print { $self->{'Socket'} } "$item\n"; } print { $self->{'Socket'} } "+END_OF_LIST\n"; } return 0; } sub recv { my $self = shift; my $fh = $self->{'Socket'}; my ($data, $dec_data); if (defined($self->{'HCE'})) { $data = ""; undef(@response); while (<$fh>) { chomp; $data = 1; print "Client recv: $_\n"; $dec_data = $self->{'HCE'}->hce_block_decode_mime($_); print "Client decode: $dec_data\n"; last if ($dec_data eq "+END_OF_LIST"); push @response, $dec_data; }; if (!defined $data) { close ($self->{'Socket'}); return $data; } else { close ($self->{'Socket'}); return @response; }; } else { $data = ""; undef(@response); while (<$fh>) { chomp; $data = 1; push @response, $_; }; if (!defined $data) { close ($self->{'Socket'}); return $data; } else { close ($self->{'Socket'}); return @response; }; } } 1; __END__ Crypt-HCE_SHA-0.70/Changes0000644000175000017500000000131710031045762015012 0ustar ericeric00000000000000Revision history for Perl extension Crypt::HCE_SHA. 0.01 Wed Oct 14 16:23:57 1998 - original version; created by h2xs 1.18 0.02 - implementation 0.03 Fri Oct 16 14:41:33 1998 - moved example modules to the examples directory 0.40 Tue Apr 06 1999 - updated man documentation - updated to use Digest::SHA1 by Gisle Aas 0.45 Tue Aug 17 1999 - bug fix on chaining key selection - bug report submitted by Jake Angerman (Thanks Jake!) 0.60 Fri Feb 18 2000 - fixed length issue caused by mime inserting returns - updated Client.pm and Server.pm to reflect the changes 0.65 Fri Mar 26 2004 - removed syslog from test.pl to support ActiveState 0.70 Fri Mar 26 2004 - removed the other syslogs from test.pl Crypt-HCE_SHA-0.70/MANIFEST0000644000175000017500000000030010031035254014632 0ustar ericeric00000000000000Changes HCE_SHA.pm MANIFEST Makefile.PL test.pl README examples/Client.pm examples/Server.pm examples/HOW_TO_USE META.yml Module meta-data (added by MakeMaker) Crypt-HCE_SHA-0.70/HCE_SHA.pm0000644000175000017500000001020010031045776015143 0ustar ericeric00000000000000# # Crypt::HCE_SHA # implements one way hash chaining encryption using SHA # # $Id: HCE_SHA.pm,v 1.3 2000/02/19 03:47:11 eric Exp $ # package Crypt::HCE_SHA; use strict; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); use Digest::SHA1; use MIME::Base64; use Carp; require Exporter; require AutoLoader; @ISA = qw(Exporter AutoLoader); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. @EXPORT = qw( ); $VERSION = '0.70'; sub new { my $class = shift; my $self = {}; bless $self, $class; if (scalar(@_) != 2) { croak "Error: must be invoked HCE_SHA->new(key, random_thing)"; } $self->{SKEY} = shift(@_); $self->{RKEY} = shift(@_); return $self; } sub _new_key { my $self = shift; my ($rnd) = @_; my $context = new Digest::SHA1; $context->add($self->{SKEY}, $rnd); my $digest = $context->digest(); my @e_block = unpack('C*', $digest); return @e_block; } sub hce_block_encrypt { my $self = shift; my ($data) = @_; my ($i, $key, $data_size, $ans, $mod, @e_block, @data, @key, @ans); @key = unpack ('C*', $self->{SKEY}); @data = unpack ('C*', $data); undef @ans; @e_block = $self->_new_key($self->{RKEY}); $data_size = scalar(@data); for($i=0; $i < $data_size; $i++) { $mod = $i % 20; if (($mod == 0) && ($i > 19)) { @e_block = $self->_new_key(pack 'C*', (@ans)[($i-20)..($i-1)]); } $ans[$i] = $e_block[$mod] ^ $data[$i]; } $ans = pack 'C*', @ans; return $ans; } sub hce_block_decrypt { my $self = shift; my ($data) = @_; my ($i, $key, $data_size, $ans, $mod, @e_block, @data, @key, @ans); @key = unpack ('C*', $self->{SKEY}); @data = unpack ('C*', $data); undef @ans; @e_block = $self->_new_key($self->{RKEY}); $data_size = scalar(@data); for($i=0; $i < $data_size; $i++) { $mod = $i % 20; if (($mod == 0) && ($i > 19)) { @e_block = $self->_new_key(pack 'C*', (@data)[($i-20)..($i-1)]); } $ans[$i] = $e_block[$mod] ^ $data[$i]; } $ans = pack 'C*', @ans; return $ans; } sub hce_block_encode_mime { my $self = shift; my ($data) = @_; my $new_data = $self->hce_block_encrypt($data); my $encode = encode_base64($new_data, ""); return $encode; } sub hce_block_decode_mime { my $self = shift; my ($data) = @_; my $decode = decode_base64($data); my $new_data = $self->hce_block_decrypt($decode); return $new_data; } # Autoload methods go after =cut, and are processed by the autosplit program. 1; __END__ =head1 NAME Crypt::HCE_SHA - Perl extension implementing one way hash chaining encryption using SHA =head1 SYNOPSIS use Crypt::HCE_SHA; $hce_sha = Crypt::HCE_SHA->new("SharedSecret", "Random01,39j309ad"); $crypted = $hce_sha->hce_block_encrypt("Encrypt this information"); $info = $hce_sha->hce_block_decrypt($crypted); $mime_crypted = $hce_sha->hce_block_encode_mime("Encrypt and Base64 this information"); $info = $hce_sha->hce_block_decode_mime($mime_crypted); =head1 DESCRIPTION This module implements a chaining block cipher using a one way hash. This method of encryption is the same that is used by radius (RFC2138) and is also described in Applied Cryptography. Two interfaces are provided in the module. The first is straight block encryption/decryption the second does base64 mime encoding/decoding of the encrypted/decrypted blocks. The idea is the the two sides have a shared secret that supplies one of the keys and a randomly generated block of bytes provides the second key. The random key is passed in cleartext between the two sides. An example client and server are packaged as modules with this module. They are used in the tests. They can be found in the examples directory. Thanks to Jake Angerman for the bug report on the bug in key generation for the chaining portion of the algorithm =head1 AUTHOR Eric Estabrooks, eric@urbanrage.com =head1 SEE ALSO perl(1). =cut Crypt-HCE_SHA-0.70/Makefile.PL0000644000175000017500000000046407754540476015517 0ustar ericeric00000000000000use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( 'NAME' => 'Crypt::HCE_SHA', 'VERSION_FROM' => 'HCE_SHA.pm', # finds $VERSION 'PREREQ_PM' => {'Digest::SHA1' => 0, 'MIME::Base64' => 2} ); Crypt-HCE_SHA-0.70/README0000644000175000017500000000134607754540476014425 0ustar ericeric00000000000000 This module implements a chaining block cipher using a one way hash. This method of encryption is the same that is used by radius (RFC2138) and is also described in Applied Cryptography. Two interfaces are provided in the module. The first is straight block encryption/decryption the second does base64 mime encoding/decoding of the encrypted/decrypted blocks. The idea is the the two sides have a shared secret that supplies one of the keys and a randomly generated block of bytes provides the second key. The random key is passed in cleartext between the two sides. An example client and server are packaged as modules with this module. They are used in the tests.