unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* S/MIME patches, v4
@ 2015-01-18  8:02 David Bremner
  2015-01-18  8:02 ` [Patch v4 1/5] test: initial tests for S/MIME and notmuch-emacs David Bremner
                   ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: David Bremner @ 2015-01-18  8:02 UTC (permalink / raw)
  To: notmuch

I took Jamie's advice and simplified the openssl based tests
to ignore the actual output.

I added a test to generate a signed+encrypted message, and verified
that with openssl (in two steps).

I'm a bit stumped why the test introduced in patch 5/5 is failing so
badly. I'd give even odds that I haven't set up gpgsm right (only
imported the public key and not the private one?). Still, it looks to
me like there should be some more diagnostics from notmuch if the
crypto is failing.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [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 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

* [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 1/3] crypto: refactor context creation to facilitate further work
  2015-01-18 10:45     ` [PATCH 1/3] crypto: refactor context creation to facilitate further work Jani Nikula
@ 2015-01-18 17:07       ` David Bremner
  0 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2015-01-18 17:07 UTC (permalink / raw)
  To: Jani Nikula, notmuch

Jani Nikula <jani@nikula.org> writes:

> ---
>  crypto.c | 27 +++++++++++++++++----------
>  1 file changed, 17 insertions(+), 10 deletions(-)

No real objections.  Although it's kindof implicit in "refactor", it
might make sense to note in the commit message that it's just code
movement.

d

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/3] crypto: make crypto ctx initialization an array
  2015-01-18 10:45     ` [PATCH 2/3] crypto: make crypto ctx initialization an array Jani Nikula
@ 2015-01-18 17:10       ` David Bremner
  0 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2015-01-18 17:10 UTC (permalink / raw)
  To: Jani Nikula, notmuch

Jani Nikula <jani@nikula.org> writes:

> ---
>  crypto.c | 30 ++++++++++++++++++++++--------
>  1 file changed, 22 insertions(+), 8 deletions(-)

A few words about the big picture would be good here, namely that we
want to make it easier to support a new protocol.

^ permalink raw reply	[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 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

* 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

end of thread, other threads:[~2015-03-02 18:15 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 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 17:07       ` David Bremner
2015-01-18 10:45     ` [PATCH 2/3] crypto: make crypto ctx initialization an array 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
2015-01-18 17:14       ` David Bremner
2015-03-02 17:56         ` Jameson Graef Rollins
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 ` [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
2015-01-26 22:59   ` David Bremner
2015-01-28  7:36     ` David Bremner

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).