From 03d3d89cdcae262065dbafd72d0d88d052cfc56b Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Sun, 10 Oct 2021 03:31:22 -0400 Subject: get-host-keys command is working The command fetches and validates the host key of a self-authenticating cryptonomic url. Then it tries to log in on the server and obtain proof of all the system's other host keys. That way, we can use SSH to share the RSA key that Strongswan needs. But still use ed25519 for the primary identity in the URL. This is the functionality that needs to be incorporated into 'cryptonomic-vpn' to make ed25519.cryptonomic.net urls work. --- get-host-keys | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ notes/update-host-keys | 26 --------------- 2 files changed, 89 insertions(+), 26 deletions(-) create mode 100755 get-host-keys delete mode 100755 notes/update-host-keys diff --git a/get-host-keys b/get-host-keys new file mode 100755 index 0000000..f55b6cd --- /dev/null +++ b/get-host-keys @@ -0,0 +1,89 @@ +#!/bin/sh +die() +{ + printf "Error: %s\n" "$*" >&2 + exit 1 +} + +b16_to_b32() +{ + printf %s "$1" | basez -x -d | basez -j -l | tr -d = +} + +to_domain_suffix() +{ + local hashtype=2 + local keystring keytype sshfp_b16 sshfp_b32 + [ -f "$1" ] || return + [ -s "$1" ] || return + sshfp_raw=$(ssh-keygen -r . -f "$1" | grep -E -e "^. IN SSHFP [0-9]+ $hashtype ") + case "$sshfp_raw" in + '. IN SSHFP 1 '*) keytype=1; keystring=rsa ;; + '. IN SSHFP 4 '*) keytype=4; keystring=ed25519 ;; + *) return 1 ;; + esac + sshfp_b16=$(printf '%s' "$sshfp_raw" | sed -ne "s/^. IN SSHFP $keytype $hashtype //p") && + [ "$sshfp_b16" ] || die "could not determine ssh client fingerprint" + sshfp_b32=$(b16_to_b32 "$sshfp_b16") + + printf %s.%s.%s "$sshfp_b32" "$keystring" cryptonomic.net | tail -c64 +} + +crypto_validate_hostname() +{ + local host="$1" t r + t=$(mktemp) + case "$host" in + *.ed25519.cryptonomic.net) + ssh-keyscan -t ed25519 "$host" 2>/dev/null | while read h keytype keydata comment + do + case "$h $keytype" in + "$host ssh-ed25519") + echo "$keytype $keydata" >> "$t" + break + ;; + esac + done ;; + *) die "unsupported hostname: $host" ;; + esac + if validated=$(to_domain_suffix "$t") + then + case "$host" in + "$validated" | *."$validated" ) + read line < "$t" + echo "$host $line" + rm -f "$t" + return 0 + ;; + esac + fi + rm -f "$t" + false +} + +set -e +_TEMP_DIR_=$(mktemp -d) +cd "$_TEMP_DIR_" +trap 'rm -rf "$_TEMP_DIR_"' EXIT +host=${1:-borges} + +# ssh-keygen -F "${host#*@}" | grep -v '^#' > ssh_known_hosts 2>/dev/null +# touch ssh_known_hosts.stamp -r ssh_known_hosts + +line=$(crypto_validate_hostname "$host") || die "could not validate hostname cryptographically" + +echo "$line" > ssh_known_hosts +cp ssh_known_hosts ssh_known_hosts~ + +ssh \ + -F /dev/null \ + -o GlobalKnownHostsFile=$PWD/ssh_known_hosts \ + -o UserKnownHostsFile=$PWD/ssh_known_hosts \ + -o UpdateHostKeys=yes \ + -o PasswordAuthentication=no \ + -o StrictHostKeyChecking=yes \ + -n -T \ + "$host" >/dev/null 2>&1 + +cat ssh_known_hosts + diff --git a/notes/update-host-keys b/notes/update-host-keys deleted file mode 100755 index 4ef0e0b..0000000 --- a/notes/update-host-keys +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -set -e -_TEMP_DIR_=$(mktemp -d) -cd "$_TEMP_DIR_" -trap 'rm -rf "$_TEMP_DIR_"' EXIT -host=${1:-borges} -ssh-keygen -F "${host#*@}" | grep -v '^#' > ssh_known_hosts 2>/dev/null -touch ssh_known_hosts.stamp -r ssh_known_hosts - -ssh() -{ - command ssh \ - -F /dev/null \ - -o GlobalKnownHostsFile=$PWD/ssh_known_hosts \ - -o UserKnownHostsFile=$PWD/ssh_known_hosts \ - -o UpdateHostKeys=yes \ - -o PasswordAuthentication=no \ - -o StrictHostKeyChecking=yes \ - "$@" -} - -have=ecdsa-sha2-nistp256 -want=rsa-sha2-256 -ssh -q -n "$host" || true - -cat ssh_known_hosts -- cgit v1.2.3