# $Id: Mac.pm,v 1.6 2001/04/20 23:23:40 btrott Exp $ package Net::SSH::Perl::Mac; use strict; use Carp qw( croak ); use vars qw( %MAC %MAC_REVERSE %SUPPORTED ); %MAC = ( 'hmac-sha1' => 'SHA1', 'hmac-md5' => 'MD5', ); sub new { my $class = shift; my $type = shift; my $mac_class = join '::', __PACKAGE__, $MAC{$type}; my $mac = bless {}, $mac_class; $mac->init(@_) if @_; $mac; } sub enabled { $_[0]->{enabled} } sub enable { $_[0]->{enabled} = 1 } sub init { my $mac = shift; my($key) = @_; $mac->{key} = substr($key, 0, $mac->key_len); } sub hmac { } sub key_len { my $mac = shift; $mac->{key_len} = shift if @_; $mac->{key_len}; } package Net::SSH::Perl::Mac::MD5; use strict; use Digest::HMAC_MD5 qw( hmac_md5 ); use vars qw( @ISA ); @ISA = qw( Net::SSH::Perl::Mac ); sub hmac { my $mac = shift; hmac_md5($_[0], $mac->{key}); } sub len { 16 } package Net::SSH::Perl::Mac::SHA1; use strict; use Digest::HMAC_SHA1 qw( hmac_sha1 ); use vars qw( @ISA ); @ISA = qw( Net::SSH::Perl::Mac ); sub hmac { my $mac = shift; hmac_sha1($_[0], $mac->{key}); } sub len { 20 } 1; __END__ =head1 NAME Net::SSH::Perl::Mac - MAC support for SSH2 =head1 SYNOPSIS use Net::SSH::Perl::Mac; my $mac = Net::SSH::Perl::Mac->new('hmac-sha1', $key); $mac->hmac("foo bar"); =head1 DESCRIPTION I (and its subclasses) provides MAC support for the SSH2 implementation in I. In the SSH2 protocol, each packet sent between client and server (after the key exchange and algorithm negotiation phase) contains a MAC to protect its integrity. The sending party computes the MAC over the length, padding, and (encrypted) payload fields of the packet, then appends the MAC; and the receiving party recomputes the MAC against the data that it receives. The MAC is computed using part of the key that is negotiated during the key exchange phase. During negotiation, packets do not contain MAC; after the I message is sent, each side turns on its respective encryption, MAC, and compression code, for each packet that is sent after that point. I supports two MAC algorithms: I and I. These algorithms are implemented, respectively, by I and I. =head1 USAGE Each MAC object supports the following methods: =head2 $mac = Net::SSH::Perl::Mac->new( $name ) Constructs a new MAC object and returns that object. =head2 $mac->init( $key ) Initializes I<$mac> and sets its key to I<$key> (or rather, to a substring of key, I bytes long). As this implies, the I method should be called before I to set the intended length of the key. =head2 $mac->hmac( $data ) Computes the MAC over I<$data>, using the key set in the initialization phase, and returns the MAC. =head2 $mac->len Returns the length of the MAC (eg. C<20> for HMAC_SHA1). =head2 $mac->key_len( $len ) Given I<$len> sets the key length of I<$mac> to I<$len>. This should be called I the I method, because I uses this value to take a substring of the provided key value. Most of the time this should just be set to the MAC length (the I method); certain SSH implementations have a bug, however, wherein they always use only the first 16 bytes of the provided key. =head2 $mac->enable Enables the MAC object. This is used by I to "turn on" the MAC after key negotiation. =head2 $mac->enabled Tests the I flag (set with the I method). This is used by I to determine whether or not to compute a MAC on an outgoing packet. =head1 AUTHOR & COPYRIGHTS Please see the Net::SSH::Perl manpage for author, copyright, and license information. =cut