X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=src%2Fshare%2Fkeytrans;h=255a271c2cefd7f2dd446d5b69e9a275f8116ce5;hb=bef7e503b70c985c2d4386146fc5881e7ab3718e;hp=ad65ed32585829b40d4332154bc08167b97461d8;hpb=67f9a419cca005c79bd7d659e3b46f6421c436a3;p=monkeysphere.git diff --git a/src/share/keytrans b/src/share/keytrans index ad65ed3..255a271 100755 --- a/src/share/keytrans +++ b/src/share/keytrans @@ -429,7 +429,7 @@ sub fingerprint { # FIXME: handle DSA keys as well! -sub pem2openpgp { +sub makeselfsig { my $rsa = shift; my $uid = shift; my $args = shift; @@ -442,10 +442,7 @@ sub pem2openpgp { if (! defined $args->{sig_timestamp}) { $args->{sig_timestamp} = time(); } - if (! defined $args->{key_timestamp}) { - $args->{key_timestamp} = $args->{sig_timestamp} + 0; - } - my $key_timestamp = $args->{key_timestamp}; + my $key_timestamp = $args->{key_timestamp} + 0; # generate and aggregate subpackets: @@ -518,10 +515,7 @@ sub pem2openpgp { $feature_subpacket. $keyserver_pref; - return - make_packet($packet_types->{seckey}, make_rsa_sec_key_body($rsa, $key_timestamp)). - make_packet($packet_types->{uid}, $uid). - gensig($rsa, $uid, $args); + return gensig($rsa, $uid, $args); } # FIXME: handle non-RSA keys @@ -728,6 +722,7 @@ sub findkey { my $foundfprstr = Crypt::OpenSSL::Bignum->new_from_bin($foundfpr)->to_hex(); # left-pad with 0's to bring up to full 40-char (160-bit) fingerprint: $foundfprstr = sprintf("%040s", $foundfprstr); + my $matched = 0; # is this a match? if ((!defined($data->{target}->{fpr})) || @@ -737,6 +732,7 @@ sub findkey { } $data->{key} = { 'rsa' => $pubkey, 'timestamp' => $key_timestamp }; + $matched = 1; } if ($tag != $packet_types->{seckey} && @@ -746,7 +742,7 @@ sub findkey { } return; } - if (!defined($data->{key})) { + if (!$matched) { # we don't think the public part of this key matches if ($readbytes < $packetlen) { read($instr, $dummy, $packetlen - $readbytes) or die "Could not skip past this packet.\n"; @@ -803,7 +799,9 @@ sub openpgp2rsa { $fpr = uc($fpr); } - my $data = { 'fpr' => $fpr}; + my $data = { target => { fpr => $fpr, + }, + }; my $subs = { $packet_types->{pubkey} => \&findkey, $packet_types->{pub_subkey} => \&findkey, $packet_types->{seckey} => \&findkey, @@ -814,6 +812,89 @@ sub openpgp2rsa { return $data->{key}->{rsa}; } +sub findkeyfprs { + my $data = shift; + my $instr = shift; + my $tag = shift; + my $packetlen = shift; + + findkey($data, $instr, $tag, $packetlen); + if (defined($data->{key})) { + if (defined($data->{key}->{rsa}) && defined($data->{key}->{timestamp})) { + $data->{keys}->{fingerprint($data->{key}->{rsa}, $data->{key}->{timestamp})} = $data->{key}; + } else { + die "should have found some key here"; + } + undef($data->{key}); + } +}; + +sub getallprimarykeys { + my $instr = shift; + + my $subs = { $packet_types->{pubkey} => \&findkeyfprs, + $packet_types->{seckey} => \&findkeyfprs, + }; + my $data = {target => { } }; + + packetwalk($instr, $subs, $data); + + if (defined $data->{keys}) { + return $data->{keys}; + } else { + return {}; + } +} + +sub adduserid { + my $instr = shift; + my $fpr = shift; + my $uid = shift; + my $args = shift; + + if ((! defined $fpr) || + (length($fpr) < 8)) { + die "We need at least 8 hex digits of fingerprint.\n"; + } + + $fpr = uc($fpr); + + if (! defined $uid) { + die "No User ID defined.\n"; + } + + my $data = { target => { fpr => $fpr, + uid => $uid, + }, + }; + my $subs = { $packet_types->{seckey} => \&findkey, + $packet_types->{uid} => \&finduid, + $packet_types->{sig} => \&findsig, + }; + + packetwalk($instr, $subs, $data); + + if ((! defined $data->{key}) || + (! defined $data->{key}->{rsa}) || + (! defined $data->{key}->{timestamp})) { + die "The key requested was not found.\n" + } + + if (defined $data->{uid}->{$uid}) { + die "The requested User ID '$uid' is already associated with this key.\n"; + } + $args->{key_timestamp} = $data->{key}->{timestamp}; + + return + make_packet($packet_types->{pubkey}, make_rsa_pub_key_body($data->{key}->{rsa}, $data->{key}->{timestamp})). + make_packet($packet_types->{uid}, $uid). + makeselfsig($data->{key}->{rsa}, + $uid, + $args); + +} + + sub revokeuserid { my $instr = shift; my $fpr = shift; @@ -996,10 +1077,18 @@ for (basename($0)) { $rsa = Crypt::OpenSSL::RSA->new_private_key($stdin); } - print pem2openpgp($rsa, + my $key_timestamp = $ENV{PEM2OPENPGP_KEY_TIMESTAMP}; + my $sig_timestamp = $ENV{PEM2OPENPGP_TIMESTAMP}; + $sig_timestamp = time() if (!defined $sig_timestamp); + $key_timestamp = $sig_timestamp if (!defined $key_timestamp); + + print + make_packet($packet_types->{seckey}, make_rsa_sec_key_body($rsa, $key_timestamp)). + make_packet($packet_types->{uid}, $uid). + makeselfsig($rsa, $uid, - { sig_timestamp => $ENV{PEM2OPENPGP_TIMESTAMP}, - key_timestamp => $ENV{PEM2OPENPGP_KEY_TIMESTAMP}, + { sig_timestamp => $sig_timestamp, + key_timestamp => $key_timestamp, expiration => $ENV{PEM2OPENPGP_EXPIRATION}, usage_flags => $ENV{PEM2OPENPGP_USAGE_FLAGS}, } @@ -1033,11 +1122,30 @@ for (basename($0)) { open($instream,'-'); binmode($instream, ":bytes"); - my $revcert = revokeuserid($instream, $fpr, $uid, $ENV{KEYTRANS_REVSIG_TIMESTAMP}); + my $revcert = revokeuserid($instream, $fpr, $uid, $ENV{PEM2OPENPGP_TIMESTAMP}); print $revcert; + } elsif (/^adduserid$/) { + my $fpr = shift; + my $uid = shift; + my $instream; + open($instream,'-'); + binmode($instream, ":bytes"); + my $newuid = adduserid($instream, $fpr, $uid, + { sig_timestamp => $ENV{PEM2OPENPGP_TIMESTAMP}, + expiration => $ENV{PEM2OPENPGP_EXPIRATION}, + usage_flags => $ENV{PEM2OPENPGP_USAGE_FLAGS}, + }); + + print $newuid; + } elsif (/^listfprs$/) { + my $instream; + open($instream,'-'); + binmode($instream, ":bytes"); + my $keys = getallprimarykeys($instream); + printf("%s\n", join("\n", map { uc(unpack('H*', $_)) } keys(%{$keys}))); } else { - die "Unrecognized subcomand. keytrans subcommands are not a stable interface!\n"; + die "Unrecognized subcommand. keytrans subcommands are not a stable interface!\n"; } } }