mirror of
https://github.com/git/git.git
synced 2025-12-12 20:36:24 +01:00
A recent commit, d9cb0e6ff8 (fast-export, fast-import: add support for
signed-commits, 2025-03-10), added support for signed commits to
fast-export and fast-import.
When a signed commit is processed, fast-export can output either
"gpgsig sha1" or "gpgsig sha256" depending on whether the signed
commit uses the SHA-1 or SHA-256 Git object format.
However, this implementation has a number of limitations:
- the output format was not properly described in the documentation,
- the output format is not very informative as it doesn't even say
if the signature is an OpenPGP, an SSH, or an X509 signature,
- the implementation doesn't support having both one signature on
the SHA-1 object and one on the SHA-256 object.
Let's improve on these limitations by improving fast-export and
fast-import so that:
- all the signatures are exported,
- at most one signature on the SHA-1 object and one on the SHA-256
are imported,
- if there is more than one signature on the SHA-1 object or on
the SHA-256 object, fast-import emits a warning for each
additional signature,
- the output format is "gpgsig <git-hash-algo> <signature-format>",
where <git-hash-algo> is the Git object format as before, and
<signature-format> is the signature type ("openpgp", "x509",
"ssh" or "unknown"),
- the output is properly documented.
About the output format:
- <git-hash-algo> allows to know which representation of the commit
was signed (the SHA-1 or the SHA-256 version) which helps with
both signature verification and interoperability between repos
with different hash functions,
- <signature-format> helps tools that process the fast-export
stream, so they don't have to parse the ASCII armor to identify
the signature type.
It could be even better to be able to import more than one signature
on the SHA-1 object and on the SHA-256 object, but other parts of
Git don't handle that well for now, so this is left for future
improvements.
Helped-by: brian m. carlson <sandals@crustytoothpaste.net>
Helped-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
108 lines
2.7 KiB
C
108 lines
2.7 KiB
C
#ifndef GPG_INTERFACE_H
|
|
#define GPG_INTERFACE_H
|
|
|
|
struct strbuf;
|
|
|
|
#define GPG_VERIFY_VERBOSE 1
|
|
#define GPG_VERIFY_RAW 2
|
|
#define GPG_VERIFY_OMIT_STATUS 4
|
|
|
|
enum signature_trust_level {
|
|
TRUST_UNDEFINED,
|
|
TRUST_NEVER,
|
|
TRUST_MARGINAL,
|
|
TRUST_FULLY,
|
|
TRUST_ULTIMATE,
|
|
};
|
|
|
|
enum payload_type {
|
|
SIGNATURE_PAYLOAD_UNDEFINED,
|
|
SIGNATURE_PAYLOAD_COMMIT,
|
|
SIGNATURE_PAYLOAD_TAG,
|
|
SIGNATURE_PAYLOAD_PUSH_CERT,
|
|
};
|
|
|
|
struct signature_check {
|
|
char *payload;
|
|
size_t payload_len;
|
|
enum payload_type payload_type;
|
|
timestamp_t payload_timestamp;
|
|
char *output;
|
|
char *gpg_status;
|
|
|
|
/*
|
|
* possible "result":
|
|
* 0 (not checked)
|
|
* N (checked but no further result)
|
|
* G (good)
|
|
* B (bad)
|
|
*/
|
|
char result;
|
|
char *signer;
|
|
char *key;
|
|
char *fingerprint;
|
|
char *primary_key_fingerprint;
|
|
enum signature_trust_level trust_level;
|
|
};
|
|
|
|
void signature_check_clear(struct signature_check *sigc);
|
|
|
|
/*
|
|
* Return the format of the signature (like "openpgp", "x509", "ssh"
|
|
* or "unknown").
|
|
*/
|
|
const char *get_signature_format(const char *buf);
|
|
|
|
/*
|
|
* Is the signature format valid (like "openpgp", "x509", "ssh" or
|
|
* "unknown")
|
|
*/
|
|
int valid_signature_format(const char *format);
|
|
|
|
/*
|
|
* Look at a GPG signed tag object. If such a signature exists, store it in
|
|
* signature and the signed content in payload. Return 1 if a signature was
|
|
* found, and 0 otherwise.
|
|
*/
|
|
int parse_signature(const char *buf, size_t size, struct strbuf *payload, struct strbuf *signature);
|
|
|
|
/*
|
|
* Look at GPG signed content (e.g. a signed tag object), whose
|
|
* payload is followed by a detached signature on it. Return the
|
|
* offset where the embedded detached signature begins, or the end of
|
|
* the data when there is no such signature.
|
|
*/
|
|
size_t parse_signed_buffer(const char *buf, size_t size);
|
|
|
|
/*
|
|
* Create a detached signature for the contents of "buffer" and append
|
|
* it after "signature"; "buffer" and "signature" can be the same
|
|
* strbuf instance, which would cause the detached signature appended
|
|
* at the end. Returns 0 on success, non-zero on failure.
|
|
*/
|
|
int sign_buffer(struct strbuf *buffer, struct strbuf *signature,
|
|
const char *signing_key);
|
|
|
|
|
|
/*
|
|
* Returns corresponding string in lowercase for a given member of
|
|
* enum signature_trust_level. For example, `TRUST_ULTIMATE` will
|
|
* return "ultimate".
|
|
*/
|
|
const char *gpg_trust_level_to_str(enum signature_trust_level level);
|
|
|
|
void set_signing_key(const char *);
|
|
char *get_signing_key(void);
|
|
|
|
/*
|
|
* Returns a textual unique representation of the signing key in use
|
|
* Either a GPG KeyID or a SSH Key Fingerprint
|
|
*/
|
|
char *get_signing_key_id(void);
|
|
int check_signature(struct signature_check *sigc,
|
|
const char *signature, size_t slen);
|
|
void print_signature_buffer(const struct signature_check *sigc,
|
|
unsigned flags);
|
|
|
|
#endif
|