1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* Parse a Microsoft Individual Code Signing blob 3 * 4 * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #define pr_fmt(fmt) "MSCODE: "fmt 9 #include <linux/kernel.h> 10 #include <linux/slab.h> 11 #include <linux/err.h> 12 #include <linux/oid_registry.h> 13 #include <crypto/pkcs7.h> 14 #include "verify_pefile.h" 15 #include "mscode.asn1.h" 16 17 /* 18 * Parse a Microsoft Individual Code Signing blob 19 */ 20 int mscode_parse(void *_ctx, const void *content_data, size_t data_len, 21 size_t asn1hdrlen) 22 { 23 struct pefile_context *ctx = _ctx; 24 25 content_data -= asn1hdrlen; 26 data_len += asn1hdrlen; 27 pr_devel("Data: %zu [%*ph]\n", data_len, (unsigned)(data_len), 28 content_data); 29 30 return asn1_ber_decoder(&mscode_decoder, ctx, content_data, data_len); 31 } 32 33 /* 34 * Check the content type OID 35 */ 36 int mscode_note_content_type(void *context, size_t hdrlen, 37 unsigned char tag, 38 const void *value, size_t vlen) 39 { 40 enum OID oid; 41 42 oid = look_up_OID(value, vlen); 43 if (oid == OID__NR) { 44 char buffer[50]; 45 46 sprint_oid(value, vlen, buffer, sizeof(buffer)); 47 pr_err("Unknown OID: %s\n", buffer); 48 return -EBADMSG; 49 } 50 51 /* 52 * pesign utility had a bug where it was putting 53 * OID_msIndividualSPKeyPurpose instead of OID_msPeImageDataObjId 54 * So allow both OIDs. 55 */ 56 if (oid != OID_msPeImageDataObjId && 57 oid != OID_msIndividualSPKeyPurpose) { 58 pr_err("Unexpected content type OID %u\n", oid); 59 return -EBADMSG; 60 } 61 62 return 0; 63 } 64 65 /* 66 * Note the digest algorithm OID 67 */ 68 int mscode_note_digest_algo(void *context, size_t hdrlen, 69 unsigned char tag, 70 const void *value, size_t vlen) 71 { 72 struct pefile_context *ctx = context; 73 char buffer[50]; 74 enum OID oid; 75 76 oid = look_up_OID(value, vlen); 77 switch (oid) { 78 case OID_sha256: 79 ctx->digest_algo = "sha256"; 80 break; 81 case OID_sha384: 82 ctx->digest_algo = "sha384"; 83 break; 84 case OID_sha512: 85 ctx->digest_algo = "sha512"; 86 break; 87 case OID_sha3_256: 88 ctx->digest_algo = "sha3-256"; 89 break; 90 case OID_sha3_384: 91 ctx->digest_algo = "sha3-384"; 92 break; 93 case OID_sha3_512: 94 ctx->digest_algo = "sha3-512"; 95 break; 96 97 case OID__NR: 98 sprint_oid(value, vlen, buffer, sizeof(buffer)); 99 pr_err("Unknown OID: %s\n", buffer); 100 return -EBADMSG; 101 102 default: 103 pr_err("Unsupported content type: %u\n", oid); 104 return -ENOPKG; 105 } 106 107 return 0; 108 } 109 110 /* 111 * Note the digest we're guaranteeing with this certificate 112 */ 113 int mscode_note_digest(void *context, size_t hdrlen, 114 unsigned char tag, 115 const void *value, size_t vlen) 116 { 117 struct pefile_context *ctx = context; 118 119 ctx->digest = kmemdup(value, vlen, GFP_KERNEL); 120 if (!ctx->digest) 121 return -ENOMEM; 122 123 ctx->digest_len = vlen; 124 125 return 0; 126 } 127