home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Authfile.pm < prev    next >
Encoding:
Perl POD Document  |  2001-07-11  |  3.5 KB  |  118 lines

  1. # $Id: Authfile.pm,v 1.5 2001/07/11 21:57:37 btrott Exp $
  2.  
  3. package Net::SSH::Perl::Util::Authfile;
  4. use strict;
  5.  
  6. use Net::SSH::Perl::Buffer;
  7. use Net::SSH::Perl::Constants qw( PRIVATE_KEY_ID_STRING );
  8. use Net::SSH::Perl::Cipher;
  9. use Net::SSH::Perl::Key;
  10.  
  11. use Carp qw( croak );
  12.  
  13. sub _load_public_key {
  14.     _load_private_key($_[0], '', 1);
  15. }
  16.  
  17. sub _load_private_key {
  18.     my($key_file, $passphrase, $want_public) = @_;
  19.     $passphrase ||= '';
  20.  
  21.     local *FH;
  22.     open FH, $key_file or croak "Can't open $key_file: $!";
  23.     my $c = do { local $/; <FH> };
  24.     close FH or die "Can't close $key_file: $!";
  25.     ($c) = $c =~ /(.*)/s;  ## Untaint data. Anything is allowed.
  26.  
  27.     my $buffer = Net::SSH::Perl::Buffer->new( MP => 'SSH1' );
  28.     $buffer->append($c);
  29.  
  30.     my $id = $buffer->bytes(0, length(PRIVATE_KEY_ID_STRING), "");
  31.     croak "Bad key file $key_file." unless $id eq PRIVATE_KEY_ID_STRING;
  32.     $buffer->bytes(0, 1, "");
  33.  
  34.     my $cipher_type = $buffer->get_int8;
  35.     $buffer->get_int32;  ## Reserved data.
  36.  
  37.     my $key = Net::SSH::Perl::Key->new('RSA1');
  38.     $key->{rsa}{bits} = $buffer->get_int32;
  39.     $key->{rsa}{n} = $buffer->get_mp_int;
  40.     $key->{rsa}{e} = $buffer->get_mp_int;
  41.  
  42.     my $comment = $buffer->get_str;
  43.  
  44.     if ($want_public) {
  45.         return wantarray ? ($key, $comment) : ($key);
  46.     }
  47.  
  48.     my $cipher_name = Net::SSH::Perl::Cipher::name($cipher_type);
  49.     unless (Net::SSH::Perl::Cipher::supported($cipher_type)) {
  50.         croak sprintf "Unsupported cipher '%s' used in key file '%s'",
  51.             $cipher_name, $key_file;
  52.     }
  53.  
  54.     my $ciph =
  55.         Net::SSH::Perl::Cipher->new_from_key_str($cipher_name, $passphrase);
  56.     my $decrypted = $ciph->decrypt($buffer->bytes($buffer->offset));
  57.     $buffer->empty;
  58.     $buffer->append($decrypted);
  59.  
  60.     my $check1 = ord $buffer->get_char;
  61.     my $check2 = ord $buffer->get_char;
  62.     if ($check1 != ord($buffer->get_char) ||
  63.         $check2 != ord($buffer->get_char)) {
  64.         croak "Bad passphrase supplied for key file $key_file";
  65.     }
  66.  
  67.     $key->{rsa}{d} = $buffer->get_mp_int;
  68.     $key->{rsa}{u} = $buffer->get_mp_int;
  69.     $key->{rsa}{p} = $buffer->get_mp_int;
  70.     $key->{rsa}{q} = $buffer->get_mp_int;
  71.  
  72.     wantarray ? ($key, $comment) : $key;
  73. }
  74.  
  75. sub _save_private_key {
  76.     my($key_file, $key, $passphrase, $comment) = @_;
  77.     $passphrase ||= '';
  78.  
  79.     my $cipher_type = $passphrase eq '' ? 'None' : 'DES3';
  80.  
  81.     my $buffer = Net::SSH::Perl::Buffer->new( MP => 'SSH1' );
  82.     my($check1, $check2);
  83.     $buffer->put_int8($check1 = int rand 255);
  84.     $buffer->put_int8($check2 = int rand 255);
  85.     $buffer->put_int8($check1);
  86.     $buffer->put_int8($check2);
  87.  
  88.     $buffer->put_mp_int($key->{rsa}{d});
  89.     $buffer->put_mp_int($key->{rsa}{u});
  90.     $buffer->put_mp_int($key->{rsa}{p});
  91.     $buffer->put_mp_int($key->{rsa}{q});
  92.  
  93.     $buffer->put_int8(0)
  94.         while $buffer->length % 8;
  95.  
  96.     my $encrypted = Net::SSH::Perl::Buffer->new( MP => 'SSH1' );
  97.     $encrypted->put_chars(PRIVATE_KEY_ID_STRING);
  98.     $encrypted->put_int8(0);
  99.     $encrypted->put_int8(Net::SSH::Perl::Cipher::id($cipher_type));
  100.     $encrypted->put_int32(0);
  101.  
  102.     $encrypted->put_int32($key->{rsa}{bits});
  103.     $encrypted->put_mp_int($key->{rsa}{n});
  104.     $encrypted->put_mp_int($key->{rsa}{e});
  105.     $encrypted->put_str($comment || '');
  106.  
  107.     my $cipher =
  108.         Net::SSH::Perl::Cipher->new_from_key_str($cipher_type, $passphrase);
  109.     $encrypted->append( $cipher->encrypt($buffer->bytes) );
  110.  
  111.     local *FH;
  112.     open FH, ">$key_file" or croak "Can't open $key_file: $!";
  113.     print FH $encrypted->bytes;
  114.     close FH or croak "Can't close $key_file: $!";
  115. }
  116.  
  117. 1;
  118.