in reply to Crypt::CBC and IO:Socket

You read from the socket until a newline is found, and you assume you have a full (encrypted) message when you do. There's two problems with that:

Start by encrypting the stream rather than each message.

# Sender $cipher->start('encrypting'); print $sock $cipher->crypt($_) while <STDIN>; print $sock $cipher->finish();
# Receiver $cipher->start('decrypting'); local $/ = \4096; process_bytes($cipher->crypt($_)) while <$sock>; process_bytes($cipher->finish());
# Interactive receiver $cipher->start('decrypting'); for (;;) { my $rv = sysread($sock, my $buf='', 4096); die $! if !defined $rv last if !$rv; process_bytes($cipher->crypt($buf)); } process_bytes($cipher->finish());

I think $/=4096;<> will wait for 4096 bytes. sysread will return as soon as any bytes are available.

If you want to read a line at a time, you'll need to accumulate and find lines in the plaintext yourself.

Upgrade: Doh! Using sysread is not enough to be truly interactive. You'll need to pad your lines to a multiple of $cipher->blocksize() bytes.

Interactive or not, why not just use IO::Socket::SSL?

Replies are listed 'Best First'.
Re^2: Crypt::CBC and IO:Socket
by WMP (Initiate) on Jul 22, 2009 at 20:42 UTC
    I writed this code: server.pl:
    sub server { # my $plaintext = $cipher->decrypt($buf); # my $in = "SERVER: Text: ".$plaintext; # my $ciphertext = $cipher->encrypt($in); # print($new_sock $ciphertext); my $plaintext = decrypt($buf); my $in = "SERVER: Text: ".$plaintext; my $ciphertext = crypt_($in); } sub crypt_ { $cipher->start('encrypting'); print $sock $cipher->crypt($_) while <STDIN>; print $sock $cipher->finish(); } sub decrypt { $cipher->start('decrypting'); local $/ = \4096; process_bytes($cipher->crypt($_)) while <$sock>; process_bytes($cipher->finish()); }
    client.pl:
    if ($kid) { # parent reads from STDIN, prints to socket while (defined($in = <STDIN>)) { # my $ciphertext = $cipher->encrypt($in); # print $ciphertext; # print $sock $ciphertext; my $ciphertext = crypt_($in); } # kill the child process kill(TERM => $kid); } else { # child reads from socket, prints to STDOUT while (defined($buf = <$sock>)) { # my $plaintext = $cipher->decrypt($buf); # print $plaintext; my $plaintext = decrypt($buf); print $plaintext; } close $sock; } sub crypt_ { $cipher->start('encrypting'); print $sock $cipher->crypt($_) while <STDIN>; print $sock $cipher->finish(); } sub decrypt { $cipher->start('decrypting'); local $/ = \4096; process_bytes($cipher->crypt($_)) while <$sock>; process_bytes($cipher->finish()); }
    In output from server.pl i have error:
    wmp@innocence:~/ISS/iss/daemon$ ./server.pl Undefined subroutine &main::process_bytes called at ./server.pl line 6 +6. wmp@innocence:~/ISS/iss/daemon$
    In client.pl again I must clicks enter. How to i can use IO::Socket::SSL ?

      In output from server.pl i have error:

      You need to provide the sub. Incoming bytes are fed to that sub. What you do in it is up to you.

      In client.pl again I must clicks enter.

      Well yeah, that's what <STDIN> means. You'll need Term::ReadKey to read a key at a time from the keyboard.

        What these functions: crypt_ ; decrypt must do? Is this function written properly? Why i'm getting this error:
        Undefined subroutine &main::process_bytes called at ./server.pl line 6 +6
        Line 66:
        process_bytes($cipher->finish());
        And, how can I use IO::Socket::SSL ? There is only http example in manual.