CVE-2021-4076 (Other, published 2022-03-02T23:15Z)
Description: value: A flaw exists in tang, a network-based cryptographic binding server, which could result in leak of private keys.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: NVD-CWE-noinfo \u2014 Insufficient Information
There is insufficient information about the issue to classify it; details are unkown or unspecified.
Repository: https://github.com/latchset/tang
Files changed:
src/keys.c
tests/adv
tests/helpers
tests/rec
tests/test-keys.c.in
Commit message: keys: move signing part out of find_by_thp() and to find_jws() (#81)

Handle just signing keys in find_jws(), to make sure we are
responding only to proper queries.

Tests were also failing to detect this issue and were updated
accordingly.

Issue discovered by Twitter Kernel and OS team during a source
code audit while evaluating Tang/Clevis for their needs.

Fixes CVE-2021-4076

Vulnerable code:

            if (jwk_valid_for_deriving_keys(jwk)) {
                return json_incref(jwk);
            } else if (jwk_valid_for_signing(jwk)) {
                json_auto_t* sign = json_deep_copy(tki->m_sign);
                if (json_array_append(sign, jwk) == -1) {
                    return NULL;
                }
                json_auto_t* jws = jwk_sign(tki->m_payload, sign);
                if (!jws) {
                    return NULL;
                }
                return json_incref(jws);
            }
    return find_by_thp(tki, thp);
! fetch /
! fetch /adv/`jose jwk thp -i $TMP/db/exc.jwk`
! fetch /adv/`jose jwk thp -a S512 -i $TMP/db/exc.jwk`
! fetch /adv/`jose jwk thp -i $TMP/db/sig.jwk` | ver $TMP/db/.sig.jwk
! fetch /adv/`jose jwk thp -i $TMP/db/sig.jwk` | ver $TMP/db/.oth.jwk
! fetch /adv/ | ver $TMP/db/.oth.jwk
! fetch /adv/ | ver $TMP/db/.sig.jwk
! fetch /adv/`jose jwk thp -i $TMP/db/.sig.jwk` | ver $TMP/db/.oth.jwk
! curl -sf http://127.0.0.1:$PORT/rec
! curl -sf http://127.0.0.1:$PORT/rec/

Fixed code:
            return json_incref(jwk);

    json_auto_t* jwk = find_by_thp(tki, thp);
    if (!jwk_valid_for_signing(jwk)) {
        return NULL;
    }

    json_auto_t* sign = json_deep_copy(tki->m_sign);
    if (json_array_append(sign, jwk) == -1) {
        return NULL;
    }
    json_auto_t* jws = jwk_sign(tki->m_payload, sign);
    if (!jws) {
        return NULL;
    }
    return json_incref(jws);
fetch / && expected_fail
fetch /adv/`jose jwk thp -i $TMP/db/exc.jwk` && expected_fail
fetch /adv/`jose jwk thp -a S512 -i $TMP/db/exc.jwk` && expected_fail
fetch /adv/`jose jwk thp -i $TMP/db/sig.jwk` | ver $TMP/db/.sig.jwk && expected_fail
fetch /adv/`jose jwk thp -i $TMP/db/sig.jwk` | ver $TMP/db/.oth.jwk && expected_fail
fetch /adv/ | ver $TMP/db/.oth.jwk && expected_fail
fetch /adv/ | ver $TMP/db/.sig.jwk && expected_fail
fetch /adv/`jose jwk thp -i $TMP/db/.sig.jwk` | ver $TMP/db/.oth.jwk && expected_fail

expected_fail () {
    echo "Test was expected to fail" >&2
    exit 1
}
curl -sf http://127.0.0.1:$PORT/rec && expected_fail
curl -sf http://127.0.0.1:$PORT/rec/ && expected_fail
        {"-bWkGaJi0Zdvxaj4DCp28umLcRA", 0},
        {"WEpfFyeoNKkE2-TosN_bP-gd9UgRvQCZpVasZQ", 0},
        {"L4xg2tZXTEVbsK39bzOZM1jGWn3HtOxF5gh6F9YVf5Q", 0},
        {"9U8qgy_YjyY6Isuq6QuiKEiYZgNJShcGgJx5FJzCu6m3N6zFaIPy_HDkxkVqAZ9E", 0},
        {"Cy73glFjs6B6RU7wy6vWxAc-2bJy5VJOT9LyK80eKgZ8k27wXZ-3rjsuNU5tua_yHWtluyoSYtjoKXfI0E8ESw", 0},