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