diff options
author | Junio C Hamano <gitster@pobox.com> | 2020-04-28 15:49:57 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2020-04-28 15:49:57 -0700 |
commit | 2abd648b17899679f9a76bfdeba8f620fa6fff21 (patch) | |
tree | 4ea2933f777ae25c343377eeb77132eed66a9614 /builtin/receive-pack.c | |
parent | Merge branch 'lr/freshen-file-fix' (diff) | |
parent | receive-pack: compilation fix (diff) | |
download | tgif-2abd648b17899679f9a76bfdeba8f620fa6fff21.tar.xz |
Merge branch 'bc/constant-memequal'
Validation of push certificate has been made more robust against
timing attacks.
* bc/constant-memequal:
receive-pack: compilation fix
builtin/receive-pack: use constant-time comparison for HMAC value
Diffstat (limited to 'builtin/receive-pack.c')
-rw-r--r-- | builtin/receive-pack.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index d46147f709..239094d2dc 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -499,12 +499,27 @@ static char *find_header(const char *msg, size_t len, const char *key, return NULL; } +/* + * Return zero if a and b are equal up to n bytes and nonzero if they are not. + * This operation is guaranteed to run in constant time to avoid leaking data. + */ +static int constant_memequal(const char *a, const char *b, size_t n) +{ + int res = 0; + size_t i; + + for (i = 0; i < n; i++) + res |= a[i] ^ b[i]; + return res; +} + static const char *check_nonce(const char *buf, size_t len) { char *nonce = find_header(buf, len, "nonce", NULL); timestamp_t stamp, ostamp; char *bohmac, *expect = NULL; const char *retval = NONCE_BAD; + size_t noncelen; if (!nonce) { retval = NONCE_MISSING; @@ -546,8 +561,14 @@ static const char *check_nonce(const char *buf, size_t len) goto leave; } + noncelen = strlen(nonce); expect = prepare_push_cert_nonce(service_dir, stamp); - if (strcmp(expect, nonce)) { + if (noncelen != strlen(expect)) { + /* This is not even the right size. */ + retval = NONCE_BAD; + goto leave; + } + if (constant_memequal(expect, nonce, noncelen)) { /* Not what we would have signed earlier */ retval = NONCE_BAD; goto leave; |