pkcs7_parser.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. /* PKCS#7 parser
  2. *
  3. * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public Licence
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the Licence, or (at your option) any later version.
  10. */
  11. #define pr_fmt(fmt) "PKCS7: "fmt
  12. #include <linux/kernel.h>
  13. #include <linux/module.h>
  14. #include <linux/export.h>
  15. #include <linux/slab.h>
  16. #include <linux/err.h>
  17. #include <linux/oid_registry.h>
  18. #include <crypto/public_key.h>
  19. #include "pkcs7_parser.h"
  20. #include "pkcs7.asn1.h"
  21. MODULE_DESCRIPTION("PKCS#7 parser");
  22. MODULE_AUTHOR("Red Hat, Inc.");
  23. MODULE_LICENSE("GPL");
  24. struct pkcs7_parse_context {
  25. struct pkcs7_message *msg; /* Message being constructed */
  26. struct pkcs7_signed_info *sinfo; /* SignedInfo being constructed */
  27. struct pkcs7_signed_info **ppsinfo;
  28. struct x509_certificate *certs; /* Certificate cache */
  29. struct x509_certificate **ppcerts;
  30. unsigned long data; /* Start of data */
  31. enum OID last_oid; /* Last OID encountered */
  32. unsigned x509_index;
  33. unsigned sinfo_index;
  34. const void *raw_serial;
  35. unsigned raw_serial_size;
  36. unsigned raw_issuer_size;
  37. const void *raw_issuer;
  38. const void *raw_skid;
  39. unsigned raw_skid_size;
  40. bool expect_skid;
  41. };
  42. /*
  43. * Free a signed information block.
  44. */
  45. static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
  46. {
  47. if (sinfo) {
  48. public_key_signature_free(sinfo->sig);
  49. kfree(sinfo);
  50. }
  51. }
  52. /**
  53. * pkcs7_free_message - Free a PKCS#7 message
  54. * @pkcs7: The PKCS#7 message to free
  55. */
  56. void pkcs7_free_message(struct pkcs7_message *pkcs7)
  57. {
  58. struct x509_certificate *cert;
  59. struct pkcs7_signed_info *sinfo;
  60. if (pkcs7) {
  61. while (pkcs7->certs) {
  62. cert = pkcs7->certs;
  63. pkcs7->certs = cert->next;
  64. x509_free_certificate(cert);
  65. }
  66. while (pkcs7->crl) {
  67. cert = pkcs7->crl;
  68. pkcs7->crl = cert->next;
  69. x509_free_certificate(cert);
  70. }
  71. while (pkcs7->signed_infos) {
  72. sinfo = pkcs7->signed_infos;
  73. pkcs7->signed_infos = sinfo->next;
  74. pkcs7_free_signed_info(sinfo);
  75. }
  76. kfree(pkcs7);
  77. }
  78. }
  79. EXPORT_SYMBOL_GPL(pkcs7_free_message);
  80. /*
  81. * Check authenticatedAttributes are provided or not provided consistently.
  82. */
  83. static int pkcs7_check_authattrs(struct pkcs7_message *msg)
  84. {
  85. struct pkcs7_signed_info *sinfo;
  86. bool want = false;
  87. sinfo = msg->signed_infos;
  88. if (!sinfo)
  89. goto inconsistent;
  90. if (sinfo->authattrs) {
  91. want = true;
  92. msg->have_authattrs = true;
  93. }
  94. for (sinfo = sinfo->next; sinfo; sinfo = sinfo->next)
  95. if (!!sinfo->authattrs != want)
  96. goto inconsistent;
  97. return 0;
  98. inconsistent:
  99. pr_warn("Inconsistently supplied authAttrs\n");
  100. return -EINVAL;
  101. }
  102. /**
  103. * pkcs7_parse_message - Parse a PKCS#7 message
  104. * @data: The raw binary ASN.1 encoded message to be parsed
  105. * @datalen: The size of the encoded message
  106. */
  107. struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
  108. {
  109. struct pkcs7_parse_context *ctx;
  110. struct pkcs7_message *msg = ERR_PTR(-ENOMEM);
  111. int ret;
  112. ctx = kzalloc(sizeof(struct pkcs7_parse_context), GFP_KERNEL);
  113. if (!ctx)
  114. goto out_no_ctx;
  115. ctx->msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL);
  116. if (!ctx->msg)
  117. goto out_no_msg;
  118. ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
  119. if (!ctx->sinfo)
  120. goto out_no_sinfo;
  121. ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
  122. GFP_KERNEL);
  123. if (!ctx->sinfo->sig)
  124. goto out_no_sig;
  125. ctx->data = (unsigned long)data;
  126. ctx->ppcerts = &ctx->certs;
  127. ctx->ppsinfo = &ctx->msg->signed_infos;
  128. /* Attempt to decode the signature */
  129. ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen);
  130. if (ret < 0) {
  131. msg = ERR_PTR(ret);
  132. goto out;
  133. }
  134. ret = pkcs7_check_authattrs(ctx->msg);
  135. if (ret < 0) {
  136. msg = ERR_PTR(ret);
  137. goto out;
  138. }
  139. msg = ctx->msg;
  140. ctx->msg = NULL;
  141. out:
  142. while (ctx->certs) {
  143. struct x509_certificate *cert = ctx->certs;
  144. ctx->certs = cert->next;
  145. x509_free_certificate(cert);
  146. }
  147. out_no_sig:
  148. pkcs7_free_signed_info(ctx->sinfo);
  149. out_no_sinfo:
  150. pkcs7_free_message(ctx->msg);
  151. out_no_msg:
  152. kfree(ctx);
  153. out_no_ctx:
  154. return msg;
  155. }
  156. EXPORT_SYMBOL_GPL(pkcs7_parse_message);
  157. /**
  158. * pkcs7_get_content_data - Get access to the PKCS#7 content
  159. * @pkcs7: The preparsed PKCS#7 message to access
  160. * @_data: Place to return a pointer to the data
  161. * @_data_len: Place to return the data length
  162. * @_headerlen: Size of ASN.1 header not included in _data
  163. *
  164. * Get access to the data content of the PKCS#7 message. The size of the
  165. * header of the ASN.1 object that contains it is also provided and can be used
  166. * to adjust *_data and *_data_len to get the entire object.
  167. *
  168. * Returns -ENODATA if the data object was missing from the message.
  169. */
  170. int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
  171. const void **_data, size_t *_data_len,
  172. size_t *_headerlen)
  173. {
  174. if (!pkcs7->data)
  175. return -ENODATA;
  176. *_data = pkcs7->data;
  177. *_data_len = pkcs7->data_len;
  178. if (_headerlen)
  179. *_headerlen = pkcs7->data_hdrlen;
  180. return 0;
  181. }
  182. EXPORT_SYMBOL_GPL(pkcs7_get_content_data);
  183. /*
  184. * Note an OID when we find one for later processing when we know how
  185. * to interpret it.
  186. */
  187. int pkcs7_note_OID(void *context, size_t hdrlen,
  188. unsigned char tag,
  189. const void *value, size_t vlen)
  190. {
  191. struct pkcs7_parse_context *ctx = context;
  192. ctx->last_oid = look_up_OID(value, vlen);
  193. if (ctx->last_oid == OID__NR) {
  194. char buffer[50];
  195. sprint_oid(value, vlen, buffer, sizeof(buffer));
  196. printk("PKCS7: Unknown OID: [%lu] %s\n",
  197. (unsigned long)value - ctx->data, buffer);
  198. }
  199. return 0;
  200. }
  201. /*
  202. * Note the digest algorithm for the signature.
  203. */
  204. int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
  205. unsigned char tag,
  206. const void *value, size_t vlen)
  207. {
  208. struct pkcs7_parse_context *ctx = context;
  209. switch (ctx->last_oid) {
  210. case OID_md4:
  211. ctx->sinfo->sig->hash_algo = "md4";
  212. break;
  213. case OID_md5:
  214. ctx->sinfo->sig->hash_algo = "md5";
  215. break;
  216. case OID_sha1:
  217. ctx->sinfo->sig->hash_algo = "sha1";
  218. break;
  219. case OID_sha256:
  220. ctx->sinfo->sig->hash_algo = "sha256";
  221. break;
  222. case OID_sha384:
  223. ctx->sinfo->sig->hash_algo = "sha384";
  224. break;
  225. case OID_sha512:
  226. ctx->sinfo->sig->hash_algo = "sha512";
  227. break;
  228. case OID_sha224:
  229. ctx->sinfo->sig->hash_algo = "sha224";
  230. break;
  231. default:
  232. printk("Unsupported digest algo: %u\n", ctx->last_oid);
  233. return -ENOPKG;
  234. }
  235. return 0;
  236. }
  237. /*
  238. * Note the public key algorithm for the signature.
  239. */
  240. int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
  241. unsigned char tag,
  242. const void *value, size_t vlen)
  243. {
  244. struct pkcs7_parse_context *ctx = context;
  245. switch (ctx->last_oid) {
  246. case OID_rsaEncryption:
  247. ctx->sinfo->sig->pkey_algo = "rsa";
  248. break;
  249. default:
  250. printk("Unsupported pkey algo: %u\n", ctx->last_oid);
  251. return -ENOPKG;
  252. }
  253. return 0;
  254. }
  255. /*
  256. * We only support signed data [RFC2315 sec 9].
  257. */
  258. int pkcs7_check_content_type(void *context, size_t hdrlen,
  259. unsigned char tag,
  260. const void *value, size_t vlen)
  261. {
  262. struct pkcs7_parse_context *ctx = context;
  263. if (ctx->last_oid != OID_signed_data) {
  264. pr_warn("Only support pkcs7_signedData type\n");
  265. return -EINVAL;
  266. }
  267. return 0;
  268. }
  269. /*
  270. * Note the SignedData version
  271. */
  272. int pkcs7_note_signeddata_version(void *context, size_t hdrlen,
  273. unsigned char tag,
  274. const void *value, size_t vlen)
  275. {
  276. struct pkcs7_parse_context *ctx = context;
  277. unsigned version;
  278. if (vlen != 1)
  279. goto unsupported;
  280. ctx->msg->version = version = *(const u8 *)value;
  281. switch (version) {
  282. case 1:
  283. /* PKCS#7 SignedData [RFC2315 sec 9.1]
  284. * CMS ver 1 SignedData [RFC5652 sec 5.1]
  285. */
  286. break;
  287. case 3:
  288. /* CMS ver 3 SignedData [RFC2315 sec 5.1] */
  289. break;
  290. default:
  291. goto unsupported;
  292. }
  293. return 0;
  294. unsupported:
  295. pr_warn("Unsupported SignedData version\n");
  296. return -EINVAL;
  297. }
  298. /*
  299. * Note the SignerInfo version
  300. */
  301. int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
  302. unsigned char tag,
  303. const void *value, size_t vlen)
  304. {
  305. struct pkcs7_parse_context *ctx = context;
  306. unsigned version;
  307. if (vlen != 1)
  308. goto unsupported;
  309. version = *(const u8 *)value;
  310. switch (version) {
  311. case 1:
  312. /* PKCS#7 SignerInfo [RFC2315 sec 9.2]
  313. * CMS ver 1 SignerInfo [RFC5652 sec 5.3]
  314. */
  315. if (ctx->msg->version != 1)
  316. goto version_mismatch;
  317. ctx->expect_skid = false;
  318. break;
  319. case 3:
  320. /* CMS ver 3 SignerInfo [RFC2315 sec 5.3] */
  321. if (ctx->msg->version == 1)
  322. goto version_mismatch;
  323. ctx->expect_skid = true;
  324. break;
  325. default:
  326. goto unsupported;
  327. }
  328. return 0;
  329. unsupported:
  330. pr_warn("Unsupported SignerInfo version\n");
  331. return -EINVAL;
  332. version_mismatch:
  333. pr_warn("SignedData-SignerInfo version mismatch\n");
  334. return -EBADMSG;
  335. }
  336. /*
  337. * Extract a certificate and store it in the context.
  338. */
  339. int pkcs7_extract_cert(void *context, size_t hdrlen,
  340. unsigned char tag,
  341. const void *value, size_t vlen)
  342. {
  343. struct pkcs7_parse_context *ctx = context;
  344. struct x509_certificate *x509;
  345. if (tag != ((ASN1_UNIV << 6) | ASN1_CONS_BIT | ASN1_SEQ)) {
  346. pr_debug("Cert began with tag %02x at %lu\n",
  347. tag, (unsigned long)ctx - ctx->data);
  348. return -EBADMSG;
  349. }
  350. /* We have to correct for the header so that the X.509 parser can start
  351. * from the beginning. Note that since X.509 stipulates DER, there
  352. * probably shouldn't be an EOC trailer - but it is in PKCS#7 (which
  353. * stipulates BER).
  354. */
  355. value -= hdrlen;
  356. vlen += hdrlen;
  357. if (((u8*)value)[1] == 0x80)
  358. vlen += 2; /* Indefinite length - there should be an EOC */
  359. x509 = x509_cert_parse(value, vlen);
  360. if (IS_ERR(x509))
  361. return PTR_ERR(x509);
  362. x509->index = ++ctx->x509_index;
  363. pr_debug("Got cert %u for %s\n", x509->index, x509->subject);
  364. pr_debug("- fingerprint %*phN\n", x509->id->len, x509->id->data);
  365. *ctx->ppcerts = x509;
  366. ctx->ppcerts = &x509->next;
  367. return 0;
  368. }
  369. /*
  370. * Save the certificate list
  371. */
  372. int pkcs7_note_certificate_list(void *context, size_t hdrlen,
  373. unsigned char tag,
  374. const void *value, size_t vlen)
  375. {
  376. struct pkcs7_parse_context *ctx = context;
  377. pr_devel("Got cert list (%02x)\n", tag);
  378. *ctx->ppcerts = ctx->msg->certs;
  379. ctx->msg->certs = ctx->certs;
  380. ctx->certs = NULL;
  381. ctx->ppcerts = &ctx->certs;
  382. return 0;
  383. }
  384. /*
  385. * Note the content type.
  386. */
  387. int pkcs7_note_content(void *context, size_t hdrlen,
  388. unsigned char tag,
  389. const void *value, size_t vlen)
  390. {
  391. struct pkcs7_parse_context *ctx = context;
  392. if (ctx->last_oid != OID_data &&
  393. ctx->last_oid != OID_msIndirectData) {
  394. pr_warn("Unsupported data type %d\n", ctx->last_oid);
  395. return -EINVAL;
  396. }
  397. ctx->msg->data_type = ctx->last_oid;
  398. return 0;
  399. }
  400. /*
  401. * Extract the data from the message and store that and its content type OID in
  402. * the context.
  403. */
  404. int pkcs7_note_data(void *context, size_t hdrlen,
  405. unsigned char tag,
  406. const void *value, size_t vlen)
  407. {
  408. struct pkcs7_parse_context *ctx = context;
  409. pr_debug("Got data\n");
  410. ctx->msg->data = value;
  411. ctx->msg->data_len = vlen;
  412. ctx->msg->data_hdrlen = hdrlen;
  413. return 0;
  414. }
  415. /*
  416. * Parse authenticated attributes.
  417. */
  418. int pkcs7_sig_note_authenticated_attr(void *context, size_t hdrlen,
  419. unsigned char tag,
  420. const void *value, size_t vlen)
  421. {
  422. struct pkcs7_parse_context *ctx = context;
  423. struct pkcs7_signed_info *sinfo = ctx->sinfo;
  424. enum OID content_type;
  425. pr_devel("AuthAttr: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
  426. switch (ctx->last_oid) {
  427. case OID_contentType:
  428. if (__test_and_set_bit(sinfo_has_content_type, &sinfo->aa_set))
  429. goto repeated;
  430. content_type = look_up_OID(value, vlen);
  431. if (content_type != ctx->msg->data_type) {
  432. pr_warn("Mismatch between global data type (%d) and sinfo %u (%d)\n",
  433. ctx->msg->data_type, sinfo->index,
  434. content_type);
  435. return -EBADMSG;
  436. }
  437. return 0;
  438. case OID_signingTime:
  439. if (__test_and_set_bit(sinfo_has_signing_time, &sinfo->aa_set))
  440. goto repeated;
  441. /* Should we check that the signing time is consistent
  442. * with the signer's X.509 cert?
  443. */
  444. return x509_decode_time(&sinfo->signing_time,
  445. hdrlen, tag, value, vlen);
  446. case OID_messageDigest:
  447. if (__test_and_set_bit(sinfo_has_message_digest, &sinfo->aa_set))
  448. goto repeated;
  449. if (tag != ASN1_OTS)
  450. return -EBADMSG;
  451. sinfo->msgdigest = value;
  452. sinfo->msgdigest_len = vlen;
  453. return 0;
  454. case OID_smimeCapabilites:
  455. if (__test_and_set_bit(sinfo_has_smime_caps, &sinfo->aa_set))
  456. goto repeated;
  457. if (ctx->msg->data_type != OID_msIndirectData) {
  458. pr_warn("S/MIME Caps only allowed with Authenticode\n");
  459. return -EKEYREJECTED;
  460. }
  461. return 0;
  462. /* Microsoft SpOpusInfo seems to be contain cont[0] 16-bit BE
  463. * char URLs and cont[1] 8-bit char URLs.
  464. *
  465. * Microsoft StatementType seems to contain a list of OIDs that
  466. * are also used as extendedKeyUsage types in X.509 certs.
  467. */
  468. case OID_msSpOpusInfo:
  469. if (__test_and_set_bit(sinfo_has_ms_opus_info, &sinfo->aa_set))
  470. goto repeated;
  471. goto authenticode_check;
  472. case OID_msStatementType:
  473. if (__test_and_set_bit(sinfo_has_ms_statement_type, &sinfo->aa_set))
  474. goto repeated;
  475. authenticode_check:
  476. if (ctx->msg->data_type != OID_msIndirectData) {
  477. pr_warn("Authenticode AuthAttrs only allowed with Authenticode\n");
  478. return -EKEYREJECTED;
  479. }
  480. /* I'm not sure how to validate these */
  481. return 0;
  482. default:
  483. return 0;
  484. }
  485. repeated:
  486. /* We permit max one item per AuthenticatedAttribute and no repeats */
  487. pr_warn("Repeated/multivalue AuthAttrs not permitted\n");
  488. return -EKEYREJECTED;
  489. }
  490. /*
  491. * Note the set of auth attributes for digestion purposes [RFC2315 sec 9.3]
  492. */
  493. int pkcs7_sig_note_set_of_authattrs(void *context, size_t hdrlen,
  494. unsigned char tag,
  495. const void *value, size_t vlen)
  496. {
  497. struct pkcs7_parse_context *ctx = context;
  498. struct pkcs7_signed_info *sinfo = ctx->sinfo;
  499. if (!test_bit(sinfo_has_content_type, &sinfo->aa_set) ||
  500. !test_bit(sinfo_has_message_digest, &sinfo->aa_set)) {
  501. pr_warn("Missing required AuthAttr\n");
  502. return -EBADMSG;
  503. }
  504. if (ctx->msg->data_type != OID_msIndirectData &&
  505. test_bit(sinfo_has_ms_opus_info, &sinfo->aa_set)) {
  506. pr_warn("Unexpected Authenticode AuthAttr\n");
  507. return -EBADMSG;
  508. }
  509. /* We need to switch the 'CONT 0' to a 'SET OF' when we digest */
  510. sinfo->authattrs = value - (hdrlen - 1);
  511. sinfo->authattrs_len = vlen + (hdrlen - 1);
  512. return 0;
  513. }
  514. /*
  515. * Note the issuing certificate serial number
  516. */
  517. int pkcs7_sig_note_serial(void *context, size_t hdrlen,
  518. unsigned char tag,
  519. const void *value, size_t vlen)
  520. {
  521. struct pkcs7_parse_context *ctx = context;
  522. ctx->raw_serial = value;
  523. ctx->raw_serial_size = vlen;
  524. return 0;
  525. }
  526. /*
  527. * Note the issuer's name
  528. */
  529. int pkcs7_sig_note_issuer(void *context, size_t hdrlen,
  530. unsigned char tag,
  531. const void *value, size_t vlen)
  532. {
  533. struct pkcs7_parse_context *ctx = context;
  534. ctx->raw_issuer = value;
  535. ctx->raw_issuer_size = vlen;
  536. return 0;
  537. }
  538. /*
  539. * Note the issuing cert's subjectKeyIdentifier
  540. */
  541. int pkcs7_sig_note_skid(void *context, size_t hdrlen,
  542. unsigned char tag,
  543. const void *value, size_t vlen)
  544. {
  545. struct pkcs7_parse_context *ctx = context;
  546. pr_devel("SKID: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
  547. ctx->raw_skid = value;
  548. ctx->raw_skid_size = vlen;
  549. return 0;
  550. }
  551. /*
  552. * Note the signature data
  553. */
  554. int pkcs7_sig_note_signature(void *context, size_t hdrlen,
  555. unsigned char tag,
  556. const void *value, size_t vlen)
  557. {
  558. struct pkcs7_parse_context *ctx = context;
  559. ctx->sinfo->sig->s = kmemdup(value, vlen, GFP_KERNEL);
  560. if (!ctx->sinfo->sig->s)
  561. return -ENOMEM;
  562. ctx->sinfo->sig->s_size = vlen;
  563. return 0;
  564. }
  565. /*
  566. * Note a signature information block
  567. */
  568. int pkcs7_note_signed_info(void *context, size_t hdrlen,
  569. unsigned char tag,
  570. const void *value, size_t vlen)
  571. {
  572. struct pkcs7_parse_context *ctx = context;
  573. struct pkcs7_signed_info *sinfo = ctx->sinfo;
  574. struct asymmetric_key_id *kid;
  575. if (ctx->msg->data_type == OID_msIndirectData && !sinfo->authattrs) {
  576. pr_warn("Authenticode requires AuthAttrs\n");
  577. return -EBADMSG;
  578. }
  579. /* Generate cert issuer + serial number key ID */
  580. if (!ctx->expect_skid) {
  581. kid = asymmetric_key_generate_id(ctx->raw_serial,
  582. ctx->raw_serial_size,
  583. ctx->raw_issuer,
  584. ctx->raw_issuer_size);
  585. } else {
  586. kid = asymmetric_key_generate_id(ctx->raw_skid,
  587. ctx->raw_skid_size,
  588. "", 0);
  589. }
  590. if (IS_ERR(kid))
  591. return PTR_ERR(kid);
  592. pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data);
  593. sinfo->sig->auth_ids[0] = kid;
  594. sinfo->index = ++ctx->sinfo_index;
  595. *ctx->ppsinfo = sinfo;
  596. ctx->ppsinfo = &sinfo->next;
  597. ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
  598. if (!ctx->sinfo)
  599. return -ENOMEM;
  600. ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
  601. GFP_KERNEL);
  602. if (!ctx->sinfo->sig)
  603. return -ENOMEM;
  604. return 0;
  605. }