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