X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=src%2Fkeytrans%2Fpem2openpgp;h=94fd3c89de16fdba5bb427b861b89b54ac9d36a9;hb=21062dd622620dd44001858bd9cb4116ac978529;hp=4e6ebe71a21f47d5ab7bfe4d3d6e3d94dc60e5e2;hpb=b08a2e207f22000b494fc1aabe413bea5eb8f7d5;p=monkeysphere.git diff --git a/src/keytrans/pem2openpgp b/src/keytrans/pem2openpgp index 4e6ebe7..94fd3c8 100755 --- a/src/keytrans/pem2openpgp +++ b/src/keytrans/pem2openpgp @@ -23,6 +23,7 @@ use strict; use warnings; +use File::Basename; use Crypt::OpenSSL::RSA; use Crypt::OpenSSL::Bignum; use Crypt::OpenSSL::Bignum::CTX; @@ -508,29 +509,120 @@ sub pem2openpgp { } -my $rsa; -my $stdin; -if (defined $ENV{PEM2OPENPGP_NEWKEY}) { - $rsa = Crypt::OpenSSL::RSA->generate_key($ENV{PEM2OPENPGP_NEWKEY}); -} else { - $stdin = do { - local $/; # slurp! - ; - }; - $rsa = Crypt::OpenSSL::RSA->new_private_key($stdin); + +sub openpgp2ssh { + my $instr = shift; + my $fpr = shift; + + my $packettag; + my $dummy; + my $tag; + + while (! eof($instr)) { + read($instr, $packettag, 1); + $packettag = ord($packettag); + + my $packetlen; + if ( ! (0x80 & $packettag)) { + die "This is not an OpenPGP packet\n"; + } + if (0x40 & $packettag) { + print STDERR "This is a new-style packet header\n"; + $tag = (0x3f & $packettag); + my $nextlen = 0; + read($instr, $nextlen, 1); + $nextlen = ord($nextlen); + if ($nextlen < 192) { + $packetlen = $nextlen; + } elsif ($nextlen < 224) { + my $newoct; + read($instr, $newoct, 1); + $newoct = ord($newoct); + $packetlen = (($nextlen - 192) << 8) + ($newoct) + 192; + } elsif ($nextlen == 255) { + read($instr, $nextlen, 4); + $packetlen = unpack('%L', $nextlen); + } else { + # packet length is undefined. + } + } else { + my $lentype; + print STDERR "This is an old-style packet header\n"; + $lentype = 0x03 & $packettag; + $tag = ( 0x3c & $packettag ) >> 2; + if ($lentype == 0) { + read($instr, $packetlen, 1) or die "could not read packet length\n"; + $packetlen = unpack('C', $packetlen); + } elsif ($lentype == 1) { + read($instr, $packetlen, 2) or die "could not read packet length\n"; + $packetlen = unpack('n', $packetlen); + } elsif ($lentype == 2) { + read($instr, $packetlen, 4) or die "could not read packet length\n"; + $packetlen = unpack('N', $packetlen); + } else { + # packet length is undefined. + } + } + + if (! defined($packetlen)) { + die "Undefined packet lengths are not supported.\n"; + } + printf(STDERR "Packet is %d long\n", $packetlen); + + if ($tag == $packet_types->{pubkey} || + $tag == $packet_types->{pub_subkey} || + $tag == $packet_types->{seckey} || + $tag == $packet_types->{sec_subkey}) { + printf(STDERR "Packet type %d\n", $tag); + read($instr, $dummy, $packetlen) or die "Could not seek!\n"; + } else { + printf(STDERR "We do not care about this packet.\n"); + read($instr, $dummy, $packetlen) or die "Could not seek!\n"; + } + } + + print $tag; } -my $uid = shift; -# FIXME: fail if there is no given user ID; or should we default to -# hostname_long() from Sys::Hostname::Long ? +for (basename($0)) { + if (/^pem2openpgp$/) { + my $rsa; + my $stdin; + if (defined $ENV{PEM2OPENPGP_NEWKEY}) { + $rsa = Crypt::OpenSSL::RSA->generate_key($ENV{PEM2OPENPGP_NEWKEY}); + } else { + $stdin = do { + local $/; # slurp! + ; + }; + + $rsa = Crypt::OpenSSL::RSA->new_private_key($stdin); + } + + my $uid = shift; + + # FIXME: fail if there is no given user ID; or should we default to + # hostname_long() from Sys::Hostname::Long ? -print pem2openpgp($rsa, - $uid, - { timestamp => $ENV{PEM2OPENPGP_TIMESTAMP}, - expiration => $ENV{PEM2OPENPGP_EXPIRATION}, - usage_flags => $ENV{PEM2OPENPGP_USAGE_FLAGS}, - } - ); + print pem2openpgp($rsa, + $uid, + { timestamp => $ENV{PEM2OPENPGP_TIMESTAMP}, + expiration => $ENV{PEM2OPENPGP_EXPIRATION}, + usage_flags => $ENV{PEM2OPENPGP_USAGE_FLAGS}, + } + ); + } + elsif (/^openpgp2ssh$/) { + my $fpr = shift; + my $instream; + open($instream,'-'); + binmode($instream, ":bytes"); + openpgp2ssh($instream, $fpr); + } + else { + die "Unrecognized keytrans call.\n"; + } +}