All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Richard W.M. Jones" <rjones@redhat.com>
To: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
	qemu-block@nongnu.org, Markus Armbruster <armbru@redhat.com>,
	qemu-devel@nongnu.org, Max Reitz <mreitz@redhat.com>,
	Eric Blake <eblake@redhat.com>
Subject: Re: [PATCH] block/ssh: add support for sha256 host key fingerprints
Date: Tue, 22 Jun 2021 13:04:19 +0100	[thread overview]
Message-ID: <20210622120419.GE26415@redhat.com> (raw)
In-Reply-To: <20210622115156.138458-1-berrange@redhat.com>

On Tue, Jun 22, 2021 at 12:51:56PM +0100, Daniel P. Berrangé wrote:
> Currently the SSH block driver supports MD5 and SHA1 for host key
> fingerprints. This is a cryptographically sensitive operation and
> so these hash algorithms are inadequate by modern standards. This
> adds support for SHA256 which has been supported in libssh since
> the 0.8.1 release.
> 
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>

Patch looks sensible:

  Acked-by: Richard W.M. Jones <rjones@redhat.com>

Would you mind taking a look at nbdkit-ssh-plugin?  This is arguably
more important (for Red Hat) since we no longer use the SSH driver in
qemu for V2V and switched to using nbdkit some time ago.  The
nbdkit-ssh-plugin appears to only support SHA1 from a cursory look.

Rich.

