lkml.org 
[lkml]   [2012]   [Oct]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 14/23] PKCS#7: Verify internal certificate chain
Date
Verify certificate chain in the X.509 certificates contained within the PKCS#7
message as far as possible. If any signature that we should be able to verify
fails, we reject the whole lot.

Signed-off-by: David Howells <dhowells@redhat.com>
---

crypto/asymmetric_keys/pkcs7_verify.c | 67 +++++++++++++++++++++++++++++++++
crypto/asymmetric_keys/x509_parser.h | 1
2 files changed, 67 insertions(+), 1 deletion(-)


diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index 614f2b6..2d729a6 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -161,6 +161,70 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7)
}

/*
+ * Verify the internal certificate chain as best we can.
+ */
+static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7)
+{
+ struct x509_certificate *x509 = pkcs7->signer, *p;
+ int ret;
+
+ kenter("");
+
+ for (;;) {
+ pr_debug("verify %s: %s\n", x509->subject, x509->fingerprint);
+ ret = x509_get_sig_params(x509);
+ if (ret < 0)
+ return ret;
+
+ if (x509->issuer)
+ pr_debug("- issuer %s\n", x509->issuer);
+ if (x509->authority)
+ pr_debug("- authkeyid %s\n", x509->authority);
+
+ if (!x509->authority ||
+ (x509->subject &&
+ strcmp(x509->subject, x509->authority) == 0)) {
+ /* If there's no authority certificate specified, then
+ * the certificate must be self-signed and is the root
+ * of the chain. Likewise if the cert is its own
+ * authority.
+ */
+ pr_debug("- no auth?\n");
+ if (x509->raw_subject_size != x509->raw_issuer_size ||
+ memcmp(x509->raw_subject, x509->raw_issuer,
+ x509->raw_issuer_size) != 0)
+ return 0;
+
+ ret = x509_check_signature(x509->pub, x509);
+ if (ret < 0)
+ return ret;
+ x509->signer = x509;
+ pr_debug("- self-signed\n");
+ return 0;
+ }
+
+ for (p = pkcs7->certs; p; p = p->next)
+ if (!p->signer &&
+ p->raw_subject_size == x509->raw_issuer_size &&
+ strcmp(p->fingerprint, x509->authority) == 0 &&
+ memcmp(p->raw_subject, x509->raw_issuer,
+ x509->raw_issuer_size) == 0)
+ goto found_issuer;
+ pr_debug("- top\n");
+ return 0;
+
+ found_issuer:
+ pr_debug("- issuer %s\n", p->subject);
+ ret = x509_check_signature(p->pub, x509);
+ if (ret < 0)
+ return ret;
+ x509->signer = p;
+ x509 = p;
+ might_sleep();
+ }
+}
+
+/*
* Verify a PKCS#7 message
*/
int pkcs7_verify(struct pkcs7_message *pkcs7)
@@ -186,6 +250,7 @@ int pkcs7_verify(struct pkcs7_message *pkcs7)

pr_devel("Verified signature\n");

- return 0;
+ /* Verify the internal certificate chain */
+ return pkcs7_verify_sig_chain(pkcs7);
}
EXPORT_SYMBOL_GPL(pkcs7_verify);
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index 6b1d877..5e35fba 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -14,6 +14,7 @@

struct x509_certificate {
struct x509_certificate *next;
+ const struct x509_certificate *signer; /* Certificate that signed this one */
struct public_key *pub; /* Public key details */
char *issuer; /* Name of certificate issuer */
char *subject; /* Name of certificate subject */


\
 
 \ /
  Last update: 2012-10-30 22:01    [W:0.621 / U:0.272 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site