* [PATCH] libkmod-signature: use PKCS7 for LibreSSL or older OpenSSL
@ 2019-02-15 4:13 Stefan Strogin
2019-02-15 8:04 ` Lucas De Marchi
0 siblings, 1 reply; 4+ messages in thread
From: Stefan Strogin @ 2019-02-15 4:13 UTC (permalink / raw)
To: linux-modules; +Cc: stefan.strogin, ykaliuta, lucas.demarchi
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 <stefan.strogin@gmail.com>
---
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
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] libkmod-signature: use PKCS7 for LibreSSL or older OpenSSL
2019-02-15 4:13 [PATCH] libkmod-signature: use PKCS7 for LibreSSL or older OpenSSL Stefan Strogin
@ 2019-02-15 8:04 ` Lucas De Marchi
2019-02-15 13:30 ` Stefan Strogin
0 siblings, 1 reply; 4+ messages in thread
From: Lucas De Marchi @ 2019-02-15 8:04 UTC (permalink / raw)
To: Stefan Strogin; +Cc: linux-modules, ykaliuta
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 <stefan.strogin@gmail.com>
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
>---
> 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
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] libkmod-signature: use PKCS7 for LibreSSL or older OpenSSL
2019-02-15 8:04 ` Lucas De Marchi
@ 2019-02-15 13:30 ` Stefan Strogin
2019-03-01 5:37 ` Stefan Strogin
0 siblings, 1 reply; 4+ messages in thread
From: Stefan Strogin @ 2019-02-15 13:30 UTC (permalink / raw)
To: Lucas De Marchi; +Cc: linux-modules, ykaliuta
On 15/02/2019 10:04, Lucas De Marchi wrote:
>
> ooh, this ifdef is messy. Why do we want both libressl and openssl? What
> distro is requiring that?
Well, in the kernel in scripts/sign-file.c the same ifdefs are used.
Every distro that tries to support LibreSSL requires that. I know at least
Gentoo [1], Alpine and Void.
> 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.
If you don't like ifdefs at all I would say that CMS is not needed. CMS and
PKCS#7 formats are very similar. CMS is newer but is as much as possible
backward compatible [2], but PKCS#7 is better supported. PKCS#7 has all the same
fields that are used when a kernel module is signed using CMS (and otherwise).
For example I can sign a module using OpenSSL-1.1.1 and CMS (even with hashes
other than sha1) and read its signing information with modinfo and PKCS#7 on a
system with LibreSSL, and otherwise.
So we can just replace CMS with PKCS#7 in fill_pkcs7().
[1] https://bugs.gentoo.org/677960
[2] https://tools.ietf.org/html/rfc5652#section-1.1
--
Stefan
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] libkmod-signature: use PKCS7 for LibreSSL or older OpenSSL
2019-02-15 13:30 ` Stefan Strogin
@ 2019-03-01 5:37 ` Stefan Strogin
0 siblings, 0 replies; 4+ messages in thread
From: Stefan Strogin @ 2019-03-01 5:37 UTC (permalink / raw)
To: Lucas De Marchi; +Cc: linux-modules, ykaliuta
Hi Lucas,
Is there any chance for accepting this patch?
Or could you tell me how it can be reworked so that modinfo would support PKCS#7
(and LibreSSL)?
--
Stefan
On 15/02/2019 15:30, Stefan Strogin wrote:
> On 15/02/2019 10:04, Lucas De Marchi wrote:
>>
>> ooh, this ifdef is messy. Why do we want both libressl and openssl? What
>> distro is requiring that?
>
> Well, in the kernel in scripts/sign-file.c the same ifdefs are used.
>
> Every distro that tries to support LibreSSL requires that. I know at least
> Gentoo [1], Alpine and Void.
>
>> 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.
>
> If you don't like ifdefs at all I would say that CMS is not needed. CMS and
> PKCS#7 formats are very similar. CMS is newer but is as much as possible
> backward compatible [2], but PKCS#7 is better supported. PKCS#7 has all the same
> fields that are used when a kernel module is signed using CMS (and otherwise).
> For example I can sign a module using OpenSSL-1.1.1 and CMS (even with hashes
> other than sha1) and read its signing information with modinfo and PKCS#7 on a
> system with LibreSSL, and otherwise.
>
> So we can just replace CMS with PKCS#7 in fill_pkcs7().
>
> [1] https://bugs.gentoo.org/677960
> [2] https://tools.ietf.org/html/rfc5652#section-1.1
>
> --
> Stefan
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-03-01 5:37 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-15 4:13 [PATCH] libkmod-signature: use PKCS7 for LibreSSL or older OpenSSL Stefan Strogin
2019-02-15 8:04 ` Lucas De Marchi
2019-02-15 13:30 ` Stefan Strogin
2019-03-01 5:37 ` Stefan Strogin
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 NNTP newsgroup(s).