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_md4: 79 ctx->digest_algo = "md4"; 80 break; 81 case OID_md5: 82 ctx->digest_algo = "md5"; 83 break; 84 case OID_sha1: 85 ctx->digest_algo = "sha1"; 86 break; 87 case OID_sha256: 88 ctx->digest_algo = "sha256"; 89 break; 90 case OID_sha384: 91 ctx->digest_algo = "sha384"; 92 break; 93 case OID_sha512: 94 ctx->digest_algo = "sha512"; 95 break; 96 case OID_sha224: 97 ctx->digest_algo = "sha224"; 98 break; 99 100 case OID__NR: 101 sprint_oid(value, vlen, buffer, sizeof(buffer)); 102 pr_err("Unknown OID: %s\n", buffer); 103 return -EBADMSG; 104 105 default: 106 pr_err("Unsupported content type: %u\n", oid); 107 return -ENOPKG; 108 } 109 110 return 0; 111 } 112 113 /* 114 * Note the digest we're guaranteeing with this certificate 115 */ 116 int mscode_note_digest(void *context, size_t hdrlen, 117 unsigned char tag, 118 const void *value, size_t vlen) 119 { 120 struct pefile_context *ctx = context; 121 122 ctx->digest = kmemdup(value, vlen, GFP_KERNEL); 123 if (!ctx->digest) 124 return -ENOMEM; 125 126 ctx->digest_len = vlen; 127 128 return 0; 129 } 130