summaryrefslogtreecommitdiff
path: root/src/keytrans
diff options
context:
space:
mode:
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>2009-01-07 12:31:37 -0500
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>2009-01-07 12:31:37 -0500
commitc2da43d48e1d8c54c089081d7f316bb925f426d9 (patch)
tree5a134db659a564861f50688b2262250156d01459 /src/keytrans
parentef9469ee700eacfb9da0b2d897b82fbe1287e864 (diff)
clean up a bit of pem2openpgp and remove some of the hardcoded data.
Diffstat (limited to 'src/keytrans')
-rwxr-xr-xsrc/keytrans/pem2openpgp102
1 files changed, 65 insertions, 37 deletions
diff --git a/src/keytrans/pem2openpgp b/src/keytrans/pem2openpgp
index 59f9bb0..38baa95 100755
--- a/src/keytrans/pem2openpgp
+++ b/src/keytrans/pem2openpgp
@@ -20,6 +20,58 @@ use Crypt::OpenSSL::Bignum;
use Digest::SHA1;
use MIME::Base64;
+
+# make an old-style packet out of the given packet type and body.
+# old-style (see RFC 4880 section 4.2)
+sub make_packet {
+ my $type = shift;
+ my $body = shift;
+
+# FIXME: yet another length():
+ my $len = length($body);
+
+ my $lenbytes;
+ my $lencode;
+
+ if ($len < 2**8) {
+ $lenbytes = 0;
+ $lencode = 'C';
+ } elsif ($len < 2**16) {
+ $lenbytes = 1;
+ $lencode = 'n';
+ } elsif ($len < 2**31) {
+ ## not testing against full 32 bits because i don't want to deal
+ ## with potential overflow.
+ $lenbytes = 2;
+ $lencode = 'N';
+ } else {
+ ## what the hell do we do here?
+ $lenbytes = 3;
+ $lencode = '';
+ }
+
+ return pack('C'.$lencode, 0x80 + ($type * 4) + $lenbytes, $len).
+ $body;
+}
+
+
+# takes a Crypt::OpenSSL::Bignum
+sub mpi_pack {
+ my $num = shift;
+
+ my $hex = $num->to_hex();
+
+ my $mpilen = length($hex)*4;
+
+# this is a kludgy way to get the number of bits in the first byte:
+ my $bitsinfirstbyte = length(sprintf("%b", hex(substr $hex, 0, 2)));
+
+ $mpilen -= (8 - $bitsinfirstbyte);
+
+ return pack('n', $mpilen).$num->to_bin();
+}
+
+
my $holdTerminator = $/;
undef $/;
my $buf = <STDIN>;
@@ -103,8 +155,14 @@ my $sig_data_to_be_hashed =
my ($n, $e, $d, $p, $q) = $rsa->get_key_parameters();
-open(KEYFILE, "</home/wt215/gpg-test/key-data");
-my $key_data = <KEYFILE>;
+my $pubkey =
+ pack('CN', 4, $timestamp).
+ $pubkey_algo.
+ mpi_pack($n).
+ mpi_pack($e);
+
+#open(KEYFILE, "</home/wt215/gpg-test/key-data");
+my $key_data = make_packet(6, $pubkey);
# FIXME: $keyid should be generated from the public key instead of
# hardcoded:
@@ -133,22 +191,7 @@ my $data_hash = Digest::SHA1::sha1_hex($datatosign);
my $issuer_packet = pack('CCH16', 9, 16, $keyid);
-my $sig = $rsa->sign($datatosign);
-
-my $bigsig = Crypt::OpenSSL::Bignum->new_from_bin($sig);
-
-
-my $hex = $bigsig->to_hex();
-
-my $mpilen = length($hex)*4;
-
-# this is a kludgy way to get the number of bits in the first byte:
-my $bitsinfirstbyte = length(sprintf("%b", hex(substr $hex, 0, 2)));
-
-$mpilen -= (8 - $bitsinfirstbyte);
-
-# emit two octets representing $mpilen, followed by the signature itself:
-
+my $sig = Crypt::OpenSSL::Bignum->new_from_bin($rsa->sign($datatosign));
my $sig_body =
$sig_data_to_be_hashed.
@@ -156,25 +199,10 @@ my $sig_body =
pack('n', length($issuer_packet)).
$issuer_packet.
pack('n', hex(substr($data_hash, 0, 4))).
- pack("n" , $mpilen).
- $sig;
-
-# FIXME: yet another length():
-my $len = length($sig_body);
-
-my $header;
-
-if ($len < 2**8) {
- $header = pack('CC', 0x88, $len);
-} elsif ($len < 2**16) {
- $header = pack('Cn', 0x89, $len);
-} elsif ($len < 2**31) {
- $header = pack('CN', 0x8a, $len);
-} else {
- # what the hell do we do here?
- $header = pack('C', 0x8b);
-}
+ mpi_pack($sig);
-print $header.$sig_body;
+print make_packet(6, $pubkey);
+print make_packet(13, $uid);
+print make_packet(2, $sig_body);
$/ = $holdTerminator;