From bernhard at intevation.de Thu Mar 1 17:06:44 2018 From: bernhard at intevation.de (Bernhard Reiter) Date: Thu, 1 Mar 2018 17:06:44 +0100 Subject: GnuPG 2.2 on elder Debian & Ubuntu distros In-Reply-To: <20171027162445.GA17617@breadbox.private.spodhuis.org> References: <201710271606.59244.bernhard@intevation.de> <20171027162445.GA17617@breadbox.private.spodhuis.org> Message-ID: <201803011706.50033.bernhard@intevation.de> Phil, Am Freitag 27 Oktober 2017 18:24:45 schrieb Phil Pennock: > Thus at https://public-packages.pennock.tech/ I have packages for 4 of > the 5 releases you mention (amd64-only). I install the `optgnupg-gnupg` > package thanks I've tried your packages today on a GNU Stretch system and got working Gnupg 2.2.5. For the X11 based pinentries: You could recommend the needed minimum set of X11 dependencies, to ease installation for people who want a graphical pinentry. > It's then just a matter of using `$PATH` for users so that I can use a > capable modern GnuPG for all my stuff, while leaving the system tooling > alone. Your page is quite helpful, my suggestion is to add or link an example how to set the path, e.g. sourcing a bash file like :::::::::::::: setgnupg :::::::::::::: base=/opt/gnupg export LD_LIBRARY_PATH=$base/lib:$LD_LIBRARY_PATH export MANPATH=$base/share/man:$MANPATH export PATH=$base/bin:$PATH :::::::::::::: Best Regards, Bernhard -- www.intevation.de/~bernhard ? +49 541 33 508 3-3 Intevation GmbH, Osnabr?ck, DE; Amtsgericht Osnabr?ck, HRB 18998 Gesch?ftsf?hrer Frank Koormann, Bernhard Reiter, Dr. Jan-Oliver Wagner -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: This is a digitally signed message part. URL: From marcelf at selfnet.de Thu Mar 1 17:33:32 2018 From: marcelf at selfnet.de (Marcel Fest) Date: Thu, 1 Mar 2018 17:33:32 +0100 Subject: Help with python library Message-ID: Hey all, I use ArchLinux and the latest gpg python library from gnupg.org Is their a function like gpg --list-packets --list-only path/to/file in the python library? I need this information at the moment to verify if a file is correctly encrypted. This will be checked against our ldap and our ansible repository. Is their a similar function in the python GPGme Wrapper? If so how can I use that function to get the required information out of an encrypted file? Thanks for your time Marcel Fest -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: OpenPGP digital signature URL: From muelli at cryptobitch.de Thu Mar 1 19:33:39 2018 From: muelli at cryptobitch.de (Tobias Mueller) Date: Thu, 01 Mar 2018 19:33:39 +0100 Subject: Help with python library In-Reply-To: References: Message-ID: <1519929219.4518.9.camel@cryptobitch.de> Hi. On Thu, 2018-03-01 at 17:33 +0100, Marcel Fest wrote: > Is their a similar function in the python GPGme Wrapper? I'd recommend to search for something like "list packet" in the gpgme manual , but you can't easily search the whole document :( Grepping through the gpgme source for "list-packet" did not yield anything, so I assume you cannot use it for getting the information you desire. You can use a more useful library for dealing with OpenPGP data such as PGPy: . HTH, Tobi From dkg at fifthhorseman.net Fri Mar 2 03:57:02 2018 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Thu, 01 Mar 2018 21:57:02 -0500 Subject: GnuPG 2.2 on elder Debian & Ubuntu distros In-Reply-To: <201803011706.50033.bernhard@intevation.de> References: <201710271606.59244.bernhard@intevation.de> <20171027162445.GA17617@breadbox.private.spodhuis.org> <201803011706.50033.bernhard@intevation.de> Message-ID: <87inafrxq9.fsf@fifthhorseman.net> On Thu 2018-03-01 17:06:44 +0100, Bernhard Reiter wrote: > thanks I've tried your packages today on a GNU Stretch system > and got working Gnupg 2.2.5. fwiw, if folks want GnuPG 2.2.5 on stretch, that should be a relatively straightforward series of backports. we should be able to upload it directly to stretch-backports, which would not only cover all the architectures supported by stretch-backports, but also would be much more straightforward to install for the end user. this is not the case for debian jessie, which has many more packages in the OS that *will* break if gpg moves from the 1.4.x version that shipped in jessie to anything from the "modern" branch. If folks want a backport of 2.2.5 to stretch specifically, please let me know. I'd particularly be happy to guide any interested would-be debian packager through the steps of creating a backport, and would be willing to sponsor an upload if it's built sensibly and behaves reasonably. --dkg -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From bernhard at intevation.de Fri Mar 2 17:28:16 2018 From: bernhard at intevation.de (Bernhard Reiter) Date: Fri, 2 Mar 2018 17:28:16 +0100 Subject: GnuPG 2.2 on elder Debian & Ubuntu distros In-Reply-To: <87inafrxq9.fsf@fifthhorseman.net> References: <201710271606.59244.bernhard@intevation.de> <201803011706.50033.bernhard@intevation.de> <87inafrxq9.fsf@fifthhorseman.net> Message-ID: <201803021728.27829.bernhard@intevation.de> Am Freitag 02 M?rz 2018 03:57:02 schrieb Daniel Kahn Gillmor: > On Thu 2018-03-01 17:06:44 +0100, Bernhard Reiter wrote: > > thanks I've tried your packages today on a GNU Stretch system > > and got working Gnupg 2.2.5. > If folks want a backport of 2.2.5 to stretch specifically, please let me > know. Personally I think that having a backport of the current GnuPG to Stretch would be helpful for spreading GnuPG as 2.2.5 has much better capabilities for WKD. Bernhard -- www.intevation.de/~bernhard ? +49 541 33 508 3-3 Intevation GmbH, Osnabr?ck, DE; Amtsgericht Osnabr?ck, HRB 18998 Gesch?ftsf?hrer Frank Koormann, Bernhard Reiter, Dr. Jan-Oliver Wagner -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: This is a digitally signed message part. URL: From ben at adversary.org Mon Mar 5 00:05:30 2018 From: ben at adversary.org (Ben McGinnes) Date: Mon, 5 Mar 2018 10:05:30 +1100 Subject: Help with python library In-Reply-To: References: Message-ID: <20180304230530.xwhrxgqe35ct3nod@adversary.org> On Thu, Mar 01, 2018 at 05:33:32PM +0100, Marcel Fest wrote: > Hey all, > > I use ArchLinux and the latest gpg python library from gnupg.org > > Is their a function like > gpg --list-packets --list-only path/to/file > > in the python library? > I need this information at the moment to verify if a file is correctly encrypted. > This will be checked against our ldap and our ansible repository. Do you mean you need to check whether a file you are encrypting has been encrypted correctly or do you mean you need to check whether a file you have received has been encrypted to the correct key(s) by a third party? > Is their a similar function in the python GPGme Wrapper? The Python bindings are a complete match for the implemented functions in GPGME. GPGME can detect the data types and packet types contained in an encrypted message, otherwise a lot of things simply wouldn't work and each operation would be more akin to playing darts blindfolded. However, gpg --list-packets is a debugging tool, so I'd need to double-check whether there was a full implementation of that in the API. Still, depending on the answer to my first question, there may be a more efficient means of solving the issue you have, without resorting to human readable debugging tools. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From justus at gnupg.org Mon Mar 5 15:13:16 2018 From: justus at gnupg.org (Justus Winter) Date: Mon, 05 Mar 2018 15:13:16 +0100 Subject: [PATCH] python: Fix crash by leaving struct members intact In-Reply-To: <1519144454.9285.13.camel@cryptobitch.de> References: <1519144454.9285.13.camel@cryptobitch.de> Message-ID: <87y3j64nlv.fsf@thinkbox.jade-hamburg.de> Tobias Mueller writes: > * lang/python/setup.py.in: Copy gpgme.h instead of parsing it. > -- > The python bindings tried to parse deprecated functions > out of gpgme.h. This fails for the current gpgme.h in > that it removes an entire field in the key sig struct (_obsolete_class). > Hence, the fields were off by an int and the bindings accessed struct > members via the wrong offset. That caused python program to crash. > At least on 32bit platforms, the crash can be easily triggered by > accessing key.uids[0].signatures. On 64bit platforms the compiler > probably aligns the struct so that the missing 4 bytes are not noticed. > > With this change, the python bindings will expose all functions > that gpgme exposes, including the deprecated ones. Some context: Previously, the bindings filtered out deprecated functions using a regular expression when generating the low-level bindings using SWIG. This is what you see as e.g. gpg.core.gpgme, a thin autogenerated wrapper around libgpgme. (Disclaimer: We inherited this from pyme). So the bindings then put a layer of sugar on top of that low-level bindings to make them more idiomatic. This layer consists of hand-written functions that carry docstrings. This is what we want people to use, and this is also what people will discover when they play around with the bindings in ipython. The bindings actually synthesize wrapper functions on demand. E.g. if I were to create a context, c = gpg.Context(), I could say c.op_assuan_result and it would wrap gpgme_op_assuan_result. (Disclaimer: We also inherited this from pyme). This is one of the deprecated functions. Without this patch, accessing c.op_assuan_result would fail, with it it succeeds. I don't know whether or not using that function from python is sensible or even possible, but that is what happens. So the cost of applying this patch is to expose some deprecated functionality that people could suddenly use if they really wanted to. However, the current state is worse, because clearly parsing and modifying C using regular expressions cannot work reliably, and in fact this is a real problem, e.g.: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=884900 When in doubt, don't lie to your compiler ;) Justus -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From wk at gnupg.org Mon Mar 5 16:36:47 2018 From: wk at gnupg.org (Werner Koch) Date: Mon, 05 Mar 2018 16:36:47 +0100 Subject: Help with python library In-Reply-To: <20180304230530.xwhrxgqe35ct3nod@adversary.org> (Ben McGinnes's message of "Mon, 5 Mar 2018 10:05:30 +1100") References: <20180304230530.xwhrxgqe35ct3nod@adversary.org> Message-ID: <871sgypm9c.fsf@wheatstone.g10code.de> On Mon, 5 Mar 2018 00:05, ben at adversary.org said: > However, gpg --list-packets is a debugging tool, so I'd need to > double-check whether there was a full implementation of that in the > API. Right. Note that there is a somewhat related feature request https://dev.gnupg.org/T3734 (Extract signature key ID with gpgme). For checking whether a file is correctly encrypted, I would suggest to simply try to decrypt it to /dev/null. The result information lists the all keys; see gpgme/tests/run-decrypt.c for sample code. If needed we can add a --dry-run feature so that no passphrase is needed. Salam-Shalom, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From dgouttegattat at incenp.org Mon Mar 5 18:15:13 2018 From: dgouttegattat at incenp.org (Damien Goutte-Gattat) Date: Mon, 5 Mar 2018 17:15:13 +0000 Subject: [PATCH 0/2] Use external process to check for passphrase quality In-Reply-To: <87r2rcxv51.fsf@wheatstone.g10code.de> References: <20171230101925.7062-1-dgouttegattat@incenp.org> <87r2rcxv51.fsf@wheatstone.g10code.de> Message-ID: <494a22de-34c5-b043-0a9b-5e8678ef736e@incenp.org> Hi GnuPG folks, On 12/30/2017 12:22 PM, Werner Koch wrote: >> The following patch set provides a way to give the user a better >> passphrase quality estimation, as discussed in ticket #2103 [1]. > > Given that this is a long standing complaint I would be fine with adding > this even to 2.2. Or should we do this only for master? Although Werner expressed an interest in this patch set, it does not seem to have found its way into neither master nor STABLE-BRANCH-2-2. Any issue that I should work on before it can be merged? Damien -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From James.Bottomley at HansenPartnership.com Mon Mar 5 20:12:05 2018 From: James.Bottomley at HansenPartnership.com (James Bottomley) Date: Mon, 05 Mar 2018 11:12:05 -0800 Subject: [RFC v2 0/5] TPM support for gpg Message-ID: <1520277125.5312.35.camel@HansenPartnership.com> This patch series adds TPM 2.0 support to gnupg. TPMs are useful as an alternative to key cards: they provide the same security against key theft and the same cryptographic protections. ?The main difference is that TPMs are universally present in every laptop, so they provide a simple and ubiquitous solution to key security. ?The only real down side is that unlike key cards, TPM protected keys cannot be transferred between laptops, you must instead keep an offline backup copy of the key can then be transferred to the TPM of any new laptop. The way TPM protection works is slightly different from key cards. ?Instead of moving the key inside the card, the TPM converts any given key to a TPM specific representation (meaning it's encrypted by a special key that only the TPM possesses). ?The TPM represenation must be stored offline somewhere and if it is lost, so is the protected key. ?The way I implemented this is to use the TPM to convert the key to protected representation and then store it in the shadow_info of a shadowed-private-key using a shadow type of tpm2-v1. ?The TPM can handle an arbitrary number of keys, but the price is the shadow_info stores the keys and must be preserved. This implementation is an RFC, because ordinarily TPM support would be integrated into the cryptosystem rather than the application but since gnupg already integrates key cards via a diversion mechanism, it was also easy to follow this route for TPM support. ?The main difference between the TPM and the card is that there's no need for a separate daemon to run the card, so I integrated diversion support directly into the agent. The way to use this is simple: I added a new command to keyedit.c: keytotpm which converts an existing encrypted private key to TPM representation. This conversion is done immediately the command completes and cannot be undone. ?Once converted, all the usual gpg operations go transparently through the TPM, so it should be largely invisible to a user. Since the last posting, I've tidied up a few things and added support for Elliptic Curve keys (as a separate patch, currently, but it could be rolled into the base). I'm also building the relevant packages for Fedora, Debian and openSUSE here, for those who want to try it out: https://build.opensuse.org/project/show/home:jejb1:TPM James --- James Bottomley (5): agent: expose shadow key type agent: add tpm specific functions agent: plumb in TPM handling g10: add ability to transfer a private key to the tpm tpm2: add handling for elliptic curve keys agent/Makefile.am | 4 +- agent/agent.h | 23 +- agent/command.c | 78 +++- agent/divert-tpm2.c | 218 +++++++++++ agent/findkey.c | 5 +- agent/pkdecrypt.c | 8 +- agent/pksign.c | 14 +- agent/protect.c | 72 +++- agent/tpm2.c | 1002 +++++++++++++++++++++++++++++++++++++++++++++++++++ agent/tpm2.h | 27 ++ g10/call-agent.c | 22 ++ g10/call-agent.h | 3 + g10/keyedit.c | 45 ++- 13 files changed, 1495 insertions(+), 26 deletions(-) create mode 100644 agent/divert-tpm2.c create mode 100644 agent/tpm2.c create mode 100644 agent/tpm2.h -- 2.12.3 From James.Bottomley at HansenPartnership.com Mon Mar 5 20:13:25 2018 From: James.Bottomley at HansenPartnership.com (James Bottomley) Date: Mon, 05 Mar 2018 11:13:25 -0800 Subject: [RFC v2 1/5] agent: expose shadow key type In-Reply-To: <1520277125.5312.35.camel@HansenPartnership.com> References: <1520277125.5312.35.camel@HansenPartnership.com> Message-ID: <1520277205.5312.37.camel@HansenPartnership.com> For TPM support it is necessary to indroduce another type of shadow key, so allow other agent functions to extract the type so they can make the right decisions based on it. Signed-off-by: James Bottomley --- agent/agent.h | 10 +++++++- agent/command.c | 21 +++++++++++++---- agent/findkey.c | 5 ++-- agent/protect.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 90 insertions(+), 18 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index 687635dc7..2df2fde53 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -420,7 +420,8 @@ int agent_is_eddsa_key (gcry_sexp_t s_key); int agent_key_available (const unsigned char *grip); gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, int *r_keytype, - unsigned char **r_shadow_info); + unsigned char **r_shadow_info, + unsigned char **r_shadow_info_type); gpg_error_t agent_delete_key (ctrl_t ctrl, const char *desc_text, const unsigned char *grip, int force, int only_stubs); @@ -502,8 +503,15 @@ unsigned char *make_shadow_info (const char *serialno, const char *idstring); int agent_shadow_key (const unsigned char *pubkey, const unsigned char *shadow_info, unsigned char **result); +int agent_shadow_key_type (const unsigned char *pubkey, + const unsigned char *shadow_info, + const unsigned char *type, + unsigned char **result); gpg_error_t agent_get_shadow_info (const unsigned char *shadowkey, unsigned char const **shadow_info); +gpg_error_t agent_get_shadow_info_type (const unsigned char *shadowkey, + unsigned char const **shadow_info, + unsigned char **shadow_type); gpg_error_t parse_shadow_info (const unsigned char *shadow_info, char **r_hexsn, char **r_idstr, int *r_pinlen); gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo, diff --git a/agent/command.c b/agent/command.c index e2486a556..32c12d93f 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1104,7 +1104,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, char hexgrip[40+1]; char *fpr = NULL; int keytype; - unsigned char *shadow_info = NULL; + unsigned char *shadow_info = NULL, *shadow_info_type = NULL; char *serialno = NULL; char *idstr = NULL; const char *keytypestr; @@ -1115,7 +1115,8 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, char ttlbuf[20]; char flagsbuf[5]; - err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info); + err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info, + &shadow_info_type); if (err) { if (in_ssh && gpg_err_code (err) == GPG_ERR_NOT_FOUND) @@ -1185,9 +1186,18 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, if (shadow_info) { - err = parse_shadow_info (shadow_info, &serialno, &idstr, NULL); - if (err) - goto leave; + if (strcmp (shadow_info_type, "t1-v1") == 0) + { + err = parse_shadow_info (shadow_info, &serialno, &idstr, NULL); + if (err) + goto leave; + } + else + { + log_error ("Unrecognised shadow key type %s\n", shadow_info_type); + err = GPG_ERR_BAD_KEY; + goto leave; + } } if (!data) @@ -1222,6 +1232,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, leave: xfree (fpr); + xfree (shadow_info_type); xfree (shadow_info); xfree (serialno); xfree (idstr); diff --git a/agent/findkey.c b/agent/findkey.c index e3e9a123f..d6c600e71 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -1359,7 +1359,8 @@ agent_key_available (const unsigned char *grip) S-expression. */ gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, - int *r_keytype, unsigned char **r_shadow_info) + int *r_keytype, unsigned char **r_shadow_info, + unsigned char **r_shadow_info_type) { gpg_error_t err; unsigned char *buf; @@ -1406,7 +1407,7 @@ agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, const unsigned char *s; size_t n; - err = agent_get_shadow_info (buf, &s); + err = agent_get_shadow_info_type (buf, &s, r_shadow_info_type); if (!err) { n = gcry_sexp_canon_len (s, 0, NULL, NULL); diff --git a/agent/protect.c b/agent/protect.c index 16ae715e1..0920667d1 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -1499,9 +1499,10 @@ make_shadow_info (const char *serialno, const char *idstring) to. The input parameters are expected to be valid canonicalized S-expressions */ int -agent_shadow_key (const unsigned char *pubkey, - const unsigned char *shadow_info, - unsigned char **result) +agent_shadow_key_type (const unsigned char *pubkey, + const unsigned char *shadow_info, + const unsigned char *type, + unsigned char **result) { const unsigned char *s; const unsigned char *point; @@ -1557,7 +1558,7 @@ agent_shadow_key (const unsigned char *pubkey, assert (depth == 1); /* Calculate required length by taking in account: the "shadowed-" - prefix, the "shadowed", "t1-v1" as well as some parenthesis */ + prefix, the "shadowed", shadow type as well as some parenthesis */ n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1; *result = xtrymalloc (n); p = (char*)*result; @@ -1567,7 +1568,7 @@ agent_shadow_key (const unsigned char *pubkey, /* (10:public-key ...)*/ memcpy (p, pubkey+14, point - (pubkey+14)); p += point - (pubkey+14); - p = stpcpy (p, "(8:shadowed5:t1-v1"); + p += sprintf (p, "(8:shadowed%d:%s", (int)strlen(type), type); memcpy (p, shadow_info, shadow_info_len); p += shadow_info_len; *p++ = ')'; @@ -1577,11 +1578,20 @@ agent_shadow_key (const unsigned char *pubkey, return 0; } +int +agent_shadow_key (const unsigned char *pubkey, + const unsigned char *shadow_info, + unsigned char **result) +{ + return agent_shadow_key_type (pubkey, shadow_info, "t1-v1", result); +} + /* Parse a canonical encoded shadowed key and return a pointer to the - inner list with the shadow_info */ + inner list with the shadow_info and the shadow type */ gpg_error_t -agent_get_shadow_info (const unsigned char *shadowkey, - unsigned char const **shadow_info) +agent_get_shadow_info_type (const unsigned char *shadowkey, + unsigned char const **shadow_info, + unsigned char **shadow_type) { const unsigned char *s; size_t n; @@ -1633,17 +1643,59 @@ agent_get_shadow_info (const unsigned char *shadowkey, n = snext (&s); if (!n) return gpg_error (GPG_ERR_INV_SEXP); - if (smatch (&s, n, "t1-v1")) + if (shadow_type) { + char *buf = xtrymalloc(n+1); + memcpy(buf, s, n); + buf[n] = '\0'; + *shadow_type = buf; + } + + if (smatch (&s, n, "t1-v1") || smatch(&s, n, "tpm2-v1")) { if (*s != '(') return gpg_error (GPG_ERR_INV_SEXP); - *shadow_info = s; + if (shadow_info) + *shadow_info = s; } else return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL); return 0; } +gpg_error_t +agent_get_shadow_info(const unsigned char *shadowkey, + unsigned char const **shadow_info) +{ + return agent_get_shadow_info_type(shadowkey, shadow_info, NULL); +} + +int +agent_is_tpm2_key(gcry_sexp_t s_skey) +{ + unsigned char *buf; + unsigned char *type; + size_t len; + gpg_error_t err; + + err = make_canon_sexp(s_skey, &buf, &len); + if (err) + return 0; + + err = agent_get_shadow_info_type(buf, NULL, &type); + if (err) + return 0; + + err = strcmp(type, "tpm2-v1") == 0; + xfree(type); + return err; +} + +gpg_error_t +agent_get_shadow_type(const unsigned char *shadowkey, + unsigned char **shadow_type) +{ + return agent_get_shadow_info_type(shadowkey, NULL, shadow_type); +} /* Parse the canonical encoded SHADOW_INFO S-expression. On success the hex encoded serial number is returned as a malloced strings at -- 2.12.3 From James.Bottomley at HansenPartnership.com Mon Mar 5 20:14:34 2018 From: James.Bottomley at HansenPartnership.com (James Bottomley) Date: Mon, 05 Mar 2018 11:14:34 -0800 Subject: [RFC v2 2/5] agent: add tpm specific functions In-Reply-To: <1520277125.5312.35.camel@HansenPartnership.com> References: <1520277125.5312.35.camel@HansenPartnership.com> Message-ID: <1520277274.5312.39.camel@HansenPartnership.com> This commit adds code to handle the three specific functions needed to make the agent TPM aware, namely the ability to load a key from shadow information, the ability to sign a digest with that key, the ability to decrypt with the key and the ability to import a key to the TPM. The TPM2 is a bit of an esoteric beast, so all TPM specific callouts are confined inside this code. Additionaly, it requires the tss2 library to function, so the code is designed such that if the library isn't present then all TPM functions simply fail. This allows the code to be compiled with TPM support, but not require that the support library be present on the system. Signed-off-by: James Bottomley --- v2: use gcrypt for AES functions and tidy up some logging --- agent/Makefile.am | 1 + agent/tpm2.c | 783 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ agent/tpm2.h | 22 ++ 3 files changed, 806 insertions(+) create mode 100644 agent/tpm2.c create mode 100644 agent/tpm2.h diff --git a/agent/Makefile.am b/agent/Makefile.am index ce29462b2..bc3d43a0f 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -51,6 +51,7 @@ gpg_agent_SOURCES = \ protect.c \ trustlist.c \ divert-scd.c \ + tpm2.c \ cvt-openpgp.c cvt-openpgp.h \ call-scd.c \ learncard.c diff --git a/agent/tpm2.c b/agent/tpm2.c new file mode 100644 index 000000000..f7fb1e043 --- /dev/null +++ b/agent/tpm2.c @@ -0,0 +1,783 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/i18n.h" +#include "../common/sexp-parse.h" + +#include +#include +#include +#include +#include + +/* List of tss2 functions we use. This is macro jiggery-pokery: + * the F argument gives us the ability to run an arbitrary macro over + * the function list as for each function do macro F */ +#define _TSS2_LIST(F) \ + F(TSS_Create); \ + F(TSS_SetProperty); \ + F(TSS_Execute); \ + F(TSS_ResponseCode_toString); \ + F(TPM2B_PUBLIC_Unmarshal); \ + F(TPM2B_PRIVATE_Unmarshal); \ + F(TSS_TPM2B_PUBLIC_Marshal); \ + F(TSS_TPMT_PUBLIC_Marshal); \ + F(TSS_TPM2B_PRIVATE_Marshal); \ + F(TSS_UINT16_Marshal); \ + F(TSS_TPMT_SENSITIVE_Marshal); \ + F(TSS_SetProperty); \ + F(TSS_GetDigestSize); \ + F(TSS_Hash_Generate); \ + F(TSS_Delete); + +/* create static declarations for the function pointers */ +#define _DL_DECLARE(func) \ + static typeof(func) *p##func +_TSS2_LIST(_DL_DECLARE); + +static const char *tpm2_dir; + +/* The TPM builds a small database of active files representing key + * parameters used for authentication and session encryption. Make sure + * they're contained in a separate directory to avoid stepping on any + * other application uses of the TPM */ +static const char * +tpm2_set_unique_tssdir(void) +{ + char *prefix = getenv("XDG_RUNTIME_DIR"), *template, + *dir; + int len = 0; + + if (!prefix) + prefix = "/tmp"; + + len = snprintf(NULL, 0, "%s/tss2.XXXXXX", prefix); + if (len <= 0) + return NULL; + template = xtrymalloc(len + 1); + if (!template) + return NULL; + + len++; + len = snprintf(template, len, "%s/tss2.XXXXXX", prefix); + + dir = mkdtemp(template); + + return dir; +} + +/* now dynamically load the tss library (if it exists) and resolve the + * above symbols. This allows us simply to return 0 for tpm2_init on + * systems where there is no TPM library */ +static int +tpm2_init(void) +{ + static int inited = 0; + const char *sym; + void *dl; + + if (inited) + return 0; + + dl = dlopen(TSS2_LIB, RTLD_LAZY); + + if (!dl) + { + log_error("opening of tss2 library failed %s\n", strerror(errno)); + return GPG_ERR_CARD_NOT_PRESENT; + } + + /* load each symbol pointer and check for existence */ +# define _DL_SYM(func) \ + sym = #func; \ + p##func = dlsym(dl, #func); \ + if (p##func == NULL) \ + goto out_symfail + + _TSS2_LIST(_DL_SYM); + + tpm2_dir = tpm2_set_unique_tssdir(); + if (!tpm2_dir) + /* make this non fatal */ + log_error("Failed to set unique TPM directory\n"); + inited = 1; + return 0; + + out_symfail: + log_error("Failed to find symbol %s in tss2 library\n", sym); + return GPG_ERR_CARD_NOT_PRESENT; +} + +static void +tpm2_error(TPM_RC rc, char *prefix) +{ + const char *msg, *submsg, *num; + + pTSS_ResponseCode_toString(&msg, &submsg, &num, rc); + log_error("%s gave TPM2 Error: %s%s%s", prefix, msg, submsg, num); +} + +#define _TSS_CHECK(f) \ + rc = f; \ + if (rc != TPM_RC_SUCCESS) \ + { \ + tpm2_error(rc, #f); \ + return GPG_ERR_CARD; \ + } + +int +tpm2_start(TSS_CONTEXT **tssc) +{ + TPM_RC rc; + int ret; + + ret = tpm2_init(); + if (ret) + return ret; + + _TSS_CHECK(pTSS_Create(tssc)); + _TSS_CHECK(pTSS_SetProperty(*tssc, TPM_DATA_DIR, tpm2_dir)); + return 0; +} + +void +tpm2_end(TSS_CONTEXT *tssc) +{ + pTSS_Delete(tssc); +} + +void +tpm2_flush_handle(TSS_CONTEXT *tssc, TPM_HANDLE h) +{ + FlushContext_In in; + + if (!h) + return; + + in.flushHandle = h; + pTSS_Execute(tssc, NULL, + (COMMAND_PARAMETERS *)&in, + NULL, + TPM_CC_FlushContext, + TPM_RH_NULL, NULL, 0); +} + +static int +tpm2_get_hmac_handle(TSS_CONTEXT *tssc, TPM_HANDLE *handle, + TPM_HANDLE salt_key) +{ + TPM_RC rc; + StartAuthSession_In in; + StartAuthSession_Out out; + StartAuthSession_Extra extra; + + memset(&in, 0, sizeof(in)); + memset(&extra, 0 , sizeof(extra)); + in.bind = TPM_RH_NULL; + in.sessionType = TPM_SE_HMAC; + in.authHash = TPM_ALG_SHA256; + in.tpmKey = TPM_RH_NULL; + in.symmetric.algorithm = TPM_ALG_AES; + in.symmetric.keyBits.aes = 128; + in.symmetric.mode.aes = TPM_ALG_CFB; + if (salt_key) { + ReadPublic_In rin; + ReadPublic_Out rout; + + rin.objectHandle = salt_key; + rc = pTSS_Execute (tssc, + (RESPONSE_PARAMETERS *)&rout, + (COMMAND_PARAMETERS *)&rin, + NULL, + TPM_CC_ReadPublic, + TPM_RH_NULL, NULL, 0); + if (rc) { + tpm2_error(rc, "TPM2_ReadPublic"); + return GPG_ERR_CARD; + } + + /* don't care what rout returns, the purpose of the operation was + * to get the public key parameters into the tss so it can + * construct the salt */ + in.tpmKey = salt_key; + } + rc = pTSS_Execute(tssc, + (RESPONSE_PARAMETERS *)&out, + (COMMAND_PARAMETERS *)&in, + (EXTRA_PARAMETERS *)&extra, + TPM_CC_StartAuthSession, + TPM_RH_NULL, NULL, 0); + if (rc) { + tpm2_error(rc, "TPM2_StartAuthSession"); + return GPG_ERR_CARD; + } + + *handle = out.sessionHandle; + + return 0; +} + +static int +tpm2_exec_with_auth(ctrl_t ctrl, TSS_CONTEXT *tssc, int cmd, char *cmd_str, + void *out, void *in) +{ + TPM_HANDLE ah; + struct pin_entry_info_s *pi; + TPM_RC rc; + + pi = gcry_xmalloc_secure(sizeof(*pi) + MAX_PASSPHRASE_LEN + 10); + pi->max_length = MAX_PASSPHRASE_LEN; + pi->min_digits = 0; /* want a real passphrase */ + pi->max_digits = 16; + pi->max_tries = 3; + rc = agent_askpin(ctrl, NULL, "TPM Key Passphrase", NULL, pi, NULL, 0); + if (rc) { + gcry_free (pi); + return rc; + } + + rc = tpm2_get_hmac_handle(tssc, &ah, 0); + if (rc) + return rc; + + rc = pTSS_Execute(tssc, out, in, NULL, + cmd, + ah, pi->pin, 0, + TPM_RH_NULL, NULL, 0); + gcry_free (pi); + if (rc) { + tpm2_error(rc, cmd_str); + tpm2_flush_handle(tssc, ah); + switch (rc & 0xFF) { + case TPM_RC_BAD_AUTH: + case TPM_RC_AUTH_FAIL: + return GPG_ERR_BAD_PASSPHRASE; + default: + return GPG_ERR_CARD; + } + } + return 0; +} + +static gpg_error_t +parse_tpm2_shadow_info (const unsigned char *shadow_info, + uint32_t *parent, + const char **pub, int *pub_len, + const char **priv, int *priv_len) +{ + const unsigned char *s; + size_t n; + int i; + + s = shadow_info; + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + *parent = 0; + for (i = 0; i < n; i++) { + *parent *= 10; + *parent += atoi_1(s+i); + } + + s += n; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + + *pub_len = n; + *pub = s; + + s += n; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + + *priv_len = n; + *priv = s; + + return 0; +} + +int +tpm2_load_key(TSS_CONTEXT *tssc, const unsigned char *shadow_info, + TPM_HANDLE *key) +{ + uint32_t parent; + Load_In in; + Load_Out out; + const char *pub, *priv; + int ret, pub_len, priv_len; + TPM_RC rc; + BYTE *buf; + uint32_t size; + + ret = parse_tpm2_shadow_info (shadow_info, &parent, &pub, &pub_len, + &priv, &priv_len); + if (ret) + return ret; + + in.parentHandle = parent; + + buf = (BYTE *)priv; + size = priv_len; + pTPM2B_PRIVATE_Unmarshal(&in.inPrivate, &buf, &size); + + buf = (BYTE *)pub; + size = pub_len; + pTPM2B_PUBLIC_Unmarshal(&in.inPublic, &buf, &size, FALSE); + + rc = pTSS_Execute(tssc, + (RESPONSE_PARAMETERS *)&out, + (COMMAND_PARAMETERS *)&in, + NULL, + TPM_CC_Load, + TPM_RS_PW, NULL, 0, + TPM_RH_NULL, NULL, 0); + if (rc != TPM_RC_SUCCESS) { + tpm2_error(rc, "TPM2_Load"); + return GPG_ERR_CARD; + } + + *key = out.objectHandle; + + return 0; +} + +int +tpm2_sign(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, + const unsigned char *digest, size_t digestlen, + unsigned char **r_sig, size_t *r_siglen) +{ + Sign_In in; + Sign_Out out; + int ret; + + /* The TPM insists on knowing the digest type, so + * calculate that from the size */ + in.inScheme.scheme = TPM_ALG_RSASSA; + switch (digestlen) { + case 20: + in.inScheme.details.rsassa.hashAlg = TPM_ALG_SHA1; + break; + case 32: + in.inScheme.details.rsassa.hashAlg = TPM_ALG_SHA256; + break; + case 48: + in.inScheme.details.rsassa.hashAlg = TPM_ALG_SHA384; + break; +#ifdef TPM_ALG_SHA512 + case 64: + in.inScheme.details.rsassa.hashAlg = TPM_ALG_SHA512; + break; +#endif + default: + log_error("Unknown signature digest length, cannot deduce hash type for TPM\n"); + return GPG_ERR_NO_SIGNATURE_SCHEME; + } + in.digest.t.size = digestlen; + memcpy(in.digest.t.buffer, digest, digestlen); + in.keyHandle = key; + in.validation.tag = TPM_ST_HASHCHECK; + in.validation.hierarchy = TPM_RH_NULL; + in.validation.digest.t.size = 0; + + ret = tpm2_exec_with_auth(ctrl, tssc, TPM_CC_Sign, "TPM2_Sign", &out, &in); + if (ret) + return ret; + + *r_siglen = out.signature.signature.rsassa.sig.t.size; + *r_sig = xtrymalloc(*r_siglen); + if (!r_sig) + return GPG_ERR_ENOMEM; + + memcpy(*r_sig, out.signature.signature.rsassa.sig.t.buffer, *r_siglen); + + return 0; +} + +static int +sexp_to_tpm2_sensitive(TPMT_SENSITIVE *s, gcry_sexp_t key) +{ + gcry_mpi_t p; + gcry_sexp_t l; + int rc = -1; + size_t len; + + s->sensitiveType = TPM_ALG_RSA; + s->seedValue.b.size = 0; + + l = gcry_sexp_find_token (key, "p", 0); + if (!l) + return rc; + p = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l); + len = sizeof(s->sensitive.rsa.t.buffer); + rc = gcry_mpi_print (GCRYMPI_FMT_USG, s->sensitive.rsa.t.buffer, len, &len, p); + s->sensitive.rsa.t.size = len; + gcry_mpi_release (p); + + return rc; +} + +static int +sexp_to_tpm2_public(TPMT_PUBLIC *p, gcry_sexp_t key) +{ + gcry_mpi_t n, e; + gcry_sexp_t l; + int rc = -1, i; + size_t len; + /* longer than an int */ + unsigned char ebuf[5]; + uint32_t exp = 0; + + p->type = TPM_ALG_RSA; + p->nameAlg = TPM_ALG_SHA256; + /* note: all our keys are decrypt only. This is because + * we use the TPM2_RSA_Decrypt operation for both signing + * and decryption (see e_tpm2.c for details) */ + p->objectAttributes.val = TPMA_OBJECT_NODA | + TPMA_OBJECT_DECRYPT | + TPMA_OBJECT_SIGN | + TPMA_OBJECT_USERWITHAUTH; + p->authPolicy.t.size = 0; + p->parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL; + p->parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL; + + l = gcry_sexp_find_token (key, "n", 0); + if (!l) + return rc; + n = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l); + len = sizeof(p->unique.rsa.t.buffer); + p->parameters.rsaDetail.keyBits = gcry_mpi_get_nbits (n); + rc = gcry_mpi_print (GCRYMPI_FMT_USG, p->unique.rsa.t.buffer, len, &len, n); + p->unique.rsa.t.size = len; + gcry_mpi_release (n); + if (rc) + return rc; + rc = -1; + l = gcry_sexp_find_token (key, "e", 0); + if (!l) + return rc; + e = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l); + len = sizeof (ebuf); + rc = gcry_mpi_print (GCRYMPI_FMT_USG, ebuf, len, &len, e); + gcry_mpi_release (e); + if (rc) + return rc; + if (len > 4) + return -1; + + /* MPI are simply big endian integers, so convert to uint32 */ + for (i = 0; i < len; i++) { + exp <<= 8; + exp += ebuf[i]; + } + if (exp == 0x10001) + p->parameters.rsaDetail.exponent = 0; + else + p->parameters.rsaDetail.exponent = exp; + return 0; +} + +static int +sexp_to_tpm2(TPMT_PUBLIC *p, TPMT_SENSITIVE *s, gcry_sexp_t s_skey) +{ + gcry_sexp_t l1, l2; + int rc = -1; + + /* find the value of (private-key */ + l1 = gcry_sexp_nth (s_skey, 1); + if (!l1) + return rc; + + l2 = gcry_sexp_find_token (l1, "rsa", 0); + if (!l2) + goto out; + + rc = sexp_to_tpm2_public(p, l2); + if (!rc) + rc = sexp_to_tpm2_sensitive(s, l2); + + gcry_sexp_release(l2); + + out: + gcry_sexp_release(l1); + return rc; +} + +/* copied from TPM implementation code */ +static TPM_RC +tpm2_ObjectPublic_GetName(TPM2B_NAME *name, + TPMT_PUBLIC *tpmtPublic) +{ + TPM_RC rc = 0; + uint16_t written = 0; + TPMT_HA digest; + uint32_t sizeInBytes; + uint8_t buffer[MAX_RESPONSE_SIZE]; + + /* marshal the TPMT_PUBLIC */ + if (rc == 0) { + INT32 size = MAX_RESPONSE_SIZE; + uint8_t *buffer1 = buffer; + rc = pTSS_TPMT_PUBLIC_Marshal(tpmtPublic, &written, &buffer1, &size); + } + /* hash the public area */ + if (rc == 0) { + sizeInBytes = pTSS_GetDigestSize(tpmtPublic->nameAlg); + digest.hashAlg = tpmtPublic->nameAlg; /* Name digest algorithm */ + /* generate the TPMT_HA */ + rc = pTSS_Hash_Generate(&digest, + written, buffer, + 0, NULL); + } + if (rc == 0) { + /* copy the digest */ + memcpy(name->t.name + sizeof(TPMI_ALG_HASH), (uint8_t *)&digest.digest, sizeInBytes); + /* copy the hash algorithm */ + TPMI_ALG_HASH nameAlgNbo = htons(tpmtPublic->nameAlg); + memcpy(name->t.name, (uint8_t *)&nameAlgNbo, sizeof(TPMI_ALG_HASH)); + /* set the size */ + name->t.size = sizeInBytes + sizeof(TPMI_ALG_HASH); + } + return rc; +} + +/* + * Cut down version of Part 4 Supporting Routines 7.6.3.10 + * + * Hard coded to symmetrically encrypt with aes128 as the inner + * wrapper and no outer wrapper but with a prototype that allows + * drop in replacement with a tss equivalent + */ +TPM_RC tpm2_SensitiveToDuplicate(TPMT_SENSITIVE *s, + TPM2B_NAME *name, + TPM_ALG_ID nalg, + TPMT_SYM_DEF_OBJECT *symdef, + TPM2B_DATA *innerkey, + TPM2B_PRIVATE *p) +{ + BYTE *buf = p->t.buffer; + + p->t.size = 0; + memset(p, 0, sizeof(*p)); + + /* hard code AES CFB */ + if (symdef->algorithm == TPM_ALG_AES + && symdef->mode.aes == TPM_ALG_CFB) { + TPMT_HA hash; + const int hlen = pTSS_GetDigestSize(nalg); + TPM2B *digest = (TPM2B *)buf; + TPM2B *s2b; + int32_t size; + unsigned char null_iv[AES_128_BLOCK_SIZE_BYTES]; + UINT16 bsize, written = 0; + gcry_cipher_hd_t hd; + + /* WARNING: don't use the static null_iv trick here: + * the AES routines alter the passed in iv */ + memset(null_iv, 0, sizeof(null_iv)); + + /* reserve space for hash before the encrypted sensitive */ + bsize = sizeof(digest->size) + hlen; + buf += bsize; + p->t.size += bsize; + s2b = (TPM2B *)buf; + + /* marshal the digest size */ + buf = (BYTE *)&digest->size; + bsize = hlen; + size = 2; + pTSS_UINT16_Marshal(&bsize, &written, &buf, &size); + + /* marshal the unencrypted sensitive in place */ + size = sizeof(*s); + bsize = 0; + buf = s2b->buffer; + pTSS_TPMT_SENSITIVE_Marshal(s, &bsize, &buf, &size); + buf = (BYTE *)&s2b->size; + size = 2; + pTSS_UINT16_Marshal(&bsize, &written, &buf, &size); + + bsize = bsize + sizeof(s2b->size); + p->t.size += bsize; + + /* compute hash of unencrypted marshalled sensitive and + * write to the digest buffer */ + hash.hashAlg = nalg; + pTSS_Hash_Generate(&hash, bsize, s2b, + name->t.size, name->t.name, + 0, NULL); + memcpy(digest->buffer, &hash.digest, hlen); + gcry_cipher_open (&hd, GCRY_CIPHER_AES128, + GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_SECURE); + gcry_cipher_setiv(hd, null_iv, sizeof(null_iv)); + gcry_cipher_setkey(hd, innerkey->b.buffer, innerkey->b.size); + /* encrypt the hash and sensitive in-place */ + gcry_cipher_encrypt(hd, p->t.buffer, p->t.size, NULL, 0); + gcry_cipher_close(hd); + + } else if (symdef->algorithm == TPM_ALG_NULL) { + TPM2B *s2b = (TPM2B *)buf; + int32_t size = sizeof(*s); + UINT16 bsize = 0, written = 0; + + buf = s2b->buffer; + + /* marshal the unencrypted sensitive in place */ + pTSS_TPMT_SENSITIVE_Marshal(s, &bsize, &buf, &size); + buf = (BYTE *)&s2b->size; + size = 2; + pTSS_UINT16_Marshal(&bsize, &written, &buf, &size); + + p->b.size += bsize + sizeof(s2b->size); + } else { + log_error ("Unknown symmetric algorithm\n"); + return TPM_RC_SYMMETRIC; + } + + return TPM_RC_SUCCESS; +} + +static void +tpm2_encrypt_duplicate(Import_In *iin, TPMT_SENSITIVE *s) +{ + TPM2B_NAME name; + TPMT_PUBLIC *p = &iin->objectPublic.publicArea; + const int aes_key_bits = 128; + const int aes_key_bytes = aes_key_bits/8; + + tpm2_ObjectPublic_GetName(&name, p); + gcry_randomize(iin->encryptionKey.t.buffer, + aes_key_bytes, GCRY_STRONG_RANDOM); + iin->encryptionKey.t.size = aes_key_bytes; + + /* set random iin.symSeed */ + iin->inSymSeed.t.size = 0; + iin->symmetricAlg.algorithm = TPM_ALG_AES; + iin->symmetricAlg.keyBits.aes = aes_key_bits; + iin->symmetricAlg.mode.aes = TPM_ALG_CFB; + + tpm2_SensitiveToDuplicate(s, &name, p->nameAlg, &iin->symmetricAlg, + &iin->encryptionKey, &iin->duplicate); +} + +int +tpm2_import_key(ctrl_t ctrl, TSS_CONTEXT *tssc, char *pub, int *pub_len, + char *priv, int *priv_len, gcry_sexp_t s_skey) +{ + Import_In iin; + Import_Out iout; + TPMT_SENSITIVE s; + TPM_HANDLE ah; + TPM_RC rc; + + uint32_t size; + uint16_t len; + BYTE *buffer; + int ret; + char *passphrase; + + iin.parentHandle = TPM2_PARENT; + ret = sexp_to_tpm2(&iin.objectPublic.publicArea, &s, s_skey); + if (ret) { + log_error("Failed to parse Key s-expression: key corrupt?\n"); + return ret; + } + + /* add an authorization password to the key which the TPM will check */ + + ret = agent_ask_new_passphrase (ctrl, _("Please enter the TPM Authorization passphrase for the key."), &passphrase); + if (ret) + return ret; + s.authValue.b.size = strlen(passphrase); + memcpy(s.authValue.b.buffer, passphrase, s.authValue.b.size); + + /* We're responsible for securing the data in transmission to the + * TPM here. The TPM provides parameter encryption via a session, + * but only for the first parameter. For TPM2_Import, the first + * parameter is a symmetric key used to encrypt the sensitive data, + * so we must populate this key with random value and encrypt the + * sensitive data with it */ + tpm2_encrypt_duplicate(&iin, &s); + + /* use salted parameter encryption to hide the key. First we read + * the public parameters of the parent key and use them to agree an + * encryption for the first parameter */ + rc = tpm2_get_hmac_handle(tssc, &ah, TPM2_PARENT); + if (rc) + return GPG_ERR_CARD; + + rc = pTSS_Execute(tssc, + (RESPONSE_PARAMETERS *)&iout, + (COMMAND_PARAMETERS *)&iin, + NULL, + TPM_CC_Import, + ah, NULL, TPMA_SESSION_DECRYPT, + TPM_RH_NULL, NULL, 0); + if (rc) { + tpm2_error(rc, "TPM2_Import"); + /* failure means auth handle is not flushed */ + tpm2_flush_handle(tssc, ah); + return GPG_ERR_CARD; + } + + size = sizeof(TPM2B_PUBLIC); + buffer = pub; + len = 0; + pTSS_TPM2B_PUBLIC_Marshal(&iin.objectPublic, + &len, &buffer, &size); + *pub_len = len; + + size = sizeof(TPM2B_PRIVATE); + buffer = priv; + len = 0; + pTSS_TPM2B_PRIVATE_Marshal(&iout.outPrivate, + &len, &buffer, &size); + *priv_len = len; + + return 0; +} + +int +tpm2_decrypt(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, + const char *ciphertext, int ciphertext_len, + char **decrypt, size_t *decrypt_len) +{ + RSA_Decrypt_In in; + RSA_Decrypt_Out out; + int ret; + + in.keyHandle = key; + in.inScheme.scheme = TPM_ALG_RSAES; + in.cipherText.t.size = ciphertext_len; + memcpy (in.cipherText.t.buffer, ciphertext, ciphertext_len); + in.label.t.size = 0; + + ret = tpm2_exec_with_auth(ctrl, tssc, TPM_CC_RSA_Decrypt, "TPM2_RSA_Decrypt", + &out, &in); + if (ret) + return ret; + + *decrypt_len = out.message.t.size; + *decrypt = xtrymalloc(out.message.t.size); + memcpy (*decrypt, out.message.t.buffer, out.message.t.size); + + return 0; +} diff --git a/agent/tpm2.h b/agent/tpm2.h new file mode 100644 index 000000000..2e168032f --- /dev/null +++ b/agent/tpm2.h @@ -0,0 +1,22 @@ +#ifndef _TPM2_H +#define _TPM2_H + +#include + +#define TSS2_LIB "libtss.so.0" +#define TPM2_PARENT 0x81000001 + +int tpm2_start(TSS_CONTEXT **tssc); +void tpm2_end(TSS_CONTEXT *tssc); +void tpm2_flush_handle(TSS_CONTEXT *tssc, TPM_HANDLE h); +int tpm2_load_key(TSS_CONTEXT *tssc, const unsigned char *shadow_info, + TPM_HANDLE *key); +int tpm2_sign(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, + const unsigned char *digest, size_t digestlen, + unsigned char **r_sig, size_t *r_siglen); +int tpm2_import_key(ctrl_t ctrl, TSS_CONTEXT *tssc, char *pub, int *pub_len, + char *priv, int *priv_len, gcry_sexp_t s_skey); +int tpm2_decrypt(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, + const char *ciphertext, int ciphertext_len, + char **decrypt, size_t *decrypt_len); +#endif -- 2.12.3 From James.Bottomley at HansenPartnership.com Mon Mar 5 20:15:29 2018 From: James.Bottomley at HansenPartnership.com (James Bottomley) Date: Mon, 05 Mar 2018 11:15:29 -0800 Subject: [RFC v2 3/5] agent: plumb in TPM handling In-Reply-To: <1520277125.5312.35.camel@HansenPartnership.com> References: <1520277125.5312.35.camel@HansenPartnership.com> Message-ID: <1520277329.5312.40.camel@HansenPartnership.com> This code installs diversions for pksign and pkdecrypt to do the operations via the TPM if a TPM shadowed key is present. It also adds an extra assuan command KEYTOTPM which moves an existing private key to a TPM shadowed key. The way TPM shadowing works is that the public and private key parts are fed in to the TPM command TPM2_Import. The output of this command is a TPM specific public and private key data where the private key data is symmetrically encrypted using a TPM internal key. If this physical TPM is ever lost or cleared, that TPM internal key will likewise be lost and nothing will ever be able to read the private key. Once the import is done, the shadow information for the key is updated to be a three part list consisting of the parent key (hard coded to 81000001 which is the Microsoft preferred RSA incarnation of the storage seed) and the public and private TPM data blobs. Now when a TPM shadowed key is used, the data blobs must be loaded into the TPM with TPM2_Load before any operation can be performed. Signed-off-by: James Bottomley --- v2: Add missing -ldl (needed for debian build) --- agent/Makefile.am | 3 +- agent/agent.h | 13 ++++ agent/command.c | 57 ++++++++++++++++ agent/divert-tpm2.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++ agent/pkdecrypt.c | 8 ++- agent/pksign.c | 14 ++-- 6 files changed, 275 insertions(+), 7 deletions(-) create mode 100644 agent/divert-tpm2.c diff --git a/agent/Makefile.am b/agent/Makefile.am index bc3d43a0f..1b8ac508f 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -51,6 +51,7 @@ gpg_agent_SOURCES = \ protect.c \ trustlist.c \ divert-scd.c \ + divert-tpm2.c \ tpm2.c \ cvt-openpgp.c cvt-openpgp.h \ call-scd.c \ @@ -71,7 +72,7 @@ gpg_agent_LDADD = $(commonpth_libs) \ $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \ $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) \ $(resource_objs) -gpg_agent_LDFLAGS = $(extra_bin_ldflags) +gpg_agent_LDFLAGS = $(extra_bin_ldflags) $(DL_LIBS) gpg_agent_DEPENDENCIES = $(resource_objs) gpg_protect_tool_SOURCES = \ diff --git a/agent/agent.h b/agent/agent.h index 2df2fde53..0ff487a59 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -417,6 +417,7 @@ gpg_error_t agent_public_key_from_file (ctrl_t ctrl, gcry_sexp_t *result); int agent_is_dsa_key (gcry_sexp_t s_key); int agent_is_eddsa_key (gcry_sexp_t s_key); +int agent_is_tpm2_key(gcry_sexp_t s_key); int agent_key_available (const unsigned char *grip); gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, int *r_keytype, @@ -532,6 +533,18 @@ gpg_error_t agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag); void agent_reload_trustlist (void); +/*-- divert-tpm2.c --*/ +int divert_tpm2_pksign (ctrl_t ctrl, const char *desc_text, + const unsigned char *digest, size_t digestlen, int algo, + const unsigned char *shadow_info, unsigned char **r_sig, + size_t *r_siglen); +int divert_tpm2_pkdecrypt (ctrl_t ctrl, const char *desc_text, + const unsigned char *cipher, + const unsigned char *shadow_info, + char **r_buf, size_t *r_len, int *r_padding); +int divert_tpm2_writekey (ctrl_t ctrl, const unsigned char *grip, + gcry_sexp_t s_skey); + /*-- divert-scd.c --*/ int divert_pksign (ctrl_t ctrl, const char *desc_text, diff --git a/agent/command.c b/agent/command.c index 32c12d93f..c439aa5f7 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1192,6 +1192,11 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, if (err) goto leave; } + else if (strcmp (shadow_info_type, "tpm2-v1") == 0) + { + serialno = xstrdup("TPM-Protected"); + idstr = NULL; + } else { log_error ("Unrecognised shadow key type %s\n", shadow_info_type); @@ -2578,6 +2583,57 @@ cmd_keytocard (assuan_context_t ctx, char *line) +static const char hlp_keytotpm[] = + "KEYTOTPM \n" + "\n"; +static gpg_error_t +cmd_keytotpm (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err = 0; + unsigned char grip[20]; + gcry_sexp_t s_skey; + unsigned char *shadow_info = NULL; + + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + + err = parse_keygrip (ctx, line, grip); + if (err) + goto leave; + + if (agent_key_available (grip)) + { + err =gpg_error (GPG_ERR_NO_SECKEY); + goto leave; + } + + err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip, + &shadow_info, CACHE_MODE_IGNORE, NULL, + &s_skey, NULL); + if (err) + { + xfree (shadow_info); + goto leave; + } + if (shadow_info) + { + /* Key is on a TPM or smartcard already. */ + xfree (shadow_info); + gcry_sexp_release (s_skey); + err = gpg_error (GPG_ERR_UNUSABLE_SECKEY); + goto leave; + } + + err = divert_tpm2_writekey (ctrl, grip, s_skey); + gcry_sexp_release (s_skey); + + leave: + return leave_cmd (ctx, err); +} + + + static const char hlp_getval[] = "GETVAL \n" "\n" @@ -3243,6 +3299,7 @@ register_commands (assuan_context_t ctx) { "RELOADAGENT", cmd_reloadagent,hlp_reloadagent }, { "GETINFO", cmd_getinfo, hlp_getinfo }, { "KEYTOCARD", cmd_keytocard, hlp_keytocard }, + { "KEYTOTPM", cmd_keytotpm, hlp_keytotpm }, { NULL } }; int i, rc; diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c new file mode 100644 index 000000000..dc3110d0b --- /dev/null +++ b/agent/divert-tpm2.c @@ -0,0 +1,187 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "agent.h" +#include "../common/i18n.h" +#include "../common/sexp-parse.h" + +#include "tpm2.h" + +int +divert_tpm2_pksign (ctrl_t ctrl, const char *desc_text, + const unsigned char *digest, size_t digestlen, int algo, + const unsigned char *shadow_info, unsigned char **r_sig, + size_t *r_siglen) +{ + TSS_CONTEXT *tssc; + TPM_HANDLE key; + int ret; + + ret = tpm2_start(&tssc); + if (ret) + return ret; + ret = tpm2_load_key(tssc, shadow_info, &key); + if (ret) + goto out; + ret = tpm2_sign(ctrl, tssc, key, digest, digestlen, r_sig, r_siglen); + + tpm2_flush_handle(tssc, key); + + out: + tpm2_end(tssc); + return ret; +} + +static unsigned char * +make_tpm2_shadow_info (uint32_t parent, const char *pub, int pub_len, + const char *priv, int priv_len) +{ + gcry_sexp_t s_exp; + size_t len; + char *info; + + gcry_sexp_build(&s_exp, NULL, "(%u%b%b)", parent, pub_len, pub, priv_len, priv); + + len = gcry_sexp_sprint(s_exp, GCRYSEXP_FMT_CANON, NULL, 0); + info = xtrymalloc(len); + gcry_sexp_sprint(s_exp, GCRYSEXP_FMT_CANON, info, len); + + gcry_sexp_release(s_exp); + + return (unsigned char *)info; +} + +static gpg_error_t +agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, + int parent, char *pub, int pub_len, + char *priv, int priv_len) +{ + gpg_error_t err; + unsigned char *shadow_info; + unsigned char *shdkey; + unsigned char *pkbuf; + size_t len; + gcry_sexp_t s_pkey; + + err = agent_public_key_from_file (ctrl, grip, &s_pkey); + len = gcry_sexp_sprint(s_pkey, GCRYSEXP_FMT_CANON, NULL, 0); + pkbuf = xtrymalloc (len); + gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, pkbuf, len); + gcry_sexp_release (s_pkey); + + shadow_info = make_tpm2_shadow_info (parent, pub, pub_len, priv, priv_len); + if (!shadow_info) { + xfree (pkbuf); + return gpg_error_from_syserror (); + } + + err = agent_shadow_key_type (pkbuf, shadow_info, "tpm2-v1", &shdkey); + xfree (shadow_info); + xfree (pkbuf); + if (err) + { + log_error ("shadowing the key failed: %s\n", gpg_strerror (err)); + return err; + } + + len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); + err = agent_write_private_key (grip, shdkey, len, 1 /*force*/); + xfree (shdkey); + if (err) + log_error ("error writing key: %s\n", gpg_strerror (err)); + + return err; +} + +int +divert_tpm2_writekey (ctrl_t ctrl, const unsigned char *grip, + gcry_sexp_t s_skey) +{ + TSS_CONTEXT *tssc; + int ret, pub_len, priv_len; + /* priv is always shielded so no special handling required */ + char pub[sizeof(TPM2B_PUBLIC)], priv[sizeof(TPM2B_PRIVATE)]; + + ret = tpm2_start(&tssc); + if (ret) + return ret; + ret = tpm2_import_key (ctrl, tssc, pub, &pub_len, priv, &priv_len, s_skey); + if (ret) + goto out; + ret = agent_write_tpm2_shadow_key (ctrl, grip, TPM2_PARENT, pub, pub_len, + priv, priv_len); + out: + tpm2_end(tssc); + return ret; +} + +int +divert_tpm2_pkdecrypt (ctrl_t ctrl, const char *desc_text, + const unsigned char *cipher, + const unsigned char *shadow_info, + char **r_buf, size_t *r_len, int *r_padding) +{ + TSS_CONTEXT *tssc; + TPM_HANDLE key; + int ret; + const unsigned char *s; + size_t n; + + *r_padding = 0; + + (void)desc_text; + + s = cipher; + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "enc-val")) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if (*s != '(') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (smatch (&s, n, "rsa")) + { + if (*s != '(') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "a")) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + n = snext (&s); + } + else + return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + + /* know we have RSA to decrypt at s,n */ + + ret = tpm2_start(&tssc); + if (ret) + return ret; + ret = tpm2_load_key(tssc, shadow_info, &key); + if (ret) + goto out; + ret = tpm2_decrypt(ctrl, tssc, key, s, n, r_buf, r_len); + + tpm2_flush_handle(tssc, key); + + out: + tpm2_end(tssc); + return ret; + +} diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 06a8e0b6f..6f766ca63 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -86,8 +86,12 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, goto leave; } - rc = divert_pkdecrypt (ctrl, desc_text, ciphertext, shadow_info, - &buf, &len, r_padding); + if (agent_is_tpm2_key (s_skey)) + rc = divert_tpm2_pkdecrypt (ctrl, desc_text, ciphertext, shadow_info, + &buf, &len, r_padding); + else + rc = divert_pkdecrypt (ctrl, desc_text, ciphertext, shadow_info, + &buf, &len, r_padding); if (rc) { log_error ("smartcard decryption failed: %s\n", gpg_strerror (rc)); diff --git a/agent/pksign.c b/agent/pksign.c index f54af0817..dae2638f4 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -353,10 +353,16 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, if (desc_text) agent_modify_description (desc_text, NULL, s_skey, &desc2); - err = divert_pksign (ctrl, desc2? desc2 : desc_text, - data, datalen, - ctrl->digest.algo, - shadow_info, &buf, &len); + if (agent_is_tpm2_key (s_skey)) + err = divert_tpm2_pksign (ctrl, desc2? desc2 : desc_text, + data, datalen, + ctrl->digest.algo, + shadow_info, &buf, &len); + else + err = divert_pksign (ctrl, desc2? desc2 : desc_text, + data, datalen, + ctrl->digest.algo, + shadow_info, &buf, &len); xfree (desc2); } if (err) -- 2.12.3 From James.Bottomley at HansenPartnership.com Mon Mar 5 20:16:40 2018 From: James.Bottomley at HansenPartnership.com (James Bottomley) Date: Mon, 05 Mar 2018 11:16:40 -0800 Subject: [RFC v2 4/5] g10: add ability to transfer a private key to the tpm In-Reply-To: <1520277125.5312.35.camel@HansenPartnership.com> References: <1520277125.5312.35.camel@HansenPartnership.com> Message-ID: <1520277400.5312.41.camel@HansenPartnership.com> Exactly like the gpg --edit-key command keytosc, keytotpm has been added which immedately converts the private key file to TPM shadowed form. Once this is done, the key cannot be recovered and may only be used via the TPM of the computer system on which the conversion was done. If that system is ever lost, or its TPM cleared, the shadowed key becomes unusable. Signed-off-by: James Bottomley --- g10/call-agent.c | 22 ++++++++++++++++++++++ g10/call-agent.h | 3 +++ g10/keyedit.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index 61d06c663..356ec8539 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -759,6 +759,28 @@ agent_scd_apdu (const char *hexapdu, unsigned int *r_sw) return err; } +int +agent_keytotpm (ctrl_t ctrl, const char *hexgrip) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + struct default_inq_parm_s parm; + + snprintf(line, DIM(line), "KEYTOTPM %s\n", hexgrip); + + rc = start_agent (ctrl, 0); + if (rc) + return rc; + parm.ctx = agent_ctx; + parm.ctrl = ctrl; + + rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm, + NULL, NULL); + if (rc) + log_log (GPGRT_LOGLVL_ERROR, _("error from TPM: %s\n"), gpg_strerror (rc)); + return rc; +} + int agent_keytocard (const char *hexgrip, int keyno, int force, diff --git a/g10/call-agent.h b/g10/call-agent.h index f45b64d90..85c939fa0 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -88,6 +88,9 @@ gpg_error_t agent_scd_apdu (const char *hexapdu, unsigned int *r_sw); /* Update INFO with the attribute NAME. */ int agent_scd_getattr (const char *name, struct agent_card_info_s *info); +/* send the KEYTOTPM command */ +int agent_keytotpm (ctrl_t ctrl, const char *hexgrip); + /* Send the KEYTOCARD command. */ int agent_keytocard (const char *hexgrip, int keyno, int force, const char *serialno, const char *timestamp); diff --git a/g10/keyedit.c b/g10/keyedit.c index 2c33a29dd..038c31821 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1241,7 +1241,7 @@ enum cmdids #endif /*!NO_TRUST_MODELS*/ cmdSHOWPREF, cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, - cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, + cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdKEYTOTPM, cmdBKUPTOCARD, cmdCLEAN, cmdMINIMIZE, cmdGRIP, cmdNOP }; @@ -1292,6 +1292,8 @@ static struct N_("add a key to a smartcard")}, { "keytocard", cmdKEYTOCARD, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK, N_("move a key to a smartcard")}, + { "keytotpm", cmdKEYTOTPM, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK, + N_("convert a key to TPM form using the local TPM")}, { "bkuptocard", cmdBKUPTOCARD, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK, N_("move a backup key to a smartcard")}, #endif /*ENABLE_CARD_SUPPORT */ @@ -1789,6 +1791,47 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, } break; + case cmdKEYTOTPM: + /* FIXME need to store the key and not commit until later */ + { + KBNODE node = NULL; + switch (count_selected_keys (keyblock)) + { + case 0: + if (cpr_get_answer_is_yes + ("keyedit.keytocard.use_primary", + /* TRANSLATORS: Please take care: This is about + moving the key and not about removing it. */ + _("Really move the primary key? (y/N) "))) + node = keyblock; + break; + case 1: + for (node = keyblock; node; node = node->next) + { + if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY + && node->flag & NODFLG_SELKEY) + break; + } + break; + default: + tty_printf (_("You must select exactly one key.\n")); + break; + } + if (node) + { + PKT_public_key *xxpk = node->pkt->pkt.public_key; + char *hexgrip; + + hexkeygrip_from_pk (xxpk, &hexgrip); + if (!agent_keytotpm (ctrl, hexgrip)) + { + redisplay = 1; + } + xfree (hexgrip); + } + } + break; + case cmdKEYTOCARD: { KBNODE node = NULL; -- 2.12.3 From James.Bottomley at HansenPartnership.com Mon Mar 5 20:18:15 2018 From: James.Bottomley at HansenPartnership.com (James Bottomley) Date: Mon, 05 Mar 2018 11:18:15 -0800 Subject: [RFC v2 5/5] tpm2: add handling for elliptic curve keys In-Reply-To: <1520277125.5312.35.camel@HansenPartnership.com> References: <1520277125.5312.35.camel@HansenPartnership.com> Message-ID: <1520277495.5312.44.camel@HansenPartnership.com> This adds handling for the way gnupg does elliptic keys, namely ECDSA for signatures and using ECDH with an ephemeral key to generate an encrypted message. The main problem is that the TPM2 usually has a very small list of built in curves and it won't handle any others. Thanks to TCG mandates, all TPM2 systems in the USA should come with NIST P-256, but do not come with the Bernstien curve 25519, so the only way to use the TPM2 to protect an elliptic curve key is first to create it with a compatible algorithm. Signed-off-by: James Bottomley --- agent/divert-tpm2.c | 41 +++++++-- agent/tpm2.c | 251 ++++++++++++++++++++++++++++++++++++++++++++++++---- agent/tpm2.h | 13 ++- 3 files changed, 280 insertions(+), 25 deletions(-) diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c index dc3110d0b..deb655a47 100644 --- a/agent/divert-tpm2.c +++ b/agent/divert-tpm2.c @@ -22,15 +22,16 @@ divert_tpm2_pksign (ctrl_t ctrl, const char *desc_text, { TSS_CONTEXT *tssc; TPM_HANDLE key; + TPMI_ALG_PUBLIC type; int ret; ret = tpm2_start(&tssc); if (ret) return ret; - ret = tpm2_load_key(tssc, shadow_info, &key); + ret = tpm2_load_key(tssc, shadow_info, &key, &type); if (ret) goto out; - ret = tpm2_sign(ctrl, tssc, key, digest, digestlen, r_sig, r_siglen); + ret = tpm2_sign(ctrl, tssc, key, type, digest, digestlen, r_sig, r_siglen); tpm2_flush_handle(tssc, key); @@ -130,11 +131,12 @@ divert_tpm2_pkdecrypt (ctrl_t ctrl, const char *desc_text, { TSS_CONTEXT *tssc; TPM_HANDLE key; + TPMI_ALG_PUBLIC type; int ret; const unsigned char *s; size_t n; - *r_padding = 0; + *r_padding = -1; (void)desc_text; @@ -155,6 +157,7 @@ divert_tpm2_pkdecrypt (ctrl_t ctrl, const char *desc_text, return gpg_error (GPG_ERR_INV_SEXP); if (smatch (&s, n, "rsa")) { + *r_padding = 0; if (*s != '(') return gpg_error (GPG_ERR_UNKNOWN_SEXP); s++; @@ -165,6 +168,30 @@ divert_tpm2_pkdecrypt (ctrl_t ctrl, const char *desc_text, return gpg_error (GPG_ERR_UNKNOWN_SEXP); n = snext (&s); } + else if (smatch (&s, n, "ecdh")) + { + if (*s != '(') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (smatch (&s, n, "s")) + { + n = snext (&s); + s += n; + if (*s++ != ')') + return gpg_error (GPG_ERR_INV_SEXP); + if (*s++ != '(') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + } + if (!smatch (&s, n, "e")) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + n = snext (&s); + } else return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); @@ -173,10 +200,14 @@ divert_tpm2_pkdecrypt (ctrl_t ctrl, const char *desc_text, ret = tpm2_start(&tssc); if (ret) return ret; - ret = tpm2_load_key(tssc, shadow_info, &key); + ret = tpm2_load_key(tssc, shadow_info, &key, &type); if (ret) goto out; - ret = tpm2_decrypt(ctrl, tssc, key, s, n, r_buf, r_len); + + if (type == TPM_ALG_RSA) + ret = tpm2_rsa_decrypt(ctrl, tssc, key, s, n, r_buf, r_len); + else if (type == TPM_ALG_ECC) + ret = tpm2_ecc_decrypt(ctrl, tssc, key, s, n, r_buf, r_len); tpm2_flush_handle(tssc, key); diff --git a/agent/tpm2.c b/agent/tpm2.c index f7fb1e043..043c91312 100644 --- a/agent/tpm2.c +++ b/agent/tpm2.c @@ -314,7 +314,7 @@ parse_tpm2_shadow_info (const unsigned char *shadow_info, int tpm2_load_key(TSS_CONTEXT *tssc, const unsigned char *shadow_info, - TPM_HANDLE *key) + TPM_HANDLE *key, TPMI_ALG_PUBLIC *type) { uint32_t parent; Load_In in; @@ -340,6 +340,8 @@ tpm2_load_key(TSS_CONTEXT *tssc, const unsigned char *shadow_info, size = pub_len; pTPM2B_PUBLIC_Unmarshal(&in.inPublic, &buf, &size, FALSE); + *type = in.inPublic.publicArea.type; + rc = pTSS_Execute(tssc, (RESPONSE_PARAMETERS *)&out, (COMMAND_PARAMETERS *)&in, @@ -359,7 +361,8 @@ tpm2_load_key(TSS_CONTEXT *tssc, const unsigned char *shadow_info, int tpm2_sign(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, - const unsigned char *digest, size_t digestlen, + TPMI_ALG_PUBLIC type, + const unsigned char *digest, size_t digestlen, unsigned char **r_sig, size_t *r_siglen) { Sign_In in; @@ -368,7 +371,6 @@ tpm2_sign(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, /* The TPM insists on knowing the digest type, so * calculate that from the size */ - in.inScheme.scheme = TPM_ALG_RSASSA; switch (digestlen) { case 20: in.inScheme.details.rsassa.hashAlg = TPM_ALG_SHA1; @@ -395,22 +397,181 @@ tpm2_sign(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, in.validation.hierarchy = TPM_RH_NULL; in.validation.digest.t.size = 0; + if (type == TPM_ALG_RSA) + in.inScheme.scheme = TPM_ALG_RSASSA; + else if (type == TPM_ALG_ECC) + in.inScheme.scheme = TPM_ALG_ECDSA; + else + return GPG_ERR_PUBKEY_ALGO; + + ret = tpm2_exec_with_auth(ctrl, tssc, TPM_CC_Sign, "TPM2_Sign", &out, &in); if (ret) return ret; - *r_siglen = out.signature.signature.rsassa.sig.t.size; + if (type == TPM_ALG_RSA) + *r_siglen = out.signature.signature.rsassa.sig.t.size; + else if (type == TPM_ALG_ECC) + *r_siglen = out.signature.signature.ecdsa.signatureR.t.size + + out.signature.signature.ecdsa.signatureS.t.size; + *r_sig = xtrymalloc(*r_siglen); if (!r_sig) return GPG_ERR_ENOMEM; - memcpy(*r_sig, out.signature.signature.rsassa.sig.t.buffer, *r_siglen); + if (type == TPM_ALG_RSA) + { + memcpy(*r_sig, out.signature.signature.rsassa.sig.t.buffer, *r_siglen); + } + else if (type == TPM_ALG_ECC) + { + memcpy(*r_sig, out.signature.signature.ecdsa.signatureR.t.buffer, + out.signature.signature.ecdsa.signatureR.t.size); + memcpy(*r_sig + out.signature.signature.ecdsa.signatureR.t.size, + out.signature.signature.ecdsa.signatureS.t.buffer, + out.signature.signature.ecdsa.signatureS.t.size); + } return 0; } static int -sexp_to_tpm2_sensitive(TPMT_SENSITIVE *s, gcry_sexp_t key) +sexp_to_tpm2_sensitive_ecc(TPMT_SENSITIVE *s, gcry_sexp_t key) +{ + gcry_mpi_t d; + gcry_sexp_t l; + int rc = -1; + size_t len; + + s->sensitiveType = TPM_ALG_ECC; + s->seedValue.b.size = 0; + + l = gcry_sexp_find_token (key, "d", 0); + if (!l) + return rc; + d = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l); + len = sizeof(s->sensitive.ecc.t.buffer); + rc = gcry_mpi_print (GCRYMPI_FMT_USG, s->sensitive.ecc.t.buffer, len, &len, d); + s->sensitive.ecc.t.size = len; + gcry_mpi_release (d); + + return rc; +} + +/* try to match the libgcrypt curve names to known TPM parameters. + * + * As of 2018 the TCG defined curves are only NIST + * (192,224,256,384,521) Barreto-Naehring (256,638) and the Chinese + * SM2 (256), which means only the NIST ones overlap with libgcrypt */ +static struct { + const char *name; + TPMI_ECC_CURVE c; +} tpm2_curves[] = { + { "NIST P-192", TPM_ECC_NIST_P192 }, + { "prime192v1", TPM_ECC_NIST_P192 }, + { "secp192r1", TPM_ECC_NIST_P192 }, + { "nistp192", TPM_ECC_NIST_P192 }, + { "NIST P-224", TPM_ECC_NIST_P224 }, + { "secp224r1", TPM_ECC_NIST_P224 }, + { "nistp224", TPM_ECC_NIST_P224 }, + { "NIST P-256", TPM_ECC_NIST_P256 }, + { "prime256v1", TPM_ECC_NIST_P256 }, + { "secp256r1", TPM_ECC_NIST_P256 }, + { "nistp256", TPM_ECC_NIST_P256 }, + { "NIST P-384", TPM_ECC_NIST_P384 }, + { "secp384r1", TPM_ECC_NIST_P384 }, + { "nistp384", TPM_ECC_NIST_P384 }, + { "NIST P-521", TPM_ECC_NIST_P521 }, + { "secp521r1", TPM_ECC_NIST_P521 }, + { "nistp521", TPM_ECC_NIST_P521 }, +}; + +static int +tpm2_ecc_curve (const char *curve_name, TPMI_ECC_CURVE *c) +{ + int i; + + for (i = 0; i < DIM (tpm2_curves); i++) + if (strcmp (tpm2_curves[i].name, curve_name) == 0) + break; + if (i == DIM (tpm2_curves)) { + log_error ("curve %s does not match any available TPM curves\n", curve_name); + return GPG_ERR_UNKNOWN_CURVE; + } + + *c = tpm2_curves[i].c; + + return 0; +} + +static int +sexp_to_tpm2_public_ecc(TPMT_PUBLIC *p, gcry_sexp_t key) +{ + const char *q; + gcry_sexp_t l; + int rc = GPG_ERR_BAD_PUBKEY; + size_t len; + TPMI_ECC_CURVE curve; + char *curve_name; + + l = gcry_sexp_find_token (key, "curve", 0); + if (!l) + return rc; + curve_name = gcry_sexp_nth_string (l, 1); + if (!curve_name) + goto out; + rc = tpm2_ecc_curve (curve_name, &curve); + gcry_free (curve_name); + if (rc) + goto out; + gcry_sexp_release(l); + + l = gcry_sexp_find_token (key, "q", 0); + if (!l) + return rc; + q = gcry_sexp_nth_data (l, 1, &len); + /* This is a point representation, the first byte tells you what + * type. The only format we understand is uncompressed (0x04) + * which has layout 0x04 | x | y */ + if (q[0] != 0x04) + { + log_error ("Point format for q is not uncompressed\n"); + goto out; + } + q++; + len--; + /* now should have to equal sized big endian point numbers */ + if ((len & 0x01) == 1) + { + log_error ("Point format for q has incorrect length\n"); + goto out; + } + + len >>= 1; + + p->type = TPM_ALG_ECC; + p->nameAlg = TPM_ALG_SHA256; + p->objectAttributes.val = TPMA_OBJECT_NODA | + TPMA_OBJECT_SIGN | + TPMA_OBJECT_DECRYPT | + TPMA_OBJECT_USERWITHAUTH; + p->authPolicy.t.size = 0; + p->parameters.eccDetail.symmetric.algorithm = TPM_ALG_NULL; + p->parameters.eccDetail.scheme.scheme = TPM_ALG_NULL; + p->parameters.eccDetail.curveID = curve; + p->parameters.eccDetail.kdf.scheme = TPM_ALG_NULL; + memcpy(p->unique.ecc.x.t.buffer, q, len); + p->unique.ecc.x.t.size = len; + memcpy(p->unique.ecc.y.t.buffer, q + len, len); + p->unique.ecc.y.t.size = len; + out: + gcry_sexp_release (l); + return rc; +} + +static int +sexp_to_tpm2_sensitive_rsa(TPMT_SENSITIVE *s, gcry_sexp_t key) { gcry_mpi_t p; gcry_sexp_t l; @@ -434,7 +595,7 @@ sexp_to_tpm2_sensitive(TPMT_SENSITIVE *s, gcry_sexp_t key) } static int -sexp_to_tpm2_public(TPMT_PUBLIC *p, gcry_sexp_t key) +sexp_to_tpm2_public_rsa(TPMT_PUBLIC *p, gcry_sexp_t key) { gcry_mpi_t n, e; gcry_sexp_t l; @@ -507,12 +668,18 @@ sexp_to_tpm2(TPMT_PUBLIC *p, TPMT_SENSITIVE *s, gcry_sexp_t s_skey) return rc; l2 = gcry_sexp_find_token (l1, "rsa", 0); - if (!l2) - goto out; - - rc = sexp_to_tpm2_public(p, l2); - if (!rc) - rc = sexp_to_tpm2_sensitive(s, l2); + if (l2) { + rc = sexp_to_tpm2_public_rsa (p, l2); + if (!rc) + rc = sexp_to_tpm2_sensitive_rsa (s, l2); + } else { + l2 = gcry_sexp_find_token (l1, "ecc", 0); + if (!l2) + goto out; + rc = sexp_to_tpm2_public_ecc (p, l2); + if (!rc) + rc = sexp_to_tpm2_sensitive_ecc (s, l2); + } gcry_sexp_release(l2); @@ -756,9 +923,61 @@ tpm2_import_key(ctrl_t ctrl, TSS_CONTEXT *tssc, char *pub, int *pub_len, } int -tpm2_decrypt(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, - const char *ciphertext, int ciphertext_len, - char **decrypt, size_t *decrypt_len) +tpm2_ecc_decrypt(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, + const char *ciphertext, int ciphertext_len, + char **decrypt, size_t *decrypt_len) +{ + ECDH_ZGen_In in; + ECDH_ZGen_Out out; + size_t len; + int ret; + + /* This isn't really a decryption per se. The ciphertext actually + * contains an EC Point which we must multiply by the private key number. + * + * The reason is to generate a diffe helman agreement on a shared + * point. This shared point is then used to generate the per + * session encryption key. + */ + if (ciphertext[0] != 0x04) + { + log_error ("Decryption Shared Point format is not uncompressed\n"); + return GPG_ERR_ENCODING_PROBLEM; + } + if ((ciphertext_len & 0x01) != 1) + { + log_error ("Decryption Shared Point has incorrect length\n"); + return GPG_ERR_ENCODING_PROBLEM; + } + len = ciphertext_len >> 1; + + in.keyHandle = key; + memcpy(in.inPoint.point.x.t.buffer, ciphertext + 1, len); + in.inPoint.point.x.t.size = len; + memcpy(in.inPoint.point.y.t.buffer, ciphertext + 1 + len, len); + in.inPoint.point.y.t.size = len; + + ret = tpm2_exec_with_auth(ctrl, tssc, TPM_CC_ECDH_ZGen, "TPM2_ECDH_ZGen", + &out, &in); + if (ret) + return ret; + + *decrypt_len = out.outPoint.point.x.t.size + out.outPoint.point.y.t.size + 1; + *decrypt = xtrymalloc(*decrypt_len); + (*decrypt)[0] = 0x04; + memcpy(*decrypt + 1, out.outPoint.point.x.t.buffer, + out.outPoint.point.x.t.size); + memcpy(*decrypt + 1 + out.outPoint.point.x.t.size, + out.outPoint.point.y.t.buffer, + out.outPoint.point.y.t.size); + + return 0; +} + +int +tpm2_rsa_decrypt(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, + const char *ciphertext, int ciphertext_len, + char **decrypt, size_t *decrypt_len) { RSA_Decrypt_In in; RSA_Decrypt_Out out; diff --git a/agent/tpm2.h b/agent/tpm2.h index 2e168032f..7a63aab88 100644 --- a/agent/tpm2.h +++ b/agent/tpm2.h @@ -10,13 +10,18 @@ int tpm2_start(TSS_CONTEXT **tssc); void tpm2_end(TSS_CONTEXT *tssc); void tpm2_flush_handle(TSS_CONTEXT *tssc, TPM_HANDLE h); int tpm2_load_key(TSS_CONTEXT *tssc, const unsigned char *shadow_info, - TPM_HANDLE *key); + TPM_HANDLE *key, TPMI_ALG_PUBLIC *type); int tpm2_sign(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, + TPMI_ALG_PUBLIC type, const unsigned char *digest, size_t digestlen, unsigned char **r_sig, size_t *r_siglen); int tpm2_import_key(ctrl_t ctrl, TSS_CONTEXT *tssc, char *pub, int *pub_len, char *priv, int *priv_len, gcry_sexp_t s_skey); -int tpm2_decrypt(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, - const char *ciphertext, int ciphertext_len, - char **decrypt, size_t *decrypt_len); +int tpm2_rsa_decrypt(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, + const char *ciphertext, int ciphertext_len, + char **decrypt, size_t *decrypt_len); +int tpm2_ecc_decrypt(ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key, + const char *ciphertext, int ciphertext_len, + char **decrypt, size_t *decrypt_len); + #endif -- 2.12.3 From ben at adversary.org Tue Mar 6 19:06:03 2018 From: ben at adversary.org (Ben McGinnes) Date: Wed, 7 Mar 2018 05:06:03 +1100 Subject: Help with python library In-Reply-To: <871sgypm9c.fsf@wheatstone.g10code.de> References: <20180304230530.xwhrxgqe35ct3nod@adversary.org> <871sgypm9c.fsf@wheatstone.g10code.de> Message-ID: <20180306180603.xcjitrm7gjn2pmvz@adversary.org> On Mon, Mar 05, 2018 at 04:36:47PM +0100, Werner Koch wrote: > On Mon, 5 Mar 2018 00:05, ben at adversary.org said: > >> However, gpg --list-packets is a debugging tool, so I'd need to >> double-check whether there was a full implementation of that in the >> API. > > Right. Note that there is a somewhat related feature request > https://dev.gnupg.org/T3734 (Extract signature key ID with gpgme). Interesting. I'd definitely like to see a feature like that added to GPGME. Something which would passively (in the sense of not performing any action on the data, as is the case with verifying a signature or decryption) read an OpenPGP file (either binary or ASCII armoured) and report the sort of things viewed with list-packets or pgpdump. It's already possible to get a lot of information about keys, for instance, via gpg.Context().keylist(); but even that doesn't get quite everything that list-packets does. It doesn't for instance, obtain the digest algorithm with which the key certified itself. > For checking whether a file is correctly encrypted, I would suggest > to simply try to decrypt it to /dev/null. The result information > lists the all keys; see gpgme/tests/run-decrypt.c for sample code. > If needed we can add a --dry-run feature so that no passphrase is > needed. The OP replied to me offlist (which was foolish because it ended up in a catchall, unlike posts to the list) indicating the use case was for messages or files received from clients of his employer. In which case he might or might not have access to the key the data is encrypted to or supposed to be encrypted to, but still need to confirm whether or not the customer has actually done what they were told to do the right way. In my experience that's rare enough in general without the additional complication cryptography brings to the party. That's definitely the sort of thing people use list-packets for fairly often. That being the case it's also the sort of thing which people would want to access programmatically. I can think of a bunch of scenarios where a security conscious IT department might need to check that employee generated keys all meet certain minimum key requirements and, depending on the size of the organisation, they might not want to do do that manually). Obviously in the OP's use case there may be limitations to that if the client used -R or -F instead of -r or -f (or if they used the throw-keyids option), but most people don't even know those options exist, let alone would choose to use them. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From ben at adversary.org Tue Mar 6 21:13:13 2018 From: ben at adversary.org (Ben McGinnes) Date: Wed, 7 Mar 2018 07:13:13 +1100 Subject: [PATCH gnupg] man page grammar Message-ID: <20180306201313.7yjbl36g6d6ty4xq@adversary.org> * Fixed one incorrect but of grammar (their vs. there) and one oddly phrased bit (not entirely wrong, but stilted and almost archaic). Signed-off-by: Ben McGinnes --- doc/gpg.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 8fea489f0..3c59e78d2 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2213,8 +2213,8 @@ handy in case where an encrypted message contains a bogus key ID. @opindex skip-hidden-recipients @opindex no-skip-hidden-recipients During decryption skip all anonymous recipients. This option helps in -the case that people use the hidden recipients feature to hide there -own encrypt-to key from others. If oneself has many secret keys this +the case that people use the hidden recipients feature to hide their +own encrypt-to key from others. If someone has many secret keys this may lead to a major annoyance because all keys are tried in turn to decrypt something which was not really intended for it. The drawback of this option is that it is currently not possible to decrypt a -- 2.16.2 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From peter at digitalbrains.com Tue Mar 6 21:32:31 2018 From: peter at digitalbrains.com (Peter Lebbing) Date: Tue, 6 Mar 2018 21:32:31 +0100 Subject: [PATCH gnupg] man page grammar In-Reply-To: <20180306201313.7yjbl36g6d6ty4xq@adversary.org> References: <20180306201313.7yjbl36g6d6ty4xq@adversary.org> Message-ID: On 06/03/18 21:13, Ben McGinnes wrote: > -the case that people use the hidden recipients feature to hide there > -own encrypt-to key from others. If oneself has many secret keys this > +the case that people use the hidden recipients feature to hide their > +own encrypt-to key from others. If someone has many secret keys this Wouldn't it make more sense to make it "If one has many secret keys", since it refers to the person using the --skip-hidden-recipients option, and not anyone else? Still slightly stilted, but I'd consider it more professional than "you". Peter. -- I use the GNU Privacy Guard (GnuPG) in combination with Enigmail. You can send me encrypted mail if you want some privacy. My key is available at -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From ben at adversary.org Wed Mar 7 00:17:05 2018 From: ben at adversary.org (Ben McGinnes) Date: Wed, 7 Mar 2018 10:17:05 +1100 Subject: [PATCH gnupg] man page grammar In-Reply-To: References: <20180306201313.7yjbl36g6d6ty4xq@adversary.org> Message-ID: <20180306231705.goslabz7xzbnt52d@adversary.org> On Tue, Mar 06, 2018 at 09:32:31PM +0100, Peter Lebbing wrote: > On 06/03/18 21:13, Ben McGinnes wrote: > > -the case that people use the hidden recipients feature to hide there > > -own encrypt-to key from others. If oneself has many secret keys this > > +the case that people use the hidden recipients feature to hide their > > +own encrypt-to key from others. If someone has many secret keys this > > Wouldn't it make more sense to make it "If one has many secret > keys", since it refers to the person using the > --skip-hidden-recipients option, and not anyone else? Still slightly > stilted, but I'd consider it more professional than "you". Yeah, I'll update it and send it through shortly. Also, after I sent it I realised the current line isn't just stilted, it is actually wrong because: When referring to one's self one must remember that one does include an apostrophe because one has only one self and thus does not need to numer one's self. :D Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From ben at adversary.org Wed Mar 7 00:28:48 2018 From: ben at adversary.org (Ben McGinnes) Date: Wed, 7 Mar 2018 10:28:48 +1100 Subject: [PATCH gnupg] man page grammar Message-ID: <20180306232848.nblbvtamejhsf73s@adversary.org> * Fixed two grammatical errors: their vs. there and oneself vs. one (one's self would still be too stilted). --- doc/gpg.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 8fea489f0..3474a5acb 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2213,8 +2213,8 @@ handy in case where an encrypted message contains a bogus key ID. @opindex skip-hidden-recipients @opindex no-skip-hidden-recipients During decryption skip all anonymous recipients. This option helps in -the case that people use the hidden recipients feature to hide there -own encrypt-to key from others. If oneself has many secret keys this +the case that people use the hidden recipients feature to hide their +own encrypt-to key from others. If one has many secret keys this may lead to a major annoyance because all keys are tried in turn to decrypt something which was not really intended for it. The drawback of this option is that it is currently not possible to decrypt a -- 2.16.2 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From wk at gnupg.org Wed Mar 7 10:03:10 2018 From: wk at gnupg.org (Werner Koch) Date: Wed, 07 Mar 2018 10:03:10 +0100 Subject: [PATCH gnupg] man page grammar In-Reply-To: <20180306232848.nblbvtamejhsf73s@adversary.org> (Ben McGinnes's message of "Wed, 7 Mar 2018 10:28:48 +1100") References: <20180306232848.nblbvtamejhsf73s@adversary.org> Message-ID: <87sh9cl0kx.fsf@wheatstone.g10code.de> On Wed, 7 Mar 2018 00:28, ben at adversary.org said: > * Fixed two grammatical errors: their vs. there and oneself vs. one > (one's self would still be too stilted). Thanks. I have changed the commit log to read --8<---------------cut here---------------start------------->8--- doc: man page grammar -- Fixed two grammatical errors: their vs. there and oneself vs. one (one's self would still be too stilted). --8<---------------cut here---------------end--------------->8--- Above the -- we put the common GNU ChnageLog entries. but for a doc chnage that does not make much sense. It is also good to prefix the subject with one of the keywords listed in doc/HACKING. Shalom-Salam, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From ben at adversary.org Wed Mar 7 10:30:52 2018 From: ben at adversary.org (Ben McGinnes) Date: Wed, 7 Mar 2018 20:30:52 +1100 Subject: GPGME TODO list old items Message-ID: <20180307093052.yrv5kbjft3jj24xd@adversary.org> Hi all, So I'm trying to tidy up some of the ancient things and make the GPGME TODO list a thing that is both worth checking and achievable. My current targets for marking off or removing or whatever is most relevant are these three items listed under "GPG breakage" (edited slightly for clarity): ** gpg 1.4.2 lacks error reporting if sign/encrypt with revoked key. ** gpg 1.4.2 does crappy error reporting (namely none at all) when smart card is missing for sign operation: [GNUPG:] CARDCTRL 4 gpg: selecting openpgp failed: ec=6.110 gpg: signing failed: general error [GNUPG:] BEGIN_ENCRYPTION 2 10 gpg: test: sign+encrypt failed: general error ** Without agent and with wrong passphrase, gpg 1.4.2 enters into an infinite loop. GPG 1.4.2 was a *long* time ago, so my questions are: 1. Have these been fixed, but not marked off? 2. If they haven't been fixed, do we really care any more? 3. Should we mark them as done, won't fix or just cut them from the TODO file? Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From ben at adversary.org Wed Mar 7 18:16:37 2018 From: ben at adversary.org (Ben McGinnes) Date: Thu, 8 Mar 2018 04:16:37 +1100 Subject: dirmngr vs. tor gateways In-Reply-To: <07d02087-17d7-71ae-43b2-5b8ec74594ba@immerda.ch> References: <7043774a-4dfa-c17d-59cb-fe20190d5510@immerda.ch> <87vaek40sw.fsf@wheatstone.g10code.de> <8647ef04-9170-6c71-36e6-fb7de3e74b2f@immerda.ch> <877eqxy4s6.fsf@wheatstone.g10code.de> <07d02087-17d7-71ae-43b2-5b8ec74594ba@immerda.ch> Message-ID: <20180307171637.dvwnew2ywuxlxntm@adversary.org> On Wed, Feb 28, 2018 at 04:34:45PM +0100, o. wrote: > On 02/28/2018 08:03 AM, Werner Koch wrote: > >> And you need top make sure that you have a full DNS resolver over Tor. >> Just looking up AAAA records is not sufficient to use the key server pools. > > I don't think that such a resolver exists for tor at the moment. The > ticket seems to still be open [0]. From what I understand of the whonix boxes, they're always configured in such a way that all traffic exits via an encrypted connection; mostly via VPN before moving on to Tor and sometimes with a couple of VPNs (well, a couple of openvpn links). The key point, though, is that all traffic runs through these links or through Tor and nothing else goes back to a plain old Internet connection. At least that's what this config page indicates: https://www.whonix.org/wiki/Tunnels/Connecting_to_a_VPN_before_Tor#DNS_Configuration_2 If that's the case and the network config already addresses the normal security concerns that come with DNS resolution and Tor then this would be precisely the scenario in which this page: https://www.whonix.org/wiki/Whonix-Gateway_System_DNS Should be overridden and bind activated on the system. Just configure it as a local resolver, you can also do some far more cleve rhings with a locl named instance running than you ever could with /etc/hosts anyway. Then just make sure all TCP and UDP traffic to and from ports 53 and 5353 (at the local end or the other end) go through the tunnel. I'd add port 43 (whois) for good measure. Then point dirmngr's nameserver option at 127.0.0.1 and you should be set. It'll look up hostnames and domains on the local resolver and all traffic from said resolver goes through the tunnels. There might be some interestingly long pauses with searches due to inevitable latency issues over Tor, but other than that it should work just fine. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From wk at gnupg.org Thu Mar 8 13:28:32 2018 From: wk at gnupg.org (Werner Koch) Date: Thu, 08 Mar 2018 13:28:32 +0100 Subject: [gmime-devel] avoiding metadata leaks when handling S/MIME-signed mail in GMime and other tools that use GnuPG In-Reply-To: <0FD3E4E1-4C61-44BC-8B67-9996DE9D5DF2@microsoft.com> (Jeffrey Stedfast via Gnupg-devel's message of "Sat, 3 Feb 2018 18:48:26 +0000") References: <87y3kb471j.fsf@fifthhorseman.net> <9201448a-83f1-2bf5-14d4-6b862a13e31e@gnome.org> <87o9l742kv.fsf@fifthhorseman.net> <0FD3E4E1-4C61-44BC-8B67-9996DE9D5DF2@microsoft.com> Message-ID: <877eqmiwen.fsf@wheatstone.g10code.de> On Sat, 3 Feb 2018 19:48, gnupg-devel at gnupg.org said: > it suggests that setting offline mode only works for CMS and not OpenPGP? Can anyone from the GPGME team verify this? If so, I'll drop the flags that would indicate that this works in OpenPGP mode. This is correct. The offline mode currently works only with gpgsm: The offline mode specifies if dirmngr should be used to do additional validation that might require connections to external services. (e.g. CRL / OCSP checks). Offline mode only affects the keylist mode @code{GPGME_KEYLIST_MODE_VALIDATE} and is only relevant to the CMS crypto engine. Offline mode is ignored otherwise. This option may be extended in the future to completely disable the use of dirmngr for any engine. I think it is time to do this now: https://dev.gnupg.org/T3831 Salam-Shalom, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From wk at gnupg.org Thu Mar 8 17:15:35 2018 From: wk at gnupg.org (Werner Koch) Date: Thu, 08 Mar 2018 17:15:35 +0100 Subject: Help with python library In-Reply-To: <20180306180603.xcjitrm7gjn2pmvz@adversary.org> (Ben McGinnes's message of "Wed, 7 Mar 2018 05:06:03 +1100") References: <20180304230530.xwhrxgqe35ct3nod@adversary.org> <871sgypm9c.fsf@wheatstone.g10code.de> <20180306180603.xcjitrm7gjn2pmvz@adversary.org> Message-ID: <87woymh7bs.fsf@wheatstone.g10code.de> On Tue, 6 Mar 2018 19:06, ben at adversary.org said: > signature or decryption) read an OpenPGP file (either binary or ASCII > armoured) and report the sort of things viewed with list-packets or I don't think that it should be GPGME's goal to provide all internals of an OpenPGP message or keyblock. However, certain things which can indeed be useful and are availabale in plaintext and without signature verification can be added to gpgme_data_identify or a new alike function. > instance, via gpg.Context().keylist(); but even that doesn't get quite > everything that list-packets does. It doesn't for instance, obtain > the digest algorithm with which the key certified itself. I consider this an internal property of OpenPGP and not of general interest for an API which should provide an mostly abstract view of the underying crypto protocol. If tehre is a policy or compliance need for this we can add this to gpg proper and set a flag in the gpgme key object. > In which case he might or might not have access to the key the data is > encrypted to or supposed to be encrypted to, but still need to confirm > whether or not the customer has actually done what they were told to > do the right way. In my experience that's rare enough in general > without the additional complication cryptography brings to the party. :-). A dry-run feature for decryption would be best I think. > scenarios where a security conscious IT department might need to check > that employee generated keys all meet certain minimum key requirements > and, depending on the size of the organisation, they might not want to That is for what we have this pretty new compliance thing. The code allows to easily add other compliance policies than the current de-vs policy. Salam-Shalom, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From wk at gnupg.org Thu Mar 8 17:23:00 2018 From: wk at gnupg.org (Werner Koch) Date: Thu, 08 Mar 2018 17:23:00 +0100 Subject: GPGME TODO list old items In-Reply-To: <20180307093052.yrv5kbjft3jj24xd@adversary.org> (Ben McGinnes's message of "Wed, 7 Mar 2018 20:30:52 +1100") References: <20180307093052.yrv5kbjft3jj24xd@adversary.org> Message-ID: <87sh9ah6zf.fsf@wheatstone.g10code.de> On Wed, 7 Mar 2018 10:30, ben at adversary.org said: > So I'm trying to tidy up some of the ancient things and make > the GPGME TODO list a thing that is both worth checking and > achievable. Oh, that is a pretty old file with the last Chnages from 2009. > ** gpg 1.4.2 lacks error reporting if sign/encrypt with revoked > key. According to the gpg NEWS this didn't chnaged. I would say mark it as WONTFIX. > ** gpg 1.4.2 does crappy error reporting (namely none at all) when > smart card is missing for sign operation: > [GNUPG:] CARDCTRL 4 > gpg: selecting openpgp failed: ec=6.110 > gpg: signing failed: general error > [GNUPG:] BEGIN_ENCRYPTION 2 10 > gpg: test: sign+encrypt failed: general error We will definitely not do any updates for smartcard in gpg 1.4 anymore. Thus this is also a WONTFIX. > ** Without agent and with wrong passphrase, gpg 1.4.2 enters into > an infinite loop. Indeed? This might have been fixes since 1.4.2 - I have not checked. > 3. Should we mark them as done, won't fix or just cut them from the > TODO file? Mark them as and also add a note to the top of the TODO that the file might be out of date and that current feature requests can be found at dev.gnupg.org. Shalom-Salam, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From ben at adversary.org Thu Mar 8 22:14:20 2018 From: ben at adversary.org (Ben McGinnes) Date: Fri, 9 Mar 2018 08:14:20 +1100 Subject: GPGME TODO list old items In-Reply-To: <87sh9ah6zf.fsf@wheatstone.g10code.de> References: <20180307093052.yrv5kbjft3jj24xd@adversary.org> <87sh9ah6zf.fsf@wheatstone.g10code.de> Message-ID: <20180308211420.ju6ddb6fud26iilp@adversary.org> On Thu, Mar 08, 2018 at 05:23:00PM +0100, Werner Koch wrote: > On Wed, 7 Mar 2018 10:30, ben at adversary.org said: > >> So I'm trying to tidy up some of the ancient things and make >> the GPGME TODO list a thing that is both worth checking and >> achievable. > > Oh, that is a pretty old file with the last Chnages from 2009. >> ** Without agent and with wrong passphrase, gpg 1.4.2 enters into >> an infinite loop. > > Indeed? This might have been fixes since 1.4.2 - I have not checked. It must've been fixed because I used a later version of 1.4 with it for a few months at some point and I must've entered a wrong passphrase at some point. I believe it was when I was transitioning from my previous key to this current one and I definitely would've encountered passphrase muscle memory issues then. I do recall some annoyances, but no infinite loops or recursion. >> 3. Should we mark them as done, won't fix or just cut them from the >> TODO file? > > Mark them as and also add a note to the top of the TODO that the file > might be out of date and that current feature requests can be found at > dev.gnupg.org. All righty, that'll be my next update to master. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From marcelf at selfnet.de Thu Mar 8 23:29:33 2018 From: marcelf at selfnet.de (Marcel Fest) Date: Thu, 8 Mar 2018 23:29:33 +0100 Subject: Help with python library In-Reply-To: <20180306180603.xcjitrm7gjn2pmvz@adversary.org> References: <20180304230530.xwhrxgqe35ct3nod@adversary.org> <871sgypm9c.fsf@wheatstone.g10code.de> <20180306180603.xcjitrm7gjn2pmvz@adversary.org> Message-ID: > Interesting. I'd definitely like to see a feature like that added to > GPGME. Something which would passively (in the sense of not > performing any action on the data, as is the case with verifying a > signature or decryption) read an OpenPGP file (either binary or ASCII > armoured) and report the sort of things viewed with list-packets or > pgpdump. > > It's already possible to get a lot of information about keys, for > instance, via gpg.Context().keylist(); but even that doesn't get quite > everything that list-packets does. It doesn't for instance, obtain > the digest algorithm with which the key certified itself. > >> For checking whether a file is correctly encrypted, I would suggest >> to simply try to decrypt it to /dev/null. The result information >> lists the all keys; see gpgme/tests/run-decrypt.c for sample code. >> If needed we can add a --dry-run feature so that no passphrase is >> needed. > The OP replied to me offlist (which was foolish because it ended up in > a catchall, unlike posts to the list) indicating the use case was for > messages or files received from clients of his employer. > > In which case he might or might not have access to the key the data is > encrypted to or supposed to be encrypted to, but still need to confirm > whether or not the customer has actually done what they were told to > do the right way. In my experience that's rare enough in general > without the additional complication cryptography brings to the party. > > That's definitely the sort of thing people use list-packets for fairly > often. That being the case it's also the sort of thing which people > would want to access programmatically. I can think of a bunch of > scenarios where a security conscious IT department might need to check > that employee generated keys all meet certain minimum key requirements > and, depending on the size of the organisation, they might not want to > do do that manually). > > Obviously in the OP's use case there may be limitations to that if the > client used -R or -F instead of -r or -f (or if they used the > throw-keyids option), but most people don't even know those options > exist, let alone would choose to use them. > > > Regards, > Ben Hey Ben, Sorry that I replied offlist, but I am not that used to mailinglists. I now use a combination of the gpgme python bindings for decryption and for encryption I use PGPy, because I need a dedicated keyring and gpgme, does not create one for me, like the gpg cli does it. To get the keys from the KeyServers I use a customized version of a github project which speaks to defined KeyServers with requests. All in all I have now a working version of my CLI completely without subprocess bindings. python-gnupg is good but only a cli wrapper for the gpg cli via subprocess. PGPy has also the support for getting issuers out of encrypted files. Best Regards Marcel Fest -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: OpenPGP digital signature URL: From gnupg-devel at spodhuis.org Fri Mar 9 04:55:53 2018 From: gnupg-devel at spodhuis.org (Phil Pennock) Date: Thu, 8 Mar 2018 22:55:53 -0500 Subject: GnuPG 2.2 on elder Debian & Ubuntu distros In-Reply-To: <201803011706.50033.bernhard@intevation.de> References: <201710271606.59244.bernhard@intevation.de> <20171027162445.GA17617@breadbox.private.spodhuis.org> <201803011706.50033.bernhard@intevation.de> Message-ID: <20180309035552.GA57277@tower.spodhuis.org> On 2018-03-01 at 17:06 +0100, Bernhard Reiter wrote: > Your page is quite helpful, my suggestion is to add or link an example how to > set the path, e.g. sourcing a bash file like > > :::::::::::::: > setgnupg > :::::::::::::: > base=/opt/gnupg > > export LD_LIBRARY_PATH=$base/lib:$LD_LIBRARY_PATH > export MANPATH=$base/share/man:$MANPATH > export PATH=$base/bin:$PATH > :::::::::::::: LD_LIBRARY_PATH is unneeded, because the executables have the RPATH stamped into them. % readelf -d $(which gpg) | grep RPATH 0x000000000000000f (RPATH) Library rpath: [/opt/gnupg/lib] You _shouldn't_ need to set MANPATH explicitly on any modern man(1) system, because they have facilities to translate $PATH to $MANPATH accordingly. On a Trusty VM, even without anything explicit for /opt/gnupg listed in /etc/manpath.config, if I run: unset MANPATH manpath then I see the inferred MANPATH which is used by default, and it contains a correct entry for PATH. Thus the _only_ step needed is to update $PATH. My personal stance is that if someone doesn't know how to update PATH, then that's fine and reasonable, but that someone at such a skill level has no business installing replacement cryptographic commands from sources which they are highly unlikely to be able to adequately assess. -Phil From bernhard at intevation.de Fri Mar 9 10:51:37 2018 From: bernhard at intevation.de (Bernhard Reiter) Date: Fri, 9 Mar 2018 10:51:37 +0100 Subject: GnuPG 2.2 on elder Debian & Ubuntu distros In-Reply-To: <20180309035552.GA57277@tower.spodhuis.org> References: <201710271606.59244.bernhard@intevation.de> <201803011706.50033.bernhard@intevation.de> <20180309035552.GA57277@tower.spodhuis.org> Message-ID: <201803091051.44901.bernhard@intevation.de> Phil, Am Freitag 09 M?rz 2018 04:55:53 schrieb Phil Pennock: > On 2018-03-01 at 17:06 +0100, Bernhard Reiter wrote: > > Your page is quite helpful, my suggestion is to add or link an example > > how to set the path, e.g. sourcing a bash file like > LD_LIBRARY_PATH is unneeded, because the executables have the RPATH > stamped into them. > You _shouldn't_ need to set MANPATH explicitly on any modern man(1) > system, > Thus the _only_ step needed is to update $PATH. thanks for these hints! While I do have some adminstration knowledge, I did not research both points. (Just trying out stuff. I've seen that manpath got more complicated in GNU systems a while ago, but this was not the right time to learn more about it.) > My personal stance is that if someone doesn't know how to update PATH, > then that's fine and reasonable, but that someone at such a skill level > has no business installing replacement cryptographic commands from > sources which they are highly unlikely to be able to adequately assess. My suggestion is about comfort and knowledge sharing, it is just easier to have your statement about LD_LIBRARY_PATH been unnecessary seen in an example script and it is less thinking even for experienced people when they see the example. Some people may know more GnuPG, but less about Debian or Ubuntu and being able to judge a new cryptographic command is okay for them. (In this case I believe I am an example, but of course I know how to set PATH.) Best Regards, Bernhard -- www.intevation.de/~bernhard ? +49 541 33 508 3-3 Intevation GmbH, Osnabr?ck, DE; Amtsgericht Osnabr?ck, HRB 18998 Gesch?ftsf?hrer Frank Koormann, Bernhard Reiter, Dr. Jan-Oliver Wagner -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: This is a digitally signed message part. URL: From wk at gnupg.org Sat Mar 10 13:03:43 2018 From: wk at gnupg.org (Werner Koch) Date: Sat, 10 Mar 2018 13:03:43 +0100 Subject: [RFC v2 0/5] TPM support for gpg In-Reply-To: <1520277125.5312.35.camel@HansenPartnership.com> (James Bottomley's message of "Mon, 05 Mar 2018 11:12:05 -0800") References: <1520277125.5312.35.camel@HansenPartnership.com> Message-ID: <87muzggmsf.fsf@wheatstone.g10code.de> On Mon, 5 Mar 2018 20:12, James.Bottomley at HansenPartnership.com said: > Since the last posting, I've tidied up a few things and added support > for Elliptic Curve keys (as a separate patch, currently, but it could > be rolled into the base). Thanks for the patches. I pushed them to a new tpm-work branch. As of now it is required that libtss0-dev is installed. Debian Stetch does not have it but it is easy to install from Sid. There are no real configure checks right now but I added an #error to explain what is going wrong if you try to build without this dependency. I have not tested the new code myself. Before this goes into master or a 2.3 release, I would like to move the entire TPM access code out to a separate daemon much like scdaemon works. Maybe it is even possible to get rid of the dlopening, but the major thing is that this code and its dependency on OpenSSL gets out of gpg-agent. James: The 3 new files are missing the copyright blurbs, can you please send a patch to add them? I would not mind if you can directly add an SPDX-License-Identifier: GPL-3.0+ line (GPL-2.0+ if you prefer). Salam-Shalom, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From James.Bottomley at HansenPartnership.com Sat Mar 10 23:50:00 2018 From: James.Bottomley at HansenPartnership.com (James Bottomley) Date: Sat, 10 Mar 2018 14:50:00 -0800 Subject: [RFC v2 0/5] TPM support for gpg In-Reply-To: <87muzggmsf.fsf@wheatstone.g10code.de> References: <1520277125.5312.35.camel@HansenPartnership.com> <87muzggmsf.fsf@wheatstone.g10code.de> Message-ID: <1520722200.4495.27.camel@HansenPartnership.com> On Sat, 2018-03-10 at 13:03 +0100, Werner Koch wrote: > On Mon,??5 Mar 2018 20:12, James.Bottomley at HansenPartnership.com > said: > > > > > Since the last posting, I've tidied up a few things and added > > support for Elliptic Curve keys (as a separate patch, currently, > > but it could be rolled into the base). > > Thanks for the patches.??I pushed them to a new tpm-work branch. Great, thanks! > As of now it is required that libtss0-dev is installed.??Debian > Stetch does not have it but it is easy to install from Sid. Actually, libtss-dev, but yes. ?However, there's a problem with that package (which is why it hasn't migrated from unstable) and it turns out the person who maintains it has left IBM, so I can't get it fixed. I think what's going to happen is that IBM will submit a new one with the ibm prefix, largely because Intel is trying to submit a tss package as well. ?I was hoping to get these two merged (the Intel one lacks the crypto pieces which are necessary for gpg key handling, so simply adding the IBM one seemed like a good solution) but it looks increasingly less likely that will happen, so separate namespaces seems a better approach. > ??There are no real configure checks right now but I added an #error > to explain what is going wrong if you try to build without this > dependency.??I have not tested the new code myself. How about the below for a stab at gating the configure on the presence of the TPM library. > Before this goes into master or a 2.3 release, I would like to move > the entire TPM access code out to a separate daemon much like > scdaemon works.??Maybe it is even possible to get rid of the > dlopening, but the major thing is that this code and its dependency > on OpenSSL gets out of gpg-agent. I should have removed the direct openssl dependency with the shift to gcrypt AES handling. ?However, I'll look at doing a separate daemon. ?It certainly should be simple enough. > James: The 3 new files are missing the copyright blurbs, can you > please send a patch to add them???I would not mind if you can > directly add an ? SPDX-License-Identifier: GPL-3.0+ > line (GPL-2.0+ if you prefer). Sure thing. ?SPX should work. ?I'll keep them at GPL-2.0+ just in case I (or anyone else) need to cut and paste into a GPL-2.0 project. James --- From cc7a25e6b41b7da07970e7ca5f57129244a8214b Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 6 Mar 2018 15:02:43 -0800 Subject: [PATCH] configure: Make TPM2 support conditional This adds a configure stanza to check for the necessary libtss to support TPM functions. If found, the library functions will be dynamically loaded, meaning that a system built with TPM2 support will still execute correctly (obviously minus TPM2 support) if installed without libtss being present. Signed-off-by: James Bottomley --- agent/Makefile.am | 7 +++++-- agent/agent.h | 26 ++++++++++++++++++++++++++ configure.ac | 11 +++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/agent/Makefile.am b/agent/Makefile.am index 1b8ac508f..c92c0ad06 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -51,12 +51,15 @@ gpg_agent_SOURCES = \ protect.c \ trustlist.c \ divert-scd.c \ - divert-tpm2.c \ - tpm2.c \ cvt-openpgp.c cvt-openpgp.h \ call-scd.c \ learncard.c +if HAVE_LIBTSS +gpg_agent_SOURCES += tpm2.c \ + divert-tpm2.c +endif + common_libs = $(libcommon) commonpth_libs = $(libcommonpth) if HAVE_W32CE_SYSTEM diff --git a/agent/agent.h b/agent/agent.h index 0ff487a59..dd6d6cb24 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -534,6 +534,7 @@ gpg_error_t agent_marktrusted (ctrl_t ctrl, const char *name, void agent_reload_trustlist (void); /*-- divert-tpm2.c --*/ +#ifdef HAVE_LIBTSS int divert_tpm2_pksign (ctrl_t ctrl, const char *desc_text, const unsigned char *digest, size_t digestlen, int algo, const unsigned char *shadow_info, unsigned char **r_sig, @@ -544,6 +545,31 @@ int divert_tpm2_pkdecrypt (ctrl_t ctrl, const char *desc_text, char **r_buf, size_t *r_len, int *r_padding); int divert_tpm2_writekey (ctrl_t ctrl, const unsigned char *grip, gcry_sexp_t s_skey); +#else +static inline int divert_tpm2_pksign (ctrl_t ctrl, const char *desc_text, + const unsigned char *digest, + size_t digestlen, int algo, + const unsigned char *shadow_info, + unsigned char **r_sig, + size_t *r_siglen) +{ + return -EINVAL; +} +static inline int divert_tpm2_pkdecrypt (ctrl_t ctrl, const char *desc_text, + const unsigned char *cipher, + const unsigned char *shadow_info, + char **r_buf, size_t *r_len, + int *r_padding) +{ + return -EINVAL; +} +static inline int divert_tpm2_writekey (ctrl_t ctrl, const unsigned char *grip, + gcry_sexp_t s_skey) +{ + return -EINVAL; +} +#endif + /*-- divert-scd.c --*/ diff --git a/configure.ac b/configure.ac index 7522b6922..6df4d0a57 100644 --- a/configure.ac +++ b/configure.ac @@ -100,6 +100,7 @@ have_gnutls=no have_sqlite=no have_npth=no have_libusb=no +have_libtss=no have_system_resolver=no gnupg_have_ldap="n/a" @@ -1590,6 +1591,15 @@ AC_SUBST(NETLIBS) AC_SUBST(W32SOCKLIBS) # +# TPM libtss library .. don't compile TPM support if we don't have it +# +AC_CHECK_LIB(tss, TSS_Create, [have_libtss=yes]) +if test "$have_libtss" = yes; then + AC_DEFINE(HAVE_LIBTSS, 1, [Defined if we have TPM2 support library]) +fi +AM_CONDITIONAL(HAVE_LIBTSS, test "$have_libtss" = yes) + +# # Setup gcc specific options # USE_C99_CFLAGS= @@ -2072,6 +2082,7 @@ echo " TLS support: $use_tls_library TOFU support: $use_tofu Tor support: $show_tor_support + TPM support: $have_libtss " if test x"$use_regex" != xyes ; then echo " -- 2.12.3 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: This is a digitally signed message part URL: From ben at adversary.org Sun Mar 11 06:52:45 2018 From: ben at adversary.org (Ben McGinnes) Date: Sun, 11 Mar 2018 16:52:45 +1100 Subject: Help with python library In-Reply-To: References: <20180304230530.xwhrxgqe35ct3nod@adversary.org> <871sgypm9c.fsf@wheatstone.g10code.de> <20180306180603.xcjitrm7gjn2pmvz@adversary.org> Message-ID: <20180311055245.aa6xdbyvkdtojrzy@adversary.org> On Thu, Mar 08, 2018 at 11:29:33PM +0100, Marcel Fest wrote: > > Sorry that I replied offlist, but I am not that used to mailinglists. It's all right, just *really* inefficient. I've been online for a while now and had this email address for much of that time, I receive a lot of email and if there isn't an existing rule for an address then it'll end up in one of several catchalls (depending on which address was used mainly). I'll see those emails eventually, but it was pure luck that I saw yours the same month as it was sent ... let alone the same week. Whereas most of my list subscriptions are filtered on the list-id header information. > I now use a combination of the gpgme python bindings for decryption > and for encryption I use PGPy, because I need a dedicated keyring > and gpgme, does not create one for me, like the gpg cli does it. By default GPGME will use the same configuration and keyring/keybox of the user invoking the code. That can be changed to a custom or alternative configuration or homedir location, but it is a little fiddly. Mind you, so is doing that on the command line. > To get the keys from the KeyServers I use a customized version of a > github project which speaks to defined KeyServers with requests. Fair enough. HKP and HKPS are just slightly modified HTTP and HTTPS anyway (well, actually they haven't modified those protocols, they just define that what's running on them is a keyserver and then define that). I used to do something similar when directing certain key retrievals through tor (before it was supported natively), but now I can't recall where I left that script. Oh well. > All in all I have now a working version of my CLI completely without > subprocess bindings. Which is excellent to hear. > python-gnupg is good but only a cli wrapper for the gpg cli via > subprocess. For relative values of good. It's okay for quick and dirty if the only people accessing the script already have shell access, but otherwise it's been known to have issues. It also has a very limited subset of GPG features and sometimes for rather surprising reasons. > PGPy has also the support for getting issuers out of encrypted > files. Hmm, I suspect that most use of list-packets or pgpdump on an encrypted message is to check the number and key IDs a message is encrypted to prior to attempting decryption and so there's probably a decent enough case for adding that to GPGME. Probably the ciphers and algorithms used too. The other lacking item is support for groups from the gpg.conf. I've got a work around for that, but it's not ideal (and it's also not online yet, I want to give it some basic testing first). Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From dashohoxha at gmail.com Sun Mar 11 17:43:34 2018 From: dashohoxha at gmail.com (Dashamir Hoxha) Date: Sun, 11 Mar 2018 17:43:34 +0100 Subject: GSoC project about improving EasyGnuPG Message-ID: Hi, I have started a GSoC project about improving EasyGnuPG under the organizational umbrella of Debian: https://wiki.debian.org/SummerOfCode2018/Projects/EasyGnuPG So far there have been about 10 students interested in it. >From interactions that I had with them (I give them small tasks to complete, etc.) I think that 2-3 of them are really promising. Actually I would like to support 2-3 students, if possible. They can work on different tasks, like: - Rewrite EasyGnuPG (or parts of it) so that it is built with Python and GPGME - Implement a GUI to EasyGnuPG (maybe with Python). - Write a Debian package for installing EasyGnuPG. Extend EasyGnuPG with scripts/commands that automate other common usage scenarios (for example keeping the master key on a card). The problem is that for each student-proposal pair you also have to find at least a mentor, and a mentor is not allowed to be primary mentor for more than 2 projects. Meanwhile I have also proposed a couple of other projects and I am committed to them as well. So, I would like some help or support for mentoring these students. I can still be a co-mentor for each of the projects, and maybe I will do most of the interaction with the students (right now I am not working, so I have plenty of time). But I am not allowed to be a primary mentor for more than 2 projects. Besides this, I am not an expert on Python programming or making GUI applications (and even I am not an expert on GPG itself), so some help or support would be really useful. Would somebody like to help with mentoring? If you wish you can check the interactions that I had with the students so far, in order to create your own opinion about them, or maybe to assign them additional testing tasks. Students will submit their project proposals between 12 and 27 March, and after that we will have to decide which ones to accept. Best regards, Dashamir -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcelf at selfnet.de Mon Mar 12 10:36:24 2018 From: marcelf at selfnet.de (Marcel Fest) Date: Mon, 12 Mar 2018 10:36:24 +0100 Subject: Help with python library In-Reply-To: <20180311055245.aa6xdbyvkdtojrzy@adversary.org> References: <20180304230530.xwhrxgqe35ct3nod@adversary.org> <871sgypm9c.fsf@wheatstone.g10code.de> <20180306180603.xcjitrm7gjn2pmvz@adversary.org> <20180311055245.aa6xdbyvkdtojrzy@adversary.org> Message-ID: <1edb1fbd-5195-dfb3-f932-3410c20fa21b@selfnet.de> > Hmm, I suspect that most use of list-packets or pgpdump on an > encrypted message is to check the number and key IDs a message is > encrypted to prior to attempting decryption and so there's probably a > decent enough case for adding that to GPGME. Probably the ciphers and > algorithms used too. > > The other lacking item is support for groups from the gpg.conf. I've > got a work around for that, but it's not ideal (and it's also not > online yet, I want to give it some basic testing first). > > > Regards, > Ben > > > _______________________________________________ > Gnupg-devel mailing list > Gnupg-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gnupg-devel Thanks for your help and the help from all the others who replied to me. Regards Marcel -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: OpenPGP digital signature URL: From wk at gnupg.org Mon Mar 12 10:42:18 2018 From: wk at gnupg.org (Werner Koch) Date: Mon, 12 Mar 2018 10:42:18 +0100 Subject: [RFC v2 0/5] TPM support for gpg In-Reply-To: <1520722200.4495.27.camel@HansenPartnership.com> (James Bottomley's message of "Sat, 10 Mar 2018 14:50:00 -0800") References: <1520277125.5312.35.camel@HansenPartnership.com> <87muzggmsf.fsf@wheatstone.g10code.de> <1520722200.4495.27.camel@HansenPartnership.com> Message-ID: <87a7vdhbph.fsf@wheatstone.g10code.de> On Sat, 10 Mar 2018 23:50, James.Bottomley at HansenPartnership.com said: > package (which is why it hasn't migrated from unstable) and it turns > out the person who maintains it has left IBM, so I can't get it fixed. Thanks for the background info. > How about the below for a stab at gating the configure on the presence > of the TPM library. Thanks. I just pushed it with a minor edit (missing tpm2.h in Makefile.am which I added later) > I should have removed the direct openssl dependency with the shift to > gcrypt AES handling. ?However, I'll look at doing a separate daemon. > ?It certainly should be simple enough. It is not urgent, thouigh. I am actually willing to do the framework for a new daemon - or do you want to have it independet from GnuPG? > Sure thing. ?SPX should work. ?I'll keep them at GPL-2.0+ just in case > I (or anyone else) need to cut and paste into a GPL-2.0 project. Fine with me. Salam-Shalom, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From James.Bottomley at HansenPartnership.com Mon Mar 12 16:01:13 2018 From: James.Bottomley at HansenPartnership.com (James Bottomley) Date: Mon, 12 Mar 2018 08:01:13 -0700 Subject: [RFC v2 0/5] TPM support for gpg In-Reply-To: <87a7vdhbph.fsf@wheatstone.g10code.de> References: <1520277125.5312.35.camel@HansenPartnership.com> <87muzggmsf.fsf@wheatstone.g10code.de> <1520722200.4495.27.camel@HansenPartnership.com> <87a7vdhbph.fsf@wheatstone.g10code.de> Message-ID: <1520866873.4522.7.camel@HansenPartnership.com> On Mon, 2018-03-12 at 10:42 +0100, Werner Koch wrote: > On Sat, 10 Mar 2018 23:50, James.Bottomley at HansenPartnership.com > said: > > > > > package (which is why it hasn't migrated from unstable) and it > > turns out the person who maintains it has left IBM, so I can't get > > it fixed. > > Thanks for the background info. I think once we have the daemon, coping with any potential name change is quite easy, the AC_CHECK_LIB can just become AC_SEARCH_LIB over all the names the library has had? > > How about the below for a stab at gating the configure on the > > presence of the TPM library. > > Thanks.??I just pushed it with a minor edit (missing tpm2.h in > Makefile.am which I added later) Great, thanks. ?I made this branch the basis of what I'm working on. > > I should have removed the direct openssl dependency with the shift > > to gcrypt AES handling. ?However, I'll look at doing a separate > > daemon. ?It certainly should be simple enough. > > It is not urgent, thouigh.??I am actually willing to do the framework > for a new daemon - or do you want to have it independet from GnuPG? No ... there's value in having the TPM code cut and pasteable because this is a nice demo of how to use TPM crypto functions, hence the desire to keep it GPL2+ but the daemon framework is very gnupg specific and should be kept there. I had a brief look at what it would take, and it looks simple enough except that there's a lot of daemon code in call-scd.c that should be reused, so it looks like the project would have two stages:? 1. Separate generic daemon code out of call-scd for reuse 2. build the tpm handling daemon based on the generic code I'm guessing you'll have strong opinions on the framework in 1. ... James > > > > Sure thing. ?SPX should work. ?I'll keep them at GPL-2.0+ just in > > case > > I (or anyone else) need to cut and paste into a GPL-2.0 project. > > Fine with me. > > > Salam-Shalom, > > ???Werner > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: This is a digitally signed message part URL: From bradleyb at fuzziesquirrel.com Wed Mar 14 22:09:01 2018 From: bradleyb at fuzziesquirrel.com (Brad Bishop) Date: Wed, 14 Mar 2018 17:09:01 -0400 Subject: [PATCH libgpg-error] syscfg: Add ppc64le cross build support Message-ID: <20180314210901.20952-1-bradleyb@fuzziesquirrel.com> * src/syscfg/lock-obj-pub.ppc64le-unknown-linux-gnu.h: New. * src/Makefile.am (lock_obj_pub): Add. -- Signed-off-by: Brad Bishop --- src/Makefile.am | 1 + .../lock-obj-pub.ppc64le-unknown-linux-gnu.h | 25 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/syscfg/lock-obj-pub.ppc64le-unknown-linux-gnu.h diff --git a/src/Makefile.am b/src/Makefile.am index 268c2ab..e3ed6c1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,6 +64,7 @@ lock_obj_pub = \ syscfg/lock-obj-pub.powerpc-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc64-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc64le-unknown-linux-gnu.h \ + syscfg/lock-obj-pub.ppc64le-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc-unknown-linux-gnuspe.h \ syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h \ syscfg/lock-obj-pub.s390x-ibm-linux-gnu.h \ diff --git a/src/syscfg/lock-obj-pub.ppc64le-unknown-linux-gnu.h b/src/syscfg/lock-obj-pub.ppc64le-unknown-linux-gnu.h new file mode 100644 index 0000000..b9407d4 --- /dev/null +++ b/src/syscfg/lock-obj-pub.ppc64le-unknown-linux-gnu.h @@ -0,0 +1,25 @@ +## lock-obj-pub.ppc64le-unknown-linux-gnu.h +## File created by gen-posix-lock-obj - DO NOT EDIT +## To be included by mkheader into gpg-error.h + +typedef struct +{ + long _vers; + union { + volatile char _priv[40]; + long _x_align; + long *_xp_align; + } u; +} gpgrt_lock_t; + +#define GPGRT_LOCK_INITIALIZER {1,{{0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0}}} +## +## Local Variables: +## mode: c +## buffer-read-only: t +## End: +## -- 2.5.0 From ben at adversary.org Thu Mar 15 14:00:49 2018 From: ben at adversary.org (Ben McGinnes) Date: Fri, 16 Mar 2018 00:00:49 +1100 Subject: Python bindings HOWTO proof reader request Message-ID: <20180315130049.4sc54dk3zgvmlalq@adversary.org> Hello, The major work on a HOWTO for the Python bindings is done, but I'd appreciate some fresh eyes proof reading it before I merge it with master. The full thing, in org-mode format,is here: https://files.gnupg.net/file/data/ossmg4ung2hcpyyuks6j/PHID-FILE-xgbofmytge7fzn3u5kuc/GPGMEpythonHOWTOen.org Don't worry about dialectic differences between American English and Australian or British English, I'll do a translation for en-US later. Also don't worry about the lack of instructions on revoking UIDs or keys, that will be added later too. I'm more interested in being sure that the example code works (it should, I was running it as I was writing the thing) and that the corresponding text descriptions actually help to clarify what's going on in that code. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From muelli at cryptobitch.de Thu Mar 15 15:50:46 2018 From: muelli at cryptobitch.de (Tobias Mueller) Date: Thu, 15 Mar 2018 15:50:46 +0100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <20180315130049.4sc54dk3zgvmlalq@adversary.org> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> Message-ID: <1521125446.24704.89.camel@cryptobitch.de> Hi. On Fri, 2018-03-16 at 00:00 +1100, Ben McGinnes wrote: > I'd appreciate some fresh eyes proof reading it before I merge it with > master. The full thing, in org-mode format,is here: > > https://files.gnupg.net/file/data/ossmg4ung2hcpyyuks6j/PHID-FILE- > xgbofmytge7fzn3u5kuc/GPGMEpythonHOWTOen.org Cool, thanks. Can you elaborate on this paragraph: Most third-party Python packages and modules are available and distributed through the Python Package Installer, known as PyPI. Due to the nature of what these bindings are and how they work, it is infeasible to install the GPGME Python bindings in the same way. Without any further explanation I consider the argument to be weak. What's the nature and how is it different from all the other binary packages on pypi? These days, with Python manylinux wheels it's much easier to distribute your package along with the dependencies. And libgpgme should be the only dependency, right? Shipping that as part of the gpg package on pypi would make its adoption easier. Users may have a compatible version of gpg installed, because other packages require gpg or even libgpgme. But not necessarily the python bindings. And having these installed by your distribution is not necessarily an option, although really only current Ubuntu stable comes to my mind. Telling the users now to install everything needed to compile something against your local python version is not as nice as having a manylinux wheel of gpgme that just works. If we're taking Ubuntu stable out of the equation, we still might want users on slow distros to take advantage of a newer python-gpg version. Maybe one that doesn't crash on 32bit. Having a wheel there might help. > I'm more interested in being sure that the example code works (it > should, I was running it as I was writing the thing) and that the > corresponding text descriptions actually help to clarify what's going > on in that code. In the "Key certification" section, I'd appreciate the "expires_in = 2764800" in the example to be more accessible. What is this magic number? I notice that there are no sections about getting keys in and out. For a tool building on OpenPGP that might be an important thing. Cheers, Tobi From justus at gnupg.org Thu Mar 15 15:01:30 2018 From: justus at gnupg.org (Justus Winter) Date: Thu, 15 Mar 2018 15:01:30 +0100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <20180315130049.4sc54dk3zgvmlalq@adversary.org> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> Message-ID: <87lget5tfp.fsf@europa.jade-hamburg.de> Hi Ben, thanks for working on this. Ben McGinnes writes: > https://files.gnupg.net/file/data/ossmg4ung2hcpyyuks6j/PHID-FILE-xgbofmytge7fzn3u5kuc/GPGMEpythonHOWTOen.org > > [...] > > I'm more interested in being sure that the example code works (it > should, I was running it as I was writing the thing) and that the > corresponding text descriptions actually help to clarify what's going > on in that code. I find many examples not very elegant, as in they are not very pythonic and they promote the use of low-level interfaces (op_*). For example: > #+begin_src python > import gpg > import os > > rkey = "0x12345678DEADBEEF" > text = """ > Some plain text to test with. Obtained from any input source Python can read. > > It makes no difference whether it is string or bytes, but the bindings always > produce byte output data. Which is useful to know when writing out either the > encrypted or decrypted results. > > """ > > plain = gpg.core.Data(text) > cipher = gpg.core.Data() In almost all cases, explicit wrapping with core.Data is no longer necessary and provides no benefit. > c = gpg.core.Context() > c.set_armor(1) c = gpg.core.Context(armor=True) > c.op_keylist_start(rkey, 0) > r = c.op_keylist_next() > > if r == None: > print("""The key for user "{0}" was not found""".format(rkey)) r = list(c.keylist(rkey)) if not r: print("The key for user {0!r} was not found".format(rkey)) > else: > try: I see no value in wrapping this in a try-block for demonstration purposes. > c.op_encrypt([r], 1, plain, cipher) > cipher.seek(0, os.SEEK_SET) > del(text) > del(plain) In general, there is no need to del(..) anything. > afile = open("secret_plans.txt.asc", "wb") > afile.write(cipher.read()) > afile.close() > except gpg.errors.GPGMEError as ex: > print(ex.getstring()) c. encrypt(text.encode(), r, sink=open("secret_plans.txt.asc", "w")) > #+end_src Or: > #+begin_src python > import gpg > > text = b"""Oh look, another test message. > > The same rules apply as with the previous example and more likely > than not, the message will actually be drawn from reading the > contents of a file or, maybe, from entering data at an input() > prompt. > > Since the text in this case must be bytes, it is most likely that > the input form will be a separate file which is opened with "rb" > as this is the simplest method of obtaining the correct data > format. > """ > > c = gpg.Context(armor=True) > rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) > logrus = [] > > for i in range(len(rpattern)): > if rpattern[i].can_encrypt == 1: > logrus.append(rpattern[i]) r = [r for r in c.keylist(pattern="@gnupg.org", secret=False) if r.can_encrypt] Also, I don't get 'logrus'. > cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) > > afile = open("secret_plans.txt.asc", "wb") > afile.write(cipher[0]) > afile.close() Again, sink= is better. But if you do want to get results from e.g. .encrypt(..), please use destructuring assignment to get the returned values, e.g.: cipher, _, _ = c.encrypt(...) > #+end_src > #+begin_src python > import os.path > import gpg > > if os.path.exists("/path/to/secret_plans.txt.asc") is True: > ciphertext = "/path/to/secret_plans.txt.asc" 1/ I don't see why example code wouldn't just assume one variant, or maybe even better, take the path as command line argument. 2/ some_predicate is True =^= some_predicate > elif os.path.exists("/path/to/secret_plans.txt.gpg") is True: > ciphertext = "/path/to/secret_plans.txt.gpg" > else: > ciphertext = None > > if ciphertext is not None: Just fail if the input does not exist. > afile = open(ciphertext, "rb") > plaintext = gpg.Context().decrypt(afile) > afile.close() > newfile = open("/path/to/secret_plans.txt", "wb") > newfile.write(plaintext[0]) > newfile.close() > print(plaintext[0]) > plaintext[1] > plaintext[2] Statements without effect. > del(plaintext) Don't del stuff. > else: > pass if pred: pass else: pass =^= if pred: pass > #+end_src Also, I feel like this whole example should be a oneliner: gpg.core.Context().decrypt(sys.stdin, sink=sys.stdout) > signed = c.sign(text, mode=0) Destructuring assignment, please don't use magic values, use symbolic modes instead. > text = text0.encode("utf-8") UTF-8 is the default for .encode() and .decode(). Cheers, Justus -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From ben at adversary.org Thu Mar 15 17:51:18 2018 From: ben at adversary.org (Ben McGinnes) Date: Fri, 16 Mar 2018 03:51:18 +1100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <1521125446.24704.89.camel@cryptobitch.de> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> Message-ID: <20180315165118.ykhafcvox7saspww@adversary.org> On Thu, Mar 15, 2018 at 03:50:46PM +0100, Tobias Mueller wrote: > Hi. > > On Fri, 2018-03-16 at 00:00 +1100, Ben McGinnes wrote: > > I'd appreciate some fresh eyes proof reading it before I merge it with > > master. The full thing, in org-mode format,is here: > > > > https://files.gnupg.net/file/data/ossmg4ung2hcpyyuks6j/PHID-FILE- > > xgbofmytge7fzn3u5kuc/GPGMEpythonHOWTOen.org > Cool, thanks. > > Can you elaborate on this paragraph: > > Most third-party Python packages and modules are available and > distributed through the Python Package Installer, known as PyPI. > > Due to the nature of what these bindings are and how they work, it > is infeasible to install the GPGME Python bindings in the same way. > > Without any further explanation I consider the argument to be weak. > What's the nature and how is it different from all the other binary > packages on pypi? Fair enough, how about adding this paragraph immediately thereafter as an explanation or clarification: This is because the bindings use SWIG to dynamically generate C bindings against =gpgme.h= and =gpgme.h= is generated at compile time when GPGME is built from source. Thus to include a package in PyPI which actually built correctly would require either statically built libraries for every architecture bundled with it or a full implementation of C for each architecture. By the way, each architecture there would mean *both* software (operating system) and hardware. So if we don't want to duplicate the work of glibc, gcc and/or clang (and I assure you, we absolutely do not want to do that) then we'd need to ship statically linked precompiled binaries for Linux, BSD, OS X, Windows, Solaris, AIX, HP-UX, HURD and other operating systems some running on any combination of x86 (i386, i586), x86-64, 68K, RISC, SPARC, UltraSPARC and a few other hardware types. I dont have the hardware to cover all of those. Do you? I'm guessing probably not. Anyway, that's why these bindings don't get pushed to PyPI, because we can't be certain that gpgme.h will build identically everywhere GPGME is installed. If we could be certain then it wouldn't need to be generated from gpgme.h.in in the first place and the bindings would be on PyPI. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From jwilk at jwilk.net Thu Mar 15 17:09:19 2018 From: jwilk at jwilk.net (Jakub Wilk) Date: Thu, 15 Mar 2018 17:09:19 +0100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <20180315130049.4sc54dk3zgvmlalq@adversary.org> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> Message-ID: <20180315160919.qtbicuvjee6pet7g@jwilk.net> * Ben McGinnes , 2018-03-16, 00:00: >https://files.gnupg.net/file/data/ossmg4ung2hcpyyuks6j/PHID-FILE-xgbofmytge7fzn3u5kuc/GPGMEpythonHOWTOen.org I had a superficial look at this: >later version) and the GNU Lesser Public License version 2.1 (or Common misspelling of the license name. Should be: GNU Lesser *General* Public License >strongly anticipated (e.g selecting and encrypting to a key known Missing full stop after "g". >afile = open("secret_plans.txt.asc", "wb") >afile.write(cipher.read()) >afile.close() More idiomatic and with better error handling: with open("secret_plans.txt.asc", "wb") as afile: afile.write(cipher.read()) >c.home_dir = "/tmp/dmgpg" Looks like insecure use of /tmp. -- Jakub Wilk From ben at adversary.org Fri Mar 16 15:23:27 2018 From: ben at adversary.org (Ben McGinnes) Date: Sat, 17 Mar 2018 01:23:27 +1100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <20180315160919.qtbicuvjee6pet7g@jwilk.net> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <20180315160919.qtbicuvjee6pet7g@jwilk.net> Message-ID: <20180316142327.hugw7cwo7enlufvg@adversary.org> On Thu, Mar 15, 2018 at 05:09:19PM +0100, Jakub Wilk wrote: > * Ben McGinnes , 2018-03-16, 00:00: > > https://files.gnupg.net/file/data/ossmg4ung2hcpyyuks6j/PHID-FILE-xgbofmytge7fzn3u5kuc/GPGMEpythonHOWTOen.org > > I had a superficial look at this: > > > later version) and the GNU Lesser Public License version 2.1 (or > > Common misspelling of the license name. Should be: > GNU Lesser *General* Public License Nice catch and since I copied and pasted from elsewhere in the project I'll also go fix those too. > > strongly anticipated (e.g selecting and encrypting to a key known > > Missing full stop after "g". Another nice catch, I'll also doube check any "i.e." instances for the same sort of thing. > > afile = open("secret_plans.txt.asc", "wb") > > afile.write(cipher.read()) > > afile.close() > > More idiomatic and with better error handling: > > with open("secret_plans.txt.asc", "wb") as afile: > afile.write(cipher.read()) Good call. Justus had a number of similar suggestions which I already replied to and I'll be updating those as well as pretty much entirely replacing the first encryption example and the decryption example. > > c.home_dir = "/tmp/dmgpg" > > Looks like insecure use of /tmp. Probably. What I left out was that I'd chmodded the temp directory to 700 and it was going to be removed after running the examples. In fact, it already has been (though I did archive Danger Mouse's key, just in case). Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From dkg at fifthhorseman.net Fri Mar 16 17:14:36 2018 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Fri, 16 Mar 2018 16:14:36 +0000 Subject: [PATCH libgpg-error] syscfg: Add ppc64le cross build support In-Reply-To: <20180314210901.20952-1-bradleyb@fuzziesquirrel.com> References: <20180314210901.20952-1-bradleyb@fuzziesquirrel.com> Message-ID: <87zi38vvyr.fsf@fifthhorseman.net> hi Brad-- On Wed 2018-03-14 17:09:01 -0400, Brad Bishop wrote: > * src/syscfg/lock-obj-pub.ppc64le-unknown-linux-gnu.h: New. > * src/Makefile.am (lock_obj_pub): Add. this looks the same as src/syscfg/lock-obj-pub.powerpc64le-unknown-linux-gnu.h what platform are you building on that produces this triplet? --dkg From bradleyb at fuzziesquirrel.com Fri Mar 16 17:49:14 2018 From: bradleyb at fuzziesquirrel.com (Brad Bishop) Date: Fri, 16 Mar 2018 12:49:14 -0400 Subject: [PATCH libgpg-error] syscfg: Add ppc64le cross build support In-Reply-To: <87zi38vvyr.fsf@fifthhorseman.net> References: <20180314210901.20952-1-bradleyb@fuzziesquirrel.com> <87zi38vvyr.fsf@fifthhorseman.net> Message-ID: <65348DDD-6F9C-4322-A47C-169271990C87@fuzziesquirrel.com> > On Mar 16, 2018, at 12:14 PM, Daniel Kahn Gillmor wrote: > > hi Brad-- > > On Wed 2018-03-14 17:09:01 -0400, Brad Bishop wrote: >> * src/syscfg/lock-obj-pub.ppc64le-unknown-linux-gnu.h: New. >> * src/Makefile.am (lock_obj_pub): Add. > > this looks the same as > src/syscfg/lock-obj-pub.powerpc64le-unknown-linux-gnu.h > > what platform are you building on that produces this triplet? Thanks for having a look! $ uname -a Linux zzzzzz 4.4.0-112-generic #135-Ubuntu SMP Fri Jan 19 11:48:46 UTC 2018 ppc64le ppc64le ppc64le GNU/Linux So I?m building on ppc64le for an arm target. Does that answer the question completely? It seemed like there was some support for aliasing in mkheader (powerpc64le does indeed == ppc64le) but I couldn?t figure it out. Thanks! -brad > > --dkg From dkg at fifthhorseman.net Fri Mar 16 18:11:48 2018 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Fri, 16 Mar 2018 17:11:48 +0000 Subject: [LIBGPG-ERROR PATCH] doc: use compiler flags for yat2m when not cross-built. In-Reply-To: <87lgg6xbnq.fsf@fifthhorseman.net> References: <20180206025330.12028-1-dkg@fifthhorseman.net> <87r2pyvy4r.fsf@wheatstone.g10code.de> <87lgg6xbnq.fsf@fifthhorseman.net> Message-ID: <87vadwvtbf.fsf@fifthhorseman.net> On Tue 2018-02-06 12:36:57 -0500, Daniel Kahn Gillmor wrote: > On Tue 2018-02-06 18:14:28 +0100, Werner Koch wrote: >> so that all flags (in particular AM_CFLAGS) as used as usually. More >> elegant would be [?] > > Any of these work for me. Feel free to commit the version that you > think is the most elegant :) i tried to get the proposed elegant way to work, but my autotools-fu is too weak to do that effectively (i ended up with COMPILE_NATIVE_OR_CROSS being empty somehow) so i'm sticking with the earlier proposed form for the debian packaging. I'd really appreciate having some flavor of this merged upstream, though. if you're ok with the inelegant form, i'm happy to push the commit. if you want the other form, i'm also happy to follow your lead. let me know what you think are the right next steps! --dkg -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From dkg at fifthhorseman.net Fri Mar 16 23:46:51 2018 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Fri, 16 Mar 2018 22:46:51 +0000 Subject: [PATCH libgpg-error] syscfg: Add ppc64le cross build support In-Reply-To: <65348DDD-6F9C-4322-A47C-169271990C87@fuzziesquirrel.com> References: <20180314210901.20952-1-bradleyb@fuzziesquirrel.com> <87zi38vvyr.fsf@fifthhorseman.net> <65348DDD-6F9C-4322-A47C-169271990C87@fuzziesquirrel.com> Message-ID: <87k1ubwsdg.fsf@fifthhorseman.net> On Fri 2018-03-16 12:49:14 -0400, Brad Bishop wrote: >> On Mar 16, 2018, at 12:14 PM, Daniel Kahn Gillmor wrote: >> >> hi Brad-- >> >> On Wed 2018-03-14 17:09:01 -0400, Brad Bishop wrote: >>> * src/syscfg/lock-obj-pub.ppc64le-unknown-linux-gnu.h: New. >>> * src/Makefile.am (lock_obj_pub): Add. >> >> this looks the same as >> src/syscfg/lock-obj-pub.powerpc64le-unknown-linux-gnu.h >> >> what platform are you building on that produces this triplet? > > Thanks for having a look! > > $ uname -a > Linux zzzzzz 4.4.0-112-generic #135-Ubuntu SMP Fri Jan 19 11:48:46 UTC 2018 ppc64le ppc64le ppc64le GNU/Linux > > So I?m building on ppc64le for an arm target. Does that answer the question > completely? It seemed like there was some support for aliasing in mkheader > (powerpc64le does indeed == ppc64le) but I couldn?t figure it out. sorry, this is still confusing to me, but probably because i haven't really internalized the "triplet" platform labeling scheme well enough (i mean, i'm still calling it "triplet" and there are usually 4 fields!) i guess i'm asking why some 64-bit little-endian powerpc machines would get reported as powerpc64le and others would be ppc64le, if they're the same underlying hardware. perhaps someone with more of an understanding of the nuances of different platforms can weigh in here. i don't know enough to be able to make this call. --dkg From dkg at fifthhorseman.net Sat Mar 17 00:20:53 2018 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Fri, 16 Mar 2018 23:20:53 +0000 Subject: libgpg-error 1.28 build failures on arm64 Message-ID: <87efkjwqsq.fsf@fifthhorseman.net> hi folks-- i've uploaded libgpg-error 1.28 to debian. everything is seems ok except that it fails to build from source on arm64: https://buildd.debian.org/status/fetch.php?pkg=libgpg-error&arch=arm64&ver=1.28-1&stamp=1521240615&raw=0 here's the relevant bit of the build log with the failure in it: /bin/bash ../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I../../src -I.. -DLOCALEDIR=\"/usr/share/locale\" -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/<>=. -fstack-protector-strong -Wformat -Werror=format-security -Wall -Wpointer-arith -Wno-psabi -fvisibility=hidden -c -o libgpg_error_la-logging.lo `test -f 'logging.c' || echo '../../src/'`logging.c libtool: compile: gcc -DHAVE_CONFIG_H -I. -I../../src -I.. -DLOCALEDIR=\"/usr/share/locale\" -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/<>=. -fstack-protector-strong -Wformat -Werror=format-security -Wall -Wpointer-arith -Wno-psabi -fvisibility=hidden -c ../../src/logging.c -fPIC -DPIC -o .libs/libgpg_error_la-logging.o ../../src/logging.c: In function '_gpgrt_log_printhex': ../../src/logging.c:1153:49: error: incompatible type for argument 4 of '_gpgrt_logv_printhex' _gpgrt_logv_printhex (buffer, length, NULL, NULL); ^~~~ ../../src/logging.c:1097:1: note: expected 'va_list {aka __va_list}' but argument is of type 'void *' _gpgrt_logv_printhex (const void *buffer, size_t length, ^~~~~~~~~~~~~~~~~~~~ Makefile:1041: recipe for target 'libgpg_error_la-logging.lo' failed make[5]: *** [libgpg_error_la-logging.lo] Error 1 make[5]: Leaving directory '/<>/build/src' make[5]: *** Waiting for unfinished jobs.... make[5]: Entering directory '/<>/build/src' the other platforms seem to build fine: https://buildd.debian.org/status/logs.php?pkg=libgpg-error&ver=1.28-1 any ideas what i should look into for fixing this? --dkg From jwilk at jwilk.net Sat Mar 17 11:52:56 2018 From: jwilk at jwilk.net (Jakub Wilk) Date: Sat, 17 Mar 2018 11:52:56 +0100 Subject: libgpg-error 1.28 build failures on arm64 In-Reply-To: <87efkjwqsq.fsf@fifthhorseman.net> References: <87efkjwqsq.fsf@fifthhorseman.net> Message-ID: <20180317105256.xvnoqcazmhpr55kp@jwilk.net> * Daniel Kahn Gillmor , 2018-03-16, 23:20: >../../src/logging.c: In function '_gpgrt_log_printhex': >../../src/logging.c:1153:49: error: incompatible type for argument 4 of '_gpgrt_logv_printhex' > _gpgrt_logv_printhex (buffer, length, NULL, NULL); > ^~~~ The prototype of the called function is: void _gpgrt_logv_printhex (const void *buffer, size_t length, const char *fmt, va_list arg_ptr) va_list is supposed to be an opaque type, but on most architectures it is a pointer or an array, so you can get away with using NULL. But on arm64 it's a struct, so this breaks. Assuming that arg_ptr is unused when fmt is null, something like this should work: static va_list null_args; _gpgrt_logv_printhex (buffer, length, NULL, null_args); -- Jakub Wilk From wk at gnupg.org Sat Mar 17 19:28:35 2018 From: wk at gnupg.org (Werner Koch) Date: Sat, 17 Mar 2018 19:28:35 +0100 Subject: libgpg-error 1.28 build failures on arm64 In-Reply-To: <20180317105256.xvnoqcazmhpr55kp@jwilk.net> (Jakub Wilk's message of "Sat, 17 Mar 2018 11:52:56 +0100") References: <87efkjwqsq.fsf@fifthhorseman.net> <20180317105256.xvnoqcazmhpr55kp@jwilk.net> Message-ID: <87bmfmeeuk.fsf@wheatstone.g10code.de> On Sat, 17 Mar 2018 11:52, jwilk at jwilk.net said: > va_list is supposed to be an opaque type, but on most architectures it > is a pointer or an array, so you can get away with using NULL. But on > arm64 it's a struct, so this breaks. I was already wondering why I handled this differently at another place but could not found any hints on this, so I assumed this was due to some ancient Unix system and bothered to take care of this. > static va_list null_args; > _gpgrt_logv_printhex (buffer, length, NULL, null_args); static analyzer will likely complain about it ;-) I'll fix in on Monday. Thanks for the background and thanks to dkg for the report. Salam-Shalom, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From muelli at cryptobitch.de Sat Mar 17 23:24:47 2018 From: muelli at cryptobitch.de (Tobias Mueller) Date: Sat, 17 Mar 2018 23:24:47 +0100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <20180315165118.ykhafcvox7saspww@adversary.org> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> Message-ID: <1521325487.24704.219.camel@cryptobitch.de> Hi, On Fri, 2018-03-16 at 03:51 +1100, Ben McGinnes wrote: > Fair enough, how about adding this paragraph immediately thereafter as > an explanation or clarification: yeah, cool. Thanks. I think it's worth discussing the technical aspects further. > > This is because the bindings use SWIG to dynamically generate C > bindings against =gpgme.h= and =gpgme.h= is generated at compile > time when GPGME is built from source. Thus to include a package in > PyPI which actually built correctly would require either statically > built libraries for every architecture bundled with it or a full > implementation of C for each architecture. > I understand that the system's gpgme.h is needed for generating the python bindings. But is that not very similar to other python bindings to (system wide) libraries on PyPI? What's making gpgme more special than those? You don't really have to ship a gpgme.h, do you? Neither for source distribution (you pick the system's header) nor for binary distribution (the header is not needed at runtime, is it?). That's at least how to packages that I know do it. For binary distribution, you don't have to provide things for each and every OS on each and every architecture under the sun. If you provide only a small subset, you've helped already someone installing the library. That is to say, PyPI is quite happy to accept packages without having binaries compiled for HURD on s/390 or BSD on a toaster. So there is no technical limitation in providing only, say, Linux binaries for x86 and x64. Soon the question becomes whether it's worth the hassle to provide a binary package. Of course, for your HURD on s/390 or the BSD on someone's forgotten MIPS laptop, it's probably not really worth the effort. Because it turns out that the consumers of the gpgme bindings published on PyPI are not equally distributed over the combinations of OS and architecture, but rather concentrating on Linux on x64. > By the way, each architecture there would mean *both* software > (operating system) and hardware. I guess it depends on what you want to achieve. If you want to cater for the HURD user with their s/390 server or the single remaining person running Solaris on an UltraSPARC then yes, you'll have trouble providing that. I'd argue that if you publish on PyPI you want to make your library more accessible to people; users and developers alike. I'd further argue that making it more interesting for people to adopt the gpgme Python bindings, providing binaries for Linux on x64 would help a lot, if only because that's where close to all consumers of the gpgme bindings published as binary package on PyPI are. The BSD user who installs everything on their own PCB won't lack the build environment nor the willingness of providing that, so they will be happy to use the source distribution. But if you're creating an OpenPGP-based tool and you're deciding what library to use, then having to have a full build environment for C code may very well scare you away from gpgme. The fact that you can't easily distribute your app, because your users would have to have a full build environment is probably an even heavier argument. A quick comparison of "gpg" and "build-essential" on Debian's popcon seems to indicate that it's much easier to bring gpgme to user's machines if there was a binary package on PyPI. I appreciate that this is not a short-term problem, because Ubuntu stable will just be EOLed soon and that there is no other relevant GNU/Linux distribution which doesn't have a recent enough gpgme along with Python bindings. But the next distribution not shipping a recent enough version will come. Long story short, PEP-513 is quite clear about what it expects and while producing such a manylinux wheel is a bit of an effort, the number of potential consumers might make up for it. Cheers, Tobi From jwilk at jwilk.net Sun Mar 18 00:44:56 2018 From: jwilk at jwilk.net (Jakub Wilk) Date: Sun, 18 Mar 2018 00:44:56 +0100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <1521325487.24704.219.camel@cryptobitch.de> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> Message-ID: <20180317234456.idryu4iy5dll2tkl@jwilk.net> * Tobias Mueller , 2018-03-17, 23:24: >PyPI is quite happy to accept packages without having binaries compiled >for HURD on s/390 or BSD on a toaster. So there is no technical >limitation in providing only, say, Linux binaries for x86 and x64. These are in fact the only architectures currently allowed for Linux wheels: https://www.python.org/dev/peps/pep-0513/#the-manylinux1-policy "Python wheel must [...] work on a stock CentOS 5.11 system [...]. Because CentOS 5 is only available for x86_64 and i686 architectures, these are the only architectures currently supported by the manylinux1 policy." -- Jakub Wilk From wk at gnupg.org Sun Mar 18 17:42:28 2018 From: wk at gnupg.org (Werner Koch) Date: Sun, 18 Mar 2018 17:42:28 +0100 Subject: libgpg-error 1.28 build failures on arm64 In-Reply-To: <20180317105256.xvnoqcazmhpr55kp@jwilk.net> (Jakub Wilk's message of "Sat, 17 Mar 2018 11:52:56 +0100") References: <87efkjwqsq.fsf@fifthhorseman.net> <20180317105256.xvnoqcazmhpr55kp@jwilk.net> Message-ID: <87r2ohcp3f.fsf@wheatstone.g10code.de> On Sat, 17 Mar 2018 11:52, jwilk at jwilk.net said: > static va_list null_args; > _gpgrt_logv_printhex (buffer, length, NULL, null_args); Let's go with this. I pushed but I have no arm64 box to test it at hand. Salam-Shalom, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From vinay_sajip at yahoo.co.uk Sun Mar 18 18:07:02 2018 From: vinay_sajip at yahoo.co.uk (Vinay Sajip) Date: Sun, 18 Mar 2018 17:07:02 +0000 (UTC) Subject: Python bindings HOWTO proof reader request In-Reply-To: References: Message-ID: <1298518696.4077526.1521392822184@mail.yahoo.com> Dear Ben, I am the maintainer of the python-gnupg package. This section about it in your HOWTO is, I believe, incorrect: "Unfortunately it has been beset by a number of security issues, most of which stemmed from using unsafe methods of accessing the command line via the subprocess calls." At one time this was true - the subprocess calls in early versions were made with shell=True and therefore subject to injection attacks. However, this has not been the case for quite some time - subprocess is currently called with shell=False and not (as far as I know) insecure in the way you describe. You also say "most of which stemmed ?from using unsafe methods of accessing the command line" - what were the *other* security issues, and where were they raised / who raised them? Obviously, I want to ensure that python-gnupg has no avoidable security issues, so your feedback would be helpful in achieving this. I would also be grateful if you updated your HOWTO to remove the inaccuracy about python-gnupg. Regards, Vinay Sajip-------------------------------------------------------------Date: Fri, 16 Mar 2018 00:00:49 +1100 From: Ben McGinnes To: gnupg-devel at gnupg.org Subject: Python bindings HOWTO proof reader request Message-ID: <20180315130049.4sc54dk3zgvmlalq at adversary.org> Content-Type: text/plain; charset="us-ascii" Hello, ??? The major work on a HOWTO for the Python bindings is done, but I'd appreciate some fresh eyes proof reading it before I merge it with master.? The full thing, in org-mode format,is here: https://files.gnupg.net/file/data/ossmg4ung2hcpyyuks6j/PHID-FILE-xgbofmytge7fzn3u5kuc/GPGMEpythonHOWTOen.org Don't worry about dialectic differences between American English and Australian or British English, I'll do a translation for en-US later. Also don't worry about the lack of instructions on revoking UIDs or keys, that will be added later too. I'm more interested in being sure that the example code works (it should, I was running it as I was writing the thing) and that the corresponding text descriptions actually help to clarify what's going on in that code. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben at adversary.org Mon Mar 19 04:35:02 2018 From: ben at adversary.org (Ben McGinnes) Date: Mon, 19 Mar 2018 14:35:02 +1100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <1521325487.24704.219.camel@cryptobitch.de> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> Message-ID: <20180319033502.2agldiihu4sfket4@adversary.org> On Sat, Mar 17, 2018 at 11:24:47PM +0100, Tobias Mueller wrote: > Hi, > > On Fri, 2018-03-16 at 03:51 +1100, Ben McGinnes wrote: >> Fair enough, how about adding this paragraph immediately thereafter as >> an explanation or clarification: > yeah, cool. Thanks. Done. :) > I think it's worth discussing the technical aspects further. Okey-dokies ... > I understand that the system's gpgme.h is needed for generating the > python bindings. But is that not very similar to other python bindings > to (system wide) libraries on PyPI? What's making gpgme more special > than those? Essentially it boils down to the dynamic generation of that header file when GPGME is compiled in conjunction with the dynamic generation of the SWIG bindings. If gpgme.h shipped statically with the source then there'd be no problem, but that isn't the case here. > You don't really have to ship a gpgme.h, do you? Yeah, actually we do since that's what GPGME itself depends upon. Take my MUA, for instance, though it's dealing solely with the C code itself it does support GPGME natively (and is compiled with GPGME support). It is explicitly compiled against the version of gpgme.h on this system and it explicitly calls those features of the version of GPGME in the specific path I point it to at compile time (which is usually the current master or pretty close to it). > Neither for source distribution (you pick the system's header) nor for > binary distribution (the header is not needed at runtime, is it?). > That's at least how to packages that I know do it. You've just hit the nail on the head; these bindings don't behave the same way as the ones you're used to do. > For binary distribution, you don't have to provide things for each > and every OS on each and every architecture under the sun. If you > provide only a small subset, you've helped already someone > installing the library. No, but we are already aware of the range of architectures which actively use GnuPG components and attempt to keep binary distributions of any type to a minimum as a result. Although there is another aspect to that, of course, and that is that with crypto projects there is a general preference to not ship binaries at all. We want end users to know their installations were made from the same source code everyone is looking at. We want them to verify the tarballs of that source code and we want them to then compile that source code. These are good habits to encourage. > That is to say, PyPI is quite happy to accept packages without > having binaries compiled for HURD on s/390 or BSD on a toaster. So > there is no technical limitation in providing only, say, Linux > binaries for x86 and x64. As Jakob already pointed out, it's more accurate to say that those are the only options available for Linux binaries on PyPI. > Soon the question becomes whether it's worth the hassle to provide a > binary package. Of course, for your HURD on s/390 or the BSD on > someone's forgotten MIPS laptop, it's probably not really worth the > effort. Because it turns out that the consumers of the gpgme > bindings published on PyPI are not equally distributed over the > combinations of OS and architecture, but rather concentrating on > Linux on x64. So the question then becomes, is that usage enough to justify a special binary built just for Linux x86-64 users or not? Maybe there is? I'm unsure ... since my own usage spans Linux, FreeBSD and OS X ... with the occasional return to Solaris every now and then. On the other hand, I generally make a point of compiling my crypto libraries from source no matter what. OTOH, I know better than to assume that my use case will be the standard. If anything, I'm just not convinced that there is going to be a "standard use case" in this particular field. >> By the way, each architecture there would mean *both* software >> (operating system) and hardware. > > I guess it depends on what you want to achieve. If you want to > cater for the HURD user with their s/390 server or the single > remaining person running Solaris on an UltraSPARC then yes, you'll > have trouble providing that. And yet GnuPG has an extraordinarily wide customer base. Recent posts to gnupg-devel and gnupg-users alone indicates there are still plenty of people using Solaris and GPG. Hell, there are even still people trying to port OpenBSD to every bit of SPARC and UltraSPARC hardware they can get there hands on (and then inevitably run into trouble when they encounter the Fujitsu UltraSPARCs ... but that's quite off-topic). > I'd argue that if you publish on PyPI you want to make your library > more accessible to people; users and developers alike. That's a fair point. > I'd further argue that making it more interesting for people to > adopt the gpgme Python bindings, providing binaries for Linux on x64 > would help a lot, if only because that's where close to all > consumers of the gpgme bindings published as binary package on PyPI > are. This too is a very good point. > The BSD user who installs everything on their own PCB won't > lack the build environment nor the willingness of providing that, so > they will be happy to use the source distribution. Yep. The same actually applies to certain types of OS X users (generally the ones using MacPorts). Homebrew is a car crash in slow motion and so far GPGME is not bundled with GPG Suite (formerly known as GPG Tools). > But if you're creating an OpenPGP-based tool and you're deciding > what library to use, then having to have a full build environment > for C code may very well scare you away from gpgme. Which has been the state of play for a long time, hence wanting to bring it to more players through various types of bindings in the first place. > The fact that you can't easily distribute your app, because your > users would have to have a full build environment is probably an > even heavier argument. Yeah, there's actually a much longer term goal that's aimed at addressing this, but it's still in the early stages and requires further research. > A quick comparison of "gpg" and "build-essential" on Debian's popcon > seems to indicate that it's much easier to bring gpgme to user's > machines if there was a binary package on PyPI. Ah, yes, the Debian ecosystem ... I have a slightly different plan there, but that essentially boils down to convincing dkg to make sure GPGME ships with future Debian releases in whole with the relevant language bindings (specifically the Python bondings and the C++/Qt bindings) should open that up quite nicely. With its inevitable flow-on effect with Debian-based distros. > I appreciate that this is not a short-term problem, Now *that* is a distinct understatement. > because Ubuntu stable will just be EOLed soon and that there is no > other relevant GNU/Linux distribution which doesn't have a recent > enough gpgme along with Python bindings. But the next distribution > not shipping a recent enough version will come. Indeed. > Long story short, Too late! :P > PEP-513 is quite clear about what it expects and while producing > such a manylinux wheel is a bit of an effort, the number of > potential consumers might make up for it. Yes, it might very well do so at that. We'll certainly consider it and if we do decide to change tack there and start pushing binary installs to PyPI then I'll update the HOWTO to reflect that. It would obviously need to remain as accurate as possible (hence giving it a version number from the outset). Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From ben at adversary.org Mon Mar 19 05:10:58 2018 From: ben at adversary.org (ben at adversary.org) Date: Mon, 19 Mar 2018 15:10:58 +1100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <1298518696.4077526.1521392822184@mail.yahoo.com> References: <1298518696.4077526.1521392822184@mail.yahoo.com> Message-ID: <20180319041058.y5s5yrtthtkrhnpl@adversary.org> On Sun, Mar 18, 2018 at 05:07:02PM +0000, Vinay Sajip via Gnupg-devel wrote: > Dear Ben, > I am the maintainer of the python-gnupg package. This section about > it in your HOWTO is, I believe, incorrect: "Unfortunately it has > been beset by a number of security issues, most of which stemmed > from using unsafe methods of accessing the command line via the > subprocess calls." I've amended it to indicate that that was the case in the past, but that efforts have been made to mitigate that. > At one time this was true - the subprocess calls in early versions > were made with shell=True and therefore subject to injection > attacks. However, this has not been the case for quite some time - > subprocess is currently called with shell=False and not (as far as I > know) insecure in the way you describe. The HOWTO was mainly referring to the old shell=True issues and the current change should address that in context. > You also say "most of which stemmed ?from using unsafe methods of > accessing the command line" - what were the *other* security issues, > and where were they raised / who raised them? That also referred to the code you added to prevent certain types of operators being used to inject code even via shell=False, but without going into the full details in what's essentially a short summary. So the "who" there would be you and looking at things like the "UNSAFE" regex mitigation you have on line 93 of the current code. ;) > Obviously, I want to ensure that python-gnupg has no avoidable > security issues, so your feedback would be helpful in achieving > this. Fair enough. I know I've commented on a few past logged issues, but it has been a while (I got distracted by, well, by this project). > I would also be grateful if you updated your HOWTO to remove the > inaccuracy about python-gnupg. Done. Though I stopped short of giving it the complete all clear on the grounds that there hasn't been a full audit of the project recently. I don't think it'll do bad things, but that's not the same as knowing for sure. Also, I stopped using it before the shell changes were made, so I'm not across the most recent updates. For my own projects I briefly used the, now very defunct, PyCrypto library (before the project died), and then switched to my port of pyme and its brief appearance as pyme3 in 2015. Then ultimately updated to the current bindings after Justus worked his magic on pyme3 to make them this thing. I think the last time I really looked at python-gnupg was around the time support was added for enabling multiple signatures of a single file or message. I vaguely recall citing my own key transition statement as the use case for someone else's feature request. So that was clearly a while ago. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From vinay_sajip at yahoo.co.uk Mon Mar 19 09:35:16 2018 From: vinay_sajip at yahoo.co.uk (Vinay Sajip) Date: Mon, 19 Mar 2018 08:35:16 +0000 (UTC) Subject: Python bindings HOWTO proof reader request In-Reply-To: <20180319041058.y5s5yrtthtkrhnpl@adversary.org> References: <1298518696.4077526.1521392822184@mail.yahoo.com> <20180319041058.y5s5yrtthtkrhnpl@adversary.org> Message-ID: <660482912.4468265.1521448516665@mail.yahoo.com> Dear Ben, Thanks for the update. Regards, Vinay Sajip On Monday, 19 March 2018, 04:11:03 GMT, ben at adversary.org wrote: On Sun, Mar 18, 2018 at 05:07:02PM +0000, Vinay Sajip via Gnupg-devel wrote: >? Dear Ben, > I am the maintainer of the python-gnupg package. This section about > it in your HOWTO is, I believe, incorrect: "Unfortunately it has > been beset by a number of security issues, most of which stemmed > from using unsafe methods of accessing the command line via the > subprocess calls." I've amended it to indicate that that was the case in the past, but that efforts have been made to mitigate that. > At one time this was true - the subprocess calls in early versions > were made with shell=True and therefore subject to injection > attacks. However, this has not been the case for quite some time - > subprocess is currently called with shell=False and not (as far as I > know) insecure in the way you describe. The HOWTO was mainly referring to the old shell=True issues and the current change should address that in context. > You also say "most of which stemmed ?from using unsafe methods of > accessing the command line" - what were the *other* security issues, > and where were they raised / who raised them? That also referred to the code you added to prevent certain types of operators being used to inject code even via shell=False, but without going into the full details in what's essentially a short summary. So the "who" there would be you and looking at things like the "UNSAFE" regex mitigation you have on line 93 of the current code.? ;) > Obviously, I want to ensure that python-gnupg has no avoidable > security issues, so your feedback would be helpful in achieving > this. Fair enough.? I know I've commented on a few past logged issues, but it has been a while (I got distracted by, well, by this project). > I would also be grateful if you updated your HOWTO to remove the > inaccuracy about python-gnupg. Done.? Though I stopped short of giving it the complete all clear on the grounds that there hasn't been a full audit of the project recently.? I don't think it'll do bad things, but that's not the same as knowing for sure. Also, I stopped using it before the shell changes were made, so I'm not across the most recent updates.? For my own projects I briefly used the, now very defunct, PyCrypto library (before the project died), and then switched to my port of pyme and its brief appearance as pyme3 in 2015.? Then ultimately updated to the current bindings after Justus worked his magic on pyme3 to make them this thing. I think the last time I really looked at python-gnupg was around the time support was added for enabling multiple signatures of a single file or message.? I vaguely recall citing my own key transition statement as the use case for someone else's feature request.? So that was clearly a while ago. Regards, Ben -------------- next part -------------- An HTML attachment was scrubbed... URL: From dkg at fifthhorseman.net Mon Mar 19 09:11:09 2018 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Mon, 19 Mar 2018 08:11:09 +0000 Subject: Python bindings HOWTO proof reader request In-Reply-To: <20180319033502.2agldiihu4sfket4@adversary.org> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> Message-ID: <87r2ogtrhe.fsf@fifthhorseman.net> On Mon 2018-03-19 14:35:02 +1100, Ben McGinnes wrote: >> A quick comparison of "gpg" and "build-essential" on Debian's popcon >> seems to indicate that it's much easier to bring gpgme to user's >> machines if there was a binary package on PyPI. > > Ah, yes, the Debian ecosystem ... I have a slightly different plan > there, but that essentially boils down to convincing dkg to make sure > GPGME ships with future Debian releases in whole with the relevant > language bindings (specifically the Python bondings and the C++/Qt > bindings) should open that up quite nicely. With its inevitable > flow-on effect with Debian-based distros. I believe debian *does* currently ship gpgme's python bindings (python-gpg and python3-gpg) and C++ (libgpgmepp6) and Qt (libqgpgme7) bindings (and their development headers: libgpgmepp-dev) already. If that's not the case, please explain what you need in more detail, i'd like to fix it. One gap that still does exist is that gpgme's source is only willing to build against one version of python3 at once, which greatly complicates python transitions for packages that depend on python-gpg: https://dev.gnupg.org/T3354 If you'd be willing to reconsider that decision and make it straightforward to build gpgme python bindings against multiple versions of python3 at once, that would make python3-gpg fit much better in the debian ecosystem. Alternately, a pure-python version (using either ctypes or cffi) might be easier to maintain and distribute, requiring the user to "only" fetch the gpgme shared library (and the binaries it ultimately invokes, like gpg, gpgsm, and their associated components like gpg-agent, etc). but i don't want to make any claims about how easy it would be to make that kind of transition while maintaining a stable python API. i suspect it would not be easy. --dkg -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From dkg at fifthhorseman.net Mon Mar 19 15:12:00 2018 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Mon, 19 Mar 2018 14:12:00 +0000 Subject: libgpg-error 1.28 build failures on arm64 In-Reply-To: <87r2ohcp3f.fsf@wheatstone.g10code.de> References: <87efkjwqsq.fsf@fifthhorseman.net> <20180317105256.xvnoqcazmhpr55kp@jwilk.net> <87r2ohcp3f.fsf@wheatstone.g10code.de> Message-ID: <87fu4wtarz.fsf@fifthhorseman.net> On Sun 2018-03-18 17:42:28 +0100, Werner Koch wrote: > On Sat, 17 Mar 2018 11:52, jwilk at jwilk.net said: > >> static va_list null_args; >> _gpgrt_logv_printhex (buffer, length, NULL, null_args); > > Let's go with this. I pushed but I have no arm64 box to test it at > hand. hm, I don't see the push at git://git.gnupg.org/gnupg.git or https://dev.gnupg.org/source/gnupg.git :/ if you give me a branch label or a commit ID to look for, i'll move your preferred fix to the debian buildds so we can evaluate it. --dkg -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From jwilk at jwilk.net Mon Mar 19 17:38:10 2018 From: jwilk at jwilk.net (Jakub Wilk) Date: Mon, 19 Mar 2018 17:38:10 +0100 Subject: libgpg-error 1.28 build failures on arm64 In-Reply-To: <87fu4wtarz.fsf@fifthhorseman.net> References: <87efkjwqsq.fsf@fifthhorseman.net> <20180317105256.xvnoqcazmhpr55kp@jwilk.net> <87r2ohcp3f.fsf@wheatstone.g10code.de> <87fu4wtarz.fsf@fifthhorseman.net> Message-ID: <20180319163810.6urikgijg2xgtu5q@jwilk.net> * Daniel Kahn Gillmor , 2018-03-19, 14:12: >>>static va_list null_args; >>>_gpgrt_logv_printhex (buffer, length, NULL, null_args); >>Let's go with this. I pushed but I have no arm64 box to test it at >>hand. > >hm, I don't see the push at git://git.gnupg.org/gnupg.git or >https://dev.gnupg.org/source/gnupg.git :/ Wrong repo. :) https://dev.gnupg.org/source/libgpg-error.git commit 791177de023574223eddf7288eb7c5a0721ac623 -- Jakub Wilk From dkg at fifthhorseman.net Mon Mar 19 18:11:44 2018 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Mon, 19 Mar 2018 17:11:44 +0000 Subject: libgpg-error 1.28 build failures on arm64 In-Reply-To: <20180319163810.6urikgijg2xgtu5q@jwilk.net> References: <87efkjwqsq.fsf@fifthhorseman.net> <20180317105256.xvnoqcazmhpr55kp@jwilk.net> <87r2ohcp3f.fsf@wheatstone.g10code.de> <87fu4wtarz.fsf@fifthhorseman.net> <20180319163810.6urikgijg2xgtu5q@jwilk.net> Message-ID: <87a7v4t2gf.fsf@fifthhorseman.net> On Mon 2018-03-19 17:38:10 +0100, Jakub Wilk wrote: > * Daniel Kahn Gillmor , 2018-03-19, 14:12: >>>>static va_list null_args; >>>>_gpgrt_logv_printhex (buffer, length, NULL, null_args); >>>Let's go with this. I pushed but I have no arm64 box to test it at >>>hand. >> >>hm, I don't see the push at git://git.gnupg.org/gnupg.git or >>https://dev.gnupg.org/source/gnupg.git :/ > > Wrong repo. :) > https://dev.gnupg.org/source/libgpg-error.git > commit 791177de023574223eddf7288eb7c5a0721ac623 wow, looks like i need more sleep. thanks, Jakub. :P --dkg -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From ben at adversary.org Tue Mar 20 00:26:31 2018 From: ben at adversary.org (Ben McGinnes) Date: Tue, 20 Mar 2018 10:26:31 +1100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <87r2ogtrhe.fsf@fifthhorseman.net> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <87r2ogtrhe.fsf@fifthhorseman.net> Message-ID: <20180319232631.rvinyxj7hti57yhs@adversary.org> On Mon, Mar 19, 2018 at 08:11:09AM +0000, Daniel Kahn Gillmor wrote: > On Mon 2018-03-19 14:35:02 +1100, Ben McGinnes wrote: > > I believe debian *does* currently ship gpgme's python bindings > (python-gpg and python3-gpg) and C++ (libgpgmepp6) and Qt > (libqgpgme7) bindings (and their development headers: > libgpgmepp-dev) already. If that's not the case, please explain > what you need in more detail, i'd like to fix it. Cool, I generally don't use Debian (or RHEL/CentOS) so I wasn't sure on that. My Linux history tended more towards Slackware. In fact it's been pretty much Slackware and Solaris since the '90s (yeah, I know, but that's how I ended up at Sun in the first place). > One gap that still does exist is that gpgme's source is only willing > to build against one version of python3 at once, which greatly > complicates python transitions for packages that depend on > python-gpg: > > https://dev.gnupg.org/T3354 Ah, that. > If you'd be willing to reconsider that decision and make it > straightforward to build gpgme python bindings against multiple > versions of python3 at once, that would make python3-gpg fit much > better in the debian ecosystem. Part of the problem is the M4 code in configure.ac is already pretty hacky as it is. Originally it would only find the first two of each major branch it found and that's since been updated to find the latest release of each major release (i.e. python and python3) in the $PATH at the time GPGME is compiled. The M4 code then calls the relevant Python executables with "setup.py install" to install to site-packages. We may be able to adjust this to check for other versions explicitly and also install for those versions. > Alternately, a pure-python version (using either ctypes or cffi) might > be easier to maintain and distribute, requiring the user to "only" fetch > the gpgme shared library (and the binaries it ultimately invokes, like > gpg, gpgsm, and their associated components like gpg-agent, etc). That is my long term plan: to (ideally) port the damned thing off SWIG entirely and to CFFI. Ctypes are pretty much out since that would result in not only a difficult migration, but also a difficult maintenance path. If you want to see how difficult, have a look at vlc.py which uses ctypes to link to libvlc. It works, but not without some seriously broken bits and it doesn't handle differing release versions at all well (yeah, I contributed a little there too a few years ago and it was a bit migraine inducing). CFFI, on the other hand, has lots of advantageous aspects. Not least of which being that once done it would open up a lot more in the way of platform support, including PyPy and comparable reach to cryptography.py (possibly also to PyCryptodome, the successor to PyCrypto). The problem with CFFI, however, is that it doesn't quite cover all the features of C99 yet and some of the features it doesn't cover are in gpgme.h. There may be ways around these drawbacks to still get it to play nicely, but I'm still researching that. The other possibility is seeing what it takes to get the C parser that CFFI uses updated to cover all of C99, but again I'm not a hundred percent sure what that requires either. So far efforts to convince certain Google engineers to do it haven't worked, but who knows? ;) > but i don't want to make any claims about how easy it would be to > make that kind of transition while maintaining a stable python API. > i suspect it would not be easy. You suspect correctly. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From gniibe at fsij.org Tue Mar 20 06:58:14 2018 From: gniibe at fsij.org (NIIBE Yutaka) Date: Tue, 20 Mar 2018 14:58:14 +0900 Subject: [LIBGPG-ERROR PATCH] doc: use compiler flags for yat2m when not cross-built. In-Reply-To: <87vadwvtbf.fsf@fifthhorseman.net> References: <20180206025330.12028-1-dkg@fifthhorseman.net> <87r2pyvy4r.fsf@wheatstone.g10code.de> <87lgg6xbnq.fsf@fifthhorseman.net> <87vadwvtbf.fsf@fifthhorseman.net> Message-ID: <87370v47bd.fsf@iwagami.gniibe.org> Daniel Kahn Gillmor wrote: > i tried to get the proposed elegant way to work, but my autotools-fu is > too weak to do that effectively (i ended up with COMPILE_NATIVE_OR_CROSS > being empty somehow) so i'm sticking with the earlier proposed form for > the debian packaging. I don't think the elegant way works. Since there is nothing for PROGRAMS, doc/Makefile.in won't have the COMPILE variable. Why not simpler solution? Now (1.28) yat2m is installed by libgpg-error, but it's strange for me that it's for native build only. I think that we should add: bin_PROGRAMS = yat2m so that it will be built and installed (even for cross compiling). And then, configure should detect yat2m on the build system, which will convert .texi files to man. It is possible to support cross compiling with no yat2m installed on the build system yet, but I don't think we should support this situation. Perhaps, it would be better to support this situation, though. -- From gniibe at fsij.org Tue Mar 20 08:00:12 2018 From: gniibe at fsij.org (NIIBE Yutaka) Date: Tue, 20 Mar 2018 16:00:12 +0900 Subject: [LIBGPG-ERROR PATCH] doc: use compiler flags for yat2m when not cross-built. In-Reply-To: <87vadwvtbf.fsf@fifthhorseman.net> References: <20180206025330.12028-1-dkg@fifthhorseman.net> <87r2pyvy4r.fsf@wheatstone.g10code.de> <87lgg6xbnq.fsf@fifthhorseman.net> <87vadwvtbf.fsf@fifthhorseman.net> Message-ID: <87zi332pvn.fsf@iwagami.gniibe.org> I meant a change like this: ========================== diff --git a/configure.ac b/configure.ac index 1e648d1..3918e74 100644 --- a/configure.ac +++ b/configure.ac @@ -80,6 +80,8 @@ AM_PROG_CC_C_O AC_PROG_CPP AC_PROG_AWK AC_CHECK_TOOL(AR, ar, :) +AC_PATH_PROG(YAT2M, "yat2m", "./yat2m" ) +AC_ARG_VAR(YAT2M, [tool to convert texi to man pages]) AC_GNU_SOURCE # Set some variables depending on the platform for later use. diff --git a/doc/Makefile.am b/doc/Makefile.am index d052283..328089a 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -17,11 +17,14 @@ # License along with this program; if not, see . -EXTRA_DIST = HACKING errorref.txt \ - yat2m.c +EXTRA_DIST = HACKING errorref.txt + +bin_PROGRAMS = yat2m +yat2m_SOURCES = yat2m.c +yat2m_CFLAGS= -DPACKAGE_VERSION="\"$(PACKAGE_VERSION)\"" DISTCLEANFILES = gpgrt.cps yat2m-stamp.tmp yat2m-stamp $(myman_pages) -CLEANFILES = yat2m errorref.txt.x +CLEANFILES = errorref.txt.x info_TEXINFOS = gpgrt.texi gpgrt_TEXINFOS = lgpl.texi gpl.texi @@ -34,20 +37,15 @@ myman_pages = gpg-error-config.1 man_MANS = $(myman_pages) -yat2m: yat2m.c - $(CC_FOR_BUILD) -DPACKAGE_VERSION="\"$(PACKAGE_VERSION)\"" \ - -o $@ $(srcdir)/yat2m.c - - yat2m-stamp: $(myman_sources) @rm -f yat2m-stamp.tmp @touch yat2m-stamp.tmp for file in $(myman_sources) ; do \ - ./yat2m $(YAT2M_OPTIONS) --store \ + $(YAT2M) $(YAT2M_OPTIONS) --store \ `test -f '$$file' || echo '$(srcdir)/'`$$file ; done @mv -f yat2m-stamp.tmp $@ -yat2m-stamp: yat2m +yat2m-stamp: $(YAT2M) $(myman_pages) : yat2m-stamp @if test -f $@; then :; else \ @@ -72,22 +70,9 @@ errorref.txt.x : errorref.txt sed '/^##/ d' $< >$@ echo "# Installed by $(PACKAGE_NAME) $(PACKAGE_VERSION)" >>$@ -install-exec-hook: -if CROSS_COMPILING - @echo "not install yat2m while cross-compiling" -else - @echo "installing yat2m on the build system"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)"; \ - $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) \ - yat2m "$(DESTDIR)$(bindir)/yat2m" -endif - install-data-local: errorref.txt.x $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) $(INSTALL_DATA) errorref.txt.x $(DESTDIR)$(pkgdatadir)/errorref.txt uninstall-local: - at rm $(DESTDIR)$(pkgdatadir)/errorref.txt -if !CROSS_COMPILING - - at rm $(DESTDIR)$(bindir)/yat2m -endif -- From wk at gnupg.org Tue Mar 20 07:56:57 2018 From: wk at gnupg.org (Werner Koch) Date: Tue, 20 Mar 2018 07:56:57 +0100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <20180319232631.rvinyxj7hti57yhs@adversary.org> (Ben McGinnes's message of "Tue, 20 Mar 2018 10:26:31 +1100") References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <87r2ogtrhe.fsf@fifthhorseman.net> <20180319232631.rvinyxj7hti57yhs@adversary.org> Message-ID: <87y3inb5fq.fsf@wheatstone.g10code.de> On Tue, 20 Mar 2018 00:26, ben at adversary.org said: > The problem with CFFI, however, is that it doesn't quite cover all the > features of C99 yet and some of the features it doesn't cover are in > gpgme.h. I don't think that we use any C99 features in GPGME. I am considering to use var_args macros in thye future but apart from that I am not zwr of any C99 use. Or do you mean GCC specific features like __attribute__? Those are protected by GCC macros and should thus be no problem as long as the parser works in the pre-processed source. gpgme.h is platform specific but I don't think that can be a real problem. Salam-Shalom, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From wk at gnupg.org Tue Mar 20 08:25:56 2018 From: wk at gnupg.org (Werner Koch) Date: Tue, 20 Mar 2018 08:25:56 +0100 Subject: [LIBGPG-ERROR PATCH] doc: use compiler flags for yat2m when not cross-built. In-Reply-To: <87370v47bd.fsf@iwagami.gniibe.org> (NIIBE Yutaka's message of "Tue, 20 Mar 2018 14:58:14 +0900") References: <20180206025330.12028-1-dkg@fifthhorseman.net> <87r2pyvy4r.fsf@wheatstone.g10code.de> <87lgg6xbnq.fsf@fifthhorseman.net> <87vadwvtbf.fsf@fifthhorseman.net> <87370v47bd.fsf@iwagami.gniibe.org> Message-ID: <87lgenb43f.fsf@wheatstone.g10code.de> On Tue, 20 Mar 2018 06:58, gniibe at fsij.org said: > Now (1.28) yat2m is installed by libgpg-error, but it's strange for me > that it's for native build only. Well, I don't see a reason to build it for the target (host) platform when cross-compiling. yat2m is a tool which is used to build software so when you are cross-compiling it should have been installed. > It is possible to support cross compiling with no yat2m installed on the > build system yet, but I don't think we should support this situation. We already have or will soon have other developments tools in libgpg-error as well. For example the gitlog-to-changelog which will eventually be moved from gnupg to libgpg-error. Is there a real need to cross-build development tools? Shalom-Salam, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From gniibe at fsij.org Tue Mar 20 09:22:49 2018 From: gniibe at fsij.org (NIIBE Yutaka) Date: Tue, 20 Mar 2018 17:22:49 +0900 Subject: [LIBGPG-ERROR PATCH] doc: use compiler flags for yat2m when not cross-built. In-Reply-To: <87vadwvtbf.fsf@fifthhorseman.net> References: <20180206025330.12028-1-dkg@fifthhorseman.net> <87r2pyvy4r.fsf@wheatstone.g10code.de> <87lgg6xbnq.fsf@fifthhorseman.net> <87vadwvtbf.fsf@fifthhorseman.net> Message-ID: <87woy72m1y.fsf@iwagami.gniibe.org> Here is updated version. * For cross compile, configure requires yat2m on the build machine. * For cross compile, yat2m is built and installed. * For native compile, we support the situation yat2m is not yet installed. In this case, we use yat2m now being built. ========================== diff --git a/configure.ac b/configure.ac index 1e648d1..2c23734 100644 --- a/configure.ac +++ b/configure.ac @@ -80,6 +80,7 @@ AM_PROG_CC_C_O AC_PROG_CPP AC_PROG_AWK AC_CHECK_TOOL(AR, ar, :) +AC_ARG_VAR(YAT2M, [tool to convert texi to man pages]) AC_GNU_SOURCE # Set some variables depending on the platform for later use. @@ -138,6 +139,14 @@ fi AC_MSG_RESULT($CC_FOR_BUILD) AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler]) +AC_PATH_PROG(YAT2M, yat2m, ./yat2m) +if test "$cross_compiling" = "yes" -a ac_cv_path_YAT2M = "./yat2m"; then + AC_MSG_ERROR([[ +*** +*** yat2m is not installed on this build system. Please install. +***]]) +fi + AH_BOTTOM([ /* Force using of NLS for W32 even if no libintl has been found. This is diff --git a/doc/Makefile.am b/doc/Makefile.am index d052283..328089a 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -17,11 +17,14 @@ # License along with this program; if not, see . -EXTRA_DIST = HACKING errorref.txt \ - yat2m.c +EXTRA_DIST = HACKING errorref.txt + +bin_PROGRAMS = yat2m +yat2m_SOURCES = yat2m.c +yat2m_CFLAGS= -DPACKAGE_VERSION="\"$(PACKAGE_VERSION)\"" DISTCLEANFILES = gpgrt.cps yat2m-stamp.tmp yat2m-stamp $(myman_pages) -CLEANFILES = yat2m errorref.txt.x +CLEANFILES = errorref.txt.x info_TEXINFOS = gpgrt.texi gpgrt_TEXINFOS = lgpl.texi gpl.texi @@ -34,20 +37,15 @@ myman_pages = gpg-error-config.1 man_MANS = $(myman_pages) -yat2m: yat2m.c - $(CC_FOR_BUILD) -DPACKAGE_VERSION="\"$(PACKAGE_VERSION)\"" \ - -o $@ $(srcdir)/yat2m.c - - yat2m-stamp: $(myman_sources) @rm -f yat2m-stamp.tmp @touch yat2m-stamp.tmp for file in $(myman_sources) ; do \ - ./yat2m $(YAT2M_OPTIONS) --store \ + $(YAT2M) $(YAT2M_OPTIONS) --store \ `test -f '$$file' || echo '$(srcdir)/'`$$file ; done @mv -f yat2m-stamp.tmp $@ -yat2m-stamp: yat2m +yat2m-stamp: $(YAT2M) $(myman_pages) : yat2m-stamp @if test -f $@; then :; else \ @@ -72,22 +70,9 @@ errorref.txt.x : errorref.txt sed '/^##/ d' $< >$@ echo "# Installed by $(PACKAGE_NAME) $(PACKAGE_VERSION)" >>$@ -install-exec-hook: -if CROSS_COMPILING - @echo "not install yat2m while cross-compiling" -else - @echo "installing yat2m on the build system"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)"; \ - $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) \ - yat2m "$(DESTDIR)$(bindir)/yat2m" -endif - install-data-local: errorref.txt.x $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) $(INSTALL_DATA) errorref.txt.x $(DESTDIR)$(pkgdatadir)/errorref.txt uninstall-local: - at rm $(DESTDIR)$(pkgdatadir)/errorref.txt -if !CROSS_COMPILING - - at rm $(DESTDIR)$(bindir)/yat2m -endif -- From ben at adversary.org Tue Mar 20 19:30:46 2018 From: ben at adversary.org (Ben McGinnes) Date: Wed, 21 Mar 2018 05:30:46 +1100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <87y3inb5fq.fsf@wheatstone.g10code.de> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <87r2ogtrhe.fsf@fifthhorseman.net> <20180319232631.rvinyxj7hti57yhs@adversary.org> <87y3inb5fq.fsf@wheatstone.g10code.de> Message-ID: <20180320183046.6ul6jckvimkbj7db@adversary.org> On Tue, Mar 20, 2018 at 07:56:57AM +0100, Werner Koch wrote: > On Tue, 20 Mar 2018 00:26, ben at adversary.org said: > > > The problem with CFFI, however, is that it doesn't quite cover all the > > features of C99 yet and some of the features it doesn't cover are in > > gpgme.h. > > I don't think that we use any C99 features in GPGME. I am considering > to use var_args macros in thye future but apart from that I am not zwr > of any C99 use. I'll have to double check which features or type of features, but I'm fairly sure it wasn't compiler specific. It may not be explicitly C99, though. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From muelli at cryptobitch.de Wed Mar 21 10:49:03 2018 From: muelli at cryptobitch.de (Tobias Mueller) Date: Wed, 21 Mar 2018 10:49:03 +0100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <20180319033502.2agldiihu4sfket4@adversary.org> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> Message-ID: <1521625743.17642.64.camel@cryptobitch.de> hi, On Mon, 2018-03-19 at 14:35 +1100, Ben McGinnes wrote: > On Sat, Mar 17, 2018 at 11:24:47PM +0100, Tobias Mueller wrote: > > I understand that the system's gpgme.h is needed for generating the > > python bindings. But is that not very similar to other python > > bindings > > to (system wide) libraries on PyPI? What's making gpgme more special > > than those? > > Essentially it boils down to the dynamic generation of that header > file when GPGME is compiled But that's before someone installed the python bindings, right? > in conjunction with the dynamic generation > of the SWIG bindings. If gpgme.h shipped statically with the source > then there'd be no problem, but that isn't the case here. > But in case of source distribution, gpgme.h is on the target system, no? And for a binary distribution, gpgme.h doesn't matter. > > You don't really have to ship a gpgme.h, do you? > > Yeah, actually we do since that's what GPGME itself depends upon. wait. what? Of course, gpgme itself does not depend on an existing gpgme.h. The python bindings do. The source distribution of the Python bindings can probably pick the gpgme.h up that is already present on the system. One problem with that approach: When the python bindings make use of features not present in the system's GPGME and thus try to access fields or functions that do not exist. But even then you could argue that having the source up on PyPI helps people finding and installing the library. A binary distribution would neatly solve this problem, assuming gpgme itself being able to deal with older version of gnupg (which it generally does). > > Neither for source distribution (you pick the system's header) nor > > for > > binary distribution (the header is not needed at runtime, is it?). > > That's at least how to packages that I know do it. > > You've just hit the nail on the head; these bindings don't behave the > same way as the ones you're used to do. > I still don't see why it wouldn't. > > For binary distribution, you don't have to provide things for each > > and every OS on each and every architecture under the sun. If you > > provide only a small subset, you've helped already someone > > installing the library. > > No, but we are already aware of the range of architectures which > actively use GnuPG components Right. I assume that people on most of these architectures are happy to compile their own stuff. That's unlike people on consumer hardware. > > Although there is another aspect to that, of course, and that is that > with crypto projects there is a general preference to not ship > binaries at all. Sure. Notice how I started my last email with "discussing the technical bits". Whether you (the general you, not you, personally) actually want to distribute binaries via PyPI is a whole other set of questions. (hint: I'm in favour of doing that) > > That is to say, PyPI is quite happy to accept packages without > > having binaries compiled for HURD on s/390 or BSD on a toaster. So > > there is no technical limitation in providing only, say, Linux > > binaries for x86 and x64. > > As Jakob already pointed out, it's more accurate to say that those are > the only options available for Linux binaries on PyPI. You see what I did there. > So the question then becomes, is that usage enough to justify a > special binary built just for Linux x86-64 users or not? I don't think it's needs to be special. Otherwise, I think your assessment is correct. My na?ve thinking is that the those users benefit the most from a binary distribution on PyPI. Many others are comfortable with a binary distribution via other channels (I'm thinking Windows here), source distribution via PyPI (probably the BSD and other folks who are happy to compile their own stuff), or source distribution via other channels (MacOS probably). And the hassle should be really small. For a release, you probably do a sdist and a bdist anyway to check whether everything builds correctly. Publishing these is a "twine upload" away. > > > By the way, each architecture there would mean *both* software > > > (operating system) and hardware. > > > > I guess it depends on what you want to achieve. If you want to > > cater for the HURD user with their s/390 server or the single > > remaining person running Solaris on an UltraSPARC then yes, you'll > > have trouble providing that. > > And yet GnuPG has an extraordinarily wide customer base. Recent posts > to gnupg-devel and gnupg-users alone indicates there are still plenty > of people using Solaris and GPG. I appreciate that. As by my last argument, these people are happy to provide the necessary infrastructure for building from source. The casual developer for Ubuntu apps, let alone their users, are probably not. > > PEP-513 is quite clear about what it expects and while producing > > such a manylinux wheel is a bit of an effort, the number of > > potential consumers might make up for it. > > Yes, it might very well do so at that. We'll certainly consider it nice. Thanks for this fruitful discussion, Tobi From muelli at cryptobitch.de Wed Mar 21 10:50:38 2018 From: muelli at cryptobitch.de (Tobias Mueller) Date: Wed, 21 Mar 2018 10:50:38 +0100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <20180319232631.rvinyxj7hti57yhs@adversary.org> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <87r2ogtrhe.fsf@fifthhorseman.net> <20180319232631.rvinyxj7hti57yhs@adversary.org> Message-ID: <1521625838.17642.66.camel@cryptobitch.de> hi, On Tue, 2018-03-20 at 10:26 +1100, Ben McGinnes wrote: > That is my long term plan: to (ideally) port the damned thing off SWIG > entirely and to CFFI. hrm. The benefit of SWIG is that it nicely exposes everything the native build does. So it's more work to not expose an existing gpgme feature than it is to implement it in the python bindings. Does CFFI also provide that kind of automatic exposure? There are a few alternatives. Coming from the GNOME camp, I'm thinking gobject-introspection, but gpgme has to come a long way before that's a viable thing to do. But the GNOME ecosystem is reasonably happy with that. Cheers, Tobi From justus at gnupg.org Wed Mar 21 10:57:14 2018 From: justus at gnupg.org (Justus Winter) Date: Wed, 21 Mar 2018 10:57:14 +0100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <1521625838.17642.66.camel@cryptobitch.de> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <87r2ogtrhe.fsf@fifthhorseman.net> <20180319232631.rvinyxj7hti57yhs@adversary.org> <1521625838.17642.66.camel@cryptobitch.de> Message-ID: <87tvt94upx.fsf@thinkbox.jade-hamburg.de> Tobias Mueller writes: > On Tue, 2018-03-20 at 10:26 +1100, Ben McGinnes wrote: >> That is my long term plan: to (ideally) port the damned thing off SWIG >> entirely and to CFFI. > hrm. > The benefit of SWIG is that it nicely exposes everything the native > build does. So it's more work to not expose an existing gpgme feature > than it is to implement it in the python bindings. > Does CFFI also provide that kind of automatic exposure? Yes. You feed it a header file and get an object with a method for every function found in the header. What it does *not* provide is automatic translation of values at the ffi boundary. I consider that a rather cool feature of SWIG. Justus -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From gnupg-devel at sambull.org Wed Mar 21 15:44:25 2018 From: gnupg-devel at sambull.org (Sam Bull) Date: Wed, 21 Mar 2018 14:44:25 +0000 Subject: Web Key Discovery Message-ID: <1521643465.4063.3.camel@sambull.org> Can someone explain if the web key directory might be able to work with my email system? I have >1000 email aliases. Every person I contact gets a new email alias. If someone wants to contact me from my website, they receive a brand new generated address. If I understand correctly, the web key directory must return a key containing a matching email address. It also doesn't seem to support any wildcards, so there needs to be a new PGP key for every single alias. I don't really understand what this requirement actually adds, I don't see how it adds any real security to the protocol, but it seems to make it impossible for me to combine it with my email system. Am I right, or is there a way to make this work with my email system? Thanks, Sam -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: This is a digitally signed message part URL: From gnupg-devel at sambull.org Wed Mar 21 15:44:37 2018 From: gnupg-devel at sambull.org (Sam Bull) Date: Wed, 21 Mar 2018 14:44:37 +0000 Subject: RSS feeds Message-ID: <1521643477.4063.4.camel@sambull.org> Just a small note on the website, neither?https://gnupg.org/blog/?nor https://gnupg.org/news.html?seem to have an RSS feed available. It would be a lot easier to follow updates if there was a feed to subscribe to. Thanks, Sam -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: This is a digitally signed message part URL: From dgouttegattat at incenp.org Wed Mar 21 18:59:17 2018 From: dgouttegattat at incenp.org (Damien Goutte-Gattat) Date: Wed, 21 Mar 2018 17:59:17 +0000 Subject: Web Key Discovery In-Reply-To: <1521643465.4063.3.camel@sambull.org> References: <1521643465.4063.3.camel@sambull.org> Message-ID: Hi, On 03/21/2018 02:44 PM, Sam Bull wrote: > If I understand correctly, the web key directory must return a key containing a > matching email address. It also doesn't seem to support any wildcards, If I understand your setup correctly, your problem is not with the Web Key Directory system, but with OpenPGP itself, as OpenPGP keys indeed don't support wildcards. > so there needs to be a new PGP key for every single alias. Not necessarily. An OpenPGP key can have more than one User ID associated to it. As far as I know, there's no arbitrary limit to the number of User IDs one can attach to a key. I am not sure whether it would be a good idea to have a single key associated to >1000 aliases, but it should be possible. > Am I right, or is there a way to make this work with my email system? If your system generates a new alias on the fly when someone want to contact you, it would have to also add a new User ID to your key at that moment. This is doable, but sounds like a terrible idea to me, as it implies among other things that your server would need to be able to use your master primary key (this is necessary to add any new User ID) at any time. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From astieger at suse.com Wed Mar 21 17:57:16 2018 From: astieger at suse.com (Andreas Stieger) Date: Wed, 21 Mar 2018 17:57:16 +0100 Subject: RSS feeds In-Reply-To: <1521643477.4063.4.camel@sambull.org> References: <1521643477.4063.4.camel@sambull.org> Message-ID: <6178e62f-3154-c111-8784-446230767aa0@suse.com> On 03/21/2018 03:44 PM, Sam Bull wrote: > Just a small note on the website, neither?https://gnupg.org/blog/?nor > https://gnupg.org/news.html?seem to have an RSS feed available. It would be a > lot easier to follow updates if there was a feed to subscribe to. https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg-doc.git;a=rss;f=web/news.org https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg-doc.git;a=rss;f=misc/blog.gnupg.org Andreas -- Andreas Stieger Project Manager Security SUSE Linux GmbH, GF: Felix Imend?rffer, Jane Smithard, Graham Norton, HRB 21284 (AG N?rnberg) From gnupg-devel at sambull.org Thu Mar 22 00:35:14 2018 From: gnupg-devel at sambull.org (Sam Bull) Date: Wed, 21 Mar 2018 23:35:14 +0000 Subject: RSS feeds In-Reply-To: <6178e62f-3154-c111-8784-446230767aa0@suse.com> References: <1521643477.4063.4.camel@sambull.org> <6178e62f-3154-c111-8784-446230767aa0@suse.com> Message-ID: <1521675314.13709.3.camel@sambull.org> Thanks for that. Adding a to the site would make it easier to discover this in the future. On Wed, 2018-03-21 at 17:57 +0100, Andreas Stieger wrote: > On 03/21/2018 03:44 PM, Sam Bull wrote: > > > > Just a small note on the website, neither?https://gnupg.org/blog/?nor > > https://gnupg.org/news.html?seem to have an RSS feed available. It would be > > a > > lot easier to follow updates if there was a feed to subscribe to. > https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg-doc.git;a=rss;f=web/news.org > https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg-doc.git;a=rss;f=misc/blog.gnupg.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: This is a digitally signed message part URL: From gnupg-devel at sambull.org Thu Mar 22 00:52:37 2018 From: gnupg-devel at sambull.org (Sam Bull) Date: Wed, 21 Mar 2018 23:52:37 +0000 Subject: Web Key Discovery In-Reply-To: References: <1521643465.4063.3.camel@sambull.org> Message-ID: <1521676357.13709.9.camel@sambull.org> On Wed, 2018-03-21 at 17:59 +0000, Damien Goutte-Gattat wrote: > On 03/21/2018 02:44 PM, Sam Bull wrote: > > If I understand correctly, the web key directory must return a key > > containing a > > matching email address. It also doesn't seem to support any wildcards, > If I understand your setup correctly, your problem is not with the Web? > Key Directory system, but with OpenPGP itself, as OpenPGP keys indeed? > don't support wildcards. Not necessarily. It's the web key directory that requires a key to match the given email address. For example, I am signing this email without it matching the User ID. If the web key directory didn't require the user ID to match, I could set up a server to return my PGP key for any email address under my domain. I don't see what is added by requiring the user ID to match. Of course, supporting a wildcard in the user ID would also solve this issue. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: This is a digitally signed message part URL: From wk at gnupg.org Thu Mar 22 08:03:48 2018 From: wk at gnupg.org (Werner Koch) Date: Thu, 22 Mar 2018 08:03:48 +0100 Subject: Web Key Discovery In-Reply-To: <1521676357.13709.9.camel@sambull.org> (Sam Bull's message of "Wed, 21 Mar 2018 23:52:37 +0000") References: <1521643465.4063.3.camel@sambull.org> <1521676357.13709.9.camel@sambull.org> Message-ID: <87sh8sa8x7.fsf@wheatstone.g10code.de> On Thu, 22 Mar 2018 00:52, gnupg-devel at sambull.org said: > Not necessarily. It's the web key directory that requires a key to match the > given email address. For example, I am signing this email without it matching That is the whole pint of the web key directory. It maps a mail address to a key. It is possible to map several mail addresses to the same key but the key needs to carry a user ID for each key. > Of course, supporting a wildcard in the user ID would also solve this issue. I am not sure what you mean by wildcard. It would be possible to do a pre-mapping of mail addresses like: foo at example.org -> foo at example.org foo+a at example.org -> foo at example.org foo+b at example.org -> foo at example.org bar+a at example.org -> barexample.org however such a + delimiter is not a universal standard. We could implement a simple scheme like the above on a per domain case, though. Shalom-Salam, Werner -- # Please read: Daniel Ellsberg - The Doomsday Machine # Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From shea at shealevy.com Thu Mar 22 14:18:07 2018 From: shea at shealevy.com (Shea Levy) Date: Thu, 22 Mar 2018 09:18:07 -0400 Subject: [PATCH libgpg-error] syscfg: Add lock-obj-pub file for riscv64-unknown-linux-gnu. Message-ID: <20180322131807.12749-1-shea@shealevy.com> * src/syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h: new. * src/Makefile.am (lock_obj_pub): Add it. Signed-off-by: Shea Levy --- src/Makefile.am | 1 + .../lock-obj-pub.riscv64-unknown-linux-gnu.h | 25 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h diff --git a/src/Makefile.am b/src/Makefile.am index 4446612..5a8cc43 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -65,6 +65,7 @@ lock_obj_pub = \ syscfg/lock-obj-pub.powerpc64-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc64le-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc-unknown-linux-gnuspe.h \ + syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h \ syscfg/lock-obj-pub.s390x-ibm-linux-gnu.h \ syscfg/lock-obj-pub.sh3-unknown-linux-gnu.h \ syscfg/lock-obj-pub.sh4-unknown-linux-gnu.h \ diff --git a/src/syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h b/src/syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h new file mode 100644 index 0000000..8aab9d6 --- /dev/null +++ b/src/syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h @@ -0,0 +1,25 @@ +## lock-obj-pub.riscv64-unknown-linux-gnu.h +## File created by gen-posix-lock-obj - DO NOT EDIT +## To be included by mkheader into gpg-error.h + +typedef struct +{ + long _vers; + union { + volatile char _priv[40]; + long _x_align; + long *_xp_align; + } u; +} gpgrt_lock_t; + +#define GPGRT_LOCK_INITIALIZER {1,{{0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0}}} +## +## Local Variables: +## mode: c +## buffer-read-only: t +## End: +## -- 2.16.2 From shea at shealevy.com Thu Mar 22 14:22:39 2018 From: shea at shealevy.com (Shea Levy) Date: Thu, 22 Mar 2018 09:22:39 -0400 Subject: [PATCH libgpg-error] syscfg: Add lock-obj-pub file for riscv64-unknown-linux-gnu. In-Reply-To: <20180322131807.12749-1-shea@shealevy.com> References: <20180322131807.12749-1-shea@shealevy.com> Message-ID: <87605ogs80.fsf@xps13.shealevy.com> Ack, sorry for the duplication, I thought I had submitted this a month ago but it looks like I hadn't subscribed to the ml and now it's already in! Thanks, Shea Shea Levy writes: > * src/syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h: new. > * src/Makefile.am (lock_obj_pub): Add it. > > Signed-off-by: Shea Levy > --- > src/Makefile.am | 1 + > .../lock-obj-pub.riscv64-unknown-linux-gnu.h | 25 ++++++++++++++++++++++ > 2 files changed, 26 insertions(+) > create mode 100644 src/syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h > > diff --git a/src/Makefile.am b/src/Makefile.am > index 4446612..5a8cc43 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -65,6 +65,7 @@ lock_obj_pub = \ > syscfg/lock-obj-pub.powerpc64-unknown-linux-gnu.h \ > syscfg/lock-obj-pub.powerpc64le-unknown-linux-gnu.h \ > syscfg/lock-obj-pub.powerpc-unknown-linux-gnuspe.h \ > + syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h \ > syscfg/lock-obj-pub.s390x-ibm-linux-gnu.h \ > syscfg/lock-obj-pub.sh3-unknown-linux-gnu.h \ > syscfg/lock-obj-pub.sh4-unknown-linux-gnu.h \ > diff --git a/src/syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h b/src/syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h > new file mode 100644 > index 0000000..8aab9d6 > --- /dev/null > +++ b/src/syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h > @@ -0,0 +1,25 @@ > +## lock-obj-pub.riscv64-unknown-linux-gnu.h > +## File created by gen-posix-lock-obj - DO NOT EDIT > +## To be included by mkheader into gpg-error.h > + > +typedef struct > +{ > + long _vers; > + union { > + volatile char _priv[40]; > + long _x_align; > + long *_xp_align; > + } u; > +} gpgrt_lock_t; > + > +#define GPGRT_LOCK_INITIALIZER {1,{{0,0,0,0,0,0,0,0, \ > + 0,0,0,0,0,0,0,0, \ > + 0,0,0,0,0,0,0,0, \ > + 0,0,0,0,0,0,0,0, \ > + 0,0,0,0,0,0,0,0}}} > +## > +## Local Variables: > +## mode: c > +## buffer-read-only: t > +## End: > +## > -- > 2.16.2 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From ben at adversary.org Fri Mar 23 23:01:51 2018 From: ben at adversary.org (Ben McGinnes) Date: Sat, 24 Mar 2018 09:01:51 +1100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <1521625743.17642.64.camel@cryptobitch.de> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <1521625743.17642.64.camel@cryptobitch.de> Message-ID: <20180323220151.omwmroapyryu6dqn@adversary.org> Sorry for the delayed reply; there's been a few power outages here ... and bush fires. On Wed, Mar 21, 2018 at 10:49:03AM +0100, Tobias Mueller wrote: > hi, > > On Mon, 2018-03-19 at 14:35 +1100, Ben McGinnes wrote: >> On Sat, Mar 17, 2018 at 11:24:47PM +0100, Tobias Mueller wrote: >>> I understand that the system's gpgme.h is needed for generating the >>> python bindings. But is that not very similar to other python >>> bindings >>> to (system wide) libraries on PyPI? What's making gpgme more special >>> than those? >> >> Essentially it boils down to the dynamic generation of that header >> file when GPGME is compiled > But that's before someone installed the python bindings, right? Yes. >> in conjunction with the dynamic generation >> of the SWIG bindings. If gpgme.h shipped statically with the source >> then there'd be no problem, but that isn't the case here. > > But in case of source distribution, gpgme.h is on the target system, > no? And for a binary distribution, gpgme.h doesn't matter. Except you're not going to be able to build a binary distribution without building it from something in the first place and that step is going to need gpgme.h. >>> You don't really have to ship a gpgme.h, do you? >> >> Yeah, actually we do since that's what GPGME itself depends upon. > > wait. what? Of course, gpgme itself does not depend on an existing > gpgme.h. The python bindings do. And so does everything that uses GPGME. Take Mutt for instance; it's accessing the C code in GPGME, but every component that it does this with it does via including gpgme.h. > The source distribution of the Python bindings can probably pick the > gpgme.h up that is already present on the system. Right. Here's the thing, though; if there is already a gpgme.h on the system then GPGME has already been installed and since it is only made available (from gnupg.org) as source then it was compiled for that external system at some point. This means it was either compiled from source on that system or precompiled (e.g. by a Linux distribution for a target architecture) in a way which will "just work" on that system. Since it ships with the bindings, why is that not enough to cover the installation of those bindings at the same time? Why use PyPI instead of the version which would be built against the version of gpgme.h which matches the .so, .dll or .dylib files on the system? For the Python bindings not to be there in the first place would actually require manual intervention to disable them. For PyPI installation to be necessary it is predicated on intervention to disable default build parameters. I don't really see the value in that, though I am aware that some distributions and package managers do precisely that in order to separate the bindings from the library. > One problem with that approach: When the python bindings make use of > features not present in the system's GPGME and thus try to access > fields or functions that do not exist. Also right, but that's at the core of the current recommendation for installation. When GPGME is built from source the resulting gpgme.h file only contains functions that are in that GPGME source code. So when the Python bindings are installed during the same process it has the same features. In theory that means the scenario you describe shouldn't occur. In practice there are a couple of obscure edge cases in the underlying code that might or might not do anything following a bugfix to make it play nicely in i386 systems. Justus knows a bit more about that, though, since he fixed it. ;) > But even then you could argue that having the source up on PyPI helps > people finding and installing the library. Yes, this too is a valid point and as it happens when I last checked there was a version of 1.10.0 on PyPI. I'm just not certain how effective it is compared to a source install. > A binary distribution would neatly solve this problem, assuming > gpgme itself being able to deal with older version of gnupg (which > it generally does). I'm not certain. The bugfix I mentioned above is fairly significant for 32-bit systems and that bugfix was made after GPGME 1.10.0 was released. >>> Neither for source distribution (you pick the system's header) nor >>> for binary distribution (the header is not needed at runtime, is >>> it?). That's at least how to packages that I know do it. >> >> You've just hit the nail on the head; these bindings don't behave >> the same way as the ones you're used to do. >> > I still don't see why it wouldn't. This might be one of those cases where it would become more apparent by looking under the hood. ;) >> No, but we are already aware of the range of architectures which >> actively use GnuPG components > > Right. I assume that people on most of these architectures are happy > to compile their own stuff. That's unlike people on consumer > hardware. This is true, but in these cases it would probably be better to simply ship the entire thing as part of the consumer system's native ecosystem (i.e. including the GPGME library with all the supported language bindings included; including the python bindings and the C++/Qt bindings). >> Although there is another aspect to that, of course, and that is >> that with crypto projects there is a general preference to not ship >> binaries at all. > > Sure. Notice how I started my last email with "discussing the > technical bits". Of course. > Whether you (the general you, not you, personally) actually want to > distribute binaries via PyPI is a whole other set of > questions. (hint: I'm in favour of doing that) I figured, but I'm not convinced that with cryptographic software that's something we really want to encourage. From an ease of use for developers standpoint, I do see the advantages, of course (I've had to install GTK a few times over the years, after all), but there are inherent trust issues (in a general sense) with cryptographic software which we do need to keep in mind. >>> That is to say, PyPI is quite happy to accept packages without >>> having binaries compiled for HURD on s/390 or BSD on a toaster. So >>> there is no technical limitation in providing only, say, Linux >>> binaries for x86 and x64. >> >> As Jakob already pointed out, it's more accurate to say that those are >> the only options available for Linux binaries on PyPI. > > You see what I did there. :D >> So the question then becomes, is that usage enough to justify a >> special binary built just for Linux x86-64 users or not? > > I don't think it's needs to be special. Otherwise, I think your > assessment is correct. Well, in this context any pre-built binary would be special since currently we're not providing any GPGME binaries. To provide a functional Python binary would effectively mean providing GPGME binaries too. If we were to do that, though, then there might be a better way than the sort of wheel you're thinking of, but that gets into some of the options available via CFFI. > My na?ve thinking is that the those users benefit the most from a > binary distribution on PyPI. Many others are comfortable with a > binary distribution via other channels (I'm thinking Windows here), Yes, but Windows is a whole different issue since Windows consistently has problems with SWIG in its entirety and is one of the many reasons for considering moving from SWIG to CFFI. > source distribution via PyPI (probably the BSD and other folks who > are happy to compile their own stuff), or source distribution via > other channels (MacOS probably). MacOS definitely, that's what my current laptop is. ;) > And the hassle should be really small. For a release, you probably > do a sdist and a bdist anyway to check whether everything builds > correctly. Publishing these is a "twine upload" away. Perhaps ... alternatively a straight "configure && make && make check && sudo [-H] make install" with GPGME will install the library and all the available language bindings, including the python ones. >> And yet GnuPG has an extraordinarily wide customer base. Recent >> posts to gnupg-devel and gnupg-users alone indicates there are >> still plenty of people using Solaris and GPG. > > I appreciate that. > As by my last argument, these people are happy to provide the > necessary infrastructure for building from source. This is true. > The casual developer for Ubuntu apps, let alone their users, are > probably not. This is also true, but the question then becomes why the bindings would be deliberately left out of their distribution? Well, aside from certain distributions remaining far behind of current library versions, of course (insert pointed look at both the Ubuntu and RHEL ecosystems here, regardless of whether or not security fixes are backported). >>> PEP-513 is quite clear about what it expects and while producing >>> such a manylinux wheel is a bit of an effort, the number of >>> potential consumers might make up for it. >> >> Yes, it might very well do so at that. We'll certainly consider it > > nice. Yeah, I'm definitely not ruling it out, particularly considering some of the other things under consideration, but it will still depend on the degree of additional effort required and whether or not it introduces too much in the way of either additional points of failure or potential security problems. Not least of which being that if we release it then we *must* support it. Also, I do view this type of binary release as essentially an additional amount of work which is only made necessary by the deliberate actions of third parties to break functionality. That is, it is only necessary because distribution managers have manually removed the bindings from the library in the first place or simply not updated the versions of the libraries they bundle with their distribution in the first place. In some cases both and in some cases the latter is caused by the lack of resources at their end to conduct the same manual intervention of the former on the more recent releases. Now policies like that are fine; their distribution, their choice. A point must come, however, where "fixing" their policy choices through ad-hoc, binary installs via third party systems (in this case PyPI) may not serve the original project best. There must be a point at which it is not the responsibility of a software project to fix the, for lack of a better term, sabotage of a distribution which has modified that software. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From ben at adversary.org Fri Mar 23 23:11:54 2018 From: ben at adversary.org (Ben McGinnes) Date: Sat, 24 Mar 2018 09:11:54 +1100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <1521625838.17642.66.camel@cryptobitch.de> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <87r2ogtrhe.fsf@fifthhorseman.net> <20180319232631.rvinyxj7hti57yhs@adversary.org> <1521625838.17642.66.camel@cryptobitch.de> Message-ID: <20180323221154.wtggxnsc5pwlvsy4@adversary.org> On Wed, Mar 21, 2018 at 10:50:38AM +0100, Tobias Mueller wrote: > hi, > > On Tue, 2018-03-20 at 10:26 +1100, Ben McGinnes wrote: >> That is my long term plan: to (ideally) port the damned thing off SWIG >> entirely and to CFFI. > > hrm. > The benefit of SWIG is that it nicely exposes everything the native > build does. The disadvantage, however, is that SWIG doesn't play nicely on Windows at all, whereas CFFI does (or can). > So it's more work to not expose an existing gpgme feature than it is > to implement it in the python bindings. Does CFFI also provide that > kind of automatic exposure? Proper testing is yet to be done, but I believe there are ways. This isn't something which will happen overnight, though. > There are a few alternatives. Coming from the GNOME camp, I'm > thinking gobject-introspection, but gpgme has to come a long way > before that's a viable thing to do. But the GNOME ecosystem is > reasonably happy with that. I haven't really looked into that one, but I've been mainly looking at solutions that are designed independently of certain very specific ecosystems like GTK and Qt. Though I have considered SIP, but since that's another Riverbank project I'd need to confirm that it has a compatible license first and since that sort of thing has been a problem with Riverbank in the past I'm cautious regarding their code. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From ben at adversary.org Fri Mar 23 23:18:02 2018 From: ben at adversary.org (Ben McGinnes) Date: Sat, 24 Mar 2018 09:18:02 +1100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <87tvt94upx.fsf@thinkbox.jade-hamburg.de> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <87r2ogtrhe.fsf@fifthhorseman.net> <20180319232631.rvinyxj7hti57yhs@adversary.org> <1521625838.17642.66.camel@cryptobitch.de> <87tvt94upx.fsf@thinkbox.jade-hamburg.de> Message-ID: <20180323221802.wx5uei5wehtpmbxq@adversary.org> On Wed, Mar 21, 2018 at 10:57:14AM +0100, Justus Winter wrote: > Tobias Mueller writes: > > > On Tue, 2018-03-20 at 10:26 +1100, Ben McGinnes wrote: > >> That is my long term plan: to (ideally) port the damned thing off SWIG > >> entirely and to CFFI. > > hrm. > > The benefit of SWIG is that it nicely exposes everything the native > > build does. So it's more work to not expose an existing gpgme feature > > than it is to implement it in the python bindings. > > Does CFFI also provide that kind of automatic exposure? > > Yes. You feed it a header file and get an object with a method for > every function found in the header. Yes, but only if that header file does not contain features which are not yet supported by the underlying C parser, which I think gpgme.h currently does. > What it does *not* provide is automatic translation of values at the > ffi boundary. I consider that a rather cool feature of SWIG. It is, but I suspect that that's part of the things which stem from SWIG being its own little intermediate language between C and Python, just like Cython is. Whereas with CFFI you just need to know Python and a bit of C. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From ben at adversary.org Sat Mar 24 01:30:44 2018 From: ben at adversary.org (Ben McGinnes) Date: Sat, 24 Mar 2018 11:30:44 +1100 Subject: RSS feeds In-Reply-To: <1521675314.13709.3.camel@sambull.org> References: <1521643477.4063.4.camel@sambull.org> <6178e62f-3154-c111-8784-446230767aa0@suse.com> <1521675314.13709.3.camel@sambull.org> Message-ID: <20180324003044.5efnv2x2ilsncb2l@adversary.org> On Wed, Mar 21, 2018 at 11:35:14PM +0000, Sam Bull wrote: > > Thanks for that. Adding a to the > site would make it easier to discover this in the future. It would, I've added this to the existing case for adding RSS links which is currently in the "wishlist" category: https://dev.gnupg.org/T3211 Along with a couple of my own notes. As the website is automatically generated from org-mode files adding some things aren't always so obvious to "just add", but we'll see what we can do. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From dkg at fifthhorseman.net Fri Mar 23 21:20:29 2018 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Fri, 23 Mar 2018 20:20:29 +0000 Subject: [LIBGPG-ERROR PATCH] doc: use compiler flags for yat2m when not cross-built. In-Reply-To: <87lgenb43f.fsf@wheatstone.g10code.de> References: <20180206025330.12028-1-dkg@fifthhorseman.net> <87r2pyvy4r.fsf@wheatstone.g10code.de> <87lgg6xbnq.fsf@fifthhorseman.net> <87vadwvtbf.fsf@fifthhorseman.net> <87370v47bd.fsf@iwagami.gniibe.org> <87lgenb43f.fsf@wheatstone.g10code.de> Message-ID: <87lgeio86q.fsf@fifthhorseman.net> On Tue 2018-03-20 08:25:56 +0100, Werner Koch wrote: > On Tue, 20 Mar 2018 06:58, gniibe at fsij.org said: > >> Now (1.28) yat2m is installed by libgpg-error, but it's strange for me >> that it's for native build only. > > Well, I don't see a reason to build it for the target (host) platform > when cross-compiling. yat2m is a tool which is used to build software > so when you are cross-compiling it should have been installed. > >> It is possible to support cross compiling with no yat2m installed on the >> build system yet, but I don't think we should support this situation. > > We already have or will soon have other developments tools in > libgpg-error as well. For example the gitlog-to-changelog which will > eventually be moved from gnupg to libgpg-error. > > Is there a real need to cross-build development tools? if you're trying to bootstrap a new platform, cross-building *some* development tools can be pretty useful. in this case, though, i don't think yat2m qualifies. The bootstrap itself doesn't need documentation -- once you've bootstrapped, you can re-build natively and the native re-build can include the documentation development tools. --dkg From dkg at fifthhorseman.net Sat Mar 24 04:44:53 2018 From: dkg at fifthhorseman.net (Daniel Kahn Gillmor) Date: Fri, 23 Mar 2018 23:44:53 -0400 Subject: Python bindings HOWTO proof reader request In-Reply-To: <20180323220151.omwmroapyryu6dqn@adversary.org> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <1521625743.17642.64.camel@cryptobitch.de> <20180323220151.omwmroapyryu6dqn@adversary.org> Message-ID: <87woy2m91m.fsf@fifthhorseman.net> On Sat 2018-03-24 09:01:51 +1100, Ben McGinnes wrote: > Also, I do view this type of binary release as essentially an > additional amount of work which is only made necessary by the > deliberate actions of third parties to break functionality. That is, > it is only necessary because distribution managers have manually > removed the bindings from the library in the first place or simply not > updated the versions of the libraries they bundle with their > distribution in the first place. In some cases both and in some cases > the latter is caused by the lack of resources at their end to conduct > the same manual intervention of the former on the more recent > releases. speaking as a "distribution manager" (if i understand your terms correctly), i am not "manually removing the bindings from the library". debian administrators want modular systems, and some people run systems with some dependencies installed; others do not. Not everyone who wants libgpgme11 wants the python bindings. Furthermore, some gpgme python bindings are incompatible with some versions of python, but this is not "sabotage" on the part of the distribution manager" -- python3-gpg doesn't work with python3.7 in debian because i *haven't* deviated from upstream practice, so the package was built against python3.6 only. distribution managers are *trying* to do the work needed to make the GnuPG project easier to adopt on their distro. As you've noticed from thinking about the python bindings, it's quite difficult to do, because: a) merely shipping gpgme binary shared objects on a specific platform is a non-trivial task. b) getting the python bindings built against the current version of python is challenging, particularly if the user upgrades their own python installation. c) even if both of the above are sorted out, the GnuPG binary software itself (and all associated daemons) needs to be correctly installed for gpgme to work. distro managers are just about the only people capable of sorting out these complex dependency trees (binaries, shared-objects, python bindings) and wrapping it all up into code that Just Works?. If we're failing, it's not due to some sort of sabotage, it's due to the complexity of the GnuPG architecture. Not many projects require both shared objects and system-level binaries in order for the python bindings to work :/ If you see a way to simplify this further, i'd be happy to hear about it. All the best, --dkg From justus at gnupg.org Sat Mar 24 11:03:23 2018 From: justus at gnupg.org (Justus Winter) Date: Sat, 24 Mar 2018 11:03:23 +0100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <87woy2m91m.fsf@fifthhorseman.net> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <1521625743.17642.64.camel@cryptobitch.de> <20180323220151.omwmroapyryu6dqn@adversary.org> <87woy2m91m.fsf@fifthhorseman.net> Message-ID: <87lgehaiz8.fsf@europa.jade-hamburg.de> Daniel Kahn Gillmor writes: > Furthermore, some gpgme python bindings are incompatible with some > versions of python, but this is not "sabotage" on the part of the > distribution manager" -- python3-gpg doesn't work with python3.7 in > debian because i *haven't* deviated from upstream practice, so the > package was built against python3.6 only. FTR, there is a way to build it for several versions of Python using the 'prepare' target. See 801d7d8c5dd530d26ad6c4bcc94d986e6e022da4. Justus -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From ben at adversary.org Sat Mar 24 20:06:07 2018 From: ben at adversary.org (Ben McGinnes) Date: Sun, 25 Mar 2018 06:06:07 +1100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <87lgehaiz8.fsf@europa.jade-hamburg.de> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <1521625743.17642.64.camel@cryptobitch.de> <20180323220151.omwmroapyryu6dqn@adversary.org> <87woy2m91m.fsf@fifthhorseman.net> <87lgehaiz8.fsf@europa.jade-hamburg.de> Message-ID: <20180324190606.f65vdegamf4hy46m@adversary.org> On Sat, Mar 24, 2018 at 11:03:23AM +0100, Justus Winter wrote: > Daniel Kahn Gillmor writes: > >> Furthermore, some gpgme python bindings are incompatible with some >> versions of python, but this is not "sabotage" on the part of the >> distribution manager" -- python3-gpg doesn't work with python3.7 in >> debian because i *haven't* deviated from upstream practice, so the >> package was built against python3.6 only. > > FTR, there is a way to build it for several versions of Python using > the 'prepare' target. See 801d7d8c5dd530d26ad6c4bcc94d986e6e022da4. Excellent, that means I shouldn't need to modify configure.ac to build for every version possible if doing so is simply a different configuration parameter. Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From ben at adversary.org Sat Mar 24 21:48:30 2018 From: ben at adversary.org (Ben McGinnes) Date: Sun, 25 Mar 2018 07:48:30 +1100 Subject: Python bindings HOWTO proof reader request In-Reply-To: <87woy2m91m.fsf@fifthhorseman.net> References: <20180315130049.4sc54dk3zgvmlalq@adversary.org> <1521125446.24704.89.camel@cryptobitch.de> <20180315165118.ykhafcvox7saspww@adversary.org> <1521325487.24704.219.camel@cryptobitch.de> <20180319033502.2agldiihu4sfket4@adversary.org> <1521625743.17642.64.camel@cryptobitch.de> <20180323220151.omwmroapyryu6dqn@adversary.org> <87woy2m91m.fsf@fifthhorseman.net> Message-ID: <20180324204830.gazovotia5zc4jmk@adversary.org> On Fri, Mar 23, 2018 at 11:44:53PM -0400, Daniel Kahn Gillmor wrote: > On Sat 2018-03-24 09:01:51 +1100, Ben McGinnes wrote: >> Also, I do view this type of binary release as essentially an >> additional amount of work which is only made necessary by the >> deliberate actions of third parties to break functionality. That is, >> it is only necessary because distribution managers have manually >> removed the bindings from the library in the first place or simply not >> updated the versions of the libraries they bundle with their >> distribution in the first place. In some cases both and in some cases >> the latter is caused by the lack of resources at their end to conduct >> the same manual intervention of the former on the more recent >> releases. > > speaking as a "distribution manager" (if i understand your terms > correctly), i am not "manually removing the bindings from the > library". > > debian administrators want modular systems, and some people run > systems with some dependencies installed; others do not. Not > everyone who wants libgpgme11 wants the python bindings. Which I have no problem with, but if they were to subsequently change their minds, surely the solution would be to reinstall the relevant package(s) with the bits left out? Not return to the upstream project and request a custom binary package specifically for the their system architecture and OS and/or distribution (and/or package management format) to be distributed via a third party (regardless of whether or not that third party is related to one or more of the languages the project is implemented in). > Furthermore, some gpgme python bindings are incompatible with some > versions of python, but this is not "sabotage" on the part of the > distribution manager" I also said, "for lack of a better term" for a reason. I don't think it's actually sabotage, but I do see deliberate actions, often made for fairly logical reasons, which remove a particular function. Now that removal is resulting in requests for other means of circumventing those decisions to restore those functions via a means which adds work unnecessarily. > -- python3-gpg doesn't work with python3.7 in debian because i > *haven't* deviated from upstream practice, so the package was built > against python3.6 only. Python 3.7 does not yet have a stable production release and, IIRC, has only just recently entered beta (assuming the release timetable I glanced at recently is on track). That said, it is scheduled for a stable release in the middle of the year and if there are build failures then that should be raised as a bug. > distribution managers are *trying* to do the work needed to make the > GnuPG project easier to adopt on their distro. Which we greatly appreciate. Particularly your work and the team involved in the MacPorts project in particular. I expect to have greater discussions with FreeBSD people in the not too distant future as well (stemming from having a friend in FreeBSD Core). > As you've noticed from thinking about the python bindings, it's > quite difficult to do, because: > > a) merely shipping gpgme binary shared objects on a specific platform > is a non-trivial task. Yes and though with some platforms, like Windows, it might be necessary; it's not something I'm eagerly rushing in to doing unless there really is no other means of getting the thing to work. With Windows it's quite likely that I may need to do something like utilise the CFFI ABI calling methods to get it to play nicely. If that happens then that might turn out to be the means by which Tobias' request might be realised rather than building a Python binary from the SWIG bindings. That sort of thing would still be best served by a platform specific compilation of GPGME, but the ABI calls through CFFI would then reference version specific dynamic libraries in order to Just Work?. > b) getting the python bindings built against the current version of > python is challenging, particularly if the user upgrades their > own python installation. Which I do all the time, though not originally just to test this. > c) even if both of the above are sorted out, the GnuPG binary > software itself (and all associated daemons) needs to be > correctly installed for gpgme to work. Yes, but even the other common GPG wrappers still need most of the same things available. Both python-gnupg (Vinay Sajip's project) and the other one with the conflicting module name and annoying numbering (deliberately inflated to a higher version number in order to override python-gnupg installations) require everything short of GPGME installed to just work. The other major Python cryptography packages are cryptography.py (which depends on recent versions of OpenSSL), PyNaCl (which depends on libsodium and only implements DJB's curves) and PyCryptodome (which implements cryptographic primitives directly in Python instead). None of them actually do exactly what the GnuPG Project does and so there's definitely still value for us continuing to pursue this. > distro managers are just about the only people capable of sorting > out these complex dependency trees (binaries, shared-objects, python > bindings) and wrapping it all up into code that Just Works?. It's not an easy job to package an entire operating system, no matter which approach is taken and that's in both the F[L]OSS and commercial worlds. Having seen the inside of doing the same for commercial UNIX systems, specifically Solaris on all architectures Sun ever sold (including the re-badged Cray, aka the Sun Fire E10K, and the rest of the big iron). > If we're failing, it's not due to some sort of sabotage, it's due to > the complexity of the GnuPG architecture. Yes, which is why I preceded that comment with "for lack of a better term" and "sabotage" isn't really very accurate. Unfortunately I can't think of another word to indicate a deliberate action which produces and unwanted (from one point of view) effect in English (and not for lack of vocabulary ... I know mine's fairly large). > Not many projects require both shared objects and system-level > binaries in order for the python bindings to work :/ I can't actually think of any other projects quite like this. I can think of plenty of other very complex ones, of course, but they're all significantly larger and often either complete operating systems or environments, but there's very few projects which require this level of complexity in order to do one basic thing. In this case I'm referring to all these cryptographic operations as "one basic thing" (so more like one basic type of thing). > If you see a way to simplify this further, i'd be happy to hear > about it. If I think of something, this list will be the first to know (probably shortly after double-checking with a few people off-list that whatever it is isn't me being stupid). ;) Regards, Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From muelli at cryptobitch.de Mon Mar 26 08:59:45 2018 From: muelli at cryptobitch.de (Tobias Mueller) Date: Mon, 26 Mar 2018 08:59:45 +0200 Subject: [PATCH] python: Fix crash by leaving struct members intact In-Reply-To: <1519144454.9285.13.camel@cryptobitch.de> References: <1519144454.9285.13.camel@cryptobitch.de> Message-ID: <1522047585.8710.7.camel@cryptobitch.de> hi. Here's the test case for this crash, hoping that this fast-tracks this patch. It crashes reliably on my 32bit Debian system. As Justus mentioned, this is blocking us here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=884900 Cheers, Tobi -------------- next part -------------- A non-text attachment was scrubbed... Name: 32bit-crash.py Type: text/x-python Size: 2046 bytes Desc: not available URL: From gniibe at fsij.org Mon Mar 26 13:13:13 2018 From: gniibe at fsij.org (NIIBE Yutaka) Date: Mon, 26 Mar 2018 20:13:13 +0900 Subject: [PATCH libgpg-error] syscfg: Add ppc64le cross build support In-Reply-To: <87k1ubwsdg.fsf@fifthhorseman.net> References: <20180314210901.20952-1-bradleyb@fuzziesquirrel.com> <87zi38vvyr.fsf@fifthhorseman.net> <65348DDD-6F9C-4322-A47C-169271990C87@fuzziesquirrel.com> <87k1ubwsdg.fsf@fifthhorseman.net> Message-ID: <87370nrsxi.fsf@fsij.org> Daniel Kahn Gillmor wrote: > i guess i'm asking why some 64-bit little-endian powerpc machines would > get reported as powerpc64le and others would be ppc64le, if they're the > same underlying hardware. > > perhaps someone with more of an understanding of the nuances of > different platforms can weigh in here. i don't know enough to be able > to make this call. The triplet for "ppc64el" is powerpc64le-unknown-linux-gnu. We already have supported it in libgpg-error. For cross building, please specify correct triplet for the host. It should be powerpc64le-unknown-linux-gnu when you build for ppc64le. (Well, you should have cross compiler which supports powerpc64le-unknown-linux-gnu beforehand, so, you should know the triplet.) Name of machine type (I mean the output of uname -m), CPU in the triplet, architecture name for distribution may be different. -- From gnupg-devel at sambull.org Mon Mar 26 14:41:30 2018 From: gnupg-devel at sambull.org (Sam Bull) Date: Mon, 26 Mar 2018 13:41:30 +0100 Subject: Web Key Discovery In-Reply-To: <87sh8sa8x7.fsf@wheatstone.g10code.de> References: <1521643465.4063.3.camel@sambull.org> <1521676357.13709.9.camel@sambull.org> <87sh8sa8x7.fsf@wheatstone.g10code.de> Message-ID: <1522068090.3927.5.camel@sambull.org> On Thu, 2018-03-22 at 08:03 +0100, Werner Koch wrote: > On Thu, 22 Mar 2018 00:52, gnupg-devel at sambull.org said: > > Not necessarily. It's the web key directory that requires a key to match the > > given email address. For example, I am signing this email without it > > matching > That is the whole point of the web key directory. > > It maps a mail address to a key.??It is possible to map several mail > addresses to the same key but the key needs to carry a user ID for each > key. Right, but it seems to require mapping the key to the mail address as well, i.e. it must match in both directions. If it was only matching an address to a key, then I could configure my server to map all email addresses to the key I am currently using. This is the correct key that people should use to contact me, but the user ID would not match, therefore doesn't work when you require the key to also map to the address. > > Of course, supporting a wildcard in the user ID would also solve this issue. > I am not sure what you mean by wildcard. Well, for example, the email I am using for this mailing list is gnupg-devel at sambull.org. So, each unique email is a full email under my personal domain. So by wildcard, I mean something like "*@sambull.org" matching any valid address under my domain name. Thanks, Sam -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: This is a digitally signed message part URL: From dgouttegattat at incenp.org Thu Mar 29 14:52:57 2018 From: dgouttegattat at incenp.org (Damien Goutte-Gattat) Date: Thu, 29 Mar 2018 13:52:57 +0100 Subject: [PATCH gpa] Load the secret keyring before the public one. In-Reply-To: <20180219095946.5307-1-dgouttegattat@incenp.org> References: <20180219095946.5307-1-dgouttegattat@incenp.org> Message-ID: <20180329125257.1671-1-dgouttegattat@incenp.org> Hi GnuPG folks, I sent the patch below a few weeks ago to tentatively fix bug 3748, which affects GPA when using a TOFU trust model. Any follow-up on this? I am not sure this is the best way to fix 3748, but for what it's worth, I am using GPA with this patch applied since I first posted it and never ran into the bug again, nor into any other problem. -- >8 -- Subject: [PATCH gpa] Load the secret keyring before the public one. * src/keylist.c (gpa_keylist_init): Forcefully load the secret keyring before attempting to load the public keys. -- Gpa loads the private keyring in a kind of "lazy mode", in that the private keyring is only loaded the first time Gpa needs to lookup a private key. This normally happens during the loading of the public keyring, since for each public key Gpa must lookup in the private keyring to check whether a private counterpart is available. The result is that a Gpg process is spawn to list the secret keys while another Gpg process is still listing the public keys. If the trust model happens to be TOFU or TOFU+PGP, this can cause some problems with regard to the locking of the TOFU database. To avoid that, this patch makes sure the private keyring is actively and synchronously loaded before we fetch the public keys (no more lazy loading). GnuPG-bug-id: 3748 Signed-off-by: Damien Goutte-Gattat --- src/keylist.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/keylist.c b/src/keylist.c index 442da08..2c8e7e8 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -231,7 +231,16 @@ gpa_keylist_init (GTypeInstance *instance, void *class_ptr) } else { - /* Initialize from the global keytable. */ + /* Initialize from the global keytable. + * + * We must forcefully load the secret keytable first to + * prevent concurrent access to the TOFU database. */ + gpa_keytable_force_reload (gpa_keytable_get_secret_instance (), + NULL, (GpaKeyTableEndFunc) gtk_main_quit, + NULL); + gtk_main (); + + /* Now we can load the public keyring. */ gpa_keytable_list_keys (gpa_keytable_get_public_instance(), gpa_keylist_next, gpa_keylist_end, list); } -- 2.14.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: not available URL: