Keyrings Archive mirror
 help / color / mirror / Atom feed
From: Roberto Sassu <roberto.sassu@huaweicloud.com>
To: dhowells@redhat.com, dwmw2@infradead.org,
	herbert@gondor.apana.org.au, davem@davemloft.net
Cc: linux-kernel@vger.kernel.org, keyrings@vger.kernel.org,
	linux-crypto@vger.kernel.org, zohar@linux.ibm.com,
	linux-integrity@vger.kernel.org,
	Roberto Sassu <roberto.sassu@huawei.com>
Subject: [PATCH v2 10/14] KEYS: Calculate key digest and get signature of the key
Date: Sun, 18 Aug 2024 18:57:52 +0200	[thread overview]
Message-ID: <20240818165756.629203-11-roberto.sassu@huaweicloud.com> (raw)
In-Reply-To: <20240818165756.629203-1-roberto.sassu@huaweicloud.com>

From: Roberto Sassu <roberto.sassu@huawei.com>

Calculate the digest of the signature, according to the RFC4880 section
5.2.4, get the last suitable signature with types 0x10 (Generic
certification of a User ID and Public-Key packet) or 0x13 (Positive
certification of a User ID and Public Key packet), and store it in the
asym_auth field of the key payload, so that it is available for validating
a restriction on a keyring.

Type 0x10 is included despite not giving the strongest trust guarantees,
since it is the one used by most common PGP implementations (including
gpg).

The rationale of taking the last signature is that, if there are multiple
signatures, that would be of a different issuer (not a self-signature),
that likely has more chances to be useful for the restriction verification.
If there is one (the self-signature), that will be used.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 crypto/asymmetric_keys/pgp_public_key.c | 81 +++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/crypto/asymmetric_keys/pgp_public_key.c b/crypto/asymmetric_keys/pgp_public_key.c
index e7f74d513a9e..91678cbdc196 100644
--- a/crypto/asymmetric_keys/pgp_public_key.c
+++ b/crypto/asymmetric_keys/pgp_public_key.c
@@ -14,6 +14,7 @@
 #include <keys/asymmetric-parser.h>
 #include <crypto/hash.h>
 #include <crypto/public_key.h>
+#include <crypto/pgp.h>
 
 #include "pgp_parser.h"
 
@@ -61,6 +62,8 @@ struct pgp_key_data_parse_context {
 	size_t raw_fingerprint_len;
 	const char *user_id;
 	size_t user_id_len;
+	const char *key_pkt;
+	size_t key_pkt_len;
 };
 
 /*
@@ -226,6 +229,12 @@ static int pgp_process_public_key(struct pgp_parse_context *context,
 		return -EBADMSG;
 	}
 
+	/* Pointer refers to data being processed. */
+	if (type == PGP_PKT_PUBLIC_KEY) {
+		ctx->key_pkt = data;
+		ctx->key_pkt_len = datalen;
+	}
+
 	pub = kzalloc(sizeof(*pub), GFP_KERNEL);
 	if (!pub)
 		return -ENOMEM;
@@ -316,6 +325,77 @@ pgp_key_generate_id(struct pgp_key_data_parse_context *ctx)
 	return NULL;
 }
 
