From f9871e32622786e24bd5ad32f6849e6e6235b323 Mon Sep 17 00:00:00 2001 From: David Bremner Date: Thu, 28 Apr 2011 08:50:52 -0300 Subject: [PATCH] Add GnuPGKey_to_OpenSSH_fpr This copies sshfpr from monkeysphere, and pastes it into the skeleton of OpenPGKey_to_OpenSSH_pub. Monkeyprogramming at its finest. --- Crypt/Monkeysphere/Keytrans.pm | 37 ++++++++++++++++++++- unit-tests/40.keytrans/20.sshfpr.t | 52 ++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 unit-tests/40.keytrans/20.sshfpr.t diff --git a/Crypt/Monkeysphere/Keytrans.pm b/Crypt/Monkeysphere/Keytrans.pm index 1754a76..16542c1 100644 --- a/Crypt/Monkeysphere/Keytrans.pm +++ b/Crypt/Monkeysphere/Keytrans.pm @@ -7,7 +7,7 @@ use Carp; use MIME::Base64; use Exporter qw(import); -our @EXPORT_OK=qw(GnuPGKey_to_OpenSSH_pub); +our @EXPORT_OK=qw(GnuPGKey_to_OpenSSH_pub GnuPGKey_to_OpenSSH_fpr); # takes a Math::BigInt and returns it properly packed for openssh output. @@ -47,6 +47,41 @@ sub openssh_rsa_pubkey_pack { openssh_mpi_pack($modulus); } +# calculate/print the fingerprint of an openssh-style keyblob: + +sub sshfpr { + my $keyblob = shift; + use Digest::MD5; + return join(':', map({unpack("H*", $_)} split(//, Digest::MD5::md5($keyblob)))); +} + +=pod + +=head2 GnuPGKey_to_OpenSSH_fpr + +Find the openssh compatible fingerprint of an (RSA) GnuPG::Key + +B you will need to add add bits and (RSA) to the string to +exactly match the output of ssh-keygen -l. + +=head3 Arguments + +key - GnuPG::Key object + +=cut + +sub GnuPGKey_to_OpenSSH_fpr { + my $key = shift; + + croak("not a GnuPG::Key!") + unless($key->isa('GnuPG::Key')); + + croak("Not an RSA key!") + unless $key->algo_num == 1; + + return sshfpr(openssh_rsa_pubkey_pack(@{$key->pubkey_data}), ''); +} + =pod =head2 GnuPGKey_to_OpenSSH_pub diff --git a/unit-tests/40.keytrans/20.sshfpr.t b/unit-tests/40.keytrans/20.sshfpr.t new file mode 100644 index 0000000..d00a4b6 --- /dev/null +++ b/unit-tests/40.keytrans/20.sshfpr.t @@ -0,0 +1,52 @@ +# -*- perl -*- +use Test::More; + +use Crypt::Monkeysphere::Keytrans qw(GnuPGKey_to_OpenSSH_fpr); +use GnuPG::Interface; +use File::Temp qw(tempdir); + +plan tests => 1; + +my $tempdir = tempdir("unitXXXXX", CLEANUP => 1); +my $gnupg = new GnuPG::Interface(); +$gnupg->options->hash_init(homedir=>$tempdir); + +my $openpgpdata = " +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.11 (GNU/Linux) + +mI0ETa5YiwEEALJhsHgLEokvKM+d1oAAy+oaDywLWsbqzuCCqu5h9Hu7MYxeGmTA +tg8fXatgXEBUUe+e1i1aF94kTqcqcS5M+71ce2yHNyxl7U0pGVMOPiFiRVKK8x/7 +wE2LTaPHhskc8kkKrxoJMbXmn0Oq5wn8xLkidIsVE+AyQ+HbD9C7UAnhABEBAAG0 +NXRlc3Qga2V5IChETyBOT1QgVVNFISkgPHRlc3RAZXhhbXBsZS5uZXQ+IChJTlNF +Q1VSRSEpiL4EEwECACgFAk2uWIsCGwMFCQABUYAGCwkIBwMCBhUIAgkKCwQWAgMB +Ah4BAheAAAoJEEi/A6Yee54PGcID/iL1tRDgFnNaNNdEpChbjrWcoCIQOIw2VvYH +UJY3oiKPWv/f8NMOylFLBG9pjDUd96wkimUvAKccPDwuhwMQq+KTcDPZXm8AeeUX +IMHmPE33qqvifV9dFGlIGa4a3tmGjJvjhKmNSJGJWG9wRK3C2BrJdQVF9sk2FHXd +1nlddMRV +=MxOB +-----END PGP PUBLIC KEY BLOCK----- +"; + + +my $sshdata = "e6:b3:db:be:c6:5d:f7:65:f2:bb:6e:06:69:36:f5:e5"; + + +my $input = IO::Handle->new(); +my $output = IO::Handle->new(); +my $handles = GnuPG::Handles->new(stdin => $input, + stdout => $output, + stderr => $output); + +my $pid = $gnupg->import_keys(handles => $handles); + +$input->write($openpgpdata); +$input->close(); +waitpid($pid, 0); + +my @keys = $gnupg->get_public_keys(); + +foreach $key (@keys) { + my $output = GnuPGKey_to_OpenSSH_fpr($key); + is($sshdata, $output); +} -- 2.26.2