x509_cert_parser.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. /* X.509 certificate 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) "X.509: "fmt
  12. #include <linux/kernel.h>
  13. #include <linux/export.h>
  14. #include <linux/slab.h>
  15. #include <linux/err.h>
  16. #include <linux/oid_registry.h>
  17. #include "public_key.h"
  18. #include "x509_parser.h"
  19. #include "x509-asn1.h"
  20. #include "x509_akid-asn1.h"
  21. #include "x509_rsakey-asn1.h"
  22. struct x509_parse_context {
  23. struct x509_certificate *cert; /* Certificate being constructed */
  24. unsigned long data; /* Start of data */
  25. const void *cert_start; /* Start of cert content */
  26. const void *key; /* Key data */
  27. size_t key_size; /* Size of key data */
  28. enum OID last_oid; /* Last OID encountered */
  29. enum OID algo_oid; /* Algorithm OID */
  30. unsigned char nr_mpi; /* Number of MPIs stored */
  31. u8 o_size; /* Size of organizationName (O) */
  32. u8 cn_size; /* Size of commonName (CN) */
  33. u8 email_size; /* Size of emailAddress */
  34. u16 o_offset; /* Offset of organizationName (O) */
  35. u16 cn_offset; /* Offset of commonName (CN) */
  36. u16 email_offset; /* Offset of emailAddress */
  37. unsigned raw_akid_size;
  38. const void *raw_akid; /* Raw authorityKeyId in ASN.1 */
  39. const void *akid_raw_issuer; /* Raw directoryName in authorityKeyId */
  40. unsigned akid_raw_issuer_size;
  41. };
  42. /*
  43. * Free an X.509 certificate
  44. */
  45. void x509_free_certificate(struct x509_certificate *cert)
  46. {
  47. if (cert) {
  48. public_key_destroy(cert->pub);
  49. kfree(cert->issuer);
  50. kfree(cert->subject);
  51. kfree(cert->id);
  52. kfree(cert->skid);
  53. kfree(cert->akid_id);
  54. kfree(cert->akid_skid);
  55. kfree(cert->sig.digest);
  56. mpi_free(cert->sig.rsa.s);
  57. kfree(cert);
  58. }
  59. }
  60. EXPORT_SYMBOL_GPL(x509_free_certificate);
  61. /*
  62. * Parse an X.509 certificate
  63. */
  64. struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
  65. {
  66. struct x509_certificate *cert;
  67. struct x509_parse_context *ctx;
  68. struct asymmetric_key_id *kid;
  69. long ret;
  70. ret = -ENOMEM;
  71. cert = kzalloc(sizeof(struct x509_certificate), GFP_KERNEL);
  72. if (!cert)
  73. goto error_no_cert;
  74. cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL);
  75. if (!cert->pub)
  76. goto error_no_ctx;
  77. ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL);
  78. if (!ctx)
  79. goto error_no_ctx;
  80. ctx->cert = cert;
  81. ctx->data = (unsigned long)data;
  82. /* Attempt to decode the certificate */
  83. ret = asn1_ber_decoder(&x509_decoder, ctx, data, datalen);
  84. if (ret < 0)
  85. goto error_decode;
  86. /* Decode the AuthorityKeyIdentifier */
  87. if (ctx->raw_akid) {
  88. pr_devel("AKID: %u %*phN\n",
  89. ctx->raw_akid_size, ctx->raw_akid_size, ctx->raw_akid);
  90. ret = asn1_ber_decoder(&x509_akid_decoder, ctx,
  91. ctx->raw_akid, ctx->raw_akid_size);
  92. if (ret < 0) {
  93. pr_warn("Couldn't decode AuthKeyIdentifier\n");
  94. goto error_decode;
  95. }
  96. }
  97. /* Decode the public key */
  98. ret = asn1_ber_decoder(&x509_rsakey_decoder, ctx,
  99. ctx->key, ctx->key_size);
  100. if (ret < 0)
  101. goto error_decode;
  102. /* Generate cert issuer + serial number key ID */
  103. kid = asymmetric_key_generate_id(cert->raw_serial,
  104. cert->raw_serial_size,
  105. cert->raw_issuer,
  106. cert->raw_issuer_size);
  107. if (IS_ERR(kid)) {
  108. ret = PTR_ERR(kid);
  109. goto error_decode;
  110. }
  111. cert->id = kid;
  112. kfree(ctx);
  113. return cert;
  114. error_decode:
  115. kfree(ctx);
  116. error_no_ctx:
  117. x509_free_certificate(cert);
  118. error_no_cert:
  119. return ERR_PTR(ret);
  120. }
  121. EXPORT_SYMBOL_GPL(x509_cert_parse);
  122. /*
  123. * Note an OID when we find one for later processing when we know how
  124. * to interpret it.
  125. */
  126. int x509_note_OID(void *context, size_t hdrlen,
  127. unsigned char tag,
  128. const void *value, size_t vlen)
  129. {
  130. struct x509_parse_context *ctx = context;
  131. ctx->last_oid = look_up_OID(value, vlen);
  132. if (ctx->last_oid == OID__NR) {
  133. char buffer[50];
  134. sprint_oid(value, vlen, buffer, sizeof(buffer));
  135. pr_debug("Unknown OID: [%lu] %s\n",
  136. (unsigned long)value - ctx->data, buffer);
  137. }
  138. return 0;
  139. }
  140. /*
  141. * Save the position of the TBS data so that we can check the signature over it
  142. * later.
  143. */
  144. int x509_note_tbs_certificate(void *context, size_t hdrlen,
  145. unsigned char tag,
  146. const void *value, size_t vlen)
  147. {
  148. struct x509_parse_context *ctx = context;
  149. pr_debug("x509_note_tbs_certificate(,%zu,%02x,%ld,%zu)!\n",
  150. hdrlen, tag, (unsigned long)value - ctx->data, vlen);
  151. ctx->cert->tbs = value - hdrlen;
  152. ctx->cert->tbs_size = vlen + hdrlen;
  153. return 0;
  154. }
  155. /*
  156. * Record the public key algorithm
  157. */
  158. int x509_note_pkey_algo(void *context, size_t hdrlen,
  159. unsigned char tag,
  160. const void *value, size_t vlen)
  161. {
  162. struct x509_parse_context *ctx = context;
  163. pr_debug("PubKey Algo: %u\n", ctx->last_oid);
  164. switch (ctx->last_oid) {
  165. case OID_md2WithRSAEncryption:
  166. case OID_md3WithRSAEncryption:
  167. default:
  168. return -ENOPKG; /* Unsupported combination */
  169. case OID_md4WithRSAEncryption:
  170. ctx->cert->sig.pkey_hash_algo = HASH_ALGO_MD5;
  171. ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
  172. break;
  173. case OID_sha1WithRSAEncryption:
  174. ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA1;
  175. ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
  176. break;
  177. case OID_sha256WithRSAEncryption:
  178. ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA256;
  179. ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
  180. break;
  181. case OID_sha384WithRSAEncryption:
  182. ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA384;
  183. ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
  184. break;
  185. case OID_sha512WithRSAEncryption:
  186. ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA512;
  187. ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
  188. break;
  189. case OID_sha224WithRSAEncryption:
  190. ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA224;
  191. ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
  192. break;
  193. }
  194. ctx->algo_oid = ctx->last_oid;
  195. return 0;
  196. }
  197. /*
  198. * Note the whereabouts and type of the signature.
  199. */
  200. int x509_note_signature(void *context, size_t hdrlen,
  201. unsigned char tag,
  202. const void *value, size_t vlen)
  203. {
  204. struct x509_parse_context *ctx = context;
  205. pr_debug("Signature type: %u size %zu\n", ctx->last_oid, vlen);
  206. if (ctx->last_oid != ctx->algo_oid) {
  207. pr_warn("Got cert with pkey (%u) and sig (%u) algorithm OIDs\n",
  208. ctx->algo_oid, ctx->last_oid);
  209. return -EINVAL;
  210. }
  211. ctx->cert->raw_sig = value;
  212. ctx->cert->raw_sig_size = vlen;
  213. return 0;
  214. }
  215. /*
  216. * Note the certificate serial number
  217. */
  218. int x509_note_serial(void *context, size_t hdrlen,
  219. unsigned char tag,
  220. const void *value, size_t vlen)
  221. {
  222. struct x509_parse_context *ctx = context;
  223. ctx->cert->raw_serial = value;
  224. ctx->cert->raw_serial_size = vlen;
  225. return 0;
  226. }
  227. /*
  228. * Note some of the name segments from which we'll fabricate a name.
  229. */
  230. int x509_extract_name_segment(void *context, size_t hdrlen,
  231. unsigned char tag,
  232. const void *value, size_t vlen)
  233. {
  234. struct x509_parse_context *ctx = context;
  235. switch (ctx->last_oid) {
  236. case OID_commonName:
  237. ctx->cn_size = vlen;
  238. ctx->cn_offset = (unsigned long)value - ctx->data;
  239. break;
  240. case OID_organizationName:
  241. ctx->o_size = vlen;
  242. ctx->o_offset = (unsigned long)value - ctx->data;
  243. break;
  244. case OID_email_address:
  245. ctx->email_size = vlen;
  246. ctx->email_offset = (unsigned long)value - ctx->data;
  247. break;
  248. default:
  249. break;
  250. }
  251. return 0;
  252. }
  253. /*
  254. * Fabricate and save the issuer and subject names
  255. */
  256. static int x509_fabricate_name(struct x509_parse_context *ctx, size_t hdrlen,
  257. unsigned char tag,
  258. char **_name, size_t vlen)
  259. {
  260. const void *name, *data = (const void *)ctx->data;
  261. size_t namesize;
  262. char *buffer;
  263. if (*_name)
  264. return -EINVAL;
  265. /* Empty name string if no material */
  266. if (!ctx->cn_size && !ctx->o_size && !ctx->email_size) {
  267. buffer = kmalloc(1, GFP_KERNEL);
  268. if (!buffer)
  269. return -ENOMEM;
  270. buffer[0] = 0;
  271. goto done;
  272. }
  273. if (ctx->cn_size && ctx->o_size) {
  274. /* Consider combining O and CN, but use only the CN if it is
  275. * prefixed by the O, or a significant portion thereof.
  276. */
  277. namesize = ctx->cn_size;
  278. name = data + ctx->cn_offset;
  279. if (ctx->cn_size >= ctx->o_size &&
  280. memcmp(data + ctx->cn_offset, data + ctx->o_offset,
  281. ctx->o_size) == 0)
  282. goto single_component;
  283. if (ctx->cn_size >= 7 &&
  284. ctx->o_size >= 7 &&
  285. memcmp(data + ctx->cn_offset, data + ctx->o_offset, 7) == 0)
  286. goto single_component;
  287. buffer = kmalloc(ctx->o_size + 2 + ctx->cn_size + 1,
  288. GFP_KERNEL);
  289. if (!buffer)
  290. return -ENOMEM;
  291. memcpy(buffer,
  292. data + ctx->o_offset, ctx->o_size);
  293. buffer[ctx->o_size + 0] = ':';
  294. buffer[ctx->o_size + 1] = ' ';
  295. memcpy(buffer + ctx->o_size + 2,
  296. data + ctx->cn_offset, ctx->cn_size);
  297. buffer[ctx->o_size + 2 + ctx->cn_size] = 0;
  298. goto done;
  299. } else if (ctx->cn_size) {
  300. namesize = ctx->cn_size;
  301. name = data + ctx->cn_offset;
  302. } else if (ctx->o_size) {
  303. namesize = ctx->o_size;
  304. name = data + ctx->o_offset;
  305. } else {
  306. namesize = ctx->email_size;
  307. name = data + ctx->email_offset;
  308. }
  309. single_component:
  310. buffer = kmalloc(namesize + 1, GFP_KERNEL);
  311. if (!buffer)
  312. return -ENOMEM;
  313. memcpy(buffer, name, namesize);
  314. buffer[namesize] = 0;
  315. done:
  316. *_name = buffer;
  317. ctx->cn_size = 0;
  318. ctx->o_size = 0;
  319. ctx->email_size = 0;
  320. return 0;
  321. }
  322. int x509_note_issuer(void *context, size_t hdrlen,
  323. unsigned char tag,
  324. const void *value, size_t vlen)
  325. {
  326. struct x509_parse_context *ctx = context;
  327. ctx->cert->raw_issuer = value;
  328. ctx->cert->raw_issuer_size = vlen;
  329. return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen);
  330. }
  331. int x509_note_subject(void *context, size_t hdrlen,
  332. unsigned char tag,
  333. const void *value, size_t vlen)
  334. {
  335. struct x509_parse_context *ctx = context;
  336. ctx->cert->raw_subject = value;
  337. ctx->cert->raw_subject_size = vlen;
  338. return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->subject, vlen);
  339. }
  340. /*
  341. * Extract the data for the public key algorithm
  342. */
  343. int x509_extract_key_data(void *context, size_t hdrlen,
  344. unsigned char tag,
  345. const void *value, size_t vlen)
  346. {
  347. struct x509_parse_context *ctx = context;
  348. if (ctx->last_oid != OID_rsaEncryption)
  349. return -ENOPKG;
  350. ctx->cert->pub->pkey_algo = PKEY_ALGO_RSA;
  351. /* Discard the BIT STRING metadata */
  352. if (vlen < 1 || *(const u8 *)value != 0)
  353. return -EBADMSG;
  354. ctx->key = value + 1;
  355. ctx->key_size = vlen - 1;
  356. return 0;
  357. }
  358. /*
  359. * Extract a RSA public key value
  360. */
  361. int rsa_extract_mpi(void *context, size_t hdrlen,
  362. unsigned char tag,
  363. const void *value, size_t vlen)
  364. {
  365. struct x509_parse_context *ctx = context;
  366. MPI mpi;
  367. if (ctx->nr_mpi >= ARRAY_SIZE(ctx->cert->pub->mpi)) {
  368. pr_err("Too many public key MPIs in certificate\n");
  369. return -EBADMSG;
  370. }
  371. mpi = mpi_read_raw_data(value, vlen);
  372. if (!mpi)
  373. return -ENOMEM;
  374. ctx->cert->pub->mpi[ctx->nr_mpi++] = mpi;
  375. return 0;
  376. }
  377. /* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */
  378. #define SEQ_TAG_KEYID (ASN1_CONT << 6)
  379. /*
  380. * Process certificate extensions that are used to qualify the certificate.
  381. */
  382. int x509_process_extension(void *context, size_t hdrlen,
  383. unsigned char tag,
  384. const void *value, size_t vlen)
  385. {
  386. struct x509_parse_context *ctx = context;
  387. struct asymmetric_key_id *kid;
  388. const unsigned char *v = value;
  389. pr_debug("Extension: %u\n", ctx->last_oid);
  390. if (ctx->last_oid == OID_subjectKeyIdentifier) {
  391. /* Get hold of the key fingerprint */
  392. if (ctx->cert->skid || vlen < 3)
  393. return -EBADMSG;
  394. if (v[0] != ASN1_OTS || v[1] != vlen - 2)
  395. return -EBADMSG;
  396. v += 2;
  397. vlen -= 2;
  398. ctx->cert->raw_skid_size = vlen;
  399. ctx->cert->raw_skid = v;
  400. kid = asymmetric_key_generate_id(v, vlen, "", 0);
  401. if (IS_ERR(kid))
  402. return PTR_ERR(kid);
  403. ctx->cert->skid = kid;
  404. pr_debug("subjkeyid %*phN\n", kid->len, kid->data);
  405. return 0;
  406. }
  407. if (ctx->last_oid == OID_authorityKeyIdentifier) {
  408. /* Get hold of the CA key fingerprint */
  409. ctx->raw_akid = v;
  410. ctx->raw_akid_size = vlen;
  411. return 0;
  412. }
  413. return 0;
  414. }
  415. /**
  416. * x509_decode_time - Decode an X.509 time ASN.1 object
  417. * @_t: The time to fill in
  418. * @hdrlen: The length of the object header
  419. * @tag: The object tag
  420. * @value: The object value
  421. * @vlen: The size of the object value
  422. *
  423. * Decode an ASN.1 universal time or generalised time field into a struct the
  424. * kernel can handle and check it for validity. The time is decoded thus:
  425. *
  426. * [RFC5280 §4.1.2.5]
  427. * CAs conforming to this profile MUST always encode certificate validity
  428. * dates through the year 2049 as UTCTime; certificate validity dates in
  429. * 2050 or later MUST be encoded as GeneralizedTime. Conforming
  430. * applications MUST be able to process validity dates that are encoded in
  431. * either UTCTime or GeneralizedTime.
  432. */
  433. int x509_decode_time(time64_t *_t, size_t hdrlen,
  434. unsigned char tag,
  435. const unsigned char *value, size_t vlen)
  436. {
  437. static const unsigned char month_lengths[] = { 31, 28, 31, 30, 31, 30,
  438. 31, 31, 30, 31, 30, 31 };
  439. const unsigned char *p = value;
  440. unsigned year, mon, day, hour, min, sec, mon_len;
  441. #define dec2bin(X) ({ unsigned char x = (X) - '0'; if (x > 9) goto invalid_time; x; })
  442. #define DD2bin(P) ({ unsigned x = dec2bin(P[0]) * 10 + dec2bin(P[1]); P += 2; x; })
  443. if (tag == ASN1_UNITIM) {
  444. /* UTCTime: YYMMDDHHMMSSZ */
  445. if (vlen != 13)
  446. goto unsupported_time;
  447. year = DD2bin(p);
  448. if (year >= 50)
  449. year += 1900;
  450. else
  451. year += 2000;
  452. } else if (tag == ASN1_GENTIM) {
  453. /* GenTime: YYYYMMDDHHMMSSZ */
  454. if (vlen != 15)
  455. goto unsupported_time;
  456. year = DD2bin(p) * 100 + DD2bin(p);
  457. if (year >= 1950 && year <= 2049)
  458. goto invalid_time;
  459. } else {
  460. goto unsupported_time;
  461. }
  462. mon = DD2bin(p);
  463. day = DD2bin(p);
  464. hour = DD2bin(p);
  465. min = DD2bin(p);
  466. sec = DD2bin(p);
  467. if (*p != 'Z')
  468. goto unsupported_time;
  469. if (year < 1970 ||
  470. mon < 1 || mon > 12)
  471. goto invalid_time;
  472. mon_len = month_lengths[mon - 1];
  473. if (mon == 2) {
  474. if (year % 4 == 0) {
  475. mon_len = 29;
  476. if (year % 100 == 0) {
  477. mon_len = 28;
  478. if (year % 400 == 0)
  479. mon_len = 29;
  480. }
  481. }
  482. }
  483. if (day < 1 || day > mon_len ||
  484. hour > 23 ||
  485. min > 59 ||
  486. sec > 59)
  487. goto invalid_time;
  488. *_t = mktime64(year, mon, day, hour, min, sec);
  489. return 0;
  490. unsupported_time:
  491. pr_debug("Got unsupported time [tag %02x]: '%*phN'\n",
  492. tag, (int)vlen, value);
  493. return -EBADMSG;
  494. invalid_time:
  495. pr_debug("Got invalid time [tag %02x]: '%*phN'\n",
  496. tag, (int)vlen, value);
  497. return -EBADMSG;
  498. }
  499. EXPORT_SYMBOL_GPL(x509_decode_time);
  500. int x509_note_not_before(void *context, size_t hdrlen,
  501. unsigned char tag,
  502. const void *value, size_t vlen)
  503. {
  504. struct x509_parse_context *ctx = context;
  505. return x509_decode_time(&ctx->cert->valid_from, hdrlen, tag, value, vlen);
  506. }
  507. int x509_note_not_after(void *context, size_t hdrlen,
  508. unsigned char tag,
  509. const void *value, size_t vlen)
  510. {
  511. struct x509_parse_context *ctx = context;
  512. return x509_decode_time(&ctx->cert->valid_to, hdrlen, tag, value, vlen);
  513. }
  514. /*
  515. * Note a key identifier-based AuthorityKeyIdentifier
  516. */
  517. int x509_akid_note_kid(void *context, size_t hdrlen,
  518. unsigned char tag,
  519. const void *value, size_t vlen)
  520. {
  521. struct x509_parse_context *ctx = context;
  522. struct asymmetric_key_id *kid;
  523. pr_debug("AKID: keyid: %*phN\n", (int)vlen, value);
  524. if (ctx->cert->akid_skid)
  525. return 0;
  526. kid = asymmetric_key_generate_id(value, vlen, "", 0);
  527. if (IS_ERR(kid))
  528. return PTR_ERR(kid);
  529. pr_debug("authkeyid %*phN\n", kid->len, kid->data);
  530. ctx->cert->akid_skid = kid;
  531. return 0;
  532. }
  533. /*
  534. * Note a directoryName in an AuthorityKeyIdentifier
  535. */
  536. int x509_akid_note_name(void *context, size_t hdrlen,
  537. unsigned char tag,
  538. const void *value, size_t vlen)
  539. {
  540. struct x509_parse_context *ctx = context;
  541. pr_debug("AKID: name: %*phN\n", (int)vlen, value);
  542. ctx->akid_raw_issuer = value;
  543. ctx->akid_raw_issuer_size = vlen;
  544. return 0;
  545. }
  546. /*
  547. * Note a serial number in an AuthorityKeyIdentifier
  548. */
  549. int x509_akid_note_serial(void *context, size_t hdrlen,
  550. unsigned char tag,
  551. const void *value, size_t vlen)
  552. {
  553. struct x509_parse_context *ctx = context;
  554. struct asymmetric_key_id *kid;
  555. pr_debug("AKID: serial: %*phN\n", (int)vlen, value);
  556. if (!ctx->akid_raw_issuer || ctx->cert->akid_id)
  557. return 0;
  558. kid = asymmetric_key_generate_id(value,
  559. vlen,
  560. ctx->akid_raw_issuer,
  561. ctx->akid_raw_issuer_size);
  562. if (IS_ERR(kid))
  563. return PTR_ERR(kid);
  564. pr_debug("authkeyid %*phN\n", kid->len, kid->data);
  565. ctx->cert->akid_id = kid;
  566. return 0;
  567. }