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@xxxxxxxxx>
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