IPC-Transit

 view release on metacpan or  search on metacpan

ex/crypto.pl  view on Meta::CPAN

#!env perl

use strict;use warnings;
use IPC::Transit;

#note that this code will not work exactly as written, because it needs
#to run on two different boxes.


my ($sender_public_key, $sender_private_key) = IPC::Transit::gen_key_pair();
my ($receiver_public_key, $receiver_private_key) = IPC::Transit::gen_key_pair();


$IPC::Transit::my_hostname = 'sender.hostname.com';
$IPC::Transit::my_keys->{public} = $sender_public_key;
$IPC::Transit::my_keys->{private} = $sender_private_key;
$IPC::Transit::public_keys->{'receiver.hostname.com'} = $receiver_public_key;


IPC::Transit::send(
    message => {foo => 'bar'},
    qname => 'some_qname',
    destination => 'receiver.hostname.com',
    encrypt => 1
);

exit;

#teleport over to the receiver, magically using keys generated above

$IPC::Transit::my_hostname = 'receiver.hostname.com';
$IPC::Transit::my_keys->{public} = $receiver_public_key;
$IPC::Transit::my_keys->{private} = $receiver_private_key;
$IPC::Transit::public_keys->{'sender.hostname.com'} = $sender_public_key;

my $message = IPC::Transit::receiver(
    qname => 'some_qname'
);

if($message->{'.ipc_transit_meta'}->{encrypt_source} ne 'sender.hostname.com') {
    die 'something bad happened, $message is not to be trusted';
}

lib/IPC/Transit.pm  view on Meta::CPAN

            #validate $IPC::Transit::my_keys->{private}
            #
            my $source = $message->{wire_headers}->{S};
            my $public_key;
            if($IPC::Transit::public_keys->{$source}) {
                $public_key = $IPC::Transit::public_keys->{$source};
                $used_default_public = 0;
            } else {
                $public_key = $IPC::Transit::public_keys->{default};
            }
            my @private_keys = ($IPC::Transit::my_keys->{default});
            push @private_keys, $IPC::Transit::my_keys->{private}
                if $IPC::Transit::my_keys->{private};
            my $nonce = decode_base64($message->{wire_headers}->{n});
            my $public_keys;
            if(not ref $public_key) {
                $public_keys = [$public_key];
            } else {
                $public_keys = $public_key;
            }
            push @$public_keys, $IPC::Transit::public_keys->{default};
            my $cleartext;
            PUBLIC:
            foreach my $public (@$public_keys) {
                foreach my $private_key (@private_keys) {
                    $cleartext = crypto_box_open(
                        $message->{serialized_message},
                        $nonce,
                        decode_base64($public),
                        decode_base64($private_key),
                    );
                    last PUBLIC if $cleartext;
                }
            }
            $message->{serialized_message} = $cleartext;
        }
        return undef unless _thaw($message);
        $message->{message}->{'.ipc_transit_meta'}->{encrypt_source} =
            $message->{wire_headers}->{S} if $message->{wire_headers}->{S};
        $message->{message}->{'.ipc_transit_meta'}->{encrypt_source} = 'default'

