1 /* Verify the signature on a PKCS#7 message. 2 * 3 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public Licence 8 * as published by the Free Software Foundation; either version 9 * 2 of the Licence, or (at your option) any later version. 10 */ 11 12 #define pr_fmt(fmt) "PKCS7: "fmt 13 #include <linux/kernel.h> 14 #include <linux/export.h> 15 #include <linux/slab.h> 16 #include <linux/err.h> 17 #include <linux/asn1.h> 18 #include <crypto/hash.h> 19 #include "public_key.h" 20 #include "pkcs7_parser.h" 21 22 /* 23 * Digest the relevant parts of the PKCS#7 data 24 */ 25 static int pkcs7_digest(struct pkcs7_message *pkcs7, 26 struct pkcs7_signed_info *sinfo) 27 { 28 struct crypto_shash *tfm; 29 struct shash_desc *desc; 30 size_t digest_size, desc_size; 31 void *digest; 32 int ret; 33 34 kenter(",%u,%u", sinfo->index, sinfo->sig.pkey_hash_algo); 35 36 if (sinfo->sig.pkey_hash_algo >= PKEY_HASH__LAST || 37 !hash_algo_name[sinfo->sig.pkey_hash_algo]) 38 return -ENOPKG; 39 40 /* Allocate the hashing algorithm we're going to need and find out how 41 * big the hash operational data will be. 42 */ 43 tfm = crypto_alloc_shash(hash_algo_name[sinfo->sig.pkey_hash_algo], 44 0, 0); 45 if (IS_ERR(tfm)) 46 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 47 48 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 49 sinfo->sig.digest_size = digest_size = crypto_shash_digestsize(tfm); 50 51 ret = -ENOMEM; 52 digest = kzalloc(digest_size + desc_size, GFP_KERNEL); 53 if (!digest) 54 goto error_no_desc; 55 56 desc = digest + digest_size; 57 desc->tfm = tfm; 58 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 59 60 /* Digest the message [RFC2315 9.3] */ 61 ret = crypto_shash_init(desc); 62 if (ret < 0) 63 goto error; 64 ret = crypto_shash_finup(desc, pkcs7->data, pkcs7->data_len, digest); 65 if (ret < 0) 66 goto error; 67 pr_devel("MsgDigest = [%*ph]\n", 8, digest); 68 69 /* However, if there are authenticated attributes, there must be a 70 * message digest attribute amongst them which corresponds to the 71 * digest we just calculated. 72 */ 73 if (sinfo->msgdigest) { 74 u8 tag; 75 76 if (sinfo->msgdigest_len != sinfo->sig.digest_size) { 77 pr_debug("Sig %u: Invalid digest size (%u)\n", 78 sinfo->index, sinfo->msgdigest_len); 79 ret = -EBADMSG; 80 goto error; 81 } 82 83 if (memcmp(digest, sinfo->msgdigest, sinfo->msgdigest_len) != 0) { 84 pr_debug("Sig %u: Message digest doesn't match\n", 85 sinfo->index); 86 ret = -EKEYREJECTED; 87 goto error; 88 } 89 90 /* We then calculate anew, using the authenticated attributes 91 * as the contents of the digest instead. Note that we need to 92 * convert the attributes from a CONT.0 into a SET before we 93 * hash it. 94 */ 95 memset(digest, 0, sinfo->sig.digest_size); 96 97 ret = crypto_shash_init(desc); 98 if (ret < 0) 99 goto error; 100 tag = ASN1_CONS_BIT | ASN1_SET; 101 ret = crypto_shash_update(desc, &tag, 1); 102 if (ret < 0) 103 goto error; 104 ret = crypto_shash_finup(desc, sinfo->authattrs, 105 sinfo->authattrs_len, digest); 106 if (ret < 0) 107 goto error; 108 pr_devel("AADigest = [%*ph]\n", 8, digest); 109 } 110 111 sinfo->sig.digest = digest; 112 digest = NULL; 113 114 error: 115 kfree(digest); 116 error_no_desc: 117 crypto_free_shash(tfm); 118 kleave(" = %d", ret); 119 return ret; 120 } 121 122 /* 123 * Find the key (X.509 certificate) to use to verify a PKCS#7 message. PKCS#7 124 * uses the issuer's name and the issuing certificate serial number for 125 * matching purposes. These must match the certificate issuer's name (not 126 * subject's name) and the certificate serial number [RFC 2315 6.7]. 127 */ 128 static int pkcs7_find_key(struct pkcs7_message *pkcs7, 129 struct pkcs7_signed_info *sinfo) 130 { 131 struct x509_certificate *x509; 132 unsigned certix = 1; 133 134 kenter("%u,%u,%u", 135 sinfo->index, sinfo->raw_serial_size, sinfo->raw_issuer_size); 136 137 for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) { 138 /* I'm _assuming_ that the generator of the PKCS#7 message will 139 * encode the fields from the X.509 cert in the same way in the 140 * PKCS#7 message - but I can't be 100% sure of that. It's 141 * possible this will need element-by-element comparison. 142 */ 143 if (x509->raw_serial_size != sinfo->raw_serial_size || 144 memcmp(x509->raw_serial, sinfo->raw_serial, 145 sinfo->raw_serial_size) != 0) 146 continue; 147 pr_devel("Sig %u: Found cert serial match X.509[%u]\n", 148 sinfo->index, certix); 149 150 if (x509->raw_issuer_size != sinfo->raw_issuer_size || 151 memcmp(x509->raw_issuer, sinfo->raw_issuer, 152 sinfo->raw_issuer_size) != 0) { 153 pr_warn("Sig %u: X.509 subject and PKCS#7 issuer don't match\n", 154 sinfo->index); 155 continue; 156 } 157 158 if (x509->pub->pkey_algo != sinfo->sig.pkey_algo) { 159 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n", 160 sinfo->index); 161 continue; 162 } 163 164 sinfo->signer = x509; 165 return 0; 166 } 167 pr_warn("Sig %u: Issuing X.509 cert not found (#%*ph)\n", 168 sinfo->index, sinfo->raw_serial_size, sinfo->raw_serial); 169 return -ENOKEY; 170 } 171 172 /* 173 * Verify the internal certificate chain as best we can. 174 */ 175 static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, 176 struct pkcs7_signed_info *sinfo) 177 { 178 struct x509_certificate *x509 = sinfo->signer, *p; 179 int ret; 180 181 kenter(""); 182 183 for (p = pkcs7->certs; p; p = p->next) 184 p->seen = false; 185 186 for (;;) { 187 pr_debug("verify %s: %s\n", x509->subject, x509->fingerprint); 188 x509->seen = true; 189 ret = x509_get_sig_params(x509); 190 if (ret < 0) 191 return ret; 192 193 pr_debug("- issuer %s\n", x509->issuer); 194 if (x509->authority) 195 pr_debug("- authkeyid %s\n", x509->authority); 196 197 if (!x509->authority || 198 strcmp(x509->subject, x509->issuer) == 0) { 199 /* If there's no authority certificate specified, then 200 * the certificate must be self-signed and is the root 201 * of the chain. Likewise if the cert is its own 202 * authority. 203 */ 204 pr_debug("- no auth?\n"); 205 if (x509->raw_subject_size != x509->raw_issuer_size || 206 memcmp(x509->raw_subject, x509->raw_issuer, 207 x509->raw_issuer_size) != 0) 208 return 0; 209 210 ret = x509_check_signature(x509->pub, x509); 211 if (ret < 0) 212 return ret; 213 x509->signer = x509; 214 pr_debug("- self-signed\n"); 215 return 0; 216 } 217 218 /* Look through the X.509 certificates in the PKCS#7 message's 219 * list to see if the next one is there. 220 */ 221 pr_debug("- want %s\n", x509->authority); 222 for (p = pkcs7->certs; p; p = p->next) { 223 pr_debug("- cmp [%u] %s\n", p->index, p->fingerprint); 224 if (p->raw_subject_size == x509->raw_issuer_size && 225 strcmp(p->fingerprint, x509->authority) == 0 && 226 memcmp(p->raw_subject, x509->raw_issuer, 227 x509->raw_issuer_size) == 0) 228 goto found_issuer; 229 } 230 231 /* We didn't find the root of this chain */ 232 pr_debug("- top\n"); 233 return 0; 234 235 found_issuer: 236 pr_debug("- issuer %s\n", p->subject); 237 if (p->seen) { 238 pr_warn("Sig %u: X.509 chain contains loop\n", 239 sinfo->index); 240 return 0; 241 } 242 ret = x509_check_signature(p->pub, x509); 243 if (ret < 0) 244 return ret; 245 x509->signer = p; 246 if (x509 == p) { 247 pr_debug("- self-signed\n"); 248 return 0; 249 } 250 x509 = p; 251 might_sleep(); 252 } 253 } 254 255 /* 256 * Verify one signed information block from a PKCS#7 message. 257 */ 258 static int pkcs7_verify_one(struct pkcs7_message *pkcs7, 259 struct pkcs7_signed_info *sinfo) 260 { 261 int ret; 262 263 kenter(",%u", sinfo->index); 264 265 /* First of all, digest the data in the PKCS#7 message and the 266 * signed information block 267 */ 268 ret = pkcs7_digest(pkcs7, sinfo); 269 if (ret < 0) 270 return ret; 271 272 /* Find the key for the signature */ 273 ret = pkcs7_find_key(pkcs7, sinfo); 274 if (ret < 0) 275 return ret; 276 277 pr_devel("Using X.509[%u] for sig %u\n", 278 sinfo->signer->index, sinfo->index); 279 280 /* Verify the PKCS#7 binary against the key */ 281 ret = public_key_verify_signature(sinfo->signer->pub, &sinfo->sig); 282 if (ret < 0) 283 return ret; 284 285 pr_devel("Verified signature %u\n", sinfo->index); 286 287 /* Verify the internal certificate chain */ 288 return pkcs7_verify_sig_chain(pkcs7, sinfo); 289 } 290 291 /** 292 * pkcs7_verify - Verify a PKCS#7 message 293 * @pkcs7: The PKCS#7 message to be verified 294 */ 295 int pkcs7_verify(struct pkcs7_message *pkcs7) 296 { 297 struct pkcs7_signed_info *sinfo; 298 struct x509_certificate *x509; 299 int ret, n; 300 301 kenter(""); 302 303 for (n = 0, x509 = pkcs7->certs; x509; x509 = x509->next, n++) { 304 ret = x509_get_sig_params(x509); 305 if (ret < 0) 306 return ret; 307 pr_debug("X.509[%u] %s\n", n, x509->authority); 308 } 309 310 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { 311 ret = pkcs7_verify_one(pkcs7, sinfo); 312 if (ret < 0) { 313 kleave(" = %d", ret); 314 return ret; 315 } 316 } 317 318 kleave(" = 0"); 319 return 0; 320 } 321 EXPORT_SYMBOL_GPL(pkcs7_verify); 322