summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2020-04-28 22:49:57 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-04-28 22:49:57 (GMT)
commit2abd648b17899679f9a76bfdeba8f620fa6fff21 (patch)
tree4ea2933f777ae25c343377eeb77132eed66a9614
parent51a68dd287c86200f8da03ef105e2a5f00641a38 (diff)
parent719483e547a30819e3dbaa252f0e036e23efa561 (diff)
downloadgit-2abd648b17899679f9a76bfdeba8f620fa6fff21.zip
git-2abd648b17899679f9a76bfdeba8f620fa6fff21.tar.gz
git-2abd648b17899679f9a76bfdeba8f620fa6fff21.tar.bz2
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
-rw-r--r--builtin/receive-pack.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index d46147f..239094d 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;