From 06457313dba7156361e9ae53d6d557295ba23c22 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Fri, 29 Oct 2010 03:49:08 -0400 Subject: [PATCH] added support for rfc4716-style SSH pubkeys --- Changelog | 6 +++--- Crypt/Monkeysphere/MSVA.pm | 36 +++++++++++++++++++++++++++++++ Crypt/Monkeysphere/MSVA/Client.pm | 4 +++- tests/basic | 12 ++++++++--- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/Changelog b/Changelog index 6c50e6c..df1a6e7 100644 --- a/Changelog +++ b/Changelog @@ -12,10 +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 and opensshpubkey PKC formats in addition to x509der - (addresses MS #2566) + * support x509pem, opensshpubkey, and rfc4716 PKC formats in addition to + x509der (addresses MS #2566) - -- Daniel Kahn Gillmor Fri, 29 Oct 2010 02:55:37 -0400 + -- Daniel Kahn Gillmor Fri, 29 Oct 2010 03:48:50 -0400 msva-perl (0.5) upstream; diff --git a/Crypt/Monkeysphere/MSVA.pm b/Crypt/Monkeysphere/MSVA.pm index d1d6b12..b92821b 100755 --- a/Crypt/Monkeysphere/MSVA.pm +++ b/Crypt/Monkeysphere/MSVA.pm @@ -145,6 +145,40 @@ return $out; } + sub rfc47162key { + my $data = shift; + + my @goodlines; + my $continuation = ''; + my $state = 'outside'; + foreach my $line (split(/\n/, $data)) { + last if ($state eq 'body' && $line eq '---- END SSH2 PUBLIC KEY ----'); + if ($state eq 'outside' && $line eq '---- BEGIN SSH2 PUBLIC KEY ----') { + $state = 'header'; + next; + } + if ($state eq 'header') { + $line = $continuation.$line; + $continuation = ''; + if ($line =~ /^(.*)\\$/) { + $continuation = $1; + next; + } + if (! ($line =~ /:/)) { + $state = 'body'; + } + } + push(@goodlines, $line) if ($state eq 'body'); + } + + msvalog('debug', "Found %d lines of RFC4716 body:\n%s\n", + scalar(@goodlines), + join("\n", @goodlines)); + my $out = parse_rfc4716body(join('', @goodlines)); + + return $out; + } + sub parse_rfc4716body { my $data = shift; $data = decode_base64($data) or return undef; @@ -573,6 +607,8 @@ $key = der2key(pem2der($data->{pkc}->{data})); } elsif (lc($data->{pkc}->{type}) eq 'opensshpubkey') { $key = opensshpubkey2key($data->{pkc}->{data}); + } elsif (lc($data->{pkc}->{type}) eq 'rfc4716') { + $key = rfc47162key($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 623e9e8..9b3991d 100644 --- a/Crypt/Monkeysphere/MSVA/Client.pm +++ b/Crypt/Monkeysphere/MSVA/Client.pm @@ -109,7 +109,9 @@ # remap raw pkc data into numeric array $transformed_data = [map(ord, split(//,$pkcdata))]; } elsif ($pkctype eq 'x509pem' || - $pkctype eq 'opensshpubkey') { + $pkctype eq 'opensshpubkey' || + $pkctype eq 'rfc4716' + ) { $transformed_data = $pkcdata; } else { $self->log('error', "unknown pkc type '%s'.\n", $pkctype); diff --git a/tests/basic b/tests/basic index c36099f..8605b13 100755 --- a/tests/basic +++ b/tests/basic @@ -25,6 +25,8 @@ srcdir=$(dirname $0)/.. REPS=5 +CERTTYPES="x509pem x509der opensshpubkey rfc4716" + printf "testing %d reps of simple/quick true/false:\n" "$REPS" for n in $(seq 1 "$REPS") ; do "${srcdir}"/test-msva msva-perl true @@ -55,6 +57,7 @@ for name in x y z ; do chmod 0400 "${WORKDIR}/sec/${name}.key" openssl x509 -inform DER -outform PEM < "${WORKDIR}/pkc/${name}.x509der" > "${WORKDIR}/pkc/${name}.x509pem" ssh-keygen -y -P '' -f "${WORKDIR}/sec/${name}.key" > "${WORKDIR}/pkc/${name}.opensshpubkey" + ssh-keygen -e -P '' -f "${WORKDIR}/sec/${name}.key" > "${WORKDIR}/pkc/${name}.rfc4716" done # translate X and Y's keys into OpenPGP cert @@ -65,7 +68,7 @@ done runtests() { # X should not validate as X or Y or Z: for name in x y z; do - for ctype in x509pem x509der opensshpubkey; do + for ctype in $CERTTYPES; do ! "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https "${name}.example.net" "${ctype}" < "${WORKDIR}/pkc/x.${ctype}" done done @@ -73,11 +76,13 @@ runtests() { # certify X's OpenPGP cert with CA gpg --batch --yes --sign-key https://x.example.net + echo "Testing bad data:" # it should fail if we pass it the wrong kind of data: ! "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https x.example.net "x509der" < "${WORKDIR}/pkc/x.x509pem" ! "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https x.example.net "x509pem" < "${WORKDIR}/pkc/x.x509der" + echo "Done testing bad data." - for ctype in x509pem x509der opensshpubkey; do + for ctype in $CERTTYPES; do # X should now validate as X "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https x.example.net "${ctype}" < "${WORKDIR}/pkc/x.${ctype}" @@ -95,8 +100,9 @@ runtests() { done } +set -x MSVA_KEYSERVER_POLICY=never runtests - +set +x echo "Completed all tests as expected!" rm -rf "$WORKDIR" -- 2.26.2