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