lib/IPC/Transit.pm  view on Meta::CPAN

    if($args->{encrypt}) {
        my $sender = _get_my_hostname();
        if(not $sender) {
            die 'encrypt selected but unable to determine hostname.  Set $IPC::Transit::my_hostname to override';
        }
    }
    if($args->{encrypt}) {
        my $nonce = crypto_box_nonce();
        $args->{nonce} = encode_base64($nonce);

        my $my_private_key;
        if($IPC::Transit::my_keys->{private}) {
            $my_private_key = $IPC::Transit::my_keys->{private};
            $args->{message}->{'.ipc_transit_meta'}->{signed_destination} = 'my_private';
        } else {
            $my_private_key = $IPC::Transit::my_keys->{default};
            $args->{message}->{'.ipc_transit_meta'}->{signed_destination} = 'default';
        }
        my $their_public_key;
        if($IPC::Transit::public_keys->{$args->{destination}}) {
            $their_public_key = $IPC::Transit::public_keys->{$args->{destination}};
        } else {
            $their_public_key = $IPC::Transit::public_keys->{default};
        }
        $args->{serialized_message} = _freeze($args);
        my $cipher_text = crypto_box(
            $args->{serialized_message},
            $nonce,
            decode_base64($their_public_key),
            decode_base64($my_private_key)
        );
        $args->{serialized_message} = $cipher_text;
        $args->{source} = _get_my_hostname();
    } else {
        $args->{serialized_message} = _freeze($args);
    }
    $args->{message_length} = length $args->{serialized_message};
    if($args->{message_length} > $IPC::Transit::max_message_size) {
        my $s;
        eval {

lib/IPC/Transit.pm  view on Meta::CPAN

This value is placed into the message by the sender, and used by the
receiver to lookup the public key of the sender.

=head3 $IPC::Transit::my_keys

This is a hash reference initially populated, in the attribute 'default',
with the private half of a default key pair.  For actual secure
communication, a new key pair must be generated on both sides, and the
sender's private key needs to be placed here:

  $IPC::Transit::my_keys->{private} = $real_private_key

=head3 $IPC::Transit::public_keys

As above, this is a hash reference initially populated, in the attribute
'default', with the public half of a default key pair.  For actual secure
communication, a new key pair must be generated on both sides, and the
receiver's public key needs to be placed here:

  $IPC::Transit::public_keys->{$receiver_hostname} = $real_public_key_from_receiver

t/crypto-basic.t  view on Meta::CPAN

use strict;use warnings;

use lib '../lib';
use lib 'lib';
use Test::More;
use Data::Dumper;

use_ok('IPC::Transit') or exit;
use_ok('IPC::Transit::Test') or exit;

my ($their_public_key, $their_private_key) = IPC::Transit::gen_key_pair();
my ($my_public_key, $my_private_key) = IPC::Transit::gen_key_pair();

undef $IPC::Transit::config_dir;
undef $IPC::Transit::config_file;
undef $IPC::Transit::config_dir;
undef $IPC::Transit::config_file;

#the following global assignments are to represent the sending box
$IPC::Transit::my_hostname = 'sender';
$IPC::Transit::my_keys->{public} = $my_public_key;
$IPC::Transit::my_keys->{private} = $my_private_key;
$IPC::Transit::public_keys->{'127.0.0.1'} = $their_public_key;


ok my $transitd_pid = IPC::Transit::Test::run_daemon('perl bin/remote-transitd');
ok my $transit_gateway_pid = IPC::Transit::Test::run_daemon('plackup --port 9816 bin/remote-transit-gateway.psgi');
sleep 2; #let them spin up a bit
IPC::Transit::send(message => {foo => 'bar'}, qname => $IPC::Transit::test_qname, destination => '127.0.0.1', encrypt => 1);
sleep 2; #let them do their jobs


#the following global assignments are to represent the receiving box
$IPC::Transit::my_hostname = '127.0.0.1';
$IPC::Transit::my_keys->{public} = $their_public_key;
$IPC::Transit::my_keys->{private} = $their_private_key;
$IPC::Transit::public_keys->{sender} = $my_public_key;


ok my $ret = eval {
    local $SIG{ALRM} = sub { die "timed out\n"; };
    alarm 3;
    return IPC::Transit::receive(qname => $IPC::Transit::test_qname);
};
alarm 0;
ok $ret->{foo}, 'foo properly exists';

t/crypto-multi-publics.t  view on Meta::CPAN


use strict;use warnings;

use lib 'lib';
use Test::More;
use Data::Dumper;

use_ok('IPC::Transit') or exit;
use_ok('IPC::Transit::Test') or exit;

my ($their_public_key, $their_private_key) = IPC::Transit::gen_key_pair();
my ($my_public_key, $my_private_key) = IPC::Transit::gen_key_pair();
my ($another_public_key, undef) = IPC::Transit::gen_key_pair();

undef $IPC::Transit::config_dir;
undef $IPC::Transit::config_file;
undef $IPC::Transit::config_dir;
undef $IPC::Transit::config_file;

#the following global assignments are to represent the sending box
$IPC::Transit::my_hostname = 'sender';
$IPC::Transit::my_keys->{public} = $my_public_key;
$IPC::Transit::my_keys->{private} = $my_private_key;
$IPC::Transit::public_keys->{'127.0.0.1'} = $their_public_key;


ok my $transitd_pid = IPC::Transit::Test::run_daemon('perl bin/remote-transitd');
ok my $transit_gateway_pid = IPC::Transit::Test::run_daemon('plackup --port 9816 bin/remote-transit-gateway.psgi');
sleep 2; #let them spin up a bit
IPC::Transit::send(message => {foo => 'bar'}, qname => $IPC::Transit::test_qname, destination => '127.0.0.1', encrypt => 1);
sleep 2; #let them do their jobs


#the following global assignments are to represent the receiving box
$IPC::Transit::my_hostname = '127.0.0.1';
$IPC::Transit::my_keys->{public} = $their_public_key;
$IPC::Transit::my_keys->{private} = $their_private_key;
#$IPC::Transit::public_keys->{sender} = $my_public_key;
$IPC::Transit::public_keys->{sender} = [$another_public_key,$my_public_key];


ok my $ret = eval {
    local $SIG{ALRM} = sub { die "timed out\n"; };
    alarm 3;
    return IPC::Transit::receive(qname => $IPC::Transit::test_qname);
};
alarm 0;



( run in 0.260 second using v1.01-cache-2.11-cpan-4d50c553e7e )