* [Patch v4 1/5] test: initial tests for S/MIME and notmuch-emacs
2015-01-18 8:02 S/MIME patches, v4 David Bremner
@ 2015-01-18 8:02 ` David Bremner
2015-01-18 8:02 ` [Patch v4 2/5] cli: S/MIME verification/decryption support David Bremner
` (3 subsequent siblings)
4 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2015-01-18 8:02 UTC (permalink / raw)
To: notmuch
Test the ability of notmuch-mua-mail to send S/MIME signed (and
encrypted) messages; this really relies on existing functionality in
message-mode.
The dependency on openssl to generate keys seems acceptable since
that's the method I got to work for smime signing in emacs.
The generated keys and messages will later be useful for testing the
notmuch CLI.
---
test/T355-smime.sh | 53 ++++++++++++++++++++++++++++++++++++++++++
test/smime/openssl-ca-req.conf | 13 +++++++++++
test/smime/openssl-req.conf | 13 +++++++++++
test/test-lib.el | 10 ++++++++
test/test-lib.sh | 1 +
5 files changed, 90 insertions(+)
create mode 100755 test/T355-smime.sh
create mode 100644 test/smime/openssl-ca-req.conf
create mode 100644 test/smime/openssl-req.conf
diff --git a/test/T355-smime.sh b/test/T355-smime.sh
new file mode 100755
index 0000000..5f3ff12
--- /dev/null
+++ b/test/T355-smime.sh
@@ -0,0 +1,53 @@
+#!/usr/bin/env bash
+
+test_description='S/MIME signature verification and decryption'
+. ./test-lib.sh
+
+test_require_external_prereq openssl
+
+test_begin_subtest "Generate CA Cert"
+openssl genpkey -algorithm RSA -out ca.key -pass pass:test -des3 1024
+openssl req -new -x509 -key ca.key -passin pass:test \
+ -config $TEST_DIRECTORY/smime/openssl-ca-req.conf -out ca.crt
+test_expect_equal "$(openssl verify ca.crt | tail -1)" "OK"
+
+test_begin_subtest "Generate User Cert"
+openssl genpkey -algorithm RSA -out smime.key 1024
+openssl req -config $TEST_DIRECTORY/smime/openssl-req.conf \
+ -new -key smime.key -passin pass:test -nodes \
+ -out smime.csr
+openssl x509 -req -in smime.csr -passin pass:test -CA ca.crt -CAkey ca.key -set_serial 1 -out test_suite.crt -setalias "Self Signed SMIME" -addtrust emailProtection -addreject clientAuth -addreject serverAuth -trustout
+# we need one file with the cert and private key
+cat test_suite.crt smime.key > test_suite.pem
+test_expect_equal "$(openssl verify -purpose smimesign -CAfile ca.crt test_suite.pem)" "test_suite.pem: OK"
+
+test_expect_success 'emacs delivery of S/MIME signed message' \
+ 'emacs_fcc_message \
+ "test signed message 001" \
+ "This is a test signed message." \
+ "(mml-secure-message-sign \"smime\")"'
+
+# Hard code the MML to avoid several interactive questions
+test_expect_success 'emacs delivery of S/MIME encrypted + signed message' \
+'emacs_fcc_message \
+ "test encrypted message 001" \
+ "<#secure method=smime mode=signencrypt keyfile=\\\"test_suite.pem\\\" certfile=\\\"test_suite.pem\\\">\nThis is a test encrypted message.\n"'
+
+test_begin_subtest "Signature verification (openssl)"
+notmuch show --format=raw subject:"test signed message 001" |\
+ openssl smime -verify -CAfile ca.crt 2>OUTPUT
+cat <<EOF > EXPECTED
+Verification successful
+EOF
+test_expect_equal_file OUTPUT EXPECTED
+
+test_begin_subtest "Decryption and signature verification (openssl)"
+notmuch show --format=raw subject:"test encrypted message 001" |\
+ openssl smime -decrypt -recip test_suite.pem |\
+ openssl smime -verify -CAfile ca.crt 2>OUTPUT
+cat <<EOF > EXPECTED
+Verification successful
+EOF
+test_expect_equal_file OUTPUT EXPECTED
+
+test_done
diff --git a/test/smime/openssl-ca-req.conf b/test/smime/openssl-ca-req.conf
new file mode 100644
index 0000000..49572ee
--- /dev/null
+++ b/test/smime/openssl-ca-req.conf
@@ -0,0 +1,13 @@
+ [ req ]
+ distinguished_name = req_distinguished_name
+ prompt = no
+
+
+ [ req_distinguished_name ]
+ C = OZ
+ ST = Munchkinlandia
+ L = Emerald City
+ O = Organization Name
+ OU = Dept. of Fake Certs
+ CN = Fast Eddies Certs and Chips
+ emailAddress = fake-ca@example.com
diff --git a/test/smime/openssl-req.conf b/test/smime/openssl-req.conf
new file mode 100644
index 0000000..c6b9de7
--- /dev/null
+++ b/test/smime/openssl-req.conf
@@ -0,0 +1,13 @@
+ [ req ]
+ distinguished_name = req_distinguished_name
+ prompt = no
+
+
+ [ req_distinguished_name ]
+ C = OZ
+ ST = Munchkinlandia
+ L = Emerald City
+ O = Not much organization
+ OU = Dept. of Testing
+ CN = Notmuch Test Suite
+ emailAddress = test_suite@notmuchmail.org
diff --git a/test/test-lib.el b/test/test-lib.el
index 04c8d63..596a705 100644
--- a/test/test-lib.el
+++ b/test/test-lib.el
@@ -188,3 +188,13 @@ nothing."
;; environments
(setq mm-text-html-renderer 'html2text)
+
+;; Set some variables for S/MIME tests.
+
+(setq smime-keys '(("" "test_suite.pem" nil)))
+
+(setq mml-smime-use 'openssl)
+
+;; all test keys are without passphrase
+(eval-after-load 'smime
+ '(defun smime-ask-passphrase (cache) nil))
diff --git a/test/test-lib.sh b/test/test-lib.sh
index 6057238..00612d9 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -1304,3 +1304,4 @@ test_declare_external_prereq gdb
test_declare_external_prereq gpg
test_declare_external_prereq python
test_declare_external_prereq python2
+test_declare_external_prereq openssl
--
2.1.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Patch v4 2/5] cli: S/MIME verification/decryption support
2015-01-18 8:02 S/MIME patches, v4 David Bremner
2015-01-18 8:02 ` [Patch v4 1/5] test: initial tests for S/MIME and notmuch-emacs David Bremner
@ 2015-01-18 8:02 ` David Bremner
2015-01-18 10:45 ` [PATCH 0/3] smime with some refactoring Jani Nikula
2015-01-18 8:02 ` [Patch v4 3/5] test: add S/MIME signature verification test for notmuch CLI David Bremner
` (2 subsequent siblings)
4 siblings, 1 reply; 16+ messages in thread
From: David Bremner @ 2015-01-18 8:02 UTC (permalink / raw)
To: notmuch
From: Jameson Graef Rollins <jrollins@finestructure.net>
The notmuch-show flags --decrypt and --verify will now also process
S/MIME multiparts if encountered. Requires gmime-2.6 and gpgsm.
---
crypto.c | 20 ++++++++++++++++++++
notmuch-client.h | 5 +++--
2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/crypto.c b/crypto.c
index 6f4a6db..d66aa66 100644
--- a/crypto.c
+++ b/crypto.c
@@ -88,6 +88,21 @@ notmuch_crypto_get_context (notmuch_crypto_t *crypto, const char *protocol)
fprintf (stderr, "Failed to construct gpg context.\n");
}
cryptoctx = crypto->gpgctx;
+#ifdef GMIME_ATLEAST_26
+ } else if ((strcasecmp (protocol, "application/pkcs7-signature") == 0)
+ || (strcasecmp (protocol, "application/x-pkcs7-signature") == 0)
+ || (strcasecmp (protocol, "application/pkcs7-encrypted") == 0)) {
+ if (! crypto->pkcs7ctx) {
+ /* TODO: GMimePasswordRequestFunc */
+ crypto->pkcs7ctx = g_mime_pkcs7_context_new (NULL);
+ if (crypto->pkcs7ctx) {
+ g_mime_pkcs7_context_set_always_trust ((GMimePkcs7Context*) crypto->pkcs7ctx, FALSE);
+ } else {
+ fprintf (stderr, "Failed to construct pkcs7 context.\n");
+ }
+ }
+ cryptoctx = crypto->pkcs7ctx;
+#endif
} else {
fprintf (stderr, "Unknown or unsupported cryptographic protocol.\n");
}
@@ -103,5 +118,10 @@ notmuch_crypto_cleanup (notmuch_crypto_t *crypto)
crypto->gpgctx = NULL;
}
+ if (crypto->pkcs7ctx) {
+ g_object_unref (crypto->pkcs7ctx);
+ crypto->pkcs7ctx = NULL;
+ }
+
return 0;
}
diff --git a/notmuch-client.h b/notmuch-client.h
index 5e0d475..986f6cd 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -78,6 +78,7 @@ typedef struct notmuch_show_format {
typedef struct notmuch_crypto {
notmuch_crypto_context_t* gpgctx;
+ notmuch_crypto_context_t* pkcs7ctx;
notmuch_bool_t verify;
notmuch_bool_t decrypt;
} notmuch_crypto_t;
@@ -414,8 +415,8 @@ struct mime_node {
/* Construct a new MIME node pointing to the root message part of
* message. If crypto->verify is true, signed child parts will be
* verified. If crypto->decrypt is true, encrypted child parts will be
- * decrypted. If crypto->gpgctx is NULL, it will be lazily
- * initialized.
+ * decrypted. If the crypto contexts (crypto->gpgctx or
+ * crypto->pkcs7) are NULL, they will be lazily initialized.
*
* Return value:
*
--
2.1.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 0/3] smime with some refactoring
2015-01-18 8:02 ` [Patch v4 2/5] cli: S/MIME verification/decryption support David Bremner
@ 2015-01-18 10:45 ` Jani Nikula
2015-01-18 10:45 ` [PATCH 1/3] crypto: refactor context creation to facilitate further work Jani Nikula
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Jani Nikula @ 2015-01-18 10:45 UTC (permalink / raw)
To: david, notmuch
On Sun, 18 Jan 2015, David Bremner <david@tethera.net> wrote:
> The notmuch-show flags --decrypt and --verify will now also process
> S/MIME multiparts if encountered. Requires gmime-2.6 and gpgsm.
Hi David -
I've had some S/MIME patches laying around since 2013, almost
forgotten... functionally it's the same but I have a couple of
refactoring prep patches that I think makes it a bit nicer.
BR,
Jani.
Jani Nikula (3):
crypto: refactor context creation to facilitate further work
crypto: make crypto ctx initialization an array
cli: crypto: S/MIME verification/decryption support
crypto.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++---------
notmuch-client.h | 7 ++--
2 files changed, 91 insertions(+), 19 deletions(-)
--
2.1.4
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/3] crypto: refactor context creation to facilitate further work
2015-01-18 10:45 ` [PATCH 0/3] smime with some refactoring Jani Nikula
@ 2015-01-18 10:45 ` Jani Nikula
2015-01-18 17:07 ` David Bremner
2015-01-18 10:45 ` [PATCH 2/3] crypto: make crypto ctx initialization an array Jani Nikula
2015-01-18 10:45 ` [PATCH 3/3] cli: crypto: S/MIME verification/decryption support Jani Nikula
2 siblings, 1 reply; 16+ messages in thread
From: Jani Nikula @ 2015-01-18 10:45 UTC (permalink / raw)
To: david, notmuch
---
crypto.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/crypto.c b/crypto.c
index 6f4a6db9d0f1..7cd7b69d1221 100644
--- a/crypto.c
+++ b/crypto.c
@@ -24,14 +24,20 @@
/* Create a GPG context (GMime 2.6) */
static notmuch_crypto_context_t *
-create_gpg_context (void)
+create_gpg_context (notmuch_crypto_t *crypto)
{
notmuch_crypto_context_t *gpgctx;
+ if (crypto->gpgctx)
+ return crypto->gpgctx;
+
/* TODO: GMimePasswordRequestFunc */
gpgctx = g_mime_gpg_context_new (NULL, "gpg");
- if (! gpgctx)
+ if (! gpgctx) {
+ fprintf (stderr, "Failed to construct gpg context.\n");
return NULL;
+ }
+ crypto->gpgctx = gpgctx;
g_mime_gpg_context_set_use_agent ((GMimeGpgContext *) gpgctx, TRUE);
g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) gpgctx, FALSE);
@@ -43,17 +49,23 @@ create_gpg_context (void)
/* Create a GPG context (GMime 2.4) */
static notmuch_crypto_context_t *
-create_gpg_context (void)
+create_gpg_context (notmuch_crypto_t *crypto)
{
GMimeSession *session;
notmuch_crypto_context_t *gpgctx;
+ if (crypto->gpgctx)
+ return crypto->gpgctx;
+
session = g_object_new (g_mime_session_get_type (), NULL);
gpgctx = g_mime_gpg_context_new (session, "gpg");
g_object_unref (session);
- if (! gpgctx)
+ if (! gpgctx) {
+ fprintf (stderr, "Failed to construct gpg context.\n");
return NULL;
+ }
+ crypto->gpgctx = gpgctx;
g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) gpgctx, FALSE);
@@ -82,12 +94,7 @@ notmuch_crypto_get_context (notmuch_crypto_t *crypto, const char *protocol)
*/
if (strcasecmp (protocol, "application/pgp-signature") == 0 ||
strcasecmp (protocol, "application/pgp-encrypted") == 0) {
- if (! crypto->gpgctx) {
- crypto->gpgctx = create_gpg_context ();
- if (! crypto->gpgctx)
- fprintf (stderr, "Failed to construct gpg context.\n");
- }
- cryptoctx = crypto->gpgctx;
+ cryptoctx = create_gpg_context (crypto);
} else {
fprintf (stderr, "Unknown or unsupported cryptographic protocol.\n");
}
--
2.1.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/3] crypto: make crypto ctx initialization an array
2015-01-18 10:45 ` [PATCH 0/3] smime with some refactoring Jani Nikula
2015-01-18 10:45 ` [PATCH 1/3] crypto: refactor context creation to facilitate further work Jani Nikula
@ 2015-01-18 10:45 ` Jani Nikula
2015-01-18 17:10 ` David Bremner
2015-01-18 10:45 ` [PATCH 3/3] cli: crypto: S/MIME verification/decryption support Jani Nikula
2 siblings, 1 reply; 16+ messages in thread
From: Jani Nikula @ 2015-01-18 10:45 UTC (permalink / raw)
To: david, notmuch
---
crypto.c | 30 ++++++++++++++++++++++--------
1 file changed, 22 insertions(+), 8 deletions(-)
diff --git a/crypto.c b/crypto.c
index 7cd7b69d1221..8e58dcca4ee5 100644
--- a/crypto.c
+++ b/crypto.c
@@ -74,16 +74,30 @@ create_gpg_context (notmuch_crypto_t *crypto)
#endif /* GMIME_ATLEAST_26 */
+static struct {
+ const char *protocol;
+ notmuch_crypto_context_t *(*get_context) (notmuch_crypto_t *crypto);
+} protocols[] = {
+ {
+ .protocol = "application/pgp-signature",
+ .get_context = create_gpg_context,
+ },
+ {
+ .protocol = "application/pgp-encrypted",
+ .get_context = create_gpg_context,
+ },
+};
+
/* for the specified protocol return the context pointer (initializing
* if needed) */
notmuch_crypto_context_t *
notmuch_crypto_get_context (notmuch_crypto_t *crypto, const char *protocol)
{
- notmuch_crypto_context_t *cryptoctx = NULL;
+ size_t i;
if (! protocol) {
fprintf (stderr, "Cryptographic protocol is empty.\n");
- return cryptoctx;
+ return NULL;
}
/* As per RFC 1847 section 2.1: "the [protocol] value token is
@@ -92,14 +106,14 @@ notmuch_crypto_get_context (notmuch_crypto_t *crypto, const char *protocol)
* parameter names as defined in this document are
* case-insensitive." Thus, we use strcasecmp for the protocol.
*/
- if (strcasecmp (protocol, "application/pgp-signature") == 0 ||
- strcasecmp (protocol, "application/pgp-encrypted") == 0) {
- cryptoctx = create_gpg_context (crypto);
- } else {
- fprintf (stderr, "Unknown or unsupported cryptographic protocol.\n");
+ for (i = 0; i < ARRAY_SIZE (protocols); i++) {
+ if (strcasecmp (protocol, protocols[i].protocol) == 0)
+ return protocols[i].get_context (crypto);
}
- return cryptoctx;
+ fprintf (stderr, "Unknown or unsupported cryptographic protocol.\n");
+
+ return NULL;
}
int
--
2.1.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/3] cli: crypto: S/MIME verification/decryption support
2015-01-18 10:45 ` [PATCH 0/3] smime with some refactoring Jani Nikula
2015-01-18 10:45 ` [PATCH 1/3] crypto: refactor context creation to facilitate further work Jani Nikula
2015-01-18 10:45 ` [PATCH 2/3] crypto: make crypto ctx initialization an array Jani Nikula
@ 2015-01-18 10:45 ` Jani Nikula
2015-01-18 17:14 ` David Bremner
2 siblings, 1 reply; 16+ messages in thread
From: Jani Nikula @ 2015-01-18 10:45 UTC (permalink / raw)
To: david, notmuch
The notmuch-show flags --decrypt and --verify will now also process
S/MIME multiparts if encountered. Requires gmime-2.6 and gpgsm.
Based on work by Jameson Graef Rollins <jrollins@finestructure.net>.
---
id:1340995101-9616-2-git-send-email-jrollins@finestructure.net
---
crypto.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
notmuch-client.h | 7 +++++--
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/crypto.c b/crypto.c
index 8e58dcca4ee5..8944cc5d4bcd 100644
--- a/crypto.c
+++ b/crypto.c
@@ -45,6 +45,29 @@ create_gpg_context (notmuch_crypto_t *crypto)
return gpgctx;
}
+/* Create a PKCS7 context (GMime 2.6) */
+static notmuch_crypto_context_t *
+create_pkcs7_context (notmuch_crypto_t *crypto)
+{
+ notmuch_crypto_context_t *pkcs7ctx;
+
+ if (crypto->pkcs7ctx)
+ return crypto->pkcs7ctx;
+
+ /* TODO: GMimePasswordRequestFunc */
+ pkcs7ctx = g_mime_pkcs7_context_new (NULL);
+ if (! pkcs7ctx) {
+ fprintf (stderr, "Failed to construct pkcs7 context.\n");
+ return NULL;
+ }
+ crypto->pkcs7ctx = pkcs7ctx;
+
+ g_mime_pkcs7_context_set_always_trust ((GMimePkcs7Context *) pkcs7ctx,
+ FALSE);
+
+ return pkcs7ctx;
+}
+
#else /* GMIME_ATLEAST_26 */
/* Create a GPG context (GMime 2.4) */
@@ -72,6 +95,14 @@ create_gpg_context (notmuch_crypto_t *crypto)
return gpgctx;
}
+/* Create a PKCS7 context (GMime 2.4) */
+static notmuch_crypto_context_t *
+create_pkcs7_context (notmuch_crypto_t *crypto)
+{
+ fprintf (stderr, "pkcs7 is not supported in gmime 2.4.\n");
+ return NULL;
+}
+
#endif /* GMIME_ATLEAST_26 */
static struct {
@@ -86,6 +117,18 @@ static struct {
.protocol = "application/pgp-encrypted",
.get_context = create_gpg_context,
},
+ {
+ .protocol = "application/pkcs7-signature",
+ .get_context = create_pkcs7_context,
+ },
+ {
+ .protocol = "application/x-pkcs7-signature",
+ .get_context = create_pkcs7_context,
+ },
+ {
+ .protocol = "application/pkcs7-encrypted",
+ .get_context = create_pkcs7_context,
+ },
};
/* for the specified protocol return the context pointer (initializing
@@ -124,5 +167,10 @@ notmuch_crypto_cleanup (notmuch_crypto_t *crypto)
crypto->gpgctx = NULL;
}
+ if (crypto->pkcs7ctx) {
+ g_object_unref (crypto->pkcs7ctx);
+ crypto->pkcs7ctx = NULL;
+ }
+
return 0;
}
diff --git a/notmuch-client.h b/notmuch-client.h
index 5e0d47508c6a..5f2a11ed8dc5 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -37,6 +37,8 @@
#ifdef GMIME_MAJOR_VERSION
#define GMIME_ATLEAST_26
typedef GMimeCryptoContext notmuch_crypto_context_t;
+/* This is automatically included only since gmime 2.6.10 */
+#include <gmime/gmime-pkcs7-context.h>
#else
typedef GMimeCipherContext notmuch_crypto_context_t;
#endif
@@ -78,6 +80,7 @@ typedef struct notmuch_show_format {
typedef struct notmuch_crypto {
notmuch_crypto_context_t* gpgctx;
+ notmuch_crypto_context_t* pkcs7ctx;
notmuch_bool_t verify;
notmuch_bool_t decrypt;
} notmuch_crypto_t;
@@ -414,8 +417,8 @@ struct mime_node {
/* Construct a new MIME node pointing to the root message part of
* message. If crypto->verify is true, signed child parts will be
* verified. If crypto->decrypt is true, encrypted child parts will be
- * decrypted. If crypto->gpgctx is NULL, it will be lazily
- * initialized.
+ * decrypted. If the crypto contexts (crypto->gpgctx or
+ * crypto->pkcs7) are NULL, they will be lazily initialized.
*
* Return value:
*
--
2.1.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 3/3] cli: crypto: S/MIME verification/decryption support
2015-01-18 10:45 ` [PATCH 3/3] cli: crypto: S/MIME verification/decryption support Jani Nikula
@ 2015-01-18 17:14 ` David Bremner
2015-03-02 17:56 ` Jameson Graef Rollins
0 siblings, 1 reply; 16+ messages in thread
From: David Bremner @ 2015-01-18 17:14 UTC (permalink / raw)
To: Jani Nikula, notmuch
Jani Nikula <jani@nikula.org> writes:
> The notmuch-show flags --decrypt and --verify will now also process
> S/MIME multiparts if encountered. Requires gmime-2.6 and gpgsm.
>
> Based on work by Jameson Graef Rollins <jrollins@finestructure.net>.
>
I tend to agree this version is a bit easier to read, if a bit longer.
Jamie, do you have any objections?
I haven't tried this version with the tests in this thread.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 3/3] cli: crypto: S/MIME verification/decryption support
2015-01-18 17:14 ` David Bremner
@ 2015-03-02 17:56 ` Jameson Graef Rollins
0 siblings, 0 replies; 16+ messages in thread
From: Jameson Graef Rollins @ 2015-03-02 17:56 UTC (permalink / raw)
To: David Bremner, Jani Nikula, notmuch
[-- Attachment #1: Type: text/plain, Size: 647 bytes --]
On Sun, Jan 18 2015, David Bremner <david@tethera.net> wrote:
> Jani Nikula <jani@nikula.org> writes:
>
>> The notmuch-show flags --decrypt and --verify will now also process
>> S/MIME multiparts if encountered. Requires gmime-2.6 and gpgsm.
>>
>> Based on work by Jameson Graef Rollins <jrollins@finestructure.net>.
>>
>
> I tend to agree this version is a bit easier to read, if a bit longer.
> Jamie, do you have any objections?
>
> I haven't tried this version with the tests in this thread.
So sorry to take so long to respond. If Jani has a cleaner version of
the patch then by all means, please let it supersede what I have done.
jamie.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Patch v4 3/5] test: add S/MIME signature verification test for notmuch CLI
2015-01-18 8:02 S/MIME patches, v4 David Bremner
2015-01-18 8:02 ` [Patch v4 1/5] test: initial tests for S/MIME and notmuch-emacs David Bremner
2015-01-18 8:02 ` [Patch v4 2/5] cli: S/MIME verification/decryption support David Bremner
@ 2015-01-18 8:02 ` David Bremner
2015-01-18 8:02 ` [Patch v4 4/5] debian: Recommend gpgsm for S/MIME support David Bremner
2015-01-18 8:02 ` [Patch v4 5/5] test: add broken test for SMIME decryption with notmuch CLI David Bremner
4 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2015-01-18 8:02 UTC (permalink / raw)
To: notmuch
The test is pretty much cut and paste from the PGP/MIME version, with
obvious updates taken from notmuch output. This also requires setting
up gpgsm infrastucture.
---
test/T355-smime.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
test/test-lib.sh | 1 +
2 files changed, 50 insertions(+)
diff --git a/test/T355-smime.sh b/test/T355-smime.sh
index 5f3ff12..caedf5e 100755
--- a/test/T355-smime.sh
+++ b/test/T355-smime.sh
@@ -3,7 +3,17 @@
test_description='S/MIME signature verification and decryption'
. ./test-lib.sh
+add_gpgsm_home ()
+{
+ local output
+ [ -d ${GNUPGHOME} ] && return
+ mkdir -m 0700 "$GNUPGHOME"
+ gpgsm --no-tty --import < test_suite.pem >"$GNUPGHOME"/import.log 2>&1
+ test_debug "cat $GNUPGHOME/import.log"
+}
+
test_require_external_prereq openssl
+test_require_external_prereq gpgsm
test_begin_subtest "Generate CA Cert"
openssl genpkey -algorithm RSA -out ca.key -pass pass:test -des3 1024
@@ -21,6 +31,10 @@ openssl x509 -req -in smime.csr -passin pass:test -CA ca.crt -CAkey ca.key -set_
cat test_suite.crt smime.key > test_suite.pem
test_expect_equal "$(openssl verify -purpose smimesign -CAfile ca.crt test_suite.pem)" "test_suite.pem: OK"
+add_gpgsm_home
+
+FINGERPRINT=$(openssl x509 -fingerprint -in test_suite.crt -noout | sed -e 's/^.*=//' -e s/://g)
+
test_expect_success 'emacs delivery of S/MIME signed message' \
'emacs_fcc_message \
"test signed message 001" \
@@ -41,6 +55,41 @@ Verification successful
EOF
test_expect_equal_file OUTPUT EXPECTED
+test_begin_subtest "signature verification (notmuch CLI)"
+output=$(notmuch show --format=json --verify subject:"test signed message 001" \
+ | notmuch_json_show_sanitize \
+ | sed -e 's|"created": [1234567890]*|"created": 946728000|' \
+ -e 's|"expires": [1234567890]*|"expires": 424242424|' )
+expected='[[[{"id": "XXXXX",
+ "match": true,
+ "excluded": false,
+ "filename": "YYYYY",
+ "timestamp": 946728000,
+ "date_relative": "2000-01-01",
+ "tags": ["inbox","signed"],
+ "headers": {"Subject": "test signed message 001",
+ "From": "Notmuch Test Suite <test_suite@notmuchmail.org>",
+ "To": "test_suite@notmuchmail.org",
+ "Date": "Sat, 01 Jan 2000 12:00:00 +0000"},
+ "body": [{"id": 1,
+ "sigstatus": [{"status": "good",
+ "fingerprint": "'$FINGERPRINT'",
+ "expires": 424242424,
+ "created": 946728000}],
+ "content-type": "multipart/signed",
+ "content": [{"id": 2,
+ "content-type": "text/plain",
+ "content": "This is a test signed message.\n"},
+ {"id": 3,
+ "content-length": 1930,
+ "content-transfer-encoding": "base64",
+ "content-type": "application/x-pkcs7-signature",
+ "filename": "smime.p7s"}]}]},
+ []]]]'
+test_expect_equal_json \
+ "$output" \
+ "$expected"
+
test_begin_subtest "Decryption and signature verification (openssl)"
notmuch show --format=raw subject:"test encrypted message 001" |\
openssl smime -decrypt -recip test_suite.pem |\
diff --git a/test/test-lib.sh b/test/test-lib.sh
index 00612d9..a0d44e1 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -1305,3 +1305,4 @@ test_declare_external_prereq gpg
test_declare_external_prereq python
test_declare_external_prereq python2
test_declare_external_prereq openssl
+test_declare_external_prereq gpgsm
--
2.1.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Patch v4 4/5] debian: Recommend gpgsm for S/MIME support
2015-01-18 8:02 S/MIME patches, v4 David Bremner
` (2 preceding siblings ...)
2015-01-18 8:02 ` [Patch v4 3/5] test: add S/MIME signature verification test for notmuch CLI David Bremner
@ 2015-01-18 8:02 ` David Bremner
2015-01-18 8:02 ` [Patch v4 5/5] test: add broken test for SMIME decryption with notmuch CLI David Bremner
4 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2015-01-18 8:02 UTC (permalink / raw)
To: notmuch
From: Jameson Graef Rollins <jrollins@finestructure.net>
---
debian/control | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/debian/control b/debian/control
index 4bc4cd9..05cd04f 100644
--- a/debian/control
+++ b/debian/control
@@ -31,7 +31,7 @@ Vcs-Browser: http://git.notmuchmail.org/git/notmuch
Package: notmuch
Architecture: any
Depends: libnotmuch4 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
-Recommends: notmuch-emacs | notmuch-vim | notmuch-mutt | alot, gnupg-agent
+Recommends: notmuch-emacs | notmuch-vim | notmuch-mutt | alot, gnupg-agent, gpgsm
Description: thread-based email index, search and tagging
Notmuch is a system for indexing, searching, reading, and tagging
large collections of email messages in maildir or mh format. It uses
--
2.1.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Patch v4 5/5] test: add broken test for SMIME decryption with notmuch CLI
2015-01-18 8:02 S/MIME patches, v4 David Bremner
` (3 preceding siblings ...)
2015-01-18 8:02 ` [Patch v4 4/5] debian: Recommend gpgsm for S/MIME support David Bremner
@ 2015-01-18 8:02 ` David Bremner
2015-01-26 22:59 ` David Bremner
4 siblings, 1 reply; 16+ messages in thread
From: David Bremner @ 2015-01-18 8:02 UTC (permalink / raw)
To: notmuch
The test JSON here is not correct, but the larger problem is thatit seems like no actual decryption is being done.
---
test/T355-smime.sh | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/test/T355-smime.sh b/test/T355-smime.sh
index caedf5e..95dbf8f 100755
--- a/test/T355-smime.sh
+++ b/test/T355-smime.sh
@@ -99,4 +99,40 @@ Verification successful
EOF
test_expect_equal_file OUTPUT EXPECTED
+test_begin_subtest "Decryption and signature verification (notmuch CLI)"
+test_subtest_known_broken
+output=$(notmuch show --format=json --decrypt subject:"test encrypted message 001" \
+ | notmuch_json_show_sanitize \
+ | sed -e 's|"created": [1234567890]*|"created": 946728000|' \
+ -e 's|"expires": [1234567890]*|"expires": 424242424|' )
+expected='[[[{"id": "XXXXX",
+ "match": true,
+ "excluded": false,
+ "filename": "YYYYY",
+ "timestamp": 946728000,
+ "date_relative": "2000-01-01",
+ "tags": ["inbox","signed"],
+ "headers": {"Subject": "test encrypted message 001",
+ "From": "Notmuch Test Suite <test_suite@notmuchmail.org>",
+ "To": "test_suite@notmuchmail.org",
+ "Date": "Sat, 01 Jan 2000 12:00:00 +0000"},
+ "body": [{"id": 1,
+ "sigstatus": [{"status": "good",
+ "fingerprint": "'$FINGERPRINT'",
+ "expires": 424242424,
+ "created": 946728000}],
+ "content-type": "multipart/signed",
+ "content": [{"id": 2,
+ "content-type": "text/plain",
+ "content": "This is a test encrypted message.\n"},
+ {"id": 3,
+ "content-length": 1930,
+ "content-transfer-encoding": "base64",
+ "content-type": "application/x-pkcs7-signature",
+ "filename": "smime.p7s"}]}]},
+ []]]]'
+test_expect_equal_json \
+ "$output" \
+ "$expected"
+
test_done
--
2.1.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [Patch v4 5/5] test: add broken test for SMIME decryption with notmuch CLI
2015-01-18 8:02 ` [Patch v4 5/5] test: add broken test for SMIME decryption with notmuch CLI David Bremner
@ 2015-01-26 22:59 ` David Bremner
2015-01-28 7:36 ` David Bremner
0 siblings, 1 reply; 16+ messages in thread
From: David Bremner @ 2015-01-26 22:59 UTC (permalink / raw)
To: notmuch
David Bremner <david@tethera.net> writes:
> The test JSON here is not correct, but the larger problem is thatit
> seems like no actual decryption is being done.
I played with this some more, and it seems like Jamie's code (and the
gmime sample code [1] expects the top level part to be
multipart/encrypted. Message-mode on the other hand generates messages
with a single application/x-pkcs7-mime part. According to my reading of
rfc5751 section 3.9, they're both wrong. 'application/pkcs7-mime' is
legit, as is, wait for it, "application/octet-stream" with a file suffix
of "p7m", "p7s", "p7c", or "p7z". So I guess we have to check for
x-pkcs7-mime as well? Apparently this has only been a known problem [2]
for 15 years or so.
[1]: https://github.com/GNOME/gmime/blob/master/tests/test-smime.c
[2]: http://www.imc.org/ietf-smime/mail-archive/msg00726.html
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Patch v4 5/5] test: add broken test for SMIME decryption with notmuch CLI
2015-01-26 22:59 ` David Bremner
@ 2015-01-28 7:36 ` David Bremner
0 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2015-01-28 7:36 UTC (permalink / raw)
To: notmuch
[-- Attachment #1: Type: text/plain, Size: 795 bytes --]
David Bremner <david@tethera.net> writes:
> David Bremner <david@tethera.net> writes:
>
>> The test JSON here is not correct, but the larger problem is thatit
>> seems like no actual decryption is being done.
>
> I played with this some more, and it seems like Jamie's code (and the
> gmime sample code [1] expects the top level part to be
> multipart/encrypted.
By repeated bludgeoning I convinced notmuch show to actually run the
decryption code, but then I hit another problem: there isn't an obvious
high level way to decrypt an application/(x)-pkcs7-mime part (and the
current code only works for multipart/encrypted). It should
be possible up GMimeStreams and use g_mime_crypto_context_decrypt, but
that seems like quite a bit more work than calling
g_mime_multipart_encrypted_decrypt.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: smime.diff --]
[-- Type: text/x-diff, Size: 2551 bytes --]
diff --git a/mime-node.c b/mime-node.c
index fd9e4a4..7019be7 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -54,6 +54,20 @@ _mime_node_context_free (mime_node_context_t *res)
return 0;
}
+static
+notmuch_bool_t
+_is_smime_encrypted_part (GMimeObject *part) {
+
+ GMimeContentType *content_type = g_mime_object_get_content_type(part);
+ if (content_type) {
+ return g_mime_content_type_is_type (content_type, "application",
+ "pkcs7-mime") ||
+ g_mime_content_type_is_type (content_type, "application",
+ "x-pkcs7-mime");
+ }
+ return FALSE;
+}
+
notmuch_status_t
mime_node_open (const void *ctx, notmuch_message_t *message,
notmuch_crypto_t *crypto, mime_node_t **root_out)
@@ -323,22 +337,33 @@ _mime_node_create (mime_node_t *parent, GMimeObject *part)
return NULL;
}
- if ((GMIME_IS_MULTIPART_ENCRYPTED (part) && node->ctx->crypto->decrypt)
+ if (((GMIME_IS_MULTIPART_ENCRYPTED (part) || _is_smime_encrypted_part (part))
+ && node->ctx->crypto->decrypt)
|| (GMIME_IS_MULTIPART_SIGNED (part) && node->ctx->crypto->verify)) {
GMimeContentType *content_type = g_mime_object_get_content_type (part);
const char *protocol = g_mime_content_type_get_parameter (content_type, "protocol");
+ if (!protocol) {
+ if (_is_smime_encrypted_part (part)) {
+ protocol = "application/pkcs7-encrypted";
+ }
+ }
cryptoctx = notmuch_crypto_get_context (node->ctx->crypto, protocol);
}
- /* Handle PGP/MIME parts */
- if (GMIME_IS_MULTIPART_ENCRYPTED (part) && node->ctx->crypto->decrypt && cryptoctx) {
- if (node->nchildren != 2) {
- /* this violates RFC 3156 section 4, so we won't bother with it. */
- fprintf (stderr, "Error: %d part(s) for a multipart/encrypted "
- "message (must be exactly 2)\n",
- node->nchildren);
- } else {
+ /* Are we ready and able to decrypt something ? */
+ if (node->ctx->crypto->decrypt && cryptoctx) {
+ if (_is_smime_encrypted_part (part)) {
node_decrypt_and_verify (node, part, cryptoctx);
+ } else if (GMIME_IS_MULTIPART_ENCRYPTED (part)) {
+ /* Handle PGP/MIME parts */
+ if (node->nchildren != 2) {
+ /* this violates RFC 3156 section 4, so we won't bother with it. */
+ fprintf (stderr, "Error: %d part(s) for a multipart/encrypted "
+ "message (must be exactly 2)\n",
+ node->nchildren);
+ } else {
+ node_decrypt_and_verify (node, part, cryptoctx);
+ }
}
} else if (GMIME_IS_MULTIPART_SIGNED (part) && node->ctx->crypto->verify && cryptoctx) {
if (node->nchildren != 2) {
^ permalink raw reply related [flat|nested] 16+ messages in thread