From e3aa5fb59e53f8d90608c463fb7fe1a3e1c3678b Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Fri, 29 Oct 2010 02:56:31 -0400 Subject: [PATCH] added opensshpubkey pkc support --- Changelog | 5 ++-- Crypt/Monkeysphere/MSVA.pm | 45 ++++++++++++++++++++++--------- Crypt/Monkeysphere/MSVA/Client.pm | 3 ++- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/Changelog b/Changelog index 4f5e0ae..6c50e6c 100644 --- a/Changelog +++ b/Changelog @@ -12,9 +12,10 @@ msva-perl (0.6~pre) upstream; (closes MS #2567) * report server implementation name and version with every query (closes MS # 2564) - * support x509pem PKC format in addition to x509der (addresses MS #2566) + * support x509pem and opensshpubkey PKC formats in addition to x509der + (addresses MS #2566) - -- Daniel Kahn Gillmor Fri, 29 Oct 2010 00:53:37 -0400 + -- Daniel Kahn Gillmor Fri, 29 Oct 2010 02:55:37 -0400 msva-perl (0.5) upstream; diff --git a/Crypt/Monkeysphere/MSVA.pm b/Crypt/Monkeysphere/MSVA.pm index a425204..d1d6b12 100755 --- a/Crypt/Monkeysphere/MSVA.pm +++ b/Crypt/Monkeysphere/MSVA.pm @@ -135,23 +135,41 @@ }; } - # returns an empty list if bad key found. - sub parse_openssh_pubkey { + sub opensshpubkey2key { my $data = shift; + # FIXME: do we care that the label matches the type of key? my ($label, $prop) = split(/ +/, $data); - $prop = decode_base64($prop) or return (); - msvalog('debug', "key properties: %s\n", unpack('H*', $prop)); - my @out; - while (length($prop) > 4) { - my $size = unpack('N', substr($prop, 0, 4)); + my $out = parse_rfc4716body($prop); + + return $out; + } + + sub parse_rfc4716body { + my $data = shift; + $data = decode_base64($data) or return undef; + + msvalog('debug', "key properties: %s\n", unpack('H*', $data)); + my $out = [ ]; + while (length($data) > 4) { + my $size = unpack('N', substr($data, 0, 4)); msvalog('debug', "size: 0x%08x\n", $size); - return () if (length($prop) < $size + 4); - push(@out, substr($prop, 4, $size)); - $prop = substr($prop, 4 + $size); + return undef if (length($data) < $size + 4); + push(@{$out}, substr($data, 4, $size)); + $data = substr($data, 4 + $size); } - return () if ($label ne $out[0]); - return @out; + + if ($out->[0] ne "ssh-rsa") { + return {error => 'Not an RSA key'}; + } + + if (scalar(@{$out}) != 3) { + return {error => 'Does not contain the right number of bigints for RSA'}; + } + + return { exponent => Math::BigInt->from_hex('0x'.unpack('H*', $out->[1])), + modulus => Math::BigInt->from_hex('0x'.unpack('H*', $out->[2])), + } ; } @@ -394,7 +412,6 @@ my @lines = split(/\n/, $pem); my @goodlines = (); my $ready = 0; - use MIME::Base64; foreach my $line (@lines) { if ($line eq '-----END CERTIFICATE-----') { last; @@ -554,6 +571,8 @@ $key = der2key(join('', map(chr, @{$data->{pkc}->{data}}))); } elsif (lc($data->{pkc}->{type}) eq 'x509pem') { $key = der2key(pem2der($data->{pkc}->{data})); + } elsif (lc($data->{pkc}->{type}) eq 'opensshpubkey') { + $key = opensshpubkey2key($data->{pkc}->{data}); } else { $ret->{message} = sprintf("Don't know this public key carrier type: %s", $data->{pkc}->{type}); return $status,$ret; diff --git a/Crypt/Monkeysphere/MSVA/Client.pm b/Crypt/Monkeysphere/MSVA/Client.pm index a6d1ed7..623e9e8 100644 --- a/Crypt/Monkeysphere/MSVA/Client.pm +++ b/Crypt/Monkeysphere/MSVA/Client.pm @@ -108,7 +108,8 @@ } # remap raw pkc data into numeric array $transformed_data = [map(ord, split(//,$pkcdata))]; - } elsif ($pkctype eq 'x509pem') { + } elsif ($pkctype eq 'x509pem' || + $pkctype eq 'opensshpubkey') { $transformed_data = $pkcdata; } else { $self->log('error', "unknown pkc type '%s'.\n", $pkctype); -- 2.26.2