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:
@ -212,9 +212,9 @@ out of what the server said it could do with the first 'want' line.
|
||||
want-list = first-want
|
||||
*additional-want
|
||||
|
||||
shallow-line = PKT_LINE("shallow" SP obj-id)
|
||||
shallow-line = PKT-LINE("shallow" SP obj-id)
|
||||
|
||||
depth-request = PKT_LINE("deepen" SP depth)
|
||||
depth-request = PKT-LINE("deepen" SP depth)
|
||||
|
||||
first-want = PKT-LINE("want" SP obj-id SP capability-list LF)
|
||||
additional-want = PKT-LINE("want" SP obj-id LF)
|
||||
@ -465,7 +465,7 @@ contain all the objects that the server will need to complete the new
|
||||
references.
|
||||
|
||||
----
|
||||
update-request = *shallow command-list [pack-file]
|
||||
update-request = *shallow ( command-list | push-cert ) [pack-file]
|
||||
|
||||
shallow = PKT-LINE("shallow" SP obj-id LF)
|
||||
|
||||
@ -481,12 +481,27 @@ references.
|
||||
old-id = obj-id
|
||||
new-id = obj-id
|
||||
|
||||
push-cert = PKT-LINE("push-cert" NUL capability-list LF)
|
||||
PKT-LINE("certificate version 0.1" LF)
|
||||
PKT-LINE("pusher" SP ident LF)
|
||||
PKT-LINE("pushee" SP url LF)
|
||||
PKT-LINE("nonce" SP nonce LF)
|
||||
PKT-LINE(LF)
|
||||
*PKT-LINE(command LF)
|
||||
*PKT-LINE(gpg-signature-lines LF)
|
||||
PKT-LINE("push-cert-end" LF)
|
||||
|
||||
pack-file = "PACK" 28*(OCTET)
|
||||
----
|
||||
|
||||
If the receiving end does not support delete-refs, the sending end MUST
|
||||
NOT ask for delete command.
|
||||
|
||||
If the receiving end does not support push-cert, the sending end
|
||||
MUST NOT send a push-cert command. When a push-cert command is
|
||||
sent, command-list MUST NOT be sent; the commands recorded in the
|
||||
push certificate is used instead.
|
||||
|
||||
The pack-file MUST NOT be sent if the only command used is 'delete'.
|
||||
|
||||
A pack-file MUST be sent if either create or update command is used,
|
||||
@ -501,6 +516,34 @@ was being processed (the obj-id is still the same as the old-id), and
|
||||
it will run any update hooks to make sure that the update is acceptable.
|
||||
If all of that is fine, the server will then update the references.
|
||||
|
||||
Push Certificate
|
||||
----------------
|
||||
|
||||
A push certificate begins with a set of header lines. After the
|
||||
header and an empty line, the protocol commands follow, one per
|
||||
line.
|
||||
|
||||
Currently, the following header fields are defined:
|
||||
|
||||
`pusher` ident::
|
||||
Identify the GPG key in "Human Readable Name <email@address>"
|
||||
format.
|
||||
|
||||
`pushee` url::
|
||||
The repository URL (anonymized, if the URL contains
|
||||
authentication material) the user who ran `git push`
|
||||
intended to push into.
|
||||
|
||||
`nonce` nonce::
|
||||
The 'nonce' string the receiving repository asked the
|
||||
pushing user to include in the certificate, to prevent
|
||||
replay attacks.
|
||||
|
||||
The GPG signature lines are a detached signature for the contents
|
||||
recorded in the push certificate before the signature block begins.
|
||||
The detached signature is used to certify that the commands were
|
||||
given by the pusher, who must be the signer.
|
||||
|
||||
Report Status
|
||||
-------------
|
||||
|
||||
|
||||
@ -18,8 +18,8 @@ was sent. Server MUST NOT ignore capabilities that client requested
|
||||
and server advertised. As a consequence of these rules, server MUST
|
||||
NOT advertise capabilities it does not understand.
|
||||
|
||||
The 'report-status', 'delete-refs', and 'quiet' capabilities are sent and
|
||||
recognized by the receive-pack (push to server) process.
|
||||
The 'report-status', 'delete-refs', 'quiet', and 'push-cert' capabilities
|
||||
are sent and recognized by the receive-pack (push to server) process.
|
||||
|
||||
The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized
|
||||
by both upload-pack and receive-pack protocols. The 'agent' capability
|
||||
@ -250,3 +250,12 @@ allow-tip-sha1-in-want
|
||||
If the upload-pack server advertises this capability, fetch-pack may
|
||||
send "want" lines with SHA-1s that exist at the server but are not
|
||||
advertised by upload-pack.
|
||||
|
||||
push-cert=<nonce>
|
||||
-----------------
|
||||
|
||||
The receive-pack server that advertises this capability is willing
|
||||
to accept a signed push certificate, and asks the <nonce> to be
|
||||
included in the push certificate. A send-pack client MUST NOT
|
||||
send a push-cert packet unless the receive-pack server advertises
|
||||
this capability.
|
||||
|
||||
Reference in New Issue
Block a user