Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/crypto/asymmetric_keys/mscode_parser.c
26278 views
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 ([email protected])
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_sha1:
79
ctx->digest_algo = "sha1";
80
break;
81
case OID_sha256:
82
ctx->digest_algo = "sha256";
83
break;
84
case OID_sha384:
85
ctx->digest_algo = "sha384";
86
break;
87
case OID_sha512:
88
ctx->digest_algo = "sha512";
89
break;
90
case OID_sha3_256:
91
ctx->digest_algo = "sha3-256";
92
break;
93
case OID_sha3_384:
94
ctx->digest_algo = "sha3-384";
95
break;
96
case OID_sha3_512:
97
ctx->digest_algo = "sha3-512";
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
131