Apache-SecSess

 view release on metacpan or  search on metacpan

SecSess/Wrapper.pm  view on Meta::CPAN

#
# Wrapper.pm - data encryption-wrapper w/ strong checksum
#
# $Id: Wrapper.pm,v 1.6 2002/05/08 02:14:59 pliam Exp $
#

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Apache::SecSess::Wrapper
# (c) 2001, 2002 John Pliam
# This is open-source software.
# See file 'COPYING' in original distribution for complete details.
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

package Apache::SecSess::Wrapper;

use IO::File;
use MIME::Base64;
use Digest::MD5 qw(md5);
use Crypt::Rijndael;

$VERSION = sprintf("%d.%02d", q$Name: SecSess_Release_0_09 $ =~ /\d+/g);

sub new {
	my($class, $method, $keyarg) = @_;

	# derive key from argument
	my $key = $class->_initkey($method, $keyarg);
		
	# crunch key and instantiate cipher object
	my $cipher = Crypt::Rijndael->new(
		pack('a16 a16', md5('1'.$key), md5('2'.$key)),
		Crypt::Rijndael::MODE_CBC
	);
	return bless({cipher => $cipher}, $class);
}

#
# How to make the key from a key argument.  Two methods defined:
#	1. $class->new(key => 'passphrase') passes key directly
#	2. $class->new(file => 'filename') takes first line as key
#
sub _initkey {
	my $class = shift;
    my($method, $keyarg) = @_;
    my($fh, $key);

	if ($method eq 'key') { return $keyarg; }
	if ($method eq 'file') { 
        unless ($fh = IO::File->new($keyarg)) { die "Cannot open keyfile."; }
        chomp($key = <$fh>);
    	return $key;
    }
	return undef;
}

# wrap string
sub wrap {
	my $self = shift;
	my($m) = @_;
	my($l,$blk,$byt,$pad,$ct);

	# form plaintext record
	$l = length($m); 					# length of plaintext message
	$blk = int((length($m)+2-1)/16)+1;	# total blocks for rec. w/o digest
	$byt = 16*$blk-2;					# total bytes for message part
	$pad = $byt-$l;						# number of padding bytes
	$dig = md5($m);
	$pt = pack("a16 n a$l a$pad", $dig, $l, $m, $dig);

	# encrypt and encode
	$ct = encode_base64($self->{cipher}->encrypt($pt), '');
	$ct =~ tr/\+\/\=/-._/;
	return $ct;
}

# unwrap string, checking integrity
sub unwrap {
	my $self = shift;
	my($ct) = @_;
	my($pt,$dig,$l,$mm,$m);

	# decode and decrypt
	$ct =~ tr/\-\.\_/+\/=/;
	$pt = $self->{cipher}->decrypt(decode_base64($ct));
	($dig, $l, $mm) = unpack("a16 n a*", $pt);
    $m = unpack("a$l", $mm);

	# caller must check validity
	return (md5($m) eq $dig) ? $m : undef;
}

# wrap a hash "uniquely"



( run in 1.050 second using v1.01-cache-2.11-cpan-df04353d9ac )