Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* PKCS#7 parser
0003  *
0004  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
0005  * Written by David Howells (dhowells@redhat.com)
0006  */
0007 
0008 #define pr_fmt(fmt) "PKCS7: "fmt
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/export.h>
0012 #include <linux/slab.h>
0013 #include <linux/err.h>
0014 #include <linux/oid_registry.h>
0015 #include <crypto/public_key.h>
0016 #include "pkcs7_parser.h"
0017 #include "pkcs7.asn1.h"
0018 
0019 MODULE_DESCRIPTION("PKCS#7 parser");
0020 MODULE_AUTHOR("Red Hat, Inc.");
0021 MODULE_LICENSE("GPL");
0022 
0023 struct pkcs7_parse_context {
0024     struct pkcs7_message    *msg;       /* Message being constructed */
0025     struct pkcs7_signed_info *sinfo;    /* SignedInfo being constructed */
0026     struct pkcs7_signed_info **ppsinfo;
0027     struct x509_certificate *certs;     /* Certificate cache */
0028     struct x509_certificate **ppcerts;
0029     unsigned long   data;           /* Start of data */
0030     enum OID    last_oid;       /* Last OID encountered */
0031     unsigned    x509_index;
0032     unsigned    sinfo_index;
0033     const void  *raw_serial;
0034     unsigned    raw_serial_size;
0035     unsigned    raw_issuer_size;
0036     const void  *raw_issuer;
0037     const void  *raw_skid;
0038     unsigned    raw_skid_size;
0039     bool        expect_skid;
0040 };
0041 
0042 /*
0043  * Free a signed information block.
0044  */
0045 static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
0046 {
0047     if (sinfo) {
0048         public_key_signature_free(sinfo->sig);
0049         kfree(sinfo);
0050     }
0051 }
0052 
0053 /**
0054  * pkcs7_free_message - Free a PKCS#7 message
0055  * @pkcs7: The PKCS#7 message to free
0056  */
0057 void pkcs7_free_message(struct pkcs7_message *pkcs7)
0058 {
0059     struct x509_certificate *cert;
0060     struct pkcs7_signed_info *sinfo;
0061 
0062     if (pkcs7) {
0063         while (pkcs7->certs) {
0064             cert = pkcs7->certs;
0065             pkcs7->certs = cert->next;
0066             x509_free_certificate(cert);
0067         }
0068         while (pkcs7->crl) {
0069             cert = pkcs7->crl;
0070             pkcs7->crl = cert->next;
0071             x509_free_certificate(cert);
0072         }
0073         while (pkcs7->signed_infos) {
0074             sinfo = pkcs7->signed_infos;
0075             pkcs7->signed_infos = sinfo->next;
0076             pkcs7_free_signed_info(sinfo);
0077         }
0078         kfree(pkcs7);
0079     }
0080 }
0081 EXPORT_SYMBOL_GPL(pkcs7_free_message);
0082 
0083 /*
0084  * Check authenticatedAttributes are provided or not provided consistently.
0085  */
0086 static int pkcs7_check_authattrs(struct pkcs7_message *msg)
0087 {
0088     struct pkcs7_signed_info *sinfo;
0089     bool want = false;
0090 
0091     sinfo = msg->signed_infos;
0092     if (!sinfo)
0093         goto inconsistent;
0094 
0095     if (sinfo->authattrs) {
0096         want = true;
0097         msg->have_authattrs = true;
0098     }
0099 
0100     for (sinfo = sinfo->next; sinfo; sinfo = sinfo->next)
0101         if (!!sinfo->authattrs != want)
0102             goto inconsistent;
0103     return 0;
0104 
0105 inconsistent:
0106     pr_warn("Inconsistently supplied authAttrs\n");
0107     return -EINVAL;
0108 }
0109 
0110 /**
0111  * pkcs7_parse_message - Parse a PKCS#7 message
0112  * @data: The raw binary ASN.1 encoded message to be parsed
0113  * @datalen: The size of the encoded message
0114  */
0115 struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
0116 {
0117     struct pkcs7_parse_context *ctx;
0118     struct pkcs7_message *msg = ERR_PTR(-ENOMEM);
0119     int ret;
0120 
0121     ctx = kzalloc(sizeof(struct pkcs7_parse_context), GFP_KERNEL);
0122     if (!ctx)
0123         goto out_no_ctx;
0124     ctx->msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL);
0125     if (!ctx->msg)
0126         goto out_no_msg;
0127     ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
0128     if (!ctx->sinfo)
0129         goto out_no_sinfo;
0130     ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
0131                   GFP_KERNEL);
0132     if (!ctx->sinfo->sig)
0133         goto out_no_sig;
0134 
0135     ctx->data = (unsigned long)data;
0136     ctx->ppcerts = &ctx->certs;
0137     ctx->ppsinfo = &ctx->msg->signed_infos;
0138 
0139     /* Attempt to decode the signature */
0140     ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen);
0141     if (ret < 0) {
0142         msg = ERR_PTR(ret);
0143         goto out;
0144     }
0145 
0146     ret = pkcs7_check_authattrs(ctx->msg);
0147     if (ret < 0) {
0148         msg = ERR_PTR(ret);
0149         goto out;
0150     }
0151 
0152     msg = ctx->msg;
0153     ctx->msg = NULL;
0154 
0155 out:
0156     while (ctx->certs) {
0157         struct x509_certificate *cert = ctx->certs;
0158         ctx->certs = cert->next;
0159         x509_free_certificate(cert);
0160     }
0161 out_no_sig:
0162     pkcs7_free_signed_info(ctx->sinfo);
0163 out_no_sinfo:
0164     pkcs7_free_message(ctx->msg);
0165 out_no_msg:
0166     kfree(ctx);
0167 out_no_ctx:
0168     return msg;
0169 }
0170 EXPORT_SYMBOL_GPL(pkcs7_parse_message);
0171 
0172 /**
0173  * pkcs7_get_content_data - Get access to the PKCS#7 content
0174  * @pkcs7: The preparsed PKCS#7 message to access
0175  * @_data: Place to return a pointer to the data
0176  * @_data_len: Place to return the data length
0177  * @_headerlen: Size of ASN.1 header not included in _data
0178  *
0179  * Get access to the data content of the PKCS#7 message.  The size of the
0180  * header of the ASN.1 object that contains it is also provided and can be used
0181  * to adjust *_data and *_data_len to get the entire object.
0182  *
0183  * Returns -ENODATA if the data object was missing from the message.
0184  */
0185 int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
0186                const void **_data, size_t *_data_len,
0187                size_t *_headerlen)
0188 {
0189     if (!pkcs7->data)
0190         return -ENODATA;
0191 
0192     *_data = pkcs7->data;
0193     *_data_len = pkcs7->data_len;
0194     if (_headerlen)
0195         *_headerlen = pkcs7->data_hdrlen;
0196     return 0;
0197 }
0198 EXPORT_SYMBOL_GPL(pkcs7_get_content_data);
0199 
0200 /*
0201  * Note an OID when we find one for later processing when we know how
0202  * to interpret it.
0203  */
0204 int pkcs7_note_OID(void *context, size_t hdrlen,
0205            unsigned char tag,
0206            const void *value, size_t vlen)
0207 {
0208     struct pkcs7_parse_context *ctx = context;
0209 
0210     ctx->last_oid = look_up_OID(value, vlen);
0211     if (ctx->last_oid == OID__NR) {
0212         char buffer[50];
0213         sprint_oid(value, vlen, buffer, sizeof(buffer));
0214         printk("PKCS7: Unknown OID: [%lu] %s\n",
0215                (unsigned long)value - ctx->data, buffer);
0216     }
0217     return 0;
0218 }
0219 
0220 /*
0221  * Note the digest algorithm for the signature.
0222  */
0223 int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
0224                    unsigned char tag,
0225                    const void *value, size_t vlen)
0226 {
0227     struct pkcs7_parse_context *ctx = context;
0228 
0229     switch (ctx->last_oid) {
0230     case OID_md4:
0231         ctx->sinfo->sig->hash_algo = "md4";
0232         break;
0233     case OID_md5:
0234         ctx->sinfo->sig->hash_algo = "md5";
0235         break;
0236     case OID_sha1:
0237         ctx->sinfo->sig->hash_algo = "sha1";
0238         break;
0239     case OID_sha256:
0240         ctx->sinfo->sig->hash_algo = "sha256";
0241         break;
0242     case OID_sha384:
0243         ctx->sinfo->sig->hash_algo = "sha384";
0244         break;
0245     case OID_sha512:
0246         ctx->sinfo->sig->hash_algo = "sha512";
0247         break;
0248     case OID_sha224:
0249         ctx->sinfo->sig->hash_algo = "sha224";
0250         break;
0251     case OID_sm3:
0252         ctx->sinfo->sig->hash_algo = "sm3";
0253         break;
0254     case OID_gost2012Digest256:
0255         ctx->sinfo->sig->hash_algo = "streebog256";
0256         break;
0257     case OID_gost2012Digest512:
0258         ctx->sinfo->sig->hash_algo = "streebog512";
0259         break;
0260     default:
0261         printk("Unsupported digest algo: %u\n", ctx->last_oid);
0262         return -ENOPKG;
0263     }
0264     return 0;
0265 }
0266 
0267 /*
0268  * Note the public key algorithm for the signature.
0269  */
0270 int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
0271                  unsigned char tag,
0272                  const void *value, size_t vlen)
0273 {
0274     struct pkcs7_parse_context *ctx = context;
0275 
0276     switch (ctx->last_oid) {
0277     case OID_rsaEncryption:
0278         ctx->sinfo->sig->pkey_algo = "rsa";
0279         ctx->sinfo->sig->encoding = "pkcs1";
0280         break;
0281     case OID_id_ecdsa_with_sha1:
0282     case OID_id_ecdsa_with_sha224:
0283     case OID_id_ecdsa_with_sha256:
0284     case OID_id_ecdsa_with_sha384:
0285     case OID_id_ecdsa_with_sha512:
0286         ctx->sinfo->sig->pkey_algo = "ecdsa";
0287         ctx->sinfo->sig->encoding = "x962";
0288         break;
0289     case OID_SM2_with_SM3:
0290         ctx->sinfo->sig->pkey_algo = "sm2";
0291         ctx->sinfo->sig->encoding = "raw";
0292         break;
0293     case OID_gost2012PKey256:
0294     case OID_gost2012PKey512:
0295         ctx->sinfo->sig->pkey_algo = "ecrdsa";
0296         ctx->sinfo->sig->encoding = "raw";
0297         break;
0298     default:
0299         printk("Unsupported pkey algo: %u\n", ctx->last_oid);
0300         return -ENOPKG;
0301     }
0302     return 0;
0303 }
0304 
0305 /*
0306  * We only support signed data [RFC2315 sec 9].
0307  */
0308 int pkcs7_check_content_type(void *context, size_t hdrlen,
0309                  unsigned char tag,
0310                  const void *value, size_t vlen)
0311 {
0312     struct pkcs7_parse_context *ctx = context;
0313 
0314     if (ctx->last_oid != OID_signed_data) {
0315         pr_warn("Only support pkcs7_signedData type\n");
0316         return -EINVAL;
0317     }
0318 
0319     return 0;
0320 }
0321 
0322 /*
0323  * Note the SignedData version
0324  */
0325 int pkcs7_note_signeddata_version(void *context, size_t hdrlen,
0326                   unsigned char tag,
0327                   const void *value, size_t vlen)
0328 {
0329     struct pkcs7_parse_context *ctx = context;
0330     unsigned version;
0331 
0332     if (vlen != 1)
0333         goto unsupported;
0334 
0335     ctx->msg->version = version = *(const u8 *)value;
0336     switch (version) {
0337     case 1:
0338         /* PKCS#7 SignedData [RFC2315 sec 9.1]
0339          * CMS ver 1 SignedData [RFC5652 sec 5.1]
0340          */
0341         break;
0342     case 3:
0343         /* CMS ver 3 SignedData [RFC2315 sec 5.1] */
0344         break;
0345     default:
0346         goto unsupported;
0347     }
0348 
0349     return 0;
0350 
0351 unsupported:
0352     pr_warn("Unsupported SignedData version\n");
0353     return -EINVAL;
0354 }
0355 
0356 /*
0357  * Note the SignerInfo version
0358  */
0359 int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
0360                   unsigned char tag,
0361                   const void *value, size_t vlen)
0362 {
0363     struct pkcs7_parse_context *ctx = context;
0364     unsigned version;
0365 
0366     if (vlen != 1)
0367         goto unsupported;
0368 
0369     version = *(const u8 *)value;
0370     switch (version) {
0371     case 1:
0372         /* PKCS#7 SignerInfo [RFC2315 sec 9.2]
0373          * CMS ver 1 SignerInfo [RFC5652 sec 5.3]
0374          */
0375         if (ctx->msg->version != 1)
0376             goto version_mismatch;
0377         ctx->expect_skid = false;
0378         break;
0379     case 3:
0380         /* CMS ver 3 SignerInfo [RFC2315 sec 5.3] */
0381         if (ctx->msg->version == 1)
0382             goto version_mismatch;
0383         ctx->expect_skid = true;
0384         break;
0385     default:
0386         goto unsupported;
0387     }
0388 
0389     return 0;
0390 
0391 unsupported:
0392     pr_warn("Unsupported SignerInfo version\n");
0393     return -EINVAL;
0394 version_mismatch:
0395     pr_warn("SignedData-SignerInfo version mismatch\n");
0396     return -EBADMSG;
0397 }
0398 
0399 /*
0400  * Extract a certificate and store it in the context.
0401  */
0402 int pkcs7_extract_cert(void *context, size_t hdrlen,
0403                unsigned char tag,
0404                const void *value, size_t vlen)
0405 {
0406     struct pkcs7_parse_context *ctx = context;
0407     struct x509_certificate *x509;
0408 
0409     if (tag != ((ASN1_UNIV << 6) | ASN1_CONS_BIT | ASN1_SEQ)) {
0410         pr_debug("Cert began with tag %02x at %lu\n",
0411              tag, (unsigned long)ctx - ctx->data);
0412         return -EBADMSG;
0413     }
0414 
0415     /* We have to correct for the header so that the X.509 parser can start
0416      * from the beginning.  Note that since X.509 stipulates DER, there
0417      * probably shouldn't be an EOC trailer - but it is in PKCS#7 (which
0418      * stipulates BER).
0419      */
0420     value -= hdrlen;
0421     vlen += hdrlen;
0422 
0423     if (((u8*)value)[1] == 0x80)
0424         vlen += 2; /* Indefinite length - there should be an EOC */
0425 
0426     x509 = x509_cert_parse(value, vlen);
0427     if (IS_ERR(x509))
0428         return PTR_ERR(x509);
0429 
0430     x509->index = ++ctx->x509_index;
0431     pr_debug("Got cert %u for %s\n", x509->index, x509->subject);
0432     pr_debug("- fingerprint %*phN\n", x509->id->len, x509->id->data);
0433 
0434     *ctx->ppcerts = x509;
0435     ctx->ppcerts = &x509->next;
0436     return 0;
0437 }
0438 
0439 /*
0440  * Save the certificate list
0441  */
0442 int pkcs7_note_certificate_list(void *context, size_t hdrlen,
0443                 unsigned char tag,
0444                 const void *value, size_t vlen)
0445 {
0446     struct pkcs7_parse_context *ctx = context;
0447 
0448     pr_devel("Got cert list (%02x)\n", tag);
0449 
0450     *ctx->ppcerts = ctx->msg->certs;
0451     ctx->msg->certs = ctx->certs;
0452     ctx->certs = NULL;
0453     ctx->ppcerts = &ctx->certs;
0454     return 0;
0455 }
0456 
0457 /*
0458  * Note the content type.
0459  */
0460 int pkcs7_note_content(void *context, size_t hdrlen,
0461                unsigned char tag,
0462                const void *value, size_t vlen)
0463 {
0464     struct pkcs7_parse_context *ctx = context;
0465 
0466     if (ctx->last_oid != OID_data &&
0467         ctx->last_oid != OID_msIndirectData) {
0468         pr_warn("Unsupported data type %d\n", ctx->last_oid);
0469         return -EINVAL;
0470     }
0471 
0472     ctx->msg->data_type = ctx->last_oid;
0473     return 0;
0474 }
0475 
0476 /*
0477  * Extract the data from the message and store that and its content type OID in
0478  * the context.
0479  */
0480 int pkcs7_note_data(void *context, size_t hdrlen,
0481             unsigned char tag,
0482             const void *value, size_t vlen)
0483 {
0484     struct pkcs7_parse_context *ctx = context;
0485 
0486     pr_debug("Got data\n");
0487 
0488     ctx->msg->data = value;
0489     ctx->msg->data_len = vlen;
0490     ctx->msg->data_hdrlen = hdrlen;
0491     return 0;
0492 }
0493 
0494 /*
0495  * Parse authenticated attributes.
0496  */
0497 int pkcs7_sig_note_authenticated_attr(void *context, size_t hdrlen,
0498                       unsigned char tag,
0499                       const void *value, size_t vlen)
0500 {
0501     struct pkcs7_parse_context *ctx = context;
0502     struct pkcs7_signed_info *sinfo = ctx->sinfo;
0503     enum OID content_type;
0504 
0505     pr_devel("AuthAttr: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
0506 
0507     switch (ctx->last_oid) {
0508     case OID_contentType:
0509         if (__test_and_set_bit(sinfo_has_content_type, &sinfo->aa_set))
0510             goto repeated;
0511         content_type = look_up_OID(value, vlen);
0512         if (content_type != ctx->msg->data_type) {
0513             pr_warn("Mismatch between global data type (%d) and sinfo %u (%d)\n",
0514                 ctx->msg->data_type, sinfo->index,
0515                 content_type);
0516             return -EBADMSG;
0517         }
0518         return 0;
0519 
0520     case OID_signingTime:
0521         if (__test_and_set_bit(sinfo_has_signing_time, &sinfo->aa_set))
0522             goto repeated;
0523         /* Should we check that the signing time is consistent
0524          * with the signer's X.509 cert?
0525          */
0526         return x509_decode_time(&sinfo->signing_time,
0527                     hdrlen, tag, value, vlen);
0528 
0529     case OID_messageDigest:
0530         if (__test_and_set_bit(sinfo_has_message_digest, &sinfo->aa_set))
0531             goto repeated;
0532         if (tag != ASN1_OTS)
0533             return -EBADMSG;
0534         sinfo->msgdigest = value;
0535         sinfo->msgdigest_len = vlen;
0536         return 0;
0537 
0538     case OID_smimeCapabilites:
0539         if (__test_and_set_bit(sinfo_has_smime_caps, &sinfo->aa_set))
0540             goto repeated;
0541         if (ctx->msg->data_type != OID_msIndirectData) {
0542             pr_warn("S/MIME Caps only allowed with Authenticode\n");
0543             return -EKEYREJECTED;
0544         }
0545         return 0;
0546 
0547         /* Microsoft SpOpusInfo seems to be contain cont[0] 16-bit BE
0548          * char URLs and cont[1] 8-bit char URLs.
0549          *
0550          * Microsoft StatementType seems to contain a list of OIDs that
0551          * are also used as extendedKeyUsage types in X.509 certs.
0552          */
0553     case OID_msSpOpusInfo:
0554         if (__test_and_set_bit(sinfo_has_ms_opus_info, &sinfo->aa_set))
0555             goto repeated;
0556         goto authenticode_check;
0557     case OID_msStatementType:
0558         if (__test_and_set_bit(sinfo_has_ms_statement_type, &sinfo->aa_set))
0559             goto repeated;
0560     authenticode_check:
0561         if (ctx->msg->data_type != OID_msIndirectData) {
0562             pr_warn("Authenticode AuthAttrs only allowed with Authenticode\n");
0563             return -EKEYREJECTED;
0564         }
0565         /* I'm not sure how to validate these */
0566         return 0;
0567     default:
0568         return 0;
0569     }
0570 
0571 repeated:
0572     /* We permit max one item per AuthenticatedAttribute and no repeats */
0573     pr_warn("Repeated/multivalue AuthAttrs not permitted\n");
0574     return -EKEYREJECTED;
0575 }
0576 
0577 /*
0578  * Note the set of auth attributes for digestion purposes [RFC2315 sec 9.3]
0579  */
0580 int pkcs7_sig_note_set_of_authattrs(void *context, size_t hdrlen,
0581                     unsigned char tag,
0582                     const void *value, size_t vlen)
0583 {
0584     struct pkcs7_parse_context *ctx = context;
0585     struct pkcs7_signed_info *sinfo = ctx->sinfo;
0586 
0587     if (!test_bit(sinfo_has_content_type, &sinfo->aa_set) ||
0588         !test_bit(sinfo_has_message_digest, &sinfo->aa_set)) {
0589         pr_warn("Missing required AuthAttr\n");
0590         return -EBADMSG;
0591     }
0592 
0593     if (ctx->msg->data_type != OID_msIndirectData &&
0594         test_bit(sinfo_has_ms_opus_info, &sinfo->aa_set)) {
0595         pr_warn("Unexpected Authenticode AuthAttr\n");
0596         return -EBADMSG;
0597     }
0598 
0599     /* We need to switch the 'CONT 0' to a 'SET OF' when we digest */
0600     sinfo->authattrs = value - (hdrlen - 1);
0601     sinfo->authattrs_len = vlen + (hdrlen - 1);
0602     return 0;
0603 }
0604 
0605 /*
0606  * Note the issuing certificate serial number
0607  */
0608 int pkcs7_sig_note_serial(void *context, size_t hdrlen,
0609               unsigned char tag,
0610               const void *value, size_t vlen)
0611 {
0612     struct pkcs7_parse_context *ctx = context;
0613     ctx->raw_serial = value;
0614     ctx->raw_serial_size = vlen;
0615     return 0;
0616 }
0617 
0618 /*
0619  * Note the issuer's name
0620  */
0621 int pkcs7_sig_note_issuer(void *context, size_t hdrlen,
0622               unsigned char tag,
0623               const void *value, size_t vlen)
0624 {
0625     struct pkcs7_parse_context *ctx = context;
0626     ctx->raw_issuer = value;
0627     ctx->raw_issuer_size = vlen;
0628     return 0;
0629 }
0630 
0631 /*
0632  * Note the issuing cert's subjectKeyIdentifier
0633  */
0634 int pkcs7_sig_note_skid(void *context, size_t hdrlen,
0635             unsigned char tag,
0636             const void *value, size_t vlen)
0637 {
0638     struct pkcs7_parse_context *ctx = context;
0639 
0640     pr_devel("SKID: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
0641 
0642     ctx->raw_skid = value;
0643     ctx->raw_skid_size = vlen;
0644     return 0;
0645 }
0646 
0647 /*
0648  * Note the signature data
0649  */
0650 int pkcs7_sig_note_signature(void *context, size_t hdrlen,
0651                  unsigned char tag,
0652                  const void *value, size_t vlen)
0653 {
0654     struct pkcs7_parse_context *ctx = context;
0655 
0656     ctx->sinfo->sig->s = kmemdup(value, vlen, GFP_KERNEL);
0657     if (!ctx->sinfo->sig->s)
0658         return -ENOMEM;
0659 
0660     ctx->sinfo->sig->s_size = vlen;
0661     return 0;
0662 }
0663 
0664 /*
0665  * Note a signature information block
0666  */
0667 int pkcs7_note_signed_info(void *context, size_t hdrlen,
0668                unsigned char tag,
0669                const void *value, size_t vlen)
0670 {
0671     struct pkcs7_parse_context *ctx = context;
0672     struct pkcs7_signed_info *sinfo = ctx->sinfo;
0673     struct asymmetric_key_id *kid;
0674 
0675     if (ctx->msg->data_type == OID_msIndirectData && !sinfo->authattrs) {
0676         pr_warn("Authenticode requires AuthAttrs\n");
0677         return -EBADMSG;
0678     }
0679 
0680     /* Generate cert issuer + serial number key ID */
0681     if (!ctx->expect_skid) {
0682         kid = asymmetric_key_generate_id(ctx->raw_serial,
0683                          ctx->raw_serial_size,
0684                          ctx->raw_issuer,
0685                          ctx->raw_issuer_size);
0686     } else {
0687         kid = asymmetric_key_generate_id(ctx->raw_skid,
0688                          ctx->raw_skid_size,
0689                          "", 0);
0690     }
0691     if (IS_ERR(kid))
0692         return PTR_ERR(kid);
0693 
0694     pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data);
0695 
0696     sinfo->sig->auth_ids[0] = kid;
0697     sinfo->index = ++ctx->sinfo_index;
0698     *ctx->ppsinfo = sinfo;
0699     ctx->ppsinfo = &sinfo->next;
0700     ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
0701     if (!ctx->sinfo)
0702         return -ENOMEM;
0703     ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
0704                   GFP_KERNEL);
0705     if (!ctx->sinfo->sig)
0706         return -ENOMEM;
0707     return 0;
0708 }