Subject: [PATCH v6 0/9] ssh signing: Add commit & tag signing/verification via SSH keys using ssh-keygen

From: "Fabian Stelzer via GitGitGadget" <[email-masked]>
Date: Wed, 28 Jul 2021 19:36:40 +0000

I have added support for using keyfiles directly, lots of tests and
generally cleaned up the signing & verification code a lot.

I can still rename things from being gpg specific to a more general
"signing" but thats rather cosmetic. Also i'm not sure if i named the new
test files correctly.

openssh 8.7 will add valid-after, valid-before options to the allowed keys
keyring. This allows us to pass the commit timestamp to the verification
call and make key rollover possible and still be able to verify older
commits. Set valid-after=NOW when adding your key to the keyring and set
valid-before to make it fail if used after a certain date. Software like
gitolite/github or corporate automation can do this automatically when ssh
push keys are addded / removed I will add this feature in a follow up patch
afterwards.

v3 addresses some issues & refactoring and splits the large commit into
several smaller ones.

v4:

 * restructures and cleans up the whole patch set - patches build on its own
   now and commit messages try to explain whats going on
 * got rid of the if branches and used callback functions in the format
   struct
 * fixed a bug with whitespace in principal identifiers that required a
   rewrite of the parse_ssh_output function
 * rewrote documentation to be more clear - also renamed keyring back to
   allowedSignersFile

v5:

 * moved t7527 to t7528 to not collide with another patch in "seen"
 * clean up return logic for failed signing & verification
 * some minor renames / reformatting to make things clearer

v6: fixed tests when using shm output dir

Fabian Stelzer (9):
  ssh signing: preliminary refactoring and clean-up
  ssh signing: add ssh signature format and signing using ssh keys
  ssh signing: retrieve a default key from ssh-agent
  ssh signing: provide a textual representation of the signing key
  ssh signing: parse ssh-keygen output and verify signatures
  ssh signing: add test prereqs
  ssh signing: duplicate t7510 tests for commits
  ssh signing: add more tests for logs, tags & push certs
  ssh signing: add documentation

 Documentation/config/gpg.txt     |  39 ++-
 Documentation/config/user.txt    |   6 +
 builtin/receive-pack.c           |   2 +
 fmt-merge-msg.c                  |   6 +-
 gpg-interface.c                  | 490 +++++++++++++++++++++++++++----
 gpg-interface.h                  |   8 +-
 log-tree.c                       |   8 +-
 pretty.c                         |   4 +-
 send-pack.c                      |   8 +-
 t/lib-gpg.sh                     |  29 ++
 t/t4202-log.sh                   |  23 ++
 t/t5534-push-signed.sh           | 101 +++++++
 t/t7031-verify-tag-signed-ssh.sh | 161 ++++++++++
 t/t7528-signed-commit-ssh.sh     | 398 +++++++++++++++++++++++++
 14 files changed, 1218 insertions(+), 65 deletions(-)
 create mode 100755 t/t7031-verify-tag-signed-ssh.sh
 create mode 100755 t/t7528-signed-commit-ssh.sh

base-commit: eb27b338a3e71c7c4079fbac8aeae3f8fbb5c687
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1041%2FFStelzer%2Fsshsign-v6
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1041/FStelzer/sshsign-v6
Pull-Request: https://github.com/git/git/pull/1041

Range-diff vs v5:

  1:  7c8502c65b8 =  1:  7c8502c65b8 ssh signing: preliminary refactoring and clean-up
  2:  f05bab16096 =  2:  f05bab16096 ssh signing: add ssh signature format and signing using ssh keys
  3:  071e6173d8e =  3:  071e6173d8e ssh signing: retrieve a default key from ssh-agent
  4:  7d1d131ff5b =  4:  7d1d131ff5b ssh signing: provide a textual representation of the signing key
  5:  725764018ce =  5:  725764018ce ssh signing: parse ssh-keygen output and verify signatures
  6:  eb677b1b6a8 !  6:  18a26ca49e7 ssh signing: add test prereqs
     @@ t/lib-gpg.sh: test_lazy_prereq RFC1991 '
      +	test $? = 0 || exit 1;
      +	mkdir -p "${GNUPGHOME}" &&
      +	chmod 0700 "${GNUPGHOME}" &&
     -+	ssh-keygen -t ed25519 -N "" -f "${GNUPGHOME}/ed25519_ssh_signing_key" >/dev/null &&
     -+	ssh-keygen -t rsa -b 2048 -N "" -f "${GNUPGHOME}/rsa_2048_ssh_signing_key" >/dev/null &&
     -+	ssh-keygen -t ed25519 -N "super_secret" -f "${GNUPGHOME}/protected_ssh_signing_key" >/dev/null &&
     -+	find "${GNUPGHOME}" -name *ssh_signing_key.pub -exec cat {} \; | awk "{print \"\\\"principal with number \" NR \"\\\" \" \$0}" > "${GNUPGHOME}/ssh.all_valid.allowedSignersFile" &&
     ++	ssh-keygen -t ed25519 -N "" -C "git ed25519 key" -f "${GNUPGHOME}/ed25519_ssh_signing_key" >/dev/null &&
     ++	echo "\"principal with number 1\" $(cat "${GNUPGHOME}/ed25519_ssh_signing_key.pub")" >> "${GNUPGHOME}/ssh.all_valid.allowedSignersFile" &&
     ++	ssh-keygen -t rsa -b 2048 -N "" -C "git rsa2048 key" -f "${GNUPGHOME}/rsa_2048_ssh_signing_key" >/dev/null &&
     ++	echo "\"principal with number 2\" $(cat "${GNUPGHOME}/rsa_2048_ssh_signing_key.pub")" >> "${GNUPGHOME}/ssh.all_valid.allowedSignersFile" &&
     ++	ssh-keygen -t ed25519 -N "super_secret" -C "git ed25519 encrypted key" -f "${GNUPGHOME}/protected_ssh_signing_key" >/dev/null &&
     ++	echo "\"principal with number 3\" $(cat "${GNUPGHOME}/protected_ssh_signing_key.pub")" >> "${GNUPGHOME}/ssh.all_valid.allowedSignersFile" &&
      +	cat "${GNUPGHOME}/ssh.all_valid.allowedSignersFile" &&
      +	ssh-keygen -t ed25519 -N "" -f "${GNUPGHOME}/untrusted_ssh_signing_key" >/dev/null
      +'
  7:  c877951df23 =  7:  01da9a07934 ssh signing: duplicate t7510 tests for commits
  8:  60265e8c399 =  8:  d9707443f5c ssh signing: add more tests for logs, tags & push certs
  9:  f758ce0ade4 =  9:  275af516eba ssh signing: add documentation

-- 
gitgitgadget