Thread (4 messages) 4 messages, 2 authors, 2019-03-01

Re: [PATCH] libkmod-signature: use PKCS7 for LibreSSL or older OpenSSL

From: Lucas De Marchi <hidden>
Date: 2019-02-15 08:04:34

On Fri, Feb 15, 2019 at 06:13:40AM +0200, Stefan Strogin wrote:
Linux kernel uses either PKCS #7 or CMS signing modules (scripts/sign-file.c).
CMS is not supported by LibreSSL, PKCS #7 is used instead.
For now modinfo used CMS with no altenative requiring >=openssl-1.1.0
built with CMS support.

Use PKCS #7 for parsing module signature information when CMS is not available.

Signed-off-by: Stefan Strogin <redacted>
ooh, this ifdef is messy. Why do we want both libressl and openssl? What
distro is requiring that?

if in the end we end up with ifdefs for N different libs I'd rather just
add the implementation in kmod itself or convince kernel guys to just
fill out the struct they are supposed to fill.

Lucas De Marchi
quoted hunk ↗ jump to hunk
---
libkmod/libkmod-signature.c | 78 +++++++++++++++++++++++++++++++++++--
1 file changed, 75 insertions(+), 3 deletions(-)
diff --git a/libkmod/libkmod-signature.c b/libkmod/libkmod-signature.c
index 48d0145..aa2a60e 100644
--- a/libkmod/libkmod-signature.c
+++ b/libkmod/libkmod-signature.c
@@ -20,9 +20,16 @@
#include <endian.h>
#include <inttypes.h>
#ifdef ENABLE_OPENSSL
-#include <openssl/cms.h>
-#include <openssl/ssl.h>
-#endif
+# include <openssl/ssl.h>
+# if defined(LIBRESSL_VERSION_NUMBER) || \
+	OPENSSL_VERSION_NUMBER < 0x10100000L || \
+	defined(OPENSSL_NO_CMS)
+#  define USE_PKCS7
+#  include <openssl/pkcs7.h>
+# else
+#  include <openssl/cms.h>
+# endif /* LIBRESSL_VERSION_NUMBER */
+#endif /* ENABLE_OPENSSL */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -122,7 +129,11 @@ static bool fill_default(const char *mem, off_t size,
#ifdef ENABLE_OPENSSL

struct pkcs7_private {
+#ifndef USE_PKCS7
	CMS_ContentInfo *cms;
+#else
+	PKCS7 *pkcs7;
+#endif
	unsigned char *key_id;
	BIGNUM *sno;
};
@@ -132,7 +143,11 @@ static void pkcs7_free(void *s)
	struct kmod_signature_info *si = s;
	struct pkcs7_private *pvt = si->private;

+#ifndef USE_PKCS7
	CMS_ContentInfo_free(pvt->cms);
+#else
+	PKCS7_free(pvt->pkcs7);
+#endif
	BN_free(pvt->sno);
	free(pvt->key_id);
	free(pvt);
@@ -187,7 +202,13 @@ static const char *x509_name_to_str(X509_NAME *name)
		return NULL;

	d = X509_NAME_ENTRY_get_data(e);
+#if (defined(LIBRESSL_VERSION_NUMBER) && \
+		LIBRESSL_VERSION_NUMBER < 0x20700000L) || \
+	OPENSSL_VERSION_NUMBER < 0x10100000L
+	str = (const char *)ASN1_STRING_data(d);
+#else
	str = (const char *)ASN1_STRING_get0_data(d);
+#endif

	return str;
}
@@ -197,11 +218,18 @@ static bool fill_pkcs7(const char *mem, off_t size,
		       struct kmod_signature_info *sig_info)
{
	const char *pkcs7_raw;
+#ifndef USE_PKCS7
	CMS_ContentInfo *cms;
	STACK_OF(CMS_SignerInfo) *sis;
	CMS_SignerInfo *si;
	int rc;
	ASN1_OCTET_STRING *key_id;
+#else
+	PKCS7 *pkcs7;
+	STACK_OF(PKCS7_SIGNER_INFO) *sis;
+	PKCS7_SIGNER_INFO *si;
+	PKCS7_ISSUER_AND_SERIAL *is;
+#endif
	X509_NAME *issuer;
	ASN1_INTEGER *sno;
	ASN1_OCTET_STRING *sig;
@@ -220,14 +248,23 @@ static bool fill_pkcs7(const char *mem, off_t size,
	in = BIO_new_mem_buf(pkcs7_raw, sig_len);

+#ifndef USE_PKCS7
	cms = d2i_CMS_bio(in, NULL);
	if (cms == NULL) {
		BIO_free(in);
		return false;
	}
+#else
+	pkcs7 = d2i_PKCS7_bio(in, NULL);
+	if (pkcs7 == NULL) {
+		BIO_free(in);
+		return false;
+	}
+#endif

	BIO_free(in);

+#ifndef USE_PKCS7
	sis = CMS_get0_SignerInfos(cms);
	if (sis == NULL)
		goto err;
@@ -245,8 +282,35 @@ static bool fill_pkcs7(const char *mem, off_t size,
		goto err;

	CMS_SignerInfo_get0_algs(si, NULL, NULL, &dig_alg, &sig_alg);
+#else
+	sis = PKCS7_get_signer_info(pkcs7);
+	if (sis == NULL)
+		goto err;
+
+	si = sk_PKCS7_SIGNER_INFO_value(sis, 0);
+	if (si == NULL)
+		goto err;
+
+	is = si->issuer_and_serial;
+	if (is == NULL)
+		goto err;
+	issuer = is->issuer;
+	sno = is->serial;
+
+	sig = si->enc_digest;
+	if (sig == NULL)
+		goto err;
+
+	PKCS7_SIGNER_INFO_get0_algs(si, NULL, &dig_alg, &sig_alg);
+#endif

+#if (defined(LIBRESSL_VERSION_NUMBER) && \
+		LIBRESSL_VERSION_NUMBER < 0x20700000L) || \
+	OPENSSL_VERSION_NUMBER < 0x10100000L
+	sig_info->sig = (const char *)ASN1_STRING_data(sig);
+#else
	sig_info->sig = (const char *)ASN1_STRING_get0_data(sig);
+#endif
	sig_info->sig_len = ASN1_STRING_length(sig);

	sno_bn = ASN1_INTEGER_to_BN(sno, NULL);
@@ -277,7 +341,11 @@ static bool fill_pkcs7(const char *mem, off_t size,
	if (pvt == NULL)
		goto err3;

+#ifndef USE_PKCS7
	pvt->cms = cms;
+#else
+	pvt->pkcs7 = pkcs7;
+#endif
	pvt->key_id = key_id_str;
	pvt->sno = sno_bn;
	sig_info->private = pvt;
@@ -290,7 +358,11 @@ err3:
err2:
	BN_free(sno_bn);
err:
+#ifndef USE_PKCS7
	CMS_ContentInfo_free(cms);
+#else
+	PKCS7_free(pkcs7);
+#endif
	return false;
}

-- 
2.20.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help