Skip to content

Unable to pull and verify images signed with a GPG *subkey* ("None of the signatures were accepted") #16406

@faern

Description

@faern

/kind bug

Description

I'm unable to pull and verify an image signed with a GPG subkey, but it works fine if the image was signed directly with the main/master key. It is good practice to work with subkeys and only use the main GPG key for signing the subkeys. But this recommended workflow does not currently work with podman for me. I have tried this with both ed25519 and rsa4096 keys, same issue. I run podman in rootless mode and have not tried this in root mode.

Steps to reproduce the issue:

~/.config/containers/registries.d/default.yaml:

default-docker:
  sigstore: file:///home/faern/sandbox/sigstore
  sigstore-staging: file:///home/faern/sandbox/sigstore

~/.config/containers/policy.json:

{
  "default": [{ "type": "insecureAcceptAnything" }],
  "transports": {
    "docker": {
      "ghcr.io": [
        {
          "type": "signedBy",
          "keyType": "GPGKeys",
          "keyPath": "/home/faern/sandbox/key.pub"
        }
      ]
    }
  }
}

GPG key:

$ gpg ~/sandbox/key.pub
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
pub   rsa4096 2022-10-26 [SC]
      8716EC50A50A9744EF8F573DE163D46385F9421A
uid           Podman Testsign (For signing podman images) <[email protected]>
sub   rsa4096 2022-11-04 [S]

Dockerfile (probably reproducible with any type of image you sign):

FROM alpine:latest

LABEL org.opencontainers.image.description="Testing signatures"

Commands:

  1. podman build . --sign-by=8716EC50A50A9744EF8F573DE163D46385F9421A -t ghcr.io/faern/faern-sign-test
  2. podman push --sign-by=8716EC50A50A9744EF8F573DE163D46385F9421A ghcr.io/faern/faern-sign-test
  3. podman rmi ghcr.io/faern/faern-sign-test
  4. podman pull --log-level debug ghcr.io/faern/faern-sign-test

Describe the results you received:

Output of the podman pull command above:

...
DEBU[0000] IsRunningImageAllowed for image docker:ghcr.io/faern/faern-sign-test:latest
DEBU[0000]  Using transport "docker" specific policy section ghcr.io/faern
DEBU[0000] Reading /home/faern/sandbox/sigstore/faern/faern-sign-test@sha256=f8c1f88edfe198a8321ee13d822179cfe1c36cc45b1ae40d39d10166ae1b3bd7/signature-1
DEBU[0000] Reading /home/faern/sandbox/sigstore/faern/faern-sign-test@sha256=f8c1f88edfe198a8321ee13d822179cfe1c36cc45b1ae40d39d10166ae1b3bd7/signature-2
DEBU[0000] Reading /home/faern/sandbox/sigstore/faern/faern-sign-test@sha256=f8c1f88edfe198a8321ee13d822179cfe1c36cc45b1ae40d39d10166ae1b3bd7/signature-3
DEBU[0000] Not looking for sigstore attachments: disabled by configuration
DEBU[0000] Requirement 0: denied, done
DEBU[0000] Error pulling candidate ghcr.io/faern/faern-sign-test:latest: Source image rejected: None of the signatures were accepted, reasons: Signature by key 73C091A52C48057289DC3AB98981BCE19E42BD72 is not accepted; Signature by key 73C091A52C48057289DC3AB98981BCE19E42BD72 is not accepted
Error: Source image rejected: None of the signatures were accepted, reasons: Signature by key 73C091A52C48057289DC3AB98981BCE19E42BD72 is not accepted; Signature by key 73C091A52C48057289DC3AB98981BCE19E42BD72 is not accepted

73C091A52C48057289DC3AB98981BCE19E42BD72 is the fingerprint of the signing subkey.

However, the signature files that podman push produced are valid:

$ gpg --verify ~/sandbox/sigstore/faern/faern-sign-test\@sha256\=f8c1f88edfe198a8321ee13d822179cfe1c36cc45b1ae40d39d10166ae1b3bd7/signature-1
gpg: Signature made fre  4 nov 2022 11:03:36 CET
gpg:                using RSA key 73C091A52C48057289DC3AB98981BCE19E42BD72
gpg: Good signature from "Podman Testsign (For signing podman images) <[email protected]>" [ultimate]
$ gpg --verify ~/sandbox/sigstore/faern/faern-sign-test\@sha256\=f8c1f88edfe198a8321ee13d822179cfe1c36cc45b1ae40d39d10166ae1b3bd7/signature-2
gpg: Signature made fre  4 nov 2022 11:04:15 CET
gpg:                using RSA key 73C091A52C48057289DC3AB98981BCE19E42BD72
gpg: Good signature from "Podman Testsign (For signing podman images) <[email protected]>" [ultimate]

If I remove the subkey from the GPG key:

$ gpg --edit-key 8716EC50A50A9744EF8F573DE163D46385F9421A
gpg> key 1
gpg> delkey
Do you really want to delete this key? (y/N) y
gpg> save

... And re-run the commands above. Then it works fine. Output of the podman pull:

...
DEBU[0000] IsRunningImageAllowed for image docker:ghcr.io/faern/faern-sign-test:latest
DEBU[0000]  Using transport "docker" specific policy section ghcr.io/faern
DEBU[0000] Reading /home/faern/sandbox/sigstore/faern/faern-sign-test@sha256=36418b737decb41c363b0f5182d864f5e1466d7b17f724fd1ab0577aceb58728/signature-1
DEBU[0000] Reading /home/faern/sandbox/sigstore/faern/faern-sign-test@sha256=36418b737decb41c363b0f5182d864f5e1466d7b17f724fd1ab0577aceb58728/signature-2
DEBU[0000] Reading /home/faern/sandbox/sigstore/faern/faern-sign-test@sha256=36418b737decb41c363b0f5182d864f5e1466d7b17f724fd1ab0577aceb58728/signature-3
DEBU[0000] Not looking for sigstore attachments: disabled by configuration
DEBU[0000]  Requirement 0: allowed
DEBU[0000] Overall: allowed
...

Describe the results you expected:

I would expect to be able to verify images signed with GPG subkeys. This works fine with regular gpg (gpg --sign + gpg --verify) and is often the recommended setup of your keys.

Additional information you deem important (e.g. issue happens only occasionally):

Output of podman version:

Client:       Podman Engine
Version:      4.2.1
API Version:  4.2.1
Go Version:   go1.18.5
Built:        Wed Sep  7 21:58:19 2022
OS/Arch:      linux/amd64

Output of podman info:

host:
  arch: amd64
  buildahVersion: 1.27.0
  cgroupControllers:
  - cpu
  - io
  - memory
  - pids
  cgroupManager: systemd
  cgroupVersion: v2
  conmon:
    package: conmon-2.1.4-3.fc36.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.1.4, commit: '
  cpuUtilization:
    idlePercent: 95.28
    systemPercent: 1.2
    userPercent: 3.52
  cpus: 8
  distribution:
    distribution: fedora
    variant: workstation
    version: "36"
  eventLogger: journald
  hostname: mole
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
  kernel: 5.18.16-200.fc36.x86_64
  linkmode: dynamic
  logDriver: journald
  memFree: 2302832640
  memTotal: 33347612672
  networkBackend: netavark
  ociRuntime:
    name: crun
    package: crun-1.6-2.fc36.x86_64
    path: /usr/bin/crun
    version: |-
      crun version 1.6
      commit: 18cf2efbb8feb2b2f20e316520e0fd0b6c41ef4d
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +YAJL
  os: linux
  remoteSocket:
    path: /run/user/1000/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: true
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: true
  serviceIsRemote: false
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns-1.2.0-0.2.beta.0.fc36.x86_64
    version: |-
      slirp4netns version 1.2.0-beta.0
      commit: 477db14a24ff1a3de3a705e51ca2c4c1fe3dda64
      libslirp: 4.6.1
      SLIRP_CONFIG_VERSION_MAX: 3
      libseccomp: 2.5.3
  swapFree: 5250170880
  swapTotal: 8589930496
  uptime: 1419h 36m 47.00s (Approximately 59.12 days)
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  volume:
  - local
registries:
  search:
  - registry.fedoraproject.org
  - registry.access.redhat.com
  - docker.io
  - quay.io
store:
  configFile: /home/faern/.config/containers/storage.conf
  containerStore:
    number: 1
    paused: 0
    running: 0
    stopped: 1
  graphDriverName: overlay
  graphOptions: {}
  graphRoot: /home/faern/.local/share/containers/storage
  graphRootAllocated: 1022487429120
  graphRootUsed: 279608852480
  graphStatus:
    Backing Filesystem: btrfs
    Native Overlay Diff: "true"
    Supports d_type: "true"
    Using metacopy: "false"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 69
  runRoot: /run/user/1000/containers
  volumePath: /home/faern/.local/share/containers/storage/volumes
version:
  APIVersion: 4.2.1
  Built: 1662580699
  BuiltTime: Wed Sep  7 21:58:19 2022
  GitCommit: ""
  GoVersion: go1.18.5
  Os: linux
  OsArch: linux/amd64
  Version: 4.2.1

GnuPG version:

gpg (GnuPG) 2.3.7
libgcrypt 1.10.1-unknown
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /home/faern/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
AEAD: EAX, OCB
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

Package info (e.g. output of rpm -q podman or apt list podman or brew info podman):

podman-4.2.1-2.fc36.x86_64

Have you tested with the latest version of Podman and have you checked the Podman Troubleshooting Guide? (https://github.com/containers/podman/blob/main/troubleshooting.md)

I have tested with 4.2.1 as it's the newest version in my distro. But I can't see anything about sigstores or GPG in the release notes for the newer versions. Also nothing on this reported in the issue tracker. So I doubt it's fixed in 4.3.0.

The troubleshooting guide has nothing on sigstores or GPG.

Additional environment details (AWS, VirtualBox, physical, etc.):

Physical machines with Fedora 36.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.locked - please file new issue/PRAssist humans wanting to comment on an old issue or PR with locked comments.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions