Merge branch 'jc/push-cert'

Allow "git push" request to be signed, so that it can be verified and
audited, using the GPG signature of the person who pushed, that the
tips of branches at a public repository really point the commits
the pusher wanted to, without having to "trust" the server.

* jc/push-cert: (24 commits)
  receive-pack::hmac_sha1(): copy the entire SHA-1 hash out
  signed push: allow stale nonce in stateless mode
  signed push: teach smart-HTTP to pass "git push --signed" around
  signed push: fortify against replay attacks
  signed push: add "pushee" header to push certificate
  signed push: remove duplicated protocol info
  send-pack: send feature request on push-cert packet
  receive-pack: GPG-validate push certificates
  push: the beginning of "git push --signed"
  pack-protocol doc: typofix for PKT-LINE
  gpg-interface: move parse_signature() to where it should be
  gpg-interface: move parse_gpg_output() to where it should be
  send-pack: clarify that cmds_sent is a boolean
  send-pack: refactor inspecting and resetting status and sending commands
  send-pack: rename "new_refs" to "need_pack_data"
  receive-pack: factor out capability string generation
  send-pack: factor out capability string generation
  send-pack: always send capabilities
  send-pack: refactor decision to send update per ref
  send-pack: move REF_STATUS_REJECT_NODELETE logic a bit higher
  ...
This commit is contained in:
Junio C Hamano
2014-10-08 13:05:15 -07:00
23 changed files with 933 additions and 160 deletions

View File

@ -12,6 +12,7 @@ if test -n "$NO_CURL"; then
fi
ROOT_PATH="$PWD"
. "$TEST_DIRECTORY"/lib-gpg.sh
. "$TEST_DIRECTORY"/lib-httpd.sh
. "$TEST_DIRECTORY"/lib-terminal.sh
start_httpd
@ -338,5 +339,45 @@ test_expect_success CMDLINE_LIMIT 'push 2000 tags over http' '
run_with_limited_cmdline git push --mirror
'
test_expect_success GPG 'push with post-receive to inspect certificate' '
(
cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
mkdir -p hooks &&
write_script hooks/post-receive <<-\EOF &&
# discard the update list
cat >/dev/null
# record the push certificate
if test -n "${GIT_PUSH_CERT-}"
then
git cat-file blob $GIT_PUSH_CERT >../push-cert
fi &&
cat >../push-cert-status <<E_O_F
SIGNER=${GIT_PUSH_CERT_SIGNER-nobody}
KEY=${GIT_PUSH_CERT_KEY-nokey}
STATUS=${GIT_PUSH_CERT_STATUS-nostatus}
NONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}
NONCE=${GIT_PUSH_CERT_NONCE-nononce}
E_O_F
EOF
git config receive.certnonceseed sekrit &&
git config receive.certnonceslop 30
) &&
cd "$ROOT_PATH/test_repo_clone" &&
test_commit cert-test &&
git push --signed "$HTTPD_URL/smart/test_repo.git" &&
(
cd "$HTTPD_DOCUMENT_ROOT_PATH" &&
cat <<-\EOF &&
SIGNER=C O Mitter <committer@example.com>
KEY=13B6F51ECDDE430D
STATUS=G
NONCE_STATUS=OK
EOF
sed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" push-cert
) >expect &&
test_cmp expect "$HTTPD_DOCUMENT_ROOT_PATH/push-cert-status"
'
stop_httpd
test_done