root/crypto/asymmetric_keys/x509_cert_parser.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. x509_free_certificate
  2. x509_cert_parse
  3. x509_note_OID
  4. x509_note_tbs_certificate
  5. x509_note_pkey_algo
  6. x509_note_signature
  7. x509_note_serial
  8. x509_extract_name_segment
  9. x509_fabricate_name
  10. x509_note_issuer
  11. x509_note_subject
  12. x509_note_params
  13. x509_extract_key_data
  14. x509_process_extension
  15. x509_decode_time
  16. x509_note_not_before
  17. x509_note_not_after
  18. x509_akid_note_kid
  19. x509_akid_note_name
  20. x509_akid_note_serial

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

/* [<][>][^][v][top][bottom][index][help] */