Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* Parse a Microsoft Individual Code Signing blob
0003  *
0004  * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.
0005  * Written by David Howells (dhowells@redhat.com)
0006  */
0007 
0008 #define pr_fmt(fmt) "MSCODE: "fmt
0009 #include <linux/kernel.h>
0010 #include <linux/slab.h>
0011 #include <linux/err.h>
0012 #include <linux/oid_registry.h>
0013 #include <crypto/pkcs7.h>
0014 #include "verify_pefile.h"
0015 #include "mscode.asn1.h"
0016 
0017 /*
0018  * Parse a Microsoft Individual Code Signing blob
0019  */
0020 int mscode_parse(void *_ctx, const void *content_data, size_t data_len,
0021          size_t asn1hdrlen)
0022 {
0023     struct pefile_context *ctx = _ctx;
0024 
0025     content_data -= asn1hdrlen;
0026     data_len += asn1hdrlen;
0027     pr_devel("Data: %zu [%*ph]\n", data_len, (unsigned)(data_len),
0028          content_data);
0029 
0030     return asn1_ber_decoder(&mscode_decoder, ctx, content_data, data_len);
0031 }
0032 
0033 /*
0034  * Check the content type OID
0035  */
0036 int mscode_note_content_type(void *context, size_t hdrlen,
0037                  unsigned char tag,
0038                  const void *value, size_t vlen)
0039 {
0040     enum OID oid;
0041 
0042     oid = look_up_OID(value, vlen);
0043     if (oid == OID__NR) {
0044         char buffer[50];
0045 
0046         sprint_oid(value, vlen, buffer, sizeof(buffer));
0047         pr_err("Unknown OID: %s\n", buffer);
0048         return -EBADMSG;
0049     }
0050 
0051     /*
0052      * pesign utility had a bug where it was putting
0053      * OID_msIndividualSPKeyPurpose instead of OID_msPeImageDataObjId
0054      * So allow both OIDs.
0055      */
0056     if (oid != OID_msPeImageDataObjId &&
0057         oid != OID_msIndividualSPKeyPurpose) {
0058         pr_err("Unexpected content type OID %u\n", oid);
0059         return -EBADMSG;
0060     }
0061 
0062     return 0;
0063 }
0064 
0065 /*
0066  * Note the digest algorithm OID
0067  */
0068 int mscode_note_digest_algo(void *context, size_t hdrlen,
0069                 unsigned char tag,
0070                 const void *value, size_t vlen)
0071 {
0072     struct pefile_context *ctx = context;
0073     char buffer[50];
0074     enum OID oid;
0075 
0076     oid = look_up_OID(value, vlen);
0077     switch (oid) {
0078     case OID_md4:
0079         ctx->digest_algo = "md4";
0080         break;
0081     case OID_md5:
0082         ctx->digest_algo = "md5";
0083         break;
0084     case OID_sha1:
0085         ctx->digest_algo = "sha1";
0086         break;
0087     case OID_sha256:
0088         ctx->digest_algo = "sha256";
0089         break;
0090     case OID_sha384:
0091         ctx->digest_algo = "sha384";
0092         break;
0093     case OID_sha512:
0094         ctx->digest_algo = "sha512";
0095         break;
0096     case OID_sha224:
0097         ctx->digest_algo = "sha224";
0098         break;
0099 
0100     case OID__NR:
0101         sprint_oid(value, vlen, buffer, sizeof(buffer));
0102         pr_err("Unknown OID: %s\n", buffer);
0103         return -EBADMSG;
0104 
0105     default:
0106         pr_err("Unsupported content type: %u\n", oid);
0107         return -ENOPKG;
0108     }
0109 
0110     return 0;
0111 }
0112 
0113 /*
0114  * Note the digest we're guaranteeing with this certificate
0115  */
0116 int mscode_note_digest(void *context, size_t hdrlen,
0117                unsigned char tag,
0118                const void *value, size_t vlen)
0119 {
0120     struct pefile_context *ctx = context;
0121 
0122     ctx->digest = kmemdup(value, vlen, GFP_KERNEL);
0123     if (!ctx->digest)
0124         return -ENOMEM;
0125 
0126     ctx->digest_len = vlen;
0127 
0128     return 0;
0129 }