pkcs7_trust.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /* Validate the trust chain of 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. #define pr_fmt(fmt) "PKCS7: "fmt
  12. #include <linux/kernel.h>
  13. #include <linux/export.h>
  14. #include <linux/slab.h>
  15. #include <linux/err.h>
  16. #include <linux/asn1.h>
  17. #include <linux/key.h>
  18. #include <keys/asymmetric-type.h>
  19. #include "public_key.h"
  20. #include "pkcs7_parser.h"
  21. /**
  22. * Check the trust on one PKCS#7 SignedInfo block.
  23. */
  24. static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
  25. struct pkcs7_signed_info *sinfo,
  26. struct key *trust_keyring)
  27. {
  28. struct public_key_signature *sig = &sinfo->sig;
  29. struct x509_certificate *x509, *last = NULL, *p;
  30. struct key *key;
  31. bool trusted;
  32. int ret;
  33. kenter(",%u,", sinfo->index);
  34. if (sinfo->unsupported_crypto) {
  35. kleave(" = -ENOPKG [cached]");
  36. return -ENOPKG;
  37. }
  38. for (x509 = sinfo->signer; x509; x509 = x509->signer) {
  39. if (x509->seen) {
  40. if (x509->verified) {
  41. trusted = x509->trusted;
  42. goto verified;
  43. }
  44. kleave(" = -ENOKEY [cached]");
  45. return -ENOKEY;
  46. }
  47. x509->seen = true;
  48. /* Look to see if this certificate is present in the trusted
  49. * keys.
  50. */
  51. key = x509_request_asymmetric_key(trust_keyring, x509->id,
  52. false);
  53. if (!IS_ERR(key)) {
  54. /* One of the X.509 certificates in the PKCS#7 message
  55. * is apparently the same as one we already trust.
  56. * Verify that the trusted variant can also validate
  57. * the signature on the descendant.
  58. */
  59. pr_devel("sinfo %u: Cert %u as key %x\n",
  60. sinfo->index, x509->index, key_serial(key));
  61. goto matched;
  62. }
  63. if (key == ERR_PTR(-ENOMEM))
  64. return -ENOMEM;
  65. /* Self-signed certificates form roots of their own, and if we
  66. * don't know them, then we can't accept them.
  67. */
  68. if (x509->next == x509) {
  69. kleave(" = -ENOKEY [unknown self-signed]");
  70. return -ENOKEY;
  71. }
  72. might_sleep();
  73. last = x509;
  74. sig = &last->sig;
  75. }
  76. /* No match - see if the root certificate has a signer amongst the
  77. * trusted keys.
  78. */
  79. if (last && last->authority) {
  80. key = x509_request_asymmetric_key(trust_keyring, last->authority,
  81. false);
  82. if (!IS_ERR(key)) {
  83. x509 = last;
  84. pr_devel("sinfo %u: Root cert %u signer is key %x\n",
  85. sinfo->index, x509->index, key_serial(key));
  86. goto matched;
  87. }
  88. if (PTR_ERR(key) != -ENOKEY)
  89. return PTR_ERR(key);
  90. }
  91. /* As a last resort, see if we have a trusted public key that matches
  92. * the signed info directly.
  93. */
  94. key = x509_request_asymmetric_key(trust_keyring,
  95. sinfo->signing_cert_id,
  96. false);
  97. if (!IS_ERR(key)) {
  98. pr_devel("sinfo %u: Direct signer is key %x\n",
  99. sinfo->index, key_serial(key));
  100. x509 = NULL;
  101. goto matched;
  102. }
  103. if (PTR_ERR(key) != -ENOKEY)
  104. return PTR_ERR(key);
  105. kleave(" = -ENOKEY [no backref]");
  106. return -ENOKEY;
  107. matched:
  108. ret = verify_signature(key, sig);
  109. trusted = test_bit(KEY_FLAG_TRUSTED, &key->flags);
  110. key_put(key);
  111. if (ret < 0) {
  112. if (ret == -ENOMEM)
  113. return ret;
  114. kleave(" = -EKEYREJECTED [verify %d]", ret);
  115. return -EKEYREJECTED;
  116. }
  117. verified:
  118. if (x509) {
  119. x509->verified = true;
  120. for (p = sinfo->signer; p != x509; p = p->signer) {
  121. p->verified = true;
  122. p->trusted = trusted;
  123. }
  124. }
  125. sinfo->trusted = trusted;
  126. kleave(" = 0");
  127. return 0;
  128. }
  129. /**
  130. * pkcs7_validate_trust - Validate PKCS#7 trust chain
  131. * @pkcs7: The PKCS#7 certificate to validate
  132. * @trust_keyring: Signing certificates to use as starting points
  133. * @_trusted: Set to true if trustworth, false otherwise
  134. *
  135. * Validate that the certificate chain inside the PKCS#7 message intersects
  136. * keys we already know and trust.
  137. *
  138. * Returns, in order of descending priority:
  139. *
  140. * (*) -EKEYREJECTED if a signature failed to match for which we have a valid
  141. * key, or:
  142. *
  143. * (*) 0 if at least one signature chain intersects with the keys in the trust
  144. * keyring, or:
  145. *
  146. * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a
  147. * chain.
  148. *
  149. * (*) -ENOKEY if we couldn't find a match for any of the signature chains in
  150. * the message.
  151. *
  152. * May also return -ENOMEM.
  153. */
  154. int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
  155. struct key *trust_keyring,
  156. bool *_trusted)
  157. {
  158. struct pkcs7_signed_info *sinfo;
  159. struct x509_certificate *p;
  160. int cached_ret = -ENOKEY;
  161. int ret;
  162. for (p = pkcs7->certs; p; p = p->next)
  163. p->seen = false;
  164. for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
  165. ret = pkcs7_validate_trust_one(pkcs7, sinfo, trust_keyring);
  166. switch (ret) {
  167. case -ENOKEY:
  168. continue;
  169. case -ENOPKG:
  170. if (cached_ret == -ENOKEY)
  171. cached_ret = -ENOPKG;
  172. continue;
  173. case 0:
  174. *_trusted |= sinfo->trusted;
  175. cached_ret = 0;
  176. continue;
  177. default:
  178. return ret;
  179. }
  180. }
  181. return cached_ret;
  182. }
  183. EXPORT_SYMBOL_GPL(pkcs7_validate_trust);