From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B02C5C46466 for ; Wed, 12 May 2021 16:37:55 +0000 (UTC) Received: by mail.kernel.org (Postfix) id 7A91661006; Wed, 12 May 2021 16:37:55 +0000 (UTC) Received: by mail.kernel.org (Postfix) with ESMTPSA id 2CD4060BBB for ; Wed, 12 May 2021 16:37:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620837475; bh=05YMv1JgvcpaN5FJt9uLmgcTdQ3QFdt/FEln2TlkMr4=; h=From:List-Id:To:Subject:Date:From; b=Uzdx7Og1RznMfrr2HhNTFqNlsvRRfffDC/t3icUt0Ja1F1kZIeB+Jfix0igpkU6At OIQytKK8eZhfB0GGAW1bndtJkNRSZwNwOKr+zmeekYc6dRKALN1fPhxEAMVMDIx6dU acEkTznIQuGscMLRxiEnIad6VVDUJ0B5xp3hGbLI= From: Konstantin Ryabitsev List-Id: To: signatures@kernel.org Subject: [PATCH 1/3] Return better result than just pass/fail Date: Wed, 12 May 2021 16:37:52 +0000 Message-Id: <20210512163754.4865-1-konstantin@linuxfoundation.org> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1620837473; l=4532; h=from:subject; bh=05YMv1JgvcpaN5FJt9uLmgcTdQ3QFdt/FEln2TlkMr4=; b=k0/4rl3tIw1F1VogC07Xrlfnir+69mf1aYVeNd4wwR/RciS49CkkTWSR6dzaB0JYXZ0nA9sXzr7u B07OAxr1Bw0SDpGphlsEa/Sl8eFAHi0SsGO3nzUCq3x+ZQ5fkzcd X-Developer-Key: i=konstantin@linuxfoundation.org; a=ed25519; pk=9ciBWmyn5HjhDlbO11pAsl37cQv79bkr5meFI7Av/+w= Content-Transfer-Encoding: 8bit We want to pass some better information about why verification failed, if only because "we don't have a key" is not nearly as bad as "we have a key and it actively failed verification". Signed-off-by: Konstantin Ryabitsev --- patatt/__init__.py | 50 ++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/patatt/__init__.py b/patatt/__init__.py index 9ceaa29..be32e36 100644 --- a/patatt/__init__.py +++ b/patatt/__init__.py @@ -33,6 +33,13 @@ GPGBIN = 'gpg' # Hardcoded defaults DEVSIG_HDR = b'X-Developer-Signature' DEVKEY_HDR = b'X-Developer-Key' + +# Result and severity levels +RES_VALID = 0 +RES_NOKEY = 8 +RES_ERROR = 16 +RES_BADSIG = 32 + REQ_HDRS = [b'from', b'subject'] DEFAULT_CONFIG = { 'keyringsrc': ['ref::.keys', 'ref::.local-keys', 'ref:refs/meta/keyring:'], @@ -862,7 +869,7 @@ def validate_message(msgdata: bytes, sources: list, trim_body: bool = False) -> algo = 'openpgp' else: errors.append('%s/%s Unknown algorigthm: %s' % (i, s, a)) - attestations.append((False, i, t, None, a, errors)) + attestations.append((RES_ERROR, i, t, None, a, errors)) continue pkey = keysrc = None @@ -875,15 +882,15 @@ def validate_message(msgdata: bytes, sources: list, trim_body: bool = False) -> if not pkey and algo == 'ed25519': errors.append('%s/%s no matching ed25519 key found' % (i, s)) - attestations.append((False, i, t, None, algo, errors)) + attestations.append((RES_NOKEY, i, t, None, algo, errors)) continue try: signtime = pm.validate(i, pkey, trim_body=trim_body) - attestations.append((True, i, signtime, keysrc, algo, errors)) + attestations.append((RES_VALID, i, signtime, keysrc, algo, errors)) except ValidationError: errors.append('failed to validate using %s' % keysrc) - attestations.append((False, i, t, keysrc, algo, errors)) + attestations.append((RES_BADSIG, i, t, keysrc, algo, errors)) return attestations @@ -916,29 +923,38 @@ def cmd_validate(cmdargs, config: dict): else: trim_body = False - allgood = True + highest_err = 0 for fn, msgdata in messages.items(): try: attestations = validate_message(msgdata, sources, trim_body=trim_body) - for passing, identity, signtime, keysrc, algo, errors in attestations: - if passing: - logger.critical('PASS | %s | %s', identity, fn) + for result, identity, signtime, keysrc, algo, errors in attestations: + if result > highest_err: + highest_err = result + + if result == RES_VALID: + logger.critical(' PASS | %s, %s', identity, fn) if keysrc: - logger.info(' | key: %s', keysrc) + logger.info(' | key: %s', keysrc) else: - logger.info(' | key: default GnuPG keyring') + logger.info(' | key: default GnuPG keyring') + elif result <= RES_NOKEY: + logger.critical(' NOKEY | %s, %s', identity, fn) + for error in errors: + logger.critical(' | %s', error) + elif result <= RES_ERROR: + logger.critical(' ERROR | %s, %s', identity, fn) + for error in errors: + logger.critical(' | %s', error) else: - allgood = False - logger.critical('FAIL | %s | %s', identity, fn) + logger.critical('BADSIG | %s, %s', identity, fn) for error in errors: - logger.critical(' | %s', error) + logger.critical(' | %s', error) except RuntimeError as ex: - allgood = False - logger.critical('ERR | err: %s | %s', ex, fn) + highest_err = RES_ERROR + logger.critical(' ERROR | err: %s | %s', ex, fn) - if not allgood: - sys.exit(1) + sys.exit(highest_err) def cmd_genkey(cmdargs, config: dict) -> None: -- 2.25.1