+/*
+ * Calculate the digest of the signature according to the RFC4880, section
+ * 5.2.4 (packet type 0x13).
+ */
+static int pgp_key_add_sig_data(struct pgp_key_data_parse_context *ctx,
+				struct pgp_sig_verify *sig_ctx)
+{
+	loff_t offset = 0;
+	u8 *data;
+
+	if (!ctx->key_pkt_len || !ctx->user_id_len)
+		return 0;
+
+	/* 0x99 + key pkt len + key pkt + 0xb4 + user ID len + user ID */
+	data = kmalloc(1 + sizeof(u16) + ctx->key_pkt_len +
+		       1 + sizeof(u32) + ctx->user_id_len, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data[offset++] = 0x99;
+	data[offset++] = ctx->key_pkt_len >> 8;
+	data[offset++] = ctx->key_pkt_len;
+
+	memcpy(data + offset, ctx->key_pkt, ctx->key_pkt_len);
+	offset += ctx->key_pkt_len;
+
+	if (pgp_sig_get_version(sig_ctx) == PGP_SIG_VERSION_4) {
+		data[offset++] = 0xb4;
+		data[offset++] = ctx->user_id_len >> 24;
+		data[offset++] = ctx->user_id_len >> 16;
+		data[offset++] = ctx->user_id_len >> 8;
+		data[offset++] = ctx->user_id_len;
+	}
+
+	memcpy(data + offset, ctx->user_id, ctx->user_id_len);
+	offset += ctx->user_id_len;
+
+	pgp_sig_add_data(sig_ctx, data, offset);
+	kfree(data);
+	return 0;
+}
+
+static struct public_key_signature *
+pgp_key_get_sig(struct key_preparsed_payload *prep,
+		struct pgp_key_data_parse_context *ctx)
+{
+	struct public_key_signature *sig = NULL;
+	struct pgp_sig_verify *sig_ctx;
+	bool keep_sig = false;
+	int ret;
+
+	sig_ctx = pgp_sig_parse(prep->data, prep->datalen);
+	if (IS_ERR(sig_ctx))
+		return NULL;
+
+	ret = pgp_key_add_sig_data(ctx, sig_ctx);
+	if (ret < 0)
+		goto out;
+
+	sig = pgp_sig_get_sig(sig_ctx, true);
+	if (IS_ERR(sig)) {
+		sig = NULL;
+		goto out;
+	}
+
+	keep_sig = true;
+out:
+	pgp_sig_verify_cancel(sig_ctx, keep_sig);
+	return sig;
+}
+
 /*
  * Attempt to parse the instantiation data blob for a key as a PGP packet
  * message holding a key.
@@ -380,6 +460,7 @@ static int pgp_key_parse(struct key_preparsed_payload *prep)
 	prep->payload.data[asym_subtype] = &public_key_subtype;
 	prep->payload.data[asym_key_ids] = pgp_key_generate_id(&ctx);
 	prep->payload.data[asym_crypto] = ctx.pub;
+	prep->payload.data[asym_auth] = pgp_key_get_sig(prep, &ctx);
 	prep->quotalen = 100;
 	return 0;
 
-- 
2.34.1


  parent reply	other threads:[~2024-08-18 17:01 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-18 16:57 [PATCH v2 00/14] KEYS: Add support for PGP keys and signatures Roberto Sassu
2024-08-18 16:57 ` [PATCH v2 01/14] mpi: Introduce mpi_key_length() Roberto Sassu
2024-08-19 17:55   ` Jarkko Sakkinen
2024-08-18 16:57 ` [PATCH v2 02/14] rsa: add parser of raw format Roberto Sassu
2024-08-19 17:56   ` Jarkko Sakkinen
2024-08-18 16:57 ` [PATCH v2 03/14] PGPLIB: PGP definitions (RFC 4880) Roberto Sassu
2024-08-18 16:57 ` [PATCH v2 04/14] PGPLIB: Basic packet parser Roberto Sassu
2024-08-19 14:34   ` Jeff Johnson
2024-08-19 15:06     ` Roberto Sassu
2024-08-18 16:57 ` [PATCH v2 05/14] PGPLIB: Signature parser Roberto Sassu
2024-08-18 16:57 ` [PATCH v2 06/14] KEYS: PGP data parser Roberto Sassu
2024-08-19 14:36   ` Jeff Johnson
2024-08-19 14:38     ` Roberto Sassu
2024-08-18 16:57 ` [PATCH v2 07/14] KEYS: Provide PGP key description autogeneration Roberto Sassu
2024-08-18 16:57 ` [PATCH v2 08/14] KEYS: PGP-based public key signature verification Roberto Sassu
2024-08-18 16:57 ` [PATCH v2 09/14] KEYS: Retry asym key search with partial ID in restrict_link_by_signature() Roberto Sassu
2024-08-18 16:57 ` Roberto Sassu [this message]
2024-08-18 16:57 ` [PATCH v2 11/14] verification: introduce verify_pgp_signature() Roberto Sassu
2024-08-18 16:57 ` [PATCH v2 12/14] PGP: Provide a key type for testing PGP signatures Roberto Sassu
2024-08-19 14:37   ` Jeff Johnson
2024-08-18 16:57 ` [PATCH v2 13/14] KEYS: Provide a function to load keys from a PGP keyring blob Roberto Sassu
2024-08-18 16:57 ` [PATCH v2 14/14] KEYS: Introduce load_pgp_public_keyring() Roberto Sassu
2024-08-19 15:08 ` [PATCH v2 00/14] KEYS: Add support for PGP keys and signatures Jonathan McDowell
2024-08-19 15:15   ` Roberto Sassu
2024-08-20 14:12     ` Jonathan McDowell
2024-08-20 14:14       ` Roberto Sassu
2024-09-10 14:36       ` Roberto Sassu
2024-09-10 14:51         ` Roberto Sassu
2024-09-10 15:16           ` Jonathan McDowell
2024-09-11  9:55             ` Roberto Sassu
2024-08-19 16:30 ` Roberto Sassu
2024-08-19 17:53 ` Jarkko Sakkinen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240818165756.629203-11-roberto.sassu@huaweicloud.com \
    --to=roberto.sassu@huaweicloud.com \
    --cc=davem@davemloft.net \
    --cc=dhowells@redhat.com \
    --cc=dwmw2@infradead.org \
    --cc=herbert@gondor.apana.org.au \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=roberto.sassu@huawei.com \
    --cc=zohar@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).