1*cc4ad7daSAndroid Build Coastguard Worker /*
2*cc4ad7daSAndroid Build Coastguard Worker * libkmod - module signature display
3*cc4ad7daSAndroid Build Coastguard Worker *
4*cc4ad7daSAndroid Build Coastguard Worker * Copyright (C) 2013 Michal Marek, SUSE
5*cc4ad7daSAndroid Build Coastguard Worker *
6*cc4ad7daSAndroid Build Coastguard Worker * This library is free software; you can redistribute it and/or
7*cc4ad7daSAndroid Build Coastguard Worker * modify it under the terms of the GNU Lesser General Public
8*cc4ad7daSAndroid Build Coastguard Worker * License as published by the Free Software Foundation; either
9*cc4ad7daSAndroid Build Coastguard Worker * version 2.1 of the License, or (at your option) any later version.
10*cc4ad7daSAndroid Build Coastguard Worker *
11*cc4ad7daSAndroid Build Coastguard Worker * This library is distributed in the hope that it will be useful,
12*cc4ad7daSAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*cc4ad7daSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14*cc4ad7daSAndroid Build Coastguard Worker * Lesser General Public License for more details.
15*cc4ad7daSAndroid Build Coastguard Worker *
16*cc4ad7daSAndroid Build Coastguard Worker * You should have received a copy of the GNU Lesser General Public
17*cc4ad7daSAndroid Build Coastguard Worker * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18*cc4ad7daSAndroid Build Coastguard Worker */
19*cc4ad7daSAndroid Build Coastguard Worker
20*cc4ad7daSAndroid Build Coastguard Worker #include <inttypes.h>
21*cc4ad7daSAndroid Build Coastguard Worker #ifdef ENABLE_OPENSSL
22*cc4ad7daSAndroid Build Coastguard Worker #include <openssl/pkcs7.h>
23*cc4ad7daSAndroid Build Coastguard Worker #include <openssl/ssl.h>
24*cc4ad7daSAndroid Build Coastguard Worker #endif
25*cc4ad7daSAndroid Build Coastguard Worker #include <stdio.h>
26*cc4ad7daSAndroid Build Coastguard Worker #include <stdlib.h>
27*cc4ad7daSAndroid Build Coastguard Worker #include <string.h>
28*cc4ad7daSAndroid Build Coastguard Worker
29*cc4ad7daSAndroid Build Coastguard Worker #include <shared/missing.h>
30*cc4ad7daSAndroid Build Coastguard Worker #include <shared/util.h>
31*cc4ad7daSAndroid Build Coastguard Worker
32*cc4ad7daSAndroid Build Coastguard Worker #include "libkmod-internal.h"
33*cc4ad7daSAndroid Build Coastguard Worker
34*cc4ad7daSAndroid Build Coastguard Worker /* These types and tables were copied from the 3.7 kernel sources.
35*cc4ad7daSAndroid Build Coastguard Worker * As this is just description of the signature format, it should not be
36*cc4ad7daSAndroid Build Coastguard Worker * considered derived work (so libkmod can use the LGPL license).
37*cc4ad7daSAndroid Build Coastguard Worker */
38*cc4ad7daSAndroid Build Coastguard Worker enum pkey_algo {
39*cc4ad7daSAndroid Build Coastguard Worker PKEY_ALGO_DSA,
40*cc4ad7daSAndroid Build Coastguard Worker PKEY_ALGO_RSA,
41*cc4ad7daSAndroid Build Coastguard Worker PKEY_ALGO__LAST
42*cc4ad7daSAndroid Build Coastguard Worker };
43*cc4ad7daSAndroid Build Coastguard Worker
44*cc4ad7daSAndroid Build Coastguard Worker static const char *const pkey_algo[PKEY_ALGO__LAST] = {
45*cc4ad7daSAndroid Build Coastguard Worker [PKEY_ALGO_DSA] = "DSA",
46*cc4ad7daSAndroid Build Coastguard Worker [PKEY_ALGO_RSA] = "RSA",
47*cc4ad7daSAndroid Build Coastguard Worker };
48*cc4ad7daSAndroid Build Coastguard Worker
49*cc4ad7daSAndroid Build Coastguard Worker enum pkey_hash_algo {
50*cc4ad7daSAndroid Build Coastguard Worker PKEY_HASH_MD4,
51*cc4ad7daSAndroid Build Coastguard Worker PKEY_HASH_MD5,
52*cc4ad7daSAndroid Build Coastguard Worker PKEY_HASH_SHA1,
53*cc4ad7daSAndroid Build Coastguard Worker PKEY_HASH_RIPE_MD_160,
54*cc4ad7daSAndroid Build Coastguard Worker PKEY_HASH_SHA256,
55*cc4ad7daSAndroid Build Coastguard Worker PKEY_HASH_SHA384,
56*cc4ad7daSAndroid Build Coastguard Worker PKEY_HASH_SHA512,
57*cc4ad7daSAndroid Build Coastguard Worker PKEY_HASH_SHA224,
58*cc4ad7daSAndroid Build Coastguard Worker PKEY_HASH_SM3,
59*cc4ad7daSAndroid Build Coastguard Worker PKEY_HASH__LAST
60*cc4ad7daSAndroid Build Coastguard Worker };
61*cc4ad7daSAndroid Build Coastguard Worker
62*cc4ad7daSAndroid Build Coastguard Worker const char *const pkey_hash_algo[PKEY_HASH__LAST] = {
63*cc4ad7daSAndroid Build Coastguard Worker [PKEY_HASH_MD4] = "md4",
64*cc4ad7daSAndroid Build Coastguard Worker [PKEY_HASH_MD5] = "md5",
65*cc4ad7daSAndroid Build Coastguard Worker [PKEY_HASH_SHA1] = "sha1",
66*cc4ad7daSAndroid Build Coastguard Worker [PKEY_HASH_RIPE_MD_160] = "rmd160",
67*cc4ad7daSAndroid Build Coastguard Worker [PKEY_HASH_SHA256] = "sha256",
68*cc4ad7daSAndroid Build Coastguard Worker [PKEY_HASH_SHA384] = "sha384",
69*cc4ad7daSAndroid Build Coastguard Worker [PKEY_HASH_SHA512] = "sha512",
70*cc4ad7daSAndroid Build Coastguard Worker [PKEY_HASH_SHA224] = "sha224",
71*cc4ad7daSAndroid Build Coastguard Worker [PKEY_HASH_SM3] = "sm3",
72*cc4ad7daSAndroid Build Coastguard Worker };
73*cc4ad7daSAndroid Build Coastguard Worker
74*cc4ad7daSAndroid Build Coastguard Worker enum pkey_id_type {
75*cc4ad7daSAndroid Build Coastguard Worker PKEY_ID_PGP, /* OpenPGP generated key ID */
76*cc4ad7daSAndroid Build Coastguard Worker PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */
77*cc4ad7daSAndroid Build Coastguard Worker PKEY_ID_PKCS7, /* Signature in PKCS#7 message */
78*cc4ad7daSAndroid Build Coastguard Worker PKEY_ID_TYPE__LAST
79*cc4ad7daSAndroid Build Coastguard Worker };
80*cc4ad7daSAndroid Build Coastguard Worker
81*cc4ad7daSAndroid Build Coastguard Worker const char *const pkey_id_type[PKEY_ID_TYPE__LAST] = {
82*cc4ad7daSAndroid Build Coastguard Worker [PKEY_ID_PGP] = "PGP",
83*cc4ad7daSAndroid Build Coastguard Worker [PKEY_ID_X509] = "X509",
84*cc4ad7daSAndroid Build Coastguard Worker [PKEY_ID_PKCS7] = "PKCS#7",
85*cc4ad7daSAndroid Build Coastguard Worker };
86*cc4ad7daSAndroid Build Coastguard Worker
87*cc4ad7daSAndroid Build Coastguard Worker /*
88*cc4ad7daSAndroid Build Coastguard Worker * Module signature information block.
89*cc4ad7daSAndroid Build Coastguard Worker */
90*cc4ad7daSAndroid Build Coastguard Worker struct module_signature {
91*cc4ad7daSAndroid Build Coastguard Worker uint8_t algo; /* Public-key crypto algorithm [enum pkey_algo] */
92*cc4ad7daSAndroid Build Coastguard Worker uint8_t hash; /* Digest algorithm [enum pkey_hash_algo] */
93*cc4ad7daSAndroid Build Coastguard Worker uint8_t id_type; /* Key identifier type [enum pkey_id_type] */
94*cc4ad7daSAndroid Build Coastguard Worker uint8_t signer_len; /* Length of signer's name */
95*cc4ad7daSAndroid Build Coastguard Worker uint8_t key_id_len; /* Length of key identifier */
96*cc4ad7daSAndroid Build Coastguard Worker uint8_t __pad[3];
97*cc4ad7daSAndroid Build Coastguard Worker uint32_t sig_len; /* Length of signature data (big endian) */
98*cc4ad7daSAndroid Build Coastguard Worker };
99*cc4ad7daSAndroid Build Coastguard Worker
fill_default(const char * mem,off_t size,const struct module_signature * modsig,size_t sig_len,struct kmod_signature_info * sig_info)100*cc4ad7daSAndroid Build Coastguard Worker static bool fill_default(const char *mem, off_t size,
101*cc4ad7daSAndroid Build Coastguard Worker const struct module_signature *modsig, size_t sig_len,
102*cc4ad7daSAndroid Build Coastguard Worker struct kmod_signature_info *sig_info)
103*cc4ad7daSAndroid Build Coastguard Worker {
104*cc4ad7daSAndroid Build Coastguard Worker size -= sig_len;
105*cc4ad7daSAndroid Build Coastguard Worker sig_info->sig = mem + size;
106*cc4ad7daSAndroid Build Coastguard Worker sig_info->sig_len = sig_len;
107*cc4ad7daSAndroid Build Coastguard Worker
108*cc4ad7daSAndroid Build Coastguard Worker size -= modsig->key_id_len;
109*cc4ad7daSAndroid Build Coastguard Worker sig_info->key_id = mem + size;
110*cc4ad7daSAndroid Build Coastguard Worker sig_info->key_id_len = modsig->key_id_len;
111*cc4ad7daSAndroid Build Coastguard Worker
112*cc4ad7daSAndroid Build Coastguard Worker size -= modsig->signer_len;
113*cc4ad7daSAndroid Build Coastguard Worker sig_info->signer = mem + size;
114*cc4ad7daSAndroid Build Coastguard Worker sig_info->signer_len = modsig->signer_len;
115*cc4ad7daSAndroid Build Coastguard Worker
116*cc4ad7daSAndroid Build Coastguard Worker sig_info->algo = pkey_algo[modsig->algo];
117*cc4ad7daSAndroid Build Coastguard Worker sig_info->hash_algo = pkey_hash_algo[modsig->hash];
118*cc4ad7daSAndroid Build Coastguard Worker sig_info->id_type = pkey_id_type[modsig->id_type];
119*cc4ad7daSAndroid Build Coastguard Worker
120*cc4ad7daSAndroid Build Coastguard Worker return true;
121*cc4ad7daSAndroid Build Coastguard Worker }
122*cc4ad7daSAndroid Build Coastguard Worker
123*cc4ad7daSAndroid Build Coastguard Worker #ifdef ENABLE_OPENSSL
124*cc4ad7daSAndroid Build Coastguard Worker
125*cc4ad7daSAndroid Build Coastguard Worker struct pkcs7_private {
126*cc4ad7daSAndroid Build Coastguard Worker PKCS7 *pkcs7;
127*cc4ad7daSAndroid Build Coastguard Worker unsigned char *key_id;
128*cc4ad7daSAndroid Build Coastguard Worker BIGNUM *sno;
129*cc4ad7daSAndroid Build Coastguard Worker char *hash_algo;
130*cc4ad7daSAndroid Build Coastguard Worker };
131*cc4ad7daSAndroid Build Coastguard Worker
pkcs7_free(void * s)132*cc4ad7daSAndroid Build Coastguard Worker static void pkcs7_free(void *s)
133*cc4ad7daSAndroid Build Coastguard Worker {
134*cc4ad7daSAndroid Build Coastguard Worker struct kmod_signature_info *si = s;
135*cc4ad7daSAndroid Build Coastguard Worker struct pkcs7_private *pvt = si->private;
136*cc4ad7daSAndroid Build Coastguard Worker
137*cc4ad7daSAndroid Build Coastguard Worker PKCS7_free(pvt->pkcs7);
138*cc4ad7daSAndroid Build Coastguard Worker BN_free(pvt->sno);
139*cc4ad7daSAndroid Build Coastguard Worker free(pvt->key_id);
140*cc4ad7daSAndroid Build Coastguard Worker free(pvt->hash_algo);
141*cc4ad7daSAndroid Build Coastguard Worker free(pvt);
142*cc4ad7daSAndroid Build Coastguard Worker si->private = NULL;
143*cc4ad7daSAndroid Build Coastguard Worker }
144*cc4ad7daSAndroid Build Coastguard Worker
x509_name_to_str(X509_NAME * name)145*cc4ad7daSAndroid Build Coastguard Worker static const char *x509_name_to_str(X509_NAME *name)
146*cc4ad7daSAndroid Build Coastguard Worker {
147*cc4ad7daSAndroid Build Coastguard Worker int i;
148*cc4ad7daSAndroid Build Coastguard Worker X509_NAME_ENTRY *e;
149*cc4ad7daSAndroid Build Coastguard Worker ASN1_STRING *d;
150*cc4ad7daSAndroid Build Coastguard Worker ASN1_OBJECT *o;
151*cc4ad7daSAndroid Build Coastguard Worker int nid = -1;
152*cc4ad7daSAndroid Build Coastguard Worker const char *str;
153*cc4ad7daSAndroid Build Coastguard Worker
154*cc4ad7daSAndroid Build Coastguard Worker for (i = 0; i < X509_NAME_entry_count(name); i++) {
155*cc4ad7daSAndroid Build Coastguard Worker e = X509_NAME_get_entry(name, i);
156*cc4ad7daSAndroid Build Coastguard Worker o = X509_NAME_ENTRY_get_object(e);
157*cc4ad7daSAndroid Build Coastguard Worker nid = OBJ_obj2nid(o);
158*cc4ad7daSAndroid Build Coastguard Worker if (nid == NID_commonName)
159*cc4ad7daSAndroid Build Coastguard Worker break;
160*cc4ad7daSAndroid Build Coastguard Worker }
161*cc4ad7daSAndroid Build Coastguard Worker if (nid == -1)
162*cc4ad7daSAndroid Build Coastguard Worker return NULL;
163*cc4ad7daSAndroid Build Coastguard Worker
164*cc4ad7daSAndroid Build Coastguard Worker d = X509_NAME_ENTRY_get_data(e);
165*cc4ad7daSAndroid Build Coastguard Worker str = (const char *)ASN1_STRING_get0_data(d);
166*cc4ad7daSAndroid Build Coastguard Worker
167*cc4ad7daSAndroid Build Coastguard Worker return str;
168*cc4ad7daSAndroid Build Coastguard Worker }
169*cc4ad7daSAndroid Build Coastguard Worker
fill_pkcs7(const char * mem,off_t size,const struct module_signature * modsig,size_t sig_len,struct kmod_signature_info * sig_info)170*cc4ad7daSAndroid Build Coastguard Worker static bool fill_pkcs7(const char *mem, off_t size,
171*cc4ad7daSAndroid Build Coastguard Worker const struct module_signature *modsig, size_t sig_len,
172*cc4ad7daSAndroid Build Coastguard Worker struct kmod_signature_info *sig_info)
173*cc4ad7daSAndroid Build Coastguard Worker {
174*cc4ad7daSAndroid Build Coastguard Worker const char *pkcs7_raw;
175*cc4ad7daSAndroid Build Coastguard Worker PKCS7 *pkcs7;
176*cc4ad7daSAndroid Build Coastguard Worker STACK_OF(PKCS7_SIGNER_INFO) *sis;
177*cc4ad7daSAndroid Build Coastguard Worker PKCS7_SIGNER_INFO *si;
178*cc4ad7daSAndroid Build Coastguard Worker PKCS7_ISSUER_AND_SERIAL *is;
179*cc4ad7daSAndroid Build Coastguard Worker X509_NAME *issuer;
180*cc4ad7daSAndroid Build Coastguard Worker ASN1_INTEGER *sno;
181*cc4ad7daSAndroid Build Coastguard Worker ASN1_OCTET_STRING *sig;
182*cc4ad7daSAndroid Build Coastguard Worker BIGNUM *sno_bn;
183*cc4ad7daSAndroid Build Coastguard Worker X509_ALGOR *dig_alg;
184*cc4ad7daSAndroid Build Coastguard Worker X509_ALGOR *sig_alg;
185*cc4ad7daSAndroid Build Coastguard Worker const ASN1_OBJECT *o;
186*cc4ad7daSAndroid Build Coastguard Worker BIO *in;
187*cc4ad7daSAndroid Build Coastguard Worker int len;
188*cc4ad7daSAndroid Build Coastguard Worker unsigned char *key_id_str;
189*cc4ad7daSAndroid Build Coastguard Worker struct pkcs7_private *pvt;
190*cc4ad7daSAndroid Build Coastguard Worker const char *issuer_str;
191*cc4ad7daSAndroid Build Coastguard Worker char *hash_algo;
192*cc4ad7daSAndroid Build Coastguard Worker int hash_algo_len;
193*cc4ad7daSAndroid Build Coastguard Worker
194*cc4ad7daSAndroid Build Coastguard Worker size -= sig_len;
195*cc4ad7daSAndroid Build Coastguard Worker pkcs7_raw = mem + size;
196*cc4ad7daSAndroid Build Coastguard Worker
197*cc4ad7daSAndroid Build Coastguard Worker in = BIO_new_mem_buf(pkcs7_raw, sig_len);
198*cc4ad7daSAndroid Build Coastguard Worker
199*cc4ad7daSAndroid Build Coastguard Worker pkcs7 = d2i_PKCS7_bio(in, NULL);
200*cc4ad7daSAndroid Build Coastguard Worker if (pkcs7 == NULL) {
201*cc4ad7daSAndroid Build Coastguard Worker BIO_free(in);
202*cc4ad7daSAndroid Build Coastguard Worker return false;
203*cc4ad7daSAndroid Build Coastguard Worker }
204*cc4ad7daSAndroid Build Coastguard Worker
205*cc4ad7daSAndroid Build Coastguard Worker BIO_free(in);
206*cc4ad7daSAndroid Build Coastguard Worker
207*cc4ad7daSAndroid Build Coastguard Worker sis = PKCS7_get_signer_info(pkcs7);
208*cc4ad7daSAndroid Build Coastguard Worker if (sis == NULL)
209*cc4ad7daSAndroid Build Coastguard Worker goto err;
210*cc4ad7daSAndroid Build Coastguard Worker
211*cc4ad7daSAndroid Build Coastguard Worker si = sk_PKCS7_SIGNER_INFO_value(sis, 0);
212*cc4ad7daSAndroid Build Coastguard Worker if (si == NULL)
213*cc4ad7daSAndroid Build Coastguard Worker goto err;
214*cc4ad7daSAndroid Build Coastguard Worker
215*cc4ad7daSAndroid Build Coastguard Worker is = si->issuer_and_serial;
216*cc4ad7daSAndroid Build Coastguard Worker if (is == NULL)
217*cc4ad7daSAndroid Build Coastguard Worker goto err;
218*cc4ad7daSAndroid Build Coastguard Worker issuer = is->issuer;
219*cc4ad7daSAndroid Build Coastguard Worker sno = is->serial;
220*cc4ad7daSAndroid Build Coastguard Worker
221*cc4ad7daSAndroid Build Coastguard Worker sig = si->enc_digest;
222*cc4ad7daSAndroid Build Coastguard Worker if (sig == NULL)
223*cc4ad7daSAndroid Build Coastguard Worker goto err;
224*cc4ad7daSAndroid Build Coastguard Worker
225*cc4ad7daSAndroid Build Coastguard Worker PKCS7_SIGNER_INFO_get0_algs(si, NULL, &dig_alg, &sig_alg);
226*cc4ad7daSAndroid Build Coastguard Worker
227*cc4ad7daSAndroid Build Coastguard Worker sig_info->sig = (const char *)ASN1_STRING_get0_data(sig);
228*cc4ad7daSAndroid Build Coastguard Worker sig_info->sig_len = ASN1_STRING_length(sig);
229*cc4ad7daSAndroid Build Coastguard Worker
230*cc4ad7daSAndroid Build Coastguard Worker sno_bn = ASN1_INTEGER_to_BN(sno, NULL);
231*cc4ad7daSAndroid Build Coastguard Worker if (sno_bn == NULL)
232*cc4ad7daSAndroid Build Coastguard Worker goto err;
233*cc4ad7daSAndroid Build Coastguard Worker
234*cc4ad7daSAndroid Build Coastguard Worker len = BN_num_bytes(sno_bn);
235*cc4ad7daSAndroid Build Coastguard Worker key_id_str = malloc(len);
236*cc4ad7daSAndroid Build Coastguard Worker if (key_id_str == NULL)
237*cc4ad7daSAndroid Build Coastguard Worker goto err2;
238*cc4ad7daSAndroid Build Coastguard Worker BN_bn2bin(sno_bn, key_id_str);
239*cc4ad7daSAndroid Build Coastguard Worker
240*cc4ad7daSAndroid Build Coastguard Worker sig_info->key_id = (const char *)key_id_str;
241*cc4ad7daSAndroid Build Coastguard Worker sig_info->key_id_len = len;
242*cc4ad7daSAndroid Build Coastguard Worker
243*cc4ad7daSAndroid Build Coastguard Worker issuer_str = x509_name_to_str(issuer);
244*cc4ad7daSAndroid Build Coastguard Worker if (issuer_str != NULL) {
245*cc4ad7daSAndroid Build Coastguard Worker sig_info->signer = issuer_str;
246*cc4ad7daSAndroid Build Coastguard Worker sig_info->signer_len = strlen(issuer_str);
247*cc4ad7daSAndroid Build Coastguard Worker }
248*cc4ad7daSAndroid Build Coastguard Worker
249*cc4ad7daSAndroid Build Coastguard Worker X509_ALGOR_get0(&o, NULL, NULL, dig_alg);
250*cc4ad7daSAndroid Build Coastguard Worker
251*cc4ad7daSAndroid Build Coastguard Worker // Use OBJ_obj2txt to calculate string length
252*cc4ad7daSAndroid Build Coastguard Worker hash_algo_len = OBJ_obj2txt(NULL, 0, o, 0);
253*cc4ad7daSAndroid Build Coastguard Worker if (hash_algo_len < 0)
254*cc4ad7daSAndroid Build Coastguard Worker goto err3;
255*cc4ad7daSAndroid Build Coastguard Worker hash_algo = malloc(hash_algo_len + 1);
256*cc4ad7daSAndroid Build Coastguard Worker if (hash_algo == NULL)
257*cc4ad7daSAndroid Build Coastguard Worker goto err3;
258*cc4ad7daSAndroid Build Coastguard Worker hash_algo_len = OBJ_obj2txt(hash_algo, hash_algo_len + 1, o, 0);
259*cc4ad7daSAndroid Build Coastguard Worker if (hash_algo_len < 0)
260*cc4ad7daSAndroid Build Coastguard Worker goto err4;
261*cc4ad7daSAndroid Build Coastguard Worker
262*cc4ad7daSAndroid Build Coastguard Worker // Assign libcrypto hash algo string or number
263*cc4ad7daSAndroid Build Coastguard Worker sig_info->hash_algo = hash_algo;
264*cc4ad7daSAndroid Build Coastguard Worker
265*cc4ad7daSAndroid Build Coastguard Worker sig_info->id_type = pkey_id_type[modsig->id_type];
266*cc4ad7daSAndroid Build Coastguard Worker
267*cc4ad7daSAndroid Build Coastguard Worker pvt = malloc(sizeof(*pvt));
268*cc4ad7daSAndroid Build Coastguard Worker if (pvt == NULL)
269*cc4ad7daSAndroid Build Coastguard Worker goto err4;
270*cc4ad7daSAndroid Build Coastguard Worker
271*cc4ad7daSAndroid Build Coastguard Worker pvt->pkcs7 = pkcs7;
272*cc4ad7daSAndroid Build Coastguard Worker pvt->key_id = key_id_str;
273*cc4ad7daSAndroid Build Coastguard Worker pvt->sno = sno_bn;
274*cc4ad7daSAndroid Build Coastguard Worker pvt->hash_algo = hash_algo;
275*cc4ad7daSAndroid Build Coastguard Worker sig_info->private = pvt;
276*cc4ad7daSAndroid Build Coastguard Worker
277*cc4ad7daSAndroid Build Coastguard Worker sig_info->free = pkcs7_free;
278*cc4ad7daSAndroid Build Coastguard Worker
279*cc4ad7daSAndroid Build Coastguard Worker return true;
280*cc4ad7daSAndroid Build Coastguard Worker err4:
281*cc4ad7daSAndroid Build Coastguard Worker free(hash_algo);
282*cc4ad7daSAndroid Build Coastguard Worker err3:
283*cc4ad7daSAndroid Build Coastguard Worker free(key_id_str);
284*cc4ad7daSAndroid Build Coastguard Worker err2:
285*cc4ad7daSAndroid Build Coastguard Worker BN_free(sno_bn);
286*cc4ad7daSAndroid Build Coastguard Worker err:
287*cc4ad7daSAndroid Build Coastguard Worker PKCS7_free(pkcs7);
288*cc4ad7daSAndroid Build Coastguard Worker return false;
289*cc4ad7daSAndroid Build Coastguard Worker }
290*cc4ad7daSAndroid Build Coastguard Worker
291*cc4ad7daSAndroid Build Coastguard Worker #else /* ENABLE OPENSSL */
292*cc4ad7daSAndroid Build Coastguard Worker
fill_pkcs7(const char * mem,off_t size,const struct module_signature * modsig,size_t sig_len,struct kmod_signature_info * sig_info)293*cc4ad7daSAndroid Build Coastguard Worker static bool fill_pkcs7(const char *mem, off_t size,
294*cc4ad7daSAndroid Build Coastguard Worker const struct module_signature *modsig, size_t sig_len,
295*cc4ad7daSAndroid Build Coastguard Worker struct kmod_signature_info *sig_info)
296*cc4ad7daSAndroid Build Coastguard Worker {
297*cc4ad7daSAndroid Build Coastguard Worker sig_info->hash_algo = "unknown";
298*cc4ad7daSAndroid Build Coastguard Worker sig_info->id_type = pkey_id_type[modsig->id_type];
299*cc4ad7daSAndroid Build Coastguard Worker return true;
300*cc4ad7daSAndroid Build Coastguard Worker }
301*cc4ad7daSAndroid Build Coastguard Worker
302*cc4ad7daSAndroid Build Coastguard Worker #endif /* ENABLE OPENSSL */
303*cc4ad7daSAndroid Build Coastguard Worker
304*cc4ad7daSAndroid Build Coastguard Worker #define SIG_MAGIC "~Module signature appended~\n"
305*cc4ad7daSAndroid Build Coastguard Worker
306*cc4ad7daSAndroid Build Coastguard Worker /*
307*cc4ad7daSAndroid Build Coastguard Worker * A signed module has the following layout:
308*cc4ad7daSAndroid Build Coastguard Worker *
309*cc4ad7daSAndroid Build Coastguard Worker * [ module ]
310*cc4ad7daSAndroid Build Coastguard Worker * [ signer's name ]
311*cc4ad7daSAndroid Build Coastguard Worker * [ key identifier ]
312*cc4ad7daSAndroid Build Coastguard Worker * [ signature data ]
313*cc4ad7daSAndroid Build Coastguard Worker * [ struct module_signature ]
314*cc4ad7daSAndroid Build Coastguard Worker * [ SIG_MAGIC ]
315*cc4ad7daSAndroid Build Coastguard Worker */
316*cc4ad7daSAndroid Build Coastguard Worker
kmod_module_signature_info(const struct kmod_file * file,struct kmod_signature_info * sig_info)317*cc4ad7daSAndroid Build Coastguard Worker bool kmod_module_signature_info(const struct kmod_file *file, struct kmod_signature_info *sig_info)
318*cc4ad7daSAndroid Build Coastguard Worker {
319*cc4ad7daSAndroid Build Coastguard Worker const char *mem;
320*cc4ad7daSAndroid Build Coastguard Worker off_t size;
321*cc4ad7daSAndroid Build Coastguard Worker const struct module_signature *modsig;
322*cc4ad7daSAndroid Build Coastguard Worker size_t sig_len;
323*cc4ad7daSAndroid Build Coastguard Worker
324*cc4ad7daSAndroid Build Coastguard Worker size = kmod_file_get_size(file);
325*cc4ad7daSAndroid Build Coastguard Worker mem = kmod_file_get_contents(file);
326*cc4ad7daSAndroid Build Coastguard Worker if (size < (off_t)strlen(SIG_MAGIC))
327*cc4ad7daSAndroid Build Coastguard Worker return false;
328*cc4ad7daSAndroid Build Coastguard Worker size -= strlen(SIG_MAGIC);
329*cc4ad7daSAndroid Build Coastguard Worker if (memcmp(SIG_MAGIC, mem + size, strlen(SIG_MAGIC)) != 0)
330*cc4ad7daSAndroid Build Coastguard Worker return false;
331*cc4ad7daSAndroid Build Coastguard Worker
332*cc4ad7daSAndroid Build Coastguard Worker if (size < (off_t)sizeof(struct module_signature))
333*cc4ad7daSAndroid Build Coastguard Worker return false;
334*cc4ad7daSAndroid Build Coastguard Worker size -= sizeof(struct module_signature);
335*cc4ad7daSAndroid Build Coastguard Worker modsig = (struct module_signature *)(mem + size);
336*cc4ad7daSAndroid Build Coastguard Worker if (modsig->algo >= PKEY_ALGO__LAST ||
337*cc4ad7daSAndroid Build Coastguard Worker modsig->hash >= PKEY_HASH__LAST ||
338*cc4ad7daSAndroid Build Coastguard Worker modsig->id_type >= PKEY_ID_TYPE__LAST)
339*cc4ad7daSAndroid Build Coastguard Worker return false;
340*cc4ad7daSAndroid Build Coastguard Worker sig_len = be32toh(get_unaligned(&modsig->sig_len));
341*cc4ad7daSAndroid Build Coastguard Worker if (sig_len == 0 ||
342*cc4ad7daSAndroid Build Coastguard Worker size < (int64_t)(modsig->signer_len + modsig->key_id_len + sig_len))
343*cc4ad7daSAndroid Build Coastguard Worker return false;
344*cc4ad7daSAndroid Build Coastguard Worker
345*cc4ad7daSAndroid Build Coastguard Worker switch (modsig->id_type) {
346*cc4ad7daSAndroid Build Coastguard Worker case PKEY_ID_PKCS7:
347*cc4ad7daSAndroid Build Coastguard Worker return fill_pkcs7(mem, size, modsig, sig_len, sig_info);
348*cc4ad7daSAndroid Build Coastguard Worker default:
349*cc4ad7daSAndroid Build Coastguard Worker return fill_default(mem, size, modsig, sig_len, sig_info);
350*cc4ad7daSAndroid Build Coastguard Worker }
351*cc4ad7daSAndroid Build Coastguard Worker }
352*cc4ad7daSAndroid Build Coastguard Worker
kmod_module_signature_info_free(struct kmod_signature_info * sig_info)353*cc4ad7daSAndroid Build Coastguard Worker void kmod_module_signature_info_free(struct kmod_signature_info *sig_info)
354*cc4ad7daSAndroid Build Coastguard Worker {
355*cc4ad7daSAndroid Build Coastguard Worker if (sig_info->free)
356*cc4ad7daSAndroid Build Coastguard Worker sig_info->free(sig_info);
357*cc4ad7daSAndroid Build Coastguard Worker }
358