git/gpg-interface.h
Fabian Stelzer 6393c956f4 ssh signing: make verify-commit consider key lifetime
If valid-before/after dates are configured for this signatures key in the
allowedSigners file then the verification should check if the key was valid at
the time the commit was made. This allows for graceful key rollover and
revoking keys without invalidating all previous commits.
This feature needs openssh > 8.8. Older ssh-keygen versions will simply
ignore this flag and use the current time.
Strictly speaking this feature is available in 8.7, but since 8.7 has a
bug that makes it unusable in another needed call we require 8.8.

Timestamp information is present on most invocations of check_signature.
However signer ident is not. We will need the signer email / name to be able
to implement "Trust on first use" functionality later.
Since the payload contains all necessary information we can parse it
from there. The caller only needs to provide us some info about the
payload by setting payload_type in the signature_check struct.

 - Add payload_type field & enum and payload_timestamp to struct
   signature_check
 - Populate the timestamp when not already set if we know about the
   payload type
 - Pass -Overify-time={payload_timestamp} in the users timezone to all
   ssh-keygen verification calls
 - Set the payload type when verifying commits
 - Add tests for expired, not yet valid and keys having a commit date
   outside of key validity as well as within

Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-09 13:38:04 -08:00

89 lines
2.2 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);
/*
* 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.
*/
int sign_buffer(struct strbuf *buffer, struct strbuf *signature,
const char *signing_key);
int git_gpg_config(const char *, const char *, void *);
void set_signing_key(const char *);
const 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
*/
const 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