uboot/lib/crypto/x509_cert_parser.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/* X.509 certificate parser
   3 *
   4 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
   5 * Written by David Howells (dhowells@redhat.com)
   6 */
   7
   8#define pr_fmt(fmt) "X.509: "fmt
   9#include <log.h>
  10#include <dm/devres.h>
  11#include <linux/kernel.h>
  12#ifndef __UBOOT__
  13#include <linux/export.h>
  14#include <linux/slab.h>
  15#endif
  16#include <linux/err.h>
  17#include <linux/oid_registry.h>
  18#ifdef __UBOOT__
  19#include <linux/string.h>
  20#endif
  21#include <crypto/public_key.h>
  22#ifdef __UBOOT__
  23#include <crypto/x509_parser.h>
  24#else
  25#include "x509_parser.h"
  26#endif
  27#include "x509.asn1.h"
  28#include "x509_akid.asn1.h"
  29
  30struct x509_parse_context {
  31        struct x509_certificate *cert;          /* Certificate being constructed */
  32        unsigned long   data;                   /* Start of data */
  33        const void      *cert_start;            /* Start of cert content */
  34        const void      *key;                   /* Key data */
  35        size_t          key_size;               /* Size of key data */
  36        const void      *params;                /* Key parameters */
  37        size_t          params_size;            /* Size of key parameters */
  38        enum OID        key_algo;               /* Public key algorithm */
  39        enum OID        last_oid;               /* Last OID encountered */
  40        enum OID        algo_oid;               /* Algorithm OID */
  41        unsigned char   nr_mpi;                 /* Number of MPIs stored */
  42        u8              o_size;                 /* Size of organizationName (O) */
  43        u8              cn_size;                /* Size of commonName (CN) */
  44        u8              email_size;             /* Size of emailAddress */
  45        u16             o_offset;               /* Offset of organizationName (O) */
  46        u16             cn_offset;              /* Offset of commonName (CN) */
  47        u16             email_offset;           /* Offset of emailAddress */
  48        unsigned        raw_akid_size;
  49        const void      *raw_akid;              /* Raw authorityKeyId in ASN.1 */
  50        const void      *akid_raw_issuer;       /* Raw directoryName in authorityKeyId */
  51        unsigned        akid_raw_issuer_size;
  52};
  53
  54/*
  55 * Free an X.509 certificate
  56 */
  57void x509_free_certificate(struct x509_certificate *cert)
  58{
  59        if (cert) {
  60                public_key_free(cert->pub);
  61                public_key_signature_free(cert->sig);
  62                kfree(cert->issuer);
  63                kfree(cert->subject);
  64                kfree(cert->id);
  65                kfree(cert->skid);
  66                kfree(cert);
  67        }
  68}
  69EXPORT_SYMBOL_GPL(x509_free_certificate);
  70
  71/*
  72 * Parse an X.509 certificate
  73 */
  74struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
  75{
  76        struct x509_certificate *cert;
  77        struct x509_parse_context *ctx;
  78        struct asymmetric_key_id *kid;
  79        long ret;
  80
  81        ret = -ENOMEM;
  82        cert = kzalloc(sizeof(struct x509_certificate), GFP_KERNEL);
  83        if (!cert)
  84                goto error_no_cert;
  85        cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL);
  86        if (!cert->pub)
  87                goto error_no_ctx;
  88        cert->sig = kzalloc(sizeof(struct public_key_signature), GFP_KERNEL);
  89        if (!cert->sig)
  90                goto error_no_ctx;
  91        ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL);
  92        if (!ctx)
  93                goto error_no_ctx;
  94
  95        ctx->cert = cert;
  96        ctx->data = (unsigned long)data;
  97
  98        /* Attempt to decode the certificate */
  99        ret = asn1_ber_decoder(&x509_decoder, ctx, data, datalen);
 100        if (ret < 0)
 101                goto error_decode;
 102
 103        /* Decode the AuthorityKeyIdentifier */
 104        if (ctx->raw_akid) {
 105                pr_devel("AKID: %u %*phN\n",
 106                         ctx->raw_akid_size, ctx->raw_akid_size, ctx->raw_akid);
 107                ret = asn1_ber_decoder(&x509_akid_decoder, ctx,
 108                                       ctx->raw_akid, ctx->raw_akid_size);
 109                if (ret < 0) {
 110                        pr_warn("Couldn't decode AuthKeyIdentifier\n");
 111                        goto error_decode;
 112                }
 113        }
 114
 115        ret = -ENOMEM;
 116        cert->pub->key = kmemdup(ctx->key, ctx->key_size, GFP_KERNEL);
 117        if (!cert->pub->key)
 118                goto error_decode;
 119
 120        cert->pub->keylen = ctx->key_size;
 121
 122        cert->pub->params = kmemdup(ctx->params, ctx->params_size, GFP_KERNEL);
 123        if (!cert->pub->params)
 124                goto error_decode;
 125
 126        cert->pub->paramlen = ctx->params_size;
 127        cert->pub->algo = ctx->key_algo;
 128
 129        /* Grab the signature bits */
 130        ret = x509_get_sig_params(cert);
 131        if (ret < 0)
 132                goto error_decode;
 133
 134        /* Generate cert issuer + serial number key ID */
 135        kid = asymmetric_key_generate_id(cert->raw_serial,
 136                                         cert->raw_serial_size,
 137                                         cert->raw_issuer,
 138                                         cert->raw_issuer_size);
 139        if (IS_ERR(kid)) {
 140                ret = PTR_ERR(kid);
 141                goto error_decode;
 142        }
 143        cert->id = kid;
 144
 145        /* Detect self-signed certificates */
 146        ret = x509_check_for_self_signed(cert);
 147        if (ret < 0)
 148                goto error_decode;
 149
 150        kfree(ctx);
 151        return cert;
 152
 153error_decode:
 154        kfree(ctx);
 155error_no_ctx:
 156        x509_free_certificate(cert);
 157error_no_cert:
 158        return ERR_PTR(ret);
 159}
 160EXPORT_SYMBOL_GPL(x509_cert_parse);
 161
 162/*
 163 * Note an OID when we find one for later processing when we know how
 164 * to interpret it.
 165 */
 166int x509_note_OID(void *context, size_t hdrlen,
 167             unsigned char tag,
 168             const void *value, size_t vlen)
 169{
 170        struct x509_parse_context *ctx = context;
 171
 172        ctx->last_oid = look_up_OID(value, vlen);
 173        if (ctx->last_oid == OID__NR) {
 174                char buffer[50];
 175                sprint_oid(value, vlen, buffer, sizeof(buffer));
 176                pr_debug("Unknown OID: [%lu] %s\n",
 177                         (unsigned long)value - ctx->data, buffer);
 178        }
 179        return 0;
 180}
 181
 182/*
 183 * Save the position of the TBS data so that we can check the signature over it
 184 * later.
 185 */
 186int x509_note_tbs_certificate(void *context, size_t hdrlen,
 187                              unsigned char tag,
 188                              const void *value, size_t vlen)
 189{
 190        struct x509_parse_context *ctx = context;
 191
 192        pr_debug("x509_note_tbs_certificate(,%zu,%02x,%ld,%zu)!\n",
 193                 hdrlen, tag, (unsigned long)value - ctx->data, vlen);
 194
 195        ctx->cert->tbs = value - hdrlen;
 196        ctx->cert->tbs_size = vlen + hdrlen;
 197        return 0;
 198}
 199
 200/*
 201 * Record the public key algorithm
 202 */
 203int x509_note_pkey_algo(void *context, size_t hdrlen,
 204                        unsigned char tag,
 205                        const void *value, size_t vlen)
 206{
 207        struct x509_parse_context *ctx = context;
 208
 209        pr_debug("PubKey Algo: %u\n", ctx->last_oid);
 210
 211        switch (ctx->last_oid) {
 212        case OID_md2WithRSAEncryption:
 213        case OID_md3WithRSAEncryption:
 214        default:
 215                return -ENOPKG; /* Unsupported combination */
 216
 217        case OID_md4WithRSAEncryption:
 218                ctx->cert->sig->hash_algo = "md4";
 219                goto rsa_pkcs1;
 220
 221        case OID_sha1WithRSAEncryption:
 222                ctx->cert->sig->hash_algo = "sha1";
 223                goto rsa_pkcs1;
 224
 225        case OID_sha256WithRSAEncryption:
 226                ctx->cert->sig->hash_algo = "sha256";
 227                goto rsa_pkcs1;
 228
 229        case OID_sha384WithRSAEncryption:
 230                ctx->cert->sig->hash_algo = "sha384";
 231                goto rsa_pkcs1;
 232
 233        case OID_sha512WithRSAEncryption:
 234                ctx->cert->sig->hash_algo = "sha512";
 235                goto rsa_pkcs1;
 236
 237        case OID_sha224WithRSAEncryption:
 238                ctx->cert->sig->hash_algo = "sha224";
 239                goto rsa_pkcs1;
 240
 241        case OID_gost2012Signature256:
 242                ctx->cert->sig->hash_algo = "streebog256";
 243                goto ecrdsa;
 244
 245        case OID_gost2012Signature512:
 246                ctx->cert->sig->hash_algo = "streebog512";
 247                goto ecrdsa;
 248        }
 249
 250rsa_pkcs1:
 251        ctx->cert->sig->pkey_algo = "rsa";
 252        ctx->cert->sig->encoding = "pkcs1";
 253        ctx->algo_oid = ctx->last_oid;
 254        return 0;
 255ecrdsa:
 256        ctx->cert->sig->pkey_algo = "ecrdsa";
 257        ctx->cert->sig->encoding = "raw";
 258        ctx->algo_oid = ctx->last_oid;
 259        return 0;
 260}
 261
 262/*
 263 * Note the whereabouts and type of the signature.
 264 */
 265int x509_note_signature(void *context, size_t hdrlen,
 266                        unsigned char tag,
 267                        const void *value, size_t vlen)
 268{
 269        struct x509_parse_context *ctx = context;
 270
 271        pr_debug("Signature type: %u size %zu\n", ctx->last_oid, vlen);
 272
 273        if (ctx->last_oid != ctx->algo_oid) {
 274                pr_warn("Got cert with pkey (%u) and sig (%u) algorithm OIDs\n",
 275                        ctx->algo_oid, ctx->last_oid);
 276                return -EINVAL;
 277        }
 278
 279        if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0 ||
 280            strcmp(ctx->cert->sig->pkey_algo, "ecrdsa") == 0) {
 281                /* Discard the BIT STRING metadata */
 282                if (vlen < 1 || *(const u8 *)value != 0)
 283                        return -EBADMSG;
 284
 285                value++;
 286                vlen--;
 287        }
 288
 289        ctx->cert->raw_sig = value;
 290        ctx->cert->raw_sig_size = vlen;
 291        return 0;
 292}
 293
 294/*
 295 * Note the certificate serial number
 296 */
 297int x509_note_serial(void *context, size_t hdrlen,
 298                     unsigned char tag,
 299                     const void *value, size_t vlen)
 300{
 301        struct x509_parse_context *ctx = context;
 302        ctx->cert->raw_serial = value;
 303        ctx->cert->raw_serial_size = vlen;
 304        return 0;
 305}
 306
 307/*
 308 * Note some of the name segments from which we'll fabricate a name.
 309 */
 310int x509_extract_name_segment(void *context, size_t hdrlen,
 311                              unsigned char tag,
 312                              const void *value, size_t vlen)
 313{
 314        struct x509_parse_context *ctx = context;
 315
 316        switch (ctx->last_oid) {
 317        case OID_commonName:
 318                ctx->cn_size = vlen;
 319                ctx->cn_offset = (unsigned long)value - ctx->data;
 320                break;
 321        case OID_organizationName:
 322                ctx->o_size = vlen;
 323                ctx->o_offset = (unsigned long)value - ctx->data;
 324                break;
 325        case OID_email_address:
 326                ctx->email_size = vlen;
 327                ctx->email_offset = (unsigned long)value - ctx->data;
 328                break;
 329        default:
 330                break;
 331        }
 332
 333        return 0;
 334}
 335
 336/*
 337 * Fabricate and save the issuer and subject names
 338 */
 339static int x509_fabricate_name(struct x509_parse_context *ctx, size_t hdrlen,
 340                               unsigned char tag,
 341                               char **_name, size_t vlen)
 342{
 343        const void *name, *data = (const void *)ctx->data;
 344        size_t namesize;
 345        char *buffer;
 346
 347        if (*_name)
 348                return -EINVAL;
 349
 350        /* Empty name string if no material */
 351        if (!ctx->cn_size && !ctx->o_size && !ctx->email_size) {
 352                buffer = kmalloc(1, GFP_KERNEL);
 353                if (!buffer)
 354                        return -ENOMEM;
 355                buffer[0] = 0;
 356                goto done;
 357        }
 358
 359        if (ctx->cn_size && ctx->o_size) {
 360                /* Consider combining O and CN, but use only the CN if it is
 361                 * prefixed by the O, or a significant portion thereof.
 362                 */
 363                namesize = ctx->cn_size;
 364                name = data + ctx->cn_offset;
 365                if (ctx->cn_size >= ctx->o_size &&
 366                    memcmp(data + ctx->cn_offset, data + ctx->o_offset,
 367                           ctx->o_size) == 0)
 368                        goto single_component;
 369                if (ctx->cn_size >= 7 &&
 370                    ctx->o_size >= 7 &&
 371                    memcmp(data + ctx->cn_offset, data + ctx->o_offset, 7) == 0)
 372                        goto single_component;
 373
 374                buffer = kmalloc(ctx->o_size + 2 + ctx->cn_size + 1,
 375                                 GFP_KERNEL);
 376                if (!buffer)
 377                        return -ENOMEM;
 378
 379                memcpy(buffer,
 380                       data + ctx->o_offset, ctx->o_size);
 381                buffer[ctx->o_size + 0] = ':';
 382                buffer[ctx->o_size + 1] = ' ';
 383                memcpy(buffer + ctx->o_size + 2,
 384                       data + ctx->cn_offset, ctx->cn_size);
 385                buffer[ctx->o_size + 2 + ctx->cn_size] = 0;
 386                goto done;
 387
 388        } else if (ctx->cn_size) {
 389                namesize = ctx->cn_size;
 390                name = data + ctx->cn_offset;
 391        } else if (ctx->o_size) {
 392                namesize = ctx->o_size;
 393                name = data + ctx->o_offset;
 394        } else {
 395                namesize = ctx->email_size;
 396                name = data + ctx->email_offset;
 397        }
 398
 399single_component:
 400        buffer = kmalloc(namesize + 1, GFP_KERNEL);
 401        if (!buffer)
 402                return -ENOMEM;
 403        memcpy(buffer, name, namesize);
 404        buffer[namesize] = 0;
 405
 406done:
 407        *_name = buffer;
 408        ctx->cn_size = 0;
 409        ctx->o_size = 0;
 410        ctx->email_size = 0;
 411        return 0;
 412}
 413
 414int x509_note_issuer(void *context, size_t hdrlen,
 415                     unsigned char tag,
 416                     const void *value, size_t vlen)
 417{
 418        struct x509_parse_context *ctx = context;
 419        ctx->cert->raw_issuer = value;
 420        ctx->cert->raw_issuer_size = vlen;
 421        return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen);
 422}
 423
 424int x509_note_subject(void *context, size_t hdrlen,
 425                      unsigned char tag,
 426                      const void *value, size_t vlen)
 427{
 428        struct x509_parse_context *ctx = context;
 429        ctx->cert->raw_subject = value;
 430        ctx->cert->raw_subject_size = vlen;
 431        return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->subject, vlen);
 432}
 433
 434/*
 435 * Extract the parameters for the public key
 436 */
 437int x509_note_params(void *context, size_t hdrlen,
 438                     unsigned char tag,
 439                     const void *value, size_t vlen)
 440{
 441        struct x509_parse_context *ctx = context;
 442
 443        /*
 444         * AlgorithmIdentifier is used three times in the x509, we should skip
 445         * first and ignore third, using second one which is after subject and
 446         * before subjectPublicKey.
 447         */
 448        if (!ctx->cert->raw_subject || ctx->key)
 449                return 0;
 450        ctx->params = value - hdrlen;
 451        ctx->params_size = vlen + hdrlen;
 452        return 0;
 453}
 454
 455/*
 456 * Extract the data for the public key algorithm
 457 */
 458int x509_extract_key_data(void *context, size_t hdrlen,
 459                          unsigned char tag,
 460                          const void *value, size_t vlen)
 461{
 462        struct x509_parse_context *ctx = context;
 463
 464        ctx->key_algo = ctx->last_oid;
 465        if (ctx->last_oid == OID_rsaEncryption)
 466                ctx->cert->pub->pkey_algo = "rsa";
 467        else if (ctx->last_oid == OID_gost2012PKey256 ||
 468                 ctx->last_oid == OID_gost2012PKey512)
 469                ctx->cert->pub->pkey_algo = "ecrdsa";
 470        else
 471                return -ENOPKG;
 472
 473        /* Discard the BIT STRING metadata */
 474        if (vlen < 1 || *(const u8 *)value != 0)
 475                return -EBADMSG;
 476        ctx->key = value + 1;
 477        ctx->key_size = vlen - 1;
 478        return 0;
 479}
 480
 481/* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */
 482#define SEQ_TAG_KEYID (ASN1_CONT << 6)
 483
 484/*
 485 * Process certificate extensions that are used to qualify the certificate.
 486 */
 487int x509_process_extension(void *context, size_t hdrlen,
 488                           unsigned char tag,
 489                           const void *value, size_t vlen)
 490{
 491        struct x509_parse_context *ctx = context;
 492        struct asymmetric_key_id *kid;
 493        const unsigned char *v = value;
 494
 495        pr_debug("Extension: %u\n", ctx->last_oid);
 496
 497        if (ctx->last_oid == OID_subjectKeyIdentifier) {
 498                /* Get hold of the key fingerprint */
 499                if (ctx->cert->skid || vlen < 3)
 500                        return -EBADMSG;
 501                if (v[0] != ASN1_OTS || v[1] != vlen - 2)
 502                        return -EBADMSG;
 503                v += 2;
 504                vlen -= 2;
 505
 506                ctx->cert->raw_skid_size = vlen;
 507                ctx->cert->raw_skid = v;
 508                kid = asymmetric_key_generate_id(v, vlen, "", 0);
 509                if (IS_ERR(kid))
 510                        return PTR_ERR(kid);
 511                ctx->cert->skid = kid;
 512                pr_debug("subjkeyid %*phN\n", kid->len, kid->data);
 513                return 0;
 514        }
 515
 516        if (ctx->last_oid == OID_authorityKeyIdentifier) {
 517                /* Get hold of the CA key fingerprint */
 518                ctx->raw_akid = v;
 519                ctx->raw_akid_size = vlen;
 520                return 0;
 521        }
 522
 523        return 0;
 524}
 525
 526/**
 527 * x509_decode_time - Decode an X.509 time ASN.1 object
 528 * @_t: The time to fill in
 529 * @hdrlen: The length of the object header
 530 * @tag: The object tag
 531 * @value: The object value
 532 * @vlen: The size of the object value
 533 *
 534 * Decode an ASN.1 universal time or generalised time field into a struct the
 535 * kernel can handle and check it for validity.  The time is decoded thus:
 536 *
 537 *      [RFC5280 ยง4.1.2.5]
 538 *      CAs conforming to this profile MUST always encode certificate validity
 539 *      dates through the year 2049 as UTCTime; certificate validity dates in
 540 *      2050 or later MUST be encoded as GeneralizedTime.  Conforming
 541 *      applications MUST be able to process validity dates that are encoded in
 542 *      either UTCTime or GeneralizedTime.
 543 */
 544int x509_decode_time(time64_t *_t,  size_t hdrlen,
 545                     unsigned char tag,
 546                     const unsigned char *value, size_t vlen)
 547{
 548        static const unsigned char month_lengths[] = { 31, 28, 31, 30, 31, 30,
 549                                                       31, 31, 30, 31, 30, 31 };
 550        const unsigned char *p = value;
 551        unsigned year, mon, day, hour, min, sec, mon_len;
 552
 553#define dec2bin(X) ({ unsigned char x = (X) - '0'; if (x > 9) goto invalid_time; x; })
 554#define DD2bin(P) ({ unsigned x = dec2bin(P[0]) * 10 + dec2bin(P[1]); P += 2; x; })
 555
 556        if (tag == ASN1_UNITIM) {
 557                /* UTCTime: YYMMDDHHMMSSZ */
 558                if (vlen != 13)
 559                        goto unsupported_time;
 560                year = DD2bin(p);
 561                if (year >= 50)
 562                        year += 1900;
 563                else
 564                        year += 2000;
 565        } else if (tag == ASN1_GENTIM) {
 566                /* GenTime: YYYYMMDDHHMMSSZ */
 567                if (vlen != 15)
 568                        goto unsupported_time;
 569                year = DD2bin(p) * 100 + DD2bin(p);
 570                if (year >= 1950 && year <= 2049)
 571                        goto invalid_time;
 572        } else {
 573                goto unsupported_time;
 574        }
 575
 576        mon  = DD2bin(p);
 577        day = DD2bin(p);
 578        hour = DD2bin(p);
 579        min  = DD2bin(p);
 580        sec  = DD2bin(p);
 581
 582        if (*p != 'Z')
 583                goto unsupported_time;
 584
 585        if (year < 1970 ||
 586            mon < 1 || mon > 12)
 587                goto invalid_time;
 588
 589        mon_len = month_lengths[mon - 1];
 590        if (mon == 2) {
 591                if (year % 4 == 0) {
 592                        mon_len = 29;
 593                        if (year % 100 == 0) {
 594                                mon_len = 28;
 595                                if (year % 400 == 0)
 596                                        mon_len = 29;
 597                        }
 598                }
 599        }
 600
 601        if (day < 1 || day > mon_len ||
 602            hour > 24 || /* ISO 8601 permits 24:00:00 as midnight tomorrow */
 603            min > 59 ||
 604            sec > 60) /* ISO 8601 permits leap seconds [X.680 46.3] */
 605                goto invalid_time;
 606
 607        *_t = mktime64(year, mon, day, hour, min, sec);
 608        return 0;
 609
 610unsupported_time:
 611        pr_debug("Got unsupported time [tag %02x]: '%*phN'\n",
 612                 tag, (int)vlen, value);
 613        return -EBADMSG;
 614invalid_time:
 615        pr_debug("Got invalid time [tag %02x]: '%*phN'\n",
 616                 tag, (int)vlen, value);
 617        return -EBADMSG;
 618}
 619EXPORT_SYMBOL_GPL(x509_decode_time);
 620
 621int x509_note_not_before(void *context, size_t hdrlen,
 622                         unsigned char tag,
 623                         const void *value, size_t vlen)
 624{
 625        struct x509_parse_context *ctx = context;
 626        return x509_decode_time(&ctx->cert->valid_from, hdrlen, tag, value, vlen);
 627}
 628
 629int x509_note_not_after(void *context, size_t hdrlen,
 630                        unsigned char tag,
 631                        const void *value, size_t vlen)
 632{
 633        struct x509_parse_context *ctx = context;
 634        return x509_decode_time(&ctx->cert->valid_to, hdrlen, tag, value, vlen);
 635}
 636
 637/*
 638 * Note a key identifier-based AuthorityKeyIdentifier
 639 */
 640int x509_akid_note_kid(void *context, size_t hdrlen,
 641                       unsigned char tag,
 642                       const void *value, size_t vlen)
 643{
 644        struct x509_parse_context *ctx = context;
 645        struct asymmetric_key_id *kid;
 646
 647        pr_debug("AKID: keyid: %*phN\n", (int)vlen, value);
 648
 649        if (ctx->cert->sig->auth_ids[1])
 650                return 0;
 651
 652        kid = asymmetric_key_generate_id(value, vlen, "", 0);
 653        if (IS_ERR(kid))
 654                return PTR_ERR(kid);
 655        pr_debug("authkeyid %*phN\n", kid->len, kid->data);
 656        ctx->cert->sig->auth_ids[1] = kid;
 657        return 0;
 658}
 659
 660/*
 661 * Note a directoryName in an AuthorityKeyIdentifier
 662 */
 663int x509_akid_note_name(void *context, size_t hdrlen,
 664                        unsigned char tag,
 665                        const void *value, size_t vlen)
 666{
 667        struct x509_parse_context *ctx = context;
 668
 669        pr_debug("AKID: name: %*phN\n", (int)vlen, value);
 670
 671        ctx->akid_raw_issuer = value;
 672        ctx->akid_raw_issuer_size = vlen;
 673        return 0;
 674}
 675
 676/*
 677 * Note a serial number in an AuthorityKeyIdentifier
 678 */
 679int x509_akid_note_serial(void *context, size_t hdrlen,
 680                          unsigned char tag,
 681                          const void *value, size_t vlen)
 682{
 683        struct x509_parse_context *ctx = context;
 684        struct asymmetric_key_id *kid;
 685
 686        pr_debug("AKID: serial: %*phN\n", (int)vlen, value);
 687
 688        if (!ctx->akid_raw_issuer || ctx->cert->sig->auth_ids[0])
 689                return 0;
 690
 691        kid = asymmetric_key_generate_id(value,
 692                                         vlen,
 693                                         ctx->akid_raw_issuer,
 694                                         ctx->akid_raw_issuer_size);
 695        if (IS_ERR(kid))
 696                return PTR_ERR(kid);
 697
 698        pr_debug("authkeyid %*phN\n", kid->len, kid->data);
 699        ctx->cert->sig->auth_ids[0] = kid;
 700        return 0;
 701}
 702