> 
> Note I can't actually get iotest '207' to fully pass. It always
> complains that it can't validate the "known_hosts" file
> 
>   qemu-img: Could not open 'TEST_IMG': no host key was found in known_hosts
> 
> it seems to rely on some specific developer host setup that my
> laptop doesn't satisfy. It would be useful if any pre-requisite
> could be documented in the iotest.
> 
> At least the sha256 verification step I added to 207 does pass
> though.
> 
>  block/ssh.c                |  3 +++
>  qapi/block-core.json       |  3 ++-
>  tests/qemu-iotests/207     | 54 ++++++++++++++++++++++++++++++++++++++
>  tests/qemu-iotests/207.out | 25 ++++++++++++++++++
>  4 files changed, 84 insertions(+), 1 deletion(-)
> 
> diff --git a/block/ssh.c b/block/ssh.c
> index b51a031620..d008caf059 100644
> --- a/block/ssh.c
> +++ b/block/ssh.c
> @@ -442,6 +442,9 @@ static int check_host_key(BDRVSSHState *s, SshHostKeyCheck *hkc, Error **errp)
>          } else if (hkc->u.hash.type == SSH_HOST_KEY_CHECK_HASH_TYPE_SHA1) {
>              return check_host_key_hash(s, hkc->u.hash.hash,
>                                         SSH_PUBLICKEY_HASH_SHA1, errp);
> +        } else if (hkc->u.hash.type == SSH_HOST_KEY_CHECK_HASH_TYPE_SHA256) {
> +            return check_host_key_hash(s, hkc->u.hash.hash,
> +                                       SSH_PUBLICKEY_HASH_SHA256, errp);
>          }
>          g_assert_not_reached();
>          break;
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index 2ea294129e..4247dc46a5 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -3186,11 +3186,12 @@
>  #
>  # @md5: The given hash is an md5 hash
>  # @sha1: The given hash is an sha1 hash
> +# @sha256: The given hash is an sha256 hash
>  #
>  # Since: 2.12
>  ##
>  { 'enum': 'SshHostKeyCheckHashType',
> -  'data': [ 'md5', 'sha1' ] }
> +  'data': [ 'md5', 'sha1', 'sha256' ] }
>  
>  ##
>  # @SshHostKeyHash:
> diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207
> index f9f3fd7131..0f5c4bc8a0 100755
> --- a/tests/qemu-iotests/207
> +++ b/tests/qemu-iotests/207
> @@ -73,6 +73,9 @@ with iotests.FilePath('t.img') as disk_path, \
>      iotests.log("=== Test host-key-check options ===")
>      iotests.log("")
>  
> +    iotests.log("--- no host key checking --")
> +    iotests.log("")
> +
>      vm.launch()
>      blockdev_create(vm, { 'driver': 'ssh',
>                            'location': {
> @@ -90,6 +93,9 @@ with iotests.FilePath('t.img') as disk_path, \
>  
>      iotests.img_info_log(remote_path)
>  
> +    iotests.log("--- known_hosts key checking --")
> +    iotests.log("")
> +
>      vm.launch()
>      blockdev_create(vm, { 'driver': 'ssh',
>                            'location': {
> @@ -115,6 +121,7 @@ with iotests.FilePath('t.img') as disk_path, \
>      # Mappings of base64 representations to digests
>      md5_keys = {}
>      sha1_keys = {}
> +    sha256_keys = {}
>  
>      for key in keys:
>          md5_keys[key] = subprocess.check_output(
> @@ -125,6 +132,10 @@ with iotests.FilePath('t.img') as disk_path, \
>              'echo %s | base64 -d | sha1sum -b | cut -d" " -f1' % key,
>              shell=True).rstrip().decode('ascii')
>  
> +        sha256_keys[key] = subprocess.check_output(
> +            'echo %s | base64 -d | sha256sum -b | cut -d" " -f1' % key,
> +            shell=True).rstrip().decode('ascii')
> +
>      vm.launch()
>  
>      # Find correct key first
> @@ -150,6 +161,9 @@ with iotests.FilePath('t.img') as disk_path, \
>          vm.shutdown()
>          iotests.notrun('Did not find a key that fits 127.0.0.1')
>  
> +    iotests.log("--- explicit md5 key checking --")
> +    iotests.log("")
> +
>      blockdev_create(vm, { 'driver': 'ssh',
>                            'location': {
>                                'path': disk_path,
> @@ -164,6 +178,7 @@ with iotests.FilePath('t.img') as disk_path, \
>                                }
>                            },
>                            'size': 2097152 })
> +
>      blockdev_create(vm, { 'driver': 'ssh',
>                            'location': {
>                                'path': disk_path,
> @@ -182,6 +197,9 @@ with iotests.FilePath('t.img') as disk_path, \
>  
>      iotests.img_info_log(remote_path)
>  
> +    iotests.log("--- explicit sha1 key checking --")
> +    iotests.log("")
> +
>      vm.launch()
>      blockdev_create(vm, { 'driver': 'ssh',
>                            'location': {
> @@ -215,6 +233,42 @@ with iotests.FilePath('t.img') as disk_path, \
>  
>      iotests.img_info_log(remote_path)
>  
> +    iotests.log("--- explicit sha256 key checking --")
> +    iotests.log("")
> +
> +    vm.launch()
> +    blockdev_create(vm, { 'driver': 'ssh',
> +                          'location': {
> +                              'path': disk_path,
> +                              'server': {
> +                                  'host': '127.0.0.1',
> +                                  'port': '22'
> +                              },
> +                              'host-key-check': {
> +                                  'mode': 'hash',
> +                                  'type': 'sha256',
> +                                  'hash': 'wrong',
> +                              }
> +                          },
> +                          'size': 2097152 })
> +    blockdev_create(vm, { 'driver': 'ssh',
> +                          'location': {
> +                              'path': disk_path,
> +                              'server': {
> +                                  'host': '127.0.0.1',
> +                                  'port': '22'
> +                              },
> +                              'host-key-check': {
> +                                  'mode': 'hash',
> +                                  'type': 'sha256',
> +                                  'hash': sha256_keys[matching_key],
> +                              }
> +                          },
> +                          'size': 4194304 })
> +    vm.shutdown()
> +
> +    iotests.img_info_log(remote_path)
> +
>      #
>      # Invalid path and user
>      #
> diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out
> index 1239d9d648..aeb8569d77 100644
> --- a/tests/qemu-iotests/207.out
> +++ b/tests/qemu-iotests/207.out
> @@ -16,6 +16,8 @@ virtual size: 4 MiB (4194304 bytes)
>  
>  === Test host-key-check options ===
>  
> +--- no host key checking --
> +
>  {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "none"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 8388608}}}
>  {"return": {}}
>  {"execute": "job-dismiss", "arguments": {"id": "job0"}}
> @@ -25,6 +27,8 @@ image: TEST_IMG
>  file format: IMGFMT
>  virtual size: 8 MiB (8388608 bytes)
>  
> +--- known_hosts key checking --
> +
>  {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "known_hosts"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}}
>  {"return": {}}
>  {"execute": "job-dismiss", "arguments": {"id": "job0"}}
> @@ -34,6 +38,8 @@ image: TEST_IMG
>  file format: IMGFMT
>  virtual size: 4 MiB (4194304 bytes)
>  
> +--- explicit md5 key checking --
> +
>  {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "wrong", "mode": "hash", "type": "md5"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 2097152}}}
>  {"return": {}}
>  Job failed: remote host key does not match host_key_check 'wrong'
> @@ -49,6 +55,8 @@ image: TEST_IMG
>  file format: IMGFMT
>  virtual size: 8 MiB (8388608 bytes)
>  
> +--- explicit sha1 key checking --
> +
>  {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "wrong", "mode": "hash", "type": "sha1"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 2097152}}}
>  {"return": {}}
>  Job failed: remote host key does not match host_key_check 'wrong'
> @@ -64,6 +72,23 @@ image: TEST_IMG
>  file format: IMGFMT
>  virtual size: 4 MiB (4194304 bytes)
>  
> +--- explicit sha256 key checking --
> +
> +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "wrong", "mode": "hash", "type": "sha256"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 2097152}}}
> +{"return": {}}
> +Job failed: remote host key does not match host_key_check 'wrong'
> +{"execute": "job-dismiss", "arguments": {"id": "job0"}}
> +{"return": {}}
> +
> +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "HASH", "mode": "hash", "type": "sha256"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}}
> +{"return": {}}
> +{"execute": "job-dismiss", "arguments": {"id": "job0"}}
> +{"return": {}}
> +
> +image: TEST_IMG
> +file format: IMGFMT
> +virtual size: 4 MiB (4194304 bytes)
> +
>  === Invalid path and user ===
>  
>  {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "none"}, "path": "/this/is/not/an/existing/path", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}}
> -- 
> 2.31.1

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines.  Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top



  reply	other threads:[~2021-06-22 12:07 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-22 11:51 [PATCH] block/ssh: add support for sha256 host key fingerprints Daniel P. Berrangé
2021-06-22 12:04 ` Richard W.M. Jones [this message]
2021-06-22 12:27 ` Philippe Mathieu-Daudé
2021-06-30 10:52 ` Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210622120419.GE26415@redhat.com \
    --to=rjones@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=eblake@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.