From cvs at cvs.gnupg.org Thu Mar 1 13:47:19 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 01 Mar 2018 13:47:19 +0100 Subject: [git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-56-g3e851be Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, async-enc has been updated via 3e851bed56cba229a1a6de656c6639ffbc288081 (commit) via 16cf48705599010e380bc7c72ba8b2d945006471 (commit) via d6246cd90e33d530cfecf654cecc097d73bef038 (commit) via 6ec4348a7e575921db013b6cc9d1f0d07ae0ddb8 (commit) via eb1ed3493ebe49cbbb61fb4deb311f44f553b176 (commit) via 456cdf6165ef012769058507b5ef3edde729ca47 (commit) via 14d0e2d9d1e0f058ee391363aeee67614d9a7734 (commit) via 7700f5da2744cc7aa718aaaeedc66618b4088bff (commit) via dc2f7424d081c1de0b639b3ab52aaa8092077c27 (commit) via 13ec7979aaff33e2d3112bc397ab0a291ffade2f (commit) from 325b90573a184b65bf1d66e5f6f0eebeb9f0d6ea (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3e851bed56cba229a1a6de656c6639ffbc288081 Author: Andre Heinecke Date: Thu Mar 1 13:46:50 2018 +0100 Minor wait cleanup in overlay * src/overlay.cpp (Overlay::~Overlay): Wait afteer writing the quit. diff --git a/src/overlay.cpp b/src/overlay.cpp index f1467b9..8e088d6 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -81,8 +81,8 @@ Overlay::~Overlay() { log_debug ("%s:%s: Stopping overlay.", SRCNAME, __func__); - m_overlayCtx->wait (); m_overlayStdin.write ("quit\n", 5); m_overlayStdin.write (nullptr, 0); + m_overlayCtx->wait (); EnableWindow (m_wid, TRUE); } commit 16cf48705599010e380bc7c72ba8b2d945006471 Author: Andre Heinecke Date: Thu Mar 1 13:46:13 2018 +0100 Localize keyresolver * src/cryptcontroller.cpp (CryptController::resolve_keys): Add --lang argument. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index e2e4570..8557cc4 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -375,24 +375,23 @@ CryptController::resolve_keys () release_cArray (recipients); } - // Convert our collected vector to c strings - // It's a bit overhead but should be quick for such small - // data. - char **cargs = vector_to_cArray (args); + args.push_back (std::string ("--lang")); + args.push_back (std::string (gettext_localename ())); // Args are prepared. Spawn the resolver. auto ctx = GpgME::Context::createForEngine (GpgME::SpawnEngine); - if (!ctx) { // can't happen - release_cArray (cargs); TRACEPOINT; return -1; } - GpgME::Data mystdin (GpgME::Data::null), mystdout, mystderr; + // Convert our collected vector to c strings + // It's a bit overhead but should be quick for such small + // data. + char **cargs = vector_to_cArray (args); #ifdef DEBUG_RESOLVER log_debug ("Spawning args:"); for (size_t i = 0; cargs && cargs[i]; i++) @@ -401,6 +400,7 @@ CryptController::resolve_keys () } #endif + GpgME::Data mystdin (GpgME::Data::null), mystdout, mystderr; GpgME::Error err = ctx->spawn (cargs[0], const_cast (cargs), mystdin, mystdout, mystderr, (GpgME::Context::SpawnFlags) ( commit d6246cd90e33d530cfecf654cecc097d73bef038 Author: Andre Heinecke Date: Thu Mar 1 13:39:06 2018 +0100 Add keycache for located keys * src/keycache.cpp, src/keycache.h: New. * src/Makefile.am: Add new files. * src/mail.cpp (in_de_vs_mode): Move to cpphelp. Rename global maps to s_ prefix to be more clear. (Mail::locate_keys): Use keycache. (do_locate): Removed. (Mail::locate_all_crypto_recipents): New. * src/cpphelp.cpp: Add in_de_vs_mode. * src/ribbon-callbacks.cpp (mark_mime_action): Trigger locate on crypto toggle. -- Every serious MUA needs a Keycache ;-) This is needed to store the keys returned by gpg --locate-keys if we want to use them later to automatically send to the keys located this way. diff --git a/src/Makefile.am b/src/Makefile.am index 7ef1edd..125265d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -88,7 +88,8 @@ gpgol_SOURCES = \ cryptcontroller.cpp cryptcontroller.h \ cpphelp.cpp cpphelp.h \ wks-helper.cpp wks-helper.h \ - overlay.cpp overlay.h + overlay.cpp overlay.h \ + keycache.cpp keycache.h #treeview_SOURCES = treeview.c diff --git a/src/cpphelp.cpp b/src/cpphelp.cpp index 20b91d3..85c8db3 100644 --- a/src/cpphelp.cpp +++ b/src/cpphelp.cpp @@ -26,6 +26,10 @@ #include "common.h" +#include +#include +#include + void release_cArray (char **carray) { @@ -55,3 +59,55 @@ vector_to_cArray(const std::vector &vec) ret[vec.size()] = NULL; return ret; } + +bool +in_de_vs_mode() +{ +/* We cache the values only once. A change requires restart. + This is because checking this is very expensive as gpgconf + spawns each process to query the settings. */ + static bool checked; + static bool vs_mode; + + if (checked) + { + return vs_mode; + } + GpgME::Error err; + const auto components = GpgME::Configuration::Component::load (err); + log_debug ("%s:%s: Checking for de-vs mode.", + SRCNAME, __func__); + if (err) + { + log_error ("%s:%s: Failed to get gpgconf components: %s", + SRCNAME, __func__, err.asString ()); + checked = true; + vs_mode = false; + return vs_mode; + } + for (const auto &component: components) + { + if (component.name () && !strcmp (component.name (), "gpg")) + { + for (const auto &option: component.options ()) + { + if (option.name () && !strcmp (option.name (), "compliance") && + option.currentValue ().stringValue () && + !stricmp (option.currentValue ().stringValue (), "de-vs")) + { + log_debug ("%s:%s: Detected de-vs mode", + SRCNAME, __func__); + checked = true; + vs_mode = true; + return vs_mode; + } + } + checked = true; + vs_mode = false; + return vs_mode; + } + } + checked = true; + vs_mode = false; + return false; +} diff --git a/src/cpphelp.h b/src/cpphelp.h index 0b60170..bbf68e0 100644 --- a/src/cpphelp.h +++ b/src/cpphelp.h @@ -36,4 +36,7 @@ void rtrim(std::string &s); /* Convert a string vector to a null terminated char array */ char **vector_to_cArray (const std::vector &vec); +/* Check if we are in de_vs mode. */ +bool in_de_vs_mode (); + #endif // CPPHELP_H diff --git a/src/keycache.cpp b/src/keycache.cpp new file mode 100644 index 0000000..3907772 --- /dev/null +++ b/src/keycache.cpp @@ -0,0 +1,366 @@ +/* @file keycache.cpp + * @brief Internal keycache + * + * Copyright (C) 2018 Intevation GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#include "keycache.h" + +#include "common.h" +#include "cpphelp.h" + +#include +#include +#include + +#include + +#include + +GPGRT_LOCK_DEFINE (keycache_lock); +static KeyCache* singleton = nullptr; + +class KeyCache::Private +{ +public: + Private() + { + + } + + void setPgpKey(const char *mbox, const GpgME::Key &key) + { + const std::string sMbox(mbox); + + gpgrt_lock_lock (&keycache_lock); + auto it = m_pgp_key_map.find (sMbox); + + if ( it == m_pgp_key_map.end ()) + { + m_pgp_key_map.insert (std::pair (sMbox, GpgME::Key())); + } + else + { + it->second = key; + } + gpgrt_lock_unlock (&keycache_lock); + } + + void setSmimeKey(const char *mbox, const GpgME::Key &key) + { + const std::string sMbox(mbox); + + gpgrt_lock_lock (&keycache_lock); + auto it = m_smime_key_map.find (sMbox); + + if ( it == m_smime_key_map.end ()) + { + m_smime_key_map.insert (std::pair (sMbox, GpgME::Key())); + } + else + { + it->second = key; + } + gpgrt_lock_unlock (&keycache_lock); + } + + GpgME::Key getKey (const char *addr, GpgME::Protocol proto) + { + if (!addr) + { + return GpgME::Key(); + } + auto mbox = GpgME::UserID::addrSpecFromString (addr); + + if (proto == GpgME::OpenPGP) + { + gpgrt_lock_lock (&keycache_lock); + const auto it = m_pgp_key_map.find (mbox); + + if (it == m_pgp_key_map.end ()) + { + gpgrt_lock_unlock (&keycache_lock); + return GpgME::Key(); + } + const auto ret = it->second; + gpgrt_lock_unlock (&keycache_lock); + + return ret; + } + gpgrt_lock_lock (&keycache_lock); + const auto it = m_smime_key_map.find (mbox); + + if (it == m_smime_key_map.end ()) + { + gpgrt_lock_unlock (&keycache_lock); + return GpgME::Key(); + } + const auto ret = it->second; + gpgrt_lock_unlock (&keycache_lock); + + return ret; + } + + GpgME::Key getSigningKey (const char *addr, GpgME::Protocol proto) + { + const auto key = getKey (addr, proto); + if (key.isNull()) + { + return key; + } + if (!key.canReallySign()) + { + log_mime_parser ("%s:%s: Discarding key for %s because it can't sign", + SRCNAME, __func__, addr); + return GpgME::Key(); + } + if (!key.hasSecret()) + { + log_mime_parser ("%s:%s: Discarding key for %s because it has no secret", + SRCNAME, __func__, addr); + return GpgME::Key(); + } + if (in_de_vs_mode () && !key.isDeVs()) + { + log_mime_parser ("%s:%s: signing key for %s is not deVS", + SRCNAME, __func__, addr); + return GpgME::Key(); + } + return key; + } + + std::vector getEncryptionKeys (const char **recipients, + GpgME::Protocol proto) + { + std::vector ret; + if (!recipients) + { + TRACEPOINT; + return ret; + } + for (int i = 0; recipients[i]; i++) + { + const auto key = getKey (recipients[i], proto); + if (key.isNull()) + { + log_mime_parser ("%s:%s: No key for %s. no internal encryption", + SRCNAME, __func__, recipients[i]); + return std::vector(); + } + + if (!key.canEncrypt() || key.isRevoked() || + key.isExpired() || key.isDisabled() || key.isInvalid()) + { + log_mime_parser ("%s:%s: Invalid key for %s. no internal encryption", + SRCNAME, __func__, recipients[i]); + return std::vector(); + } + + if (in_de_vs_mode () && key.isDeVs ()) + { + log_mime_parser ("%s:%s: key for %s is not deVS", + SRCNAME, __func__, recipients[i]); + return std::vector(); + } + + bool validEnough = false; + /* Here we do the check if the key is valid for this recipient */ + const auto addrSpec = GpgME::UserID::addrSpecFromString (recipients[i]); + for (const auto &uid: key.userIDs ()) + { + if (addrSpec != uid.addrSpec()) + { + // Ignore unmatching addr specs + continue; + } + if (uid.validity() >= GpgME::UserID::Marginal) + { + validEnough = true; + break; + } + } + if (!validEnough) + { + log_mime_parser ("%s:%s: UID for %s does not have at least marginal trust", + SRCNAME, __func__, recipients[i]); + return std::vector(); + } + // Accepting key + ret.push_back (key); + } + return ret; + } + + std::map m_pgp_key_map; + std::map m_smime_key_map; +}; + +KeyCache::KeyCache(): + d(new Private) +{ +} + +KeyCache * +KeyCache::instance () +{ + if (!singleton) + { + singleton = new KeyCache(); + } + return singleton; +} + +GpgME::Key +KeyCache::getSigningKey (const char *addr, GpgME::Protocol proto) const +{ + return d->getSigningKey (addr, proto); +} + +std::vector +KeyCache::getEncryptionKeys (const char **recipients, GpgME::Protocol proto) const +{ + return d->getEncryptionKeys (recipients, proto); +} + +static DWORD WINAPI +do_locate (LPVOID arg) +{ + char *addr = (char*) arg; + + log_mime_parser ("%s:%s searching key for addr: \"%s\"", + SRCNAME, __func__, addr); + + const auto k = GpgME::Key::locate (addr); + + if (!k.isNull ()) + { + log_mime_parser ("%s:%s found key for addr: \"%s\":%s", + SRCNAME, __func__, addr, k.primaryFingerprint()); + KeyCache::instance ()->setPgpKey (addr, k); + } + + if (opt.enable_smime) + { + auto ctx = GpgME::Context::createForProtocol (GpgME::OpenPGP); + if (!ctx) + { + TRACEPOINT; + xfree (addr); + return 0; + } + // We need to validate here to fetch CRL's + ctx->setKeyListMode (GpgME::KeyListMode::Local | + GpgME::KeyListMode::Validate); + GpgME::Error e = ctx->startKeyListing (addr); + if (e) + { + TRACEPOINT; + xfree (addr); + return 0; + } + + std::vector keys; + GpgME::Error err; + do { + keys.push_back(ctx->nextKey(err)); + } while (!err); + keys.pop_back(); + delete ctx; + + GpgME::Key candidate; + for (const auto &key: keys) + { + if (key.isRevoked() || key.isExpired() || + key.isDisabled() || key.isInvalid()) + { + log_mime_parser ("%s:%s: Skipping invalid S/MIME key", + SRCNAME, __func__); + continue; + } + if (candidate.isNull() || !candidate.numUserIDs()) + { + if (key.numUserIDs() && + candidate.userID(0).validity() <= key.userID(0).validity()) + { + candidate = key; + } + } + } + if (!candidate.isNull()) + { + log_mime_parser ("%s:%s found SMIME key for addr: \"%s\":%s", + SRCNAME, __func__, addr, candidate.primaryFingerprint()); + KeyCache::instance()->setSmimeKey (addr, candidate); + } + } + xfree (addr); + + log_debug ("%s:%s locator thread done", + SRCNAME, __func__); + return 0; +} + +void KeyCache::startLocate (char **recipients) const +{ + log_debug ("%s:%s start locate", + SRCNAME, __func__); + if (!recipients) + { + TRACEPOINT; + return; + } + gpgrt_lock_lock (&keycache_lock); + log_debug ("%s:%s locked", + SRCNAME, __func__); + + for (int i = 0; recipients[i]; i++) + { + log_debug ("%s:%s looking tat %s", + SRCNAME, __func__, recipients[i]); + std::string recp = GpgME::UserID::addrSpecFromString (recipients[i]); + if (recp.empty ()) + { + continue; + } + if (d->m_pgp_key_map.find (recp) == d->m_pgp_key_map.end ()) + { + // It's enough to look at the PGP Key map. We marked + // searched keys there. + d->m_pgp_key_map.insert (std::pair (recp, GpgME::Key())); + log_debug ("%s:%s Creating a locator thread", + SRCNAME, __func__); + HANDLE thread = CreateThread (NULL, 0, do_locate, + (LPVOID) strdup (recp.c_str ()), 0, + NULL); + CloseHandle (thread); + } + } + gpgrt_lock_unlock (&keycache_lock); +} + +void +KeyCache::setSmimeKey(const char *mbox, const GpgME::Key &key) +{ + d->setSmimeKey(mbox, key); +} + +void +KeyCache::setPgpKey(const char *mbox, const GpgME::Key &key) +{ + d->setPgpKey(mbox, key); +} diff --git a/src/keycache.h b/src/keycache.h new file mode 100644 index 0000000..7f68fe2 --- /dev/null +++ b/src/keycache.h @@ -0,0 +1,74 @@ +#ifndef KEYCACHE_H +#define KEYCACHE_H + +/* @file keycache.h + * @brief Internal keycache + * + * Copyright (C) 2018 Intevation GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#include "config.h" + +#include +#include + +#include + +namespace GpgME +{ + class Key; +}; + +class KeyCache +{ +protected: + /** Internal ctor */ + explicit KeyCache (); + +public: + /** Get the KeyCache */ + static KeyCache* instance (); + + /* Try to find a key for signing in the internal + cache. If no proper key is found a Null key is + returned.*/ + GpgME::Key getSigningKey (const char *addr, GpgME::Protocol proto) const; + + /* Get the keys for recipents. The keys + are taken from the internal cache. If + one recipient can't be resolved an empty + list is returned. */ + std::vector getEncryptionKeys (const char **recipients, + GpgME::Protocol proto) const; + + /* Start a key location in a background thread filling + the key cache. cArray is a null terminated array + of address strings. */ + void startLocate (char **cArray) const; + + + // Internal for thread + void setSmimeKey(const char *mbox, const GpgME::Key &key); + void setPgpKey(const char *mbox, const GpgME::Key &key); + +private: + class Private; + std::shared_ptr d; +}; + +#endif diff --git a/src/mail.cpp b/src/mail.cpp index 818dc69..7405328 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -38,6 +38,8 @@ #include "windowmessages.h" #include "mlang-charset.h" #include "wks-helper.h" +#include "keycache.h" +#include "cpphelp.h" #include #include @@ -59,64 +61,12 @@ using namespace GpgME; -static std::map g_mail_map; -static std::map g_uid_map; +static std::map s_mail_map; +static std::map s_uid_map; static std::set uids_searched; static Mail *s_last_mail; -static bool -in_de_vs_mode() -{ - /* We cache the values only once. A change requires restart. - This is because checking this is very expensive as gpgconf - spawns each process to query the settings. */ - static bool checked; - static bool vs_mode; - - if (checked) - { - return vs_mode; - } - Error err; - const auto components = Configuration::Component::load (err); - log_debug ("%s:%s: Checking for de-vs mode.", - SRCNAME, __func__); - if (err) - { - log_error ("%s:%s: Failed to get gpgconf components: %s", - SRCNAME, __func__, err.asString ()); - checked = true; - vs_mode = false; - return vs_mode; - } - for (const auto &component: components) - { - if (component.name () && !strcmp (component.name (), "gpg")) - { - for (const auto &option: component.options ()) - { - if (option.name () && !strcmp (option.name (), "compliance") && - option.currentValue ().stringValue () && - !stricmp (option.currentValue ().stringValue (), "de-vs")) - { - log_debug ("%s:%s: Detected de-vs mode", - SRCNAME, __func__); - checked = true; - vs_mode = true; - return vs_mode; - } - } - checked = true; - vs_mode = false; - return vs_mode; - } - } - checked = true; - vs_mode = false; - return false; -} - #define COPYBUFSIZE (8 * 1024) Mail::Mail (LPDISPATCH mailitem) : @@ -161,7 +111,7 @@ Mail::Mail (LPDISPATCH mailitem) : gpgol_release(mailitem); return; } - g_mail_map.insert (std::pair (mailitem, this)); + s_mail_map.insert (std::pair (mailitem, this)); s_last_mail = this; } @@ -180,18 +130,18 @@ Mail::~Mail() detach_MailItemEvents_sink (m_event_sink); gpgol_release(m_event_sink); - it = g_mail_map.find(m_mailitem); - if (it != g_mail_map.end()) + it = s_mail_map.find(m_mailitem); + if (it != s_mail_map.end()) { - g_mail_map.erase (it); + s_mail_map.erase (it); } if (!m_uuid.empty()) { - auto it2 = g_uid_map.find(m_uuid); - if (it2 != g_uid_map.end()) + auto it2 = s_uid_map.find(m_uuid); + if (it2 != s_uid_map.end()) { - g_uid_map.erase (it2); + s_uid_map.erase (it2); } } @@ -222,8 +172,8 @@ Mail::get_mail_for_item (LPDISPATCH mailitem) return NULL; } std::map::iterator it; - it = g_mail_map.find(mailitem); - if (it == g_mail_map.end()) + it = s_mail_map.find(mailitem); + if (it == s_mail_map.end()) { return NULL; } @@ -237,8 +187,8 @@ Mail::get_mail_for_uuid (const char *uuid) { return NULL; } - auto it = g_uid_map.find(std::string(uuid)); - if (it == g_uid_map.end()) + auto it = s_uid_map.find(std::string(uuid)); + if (it == s_uid_map.end()) { return NULL; } @@ -248,8 +198,8 @@ Mail::get_mail_for_uuid (const char *uuid) bool Mail::is_valid_ptr (const Mail *mail) { - auto it = g_mail_map.begin(); - while (it != g_mail_map.end()) + auto it = s_mail_map.begin(); + while (it != s_mail_map.end()) { if (it->second == mail) return true; @@ -1415,7 +1365,7 @@ Mail::close_all_mails () int err = 0; std::map::iterator it; TRACEPOINT; - std::map mail_map_copy = g_mail_map; + std::map mail_map_copy = s_mail_map; for (it = mail_map_copy.begin(); it != mail_map_copy.end(); ++it) { /* XXX For non racy code the is_valid_ptr check should not @@ -1449,7 +1399,7 @@ Mail::revert_all_mails () { int err = 0; std::map::iterator it; - for (it = g_mail_map.begin(); it != g_mail_map.end(); ++it) + for (it = s_mail_map.begin(); it != s_mail_map.end(); ++it) { if (it->second->revert ()) { @@ -1474,7 +1424,7 @@ Mail::wipe_all_mails () { int err = 0; std::map::iterator it; - for (it = g_mail_map.begin(); it != g_mail_map.end(); ++it) + for (it = s_mail_map.begin(); it != s_mail_map.end(); ++it) { if (it->second->wipe ()) { @@ -1953,7 +1903,7 @@ Mail::set_uuid() SRCNAME, __func__, m_mailitem, uuid); delete other; } - g_uid_map.insert (std::pair (m_uuid, this)); + s_uid_map.insert (std::pair (m_uuid, this)); log_debug ("%s:%s: uuid for %p is now %s", SRCNAME, __func__, this, m_uuid.c_str()); @@ -2450,71 +2400,12 @@ Mail::get_sig_fpr() const return m_sig.fingerprint(); } - -static DWORD WINAPI -do_locate (LPVOID arg) -{ - char *recipient = (char*) arg; - log_debug ("%s:%s searching key for recipient: \"%s\"", - SRCNAME, __func__, recipient); - Context *ctx = Context::createForProtocol (OpenPGP); - - if (!ctx) - { - TRACEPOINT; - return 0; - } - - ctx->setKeyListMode (GpgME::Extern | GpgME::Local); - ctx->startKeyListing (recipient, false); - - std::vector keys; - Error err; - do { - keys.push_back (ctx->nextKey(err)); - } while (!err); - keys.pop_back (); - ctx->endKeyListing (); - delete ctx; - - if (keys.size ()) - { - log_debug ("%s:%s found key for recipient: \"%s\"", - SRCNAME, __func__, recipient); - } - xfree (recipient); - // do_in_ui_thread (UNKNOWN, NULL); - return 0; -} - -GPGRT_LOCK_DEFINE(uids_searched_lock); - /** Try to locate the keys for all recipients */ void Mail::locate_keys() { - gpgrt_lock_lock (&uids_searched_lock); char ** recipients = get_recipients (); - - if (!recipients) - { - TRACEPOINT; - return; - } - for (int i = 0; recipients[i]; i++) - { - std::string recp = recipients[i]; - if (uids_searched.find (recp) == uids_searched.end ()) - { - uids_searched.insert (recp); - HANDLE thread = CreateThread (NULL, 0, do_locate, - (LPVOID) strdup(recipients[i]), 0, - NULL); - CloseHandle (thread); - } - xfree (recipients[i]); - } - xfree (recipients); - gpgrt_lock_unlock (&uids_searched_lock); + KeyCache::instance()->startLocate (recipients); + release_cArray (recipients); } bool @@ -2756,3 +2647,22 @@ Mail::get_last_mail () } return s_last_mail; } + +// static +void +Mail::locate_all_crypto_recipients() +{ + if (!opt.autoresolve) + { + return; + } + + std::map::iterator it; + for (it = s_mail_map.begin(); it != s_mail_map.end(); ++it) + { + if (it->second->needs_crypto ()) + { + it->second->locate_keys (); + } + } +} diff --git a/src/mail.h b/src/mail.h index 53c0e23..f8cdbab 100644 --- a/src/mail.h +++ b/src/mail.h @@ -133,6 +133,18 @@ public: */ static int close_all_mails (); + /** @brief locate recipients for all crypto mails + * + * To avoid lookups of recipients for non crypto mails we only + * locate keys when a crypto action is already selected. + * + * As the user can do this after recipients were added but + * we don't know for which mail the crypt button was triggered. + * we march over all mails and if they are crypto mails we check + * that the recipents were located. + */ + static void locate_all_crypto_recipients (); + /** @brief Reference to the mailitem. Do not Release! */ LPDISPATCH item () { return m_mailitem; } diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp index e579026..4f7d0a9 100644 --- a/src/ribbon-callbacks.cpp +++ b/src/ribbon-callbacks.cpp @@ -1357,6 +1357,11 @@ mark_mime_action (LPDISPATCH ctrl, int flags, bool is_explorer) we invalidate a lot *sigh* */ gpgoladdin_invalidate_ui (); + if (newflags & 1) + { + Mail::locate_all_crypto_recipients (); + } + done: gpgol_release (context); gpgol_release (mailitem); commit 6ec4348a7e575921db013b6cc9d1f0d07ae0ddb8 Author: Andre Heinecke Date: Thu Mar 1 13:37:38 2018 +0100 Fix surprising toggle behavior * src/ribbon-callbacks.cpp (mark_mime_action): If a sub action was active click on secure activates both sign and encrypt. diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp index 92c3e36..e579026 100644 --- a/src/ribbon-callbacks.cpp +++ b/src/ribbon-callbacks.cpp @@ -1333,7 +1333,16 @@ mark_mime_action (LPDISPATCH ctrl, int flags, bool is_explorer) oldflags = get_gpgol_draft_info_flags (message); - newflags = oldflags xor flags; + if (flags == 3 && oldflags != 3) + { + // If only one sub button is active activate + // both now. + newflags = 3; + } + else + { + newflags = oldflags xor flags; + } if (set_gpgol_draft_info_flags (message, newflags)) { commit eb1ed3493ebe49cbbb61fb4deb311f44f553b176 Merge: 325b905 456cdf6 Author: Andre Heinecke Date: Tue Feb 27 07:50:01 2018 +0100 Merge branch 'master' into async-enc diff --cc src/mapihelp.cpp index 4647ee1,0c1bff3..7e33823 --- a/src/mapihelp.cpp +++ b/src/mapihelp.cpp @@@ -1140,10 -1182,22 +1182,26 @@@ change_message_class_ipm_note_smime_mul { newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned"); } + else if (!strcmp (ct, "wks.confirmation.mail")) + { + newvalue = xstrdup ("IPM.Note.GpgOL.WKSConfirmation"); + } + else if (ct && !strcmp (ct, "application/ms-tnef")) + { + /* So no PGP Inline. Lets look at the attachment. */ + char *attach_mime = get_first_attach_mime_tag (message); + if (!attach_mime) + { + xfree (ct); + xfree (proto); + return nullptr; + } + if (!strcmp (attach_mime, "multipart/signed")) + { + newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned"); + xfree (attach_mime); + } + } xfree (proto); xfree (ct); } ----------------------------------------------------------------------- Summary of changes: src/Makefile.am | 3 +- src/cpphelp.cpp | 56 ++++++++ src/cpphelp.h | 3 + src/cryptcontroller.cpp | 14 +- src/keycache.cpp | 366 +++++++++++++++++++++++++++++++++++++++++++++++ src/keycache.h | 74 ++++++++++ src/mail.cpp | 196 ++++++++----------------- src/mail.h | 12 ++ src/mapihelp.cpp | 66 ++++++++- src/oomhelp.h | 5 + src/overlay.cpp | 2 +- src/parsecontroller.cpp | 12 +- src/ribbon-callbacks.cpp | 69 +++++---- 13 files changed, 706 insertions(+), 172 deletions(-) create mode 100644 src/keycache.cpp create mode 100644 src/keycache.h hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 1 16:14:29 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 01 Mar 2018 16:14:29 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-1.1.0-4-g141fd94 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The standard pinentry collection". The branch, master has been updated via 141fd941a58f70692cb6244f011e54b005d2195c (commit) from 84d473f5c323a3001374b0db736af9be4e3478a3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 141fd941a58f70692cb6244f011e54b005d2195c Author: Andre Heinecke Date: Thu Mar 1 16:12:28 2018 +0100 qt: Renable Windows Foreground Window hacks * qt/main.cpp, qt/pinentryconfirm.cpp: Use raiseWindow again. * qt/pinentrydialog.cpp: Renable Foreground Window hacks. -- Enabled this again because the focus did not change to the pinentry window without the attach thread input stuff. The setup_foreground_window helps though, so that stays. Either Qt Windows foreign Window Management is a mess and does not really work or I don't understand it. diff --git a/qt/main.cpp b/qt/main.cpp index f236781..fe88d26 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -292,7 +292,7 @@ qt_cmd_handler(pinentry_t pe) } box.show(); - box.raise(); + raiseWindow(&box); const int rc = box.exec(); diff --git a/qt/pinentryconfirm.cpp b/qt/pinentryconfirm.cpp index e549e10..65b191c 100644 --- a/qt/pinentryconfirm.cpp +++ b/qt/pinentryconfirm.cpp @@ -38,7 +38,7 @@ PinentryConfirm::PinentryConfirm(Icon icon, int timeout, const QString &title, setAccessibleDescription(desc); setAccessibleName(title); #endif - raise(); + raiseWindow(this); } bool PinentryConfirm::timedOut() const @@ -61,7 +61,7 @@ void PinentryConfirm::showEvent(QShowEvent *event) } QDialog::showEvent(event); - raise(); + raiseWindow(this); } void PinentryConfirm::slotTimeout() diff --git a/qt/pinentrydialog.cpp b/qt/pinentrydialog.cpp index 9bff8d2..5212f88 100644 --- a/qt/pinentrydialog.cpp +++ b/qt/pinentrydialog.cpp @@ -41,7 +41,6 @@ #include #endif -#if 0 /* I [wk] have no idea for what this code was supposed to do. Foregrounding a window is heavily restricted by modern Windows versions. This is the reason why gpg-agent employs its @@ -57,6 +56,11 @@ [ah 2018-02-28] Disabled this again in favor of using windows stays on top hint. The code that is in main setup_foreground_window. + + [ah 2018-03-01] Enabled this again because the focus did + not change to the pinentry window without the attach + thread input stuff. The setup_foreground_window helps though + so that stays enabled. */ #ifdef Q_OS_WIN WINBOOL SetForegroundWindowEx(HWND hWnd) @@ -108,8 +112,6 @@ void raiseWindow(QWidget *w) #endif } -#endif - QPixmap icon(QStyle::StandardPixmap which) { QPixmap pm = qApp->windowIcon().pixmap(48, 48); @@ -266,7 +268,7 @@ PinEntryDialog::PinEntryDialog(QWidget *parent, const char *name, void PinEntryDialog::showEvent(QShowEvent *event) { QDialog::showEvent(event); - raise(); + raiseWindow(this); } void PinEntryDialog::setDescription(const QString &txt) ----------------------------------------------------------------------- Summary of changes: qt/main.cpp | 2 +- qt/pinentryconfirm.cpp | 4 ++-- qt/pinentrydialog.cpp | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 1 16:17:52 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 01 Mar 2018 16:17:52 +0100 Subject: [git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-58-gab5232c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, async-enc has been updated via ab5232cb52e4265be48c1d4d977aae45ad91f844 (commit) via 93b423f9632b7740dbf0a21341898fb3efb48b4a (commit) from 3e851bed56cba229a1a6de656c6639ffbc288081 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ab5232cb52e4265be48c1d4d977aae45ad91f844 Author: Andre Heinecke Date: Thu Mar 1 16:16:09 2018 +0100 Use keycache to autoresolve * lots of changes. -- The keycache is now used if opt.autoresolve is set to resolve the signing / encryption keys without loading the resolver binary. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index 8557cc4..a977e79 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -28,6 +28,7 @@ #include "mimemaker.h" #include "wks-helper.h" #include "overlay.h" +#include "keycache.h" #include #include @@ -76,12 +77,14 @@ CryptController::CryptController (Mail *mail, bool encrypt, bool sign, { log_debug ("%s:%s: CryptController ctor for %p encrypt %i sign %i inline %i.", SRCNAME, __func__, mail, encrypt, sign, doInline); + m_recipient_addrs = mail->take_cached_recipients (); } CryptController::~CryptController() { log_debug ("%s:%s:%p", SRCNAME, __func__, m_mail); + release_cArray (m_recipient_addrs); } int @@ -298,10 +301,65 @@ CryptController::parse_output (GpgME::Data &resolverOutput) } int +CryptController::resolve_keys_cached() +{ + const auto cache = KeyCache::instance(); + + bool fallbackToSMIME = false; + + if (m_encrypt) + { + m_recipients = cache->getEncryptionKeys((const char **)m_recipient_addrs, GpgME::OpenPGP); + + if (m_recipients.empty() && opt.enable_smime) + { + m_recipients = cache->getEncryptionKeys((const char **)m_recipient_addrs, GpgME::CMS); + fallbackToSMIME = true; + } + if (m_recipients.empty()) + { + log_debug ("%s:%s: Failed to resolve keys through cache", + SRCNAME, __func__); + return 1; + } + } + + if (m_sign) + { + if (!fallbackToSMIME) + { + m_signer_key = cache->getSigningKey (m_mail->get_cached_sender ().c_str (), + GpgME::OpenPGP); + } + if (m_signer_key.isNull() && opt.enable_smime) + { + m_signer_key = cache->getSigningKey (m_mail->get_cached_sender ().c_str (), + GpgME::CMS); + } + if (m_signer_key.isNull()) + { + log_debug ("%s:%s: Failed to resolve signer key through cache", + SRCNAME, __func__); + m_recipients.clear(); + return 1; + } + } + return 0; +} + +int CryptController::resolve_keys () { m_recipients.clear(); + if (opt.autoresolve && !resolve_keys_cached ()) + { + log_debug ("%s:%s: resolved keys through the cache", + SRCNAME, __func__); + start_crypto_overlay(); + return 0; + } + std::vector args; // Collect the arguments @@ -366,13 +424,10 @@ CryptController::resolve_keys () { args.push_back (std::string ("--encrypt")); // Get the recipients that are cached from OOM - char **recipients = m_mail->take_cached_recipients (); - for (size_t i = 0; recipients && recipients[i]; i++) + for (size_t i = 0; m_recipient_addrs && m_recipient_addrs[i]; i++) { - args.push_back (GpgME::UserID::addrSpecFromString (recipients[i])); + args.push_back (GpgME::UserID::addrSpecFromString (m_recipient_addrs[i])); } - - release_cArray (recipients); } args.push_back (std::string ("--lang")); diff --git a/src/cryptcontroller.h b/src/cryptcontroller.h index ebcd4e0..9398c5b 100644 --- a/src/cryptcontroller.h +++ b/src/cryptcontroller.h @@ -66,6 +66,7 @@ public: private: int resolve_keys (); + int resolve_keys_cached (); int parse_output (GpgME::Data &resolverOutput); int lookup_fingerprints (const std::string &sigFpr, const std::vector recpFprs); @@ -83,6 +84,7 @@ private: GpgME::Key m_signer_key; std::vector m_recipients; std::unique_ptr m_overlay; + char **m_recipient_addrs; }; #endif diff --git a/src/keycache.cpp b/src/keycache.cpp index 3907772..73011aa 100644 --- a/src/keycache.cpp +++ b/src/keycache.cpp @@ -50,9 +50,9 @@ public: gpgrt_lock_lock (&keycache_lock); auto it = m_pgp_key_map.find (sMbox); - if ( it == m_pgp_key_map.end ()) + if (it == m_pgp_key_map.end ()) { - m_pgp_key_map.insert (std::pair (sMbox, GpgME::Key())); + m_pgp_key_map.insert (std::pair (sMbox, key)); } else { @@ -68,9 +68,45 @@ public: gpgrt_lock_lock (&keycache_lock); auto it = m_smime_key_map.find (sMbox); - if ( it == m_smime_key_map.end ()) + if (it == m_smime_key_map.end ()) + { + m_smime_key_map.insert (std::pair (sMbox, key)); + } + else + { + it->second = key; + } + gpgrt_lock_unlock (&keycache_lock); + } + + void setPgpKeySecret(const char *mbox, const GpgME::Key &key) + { + const std::string sMbox(mbox); + + gpgrt_lock_lock (&keycache_lock); + auto it = m_pgp_skey_map.find (sMbox); + + if (it == m_pgp_skey_map.end ()) { - m_smime_key_map.insert (std::pair (sMbox, GpgME::Key())); + m_pgp_skey_map.insert (std::pair (sMbox, key)); + } + else + { + it->second = key; + } + gpgrt_lock_unlock (&keycache_lock); + } + + void setSmimeKeySecret(const char *mbox, const GpgME::Key &key) + { + const std::string sMbox(mbox); + + gpgrt_lock_lock (&keycache_lock); + auto it = m_smime_skey_map.find (sMbox); + + if (it == m_smime_skey_map.end ()) + { + m_smime_skey_map.insert (std::pair (sMbox, key)); } else { @@ -116,11 +152,50 @@ public: return ret; } + GpgME::Key getSKey (const char *addr, GpgME::Protocol proto) + { + if (!addr) + { + return GpgME::Key(); + } + auto mbox = GpgME::UserID::addrSpecFromString (addr); + + if (proto == GpgME::OpenPGP) + { + gpgrt_lock_lock (&keycache_lock); + const auto it = m_pgp_skey_map.find (mbox); + + if (it == m_pgp_skey_map.end ()) + { + gpgrt_lock_unlock (&keycache_lock); + return GpgME::Key(); + } + const auto ret = it->second; + gpgrt_lock_unlock (&keycache_lock); + + return ret; + } + gpgrt_lock_lock (&keycache_lock); + const auto it = m_smime_skey_map.find (mbox); + + if (it == m_smime_skey_map.end ()) + { + gpgrt_lock_unlock (&keycache_lock); + return GpgME::Key(); + } + const auto ret = it->second; + gpgrt_lock_unlock (&keycache_lock); + + return ret; + } + GpgME::Key getSigningKey (const char *addr, GpgME::Protocol proto) { - const auto key = getKey (addr, proto); + const auto key = getSKey (addr, proto); if (key.isNull()) { + log_mime_parser ("%s:%s: secret key for %s is null", + SRCNAME, __func__, addr); return key; } if (!key.canReallySign()) @@ -208,6 +283,8 @@ public: std::map m_pgp_key_map; std::map m_smime_key_map; + std::map m_pgp_skey_map; + std::map m_smime_skey_map; }; KeyCache::KeyCache(): @@ -256,7 +333,7 @@ do_locate (LPVOID arg) if (opt.enable_smime) { - auto ctx = GpgME::Context::createForProtocol (GpgME::OpenPGP); + auto ctx = GpgME::Context::createForProtocol (GpgME::CMS); if (!ctx) { TRACEPOINT; @@ -315,44 +392,155 @@ do_locate (LPVOID arg) return 0; } -void KeyCache::startLocate (char **recipients) const +static void +locate_secret (char *addr, GpgME::Protocol proto) { - log_debug ("%s:%s start locate", - SRCNAME, __func__); - if (!recipients) + auto ctx = GpgME::Context::createForProtocol (proto); + if (!ctx) { TRACEPOINT; return; } - gpgrt_lock_lock (&keycache_lock); - log_debug ("%s:%s locked", - SRCNAME, __func__); + // We need to validate here to fetch CRL's + ctx->setKeyListMode (GpgME::KeyListMode::Local | + GpgME::KeyListMode::Validate); + GpgME::Error e = ctx->startKeyListing (addr, true); + if (e) + { + TRACEPOINT; + xfree (addr); + return; + } - for (int i = 0; recipients[i]; i++) + std::vector keys; + GpgME::Error err; + do { - log_debug ("%s:%s looking tat %s", - SRCNAME, __func__, recipients[i]); - std::string recp = GpgME::UserID::addrSpecFromString (recipients[i]); - if (recp.empty ()) + const auto key = ctx->nextKey(err); + if (key.isNull()) { continue; } - if (d->m_pgp_key_map.find (recp) == d->m_pgp_key_map.end ()) + if (key.isRevoked() || key.isExpired() || + key.isDisabled() || key.isInvalid()) { - // It's enough to look at the PGP Key map. We marked - // searched keys there. - d->m_pgp_key_map.insert (std::pair (recp, GpgME::Key())); - log_debug ("%s:%s Creating a locator thread", - SRCNAME, __func__); - HANDLE thread = CreateThread (NULL, 0, do_locate, - (LPVOID) strdup (recp.c_str ()), 0, - NULL); - CloseHandle (thread); + log_mime_parser ("%s:%s: Skipping invalid secret key", + SRCNAME, __func__); + continue; } + if (proto == GpgME::OpenPGP) + { + log_mime_parser ("%s:%s found pgp skey for addr: \"%s\":%s", + SRCNAME, __func__, addr, key.primaryFingerprint()); + KeyCache::instance()->setPgpKeySecret (addr, key); + delete ctx; + return; + } + if (proto == GpgME::CMS) + { + log_mime_parser ("%s:%s found cms skey for addr: \"%s\":%s", + SRCNAME, __func__, addr, key.primaryFingerprint()); + KeyCache::instance()->setSmimeKeySecret (addr, key); + delete ctx; + return; + } + } while (!err); + delete ctx; + return; +} + +static DWORD WINAPI +do_locate_secret (LPVOID arg) +{ + char *addr = (char*) arg; + + log_mime_parser ("%s:%s searching secret key for addr: \"%s\"", + SRCNAME, __func__, addr); + + locate_secret (addr, GpgME::OpenPGP); + if (opt.enable_smime) + { + locate_secret (addr, GpgME::CMS); + } + xfree (addr); + log_debug ("%s:%s locator sthread thread done", + SRCNAME, __func__); + return 0; +} + +void +KeyCache::startLocate (char **recipients) const +{ + if (!recipients) + { + TRACEPOINT; + return; + } + for (int i = 0; recipients[i]; i++) + { + startLocate (recipients[i]); + } +} + +void +KeyCache::startLocate (const char *addr) const +{ + if (!addr) + { + TRACEPOINT; + return; + } + std::string recp = GpgME::UserID::addrSpecFromString (addr); + if (recp.empty ()) + { + return; + } + gpgrt_lock_lock (&keycache_lock); + if (d->m_pgp_key_map.find (recp) == d->m_pgp_key_map.end ()) + { + // It's enough to look at the PGP Key map. We marked + // searched keys there. + d->m_pgp_key_map.insert (std::pair (recp, GpgME::Key())); + log_debug ("%s:%s Creating a locator thread", + SRCNAME, __func__); + HANDLE thread = CreateThread (NULL, 0, do_locate, + (LPVOID) strdup (recp.c_str ()), 0, + NULL); + CloseHandle (thread); + } + gpgrt_lock_unlock (&keycache_lock); +} + +void +KeyCache::startLocateSecret (const char *addr) const +{ + if (!addr) + { + TRACEPOINT; + return; + } + std::string recp = GpgME::UserID::addrSpecFromString (addr); + if (recp.empty ()) + { + return; + } + gpgrt_lock_lock (&keycache_lock); + if (d->m_pgp_skey_map.find (recp) == d->m_pgp_skey_map.end ()) + { + // It's enough to look at the PGP Key map. We marked + // searched keys there. + d->m_pgp_skey_map.insert (std::pair (recp, GpgME::Key())); + log_debug ("%s:%s Creating a locator thread", + SRCNAME, __func__); + HANDLE thread = CreateThread (NULL, 0, do_locate_secret, + (LPVOID) strdup (recp.c_str ()), 0, + NULL); + CloseHandle (thread); } gpgrt_lock_unlock (&keycache_lock); } + void KeyCache::setSmimeKey(const char *mbox, const GpgME::Key &key) { @@ -364,3 +552,15 @@ KeyCache::setPgpKey(const char *mbox, const GpgME::Key &key) { d->setPgpKey(mbox, key); } + +void +KeyCache::setSmimeKeySecret(const char *mbox, const GpgME::Key &key) +{ + d->setSmimeKeySecret(mbox, key); +} + +void +KeyCache::setPgpKeySecret(const char *mbox, const GpgME::Key &key) +{ + d->setPgpKeySecret(mbox, key); +} diff --git a/src/keycache.h b/src/keycache.h index 7f68fe2..9a3aded 100644 --- a/src/keycache.h +++ b/src/keycache.h @@ -44,7 +44,7 @@ public: /** Get the KeyCache */ static KeyCache* instance (); - /* Try to find a key for signing in the internal + /* Try to find a key for signing in the internal secret key cache. If no proper key is found a Null key is returned.*/ GpgME::Key getSigningKey (const char *addr, GpgME::Protocol proto) const; @@ -61,12 +61,21 @@ public: of address strings. */ void startLocate (char **cArray) const; + /* Look for a secret key for the addr. */ + void startLocateSecret (const char *addr) const; + + /* Start a key location in a background thread filling + the key cache. */ + void startLocate (const char *addr) const; // Internal for thread void setSmimeKey(const char *mbox, const GpgME::Key &key); void setPgpKey(const char *mbox, const GpgME::Key &key); + void setSmimeKeySecret(const char *mbox, const GpgME::Key &key); + void setPgpKeySecret(const char *mbox, const GpgME::Key &key); private: + class Private; std::shared_ptr d; }; diff --git a/src/mail.cpp b/src/mail.cpp index 7405328..04dec00 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -2401,10 +2401,13 @@ Mail::get_sig_fpr() const } /** Try to locate the keys for all recipients */ -void Mail::locate_keys() +void +Mail::locate_keys() { char ** recipients = get_recipients (); KeyCache::instance()->startLocate (recipients); + KeyCache::instance()->startLocate (get_sender ().c_str ()); + KeyCache::instance()->startLocateSecret (get_sender ().c_str ()); release_cArray (recipients); } commit 93b423f9632b7740dbf0a21341898fb3efb48b4a Author: Andre Heinecke Date: Thu Mar 1 16:10:22 2018 +0100 Bring mail to front after encryption * src/overlay.cpp (Overlay::~Overlay): Bring old window to front. -- Pinentry brings the wrong window to front. This mitigates that a bit. diff --git a/src/overlay.cpp b/src/overlay.cpp index 8e088d6..a6ba341 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -85,4 +85,5 @@ Overlay::~Overlay() m_overlayStdin.write (nullptr, 0); m_overlayCtx->wait (); EnableWindow (m_wid, TRUE); + bring_to_front (m_wid); } ----------------------------------------------------------------------- Summary of changes: src/cryptcontroller.cpp | 65 +++++++++++- src/cryptcontroller.h | 2 + src/keycache.cpp | 256 ++++++++++++++++++++++++++++++++++++++++++------ src/keycache.h | 11 ++- src/mail.cpp | 5 +- src/overlay.cpp | 1 + 6 files changed, 305 insertions(+), 35 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 1 19:09:30 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 01 Mar 2018 19:09:30 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-5-gfd595c9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via fd595c9d3642dba437fbe0f6e25d7aaaae095f94 (commit) from e43844c3b0b9ec93b7f2a88752bcd6b6244aacfb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fd595c9d3642dba437fbe0f6e25d7aaaae095f94 Author: Werner Koch Date: Thu Mar 1 19:03:23 2018 +0100 gpg: Print the keygrip with --card-status * g10/call-agent.h (agent_card_info_s): Add fields grp1, grp2 and grp3. * g10/call-agent.c (unhexify_fpr): Allow for space as delimiter. (learn_status_cb): Parse KEYPARIINFO int the grpX fields. * g10/card-util.c (print_keygrip): New. (current_card_status): Print "grp:" records or with --with-keygrip a human readable keygrip. -- Suggested-by: Peter Lebbing Signed-off-by: Werner Koch diff --git a/g10/call-agent.c b/g10/call-agent.c index 545b244..f29e1b1 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -381,10 +381,11 @@ unhexify_fpr (const char *hexstr, unsigned char *fpr) for (s=hexstr, n=0; hexdigitp (s); s++, n++) ; - if (*s || (n != 40)) + if ((*s && *s != ' ') || (n != 40)) return 0; /* no fingerprint (invalid or wrong length). */ for (s=hexstr, n=0; *s; s += 2, n++) fpr[n] = xtoi_2 (s); + return 1; /* okay */ } @@ -625,6 +626,24 @@ learn_status_cb (void *opaque, const char *line) else if (no == 3) parm->fpr3time = strtoul (line, NULL, 10); } + else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen)) + { + const char *hexgrp = line; + int no; + + while (*line && !spacep (line)) + line++; + while (spacep (line)) + line++; + if (strncmp (line, "OPENPGP.", 8)) + ; + else if ((no = atoi (line+8)) == 1) + unhexify_fpr (hexgrp, parm->grp1); + else if (no == 2) + unhexify_fpr (hexgrp, parm->grp2); + else if (no == 3) + unhexify_fpr (hexgrp, parm->grp3); + } else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen)) { int no = atoi (line); diff --git a/g10/call-agent.h b/g10/call-agent.h index f45b64d..53775c5 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -47,6 +47,9 @@ struct agent_card_info_s u32 fpr1time; u32 fpr2time; u32 fpr3time; + char grp1[20]; /* The keygrip for OPENPGP.1 */ + char grp2[20]; /* The keygrip for OPENPGP.2 */ + char grp3[20]; /* The keygrip for OPENPGP.3 */ unsigned long sig_counter; int chv1_cached; /* True if a PIN is not required for each signing. Note that the gpg-agent might cache diff --git a/g10/card-util.c b/g10/card-util.c index 759dde8..bda4e83 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -264,6 +264,21 @@ print_sha1_fpr_colon (estream_t fp, const unsigned char *fpr) static void +print_keygrip (estream_t fp, const unsigned char *grp) +{ + int i; + + if (opt.with_keygrip) + { + tty_fprintf (fp, " keygrip ....: "); + for (i=0; i < 20 ; i++, grp++) + es_fprintf (fp, "%02X", *grp); + tty_fprintf (fp, "\n"); + } +} + + +static void print_name (estream_t fp, const char *text, const char *name) { tty_fprintf (fp, "%s", text); @@ -517,6 +532,11 @@ current_card_status (ctrl_t ctrl, estream_t fp, es_fprintf (fp, "fprtime:%lu:%lu:%lu:\n", (unsigned long)info.fpr1time, (unsigned long)info.fpr2time, (unsigned long)info.fpr3time); + es_fputs ("grp:", fp); + print_sha1_fpr_colon (fp, info.grp1); + print_sha1_fpr_colon (fp, info.grp2); + print_sha1_fpr_colon (fp, info.grp3); + es_putc ('\n', fp); } else { @@ -593,18 +613,27 @@ current_card_status (ctrl_t ctrl, estream_t fp, tty_fprintf (fp, "Signature key ....:"); print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL); if (info.fpr1valid && info.fpr1time) - tty_fprintf (fp, " created ....: %s\n", - isotimestamp (info.fpr1time)); + { + tty_fprintf (fp, " created ....: %s\n", + isotimestamp (info.fpr1time)); + print_keygrip (fp, info.grp1); + } tty_fprintf (fp, "Encryption key....:"); print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL); if (info.fpr2valid && info.fpr2time) - tty_fprintf (fp, " created ....: %s\n", - isotimestamp (info.fpr2time)); + { + tty_fprintf (fp, " created ....: %s\n", + isotimestamp (info.fpr2time)); + print_keygrip (fp, info.grp2); + } tty_fprintf (fp, "Authentication key:"); print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL); if (info.fpr3valid && info.fpr3time) - tty_fprintf (fp, " created ....: %s\n", - isotimestamp (info.fpr3time)); + { + tty_fprintf (fp, " created ....: %s\n", + isotimestamp (info.fpr3time)); + print_keygrip (fp, info.grp2); + } tty_fprintf (fp, "General key info..: "); thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 : ----------------------------------------------------------------------- Summary of changes: g10/call-agent.c | 21 ++++++++++++++++++++- g10/call-agent.h | 3 +++ g10/card-util.c | 41 +++++++++++++++++++++++++++++++++++------ 3 files changed, 58 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 1 19:16:28 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 01 Mar 2018 19:16:28 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-6-gbf43b39 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via bf43b39c05cfc68ea17483c78f14bfca6faf08eb (commit) from fd595c9d3642dba437fbe0f6e25d7aaaae095f94 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bf43b39c05cfc68ea17483c78f14bfca6faf08eb Author: Werner Koch Date: Thu Mar 1 19:10:10 2018 +0100 gpg: Fix regression in last --card-status patch -- Sorry, I accidentally pushed the last commit without having amended it with this fix. Fixes-commit: fd595c9d3642dba437fbe0f6e25d7aaaae095f94 Signed-off-by: Werner Koch diff --git a/g10/call-agent.c b/g10/call-agent.c index f29e1b1..ea530e7 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -383,7 +383,7 @@ unhexify_fpr (const char *hexstr, unsigned char *fpr) ; if ((*s && *s != ' ') || (n != 40)) return 0; /* no fingerprint (invalid or wrong length). */ - for (s=hexstr, n=0; *s; s += 2, n++) + for (s=hexstr, n=0; *s && n < 20; s += 2, n++) fpr[n] = xtoi_2 (s); return 1; /* okay */ ----------------------------------------------------------------------- Summary of changes: g10/call-agent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Mar 3 22:39:02 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sat, 03 Mar 2018 22:39:02 +0100 Subject: [git] GPGME - branch, ben/docs/2018-02, updated. gpgme-1.10.0-46-g1d91067 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-02 has been updated via 1d910672539686e2e17fd8fa1a894cee92863417 (commit) via 12a87af1df906744a14079ff7ff88e7d60679695 (commit) from 85bdca3b2b095afb672f19abbffccd2bcb8bbd0a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1d910672539686e2e17fd8fa1a894cee92863417 Author: Ben McGinnes Date: Sun Mar 4 08:38:19 2018 +1100 TODO * WS removal diff --git a/TODO b/TODO index c865ba4..ad18a00 100644 --- a/TODO +++ b/TODO @@ -504,7 +504,7 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: malloc-vasprintf :END: - + ignored (and logged with 255?!), or really be assertions. ! commit 12a87af1df906744a14079ff7ff88e7d60679695 Author: Ben McGinnes Date: Sun Mar 4 08:32:31 2018 +1100 TODO updates * Updated TODO with tags to make everything appear properly when exported to HTML or PDF. * Added a couple more items, mainly to do with docs or future bindings. * Marked some, but not all as actual TODO items. * Some items should probably be removed, but haven't been yet. * Some have probably been completed already. diff --git a/TODO b/TODO index 8efa4b5..c865ba4 100644 --- a/TODO +++ b/TODO @@ -158,25 +158,25 @@ Hey Emacs, this is -*- org -*- mode! * Thread support: :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: threads :END: ** When GNU Pth supports sendmsg/recvmsg, wrap them properly. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: wrap-oth :END: ** Without timegm (3) support our ISO time parser is not thread safe. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: time-threads :END: There is a configure time warning, though. * New features: :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: new-features :END: ** Flow control for data objects. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: flow-control-is-not-a-euphemism-for-an-s-bend :END: Currently, gpgme_data_t objects are assumed to be blocking. To break this assumption, we need either (A) a way for an user I/O @@ -188,12 +188,12 @@ Hey Emacs, this is -*- org -*- mode! user event loop. Neither is particularly simple. ** Extended notation support. When gpg supports arbitrary binary :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: extended-notation :END: notation data, provide a user interface for that. ** notification system :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: notification-system :END: We need a simple notification system, probably a simple callback with a string and some optional arguments. This is for example @@ -207,7 +207,7 @@ Hey Emacs, this is -*- org -*- mode! ** --learn-code support :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: learn-code :END: This might be integrated with import. we still need to work out how to learn a card when gpg and gpgsm have support for smartcards. In @@ -215,72 +215,72 @@ Hey Emacs, this is -*- org -*- mode! ** Might need a stat() for data objects and use it for length param to gpg. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: stat-data :END: ** Implement support for photo ids. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: photo-id :END: ** Allow selection of subkeys :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: subkey-selection :END: ** Allow to return time stamps in ISO format :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: iso-format-datetime :END: This allows us to handle years later than 2037 properly. With the time_t interface they are all mapped to 2037-12-31 ** New features requested by our dear users, but rejected or left for :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: feature-requests :END: later consideration: *** Allow to export secret keys. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: export-secret-keys :END: Rejected because this is conceptually flawed. Secret keys on a smart card can not be exported, for example. May eventually e supproted with a keywrapping system. *** Selecting the key ring, setting the version or comment in output. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: select-keyring-version :END: Rejected because the naive implementation is engine specific, the configuration is part of the engine's configuration or readily worked around in a different way *** Selecting the symmetric cipher. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: symmetric-cipher-selection :END: *** Exchanging keys with key servers. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: key-server-exchange :END: * Documentation :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: documentation :END: -** Document validity and trust issues. +** TODO Document validity and trust issues. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: valid-trust-issues :END: ** In gpgme.texi: Register callbacks under the right letter in the index. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: gpgme-texi :END: * Engines :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: engines :END: ** Do not create/destroy engines, but create engine and then reset it. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: reset-engine-is-not-quite-just-ignition :END: Internally the reset operation still spawns a new engine process, but this can be replaced with a reset later. Also, be very sure to @@ -292,27 +292,27 @@ Hey Emacs, this is -*- org -*- mode! other options. ** Optimize the case where a data object has an underlying fd we can pass :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: optimus-data-cousin-of-optimus-prime :END: directly to the engine. This will be automatic with socket I/O and descriptor passing. ** Move code common to all engines up from gpg to engine. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: move-code-common-to-engines-out-of-gpg :END: ** engine operations can return General Error on unknown protocol :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: general-error-looking-to-be-court-martialled :END: (it's an internal error, as select_protocol checks already). ** When server mode is implemented properly, more care has to be taken to :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: server-mode :END: release all resources on error (for example to free assuan_cmd). -** op_import_keys and op_export_keys have a limit ion the number of keys. +** op_import_keys and op_export_keys have a limit in the number of keys. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: import-export-problems :END: This is because we pass them in gpg via the command line and gpgsm via an assuan control line. We should pipe them instead and maybe @@ -321,15 +321,15 @@ Hey Emacs, this is -*- org -*- mode! * GPG breakage: :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: gpg-breakage :END: ** gpg 1.4.2 lacks error reporting if sign/encrypt with revoked key. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: gpg-classic-lacks-stuff :END: ** gpg 1.4.2 does crappy error reporting (namely none at all) when :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: gpg-classic-problems-but-do-we-care :END: smart card is missing for sign operation: [GNUPG:] CARDCTRL 4 @@ -339,12 +339,12 @@ Hey Emacs, this is -*- org -*- mode! gpg: test: sign+encrypt failed: general error ** Without agent and with wrong passphrase, gpg 1.4.2 enters into an :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: recursive-gpg-classic :END: infinite loop. ** Use correct argv[0] :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: correct-argv :END: In rungpg.c:build_argv we use argv[argc] = strdup ("gpg"); /* argv[0] */ @@ -353,95 +353,95 @@ Hey Emacs, this is -*- org -*- mode! * Operations :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: operations-are-not-surgical :END: ** Include cert values -2, -1, 0 and 1 should be defined as macros. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: certified-macros :END: ** If an operation failed, make sure that the result functions don't return :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: operation-failure :END: corrupt partial information. !!! NOTE: The EOF status handler is not called in this case !!! ** Verify must not fail on NODATA premature if auto-key-retrieval failed. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: autobot-key-retrieval :END: It should not fail silently if it knows there is an error. !!! ** All operations: Better error reporting. !! :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: better-reporting-not-like-fox-news :END: ** Export status handler need much more work. !!! :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: export-status-handler :END: ** Import should return a useful error when one happened. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: import-useful-stuff-even-wrong-stuff :END: *** Import does not take notice of NODATA status report. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: import-no-data :END: *** When GPGSM does issue IMPORT_OK status reports, make sure to check for :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: gpgsm-import-ok :END: them in tests/gpgs m/t-import.c. ** Verify can include info about version/algo/class, but currently :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: verify-class :END: this is only available for gpg, not gpgsm. ** Return ENC_TO output in verify result. Again, this is not available :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: return-to-enc :END: for gpgsm. ** Genkey should return something more useful than General_Error. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: general-key-assumed-command-from-general-error :END: ** If possible, use --file-setsize to set the file size for proper progress :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: file-setsize :END: callback handling. Write data interface for file size. ** Optimize the file descriptor list, so the number of open fds is :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: optimus-descriptus-younger-brother-of-optimus-prime :END: always known easily. ** Encryption: It should be verified that the behaviour for partially untrusted :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: only-mostly-dead-means-partially-alive :END: recipients is correct. ** When GPG issues INV_something for invalid signers, catch them. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: invalid-sig :END: * Error Values :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: error-value :END: ** Map ASSUAN/GpgSM ERR error values in a better way than is done now. !! :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: map-ass-error :END: ** Some error values should identify the source more correctly (mostly error :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: source-errors :END: values derived from status messages). ** In rungpg.c we need to check the version of the engine :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: rungpg-c-engine-ver :END: This requires a way to get the cached version number from the engine layer. @@ -449,35 +449,35 @@ Hey Emacs, this is -*- org -*- mode! * Tests :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: tests :END: -** Write a fake gpg-agent so that we can supply known passphrases to +** TODO Write a fake gpg-agent so that we can supply known passphrases to :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: test-fake-gpg-agent :END: gpgsm and setup the configuration files to use the agent. Without this we are testing a currently running gpg-agent which is not a clever idea. ! ** t-data :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: test-data :END: *** Test gpgme_data_release_and_get_mem. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: test-gpgme-data-release-mem :END: *** Test gpgme_data_seek for invalid types. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: test-gpgme-data-seek :END: ** t-keylist :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: test-keylist :END: Write a test for ext_keylist. ** Test reading key signatures. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: test-key-sig :END: @@ -487,7 +487,7 @@ Hey Emacs, this is -*- org -*- mode! :END: ** Tracepoints should be added at: Every public interface enter/leave, :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: tracepoint-pub-int :END: before and in every callback, at major decision points, at every internal data point which might easily be observed by the outside @@ -500,10 +500,11 @@ Hey Emacs, this is -*- org -*- mode! decrypt-verify.c delete.c edit.c encrypt.c encrypt-sign.c export.c genkey.c import.c key.c keylist.c passphrase.c progress.c signers.c sig-notation.c trust-item.c trustlist.c verify.c -** Handle malloc and vasprintf errors. But decide first if they should be +** TODO Handle malloc and vasprintf errors. But decide first if they should be :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: malloc-vasprintf :END: + ignored (and logged with 255?!), or really be assertions. ! @@ -511,13 +512,13 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: :END: -** Make sure everything is cleaned correctly (esp. test area). +** TODO Make sure everything is cleaned correctly (esp. test area). :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: clean-tests :END: -** Enable AC_CONFIG_MACRO_DIR and bump up autoconf version requirement. +** TODO Enable AC_CONFIG_MACRO_DIR and bump up autoconf version requirement. :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: autoconf-macros :END: (To fix "./autogen.sh; ./configure --enable-maintainer-mode; touch configure.ac; make"). Currently worked around with ACLOCAL_AMFLAGS??? @@ -525,11 +526,11 @@ Hey Emacs, this is -*- org -*- mode! * Error checking :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: error-checking :END: -** engine-gpgsm, with-validation +** TODO engine-gpgsm, with-validation :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: gpgsm-validation :END: Add error checking some time after releasing a new gpgsm. @@ -559,6 +560,13 @@ Hey Emacs, this is -*- org -*- mode! See the more detailed notes on this in the [[lang/python/docs/TODO.org][python TODO]]. +** TODO GPGME installation and package management guide + :PROPERTIES: + :CUSTOM_ID: package-management + :END: + + Write a guide/best practices for maintainers of GPGME packages with + third party package management systems. Copyright 2004, 2005, 2018 g10 Code GmbH ----------------------------------------------------------------------- Summary of changes: TODO | 152 +++++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 80 insertions(+), 72 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sat Mar 3 23:00:38 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sat, 03 Mar 2018 23:00:38 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-48-g75f5e6e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 75f5e6e6672a1bbd16b7680313c0f96796c219bd (commit) via b438e5e44c2eaf22549db94141a3ec8731556674 (commit) via 1d910672539686e2e17fd8fa1a894cee92863417 (commit) via 12a87af1df906744a14079ff7ff88e7d60679695 (commit) via 85bdca3b2b095afb672f19abbffccd2bcb8bbd0a (commit) via 8047e1374fe6e69e8c4502e58e6522ea86e4bef4 (commit) via 73c51bc9858de2aab25844e7e283a6334038ccc8 (commit) from 59fe3f26c1ca0fba16f76738cd05aaf80fb735ef (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 75f5e6e6672a1bbd16b7680313c0f96796c219bd Author: Ben McGinnes Date: Sun Mar 4 08:59:41 2018 +1100 Missed a couple * WS indicated 2 custom-ids were missed, now they're set. Signed-off-by: Ben McGinnes diff --git a/TODO b/TODO index 053f378..d02a0d2 100644 --- a/TODO +++ b/TODO @@ -495,7 +495,7 @@ Hey Emacs, this is -*- org -*- mode! * Debug :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: debug :END: ** Tracepoints should be added at: Every public interface enter/leave, :PROPERTIES: @@ -522,7 +522,7 @@ Hey Emacs, this is -*- org -*- mode! * Build suite :PROPERTIES: - :CUSTOM_ID: + :CUSTOM_ID: build-suite :END: ** TODO Make sure everything is cleaned correctly (esp. test area). :PROPERTIES: commit b438e5e44c2eaf22549db94141a3ec8731556674 Author: Ben McGinnes Date: Sun Mar 4 08:56:26 2018 +1100 TODO DONE * Marked off a TODO for this clean-up. Signed-off-by: Ben McGinnes diff --git a/TODO b/TODO index ad18a00..053f378 100644 --- a/TODO +++ b/TODO @@ -272,7 +272,19 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: gpgme-texi :END: +** TODO Update TODO file + :PROPERTIES: + :CUSTOM_ID: todo-update + :END: + +*** DONE fix TODO items + CLOSED: [2018-03-04 Sun 08:55] + :PROPERTIES: + :CUSTOM_ID: fix-todo-items + :END: + Adjust todo items so each can now be referenced by custom-id and + checked off as necessary. * Engines :PROPERTIES: ----------------------------------------------------------------------- Summary of changes: TODO | 384 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 374 insertions(+), 10 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 5 11:49:02 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 05 Mar 2018 11:49:02 +0100 Subject: [git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-61-ge07ab6c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, async-enc has been updated via e07ab6c300589dcc8de0129051ce0800f772a52c (commit) via 2d069391aa5c5bace8a5460f0bdb60a1e015642a (commit) via bd2a79d9661a5e204a56e7b64da785b04ece1583 (commit) from ab5232cb52e4265be48c1d4d977aae45ad91f844 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e07ab6c300589dcc8de0129051ce0800f772a52c Author: Andre Heinecke Date: Mon Mar 5 11:46:11 2018 +0100 Implement Load / Save for WKS States * src/wks-helper.cpp (WKSHelper::load, WKSHelper::save): Implement. (WKSHelper::check_published): New. (do_check): Also check for published. (WKSHelper::update_last_checked): New. (WKSHelper::start_check): Handle saved states. diff --git a/src/wks-helper.cpp b/src/wks-helper.cpp index 6d9f9e2..16d42ba 100644 --- a/src/wks-helper.cpp +++ b/src/wks-helper.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -37,6 +38,7 @@ #include #define CHECK_MIN_INTERVAL (60 * 60 * 24 * 7) +#define WKS_REG_KEY "webkey" #define DEBUG_WKS 1 @@ -142,6 +144,54 @@ get_wks_client_path () return std::string (); } +static bool +check_published (const std::string &mbox) +{ + const auto wksPath = get_wks_client_path (); + + if (wksPath.empty()) + { + return 0; + } + + std::vector args; + + args.push_back (wksPath); + args.push_back (std::string ("--status-fd")); + args.push_back (std::string ("1")); + args.push_back (std::string ("--check")); + args.push_back (mbox); + + // Spawn the process + auto ctx = GpgME::Context::createForEngine (GpgME::SpawnEngine); + + if (!ctx) + { + TRACEPOINT; + return false; + } + + GpgME::Data mystdin, mystdout, mystderr; + + char **cargs = vector_to_cArray (args); + + GpgME::Error err = ctx->spawn (cargs[0], const_cast (cargs), + mystdin, mystdout, mystderr, + GpgME::Context::SpawnNone); + release_cArray (cargs); + + if (err) + { + log_debug ("%s:%s: WKS client spawn code: %i asString: %s", + SRCNAME, __func__, err.code(), err.asString()); + return false; + } + auto data = mystdout.toString (); + rtrim (data); + + return data == "[GNUPG:] SUCCESS"; +} + static DWORD WINAPI do_check (LPVOID arg) { @@ -192,29 +242,26 @@ do_check (LPVOID arg) bool success = data == "[GNUPG:] SUCCESS"; // TODO Figure out NeedsPublish state. - const auto state = success ? WKSHelper::NeedsPublish : WKSHelper::NotSupported; + auto state = success ? WKSHelper::NeedsPublish : WKSHelper::NotSupported; + bool isPublished = false; + if (success) { log_debug ("%s:%s: WKS client: '%s' is supported", SRCNAME, __func__, mbox.c_str ()); + isPublished = check_published (mbox); } - WKSHelper::instance()->update_state (mbox, state); - - gpgrt_lock_lock (&wks_lock); - auto tit = s_last_checked.find(mbox); - auto now = time (0); - if (tit != s_last_checked.end()) - { - tit->second = now; - } - else + if (isPublished) { - s_last_checked.insert (std::make_pair (mbox, now)); + log_debug ("%s:%s: WKS client: '%s' is published", + SRCNAME, __func__, mbox.c_str ()); + state = WKSHelper::IsPublished; } - gpgrt_lock_unlock (&wks_lock); - WKSHelper::instance()->save (); + WKSHelper::instance()->update_state (mbox, state, false); + WKSHelper::instance()->update_last_checked (mbox, time (0)); + return 0; } @@ -222,11 +269,25 @@ do_check (LPVOID arg) void WKSHelper::start_check (const std::string &mbox, bool forced) const { + const auto state = get_state (mbox); + + if (!forced && (state != NotChecked && state != NotSupported)) + { + log_debug ("%s:%s: Check aborted because its neither " + "not supported nor not checked.", + SRCNAME, __func__); + return; + } + auto lastTime = get_check_time (mbox); auto now = time (0); - if (!forced && lastTime && difftime (lastTime, now) < CHECK_MIN_INTERVAL) + + if (!forced && (state == NotSupported && lastTime && + difftime (now, lastTime) < CHECK_MIN_INTERVAL)) { /* Data is new enough */ + log_debug ("%s:%s: Check aborted because last checked is too recent.", + SRCNAME, __func__); return; } @@ -247,13 +308,54 @@ WKSHelper::start_check (const std::string &mbox, bool forced) const void WKSHelper::load () const { - // TODO + /* Map of mbox'es to states. states are ; */ + const auto map = get_registry_subkeys (WKS_REG_KEY); + + for (const auto &pair: map) + { + const auto mbox = pair.first; + const auto states = gpgol_split (pair.second, ';'); + + if (states.size() != 2) + { + log_error ("%s:%s: Invalid state '%s' for '%s'", + SRCNAME, __func__, mbox.c_str (), pair.second.c_str ()); + continue; + } + + WKSState state = (WKSState) strtol (states[0].c_str (), nullptr, 10); + time_t update_time = (time_t) strtol (states[1].c_str (), nullptr, 10); + + update_state (mbox, state, false); + update_last_checked (mbox, update_time, false); + } } void WKSHelper::save () const { - // TODO + gpgrt_lock_lock (&wks_lock); + for (const auto &pair: s_states) + { + auto state = std::to_string (pair.second) + ';'; + + const auto it = s_last_checked.find (pair.first); + if (it != s_last_checked.end ()) + { + state += std::to_string (it->second); + } + else + { + state += '0'; + } + if (store_extension_subkey_value (WKS_REG_KEY, pair.first.c_str (), + state.c_str ())) + { + log_error ("%s:%s: Failed to store state.", + SRCNAME, __func__); + } + } + gpgrt_lock_unlock (&wks_lock); } static DWORD WINAPI @@ -278,7 +380,8 @@ WKSHelper::allow_notify (int sleepTimeMS) const if (pair.second == ConfirmationSeen || pair.second == NeedsPublish) { - auto *args = new std::pair (strdup (pair.first.c_str()), sleepTimeMS); + auto *args = new std::pair (strdup (pair.first.c_str()), + sleepTimeMS); CloseHandle (CreateThread (nullptr, 0, do_notify, args, 0, nullptr)); @@ -309,7 +412,7 @@ WKSHelper::notify (const char *cBox) const } else { - update_state (mbox, PublishDenied); + update_state (mbox, PublishDenied); } return; } @@ -406,7 +509,8 @@ WKSHelper::start_publish (const std::string &mbox) const } void -WKSHelper::update_state (const std::string &mbox, WKSState state) const +WKSHelper::update_state (const std::string &mbox, WKSState state, + bool store) const { gpgrt_lock_lock (&wks_lock); auto it = s_states.find(mbox); @@ -420,6 +524,33 @@ WKSHelper::update_state (const std::string &mbox, WKSState state) const s_states.insert (std::make_pair (mbox, state)); } gpgrt_lock_unlock (&wks_lock); + + if (store) + { + save (); + } +} + +void +WKSHelper::update_last_checked (const std::string &mbox, time_t time, + bool store) const +{ + gpgrt_lock_lock (&wks_lock); + auto it = s_last_checked.find(mbox); + if (it != s_last_checked.end()) + { + it->second = time; + } + else + { + s_last_checked.insert (std::make_pair (mbox, time)); + } + gpgrt_lock_unlock (&wks_lock); + + if (store) + { + save (); + } } int diff --git a/src/wks-helper.h b/src/wks-helper.h index a6429f7..be3ae7b 100644 --- a/src/wks-helper.h +++ b/src/wks-helper.h @@ -48,8 +48,8 @@ public: { NotChecked, /*<-- Supported state was not checked */ NotSupported, /* <-- WKS is not supported for this address */ - Supported, /* <-- WKS is supported for this address */ NeedsPublish, /* <-- There was no key published for this address */ + IsPublished, /* <-- WKS is supported for this address and published */ ConfirmationSeen, /* A confirmation request was seen for this mail addres. */ NeedsUpdate, /* <-- Not yet implemeted. */ RequestSent, /* <-- A publishing request has been sent. */ @@ -99,7 +99,11 @@ public: void save () const; /** Update or insert a state in the static maps. */ - void update_state (const std::string &mbox, WKSState state) const; + void update_state (const std::string &mbox, WKSState state, bool save = true) const; + + /** Update or insert last_checked in the static maps. */ + void update_last_checked (const std::string &mbox, time_t last_checked, + bool save = true) const; /** Create / Build / Send Mail returns 0 on success. commit 2d069391aa5c5bace8a5460f0bdb60a1e015642a Author: Andre Heinecke Date: Mon Mar 5 11:45:51 2018 +0100 Add helpers to store string map in registry * src/common.c (store_extension_subkey_value): New. (GPGOL_REGPATH): Move into header. * src/common.h: Expose store_extension_subkey_value. * src/cpphelp.cpp (get_registry_subkeys): New. (gpgol_split): New Helper. * src/cpphelp.h: Update accordingly. diff --git a/src/common.c b/src/common.c index 8997b16..adda352 100644 --- a/src/common.c +++ b/src/common.c @@ -40,9 +40,6 @@ #include "dialogs.h" -/* Registry path to store plugin settings */ -#define GPGOL_REGPATH "Software\\GNU\\GpgOL" - HINSTANCE glob_hinst = NULL; void @@ -1178,3 +1175,16 @@ load_extension_value (const char *key, char **val) { return load_config_value (HKEY_CURRENT_USER, GPGOL_REGPATH, key, val); } + +int +store_extension_subkey_value (const char *subkey, + const char *key, + const char *val) +{ + int ret; + char *path; + gpgrt_asprintf (&path, "%s\\%s", GPGOL_REGPATH, subkey); + ret = store_config_value (HKEY_CURRENT_USER, path, key, val); + xfree (path); + return ret; +} diff --git a/src/common.h b/src/common.h index ed7b87a..c8e32df 100644 --- a/src/common.h +++ b/src/common.h @@ -39,6 +39,9 @@ # define MIME_UI_DEFAULT 0 #endif +/* Registry path to store plugin settings */ +#define GPGOL_REGPATH "Software\\GNU\\GpgOL" + #ifdef __cplusplus extern "C" { #if 0 @@ -60,6 +63,11 @@ const char *default_homedir (void); char *get_data_dir (void); char *get_gpg4win_dir (void); +int store_extension_value (const char *key, const char *val); +int store_extension_subkey_value (const char *subkey, const char *key, + const char *val); +int load_extension_value (const char *key, char **val); + /* Get a temporary filename with and its name */ wchar_t *get_tmp_outfile (wchar_t *name, HANDLE *outHandle); @@ -81,8 +89,6 @@ const char *get_pubkey_algo_str (gpgme_pubkey_algo_t id); /*-- config-dialog.c --*/ void config_dialog_box (HWND parent); -int store_extension_value (const char *key, const char *val); -int load_extension_value (const char *key, char **val); /*-- verify-dialog.c --*/ int verify_dialog_box (gpgme_protocol_t protocol, diff --git a/src/cpphelp.cpp b/src/cpphelp.cpp index 85c8db3..8d38feb 100644 --- a/src/cpphelp.cpp +++ b/src/cpphelp.cpp @@ -21,15 +21,21 @@ #include "config.h" -#include #include "cpphelp.h" +#include +#include +#include +#include + #include "common.h" #include #include #include +#include + void release_cArray (char **carray) { @@ -111,3 +117,110 @@ in_de_vs_mode() vs_mode = false; return false; } + +std::map +get_registry_subkeys (const char *path) +{ + HKEY theKey; + std::map ret; + + std::string regPath = GPGOL_REGPATH; + regPath += "\\"; + regPath += path; + + if (RegOpenKeyEx (HKEY_CURRENT_USER, + regPath.c_str (), + 0, KEY_ENUMERATE_SUB_KEYS | KEY_READ, + &theKey) != ERROR_SUCCESS) + { + TRACEPOINT; + return ret; + } + + DWORD values = 0, + maxValueName = 0, + maxValueLen = 0; + + DWORD err = RegQueryInfoKey (theKey, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + &values, + &maxValueName, + &maxValueLen, + nullptr, + nullptr); + + if (err != ERROR_SUCCESS) + { + TRACEPOINT; + RegCloseKey (theKey); + return ret; + } + + /* Add space for NULL */ + maxValueName++; + maxValueLen++; + + char name[maxValueName + 1]; + char value[maxValueLen + 1]; + for (int i = 0; i < values; i++) + { + DWORD nameLen = maxValueName; + err = RegEnumValue (theKey, i, + name, + &nameLen, + nullptr, + nullptr, + nullptr, + nullptr); + + if (err != ERROR_SUCCESS) + { + TRACEPOINT; + continue; + } + + DWORD type; + DWORD valueLen = maxValueLen; + err = RegQueryValueEx (theKey, name, + NULL, &type, + (BYTE*)value, &valueLen); + + if (err != ERROR_SUCCESS) + { + TRACEPOINT; + continue; + } + if (type != REG_SZ) + { + TRACEPOINT; + continue; + } + ret.insert (std::make_pair (std::string (name, nameLen), + std::string (value, valueLen))); + } + RegCloseKey (theKey); + return ret; +} + +template void +internal_split (const std::string &s, char delim, Out result) { + std::stringstream ss(s); + std::string item; + while (std::getline (ss, item, delim)) + { + *(result++) = item; + } +} + +std::vector +gpgol_split (const std::string &s, char delim) +{ + std::vector elems; + internal_split (s, delim, std::back_inserter (elems)); + return elems; +} diff --git a/src/cpphelp.h b/src/cpphelp.h index bbf68e0..51ffe80 100644 --- a/src/cpphelp.h +++ b/src/cpphelp.h @@ -23,6 +23,7 @@ #include #include +#include /* Stuff that should be in common but is c++ so it does not fit in there. */ @@ -39,4 +40,8 @@ char **vector_to_cArray (const std::vector &vec); /* Check if we are in de_vs mode. */ bool in_de_vs_mode (); +/* Get a map of all subkey value pairs in a registry key */ +std::map get_registry_subkeys (const char *path); + +std::vector gpgol_split(const std::string &s, char delim); #endif // CPPHELP_H commit bd2a79d9661a5e204a56e7b64da785b04ece1583 Author: Andre Heinecke Date: Fri Mar 2 14:32:08 2018 +0100 Move registry helper code into common * src/common.c (load_extension_value, store_extension_value), (store_config_value, load_config_value, expand_path): Moved from config-dialog.c * src/config-dialog.c: Remove moved functions. diff --git a/src/common.c b/src/common.c index 724aebe..8997b16 100644 --- a/src/common.c +++ b/src/common.c @@ -40,6 +40,9 @@ #include "dialogs.h" +/* Registry path to store plugin settings */ +#define GPGOL_REGPATH "Software\\GNU\\GpgOL" + HINSTANCE glob_hinst = NULL; void @@ -1057,3 +1060,121 @@ gpgol_message_box (HWND parent, const char *utf8_text, xfree (w_caption); return ret; } + +static char* +expand_path (const char *path) +{ + DWORD len; + char *p; + + len = ExpandEnvironmentStrings (path, NULL, 0); + if (!len) + { + return NULL; + } + len += 1; + p = xcalloc (1, len+1); + if (!p) + { + return NULL; + } + len = ExpandEnvironmentStrings (path, p, len); + if (!len) + { + xfree (p); + return NULL; + } + return p; +} + +static int +load_config_value (HKEY hk, const char *path, const char *key, char **val) +{ + HKEY h; + DWORD size=0, type; + int ec; + + *val = NULL; + if (hk == NULL) + { + hk = HKEY_CURRENT_USER; + } + ec = RegOpenKeyEx (hk, path, 0, KEY_READ, &h); + if (ec != ERROR_SUCCESS) + { + return -1; + } + + ec = RegQueryValueEx(h, key, NULL, &type, NULL, &size); + if (ec != ERROR_SUCCESS) + { + RegCloseKey (h); + return -1; + } + if (type == REG_EXPAND_SZ) + { + char tmp[256]; + RegQueryValueEx (h, key, NULL, NULL, (BYTE*)tmp, &size); + *val = expand_path (tmp); + } + else + { + *val = xcalloc(1, size+1); + ec = RegQueryValueEx (h, key, NULL, &type, (BYTE*)*val, &size); + if (ec != ERROR_SUCCESS) + { + xfree (*val); + *val = NULL; + RegCloseKey (h); + return -1; + } + } + RegCloseKey (h); + return 0; +} + +static int +store_config_value (HKEY hk, const char *path, const char *key, const char *val) +{ + HKEY h; + int type; + int ec; + + if (hk == NULL) + { + hk = HKEY_CURRENT_USER; + } + ec = RegCreateKeyEx (hk, path, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, NULL, &h, NULL); + if (ec != ERROR_SUCCESS) + { + log_debug_w32 (ec, "creating/opening registry key `%s' failed", path); + return -1; + } + type = strchr (val, '%')? REG_EXPAND_SZ : REG_SZ; + ec = RegSetValueEx (h, key, 0, type, (const BYTE*)val, strlen (val)); + if (ec != ERROR_SUCCESS) + { + log_debug_w32 (ec, "saving registry key `%s'->`%s' failed", path, key); + RegCloseKey(h); + return -1; + } + RegCloseKey(h); + return 0; +} + +/* Store a key in the registry with the key given by @key and the + value @value. */ +int +store_extension_value (const char *key, const char *val) +{ + return store_config_value (HKEY_CURRENT_USER, GPGOL_REGPATH, key, val); +} + +/* Load a key from the registry with the key given by @key. The value is + returned in @val and needs to freed by the caller. */ +int +load_extension_value (const char *key, char **val) +{ + return load_config_value (HKEY_CURRENT_USER, GPGOL_REGPATH, key, val); +} diff --git a/src/config-dialog.c b/src/config-dialog.c index 14573d2..b2663f7 100644 --- a/src/config-dialog.c +++ b/src/config-dialog.c @@ -23,108 +23,11 @@ #include #include #include -#include -#include -#include #include "common.h" #include "gpgol-ids.h" #include "dialogs.h" - -/* Registry path to store plugin settings */ -#define GPGOL_REGPATH "Software\\GNU\\GpgOL" - - -static char* -expand_path (const char *path) -{ - DWORD len; - char *p; - - len = ExpandEnvironmentStrings (path, NULL, 0); - if (!len) - return NULL; - len += 1; - p = xcalloc (1, len+1); - if (!p) - return NULL; - len = ExpandEnvironmentStrings (path, p, len); - if (!len) { - xfree (p); - return NULL; - } - return p; -} - -static int -load_config_value (HKEY hk, const char *path, const char *key, char **val) -{ - HKEY h; - DWORD size=0, type; - int ec; - - *val = NULL; - if (hk == NULL) - hk = HKEY_CURRENT_USER; - ec = RegOpenKeyEx (hk, path, 0, KEY_READ, &h); - if (ec != ERROR_SUCCESS) - return -1; - - ec = RegQueryValueEx(h, key, NULL, &type, NULL, &size); - if (ec != ERROR_SUCCESS) { - RegCloseKey (h); - return -1; - } - if (type == REG_EXPAND_SZ) { - char tmp[256]; /* XXX: do not use a static buf */ - RegQueryValueEx (h, key, NULL, NULL, (BYTE*)tmp, &size); - *val = expand_path (tmp); - } - else { - *val = xcalloc(1, size+1); - ec = RegQueryValueEx (h, key, NULL, &type, (BYTE*)*val, &size); - if (ec != ERROR_SUCCESS) { - xfree (*val); - *val = NULL; - RegCloseKey (h); - return -1; - } - } - RegCloseKey (h); - return 0; -} - - -static int -store_config_value (HKEY hk, const char *path, const char *key, const char *val) -{ - HKEY h; - int type; - int ec; - - if (hk == NULL) - hk = HKEY_CURRENT_USER; - ec = RegCreateKeyEx (hk, path, 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, NULL, &h, NULL); - if (ec != ERROR_SUCCESS) - { - log_debug_w32 (ec, "creating/opening registry key `%s' failed", path); - return -1; - } - type = strchr (val, '%')? REG_EXPAND_SZ : REG_SZ; - ec = RegSetValueEx (h, key, 0, type, (const BYTE*)val, strlen (val)); - if (ec != ERROR_SUCCESS) - { - log_debug_w32 (ec, "saving registry key `%s'->`%s' failed", path, key); - RegCloseKey(h); - return -1; - } - RegCloseKey(h); - return 0; -} - - /* To avoid writing a dialog template for each language we use gettext for the labels and hope that there is enough space in the dialog to fit teh longest translation. */ @@ -139,8 +42,8 @@ config_dlg_set_labels (HWND dlg) for (i=0; labels[i].itemid; i++) SetDlgItemText (dlg, labels[i].itemid, _(labels[i].label)); - -} + +} static BOOL CALLBACK config_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam) @@ -150,7 +53,7 @@ config_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam) const char *s; (void)lparam; - + switch (msg) { case WM_INITDIALOG: @@ -159,23 +62,21 @@ config_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam) SetDlgItemText (dlg, IDC_DEBUG_LOGFILE, s? s:""); config_dlg_set_labels (dlg); break; - + case WM_COMMAND: switch (LOWORD (wparam)) { - case IDOK: + case IDOK: n = GetDlgItemText (dlg, IDC_DEBUG_LOGFILE, name, MAX_PATH-1); set_log_file (n>0?name:NULL); EndDialog (dlg, TRUE); break; - } + } break; } - return FALSE; } - /* Display GPG configuration dialog. */ void config_dialog_box (HWND parent) @@ -193,21 +94,3 @@ config_dialog_box (HWND parent) (void)config_dlg_proc; #endif } - - - -/* Store a key in the registry with the key given by @key and the - value @value. */ -int -store_extension_value (const char *key, const char *val) -{ - return store_config_value (HKEY_CURRENT_USER, GPGOL_REGPATH, key, val); -} - -/* Load a key from the registry with the key given by @key. The value is - returned in @val and needs to freed by the caller. */ -int -load_extension_value (const char *key, char **val) -{ - return load_config_value (HKEY_CURRENT_USER, GPGOL_REGPATH, key, val); -} ----------------------------------------------------------------------- Summary of changes: src/common.c | 131 ++++++++++++++++++++++++++++++++++++++++ src/common.h | 10 ++- src/config-dialog.c | 129 ++------------------------------------- src/cpphelp.cpp | 115 ++++++++++++++++++++++++++++++++++- src/cpphelp.h | 5 ++ src/wks-helper.cpp | 171 ++++++++++++++++++++++++++++++++++++++++++++++------ src/wks-helper.h | 8 ++- 7 files changed, 421 insertions(+), 148 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 5 12:18:15 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 05 Mar 2018 12:18:15 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-1.1.0-5-gfa817f0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The standard pinentry collection". The branch, master has been updated via fa817f00363cdc305728ece6139d76361c77f361 (commit) from 141fd941a58f70692cb6244f011e54b005d2195c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fa817f00363cdc305728ece6139d76361c77f361 Author: Andre Heinecke Date: Mon Mar 5 12:16:44 2018 +0100 qt: Try again to fix Windows Window Management * qt/pinentrydialog.cpp (raiseWindow): Activate Window and disable windows hacks. (PinEntryDialog::PinEntryDialog): Delay setFocus after the event loop returns. -- This fixes getting the input focus on Windows without the Buggy AttachThreadInput hacks. diff --git a/qt/pinentrydialog.cpp b/qt/pinentrydialog.cpp index 5212f88..d42ae4a 100644 --- a/qt/pinentrydialog.cpp +++ b/qt/pinentrydialog.cpp @@ -53,16 +53,13 @@ does not always work (e.g. when the ForegroundWindow timeout has not expired. - [ah 2018-02-28] Disabled this again in favor of using + [ah 2018-03-05] Disabled this again in favor of using windows stays on top hint. The code that is in main - setup_foreground_window. - - [ah 2018-03-01] Enabled this again because the focus did - not change to the pinentry window without the attach - thread input stuff. The setup_foreground_window helps though - so that stays enabled. + setup_foreground_window. Additionally the setFocus + now works because it is posted after the window is shown + and our raise window also activates the pinentry window. */ -#ifdef Q_OS_WIN +#if 0 WINBOOL SetForegroundWindowEx(HWND hWnd) { //Attach foreground window thread to our thread @@ -83,10 +80,9 @@ WINBOOL SetForegroundWindowEx(HWND hWnd) void raiseWindow(QWidget *w) { - /* Maybe Qt will become aggressive enough one day that - * this is enough on windows too*/ + w->activateWindow(); w->raise(); -#ifdef Q_OS_WIN +#if 0 HWND wid = (HWND)w->effectiveWinId(); /* In the meantime we do our own attention grabbing */ if (!SetForegroundWindow(wid) && !SetForegroundWindowEx(wid)) { @@ -210,7 +206,7 @@ PinEntryDialog::PinEntryDialog(QWidget *parent, const char *name, connect(_edit, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString))); - _edit->setFocus(); + QTimer::singleShot(0, _edit, SLOT(setFocus())); QGridLayout *const grid = new QGridLayout(this); int row = 1; ----------------------------------------------------------------------- Summary of changes: qt/pinentrydialog.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 5 14:28:04 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 05 Mar 2018 14:28:04 +0100 Subject: [git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-62-g2a160cc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, async-enc has been updated via 2a160cc178f0278194ad833f92b4a5af95fe60c0 (commit) from e07ab6c300589dcc8de0129051ce0800f772a52c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: src/addin-options.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 5 14:28:05 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 05 Mar 2018 14:28:05 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-62-g2a160cc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 2a160cc178f0278194ad833f92b4a5af95fe60c0 (commit) via e07ab6c300589dcc8de0129051ce0800f772a52c (commit) via 2d069391aa5c5bace8a5460f0bdb60a1e015642a (commit) via bd2a79d9661a5e204a56e7b64da785b04ece1583 (commit) via ab5232cb52e4265be48c1d4d977aae45ad91f844 (commit) via 93b423f9632b7740dbf0a21341898fb3efb48b4a (commit) via 3e851bed56cba229a1a6de656c6639ffbc288081 (commit) via 16cf48705599010e380bc7c72ba8b2d945006471 (commit) via d6246cd90e33d530cfecf654cecc097d73bef038 (commit) via 6ec4348a7e575921db013b6cc9d1f0d07ae0ddb8 (commit) via eb1ed3493ebe49cbbb61fb4deb311f44f553b176 (commit) via 325b90573a184b65bf1d66e5f6f0eebeb9f0d6ea (commit) via 0853344d1dcf520ea657d7208661214f69b59dad (commit) via 9017cf6fb9c78a83d9d5d08d886c41878444369b (commit) via 569f4065d0863ac8c44c9f9c07fcd3b89ba4f7cb (commit) via 1a1c949670faf05f1f1ea1b1f66ca808e9c026dd (commit) via c5133586929626685ac6ceef57e775ac7761cdb0 (commit) via d483d0d02d99cd4b5b76213e17876e00bd6d6268 (commit) via 087562b5f4f6f72143efa59b9aea4582b1a10028 (commit) via 5c188d6a800675dc7b9017c257a0f2b757b9eb71 (commit) via 573661d09c07b67680be17418e13fcfa960c4a2d (commit) via 6436349496e052cddbebef7394fb88db60bb4846 (commit) via 7c611426da261b67dd422ada7ae5b85bd8265649 (commit) via e59a0ab7032ad219d1ed727831034ee51d12649f (commit) via acf089c3376a1e097ebc6d4cc1dde8ac124df8a8 (commit) via cc08ea5d290c279fcd69a7f6b712e20f9f8f5900 (commit) via e25a51950583d0ae051b38f0aed17522fb8f77b5 (commit) via ab69aab5ea815d377236f02f207ebb0aaaf6406a (commit) via 594b9eadcc1539e01e5539f51834c085fb477a19 (commit) via 8adf84384e24e7241068ac4bd3868ac6bc50079e (commit) via 7e065b097cce4a694e2c59161a2c97040f5d4ba2 (commit) via 49aa620f7d551976c36d0141fdaeaca5d0e94cd1 (commit) via 3e1974e6ee4fa457c0953faf5d4770338f8c999a (commit) via 6b5f7b1fb392fce7b87aa7aa2bdf329b2ffc3c1f (commit) via be3109df4ca2f3374658c05e40fe34a9a23c7612 (commit) via d66b17083386f8be9fe190814abbc41cf85e1290 (commit) via 31b54cd71c4ff798b04b129f1739852f93a72167 (commit) via 65599bb918388d537c29a3d29b4263497eb261de (commit) via cd5db6bf72dd3318d06a4861070ecdf2effec1a7 (commit) via c7b17baec73ee5191ee7a98c9e884e70bea3621d (commit) via 77208c29861a06b70a8f4464e3255f0818ba96b0 (commit) via 88118b5baaff9c7289d27ca55b084e5c1860f8aa (commit) via 193d521b1bd7161fa28b86524acaf2e7046dc343 (commit) via 26b931937fe139a9acd3240242e154d3789652f5 (commit) via 3ed205e7f9d96edfa03762c8692267f68d82ebb8 (commit) via ee673d23ae83563faabe5168019092203766e670 (commit) via c52f7ed9456ad1db74b09bc1eae32750b4277fee (commit) via f622470a3a291cd8d39e9dc45fa5d6496e66089d (commit) via e789048f47fccab444df477f6e82ece69fa2a8b4 (commit) via e133064eb799de9a1138f23afc5cd13d1b053fdf (commit) via bec715ab3f57709db1fbf4759b0b0593055b5b04 (commit) from 456cdf6165ef012769058507b5ef3edde729ca47 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: src/Makefile.am | 7 +- src/addin-options.cpp | 2 +- src/common.c | 177 +++++++ src/common.h | 14 +- src/common_indep.h | 4 +- src/config-dialog.c | 129 +---- src/cpphelp.cpp | 226 +++++++++ src/cpphelp.h | 47 ++ src/cryptcontroller.cpp | 995 +++++++++++++++++++++++++++++++++++++ src/cryptcontroller.h | 90 ++++ src/dialogs.h | 1 + src/dialogs.rc | 2 + src/engine-assuan.c | 37 -- src/icons/Makefile.am | 2 +- src/icons/lock.ico | Bin 0 -> 101758 bytes src/keycache.cpp | 566 +++++++++++++++++++++ src/keycache.h | 83 ++++ src/mail.cpp | 529 ++++++++++++++------ src/mail.h | 110 +++- src/mailitem-events.cpp | 199 ++++---- src/mapihelp.cpp | 38 +- src/mapihelp.h | 2 + src/message.cpp | 4 + src/mimemaker.cpp | 24 +- src/mimemaker.h | 20 + src/oomhelp.cpp | 135 ++++- src/oomhelp.h | 8 + src/overlay.cpp | 89 ++++ src/{addin-options.h => overlay.h} | 37 +- src/ribbon-callbacks.cpp | 16 +- src/windowmessages.cpp | 39 +- src/windowmessages.h | 6 +- src/wks-helper.cpp | 832 +++++++++++++++++++++++++++++++ src/wks-helper.h | 126 +++++ 34 files changed, 4137 insertions(+), 459 deletions(-) create mode 100644 src/cpphelp.cpp create mode 100644 src/cpphelp.h create mode 100644 src/cryptcontroller.cpp create mode 100644 src/cryptcontroller.h create mode 100644 src/icons/lock.ico create mode 100644 src/keycache.cpp create mode 100644 src/keycache.h create mode 100644 src/overlay.cpp copy src/{addin-options.h => overlay.h} (57%) create mode 100644 src/wks-helper.cpp create mode 100644 src/wks-helper.h hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 6 07:42:00 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 06 Mar 2018 07:42:00 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-68-gca90399 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via ca9039910b1171bf503d052dcdee898fa814aa3d (commit) from 53102e21518873edb355569469b9f98bd386d957 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ca9039910b1171bf503d052dcdee898fa814aa3d Author: Andre Heinecke Date: Tue Mar 6 07:41:05 2018 +0100 Fix w64 build * src/cryptcontroller.cpp (CryptController::resolve_keys): Use SIZE_T_FORMAT and hwnd conversion. * src/overlay.cpp (Overlay::Overlay): HWND cast to int is ok. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index a977e79..b3d39e5 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -384,7 +384,7 @@ CryptController::resolve_keys () { // Pass the handle of the active window for raise / overlay. args.push_back (std::string ("--hwnd")); - args.push_back (std::to_string ((int) wnd)); + args.push_back (std::to_string ((int) (intptr_t) wnd)); } // Set the overlay caption @@ -451,7 +451,7 @@ CryptController::resolve_keys () log_debug ("Spawning args:"); for (size_t i = 0; cargs && cargs[i]; i++) { - log_debug ("%i: '%s'", i, cargs[i]); + log_debug (SIZE_T_FORMAT ": '%s'", i, cargs[i]); } #endif diff --git a/src/overlay.cpp b/src/overlay.cpp index a6ba341..2078bd4 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -46,7 +46,7 @@ Overlay::Overlay (HWND wid, const std::string &text): m_wid (wid) args.push_back (overlayer); args.push_back (std::string ("--hwnd")); - args.push_back (std::to_string ((int) wid)); + args.push_back (std::to_string ((int) (intptr_t) wid)); args.push_back (std::string ("--overlayText")); args.push_back (text); ----------------------------------------------------------------------- Summary of changes: src/cryptcontroller.cpp | 4 ++-- src/overlay.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 6 11:58:49 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 06 Mar 2018 11:58:49 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-73-ga243c8a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via a243c8af5f07ea375f4953808d31c4933e79b928 (commit) via 7f4d6d27fa0242d6d48dcc8f54149fd77af4891f (commit) via 149a0928250aad96a78cf695ec91d9a396b42dbc (commit) via ba9ffe523a0848f35c6347e256f3cc74112752f7 (commit) via 8be065b5c8e095eea2ddbce5db2b5d2741a45dc4 (commit) from ca9039910b1171bf503d052dcdee898fa814aa3d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a243c8af5f07ea375f4953808d31c4933e79b928 Author: Andre Heinecke Date: Tue Mar 6 09:51:38 2018 +0100 Bring Outlook back into focus after enc/sign * src/mail.cpp (do_crypt): Send BRING_TO_FRONT message after encryption. * src/windowmessages.cpp, src/windowmessages.h: New call to bring the active outlook window to front. -- As explained in the comment this is a workaround for strange behavior with pinentry and foreground windows. After encrypt/sign often times the wrong window has focus. So we better bring Outlook to front. GnuPG-Bug-Id: T3732 diff --git a/src/mail.cpp b/src/mail.cpp index 04dec00..07b41a7 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -759,6 +759,13 @@ do_crypt (LPVOID arg) mail->update_crypt_mapi (); mail->set_crypt_state (Mail::NeedsUpdateInOOM); } + /* This works around a bug in pinentry that it might + bring the wrong window to front. So after encryption / + signing we bring outlook back to front. + + See GnuPG-Bug-Id: T3732 + */ + do_in_ui_thread_async (BRING_TO_FRONT, nullptr); gpgrt_lock_unlock (&dtor_lock); return 0; } diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index e9934a5..b0e2311 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -118,6 +118,22 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) WKSHelper::instance()->allow_notify (); break; } + case (BRING_TO_FRONT): + { + HWND wnd = get_active_hwnd (); + if (wnd) + { + log_debug ("%s:%s: Bringing window %p to front.", + SRCNAME, __func__, wnd); + bring_to_front (wnd); + } + else + { + log_debug ("%s:%s: No active window found for bring to front.", + SRCNAME, __func__); + } + break; + } case (WKS_NOTIFY): { WKSHelper::instance ()->notify ((const char *) ctx->data); diff --git a/src/windowmessages.h b/src/windowmessages.h index 8fdd55e..979f0b4 100644 --- a/src/windowmessages.h +++ b/src/windowmessages.h @@ -49,6 +49,7 @@ typedef enum _gpgol_wmsg_type CLOSE, /* Close the message in the next event loop. */ CRYPTO_DONE, /* Sign / Encrypt done. */ WKS_NOTIFY, /* Show a WKS Notification. */ + BRING_TO_FRONT, /* Bring the active Outlook window to the front. */ } gpgol_wmsg_type; typedef struct commit 7f4d6d27fa0242d6d48dcc8f54149fd77af4891f Author: Andre Heinecke Date: Tue Mar 6 09:50:52 2018 +0100 Add new Window Message helper * src/windowmessages.cpp (do_async, do_in_ui_thread_async): Add new fire and forget window messaging helper. * src/windowmessages.h: Update accordingly. diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index 9bb0f5c..e9934a5 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -194,6 +194,25 @@ do_in_ui_thread (gpgol_wmsg_type type, void *data) return ctx.err; } +static DWORD WINAPI +do_async (LPVOID arg) +{ + wm_ctx_t *ctx = (wm_ctx_t*) arg; + send_msg_to_ui_thread (ctx); + xfree (ctx); + return 0; +} + +void +do_in_ui_thread_async (gpgol_wmsg_type type, void *data) +{ + wm_ctx_t *ctx = (wm_ctx_t *) calloc (1, sizeof (wm_ctx_t)); + ctx->wmsg_type = type; + ctx->data = data; + + CloseHandle (CreateThread (NULL, 0, do_async, (LPVOID) ctx, 0, NULL)); +} + static std::vector explorers; void diff --git a/src/windowmessages.h b/src/windowmessages.h index 69762af..8fdd55e 100644 --- a/src/windowmessages.h +++ b/src/windowmessages.h @@ -73,6 +73,11 @@ send_msg_to_ui_thread (wm_ctx_t *ctx); int do_in_ui_thread (gpgol_wmsg_type type, void *data); +/** Send a message to the UI thread but returns + immediately without waiting for the execution. */ +void +do_in_ui_thread_async (gpgol_wmsg_type type, void *data); + /** Create our filter before outlook Window Messages. */ HHOOK create_message_hook(); commit 149a0928250aad96a78cf695ec91d9a396b42dbc Author: Andre Heinecke Date: Tue Mar 6 09:02:20 2018 +0100 Be more lenient with broken PGP Inline messages * src/mimedataprovider.cpp (MimeDataProvider::collect_data): Fix up PGP Messages. -- In the Outlook world sometimes messages are rewritten / converted to HTML and then converted back to Plaintext etc. This can lead to broken PGP Messages where there is extra whitespace. We now fix up the whitespace and remove comments in the Mimedataprovider in the spirit of trying to accept as much input as possible. GnuPG-Bug-Id: T3821 diff --git a/src/mimedataprovider.cpp b/src/mimedataprovider.cpp index a760486..ff6538c 100644 --- a/src/mimedataprovider.cpp +++ b/src/mimedataprovider.cpp @@ -22,12 +22,14 @@ #include "xmalloc.h" #include #include +#include #include "mimedataprovider.h" #include "parsetlv.h" #include "rfc822parse.h" #include "rfc2047parse.h" #include "attachment.h" +#include "cpphelp.h" #ifndef HAVE_W32_SYSTEM #define stricmp strcasecmp @@ -770,6 +772,8 @@ MimeDataProvider::collect_data(LPSTREAM stream) char buf[BUFSIZE]; ULONG bRead; bool first_read = true; + bool is_pgp_message = false; + size_t allRead = 0; while ((hr = stream->Read (buf, BUFSIZE, &bRead)) == S_OK || hr == S_FALSE) { @@ -777,11 +781,11 @@ MimeDataProvider::collect_data(LPSTREAM stream) { log_mime_parser ("%s:%s: Input stream at EOF.", SRCNAME, __func__); - return; + break; } log_mime_parser ("%s:%s: Read %lu bytes.", SRCNAME, __func__, bRead); - + allRead += bRead; if (first_read) { if (bRead > 12 && strncmp ("MIME-Version", buf, 12) == 0) @@ -800,6 +804,18 @@ MimeDataProvider::collect_data(LPSTREAM stream) SRCNAME, __func__); } + /* check for the PGP MESSAGE marker to see if we have it. */ + if (bRead && m_collect_everything) + { + std::string tmp (buf, bRead); + std::size_t found = tmp.find ("-----BEGIN PGP MESSAGE-----"); + if (found != std::string::npos) + { + log_debug ("%s:%s: found PGP Message marker,", + SRCNAME, __func__); + is_pgp_message = true; + } + } } first_read = false; @@ -822,12 +838,53 @@ MimeDataProvider::collect_data(LPSTREAM stream) log_error ("%s:%s: Collect failed to consume anything.\n" "Buffer too small?", SRCNAME, __func__); - return; + break; } log_mime_parser ("%s:%s: Consumed: " SIZE_T_FORMAT " bytes", SRCNAME, __func__, m_rawbuf.size() - not_taken); m_rawbuf.erase (0, m_rawbuf.size() - not_taken); } + + + if (is_pgp_message && allRead < (1024 * 100)) + { + /* Sometimes received PGP Messsages contain extra whitespace / + newlines. To also accept such messages we fix up pgp inline + messages here. We only do this for messages which are smaller + then a hundred KByte for performance. */ + log_debug ("%s:%s: Fixing up a possible broken message.", + SRCNAME, __func__); + /* Copy crypto data to string */ + std::string data = m_crypto_data.toString(); + m_crypto_data = GpgME::Data(); + std::istringstream iss (data); + // Now parse it by line. + std::string line; + while (std::getline (iss, line)) + { + trim (line); + if (line == "-----BEGIN PGP MESSAGE-----") + { + /* Finish an armor header */ + line += "\n\n"; + m_crypto_data.write (line.c_str (), line.size ()); + continue; + } + /* Remove empty lines */ + if (line.empty()) + { + continue; + } + if (line.find (':') != std::string::npos) + { + log_mime_parser ("%s:%s: Removing comment '%s'.", + SRCNAME, __func__, line.c_str ()); + continue; + } + line += '\n'; + m_crypto_data.write (line.c_str (), line.size ()); + } + } } #endif commit ba9ffe523a0848f35c6347e256f3cc74112752f7 Author: Andre Heinecke Date: Tue Mar 6 09:01:33 2018 +0100 Add trim and ltrim to cpphelp * src/cpphelp.cpp (ltrim, trim): New. * src/cpphelp.h: Update accordingly. diff --git a/src/cpphelp.cpp b/src/cpphelp.cpp index 8d38feb..122703e 100644 --- a/src/cpphelp.cpp +++ b/src/cpphelp.cpp @@ -48,10 +48,26 @@ release_cArray (char **carray) } void -rtrim(std::string &s) { - s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { - return !std::isspace(ch); - }).base(), s.end()); +rtrim(std::string &s) +{ + s.erase (std::find_if (s.rbegin(), s.rend(), [] (int ch) { + return !std::isspace(ch); + }).base(), s.end()); +} + +void +ltrim(std::string &s) +{ + s.erase (s.begin(), std::find_if (s.begin(), s.end(), [] (int ch) { + return !std::isspace(ch); + })); +} + +void +trim(std::string &s) +{ + ltrim (s); + rtrim (s); } char ** diff --git a/src/cpphelp.h b/src/cpphelp.h index 51ffe80..c2f2983 100644 --- a/src/cpphelp.h +++ b/src/cpphelp.h @@ -32,7 +32,9 @@ void release_cArray (char **carray); /* Trim whitespace from a string. */ -void rtrim(std::string &s); +void rtrim (std::string &s); +void ltrim (std::string &s); +void trim (std::string &s); /* Convert a string vector to a null terminated char array */ char **vector_to_cArray (const std::vector &vec); commit 8be065b5c8e095eea2ddbce5db2b5d2741a45dc4 Author: Andre Heinecke Date: Tue Mar 6 08:36:53 2018 +0100 Auto update translation * po/de.po: Msgmerge moves the newline. diff --git a/po/de.po b/po/de.po index 1436756..c0f8061 100644 --- a/po/de.po +++ b/po/de.po @@ -1152,8 +1152,7 @@ msgstr "" "\n" "Tragen Sie ihren ?ffentlichen Schl?ssel in diesem\n" "Verzeichnis ein um es anderen leicht zu machen ihnen verschl?sselte\n" -"Mails zu schicken. " -"\n" +"Mails zu schicken. \n" "Dies ist sicher und kostenlos!\n" "\n" "Automatisch eintragen?" ----------------------------------------------------------------------- Summary of changes: po/de.po | 3 +-- src/cpphelp.cpp | 24 +++++++++++++++--- src/cpphelp.h | 4 ++- src/mail.cpp | 7 ++++++ src/mimedataprovider.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++--- src/windowmessages.cpp | 35 +++++++++++++++++++++++++++ src/windowmessages.h | 6 +++++ 7 files changed, 132 insertions(+), 10 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 6 15:17:47 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 06 Mar 2018 15:17:47 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-75-gb4c25ec Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via b4c25ecda4b02f1c3dda9ce424ce21aa5471509e (commit) via 4f97c6c378cc93c889c8f9f0977af77df4510f60 (commit) from a243c8af5f07ea375f4953808d31c4933e79b928 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b4c25ecda4b02f1c3dda9ce424ce21aa5471509e Author: Andre Heinecke Date: Tue Mar 6 15:11:26 2018 +0100 Prefer Sender over SendUsingAccount for crypt mail * src/mail.cpp (Mail::update_oom_data): Prefer the Sender fallbacks before using sendUsingAccount for crypto mail (reading). -- GnuPG-Bug-Id: T3802 diff --git a/src/mail.cpp b/src/mail.cpp index 5fd8c55..db27ee6 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1259,13 +1259,19 @@ Mail::update_oom_data () outlook will keep the SenderEmailAddress of UserA. This is all so horrible. */ buf = get_sender_SenderEMailAddress (m_mailitem); + + if (!buf) + { + /* Try the sender Object */ + buf = get_sender_Sender (m_mailitem); + } } if (!buf) { buf = get_sender_SendUsingAccount (m_mailitem, &m_is_gsuite); } - if (!buf) + if (!buf && !is_crypto_mail ()) { /* Try the sender Object */ buf = get_sender_Sender (m_mailitem); commit 4f97c6c378cc93c889c8f9f0977af77df4510f60 Author: Andre Heinecke Date: Tue Mar 6 15:02:41 2018 +0100 Factor sender fallbacks into seperate functs * src/mail.cpp (Mail::update_oom_data): Move out sender fallbacks. * src/oomhelp.cpp, src/oomhelp.h (get_sender_CurrentUser), (get_sender_Sender, get_sender_SenderEMailAddress) (get_sender_SendUsingAccount): New. -- This should not do a functional change. diff --git a/src/mail.cpp b/src/mail.cpp index 07b41a7..5fd8c55 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1224,7 +1224,7 @@ Mail::wipe (bool force) int Mail::update_oom_data () { - LPDISPATCH sender = NULL; + char *buf = nullptr; log_debug ("%s:%s", SRCNAME, __func__); if (!is_crypto_mail()) @@ -1258,98 +1258,33 @@ Mail::update_oom_data () you send from the folder of userA but change the from to userB outlook will keep the SenderEmailAddress of UserA. This is all so horrible. */ - char *type = get_oom_string (m_mailitem, "SenderEmailType"); - if (type && !strcmp ("SMTP", type)) - { - char *senderMail = get_oom_string (m_mailitem, "SenderEmailAddress"); - if (senderMail) - { - log_debug ("%s:%s Sender found", SRCNAME, __func__); - m_sender = senderMail; - xfree (senderMail); - xfree (type); - return 0; - } - } - xfree (type); + buf = get_sender_SenderEMailAddress (m_mailitem); } - sender = get_oom_object (m_mailitem, "SendUsingAccount"); - if (sender) - { - char *buf = get_oom_string (sender, "SmtpAddress"); - char *dispName = get_oom_string (sender, "DisplayName"); - gpgol_release (sender); - /* Check for G Suite account */ - if (dispName && !strcmp ("G Suite", dispName)) - { - m_is_gsuite = true; - } - xfree (dispName); - if (buf && strlen (buf)) - { - log_debug ("%s:%s Sender fallback 1", SRCNAME, __func__); - m_sender = buf; - xfree (buf); - return 0; - } - xfree (buf); + if (!buf) + { + buf = get_sender_SendUsingAccount (m_mailitem, &m_is_gsuite); } - /* Fallback to Sender object */ - sender = get_oom_object (m_mailitem, "Sender"); - if (sender) + if (!buf) { - char *buf = get_pa_string (sender, PR_SMTP_ADDRESS_DASL); - gpgol_release (sender); - if (buf && strlen (buf)) - { - log_debug ("%s:%s Sender fallback 2", SRCNAME, __func__); - m_sender = buf; - xfree (buf); - return 0; - } - xfree (buf); - /* We have a sender object but not yet an smtp address likely - exchange. Try some more propertys of the message. */ - buf = get_pa_string (m_mailitem, PR_TAG_SENDER_SMTP_ADDRESS); - if (buf && strlen (buf)) - { - log_debug ("%s:%s Sender fallback 3", SRCNAME, __func__); - m_sender = buf; - xfree (buf); - return 0; - } - xfree (buf); - buf = get_pa_string (m_mailitem, PR_TAG_RECEIVED_REPRESENTING_SMTP_ADDRESS); - if (buf && strlen (buf)) - { - log_debug ("%s:%s Sender fallback 4", SRCNAME, __func__); - m_sender = buf; - xfree (buf); - return 0; - } - xfree (buf); + /* Try the sender Object */ + buf = get_sender_Sender (m_mailitem); } - /* We don't have s sender object or SendUsingAccount, - well, in that case fall back to the current user. */ - sender = get_oom_object (m_mailitem, "Session.CurrentUser"); - if (sender) + if (!buf) { - char *buf = get_pa_string (sender, PR_SMTP_ADDRESS_DASL); - gpgol_release (sender); - if (buf && strlen (buf)) - { - log_debug ("%s:%s Sender fallback 5", SRCNAME, __func__); - m_sender = buf; - xfree (buf); - return 0; - } - xfree (buf); + /* We don't have s sender object or SendUsingAccount, + well, in that case fall back to the current user. */ + buf = get_sender_CurrentUser (m_mailitem); } - - log_debug ("%s:%s: All fallbacks failed.", - SRCNAME, __func__); - return -1; + if (!buf) + { + log_debug ("%s:%s: All fallbacks failed.", + SRCNAME, __func__); + return -1; + } + m_sender = buf; + xfree (buf); + return 0; } std::string diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp index 69695f1..ba3d89f 100644 --- a/src/oomhelp.cpp +++ b/src/oomhelp.cpp @@ -1900,3 +1900,105 @@ get_account_for_mail (const char *mbox) return nullptr; } + +char * +get_sender_SendUsingAccount (LPDISPATCH mailitem, bool *r_is_GSuite) +{ + LPDISPATCH sender = get_oom_object (mailitem, "SendUsingAccount"); + if (!sender) + { + return nullptr; + } + + char *buf = get_oom_string (sender, "SmtpAddress"); + char *dispName = get_oom_string (sender, "DisplayName"); + gpgol_release (sender); + + /* Check for G Suite account */ + if (dispName && !strcmp ("G Suite", dispName) && r_is_GSuite) + { + *r_is_GSuite = true; + } + xfree (dispName); + if (buf && strlen (buf)) + { + log_debug ("%s:%s: found sender", SRCNAME, __func__); + return buf; + } + xfree (buf); + return nullptr; +} + +char * +get_sender_Sender (LPDISPATCH mailitem) +{ + LPDISPATCH sender = get_oom_object (mailitem, "Sender"); + if (!sender) + { + return nullptr; + } + char *buf = get_pa_string (sender, PR_SMTP_ADDRESS_DASL); + gpgol_release (sender); + if (buf && strlen (buf)) + { + log_debug ("%s:%s Sender fallback 2", SRCNAME, __func__); + return buf; + } + xfree (buf); + /* We have a sender object but not yet an smtp address likely + exchange. Try some more propertys of the message. */ + buf = get_pa_string (mailitem, PR_TAG_SENDER_SMTP_ADDRESS); + if (buf && strlen (buf)) + { + log_debug ("%s:%s Sender fallback 3", SRCNAME, __func__); + return buf; + } + xfree (buf); + buf = get_pa_string (mailitem, PR_TAG_RECEIVED_REPRESENTING_SMTP_ADDRESS); + if (buf && strlen (buf)) + { + log_debug ("%s:%s Sender fallback 4", SRCNAME, __func__); + return buf; + } + xfree (buf); + return nullptr; +} + +char * +get_sender_CurrentUser (LPDISPATCH mailitem) +{ + LPDISPATCH sender = get_oom_object (mailitem, + "Session.CurrentUser"); + if (!sender) + { + return nullptr; + } + char *buf = get_pa_string (sender, PR_SMTP_ADDRESS_DASL); + gpgol_release (sender); + if (buf && strlen (buf)) + { + log_debug ("%s:%s Sender fallback 5", SRCNAME, __func__); + return buf; + } + xfree (buf); + return nullptr; +} + +char * +get_sender_SenderEMailAddress (LPDISPATCH mailitem) +{ + + char *type = get_oom_string (mailitem, "SenderEmailType"); + if (type && !strcmp ("SMTP", type)) + { + char *senderMail = get_oom_string (mailitem, "SenderEmailAddress"); + if (senderMail) + { + log_debug ("%s:%s: Sender found", SRCNAME, __func__); + xfree (type); + return senderMail; + } + } + xfree (type); + return nullptr; +} diff --git a/src/oomhelp.h b/src/oomhelp.h index 430fee1..2af096b 100644 --- a/src/oomhelp.h +++ b/src/oomhelp.h @@ -333,7 +333,13 @@ HWND get_active_hwnd (void); LPDISPATCH create_mail (void); LPDISPATCH get_account_for_mail (const char *mbox); + +/* Sender fallbacks. All return either null or a malloced address. */ +char *get_sender_CurrentUser (LPDISPATCH mailitem); +char *get_sender_Sender (LPDISPATCH mailitem); +char *get_sender_SenderEMailAddress (LPDISPATCH mailitem); #ifdef __cplusplus +char *get_sender_SendUsingAccount (LPDISPATCH mailitem, bool *r_is_GSuite); } #endif #endif /*OOMHELP_H*/ ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 109 +++++++++++++------------------------------------------- src/oomhelp.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/oomhelp.h | 6 ++++ 3 files changed, 133 insertions(+), 84 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 6 16:30:10 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 06 Mar 2018 16:30:10 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-7-gf060cb5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via f060cb5c63923d6caec784f65f3bb0aadf52f795 (commit) from bf43b39c05cfc68ea17483c78f14bfca6faf08eb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f060cb5c63923d6caec784f65f3bb0aadf52f795 Author: Werner Koch Date: Tue Mar 6 16:22:42 2018 +0100 agent: Also evict cached items via a timer. * agent/cache.c (agent_cache_housekeeping): New func. * agent/gpg-agent.c (handle_tick): Call it. -- This change mitigates the risk of having cached items in a post mortem dump. GnuPG-bug-id: 3829 Signed-off-by: Werner Koch diff --git a/agent/agent.h b/agent/agent.h index c2d8579..743b765 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -450,6 +450,7 @@ int agent_clear_passphrase (ctrl_t ctrl, /*-- cache.c --*/ void initialize_module_cache (void); void deinitialize_module_cache (void); +void agent_cache_housekeeping (void); void agent_flush_cache (void); int agent_put_cache (const char *key, cache_mode_t cache_mode, const char *data, int ttl); diff --git a/agent/cache.c b/agent/cache.c index 80d5f8d..ed5c97c 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -259,6 +259,26 @@ housekeeping (void) void +agent_cache_housekeeping (void) +{ + int res; + + if (DBG_CACHE) + log_debug ("agent_cache_housekeeping\n"); + + res = npth_mutex_lock (&cache_lock); + if (res) + log_fatal ("failed to acquire cache mutex: %s\n", strerror (res)); + + housekeeping (); + + res = npth_mutex_unlock (&cache_lock); + if (res) + log_fatal ("failed to release cache mutex: %s\n", strerror (res)); +} + + +void agent_flush_cache (void) { ITEM r; diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index a1964ec..bd9a471 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -2398,6 +2398,9 @@ handle_tick (void) } #endif + /* Need to check for expired cache entries. */ + agent_cache_housekeeping (); + /* Check whether the homedir is still available. */ if (!shutdown_pending && (!have_homedir_inotify || !reliable_homedir_inotify) diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 3e8bd89..4781bbd 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -403,7 +403,10 @@ control this behavior but this command line option takes precedence. Set the time a cache entry is valid to @var{n} seconds. The default is 600 seconds. Each time a cache entry is accessed, the entry's timer is reset. To set an entry's maximum lifetime, use - at command{max-cache-ttl}. + at command{max-cache-ttl}. Note that a cached passphrase may not +evicted immediately from memory if no client requests a cache +operation. This is due to an internal housekeeping function which is +only run every few seconds. @item --default-cache-ttl-ssh @var{n} @opindex default-cache-ttl ----------------------------------------------------------------------- Summary of changes: agent/agent.h | 1 + agent/cache.c | 20 ++++++++++++++++++++ agent/gpg-agent.c | 3 +++ doc/gpg-agent.texi | 5 ++++- 4 files changed, 28 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 6 16:36:34 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 06 Mar 2018 16:36:34 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.5-120-gf574aab Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via f574aabeeb873f14a586f80cac16b857e6088534 (commit) via f060cb5c63923d6caec784f65f3bb0aadf52f795 (commit) via bf43b39c05cfc68ea17483c78f14bfca6faf08eb (commit) via fd595c9d3642dba437fbe0f6e25d7aaaae095f94 (commit) via e43844c3b0b9ec93b7f2a88752bcd6b6244aacfb (commit) via ecfc4db3a2f8bc2652ba4ac4de5ca1cd13bfcbec (commit) via 641aae783e46af9eb47994dd598df4e51fb8296c (commit) from f2c09203b98b83669a460dc8161283de96022536 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f574aabeeb873f14a586f80cac16b857e6088534 Merge: f2c0920 f060cb5 Author: Werner Koch Date: Tue Mar 6 16:26:26 2018 +0100 Merge branch 'STABLE-BRANCH-2-2' into wk-master ----------------------------------------------------------------------- Summary of changes: agent/agent.h | 1 + agent/cache.c | 20 ++++++++++++++++++++ agent/gpg-agent.c | 3 +++ dirmngr/ks-engine-hkp.c | 2 ++ doc/gpg-agent.texi | 5 ++++- doc/gpgsm.texi | 2 +- g10/call-agent.c | 23 +++++++++++++++++++++-- g10/call-agent.h | 3 +++ g10/card-util.c | 41 +++++++++++++++++++++++++++++++++++------ tools/gpgconf-comp.c | 4 +++- 10 files changed, 93 insertions(+), 11 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 7 06:19:45 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 07 Mar 2018 06:19:45 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, created. gpgme-1.10.0-52-g3a746d5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been created at 3a746d5d46ffd7d332dc24fd6a4d24efc5fc1230 (commit) - Log ----------------------------------------------------------------- commit 3a746d5d46ffd7d332dc24fd6a4d24efc5fc1230 Author: Ben McGinnes Date: Wed Mar 7 16:11:35 2018 +1100 copyright fix * Made the copyright line a new top level org heading in order to prevent it getting folded into other tasks which will eventually get closed (so it doesn't go missing if those items are subsequently archived). diff --git a/TODO b/TODO index ae6ff13..a431651 100644 --- a/TODO +++ b/TODO @@ -578,7 +578,11 @@ Hey Emacs, this is -*- org -*- mode! Write a guide/best practices for maintainers of GPGME packages with third party package management systems. -Copyright 2004, 2005, 2018 g10 Code GmbH + +* Copyright 2004, 2005, 2018 g10 Code GmbH + :PROPERTIES: + :CUSTOM_ID: copyright-and-license + :END: This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without commit 13d2164cd9f313b409b2210d9e63465681cccc99 Author: Ben McGinnes Date: Wed Mar 7 16:07:24 2018 +1100 Nuxed doubles * Just because there's a lot of documentation which needs to be added, doesn't mean it needs to be listed twice. Merged the two lists. diff --git a/TODO b/TODO index d02a0d2..ae6ff13 100644 --- a/TODO +++ b/TODO @@ -1,22 +1,5 @@ Hey Emacs, this is -*- org -*- mode! -* Document all the new stuff. - :PROPERTIES: - :CUSTOM_ID: more-docs-is-better - :END: -** TODO Fix this TODO list. - :PROPERTIES: - :CUSTOM_ID: fix-todo - :END: - Clean up the current TODO list. Include properties as relevant (so - if someone does make a PDF or HTML version the TOC will work). - - Also check ans see if some of these ancient things can be removed - (e.g. do we really need to fix things that were broken in GPG - 1.3.x? I'm thinking not so much). - - - * Fix the remaining UI Server problems: :PROPERTIES: :CUSTOM_ID: ui-server-fix @@ -264,27 +247,42 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: documentation :END: + ** TODO Document validity and trust issues. :PROPERTIES: :CUSTOM_ID: valid-trust-issues :END: + ** In gpgme.texi: Register callbacks under the right letter in the index. :PROPERTIES: :CUSTOM_ID: gpgme-texi :END: -** TODO Update TODO file + +** Document all the new stuff. :PROPERTIES: - :CUSTOM_ID: todo-update + :CUSTOM_ID: more-docs-is-better :END: -*** DONE fix TODO items - CLOSED: [2018-03-04 Sun 08:55] +*** TODO Fix this TODO list. :PROPERTIES: - :CUSTOM_ID: fix-todo-items + :CUSTOM_ID: fix-todo :END: - Adjust todo items so each can now be referenced by custom-id and - checked off as necessary. + Clean up the current TODO list. Include properties as relevant (so + if someone does make a PDF or HTML version the TOC will work). + + Also check ans see if some of these ancient things can be removed + (e.g. do we really need to fix things that were broken in GPG + 1.3.x? I'm thinking not so much). + +**** DONE fix TODO items + CLOSED: [2018-03-04 Sun 08:55] + :PROPERTIES: + :CUSTOM_ID: fix-todo-items + :END: + + Adjust todo items so each can now be referenced by custom-id and + checked off as necessary. * Engines :PROPERTIES: commit 1516c56ee4da28eb720bbacb026892393d10b24a Author: Ben McGinnes Date: Wed Mar 7 10:41:18 2018 +1100 Removed double * default.profraw didn't need to be listed twice. diff --git a/.gitignore b/.gitignore index de173b8..e5bf69d 100644 --- a/.gitignore +++ b/.gitignore @@ -52,4 +52,3 @@ nosetests.xml default.profraw .DS_Store ._.DS_Store -default.profraw \ No newline at end of file commit f61d4f585f27c13fabf7a23ad295bdc8bea7c838 Author: Ben McGinnes Date: Mon Mar 5 09:40:41 2018 +1100 IDENTIFY * Fixed sp error in docstring. diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c index 3e2dc78..e7a7a6f 100644 --- a/src/gpgme-tool.c +++ b/src/gpgme-tool.c @@ -3101,7 +3101,7 @@ cmd_hash_algo_name (assuan_context_t ctx, char *line) static const char hlp_identify[] = - "IDENTIY\n" + "IDENTIFY\n" "\n" "Identify the type of data set with the INPUT command."; static gpg_error_t ----------------------------------------------------------------------- hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 7 08:24:47 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 07 Mar 2018 08:24:47 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-77-g808be5a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 808be5a08d8a6f46f9e6eff82e23797ae9ec5343 (commit) via 4040b97d6d4177ed64765c5666175b09f780a1bd (commit) from b4c25ecda4b02f1c3dda9ce424ce21aa5471509e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 808be5a08d8a6f46f9e6eff82e23797ae9ec5343 Author: Andre Heinecke Date: Wed Mar 7 08:24:31 2018 +0100 Auto update translations * po/: update. diff --git a/po/de.po b/po/de.po index c0f8061..d516fd5 100644 --- a/po/de.po +++ b/po/de.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL 1.0.0\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-05 14:35+0100\n" -"PO-Revision-Date: 2018-03-05 14:43+0100\n" +"POT-Creation-Date: 2018-03-06 15:25+0100\n" +"PO-Revision-Date: 2018-03-07 08:24+0100\n" "Last-Translator: Andre Heinecke \n" "Language-Team: English \n" "Language: en_US\n" @@ -46,7 +46,7 @@ msgstr "Neue Nachrichten per Voreinstellung signieren" #: src/addin-options.cpp:46 msgid "&Send OpenPGP mails without attachments as PGP/Inline" -msgstr "&OpenPGP-Nachrichten ohne Anh?nge als PGP/Inline verschl?sseln" +msgstr "&OpenPGP-Nachrichten ohne Anh?nge als PGP/Inline senden" #: src/addin-options.cpp:48 msgid "S&elect crypto settings automatically for reply and forward" @@ -175,11 +175,11 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "M?chten Sie diesen Ordner von GpgOL befreien?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1743 src/mail.cpp:1814 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 msgid "GpgOL: Encrypted Message" msgstr "GpgOL: Verschl?sselte Nachricht" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1744 src/mail.cpp:1815 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 msgid "GpgOL: Trusted Sender Address" msgstr "GpgOL: Vertraute Absenderadresse" @@ -425,11 +425,11 @@ msgstr "" msgid "GpgOL Warning" msgstr "GpgOL Warnung" -#: src/mail.cpp:804 +#: src/mail.cpp:811 msgid "Pubkey directory confirmation" msgstr "?schl Verzeichnis Best?tigung" -#: src/mail.cpp:805 +#: src/mail.cpp:812 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -443,19 +443,19 @@ msgstr "" "

Wenn sie dies nicht angefordert haben, k?nnen Sie diese Mail ignorieren.\n" -#: src/mail.cpp:813 src/mail.cpp:2058 +#: src/mail.cpp:820 src/mail.cpp:2006 msgid "Encrypted message" msgstr "Verschl?sselte Nachricht" -#: src/mail.cpp:814 +#: src/mail.cpp:821 msgid "Please wait while the message is being decrypted / verified..." msgstr "Bitte warten Sie w?hrend die Nachricht entschl?sselt / gepr?ft wird..." -#: src/mail.cpp:1088 +#: src/mail.cpp:1095 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "GpgOL: Oops, G Suite Sync Konto erkannt" -#: src/mail.cpp:1092 +#: src/mail.cpp:1099 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -468,7 +468,7 @@ msgstr "" "\n" "Details siehe: https://dev.gnupg.org/T3545" -#: src/mail.cpp:1107 +#: src/mail.cpp:1114 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -481,7 +481,7 @@ msgstr "" "\n" "Details siehe: https://dev.gnupg.org/T3545" -#: src/mail.cpp:1122 +#: src/mail.cpp:1129 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -498,93 +498,93 @@ msgstr "" "\n" "M?chten Sie die Nachricht nur verschl?sseln?" -#: src/mail.cpp:2003 +#: src/mail.cpp:1951 msgid "Security Level 4" msgstr "Sicherheit Stufe 4" -#: src/mail.cpp:2007 +#: src/mail.cpp:1955 msgid "Trust Level 4" msgstr "Vertrauen Stufe 4" -#: src/mail.cpp:2011 +#: src/mail.cpp:1959 msgid "Security Level 3" msgstr "Sicherheit Stufe 3" -#: src/mail.cpp:2015 +#: src/mail.cpp:1963 msgid "Trust Level 3" msgstr "Vertrauen Stufe 3" -#: src/mail.cpp:2019 +#: src/mail.cpp:1967 msgid "Security Level 2" msgstr "Sicherheit Stufe 2" -#: src/mail.cpp:2023 +#: src/mail.cpp:1971 msgid "Trust Level 2" msgstr "Vertrauen Stufe 2" -#: src/mail.cpp:2027 +#: src/mail.cpp:1975 msgid "Encrypted" msgstr "Verschl?sselt" -#: src/mail.cpp:2036 src/mail.cpp:2038 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "Unsicher" -#: src/mail.cpp:2050 +#: src/mail.cpp:1998 msgid "Signed and encrypted message" msgstr "Signierte und verschl?sselte Nachricht" -#: src/mail.cpp:2054 +#: src/mail.cpp:2002 msgid "Signed message" msgstr "Signierte Nachricht" -#: src/mail.cpp:2061 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 msgid "Insecure message" msgstr "Unsichere Nachricht" -#: src/mail.cpp:2072 src/mail.cpp:2083 +#: src/mail.cpp:2020 src/mail.cpp:2031 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" "Sie k?nnen nicht sicher sein wer die Nachricht gesendet, modifiziert oder " "w?hrend der ?bertragung gelesen hat." -#: src/mail.cpp:2075 +#: src/mail.cpp:2023 msgid "The message was signed but the verification failed with:" msgstr "Die Nachricht ist signiert aber die ?berpr?fung schlug fehl mit:" -#: src/mail.cpp:2093 +#: src/mail.cpp:2041 msgid "The encryption was VS-NfD-compliant." msgstr "Diese Verschl?sselung war VS-NfD-konform." -#: src/mail.cpp:2097 +#: src/mail.cpp:2045 msgid "The encryption was not VS-NfD-compliant." msgstr "Diese Verschl?sselung war nicht VS-NfD-konform." -#: src/mail.cpp:2101 +#: src/mail.cpp:2049 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" "Aber Sie k?nnen nicht sicher sein wer der Absender der Nachricht ist da " "diese nicht signiert wurde. " -#: src/mail.cpp:2124 +#: src/mail.cpp:2072 msgid "You signed this message." msgstr "Sie haben diese Nachricht signiert." -#: src/mail.cpp:2128 +#: src/mail.cpp:2076 msgid "The senders identity was certified by yourself." msgstr "Die Idenit?t des Absenders wurde von ihnen selbst beglaubigt." -#: src/mail.cpp:2132 +#: src/mail.cpp:2080 msgid "The sender is allowed to certify identities for you." msgstr "Der Absender ist berechtigt f?r Sie Identit?ten zu beglaubigen." -#: src/mail.cpp:2145 +#: src/mail.cpp:2093 msgid "The senders identity was certified by several trusted people." msgstr "" "Die Identit?t des Absenders wurde von mehreren vertrauensw?rdigen Personen " "beglaubigt." -#: src/mail.cpp:2150 +#: src/mail.cpp:2098 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" @@ -593,12 +593,12 @@ msgstr "" "Die Idenit?t des Absenders wurde best?tigt von:\n" "'%s'\n" -#: src/mail.cpp:2158 +#: src/mail.cpp:2106 msgid "Some trusted people have certified the senders identity." msgstr "" "Einige vertrauensw?rde Personen haben die Identit?t des Absenders beglaubigt." -#: src/mail.cpp:2168 +#: src/mail.cpp:2116 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -610,11 +610,11 @@ msgstr "" "Seit %s haben Sie %i Nachrichten an diesen Absender verschl?sselt und %i " "Signaturen gepr?ft." -#: src/mail.cpp:2184 +#: src/mail.cpp:2132 msgid "The senders signature was verified for the first time." msgstr "The Signatur des Absenders wurde das erste mal verifiziert." -#: src/mail.cpp:2191 +#: src/mail.cpp:2139 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " @@ -624,70 +624,70 @@ msgstr "" "Nachrichten von diesem absender verifziert und %i Nachrichten verschl?ssel " "haben. Seit dem %s." -#: src/mail.cpp:2205 +#: src/mail.cpp:2153 msgid "But the sender address is not trustworthy because:" msgstr "Aber die Absenderadresse ist nicht vertrauensw?rdig da:" -#: src/mail.cpp:2206 +#: src/mail.cpp:2154 msgid "The sender address is not trustworthy because:" msgstr "Die Absenderadresse ist nicht vertrauensw?rdig da:" -#: src/mail.cpp:2214 +#: src/mail.cpp:2162 msgid "The signature is invalid: \n" msgstr "Die Signatur ist ung?ltig: \n" -#: src/mail.cpp:2219 +#: src/mail.cpp:2167 msgid "There was an error verifying the signature.\n" msgstr "Beim ?berpr?fen der Signatur ist ein Fehler aufgetreten.\n" -#: src/mail.cpp:2223 +#: src/mail.cpp:2171 msgid "The signature is expired.\n" msgstr "Die Signatur ist abgelaufen.\n" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 msgid "The used key" msgstr "Der verwendete Schl?ssel" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 msgid "The used certificate" msgstr "Das verwendete Zertifikat" -#: src/mail.cpp:2235 +#: src/mail.cpp:2183 msgid "is not available." msgstr "ist nicht verf?gbar." -#: src/mail.cpp:2239 +#: src/mail.cpp:2187 msgid "is revoked." msgstr "wurde zur?ckgezogen." -#: src/mail.cpp:2243 +#: src/mail.cpp:2191 msgid "is expired." msgstr "ist veraltet. " -#: src/mail.cpp:2247 +#: src/mail.cpp:2195 msgid "is not meant for signing." msgstr "ist nicht zum signieren vorgesehen. " -#: src/mail.cpp:2251 src/mail.cpp:2255 +#: src/mail.cpp:2199 src/mail.cpp:2203 msgid "could not be checked for revocation." msgstr "wurde m?glicherweise zur?ckgezogen." -#: src/mail.cpp:2260 +#: src/mail.cpp:2208 msgid "is not the same as the key that was used for this address in the past." msgstr "" "ist nicht der gleiche Schl?ssel der in der vergangenheit f?r diese Adresse " "verwendet wurde." -#: src/mail.cpp:2266 +#: src/mail.cpp:2214 #, c-format msgid "does not claim the address: \"%s\"." msgstr "passt nicht zu der mailaddresse: \"%s\". " -#: src/mail.cpp:2279 +#: src/mail.cpp:2227 msgid "is not certified by any trustworthy key." msgstr "wurde von keinem vertrauensw?rdigen Schl?ssel beglaubigt." -#: src/mail.cpp:2283 +#: src/mail.cpp:2231 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." @@ -695,59 +695,59 @@ msgstr "" "wurde von keiner vertrauensw?rdigen Zertifizierungsstelle beglaubigt oder " "die Zertifizierungsstelle ist unbekannt." -#: src/mail.cpp:2288 +#: src/mail.cpp:2236 msgid "The sender marked this address as revoked." msgstr "Der Absender hat diese Adresse zur?ckgezogen." -#: src/mail.cpp:2292 +#: src/mail.cpp:2240 msgid "is marked as not trustworthy." msgstr "ist als nicht vertrauensw?rdig markiert." -#: src/mail.cpp:2302 +#: src/mail.cpp:2250 msgid "The signature is VS-NfD-compliant." msgstr "Die Signatur ist VS-NfD-konform." -#: src/mail.cpp:2306 +#: src/mail.cpp:2254 msgid "The signature is not VS-NfD-compliant." msgstr "Die Signatur ist nicht VS-NfD-konform." -#: src/mail.cpp:2314 +#: src/mail.cpp:2262 msgid "The encryption is VS-NfD-compliant." msgstr "Diese Verschl?sselung ist VS-NfD-konform." -#: src/mail.cpp:2318 +#: src/mail.cpp:2266 msgid "The encryption is not VS-NfD-compliant." msgstr "Diese Verschl?sselung ist nicht VS-NfD-konform." -#: src/mail.cpp:2329 +#: src/mail.cpp:2277 msgid "Click here to change the key used for this address." msgstr "Klicken Sie hier um den Schl?ssel f?r diese Adresse zu ?ndern." -#: src/mail.cpp:2333 +#: src/mail.cpp:2281 msgid "Click here for details about the key." msgstr "Klicken Sie hier f?r Details zu dem Schl?ssel" -#: src/mail.cpp:2334 +#: src/mail.cpp:2282 msgid "Click here for details about the certificate." msgstr "Klicken Sie hier f?r Details zu dem Zertifiakt." -#: src/mail.cpp:2338 +#: src/mail.cpp:2286 msgid "Click here to search the key on the configured keyserver." msgstr "" "Klicken Sie hier um den Schl?ssel auf dem konfigurierten Schl?sselserver zu " "suchen. " -#: src/mail.cpp:2339 +#: src/mail.cpp:2287 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" "Klicken Sie hier um das Zertifikat auf dem konfigurierten X509 " "Schl?sselserver zu suchen." -#: src/mail.cpp:2567 +#: src/mail.cpp:2515 msgid "GpgOL: Encryption not possible!" msgstr "GpgOL: Verschl?sselung nicht m?glich!" -#: src/mail.cpp:2569 +#: src/mail.cpp:2517 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" diff --git a/po/fr.po b/po/fr.po index af6d6fa..3e9939d 100644 --- a/po/fr.po +++ b/po/fr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-05 14:35+0100\n" +"POT-Creation-Date: 2018-03-06 15:25+0100\n" "PO-Revision-Date: 2015-10-01 17:05+0200\n" "Last-Translator: Olivier Serve \n" "Language-Team: French \n" @@ -172,12 +172,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "Voulez-vous r?cup?rer ce dossier ?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1743 src/mail.cpp:1814 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "D?chiffrer le message" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1744 src/mail.cpp:1815 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -409,11 +409,11 @@ msgstr "" msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:804 +#: src/mail.cpp:811 msgid "Pubkey directory confirmation" msgstr "" -#: src/mail.cpp:805 +#: src/mail.cpp:812 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -422,20 +422,20 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:813 src/mail.cpp:2058 +#: src/mail.cpp:820 src/mail.cpp:2006 #, fuzzy msgid "Encrypted message" msgstr "D?chiffrer le message" -#: src/mail.cpp:814 +#: src/mail.cpp:821 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1088 +#: src/mail.cpp:1095 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1092 +#: src/mail.cpp:1099 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -443,7 +443,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1107 +#: src/mail.cpp:1114 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -451,7 +451,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1122 +#: src/mail.cpp:1129 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -461,105 +461,105 @@ msgid "" "Do you want to only encrypt the message?" msgstr "" -#: src/mail.cpp:2003 +#: src/mail.cpp:1951 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:2007 +#: src/mail.cpp:1955 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:2011 +#: src/mail.cpp:1959 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:2015 +#: src/mail.cpp:1963 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:2019 +#: src/mail.cpp:1967 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:2023 +#: src/mail.cpp:1971 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:2027 +#: src/mail.cpp:1975 #, fuzzy msgid "Encrypted" msgstr "Chiffrer" -#: src/mail.cpp:2036 src/mail.cpp:2038 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "" -#: src/mail.cpp:2050 +#: src/mail.cpp:1998 #, fuzzy msgid "Signed and encrypted message" msgstr "D?chiffrer le message" -#: src/mail.cpp:2054 +#: src/mail.cpp:2002 #, fuzzy msgid "Signed message" msgstr "D?chiffrer le message" -#: src/mail.cpp:2061 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 #, fuzzy msgid "Insecure message" msgstr "D?chiffrer le message" -#: src/mail.cpp:2072 src/mail.cpp:2083 +#: src/mail.cpp:2020 src/mail.cpp:2031 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:2075 +#: src/mail.cpp:2023 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2041 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2097 +#: src/mail.cpp:2045 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2101 +#: src/mail.cpp:2049 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2124 +#: src/mail.cpp:2072 #, fuzzy msgid "You signed this message." msgstr "D?chiffrer le message" -#: src/mail.cpp:2128 +#: src/mail.cpp:2076 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2080 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2145 +#: src/mail.cpp:2093 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2150 +#: src/mail.cpp:2098 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2158 +#: src/mail.cpp:2106 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2168 +#: src/mail.cpp:2116 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -567,142 +567,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2184 +#: src/mail.cpp:2132 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2191 +#: src/mail.cpp:2139 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2205 +#: src/mail.cpp:2153 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2206 +#: src/mail.cpp:2154 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2214 +#: src/mail.cpp:2162 #, fuzzy msgid "The signature is invalid: \n" msgstr "Cette signature est valide\n" -#: src/mail.cpp:2219 +#: src/mail.cpp:2167 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2223 +#: src/mail.cpp:2171 #, fuzzy msgid "The signature is expired.\n" msgstr "Cette signature est valide\n" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 msgid "The used key" msgstr "" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 #, fuzzy msgid "The used certificate" msgstr "Erreur de v?rification" -#: src/mail.cpp:2235 +#: src/mail.cpp:2183 #, fuzzy msgid "is not available." msgstr "La liste de r?vocation (CRL) n'est pas disponible\n" -#: src/mail.cpp:2239 +#: src/mail.cpp:2187 msgid "is revoked." msgstr "" -#: src/mail.cpp:2243 +#: src/mail.cpp:2191 msgid "is expired." msgstr "" -#: src/mail.cpp:2247 +#: src/mail.cpp:2195 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2251 src/mail.cpp:2255 +#: src/mail.cpp:2199 src/mail.cpp:2203 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2260 +#: src/mail.cpp:2208 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2266 +#: src/mail.cpp:2214 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2279 +#: src/mail.cpp:2227 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2283 +#: src/mail.cpp:2231 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2288 +#: src/mail.cpp:2236 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2292 +#: src/mail.cpp:2240 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2302 +#: src/mail.cpp:2250 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2306 +#: src/mail.cpp:2254 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2314 +#: src/mail.cpp:2262 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2318 +#: src/mail.cpp:2266 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2329 +#: src/mail.cpp:2277 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2333 +#: src/mail.cpp:2281 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2334 +#: src/mail.cpp:2282 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2338 +#: src/mail.cpp:2286 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2339 +#: src/mail.cpp:2287 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2567 +#: src/mail.cpp:2515 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "D?chiffrer le message" -#: src/mail.cpp:2569 +#: src/mail.cpp:2517 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" diff --git a/po/pt.po b/po/pt.po index 258fa6b..5bfe6fd 100644 --- a/po/pt.po +++ b/po/pt.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL 1.1.1\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-05 14:35+0100\n" +"POT-Creation-Date: 2018-03-06 15:25+0100\n" "PO-Revision-Date: 2017-10-16 14:17+0100\n" "Last-Translator: Marco A.G.Pinto \n" "Language-Team: Portuguese \n" @@ -175,11 +175,11 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "Queres reverter esta pasta?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1743 src/mail.cpp:1814 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 msgid "GpgOL: Encrypted Message" msgstr "GpgOL: Mensagem Encriptada" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1744 src/mail.cpp:1815 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 msgid "GpgOL: Trusted Sender Address" msgstr "GpgOL: Endere?o de Remetente Confi?vel" @@ -425,11 +425,11 @@ msgstr "" msgid "GpgOL Warning" msgstr "Aviso do GpgOL" -#: src/mail.cpp:804 +#: src/mail.cpp:811 msgid "Pubkey directory confirmation" msgstr "" -#: src/mail.cpp:805 +#: src/mail.cpp:812 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -438,21 +438,21 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:813 src/mail.cpp:2058 +#: src/mail.cpp:820 src/mail.cpp:2006 msgid "Encrypted message" msgstr "Mensagem encriptada" -#: src/mail.cpp:814 +#: src/mail.cpp:821 msgid "Please wait while the message is being decrypted / verified..." msgstr "" "Por favor aguarda enquanto a mensagem est? a ser desencriptada / " "verificada..." -#: src/mail.cpp:1088 +#: src/mail.cpp:1095 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1092 +#: src/mail.cpp:1099 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -460,7 +460,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1107 +#: src/mail.cpp:1114 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -468,7 +468,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1122 +#: src/mail.cpp:1129 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -478,91 +478,91 @@ msgid "" "Do you want to only encrypt the message?" msgstr "" -#: src/mail.cpp:2003 +#: src/mail.cpp:1951 msgid "Security Level 4" msgstr "N?vel de seguran?a 4" -#: src/mail.cpp:2007 +#: src/mail.cpp:1955 msgid "Trust Level 4" msgstr "N?vel de Confian?a 4" -#: src/mail.cpp:2011 +#: src/mail.cpp:1959 msgid "Security Level 3" msgstr "N?vel de Seguran?a 3" -#: src/mail.cpp:2015 +#: src/mail.cpp:1963 msgid "Trust Level 3" msgstr "N?vel de Confian?a 3" -#: src/mail.cpp:2019 +#: src/mail.cpp:1967 msgid "Security Level 2" msgstr "N?vel de Seguran?a 2" -#: src/mail.cpp:2023 +#: src/mail.cpp:1971 msgid "Trust Level 2" msgstr "N?vel de Confian?a 2" -#: src/mail.cpp:2027 +#: src/mail.cpp:1975 msgid "Encrypted" msgstr "Encriptada" -#: src/mail.cpp:2036 src/mail.cpp:2038 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "Insegura" -#: src/mail.cpp:2050 +#: src/mail.cpp:1998 msgid "Signed and encrypted message" msgstr "Mensagem assinada e encriptada" -#: src/mail.cpp:2054 +#: src/mail.cpp:2002 msgid "Signed message" msgstr "Mensagem assinada" -#: src/mail.cpp:2061 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 msgid "Insecure message" msgstr "Mensagem insegura" -#: src/mail.cpp:2072 src/mail.cpp:2083 +#: src/mail.cpp:2020 src/mail.cpp:2031 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" "N?o podes ter a certeza de quem enviou, modificou e leu a mensagem em " "tr?nsito." -#: src/mail.cpp:2075 +#: src/mail.cpp:2023 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2041 msgid "The encryption was VS-NfD-compliant." msgstr "A encripta??o est? em conformidade com VS-NfD." -#: src/mail.cpp:2097 +#: src/mail.cpp:2045 msgid "The encryption was not VS-NfD-compliant." msgstr "A encripta??o n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2101 +#: src/mail.cpp:2049 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" "N?o podes ter certeza de quem enviou a mensagem, porque n?o est? assinada." -#: src/mail.cpp:2124 +#: src/mail.cpp:2072 msgid "You signed this message." msgstr "Assinaste esta mensagem." -#: src/mail.cpp:2128 +#: src/mail.cpp:2076 msgid "The senders identity was certified by yourself." msgstr "A identidade dos remetentes foi certificada por ti pr?prio." -#: src/mail.cpp:2132 +#: src/mail.cpp:2080 msgid "The sender is allowed to certify identities for you." msgstr "O remetente pode certificar identidades para ti." -#: src/mail.cpp:2145 +#: src/mail.cpp:2093 msgid "The senders identity was certified by several trusted people." msgstr "" "A identidade dos remetentes foi certificada por v?rias pessoas confi?veis." -#: src/mail.cpp:2150 +#: src/mail.cpp:2098 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" @@ -571,11 +571,11 @@ msgstr "" "A identidade dos remetentes ? certificada pelo emissor confi?vel:\n" "'%s'\n" -#: src/mail.cpp:2158 +#: src/mail.cpp:2106 msgid "Some trusted people have certified the senders identity." msgstr "Algumas pessoas confi?veis certificaram a identidade dos remetentes." -#: src/mail.cpp:2168 +#: src/mail.cpp:2116 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -586,11 +586,11 @@ msgstr "" "comunica??o com este endere?o desde %s.\n" "Encriptaste %i e verificaste %i mensagens desde ent?o." -#: src/mail.cpp:2184 +#: src/mail.cpp:2132 msgid "The senders signature was verified for the first time." msgstr "A assinatura dos remetentes foi verificada pela primeira vez." -#: src/mail.cpp:2191 +#: src/mail.cpp:2139 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " @@ -599,68 +599,68 @@ msgstr "" "O endere?o dos remetentes ainda n?o ? confi?vel porque apenas verificaste %i " "mensagens e encriptaste %i mensagens a eles desde %s." -#: src/mail.cpp:2205 +#: src/mail.cpp:2153 msgid "But the sender address is not trustworthy because:" msgstr "Mas o endere?o do remetente n?o ? confi?vel porque:" -#: src/mail.cpp:2206 +#: src/mail.cpp:2154 msgid "The sender address is not trustworthy because:" msgstr "O endere?o do remetente n?o ? confi?vel porque:" -#: src/mail.cpp:2214 +#: src/mail.cpp:2162 msgid "The signature is invalid: \n" msgstr "A assinatura ? inv?lida: \n" -#: src/mail.cpp:2219 +#: src/mail.cpp:2167 msgid "There was an error verifying the signature.\n" msgstr "Houve um erro ao verificar a assinatura.\n" -#: src/mail.cpp:2223 +#: src/mail.cpp:2171 msgid "The signature is expired.\n" msgstr "A assinatura expirou.\n" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 msgid "The used key" msgstr "A chave usada" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 msgid "The used certificate" msgstr "O certificado usado" -#: src/mail.cpp:2235 +#: src/mail.cpp:2183 msgid "is not available." msgstr "n?o est? dispon?vel." -#: src/mail.cpp:2239 +#: src/mail.cpp:2187 msgid "is revoked." msgstr "est? revogado." -#: src/mail.cpp:2243 +#: src/mail.cpp:2191 msgid "is expired." msgstr "expirou." -#: src/mail.cpp:2247 +#: src/mail.cpp:2195 msgid "is not meant for signing." msgstr "n?o ? destinado a assinar." -#: src/mail.cpp:2251 src/mail.cpp:2255 +#: src/mail.cpp:2199 src/mail.cpp:2203 msgid "could not be checked for revocation." msgstr "n?o pode ser verificado para revoga??o." -#: src/mail.cpp:2260 +#: src/mail.cpp:2208 msgid "is not the same as the key that was used for this address in the past." msgstr "n?o ? o mesmo que a chave usada para este endere?o no passado." -#: src/mail.cpp:2266 +#: src/mail.cpp:2214 #, c-format msgid "does not claim the address: \"%s\"." msgstr "n?o reivindica o endere?o: \"%s\"." -#: src/mail.cpp:2279 +#: src/mail.cpp:2227 msgid "is not certified by any trustworthy key." msgstr "n?o est? certificado por qualquer chave confi?vel." -#: src/mail.cpp:2283 +#: src/mail.cpp:2231 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." @@ -668,58 +668,58 @@ msgstr "" "n?o est? certificado por uma Autoridade de Certifica??o confi?vel ou a " "Autoridade de Certifica??o ? desconhecida." -#: src/mail.cpp:2288 +#: src/mail.cpp:2236 msgid "The sender marked this address as revoked." msgstr "O remetente marcou este endere?o como revogado." -#: src/mail.cpp:2292 +#: src/mail.cpp:2240 msgid "is marked as not trustworthy." msgstr "est? marcado como n?o confi?vel." -#: src/mail.cpp:2302 +#: src/mail.cpp:2250 msgid "The signature is VS-NfD-compliant." msgstr "A assinatura est? em conformidade com VS-NfD." -#: src/mail.cpp:2306 +#: src/mail.cpp:2254 msgid "The signature is not VS-NfD-compliant." msgstr "A assinatura n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2314 +#: src/mail.cpp:2262 msgid "The encryption is VS-NfD-compliant." msgstr "A encripta??o est? em conformidade com VS-NfD." -#: src/mail.cpp:2318 +#: src/mail.cpp:2266 msgid "The encryption is not VS-NfD-compliant." msgstr "A encripta??o n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2329 +#: src/mail.cpp:2277 msgid "Click here to change the key used for this address." msgstr "Clica aqui para alterar a chave usada para este endere?o." -#: src/mail.cpp:2333 +#: src/mail.cpp:2281 msgid "Click here for details about the key." msgstr "Clica aqui para obter detalhes sobre a chave." -#: src/mail.cpp:2334 +#: src/mail.cpp:2282 msgid "Click here for details about the certificate." msgstr "Clica aqui para obter detalhes sobre o certificado." -#: src/mail.cpp:2338 +#: src/mail.cpp:2286 msgid "Click here to search the key on the configured keyserver." msgstr "Clica aqui para localizar a chave no servidor de chaves configurado." -#: src/mail.cpp:2339 +#: src/mail.cpp:2287 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" "Clica aqui para localizar o certificado no servidor de chaves X509 " "configurado." -#: src/mail.cpp:2567 +#: src/mail.cpp:2515 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "GpgOL: Mensagem Encriptada" -#: src/mail.cpp:2569 +#: src/mail.cpp:2517 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" diff --git a/po/sv.po b/po/sv.po index 9f99ae6..b5c5ad4 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GPGol\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-05 14:35+0100\n" +"POT-Creation-Date: 2018-03-06 15:25+0100\n" "PO-Revision-Date: 2006-12-12 23:52+0100\n" "Last-Translator: Daniel Nylander \n" "Language-Team: Swedish \n" @@ -164,12 +164,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1743 src/mail.cpp:1814 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "Dekryptera och validera meddelandet." -#: src/gpgoladdin.cpp:447 src/mail.cpp:1744 src/mail.cpp:1815 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -398,11 +398,11 @@ msgstr "" msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:804 +#: src/mail.cpp:811 msgid "Pubkey directory confirmation" msgstr "" -#: src/mail.cpp:805 +#: src/mail.cpp:812 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -411,20 +411,20 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:813 src/mail.cpp:2058 +#: src/mail.cpp:820 src/mail.cpp:2006 #, fuzzy msgid "Encrypted message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:814 +#: src/mail.cpp:821 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1088 +#: src/mail.cpp:1095 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1092 +#: src/mail.cpp:1099 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -432,7 +432,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1107 +#: src/mail.cpp:1114 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -440,7 +440,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1122 +#: src/mail.cpp:1129 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -450,105 +450,105 @@ msgid "" "Do you want to only encrypt the message?" msgstr "" -#: src/mail.cpp:2003 +#: src/mail.cpp:1951 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:2007 +#: src/mail.cpp:1955 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:2011 +#: src/mail.cpp:1959 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:2015 +#: src/mail.cpp:1963 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:2019 +#: src/mail.cpp:1967 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:2023 +#: src/mail.cpp:1971 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:2027 +#: src/mail.cpp:1975 #, fuzzy msgid "Encrypted" msgstr "Kryptering" -#: src/mail.cpp:2036 src/mail.cpp:2038 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "" -#: src/mail.cpp:2050 +#: src/mail.cpp:1998 #, fuzzy msgid "Signed and encrypted message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2054 +#: src/mail.cpp:2002 #, fuzzy msgid "Signed message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2061 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 #, fuzzy msgid "Insecure message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2072 src/mail.cpp:2083 +#: src/mail.cpp:2020 src/mail.cpp:2031 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:2075 +#: src/mail.cpp:2023 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2041 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2097 +#: src/mail.cpp:2045 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2101 +#: src/mail.cpp:2049 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2124 +#: src/mail.cpp:2072 #, fuzzy msgid "You signed this message." msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2128 +#: src/mail.cpp:2076 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2080 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2145 +#: src/mail.cpp:2093 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2150 +#: src/mail.cpp:2098 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2158 +#: src/mail.cpp:2106 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2168 +#: src/mail.cpp:2116 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -556,142 +556,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2184 +#: src/mail.cpp:2132 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2191 +#: src/mail.cpp:2139 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2205 +#: src/mail.cpp:2153 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2206 +#: src/mail.cpp:2154 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2214 +#: src/mail.cpp:2162 #, fuzzy msgid "The signature is invalid: \n" msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2219 +#: src/mail.cpp:2167 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2223 +#: src/mail.cpp:2171 #, fuzzy msgid "The signature is expired.\n" msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 msgid "The used key" msgstr "" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 #, fuzzy msgid "The used certificate" msgstr "Validering" -#: src/mail.cpp:2235 +#: src/mail.cpp:2183 #, fuzzy msgid "is not available." msgstr "Sp?rrlistan ?r inte tillg?nglig\n" -#: src/mail.cpp:2239 +#: src/mail.cpp:2187 msgid "is revoked." msgstr "" -#: src/mail.cpp:2243 +#: src/mail.cpp:2191 msgid "is expired." msgstr "" -#: src/mail.cpp:2247 +#: src/mail.cpp:2195 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2251 src/mail.cpp:2255 +#: src/mail.cpp:2199 src/mail.cpp:2203 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2260 +#: src/mail.cpp:2208 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2266 +#: src/mail.cpp:2214 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2279 +#: src/mail.cpp:2227 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2283 +#: src/mail.cpp:2231 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2288 +#: src/mail.cpp:2236 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2292 +#: src/mail.cpp:2240 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2302 +#: src/mail.cpp:2250 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2306 +#: src/mail.cpp:2254 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2314 +#: src/mail.cpp:2262 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2318 +#: src/mail.cpp:2266 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2329 +#: src/mail.cpp:2277 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2333 +#: src/mail.cpp:2281 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2334 +#: src/mail.cpp:2282 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2338 +#: src/mail.cpp:2286 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2339 +#: src/mail.cpp:2287 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2567 +#: src/mail.cpp:2515 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2569 +#: src/mail.cpp:2517 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" diff --git a/po/zh_CN.po b/po/zh_CN.po index 4daba20..bf3b05b 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-05 14:35+0100\n" +"POT-Creation-Date: 2018-03-06 15:25+0100\n" "PO-Revision-Date: 2015-08-15 21:58+0800\n" "Last-Translator: Mingye Wang (Arthur2e5) \n" "Language-Team: \n" @@ -168,12 +168,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "????????????" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1743 src/mail.cpp:1814 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "????" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1744 src/mail.cpp:1815 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -397,11 +397,11 @@ msgstr "" msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:804 +#: src/mail.cpp:811 msgid "Pubkey directory confirmation" msgstr "" -#: src/mail.cpp:805 +#: src/mail.cpp:812 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -410,20 +410,20 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:813 src/mail.cpp:2058 +#: src/mail.cpp:820 src/mail.cpp:2006 #, fuzzy msgid "Encrypted message" msgstr "????" -#: src/mail.cpp:814 +#: src/mail.cpp:821 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1088 +#: src/mail.cpp:1095 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1092 +#: src/mail.cpp:1099 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -431,7 +431,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1107 +#: src/mail.cpp:1114 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -439,7 +439,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1122 +#: src/mail.cpp:1129 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -449,105 +449,105 @@ msgid "" "Do you want to only encrypt the message?" msgstr "" -#: src/mail.cpp:2003 +#: src/mail.cpp:1951 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:2007 +#: src/mail.cpp:1955 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:2011 +#: src/mail.cpp:1959 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:2015 +#: src/mail.cpp:1963 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:2019 +#: src/mail.cpp:1967 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:2023 +#: src/mail.cpp:1971 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:2027 +#: src/mail.cpp:1975 #, fuzzy msgid "Encrypted" msgstr "??" -#: src/mail.cpp:2036 src/mail.cpp:2038 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "" -#: src/mail.cpp:2050 +#: src/mail.cpp:1998 #, fuzzy msgid "Signed and encrypted message" msgstr "????" -#: src/mail.cpp:2054 +#: src/mail.cpp:2002 #, fuzzy msgid "Signed message" msgstr "????" -#: src/mail.cpp:2061 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 #, fuzzy msgid "Insecure message" msgstr "????" -#: src/mail.cpp:2072 src/mail.cpp:2083 +#: src/mail.cpp:2020 src/mail.cpp:2031 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:2075 +#: src/mail.cpp:2023 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2041 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2097 +#: src/mail.cpp:2045 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2101 +#: src/mail.cpp:2049 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2124 +#: src/mail.cpp:2072 #, fuzzy msgid "You signed this message." msgstr "????" -#: src/mail.cpp:2128 +#: src/mail.cpp:2076 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2080 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2145 +#: src/mail.cpp:2093 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2150 +#: src/mail.cpp:2098 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2158 +#: src/mail.cpp:2106 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2168 +#: src/mail.cpp:2116 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -555,142 +555,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2184 +#: src/mail.cpp:2132 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2191 +#: src/mail.cpp:2139 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2205 +#: src/mail.cpp:2153 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2206 +#: src/mail.cpp:2154 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2214 +#: src/mail.cpp:2162 #, fuzzy msgid "The signature is invalid: \n" msgstr "????\n" -#: src/mail.cpp:2219 +#: src/mail.cpp:2167 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2223 +#: src/mail.cpp:2171 #, fuzzy msgid "The signature is expired.\n" msgstr "????\n" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 msgid "The used key" msgstr "" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 #, fuzzy msgid "The used certificate" msgstr "????" -#: src/mail.cpp:2235 +#: src/mail.cpp:2183 #, fuzzy msgid "is not available." msgstr "???????CRL????\n" -#: src/mail.cpp:2239 +#: src/mail.cpp:2187 msgid "is revoked." msgstr "" -#: src/mail.cpp:2243 +#: src/mail.cpp:2191 msgid "is expired." msgstr "" -#: src/mail.cpp:2247 +#: src/mail.cpp:2195 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2251 src/mail.cpp:2255 +#: src/mail.cpp:2199 src/mail.cpp:2203 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2260 +#: src/mail.cpp:2208 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2266 +#: src/mail.cpp:2214 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2279 +#: src/mail.cpp:2227 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2283 +#: src/mail.cpp:2231 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2288 +#: src/mail.cpp:2236 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2292 +#: src/mail.cpp:2240 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2302 +#: src/mail.cpp:2250 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2306 +#: src/mail.cpp:2254 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2314 +#: src/mail.cpp:2262 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2318 +#: src/mail.cpp:2266 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2329 +#: src/mail.cpp:2277 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2333 +#: src/mail.cpp:2281 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2334 +#: src/mail.cpp:2282 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2338 +#: src/mail.cpp:2286 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2339 +#: src/mail.cpp:2287 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2567 +#: src/mail.cpp:2515 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "????" -#: src/mail.cpp:2569 +#: src/mail.cpp:2517 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" diff --git a/po/zh_TW.po b/po/zh_TW.po index ea7e1a7..8b9f530 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-05 14:35+0100\n" +"POT-Creation-Date: 2018-03-06 15:25+0100\n" "PO-Revision-Date: 2015-08-15 21:58+0800\n" "Last-Translator: Mingye Wang (Arthur2e5) \n" "Language-Team: \n" @@ -168,12 +168,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "????????????" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1743 src/mail.cpp:1814 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "????" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1744 src/mail.cpp:1815 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -397,11 +397,11 @@ msgstr "" msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:804 +#: src/mail.cpp:811 msgid "Pubkey directory confirmation" msgstr "" -#: src/mail.cpp:805 +#: src/mail.cpp:812 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -410,20 +410,20 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:813 src/mail.cpp:2058 +#: src/mail.cpp:820 src/mail.cpp:2006 #, fuzzy msgid "Encrypted message" msgstr "????" -#: src/mail.cpp:814 +#: src/mail.cpp:821 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1088 +#: src/mail.cpp:1095 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1092 +#: src/mail.cpp:1099 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -431,7 +431,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1107 +#: src/mail.cpp:1114 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -439,7 +439,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1122 +#: src/mail.cpp:1129 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -449,105 +449,105 @@ msgid "" "Do you want to only encrypt the message?" msgstr "" -#: src/mail.cpp:2003 +#: src/mail.cpp:1951 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:2007 +#: src/mail.cpp:1955 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:2011 +#: src/mail.cpp:1959 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:2015 +#: src/mail.cpp:1963 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:2019 +#: src/mail.cpp:1967 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:2023 +#: src/mail.cpp:1971 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:2027 +#: src/mail.cpp:1975 #, fuzzy msgid "Encrypted" msgstr "??" -#: src/mail.cpp:2036 src/mail.cpp:2038 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "" -#: src/mail.cpp:2050 +#: src/mail.cpp:1998 #, fuzzy msgid "Signed and encrypted message" msgstr "????" -#: src/mail.cpp:2054 +#: src/mail.cpp:2002 #, fuzzy msgid "Signed message" msgstr "????" -#: src/mail.cpp:2061 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 #, fuzzy msgid "Insecure message" msgstr "????" -#: src/mail.cpp:2072 src/mail.cpp:2083 +#: src/mail.cpp:2020 src/mail.cpp:2031 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:2075 +#: src/mail.cpp:2023 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2041 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2097 +#: src/mail.cpp:2045 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2101 +#: src/mail.cpp:2049 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2124 +#: src/mail.cpp:2072 #, fuzzy msgid "You signed this message." msgstr "????" -#: src/mail.cpp:2128 +#: src/mail.cpp:2076 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2080 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2145 +#: src/mail.cpp:2093 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2150 +#: src/mail.cpp:2098 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2158 +#: src/mail.cpp:2106 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2168 +#: src/mail.cpp:2116 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -555,142 +555,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2184 +#: src/mail.cpp:2132 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2191 +#: src/mail.cpp:2139 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2205 +#: src/mail.cpp:2153 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2206 +#: src/mail.cpp:2154 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2214 +#: src/mail.cpp:2162 #, fuzzy msgid "The signature is invalid: \n" msgstr "????\n" -#: src/mail.cpp:2219 +#: src/mail.cpp:2167 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2223 +#: src/mail.cpp:2171 #, fuzzy msgid "The signature is expired.\n" msgstr "????\n" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 msgid "The used key" msgstr "" -#: src/mail.cpp:2227 +#: src/mail.cpp:2175 #, fuzzy msgid "The used certificate" msgstr "????" -#: src/mail.cpp:2235 +#: src/mail.cpp:2183 #, fuzzy msgid "is not available." msgstr "???????CRL????\n" -#: src/mail.cpp:2239 +#: src/mail.cpp:2187 msgid "is revoked." msgstr "" -#: src/mail.cpp:2243 +#: src/mail.cpp:2191 msgid "is expired." msgstr "" -#: src/mail.cpp:2247 +#: src/mail.cpp:2195 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2251 src/mail.cpp:2255 +#: src/mail.cpp:2199 src/mail.cpp:2203 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2260 +#: src/mail.cpp:2208 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2266 +#: src/mail.cpp:2214 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2279 +#: src/mail.cpp:2227 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2283 +#: src/mail.cpp:2231 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2288 +#: src/mail.cpp:2236 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2292 +#: src/mail.cpp:2240 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2302 +#: src/mail.cpp:2250 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2306 +#: src/mail.cpp:2254 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2314 +#: src/mail.cpp:2262 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2318 +#: src/mail.cpp:2266 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2329 +#: src/mail.cpp:2277 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2333 +#: src/mail.cpp:2281 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2334 +#: src/mail.cpp:2282 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2338 +#: src/mail.cpp:2286 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2339 +#: src/mail.cpp:2287 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2567 +#: src/mail.cpp:2515 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "????" -#: src/mail.cpp:2569 +#: src/mail.cpp:2517 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" commit 4040b97d6d4177ed64765c5666175b09f780a1bd Author: Andre Heinecke Date: Wed Mar 7 08:21:36 2018 +0100 Allow Inline for signed & encrypted with GSuite * src/mail.cpp (Mail::encrypt_sign_start): Relax GSuite checks. -- We now support clearsigned and signed & encrypted inline mails thanks to the new crypto architecture. GnuPG-Bug-Id: T3545 diff --git a/src/mail.cpp b/src/mail.cpp index db27ee6..aba08d3 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1091,10 +1091,10 @@ Mail::encrypt_sign_start () mapi_release_attach_table (att_table); /* Check for attachments if we have some abort. */ - wchar_t *w_title = utf8_to_wchar (_( - "GpgOL: Oops, G Suite Sync account detected")); if (n_att_usable) { + wchar_t *w_title = utf8_to_wchar (_( + "GpgOL: Oops, G Suite Sync account detected")); wchar_t *msg = utf8_to_wchar ( _("G Suite Sync breaks outgoing crypto mails " "with attachments.\nUsing crypto and attachments " @@ -1108,45 +1108,6 @@ Mail::encrypt_sign_start () xfree (w_title); return -1; } - if (flags == 2) - { - wchar_t *msg = utf8_to_wchar ( - _("G Suite Sync breaks outgoing signed mails.\n" - "Ensuring mail integrity (signing) with G Suite Sync " - "is not supported.\n\n" - "See: https://dev.gnupg.org/T3545 for details.")); - MessageBoxW (window, - msg, - w_title, - MB_ICONINFORMATION|MB_OK); - xfree (msg); - xfree (w_title); - return -1; - } - if (flags == 3) - { - wchar_t *msg = utf8_to_wchar ( - _("G Suite Sync breaks outgoing signed mails.\n" - "Ensuring mail integrity (signing) with G Suite Sync " - "is not supported.\n\n" - "See: https://dev.gnupg.org/T3545 for details.\n\n" - "Do you want to only encrypt the message?")); - if(MessageBoxW (window, - msg, - w_title, - MB_ICONINFORMATION|MB_YESNO) != IDYES) - { - xfree (msg); - xfree (w_title); - return -1; - } - else - { - flags = 1; - } - xfree (msg); - } - xfree (w_title); } m_do_inline = m_is_gsuite ? true : opt.inline_pgp; ----------------------------------------------------------------------- Summary of changes: po/de.po | 134 +++++++++++++++++++++++++++++------------------------------ po/fr.po | 130 ++++++++++++++++++++++++++++----------------------------- po/pt.po | 130 ++++++++++++++++++++++++++++----------------------------- po/sv.po | 130 ++++++++++++++++++++++++++++----------------------------- po/zh_CN.po | 130 ++++++++++++++++++++++++++++----------------------------- po/zh_TW.po | 130 ++++++++++++++++++++++++++++----------------------------- src/mail.cpp | 43 +------------------ 7 files changed, 394 insertions(+), 433 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 7 10:06:56 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 07 Mar 2018 10:06:56 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-8-g7e40c5e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 7e40c5efbea65c7804b06d62dfcd7f991557bfaa (commit) from f060cb5c63923d6caec784f65f3bb0aadf52f795 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7e40c5efbea65c7804b06d62dfcd7f991557bfaa Author: Ben McGinnes Date: Wed Mar 7 10:28:48 2018 +1100 doc: man page grammar -- Fixed two grammatical errors: their vs. there and oneself vs. one (one's self would still be too stilted). diff --git a/doc/gpg.texi b/doc/gpg.texi index ddebc69..e3c3662 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 ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 7 10:14:23 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 07 Mar 2018 10:14:23 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-56-g8a76deb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 8a76deb11efd7dadfde6e8e7e69fbcd92577982f (commit) via 5215d58ae2521d81c3db0b45dfbdce01a679acab (commit) via 8f2c0f4534ea2a07f071f360a63e877f60dc52f2 (commit) via d4778bb23d0817ee6fbcbe4f0ff0ff0429bf3669 (commit) from 3a746d5d46ffd7d332dc24fd6a4d24efc5fc1230 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8a76deb11efd7dadfde6e8e7e69fbcd92577982f Author: Ben McGinnes Date: Wed Mar 7 20:12:26 2018 +1100 HOWTO update * removed one bit of whitespace. * Marked up references to gpgme.h. * Fixed one spelling error. * Removed py2.6 from python search order since even if it is supported, it shouldn't be encouraged. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index b9dc882..1767cd4 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -14,7 +14,7 @@ :CUSTOM_ID: intro :END: -Version: 0.0.1-alpha [2018-03-07 Wed] +Version: 0.0.1-alpha [2018-03-07 Wed] Author: Ben McGinnes Author GPG Key: DB4724E6FA4286C92B4E55C4321E4E2373590E5D @@ -35,7 +35,7 @@ Python bindings to programmatically leverage the GPGME library. Unlike many modern APIs with which programmers will be more familiar with these days, the GPGME API is a C API. The API is intended for use by C coders who would be able to access its - features by including the gpgme.h header file eith their own C + features by including the =gpgme.h= header file eith their own C source code and then access its functions just as they would any other C headers. @@ -56,11 +56,11 @@ Python bindings to programmatically leverage the GPGME library. provides a more pythonic means of calling these API functions. The bindings are generated dynamically with SWIG and the copy of - gpgme.h gemerated when GPGME is compiled. + =gpgme.h= generated when GPGME is compiled. This means that a version of the Python bindings is fundamentally tied to the exact same version of GPGME used to gemerate that copy - of gpgme.h. + of =gpgme.h=. ** Difference between the Python bindings and other GnuPG Python packages :PROPERTIES: @@ -186,7 +186,7 @@ Python bindings to programmatically leverage the GPGME library. numbers. For Python 2 it checks for these executables in this order: - =python=, =python2=, =python2.7= and =python2.6=. + =python=, =python2= and =python2.7=. For Python 3 it checks for these executables in this order: =python3=, =python3.6=, =python3.5= and =python3.4=. commit 5215d58ae2521d81c3db0b45dfbdce01a679acab Author: Ben McGinnes Date: Wed Mar 7 20:05:21 2018 +1100 GPGME Python bindings HOWTO * Started work on the GPGME Python bindings HOWTO. * 1,050 words to begin with at approx. 7.5KB. * Got as far as installation. * Includes instruction not to use PyPI for this. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org new file mode 100644 index 0000000..b9dc882 --- /dev/null +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -0,0 +1,221 @@ +#+TITLE: GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English) + +#+LATEX_COMPILER: xelatex +#+LATEX_CLASS: article +#+LATEX_CLASS_OPTIONS: [12pt] +#+LATEX_HEADER: \usepackage{xltxtra} +#+LATEX_HEADER: \usepackage[margin=1in]{geometry} +#+LATEX_HEADER: \setmainfont[Ligatures={Common}]{Times New Roman} +#+LATEX_HEADER: \author{Ben McGinnes } + + +* Introduction + :PROPERTIES: + :CUSTOM_ID: intro + :END: + +Version: 0.0.1-alpha [2018-03-07 Wed] +Author: Ben McGinnes +Author GPG Key: DB4724E6FA4286C92B4E55C4321E4E2373590E5D + +This document provides basic instruction in how to use the GPGME +Python bindings to programmatically leverage the GPGME library. + + +* GPGME Concepts + :PROPERTIES: + :CUSTOM_ID: gpgme-concepts + :END: + +** A C API + :PROPERTIES: + :CUSTOM_ID: gpgme-c-api + :END: + + Unlike many modern APIs with which programmers will be more + familiar with these days, the GPGME API is a C API. The API is + intended for use by C coders who would be able to access its + features by including the gpgme.h header file eith their own C + source code and then access its functions just as they would any + other C headers. + + This is a very effective method of gaining complete access to the + API and in the most efficient manner possible. It does, however, + have the drawback that it cannot be directly used by other + languages without some means of providing an interface to those + languages. This is where the need for bindings in various + languages stems. + +** Python bindings + :PROPERTIES: + :CUSTOM_ID: gpgme-python-bindings + :END: + + The Python bindings for GPGME provide a higher level means of + accessing the complete feature set of GPGME itself. It also + provides a more pythonic means of calling these API functions. + + The bindings are generated dynamically with SWIG and the copy of + gpgme.h gemerated when GPGME is compiled. + + This means that a version of the Python bindings is fundamentally + tied to the exact same version of GPGME used to gemerate that copy + of gpgme.h. + +** Difference between the Python bindings and other GnuPG Python packages + :PROPERTIES: + :CUSTOM_ID: gpgme-python-bindings-diffs + :END: + + There have been numerous attempts to add GnuPG support to Python + over the years. Some of the most well known are listed here, along + with what differentiates them. + +*** The python-gnupg package maintained by Vinay Sajip + :PROPERTIES: + :CUSTOM_ID: diffs-python-gnupg + :END: + + This is arguably the most popular means of integrating GPG with + Python. The package utilises the =subprocess= module to implement + wrappers for the =gpg= and =gpg2= executables normally invoked on + the command line (=gpg.exe= and =gpg2.exe= on Windows). + + The popularity of this package stemmed from its ease of use and + capability in providing the most commonly required features. + + 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. + + The python-gnupg package is available under the MIT license. + +*** The gnupg package created and maintained by Isis Lovecruft + :PROPERTIES: + :CUSTOM_ID: diffs-isis-gnupg + :END: + + In 2015 Isis Lovecruft from the Tor Project forked and then + re-implemented the python-gnupg package as just gnupg. This new + package also relied on subprocess to call the =gpg= or =gpg2= + binaries, but did so somewhat more securely. + + However the naming and version numbering selected for this package + resulted in conflicts with the original python-gnupg and since its + functions were called in a different manner, the release of this + package also resulted in a great deal of consternation when people + installed what they thought was an upgrade that subsequently broke + the code relying on it. + + The gnupg package is available under the GNU General Public + License version 3.0 (or later). + +*** The PyME package maintained by Martin Albrecht + :PROPERTIES: + :CUSTOM_ID: diffs-pyme + :END: + + This package is the origin of these bindings, though they are + somewhat different now. For details of when and how the PyME + package was folded back into GPGME itself see the [[Short_History.org][Short History]] + document in this Python bindings =docs= directory. + + The PyME package was first released in 2002 and was also the first + attempt to implement a low level binding to GPGME. In doing so it + provided access to considerably more functionality than either the + =python-gnupg= or =gnupg= packages. + + The PyME package is only available for Python 2.6 and 2.7. + + Porting the PyME package to Python 3.4 in 2015 is what resulted in + it being folded into the GPGME project and the current bindings + are the end result of that effort. + + The PyME package is available under the same dual licensing as + GPGME itself: the GNU General Public License version 2.0 (or any + later version) and the GNU Lesser Public License version 2.1 (or + any later version). + + +* GPGME Python bindings installation + :PROPERTIES: + :CUSTOM_ID: gpgme-python-install + :END: + +** No PyPI + :PROPERTIES: + :CUSTOM_ID: do-not-use-pypi + :END: + + 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. + +** Requirements + :PROPERTIES: + :CUSTOM_ID: gpgme-python-requirements + :END: + + The GPGME Python bindings only have three requirements: + + 1. A suitable version of Python 2 or Python 3. With Python 2 that + means Python 2.7 and with Python 3 that means Python 3.4 or + higher. + 2. SWIG. + 3. GPGME itself. Which also means that all of GPGME's dependencies + must be installed too. + +** Installation + :PROPERTIES: + :CUSTOM_ID: installation + :END: + + Installing the Python bindings is effectively achieved by compiling + and installing GPGME itself. + + Once SWIG is installed with Python and all the dependencies for + GPGME are installed you only need to confirm that the version(s) of + Python you want the bindings installed for are in your =$PATH=. + + By default GPGME will attempt to install the bindings for the most + recent or highest version number of Python 2 and Python 3 it + detects in =$PATH=. It specifically checks for the =python= and + =python3= executabled first and then checks for specific version + numbers. + + For Python 2 it checks for these executables in this order: + =python=, =python2=, =python2.7= and =python2.6=. + + For Python 3 it checks for these executables in this order: + =python3=, =python3.6=, =python3.5= and =python3.4=. + +*** Installing GPGME + :PROPERTIES: + :CUSTOM_ID: install-gpgme + :END: + + See the [[../../../README][GPGME README file]] for details of how to install GPGME from + source. + + +* Copyright and Licensing + :PROPERTIES: + :CUSTOM_ID: copyright-and-license + :END: + +** Copyright (C) The GnuPG Project, 2018 + :PROPERTIES: + :CUSTOM_ID: copyright + :END: + + Copyright ? The GnuPG Project, 2018. + +** License TBA + :PROPERTIES: + :CUSTOM_ID: license + :END: + + Which license shall we use for these docs, hmm? Gotta be free, so + that rules the GFDL out. I'll pick a CC or something later ... commit 8f2c0f4534ea2a07f071f360a63e877f60dc52f2 Author: Ben McGinnes Date: Wed Mar 7 19:13:37 2018 +1100 TODO - HOWTO * Added suv-entry for the new HOWTO being started and, since it has been started, checked it off. diff --git a/lang/python/docs/TODO.org b/lang/python/docs/TODO.org index 9b042d9..4e067df 100644 --- a/lang/python/docs/TODO.org +++ b/lang/python/docs/TODO.org @@ -35,7 +35,8 @@ Write a HOWTO style guide for the current Python bindings. -*** TODO Start python bindings HOWTO +*** DONE Start python bindings HOWTO + CLOSED: [2018-03-07 Wed 18:14] :PROPERTIES: :CUSTOM_ID: howto-start :END: commit d4778bb23d0817ee6fbcbe4f0ff0ff0429bf3669 Author: Ben McGinnes Date: Wed Mar 7 17:56:54 2018 +1100 TODO * Slightly expanded the list. diff --git a/lang/python/docs/TODO.org b/lang/python/docs/TODO.org index 9f039d8..9b042d9 100644 --- a/lang/python/docs/TODO.org +++ b/lang/python/docs/TODO.org @@ -35,6 +35,11 @@ Write a HOWTO style guide for the current Python bindings. +*** TODO Start python bindings HOWTO + :PROPERTIES: + :CUSTOM_ID: howto-start + :END: + ** TODO Documentation SWIG :PROPERTIES: :CUSTOM_ID: todo-docs-swig @@ -94,6 +99,7 @@ available or for which it is too difficult to create proper bindings. + * Project Task Details :PROPERTIES: :CUSTOM_ID: detailed-tasks ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 221 ++++++++++++++++++++++++++++++++ lang/python/docs/TODO.org | 7 + 2 files changed, 228 insertions(+) create mode 100644 lang/python/docs/GPGMEpythonHOWTOen.org hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 7 10:16:59 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 07 Mar 2018 10:16:59 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-80-g18db01e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 18db01ed4915a38622c90c81d16f1b7e812c3917 (commit) via fde43045b717413d5358f3cc06592a83ebef7805 (commit) via 6a3fc31f4b02388fb6b7e2ca1e8673303632d002 (commit) from 808be5a08d8a6f46f9e6eff82e23797ae9ec5343 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 18db01ed4915a38622c90c81d16f1b7e812c3917 Author: Andre Heinecke Date: Wed Mar 7 10:01:38 2018 +0100 Update translations and fix some german strings * po: Update. diff --git a/po/de.po b/po/de.po index d516fd5..d58fd75 100644 --- a/po/de.po +++ b/po/de.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL 1.0.0\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-06 15:25+0100\n" -"PO-Revision-Date: 2018-03-07 08:24+0100\n" +"POT-Creation-Date: 2018-03-07 10:01+0100\n" +"PO-Revision-Date: 2018-03-07 08:59+0100\n" "Last-Translator: Andre Heinecke \n" "Language-Team: English \n" "Language: en_US\n" @@ -175,11 +175,11 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "M?chten Sie diesen Ordner von GpgOL befreien?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 msgid "GpgOL: Encrypted Message" msgstr "GpgOL: Verschl?sselte Nachricht" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 msgid "GpgOL: Trusted Sender Address" msgstr "GpgOL: Vertraute Absenderadresse" @@ -443,7 +443,7 @@ msgstr "" "

Wenn sie dies nicht angefordert haben, k?nnen Sie diese Mail ignorieren.\n" -#: src/mail.cpp:820 src/mail.cpp:2006 +#: src/mail.cpp:820 src/mail.cpp:1967 msgid "Encrypted message" msgstr "Verschl?sselte Nachricht" @@ -451,7 +451,7 @@ msgstr "Verschl?sselte Nachricht" msgid "Please wait while the message is being decrypted / verified..." msgstr "Bitte warten Sie w?hrend die Nachricht entschl?sselt / gepr?ft wird..." -#: src/mail.cpp:1095 +#: src/mail.cpp:1097 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "GpgOL: Oops, G Suite Sync Konto erkannt" @@ -468,123 +468,93 @@ msgstr "" "\n" "Details siehe: https://dev.gnupg.org/T3545" -#: src/mail.cpp:1114 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details." -msgstr "" -"G Suite Sync bricht ausgehende, signierte, Mails.\n" -"Sicherung der Integrit?t (signieren) wird mit G Suite Sync nicht " -"unterst?tzt.\n" -"\n" -"Details siehe: https://dev.gnupg.org/T3545" - -#: src/mail.cpp:1129 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details.\n" -"\n" -"Do you want to only encrypt the message?" -msgstr "" -"G Suite Sync bricht ausgehende, signierte, Mails.\n" -"Sicherung der Integrit?t (signieren) wird mit G Suite Sync nicht " -"unterst?tzt.\n" -"\n" -"Details siehe: https://dev.gnupg.org/T3545\n" -"\n" -"M?chten Sie die Nachricht nur verschl?sseln?" - -#: src/mail.cpp:1951 +#: src/mail.cpp:1912 msgid "Security Level 4" msgstr "Sicherheit Stufe 4" -#: src/mail.cpp:1955 +#: src/mail.cpp:1916 msgid "Trust Level 4" msgstr "Vertrauen Stufe 4" -#: src/mail.cpp:1959 +#: src/mail.cpp:1920 msgid "Security Level 3" msgstr "Sicherheit Stufe 3" -#: src/mail.cpp:1963 +#: src/mail.cpp:1924 msgid "Trust Level 3" msgstr "Vertrauen Stufe 3" -#: src/mail.cpp:1967 +#: src/mail.cpp:1928 msgid "Security Level 2" msgstr "Sicherheit Stufe 2" -#: src/mail.cpp:1971 +#: src/mail.cpp:1932 msgid "Trust Level 2" msgstr "Vertrauen Stufe 2" -#: src/mail.cpp:1975 +#: src/mail.cpp:1936 msgid "Encrypted" msgstr "Verschl?sselt" -#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "Unsicher" -#: src/mail.cpp:1998 +#: src/mail.cpp:1959 msgid "Signed and encrypted message" msgstr "Signierte und verschl?sselte Nachricht" -#: src/mail.cpp:2002 +#: src/mail.cpp:1963 msgid "Signed message" msgstr "Signierte Nachricht" -#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 msgid "Insecure message" msgstr "Unsichere Nachricht" -#: src/mail.cpp:2020 src/mail.cpp:2031 +#: src/mail.cpp:1981 src/mail.cpp:1992 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" "Sie k?nnen nicht sicher sein wer die Nachricht gesendet, modifiziert oder " "w?hrend der ?bertragung gelesen hat." -#: src/mail.cpp:2023 +#: src/mail.cpp:1984 msgid "The message was signed but the verification failed with:" msgstr "Die Nachricht ist signiert aber die ?berpr?fung schlug fehl mit:" -#: src/mail.cpp:2041 +#: src/mail.cpp:2002 msgid "The encryption was VS-NfD-compliant." msgstr "Diese Verschl?sselung war VS-NfD-konform." -#: src/mail.cpp:2045 +#: src/mail.cpp:2006 msgid "The encryption was not VS-NfD-compliant." msgstr "Diese Verschl?sselung war nicht VS-NfD-konform." -#: src/mail.cpp:2049 +#: src/mail.cpp:2010 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" "Aber Sie k?nnen nicht sicher sein wer der Absender der Nachricht ist da " "diese nicht signiert wurde. " -#: src/mail.cpp:2072 +#: src/mail.cpp:2033 msgid "You signed this message." msgstr "Sie haben diese Nachricht signiert." -#: src/mail.cpp:2076 +#: src/mail.cpp:2037 msgid "The senders identity was certified by yourself." msgstr "Die Idenit?t des Absenders wurde von ihnen selbst beglaubigt." -#: src/mail.cpp:2080 +#: src/mail.cpp:2041 msgid "The sender is allowed to certify identities for you." msgstr "Der Absender ist berechtigt f?r Sie Identit?ten zu beglaubigen." -#: src/mail.cpp:2093 +#: src/mail.cpp:2054 msgid "The senders identity was certified by several trusted people." msgstr "" "Die Identit?t des Absenders wurde von mehreren vertrauensw?rdigen Personen " "beglaubigt." -#: src/mail.cpp:2098 +#: src/mail.cpp:2059 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" @@ -593,12 +563,12 @@ msgstr "" "Die Idenit?t des Absenders wurde best?tigt von:\n" "'%s'\n" -#: src/mail.cpp:2106 +#: src/mail.cpp:2067 msgid "Some trusted people have certified the senders identity." msgstr "" "Einige vertrauensw?rde Personen haben die Identit?t des Absenders beglaubigt." -#: src/mail.cpp:2116 +#: src/mail.cpp:2077 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -610,11 +580,11 @@ msgstr "" "Seit %s haben Sie %i Nachrichten an diesen Absender verschl?sselt und %i " "Signaturen gepr?ft." -#: src/mail.cpp:2132 +#: src/mail.cpp:2093 msgid "The senders signature was verified for the first time." msgstr "The Signatur des Absenders wurde das erste mal verifiziert." -#: src/mail.cpp:2139 +#: src/mail.cpp:2100 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " @@ -624,70 +594,70 @@ msgstr "" "Nachrichten von diesem absender verifziert und %i Nachrichten verschl?ssel " "haben. Seit dem %s." -#: src/mail.cpp:2153 +#: src/mail.cpp:2114 msgid "But the sender address is not trustworthy because:" msgstr "Aber die Absenderadresse ist nicht vertrauensw?rdig da:" -#: src/mail.cpp:2154 +#: src/mail.cpp:2115 msgid "The sender address is not trustworthy because:" msgstr "Die Absenderadresse ist nicht vertrauensw?rdig da:" -#: src/mail.cpp:2162 +#: src/mail.cpp:2123 msgid "The signature is invalid: \n" msgstr "Die Signatur ist ung?ltig: \n" -#: src/mail.cpp:2167 +#: src/mail.cpp:2128 msgid "There was an error verifying the signature.\n" msgstr "Beim ?berpr?fen der Signatur ist ein Fehler aufgetreten.\n" -#: src/mail.cpp:2171 +#: src/mail.cpp:2132 msgid "The signature is expired.\n" msgstr "Die Signatur ist abgelaufen.\n" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 msgid "The used key" msgstr "Der verwendete Schl?ssel" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 msgid "The used certificate" msgstr "Das verwendete Zertifikat" -#: src/mail.cpp:2183 +#: src/mail.cpp:2144 msgid "is not available." msgstr "ist nicht verf?gbar." -#: src/mail.cpp:2187 +#: src/mail.cpp:2148 msgid "is revoked." msgstr "wurde zur?ckgezogen." -#: src/mail.cpp:2191 +#: src/mail.cpp:2152 msgid "is expired." msgstr "ist veraltet. " -#: src/mail.cpp:2195 +#: src/mail.cpp:2156 msgid "is not meant for signing." msgstr "ist nicht zum signieren vorgesehen. " -#: src/mail.cpp:2199 src/mail.cpp:2203 +#: src/mail.cpp:2160 src/mail.cpp:2164 msgid "could not be checked for revocation." msgstr "wurde m?glicherweise zur?ckgezogen." -#: src/mail.cpp:2208 +#: src/mail.cpp:2169 msgid "is not the same as the key that was used for this address in the past." msgstr "" "ist nicht der gleiche Schl?ssel der in der vergangenheit f?r diese Adresse " "verwendet wurde." -#: src/mail.cpp:2214 +#: src/mail.cpp:2175 #, c-format msgid "does not claim the address: \"%s\"." msgstr "passt nicht zu der mailaddresse: \"%s\". " -#: src/mail.cpp:2227 +#: src/mail.cpp:2188 msgid "is not certified by any trustworthy key." msgstr "wurde von keinem vertrauensw?rdigen Schl?ssel beglaubigt." -#: src/mail.cpp:2231 +#: src/mail.cpp:2192 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." @@ -695,59 +665,59 @@ msgstr "" "wurde von keiner vertrauensw?rdigen Zertifizierungsstelle beglaubigt oder " "die Zertifizierungsstelle ist unbekannt." -#: src/mail.cpp:2236 +#: src/mail.cpp:2197 msgid "The sender marked this address as revoked." msgstr "Der Absender hat diese Adresse zur?ckgezogen." -#: src/mail.cpp:2240 +#: src/mail.cpp:2201 msgid "is marked as not trustworthy." msgstr "ist als nicht vertrauensw?rdig markiert." -#: src/mail.cpp:2250 +#: src/mail.cpp:2211 msgid "The signature is VS-NfD-compliant." msgstr "Die Signatur ist VS-NfD-konform." -#: src/mail.cpp:2254 +#: src/mail.cpp:2215 msgid "The signature is not VS-NfD-compliant." msgstr "Die Signatur ist nicht VS-NfD-konform." -#: src/mail.cpp:2262 +#: src/mail.cpp:2223 msgid "The encryption is VS-NfD-compliant." msgstr "Diese Verschl?sselung ist VS-NfD-konform." -#: src/mail.cpp:2266 +#: src/mail.cpp:2227 msgid "The encryption is not VS-NfD-compliant." msgstr "Diese Verschl?sselung ist nicht VS-NfD-konform." -#: src/mail.cpp:2277 +#: src/mail.cpp:2238 msgid "Click here to change the key used for this address." msgstr "Klicken Sie hier um den Schl?ssel f?r diese Adresse zu ?ndern." -#: src/mail.cpp:2281 +#: src/mail.cpp:2242 msgid "Click here for details about the key." msgstr "Klicken Sie hier f?r Details zu dem Schl?ssel" -#: src/mail.cpp:2282 +#: src/mail.cpp:2243 msgid "Click here for details about the certificate." msgstr "Klicken Sie hier f?r Details zu dem Zertifiakt." -#: src/mail.cpp:2286 +#: src/mail.cpp:2247 msgid "Click here to search the key on the configured keyserver." msgstr "" "Klicken Sie hier um den Schl?ssel auf dem konfigurierten Schl?sselserver zu " "suchen. " -#: src/mail.cpp:2287 +#: src/mail.cpp:2248 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" "Klicken Sie hier um das Zertifikat auf dem konfigurierten X509 " "Schl?sselserver zu suchen." -#: src/mail.cpp:2515 +#: src/mail.cpp:2476 msgid "GpgOL: Encryption not possible!" msgstr "GpgOL: Verschl?sselung nicht m?glich!" -#: src/mail.cpp:2517 +#: src/mail.cpp:2478 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -1198,6 +1168,50 @@ msgstr "" msgid "GpgOL: Request confirmed!" msgstr "GpgOL: Eintragung best?tigt." +#: src/cryptcontroller.cpp:394 +msgid "Resolving recipients..." +msgstr "Empf?nger aufl?sen..." + +#: src/cryptcontroller.cpp:398 +msgid "Resolving signers..." +msgstr "Signierer aufl?sen..." + +#: src/cryptcontroller.cpp:994 +msgid "Encrypting..." +msgstr "Verschl?sseln..." + +#: src/cryptcontroller.cpp:998 +msgid "Signing..." +msgstr "Signieren..." + +#~ msgid "" +#~ "G Suite Sync breaks outgoing signed mails.\n" +#~ "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" +#~ "\n" +#~ "See: https://dev.gnupg.org/T3545 for details." +#~ msgstr "" +#~ "G Suite Sync bricht ausgehende, signierte, Mails.\n" +#~ "Sicherung der Integrit?t (signieren) wird mit G Suite Sync nicht " +#~ "unterst?tzt.\n" +#~ "\n" +#~ "Details siehe: https://dev.gnupg.org/T3545" + +#~ msgid "" +#~ "G Suite Sync breaks outgoing signed mails.\n" +#~ "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" +#~ "\n" +#~ "See: https://dev.gnupg.org/T3545 for details.\n" +#~ "\n" +#~ "Do you want to only encrypt the message?" +#~ msgstr "" +#~ "G Suite Sync bricht ausgehende, signierte, Mails.\n" +#~ "Sicherung der Integrit?t (signieren) wird mit G Suite Sync nicht " +#~ "unterst?tzt.\n" +#~ "\n" +#~ "Details siehe: https://dev.gnupg.org/T3545\n" +#~ "\n" +#~ "M?chten Sie die Nachricht nur verschl?sseln?" + #~ msgid "&Search for OpenPGP keys automatically when encrypting" #~ msgstr "OpenPGP-&Schl?ssel zum verschl?sseln automatisch suchen" @@ -1344,9 +1358,6 @@ msgstr "GpgOL: Eintragung best?tigt." #~ "\n" #~ "Die Nachricht wird deswegen nicht f?r dieses Zertifikat verschl?sselt!" -#~ msgid "Encryption" -#~ msgstr "Verschl?sselung" - #~ msgid "Fingerprint: " #~ msgstr "Fingerabdruck: " @@ -1469,9 +1480,6 @@ msgstr "GpgOL: Eintragung best?tigt." #~ msgid "Validity" #~ msgstr "G?ltigkeit" -#~ msgid "Selected recipients:" -#~ msgstr "Ausgew?hlte Empf?nger:" - #~ msgid "Recipient which were NOT found" #~ msgstr "Empf?nger die NICHT gefunden wurden:" diff --git a/po/fr.po b/po/fr.po index 3e9939d..f69b207 100644 --- a/po/fr.po +++ b/po/fr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-06 15:25+0100\n" +"POT-Creation-Date: 2018-03-07 10:01+0100\n" "PO-Revision-Date: 2015-10-01 17:05+0200\n" "Last-Translator: Olivier Serve \n" "Language-Team: French \n" @@ -172,12 +172,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "Voulez-vous r?cup?rer ce dossier ?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "D?chiffrer le message" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -422,7 +422,7 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:820 src/mail.cpp:2006 +#: src/mail.cpp:820 src/mail.cpp:1967 #, fuzzy msgid "Encrypted message" msgstr "D?chiffrer le message" @@ -431,7 +431,7 @@ msgstr "D?chiffrer le message" msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1095 +#: src/mail.cpp:1097 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" @@ -443,123 +443,105 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1114 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details." -msgstr "" - -#: src/mail.cpp:1129 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details.\n" -"\n" -"Do you want to only encrypt the message?" -msgstr "" - -#: src/mail.cpp:1951 +#: src/mail.cpp:1912 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1955 +#: src/mail.cpp:1916 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1959 +#: src/mail.cpp:1920 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1963 +#: src/mail.cpp:1924 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1967 +#: src/mail.cpp:1928 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1971 +#: src/mail.cpp:1932 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1975 +#: src/mail.cpp:1936 #, fuzzy msgid "Encrypted" msgstr "Chiffrer" -#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "" -#: src/mail.cpp:1998 +#: src/mail.cpp:1959 #, fuzzy msgid "Signed and encrypted message" msgstr "D?chiffrer le message" -#: src/mail.cpp:2002 +#: src/mail.cpp:1963 #, fuzzy msgid "Signed message" msgstr "D?chiffrer le message" -#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 #, fuzzy msgid "Insecure message" msgstr "D?chiffrer le message" -#: src/mail.cpp:2020 src/mail.cpp:2031 +#: src/mail.cpp:1981 src/mail.cpp:1992 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:2023 +#: src/mail.cpp:1984 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2002 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2045 +#: src/mail.cpp:2006 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2049 +#: src/mail.cpp:2010 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2072 +#: src/mail.cpp:2033 #, fuzzy msgid "You signed this message." msgstr "D?chiffrer le message" -#: src/mail.cpp:2076 +#: src/mail.cpp:2037 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2080 +#: src/mail.cpp:2041 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2054 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2098 +#: src/mail.cpp:2059 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2106 +#: src/mail.cpp:2067 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2116 +#: src/mail.cpp:2077 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -567,142 +549,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2093 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2139 +#: src/mail.cpp:2100 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2153 +#: src/mail.cpp:2114 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2154 +#: src/mail.cpp:2115 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2162 +#: src/mail.cpp:2123 #, fuzzy msgid "The signature is invalid: \n" msgstr "Cette signature est valide\n" -#: src/mail.cpp:2167 +#: src/mail.cpp:2128 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2171 +#: src/mail.cpp:2132 #, fuzzy msgid "The signature is expired.\n" msgstr "Cette signature est valide\n" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 msgid "The used key" msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 #, fuzzy msgid "The used certificate" msgstr "Erreur de v?rification" -#: src/mail.cpp:2183 +#: src/mail.cpp:2144 #, fuzzy msgid "is not available." msgstr "La liste de r?vocation (CRL) n'est pas disponible\n" -#: src/mail.cpp:2187 +#: src/mail.cpp:2148 msgid "is revoked." msgstr "" -#: src/mail.cpp:2191 +#: src/mail.cpp:2152 msgid "is expired." msgstr "" -#: src/mail.cpp:2195 +#: src/mail.cpp:2156 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2199 src/mail.cpp:2203 +#: src/mail.cpp:2160 src/mail.cpp:2164 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2208 +#: src/mail.cpp:2169 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2214 +#: src/mail.cpp:2175 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2227 +#: src/mail.cpp:2188 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2231 +#: src/mail.cpp:2192 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2236 +#: src/mail.cpp:2197 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2240 +#: src/mail.cpp:2201 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2250 +#: src/mail.cpp:2211 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2254 +#: src/mail.cpp:2215 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2262 +#: src/mail.cpp:2223 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2266 +#: src/mail.cpp:2227 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2277 +#: src/mail.cpp:2238 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2281 +#: src/mail.cpp:2242 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2282 +#: src/mail.cpp:2243 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2286 +#: src/mail.cpp:2247 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2287 +#: src/mail.cpp:2248 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2515 +#: src/mail.cpp:2476 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "D?chiffrer le message" -#: src/mail.cpp:2517 +#: src/mail.cpp:2478 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -1087,6 +1069,24 @@ msgstr "" msgid "GpgOL: Request confirmed!" msgstr "" +#: src/cryptcontroller.cpp:394 +#, fuzzy +msgid "Resolving recipients..." +msgstr "Destinataires s?lectionn?s?:" + +#: src/cryptcontroller.cpp:398 +msgid "Resolving signers..." +msgstr "" + +#: src/cryptcontroller.cpp:994 +#, fuzzy +msgid "Encrypting..." +msgstr "Chiffrement" + +#: src/cryptcontroller.cpp:998 +msgid "Signing..." +msgstr "" + #, fuzzy #~ msgid "" #~ "Error creating file\n" @@ -1164,9 +1164,6 @@ msgstr "" #~ "\n" #~ "Ce message ne sera pas chiffr? avec ce certificat ! " -#~ msgid "Encryption" -#~ msgstr "Chiffrement" - #~ msgid "Fingerprint: " #~ msgstr "Empreinte : " @@ -1283,9 +1280,6 @@ msgstr "" #~ msgid "Validity" #~ msgstr "Validit?" -#~ msgid "Selected recipients:" -#~ msgstr "Destinataires s?lectionn?s?:" - #~ msgid "Recipient which were NOT found" #~ msgstr "Destinataire non trouv?" diff --git a/po/pt.po b/po/pt.po index 5bfe6fd..a7208d8 100644 --- a/po/pt.po +++ b/po/pt.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL 1.1.1\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-06 15:25+0100\n" +"POT-Creation-Date: 2018-03-07 10:01+0100\n" "PO-Revision-Date: 2017-10-16 14:17+0100\n" "Last-Translator: Marco A.G.Pinto \n" "Language-Team: Portuguese \n" @@ -175,11 +175,11 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "Queres reverter esta pasta?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 msgid "GpgOL: Encrypted Message" msgstr "GpgOL: Mensagem Encriptada" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 msgid "GpgOL: Trusted Sender Address" msgstr "GpgOL: Endere?o de Remetente Confi?vel" @@ -438,7 +438,7 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:820 src/mail.cpp:2006 +#: src/mail.cpp:820 src/mail.cpp:1967 msgid "Encrypted message" msgstr "Mensagem encriptada" @@ -448,7 +448,7 @@ msgstr "" "Por favor aguarda enquanto a mensagem est? a ser desencriptada / " "verificada..." -#: src/mail.cpp:1095 +#: src/mail.cpp:1097 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" @@ -460,109 +460,91 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1114 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details." -msgstr "" - -#: src/mail.cpp:1129 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details.\n" -"\n" -"Do you want to only encrypt the message?" -msgstr "" - -#: src/mail.cpp:1951 +#: src/mail.cpp:1912 msgid "Security Level 4" msgstr "N?vel de seguran?a 4" -#: src/mail.cpp:1955 +#: src/mail.cpp:1916 msgid "Trust Level 4" msgstr "N?vel de Confian?a 4" -#: src/mail.cpp:1959 +#: src/mail.cpp:1920 msgid "Security Level 3" msgstr "N?vel de Seguran?a 3" -#: src/mail.cpp:1963 +#: src/mail.cpp:1924 msgid "Trust Level 3" msgstr "N?vel de Confian?a 3" -#: src/mail.cpp:1967 +#: src/mail.cpp:1928 msgid "Security Level 2" msgstr "N?vel de Seguran?a 2" -#: src/mail.cpp:1971 +#: src/mail.cpp:1932 msgid "Trust Level 2" msgstr "N?vel de Confian?a 2" -#: src/mail.cpp:1975 +#: src/mail.cpp:1936 msgid "Encrypted" msgstr "Encriptada" -#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "Insegura" -#: src/mail.cpp:1998 +#: src/mail.cpp:1959 msgid "Signed and encrypted message" msgstr "Mensagem assinada e encriptada" -#: src/mail.cpp:2002 +#: src/mail.cpp:1963 msgid "Signed message" msgstr "Mensagem assinada" -#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 msgid "Insecure message" msgstr "Mensagem insegura" -#: src/mail.cpp:2020 src/mail.cpp:2031 +#: src/mail.cpp:1981 src/mail.cpp:1992 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" "N?o podes ter a certeza de quem enviou, modificou e leu a mensagem em " "tr?nsito." -#: src/mail.cpp:2023 +#: src/mail.cpp:1984 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2002 msgid "The encryption was VS-NfD-compliant." msgstr "A encripta??o est? em conformidade com VS-NfD." -#: src/mail.cpp:2045 +#: src/mail.cpp:2006 msgid "The encryption was not VS-NfD-compliant." msgstr "A encripta??o n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2049 +#: src/mail.cpp:2010 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" "N?o podes ter certeza de quem enviou a mensagem, porque n?o est? assinada." -#: src/mail.cpp:2072 +#: src/mail.cpp:2033 msgid "You signed this message." msgstr "Assinaste esta mensagem." -#: src/mail.cpp:2076 +#: src/mail.cpp:2037 msgid "The senders identity was certified by yourself." msgstr "A identidade dos remetentes foi certificada por ti pr?prio." -#: src/mail.cpp:2080 +#: src/mail.cpp:2041 msgid "The sender is allowed to certify identities for you." msgstr "O remetente pode certificar identidades para ti." -#: src/mail.cpp:2093 +#: src/mail.cpp:2054 msgid "The senders identity was certified by several trusted people." msgstr "" "A identidade dos remetentes foi certificada por v?rias pessoas confi?veis." -#: src/mail.cpp:2098 +#: src/mail.cpp:2059 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" @@ -571,11 +553,11 @@ msgstr "" "A identidade dos remetentes ? certificada pelo emissor confi?vel:\n" "'%s'\n" -#: src/mail.cpp:2106 +#: src/mail.cpp:2067 msgid "Some trusted people have certified the senders identity." msgstr "Algumas pessoas confi?veis certificaram a identidade dos remetentes." -#: src/mail.cpp:2116 +#: src/mail.cpp:2077 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -586,11 +568,11 @@ msgstr "" "comunica??o com este endere?o desde %s.\n" "Encriptaste %i e verificaste %i mensagens desde ent?o." -#: src/mail.cpp:2132 +#: src/mail.cpp:2093 msgid "The senders signature was verified for the first time." msgstr "A assinatura dos remetentes foi verificada pela primeira vez." -#: src/mail.cpp:2139 +#: src/mail.cpp:2100 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " @@ -599,68 +581,68 @@ msgstr "" "O endere?o dos remetentes ainda n?o ? confi?vel porque apenas verificaste %i " "mensagens e encriptaste %i mensagens a eles desde %s." -#: src/mail.cpp:2153 +#: src/mail.cpp:2114 msgid "But the sender address is not trustworthy because:" msgstr "Mas o endere?o do remetente n?o ? confi?vel porque:" -#: src/mail.cpp:2154 +#: src/mail.cpp:2115 msgid "The sender address is not trustworthy because:" msgstr "O endere?o do remetente n?o ? confi?vel porque:" -#: src/mail.cpp:2162 +#: src/mail.cpp:2123 msgid "The signature is invalid: \n" msgstr "A assinatura ? inv?lida: \n" -#: src/mail.cpp:2167 +#: src/mail.cpp:2128 msgid "There was an error verifying the signature.\n" msgstr "Houve um erro ao verificar a assinatura.\n" -#: src/mail.cpp:2171 +#: src/mail.cpp:2132 msgid "The signature is expired.\n" msgstr "A assinatura expirou.\n" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 msgid "The used key" msgstr "A chave usada" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 msgid "The used certificate" msgstr "O certificado usado" -#: src/mail.cpp:2183 +#: src/mail.cpp:2144 msgid "is not available." msgstr "n?o est? dispon?vel." -#: src/mail.cpp:2187 +#: src/mail.cpp:2148 msgid "is revoked." msgstr "est? revogado." -#: src/mail.cpp:2191 +#: src/mail.cpp:2152 msgid "is expired." msgstr "expirou." -#: src/mail.cpp:2195 +#: src/mail.cpp:2156 msgid "is not meant for signing." msgstr "n?o ? destinado a assinar." -#: src/mail.cpp:2199 src/mail.cpp:2203 +#: src/mail.cpp:2160 src/mail.cpp:2164 msgid "could not be checked for revocation." msgstr "n?o pode ser verificado para revoga??o." -#: src/mail.cpp:2208 +#: src/mail.cpp:2169 msgid "is not the same as the key that was used for this address in the past." msgstr "n?o ? o mesmo que a chave usada para este endere?o no passado." -#: src/mail.cpp:2214 +#: src/mail.cpp:2175 #, c-format msgid "does not claim the address: \"%s\"." msgstr "n?o reivindica o endere?o: \"%s\"." -#: src/mail.cpp:2227 +#: src/mail.cpp:2188 msgid "is not certified by any trustworthy key." msgstr "n?o est? certificado por qualquer chave confi?vel." -#: src/mail.cpp:2231 +#: src/mail.cpp:2192 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." @@ -668,58 +650,58 @@ msgstr "" "n?o est? certificado por uma Autoridade de Certifica??o confi?vel ou a " "Autoridade de Certifica??o ? desconhecida." -#: src/mail.cpp:2236 +#: src/mail.cpp:2197 msgid "The sender marked this address as revoked." msgstr "O remetente marcou este endere?o como revogado." -#: src/mail.cpp:2240 +#: src/mail.cpp:2201 msgid "is marked as not trustworthy." msgstr "est? marcado como n?o confi?vel." -#: src/mail.cpp:2250 +#: src/mail.cpp:2211 msgid "The signature is VS-NfD-compliant." msgstr "A assinatura est? em conformidade com VS-NfD." -#: src/mail.cpp:2254 +#: src/mail.cpp:2215 msgid "The signature is not VS-NfD-compliant." msgstr "A assinatura n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2262 +#: src/mail.cpp:2223 msgid "The encryption is VS-NfD-compliant." msgstr "A encripta??o est? em conformidade com VS-NfD." -#: src/mail.cpp:2266 +#: src/mail.cpp:2227 msgid "The encryption is not VS-NfD-compliant." msgstr "A encripta??o n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2277 +#: src/mail.cpp:2238 msgid "Click here to change the key used for this address." msgstr "Clica aqui para alterar a chave usada para este endere?o." -#: src/mail.cpp:2281 +#: src/mail.cpp:2242 msgid "Click here for details about the key." msgstr "Clica aqui para obter detalhes sobre a chave." -#: src/mail.cpp:2282 +#: src/mail.cpp:2243 msgid "Click here for details about the certificate." msgstr "Clica aqui para obter detalhes sobre o certificado." -#: src/mail.cpp:2286 +#: src/mail.cpp:2247 msgid "Click here to search the key on the configured keyserver." msgstr "Clica aqui para localizar a chave no servidor de chaves configurado." -#: src/mail.cpp:2287 +#: src/mail.cpp:2248 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" "Clica aqui para localizar o certificado no servidor de chaves X509 " "configurado." -#: src/mail.cpp:2515 +#: src/mail.cpp:2476 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "GpgOL: Mensagem Encriptada" -#: src/mail.cpp:2517 +#: src/mail.cpp:2478 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -1141,6 +1123,24 @@ msgstr "" msgid "GpgOL: Request confirmed!" msgstr "" +#: src/cryptcontroller.cpp:394 +#, fuzzy +msgid "Resolving recipients..." +msgstr "Destinat?rios seleccionados:" + +#: src/cryptcontroller.cpp:398 +msgid "Resolving signers..." +msgstr "" + +#: src/cryptcontroller.cpp:994 +#, fuzzy +msgid "Encrypting..." +msgstr "Encripta??o" + +#: src/cryptcontroller.cpp:998 +msgid "Signing..." +msgstr "" + #~ msgid "&Search for OpenPGP keys automatically when encrypting" #~ msgstr "Procurar as chaves OpenPGP automaticamente ao encriptar" @@ -1257,9 +1257,6 @@ msgstr "" #~ "\n" #~ "Esta mensagem n?o ser? encriptada para este certificado!" -#~ msgid "Encryption" -#~ msgstr "Encripta??o" - #~ msgid "Fingerprint: " #~ msgstr "Fingerprint: " @@ -1379,9 +1376,6 @@ msgstr "" #~ msgid "Validity" #~ msgstr "Validade" -#~ msgid "Selected recipients:" -#~ msgstr "Destinat?rios seleccionados:" - #~ msgid "Recipient which were NOT found" #~ msgstr "Destinat?rios N?O encontrados" diff --git a/po/sv.po b/po/sv.po index b5c5ad4..28f8ce9 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GPGol\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-06 15:25+0100\n" +"POT-Creation-Date: 2018-03-07 10:01+0100\n" "PO-Revision-Date: 2006-12-12 23:52+0100\n" "Last-Translator: Daniel Nylander \n" "Language-Team: Swedish \n" @@ -164,12 +164,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "Dekryptera och validera meddelandet." -#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -411,7 +411,7 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:820 src/mail.cpp:2006 +#: src/mail.cpp:820 src/mail.cpp:1967 #, fuzzy msgid "Encrypted message" msgstr "Dekryptera och validera meddelandet." @@ -420,7 +420,7 @@ msgstr "Dekryptera och validera meddelandet." msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1095 +#: src/mail.cpp:1097 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" @@ -432,123 +432,105 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1114 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details." -msgstr "" - -#: src/mail.cpp:1129 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details.\n" -"\n" -"Do you want to only encrypt the message?" -msgstr "" - -#: src/mail.cpp:1951 +#: src/mail.cpp:1912 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1955 +#: src/mail.cpp:1916 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1959 +#: src/mail.cpp:1920 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1963 +#: src/mail.cpp:1924 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1967 +#: src/mail.cpp:1928 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1971 +#: src/mail.cpp:1932 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1975 +#: src/mail.cpp:1936 #, fuzzy msgid "Encrypted" msgstr "Kryptering" -#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "" -#: src/mail.cpp:1998 +#: src/mail.cpp:1959 #, fuzzy msgid "Signed and encrypted message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2002 +#: src/mail.cpp:1963 #, fuzzy msgid "Signed message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 #, fuzzy msgid "Insecure message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2020 src/mail.cpp:2031 +#: src/mail.cpp:1981 src/mail.cpp:1992 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:2023 +#: src/mail.cpp:1984 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2002 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2045 +#: src/mail.cpp:2006 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2049 +#: src/mail.cpp:2010 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2072 +#: src/mail.cpp:2033 #, fuzzy msgid "You signed this message." msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2076 +#: src/mail.cpp:2037 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2080 +#: src/mail.cpp:2041 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2054 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2098 +#: src/mail.cpp:2059 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2106 +#: src/mail.cpp:2067 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2116 +#: src/mail.cpp:2077 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -556,142 +538,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2093 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2139 +#: src/mail.cpp:2100 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2153 +#: src/mail.cpp:2114 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2154 +#: src/mail.cpp:2115 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2162 +#: src/mail.cpp:2123 #, fuzzy msgid "The signature is invalid: \n" msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2167 +#: src/mail.cpp:2128 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2171 +#: src/mail.cpp:2132 #, fuzzy msgid "The signature is expired.\n" msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 msgid "The used key" msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 #, fuzzy msgid "The used certificate" msgstr "Validering" -#: src/mail.cpp:2183 +#: src/mail.cpp:2144 #, fuzzy msgid "is not available." msgstr "Sp?rrlistan ?r inte tillg?nglig\n" -#: src/mail.cpp:2187 +#: src/mail.cpp:2148 msgid "is revoked." msgstr "" -#: src/mail.cpp:2191 +#: src/mail.cpp:2152 msgid "is expired." msgstr "" -#: src/mail.cpp:2195 +#: src/mail.cpp:2156 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2199 src/mail.cpp:2203 +#: src/mail.cpp:2160 src/mail.cpp:2164 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2208 +#: src/mail.cpp:2169 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2214 +#: src/mail.cpp:2175 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2227 +#: src/mail.cpp:2188 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2231 +#: src/mail.cpp:2192 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2236 +#: src/mail.cpp:2197 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2240 +#: src/mail.cpp:2201 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2250 +#: src/mail.cpp:2211 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2254 +#: src/mail.cpp:2215 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2262 +#: src/mail.cpp:2223 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2266 +#: src/mail.cpp:2227 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2277 +#: src/mail.cpp:2238 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2281 +#: src/mail.cpp:2242 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2282 +#: src/mail.cpp:2243 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2286 +#: src/mail.cpp:2247 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2287 +#: src/mail.cpp:2248 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2515 +#: src/mail.cpp:2476 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2517 +#: src/mail.cpp:2478 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -1046,6 +1028,23 @@ msgstr "" msgid "GpgOL: Request confirmed!" msgstr "" +#: src/cryptcontroller.cpp:394 +msgid "Resolving recipients..." +msgstr "" + +#: src/cryptcontroller.cpp:398 +msgid "Resolving signers..." +msgstr "" + +#: src/cryptcontroller.cpp:994 +#, fuzzy +msgid "Encrypting..." +msgstr "Kryptering" + +#: src/cryptcontroller.cpp:998 +msgid "Signing..." +msgstr "" + #, fuzzy #~ msgid "" #~ "Error creating file\n" @@ -1111,9 +1110,6 @@ msgstr "" #~ "\n" #~ "Det h?r meddelandet kommer inte att krypteras med den h?r nyckeln!" -#~ msgid "Encryption" -#~ msgstr "Kryptering" - #~ msgid "Fingerprint: " #~ msgstr "Fingeravtryck: " diff --git a/po/zh_CN.po b/po/zh_CN.po index bf3b05b..c47d904 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-06 15:25+0100\n" +"POT-Creation-Date: 2018-03-07 10:01+0100\n" "PO-Revision-Date: 2015-08-15 21:58+0800\n" "Last-Translator: Mingye Wang (Arthur2e5) \n" "Language-Team: \n" @@ -168,12 +168,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "????????????" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "????" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -410,7 +410,7 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:820 src/mail.cpp:2006 +#: src/mail.cpp:820 src/mail.cpp:1967 #, fuzzy msgid "Encrypted message" msgstr "????" @@ -419,7 +419,7 @@ msgstr "????" msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1095 +#: src/mail.cpp:1097 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" @@ -431,123 +431,105 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1114 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details." -msgstr "" - -#: src/mail.cpp:1129 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details.\n" -"\n" -"Do you want to only encrypt the message?" -msgstr "" - -#: src/mail.cpp:1951 +#: src/mail.cpp:1912 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1955 +#: src/mail.cpp:1916 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1959 +#: src/mail.cpp:1920 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1963 +#: src/mail.cpp:1924 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1967 +#: src/mail.cpp:1928 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1971 +#: src/mail.cpp:1932 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1975 +#: src/mail.cpp:1936 #, fuzzy msgid "Encrypted" msgstr "??" -#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "" -#: src/mail.cpp:1998 +#: src/mail.cpp:1959 #, fuzzy msgid "Signed and encrypted message" msgstr "????" -#: src/mail.cpp:2002 +#: src/mail.cpp:1963 #, fuzzy msgid "Signed message" msgstr "????" -#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 #, fuzzy msgid "Insecure message" msgstr "????" -#: src/mail.cpp:2020 src/mail.cpp:2031 +#: src/mail.cpp:1981 src/mail.cpp:1992 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:2023 +#: src/mail.cpp:1984 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2002 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2045 +#: src/mail.cpp:2006 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2049 +#: src/mail.cpp:2010 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2072 +#: src/mail.cpp:2033 #, fuzzy msgid "You signed this message." msgstr "????" -#: src/mail.cpp:2076 +#: src/mail.cpp:2037 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2080 +#: src/mail.cpp:2041 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2054 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2098 +#: src/mail.cpp:2059 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2106 +#: src/mail.cpp:2067 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2116 +#: src/mail.cpp:2077 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -555,142 +537,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2093 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2139 +#: src/mail.cpp:2100 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2153 +#: src/mail.cpp:2114 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2154 +#: src/mail.cpp:2115 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2162 +#: src/mail.cpp:2123 #, fuzzy msgid "The signature is invalid: \n" msgstr "????\n" -#: src/mail.cpp:2167 +#: src/mail.cpp:2128 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2171 +#: src/mail.cpp:2132 #, fuzzy msgid "The signature is expired.\n" msgstr "????\n" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 msgid "The used key" msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 #, fuzzy msgid "The used certificate" msgstr "????" -#: src/mail.cpp:2183 +#: src/mail.cpp:2144 #, fuzzy msgid "is not available." msgstr "???????CRL????\n" -#: src/mail.cpp:2187 +#: src/mail.cpp:2148 msgid "is revoked." msgstr "" -#: src/mail.cpp:2191 +#: src/mail.cpp:2152 msgid "is expired." msgstr "" -#: src/mail.cpp:2195 +#: src/mail.cpp:2156 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2199 src/mail.cpp:2203 +#: src/mail.cpp:2160 src/mail.cpp:2164 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2208 +#: src/mail.cpp:2169 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2214 +#: src/mail.cpp:2175 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2227 +#: src/mail.cpp:2188 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2231 +#: src/mail.cpp:2192 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2236 +#: src/mail.cpp:2197 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2240 +#: src/mail.cpp:2201 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2250 +#: src/mail.cpp:2211 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2254 +#: src/mail.cpp:2215 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2262 +#: src/mail.cpp:2223 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2266 +#: src/mail.cpp:2227 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2277 +#: src/mail.cpp:2238 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2281 +#: src/mail.cpp:2242 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2282 +#: src/mail.cpp:2243 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2286 +#: src/mail.cpp:2247 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2287 +#: src/mail.cpp:2248 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2515 +#: src/mail.cpp:2476 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "????" -#: src/mail.cpp:2517 +#: src/mail.cpp:2478 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -1072,6 +1054,24 @@ msgstr "" msgid "GpgOL: Request confirmed!" msgstr "" +#: src/cryptcontroller.cpp:394 +#, fuzzy +msgid "Resolving recipients..." +msgstr "??????" + +#: src/cryptcontroller.cpp:398 +msgid "Resolving signers..." +msgstr "" + +#: src/cryptcontroller.cpp:994 +#, fuzzy +msgid "Encrypting..." +msgstr "??" + +#: src/cryptcontroller.cpp:998 +msgid "Signing..." +msgstr "" + #, fuzzy #~ msgid "" #~ "Error creating file\n" @@ -1146,9 +1146,6 @@ msgstr "" #~ "\n" #~ "???????????????" -#~ msgid "Encryption" -#~ msgstr "??" - #~ msgid "Fingerprint: " #~ msgstr "???" @@ -1262,9 +1259,6 @@ msgstr "" #~ msgid "Validity" #~ msgstr "???" -#~ msgid "Selected recipients:" -#~ msgstr "??????" - #~ msgid "Recipient which were NOT found" #~ msgstr "???????" diff --git a/po/zh_TW.po b/po/zh_TW.po index 8b9f530..f3e9ff5 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-06 15:25+0100\n" +"POT-Creation-Date: 2018-03-07 10:01+0100\n" "PO-Revision-Date: 2015-08-15 21:58+0800\n" "Last-Translator: Mingye Wang (Arthur2e5) \n" "Language-Team: \n" @@ -168,12 +168,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "????????????" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1691 src/mail.cpp:1762 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "????" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1692 src/mail.cpp:1763 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -410,7 +410,7 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:820 src/mail.cpp:2006 +#: src/mail.cpp:820 src/mail.cpp:1967 #, fuzzy msgid "Encrypted message" msgstr "????" @@ -419,7 +419,7 @@ msgstr "????" msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1095 +#: src/mail.cpp:1097 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" @@ -431,123 +431,105 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1114 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details." -msgstr "" - -#: src/mail.cpp:1129 -msgid "" -"G Suite Sync breaks outgoing signed mails.\n" -"Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" -"\n" -"See: https://dev.gnupg.org/T3545 for details.\n" -"\n" -"Do you want to only encrypt the message?" -msgstr "" - -#: src/mail.cpp:1951 +#: src/mail.cpp:1912 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1955 +#: src/mail.cpp:1916 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1959 +#: src/mail.cpp:1920 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1963 +#: src/mail.cpp:1924 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1967 +#: src/mail.cpp:1928 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1971 +#: src/mail.cpp:1932 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1975 +#: src/mail.cpp:1936 #, fuzzy msgid "Encrypted" msgstr "??" -#: src/mail.cpp:1984 src/mail.cpp:1986 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "" -#: src/mail.cpp:1998 +#: src/mail.cpp:1959 #, fuzzy msgid "Signed and encrypted message" msgstr "????" -#: src/mail.cpp:2002 +#: src/mail.cpp:1963 #, fuzzy msgid "Signed message" msgstr "????" -#: src/mail.cpp:2009 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 #, fuzzy msgid "Insecure message" msgstr "????" -#: src/mail.cpp:2020 src/mail.cpp:2031 +#: src/mail.cpp:1981 src/mail.cpp:1992 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:2023 +#: src/mail.cpp:1984 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2002 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2045 +#: src/mail.cpp:2006 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2049 +#: src/mail.cpp:2010 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2072 +#: src/mail.cpp:2033 #, fuzzy msgid "You signed this message." msgstr "????" -#: src/mail.cpp:2076 +#: src/mail.cpp:2037 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2080 +#: src/mail.cpp:2041 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2054 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2098 +#: src/mail.cpp:2059 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2106 +#: src/mail.cpp:2067 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2116 +#: src/mail.cpp:2077 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -555,142 +537,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2093 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2139 +#: src/mail.cpp:2100 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2153 +#: src/mail.cpp:2114 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2154 +#: src/mail.cpp:2115 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2162 +#: src/mail.cpp:2123 #, fuzzy msgid "The signature is invalid: \n" msgstr "????\n" -#: src/mail.cpp:2167 +#: src/mail.cpp:2128 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2171 +#: src/mail.cpp:2132 #, fuzzy msgid "The signature is expired.\n" msgstr "????\n" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 msgid "The used key" msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2136 #, fuzzy msgid "The used certificate" msgstr "????" -#: src/mail.cpp:2183 +#: src/mail.cpp:2144 #, fuzzy msgid "is not available." msgstr "???????CRL????\n" -#: src/mail.cpp:2187 +#: src/mail.cpp:2148 msgid "is revoked." msgstr "" -#: src/mail.cpp:2191 +#: src/mail.cpp:2152 msgid "is expired." msgstr "" -#: src/mail.cpp:2195 +#: src/mail.cpp:2156 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2199 src/mail.cpp:2203 +#: src/mail.cpp:2160 src/mail.cpp:2164 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2208 +#: src/mail.cpp:2169 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2214 +#: src/mail.cpp:2175 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2227 +#: src/mail.cpp:2188 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2231 +#: src/mail.cpp:2192 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2236 +#: src/mail.cpp:2197 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2240 +#: src/mail.cpp:2201 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2250 +#: src/mail.cpp:2211 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2254 +#: src/mail.cpp:2215 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2262 +#: src/mail.cpp:2223 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2266 +#: src/mail.cpp:2227 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2277 +#: src/mail.cpp:2238 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2281 +#: src/mail.cpp:2242 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2282 +#: src/mail.cpp:2243 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2286 +#: src/mail.cpp:2247 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2287 +#: src/mail.cpp:2248 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2515 +#: src/mail.cpp:2476 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "????" -#: src/mail.cpp:2517 +#: src/mail.cpp:2478 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -1074,6 +1056,24 @@ msgstr "" msgid "GpgOL: Request confirmed!" msgstr "" +#: src/cryptcontroller.cpp:394 +#, fuzzy +msgid "Resolving recipients..." +msgstr "??????" + +#: src/cryptcontroller.cpp:398 +msgid "Resolving signers..." +msgstr "" + +#: src/cryptcontroller.cpp:994 +#, fuzzy +msgid "Encrypting..." +msgstr "??" + +#: src/cryptcontroller.cpp:998 +msgid "Signing..." +msgstr "" + #, fuzzy #~ msgid "" #~ "Error creating file\n" @@ -1148,9 +1148,6 @@ msgstr "" #~ "\n" #~ "???????????????" -#~ msgid "Encryption" -#~ msgstr "??" - #~ msgid "Fingerprint: " #~ msgstr "???" @@ -1264,9 +1261,6 @@ msgstr "" #~ msgid "Validity" #~ msgstr "???" -#~ msgid "Selected recipients:" -#~ msgstr "??????" - #~ msgid "Recipient which were NOT found" #~ msgstr "???????" commit fde43045b717413d5358f3cc06592a83ebef7805 Author: Andre Heinecke Date: Wed Mar 7 10:00:44 2018 +0100 Provide protocol argument to resolver * src/cryptcontroller.cpp (CryptController::resolve_recipients): Use Protocol parameter if S/MIME is disabled. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index b3d39e5..be4f7fb 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -398,6 +398,12 @@ CryptController::resolve_keys () args.push_back (std::string (_("Resolving signers..."))); } + if (!opt.enable_smime) + { + args.push_back (std::string ("--protocol")); + args.push_back (std::string ("pgp")); + } + if (m_sign) { args.push_back (std::string ("--sign")); commit 6a3fc31f4b02388fb6b7e2ca1e8673303632d002 Author: Andre Heinecke Date: Wed Mar 7 08:59:23 2018 +0100 Add cryptcontroller to Potfiles * po/POTFILES.in: Add cryptcontroller. diff --git a/po/POTFILES.in b/po/POTFILES.in index c815cd0..65ff428 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -40,3 +40,4 @@ src/user-events.h src/keycache.cpp src/wks-helper.cpp src/overlay.cpp +src/cryptcontroller.cpp ----------------------------------------------------------------------- Summary of changes: po/POTFILES.in | 1 + po/de.po | 200 +++++++++++++++++++++++++----------------------- po/fr.po | 160 +++++++++++++++++++------------------- po/pt.po | 160 +++++++++++++++++++------------------- po/sv.po | 156 ++++++++++++++++++------------------- po/zh_CN.po | 160 +++++++++++++++++++------------------- po/zh_TW.po | 160 +++++++++++++++++++------------------- src/cryptcontroller.cpp | 6 ++ 8 files changed, 495 insertions(+), 508 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 7 11:30:23 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 07 Mar 2018 11:30:23 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-57-g47d401d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 47d401d159852ea08e90af21d91bb4b93be9000d (commit) from 8a76deb11efd7dadfde6e8e7e69fbcd92577982f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 47d401d159852ea08e90af21d91bb4b93be9000d Author: Ben McGinnes Date: Wed Mar 7 21:27:54 2018 +1100 GPL compatible license for documentation * Added the same, slightly modified GPL based license that is used in other parts of GnuPG. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 1767cd4..2803861 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -212,10 +212,16 @@ Python bindings to programmatically leverage the GPGME library. Copyright ? The GnuPG Project, 2018. -** License TBA +** License GPL compatible :PROPERTIES: :CUSTOM_ID: license :END: - Which license shall we use for these docs, hmm? Gotta be free, so - that rules the GFDL out. I'll pick a CC or something later ... + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 7 13:36:29 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 07 Mar 2018 13:36:29 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-84-g8f1e092 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 8f1e092ad3d711878f8f569877ec7e0eb0860337 (commit) via 2dba229712ba521c30e8a5ad1d208509eb287a26 (commit) via 76e5456dc1f17d60d6a22f718b8197842759fa26 (commit) via 4e96a74833e5b644b5d36b0d11526e524abe21bd (commit) from 18db01ed4915a38622c90c81d16f1b7e812c3917 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8f1e092ad3d711878f8f569877ec7e0eb0860337 Author: Andre Heinecke Date: Wed Mar 7 13:36:07 2018 +0100 Bump Version to 2.1.0 and update NEWS -- diff --git a/NEWS b/NEWS index c885f95..c773c0b 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,14 @@ -Noteworthy changes for version 2.0.7 (unreleased) +Noteworthy changes for version 2.1.0 (unreleased) ================================================= + * Encryption and Signing has been reworked to, again, + work without Kleopatra. + + * WKS Setup is supported in a basic way. + + * PGP/Inline is now fully supported. + + * Many Bugfixes and Parser improvements. Noteworthy changes for version 2.0.6 (2018-01-12) diff --git a/configure.ac b/configure.ac index 009860d..7fb6a92 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ min_automake_version="1.14" # (git tag -s gpgol-k.n.m) and run "./autogen.sh --force". Please # bump the version number immediately *after* the release and do # another commit and push so that the git magic is able to work. -m4_define([mym4_version], [2.0.7]) +m4_define([mym4_version], [2.1.0]) # Below is m4 magic to extract and compute the git revision number, # the decimalized short revision number, a beta version string and a commit 2dba229712ba521c30e8a5ad1d208509eb287a26 Author: Andre Heinecke Date: Wed Mar 7 13:33:01 2018 +0100 Fix protocol selection for autoresolve * src/cryptcontroller.cpp (CryptController::resolve_keys_cached): Handle Protocol. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index 269ca96..da23de4 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -303,16 +303,19 @@ CryptController::resolve_keys_cached() if (m_encrypt) { m_recipients = cache->getEncryptionKeys((const char **)m_recipient_addrs, GpgME::OpenPGP); + m_proto = GpgME::OpenPGP; if (m_recipients.empty() && opt.enable_smime) { m_recipients = cache->getEncryptionKeys((const char **)m_recipient_addrs, GpgME::CMS); fallbackToSMIME = true; + m_proto = GpgME::CMS; } if (m_recipients.empty()) { log_debug ("%s:%s: Failed to resolve keys through cache", SRCNAME, __func__); + m_proto = GpgME::UnknownProtocol; return 1; } } @@ -323,17 +326,20 @@ CryptController::resolve_keys_cached() { m_signer_key = cache->getSigningKey (m_mail->get_cached_sender ().c_str (), GpgME::OpenPGP); + m_proto = GpgME::OpenPGP; } if (m_signer_key.isNull() && opt.enable_smime) { m_signer_key = cache->getSigningKey (m_mail->get_cached_sender ().c_str (), GpgME::CMS); + m_proto = GpgME::CMS; } if (m_signer_key.isNull()) { log_debug ("%s:%s: Failed to resolve signer key through cache", SRCNAME, __func__); m_recipients.clear(); + m_proto = GpgME::UnknownProtocol; return 1; } } commit 76e5456dc1f17d60d6a22f718b8197842759fa26 Author: Andre Heinecke Date: Wed Mar 7 13:31:54 2018 +0100 Improve error handling and fix encoding * src/cryptcontroller.cpp: Take care that command line args are not encoded to utf8. * src/mail.cpp (do_crypt): Inform user when crypto failed. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index be4f7fb..269ca96 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -34,14 +34,7 @@ #include #include -#ifdef HAVE_W32_SYSTEM #include "common.h" -/* We use UTF-8 internally. */ -#undef _ -# define _(a) utf8_gettext (a) -#else -# define _(a) a -#endif #include @@ -286,9 +279,9 @@ CryptController::parse_output (GpgME::Data &resolverOutput) if (m_sign && sigFpr.empty()) { - log_error ("%s:%s: Sign requested but no signing fingerprint", + log_error ("%s:%s: Sign requested but no signing fingerprint - sending unsigned", SRCNAME, __func__); - return -1; + m_sign = false; } if (m_encrypt && !recpFprs.size()) { @@ -487,7 +480,8 @@ CryptController::resolve_keys () SRCNAME, __func__, err.code(), err.asString()); } - if (parse_output (mystdout)) + int ret = parse_output (mystdout); + if (ret == -1) { log_debug ("%s:%s: Failed to parse / resolve keys.", SRCNAME, __func__); @@ -496,7 +490,7 @@ CryptController::resolve_keys () return -1; } - return 0; + return ret; } int @@ -508,10 +502,20 @@ CryptController::do_crypto () /* Start a WKS check if necessary. */ WKSHelper::instance()->start_check (m_mail->get_cached_sender ()); - if (resolve_keys ()) + int ret = resolve_keys (); + if (ret == -1) { + //error log_debug ("%s:%s: Failure to resolve keys.", SRCNAME, __func__); + gpgol_message_box (nullptr, + utf8_gettext ("Failure to resolve keys."), + utf8_gettext ("GpgOL"), MB_OK); + return ret; + } + if (ret == -2) + { + // Cancel return -2; } @@ -529,6 +533,9 @@ CryptController::do_crypto () { log_error ("%s:%s: Failure to create context.", SRCNAME, __func__); + gpgol_message_box (nullptr, + "Failure to create context.", + utf8_gettext ("GpgOL"), MB_OK); return -1; } if (!m_signer_key.isNull()) @@ -995,7 +1002,7 @@ CryptController::start_crypto_overlay () } else if (m_sign) { - text =_("Signing..."); + text = _("Signing..."); } m_overlay = std::unique_ptr (new Overlay (wid, text)); } diff --git a/src/mail.cpp b/src/mail.cpp index 34ef2a1..7d30895 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -738,6 +738,12 @@ do_crypt (LPVOID arg) mail->set_window_enabled (true); + if (rc == -1) + { + gpgol_message_box (nullptr, + "Crypto failed", + _("GpgOL"), MB_OK); + } if (rc) { log_debug ("%s:%s: crypto failed for: %p with: %i", commit 4e96a74833e5b644b5d36b0d11526e524abe21bd Author: Andre Heinecke Date: Wed Mar 7 13:30:14 2018 +0100 Fix deadlock in Outlook 2010 * src/mail.cpp (do_crypt): In Outlook 2010 sending destroys the Mail. So we may not hold the dtor lock for the send call. diff --git a/src/mail.cpp b/src/mail.cpp index aba08d3..34ef2a1 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -751,6 +751,8 @@ do_crypt (LPVOID arg) if (!mail->is_inline_response ()) { mail->set_crypt_state (Mail::NeedsUpdateInOOM); + gpgrt_lock_unlock (&dtor_lock); + // This deletes the Mail in Outlook 2010 do_in_ui_thread (CRYPTO_DONE, arg); } else @@ -758,6 +760,7 @@ do_crypt (LPVOID arg) mail->set_crypt_state (Mail::NeedsUpdateInMAPI); mail->update_crypt_mapi (); mail->set_crypt_state (Mail::NeedsUpdateInOOM); + gpgrt_lock_unlock (&dtor_lock); } /* This works around a bug in pinentry that it might bring the wrong window to front. So after encryption / @@ -766,7 +769,6 @@ do_crypt (LPVOID arg) See GnuPG-Bug-Id: T3732 */ do_in_ui_thread_async (BRING_TO_FRONT, nullptr); - gpgrt_lock_unlock (&dtor_lock); return 0; } ----------------------------------------------------------------------- Summary of changes: NEWS | 10 +++++++++- configure.ac | 2 +- src/cryptcontroller.cpp | 39 ++++++++++++++++++++++++++------------- src/mail.cpp | 10 +++++++++- 4 files changed, 45 insertions(+), 16 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 8 05:45:37 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 08 Mar 2018 05:45:37 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-59-ga98f2c5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via a98f2c556fe6e33a9cd38279e64e4b09f05cc675 (commit) via e8adab68f8c0cd865ff220f06dfaff7fe183e8a1 (commit) from 47d401d159852ea08e90af21d91bb4b93be9000d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a98f2c556fe6e33a9cd38279e64e4b09f05cc675 Author: Ben McGinnes Date: Thu Mar 8 15:23:05 2018 +1100 doc-howto: fundamental aspects of GPGME vs Python * Added a section for those pythonistas who are too used to web programming. Stressed that it's not simply not RESTful, it's not even REST-like. * Letting me move on to drawing a very loose parallel between a session and a context. The differences should become obvious in the subsequent sections. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 2803861..e7dc53d 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1,5 +1,4 @@ #+TITLE: GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English) - #+LATEX_COMPILER: xelatex #+LATEX_CLASS: article #+LATEX_CLASS_OPTIONS: [12pt] @@ -200,6 +199,61 @@ Python bindings to programmatically leverage the GPGME library. source. +* Fundamentals + :PROPERTIES: + :CUSTOM_ID: howto-fund-a-mental + :END: + + Before we can get to the fun stuff, there are a few matters + regarding GPGME's design which hold true whether you're dealing with + the C code directly or these Python bindings. + +** No REST + :PROPERTIES: + :CUSTOM_ID: no-rest-for-the-wicked + :END: + + The first part of which is or will be fairly blatantly obvious upon + viewing the first example, but it's worth reiterating anyway. That + being that this API is /*not*/ a REST API. Nor indeed could it + ever be one. + + Most, if not all, Python programmers (and not just Python + programmers) know how easy it is to work with a RESTful API. In + fact they've become so popular that many other APIs attempt to + emulate REST-like behaviour as much as they are able. Right down + to the use of JSON formatted output to facilitate the use of their + API without having to retrain developers. + + This API does not do that. It would not be able to do that and + also provide access to the entire C API on which it's built. It + does, however, provide a very pythonic interface on top of the + direct bindings and it's this pythonic layer with which this HOWTO + deals with. + +** Context + :PROPERTIES: + :CUSTOM_ID: howto-get-context + :END: + + One of the reasons which prevents this API from being RESTful is + that most operations require more than one instruction to the API + to perform the task. Sure, there are certain functions which can + be performed simultaneously, particularly if the result known or + strongly anticipated (e.g selecting and encrypting to a key known + to be in the public keybox). + + There are many more, however, which cannot be manipulated so + readily: they must be performed in a specific sequence and the + result of one operation has a direct bearing on the outcome of + subsequent operations. Not merely by generating an error either. + + When dealing with this type of persistant state on the web, full of + both the RESTful and REST-like, it's most commonly referred to as a + session. In GPGME, however, it is called a context and every + operation type has one. + + * Copyright and Licensing :PROPERTIES: :CUSTOM_ID: copyright-and-license commit e8adab68f8c0cd865ff220f06dfaff7fe183e8a1 Author: Ben McGinnes Date: Thu Mar 8 14:13:00 2018 +1100 doc: Added multiple TODOs for inclusion in the HOWTO * Some instructions to include are fairly obvious; as with encryption, decryption and signature verification. * Some are a little less obvious. * This includes the requests received to specifically include subkey management (adding and revoking subkeys on a primary key that's being retained. * Added the UID equivalents to the list, as well as key selection matters (and may or may not include something for handling group lines since that involves wrapping a CLI binary). * Key control documentation and examples requested by Mike Ingle of confidantmail.org. diff --git a/lang/python/docs/TODO.org b/lang/python/docs/TODO.org index 4e067df..897c617 100644 --- a/lang/python/docs/TODO.org +++ b/lang/python/docs/TODO.org @@ -28,11 +28,13 @@ to produce reST versions via Pandoc and DITA XML can be reached through converting to either Markdown or XHTML first. -** TODO Documentation HOWTO +** STARTED Documentation HOWTO :PROPERTIES: :CUSTOM_ID: todo-docs-howto :END: + - State "STARTED" from "TODO" [2018-03-08 Thu 13:59] \\ + Started yesterday. Write a HOWTO style guide for the current Python bindings. *** DONE Start python bindings HOWTO @@ -41,6 +43,46 @@ :CUSTOM_ID: howto-start :END: +*** TODO Include certain specific instructions in the HOWTO + :PROPERTIES: + :CUSTOM_ID: howto-requests + :END: + + Some functions can be worked out from the handful of examples + available, but many more can't and I've already begun receiving + requests for certain functions to be explained. + +**** TODO Standard scenarios + :PROPERTIES: + :CUSTOM_ID: howto-the-basics + :END: + + What everyone expects: encryption, decryption, signing and verifying. + +**** TODO Key control + :PROPERTIES: + :CUSTOM_ID: howto-key-control + :END: + + Generating keys, adding subkeys, revoking subkeys (and keeping + the cert key), adding and revoking UIDs, signing/certifying keys. + +**** TODO Key control + :PROPERTIES: + :CUSTOM_ID: howto-key-selection + :END: + + Selecting keys to encrypt to or manipulate in other ways (e.g. as + with key control or the basics). + +**** TODO S/MIME + :PROPERTIES: + :CUSTOM_ID: howto-s-mime + :END: + + Eventually add some of this, but it the OpenPGP details are far + more important at the moment. + ** TODO Documentation SWIG :PROPERTIES: :CUSTOM_ID: todo-docs-swig ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 56 ++++++++++++++++++++++++++++++++- lang/python/docs/TODO.org | 44 +++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 8 06:12:30 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 08 Mar 2018 06:12:30 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-9-g334b948 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 334b94898112b5d2c7c97ff0496b9a67b3de0d26 (commit) from 7e40c5efbea65c7804b06d62dfcd7f991557bfaa (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 334b94898112b5d2c7c97ff0496b9a67b3de0d26 Author: NIIBE Yutaka Date: Thu Mar 8 14:08:51 2018 +0900 gpg: Fix build on Windows. -- WIN32_LEAN_AND_MEAN is required to avoid definitions of grp1, grp2, and grp3 in dlgs.h, which is included by windows.h. Fixes-commit: fd595c9d3642dba437fbe0f6e25d7aaaae095f94 Signed-off-by: NIIBE Yutaka diff --git a/g10/gpg.h b/g10/gpg.h index 9b8b77c..1bad551 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -24,6 +24,10 @@ correct value and may be of advantage if we ever have to do special things. */ +#ifdef HAVE_W32_SYSTEM +# define WIN32_LEAN_AND_MEAN 1 +#endif + #ifdef GPG_ERR_SOURCE_DEFAULT #error GPG_ERR_SOURCE_DEFAULT already defined #endif diff --git a/g10/misc.c b/g10/misc.c index 77c8f26..9780969 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -42,6 +42,7 @@ #include #include #ifdef HAVE_WINSOCK2_H +# define WIN32_LEAN_AND_MEAN 1 # include #endif #include ----------------------------------------------------------------------- Summary of changes: g10/gpg.h | 4 ++++ g10/misc.c | 1 + 2 files changed, 5 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 8 09:02:04 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 08 Mar 2018 09:02:04 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-10-gf8b8b6a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via f8b8b6aac2ca1cb34d7a346aee1d874e7650557b (commit) from 334b94898112b5d2c7c97ff0496b9a67b3de0d26 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f8b8b6aac2ca1cb34d7a346aee1d874e7650557b Author: NIIBE Yutaka Date: Thu Mar 8 16:51:51 2018 +0900 scd: Fix status check when using PC/SC. * scd/apdu.c (struct reader_table_s): Add field of current_state. (new_reader_slot): Initialize current_state. (pcsc_get_status): Keep the status in READER_TABLE array. Return SW_HOST_NO_READER when PCSC_STATE_CHANGED. * scd/scdaemon.c (handle_connections): Silence a warning. -- To detect some change of card status, including suspend/resume possibly, SCardGetStatusChange should be used keeping the dwCurrentState field. This change could improve situation for suspend/resume with Yubikey on Windows. Even not, this is doing the Right Thing. Signed-off-by: NIIBE Yutaka diff --git a/scd/apdu.c b/scd/apdu.c index c50afbd..6758e69 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -119,6 +119,7 @@ struct reader_table_s { pcsc_dword_t modify_ioctl; int pinmin; int pinmax; + pcsc_dword_t current_state; } pcsc; #ifdef USE_G10CODE_RAPDU struct { @@ -453,6 +454,7 @@ new_reader_slot (void) reader_table[reader].pcsc.modify_ioctl = 0; reader_table[reader].pcsc.pinmin = -1; reader_table[reader].pcsc.pinmax = -1; + reader_table[reader].pcsc.current_state = PCSC_STATE_UNAWARE; return reader; } @@ -652,12 +654,12 @@ pcsc_get_status (int slot, unsigned int *status, int on_wire) (void)on_wire; memset (rdrstates, 0, sizeof *rdrstates); rdrstates[0].reader = reader_table[slot].rdrname; - rdrstates[0].current_state = PCSC_STATE_UNAWARE; + rdrstates[0].current_state = reader_table[slot].pcsc.current_state; err = pcsc_get_status_change (reader_table[slot].pcsc.context, 0, rdrstates, 1); if (err == PCSC_E_TIMEOUT) - err = 0; /* Timeout is no error error here. */ + err = 0; /* Timeout is no error here. */ if (err) { log_error ("pcsc_get_status_change failed: %s (0x%lx)\n", @@ -665,6 +667,9 @@ pcsc_get_status (int slot, unsigned int *status, int on_wire) return pcsc_error_to_sw (err); } + reader_table[slot].pcsc.current_state = + (rdrstates[0].event_state & ~PCSC_STATE_CHANGED); + /* log_debug */ /* ("pcsc_get_status_change: %s%s%s%s%s%s%s%s%s%s\n", */ /* (rdrstates[0].event_state & PCSC_STATE_IGNORE)? " ignore":"", */ @@ -701,7 +706,11 @@ pcsc_get_status (int slot, unsigned int *status, int on_wire) *status |= APDU_CARD_USABLE; #endif - return 0; + if (!on_wire && (rdrstates[0].event_state & PCSC_STATE_CHANGED)) + /* Event like sleep/resume occurs, which requires RESET. */ + return SW_HOST_NO_READER; + else + return 0; } diff --git a/scd/scdaemon.c b/scd/scdaemon.c index cebeea9..91b5599 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -1348,6 +1348,8 @@ handle_connections (int listen_fd) FD_SET (pipe_fd[0], &read_fdset); if (max_fd < pipe_fd[0]) max_fd = pipe_fd[0]; +#else + (void)max_fd; #endif #ifndef HAVE_W32_SYSTEM ----------------------------------------------------------------------- Summary of changes: scd/apdu.c | 15 ++++++++++++--- scd/scdaemon.c | 2 ++ 2 files changed, 14 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 8 23:02:41 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 08 Mar 2018 23:02:41 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-50-ge846c3d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via e846c3daeeb4e7092169cdb7bf4f55e0b105aac3 (commit) via 6849924ffbd48ba3f9d32b4a59a02e1d2083fc19 (commit) from 75f5e6e6672a1bbd16b7680313c0f96796c219bd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e846c3daeeb4e7092169cdb7bf4f55e0b105aac3 Author: Ben McGinnes Date: Fri Mar 9 09:01:53 2018 +1100 docs: TODO * Removed WS. diff --git a/TODO b/TODO index 17a5f8c..5f03fb6 100644 --- a/TODO +++ b/TODO @@ -389,7 +389,7 @@ Hey Emacs, this is -*- org -*- mode! :END: - State "CANCELLED" from "TODO" [2018-03-09 Fri 08:24] \\ WON'T FIX. - + Also, there is no rungpg.c file in GPGME (or in GPG or most, if not all of the rest of the libs and packages; I suspect there hasn't been for a very long time). commit 6849924ffbd48ba3f9d32b4a59a02e1d2083fc19 Author: Ben McGinnes Date: Fri Mar 9 08:36:12 2018 +1100 doc: TODO list update * Closed off a few ancient items and added recommendation to others to use the dev.gnupg.org site for real bugs/features updates. * See also this statement on the gnupg-devel list regarding this file: https://lists.gnupg.org/pipermail/gnupg-devel/2018-March/033499.html diff --git a/TODO b/TODO index d02a0d2..17a5f8c 100644 --- a/TODO +++ b/TODO @@ -1,13 +1,29 @@ +#+TITLE: TODO List Hey Emacs, this is -*- org -*- mode! -* Document all the new stuff. +* IMPORTANT! + :PROPERTIES: + :CUSTOM_ID: dev-gnupg-org + :END: + + There was a nine year gap (2009 to 2018) between edits of this file, + so it is likely that much of the old information in it is wrong or + no longer applicable. + + Bugs, feature requests and other development related work will be + tracked through the [[https://dev.gnupg.org/][dev.gnupg.org]] site. + + +* TODO Document all the new stuff. :PROPERTIES: :CUSTOM_ID: more-docs-is-better :END: -** TODO Fix this TODO list. + +** STARTED Fix this TODO list. :PROPERTIES: :CUSTOM_ID: fix-todo :END: + - State "STARTED" from "TODO" [2018-03-09 Fri 08:31] Clean up the current TODO list. Include properties as relevant (so if someone does make a PDF or HTML version the TOC will work). @@ -51,10 +67,13 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: pre-release :END: -** Some gpg tests fail with gpg 1.3.4-cvs (gpg/t-keylist-sig) +** CANCELLED Some gpg tests fail with gpg 1.3.4-cvs (gpg/t-keylist-sig) + CLOSED: [2018-03-09 Fri 08:16] :PROPERTIES: :CUSTOM_ID: gpg-1-3-4-really :END: + - State "CANCELLED" from "TODO" [2018-03-09 Fri 08:16] \\ + WON'T FIX ? too old or no longer applies. The test is currently disabled there and in gpg/t-import. ** When gpg supports it, write binary subpackets directly, :PROPERTIES: @@ -335,29 +354,45 @@ Hey Emacs, this is -*- org -*- mode! :PROPERTIES: :CUSTOM_ID: gpg-breakage :END: -** gpg 1.4.2 lacks error reporting if sign/encrypt with revoked key. +** CANCELLED gpg 1.4.2 lacks error reporting if sign/encrypt with revoked key. + CLOSED: [2018-03-09 Fri 08:19] :PROPERTIES: :CUSTOM_ID: gpg-classic-lacks-stuff :END: -** gpg 1.4.2 does crappy error reporting (namely none at all) when + - State "CANCELLED" from "TODO" [2018-03-09 Fri 08:19] \\ + WON'T FIX. +** CANCELLED gpg 1.4.2 does crappy error reporting (namely none at all) when + CLOSED: [2018-03-09 Fri 08:20] :PROPERTIES: :CUSTOM_ID: gpg-classic-problems-but-do-we-care :END: + - State "CANCELLED" from "TODO" [2018-03-09 Fri 08:20] \\ + WON'T FIX. 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 +** DONE Without agent and with wrong passphrase, gpg 1.4.2 enters into an + CLOSED: [2018-03-09 Fri 08:20] :PROPERTIES: :CUSTOM_ID: recursive-gpg-classic :END: + - State "DONE" from "TODO" [2018-03-09 Fri 08:20] \\ + Must have been fixed in a subsequent release. infinite loop. -** Use correct argv[0] +** CANCELLED Use correct argv[0] + CLOSED: [2018-03-09 Fri 08:24] :PROPERTIES: :CUSTOM_ID: correct-argv :END: + - State "CANCELLED" from "TODO" [2018-03-09 Fri 08:24] \\ + WON'T FIX. + + Also, there is no rungpg.c file in GPGME (or in GPG or most, if not + all of the rest of the libs and packages; I suspect there hasn't been + for a very long time). In rungpg.c:build_argv we use argv[argc] = strdup ("gpg"); /* argv[0] */ This should be changed to take the real file name used in account. ----------------------------------------------------------------------- Summary of changes: TODO | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 8 23:33:26 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 08 Mar 2018 23:33:26 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-65-gf685cda Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via f685cda281c6148072e8a6cd139c990cb041ea3d (commit) via e846c3daeeb4e7092169cdb7bf4f55e0b105aac3 (commit) via 6849924ffbd48ba3f9d32b4a59a02e1d2083fc19 (commit) via fa4927146b68dd045903285f1c45fb64deb2e361 (commit) via c767a4a3590bd8a224d0268746df443942cb28c2 (commit) via 75463d589522cba427f9e5a3a408192ffad8bb21 (commit) from a98f2c556fe6e33a9cd38279e64e4b09f05cc675 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f685cda281c6148072e8a6cd139c990cb041ea3d Merge: fa49271 e846c3d Author: Ben McGinnes Date: Fri Mar 9 09:31:44 2018 +1100 Merge branch 'master' of ssh+git://playfair.gnupg.org/git/gpgme into ben/docs/2018-03 * Fixed conflicts with TODO. diff --cc TODO index a431651,5f03fb6..a915ed7 --- a/TODO +++ b/TODO @@@ -1,5 -1,38 +1,61 @@@ + #+TITLE: TODO List Hey Emacs, this is -*- org -*- mode! + * IMPORTANT! + :PROPERTIES: + :CUSTOM_ID: dev-gnupg-org + :END: + + There was a nine year gap (2009 to 2018) between edits of this file, + so it is likely that much of the old information in it is wrong or + no longer applicable. + + Bugs, feature requests and other development related work will be + tracked through the [[https://dev.gnupg.org/][dev.gnupg.org]] site. + + -* TODO Document all the new stuff. ++* Documentation + :PROPERTIES: - :CUSTOM_ID: more-docs-is-better ++ :CUSTOM_ID: documentation + :END: + -** STARTED Fix this TODO list. ++** Document all the new stuff. + :PROPERTIES: - :CUSTOM_ID: fix-todo ++ :CUSTOM_ID: more-docs-is-better + :END: - - State "STARTED" from "TODO" [2018-03-09 Fri 08:31] - Clean up the current TODO list. Include properties as relevant (so - if someone does make a PDF or HTML version the TOC will work). + - Also check ans see if some of these ancient things can be removed - (e.g. do we really need to fix things that were broken in GPG - 1.3.x? I'm thinking not so much). ++*** TODO Fix this TODO list. ++ :PROPERTIES: ++ :CUSTOM_ID: fix-todo ++ :END: ++ ++ Clean up the current TODO list. Include properties as relevant (so ++ if someone does make a PDF or HTML version the TOC will work). ++ ++ Also check ans see if some of these ancient things can be removed ++ (e.g. do we really need to fix things that were broken in GPG ++ 1.3.x? I'm thinking not so much). ++ ++**** DONE fix TODO items ++ CLOSED: [2018-03-04 Sun 08:55] ++ :PROPERTIES: ++ :CUSTOM_ID: fix-todo-items ++ :END: ++ ++ Adjust todo items so each can now be referenced by custom-id and ++ checked off as necessary. + ++** TODO Document validity and trust issues. ++ :PROPERTIES: ++ :CUSTOM_ID: valid-trust-issues ++ :END: ++ ++** In gpgme.texi: Register callbacks under the right letter in the index. ++ :PROPERTIES: ++ :CUSTOM_ID: gpgme-texi ++ :END: + + * Fix the remaining UI Server problems: :PROPERTIES: :CUSTOM_ID: ui-server-fix @@@ -30,109 -63,112 +86,137 @@@ :END: Right now we block reading the next line with assuan. ++ * Before release: :PROPERTIES: :CUSTOM_ID: pre-release :END: - ** Some gpg tests fail with gpg 1.3.4-cvs (gpg/t-keylist-sig) ++ + ** CANCELLED Some gpg tests fail with gpg 1.3.4-cvs (gpg/t-keylist-sig) + CLOSED: [2018-03-09 Fri 08:16] :PROPERTIES: :CUSTOM_ID: gpg-1-3-4-really :END: + - State "CANCELLED" from "TODO" [2018-03-09 Fri 08:16] \\ + WON'T FIX ? too old or no longer applies. The test is currently disabled there and in gpg/t-import. ++ ** When gpg supports it, write binary subpackets directly, :PROPERTIES: :CUSTOM_ID: binary-subpackets :END: and parse SUBPACKET status lines. ++ * ABI's to break: :PROPERTIES: :CUSTOM_ID: abi-breakage-apparently-on-purpose :END: ++ ** Old opassuan interface. :PROPERTIES: :CUSTOM_ID: old-opassuan :END: ++ ** Implementation: Remove support for old style error codes in :PROPERTIES: :CUSTOM_ID: remove-old-error-codes :END: conversion.c::_gpgme_map_gnupg_error. ++ ** gpgme_edit_cb_t: Add "processed" return argument :PROPERTIES: :CUSTOM_ID: add-processed-return :END: (see edit.c::command_handler). ++ ** I/O and User Data could be made extensible. But this can be done :PROPERTIES: :CUSTOM_ID: add-io-user-data :END: without breaking the ABI hopefully. ++ ** All enums should be replaced by ints and simple macros for :PROPERTIES: :CUSTOM_ID: enums-should-be-ints :END: maximum compatibility. ++ ** Compatibility interfaces that can be removed in future versions: :PROPERTIES: :CUSTOM_ID: compat-interfaces-to-go :END: ++ *** gpgme_data_new_from_filepart :PROPERTIES: :CUSTOM_ID: gpgme-data-new-from-filepart :END: ++ *** gpgme_data_new_from_file :PROPERTIES: :CUSTOM_ID: gpgme-data-new-from-file :END: ++ *** gpgme_data_new_with_read_cb :PROPERTIES: :CUSTOM_ID: gpgme-data-new-with-read-cb :END: ++ *** gpgme_data_rewind :PROPERTIES: :CUSTOM_ID: gpgme-data-rewind :END: ++ *** gpgme_op_import_ext :PROPERTIES: :CUSTOM_ID: gpgme-op-import-ext :END: ++ *** gpgme_get_sig_key :PROPERTIES: :CUSTOM_ID: gpgme-get-sig-key :END: ++ *** gpgme_get_sig_ulong_attr :PROPERTIES: :CUSTOM_ID: gpgme-get-sig-ulong-attr :END: ++ *** gpgme_get_sig_string_attr :PROPERTIES: :CUSTOM_ID: gpgme-get-sig-string-attr :END: ++ *** GPGME_SIG_STAT_* :PROPERTIES: :CUSTOM_ID: gpgme-sig-stat :END: ++ *** gpgme_get_sig_status :PROPERTIES: :CUSTOM_ID: gpgme-get-sig-status :END: ++ *** gpgme_trust_item_release :PROPERTIES: :CUSTOM_ID: gpgme-trust-item-release :END: ++ *** gpgme_trust_item_get_string_attr :PROPERTIES: :CUSTOM_ID: gpgme-trust-item-get-string-attr :END: ++ *** gpgme_trust_item_get_ulong_attr :PROPERTIES: :CUSTOM_ID: gpgme-trust-item-get-ulong-attr :END: ++ *** gpgme_attr_t :PROPERTIES: :CUSTOM_ID: gpgme-attr-t :END: ++ *** All Gpgme* typedefs. :PROPERTIES: :CUSTOM_ID: all-gpgme-typedefs @@@ -143,20 -179,20 +227,24 @@@ :PROPERTIES: :CUSTOM_ID: threads :END: ++ ** When GNU Pth supports sendmsg/recvmsg, wrap them properly. :PROPERTIES: :CUSTOM_ID: wrap-oth :END: ++ ** Without timegm (3) support our ISO time parser is not thread safe. :PROPERTIES: :CUSTOM_ID: time-threads :END: There is a configure time warning, though. ++ * New features: :PROPERTIES: :CUSTOM_ID: new-features :END: ++ ** Flow control for data objects. :PROPERTIES: :CUSTOM_ID: flow-control-is-not-a-euphemism-for-an-s-bend @@@ -169,11 -205,11 +257,13 @@@ respective event loop. or (B) a way for gpgme data objects to be associated with a waitable object, that can be registered with the user event loop. Neither is particularly simple. ++ ** Extended notation support. When gpg supports arbitrary binary :PROPERTIES: :CUSTOM_ID: extended-notation :END: notation data, provide a user interface for that. ++ ** notification system :PROPERTIES: :CUSTOM_ID: notification-system @@@ -200,25 -236,25 +290,30 @@@ :PROPERTIES: :CUSTOM_ID: stat-data :END: ++ ** Implement support for photo ids. :PROPERTIES: :CUSTOM_ID: photo-id :END: ++ ** Allow selection of subkeys :PROPERTIES: :CUSTOM_ID: subkey-selection :END: ++ ** Allow to return time stamps in ISO format :PROPERTIES: :CUSTOM_ID: iso-format-datetime :END: -- This allows us to handle years later than 2037 properly. With the -- time_t interface they are all mapped to 2037-12-31 ++ This allows us to handle years later than 2037 properly. With the ++ time_t interface they are all mapped to 2037-12-31 ++ ** New features requested by our dear users, but rejected or left for :PROPERTIES: :CUSTOM_ID: feature-requests :END: later consideration: ++ *** Allow to export secret keys. :PROPERTIES: :CUSTOM_ID: export-secret-keys @@@ -226,6 -262,6 +321,7 @@@ Rejected because this is conceptually flawed. Secret keys on a smart card can not be exported, for example. May eventually e supproted with a keywrapping system. ++ *** Selecting the key ring, setting the version or comment in output. :PROPERTIES: :CUSTOM_ID: select-keyring-version @@@ -233,61 -269,46 +329,23 @@@ Rejected because the naive implementation is engine specific, the configuration is part of the engine's configuration or readily worked around in a different way ++ *** Selecting the symmetric cipher. :PROPERTIES: :CUSTOM_ID: symmetric-cipher-selection :END: ++ *** Exchanging keys with key servers. :PROPERTIES: :CUSTOM_ID: key-server-exchange :END: --* Documentation -- :PROPERTIES: -- :CUSTOM_ID: documentation -- :END: - --** TODO Document validity and trust issues. -- :PROPERTIES: -- :CUSTOM_ID: valid-trust-issues -- :END: - --** In gpgme.texi: Register callbacks under the right letter in the index. -- :PROPERTIES: -- :CUSTOM_ID: gpgme-texi -- :END: - - ** Document all the new stuff. -** TODO Update TODO file -- :PROPERTIES: - :CUSTOM_ID: more-docs-is-better - :CUSTOM_ID: todo-update -- :END: -- - *** TODO Fix this TODO list. -*** DONE fix TODO items - CLOSED: [2018-03-04 Sun 08:55] -- :PROPERTIES: - :CUSTOM_ID: fix-todo - :CUSTOM_ID: fix-todo-items -- :END: - - Clean up the current TODO list. Include properties as relevant (so - if someone does make a PDF or HTML version the TOC will work). - - Also check ans see if some of these ancient things can be removed - (e.g. do we really need to fix things that were broken in GPG - 1.3.x? I'm thinking not so much). - - **** DONE fix TODO items - CLOSED: [2018-03-04 Sun 08:55] - :PROPERTIES: - :CUSTOM_ID: fix-todo-items - :END: -- - Adjust todo items so each can now be referenced by custom-id and - checked off as necessary. - Adjust todo items so each can now be referenced by custom-id and - checked off as necessary. -- * Engines :PROPERTIES: :CUSTOM_ID: engines :END: ++ ** Do not create/destroy engines, but create engine and then reset it. :PROPERTIES: :CUSTOM_ID: reset-engine-is-not-quite-just-ignition @@@ -300,26 -321,26 +358,31 @@@ Note that we need support in gpgsm to set include-certs to default as RESET does not reset it, also for no_encrypt_to and probably other options. ++ ** Optimize the case where a data object has an underlying fd we can pass :PROPERTIES: :CUSTOM_ID: optimus-data-cousin-of-optimus-prime :END: directly to the engine. This will be automatic with socket I/O and descriptor passing. ++ ** Move code common to all engines up from gpg to engine. :PROPERTIES: :CUSTOM_ID: move-code-common-to-engines-out-of-gpg :END: ++ ** engine operations can return General Error on unknown protocol :PROPERTIES: :CUSTOM_ID: general-error-looking-to-be-court-martialled :END: (it's an internal error, as select_protocol checks already). ++ ** When server mode is implemented properly, more care has to be taken to :PROPERTIES: :CUSTOM_ID: server-mode :END: release all resources on error (for example to free assuan_cmd). ++ ** op_import_keys and op_export_keys have a limit in the number of keys. :PROPERTIES: :CUSTOM_ID: import-export-problems @@@ -333,11 -354,15 +396,17 @@@ :PROPERTIES: :CUSTOM_ID: gpg-breakage :END: - ** gpg 1.4.2 lacks error reporting if sign/encrypt with revoked key. ++ + ** CANCELLED gpg 1.4.2 lacks error reporting if sign/encrypt with revoked key. + CLOSED: [2018-03-09 Fri 08:19] :PROPERTIES: :CUSTOM_ID: gpg-classic-lacks-stuff :END: - ** gpg 1.4.2 does crappy error reporting (namely none at all) when + - State "CANCELLED" from "TODO" [2018-03-09 Fri 08:19] \\ + WON'T FIX. ++ + ** CANCELLED gpg 1.4.2 does crappy error reporting (namely none at all) when + CLOSED: [2018-03-09 Fri 08:20] :PROPERTIES: :CUSTOM_ID: gpg-classic-problems-but-do-we-care :END: @@@ -347,12 -374,16 +418,18 @@@ 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 ++ + ** DONE Without agent and with wrong passphrase, gpg 1.4.2 enters into an + CLOSED: [2018-03-09 Fri 08:20] :PROPERTIES: :CUSTOM_ID: recursive-gpg-classic :END: + - State "DONE" from "TODO" [2018-03-09 Fri 08:20] \\ + Must have been fixed in a subsequent release. infinite loop. - ** Use correct argv[0] ++ + ** CANCELLED Use correct argv[0] + CLOSED: [2018-03-09 Fri 08:24] :PROPERTIES: :CUSTOM_ID: correct-argv :END: @@@ -365,71 -402,71 +448,86 @@@ :PROPERTIES: :CUSTOM_ID: operations-are-not-surgical :END: ++ ** Include cert values -2, -1, 0 and 1 should be defined as macros. :PROPERTIES: :CUSTOM_ID: certified-macros :END: ++ ** If an operation failed, make sure that the result functions don't return :PROPERTIES: :CUSTOM_ID: operation-failure :END: corrupt partial information. !!! NOTE: The EOF status handler is not called in this case !!! ++ ** Verify must not fail on NODATA premature if auto-key-retrieval failed. :PROPERTIES: :CUSTOM_ID: autobot-key-retrieval :END: It should not fail silently if it knows there is an error. !!! ++ ** All operations: Better error reporting. !! :PROPERTIES: :CUSTOM_ID: better-reporting-not-like-fox-news :END: ++ ** Export status handler need much more work. !!! :PROPERTIES: :CUSTOM_ID: export-status-handler :END: ++ ** Import should return a useful error when one happened. :PROPERTIES: :CUSTOM_ID: import-useful-stuff-even-wrong-stuff :END: ++ *** Import does not take notice of NODATA status report. :PROPERTIES: :CUSTOM_ID: import-no-data :END: ++ *** When GPGSM does issue IMPORT_OK status reports, make sure to check for :PROPERTIES: :CUSTOM_ID: gpgsm-import-ok :END: them in tests/gpgs m/t-import.c. ++ ** Verify can include info about version/algo/class, but currently :PROPERTIES: :CUSTOM_ID: verify-class :END: this is only available for gpg, not gpgsm. ++ ** Return ENC_TO output in verify result. Again, this is not available :PROPERTIES: :CUSTOM_ID: return-to-enc :END: for gpgsm. ++ ** Genkey should return something more useful than General_Error. :PROPERTIES: :CUSTOM_ID: general-key-assumed-command-from-general-error :END: ++ ** If possible, use --file-setsize to set the file size for proper progress :PROPERTIES: :CUSTOM_ID: file-setsize :END: callback handling. Write data interface for file size. ++ ** Optimize the file descriptor list, so the number of open fds is :PROPERTIES: :CUSTOM_ID: optimus-descriptus-younger-brother-of-optimus-prime :END: always known easily. ++ ** Encryption: It should be verified that the behaviour for partially untrusted :PROPERTIES: :CUSTOM_ID: only-mostly-dead-means-partially-alive :END: recipients is correct. ++ ** When GPG issues INV_something for invalid signers, catch them. :PROPERTIES: :CUSTOM_ID: invalid-sig @@@ -440,15 -477,15 +538,18 @@@ :PROPERTIES: :CUSTOM_ID: error-value :END: ++ ** Map ASSUAN/GpgSM ERR error values in a better way than is done now. !! :PROPERTIES: :CUSTOM_ID: map-ass-error :END: ++ ** Some error values should identify the source more correctly (mostly error :PROPERTIES: :CUSTOM_ID: source-errors :END: values derived from status messages). ++ ** In rungpg.c we need to check the version of the engine :PROPERTIES: :CUSTOM_ID: rungpg-c-engine-ver @@@ -461,6 -498,6 +562,7 @@@ :PROPERTIES: :CUSTOM_ID: tests :END: ++ ** TODO Write a fake gpg-agent so that we can supply known passphrases to :PROPERTIES: :CUSTOM_ID: test-fake-gpg-agent @@@ -468,23 -505,23 +570,28 @@@ gpgsm and setup the configuration files to use the agent. Without this we are testing a currently running gpg-agent which is not a clever idea. ! ++ ** t-data :PROPERTIES: :CUSTOM_ID: test-data :END: ++ *** Test gpgme_data_release_and_get_mem. :PROPERTIES: :CUSTOM_ID: test-gpgme-data-release-mem :END: ++ *** Test gpgme_data_seek for invalid types. :PROPERTIES: :CUSTOM_ID: test-gpgme-data-seek :END: ++ ** t-keylist :PROPERTIES: :CUSTOM_ID: test-keylist :END: Write a test for ext_keylist. ++ ** Test reading key signatures. :PROPERTIES: :CUSTOM_ID: test-key-sig @@@ -495,6 -532,6 +602,7 @@@ :PROPERTIES: :CUSTOM_ID: debug :END: ++ ** Tracepoints should be added at: Every public interface enter/leave, :PROPERTIES: :CUSTOM_ID: tracepoint-pub-int @@@ -510,6 -547,6 +618,7 @@@ decrypt-verify.c delete.c edit.c encrypt.c encrypt-sign.c export.c genkey.c import.c key.c keylist.c passphrase.c progress.c signers.c sig-notation.c trust-item.c trustlist.c verify.c ++ ** TODO Handle malloc and vasprintf errors. But decide first if they should be :PROPERTIES: :CUSTOM_ID: malloc-vasprintf @@@ -522,10 -559,10 +631,12 @@@ :PROPERTIES: :CUSTOM_ID: build-suite :END: ++ ** TODO Make sure everything is cleaned correctly (esp. test area). :PROPERTIES: :CUSTOM_ID: clean-tests :END: ++ ** TODO Enable AC_CONFIG_MACRO_DIR and bump up autoconf version requirement. :PROPERTIES: :CUSTOM_ID: autoconf-macros @@@ -538,6 -575,6 +649,7 @@@ :PROPERTIES: :CUSTOM_ID: error-checking :END: ++ ** TODO engine-gpgsm, with-validation :PROPERTIES: :CUSTOM_ID: gpgsm-validation commit fa4927146b68dd045903285f1c45fb64deb2e361 Author: Ben McGinnes Date: Fri Mar 9 07:53:57 2018 +1100 docs: python bindings howto update. * Added all four signing code examples that are most likely to be used: armoured, clearsigned, detached armoured and detached binary. * May remove some examples and just discuss the differences, but it depends on the way the text is filled out. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index ab7e9db..17ec428 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -338,6 +338,96 @@ Python bindings to programmatically leverage the GPGME library. pass #+end_src +** Signing text + :PROPERTIES: + :CUSTOM_ID: howto-basic-signing + :END: + + Need to determine whether or not to include clearsigning and + detached signing here or give them separate sections. + + #+begin_src python + import gpg + + text = """Declaration of ... something. + + """ + + c = gpg.Context() + c.armor = True + signed = c.sign(text, mode=mode.NORMAL) + + afile = open("/path/to/statement.txt.asc", "w") + for i in range(len(signed[0].splitlines())): + afile.write("{0}\n".format(signed[0].splitlines()[i].decode('utf-8'))) + afile.close() + #+end_src + + Clearsigning: + + #+begin_src python + import gpg + + text = """Declaration of ... something. + + """ + + c = gpg.Context() + c.armor = True + signed = c.sign(text, mode=mode.CLEAR) + + afile = open("/path/to/statement.txt.asc", "w") + for i in range(len(signed[0].splitlines())): + afile.write("{0}\n".format(signed[0].splitlines()[i].decode('utf-8'))) + afile.close() + #+end_src + + Detached ASCII Armoured signing: + + #+begin_src python + import gpg + + text = """Declaration of ... something. + + """ + + c = gpg.Context() + c.armor = True + signed = c.sign(text, mode=mode.DETACH) + + afile = open("/path/to/statement.txt.asc", "w") + for i in range(len(signed[0].splitlines())): + afile.write("{0}\n".format(signed[0].splitlines()[i].decode('utf-8'))) + afile.close() + #+end_src + + Detached binary signing (maybe change text to be reading a file's + content): + + #+begin_src python +import gpg + +text = """Declaration of ... something. + +""" + +c = gpg.Context() +c.armor = True +signed = c.sign(text, mode=mode.DETACH) + +afile = open("/path/to/statement.txt.sig", "wb") +afile.write(signed[0]) +afile.close() + #+end_src + + +** Signature verification + :PROPERTIES: + :CUSTOM_ID: howto-basic-verification + :END: + +x + * Copyright and Licensing :PROPERTIES: commit c767a4a3590bd8a224d0268746df443942cb28c2 Author: Ben McGinnes Date: Fri Mar 9 05:25:49 2018 +1100 doc: python bindings howto update * Added example of decryption. * included some quick notes for myself regarding aspects to explain when I flesh out the explanatory text. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 8f81511..ab7e9db 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -269,7 +269,6 @@ Python bindings to programmatically leverage the GPGME library. #+begin_src python import gpg import os - import os.path rkey = "0x12345678DEADBEEF" text = """ @@ -297,13 +296,48 @@ Python bindings to programmatically leverage the GPGME library. cipher.seek(0, os.SEEK_SET) del(text) del(plain) - afile = open("secret_plans.txt.asc", "wb") + afile = open("secret_plans.org.asc", "wb") afile.write(cipher.read()) afile.close() except gpg.errors.GPGMEError as ex: print(ex.getstring()) #+end_src +** Decryption + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption + :END: + + Decrypting something encrypted to a key in one's secret keyring + (will display some extra data you normally wouldn't show, but which + may be of use): + + #+begin_src python + import os.path + import gpg + + if os.path.exists("/path/to/secret_plans.org.asc") is True: + ciphertext = "/path/to/secret_plans.org.asc" + elif os.path.exists("/path/to/secret_plans.org.gpg") is True: + ciphertext = "/path/to/secret_plans.org.gpg" + else: + ciphertext = None + + if ciphertext is not None: + afile = open(ciphertext, "rb") + plaintext = gpg.Context().decrypt(afile) + afile.close() + newfile = open("/path/to/secret_plans.org", "wb") + newfile.write(plaintext[0]) + newfile.close() + print(plaintext[0]) + plaintext[1] + plaintext[2] + del(plaintext) + else: + pass + #+end_src + * Copyright and Licensing :PROPERTIES: commit 75463d589522cba427f9e5a3a408192ffad8bb21 Author: Ben McGinnes Date: Fri Mar 9 04:42:41 2018 +1100 doc: Basic operation of the python bindings * Added sample code for encrypting some text to a single key. * Basically I'm just lifting existing production code and changing the key IDs from mine to "0x12345678DEADBEEF" for these first few examples. * I'll fill in the text description after. * Note: due to my regional location, I might split some tasks into more commits in order to be sure no work gets lost in case of emergency (or to put it another way: I know Telstra too well to trust them). diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index e7dc53d..8f81511 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -254,6 +254,57 @@ Python bindings to programmatically leverage the GPGME library. operation type has one. +* Basic Functions + :PROPERTIES: + :CUSTOM_ID: howto-the-basics + :END: + +** Encryption + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption + :END: + + Encrypting to one key: + + #+begin_src python + import gpg + import os + import os.path + + 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() + c = gpg.core.Context() + c.set_armor(1) + + 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)) + else: + try: + c.op_encrypt([r], 1, plain, cipher) + cipher.seek(0, os.SEEK_SET) + del(text) + del(plain) + afile = open("secret_plans.txt.asc", "wb") + afile.write(cipher.read()) + afile.close() + except gpg.errors.GPGMEError as ex: + print(ex.getstring()) + #+end_src + + * Copyright and Licensing :PROPERTIES: :CUSTOM_ID: copyright-and-license ----------------------------------------------------------------------- Summary of changes: TODO | 208 ++++++++++++++++++++++++-------- lang/python/docs/GPGMEpythonHOWTOen.org | 175 +++++++++++++++++++++++++++ 2 files changed, 335 insertions(+), 48 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 9 00:59:43 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 09 Mar 2018 00:59:43 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-11-g1e27c0e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 1e27c0e04cd3280d498dc8b72d2e410f6287f656 (commit) from f8b8b6aac2ca1cb34d7a346aee1d874e7650557b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1e27c0e04cd3280d498dc8b72d2e410f6287f656 Author: NIIBE Yutaka Date: Fri Mar 9 08:56:50 2018 +0900 scd: More fix with PC/SC for Windows. * scd/apdu.c (pcsc_get_status): Return status based on CURRENT_STATUS. Add debug log. -- GnuPG-bug-id: 3825 Signed-off-by: NIIBE Yutaka diff --git a/scd/apdu.c b/scd/apdu.c index 6758e69..e797c09 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -667,27 +667,29 @@ pcsc_get_status (int slot, unsigned int *status, int on_wire) return pcsc_error_to_sw (err); } - reader_table[slot].pcsc.current_state = - (rdrstates[0].event_state & ~PCSC_STATE_CHANGED); - - /* log_debug */ - /* ("pcsc_get_status_change: %s%s%s%s%s%s%s%s%s%s\n", */ - /* (rdrstates[0].event_state & PCSC_STATE_IGNORE)? " ignore":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_CHANGED)? " changed":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_UNKNOWN)? " unknown":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_UNAVAILABLE)?" unavail":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_EMPTY)? " empty":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_PRESENT)? " present":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_ATRMATCH)? " atr":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_EXCLUSIVE)? " excl":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_INUSE)? " unuse":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_MUTE)? " mute":"" ); */ + if ((rdrstates[0].event_state & PCSC_STATE_CHANGED)) + reader_table[slot].pcsc.current_state = + (rdrstates[0].event_state & ~PCSC_STATE_CHANGED); + + if (DBG_CARD_IO) + log_debug + ("pcsc_get_status_change: %s%s%s%s%s%s%s%s%s%s\n", + (rdrstates[0].event_state & PCSC_STATE_IGNORE)? " ignore":"", + (rdrstates[0].event_state & PCSC_STATE_CHANGED)? " changed":"", + (rdrstates[0].event_state & PCSC_STATE_UNKNOWN)? " unknown":"", + (rdrstates[0].event_state & PCSC_STATE_UNAVAILABLE)?" unavail":"", + (rdrstates[0].event_state & PCSC_STATE_EMPTY)? " empty":"", + (rdrstates[0].event_state & PCSC_STATE_PRESENT)? " present":"", + (rdrstates[0].event_state & PCSC_STATE_ATRMATCH)? " atr":"", + (rdrstates[0].event_state & PCSC_STATE_EXCLUSIVE)? " excl":"", + (rdrstates[0].event_state & PCSC_STATE_INUSE)? " unuse":"", + (rdrstates[0].event_state & PCSC_STATE_MUTE)? " mute":"" ); *status = 0; - if ( (rdrstates[0].event_state & PCSC_STATE_PRESENT) ) + if ( (reader_table[slot].pcsc.current_state & PCSC_STATE_PRESENT) ) { *status |= APDU_CARD_PRESENT; - if ( !(rdrstates[0].event_state & PCSC_STATE_MUTE) ) + if ( !(reader_table[slot].pcsc.current_state & PCSC_STATE_MUTE) ) *status |= APDU_CARD_ACTIVE; } #ifndef HAVE_W32_SYSTEM @@ -696,7 +698,7 @@ pcsc_get_status (int slot, unsigned int *status, int on_wire) mode. */ if ( (*status & (APDU_CARD_PRESENT|APDU_CARD_ACTIVE)) == (APDU_CARD_PRESENT|APDU_CARD_ACTIVE) - && !(rdrstates[0].event_state & PCSC_STATE_INUSE) ) + && !(reader_table[slot].pcsc.current_state & PCSC_STATE_INUSE) ) *status |= APDU_CARD_USABLE; #else /* Some winscard drivers may set EXCLUSIVE and INUSE at the same ----------------------------------------------------------------------- Summary of changes: scd/apdu.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 9 05:24:06 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Fri, 09 Mar 2018 05:24:06 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-66-gab81c2d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via ab81c2d868bba79fdb8f8d7f576b6bd88c6bdf3c (commit) from f685cda281c6148072e8a6cd139c990cb041ea3d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ab81c2d868bba79fdb8f8d7f576b6bd88c6bdf3c Author: Ben McGinnes Date: Fri Mar 9 15:22:24 2018 +1100 doc: python bindings howto * Added example for verifying both detached and "in-line" signatures. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 17ec428..75f1ebd 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -13,12 +13,12 @@ :CUSTOM_ID: intro :END: -Version: 0.0.1-alpha [2018-03-07 Wed] -Author: Ben McGinnes -Author GPG Key: DB4724E6FA4286C92B4E55C4321E4E2373590E5D + Version: 0.0.1-alpha [2018-03-07 Wed] + Author: Ben McGinnes + Author GPG Key: DB4724E6FA4286C92B4E55C4321E4E2373590E5D -This document provides basic instruction in how to use the GPGME -Python bindings to programmatically leverage the GPGME library. + This document provides basic instruction in how to use the GPGME + Python bindings to programmatically leverage the GPGME library. * GPGME Concepts @@ -401,23 +401,22 @@ Python bindings to programmatically leverage the GPGME library. afile.close() #+end_src - Detached binary signing (maybe change text to be reading a file's - content): + Detached binary signing of a file. #+begin_src python -import gpg - -text = """Declaration of ... something. + import gpg -""" + tfile = open("/path/to/statement.txt", "r") + text = tfile.read() + tfile.close() -c = gpg.Context() -c.armor = True -signed = c.sign(text, mode=mode.DETACH) + c = gpg.Context() + c.armor = True + signed = c.sign(text, mode=mode.DETACH) -afile = open("/path/to/statement.txt.sig", "wb") -afile.write(signed[0]) -afile.close() + afile = open("/path/to/statement.txt.sig", "wb") + afile.write(signed[0]) + afile.close() #+end_src @@ -426,7 +425,31 @@ afile.close() :CUSTOM_ID: howto-basic-verification :END: -x + Verify a signed file, both detached and not: + + #+begin_src python + import gpg + import sys + import time + + c = gpg.Context() + + data, result = c.verify(open(filename), + open(detached_sig_filename) + if detached_sig_filename else None) + + for index, sign in enumerate(result.signatures): + print("signature", index, ":") + print(" summary: %#0x" % (sign.summary)) + print(" status: %#0x" % (sign.status)) + print(" timestamp: ", sign.timestamp) + print(" timestamp: ", time.ctime(sign.timestamp)) + print(" fingerprint:", sign.fpr) + print(" uid: ", c.get_key(sign.fpr).uids[0].uid) + + if data: + sys.stdout.buffer.write(data) + #+end_src * Copyright and Licensing ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 59 +++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 18 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 9 05:29:43 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Fri, 09 Mar 2018 05:29:43 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-67-g93252df Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 93252df9dc4c9932467814745655350a8cab900e (commit) from ab81c2d868bba79fdb8f8d7f576b6bd88c6bdf3c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 93252df9dc4c9932467814745655350a8cab900e Author: Ben McGinnes Date: Fri Mar 9 15:27:40 2018 +1100 doc: python bindings TODO list * Updated to reflect the most recent work on the HOWTO for the Python bindings. diff --git a/lang/python/docs/TODO.org b/lang/python/docs/TODO.org index 897c617..df1aa4e 100644 --- a/lang/python/docs/TODO.org +++ b/lang/python/docs/TODO.org @@ -43,20 +43,23 @@ :CUSTOM_ID: howto-start :END: -*** TODO Include certain specific instructions in the HOWTO +*** STARTED Include certain specific instructions in the HOWTO :PROPERTIES: :CUSTOM_ID: howto-requests :END: + - State "STARTED" from "TODO" [2018-03-09 Fri 15:27] Some functions can be worked out from the handful of examples available, but many more can't and I've already begun receiving requests for certain functions to be explained. -**** TODO Standard scenarios +**** STARTED Standard scenarios :PROPERTIES: :CUSTOM_ID: howto-the-basics :END: + - State "STARTED" from "TODO" [2018-03-09 Fri 15:26] \\ + Began with the example code, now to add the text. What everyone expects: encryption, decryption, signing and verifying. **** TODO Key control ----------------------------------------------------------------------- Summary of changes: lang/python/docs/TODO.org | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 9 06:51:58 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Fri, 09 Mar 2018 06:51:58 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-68-g0168646 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 01686463948ac6096dd8579a110c478d3a1f9a83 (commit) from 93252df9dc4c9932467814745655350a8cab900e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 01686463948ac6096dd8579a110c478d3a1f9a83 Author: Ben McGinnes Date: Fri Mar 9 16:49:05 2018 +1100 doc: python bindings howto * Wrote the text description explaining each step in the most basic encryption operation. * Will need to include additional examples for encrypting to multiple recipients using Context().encrypt instead of Context().op_encrypt. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 75f1ebd..0b882b5 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -259,12 +259,51 @@ :CUSTOM_ID: howto-the-basics :END: + The most frequently called features of any cryptographic library + will be the most fundamental tasks for enxryption software. In this + section we will look at how to programmatically encrypt data, + decrypt it, sign it and verify signatures. + ** Encryption :PROPERTIES: :CUSTOM_ID: howto-basic-encryption :END: - Encrypting to one key: + Encrypting is very straight forward. In the first example below + the message, =text=, is encrypted to a single recipient's key. In + the second example the message will be encrypted to multiple + recipients. + +*** Encrypting to one key + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption-single + :END: + + The text is then encapsulated in a GPGME Data object as =plain= and + the =cipher= object is created with another Data object. Then we + create the Context as =c= and set it to use the ASCII armoured + OpenPGP format. In later examples there will be alternative + methods of setting the OpenPGP output to be ASCII armoured. + + Next we prepare a keylist object in our Context and follow it with + specifying the recipients as =r=. Note that the configuration in + one's =gpg.conf= file is honoured, so if you have the options set + to encrypt to one key or to a default key, that will be included + with this operation. + + This is followed by a quick check to be sure that the recipient is + actually selected and that the key is available. Assuming it is, + the encryption can proceed, but if not a message will print stating + the key was not found. + + The encryption operation is invoked within the Context with the + =c.op_encrypt= function, loading the recipien (=r=), the message + (=plain=) and the =cipher=. The =cipher.seek= uses =os.SEEK_SET= + to set the data to the correct byte format for GPGME to use it. + + At this point we no longer need the plaintext material, so we + delete both the =text= and the =plain= objects. Then we write the + encrypted data out to a file, =secret_plans.txt.asc=. #+begin_src python import gpg @@ -296,13 +335,19 @@ cipher.seek(0, os.SEEK_SET) del(text) del(plain) - afile = open("secret_plans.org.asc", "wb") + afile = open("secret_plans.txt.asc", "wb") afile.write(cipher.read()) afile.close() except gpg.errors.GPGMEError as ex: print(ex.getstring()) #+end_src +*** Encrypting to multiple keys + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption-multiple + :END: + + ** Decryption :PROPERTIES: :CUSTOM_ID: howto-basic-encryption @@ -316,10 +361,10 @@ import os.path import gpg - if os.path.exists("/path/to/secret_plans.org.asc") is True: - ciphertext = "/path/to/secret_plans.org.asc" - elif os.path.exists("/path/to/secret_plans.org.gpg") is True: - ciphertext = "/path/to/secret_plans.org.gpg" + if os.path.exists("/path/to/secret_plans.txt.asc") is True: + ciphertext = "/path/to/secret_plans.txt.asc" + elif os.path.exists("/path/to/secret_plans.txt.gpg") is True: + ciphertext = "/path/to/secret_plans.txt.gpg" else: ciphertext = None @@ -327,7 +372,7 @@ afile = open(ciphertext, "rb") plaintext = gpg.Context().decrypt(afile) afile.close() - newfile = open("/path/to/secret_plans.org", "wb") + newfile = open("/path/to/secret_plans.txt", "wb") newfile.write(plaintext[0]) newfile.close() print(plaintext[0]) @@ -338,6 +383,7 @@ pass #+end_src + ** Signing text :PROPERTIES: :CUSTOM_ID: howto-basic-signing ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 60 +++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 7 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 9 10:42:51 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 09 Mar 2018 10:42:51 +0100 Subject: [git] GnuPG - branch, tpm-work, created. gnupg-2.2.5-126-gfb0470a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, tpm-work has been created at fb0470a9f5834b77fba2bf5e1b41f56d063e556f (commit) - Log ----------------------------------------------------------------- commit fb0470a9f5834b77fba2bf5e1b41f56d063e556f Author: Werner Koch Date: Fri Mar 9 10:36:14 2018 +0100 agent: Minor cleanup of the TPM patches. * configure.ac (AC_CHECK_HEADERS): Add tss2/tss.h. * agent/divert-tpm2.c: Print an error if that file is not available. * agent/Makefile.am (gpg_agent_SOURCES): Add tpm.h * agent/command.c (do_one_keyinfo): Replace xstrdup by xtrystrdup. * agent/protect.c (agent_get_shadow_info_type): Check error of xtrystrdup. Signed-off-by: Werner Koch diff --git a/agent/Makefile.am b/agent/Makefile.am index 290ef12..4fe74f5 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -52,7 +52,7 @@ gpg_agent_SOURCES = \ trustlist.c \ divert-scd.c \ divert-tpm2.c \ - tpm2.c \ + tpm2.c tpm2.h \ cvt-openpgp.c cvt-openpgp.h \ call-scd.c \ learncard.c diff --git a/agent/command.c b/agent/command.c index c439aa5..a46e288 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1104,7 +1104,8 @@ 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, *shadow_info_type = NULL; + unsigned char *shadow_info = NULL; + unsigned char *shadow_info_type = NULL; char *serialno = NULL; char *idstr = NULL; const char *keytypestr; @@ -1194,7 +1195,12 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, } else if (strcmp (shadow_info_type, "tpm2-v1") == 0) { - serialno = xstrdup("TPM-Protected"); + serialno = xtrystrdup("TPM-Protected"); + if (!serialno) + { + err = gpg_error_from_syserror (); + goto leave; + } idstr = NULL; } else diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c index deb655a..84935de 100644 --- a/agent/divert-tpm2.c +++ b/agent/divert-tpm2.c @@ -8,6 +8,12 @@ #include #include +/* FIXME: Until we have a proper checking in configure we give a hint + * on what to do */ +#ifndef HAVE_TSS2_TSS_H +# error Please install the libtss2 dev package first +#endif + #include "agent.h" #include "../common/i18n.h" #include "../common/sexp-parse.h" diff --git a/agent/protect.c b/agent/protect.c index 0920667..09c7d61 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -1559,11 +1559,12 @@ agent_shadow_key_type (const unsigned char *pubkey, /* Calculate required length by taking in account: the "shadowed-" prefix, the "shadowed", shadow type as well as some parenthesis */ + /* FIXME: We should use membuf functions here. */ n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1; *result = xtrymalloc (n); p = (char*)*result; if (!p) - return out_of_core (); + return out_of_core (); p = stpcpy (p, "(20:shadowed-private-key"); /* (10:public-key ...)*/ memcpy (p, pubkey+14, point - (pubkey+14)); @@ -1643,12 +1644,15 @@ agent_get_shadow_info_type (const unsigned char *shadowkey, n = snext (&s); if (!n) return gpg_error (GPG_ERR_INV_SEXP); - if (shadow_type) { - char *buf = xtrymalloc(n+1); - memcpy(buf, s, n); - buf[n] = '\0'; - *shadow_type = buf; - } + if (shadow_type) + { + char *buf = xtrymalloc(n+1); + if (!buf) + return gpg_error_from_syserror (); + memcpy (buf, s, n); + buf[n] = '\0'; + *shadow_type = buf; + } if (smatch (&s, n, "t1-v1") || smatch(&s, n, "tpm2-v1")) { diff --git a/configure.ac b/configure.ac index 7522b69..9dd9230 100644 --- a/configure.ac +++ b/configure.ac @@ -1301,7 +1301,7 @@ AC_HEADER_STDC AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h \ pty.h utmp.h pwd.h inttypes.h signal.h sys/select.h \ stdint.h signal.h util.h libutil.h termios.h \ - ucred.h sys/ucred.h sys/sysmacros.h sys/mkdev.h]) + ucred.h sys/ucred.h sys/sysmacros.h sys/mkdev.h tss2/tss.h]) AC_HEADER_TIME commit 72ece35fb713eaf88d425f8b3468bec0d2b887e1 Author: James Bottomley Date: Mon Mar 5 11:18:15 2018 -0800 tpm2: add handling for elliptic curve keys * agent/divert-tpm2.c: Support ECC. -- 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 diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c index dc3110d..deb655a 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 734f0fe..ff57560 100644 --- a/agent/tpm2.c +++ b/agent/tpm2.c @@ -313,7 +313,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; @@ -339,6 +339,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, @@ -358,7 +360,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; @@ -367,7 +370,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; @@ -394,22 +396,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; @@ -433,7 +594,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; @@ -506,12 +667,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); @@ -757,9 +924,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 2e16803..7a63aab 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 commit c4c7b7d7ba6b9d52bb7884b4bb4f84b7dd96340b Author: James Bottomley Date: Mon Mar 5 11:16:40 2018 -0800 g10: add ability to transfer a private key to the tpm * g10/keyedit.c (cmdKEYTOTPM): New enum value. (cmds): New command "keytotpm". (keyedit_menu): Implement cmdKEYTOTPM. -- 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 diff --git a/g10/call-agent.c b/g10/call-agent.c index b1f589b..8b224f7 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -778,6 +778,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 53775c5..ba4c398 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -91,6 +91,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 2c33a29..038c318 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; commit 1a4a4a8f5fa575df64ab130b03e666920f7093ee Author: James Bottomley Date: Mon Mar 5 11:15:29 2018 -0800 agent: plumb in TPM handling * agent/divert-tpm2.c: New. * Makefile.am (gpg_agent_SOURCES): Add it. * agent/command.c (do_one_keyinfo): Fake serialno for TPM. (cmd_keytotpm): New. (register_commands): Register KEYTOTPM command. * agent/pkdecrypt.c (agent_pkdecrypt): Divert to TPM. * agent/pksign.c (agent_pksign_do): Divert to TPM. -- 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 - Added ChangeLog entries Signed-off-by: Werner Koch diff --git a/agent/Makefile.am b/agent/Makefile.am index 39e69cd..290ef12 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 \ diff --git a/agent/agent.h b/agent/agent.h index e13ee1f..7a77eb6 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, @@ -533,6 +534,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 32c12d9..c439aa5 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 0000000..dc3110d --- /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 06a8e0b..6f766ca 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 f54af08..dae2638 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) commit 144cceec7ca132d471cc6b7b200e0c59a23663d1 Author: James Bottomley Date: Mon Mar 5 11:14:34 2018 -0800 agent: add tpm specific functions * agent/tpm2.c: New. * agent/Makefile.am (gpg_agent_SOURCES): Add new file. (gpg_agent_LDFLAGS): Add DL_LIBS. * agent/tpm2.h: New. -- 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 - Added ChangeLog entries. - Added DL_LIBS. - Removed one -Wdeclaration-after-statement case. Signed-off-by: Werner Koch diff --git a/agent/Makefile.am b/agent/Makefile.am index ce29462..39e69cd 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 @@ -70,7 +71,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 = $(DL_LIBS) $(extra_bin_ldflags) gpg_agent_DEPENDENCIES = $(resource_objs) gpg_protect_tool_SOURCES = \ diff --git a/agent/tpm2.c b/agent/tpm2.c new file mode 100644 index 0000000..734f0fe --- /dev/null +++ b/agent/tpm2.c @@ -0,0 +1,784 @@ +#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) { + TPMI_ALG_HASH nameAlgNbo; + + /* copy the digest */ + memcpy(name->t.name + sizeof(TPMI_ALG_HASH), (uint8_t *)&digest.digest, sizeInBytes); + /* copy the hash algorithm */ + 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 0000000..2e16803 --- /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 commit 30c434eaf34e8facb3df0eebdd2de26f4fa604af Author: James Bottomley Date: Mon Mar 5 11:13:25 2018 -0800 agent: expose shadow key type * agent/findkey.c (agent_key_info_from_file): Add new return arg r_shadow_info_type. * agent/protect.c (agent_shadow_key): Factor code out to ... (agent_shadow_key_type): new. Add arg 'type'. (agent_get_shadow_info): Factor code out to ... (agent_get_shadow_info_type): new. Add arg 'shadow_type'. (agent_is_tpm2_key): New. (agent_get_shadow_type): New. * agent/command.c (do_one_keyinfo): Get and check the shadow_info_type. -- 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 Added ChangeLog entries. Signed-off-by: Werner Koch diff --git a/agent/agent.h b/agent/agent.h index 0d5cf4f..e13ee1f 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); @@ -503,8 +504,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 e2486a5..32c12d9 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 e3e9a12..d6c600e 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 16ae715..0920667 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 ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 9 10:47:23 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Fri, 09 Mar 2018 10:47:23 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-70-g172baaf Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 172baaf4d3e4ed03a4d3437be9efa3dfe6a847bc (commit) via f2c1e8d8d54068a7f072efa178fc30460821eff3 (commit) from 01686463948ac6096dd8579a110c478d3a1f9a83 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 172baaf4d3e4ed03a4d3437be9efa3dfe6a847bc Author: Ben McGinnes Date: Fri Mar 9 20:45:14 2018 +1100 doc: python bindings HOWTO * Added instructions and code to count the number of public and secret keys available since it was quick and easy. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 0b882b5..4385bc9 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -498,6 +498,39 @@ #+end_src +* Working with keys + :PROPERTIES: + :CUSTOM_ID: howto-keys + :END: + +** Counting keys + :PROPERTIES: + :CUSTOM_ID: howto-basic-verification + :END: + + Counting the number of keys in your public keybox (=pubring.kbx=), + the format shich has superceded the old keyring format + (=pubring.gpg= and =secring.gpg=) is a very simple task. + + #+begin_src python + import gpg + + c = gpg.Context() + seckeys = c.keylist(pattern=None, secret=True) + pubkeys = c.keylist(pattern=None, secret=False) + + seclist = list(seckeys) + secnum = len(seclist) + + publist = list(pubkeys) + pubnum = len(publist) + + print(""" + Number of secret keys: {0} + Number of public keys: {1} + """.format(secnum, pubnum) + #+end_src + * Copyright and Licensing :PROPERTIES: :CUSTOM_ID: copyright-and-license commit f2c1e8d8d54068a7f072efa178fc30460821eff3 Author: Ben McGinnes Date: Fri Mar 9 20:44:02 2018 +1100 doc: python TODO list * Slightly tweaked one heading to make it clear it wasn't a duplicate. diff --git a/lang/python/docs/TODO.org b/lang/python/docs/TODO.org index df1aa4e..21d2216 100644 --- a/lang/python/docs/TODO.org +++ b/lang/python/docs/TODO.org @@ -70,7 +70,7 @@ Generating keys, adding subkeys, revoking subkeys (and keeping the cert key), adding and revoking UIDs, signing/certifying keys. -**** TODO Key control +**** TODO More key control :PROPERTIES: :CUSTOM_ID: howto-key-selection :END: ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 33 +++++++++++++++++++++++++++++++++ lang/python/docs/TODO.org | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 9 10:48:07 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 09 Mar 2018 10:48:07 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.5-121-gb32de1b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via b32de1bf3e5114eb29472c301f2d5bb9ffd2f4fa (commit) from f574aabeeb873f14a586f80cac16b857e6088534 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b32de1bf3e5114eb29472c301f2d5bb9ffd2f4fa Author: Werner Koch Date: Fri Mar 9 10:41:44 2018 +0100 doc: Register DCOs for Ben McGinnes and James Bottomley -- diff --git a/AUTHORS b/AUTHORS index 0dabbc1..f43208a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -172,6 +172,9 @@ Andreas Schwier Arnaud Fontaine 2016-10-17:580484F4.8040806 at ssi.gouv.fr: +Ben McGinnes +2017-12-16:20171216002102.l6aejk5xdp6xhtfi at adversary.org: + Christian Aistleitner 2013-05-26:20130626112332.GA2228 at quelltextlich.at: @@ -187,6 +190,9 @@ Hans of Guardian Ineiev 2017-05-09:20170509121611.GH25850 at gnu.org: +James Bottomley +2018-02-01:1517501629.3145.9.camel at HansenPartnership.com: + Jonas Borgstr?m 2013-08-29:521F1E7A.5080602 at borgstrom.se: ----------------------------------------------------------------------- Summary of changes: AUTHORS | 6 ++++++ 1 file changed, 6 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 12 02:17:35 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 12 Mar 2018 02:17:35 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-12-g655f0b9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 655f0b9ad0138e6f960bf4befaf0eea569256614 (commit) from 1e27c0e04cd3280d498dc8b72d2e410f6287f656 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 655f0b9ad0138e6f960bf4befaf0eea569256614 Author: NIIBE Yutaka Date: Mon Mar 12 10:17:05 2018 +0900 scd: Fix typo in previous commit. Signed-off-by: NIIBE Yutaka diff --git a/scd/apdu.c b/scd/apdu.c index e797c09..2ae6253 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -682,7 +682,7 @@ pcsc_get_status (int slot, unsigned int *status, int on_wire) (rdrstates[0].event_state & PCSC_STATE_PRESENT)? " present":"", (rdrstates[0].event_state & PCSC_STATE_ATRMATCH)? " atr":"", (rdrstates[0].event_state & PCSC_STATE_EXCLUSIVE)? " excl":"", - (rdrstates[0].event_state & PCSC_STATE_INUSE)? " unuse":"", + (rdrstates[0].event_state & PCSC_STATE_INUSE)? " inuse":"", (rdrstates[0].event_state & PCSC_STATE_MUTE)? " mute":"" ); *status = 0; ----------------------------------------------------------------------- Summary of changes: scd/apdu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 12 10:44:07 2018 From: cvs at cvs.gnupg.org (by James Bottomley) Date: Mon, 12 Mar 2018 10:44:07 +0100 Subject: [git] GnuPG - branch, tpm-work, updated. gnupg-2.2.5-127-g06c0d7f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, tpm-work has been updated via 06c0d7f28fa1842f9c52885b142a0d31ba60c8ae (commit) from fb0470a9f5834b77fba2bf5e1b41f56d063e556f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 06c0d7f28fa1842f9c52885b142a0d31ba60c8ae Author: James Bottomley Date: Tue Mar 6 15:02:43 2018 -0800 build: Make TPM2 support conditional * configure.ac (HAVE_LIBTSS): New acdefine and am_conditional. * agent/Makefile.am: (gpg_agent_SOURCES): Move tpm files to ... (gpg_agent_SOURCES) [HAVE_LIBTSS]: ... here. * agent/agent.h (divert_tpm2_pksign, divert_tpm2_pkdecrypt) (divert_tpm2_writekey) [!HAVE_LIBTSS]: Add stub functions. -- 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 diff --git a/agent/Makefile.am b/agent/Makefile.am index 4fe74f5..3abdde4 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 tpm2.h \ cvt-openpgp.c cvt-openpgp.h \ call-scd.c \ learncard.c +if HAVE_LIBTSS +gpg_agent_SOURCES += tpm2.c tpm2.h \ + 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 7a77eb6..67e82b7 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -535,6 +535,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, @@ -545,6 +546,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 9dd9230..fe1078a 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 " ----------------------------------------------------------------------- Summary of changes: agent/Makefile.am | 7 +++++-- agent/agent.h | 26 ++++++++++++++++++++++++++ configure.ac | 11 +++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 12 11:57:46 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 12 Mar 2018 11:57:46 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.27-247-g863948a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 863948ab29d1016a271fd7e6d48af316dad4e939 (commit) via 0e503cae75cb1a6aa257228a65941b7630ff35d6 (commit) from 596c0d701edeb45e0069bb74b9343e3d5b708ef0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 863948ab29d1016a271fd7e6d48af316dad4e939 Author: Werner Koch Date: Mon Mar 12 11:50:51 2018 +0100 core: Remove accidently committed time function API. -- Fixes-commit: f9a33a7f7e44a644ff4e31f7e9f1c2c1ec1f8eee diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index dc6f637..e78a6f1 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -1078,37 +1078,6 @@ void gpgrt_release_process (pid_t pid); #endif /*0*/ -/* - * Time functions - */ - -/* Our representation of time requires 8 byte. The value guaranteed - * to be a C string with no '\n' in it. The time is always UTC. */ -typedef unsigned char gpgrt_time_t[8]; - -/* Check that ATIME is a valid time. */ -gpg_err_code_t gpgrt_check_time (const gpgrt_time_t atime); - -/* Convert time into a Julian Date. Returns 0 for invalid dates. */ -unsigned int gpgrt_time2jd (const gpgrt_time_t atime, int *r_seconds); - -/* Convert the Julian Date (JD,SECS) into a time. If SECS is -1 noon - * is assumed. */ -void gpgrt_jd2time (gpgrt_time_t atime, unsigned int jd, int secs); - -/* Convert a time into a Julian Date and return it as a float with - * fractional seconds. */ -static GPG_ERR_INLINE double -gpgrt_time2jd_dbl (const gpgrt_time_t atime) -{ - unsigned int jd; - int secs; - jd = gpgrt_time2jd (atime, &secs); - return jd + (secs/86400.0); -} - - - #ifdef __cplusplus } #endif commit 0e503cae75cb1a6aa257228a65941b7630ff35d6 Author: Werner Koch Date: Mon Mar 12 11:01:27 2018 +0100 core: Do not export the process API -- We may need to change the API and thus we better wait before publishing this new interface. Signed-off-by: Werner Koch diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in index 3f26a89..eea6e4a 100644 --- a/src/gpg-error.def.in +++ b/src/gpg-error.def.in @@ -197,14 +197,15 @@ EXPORTS gpgrt_chdir @150 gpgrt_getcwd @151 - gpgrt_make_pipe @152 - gpgrt_spawn_process @153 - gpgrt_spawn_process_fd @154 - gpgrt_spawn_process_detached @155 - gpgrt_wait_process @156 - gpgrt_wait_processes @157 - gpgrt_kill_process @158 - gpgrt_release_process @159 +;; API not yet finished for: +;; gpgrt_make_pipe @152 +;; gpgrt_spawn_process @153 +;; gpgrt_spawn_process_fd @154 +;; gpgrt_spawn_process_detached @155 +;; gpgrt_wait_process @156 +;; gpgrt_wait_processes @157 +;; gpgrt_kill_process @158 +;; gpgrt_release_process @159 ;; end of file with public symbols for Windows. diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index 46e8f53..dc6f637 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -1027,8 +1027,9 @@ void _gpgrt_log_assert (const char *expr, const char *file, int line, /* - * Spawn functions + * Spawn functions (Not yet available) */ +#if 0 #define GPGRT_SPAWN_NONBLOCK 16 /* Set the streams to non-blocking. */ #define GPGRT_SPAWN_RUN_ASFW 64 /* Use AllowSetForegroundWindow on W32. */ @@ -1075,6 +1076,8 @@ void gpgrt_kill_process (pid_t pid); /* Release process resources identified by PID. */ void gpgrt_release_process (pid_t pid); +#endif /*0*/ + /* * Time functions */ diff --git a/src/gpg-error.vers b/src/gpg-error.vers index a5f91aa..1105e80 100644 --- a/src/gpg-error.vers +++ b/src/gpg-error.vers @@ -169,14 +169,15 @@ GPG_ERROR_1.0 { gpgrt_chdir; gpgrt_getcwd; - gpgrt_make_pipe; - gpgrt_spawn_process; - gpgrt_spawn_process_fd; - gpgrt_spawn_process_detached; - gpgrt_wait_process; - gpgrt_wait_processes; - gpgrt_kill_process; - gpgrt_release_process; +## API not yet finished for: +# gpgrt_make_pipe; +# gpgrt_spawn_process; +# gpgrt_spawn_process_fd; +# gpgrt_spawn_process_detached; +# gpgrt_wait_process; +# gpgrt_wait_processes; +# gpgrt_kill_process; +# gpgrt_release_process; local: diff --git a/src/sysutils.c b/src/sysutils.c index 1f2c293..c3aaf42 100644 --- a/src/sysutils.c +++ b/src/sysutils.c @@ -50,7 +50,7 @@ _gpgrt_fd_valid_p (int fd) /* Our variant of getenv. The returned string must be freed. If the - * environment variable does not exists NULL is retruned and ERRNO set + * environment variable does not exists NULL is returned and ERRNO set * to 0. */ char * _gpgrt_getenv (const char *name) diff --git a/src/visibility.c b/src/visibility.c index 2039ef7..9358163 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -1009,6 +1009,7 @@ _gpgrt_log_assert (const char *expr, const char *file, } +#if 0 gpg_err_code_t gpgrt_make_pipe (int filedes[2], estream_t *r_fp, int direction, int nonblock) { @@ -1063,7 +1064,7 @@ gpgrt_release_process (pid_t pid) { _gpgrt_release_process (pid); } - +#endif /*0*/ /* For consistency reasons we use function wrappers also for Windows ----------------------------------------------------------------------- Summary of changes: src/gpg-error.def.in | 17 +++++++++-------- src/gpg-error.h.in | 34 +++------------------------------- src/gpg-error.vers | 17 +++++++++-------- src/sysutils.c | 2 +- src/visibility.c | 3 ++- 5 files changed, 24 insertions(+), 49 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 12 14:36:23 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 12 Mar 2018 14:36:23 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-71-g7ebc5a3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 7ebc5a357057d01b7ef965521ab68b7cb7e20a8f (commit) from 172baaf4d3e4ed03a4d3437be9efa3dfe6a847bc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7ebc5a357057d01b7ef965521ab68b7cb7e20a8f Author: Ben McGinnes Date: Tue Mar 13 00:33:11 2018 +1100 doc: python bindings howto * Switched from links to some external docs to using footnotes where necessary. * Ideally the howto should be as stand alone as possible. * Also it makes it difficult to convert to another format for proof-reading if there are links that the conversion can't find. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 4385bc9..42cd3c0 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -116,8 +116,8 @@ This package is the origin of these bindings, though they are somewhat different now. For details of when and how the PyME - package was folded back into GPGME itself see the [[Short_History.org][Short History]] - document in this Python bindings =docs= directory. + package was folded back into GPGME itself see the /Short History/ + document[fn:1] in this Python bindings =docs= directory.[fn:2] The PyME package was first released in 2002 and was also the first attempt to implement a low level binding to GPGME. In doing so it @@ -195,7 +195,7 @@ :CUSTOM_ID: install-gpgme :END: - See the [[../../../README][GPGME README file]] for details of how to install GPGME from + See the GPGME =README= file for details of how to install GPGME from source. @@ -556,3 +556,13 @@ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + +* Footnotes + :PROPERTIES: + :CUSTOM_ID: footnotes + :END: + +[fn:1] Short_History.org and/or Short_History.html. + +[fn:2] The =lang/python/docs/= directory in the GPGME source. ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 12 16:02:21 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 12 Mar 2018 16:02:21 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-86-gf63db08 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via f63db085c5d86839bb5ed8b4203b4c7b5f28975e (commit) via a3dd23ceb50bb29973dc135bc63d7e14587164c1 (commit) from 8f1e092ad3d711878f8f569877ec7e0eb0860337 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f63db085c5d86839bb5ed8b4203b4c7b5f28975e Author: Andre Heinecke Date: Mon Mar 12 15:02:25 2018 +0100 Turn up debugging at the end of crypto * src/mail.cpp (Mail::~Mail): Very verbose logging in oom_extra. (Mail::~Mail): Use release_cArray. Explicitly null shared ptrs. (do_crypt): Log when done. (Mail::update_oom_data): Use release_cArray. -- GnuPG-Bug-Id: T3617 diff --git a/src/mail.cpp b/src/mail.cpp index 7d30895..ba2b501 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -125,11 +125,17 @@ Mail::~Mail() that the parser is alive even if the mail is deleted while parsing. */ gpgrt_lock_lock (&dtor_lock); + log_oom_extra ("%s:%s: dtor: Mail: %p item: %p", + SRCNAME, __func__, this, m_mailitem); std::map::iterator it; + log_oom_extra ("%s:%s: Detaching event sink", + SRCNAME, __func__); detach_MailItemEvents_sink (m_event_sink); gpgol_release(m_event_sink); + log_oom_extra ("%s:%s: Erasing mail", + SRCNAME, __func__); it = s_mail_map.find(m_mailitem); if (it != s_mail_map.end()) { @@ -145,7 +151,12 @@ Mail::~Mail() } } + log_oom_extra ("%s:%s: releasing mailitem", + SRCNAME, __func__); gpgol_release(m_mailitem); + xfree (m_cached_html_body); + xfree (m_cached_plain_body); + release_cArray (m_cached_recipients); if (!m_uuid.empty()) { log_oom_extra ("%s:%s: destroyed: %p uuid: %s", @@ -153,15 +164,16 @@ Mail::~Mail() } else { - log_oom_extra ("%s:%s: non crypto mail: %p destroyed", + log_oom_extra ("%s:%s: non crypto (or sent) mail: %p destroyed", SRCNAME, __func__, this); } - xfree (m_cached_html_body); - xfree (m_cached_plain_body); - for (int i = 0; m_cached_recipients && m_cached_recipients[i]; ++i) - xfree (m_cached_recipients[i]); - xfree (m_cached_recipients); + log_oom_extra ("%s:%s: nulling shared pointer", + SRCNAME, __func__); + m_parser = nullptr; + m_crypter = nullptr; gpgrt_lock_unlock (&dtor_lock); + log_oom_extra ("%s:%s: returning", + SRCNAME, __func__); } Mail * @@ -775,6 +787,8 @@ do_crypt (LPVOID arg) See GnuPG-Bug-Id: T3732 */ do_in_ui_thread_async (BRING_TO_FRONT, nullptr); + log_debug ("%s:%s: crypto thread for %p finished", + SRCNAME, __func__, arg); return 0; } @@ -1212,9 +1226,7 @@ Mail::update_oom_data () xfree (m_cached_plain_body); m_cached_plain_body = get_oom_string (m_mailitem, "Body"); - for (int i = 0; m_cached_recipients && m_cached_recipients[i]; ++i) - xfree (m_cached_recipients[i]); - xfree (m_cached_recipients); + release_cArray (m_cached_recipients); m_cached_recipients = get_recipients (); } /* For some reason outlook may store the recipient address commit a3dd23ceb50bb29973dc135bc63d7e14587164c1 Author: Andre Heinecke Date: Mon Mar 12 15:01:07 2018 +0100 Update portuguese translation * po/pt.po: Update. -- Translation provided by Marco A.G. Pinto. Thanks. diff --git a/po/pt.po b/po/pt.po index a7208d8..712f14a 100644 --- a/po/pt.po +++ b/po/pt.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL 1.1.1\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-07 10:01+0100\n" -"PO-Revision-Date: 2017-10-16 14:17+0100\n" +"POT-Creation-Date: 2018-03-07 13:37+0100\n" +"PO-Revision-Date: 2018-03-09 11:00+0000\n" "Last-Translator: Marco A.G.Pinto \n" "Language-Team: Portuguese \n" "Language: pt\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-SourceCharset: UTF-8\n" -"X-Generator: Poedit 2.0.4\n" +"X-Generator: Poedit 2.0.6\n" #: src/addin-options.cpp:37 src/gpgoladdin.cpp:1172 src/gpgoladdin.cpp:1255 #: src/gpgoladdin.cpp:1334 src/olflange-dlgs.cpp:43 @@ -37,7 +37,7 @@ msgstr "Envio de mensagem" #: src/addin-options.cpp:44 src/olflange-dlgs.cpp:47 msgid "&Encrypt new messages by default" -msgstr "Encriptar novas mensagens por omiss?o" +msgstr "&Encriptar novas mensagens por omiss?o" #: src/addin-options.cpp:45 src/olflange-dlgs.cpp:48 msgid "&Sign new messages by default" @@ -55,7 +55,7 @@ msgstr "" #: src/addin-options.cpp:50 msgid "&Resolve recipient keys automatically" -msgstr "" +msgstr "&Resolver automaticamente as chaves dos destinat?rios" #: src/addin-options.cpp:53 msgid "Debug..." @@ -78,7 +78,7 @@ msgstr "Mudar a interface necessita reiniciar o Outlook." #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:303 +#: src/gpgoladdin.cpp:1338 src/mail.cpp:745 src/main.c:467 src/message.cpp:303 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -113,7 +113,7 @@ msgid "" msgstr "" "Desculpa, n?o conseguimos desencriptar este anexo.\n" "\n" -"Por favor usa o bot?o desencriptar/verificar para desencriptar\n" +"Por favor, usa o bot?o desencriptar/verificar para desencriptar\n" "a mensagem completa novamente. Depois abre este anexo." #: src/cmdbarcontrols.cpp:104 @@ -175,11 +175,11 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "Queres reverter esta pasta?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1660 src/mail.cpp:1731 msgid "GpgOL: Encrypted Message" msgstr "GpgOL: Mensagem Encriptada" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1661 src/mail.cpp:1732 msgid "GpgOL: Trusted Sender Address" msgstr "GpgOL: Endere?o de Remetente Confi?vel" @@ -425,11 +425,11 @@ msgstr "" msgid "GpgOL Warning" msgstr "Aviso do GpgOL" -#: src/mail.cpp:811 +#: src/mail.cpp:819 msgid "Pubkey directory confirmation" -msgstr "" +msgstr "Confirma??o de diretoria Pubkey" -#: src/mail.cpp:812 +#: src/mail.cpp:820 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -437,114 +437,123 @@ msgid "" "

If you did not request to publish your Pubkey in your providers " "directory, simply ignore this message.

\n" msgstr "" +"Este ? um pedido de confirma??o para publicares a tua Pubkey na diretoria " +"para o teu dom?nio.\n" +"\n" +"

Se n?o pediste para publicar a tua Pubkey na diretoria do teu provedor, " +"simplesmente ignora esta mensagem.

\n" -#: src/mail.cpp:820 src/mail.cpp:1967 +#: src/mail.cpp:828 src/mail.cpp:1975 msgid "Encrypted message" msgstr "Mensagem encriptada" -#: src/mail.cpp:821 +#: src/mail.cpp:829 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -"Por favor aguarda enquanto a mensagem est? a ser desencriptada / " +"Por favor, aguarda enquanto a mensagem est? a ser desencriptada / " "verificada..." -#: src/mail.cpp:1097 +#: src/mail.cpp:1105 msgid "GpgOL: Oops, G Suite Sync account detected" -msgstr "" +msgstr "GpgOL: Oops, conta G Suite Sync detetada" -#: src/mail.cpp:1099 +#: src/mail.cpp:1107 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" "\n" "See: https://dev.gnupg.org/T3545 for details." msgstr "" +"G Suite Sync danifica a sa?da de e-mails criptografados com anexos.\n" +"Usar criptografia e anexos com G Suite Sync n?o ? suportado.\n" +"\n" +"V?: https://dev.gnupg.org/T3545 para detalhes." -#: src/mail.cpp:1912 +#: src/mail.cpp:1920 msgid "Security Level 4" msgstr "N?vel de seguran?a 4" -#: src/mail.cpp:1916 +#: src/mail.cpp:1924 msgid "Trust Level 4" msgstr "N?vel de Confian?a 4" -#: src/mail.cpp:1920 +#: src/mail.cpp:1928 msgid "Security Level 3" msgstr "N?vel de Seguran?a 3" -#: src/mail.cpp:1924 +#: src/mail.cpp:1932 msgid "Trust Level 3" msgstr "N?vel de Confian?a 3" -#: src/mail.cpp:1928 +#: src/mail.cpp:1936 msgid "Security Level 2" msgstr "N?vel de Seguran?a 2" -#: src/mail.cpp:1932 +#: src/mail.cpp:1940 msgid "Trust Level 2" msgstr "N?vel de Confian?a 2" -#: src/mail.cpp:1936 +#: src/mail.cpp:1944 msgid "Encrypted" msgstr "Encriptada" -#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1953 src/mail.cpp:1955 src/ribbon-callbacks.cpp:1625 msgid "Insecure" msgstr "Insegura" -#: src/mail.cpp:1959 +#: src/mail.cpp:1967 msgid "Signed and encrypted message" msgstr "Mensagem assinada e encriptada" -#: src/mail.cpp:1963 +#: src/mail.cpp:1971 msgid "Signed message" msgstr "Mensagem assinada" -#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:1978 src/ribbon-callbacks.cpp:1648 msgid "Insecure message" msgstr "Mensagem insegura" -#: src/mail.cpp:1981 src/mail.cpp:1992 +#: src/mail.cpp:1989 src/mail.cpp:2000 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" "N?o podes ter a certeza de quem enviou, modificou e leu a mensagem em " "tr?nsito." -#: src/mail.cpp:1984 +#: src/mail.cpp:1992 msgid "The message was signed but the verification failed with:" -msgstr "" +msgstr "A mensagem foi assinada, mas a verifica??o falhou com:" -#: src/mail.cpp:2002 +#: src/mail.cpp:2010 msgid "The encryption was VS-NfD-compliant." msgstr "A encripta??o est? em conformidade com VS-NfD." -#: src/mail.cpp:2006 +#: src/mail.cpp:2014 msgid "The encryption was not VS-NfD-compliant." msgstr "A encripta??o n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2010 +#: src/mail.cpp:2018 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" "N?o podes ter certeza de quem enviou a mensagem, porque n?o est? assinada." -#: src/mail.cpp:2033 +#: src/mail.cpp:2041 msgid "You signed this message." msgstr "Assinaste esta mensagem." -#: src/mail.cpp:2037 +#: src/mail.cpp:2045 msgid "The senders identity was certified by yourself." msgstr "A identidade dos remetentes foi certificada por ti pr?prio." -#: src/mail.cpp:2041 +#: src/mail.cpp:2049 msgid "The sender is allowed to certify identities for you." msgstr "O remetente pode certificar identidades para ti." -#: src/mail.cpp:2054 +#: src/mail.cpp:2062 msgid "The senders identity was certified by several trusted people." msgstr "" "A identidade dos remetentes foi certificada por v?rias pessoas confi?veis." -#: src/mail.cpp:2059 +#: src/mail.cpp:2067 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" @@ -553,11 +562,11 @@ msgstr "" "A identidade dos remetentes ? certificada pelo emissor confi?vel:\n" "'%s'\n" -#: src/mail.cpp:2067 +#: src/mail.cpp:2075 msgid "Some trusted people have certified the senders identity." msgstr "Algumas pessoas confi?veis certificaram a identidade dos remetentes." -#: src/mail.cpp:2077 +#: src/mail.cpp:2085 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -568,11 +577,11 @@ msgstr "" "comunica??o com este endere?o desde %s.\n" "Encriptaste %i e verificaste %i mensagens desde ent?o." -#: src/mail.cpp:2093 +#: src/mail.cpp:2101 msgid "The senders signature was verified for the first time." msgstr "A assinatura dos remetentes foi verificada pela primeira vez." -#: src/mail.cpp:2100 +#: src/mail.cpp:2108 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " @@ -581,68 +590,68 @@ msgstr "" "O endere?o dos remetentes ainda n?o ? confi?vel porque apenas verificaste %i " "mensagens e encriptaste %i mensagens a eles desde %s." -#: src/mail.cpp:2114 +#: src/mail.cpp:2122 msgid "But the sender address is not trustworthy because:" msgstr "Mas o endere?o do remetente n?o ? confi?vel porque:" -#: src/mail.cpp:2115 +#: src/mail.cpp:2123 msgid "The sender address is not trustworthy because:" msgstr "O endere?o do remetente n?o ? confi?vel porque:" -#: src/mail.cpp:2123 +#: src/mail.cpp:2131 msgid "The signature is invalid: \n" msgstr "A assinatura ? inv?lida: \n" -#: src/mail.cpp:2128 +#: src/mail.cpp:2136 msgid "There was an error verifying the signature.\n" msgstr "Houve um erro ao verificar a assinatura.\n" -#: src/mail.cpp:2132 +#: src/mail.cpp:2140 msgid "The signature is expired.\n" msgstr "A assinatura expirou.\n" -#: src/mail.cpp:2136 +#: src/mail.cpp:2144 msgid "The used key" msgstr "A chave usada" -#: src/mail.cpp:2136 +#: src/mail.cpp:2144 msgid "The used certificate" msgstr "O certificado usado" -#: src/mail.cpp:2144 +#: src/mail.cpp:2152 msgid "is not available." msgstr "n?o est? dispon?vel." -#: src/mail.cpp:2148 +#: src/mail.cpp:2156 msgid "is revoked." msgstr "est? revogado." -#: src/mail.cpp:2152 +#: src/mail.cpp:2160 msgid "is expired." msgstr "expirou." -#: src/mail.cpp:2156 +#: src/mail.cpp:2164 msgid "is not meant for signing." msgstr "n?o ? destinado a assinar." -#: src/mail.cpp:2160 src/mail.cpp:2164 +#: src/mail.cpp:2168 src/mail.cpp:2172 msgid "could not be checked for revocation." msgstr "n?o pode ser verificado para revoga??o." -#: src/mail.cpp:2169 +#: src/mail.cpp:2177 msgid "is not the same as the key that was used for this address in the past." msgstr "n?o ? o mesmo que a chave usada para este endere?o no passado." -#: src/mail.cpp:2175 +#: src/mail.cpp:2183 #, c-format msgid "does not claim the address: \"%s\"." msgstr "n?o reivindica o endere?o: \"%s\"." -#: src/mail.cpp:2188 +#: src/mail.cpp:2196 msgid "is not certified by any trustworthy key." msgstr "n?o est? certificado por qualquer chave confi?vel." -#: src/mail.cpp:2192 +#: src/mail.cpp:2200 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." @@ -650,58 +659,57 @@ msgstr "" "n?o est? certificado por uma Autoridade de Certifica??o confi?vel ou a " "Autoridade de Certifica??o ? desconhecida." -#: src/mail.cpp:2197 +#: src/mail.cpp:2205 msgid "The sender marked this address as revoked." msgstr "O remetente marcou este endere?o como revogado." -#: src/mail.cpp:2201 +#: src/mail.cpp:2209 msgid "is marked as not trustworthy." msgstr "est? marcado como n?o confi?vel." -#: src/mail.cpp:2211 +#: src/mail.cpp:2219 msgid "The signature is VS-NfD-compliant." msgstr "A assinatura est? em conformidade com VS-NfD." -#: src/mail.cpp:2215 +#: src/mail.cpp:2223 msgid "The signature is not VS-NfD-compliant." msgstr "A assinatura n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2223 +#: src/mail.cpp:2231 msgid "The encryption is VS-NfD-compliant." msgstr "A encripta??o est? em conformidade com VS-NfD." -#: src/mail.cpp:2227 +#: src/mail.cpp:2235 msgid "The encryption is not VS-NfD-compliant." msgstr "A encripta??o n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2238 +#: src/mail.cpp:2246 msgid "Click here to change the key used for this address." msgstr "Clica aqui para alterar a chave usada para este endere?o." -#: src/mail.cpp:2242 +#: src/mail.cpp:2250 msgid "Click here for details about the key." msgstr "Clica aqui para obter detalhes sobre a chave." -#: src/mail.cpp:2243 +#: src/mail.cpp:2251 msgid "Click here for details about the certificate." msgstr "Clica aqui para obter detalhes sobre o certificado." -#: src/mail.cpp:2247 +#: src/mail.cpp:2255 msgid "Click here to search the key on the configured keyserver." msgstr "Clica aqui para localizar a chave no servidor de chaves configurado." -#: src/mail.cpp:2248 +#: src/mail.cpp:2256 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" "Clica aqui para localizar o certificado no servidor de chaves X509 " "configurado." -#: src/mail.cpp:2476 -#, fuzzy +#: src/mail.cpp:2484 msgid "GpgOL: Encryption not possible!" -msgstr "GpgOL: Mensagem Encriptada" +msgstr "GpgOL: Encripta??o n?o poss?vel!" -#: src/mail.cpp:2478 +#: src/mail.cpp:2486 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -710,6 +718,12 @@ msgid "" "If it still fails consider using an encrypted attachment or\n" "switching to PGP/Inline in GpgOL's options." msgstr "" +"O Outlook retornou um erro ao tentar enviar o e-mail encriptado.\n" +"\n" +"Por favor, reinicia o Outlook e tenta novamente.\n" +"\n" +"Se continuar a falhar, considera usar um anexo encriptado ou\n" +"alternar para PGP/Inline nas op??es do GpgOL." #: src/mailitem.cpp:160 src/message-events.cpp:279 msgid "" @@ -718,7 +732,7 @@ msgid "" "format has been selected." msgstr "" "Desculpa, s? podemos encriptar mensagens de texto simples e\n" -"n?o mensagens RTF. Por favor certifica-te que apenas o formato\n" +"n?o mensagens RTF. Por favor, certifica-te que apenas o formato\n" "de texto foi selecionado." #: src/mailitem-events.cpp:295 @@ -737,7 +751,7 @@ msgid "" "For example by right clicking but not selecting the message.\n" msgstr "" "O GpgOL impediu a altera??o para a propriedade \"%s\".\n" -"As altera??es de propriedade n?o s?o ainda manejadas para mensagens de " +"As altera??es de propriedade n?o s?o ainda manipuladas para mensagens de " "criptografia.\n" "\n" "Para contornar esta limita??o, por favor altera a propriedade quando a " @@ -803,14 +817,14 @@ msgstr "A verifica??o da assinatura de uma mensagem encriptada n?o ? poss?v #: src/message.cpp:534 msgid "Signature verification of this message class is not possible." -msgstr "A verifica??o da assinatura desta classe de mensagem n?o ? poss?vel." +msgstr "A verifica??o da assinatura desta classe de mensagens n?o ? poss?vel." #: src/message.cpp:537 msgid "" "Signature verification of this S/MIME message is not possible. Please check " "that S/MIME processing has been enabled." msgstr "" -"A verifica??o da assinatura desta mensagem S/MIME n?o ? poss?vel. Por favor " +"A verifica??o da assinatura desta mensagem S/MIME n?o ? poss?vel. Por favor, " "verifica se o processamento S/MIME foi ativado." #: src/message.cpp:541 @@ -882,7 +896,7 @@ msgstr "" "OpenPGP e S/MIME ao Outlook 2003 e 2007.\n" "\n" "Embora test?mos este software extensivamente, n?o podemos dar qualquer " -"garantia que funcione da forma esperada. A interface de programa??o em uso " +"garantia que funcione da forma esperada. A interface de programa??o usada " "n?o foi devidamente documentada pela Microsoft e da? a funcionalidade do " "GpgOL poder cessar com uma atualiza??o do teu sistema Windows.\n" "\n" @@ -904,7 +918,7 @@ msgid "" msgstr "" "Instalaste uma vers?o nova do GpgOL.\n" "\n" -"Por favor abre o di?logo de op??es e confirma se as defini??es est?o " +"Por favor, abre o di?logo de op??es e confirma se as defini??es est?o " "corretas para as tuas necessidades. O di?logo de op??es pode ser encontrado " "em: Extras->Op??es->GpgOL\n" @@ -922,7 +936,8 @@ msgstr "" "As vers?es do Outlook 2003 anteriores ao SP2 exibem crashes ao enviar as " "mensagens, podendo estas ficar presas na fila de sa?da.\n" "\n" -"Por favor atualiza pelo menos para o SP2 antes de tentar enviar uma mensagem." +"Por favor, atualiza pelo menos para o SP2 antes de tentar enviar uma " +"mensagem." #: src/olflange.cpp:811 msgid "" @@ -984,7 +999,7 @@ msgstr "Chave Desconhecida:" #: src/parsecontroller.cpp:177 msgid "Decryption canceled or timed out." -msgstr "Desencripta??o cancelada ou expirou." +msgstr "Desencripta??o cancelada ou o tempo esgotou." #: src/parsecontroller.cpp:190 msgid "" @@ -1000,7 +1015,7 @@ msgstr "N?o foi poss?vel desencriptar os dados: " #: src/parsecontroller.cpp:200 msgid "Failed to parse the mail." -msgstr "" +msgstr "Falha ao analisar o e-mail." #: src/parsecontroller.cpp:211 src/parsecontroller.cpp:266 msgid "Encrypted message (decryption not possible)" @@ -1016,7 +1031,7 @@ msgstr "" #: src/ribbon-callbacks.cpp:262 msgid "Please select text to encrypt." -msgstr "Por favor seleciona o texto a encriptar." +msgstr "Por favor, seleciona o texto a encriptar." #: src/ribbon-callbacks.cpp:274 msgid "Textbody empty." @@ -1024,15 +1039,15 @@ msgstr "Corpo do texto vazio." #: src/ribbon-callbacks.cpp:323 src/ribbon-callbacks.cpp:1077 msgid "Please add at least one recipent." -msgstr "Por favor adiciona pelo menos um destinat?rio." +msgstr "Por favor, adiciona pelo menos um destinat?rio." #: src/ribbon-callbacks.cpp:685 msgid "Please select a Mail." -msgstr "Por favor seleciona um e-mail." +msgstr "Por favor, seleciona um e-mail." #: src/ribbon-callbacks.cpp:699 msgid "Please select the data you wish to decrypt." -msgstr "Por favor seleciona os dados que desejas desencriptar." +msgstr "Por favor, seleciona os dados que desejas desencriptar." #: src/ribbon-callbacks.cpp:712 msgid "Nothing to decrypt." @@ -1071,7 +1086,7 @@ msgid "" "Please reinstall Gpg4win with the Kleopatra component enabled." msgstr "" "N?o foi poss?vel encontrar o Kleopatra.\n" -"Por favor reinstala o Gpg4win com o componente Kleopatra ativado." +"Por favor, reinstala o Gpg4win com o componente Kleopatra ativado." #: src/wks-helper.cpp:404 msgid "" @@ -1084,62 +1099,70 @@ msgid "" "\n" "Register automatically?" msgstr "" +"Uma diretoria de Pubkey est? dispon?vel para o teu dom?nio.\n" +"\n" +"Regista a tua Pubkey nessa diretoria para facilitar\n" +"que outras pessoas te enviem e-mails encriptados.\n" +"\n" +"? seguro e gr?tis!\n" +"\n" +"Registar automaticamente?" #: src/wks-helper.cpp:409 msgid "GpgOL: Pubkey directory available!" -msgstr "" +msgstr "GpgOL: Diretoria de Pubkey dispon?vel!" #: src/wks-helper.cpp:491 msgid "GpgOL: Directory request failed" -msgstr "" +msgstr "GpgOL: Pedido de diretoria falhou" #: src/wks-helper.cpp:504 msgid "" "You might receive a confirmation challenge from\n" "your provider to finish the registration." msgstr "" +"Poder?s receber um desafio de confirma??o do\n" +"teu provedor para concluir o registo." #: src/wks-helper.cpp:506 msgid "GpgOL: Registration request sent!" -msgstr "" +msgstr "GpgOL: Pedido de registo enviado!" #: src/wks-helper.cpp:687 msgid "Confirm registration?" -msgstr "" +msgstr "Confirmar o registo?" #: src/wks-helper.cpp:688 msgid "GpgOL: Pubkey directory confirmation" -msgstr "" +msgstr "GpgOL: Confirma??o da diretoria de Pubkey" #: src/wks-helper.cpp:741 msgid "GpgOL: Confirmation failed" -msgstr "" +msgstr "GpgOL: Confirma??o falhou" #: src/wks-helper.cpp:753 msgid "Your Pubkey can soon be retrieved from your domain." -msgstr "" +msgstr "A tua Pubkey pode ser brevemente recuperada do teu dom?nio." #: src/wks-helper.cpp:754 msgid "GpgOL: Request confirmed!" -msgstr "" +msgstr "GpgOL: Pedido confirmado!" -#: src/cryptcontroller.cpp:394 -#, fuzzy +#: src/cryptcontroller.cpp:393 msgid "Resolving recipients..." -msgstr "Destinat?rios seleccionados:" +msgstr "A resolver destinat?rios..." -#: src/cryptcontroller.cpp:398 +#: src/cryptcontroller.cpp:397 msgid "Resolving signers..." -msgstr "" +msgstr "A resolver assinantes..." -#: src/cryptcontroller.cpp:994 -#, fuzzy +#: src/cryptcontroller.cpp:1007 msgid "Encrypting..." -msgstr "Encripta??o" +msgstr "A encriptar..." -#: src/cryptcontroller.cpp:998 +#: src/cryptcontroller.cpp:1011 msgid "Signing..." -msgstr "" +msgstr "A assinar..." #~ msgid "&Search for OpenPGP keys automatically when encrypting" #~ msgstr "Procurar as chaves OpenPGP automaticamente ao encriptar" ----------------------------------------------------------------------- Summary of changes: po/pt.po | 237 ++++++++++++++++++++++++++++++++--------------------------- src/mail.cpp | 30 +++++--- 2 files changed, 151 insertions(+), 116 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 12 18:58:26 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 12 Mar 2018 18:58:26 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-72-g0e1300c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 0e1300ce777dd0c87f31ac8bc49846b9df242df9 (commit) from 7ebc5a357057d01b7ef965521ab68b7cb7e20a8f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0e1300ce777dd0c87f31ac8bc49846b9df242df9 Author: Ben McGinnes Date: Tue Mar 13 04:55:44 2018 +1100 doc: python bindings howto * Added a more complicated encryption example with a few variations on the encryption method to account for untrusted recipient keys, signing or not signing, including or excluding default keys and so on. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 42cd3c0..84be851 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -347,6 +347,83 @@ :CUSTOM_ID: howto-basic-encryption-multiple :END: + Encrypting to multiple keys, in addition to a default key or a key + configured to always encrypt to, is a little different and uses a + slightly different call to the op_encrypt call demonstrated in the + previous section. + + The following example encrypts a message (=text=) to everyone with + an email address on the =gnupg.org= domain,[fn:3] but does /not/ encrypt + to a default key or other key which is configured to normally + encrypt to. + + #+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)) + rlogrus = [] + + for i in range(len(rpattern)): + if rpattern[i].can_encrypt == 1: + rlogrus.append(rpattern[i]) + + cipher = c.encrypt(text, recipients=rlogrus, sign=False, always_trust=True) + + afile = open("encrypted_file.txt.asc", "wb") + afile.write(cipher[0]) + afile.close() + #+end_src + + All it would take to change the above example to sign the message + and also encrypt the message to any configured default keys would + be to change the =c.encrypt= line to this: + + #+begin_src python + cipher = c.encrypt(text, recipients=rlogrus, always_trust=True, + add_encrypt_to=True) + #+end_src + + The only keyword arguments requiring modification are those for + which the default values are changing. The default value of + =sign= is =True=, the default of =always_trust= is =False=, the + default of =add_encrypt_to= is =False=. + + If =always_trust= is not set to =True= and any of the recipient + keys are not trusted (e.g. not signed or locally signed) then the + encryption will raise an error. It is possible to mitigate this + somewhat with something more like this: + + #+begin_src python + try: + cipher = c.encrypt(text, recipients=rlogrus, add_encrypt_to=True) + except gpg.errors.InvalidRecipients as e: + for i in range(len(e.recipients)): + for n in range(len(rlogrus)): + if rlogrus[n].fpr == e.recipients[i].fpr: + rlogrus.remove(e.recipients[i]) + try: + cipher = c.encrypt(text, recipients=rlogrus, add_encrypt_to=True) + except: + pass + #+end_src + + This will attempt to encrypt to all the keys searched for, then + remove invalid recipients if it fails and try again. + ** Decryption :PROPERTIES: @@ -531,6 +608,7 @@ """.format(secnum, pubnum) #+end_src + * Copyright and Licensing :PROPERTIES: :CUSTOM_ID: copyright-and-license @@ -559,10 +637,12 @@ * Footnotes - :PROPERTIES: - :CUSTOM_ID: footnotes - :END: [fn:1] Short_History.org and/or Short_History.html. [fn:2] The =lang/python/docs/= directory in the GPGME source. + +[fn:3] You probably don't really want to do this. Searching the +keyservers for "gnupg.org" produces over 400 results, the majority of +which aren't actually at the gnupg.org domain, but just included a +comment regarding the project in their key somewhere. ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 86 +++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 3 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 12 20:12:55 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 12 Mar 2018 20:12:55 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-74-ga8f48b6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via a8f48b6f577d562c25fd0191c0cc2cc8e96078c1 (commit) via 83b1336ceebb86e13a55bbf220df2d750f6b3ec6 (commit) from 0e1300ce777dd0c87f31ac8bc49846b9df242df9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a8f48b6f577d562c25fd0191c0cc2cc8e96078c1 Author: Ben McGinnes Date: Tue Mar 13 06:09:53 2018 +1100 doc: python bindings howto * error corrections. * multiple typesetting fixes only required due to certain archaic eccentricities of LaTeX. * a couple of minor python PEP8 compliance corrections. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 22b47cc..46bd231 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -13,9 +13,10 @@ :CUSTOM_ID: intro :END: - Version: 0.0.1-alpha [2018-03-07 Wed] - Author: Ben McGinnes - Author GPG Key: DB4724E6FA4286C92B4E55C4321E4E2373590E5D + | Version: | 0.0.1-alpha | + | Author: | Ben McGinnes | + | Author GPG Key: | DB4724E6FA4286C92B4E55C4321E4E2373590E5D | + | Language: | English | This document provides basic instruction in how to use the GPGME Python bindings to programmatically leverage the GPGME library. @@ -349,7 +350,7 @@ Encrypting to multiple keys, in addition to a default key or a key configured to always encrypt to, is a little different and uses a - slightly different call to the op_encrypt call demonstrated in the + slightly different call to the =op_encrypt call= demonstrated in the previous section. The following example encrypts a message (=text=) to everyone with @@ -360,7 +361,7 @@ #+begin_src python import gpg - text=b"""Oh look, another test message. + 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 @@ -640,7 +641,7 @@ * Footnotes -[fn:1] Short_History.org and/or Short_History.html. +[fn:1] =Short_History.org= and/or =Short_History.html=. [fn:2] The =lang/python/docs/= directory in the GPGME source. commit 83b1336ceebb86e13a55bbf220df2d750f6b3ec6 Author: Ben McGinnes Date: Tue Mar 13 05:42:50 2018 +1100 doc: python bindings howto * Fixed an error in the encryption try/except statement. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 84be851..22b47cc 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -414,7 +414,9 @@ for i in range(len(e.recipients)): for n in range(len(rlogrus)): if rlogrus[n].fpr == e.recipients[i].fpr: - rlogrus.remove(e.recipients[i]) + rlogrus.remove(rlogrus[n]) + else: + pass try: cipher = c.encrypt(text, recipients=rlogrus, add_encrypt_to=True) except: ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 12 21:44:49 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 12 Mar 2018 21:44:49 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-75-g484e9a6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 484e9a6229ac9c80c6be4df638bce711f08a74c6 (commit) from a8f48b6f577d562c25fd0191c0cc2cc8e96078c1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 484e9a6229ac9c80c6be4df638bce711f08a74c6 Author: Ben McGinnes Date: Tue Mar 13 07:42:04 2018 +1100 doc: python bindings howto * updated multi-encryption final example to be complete. * second example shows most likely method of reading plaintext. * updated example filenames to stick with running gag (i.e. secret_plans.txt). diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 46bd231..622475f 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -384,7 +384,7 @@ cipher = c.encrypt(text, recipients=rlogrus, sign=False, always_trust=True) - afile = open("encrypted_file.txt.asc", "wb") + afile = open("secret_plans.txt.asc", "wb") afile.write(cipher[0]) afile.close() #+end_src @@ -409,6 +409,20 @@ somewhat with something more like this: #+begin_src python + import gpg + + afile = open("secret_plans.txt", "rb") + text = afile.read() + afile.close() + + c = gpg.Context(armor=True) + rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) + rlogrus = [] + + for i in range(len(rpattern)): + if rpattern[i].can_encrypt == 1: + rlogrus.append(rpattern[i]) + try: cipher = c.encrypt(text, recipients=rlogrus, add_encrypt_to=True) except gpg.errors.InvalidRecipients as e: @@ -422,6 +436,10 @@ cipher = c.encrypt(text, recipients=rlogrus, add_encrypt_to=True) except: pass + + afile = open("secret_plans.txt.asc", "wb") + afile.write(cipher[0]) + afile.close() #+end_src This will attempt to encrypt to all the keys searched for, then ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 12 21:50:52 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 12 Mar 2018 21:50:52 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-76-g36dfbdf Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 36dfbdffea60c529a6d1e1ff3e507be016b6a0f6 (commit) from 484e9a6229ac9c80c6be4df638bce711f08a74c6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 36dfbdffea60c529a6d1e1ff3e507be016b6a0f6 Author: Ben McGinnes Date: Tue Mar 13 07:49:42 2018 +1100 doc: python bindings howto * Fixed a spelling error in the key counting text. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 622475f..979ffa0 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -607,8 +607,9 @@ :END: Counting the number of keys in your public keybox (=pubring.kbx=), - the format shich has superceded the old keyring format - (=pubring.gpg= and =secring.gpg=) is a very simple task. + the format which has superceded the old keyring format + (=pubring.gpg= and =secring.gpg=), or the number of secret keys is + a very simple task. #+begin_src python import gpg ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 12 22:29:58 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 12 Mar 2018 22:29:58 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-77-gf81adeb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via f81adeba992a9fd3b5a199e9a2e242a0f53cf639 (commit) from 36dfbdffea60c529a6d1e1ff3e507be016b6a0f6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f81adeba992a9fd3b5a199e9a2e242a0f53cf639 Author: Ben McGinnes Date: Tue Mar 13 08:26:22 2018 +1100 doc: python bindings howto * Added a miscellaneous work-arounds section at the end. * Included code in said miscellaneous section for accessing the groups specified in a gpg.conf file. * It's a bit ugly since it does require subprocess (but not call, Popen or shell access and only accesses one command). diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 979ffa0..4d02f97 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -631,6 +631,56 @@ #+end_src +* Miscellaneous work-arounds + :PROPERTIES: + :CUSTOM_ID: cheats-and-hacks + :END: + +** Group lines + :PROPERTIES: + :CUSTOM_ID: group-lines + :END: + + There is not yet an easy way to access groups configured in the + gpg.conf file from within GPGME. As a consequence these central + groupings of keys cannot be shared amongst multiple programs, such + as MUAs readily. + + The following code, however, provides a work-around for obtaining + this information in Python. + + #+begin_src python + import subprocess + + lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines() + + for i in range(len(lines)): + if lines[i].startswith("group") is True: + line = lines[i] + else: + pass + + groups = line.split(":")[-1].replace('"', '').split(',') + + group_lines = groups + for i in range(len(group_lines)): + group_lines[i] = group_lines[i].split("=") + + group_lists = group_lines + for i in range(len(group_lists)): + group_lists[i][1] = group_lists[i][1].split() + #+end_src + + The result of that code is that =group_lines= is a list of lists + where =group_lines[i][0]= is the name of the group and + =group_lines[i][1]= is the key IDs of the group as a string. + + The =group_lists= result is very similar in that it is a list of + lists. The first part, =group_lists[i][0]= matches + =group_lines[i][0]= as the name of the group, but + =group_lists[i][1]= is the key IDs of the group as a string. + + * Copyright and Licensing :PROPERTIES: :CUSTOM_ID: copyright-and-license ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 13 01:51:52 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Tue, 13 Mar 2018 01:51:52 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-78-gc27a7a3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via c27a7a3f994dad0eccee890185582f4350fbf233 (commit) from f81adeba992a9fd3b5a199e9a2e242a0f53cf639 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c27a7a3f994dad0eccee890185582f4350fbf233 Author: Ben McGinnes Date: Tue Mar 13 11:50:38 2018 +1100 doc: python bindings howto * Added text description for the decryption example. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 4d02f97..40d2814 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -451,9 +451,14 @@ :CUSTOM_ID: howto-basic-encryption :END: - Decrypting something encrypted to a key in one's secret keyring - (will display some extra data you normally wouldn't show, but which - may be of use): + Decrypting something encrypted to a key in one's secret keyring is + fairly straight forward. + + In this example code, however, preconfiguring either + =gpg.Context()= or =gpg.core.Context()= as =c= is unnecessary + because there is no need to modify the Context prior to conducting + the decryption and since the Context is only used once, setting it + to =c= simply adds lines for no gain. #+begin_src python import os.path @@ -481,6 +486,11 @@ pass #+end_src + The data available in plaintext in this example is the decrypted + content as a byte object in =plaintext[0]=, the recipient key IDs + and algorithms in =plaintext[1]= and the results of verifying any + signatures of the data in =plaintext[0]=. + ** Signing text :PROPERTIES: @@ -550,7 +560,7 @@ #+begin_src python import gpg - tfile = open("/path/to/statement.txt", "r") + tfile = open("/path/to/statement.txt", "rb") text = tfile.read() tfile.close() ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 13 04:55:34 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 13 Mar 2018 04:55:34 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-14-gc84bae6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via c84bae69e9e02923f7180e09d161cb0b13257436 (commit) via 71e5282c25ba812c7091e587edd721839bc4c2ac (commit) from 655f0b9ad0138e6f960bf4befaf0eea569256614 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c84bae69e9e02923f7180e09d161cb0b13257436 Author: NIIBE Yutaka Date: Tue Mar 13 12:53:49 2018 +0900 scd: After fatal error, shutdown a reader. * scd/apdu.c (pcsc_send_apdu): Notify main loop after fatal errors. -- GnuPG-bug-id: 3825 Signed-off-by: NIIBE Yutaka diff --git a/scd/apdu.c b/scd/apdu.c index 2ae6253..cd98cc9 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -229,6 +229,7 @@ static npth_mutex_t reader_table_lock; #define PCSC_E_READER_UNAVAILABLE 0x80100017 #define PCSC_E_NO_SERVICE 0x8010001D #define PCSC_E_SERVICE_STOPPED 0x8010001E +#define PCSC_W_RESET_CARD 0x80100068 #define PCSC_W_REMOVED_CARD 0x80100069 /* Fix pcsc-lite ABI incompatibility. */ @@ -751,6 +752,14 @@ pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, log_error ("pcsc_transmit failed: %s (0x%lx)\n", pcsc_error_string (err), err); + /* Handle fatal errors which require shutdown of reader. */ + if (err == PCSC_E_NOT_TRANSACTED || err == PCSC_W_RESET_CARD + || err == PCSC_W_REMOVED_CARD) + { + reader_table[slot].pcsc.current_state = PCSC_STATE_UNAWARE; + scd_kick_the_loop (); + } + return pcsc_error_to_sw (err); } commit 71e5282c25ba812c7091e587edd721839bc4c2ac Author: NIIBE Yutaka Date: Tue Mar 13 12:05:57 2018 +0900 scd: Fix for GNU/Linux suspend/resume. * configure.ac (require_pipe_to_unblock_pselect): Default is "yes". * scd/scdaemon.c (scd_kick_the_loop): Minor clean up. -- Normally SIGCONT or SIGUSR2 works for unblocking pselect. But on my machine with GNU/Linux, when a machine is suspend/resume-ed, pselect keeps blocked, while signal itself is delivered. It's better to use pipe. Signed-off-by: NIIBE Yutaka diff --git a/configure.ac b/configure.ac index 8252db9..086af12 100644 --- a/configure.ac +++ b/configure.ac @@ -639,7 +639,7 @@ have_android_system=no use_simple_gettext=no use_ldapwrapper=yes mmap_needed=yes -require_pipe_to_unblock_pselect=no +require_pipe_to_unblock_pselect=yes case "${host}" in *-mingw32*) # special stuff for Windoze NT @@ -654,6 +654,7 @@ case "${host}" in have_w32_system=yes require_iconv=no use_ldapwrapper=no # Fixme: Do this only for CE. + require_pipe_to_unblock_pselect=no case "${host}" in *-mingw32ce*) have_w32ce_system=yes diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 91b5599..e63aca7 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -1206,18 +1206,16 @@ start_connection_thread (void *arg) void scd_kick_the_loop (void) { - int ret; - /* Kick the select loop. */ #ifdef HAVE_W32_SYSTEM - ret = SetEvent (the_event); + int ret = SetEvent (the_event); if (ret == 0) log_error ("SetEvent for scd_kick_the_loop failed: %s\n", w32_strerror (-1)); #elif defined(HAVE_PSELECT_NO_EINTR) write (notify_fd, "", 1); #else - ret = kill (main_thread_pid, SIGCONT); + int ret = kill (main_thread_pid, SIGCONT); if (ret < 0) log_error ("SetEvent for scd_kick_the_loop failed: %s\n", gpg_strerror (gpg_error_from_syserror ())); ----------------------------------------------------------------------- Summary of changes: configure.ac | 3 ++- scd/apdu.c | 9 +++++++++ scd/scdaemon.c | 6 ++---- 3 files changed, 13 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 13 05:04:36 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Tue, 13 Mar 2018 05:04:36 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-79-gf29bda8 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via f29bda8d7146b4bc0bf73d6e613131545ff86b73 (commit) from c27a7a3f994dad0eccee890185582f4350fbf233 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f29bda8d7146b4bc0bf73d6e613131545ff86b73 Author: Ben McGinnes Date: Tue Mar 13 15:03:11 2018 +1100 doc: python bindings howto * Signatures have changed as a result of the recent update from Justus. * Sample code updated. * Text to follow later. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 40d2814..5d259a6 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -503,13 +503,13 @@ #+begin_src python import gpg - text = """Declaration of ... something. + text = b"""Declaration of ... something. """ c = gpg.Context() c.armor = True - signed = c.sign(text, mode=mode.NORMAL) + signed = c.sign(text, mode=0) afile = open("/path/to/statement.txt.asc", "w") for i in range(len(signed[0].splitlines())): @@ -527,8 +527,7 @@ """ c = gpg.Context() - c.armor = True - signed = c.sign(text, mode=mode.CLEAR) + signed = c.sign(text, mode=2) afile = open("/path/to/statement.txt.asc", "w") for i in range(len(signed[0].splitlines())): @@ -547,7 +546,7 @@ c = gpg.Context() c.armor = True - signed = c.sign(text, mode=mode.DETACH) + signed = c.sign(text, mode=1) afile = open("/path/to/statement.txt.asc", "w") for i in range(len(signed[0].splitlines())): @@ -566,7 +565,7 @@ c = gpg.Context() c.armor = True - signed = c.sign(text, mode=mode.DETACH) + signed = c.sign(text, mode=1) afile = open("/path/to/statement.txt.sig", "wb") afile.write(signed[0]) ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 13 09:22:19 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Tue, 13 Mar 2018 09:22:19 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-81-gc92da2c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via c92da2c7eb148ce9fb06495a8470dd9caf662f9a (commit) via e489ddd08af29fdad8db8aa0aec0c314daa3678c (commit) from f29bda8d7146b4bc0bf73d6e613131545ff86b73 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c92da2c7eb148ce9fb06495a8470dd9caf662f9a Author: Ben McGinnes Date: Tue Mar 13 19:20:44 2018 +1100 doc: python bindings howto * Added key selection for specifying signing key or keys. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 5ee3a82..ea1b765 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -532,9 +532,7 @@ :CUSTOM_ID: howto-basic-signing :END: - Need to determine whether or not to include clearsigning and - detached signing here or give them separate sections. Yes, section - them. + X *** Signing key selection :PROPERTIES: @@ -547,6 +545,19 @@ available it may be necessary to specify the key or keys with which to sign messages and files. + #+begin_src python + import gpg + + logrus = input("Enter the email address or string to match signing keys to: ") + hancock = gpg.Context().keylist(pattern=logrus, secret=True) + sig_src = list(hancock) + #+end_src + + The signing examples in the following sections include the + explicitly designated =signers= parameter in two of the five + examples; once where the resulting signature would be ASCII + armoured and once where it would not be armoured. + *** Normal or default signing messages or files :PROPERTIES: :CUSTOM_ID: howto-basic-signing-normal @@ -559,8 +570,7 @@ """ - c = gpg.Context() - c.armor = True + c = gpg.Context(armor=True, signers=sig_src) signed = c.sign(text, mode=0) afile = open("/path/to/statement.txt.asc", "wb") @@ -598,8 +608,7 @@ """ - c = gpg.Context() - c.armor = True + c = gpg.Context(armor=True) signed = c.sign(text, mode=1) afile = open("/path/to/statement.txt.asc", "wb") @@ -617,7 +626,7 @@ text = tfile.read() tfile.close() - c = gpg.Context() + c = gpg.Context(signers=sig_src) signed = c.sign(text, mode=1) afile = open("/path/to/statement.txt.sig", "wb") commit e489ddd08af29fdad8db8aa0aec0c314daa3678c Author: Ben McGinnes Date: Tue Mar 13 18:32:30 2018 +1100 doc: python bindings howto * During the course of working out the updated signature methods, determined that key selection (including counting) will beed to be presented before the basic functions. * Moved "working with keys" up. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 5d259a6..5ee3a82 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -255,6 +255,41 @@ operation type has one. +* Working with keys + :PROPERTIES: + :CUSTOM_ID: howto-keys + :END: + +** Counting keys + :PROPERTIES: + :CUSTOM_ID: howto-basic-verification + :END: + + Counting the number of keys in your public keybox (=pubring.kbx=), + the format which has superceded the old keyring format + (=pubring.gpg= and =secring.gpg=), or the number of secret keys is + a very simple task. + + #+begin_src python + import gpg + + c = gpg.Context() + seckeys = c.keylist(pattern=None, secret=True) + pubkeys = c.keylist(pattern=None, secret=False) + + seclist = list(seckeys) + secnum = len(seclist) + + publist = list(pubkeys) + pubnum = len(publist) + + print(""" + Number of secret keys: {0} + Number of public keys: {1} + """.format(secnum, pubnum) + #+end_src + + * Basic Functions :PROPERTIES: :CUSTOM_ID: howto-the-basics @@ -492,13 +527,30 @@ signatures of the data in =plaintext[0]=. -** Signing text +** Signing text and files :PROPERTIES: :CUSTOM_ID: howto-basic-signing :END: Need to determine whether or not to include clearsigning and - detached signing here or give them separate sections. + detached signing here or give them separate sections. Yes, section + them. + +*** Signing key selection + :PROPERTIES: + :CUSTOM_ID: howto-basic-signing-signers + :END: + + By default GPGME and the Python bindings will use the default key + configured for the user invoking the GPGME API. If there is no + default key specified and there is more than one secret key + available it may be necessary to specify the key or keys with + which to sign messages and files. + +*** Normal or default signing messages or files + :PROPERTIES: + :CUSTOM_ID: howto-basic-signing-normal + :END: #+begin_src python import gpg @@ -511,36 +563,38 @@ c.armor = True signed = c.sign(text, mode=0) - afile = open("/path/to/statement.txt.asc", "w") + afile = open("/path/to/statement.txt.asc", "wb") for i in range(len(signed[0].splitlines())): - afile.write("{0}\n".format(signed[0].splitlines()[i].decode('utf-8'))) + afile.write("{0}\n".format(signed[0].splitlines()[i])) afile.close() #+end_src - Clearsigning: - #+begin_src python import gpg - text = """Declaration of ... something. - - """ + tfile = open("/path/to/statement.txt", "rb") + text = tfile.read() + tfile.close() c = gpg.Context() - signed = c.sign(text, mode=2) + signed = c.sign(text, mode=0) - afile = open("/path/to/statement.txt.asc", "w") - for i in range(len(signed[0].splitlines())): - afile.write("{0}\n".format(signed[0].splitlines()[i].decode('utf-8'))) + afile = open("/path/to/statement.txt.sig", "wb") + afile.write(signed[0]) afile.close() #+end_src +*** Detached signing messages and files + :PROPERTIES: + :CUSTOM_ID: howto-basic-signing-detached + :END: + Detached ASCII Armoured signing: #+begin_src python import gpg - text = """Declaration of ... something. + text = b"""Declaration of ... something. """ @@ -548,9 +602,9 @@ c.armor = True signed = c.sign(text, mode=1) - afile = open("/path/to/statement.txt.asc", "w") + afile = open("/path/to/statement.txt.asc", "wb") for i in range(len(signed[0].splitlines())): - afile.write("{0}\n".format(signed[0].splitlines()[i].decode('utf-8'))) + afile.write("{0}\n".format(signed[0].splitlines()[i])) afile.close() #+end_src @@ -564,7 +618,6 @@ tfile.close() c = gpg.Context() - c.armor = True signed = c.sign(text, mode=1) afile = open("/path/to/statement.txt.sig", "wb") @@ -572,6 +625,27 @@ afile.close() #+end_src +*** Clearsigning messages or text + :PROPERTIES: + :CUSTOM_ID: howto-basic-signing-clear + :END: + + #+begin_src python + import gpg + + text = """Declaration of ... something. + + """ + + c = gpg.Context() + signed = c.sign(text, mode=2) + + afile = open("/path/to/statement.txt.asc", "w") + for i in range(len(signed[0].splitlines())): + afile.write("{0}\n".format(signed[0].splitlines()[i].decode('utf-8'))) + afile.close() + #+end_src + ** Signature verification :PROPERTIES: @@ -605,41 +679,6 @@ #+end_src -* Working with keys - :PROPERTIES: - :CUSTOM_ID: howto-keys - :END: - -** Counting keys - :PROPERTIES: - :CUSTOM_ID: howto-basic-verification - :END: - - Counting the number of keys in your public keybox (=pubring.kbx=), - the format which has superceded the old keyring format - (=pubring.gpg= and =secring.gpg=), or the number of secret keys is - a very simple task. - - #+begin_src python - import gpg - - c = gpg.Context() - seckeys = c.keylist(pattern=None, secret=True) - pubkeys = c.keylist(pattern=None, secret=False) - - seclist = list(seckeys) - secnum = len(seclist) - - publist = list(pubkeys) - pubnum = len(publist) - - print(""" - Number of secret keys: {0} - Number of public keys: {1} - """.format(secnum, pubnum) - #+end_src - - * Miscellaneous work-arounds :PROPERTIES: :CUSTOM_ID: cheats-and-hacks ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 164 +++++++++++++++++++++----------- 1 file changed, 106 insertions(+), 58 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 13 10:04:55 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 13 Mar 2018 10:04:55 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.27-248-gc0d331c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via c0d331c063842ab4352e616269788b7c71d63e02 (commit) from 863948ab29d1016a271fd7e6d48af316dad4e939 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c0d331c063842ab4352e616269788b7c71d63e02 Author: Werner Koch Date: Tue Mar 13 09:57:46 2018 +0100 core: Fix regression due to not exporting the process API. -- Fixes-commit: 0e503cae75cb1a6aa257228a65941b7630ff35d6 Signed-off-by: Werner Koch diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index e78a6f1..11d4950 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -1029,12 +1029,12 @@ void _gpgrt_log_assert (const char *expr, const char *file, int line, /* * Spawn functions (Not yet available) */ -#if 0 - #define GPGRT_SPAWN_NONBLOCK 16 /* Set the streams to non-blocking. */ #define GPGRT_SPAWN_RUN_ASFW 64 /* Use AllowSetForegroundWindow on W32. */ #define GPGRT_SPAWN_DETACHED 128 /* Start the process in the background. */ +#if 0 + /* Function and convenience macros to create pipes. */ gpg_err_code_t gpgrt_make_pipe (int filedes[2], gpgrt_stream_t *r_fp, int direction, int nonblock); diff --git a/src/visibility.h b/src/visibility.h index b33744d..f37555a 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -188,6 +188,7 @@ MARK_VISIBLE (gpgrt_log_clock) MARK_VISIBLE (gpgrt_log_flush) MARK_VISIBLE (_gpgrt_log_assert) +#if 0 MARK_VISIBLE (gpgrt_make_pipe) MARK_VISIBLE (gpgrt_spawn_process) MARK_VISIBLE (gpgrt_spawn_process_fd) @@ -196,7 +197,7 @@ MARK_VISIBLE (gpgrt_wait_process) MARK_VISIBLE (gpgrt_wait_processes) MARK_VISIBLE (gpgrt_kill_process) MARK_VISIBLE (gpgrt_release_process) - +#endif #undef MARK_VISIBLE ----------------------------------------------------------------------- Summary of changes: src/gpg-error.h.in | 4 ++-- src/visibility.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 13 11:52:32 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 13 Mar 2018 11:52:32 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.27-249-ga27a09e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via a27a09eb62507dcf1fd98d91fd7c5888544c59ed (commit) from c0d331c063842ab4352e616269788b7c71d63e02 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a27a09eb62507dcf1fd98d91fd7c5888544c59ed Author: Werner Koch Date: Tue Mar 13 11:36:17 2018 +0100 build: Update copyright notices and remove gpgscm from the release. -- Signed-off-by: Werner Koch diff --git a/AUTHORS b/AUTHORS index a8e8abe..5d323eb 100644 --- a/AUTHORS +++ b/AUTHORS @@ -13,6 +13,15 @@ range, inclusive, is a copyrightable year that would otherwise be listed individually. +List of Copyright holders +========================= + + Copyright (C) 2001-2018 g10 Code GmbH + Copyright (C) 1995-2017 Free Software Foundation, Inc. + Copyright (C) 1998-2006, 2008-2017 Werner Koch + Copyright (C) 2014 Jedi Lin + + Authors with a DCO ================== diff --git a/Makefile.am b/Makefile.am index 856f44c..56145f7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -34,11 +34,11 @@ else lang_subdirs = endif -if BUILD_GPGSCM -doc = gpgscm -else -doc = -endif +#if BUILD_GPGSCM +#doc = gpgscm +#else +#doc = +#endif if BUILD_DOC doc = doc @@ -52,7 +52,7 @@ else tests = endif -SUBDIRS = m4 src $(gpgscm) $(doc) $(tests) po $(lang_subdirs) +SUBDIRS = m4 src $(doc) $(tests) po $(lang_subdirs) dist-hook: gen-ChangeLog diff --git a/NEWS b/NEWS index 687e185..a275f5f 100644 --- a/NEWS +++ b/NEWS @@ -4,8 +4,56 @@ Noteworthy changes in version 1.28 (unreleased) [C22/A22/R_] * The formerly internal yat2m tool is now installed during a native build. + * The new files gpgrt.m4 and gpgrt-config are now installed. They + can be used instead of gpg-error.m4 and gpg-error-config. + * Interface changes relative to the 1.27 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gpgrt_get_errorcount New API. + gpgrt_inc_errorcount New API. + gpgrt_log_set_sink New API. + gpgrt_log_set_socket_dir_cb New API. + gpgrt_log_set_pid_suffix_cb New API. + gpgrt_log_set_prefix New API. + gpgrt_log_get_prefix New API. + gpgrt_log_test_fd New API. + gpgrt_log_get_fd New API. + gpgrt_log_get_stream New API. + gpgrt_log New API. + gpgrt_logv New API. + gpgrt_logv_prefix New API. + gpgrt_log_string New API. + gpgrt_log_info New API. + gpgrt_log_error New API. + gpgrt_log_fatal New API. + gpgrt_log_bug New API. + gpgrt_log_debug New API. + gpgrt_log_debug_string New API. + gpgrt_log_printf New API. + gpgrt_log_flush New API. + gpgrt_log_printhex New API. + gpgrt_log_clock New API. + gpgrt_assert New macro. + _gpgrt_log_assert New internal API. + GPGRT_LOGLVL_BEGIN New const. + GPGRT_LOGLVL_CONT New const. + GPGRT_LOGLVL_INFO New const. + GPGRT_LOGLVL_WARN New const. + GPGRT_LOGLVL_ERROR New const. + GPGRT_LOGLVL_FATAL New const. + GPGRT_LOGLVL_BUG New const. + GPGRT_LOGLVL_DEBUG New const. + gpgrt_realloc New API. + gpgrt_malloc New API. + gpgrt_calloc New API. + gpgrt_strdup New API. + gpgrt_strconcat New API. + gpgrt_w32_reg_query_string New API. + gpgrt_getenv New API. + gpgrt_setenv New API. + gpgrt_mkdir New API. + gpgrt_chdir New API. + gpgrt_getcwd New API. Noteworthy changes in version 1.27 (2017-02-28) [C22/A22/R0] diff --git a/README b/README index fd6e1a8..9cc5de0 100644 --- a/README +++ b/README @@ -20,6 +20,8 @@ components are - A lean gettext and iconv implementation for Windows. + - Log functions + More components will be added over time. Most functions are prefixed with "gpgrt" (GnuPG Run Time) instead of "gpg_err" to indicate the long term plan to rename this library to gpgrt. diff --git a/configure.ac b/configure.ac index 992d1bd..04715e9 100644 --- a/configure.ac +++ b/configure.ac @@ -543,12 +543,12 @@ fi # Eventually we will reverse the meaning of that option. # build_gpgscm=no -AC_MSG_CHECKING([whether to build gpgscm]) -AC_ARG_ENABLE(gpgscm, - AC_HELP_STRING([--enable-gpgscm], - [build the gpgscm tool]), - build_gpgscm=$enableval, build_gpgscm=no) -AC_MSG_RESULT($build_gpgscm) +#AC_MSG_CHECKING([whether to build gpgscm]) +#AC_ARG_ENABLE(gpgscm, +# AC_HELP_STRING([--enable-gpgscm], +# [build the gpgscm tool]), +# build_gpgscm=$enableval, build_gpgscm=no) +#AC_MSG_RESULT($build_gpgscm) AM_CONDITIONAL([BUILD_GPGSCM], [test "x$build_gpgscm" != xno]) @@ -617,7 +617,7 @@ AM_CONDITIONAL([BUILD_TESTS], [test "x$build_tests" != xno]) # AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([doc/Makefile po/Makefile.in m4/Makefile]) -AC_CONFIG_FILES([src/Makefile gpgscm/Makefile tests/Makefile]) +AC_CONFIG_FILES([src/Makefile tests/Makefile]) AC_CONFIG_FILES([lang/Makefile lang/cl/Makefile lang/cl/gpg-error.asd]) AC_CONFIG_FILES([src/versioninfo.rc src/gpg-error.w32-manifest]) AC_CONFIG_FILES([src/gpg-error-config], [chmod +x src/gpg-error-config]) diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index 11d4950..f942098 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -1,5 +1,5 @@ /* gpg-error.h or gpgrt.h - Public interface to libgpg-error. -*- c -*- - * Copyright (C) 2003-2004, 2010, 2013-2017 g10 Code GmbH + * Copyright (C) 2001-2018 g10 Code GmbH * * This file is part of libgpg-error. * diff --git a/src/version.c b/src/version.c index eaeedf8..94b75af 100644 --- a/src/version.c +++ b/src/version.c @@ -38,8 +38,8 @@ cright_blurb (void) { static const char blurb[] = "\n\n" - "This is Libgpg-error " PACKAGE_VERSION " - An error code library\n" - "Copyright 2003-2004, 2010, 2013-2017 g10 Code GmbH\n" + "This is Libgpg-error " PACKAGE_VERSION " - A runtime library\n" + "Copyright 2001-2018 g10 Code GmbH\n" "\n" "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n" "\n\n"; ----------------------------------------------------------------------- Summary of changes: AUTHORS | 9 +++++++++ Makefile.am | 12 ++++++------ NEWS | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ README | 2 ++ configure.ac | 14 +++++++------- src/gpg-error.h.in | 2 +- src/version.c | 4 ++-- 7 files changed, 75 insertions(+), 16 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 13 14:21:03 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 13 Mar 2018 14:21:03 +0100 Subject: [git] gnupg-doc - branch, master, updated. 8aaa4d783f38be7ad5d72df0451a8208b0712dbd Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 8aaa4d783f38be7ad5d72df0451a8208b0712dbd (commit) from f9098f2c036f638b1ccb82ee2ba29c91dd1e98ae (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8aaa4d783f38be7ad5d72df0451a8208b0712dbd Author: Werner Koch Date: Tue Mar 13 14:14:46 2018 +0100 swdb: Release libgpg-error 1.28 diff --git a/web/swdb.mac b/web/swdb.mac index afb3207..1c6bebf 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -141,11 +141,11 @@ # # LIBGPG-ERROR # -#+macro: libgpg_error_ver 1.27 -#+macro: libgpg_error_date 2017-02-28 -#+macro: libgpg_error_size 794k -#+macro: libgpg_error_sha1 a428758999ff573e62d06892e3d2c0b0f335787c -#+macro: libgpg_error_sha2 4f93aac6fecb7da2b92871bb9ee33032be6a87b174f54abf8ddf0911a22d29d2 +#+macro: libgpg_error_ver 1.28 +#+macro: libgpg_error_date 2018-03-13 +#+macro: libgpg_error_size 842k +#+macro: libgpg_error_sha1 2b9baae264f3e82ebe00dcd10bae3f2d64232c10 +#+macro: libgpg_error_sha2 3edb957744905412f30de3e25da18682cbe509541e18cd3b8f9df695a075da49 # ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 13 16:24:41 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Tue, 13 Mar 2018 16:24:41 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-83-ga10dcb4 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via a10dcb4f138eb5a21881cdbc4806c25129d4ae4e (commit) via 952b6042f78017c476452088261af8d352cfa729 (commit) from c92da2c7eb148ce9fb06495a8470dd9caf662f9a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a10dcb4f138eb5a21881cdbc4806c25129d4ae4e Author: Ben McGinnes Date: Wed Mar 14 02:21:44 2018 +1100 doc: python bindings howto * Added a section on key selection. * Included recommendation for using fingerprint when selecting one specific key. * Also included the most ironically amusing example of multiple key selection in a GPG guide. Hey, it's public data ... (heh). diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index ae9e9e7..ea4b111 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -285,9 +285,68 @@ :CUSTOM_ID: howto-keys :END: +** Key selection + :PROPERTIES: + :CUSTOM_ID: howto-keys-selection + :END: + + Selecting keys to encrypt to or to sign with will be a common + occurrence when working with GPGMe and the means available for + doing so are quite simple. + + They do depend on utilising a Context; however once the data is + recorded in another variable, that Context does not need to be the + same one which subsequent operations are performed. + + The easiest way to select a specific key is by searching for that + key's key ID or fingerprint, preferably the full fingerprint + without any spaces in it. A long key ID will probably be okay, but + is not advised and short key IDs are already a problem with some + being generated to match specific patterns. It does not matter + whether the pattern is upper or lower case. + + So this is the best method: + + #+begin_src python + import gpg + + k = gpg.Context().keylist(pattern="258E88DCBD3CD44D8E7AB43F6ECB6AF0DEADBEEF") + keys = list(k) + #+end_src + + This is passable and very likely to be common: + + #+begin_src python + import gpg + + k = gpg.Context().keylist(pattern="0x6ECB6AF0DEADBEEF") + keys = list(k) + #+end_src + + And this is a really bad idea: + + #+begin_src python + import gpg + + k = gpg.Context().keylist(pattern="0xDEADBEEF") + keys = list(k) + #+end_src + + Alternatively it may be that the intention is to create a list of + keys which all match a particular search string. For instance all + the addresses at a particular domain, like this: + + #+begin_src python + import gpg + + ncsc = gpg.Context().keylist(pattern="ncsc.mil") + nsa = list(ncsc) + #+end_src + + ** Counting keys :PROPERTIES: - :CUSTOM_ID: howto-basic-verification + :CUSTOM_ID: howto-keys-counting :END: Counting the number of keys in your public keybox (=pubring.kbx=), commit 952b6042f78017c476452088261af8d352cfa729 Author: Ben McGinnes Date: Wed Mar 14 01:41:21 2018 +1100 doc: python bindings howto * Added explanation of the ascendance of Python 3 over Python 2 in the guide to the intro. * Expanded key selection description so people know what not to include regarding key IDs with this key selection method. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index ea1b765..ae9e9e7 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -21,6 +21,31 @@ This document provides basic instruction in how to use the GPGME Python bindings to programmatically leverage the GPGME library. +** Python 2 versus Python 3 + :PROPERTIES: + :CUSTOM_ID: py2-vs-py3 + :END: + + Though the GPGME Python bindings themselves provide support for + both Python 2 and 3, the focus is unequivocally on Python 3 and + specifically from Python 3.4 and above. As a consequence all the + examples and instructions in this guide use Python 3 code. + + Much of it will work with Python 2, but much of it also deals with + Python 3 byte literals, particularly when reading and writing data. + Developers concentrating on Python 2.7, and possibly even 2.6, will + need to make the approprate modifications to support the older + string and unicode types as opposted to bytes. + + There are multiple reasons for concentrating on Python 3; some of + which relate to the immediate integration of these bindings, some + of which relate to longer term plans for both GPGME and the python + bindings and some of which relate to the impending EOL period for + Python 2.7. Essentially, though, there is little value in tying + the bindings to a version of the language which is a dead end and + the advantages offered by Python 3 over Python 2 make handling the + data types with which GPGME deals considerably easier. + * GPGME Concepts :PROPERTIES: @@ -59,7 +84,7 @@ =gpgme.h= generated when GPGME is compiled. This means that a version of the Python bindings is fundamentally - tied to the exact same version of GPGME used to gemerate that copy + tied to the exact same version of GPGME used to generate that copy of =gpgme.h=. ** Difference between the Python bindings and other GnuPG Python packages @@ -411,13 +436,13 @@ c = gpg.Context(armor=True) rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) - rlogrus = [] + logrus = [] for i in range(len(rpattern)): if rpattern[i].can_encrypt == 1: - rlogrus.append(rpattern[i]) + logrus.append(rpattern[i]) - cipher = c.encrypt(text, recipients=rlogrus, sign=False, always_trust=True) + cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) afile = open("secret_plans.txt.asc", "wb") afile.write(cipher[0]) @@ -429,7 +454,7 @@ be to change the =c.encrypt= line to this: #+begin_src python - cipher = c.encrypt(text, recipients=rlogrus, always_trust=True, + cipher = c.encrypt(text, recipients=logrus, always_trust=True, add_encrypt_to=True) #+end_src @@ -452,23 +477,23 @@ c = gpg.Context(armor=True) rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) - rlogrus = [] + logrus = [] for i in range(len(rpattern)): if rpattern[i].can_encrypt == 1: - rlogrus.append(rpattern[i]) + logrus.append(rpattern[i]) try: - cipher = c.encrypt(text, recipients=rlogrus, add_encrypt_to=True) + cipher = c.encrypt(text, recipients=logrus, add_encrypt_to=True) except gpg.errors.InvalidRecipients as e: for i in range(len(e.recipients)): - for n in range(len(rlogrus)): - if rlogrus[n].fpr == e.recipients[i].fpr: - rlogrus.remove(rlogrus[n]) + for n in range(len(logrus)): + if logrus[n].fpr == e.recipients[i].fpr: + logrus.remove(logrus[n]) else: pass try: - cipher = c.encrypt(text, recipients=rlogrus, add_encrypt_to=True) + cipher = c.encrypt(text, recipients=logrus, add_encrypt_to=True) except: pass @@ -532,7 +557,7 @@ :CUSTOM_ID: howto-basic-signing :END: - X + The following sections demonstrate how to specify *** Signing key selection :PROPERTIES: @@ -558,6 +583,12 @@ examples; once where the resulting signature would be ASCII armoured and once where it would not be armoured. + While it would be possible to enter a key ID or fingerprint here + to match a specific key, it is not possible to enter two + fingerprints and match two keys since the patten expects a string, + bytes or None and not a list. A string with two fingerprints + won't match any single key. + *** Normal or default signing messages or files :PROPERTIES: :CUSTOM_ID: howto-basic-signing-normal ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 118 ++++++++++++++++++++++++++++---- 1 file changed, 104 insertions(+), 14 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 13 16:43:24 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Tue, 13 Mar 2018 16:43:24 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-84-ga71205d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via a71205dc3b58970adf591b4e4553824a33f353db (commit) from a10dcb4f138eb5a21881cdbc4806c25129d4ae4e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a71205dc3b58970adf591b4e4553824a33f353db Author: Ben McGinnes Date: Wed Mar 14 02:40:41 2018 +1100 doc: python binding howto * Clarified which English dialects this is written in. * Translating to American can happen *after* it's done. ** The Yank version would probably want to change some of the examples anyway. * Began the description for normal/default signing. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index ea4b111..e4e2a74 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -16,7 +16,8 @@ | Version: | 0.0.1-alpha | | Author: | Ben McGinnes | | Author GPG Key: | DB4724E6FA4286C92B4E55C4321E4E2373590E5D | - | Language: | English | + | Language: | Australian English, British English | + | xml:lang: | en-AU, en-GB, en | This document provides basic instruction in how to use the GPGME Python bindings to programmatically leverage the GPGME library. @@ -653,6 +654,16 @@ :CUSTOM_ID: howto-basic-signing-normal :END: + The normal or default signing process is essentially the same as + is most often invoked when also encrypting a message or file. So + when the encryption component is not utilised, the result is to + produce an encoded and signed output which may or may not be ASCII + armoured and which may or may not also be compressed. + + By default compression will be used unless GnuPG detects that the + plaintext is already compressed. ASCII armouring will be + determined according to the value of =gpg.Context().armor=. + #+begin_src python import gpg ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 13 16:49:16 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 13 Mar 2018 16:49:16 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-88-g2f39fe2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 2f39fe219c6810b51a1b428a4618b861e2d427c1 (commit) via 6754d87330659d0cc47c5340fd17f358977fb3b3 (commit) from f63db085c5d86839bb5ed8b4203b4c7b5f28975e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2f39fe219c6810b51a1b428a4618b861e2d427c1 Author: Andre Heinecke Date: Tue Mar 13 16:41:45 2018 +0100 Implement forwarding crypto mails with attachments * src/application-events.cpp (EVENT_SINK_INVOKE): Invalidate last mail in the next UI Loop. * src/mail.cpp (Mail::update_body): Safety check for parser. Keep parser around. (Mail::invalidate_last_mail): New. Clear cached last mail ptr. * src/mail.h: Update accordingly. * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Extend write event to detect forward of mails with attachments. * src/oomhelp.cpp (get_inline_body): New. * src/oomhelp.h: Update accordingly. * src/windowmessages.cpp, src/windowmessages.h (INVALIDATE_LAST_MAIL, REVERT_MAIL): New messages. * src/wks-helper.cpp (WKSHelper::send_mail): Check if last mail was invalidated. -- This is a first working draft of forwarding crypto mails with attachments. As we don't see the forward event before we get the write event (that we have to cancel usually) we now have some extra magic to detect the forward based on an ItemLoad of an empty mail in the same UI loop as the write event. This is pretty magic but it works. Once we detect the forward we save the mail and then immediately revert it and save it again. This has the usual uglyness of reverting (sync) but works and allows to forward mails. GnuPG-Bug-Id: T3836 diff --git a/src/application-events.cpp b/src/application-events.cpp index c000a86..1100934 100644 --- a/src/application-events.cpp +++ b/src/application-events.cpp @@ -33,6 +33,7 @@ #include "oomhelp.h" #include "mail.h" #include "gpgoladdin.h" +#include "windowmessages.h" /* Application Events */ BEGIN_EVENT_SINK(ApplicationEvents, IDispatch) @@ -91,6 +92,7 @@ EVENT_SINK_INVOKE(ApplicationEvents) log_debug ("%s:%s: Creating mail object for item: %p", SRCNAME, __func__, mailItem); new Mail (mailItem); + do_in_ui_thread_async (INVALIDATE_LAST_MAIL, nullptr); break; } case Quit: diff --git a/src/mail.cpp b/src/mail.cpp index 13b984d..d4e7e10 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -922,6 +922,12 @@ void find_and_replace(std::string& source, const std::string &find, void Mail::update_body() { + if (!m_parser) + { + TRACEPOINT; + return; + } + const auto error = m_parser->get_formatted_error (); if (!error.empty()) { @@ -1076,9 +1082,6 @@ Mail::parsing_done() SRCNAME, __func__); } - /* Invalidate UI to set the correct sig status. */ - m_parser = nullptr; - log_debug ("%s:%s: Delayed invalidate to update sigstate.", SRCNAME, __func__); CloseHandle(CreateThread (NULL, 0, delayed_invalidate_ui, (LPVOID) this, 0, @@ -2589,6 +2592,13 @@ Mail::get_last_mail () // static void +Mail::invalidate_last_mail () +{ + s_last_mail = nullptr; +} + +// static +void Mail::locate_all_crypto_recipients() { if (!opt.autoresolve) diff --git a/src/mail.h b/src/mail.h index f8cdbab..90f042e 100644 --- a/src/mail.h +++ b/src/mail.h @@ -92,6 +92,8 @@ public: */ static Mail* get_last_mail (); + static void invalidate_last_mail (); + /** @brief looks for existing Mail objects. @returns A reference to an existing mailitem or NULL in case none @@ -446,9 +448,9 @@ public: /** Get the mime data that should be used when sending. */ std::string get_override_mime_data () const { return m_mime_data; } + void update_body (); private: void update_categories (); - void update_body (); void update_sigstate (); LPDISPATCH m_mailitem; diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 2360789..7933826 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -480,6 +480,45 @@ EVENT_SINK_INVOKE(MailItemEvents) if (m_mail->is_crypto_mail () && !m_mail->needs_save ()) { + Mail *last_mail = Mail::get_last_mail (); + if (Mail::is_valid_ptr (last_mail)) + { + /* We want to identify here if there was a mail created that + should receive the contents of this mail. For this we check + for a write in the same loop as a mail creation. + Now when switching from one mail to another this is also what + happens. The new mail is loaded and the old mail is written. + To distinguish the two we check that the new mail does not have + an entryID, a Subject and No Size. Maybe just size or entryID + would be enough but better save then sorry. + + Security consideration: Worst case we pass the write here but + an unload follows before we get the scheduled revert. This + would leak plaintext. + + Similarly if we crash or Outlook is closed before we see this + revert. */ + const std::string lastSubject = last_mail->get_subject (); + char *lastEntryID = get_oom_string (last_mail->item (), "EntryID"); + int lastSize = get_oom_int (last_mail->item (), "Size"); + std::string lastEntryStr; + if (lastEntryID) + { + lastEntryStr = lastEntryID; + xfree (lastEntryID); + } + + if (!lastSize && !lastEntryStr.size () && !lastSubject.size ()) + { + log_debug ("%s:%s: Write in the same loop as empty load." + " Pass but schedule revert.", + SRCNAME, __func__); + + Mail::invalidate_last_mail (); + do_in_ui_thread_async (REVERT_MAIL, m_mail); + return S_OK; + } + } /* We cancel the write event to stop outlook from excessively syncing our changes. if smime support is disabled and we still have an smime diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp index ba3d89f..51d025b 100644 --- a/src/oomhelp.cpp +++ b/src/oomhelp.cpp @@ -2002,3 +2002,35 @@ get_sender_SenderEMailAddress (LPDISPATCH mailitem) xfree (type); return nullptr; } + +char * +get_inline_body () +{ + LPDISPATCH app = GpgolAddin::get_instance ()->get_application (); + if (!app) + { + TRACEPOINT; + return nullptr; + } + + LPDISPATCH explorer = get_oom_object (app, "ActiveExplorer"); + + if (!explorer) + { + TRACEPOINT; + return nullptr; + } + + LPDISPATCH inlineResponse = get_oom_object (explorer, "ActiveInlineResponse"); + gpgol_release (explorer); + + if (!inlineResponse) + { + return nullptr; + } + + char *body = get_oom_string (inlineResponse, "Body"); + gpgol_release (inlineResponse); + + return body; +} diff --git a/src/oomhelp.h b/src/oomhelp.h index 2af096b..cbc36ca 100644 --- a/src/oomhelp.h +++ b/src/oomhelp.h @@ -338,6 +338,9 @@ LPDISPATCH get_account_for_mail (const char *mbox); char *get_sender_CurrentUser (LPDISPATCH mailitem); char *get_sender_Sender (LPDISPATCH mailitem); char *get_sender_SenderEMailAddress (LPDISPATCH mailitem); + +/* Get the body of the active inline response */ +char *get_inline_body (void); #ifdef __cplusplus char *get_sender_SendUsingAccount (LPDISPATCH mailitem, bool *r_is_GSuite); } diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index b0e2311..af55d11 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -68,6 +68,34 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) mail->locate_keys(); break; } + case (REVERT_MAIL): + { + auto mail = (Mail*) ctx->data; + if (!Mail::is_valid_ptr (mail)) + { + log_debug ("%s:%s: Revert mail for mail which is gone.", + SRCNAME, __func__); + break; + } + + mail->set_needs_save (true); + /* Some magic here. Accessing any existing inline body cements + it. Otherwise updating the body through the revert also changes + the body of a inline mail. */ + char *inlineBody = get_inline_body (); + xfree (inlineBody); + + // Does the revert. + log_debug ("%s:%s: Revert mail. Invoking save.", + SRCNAME, __func__); + invoke_oom_method (mail->item (), "Save", NULL); + log_debug ("%s:%s: Revert mail. Save done. Updating body..", + SRCNAME, __func__); + mail->update_body (); + log_debug ("%s:%s: Revert mail done.", + SRCNAME, __func__); + break; + } case (INVALIDATE_UI): { log_debug ("%s:%s: Invalidating UI", @@ -77,6 +105,13 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) SRCNAME, __func__); break; } + case (INVALIDATE_LAST_MAIL): + { + log_debug ("%s:%s: Invalidating last mail", + SRCNAME, __func__); + Mail::invalidate_last_mail (); + break; + } case (CLOSE): { auto mail = (Mail*) ctx->data; @@ -114,6 +149,8 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } // Finaly this should pass. invoke_oom_method (mail->item (), "Send", NULL); + log_debug ("%s:%s: Send for %p completed.", + SRCNAME, __func__, mail); // Allow the WKS helper to queue a notification. WKSHelper::instance()->allow_notify (); break; diff --git a/src/windowmessages.h b/src/windowmessages.h index 979f0b4..56d9db8 100644 --- a/src/windowmessages.h +++ b/src/windowmessages.h @@ -50,6 +50,8 @@ typedef enum _gpgol_wmsg_type CRYPTO_DONE, /* Sign / Encrypt done. */ WKS_NOTIFY, /* Show a WKS Notification. */ BRING_TO_FRONT, /* Bring the active Outlook window to the front. */ + INVALIDATE_LAST_MAIL, + REVERT_MAIL, } gpgol_wmsg_type; typedef struct diff --git a/src/wks-helper.cpp b/src/wks-helper.cpp index 16d42ba..52c05c1 100644 --- a/src/wks-helper.cpp +++ b/src/wks-helper.cpp @@ -623,6 +623,12 @@ WKSHelper::send_mail (const std::string &mimeData) const a Hack! :-) */ auto last_mail = Mail::get_last_mail (); + if (!Mail::is_valid_ptr (last_mail)) + { + log_error ("%s:%s: Invalid last mail %p.", + SRCNAME, __func__, last_mail); + return -1; + } last_mail->set_override_mime_data (mimeData); last_mail->set_crypt_state (Mail::NeedsSecondAfterWrite); commit 6754d87330659d0cc47c5340fd17f358977fb3b3 Author: Andre Heinecke Date: Tue Mar 13 16:38:54 2018 +0100 Improve error handling on enc/sign errors * src/cryptcontroller.cpp (CryptController::do_crypto): Improve error handling. * src/mail.cpp (do_crypt): Use correct window and hide overlay / destroy crypter before showing the error. Add better text for general "Crypto failed" error. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index da23de4..da60c3b 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -517,7 +517,8 @@ CryptController::do_crypto () gpgol_message_box (nullptr, utf8_gettext ("Failure to resolve keys."), utf8_gettext ("GpgOL"), MB_OK); - return ret; + // Error handled, return as canceled. + return -2; } if (ret == -2) { @@ -539,7 +540,7 @@ CryptController::do_crypto () { log_error ("%s:%s: Failure to create context.", SRCNAME, __func__); - gpgol_message_box (nullptr, + gpgol_message_box (m_mail->get_window (), "Failure to create context.", utf8_gettext ("GpgOL"), MB_OK); return -1; diff --git a/src/mail.cpp b/src/mail.cpp index ba2b501..13b984d 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -748,20 +748,27 @@ do_crypt (LPVOID arg) return 0; } - mail->set_window_enabled (true); - if (rc == -1) { - gpgol_message_box (nullptr, - "Crypto failed", + mail->reset_crypter (); + crypter = nullptr; + gpgol_message_box (mail->get_window (), + utf8_gettext ("Sign / Encrypt failed.\n\n" + "This is usually caused by an error in your system.\n" + "Please refer to the Gpg4win compendium how to enable debugging in GpgOL," + "or ask your Administrator for support."), _("GpgOL"), MB_OK); } + + mail->set_window_enabled (true); + if (rc) { log_debug ("%s:%s: crypto failed for: %p with: %i", SRCNAME, __func__, arg, rc); mail->set_crypt_state (Mail::NoCryptMail); mail->reset_crypter (); + crypter = nullptr; gpgrt_lock_unlock (&dtor_lock); return rc; } ----------------------------------------------------------------------- Summary of changes: src/application-events.cpp | 2 ++ src/cryptcontroller.cpp | 5 +++-- src/mail.cpp | 31 ++++++++++++++++++++++++------- src/mail.h | 4 +++- src/mailitem-events.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/oomhelp.cpp | 32 ++++++++++++++++++++++++++++++++ src/oomhelp.h | 3 +++ src/windowmessages.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/windowmessages.h | 2 ++ src/wks-helper.cpp | 6 ++++++ 10 files changed, 151 insertions(+), 10 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 14 08:01:05 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 14 Mar 2018 08:01:05 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-1-gc0c5fb5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via c0c5fb51c5e87954af0b60fea7f543352998e1cc (commit) via e32342397eab85fed5ef709317cc50dc7cbc41a5 (commit) from a27a09eb62507dcf1fd98d91fd7c5888544c59ed (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c0c5fb51c5e87954af0b60fea7f543352998e1cc Author: Werner Koch Date: Tue Mar 13 13:42:17 2018 +0100 Post release updates -- diff --git a/NEWS b/NEWS index d30e913..fe66d2c 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.29 (unreleased) [C23/A23/R_] +----------------------------------------------- + + Noteworthy changes in version 1.28 (2018-03-13) [C23/A23/R0] ----------------------------------------------- diff --git a/configure.ac b/configure.ac index aca9300..1e648d1 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ min_automake_version="1.14" # See below for the LT versions. m4_define([mym4_package],[libgpg-error]) m4_define([mym4_major], [1]) -m4_define([mym4_minor], [28]) +m4_define([mym4_minor], [29]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag commit e32342397eab85fed5ef709317cc50dc7cbc41a5 Author: Werner Koch Date: Tue Mar 13 13:02:58 2018 +0100 Release 1.28 Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index a275f5f..d30e913 100644 --- a/NEWS +++ b/NEWS @@ -1,12 +1,16 @@ -Noteworthy changes in version 1.28 (unreleased) [C22/A22/R_] +Noteworthy changes in version 1.28 (2018-03-13) [C23/A23/R0] ----------------------------------------------- - * The formerly internal yat2m tool is now installed during a native + * The formerly internal yat2m tool is now installed for a native build. * The new files gpgrt.m4 and gpgrt-config are now installed. They can be used instead of gpg-error.m4 and gpg-error-config. + * New logging functions similar to those used by GnuPG. + + * New helper functions for platform abstraction. + * Interface changes relative to the 1.27 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgrt_get_errorcount New API. diff --git a/configure.ac b/configure.ac index 04715e9..aca9300 100644 --- a/configure.ac +++ b/configure.ac @@ -49,8 +49,8 @@ AC_INIT([mym4_package],[mym4_version], [https://bugs.gnupg.org]) # (Interfaces added: AGE++) # (Interfaces removed: AGE=0) # Note that added error codes don't constitute an interface change. -LIBGPG_ERROR_LT_CURRENT=22 -LIBGPG_ERROR_LT_AGE=22 +LIBGPG_ERROR_LT_CURRENT=23 +LIBGPG_ERROR_LT_AGE=23 LIBGPG_ERROR_LT_REVISION=0 ################################################ ----------------------------------------------------------------------- Summary of changes: NEWS | 12 ++++++++++-- configure.ac | 6 +++--- 2 files changed, 13 insertions(+), 5 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 14 10:14:45 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 14 Mar 2018 10:14:45 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-2-gc36a606 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via c36a60687976d98b54dac17f699dfca4918a737c (commit) from c0c5fb51c5e87954af0b60fea7f543352998e1cc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c36a60687976d98b54dac17f699dfca4918a737c Author: Werner Koch Date: Wed Mar 14 10:07:42 2018 +0100 core: Fix building on W64 * src/w32-add.h: Remove hack to define pid_t. * src/gpg-error.h.in: Eval macro to define pid_t. * src/mkheader.c (have_sys_types_h, sys_types_h_included): New. (parse_config_h): Test for sys/types.h. (write_special): Protect inclusion of sys/types.h. Define new macro 'define:pid_t'. -- Regression-due-to: 1865c0ba1769b407a3c504f1ab0a4278704a9fc1 Signed-off-by: Werner Koch diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index f942098..cc2e361 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -405,6 +405,7 @@ const char *gpgrt_check_version (const char *req_version); const char *gpg_error_check_version (const char *req_version); /* System specific type definitions. */ + at define:pid_t@ @define:gpgrt_ssize_t@ @define:gpgrt_off_t@ diff --git a/src/mkheader.c b/src/mkheader.c index 997cab5..2fc5fad 100644 --- a/src/mkheader.c +++ b/src/mkheader.c @@ -30,6 +30,7 @@ static const char *hdr_version_number; /* Values take from the supplied config.h. */ static int have_stdint_h; +static int have_sys_types_h; static int have_w32_system; static int have_w64_system; static char *replacement_for_off_type; @@ -37,6 +38,7 @@ static int use_posix_threads; /* Various state flags. */ static int stdint_h_included; +static int sys_types_h_included; /* The usual free wrapper. */ @@ -151,6 +153,8 @@ parse_config_h (const char *fname) continue; /* oops */ if (!strcmp (p1, "HAVE_STDINT_H")) have_stdint_h = 1; + else if (!strcmp (p1, "HAVE_SYS_TYPES_H")) + have_sys_types_h = 1; else if (!strcmp (p1, "HAVE_W32_SYSTEM")) have_w32_system = 1; else if (!strcmp (p1, "HAVE_W64_SYSTEM")) @@ -474,8 +478,12 @@ write_special (const char *fname, int lnr, const char *tag) } else { - fputs ("#include \n" - "typedef ssize_t gpgrt_ssize_t;\n", stdout); + if (!sys_types_h_included) + { + fputs ("#include \n", stdout); + sys_types_h_included = 1; + } + fputs ("typedef ssize_t gpgrt_ssize_t;\n", stdout); } } else if (!strcmp (tag, "api_ssize_t")) @@ -485,6 +493,30 @@ write_special (const char *fname, int lnr, const char *tag) else fputs ("ssize_t", stdout); } + else if (!strcmp (tag, "define:pid_t")) + { + if (have_sys_types_h) + { + if (!sys_types_h_included) + { + fputs ("#include \n", stdout); + sys_types_h_included = 1; + } + } + else if (have_w64_system) + { + if (!stdint_h_included && have_stdint_h) + { + fputs ("#include \n", stdout); + stdint_h_included = 1; + } + fputs ("typedef int64_t pid_t\n", stdout); + } + else + { + fputs ("typedef int pid_t\n", stdout); + } + } else if (!strcmp (tag, "include:err-sources")) { write_sources_or_codes (NULL); diff --git a/src/w32-add.h b/src/w32-add.h index 6f9f12a..07e3c7d 100644 --- a/src/w32-add.h +++ b/src/w32-add.h @@ -3,10 +3,6 @@ ## peculiarity of the script the first used line must not ## start with a hash mark. -/* Fixme: This is a quick hack. We need to check whether the compiler - * actually in use already knows that type. */ -typedef int pid_t; - /* Decide whether to use the format_arg attribute. */ #if _GPG_ERR_GCC_VERSION > 20800 # define _GPG_ERR_ATTR_FORMAT_ARG(a) __attribute__ ((__format_arg__ (a))) ----------------------------------------------------------------------- Summary of changes: src/gpg-error.h.in | 1 + src/mkheader.c | 36 ++++++++++++++++++++++++++++++++++-- src/w32-add.h | 4 ---- 3 files changed, 35 insertions(+), 6 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 14 10:42:24 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 14 Mar 2018 10:42:24 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-86-gef27f37 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via ef27f3781a37e264d0eb7d1745eb2c804ec062c4 (commit) via 423fdcd4653cb01f07f2b0e72cfcf49554930f70 (commit) from a71205dc3b58970adf591b4e4553824a33f353db (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ef27f3781a37e264d0eb7d1745eb2c804ec062c4 Author: Ben McGinnes Date: Wed Mar 14 20:40:50 2018 +1100 doc: python bindings todo * minor phrasing fix. diff --git a/lang/python/docs/TODO.org b/lang/python/docs/TODO.org index 21d2216..e85315a 100644 --- a/lang/python/docs/TODO.org +++ b/lang/python/docs/TODO.org @@ -83,8 +83,8 @@ :CUSTOM_ID: howto-s-mime :END: - Eventually add some of this, but it the OpenPGP details are far - more important at the moment. + Eventually add some of this, but the OpenPGP details are far more + important at the moment. ** TODO Documentation SWIG :PROPERTIES: commit 423fdcd4653cb01f07f2b0e72cfcf49554930f70 Author: Ben McGinnes Date: Wed Mar 14 20:36:30 2018 +1100 doc: python bindings howto * Added recommended method of single encryption with description. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index e4e2a74..360bce9 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -565,6 +565,72 @@ This will attempt to encrypt to all the keys searched for, then remove invalid recipients if it fails and try again. +**** Encrypting to one key using the second method + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption-monogamous + :END: + + This example re-creates the first encryption example except it + uses the same =encrypt= method used in the subsequent examples + instead of the =op_encrypt= method. This means that, unlike the + =op_encrypt= method, it /must/ use byte literal input data. + + #+begin_src python + import gpg + + rkey = "0x12345678DEADBEEF" + text = b"""Some text to test with. + + 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=rkey, secret=False)) + logrus = [] + + for i in range(len(rpattern)): + if rpattern[i].can_encrypt == 1: + logrus.append(rpattern[i]) + + cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) + + afile = open("secret_plans.txt.asc", "wb") + afile.write(cipher[0]) + afile.close() + #+end_src + + With one or two exceptions, this method will probably prove to be + easier to implement than the first method and thus it is the + recommended encryption method. Though it is even more likely to + be used like this: + + #+begin_src python + import gpg + + rkey = "0x12345678DEADBEEF" + + afile = open("secret_plans.txt", "rb") + text = afile.read() + afile.close() + + c = gpg.Context(armor=True) + rpattern = list(c.keylist(pattern=rkey, secret=False)) + logrus = [] + + for i in range(len(rpattern)): + if rpattern[i].can_encrypt == 1: + logrus.append(rpattern[i]) + + cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) + + afile = open("secret_plans.txt.asc", "wb") + afile.write(cipher[0]) + afile.close() + #+end_src + ** Decryption :PROPERTIES: ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 66 +++++++++++++++++++++++++++++++++ lang/python/docs/TODO.org | 4 +- 2 files changed, 68 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 14 12:02:13 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 14 Mar 2018 12:02:13 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-89-g4662ad2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 4662ad2828cbba6f3b4c0825439ebaa3db83f6c9 (commit) from 2f39fe219c6810b51a1b428a4618b861e2d427c1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4662ad2828cbba6f3b4c0825439ebaa3db83f6c9 Author: Andre Heinecke Date: Wed Mar 14 11:16:03 2018 +0100 Further extend debugging around mail dtor * src/mail.cpp (do_crypt): Note when ui thread is done. * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Log when deletion is done in unload. * src/windowmessages.cpp (gpgol_window_proc): Log when crypto done handler is complete. (do_async): Log invocation. diff --git a/src/mail.cpp b/src/mail.cpp index d4e7e10..d8a160d 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -779,6 +779,8 @@ do_crypt (LPVOID arg) gpgrt_lock_unlock (&dtor_lock); // This deletes the Mail in Outlook 2010 do_in_ui_thread (CRYPTO_DONE, arg); + log_debug ("%s:%s: UI thread finished for %p", + SRCNAME, __func__, arg); } else { diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 7933826..de4c274 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -611,6 +611,8 @@ EVENT_SINK_INVOKE(MailItemEvents) log_debug ("%s:%s: Removing Mail for message: %p.", SRCNAME, __func__, m_object); delete m_mail; + log_oom_extra ("%s:%s: deletion done", + SRCNAME, __func__); return S_OK; } case Forward: diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index af55d11..9d96956 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -153,6 +153,8 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) SRCNAME, __func__, mail); // Allow the WKS helper to queue a notification. WKSHelper::instance()->allow_notify (); + log_debug ("%s:%s: Crypto done handler completed.", + SRCNAME, __func__); break; } case (BRING_TO_FRONT): @@ -251,6 +253,8 @@ static DWORD WINAPI do_async (LPVOID arg) { wm_ctx_t *ctx = (wm_ctx_t*) arg; + log_debug ("%s:%s: Do async with type %i", + SRCNAME, __func__, ctx ? ctx->wmsg_type : -1); send_msg_to_ui_thread (ctx); xfree (ctx); return 0; ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 2 ++ src/mailitem-events.cpp | 2 ++ src/windowmessages.cpp | 4 ++++ 3 files changed, 8 insertions(+) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 14 15:27:17 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 14 Mar 2018 15:27:17 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-92-g3917638 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 39176388f3a1f55cfb05ae24e06851925c1d0032 (commit) via 35e706fe06e9d0b8148f372fa353c64ddfcf0525 (commit) via 95ae9cb976a35cfc6f43aaacb01054b132c8eb40 (commit) from 4662ad2828cbba6f3b4c0825439ebaa3db83f6c9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 39176388f3a1f55cfb05ae24e06851925c1d0032 Author: Andre Heinecke Date: Wed Mar 14 15:24:45 2018 +0100 Disable async crypto for now * src/mail.cpp (Mail::is_inline_response): Treat every mail as inline response exept when DO_ASYNC_CRYPTO is defined. -- So sad :'-( I really hope I find a way in the future to make it work. GnuPG-Bug-Id: T3838 diff --git a/src/mail.cpp b/src/mail.cpp index d8a160d..b3c375c 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -2538,6 +2538,10 @@ Mail::set_window_enabled (bool value) bool Mail::check_inline_response () { +/* Async sending might lead to crashes when the send invocation is done. + * For now we treat every mail as an inline response to disable async + * encryption. :-( For more details see: T3838 */ +#ifdef DO_ASYNC_CRYPTO m_is_inline_response = false; LPDISPATCH app = GpgolAddin::get_instance ()->get_application (); if (!app) @@ -2577,6 +2581,9 @@ Mail::check_inline_response () m_is_inline_response = true; } xfree (inlineSubject); +#else + m_is_inline_response = true; +#endif return m_is_inline_response; } commit 35e706fe06e9d0b8148f372fa353c64ddfcf0525 Author: Andre Heinecke Date: Wed Mar 14 14:11:18 2018 +0100 Remove error handling for failure to resolve * src/cryptcontroller.cpp (CryptController::do_crypto): Remove an error handling. -- This should never happen except when a bug occurs. And handling it here would result in the overlay not beeing properly destroyed. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index da60c3b..dc07146 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -514,11 +514,7 @@ CryptController::do_crypto () //error log_debug ("%s:%s: Failure to resolve keys.", SRCNAME, __func__); - gpgol_message_box (nullptr, - utf8_gettext ("Failure to resolve keys."), - utf8_gettext ("GpgOL"), MB_OK); - // Error handled, return as canceled. - return -2; + return -1; } if (ret == -2) { commit 95ae9cb976a35cfc6f43aaacb01054b132c8eb40 Author: Andre Heinecke Date: Wed Mar 14 14:09:34 2018 +0100 Add small safety check in ribbon callback * src/ribbon-callbacks.cpp (get_is_details_enabled): Add safety check. -- I doubt that it is necessary but I've seen logs where this function is the last before a crash. So just be sure. diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp index 4f7d0a9..07b5ba7 100644 --- a/src/ribbon-callbacks.cpp +++ b/src/ribbon-callbacks.cpp @@ -1605,6 +1605,12 @@ HRESULT get_is_details_enabled (LPDISPATCH ctrl, VARIANT *result) { MY_MAIL_GETTER + if (!result) + { + TRACEPOINT; + return S_OK; + } + result->vt = VT_BOOL | VT_BYREF; result->pboolVal = (VARIANT_BOOL*) xmalloc (sizeof (VARIANT_BOOL)); *(result->pboolVal) = none_selected ? VARIANT_FALSE : VARIANT_TRUE; ----------------------------------------------------------------------- Summary of changes: src/cryptcontroller.cpp | 6 +----- src/mail.cpp | 7 +++++++ src/ribbon-callbacks.cpp | 6 ++++++ 3 files changed, 14 insertions(+), 5 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 14 17:54:05 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 14 Mar 2018 17:54:05 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-87-gada059b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via ada059b07178147821b1598c935aa70ae45e3e6c (commit) from ef27f3781a37e264d0eb7d1745eb2c804ec062c4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ada059b07178147821b1598c935aa70ae45e3e6c Author: Ben McGinnes Date: Thu Mar 15 03:51:51 2018 +1100 doc: python bindings howto * Fixed multiple sample code examples of writing output to a file. * Added the description of detached signatures. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 360bce9..71ddbcf 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -730,22 +730,34 @@ plaintext is already compressed. ASCII armouring will be determined according to the value of =gpg.Context().armor=. + The compression algorithm is selected in much the same way as the + symmetric encryption algorithm or the hash digest algorithm is + when multiple keys are involved; from the preferences saved into + the key itself or by comparison with the preferences with all + other keys involved. + #+begin_src python import gpg - text = b"""Declaration of ... something. + text0 = """Declaration of ... something. """ + text = text0.encode("utf-8") c = gpg.Context(armor=True, signers=sig_src) signed = c.sign(text, mode=0) - afile = open("/path/to/statement.txt.asc", "wb") - for i in range(len(signed[0].splitlines())): - afile.write("{0}\n".format(signed[0].splitlines()[i])) + afile = open("/path/to/statement.txt.asc", "w") + for line in signed[0]: + afile.write("{0}\n".format(line.decode("utf-8"))) afile.close() #+end_src + Though everything in this example is accurate, it is more likely + that reading the input data from another file and writing the + result to a new file will be perfprmed more like the way it is done + in the next example. Even if the output format is ASCII armoured. + #+begin_src python import gpg @@ -766,40 +778,45 @@ :CUSTOM_ID: howto-basic-signing-detached :END: - Detached ASCII Armoured signing: + Detached signatures will often be needed in programmatic uses of + GPGME, either for signing files (e.g. tarballs of code releases) + or as a component of message signing (e.g. PGP/MIME encoded + email). - #+begin_src python - import gpg + #+begin_src python + import gpg - text = b"""Declaration of ... something. + text0 = """Declaration of ... something. - """ + """ + text = text0.encode("utf-8") - c = gpg.Context(armor=True) - signed = c.sign(text, mode=1) + c = gpg.Context(armor=True) + signed = c.sign(text, mode=1) - afile = open("/path/to/statement.txt.asc", "wb") - for i in range(len(signed[0].splitlines())): - afile.write("{0}\n".format(signed[0].splitlines()[i])) - afile.close() - #+end_src + afile = open("/path/to/statement.txt.asc", "w") + for line in signed[0].splitlines()L + afile.write("{0}\n".format(line.decode("utf-8"))) + afile.close() + #+end_src - Detached binary signing of a file. + As with normal signatures, detached signatures are best handled as + byte literals, even when the output is ASCII armoured. - #+begin_src python - import gpg + #+begin_src python + import gpg - tfile = open("/path/to/statement.txt", "rb") - text = tfile.read() - tfile.close() + tfile = open("/path/to/statement.txt", "rb") + text = tfile.read() + tfile.close() - c = gpg.Context(signers=sig_src) - signed = c.sign(text, mode=1) + c = gpg.Context(signers=sig_src) + signed = c.sign(text, mode=1) - afile = open("/path/to/statement.txt.sig", "wb") - afile.write(signed[0]) - afile.close() - #+end_src + afile = open("/path/to/statement.txt.sig", "wb") + afile.write(signed[0]) + afile.close() + #+end_src *** Clearsigning messages or text :PROPERTIES: ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 73 ++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 28 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 14 21:22:08 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 14 Mar 2018 21:22:08 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-89-g6bc12a0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 6bc12a0eeb20409770cb8b923d08c18c2b730cb8 (commit) via e5c85fba25de1187949697e2dae0e89345b71e89 (commit) from ada059b07178147821b1598c935aa70ae45e3e6c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6bc12a0eeb20409770cb8b923d08c18c2b730cb8 Author: Ben McGinnes Date: Thu Mar 15 07:20:31 2018 +1100 doc: python bindings howto * Added 4 signature verification methods and partial text for them. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index b3f787a..7e7265f 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -825,7 +825,7 @@ Though PGP/in-line messages are no longer encouraged in favour of PGP/MIME, there is still sometimes value in utilising in-line - signatures. This is where clearsigned messages or text is of + signatures. This is where clear-signed messages or text is of value. #+begin_src python @@ -845,7 +845,7 @@ afile.close() #+end_src - In spite of the appearance of a clearsigned message, the data + In spite of the appearance of a clear-signed message, the data handled by GPGME in signing it must still be byte literals. #+begin_src python @@ -869,30 +869,127 @@ :CUSTOM_ID: howto-basic-verification :END: - Verify a signed file, both detached and not: + Essentially there are two principal methods of verification of a + signature. The first of these is for use with the normal or + default signing method and for clear-signed messages. The second is + for use with files and data with detached signatures. + + The following example is intended for use with the default signing + method where the file was not ASCII armoured: #+begin_src python import gpg - import sys import time + filename = "statement.txt" + gpg_file = "statement.txt.gpg" + c = gpg.Context() - data, result = c.verify(open(filename), - open(detached_sig_filename) - if detached_sig_filename else None) - - for index, sign in enumerate(result.signatures): - print("signature", index, ":") - print(" summary: %#0x" % (sign.summary)) - print(" status: %#0x" % (sign.status)) - print(" timestamp: ", sign.timestamp) - print(" timestamp: ", time.ctime(sign.timestamp)) - print(" fingerprint:", sign.fpr) - print(" uid: ", c.get_key(sign.fpr).uids[0].uid) - - if data: - sys.stdout.buffer.write(data) + try: + verified = c.verify(open(gpg_file)) + except gpg.errors.BadSignatures as e: + verified = None + print(e) + + if verified is not None: + for i in range(len(verified[1].signatures)): + sign = verified[1].signatures[i] + print("""Good signature from: + {0} + with key {1} + made at {2} + """.format(c.get_key(sign.fpr).uids[0].uid, + sign.fpr, time.ctime(sign.timestamp))) + else: + pass(e) + #+end_src + + Whereas this next example, which is almost identical would work + with normal ASCII armoured files and with clear-signed files: + + #+begin_src python + import gpg + import time + + filename = "statement.txt" + asc_file = "statement.txt.asc" + + c = gpg.Context() + + try: + verified = c.verify(open(asc_file)) + except gpg.errors.BadSignatures as e: + verified = None + print(e) + + if verified is not None: + for i in range(len(verified[1].signatures)): + sign = verified[1].signatures[i] + print("""Good signature from: + {0} + with key {1} + made at {2} + """.format(c.get_key(sign.fpr).uids[0].uid, + sign.fpr, time.ctime(sign.timestamp))) + else: + pass + #+end_src + + #+begin_src python + import gpg + import time + + filename = "statement.txt" + sig_file = "statement.txt.sig" + + c = gpg.Context() + + try: + verified = c.verify(open(filename), open(sig_file)) + except gpg.errors.BadSignatures as e: + verified = None + print(e) + + if verified is not None: + for i in range(len(verified[1].signatures)): + sign = verified[1].signatures[i] + print("""Good signature from: + {0} + with key {1} + made at {2} + """.format(c.get_key(sign.fpr).uids[0].uid, + sign.fpr, time.ctime(sign.timestamp))) + else: + pass + #+end_src + + #+begin_src python + import gpg + import time + + filename = "statement.txt" + asc_file = "statement.txt.asc" + + c = gpg.Context() + + try: + verified = c.verify(open(filename), open(asc_file)) + except gpg.errors.BadSignatures as e: + verified = None + print(e) + + if verified is not None: + for i in range(len(verified[1].signatures)): + sign = verified[1].signatures[i] + print("""Good signature from: + {0} + with key {1} + made at {2} + """.format(c.get_key(sign.fpr).uids[0].uid, + sign.fpr, time.ctime(sign.timestamp))) + else: + pass #+end_src commit e5c85fba25de1187949697e2dae0e89345b71e89 Author: Ben McGinnes Date: Thu Mar 15 04:07:57 2018 +1100 doc: python bindings howto * Added description for detached signatures. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 71ddbcf..b3f787a 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -823,21 +823,45 @@ :CUSTOM_ID: howto-basic-signing-clear :END: - #+begin_src python - import gpg + Though PGP/in-line messages are no longer encouraged in favour of + PGP/MIME, there is still sometimes value in utilising in-line + signatures. This is where clearsigned messages or text is of + value. - text = """Declaration of ... something. + #+begin_src python + import gpg - """ + text0 = """Declaration of ... something. - c = gpg.Context() - signed = c.sign(text, mode=2) + """ + text = text0.encode("utf-8") - afile = open("/path/to/statement.txt.asc", "w") - for i in range(len(signed[0].splitlines())): - afile.write("{0}\n".format(signed[0].splitlines()[i].decode('utf-8'))) - afile.close() - #+end_src + c = gpg.Context() + signed = c.sign(text, mode=2) + + afile = open("/path/to/statement.txt.asc", "w") + for line in signed[0].splitlines(): + afile.write("{0}\n".format(line.decode("utf-8"))) + afile.close() + #+end_src + + In spite of the appearance of a clearsigned message, the data + handled by GPGME in signing it must still be byte literals. + + #+begin_src python + import gpg + + tfile = open("/path/to/statement.txt", "rb") + text = tfile.read() + tfile.close() + + c = gpg.Context() + signed = c.sign(text, mode=2) + + afile = open("/path/to/statement.txt.asc", "wb") + afile.write(signed[0]) + afile.close() + #+end_src ** Signature verification ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 177 +++++++++++++++++++++++++++----- 1 file changed, 149 insertions(+), 28 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 01:19:24 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 15 Mar 2018 01:19:24 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-90-gb35aaef Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via b35aaef7a3b793b8f6f5b42596c0a6a51e87f78c (commit) from 6bc12a0eeb20409770cb8b923d08c18c2b730cb8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b35aaef7a3b793b8f6f5b42596c0a6a51e87f78c Author: Ben McGinnes Date: Thu Mar 15 11:18:02 2018 +1100 doc: python bindings howto * Added text for verifying signatures. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 7e7265f..dca6999 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -936,6 +936,27 @@ pass #+end_src + In both of the previous examples it is also possible to compare the + original data that was signed against the signed data in + =verified[0]= to see if it matches with something like this: + + #+begin_src python + afile = open(filename, "rb") + text = afile.read() + afile.close() + + if text == verified[0]: + print("Good signature.") + else: + pass + #+end_src + + The following two examples, however, deal with detached signatures. + With his method of verification the data that was signed does not + get returned since it is already being explicitly referenced in the + first argument of =c.verify=. So =verified[0]= is None and only + the data in =verified[1]= is available. + #+begin_src python import gpg import time ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 02:15:39 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 15 Mar 2018 02:15:39 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-91-g1d05e6a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 1d05e6aa4ea467c8c5926b827cfcfba357d03312 (commit) from b35aaef7a3b793b8f6f5b42596c0a6a51e87f78c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1d05e6aa4ea467c8c5926b827cfcfba357d03312 Author: Ben McGinnes Date: Thu Mar 15 12:14:29 2018 +1100 doc: python bindings howto * Added c.get_key instructions and examples. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index dca6999..8f57adb 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -345,35 +345,78 @@ #+end_src -** Counting keys +*** Counting keys + :PROPERTIES: + :CUSTOM_ID: howto-keys-counting + :END: + + Counting the number of keys in your public keybox (=pubring.kbx=), + the format which has superceded the old keyring format + (=pubring.gpg= and =secring.gpg=), or the number of secret keys is + a very simple task. + + #+begin_src python + import gpg + + c = gpg.Context() + seckeys = c.keylist(pattern=None, secret=True) + pubkeys = c.keylist(pattern=None, secret=False) + + seclist = list(seckeys) + secnum = len(seclist) + + publist = list(pubkeys) + pubnum = len(publist) + + print(""" + Number of secret keys: {0} + Number of public keys: {1} + """.format(secnum, pubnum) + #+end_src + + +** Get key :PROPERTIES: - :CUSTOM_ID: howto-keys-counting + :CUSTOM_ID: howto-get-key :END: - Counting the number of keys in your public keybox (=pubring.kbx=), - the format which has superceded the old keyring format - (=pubring.gpg= and =secring.gpg=), or the number of secret keys is - a very simple task. + An alternative method of getting a single key via its fingerprint + is available directly within a Context with =Context().get_key=. + This is the preferred method of selecting a key in order to modify + it, sign or certify it and for obtaining relevant data about a + single key as a part of other functions; when verifying a signature + made by that key, for instance. + + By default this method will select public keys, but it can select + secret keys as well. + + This first example demonstrates selecting the current key of Werner + Koch, which is due to expire at the end of 2018: #+begin_src python import gpg - c = gpg.Context() - seckeys = c.keylist(pattern=None, secret=True) - pubkeys = c.keylist(pattern=None, secret=False) + fingerprint = "80615870F5BAD690333686D0F2AD85AC1E42B367" + key = gpg.Context().get_key(fingerprint) + #+end_src - seclist = list(seckeys) - secnum = len(seclist) + Whereas this example demonstrates selecting the author's current + key with the =secret= key word argument set to =True=: - publist = list(pubkeys) - pubnum = len(publist) + #+begin_src python + import gpg - print(""" - Number of secret keys: {0} - Number of public keys: {1} - """.format(secnum, pubnum) + fingerprint = "DB4724E6FA4286C92B4E55C4321E4E2373590E5D" + key = gpg.Context().get_key(fingerprint, secret=True) #+end_src + It is, of course, quite possible to select expired, disabled and + revoked keys with this function, but only to effectively display + information about those keys. + + It is also possible to use both unicode or string literals and byte + literals with the fingerprint when getting a key in this way. + * Basic Functions :PROPERTIES: ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 77 +++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 17 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 04:02:50 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 15 Mar 2018 04:02:50 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-93-g5432e5f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 5432e5f9d1dfc02812d0b181f8d88cdf4a2bfbfb (commit) via 5d1dd2abe5cf787875d12afe46c78c75385d7b31 (commit) from 1d05e6aa4ea467c8c5926b827cfcfba357d03312 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5432e5f9d1dfc02812d0b181f8d88cdf4a2bfbfb Author: Ben McGinnes Date: Thu Mar 15 14:01:30 2018 +1100 doc: python bindings howto * generated a new primary key for Danger Mouse in an alternative homedir. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index af5a18c..909d949 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1068,12 +1068,105 @@ disabling them, sometimes deleting them and doing the same for user IDs. + In the following examples a key will be created for the world's + greatest secret agent, Danger Mouse. Since Danger Mouse is a secret + agent he needs to be able to protect information to =SECRET= level + clearance, so his keys will be 3072-bit keys. + ** Primary key :PROPERTIES: :CUSTOM_ID: keygen-primary :END: + Generating a primary key uses the =create_key= method in a Context. + It contains multiple arguments and keyword arguments, including: + =userid=, =algorithm=, =expires_in=, =expires=, =sign=, =encrypt=, + =certify=, =authenticate=, =passphrase= and =force=. The defaults + for all of those except =userid=, =algorithm=, =expires_in=, + =expires= and =passphrase= is =False=. The defaults for + =algorithm= and =passphrase= is =None=. The default for + =expires_in= is =0=. The default for =expires= is =True=. There + is no default for =userid=. + + If =passphrase= is left as =None= then the key will not be + generated with a passphrase, if =passphrase= is set to a string + then that will be the passphrase and if =passphrase= is set to + =True= then gpg-agent will launch pinentry to prompt for a + passphrase. For the sake of convenience, these examples will keep + =passphrase= set to =None=. + + #+begin_src python + import gpg + + c = gpg.Context() + + c.home_dir = "/tmp/dmgpg" + userid = "Danger Mouse " + + dmkey = c.create_key(userid, algorithm = "rsa3072", expires_in = 31536000, + sign = True, certify = True) + #+end_src + + One thing to note here is the use of setting the =c.home_dir= + parameter. This enables generating the key or keys in a different + location. In this case to keep the new key data created for this + example in a separate location rather than adding it to existing + and active key store data. + + The successful generation of the key can be confirmed via the + returned =GenkeyResult= object, which includes the following data: + + #+begin_src python + print(""" + Fingerprint: {0} + Primary Key: {1} + Public Key: {2} + Secret Key: {3} + Sub Key: {4} + User IDs: {5} + """.format(dmkey.fpr, dmkey.primary, dmkey.pubkey, dmkey.seckey, dmkey.sub, + dmkey.uid)) + #+end_src + + Alternatively the information can be confirmed using the command + line program: + + #+begin_src shell + bash-4.4$ gpg --homedir /tmp/dmgpg -K + /tmp/dmgpg/pubring.kbx + ---------------------- + sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] + 177B7C25DB99745EE2EE13ED026D2F19E99E63AA + uid [ultimate] Danger Mouse + + bash-4.4$ + #+end_src + + As with generating keys manually, to preconfigure expanded + preferences for the cipher, digest and compression algorithms, the + =gpg.conf= file must contain those details in the home directory in + which the new key is being generated. I used a cut down version of + my own =gpg.conf= file in order to be able to generate this: + + #+begin_src shell + bash-4.4$ gpg --homedir /tmp/dmgpg --edit-key 177B7C25DB99745EE2EE13ED026D2F19E99E63AA showpref quit + Secret key is available. + + sec rsa3072/026D2F19E99E63AA + created: 2018-03-15 expires: 2019-03-15 usage: SC + trust: ultimate validity: ultimate + [ultimate] (1). Danger Mouse + + [ultimate] (1). Danger Mouse + Cipher: TWOFISH, CAMELLIA256, AES256, CAMELLIA192, AES192, CAMELLIA128, AES, BLOWFISH, IDEA, CAST5, 3DES + Digest: SHA512, SHA384, SHA256, SHA224, RIPEMD160, SHA1 + Compression: ZLIB, BZIP2, ZIP, Uncompressed + Features: MDC, Keyserver no-modify + + bash-4.4$ + #+end_src + ** Subkeys :PROPERTIES: commit 5d1dd2abe5cf787875d12afe46c78c75385d7b31 Author: Ben McGinnes Date: Thu Mar 15 12:27:45 2018 +1100 doc: python bindings howto * Added sections for key generation and key editing. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 8f57adb..af5a18c 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1057,6 +1057,48 @@ #+end_src +* Creating keys and subkeys + :PROPERTIES: + :CUSTOM_ID: key-generation + :END: + + The one thing, aside from GnuPG itself, that GPGME depends on, of + course, is the keys themselves. So it is necessary to be able to + generate them and modify them by adding subkeys, revoking or + disabling them, sometimes deleting them and doing the same for user + IDs. + + +** Primary key + :PROPERTIES: + :CUSTOM_ID: keygen-primary + :END: + + +** Subkeys + :PROPERTIES: + :CUSTOM_ID: keygen-subkeys + :END: + + +** User IDs + :PROPERTIES: + :CUSTOM_ID: keygen-uids + :END: + + +** Key preferences + :PROPERTIES: + :CUSTOM_ID: keygen-prefs + :END: + + +** Key certification + :PROPERTIES: + :CUSTOM_ID: keygen-certify + :END: + + * Miscellaneous work-arounds :PROPERTIES: :CUSTOM_ID: cheats-and-hacks ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 135 ++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 04:45:14 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 15 Mar 2018 04:45:14 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-94-gb02d9d0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via b02d9d0a7b96b186eb3063d94bde369339181461 (commit) from 5432e5f9d1dfc02812d0b181f8d88cdf4a2bfbfb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b02d9d0a7b96b186eb3063d94bde369339181461 Author: Ben McGinnes Date: Thu Mar 15 14:43:44 2018 +1100 doc: python bindings howto * Added an encryption subkey to Danger Mouse's primary key. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 909d949..0e61746 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1073,6 +1073,28 @@ agent he needs to be able to protect information to =SECRET= level clearance, so his keys will be 3072-bit keys. + The pre-configured =gpg.conf= file which sets cipher, digest and + other preferences contains the following configuration parameters: + + #+begin_src conf + expert + allow-freeform-uid + allow-secret-key-import + trust-model tofu+pgp + tofu-default-policy unknown + # no-auto-check-trustdb + enable-large-rsa + enable-dsa2 + # no-emit-version + # no-comments + # cert-digest-algo SHA256 + cert-digest-algo SHA512 + default-preference-list TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 ZLIB BZIP2 ZIP Uncompressed + personal-cipher-preferences TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES + personal-digest-preferences SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 + personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed + #+end_src + ** Primary key :PROPERTIES: @@ -1173,6 +1195,56 @@ :CUSTOM_ID: keygen-subkeys :END: + Adding subkeys to a primary key is fairly similar to creating the + primary key with the =create_subkey= method. Most of the arguments + are the same, but not quite all. Instead of the =userid= argument + there is now a =key= argument for selecting which primary key to + add the subkey to. + + In the following example an encryption subkey will be added to the + primary key. Since Danger Mouse is a security conscious secret + agent, this subkey will only be valid for about six months, half + the length of the primary key. + + #+begin_src python + import gpg + + c = gpg.Context() + c.home_dir = "/tmp/dmgpg" + + key = c.get_key(dmkey.fpr, secret = True) + dmsub = c.create_subkey(key, algorithm = "rsa3072", expires_in = 15768000, + encrypt = True) + #+end_src + + As with the primary key, the results here can be checked with: + + #+begin_src python + print(""" + Fingerprint: {0} + Primary Key: {1} + Public Key: {2} + Secret Key: {3} + Sub Key: {4} + User IDs: {5} + """.format(dmsub.fpr, dmsub.primary, dmsub.pubkey, dmsub.seckey, dmsub.sub, + dmsub.uid)) + #+end_src + + As well as on the command line with: + + #+begin_src shell + bash-4.4$ gpg --homedir /tmp/dmgpg -K + /tmp/dmgpg/pubring.kbx + ---------------------- + sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] + 177B7C25DB99745EE2EE13ED026D2F19E99E63AA + uid [ultimate] Danger Mouse + ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13] + + bash-4.4$ + #+end_src + ** User IDs :PROPERTIES: ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 72 +++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 05:52:01 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 15 Mar 2018 05:52:01 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-97-g961aea2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 961aea212ef48914ecbfa169addf951b0854b0b4 (commit) via 7ac65b10837740caf68cdade791b8c5ce4eb1b03 (commit) via 9e3e4a835c64f5d06de821b1fd648af37827ff26 (commit) from b02d9d0a7b96b186eb3063d94bde369339181461 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 961aea212ef48914ecbfa169addf951b0854b0b4 Author: Ben McGinnes Date: Thu Mar 15 15:51:01 2018 +1100 doc: python bindings howto * Added key signing. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index d22efbe..582a28f 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1290,6 +1290,38 @@ :CUSTOM_ID: key-sign :END: + Since key certification is more frequently referred to as key + signing, the method used to perform this function is =key_sign=. + + The =key_sign= method takes four arguments: =key=, =uids=, + =expires_in= and =local=. The default value of =uids= is =None= + and which results in all user IDs being selected. The default + values of =expires_in= snd =local= is =False=; which result in the + signature never expiring and being able to be exported. + + The =key= is the key being signed rather than the key doing the + signing. To change the key doing the signing refer to the signing + key selection above for signing messages and files. + + If the =uids= value is not =None= then it must either be a string + to match a single user ID or a list of strings to match multiple + user IDs. In this case the matching of those strings must be + precise and it is case sensitive. + + To sign Danger Mouse's key for just the initial user ID with a + signature which will last a little over a month, do this: + + #+begin_src python + import gpg + + c = gpg.Context() + uid = "Danger Mouse " + + dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" + key = c.get_key(dmfpr, secret = True) + c.key_sign(key, uids = uid, expires_in = 2764800) + #+end_src + * Miscellaneous work-arounds :PROPERTIES: commit 7ac65b10837740caf68cdade791b8c5ce4eb1b03 Author: Ben McGinnes Date: Thu Mar 15 15:16:23 2018 +1100 doc: python bindings howto * Added a new user ID for Danger Mouse. * Removed the empty entry for key preferences since that is handled through gpg.conf and/or editing the key directly. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 37318fc..d22efbe 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1251,16 +1251,43 @@ :CUSTOM_ID: keygen-uids :END: + By comparison to creating primary keys and subkeys, adding a new + user ID to an existing key is much simpler. The method used to do + this is =key_add_uid= and the only arguments it takes are for the + =key= and the new =uid=. -** Key preferences - :PROPERTIES: - :CUSTOM_ID: keygen-prefs - :END: + #+begin_src python + import gpg + + c = gpg.Context() + c.home_dir = "/tmp/dmgpg" + + dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" + key = c.get_key(dmfpr, secret = True) + uid = "Danger Mouse " + + c.key_add_uid(key, uid) + #+end_src + + Unsurprisingly the result of this is: + + #+begin_src shell + bash-4.4$ gpg --homedir /tmp/dmgpg -K + /tmp/dmgpg/pubring.kbx + ---------------------- + sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] + 177B7C25DB99745EE2EE13ED026D2F19E99E63AA + uid [ultimate] Danger Mouse + uid [ultimate] Danger Mouse + ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13] + + bash-4.4$ + #+end_src ** Key certification :PROPERTIES: - :CUSTOM_ID: keygen-certify + :CUSTOM_ID: key-sign :END: commit 9e3e4a835c64f5d06de821b1fd648af37827ff26 Author: Ben McGinnes Date: Thu Mar 15 14:59:36 2018 +1100 doc: python bindings howto * Spell checking and fixing the few errors. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 0e61746..37318fc 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -35,8 +35,8 @@ Much of it will work with Python 2, but much of it also deals with Python 3 byte literals, particularly when reading and writing data. Developers concentrating on Python 2.7, and possibly even 2.6, will - need to make the approprate modifications to support the older - string and unicode types as opposted to bytes. + need to make the appropriate modifications to support the older + string and unicode types as opposed to bytes. There are multiple reasons for concentrating on Python 3; some of which relate to the immediate integration of these bindings, some @@ -61,7 +61,7 @@ Unlike many modern APIs with which programmers will be more familiar with these days, the GPGME API is a C API. The API is intended for use by C coders who would be able to access its - features by including the =gpgme.h= header file eith their own C + features by including the =gpgme.h= header file with their own C source code and then access its functions just as they would any other C headers. @@ -208,7 +208,7 @@ By default GPGME will attempt to install the bindings for the most recent or highest version number of Python 2 and Python 3 it detects in =$PATH=. It specifically checks for the =python= and - =python3= executabled first and then checks for specific version + =python3= executables first and then checks for specific version numbers. For Python 2 it checks for these executables in this order: @@ -275,7 +275,7 @@ result of one operation has a direct bearing on the outcome of subsequent operations. Not merely by generating an error either. - When dealing with this type of persistant state on the web, full of + When dealing with this type of persistent state on the web, full of both the RESTful and REST-like, it's most commonly referred to as a session. In GPGME, however, it is called a context and every operation type has one. @@ -351,7 +351,7 @@ :END: Counting the number of keys in your public keybox (=pubring.kbx=), - the format which has superceded the old keyring format + the format which has superseded the old keyring format (=pubring.gpg= and =secring.gpg=), or the number of secret keys is a very simple task. @@ -424,7 +424,7 @@ :END: The most frequently called features of any cryptographic library - will be the most fundamental tasks for enxryption software. In this + will be the most fundamental tasks for encryption software. In this section we will look at how to programmatically encrypt data, decrypt it, sign it and verify signatures. @@ -461,7 +461,7 @@ the key was not found. The encryption operation is invoked within the Context with the - =c.op_encrypt= function, loading the recipien (=r=), the message + =c.op_encrypt= function, loading the recipients (=r=), the message (=plain=) and the =cipher=. The =cipher.seek= uses =os.SEEK_SET= to set the data to the correct byte format for GPGME to use it. @@ -798,7 +798,7 @@ Though everything in this example is accurate, it is more likely that reading the input data from another file and writing the - result to a new file will be perfprmed more like the way it is done + result to a new file will be performed more like the way it is done in the next example. Even if the output format is ASCII armoured. #+begin_src python @@ -838,7 +838,7 @@ signed = c.sign(text, mode=1) afile = open("/path/to/statement.txt.asc", "w") - for line in signed[0].splitlines()L + for line in signed[0].splitlines(): afile.write("{0}\n".format(line.decode("utf-8"))) afile.close() #+end_src ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 89 +++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 15 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 06:20:14 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 15 Mar 2018 06:20:14 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-98-g3d0c7a2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 3d0c7a2202c8e9bd4f284fd00069d34b8d3d3d4c (commit) from 961aea212ef48914ecbfa169addf951b0854b0b4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3d0c7a2202c8e9bd4f284fd00069d34b8d3d3d4c Author: Ben McGinnes Date: Thu Mar 15 16:13:34 2018 +1100 doc: python bindings howto * Fixed a minor typographic error. * Bumped version number in preparation for merge with master. * While there are probably a few more things worthy of being added (mainly how to revoke things), this document is essentially ready for publication now. Signed-off-by: Ben McGinnes diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 582a28f..71e738a 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -13,7 +13,7 @@ :CUSTOM_ID: intro :END: - | Version: | 0.0.1-alpha | + | Version: | 0.1.0 | | Author: | Ben McGinnes | | Author GPG Key: | DB4724E6FA4286C92B4E55C4321E4E2373590E5D | | Language: | Australian English, British English | @@ -513,7 +513,7 @@ Encrypting to multiple keys, in addition to a default key or a key configured to always encrypt to, is a little different and uses a - slightly different call to the =op_encrypt call= demonstrated in the + slightly different call to the =op_encrypt= call demonstrated in the previous section. The following example encrypts a message (=text=) to everyone with ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 09:30:43 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 15 Mar 2018 09:30:43 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-94-gbf9098d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via bf9098d2d63de6feaf8fe9486299b7cae924022f (commit) via 7ba9dc3962fb3fb854c2b1cd9338618ffafbc5b4 (commit) from 39176388f3a1f55cfb05ae24e06851925c1d0032 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bf9098d2d63de6feaf8fe9486299b7cae924022f Author: Andre Heinecke Date: Thu Mar 15 09:27:24 2018 +0100 Fix unencrypted forward of crypto mail * src/mail.cpp (Mail::Mail): Add new marker for forwarded crypto mails. (Mail::remove_our_attachments): New. Removes gpgol attachments. (Mail::set_is_forwarded_crypto_mail, Mail::is_forwarded_crypto_mail): New accessors to marker. * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Set marker on forward. Handle marker on write. -- GnuPG-Bug-Id: T3836 diff --git a/src/mail.cpp b/src/mail.cpp index b3c375c..7e8360f 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -92,7 +92,8 @@ Mail::Mail (LPDISPATCH mailitem) : m_is_gsuite(false), m_crypt_state(NoCryptMail), m_window(nullptr), - m_is_inline_response(false) + m_is_inline_response(false), + m_is_forwarded_crypto_mail(false) { if (get_mail_for_item (mailitem)) { @@ -2624,3 +2625,63 @@ Mail::locate_all_crypto_recipients() } } } + +int +Mail::remove_our_attachments () +{ + LPDISPATCH attachments = get_oom_object (m_mailitem, "Attachments"); + if (!attachments) + { + TRACEPOINT; + return 0; + } + int count = get_oom_int (attachments, "Count"); + LPDISPATCH to_delete[count]; + int del_cnt = 0; + for (int i = 1; i <= count; i++) + { + auto item_str = std::string("Item(") + std::to_string (i) + ")"; + LPDISPATCH attachment = get_oom_object (attachments, item_str.c_str()); + if (!attachment) + { + TRACEPOINT; + continue; + } + + attachtype_t att_type; + if (get_pa_int (attachment, GPGOL_ATTACHTYPE_DASL, (int*) &att_type)) + { + /* Not our attachment. */ + gpgol_release (attachment); + continue; + } + + if (att_type == ATTACHTYPE_PGPBODY || att_type == ATTACHTYPE_MOSS || + att_type == ATTACHTYPE_MOSSTEMPL) + { + /* One of ours to delete. */ + to_delete[del_cnt++] = attachment; + /* Dont' release yet */ + continue; + } + gpgol_release (attachment); + } + gpgol_release (attachments); + + int ret = 0; + + for (int i = 0; i < del_cnt; i++) + { + LPDISPATCH attachment = to_delete[i]; + + /* Delete the attachments that are marked to delete */ + if (invoke_oom_method (attachment, "Delete", NULL)) + { + log_error ("%s:%s: Error: deleting attachment %i", + SRCNAME, __func__, i); + ret = -1; + } + gpgol_release (attachment); + } + return ret; +} diff --git a/src/mail.h b/src/mail.h index 90f042e..7410f61 100644 --- a/src/mail.h +++ b/src/mail.h @@ -448,6 +448,15 @@ public: /** Get the mime data that should be used when sending. */ std::string get_override_mime_data () const { return m_mime_data; } + /** Set if this is a forward of a crypto mail. */ + void set_is_forwarded_crypto_mail (bool value) { m_is_forwarded_crypto_mail = value; } + bool is_forwarded_crypto_mail () { return m_is_forwarded_crypto_mail; } + + /** Remove the hidden GpgOL attachments. This is needed when forwarding + without encryption so that our attachments are not included in the forward. + Returns 0 on success. Works in OOM. */ + int remove_our_attachments (); + void update_body (); private: void update_categories (); @@ -488,5 +497,6 @@ private: HWND m_window; bool m_is_inline_response; std::string m_mime_data; + bool m_is_forwarded_crypto_mail; /* Is this a forward of a crypto mail */ }; #endif // MAIL_H diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index de4c274..273c842 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -494,10 +494,11 @@ EVENT_SINK_INVOKE(MailItemEvents) Security consideration: Worst case we pass the write here but an unload follows before we get the scheduled revert. This - would leak plaintext. + would leak plaintext. But does not happen in our tests. Similarly if we crash or Outlook is closed before we see this - revert. */ + revert. But as we immediately revert after the write this should + also not happen. */ const std::string lastSubject = last_mail->get_subject (); char *lastEntryID = get_oom_string (last_mail->item (), "EntryID"); int lastSize = get_oom_int (last_mail->item (), "Size"); @@ -542,6 +543,27 @@ EVENT_SINK_INVOKE(MailItemEvents) *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; } + if (!m_mail->is_crypto_mail () && m_mail->is_forwarded_crypto_mail () && + !m_mail->needs_crypto () && m_mail->crypt_state () == Mail::NoCryptMail) + { + /* We are sure now that while this is a forward of an encrypted + * mail that the forward should not be signed or encrypted. So + * it's not constructed by us. We need to remove our attachments + * though so that they are not included in the forward. */ + log_debug ("%s:%s: Writing unencrypted forward of crypt mail. " + "Removing attachments. mail: %p item: %p", + SRCNAME, __func__, m_mail, m_object); + if (m_mail->remove_our_attachments ()) + { + // Worst case we forward some encrypted data here not + // a security problem, so let it pass. + log_error ("%s:%s: Failed to remove our attachments.", + SRCNAME, __func__); + } + /* Remove marker because we did this now. */ + m_mail->set_is_forwarded_crypto_mail (false); + } + log_debug ("%s:%s: Passing write event.", SRCNAME, __func__); m_mail->set_needs_save (false); @@ -616,6 +638,41 @@ EVENT_SINK_INVOKE(MailItemEvents) return S_OK; } case Forward: + { + log_oom_extra ("%s:%s: Forward: %p", + SRCNAME, __func__, m_mail); + if (!m_mail->is_crypto_mail ()) + { + /* Non crypto mails do not interest us.*/ + break; + } + Mail *last_mail = Mail::get_last_mail (); + if (Mail::is_valid_ptr (last_mail)) + { + /* We want to identify here if there was a mail created that + should receive the contents of this mail. For this we check + for a forward in the same loop as a mail creation. + */ + char *lastEntryID = get_oom_string (last_mail->item (), "EntryID"); + int lastSize = get_oom_int (last_mail->item (), "Size"); + std::string lastEntryStr; + if (lastEntryID) + { + lastEntryStr = lastEntryID; + xfree (lastEntryID); + } + + if (!lastSize && !lastEntryStr.size ()) + { + log_debug ("%s:%s: Forward in the same loop as empty load." + " Marking %p (item %p) as forwarded.", + SRCNAME, __func__, last_mail, last_mail->item ()); + + last_mail->set_is_forwarded_crypto_mail (true); + } + } + } + /* Fallthrough */ case Reply: case ReplyAll: { commit 7ba9dc3962fb3fb854c2b1cd9338618ffafbc5b4 Author: Andre Heinecke Date: Thu Mar 15 08:26:46 2018 +0100 Avoid double gpgme_data_identify * src/parsecontroller.cpp (ParseController::parse): Store first identify value and reuse it. diff --git a/src/parsecontroller.cpp b/src/parsecontroller.cpp index 860c215..484afc2 100644 --- a/src/parsecontroller.cpp +++ b/src/parsecontroller.cpp @@ -234,7 +234,9 @@ ParseController::parse() Data input (m_inputprovider); - if (input.type () == Data::Type::PGPSigned) + auto inputType = input.type (); + + if (inputType == Data::Type::PGPSigned) { verify = true; decrypt = false; @@ -289,7 +291,7 @@ ParseController::parse() decrypt, verify, protocol == OpenPGP ? "OpenPGP" : protocol == CMS ? "CMS" : "Unknown", - m_sender.empty() ? "none" : m_sender.c_str(), input.type ()); + m_sender.empty() ? "none" : m_sender.c_str(), inputType); if (decrypt) { input.seek (0, SEEK_SET); ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++++- src/mail.h | 10 ++++++++ src/mailitem-events.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++-- src/parsecontroller.cpp | 6 +++-- 4 files changed, 135 insertions(+), 5 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 15:51:25 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 15 Mar 2018 15:51:25 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-100-g22e2445 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 22e2445beee46ed1e527a98e635153c7cf03786f (commit) via 94a95ac12364989db7f4be333107f3c023551857 (commit) from 3d0c7a2202c8e9bd4f284fd00069d34b8d3d3d4c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 22e2445beee46ed1e527a98e635153c7cf03786f Author: Ben McGinnes Date: Fri Mar 16 01:48:56 2018 +1100 doc: python bindings howto * fixed custom_id for decryption so the XHTML validates. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 30e1018..4aa4398 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -677,7 +677,7 @@ ** Decryption :PROPERTIES: - :CUSTOM_ID: howto-basic-encryption + :CUSTOM_ID: howto-basic-decryption :END: Decrypting something encrypted to a key in one's secret keyring is commit 94a95ac12364989db7f4be333107f3c023551857 Author: Ben McGinnes Date: Fri Mar 16 01:34:22 2018 +1100 doc: python bindings howto * Promoted final encryption example so that it will appear as heading 6.1.3 when exported to HTML or PDF. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 71e738a..30e1018 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -608,71 +608,71 @@ This will attempt to encrypt to all the keys searched for, then remove invalid recipients if it fails and try again. -**** Encrypting to one key using the second method - :PROPERTIES: - :CUSTOM_ID: howto-basic-encryption-monogamous - :END: +*** Encrypting to one key using the second method + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption-monogamous + :END: - This example re-creates the first encryption example except it - uses the same =encrypt= method used in the subsequent examples - instead of the =op_encrypt= method. This means that, unlike the - =op_encrypt= method, it /must/ use byte literal input data. + This example re-creates the first encryption example except it + uses the same =encrypt= method used in the subsequent examples + instead of the =op_encrypt= method. This means that, unlike the + =op_encrypt= method, it /must/ use byte literal input data. - #+begin_src python - import gpg + #+begin_src python + import gpg - rkey = "0x12345678DEADBEEF" - text = b"""Some text to test with. + rkey = "0x12345678DEADBEEF" + text = b"""Some text to test with. - 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. - """ + 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=rkey, secret=False)) - logrus = [] + c = gpg.Context(armor=True) + rpattern = list(c.keylist(pattern=rkey, secret=False)) + logrus = [] - for i in range(len(rpattern)): - if rpattern[i].can_encrypt == 1: - logrus.append(rpattern[i]) + for i in range(len(rpattern)): + if rpattern[i].can_encrypt == 1: + logrus.append(rpattern[i]) - cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) + cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) - afile = open("secret_plans.txt.asc", "wb") - afile.write(cipher[0]) - afile.close() - #+end_src + afile = open("secret_plans.txt.asc", "wb") + afile.write(cipher[0]) + afile.close() + #+end_src - With one or two exceptions, this method will probably prove to be - easier to implement than the first method and thus it is the - recommended encryption method. Though it is even more likely to - be used like this: + With one or two exceptions, this method will probably prove to be + easier to implement than the first method and thus it is the + recommended encryption method. Though it is even more likely to + be used like this: - #+begin_src python - import gpg + #+begin_src python + import gpg - rkey = "0x12345678DEADBEEF" + rkey = "0x12345678DEADBEEF" - afile = open("secret_plans.txt", "rb") - text = afile.read() - afile.close() + afile = open("secret_plans.txt", "rb") + text = afile.read() + afile.close() - c = gpg.Context(armor=True) - rpattern = list(c.keylist(pattern=rkey, secret=False)) - logrus = [] + c = gpg.Context(armor=True) + rpattern = list(c.keylist(pattern=rkey, secret=False)) + logrus = [] - for i in range(len(rpattern)): - if rpattern[i].can_encrypt == 1: - logrus.append(rpattern[i]) + for i in range(len(rpattern)): + if rpattern[i].can_encrypt == 1: + logrus.append(rpattern[i]) - cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) + cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) - afile = open("secret_plans.txt.asc", "wb") - afile.write(cipher[0]) - afile.close() - #+end_src + afile = open("secret_plans.txt.asc", "wb") + afile.write(cipher[0]) + afile.close() + #+end_src ** Decryption ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 100 ++++++++++++++++---------------- 1 file changed, 50 insertions(+), 50 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 16:03:31 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 15 Mar 2018 16:03:31 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-15-gfd23a05 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via fd23a0524d8060ed12d87c679b7823686614aaee (commit) from c84bae69e9e02923f7180e09d161cb0b13257436 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fd23a0524d8060ed12d87c679b7823686614aaee Author: NIIBE Yutaka Date: Thu Mar 15 23:59:22 2018 +0900 scd: Fix suspend/resume handling for CCID driver. * scd/ccid-driver.c (intr_cb): Try submitting INTERRUPT urb to see if it's suspend/resume. -- Upon suspend/resume, LIBUSB_TRANSFER_NO_DEVICE is returned, since all URBs are cancelled. We need to see if it's real NODEV error or its by suspend/resume. We can distinguish by sending URB again. Signed-off-by: NIIBE Yutaka diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 5046da5..f33a36c 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -1467,7 +1467,8 @@ intr_cb (struct libusb_transfer *transfer) DEBUGOUT_1 ("CCID: interrupt callback %d\n", transfer->status); - if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) + if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT + || transfer->status == LIBUSB_TRANSFER_NO_DEVICE) { int err; ----------------------------------------------------------------------- Summary of changes: scd/ccid-driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 16:23:22 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 15 Mar 2018 16:23:22 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-52-gad95288 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via ad95288d3b3efc38998841add4fe658c84701f98 (commit) via a630a1e3e74c926163864b013cb164b4cd1866fc (commit) from e846c3daeeb4e7092169cdb7bf4f55e0b105aac3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ad95288d3b3efc38998841add4fe658c84701f98 Author: Andre Heinecke Date: Thu Mar 15 16:21:00 2018 +0100 cpp: Expose skipped_v3_keys * lang/cpp/src/importresult.cpp, lang/cpp/src/importresult.h (ImportResult::numV3KeysSkipped): New. -- GnuPG-Bug-Id: T3776 diff --git a/NEWS b/NEWS index c172697..7b6fdd9 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ Noteworthy changes in version 1.10.1 (unreleased) gpgme_import_result_t EXTENDED: New field 'skipped_v3_keys' cpp: Key::locate NEW. cpp: Data::toString NEW. + cpp: ImportResult::numV3KeysSkipped NEW. Noteworthy changes in version 1.10.0 (2017-12-12) ------------------------------------------------- diff --git a/lang/cpp/src/importresult.cpp b/lang/cpp/src/importresult.cpp index 8c35f9c..dbb31d0 100644 --- a/lang/cpp/src/importresult.cpp +++ b/lang/cpp/src/importresult.cpp @@ -154,6 +154,11 @@ int GpgME::ImportResult::notImported() const return d ? d->res.not_imported : 0 ; } +int GpgME::ImportResult::numV3KeysSkipped() const +{ + return d ? d->res.skipped_v3_keys : 0 ; +} + GpgME::Import GpgME::ImportResult::import(unsigned int idx) const { return Import(d, idx); diff --git a/lang/cpp/src/importresult.h b/lang/cpp/src/importresult.h index 2f0e7f2..0547679 100644 --- a/lang/cpp/src/importresult.h +++ b/lang/cpp/src/importresult.h @@ -78,6 +78,7 @@ public: int numSecretKeysUnchanged() const; int notImported() const; + int numV3KeysSkipped() const; Import import(unsigned int idx) const; std::vector imports() const; commit a630a1e3e74c926163864b013cb164b4cd1866fc Author: Andre Heinecke Date: Thu Mar 15 15:58:32 2018 +0100 core: Parse skipped_v3_keys * src/gpgme.h.in (gpgme_import_result_t): Extend with skipped_v3_keys. * src/import.c (gpgme_op_import_result): Extend debug with new field. (parse_import_res): Parse skipped_v3_keys. * tests/gpg/t-support.h, tests/run-support.h (print_import_result): Print skipped_v3_keys. -- This makes it possible to handle this in a GUI in a future version. GnuPG-Bug-Id: T3776 diff --git a/NEWS b/NEWS index 1a342b1..c172697 100644 --- a/NEWS +++ b/NEWS @@ -3,10 +3,10 @@ Noteworthy changes in version 1.10.1 (unreleased) * Interface changes relative to the 1.10.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gpgme_import_result_t EXTENDED: New field 'skipped_v3_keys' cpp: Key::locate NEW. cpp: Data::toString NEW. - Noteworthy changes in version 1.10.0 (2017-12-12) ------------------------------------------------- diff --git a/src/gpgme.h.in b/src/gpgme.h.in index ff80023..73f2c94 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1637,6 +1637,9 @@ struct _gpgme_op_import_result /* Number of keys not imported. */ int not_imported; + /* Number of v3 keys skipped. */ + int skipped_v3_keys; + /* List of keys for which an import was attempted. */ gpgme_import_status_t imports; }; diff --git a/src/import.c b/src/import.c index 386ca72..f0d9d9f 100644 --- a/src/import.c +++ b/src/import.c @@ -94,8 +94,9 @@ gpgme_op_import_result (gpgme_ctx_t ctx) TRACE_LOG3 ("%i secret keys, %i imported, %i unchanged", opd->result.secret_read, opd->result.secret_imported, opd->result.secret_unchanged); - TRACE_LOG2 ("%i skipped new keys, %i not imported", - opd->result.skipped_new_keys, opd->result.not_imported); + TRACE_LOG3 ("%i skipped new keys, %i not imported, %i v3 skipped", + opd->result.skipped_new_keys, opd->result.not_imported, + opd->result.skipped_v3_keys); impstat = opd->result.imports; i = 0; @@ -212,6 +213,10 @@ parse_import_res (char *args, gpgme_import_result_t result) PARSE_NEXT (result->secret_unchanged); PARSE_NEXT (result->skipped_new_keys); PARSE_NEXT (result->not_imported); + if (args && *args) + { + PARSE_NEXT (result->skipped_v3_keys); + } return 0; } diff --git a/tests/gpg/t-support.h b/tests/gpg/t-support.h index f6dec68..ef5766a 100644 --- a/tests/gpg/t-support.h +++ b/tests/gpg/t-support.h @@ -196,7 +196,8 @@ print_import_result (gpgme_import_result_t r) " secret imported: %d\n" " secret unchanged: %d\n" " skipped new keys: %d\n" - " not imported: %d\n", + " not imported: %d\n" + " skipped v3 keys: %d\n", r->considered, r->no_user_id, r->imported, @@ -210,6 +211,7 @@ print_import_result (gpgme_import_result_t r) r->secret_imported, r->secret_unchanged, r->skipped_new_keys, - r->not_imported); + r->not_imported, + r->skipped_v3_keys); } diff --git a/tests/run-support.h b/tests/run-support.h index 6a2170b..6c713a9 100644 --- a/tests/run-support.h +++ b/tests/run-support.h @@ -177,7 +177,8 @@ print_import_result (gpgme_import_result_t r) " secret imported: %d\n" " secret unchanged: %d\n" " skipped new keys: %d\n" - " not imported: %d\n", + " not imported: %d\n" + " skipped v3 keys: %d\n", r->considered, r->no_user_id, r->imported, @@ -191,6 +192,7 @@ print_import_result (gpgme_import_result_t r) r->secret_imported, r->secret_unchanged, r->skipped_new_keys, - r->not_imported); + r->not_imported, + r->skipped_v3_keys); } ----------------------------------------------------------------------- Summary of changes: NEWS | 3 ++- lang/cpp/src/importresult.cpp | 5 +++++ lang/cpp/src/importresult.h | 1 + src/gpgme.h.in | 3 +++ src/import.c | 9 +++++++-- tests/gpg/t-support.h | 6 ++++-- tests/run-support.h | 6 ++++-- 7 files changed, 26 insertions(+), 7 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 16:33:32 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 15 Mar 2018 16:33:32 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-95-ga6bf8ef Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via a6bf8ef284d98f87a9e64ce326e2a0a55633213c (commit) from bf9098d2d63de6feaf8fe9486299b7cae924022f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a6bf8ef284d98f87a9e64ce326e2a0a55633213c Author: Andre Heinecke Date: Thu Mar 15 15:03:04 2018 +0100 Jump the event queue * src/olflange.h (ProgID): We are now Z.GNU.GpgOL -- According to hearsay events are handled in reverse alphabetical order. Let's try this to see if it results in fewer problems with other addins. The ProgId is not user visible anywhere. GnuPG-Bug-Id: T3769 diff --git a/src/olflange.h b/src/olflange.h index 7601eb6..31aea7a 100644 --- a/src/olflange.h +++ b/src/olflange.h @@ -37,7 +37,7 @@ DEFINE_GUID(CLSID_GPGOL, 0x42d30988, 0x1a3a, 0x11da, */ /* The ProgID used by us */ -#define GPGOL_PROGID "GNU.GpgOL" +#define GPGOL_PROGID "Z.GNU.GpgOL" /* User friendly add in name */ #define GPGOL_PRETTY "GpgOL - The GnuPG Outlook Plugin" /* Short description of the addin */ ----------------------------------------------------------------------- Summary of changes: src/olflange.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 15 17:54:38 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 15 Mar 2018 17:54:38 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-101-g431897a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 431897a4c48fe1bc9d37f655097aabaf5b685d11 (commit) from 22e2445beee46ed1e527a98e635153c7cf03786f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 431897a4c48fe1bc9d37f655097aabaf5b685d11 Author: Ben McGinnes Date: Fri Mar 16 03:52:58 2018 +1100 doc: python bindings howto * Added clarification on why it's not on PyPI. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 4aa4398..28d2e25 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -179,6 +179,14 @@ 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. + This is because the bindings use SWIG to dynamically generate C + bindings against =gpgme.h= and =gpgme.h= is generated from + =gpgme.h.in= 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. + ** Requirements :PROPERTIES: :CUSTOM_ID: gpgme-python-requirements ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 8 ++++++++ 1 file changed, 8 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 16 03:32:29 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 16 Mar 2018 03:32:29 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-16-g2c85e20 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 2c85e202bc30231b9555100dec0c490c60d7b88c (commit) from fd23a0524d8060ed12d87c679b7823686614aaee (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2c85e202bc30231b9555100dec0c490c60d7b88c Author: NIIBE Yutaka Date: Fri Mar 16 11:27:33 2018 +0900 scd: Better user interaction for factory-reset. * g10/card-util.c (factory_reset): Dummy PIN size is now 32-byte. Connect the card again at the last step. -- Before the change, a user has to quit the session to continue. Now, it is possible to type RET in the session and see if it's really done. Signed-off-by: NIIBE Yutaka diff --git a/g10/card-util.c b/g10/card-util.c index bda4e83..7616dbb 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -659,7 +659,7 @@ current_card_status (ctrl_t ctrl, estream_t fp, /* Print all available information for specific card with SERIALNO. Print all available information for current card when SERIALNO is NULL. - Or print llfor all cards when SERIALNO is "all". */ + Or print for all cards when SERIALNO is "all". */ void card_status (ctrl_t ctrl, estream_t fp, const char *serialno) { @@ -1792,6 +1792,7 @@ factory_reset (void) scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40 scd apdu 00 e6 00 00 scd apdu 00 44 00 00 + scd reset /echo Card has been reset to factory defaults but tries to find out something about the card first. @@ -1804,7 +1805,7 @@ factory_reset (void) else if (err) { log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (err)); - return; + goto leave; } if (!termstate) @@ -1854,10 +1855,16 @@ factory_reset (void) command because there is no machinery in scdaemon to catch the verify command and ask for the PIN when the "APDU" command is used. */ + /* Here, the length of dummy wrong PIN is 32-byte, also + supporting authentication with KDF DO. */ for (i=0; i < 4; i++) - send_apdu ("00200081084040404040404040", "VERIFY", 0xffff); + send_apdu ("0020008120" + "40404040404040404040404040404040" + "40404040404040404040404040404040", "VERIFY", 0xffff); for (i=0; i < 4; i++) - send_apdu ("00200083084040404040404040", "VERIFY", 0xffff); + send_apdu ("0020008320" + "40404040404040404040404040404040" + "40404040404040404040404040404040", "VERIFY", 0xffff); /* Send terminate datafile command. */ err = send_apdu ("00e60000", "TERMINATE DF", 0x6985); @@ -1873,8 +1880,16 @@ factory_reset (void) /* Finally we reset the card reader once more. */ err = send_apdu (NULL, "RESET", 0); - if (err) - goto leave; + + /* Then, connect the card again. */ + if (!err) + { + char *serialno0; + + err = agent_scd_serialno (&serialno0, NULL); + if (!err) + xfree (serialno0); + } leave: xfree (answer); ----------------------------------------------------------------------- Summary of changes: g10/card-util.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 16 14:03:32 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 16 Mar 2018 14:03:32 +0100 Subject: [git] GPGME - branch, json-tool, created. gpgme-1.10.0-53-gd2b31d8 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, json-tool has been created at d2b31d8c106423bd0eaa5fffaa39b0983c9ae525 (commit) - Log ----------------------------------------------------------------- commit d2b31d8c106423bd0eaa5fffaa39b0983c9ae525 Author: Werner Koch Date: Fri Mar 16 13:55:48 2018 +0100 json: Add framework for the gpgme-json tool * src/gpgme-json.c: New. * src/Makefile.am (bin_PROGRAMS): Add gpgme-json. (gpgme_json_SOURCES, gpgme_json_LDADD): New. Signed-off-by: Werner Koch diff --git a/lang/README b/lang/README index 0c5bbd9..ee99f0f 100644 --- a/lang/README +++ b/lang/README @@ -13,3 +13,4 @@ cl Common Lisp cpp C++ qt Qt-Framework API python Python 2 and 3 (module name: gpg) +javascript Native messaging client for the gpgme-json server. diff --git a/src/Makefile.am b/src/Makefile.am index ce6f1d4..b5941fc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,7 @@ m4datadir = $(datadir)/aclocal m4data_DATA = gpgme.m4 nodist_include_HEADERS = gpgme.h -bin_PROGRAMS = gpgme-tool +bin_PROGRAMS = gpgme-tool gpgme-json if BUILD_W32_GLIB ltlib_gpgme_glib = libgpgme-glib.la @@ -95,13 +95,18 @@ if BUILD_W32_GLIB libgpgme_glib_la_SOURCES = $(main_sources) w32-glib-io.c endif -# We use a global CFLAGS setting for all library +# We use a global CFLAGS setting for all libraries # versions, because then every object file is only compiled once. AM_CFLAGS = @LIBASSUAN_CFLAGS@ @GLIB_CFLAGS@ gpgme_tool_SOURCES = gpgme-tool.c argparse.c argparse.h gpgme_tool_LDADD = libgpgme.la @LIBASSUAN_LIBS@ +gpgme_json_SOURCES = gpgme-json.c argparse.c argparse.h cJSON.c cJSON.h +gpgme_json_LDADD = -lm libgpgme.la $(GPG_ERROR_LIBS) +## We use -no-install temporary during development. +#gpgme_json_LDFLAGS = -no-install + if HAVE_W32_SYSTEM # Windows provides us with an endless stream of Tough Love. To spawn diff --git a/src/gpgme-json.c b/src/gpgme-json.c new file mode 100644 index 0000000..4251f2b --- /dev/null +++ b/src/gpgme-json.c @@ -0,0 +1,825 @@ +/* gpgme-json.c - JSON based interface to gpgme (server) + * Copyright (C) 2018 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * GPGME is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1+ + */ + +/* This is tool implements the Native Messaging protocol of web + * browsers and provides the server part of it. A Javascript based + * client can be found in lang/javascript. The used data format is + * similar to the API of openpgpjs. + */ + +#include +#include +#include +#include +#include +#ifdef HAVE_LOCALE_H +#include +#endif +#include + +#define GPGRT_ENABLE_ES_MACROS 1 +#define GPGRT_ENABLE_LOG_MACROS 1 +#include "gpgme.h" +#include "argparse.h" +#include "cJSON.h" + + +/* We don't allow a request with more than 64 MiB. */ +#define MAX_REQUEST_SIZE (64 * 1024 * 1024) + + +static void xoutofcore (const char *type) GPGRT_ATTR_NORETURN; +static cjson_t error_object_v (const char *message, + va_list arg_ptr) GPGRT_ATTR_PRINTF(1,0); +static cjson_t error_object (const char *message, + ...) GPGRT_ATTR_PRINTF(1,2); +static char *error_object_string (const char *message, + ...) GPGRT_ATTR_PRINTF(1,2); + + +/* True if interactive mode is active. */ +static int opt_interactive; + + + +/* + * Helper functions and macros + */ + +#define xtrymalloc(a) gpgrt_malloc ((a)) +#define xstrdup(a) ({ \ + char *_r = gpgrt_strdup ((a)); \ + if (!_r) \ + xoutofcore ("strdup"); \ + _r; }) +#define xstrconcat(a, ...) ({ \ + char *_r = gpgrt_strconcat ((a), __VA_ARGS__); \ + if (!_r) \ + xoutofcore ("strconcat"); \ + _r; }) +#define xfree(a) gpgrt_free ((a)) + +#define spacep(p) (*(p) == ' ' || *(p) == '\t') + + +static void +xoutofcore (const char *type) +{ + gpg_error_t err = gpg_error_from_syserror (); + log_error ("%s failed: %s\n", type, gpg_strerror (err)); + exit (2); +} + + +/* Call cJSON_CreateObject but terminate in case of an error. */ +static cjson_t +xjson_CreateObject (void) +{ + cjson_t json = cJSON_CreateObject (); + if (!json) + xoutofcore ("cJSON_CreateObject"); + return json; +} + + +/* Wrapper around cJSON_AddStringToObject which returns an gpg-error + * code instead of the NULL or the object. */ +static gpg_error_t +cjson_AddStringToObject (cjson_t object, const char *name, const char *string) +{ + if (!cJSON_AddStringToObject (object, name, string)) + return gpg_error_from_syserror (); + return 0; +} + + +/* Same as cjson_AddStringToObject but prints an error message and + * terminates. the process. */ +static void +xjson_AddStringToObject (cjson_t object, const char *name, const char *string) +{ + if (!cJSON_AddStringToObject (object, name, string)) + xoutofcore ("cJSON_AddStringToObject"); +} + + +/* Create a JSON error object. */ +static cjson_t +error_object_v (const char *message, va_list arg_ptr) +{ + cjson_t response; + char *msg; + + msg = gpgrt_vbsprintf (message, arg_ptr); + if (!msg) + xoutofcore ("error_object"); + + response = xjson_CreateObject (); + xjson_AddStringToObject (response, "type", "error"); + xjson_AddStringToObject (response, "msg", msg); + + xfree (msg); + return response; +} + + +/* Call cJSON_Print but terminate in case of an error. */ +static char * +xjson_Print (cjson_t object) +{ + char *buf; + buf = cJSON_Print (object); + if (!buf) + xoutofcore ("cJSON_Print"); + return buf; +} + + +static cjson_t +error_object (const char *message, ...) +{ + cjson_t response; + va_list arg_ptr; + + va_start (arg_ptr, message); + response = error_object_v (message, arg_ptr); + va_end (arg_ptr); + return response; +} + + +static char * +error_object_string (const char *message, ...) +{ + cjson_t response; + va_list arg_ptr; + char *msg; + + va_start (arg_ptr, message); + response = error_object_v (message, arg_ptr); + va_end (arg_ptr); + + msg = xjson_Print (response); + cJSON_Delete (response); + return msg; +} + + + +/* + * Implementaion of the commands. + */ + + +static const char hlp_encrypt[] = + "op: \"encrypt\"\n" + "keys: Array of strings with the fingerprints or user-ids\n" + " of the keys to encrypt the data. For a single key\n" + " a String may be used instead of an array.\n" + "data: Base64 encoded input data.\n" + "\n" + "Optional parameters:\n" + "protocol: Either \"openpgp\" (default) or \"cms\".\n" + "\n" + "Optional boolean flags (default is false):\n" + "armor: Request output in armored format.\n" + "always-trust: Request --always-trust option.\n" + "no-encrypt-to: Do not use a default recipient.\n" + "no-compress: Do not compress the plaintext first.\n" + "throw-keyids: Request the --throw-keyids option.\n" + "wrap: Assume the input is an OpenPGP message.\n" + "\n" + "Response on success:\n" + "type: \"ciphertext\"\n" + "data: Unless armor mode is used a Base64 encoded binary\n" + " ciphertext. In armor mode a string with an armored\n" + " OpenPGP or a PEM message.\n" + "base64: Boolean indicating whether data is base64 encoded."; +static gpg_error_t +op_encrypt (cjson_t request, cjson_t *r_result) +{ + + + return 0; +} + + + +static const char hlp_help[] = + "The tool expects a JSON object with the request and responds with\n" + "another JSON object. Even on error a JSON object is returned. The\n" + "property \"op\" is mandatory and its string value selects the\n" + "operation; if the property \"help\" with the value \"true\" exists, the\n" + "operation is not performned but a string with the documentation\n" + "returned. To list all operations it is allowed to leave out \"op\" in\n" + "help mode. Supported values for \"op\" are:\n\n" + " encrypt Encrypt data.\n" + " help Help overview."; +static gpg_error_t +op_help (cjson_t request, cjson_t *r_result) +{ + gpg_error_t err = 0; + cjson_t result = NULL; + cjson_t j_tmp; + char *buffer = NULL; + const char *msg; + + j_tmp = cJSON_GetObjectItem (request, "interactive_help"); + if (opt_interactive && j_tmp && cjson_is_string (j_tmp)) + msg = buffer = xstrconcat (hlp_help, "\n", j_tmp->valuestring, NULL); + else + msg = hlp_help; + + result = cJSON_CreateObject (); + if (!result) + err = gpg_error_from_syserror (); + if (!err) + err = cjson_AddStringToObject (result, "type", "help"); + if (!err) + err = cjson_AddStringToObject (result, "msg", msg); + + xfree (buffer); + if (err) + xfree (result); + else + *r_result = result; + return err; +} + + + +/* Process a request and return the response. The response is a newly + * allocated staring or NULL in case of an error. */ +static char * +process_request (const char *request) +{ + static struct { + const char *op; + gpg_error_t (*handler)(cjson_t request, cjson_t *r_result); + const char * const helpstr; + } optbl[] = { + { "encrypt", op_encrypt, hlp_encrypt }, + + + { "help", op_help, hlp_help }, + { NULL } + }; + gpg_error_t err = 0; + size_t erroff; + cjson_t json; + cjson_t j_tmp, j_op; + cjson_t response = NULL; + int helpmode; + const char *op; + char *res; + int idx; + + json = cJSON_Parse (request, &erroff); + if (!json) + { + log_string (GPGRT_LOGLVL_INFO, request); + log_info ("invalid JSON object at offset %zu\n", erroff); + response = error_object ("invalid JSON object at offset %zu\n", erroff); + goto leave; + } + + j_tmp = cJSON_GetObjectItem (json, "help"); + helpmode = (j_tmp && cjson_is_true (j_tmp)); + + j_op = cJSON_GetObjectItem (json, "op"); + if (!j_op || !cjson_is_string (j_op)) + { + if (!helpmode) + { + response = error_object ("Property \"op\" missing"); + goto leave; + } + op = "help"; /* Help summary. */ + } + else + op = j_op->valuestring; + + for (idx=0; optbl[idx].op; idx++) + if (!strcmp (op, optbl[idx].op)) + break; + if (optbl[idx].op) + { + if (helpmode && strcmp (op, "help")) + { + response = cJSON_CreateObject (); + if (!response) + err = gpg_error_from_syserror (); + if (!err) + err = cjson_AddStringToObject (response, "type", "help"); + if (!err) + err = cjson_AddStringToObject (response, "op", op); + if (!err) + err = cjson_AddStringToObject (response, "msg", optbl[idx].helpstr); + } + else + err = optbl[idx].handler (json, &response); + } + else /* Operation not supported. */ + { + response = error_object ("Unknown operation '%s'", op); + err = cjson_AddStringToObject (response, "op", op); + } + + leave: + cJSON_Delete (json); + json = NULL; + if (err) + log_error ("failed to create the response: %s\n", gpg_strerror (err)); + if (response) + { + res = cJSON_Print (response); + if (!res) + log_error ("Printing JSON data failed\n"); + cJSON_Delete (response); + } + else + res = NULL; + + return res; +} + + + +/* + * Driver code + */ + +/* Return a malloced line or NULL on EOF. Terminate on read + * error. */ +static char * +get_line (void) +{ + char *line = NULL; + size_t linesize = 0; + gpg_error_t err; + size_t maxlength = 2048; + int n; + const char *s; + char *p; + + again: + n = es_read_line (es_stdin, &line, &linesize, &maxlength); + if (n < 0) + { + err = gpg_error_from_syserror (); + log_error ("error reading line: %s\n", gpg_strerror (err)); + exit (1); + } + if (!n) + { + xfree (line); + line = NULL; + return NULL; /* EOF */ + } + if (!maxlength) + { + log_info ("line too long - skipped\n"); + goto again; + } + if (memchr (line, 0, n)) + log_info ("warning: line shortened due to embedded Nul character\n"); + + if (line[n-1] == '\n') + line[n-1] = 0; + + /* Trim leading spaces. */ + for (s=line; spacep (s); s++) + ; + if (s != line) + { + for (p=line; *s;) + *p++ = *s++; + *p = 0; + n = p - line; + } + + return line; +} + + +/* Process meta commands used with the standard REPL. */ +static char * +process_meta_commands (const char *request) +{ + char *result = NULL; + + while (spacep (request)) + request++; + + if (!strncmp (request, "help", 4) && (spacep (request+4) || !request[4])) + result = process_request ("{ \"op\": \"help\"," + " \"interactive_help\": " + "\"\\nMeta commands:\\n" + " ,help This help\\n" + " ,quit Terminate process\"" + "}"); + else if (!strncmp (request, "quit", 4) && (spacep (request+4) || !request[4])) + exit (0); + else + log_info ("invalid meta command\n"); + + return result; +} + + +/* If STRING has a help response, return the MSG property in a human + * readable format. */ +static char * +get_help_msg (const char *string) +{ + cjson_t json, j_type, j_msg; + const char *msg; + char *buffer = NULL; + char *p; + + json = cJSON_Parse (string, NULL); + if (json) + { + j_type = cJSON_GetObjectItem (json, "type"); + if (j_type && cjson_is_string (j_type) + && !strcmp (j_type->valuestring, "help")) + { + j_msg = cJSON_GetObjectItem (json, "msg"); + if (j_msg || cjson_is_string (j_msg)) + { + msg = j_msg->valuestring; + buffer = malloc (strlen (msg)+1); + if (buffer) + { + for (p=buffer; *msg; msg++) + { + if (*msg == '\\' && msg[1] == '\n') + *p++ = '\n'; + else + *p++ = *msg; + } + *p = 0; + } + } + } + cJSON_Delete (json); + } + return buffer; +} + + +/* An interactive standard REPL. */ +static void +interactive_repl (void) +{ + char *line = NULL; + char *request = NULL; + char *response = NULL; + char *p; + int first; + + es_setvbuf (es_stdin, NULL, _IONBF, 0); + es_fprintf (es_stderr, "%s %s ready (enter \",help\" for help)\n", + strusage (11), strusage (13)); + do + { + es_fputs ("> ", es_stderr); + es_fflush (es_stderr); + es_fflush (es_stdout); + xfree (line); + line = get_line (); + es_fflush (es_stderr); + es_fflush (es_stdout); + + first = !request; + if (line && *line) + { + if (!request) + request = xstrdup (line); + else + request = xstrconcat (request, "\n", line, NULL); + } + + if (!line) + es_fputs ("\n", es_stderr); + + if (!line || !*line || (first && *request == ',')) + { + /* Process the input. */ + xfree (response); + response = NULL; + if (request && *request == ',') + { + response = process_meta_commands (request+1); + } + else if (request) + { + response = process_request (request); + } + xfree (request); + request = NULL; + + if (response) + { + if (opt_interactive) + { + char *msg = get_help_msg (response); + if (msg) + { + xfree (response); + response = msg; + } + } + + es_fputs ("===> ", es_stderr); + es_fflush (es_stderr); + for (p=response; *p; p++) + { + if (*p == '\n') + { + es_fflush (es_stdout); + es_fputs ("\n===> ", es_stderr); + es_fflush (es_stderr); + } + else + es_putc (*p, es_stdout); + } + es_fflush (es_stdout); + es_fputs ("\n", es_stderr); + } + } + } + while (line); + + xfree (request); + xfree (response); + xfree (line); +} + + +/* Read and process asingle request. */ +static void +read_and_process_single_request (void) +{ + char *line = NULL; + char *request = NULL; + char *response = NULL; + size_t n; + + for (;;) + { + xfree (line); + line = get_line (); + if (line && *line) + request = (request? xstrconcat (request, "\n", line, NULL) + /**/ : xstrdup (line)); + if (!line) + { + if (request) + { + xfree (response); + response = process_request (request); + if (response) + { + es_fputs (response, es_stdout); + if ((n = strlen (response)) && response[n-1] != '\n') + es_fputc ('\n', es_stdout); + } + es_fflush (es_stdout); + } + break; + } + } + + xfree (response); + xfree (request); + xfree (line); +} + + +/* The Native Messaging processing loop. */ +static void +native_messaging_repl (void) +{ + gpg_error_t err; + uint32_t nrequest, nresponse; + char *request = NULL; + char *response = NULL; + size_t n; + + /* Due to the length octets we need to switch the I/O stream into + * binary mode. */ + es_set_binary (es_stdin); + es_set_binary (es_stdout); + + for (;;) + { + /* Read length. Note that the protocol uses native endianess. + * Is it allowed to call such a thing a well thought out + * protocol? */ + if (es_read (es_stdin, &nrequest, sizeof nrequest, &n)) + { + err = gpg_error_from_syserror (); + log_error ("error reading request header: %s\n", gpg_strerror (err)); + break; + } + if (!n) + break; /* EOF */ + if (n != sizeof nrequest) + { + log_error ("error reading request header: short read\n"); + break; + } + if (nrequest > MAX_REQUEST_SIZE) + { + log_error ("error reading request: request too long (%zu MiB)\n", + (size_t)nrequest / (1024*1024)); + /* Fixme: Shall we read the request t the bit bucket and + * return an error reponse or just return an error reponse + * and terminate? Needs some testing. */ + break; + } + + /* Read request. */ + request = xtrymalloc (nrequest); + if (!request) + { + err = gpg_error_from_syserror (); + log_error ("error reading request: Not enough memory for %zu MiB)\n", + (size_t)nrequest / (1024*1024)); + /* FIXME: See comment above. */ + break; + } + if (es_read (es_stdin, request, nrequest, &n)) + { + err = gpg_error_from_syserror (); + log_error ("error reading request: %s\n", gpg_strerror (err)); + break; + } + if (n != nrequest) + { + /* That is a protocol violation. */ + xfree (response); + response = error_object_string ("Invalid request:" + " short read (%zu of %zu bytes)\n", + n, (size_t)nrequest); + } + else /* Process request */ + { + xfree (response); + response = process_request (request); + } + nresponse = strlen (response); + + /* Write response */ + if (es_write (es_stdout, &nresponse, sizeof nresponse, &n)) + { + err = gpg_error_from_syserror (); + log_error ("error writing request header: %s\n", gpg_strerror (err)); + break; + } + if (n != sizeof nrequest) + { + log_error ("error writing request header: short write\n"); + break; + } + if (es_write (es_stdout, response, nresponse, &n)) + { + err = gpg_error_from_syserror (); + log_error ("error writing request: %s\n", gpg_strerror (err)); + break; + } + if (n != nresponse) + { + log_error ("error writing request: short write\n"); + break; + } + if (es_fflush (es_stdout) || es_ferror (es_stdout)) + { + err = gpg_error_from_syserror (); + log_error ("error writing request: %s\n", gpg_strerror (err)); + break; + } + } + + xfree (response); + xfree (request); +} + + + +static const char * +my_strusage( int level ) +{ + const char *p; + + switch (level) + { + case 11: p = "gpgme-json"; break; + case 13: p = PACKAGE_VERSION; break; + case 14: p = "Copyright (C) 2018 g10 Code GmbH"; break; + case 19: p = "Please report bugs to <" PACKAGE_BUGREPORT ">.\n"; break; + case 1: + case 40: + p = "Usage: gpgme-json [OPTIONS]"; + break; + case 41: + p = "Native messaging based GPGME operations.\n"; + break; + case 42: + p = "1"; /* Flag print 40 as part of 41. */ + break; + default: p = NULL; break; + } + return p; +} + + +int +main (int argc, char *argv[]) +{ + enum { CMD_DEFAULT = 0, + CMD_INTERACTIVE = 'i', + CMD_SINGLE = 's', + CMD_LIBVERSION = 501 + } cmd = CMD_DEFAULT; + static ARGPARSE_OPTS opts[] = { + ARGPARSE_c (CMD_INTERACTIVE, "interactive", "Interactive REPL"), + ARGPARSE_c (CMD_SINGLE, "single", "Single request mode"), + ARGPARSE_c (CMD_LIBVERSION, "lib-version", "Show library version"), + ARGPARSE_end() + }; + ARGPARSE_ARGS pargs = { &argc, &argv, 0 }; + + set_strusage (my_strusage); + +#ifdef HAVE_SETLOCALE + setlocale (LC_ALL, ""); +#endif + gpgme_check_version (NULL); +#ifdef LC_CTYPE + gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); +#endif +#ifdef LC_MESSAGES + gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); +#endif + + while (arg_parse (&pargs, opts)) + { + switch (pargs.r_opt) + { + case CMD_INTERACTIVE: + opt_interactive = 1; + /* Fall trough. */ + case CMD_SINGLE: + case CMD_LIBVERSION: + cmd = pargs.r_opt; + break; + + default: + pargs.err = ARGPARSE_PRINT_WARNING; + break; + } + } + + switch (cmd) + { + case CMD_DEFAULT: + native_messaging_repl (); + break; + + case CMD_SINGLE: + read_and_process_single_request (); + break; + + case CMD_INTERACTIVE: + interactive_repl (); + break; + + case CMD_LIBVERSION: + printf ("Version from header: %s (0x%06x)\n", + GPGME_VERSION, GPGME_VERSION_NUMBER); + printf ("Version from binary: %s\n", gpgme_check_version (NULL)); + printf ("Copyright blurb ...:%s\n", gpgme_check_version ("\x01\x01")); + break; + } + + return 0; +} commit 81c90d0cd0f959fd5e01baed9b4af0ec35ecb85c Author: Werner Koch Date: Wed Mar 14 11:24:38 2018 +0100 core: Adjust cJSON code for use in GPGME. * src/cJSON.c: Remove util.h. Use gpgrt alloc functions. (cJSON_Delete): Do not clobber ERRNO. (cJSON_AddItemToObject): Return OBJECT or NULL. (cJSON_AddNullToObject): New. (cJSON_AddTrueToObject): New. (cJSON_AddFalseToObject): New. (cJSON_AddBoolToObject): New. (cJSON_AddNumberToObject): New. (cJSON_AddStringToObject): New. * src/cJSON.h (cJSON__h): Replace macro by cJSON_h for C compliance. (cJSON_AddNullToObject): Remove macro. (cJSON_AddTrueToObject): Remove macro. (cJSON_AddFalseToObject): Remove macro. (cJSON_AddBoolToObject): Remove macro. (cJSON_AddNumberToObject): Remove macro. (cJSON_AddStringToObject): Remove macro. -- The gpgrt malloc functions are used so that we can easily mix memory returned by gpgrt (e.g. es_read_line) with memory returned from the JSON function. In general that is not needed but on Windows it makes a difference if the gpgme DLL is linked to a different C runtime than the application. The macros have been replaced to allow error checking (i.e out of core) for these functions. More error checking should be implemented instead of silently creating objects which are not as requested. Signed-off-by: Werner Koch diff --git a/src/cJSON.c b/src/cJSON.c index 504e33a..1941d11 100644 --- a/src/cJSON.c +++ b/src/cJSON.c @@ -20,6 +20,9 @@ * THE SOFTWARE. * * SPDX-License-Identifier: MIT + * + * Note that this code has been modified from the original code taken + * from cjson-code-58.zip. */ #ifdef HAVE_CONFIG_H @@ -35,9 +38,23 @@ #include #include -#include "util.h" /* (Payproc specific.) */ #include "cJSON.h" +/* We use malloc function wrappers from gpgrt (aka libgpg-error). */ +#if 1 +# include +# define xtrymalloc(a) gpgrt_malloc ((a)) +# define xtrycalloc(a,b) gpgrt_calloc ((a), (b)) +# define xtrystrdup(a) gpgrt_strdup ((a)) +# define xfree(a) gpgrt_free ((a)) +#else +# define xtrymalloc(a) malloc ((a)) +# define xtrycalloc(a,b) calloc ((a), (b)) +# define xtrystrdup(a) strdup ((a)) +# define xfree(a) free ((a)) +#endif + + static int cJSON_strcasecmp (const char *s1, const char *s2) { @@ -60,11 +77,17 @@ cJSON_New_Item (void) return xtrycalloc (1, sizeof (cJSON)); } -/* Delete a cJSON structure. */ +/* Delete a cJSON structure. (Does not clobber ERRNO). */ void cJSON_Delete (cJSON * c) { cJSON *next; + int save_errno; + + if (!c) + return; + + save_errno = errno; while (c) { next = c->next; @@ -77,6 +100,7 @@ cJSON_Delete (cJSON * c) xfree (c); c = next; } + errno = save_errno; } /* Parse the input text to generate a number, and populate the result @@ -132,13 +156,13 @@ print_number (cJSON * item) && d >= INT_MIN) { /* 2^64+1 can be represented in 21 chars. */ - str = (char *) xtrymalloc (21); + str = xtrymalloc (21); if (str) sprintf (str, "%d", item->valueint); } else { - str = (char *) xtrymalloc (64); /* This is a nice tradeoff. */ + str = xtrymalloc (64); /* This is a nice tradeoff. */ if (str) { if (fabs (floor (d) - d) <= DBL_EPSILON && fabs (d) < 1.0e60) @@ -328,7 +352,7 @@ print_string_ptr (const char *str) ptr++; } - out = (char *) xtrymalloc (len + 3); + out = xtrymalloc (len + 3); if (!out) return 0; @@ -606,13 +630,13 @@ print_array (cJSON * item, int depth, int fmt) /* Explicitly handle numentries==0 */ if (!numentries) { - out = (char *) xtrymalloc (3); + out = xtrymalloc (3); if (out) strcpy (out, "[]"); return out; } /* Allocate an array to hold the values for each */ - entries = (char **) xtrymalloc (numentries * sizeof (char *)); + entries = xtrymalloc (numentries * sizeof (char *)); if (!entries) return 0; memset (entries, 0, numentries * sizeof (char *)); @@ -629,9 +653,9 @@ print_array (cJSON * item, int depth, int fmt) child = child->next; } - /* If we didn't fail, try to malloc the output string */ + /* If we didn't fail, try to xtrymalloc the output string */ if (!fail) - out = (char *) xtrymalloc (len); + out = xtrymalloc (len); /* If that fails, we fail. */ if (!out) fail = 1; @@ -748,7 +772,7 @@ print_object (cJSON * item, int depth, int fmt) /* Explicitly handle empty object case */ if (!numentries) { - out = (char *) xtrymalloc (fmt ? depth + 4 : 3); + out = xtrymalloc (fmt ? depth + 4 : 3); if (!out) return 0; ptr = out; @@ -764,10 +788,10 @@ print_object (cJSON * item, int depth, int fmt) return out; } /* Allocate space for the names and the objects */ - entries = (char **) xtrymalloc (numentries * sizeof (char *)); + entries = xtrymalloc (numentries * sizeof (char *)); if (!entries) return 0; - names = (char **) xtrymalloc (numentries * sizeof (char *)); + names = xtrymalloc (numentries * sizeof (char *)); if (!names) { xfree (entries); @@ -794,7 +818,7 @@ print_object (cJSON * item, int depth, int fmt) /* Try to allocate the output string */ if (!fail) - out = (char *) xtrymalloc (len); + out = xtrymalloc (len); if (!out) fail = 1; @@ -920,15 +944,106 @@ cJSON_AddItemToArray (cJSON * array, cJSON * item) } } -void +cJSON * cJSON_AddItemToObject (cJSON * object, const char *string, cJSON * item) { + char *tmp; + if (!item) - return; + return 0; + tmp = xtrystrdup (string); + if (!tmp) + return NULL; + if (item->string) xfree (item->string); - item->string = xtrystrdup (string); + item->string = tmp; cJSON_AddItemToArray (object, item); + return object; +} + +cJSON * +cJSON_AddNullToObject (cJSON *object, const char *name) +{ + cJSON *obj, *tmp; + + tmp = cJSON_CreateNull (); + if (!tmp) + return NULL; + obj = cJSON_AddItemToObject(object, name, tmp); + if (!obj) + cJSON_Delete (tmp); + return obj; +} + +cJSON * +cJSON_AddTrueToObject (cJSON *object, const char *name) +{ + cJSON *obj, *tmp; + + tmp = cJSON_CreateTrue (); + if (!tmp) + return NULL; + obj = cJSON_AddItemToObject(object, name, tmp); + if (!obj) + cJSON_Delete (tmp); + return obj; +} + +cJSON * +cJSON_AddFalseToObject (cJSON *object, const char *name) +{ + cJSON *obj, *tmp; + + tmp = cJSON_CreateFalse (); + if (!tmp) + return NULL; + obj = cJSON_AddItemToObject(object, name, tmp); + if (!obj) + cJSON_Delete (tmp); + return obj; +} + +cJSON * +cJSON_AddBoolToObject (cJSON *object, const char *name, int b) +{ + cJSON *obj, *tmp; + + tmp = cJSON_CreateBool (b); + if (!tmp) + return NULL; + obj = cJSON_AddItemToObject(object, name, tmp); + if (!obj) + cJSON_Delete (tmp); + return obj; +} + +cJSON * +cJSON_AddNumberToObject (cJSON *object, const char *name, double num) +{ + cJSON *obj, *tmp; + + tmp = cJSON_CreateNumber (num); + if (!tmp) + return NULL; + obj = cJSON_AddItemToObject(object, name, tmp); + if (!obj) + cJSON_Delete (tmp); + return obj; +} + +cJSON * +cJSON_AddStringToObject (cJSON *object, const char *name, const char *string) +{ + cJSON *obj, *tmp; + + tmp = cJSON_CreateString (string); + if (!tmp) + return NULL; + obj = cJSON_AddItemToObject(object, name, tmp); + if (!obj) + cJSON_Delete (tmp); + return obj; } void diff --git a/src/cJSON.h b/src/cJSON.h index 53bac34..69c3056 100644 --- a/src/cJSON.h +++ b/src/cJSON.h @@ -20,10 +20,13 @@ * THE SOFTWARE. * * SPDX-License-Identifier: MIT + * + * Note that this code has been modified from the original code taken + * from cjson-code-58.zip. */ -#ifndef cJSON__h -#define cJSON__h +#ifndef cJSON_h +#define cJSON_h #ifdef __cplusplus extern "C" @@ -119,10 +122,20 @@ extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count); extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count); extern cJSON *cJSON_CreateStringArray(const char **strings,int count); -/* Append item to the specified array/object. */ +/* Append item to the specified array. */ extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); -extern void cJSON_AddItemToObject(cJSON *object, - const char *string, cJSON *item); + +/* Append item to the specified object. */ +extern cJSON *cJSON_AddItemToObject(cJSON *object, const char *name, + cJSON *item); +extern cJSON *cJSON_AddNullToObject (cJSON *object, const char *name); +extern cJSON *cJSON_AddTrueToObject (cJSON *object, const char *name); +extern cJSON *cJSON_AddFalseToObject (cJSON *object, const char *name); +extern cJSON *cJSON_AddBoolToObject (cJSON *object, const char *name, int b); +extern cJSON *cJSON_AddNumberToObject (cJSON *object, const char *name, + double num); +extern cJSON *cJSON_AddStringToObject (cJSON *object, const char *name, + const char *string); /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't @@ -161,20 +174,6 @@ extern cJSON *cJSON_ParseWithOpts(const char *value, extern void cJSON_Minify(char *json); -/* Macros for creating things quickly. */ -#define cJSON_AddNullToObject(object,name) \ - cJSON_AddItemToObject(object, name, cJSON_CreateNull()) -#define cJSON_AddTrueToObject(object,name) \ - cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) -#define cJSON_AddFalseToObject(object,name) \ - cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) -#define cJSON_AddBoolToObject(object,name,b) \ - cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) -#define cJSON_AddNumberToObject(object,name,n) \ - cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) -#define cJSON_AddStringToObject(object,name,s) \ - cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) - /* When assigning an integer value, it needs to be propagated to valuedouble too. */ #define cJSON_SetIntValue(object,val) \ @@ -184,4 +183,4 @@ extern void cJSON_Minify(char *json); } #endif -#endif /* cJSON__h */ +#endif /* cJSON_h */ commit 8eb08b318913644d918002f3195f7ec0e75ae239 Author: Werner Koch Date: Wed Mar 14 10:55:52 2018 +0100 core: Import cJSON code from the payproc project. * src/cJSON.c: New. * src/cJSON.h: New. * src/cJSON.readme: New. -- This is a copy of the code from the payproc commit af5d6b4f820ee19e246a2cab6f56465fe91f1233. The code was originally added to payproc with the commit below. Signed-off-by: Werner Koch =============================================== commit 7ae7ef29bc5ec19e005e6a5a739233d655f3f05f Author: Werner Koch AuthorDate: Wed Apr 2 09:01:42 2014 +0200 Commit: Werner Koch CommitDate: Wed Apr 2 09:12:02 2014 +0200 Simplify cJSON and add new macros. * src/cJSON.h: Re-indented. (cjson_t): New. (cjson_is_): New macros. * src/cJSON.c: Re-indented. Include errno.h and our util.h. (ep): Remove global var. (cJSON_GetErrorPtr): Remove. (cJSON_strcasecmp): Cast args for use with tolower. (cJSON_malloc, cJSON_free): Remove. Change callers to use xtrymalloc and xfree. (cJSON_InitHooks): Remove. (cJSON_strdup): Remove. Change callers to use xtrystrdup. (cJSON_New_Item): Simplify. (cJSON_ParseWithOpts, cJSON_Parse): Add arg R_ERROFF. (parse_string, parse_value, parse_array, parse_object): Add arg EP. -- cJSON has been taken from cjson-code-58.zip. The README file has been renamed to cJSON.readme and the files have been changed to GNU coding standards. Because that parser is small enough to be source copied it does not make sense to treat it as a library and I changed the memory allocation functions to the usual xmalloc ones. The only external dependency now is out util.h which declares those functions. The lowercase cjson_t better fits into our coding style as well as the new macros. Thanks to Dave Gamble for this nice parser. =============================================== diff --git a/src/cJSON.c b/src/cJSON.c new file mode 100644 index 0000000..504e33a --- /dev/null +++ b/src/cJSON.c @@ -0,0 +1,1277 @@ +/* cJSON.c - JSON parser in C. + * Copyright (c) 2009 Dave Gamble + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" /* (Payproc specific.) */ +#include "cJSON.h" + +static int +cJSON_strcasecmp (const char *s1, const char *s2) +{ + if (!s1) + return (s1 == s2) ? 0 : 1; + if (!s2) + return 1; + for (; tolower (*(const unsigned char *)s1) + == tolower (*(const unsigned char *) s2); ++s1, ++s2) + if (*s1 == 0) + return 0; + return tolower (*(const unsigned char *) s1) - + tolower (*(const unsigned char *) s2); +} + +/* Internal constructor. */ +static cJSON * +cJSON_New_Item (void) +{ + return xtrycalloc (1, sizeof (cJSON)); +} + +/* Delete a cJSON structure. */ +void +cJSON_Delete (cJSON * c) +{ + cJSON *next; + while (c) + { + next = c->next; + if (!(c->type & cJSON_IsReference) && c->child) + cJSON_Delete (c->child); + if (!(c->type & cJSON_IsReference) && c->valuestring) + xfree (c->valuestring); + if (c->string) + xfree (c->string); + xfree (c); + c = next; + } +} + +/* Parse the input text to generate a number, and populate the result + * into item. */ +static const char * +parse_number (cJSON * item, const char *num) +{ + double n = 0, sign = 1, scale = 0; + int subscale = 0, signsubscale = 1; + + if (*num == '-') + sign = -1, num++; /* Has sign? */ + if (*num == '0') + num++; /* is zero */ + if (*num >= '1' && *num <= '9') + do + n = (n * 10.0) + (*num++ - '0'); + while (*num >= '0' && *num <= '9'); /* Number? */ + if (*num == '.' && num[1] >= '0' && num[1] <= '9') + { + num++; + do + n = (n * 10.0) + (*num++ - '0'), scale--; + while (*num >= '0' && *num <= '9'); + } /* Fractional part? */ + if (*num == 'e' || *num == 'E') /* Exponent? */ + { + num++; + if (*num == '+') + num++; + else if (*num == '-') + signsubscale = -1, num++; /* With sign? */ + while (*num >= '0' && *num <= '9') + subscale = (subscale * 10) + (*num++ - '0'); /* Number? */ + } + + /* number = +/- number.fraction * 10^+/- exponent */ + n = sign * n * pow (10.0, (scale + subscale * signsubscale)); + + item->valuedouble = n; + item->valueint = (int) n; + item->type = cJSON_Number; + return num; +} + +/* Render the number nicely from the given item into a string. */ +static char * +print_number (cJSON * item) +{ + char *str; + double d = item->valuedouble; + if (fabs (((double) item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX + && d >= INT_MIN) + { + /* 2^64+1 can be represented in 21 chars. */ + str = (char *) xtrymalloc (21); + if (str) + sprintf (str, "%d", item->valueint); + } + else + { + str = (char *) xtrymalloc (64); /* This is a nice tradeoff. */ + if (str) + { + if (fabs (floor (d) - d) <= DBL_EPSILON && fabs (d) < 1.0e60) + sprintf (str, "%.0f", d); + else if (fabs (d) < 1.0e-6 || fabs (d) > 1.0e9) + sprintf (str, "%e", d); + else + sprintf (str, "%f", d); + } + } + return str; +} + +static unsigned +parse_hex4 (const char *str) +{ + unsigned h = 0; + if (*str >= '0' && *str <= '9') + h += (*str) - '0'; + else if (*str >= 'A' && *str <= 'F') + h += 10 + (*str) - 'A'; + else if (*str >= 'a' && *str <= 'f') + h += 10 + (*str) - 'a'; + else + return 0; + h = h << 4; + str++; + if (*str >= '0' && *str <= '9') + h += (*str) - '0'; + else if (*str >= 'A' && *str <= 'F') + h += 10 + (*str) - 'A'; + else if (*str >= 'a' && *str <= 'f') + h += 10 + (*str) - 'a'; + else + return 0; + h = h << 4; + str++; + if (*str >= '0' && *str <= '9') + h += (*str) - '0'; + else if (*str >= 'A' && *str <= 'F') + h += 10 + (*str) - 'A'; + else if (*str >= 'a' && *str <= 'f') + h += 10 + (*str) - 'a'; + else + return 0; + h = h << 4; + str++; + if (*str >= '0' && *str <= '9') + h += (*str) - '0'; + else if (*str >= 'A' && *str <= 'F') + h += 10 + (*str) - 'A'; + else if (*str >= 'a' && *str <= 'f') + h += 10 + (*str) - 'a'; + else + return 0; + return h; +} + +/* Parse the input text into an unescaped cstring, and populate item. */ +static const unsigned char firstByteMark[7] = + { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; +static const char * +parse_string (cJSON * item, const char *str, const char **ep) +{ + const char *ptr = str + 1; + char *ptr2; + char *out; + int len = 0; + unsigned uc, uc2; + if (*str != '\"') + { + *ep = str; + return 0; + } /* not a string! */ + + while (*ptr != '\"' && *ptr && ++len) + if (*ptr++ == '\\') + ptr++; /* Skip escaped quotes. */ + + out = xtrymalloc (len + 1); /* This is how long we need for the + string, roughly. */ + if (!out) + return 0; + + ptr = str + 1; + ptr2 = out; + while (*ptr != '\"' && *ptr) + { + if (*ptr != '\\') + *ptr2++ = *ptr++; + else + { + ptr++; + switch (*ptr) + { + case 'b': + *ptr2++ = '\b'; + break; + case 'f': + *ptr2++ = '\f'; + break; + case 'n': + *ptr2++ = '\n'; + break; + case 'r': + *ptr2++ = '\r'; + break; + case 't': + *ptr2++ = '\t'; + break; + case 'u': /* transcode utf16 to utf8. */ + uc = parse_hex4 (ptr + 1); + ptr += 4; /* get the unicode char. */ + + if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) + break; /* check for invalid. */ + + if (uc >= 0xD800 && uc <= 0xDBFF) /* UTF16 surrogate pairs. */ + { + if (ptr[1] != '\\' || ptr[2] != 'u') + break; /* missing second-half of surrogate. */ + uc2 = parse_hex4 (ptr + 3); + ptr += 6; + if (uc2 < 0xDC00 || uc2 > 0xDFFF) + break; /* invalid second-half of surrogate. */ + uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF)); + } + + len = 4; + if (uc < 0x80) + len = 1; + else if (uc < 0x800) + len = 2; + else if (uc < 0x10000) + len = 3; + ptr2 += len; + + switch (len) + { + case 4: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 3: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 2: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 1: + *--ptr2 = (uc | firstByteMark[len]); + } + ptr2 += len; + break; + default: + *ptr2++ = *ptr; + break; + } + ptr++; + } + } + *ptr2 = 0; + if (*ptr == '\"') + ptr++; + item->valuestring = out; + item->type = cJSON_String; + return ptr; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static char * +print_string_ptr (const char *str) +{ + const char *ptr; + char *ptr2, *out; + int len = 0; + unsigned char token; + + if (!str) + return xtrystrdup (""); + ptr = str; + while ((token = *ptr) && ++len) + { + if (strchr ("\"\\\b\f\n\r\t", token)) + len++; + else if (token < 32) + len += 5; + ptr++; + } + + out = (char *) xtrymalloc (len + 3); + if (!out) + return 0; + + ptr2 = out; + ptr = str; + *ptr2++ = '\"'; + while (*ptr) + { + if ((unsigned char) *ptr > 31 && *ptr != '\"' && *ptr != '\\') + *ptr2++ = *ptr++; + else + { + *ptr2++ = '\\'; + switch (token = *ptr++) + { + case '\\': + *ptr2++ = '\\'; + break; + case '\"': + *ptr2++ = '\"'; + break; + case '\b': + *ptr2++ = 'b'; + break; + case '\f': + *ptr2++ = 'f'; + break; + case '\n': + *ptr2++ = 'n'; + break; + case '\r': + *ptr2++ = 'r'; + break; + case '\t': + *ptr2++ = 't'; + break; + default: + sprintf (ptr2, "u%04x", token); + ptr2 += 5; + break; /* escape and print */ + } + } + } + *ptr2++ = '\"'; + *ptr2++ = 0; + return out; +} + +/* Invote print_string_ptr (which is useful) on an item. */ +static char * +print_string (cJSON * item) +{ + return print_string_ptr (item->valuestring); +} + +/* Predeclare these prototypes. */ +static const char *parse_value (cJSON * item, const char *value, + const char **ep); +static char *print_value (cJSON * item, int depth, int fmt); +static const char *parse_array (cJSON * item, const char *value, + const char **ep); +static char *print_array (cJSON * item, int depth, int fmt); +static const char *parse_object (cJSON * item, const char *value, + const char **ep); +static char *print_object (cJSON * item, int depth, int fmt); + +/* Utility to jump whitespace and cr/lf */ +static const char * +skip (const char *in) +{ + while (in && *in && (unsigned char) *in <= 32) + in++; + return in; +} + +/* Parse an object - create a new root, and populate. */ +cJSON * +cJSON_ParseWithOpts (const char *value, const char **return_parse_end, + int require_null_terminated, size_t *r_erroff) +{ + const char *end = 0; + const char *ep = 0; + cJSON *c; + + if (r_erroff) + *r_erroff = 0; + + c = cJSON_New_Item (); + if (!c) + return NULL; /* memory fail */ + + end = parse_value (c, skip (value), &ep); + if (!end) + { + cJSON_Delete (c); + errno = EINVAL; + if (r_erroff) + *r_erroff = ep - value; + return 0; + } /* parse failure. ep is set. */ + + /* if we require null-terminated JSON without appended garbage, skip + and then check for a null terminator */ + if (require_null_terminated) + { + end = skip (end); + if (*end) + { + cJSON_Delete (c); + ep = end; + errno = EINVAL; + if (r_erroff) + *r_erroff = ep - value; + return 0; + } + } + if (return_parse_end) + *return_parse_end = end; + return c; +} + +/* Default options for cJSON_Parse */ +cJSON * +cJSON_Parse (const char *value, size_t *r_erroff) +{ + return cJSON_ParseWithOpts (value, 0, 0, r_erroff); +} + +/* Render a cJSON item/entity/structure to text. */ +char * +cJSON_Print (cJSON * item) +{ + return print_value (item, 0, 1); +} + +char * +cJSON_PrintUnformatted (cJSON * item) +{ + return print_value (item, 0, 0); +} + +/* Parser core - when encountering text, process appropriately. */ +static const char * +parse_value (cJSON * item, const char *value, const char **ep) +{ + if (!value) + return 0; /* Fail on null. */ + if (!strncmp (value, "null", 4)) + { + item->type = cJSON_NULL; + return value + 4; + } + if (!strncmp (value, "false", 5)) + { + item->type = cJSON_False; + return value + 5; + } + if (!strncmp (value, "true", 4)) + { + item->type = cJSON_True; + item->valueint = 1; + return value + 4; + } + if (*value == '\"') + { + return parse_string (item, value, ep); + } + if (*value == '-' || (*value >= '0' && *value <= '9')) + { + return parse_number (item, value); + } + if (*value == '[') + { + return parse_array (item, value, ep); + } + if (*value == '{') + { + return parse_object (item, value, ep); + } + + *ep = value; + return 0; /* failure. */ +} + +/* Render a value to text. */ +static char * +print_value (cJSON * item, int depth, int fmt) +{ + char *out = 0; + if (!item) + return 0; + switch ((item->type) & 255) + { + case cJSON_NULL: + out = xtrystrdup ("null"); + break; + case cJSON_False: + out = xtrystrdup ("false"); + break; + case cJSON_True: + out = xtrystrdup ("true"); + break; + case cJSON_Number: + out = print_number (item); + break; + case cJSON_String: + out = print_string (item); + break; + case cJSON_Array: + out = print_array (item, depth, fmt); + break; + case cJSON_Object: + out = print_object (item, depth, fmt); + break; + } + return out; +} + +/* Build an array from input text. */ +static const char * +parse_array (cJSON * item, const char *value, const char **ep) +{ + cJSON *child; + if (*value != '[') + { + *ep = value; + return 0; + } /* not an array! */ + + item->type = cJSON_Array; + value = skip (value + 1); + if (*value == ']') + return value + 1; /* empty array. */ + + item->child = child = cJSON_New_Item (); + if (!item->child) + return 0; /* memory fail */ + /* skip any spacing, get the value. */ + value = skip (parse_value (child, skip (value), ep)); + if (!value) + return 0; + + while (*value == ',') + { + cJSON *new_item; + if (!(new_item = cJSON_New_Item ())) + return 0; /* memory fail */ + child->next = new_item; + new_item->prev = child; + child = new_item; + value = skip (parse_value (child, skip (value + 1), ep)); + if (!value) + return 0; /* memory fail */ + } + + if (*value == ']') + return value + 1; /* end of array */ + *ep = value; + return 0; /* malformed. */ +} + +/* Render an array to text */ +static char * +print_array (cJSON * item, int depth, int fmt) +{ + char **entries; + char *out = 0, *ptr, *ret; + int len = 5; + cJSON *child = item->child; + int numentries = 0, i = 0, fail = 0; + + /* How many entries in the array? */ + while (child) + numentries++, child = child->next; + /* Explicitly handle numentries==0 */ + if (!numentries) + { + out = (char *) xtrymalloc (3); + if (out) + strcpy (out, "[]"); + return out; + } + /* Allocate an array to hold the values for each */ + entries = (char **) xtrymalloc (numentries * sizeof (char *)); + if (!entries) + return 0; + memset (entries, 0, numentries * sizeof (char *)); + /* Retrieve all the results: */ + child = item->child; + while (child && !fail) + { + ret = print_value (child, depth + 1, fmt); + entries[i++] = ret; + if (ret) + len += strlen (ret) + 2 + (fmt ? 1 : 0); + else + fail = 1; + child = child->next; + } + + /* If we didn't fail, try to malloc the output string */ + if (!fail) + out = (char *) xtrymalloc (len); + /* If that fails, we fail. */ + if (!out) + fail = 1; + + /* Handle failure. */ + if (fail) + { + for (i = 0; i < numentries; i++) + if (entries[i]) + xfree (entries[i]); + xfree (entries); + return 0; + } + + /* Compose the output array. */ + *out = '['; + ptr = out + 1; + *ptr = 0; + for (i = 0; i < numentries; i++) + { + strcpy (ptr, entries[i]); + ptr += strlen (entries[i]); + if (i != numentries - 1) + { + *ptr++ = ','; + if (fmt) + *ptr++ = ' '; + *ptr = 0; + } + xfree (entries[i]); + } + xfree (entries); + *ptr++ = ']'; + *ptr++ = 0; + return out; +} + +/* Build an object from the text. */ +static const char * +parse_object (cJSON * item, const char *value, const char **ep) +{ + cJSON *child; + if (*value != '{') + { + *ep = value; + return 0; + } /* not an object! */ + + item->type = cJSON_Object; + value = skip (value + 1); + if (*value == '}') + return value + 1; /* empty array. */ + + item->child = child = cJSON_New_Item (); + if (!item->child) + return 0; + value = skip (parse_string (child, skip (value), ep)); + if (!value) + return 0; + child->string = child->valuestring; + child->valuestring = 0; + if (*value != ':') + { + *ep = value; + return 0; + } /* fail! */ + /* skip any spacing, get the value. */ + value = skip (parse_value (child, skip (value + 1), ep)); + if (!value) + return 0; + + while (*value == ',') + { + cJSON *new_item; + if (!(new_item = cJSON_New_Item ())) + return 0; /* memory fail */ + child->next = new_item; + new_item->prev = child; + child = new_item; + value = skip (parse_string (child, skip (value + 1), ep)); + if (!value) + return 0; + child->string = child->valuestring; + child->valuestring = 0; + if (*value != ':') + { + *ep = value; + return 0; + } /* fail! */ + /* skip any spacing, get the value. */ + value = skip (parse_value (child, skip (value + 1), ep)); + if (!value) + return 0; + } + + if (*value == '}') + return value + 1; /* end of array */ + *ep = value; + return 0; /* malformed. */ +} + +/* Render an object to text. */ +static char * +print_object (cJSON * item, int depth, int fmt) +{ + char **entries = 0, **names = 0; + char *out = 0, *ptr, *ret, *str; + int len = 7, i = 0, j; + cJSON *child = item->child; + int numentries = 0, fail = 0; + /* Count the number of entries. */ + while (child) + numentries++, child = child->next; + /* Explicitly handle empty object case */ + if (!numentries) + { + out = (char *) xtrymalloc (fmt ? depth + 4 : 3); + if (!out) + return 0; + ptr = out; + *ptr++ = '{'; + if (fmt) + { + *ptr++ = '\n'; + for (i = 0; i < depth - 1; i++) + *ptr++ = '\t'; + } + *ptr++ = '}'; + *ptr++ = 0; + return out; + } + /* Allocate space for the names and the objects */ + entries = (char **) xtrymalloc (numentries * sizeof (char *)); + if (!entries) + return 0; + names = (char **) xtrymalloc (numentries * sizeof (char *)); + if (!names) + { + xfree (entries); + return 0; + } + memset (entries, 0, sizeof (char *) * numentries); + memset (names, 0, sizeof (char *) * numentries); + + /* Collect all the results into our arrays: */ + child = item->child; + depth++; + if (fmt) + len += depth; + while (child) + { + names[i] = str = print_string_ptr (child->string); + entries[i++] = ret = print_value (child, depth, fmt); + if (str && ret) + len += strlen (ret) + strlen (str) + 2 + (fmt ? 2 + depth : 0); + else + fail = 1; + child = child->next; + } + + /* Try to allocate the output string */ + if (!fail) + out = (char *) xtrymalloc (len); + if (!out) + fail = 1; + + /* Handle failure */ + if (fail) + { + for (i = 0; i < numentries; i++) + { + if (names[i]) + xfree (names[i]); + if (entries[i]) + xfree (entries[i]); + } + xfree (names); + xfree (entries); + return 0; + } + + /* Compose the output: */ + *out = '{'; + ptr = out + 1; + if (fmt) + *ptr++ = '\n'; + *ptr = 0; + for (i = 0; i < numentries; i++) + { + if (fmt) + for (j = 0; j < depth; j++) + *ptr++ = '\t'; + strcpy (ptr, names[i]); + ptr += strlen (names[i]); + *ptr++ = ':'; + if (fmt) + *ptr++ = '\t'; + strcpy (ptr, entries[i]); + ptr += strlen (entries[i]); + if (i != numentries - 1) + *ptr++ = ','; + if (fmt) + *ptr++ = '\n'; + *ptr = 0; + xfree (names[i]); + xfree (entries[i]); + } + + xfree (names); + xfree (entries); + if (fmt) + for (i = 0; i < depth - 1; i++) + *ptr++ = '\t'; + *ptr++ = '}'; + *ptr++ = 0; + return out; +} + +/* Get Array size/item / object item. */ +int +cJSON_GetArraySize (cJSON * array) +{ + cJSON *c = array->child; + int i = 0; + while (c) + i++, c = c->next; + return i; +} + +cJSON * +cJSON_GetArrayItem (cJSON * array, int item) +{ + cJSON *c = array->child; + while (c && item > 0) + item--, c = c->next; + return c; +} + +cJSON * +cJSON_GetObjectItem (cJSON * object, const char *string) +{ + cJSON *c = object->child; + while (c && cJSON_strcasecmp (c->string, string)) + c = c->next; + return c; +} + +/* Utility for array list handling. */ +static void +suffix_object (cJSON * prev, cJSON * item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON * +create_reference (cJSON * item) +{ + cJSON *ref = cJSON_New_Item (); + if (!ref) + return 0; + memcpy (ref, item, sizeof (cJSON)); + ref->string = 0; + ref->type |= cJSON_IsReference; + ref->next = ref->prev = 0; + return ref; +} + +/* Add item to array/object. */ +void +cJSON_AddItemToArray (cJSON * array, cJSON * item) +{ + cJSON *c = array->child; + if (!item) + return; + if (!c) + { + array->child = item; + } + else + { + while (c && c->next) + c = c->next; + suffix_object (c, item); + } +} + +void +cJSON_AddItemToObject (cJSON * object, const char *string, cJSON * item) +{ + if (!item) + return; + if (item->string) + xfree (item->string); + item->string = xtrystrdup (string); + cJSON_AddItemToArray (object, item); +} + +void +cJSON_AddItemReferenceToArray (cJSON * array, cJSON * item) +{ + cJSON_AddItemToArray (array, create_reference (item)); +} + +void +cJSON_AddItemReferenceToObject (cJSON * object, const char *string, + cJSON * item) +{ + cJSON_AddItemToObject (object, string, create_reference (item)); +} + +cJSON * +cJSON_DetachItemFromArray (cJSON * array, int which) +{ + cJSON *c = array->child; + while (c && which > 0) + c = c->next, which--; + if (!c) + return 0; + if (c->prev) + c->prev->next = c->next; + if (c->next) + c->next->prev = c->prev; + if (c == array->child) + array->child = c->next; + c->prev = c->next = 0; + return c; +} + +void +cJSON_DeleteItemFromArray (cJSON * array, int which) +{ + cJSON_Delete (cJSON_DetachItemFromArray (array, which)); +} + +cJSON * +cJSON_DetachItemFromObject (cJSON * object, const char *string) +{ + int i = 0; + cJSON *c = object->child; + while (c && cJSON_strcasecmp (c->string, string)) + i++, c = c->next; + if (c) + return cJSON_DetachItemFromArray (object, i); + return 0; +} + +void +cJSON_DeleteItemFromObject (cJSON * object, const char *string) +{ + cJSON_Delete (cJSON_DetachItemFromObject (object, string)); +} + +/* Replace array/object items with new ones. */ +void +cJSON_ReplaceItemInArray (cJSON * array, int which, cJSON * newitem) +{ + cJSON *c = array->child; + while (c && which > 0) + c = c->next, which--; + if (!c) + return; + newitem->next = c->next; + newitem->prev = c->prev; + if (newitem->next) + newitem->next->prev = newitem; + if (c == array->child) + array->child = newitem; + else + newitem->prev->next = newitem; + c->next = c->prev = 0; + cJSON_Delete (c); +} + +void +cJSON_ReplaceItemInObject (cJSON * object, const char *string, + cJSON * newitem) +{ + int i = 0; + cJSON *c = object->child; + while (c && cJSON_strcasecmp (c->string, string)) + i++, c = c->next; + if (c) + { + newitem->string = xtrystrdup (string); + cJSON_ReplaceItemInArray (object, i, newitem); + } +} + +/* Create basic types: */ +cJSON * +cJSON_CreateNull (void) +{ + cJSON *item = cJSON_New_Item (); + if (item) + item->type = cJSON_NULL; + return item; +} + +cJSON * +cJSON_CreateTrue (void) +{ + cJSON *item = cJSON_New_Item (); + if (item) + item->type = cJSON_True; + return item; +} + +cJSON * +cJSON_CreateFalse (void) +{ + cJSON *item = cJSON_New_Item (); + if (item) + item->type = cJSON_False; + return item; +} + +cJSON * +cJSON_CreateBool (int b) +{ + cJSON *item = cJSON_New_Item (); + if (item) + item->type = b ? cJSON_True : cJSON_False; + return item; +} + +cJSON * +cJSON_CreateNumber (double num) +{ + cJSON *item = cJSON_New_Item (); + if (item) + { + item->type = cJSON_Number; + item->valuedouble = num; + item->valueint = (int) num; + } + return item; +} + +cJSON * +cJSON_CreateString (const char *string) +{ + cJSON *item = cJSON_New_Item (); + if (item) + { + item->type = cJSON_String; + item->valuestring = xtrystrdup (string); + } + return item; +} + +cJSON * +cJSON_CreateArray (void) +{ + cJSON *item = cJSON_New_Item (); + if (item) + item->type = cJSON_Array; + return item; +} + +cJSON * +cJSON_CreateObject (void) +{ + cJSON *item = cJSON_New_Item (); + if (item) + item->type = cJSON_Object; + return item; +} + +/* Create Arrays: */ +cJSON * +cJSON_CreateIntArray (const int *numbers, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray (); + for (i = 0; a && i < count; i++) + { + n = cJSON_CreateNumber (numbers[i]); + if (!i) + a->child = n; + else + suffix_object (p, n); + p = n; + } + return a; +} + +cJSON * +cJSON_CreateFloatArray (const float *numbers, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray (); + for (i = 0; a && i < count; i++) + { + n = cJSON_CreateNumber (numbers[i]); + if (!i) + a->child = n; + else + suffix_object (p, n); + p = n; + } + return a; +} + +cJSON * +cJSON_CreateDoubleArray (const double *numbers, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray (); + for (i = 0; a && i < count; i++) + { + n = cJSON_CreateNumber (numbers[i]); + if (!i) + a->child = n; + else + suffix_object (p, n); + p = n; + } + return a; +} + +cJSON * +cJSON_CreateStringArray (const char **strings, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray (); + for (i = 0; a && i < count; i++) + { + n = cJSON_CreateString (strings[i]); + if (!i) + a->child = n; + else + suffix_object (p, n); + p = n; + } + return a; +} + +/* Duplication */ +cJSON * +cJSON_Duplicate (cJSON * item, int recurse) +{ + cJSON *newitem, *cptr, *nptr = 0, *newchild; + /* Bail on bad ptr */ + if (!item) + return 0; + /* Create new item */ + newitem = cJSON_New_Item (); + if (!newitem) + return 0; + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference), newitem->valueint = + item->valueint, newitem->valuedouble = item->valuedouble; + if (item->valuestring) + { + newitem->valuestring = xtrystrdup (item->valuestring); + if (!newitem->valuestring) + { + cJSON_Delete (newitem); + return 0; + } + } + if (item->string) + { + newitem->string = xtrystrdup (item->string); + if (!newitem->string) + { + cJSON_Delete (newitem); + return 0; + } + } + /* If non-recursive, then we're done! */ + if (!recurse) + return newitem; + /* Walk the ->next chain for the child. */ + cptr = item->child; + while (cptr) + { + /* Duplicate (with recurse) each item in the ->next chain */ + newchild = cJSON_Duplicate (cptr, 1); + if (!newchild) + { + cJSON_Delete (newitem); + return 0; + } + if (nptr) + { + /* If newitem->child already set, + * then crosswire ->prev and ->next and move on. */ + nptr->next = newchild, newchild->prev = nptr; + nptr = newchild; + } + else + { + /* Set newitem->child and move to it. */ + newitem->child = newchild; + nptr = newchild; + } + cptr = cptr->next; + } + return newitem; +} + +void +cJSON_Minify (char *json) +{ + char *into = json; + while (*json) + { + if (*json == ' ') + json++; + else if (*json == '\t') + json++; /* Whitespace characters. */ + else if (*json == '\r') + json++; + else if (*json == '\n') + json++; + else if (*json == '/' && json[1] == '/') + while (*json && *json != '\n') + json++; /* Double-slash comments, to end of line. */ + else if (*json == '/' && json[1] == '*') + { + while (*json && !(*json == '*' && json[1] == '/')) + json++; + json += 2; + } /* Multiline comments. */ + else if (*json == '\"') + { + *into++ = *json++; + while (*json && *json != '\"') + { + if (*json == '\\') + *into++ = *json++; + *into++ = *json++; + } + *into++ = *json++; + } /* String literals, which are \" sensitive. */ + else + *into++ = *json++; /* All other characters. */ + } + *into = 0; /* and null-terminate. */ +} diff --git a/src/cJSON.h b/src/cJSON.h new file mode 100644 index 0000000..53bac34 --- /dev/null +++ b/src/cJSON.h @@ -0,0 +1,187 @@ +/* cJSON.h + * Copyright (c) 2009 Dave Gamble + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + */ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#if 0 /*(to make Emacs auto-indent happy)*/ +} +#endif +#endif + +/* cJSON Types: */ +#define cJSON_False 0 +#define cJSON_True 1 +#define cJSON_NULL 2 +#define cJSON_Number 3 +#define cJSON_String 4 +#define cJSON_Array 5 +#define cJSON_Object 6 + +#define cJSON_IsReference 256 + +/* The cJSON structure: */ +typedef struct cJSON +{ + /* next/prev allow you to walk array/object chains. Alternatively, + use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *next, *prev; + + /* An array or object item will have a child pointer pointing to a + chain of the items in the array/object. */ + struct cJSON *child; + + int type; /* The type of the item, as above. */ + + char *valuestring; /* The item's string, if type==cJSON_String */ + int valueint; /* The item's number, if type==cJSON_Number */ + double valuedouble; /* The item's number, if type==cJSON_Number */ + + /* The item's name string, if this item is the child of, or is in + the list of subitems of an object. */ + char *string; +} cJSON; + +typedef struct cJSON *cjson_t; + +/* Macros to test the type of an object. */ +#define cjson_is_boolean(a) (!((a)->type & ~1)) +#define cjson_is_false(a) ((a)->type == cJSON_False) +#define cjson_is_true(a) ((a)->type == cJSON_True) +#define cjson_is_null(a) ((a)->type == cJSON_NULL) +#define cjson_is_number(a) ((a)->type == cJSON_Number) +#define cjson_is_string(a) ((a)->type == cJSON_String) +#define cjson_is_array(a) ((a)->type == cJSON_Array) +#define cjson_is_object(a) ((a)->type == cJSON_Object) + +/* Supply a block of JSON, and this returns a cJSON object you can + interrogate. Call cJSON_Delete when finished. */ +extern cJSON *cJSON_Parse(const char *value, size_t *r_erroff); + +/* Render a cJSON entity to text for transfer/storage. Free the char* + when finished. */ +extern char *cJSON_Print(cJSON *item); + +/* Render a cJSON entity to text for transfer/storage without any + formatting. Free the char* when finished. */ +extern char *cJSON_PrintUnformatted(cJSON *item); + +/* Delete a cJSON entity and all subentities. */ +extern void cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +extern int cJSON_GetArraySize(cJSON *array); + +/* Retrieve item number "item" from array "array". Returns NULL if + unsuccessful. */ +extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); + +/* Get item "string" from object. Case insensitive. */ +extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); + +/* These calls create a cJSON item of the appropriate type. */ +extern cJSON *cJSON_CreateNull(void); +extern cJSON *cJSON_CreateTrue(void); +extern cJSON *cJSON_CreateFalse(void); +extern cJSON *cJSON_CreateBool(int b); +extern cJSON *cJSON_CreateNumber(double num); +extern cJSON *cJSON_CreateString(const char *string); +extern cJSON *cJSON_CreateArray(void); +extern cJSON *cJSON_CreateObject(void); + +/* These utilities create an Array of count items. */ +extern cJSON *cJSON_CreateIntArray(const int *numbers,int count); +extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count); +extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count); +extern cJSON *cJSON_CreateStringArray(const char **strings,int count); + +/* Append item to the specified array/object. */ +extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemToObject(cJSON *object, + const char *string, cJSON *item); + +/* Append reference to item to the specified array/object. Use this + when you want to add an existing cJSON to a new cJSON, but don't + want to corrupt your existing cJSON. */ +extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemReferenceToObject(cJSON *object, + const char *string,cJSON *item); + +/* Remove/Detatch items from Arrays/Objects. */ +extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); +extern void cJSON_DeleteItemFromArray(cJSON *array,int which); +extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); +extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); + +/* Update array items. */ +extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); +extern void cJSON_ReplaceItemInObject(cJSON *object, + const char *string, cJSON *newitem); + +/* Duplicate a cJSON item */ +extern cJSON *cJSON_Duplicate(cJSON *item,int recurse); + +/* Duplicate will create a new, identical cJSON item to the one you + pass, in new memory that will need to be released. With recurse!=0, + it will duplicate any children connected to the item. The + item->next and ->prev pointers are always zero on return from + Duplicate. */ + +/* ParseWithOpts allows you to require (and check) that the JSON is + null terminated, and to retrieve the pointer to the final byte + parsed. */ +extern cJSON *cJSON_ParseWithOpts(const char *value, + const char **return_parse_end, + int require_null_terminated, + size_t *r_erroff); + +extern void cJSON_Minify(char *json); + +/* Macros for creating things quickly. */ +#define cJSON_AddNullToObject(object,name) \ + cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object,name) \ + cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object,name) \ + cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddBoolToObject(object,name,b) \ + cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) +#define cJSON_AddNumberToObject(object,name,n) \ + cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object,name,s) \ + cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) + +/* When assigning an integer value, it needs to be propagated to + valuedouble too. */ +#define cJSON_SetIntValue(object,val) \ + ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) + +#ifdef __cplusplus +} +#endif + +#endif /* cJSON__h */ diff --git a/src/cJSON.readme b/src/cJSON.readme new file mode 100644 index 0000000..61623b4 --- /dev/null +++ b/src/cJSON.readme @@ -0,0 +1,270 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +Welcome to cJSON. + +cJSON aims to be the dumbest possible parser that you can get your job +done with. It's a single file of C, and a single header file. + +JSON is described best here: http://www.json.org/ It's like XML, but +fat-free. You use it to move data around, store things, or just +generally represent your program's state. + + +First up, how do I build? Add cJSON.c to your project, and put +cJSON.h somewhere in the header search path. For example, to build +the test app: + +gcc cJSON.c test.c -o test -lm +./test + + +As a library, cJSON exists to take away as much legwork as it can, but +not get in your way. As a point of pragmatism (i.e. ignoring the +truth), I'm going to say that you can use it in one of two modes: Auto +and Manual. Let's have a quick run-through. + + +I lifted some JSON from this page: http://www.json.org/fatfree.html +That page inspired me to write cJSON, which is a parser that tries to +share the same philosophy as JSON itself. Simple, dumb, out of the +way. + +Some JSON: +{ + "name": "Jack (\"Bee\") Nimble", + "format": { + "type": "rect", + "width": 1920, + "height": 1080, + "interlace": false, + "frame rate": 24 + } +} + +Assume that you got this from a file, a webserver, or magic JSON +elves, whatever, you have a char * to it. Everything is a cJSON +struct. Get it parsed: + + cJSON *root = cJSON_Parse(my_json_string); + +This is an object. We're in C. We don't have objects. But we do have +structs. What's the framerate? + + cJSON *format = cJSON_GetObjectItem(root,"format"); + int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint; + +Want to change the framerate? + + cJSON_GetObjectItem(format,"frame rate")->valueint=25; + +Back to disk? + + char *rendered=cJSON_Print(root); + +Finished? Delete the root (this takes care of everything else). + + cJSON_Delete(root); + +That's AUTO mode. If you're going to use Auto mode, you really ought +to check pointers before you dereference them. If you want to see how +you'd build this struct in code? + + cJSON *root,*fmt; + root=cJSON_CreateObject(); + cJSON_AddItemToObject(root, "name", + cJSON_CreateString("Jack (\"Bee\") Nimble")); + cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject()); + cJSON_AddStringToObject(fmt,"type", "rect"); + cJSON_AddNumberToObject(fmt,"width", 1920); + cJSON_AddNumberToObject(fmt,"height", 1080); + cJSON_AddFalseToObject (fmt,"interlace"); + cJSON_AddNumberToObject(fmt,"frame rate", 24); + +Hopefully we can agree that's not a lot of code? There's no overhead, +no unnecessary setup. Look at test.c for a bunch of nice examples, +mostly all ripped off the json.org site, and a few from elsewhere. + +What about manual mode? First up you need some detail. Let's cover +how the cJSON objects represent the JSON data. cJSON doesn't +distinguish arrays from objects in handling; just type. Each cJSON +has, potentially, a child, siblings, value, a name. + +- The root object has: Object Type and a Child +- The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling: +- Sibling has type Object, name "format", and a child. +- That child has type String, name "type", value "rect", and a sibling: +- Sibling has type Number, name "width", value 1920, and a sibling: +- Sibling has type Number, name "height", value 1080, and a sibling: +- Sibling hs type False, name "interlace", and a sibling: +- Sibling has type Number, name "frame rate", value 24 + +Here's the structure: + +typedef struct cJSON { + struct cJSON *next,*prev; + struct cJSON *child; + + int type; + + char *valuestring; + int valueint; + double valuedouble; + + char *string; +} cJSON; + +By default all values are 0 unless set by virtue of being meaningful. + +next/prev is a doubly linked list of siblings. next takes you to your sibling, +prev takes you back from your sibling to you. + +Only objects and arrays have a "child", and it's the head of the +doubly linked list. + +A "child" entry will have prev==0, but next potentially points on. The +last sibling has next=0. + +The type expresses Null/True/False/Number/String/Array/Object, all of +which are #defined in cJSON.h + +A Number has valueint and valuedouble. If you're expecting an int, +read valueint, if not read valuedouble. + +Any entry which is in the linked list which is the child of an object +will have a "string" which is the "name" of the entry. When I said +"name" in the above example, that's "string". "string" is the JSON +name for the 'variable name' if you will. + +Now you can trivially walk the lists, recursively, and parse as you +please. You can invoke cJSON_Parse to get cJSON to parse for you, and +then you can take the root object, and traverse the structure (which +is, formally, an N-tree), and tokenise as you please. If you wanted to +build a callback style parser, this is how you'd do it (just an +example, since these things are very specific): + +void parse_and_callback(cJSON *item,const char *prefix) +{ + while (item) + { + char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2); + sprintf(newprefix,"%s/%s",prefix,item->name); + int dorecurse=callback(newprefix, item->type, item); + if (item->child && dorecurse) + parse_and_callback(item->child,newprefix); + item=item->next; + free(newprefix); + } +} + +The prefix process will build you a separated list, to simplify your +callback handling. + +The 'dorecurse' flag would let the callback decide to handle +sub-arrays on it's own, or let you invoke it per-item. For the item +above, your callback might look like this: + +int callback(const char *name,int type,cJSON *item) +{ + if (!strcmp(name,"name")) { /* populate name */ } + else if (!strcmp(name,"format/type") { /* handle "rect" */ } + else if (!strcmp(name,"format/width") { /* 800 */ } + else if (!strcmp(name,"format/height") { /* 600 */ } + else if (!strcmp(name,"format/interlace") { /* false */ } + else if (!strcmp(name,"format/frame rate") { /* 24 */ } + return 1; +} + +Alternatively, you might like to parse iteratively. +You'd use: + +void parse_object(cJSON *item) +{ + int i; for (i=0;ichild; + while (subitem) + { + // handle subitem + if (subitem->child) parse_object(subitem->child); + + subitem=subitem->next; + } +} + +Of course, this should look familiar, since this is just a +stripped-down version of the callback-parser. + +This should cover most uses you'll find for parsing. The rest should +be possible to infer.. and if in doubt, read the source! There's not a +lot of it! ;) + + +In terms of constructing JSON data, the example code above is the +right way to do it. You can, of course, hand your sub-objects to +other functions to populate. Also, if you find a use for it, you can +manually build the objects. For instance, suppose you wanted to build +an array of objects? + +cJSON *objects[24]; + +cJSON *Create_array_of_anything(cJSON **items,int num) +{ + int i;cJSON *prev, *root=cJSON_CreateArray(); + for (i=0;i<24;i++) + { + if (!i) root->child=objects[i]; + else prev->next=objects[i], objects[i]->prev=prev; + prev=objects[i]; + } + return root; +} + +and simply: Create_array_of_anything(objects,24); + +cJSON doesn't make any assumptions about what order you create things +in. You can attach the objects, as above, and later add children to +each of those objects. + +As soon as you call cJSON_Print, it renders the structure to text. + + + +The test.c code shows how to handle a bunch of typical cases. If you +uncomment the code, it'll load, parse and print a bunch of test files, +also from json.org, which are more complex than I'd care to try and +stash into a const char array[]. + + +Enjoy cJSON! + + +- Dave Gamble, Aug 2009 ----------------------------------------------------------------------- hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 16 17:48:18 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Fri, 16 Mar 2018 17:48:18 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-102-gb549f69 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via b549f69d0520bb74957b95cec9ea918dba2374f6 (commit) from 431897a4c48fe1bc9d37f655097aabaf5b685d11 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b549f69d0520bb74957b95cec9ea918dba2374f6 Author: Ben McGinnes Date: Sat Mar 17 03:46:02 2018 +1100 doc: python bindings howto * Made the changes suggested by Jakub Wilk on gnupg-devel. * Still need to make the far more comprehensive changes suggested by Justus. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 28d2e25..d27f562 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -13,7 +13,7 @@ :CUSTOM_ID: intro :END: - | Version: | 0.1.0 | + | Version: | 0.1.0-draft | | Author: | Ben McGinnes | | Author GPG Key: | DB4724E6FA4286C92B4E55C4321E4E2373590E5D | | Language: | Australian English, British English | @@ -159,8 +159,8 @@ The PyME package is available under the same dual licensing as GPGME itself: the GNU General Public License version 2.0 (or any - later version) and the GNU Lesser Public License version 2.1 (or - any later version). + later version) and the GNU Lesser General Public License version + 2.1 (or any later version). * GPGME Python bindings installation @@ -275,7 +275,7 @@ that most operations require more than one instruction to the API to perform the task. Sure, there are certain functions which can be performed simultaneously, particularly if the result known or - strongly anticipated (e.g selecting and encrypting to a key known + strongly anticipated (e.g. selecting and encrypting to a key known to be in the public keybox). There are many more, however, which cannot be manipulated so @@ -505,11 +505,8 @@ try: c.op_encrypt([r], 1, plain, cipher) cipher.seek(0, os.SEEK_SET) - del(text) - del(plain) - afile = open("secret_plans.txt.asc", "wb") - afile.write(cipher.read()) - afile.close() + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(cipher.read()) except gpg.errors.GPGMEError as ex: print(ex.getstring()) #+end_src @@ -555,9 +552,8 @@ cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) - afile = open("secret_plans.txt.asc", "wb") - afile.write(cipher[0]) - afile.close() + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(cipher[0]) #+end_src All it would take to change the above example to sign the message @@ -582,9 +578,8 @@ #+begin_src python import gpg - afile = open("secret_plans.txt", "rb") - text = afile.read() - afile.close() + with open("secret_plans.txt.asc", "rb") as afile: + text = afile.read() c = gpg.Context(armor=True) rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) @@ -608,9 +603,8 @@ except: pass - afile = open("secret_plans.txt.asc", "wb") - afile.write(cipher[0]) - afile.close() + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(cipher[0]) #+end_src This will attempt to encrypt to all the keys searched for, then @@ -648,9 +642,8 @@ cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) - afile = open("secret_plans.txt.asc", "wb") - afile.write(cipher[0]) - afile.close() + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(cipher[0]) #+end_src With one or two exceptions, this method will probably prove to be @@ -677,9 +670,8 @@ cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) - afile = open("secret_plans.txt.asc", "wb") - afile.write(cipher[0]) - afile.close() + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(cipher[0]) #+end_src @@ -718,7 +710,6 @@ print(plaintext[0]) plaintext[1] plaintext[2] - del(plaintext) else: pass #+end_src @@ -793,15 +784,14 @@ text0 = """Declaration of ... something. """ - text = text0.encode("utf-8") + text = text0.encode() c = gpg.Context(armor=True, signers=sig_src) signed = c.sign(text, mode=0) - afile = open("/path/to/statement.txt.asc", "w") - for line in signed[0]: - afile.write("{0}\n".format(line.decode("utf-8"))) - afile.close() + with open("/path/to/statement.txt.asc", "w") as afile: + for line in signed[0]: + afile.write("{0}\n".format(line.decode())) #+end_src Though everything in this example is accurate, it is more likely @@ -812,16 +802,14 @@ #+begin_src python import gpg - tfile = open("/path/to/statement.txt", "rb") - text = tfile.read() - tfile.close() + with open("/path/to/statement.txt", "rb") as tfile: + text = tfile.read() c = gpg.Context() signed = c.sign(text, mode=0) - afile = open("/path/to/statement.txt.sig", "wb") - afile.write(signed[0]) - afile.close() + with open("/path/to/statement.txt.sig", "wb") as afile: + afile.write(signed[0]) #+end_src *** Detached signing messages and files @@ -840,15 +828,14 @@ text0 = """Declaration of ... something. """ - text = text0.encode("utf-8") + text = text0.encode() c = gpg.Context(armor=True) signed = c.sign(text, mode=1) - afile = open("/path/to/statement.txt.asc", "w") - for line in signed[0].splitlines(): - afile.write("{0}\n".format(line.decode("utf-8"))) - afile.close() + with open("/path/to/statement.txt.asc", "w") as afile: + for line in signed[0].splitlines(): + afile.write("{0}\n".format(line.decode())) #+end_src As with normal signatures, detached signatures are best handled as @@ -857,16 +844,14 @@ #+begin_src python import gpg - tfile = open("/path/to/statement.txt", "rb") - text = tfile.read() - tfile.close() + with open("/path/to/statement.txt", "rb") as tfile: + text = tfile.read() c = gpg.Context(signers=sig_src) signed = c.sign(text, mode=1) - afile = open("/path/to/statement.txt.sig", "wb") - afile.write(signed[0]) - afile.close() + with open("/path/to/statement.txt.sig", "wb") as afile: + afile.write(signed[0]) #+end_src *** Clearsigning messages or text @@ -885,15 +870,14 @@ text0 = """Declaration of ... something. """ - text = text0.encode("utf-8") + text = text0.encode() c = gpg.Context() signed = c.sign(text, mode=2) - afile = open("/path/to/statement.txt.asc", "w") - for line in signed[0].splitlines(): - afile.write("{0}\n".format(line.decode("utf-8"))) - afile.close() + with open("/path/to/statement.txt.asc", "w") as afile: + for line in signed[0].splitlines(): + afile.write("{0}\n".format(line.decode())) #+end_src In spite of the appearance of a clear-signed message, the data @@ -902,16 +886,14 @@ #+begin_src python import gpg - tfile = open("/path/to/statement.txt", "rb") - text = tfile.read() - tfile.close() + with open("/path/to/statement.txt", "rb") as tfile: + text = tfile.read() c = gpg.Context() signed = c.sign(text, mode=2) - afile = open("/path/to/statement.txt.asc", "wb") - afile.write(signed[0]) - afile.close() + with open("/path/to/statement.txt.asc", "wb") as afile: + afile.write(signed[0]) #+end_src @@ -1131,7 +1113,7 @@ c = gpg.Context() - c.home_dir = "/tmp/dmgpg" + c.home_dir = "~/.gnupg-dm" userid = "Danger Mouse " dmkey = c.create_key(userid, algorithm = "rsa3072", expires_in = 31536000, @@ -1142,7 +1124,10 @@ parameter. This enables generating the key or keys in a different location. In this case to keep the new key data created for this example in a separate location rather than adding it to existing - and active key store data. + and active key store data. As with the default directory, + =~/.gnupg=, any temporary or separate directory needs the + permissions set to only permit access by the directory owner. On + posix systems this means setting the directory permissions to 700. The successful generation of the key can be confirmed via the returned =GenkeyResult= object, which includes the following data: @@ -1163,8 +1148,8 @@ line program: #+begin_src shell - bash-4.4$ gpg --homedir /tmp/dmgpg -K - /tmp/dmgpg/pubring.kbx + bash-4.4$ gpg --homedir ~/.gnupg-dm -K + ~/.gnupg-dm/pubring.kbx ---------------------- sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] 177B7C25DB99745EE2EE13ED026D2F19E99E63AA @@ -1180,7 +1165,7 @@ my own =gpg.conf= file in order to be able to generate this: #+begin_src shell - bash-4.4$ gpg --homedir /tmp/dmgpg --edit-key 177B7C25DB99745EE2EE13ED026D2F19E99E63AA showpref quit + bash-4.4$ gpg --homedir ~/.gnupg-dm --edit-key 177B7C25DB99745EE2EE13ED026D2F19E99E63AA showpref quit Secret key is available. sec rsa3072/026D2F19E99E63AA @@ -1218,7 +1203,7 @@ import gpg c = gpg.Context() - c.home_dir = "/tmp/dmgpg" + c.home_dir = "~/.gnupg-dm" key = c.get_key(dmkey.fpr, secret = True) dmsub = c.create_subkey(key, algorithm = "rsa3072", expires_in = 15768000, @@ -1242,8 +1227,8 @@ As well as on the command line with: #+begin_src shell - bash-4.4$ gpg --homedir /tmp/dmgpg -K - /tmp/dmgpg/pubring.kbx + bash-4.4$ gpg --homedir ~/.gnupg-dm -K + ~/.gnupg-dm/pubring.kbx ---------------------- sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] 177B7C25DB99745EE2EE13ED026D2F19E99E63AA @@ -1268,7 +1253,7 @@ import gpg c = gpg.Context() - c.home_dir = "/tmp/dmgpg" + c.home_dir = "~/.gnupg-dm" dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" key = c.get_key(dmfpr, secret = True) @@ -1280,8 +1265,8 @@ Unsurprisingly the result of this is: #+begin_src shell - bash-4.4$ gpg --homedir /tmp/dmgpg -K - /tmp/dmgpg/pubring.kbx + bash-4.4$ gpg --homedir ~/.gnupg-dm -K + ~/.gnupg-dm/pubring.kbx ---------------------- sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] 177B7C25DB99745EE2EE13ED026D2F19E99E63AA ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 123 ++++++++++++++------------------ 1 file changed, 54 insertions(+), 69 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sun Mar 18 17:47:14 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 18 Mar 2018 17:47:14 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-3-g791177d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 791177de023574223eddf7288eb7c5a0721ac623 (commit) from c36a60687976d98b54dac17f699dfca4918a737c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 791177de023574223eddf7288eb7c5a0721ac623 Author: Werner Koch Date: Sun Mar 18 17:39:43 2018 +0100 core: Fix regression on arm64 due to invalid use of va_list. * src/logging.c (_gpgrt_log_printhex): Provide a dummy arg instead of NULL. -- Fix Suggested-by: Jakub Wilk Signed-off-by: Werner Koch diff --git a/src/logging.c b/src/logging.c index 1a4f620..d01f974 100644 --- a/src/logging.c +++ b/src/logging.c @@ -1090,9 +1090,10 @@ _gpgrt_log_flush (void) /* Print a hexdump of (BUFFER,LENGTH). With FMT passed as NULL print - * just the raw dump, with FMT being an empty string, print a trailing - * linefeed, otherwise print an entire debug line with the expanded - * FMT followed by a possible wrapped hexdump and a final LF. */ + * just the raw dump (in this case ARG_PTR is not used), with FMT + * being an empty string, print a trailing linefeed, otherwise print + * an entire debug line with the expanded FMT followed by a possible + * wrapped hexdump and a final LF. */ void _gpgrt_logv_printhex (const void *buffer, size_t length, const char *fmt, va_list arg_ptr) @@ -1150,7 +1151,16 @@ _gpgrt_log_printhex (const void *buffer, size_t length, va_end (arg_ptr); } else - _gpgrt_logv_printhex (buffer, length, NULL, NULL); + { + /* va_list is not necessary a pointer and thus we can't use NULL + * because that would conflict with platforms using a straight + * struct for it (e.g. arm64). We use a dummy variable instead; + * the static is a simple way zero it out so to not get + * complains about uninitialized use. */ + static va_list dummy_argptr; + + _gpgrt_logv_printhex (buffer, length, NULL, dummy_argptr); + } } ----------------------------------------------------------------------- Summary of changes: src/logging.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Sun Mar 18 22:46:00 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sun, 18 Mar 2018 22:46:00 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-103-g82c5af2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 82c5af225f2bdf3acc6fc652a96ee61c9b057395 (commit) from b549f69d0520bb74957b95cec9ea918dba2374f6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 82c5af225f2bdf3acc6fc652a96ee61c9b057395 Author: Ben McGinnes Date: Mon Mar 19 08:43:36 2018 +1100 doc: python bindings howto * Stripped decryption example to the bare bones as suggested by Justus. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index d27f562..a214423 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -690,28 +690,14 @@ to =c= simply adds lines for no gain. #+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" - 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: - 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] - else: - pass + ciphertext = input("Enter path and filename of encrypted file: ") + newfile = input("Enter path and filename of file to save decrypted data to: ") + with open(ciphertext, "rb") as cfile: + plaintext, result, verify_result = gpg.Context().decrypt(cfile) + with open(newfile, "wb" as nfile: + nfile.write(plaintext) #+end_src The data available in plaintext in this example is the decrypted ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 19 00:03:06 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 19 Mar 2018 00:03:06 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-105-g64c5886 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 64c5886132aceefc9d9600a3a6dbbbf404b95b81 (commit) via 4811ff7b6c8ef97c7d4858ce235e9bf8227f4917 (commit) from 82c5af225f2bdf3acc6fc652a96ee61c9b057395 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 64c5886132aceefc9d9600a3a6dbbbf404b95b81 Author: Ben McGinnes Date: Mon Mar 19 10:00:44 2018 +1100 doc: python bindings howto * Replaced the single encryption methods with one main way (i.e. cut the low level stuff involving SEEK_SET instructions). diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index c0606dd..a960830 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -436,6 +436,7 @@ section we will look at how to programmatically encrypt data, decrypt it, sign it and verify signatures. + ** Encryption :PROPERTIES: :CUSTOM_ID: howto-basic-encryption @@ -446,85 +447,35 @@ the second example the message will be encrypted to multiple recipients. + *** Encrypting to one key :PROPERTIES: :CUSTOM_ID: howto-basic-encryption-single :END: - The text is then encapsulated in a GPGME Data object as =plain= and - the =cipher= object is created with another Data object. Then we - create the Context as =c= and set it to use the ASCII armoured - OpenPGP format. In later examples there will be alternative - methods of setting the OpenPGP output to be ASCII armoured. - - Next we prepare a keylist object in our Context and follow it with - specifying the recipients as =r=. Note that the configuration in - one's =gpg.conf= file is honoured, so if you have the options set - to encrypt to one key or to a default key, that will be included - with this operation. - - This is followed by a quick check to be sure that the recipient is - actually selected and that the key is available. Assuming it is, - the encryption can proceed, but if not a message will print stating - the key was not found. - - The encryption operation is invoked within the Context with the - =c.op_encrypt= function, loading the recipients (=r=), the message - (=plain=) and the =cipher=. The =cipher.seek= uses =os.SEEK_SET= - to set the data to the correct byte format for GPGME to use it. - - At this point we no longer need the plaintext material, so we - delete both the =text= and the =plain= objects. Then we write the - encrypted data out to a file, =secret_plans.txt.asc=. - - #+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() - c = gpg.core.Context() - c.set_armor(1) - - 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)) - else: - try: - c.op_encrypt([r], 1, plain, cipher) - cipher.seek(0, os.SEEK_SET) - with open("secret_plans.txt.asc", "wb") as afile: - afile.write(cipher.read()) - except gpg.errors.GPGMEError as ex: - print(ex.getstring()) - #+end_src - -*** Encrypting to one key using the second method - :PROPERTIES: - :CUSTOM_ID: howto-basic-encryption-monogamous - :END: - - This example re-creates the first encryption example except it - uses the same =encrypt= method used in the subsequent examples - instead of the =op_encrypt= method. This means that, unlike the - =op_encrypt= method, it /must/ use byte literal input data. + Once the the Context is set the main issues with encrypting data + is essentially reduced to key selection and the keyword arguments + specified in the =gpg.Context().encrypt()= method. + + Those keyword arguments are: =recipients=, a list of keys + encrypted to (covered in greater detail in the following section); + =sign=, whether or not to sign the plaintext data, see subsequent + sections on signing and verifying signatures below (defaults to + =True=); =sink=, to write results or partial results to a secure + sink instead of returning it (defaults to =None=); =passphrase=, + only used when utilising symmetric encryption (defaults to + =None=); =always_trust=, used to override the trust model settings + for recipient keys (defaults to =False=); =add_encrypt_to=, + utilises any preconfigured =encrypt-to= or =default-key= settings + in the user's =gpg.conf= file (defaults to =False=); =prepare=, + prepare for encryption (defaults to =False=); =expect_sign=, + prepare for signing (defaults to =False=); =compress=, compresses + the plaintext prior to encryption (defaults to =True=). #+begin_src python import gpg - rkey = "0x12345678DEADBEEF" + a_key = "0x12345678DEADBEEF" text = b"""Some text to test with. Since the text in this case must be bytes, it is most likely that @@ -534,56 +485,51 @@ """ c = gpg.Context(armor=True) - rpattern = list(c.keylist(pattern=rkey, secret=False)) - logrus = [] - - for i in range(len(rpattern)): - if rpattern[i].can_encrypt == 1: - logrus.append(rpattern[i]) - - cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) + rkey = list(c.keylist(pattern=a_key, secret=False)) + ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=False) with open("secret_plans.txt.asc", "wb") as afile: - afile.write(cipher[0]) + afile.write(ciphertext) #+end_src - With one or two exceptions, this method will probably prove to be - easier to implement than the first method and thus it is the - recommended encryption method. Though it is even more likely to - be used like this: + Though this is even more likely to be used like this; with the + plaintext input read from a file, the recipient keys used for + encryption regardless of key trust status and the encrypted output + also encrypted to any preconfigured keys set in the =gpg.conf= + file: #+begin_src python import gpg - rkey = "0x12345678DEADBEEF" + a_key = "0x12345678DEADBEEF" - afile = open("secret_plans.txt", "rb") - text = afile.read() - afile.close() + with open("secret_plans.txt", "rb") as afile: + text = afile.read() c = gpg.Context(armor=True) - rpattern = list(c.keylist(pattern=rkey, secret=False)) - logrus = [] - - for i in range(len(rpattern)): - if rpattern[i].can_encrypt == 1: - logrus.append(rpattern[i]) - - cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) + rkey = list(c.keylist(pattern=a_key, secret=False)) + ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, + sign=True, always_trust=True, + add_encrypt_to=True) with open("secret_plans.txt.asc", "wb") as afile: - afile.write(cipher[0]) + afile.write(ciphertext) #+end_src + If the =recipients= paramater is empty then the plaintext is + encrypted symmetrically. If no =passphrase= is supplied as a + parameter or via a callback registered with the =Context()= then + an out-of-band prompt for the passphrase via pinentry will be + invoked. + + *** Encrypting to multiple keys :PROPERTIES: :CUSTOM_ID: howto-basic-encryption-multiple :END: - Encrypting to multiple keys, in addition to a default key or a key - configured to always encrypt to, is a little different and uses a - slightly different call to the =op_encrypt= call demonstrated in the - previous section. + Encrypting to multiple keys essentially just expands upon the key + selection process and the recipients from the previous examples. The following example encrypts a message (=text=) to everyone with an email address on the =gnupg.org= domain,[fn:3] but does /not/ encrypt @@ -711,7 +657,8 @@ :CUSTOM_ID: howto-basic-signing :END: - The following sections demonstrate how to specify + The following sections demonstrate how to specify keys to sign with. + *** Signing key selection :PROPERTIES: @@ -743,6 +690,7 @@ bytes or None and not a list. A string with two fingerprints won't match any single key. + *** Normal or default signing messages or files :PROPERTIES: :CUSTOM_ID: howto-basic-signing-normal @@ -798,6 +746,7 @@ afile.write(signed[0]) #+end_src + *** Detached signing messages and files :PROPERTIES: :CUSTOM_ID: howto-basic-signing-detached @@ -840,6 +789,7 @@ afile.write(signed[0]) #+end_src + *** Clearsigning messages or text :PROPERTIES: :CUSTOM_ID: howto-basic-signing-clear @@ -1307,6 +1257,7 @@ :CUSTOM_ID: cheats-and-hacks :END: + ** Group lines :PROPERTIES: :CUSTOM_ID: group-lines @@ -1357,6 +1308,7 @@ :CUSTOM_ID: copyright-and-license :END: + ** Copyright (C) The GnuPG Project, 2018 :PROPERTIES: :CUSTOM_ID: copyright @@ -1364,6 +1316,7 @@ Copyright ? The GnuPG Project, 2018. + ** License GPL compatible :PROPERTIES: :CUSTOM_ID: license commit 4811ff7b6c8ef97c7d4858ce235e9bf8227f4917 Author: Ben McGinnes Date: Mon Mar 19 08:49:17 2018 +1100 doc: python bindings howto * moved single encrytion examples up to the first ones, pending merge and major cut. * This is basically just to make future checks of revisions a little easier. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index a214423..c0606dd 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -511,6 +511,70 @@ print(ex.getstring()) #+end_src +*** Encrypting to one key using the second method + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption-monogamous + :END: + + This example re-creates the first encryption example except it + uses the same =encrypt= method used in the subsequent examples + instead of the =op_encrypt= method. This means that, unlike the + =op_encrypt= method, it /must/ use byte literal input data. + + #+begin_src python + import gpg + + rkey = "0x12345678DEADBEEF" + text = b"""Some text to test with. + + 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=rkey, secret=False)) + logrus = [] + + for i in range(len(rpattern)): + if rpattern[i].can_encrypt == 1: + logrus.append(rpattern[i]) + + cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) + + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(cipher[0]) + #+end_src + + With one or two exceptions, this method will probably prove to be + easier to implement than the first method and thus it is the + recommended encryption method. Though it is even more likely to + be used like this: + + #+begin_src python + import gpg + + rkey = "0x12345678DEADBEEF" + + afile = open("secret_plans.txt", "rb") + text = afile.read() + afile.close() + + c = gpg.Context(armor=True) + rpattern = list(c.keylist(pattern=rkey, secret=False)) + logrus = [] + + for i in range(len(rpattern)): + if rpattern[i].can_encrypt == 1: + logrus.append(rpattern[i]) + + cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) + + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(cipher[0]) + #+end_src + *** Encrypting to multiple keys :PROPERTIES: :CUSTOM_ID: howto-basic-encryption-multiple @@ -610,70 +674,6 @@ This will attempt to encrypt to all the keys searched for, then remove invalid recipients if it fails and try again. -*** Encrypting to one key using the second method - :PROPERTIES: - :CUSTOM_ID: howto-basic-encryption-monogamous - :END: - - This example re-creates the first encryption example except it - uses the same =encrypt= method used in the subsequent examples - instead of the =op_encrypt= method. This means that, unlike the - =op_encrypt= method, it /must/ use byte literal input data. - - #+begin_src python - import gpg - - rkey = "0x12345678DEADBEEF" - text = b"""Some text to test with. - - 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=rkey, secret=False)) - logrus = [] - - for i in range(len(rpattern)): - if rpattern[i].can_encrypt == 1: - logrus.append(rpattern[i]) - - cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) - - with open("secret_plans.txt.asc", "wb") as afile: - afile.write(cipher[0]) - #+end_src - - With one or two exceptions, this method will probably prove to be - easier to implement than the first method and thus it is the - recommended encryption method. Though it is even more likely to - be used like this: - - #+begin_src python - import gpg - - rkey = "0x12345678DEADBEEF" - - afile = open("secret_plans.txt", "rb") - text = afile.read() - afile.close() - - c = gpg.Context(armor=True) - rpattern = list(c.keylist(pattern=rkey, secret=False)) - logrus = [] - - for i in range(len(rpattern)): - if rpattern[i].can_encrypt == 1: - logrus.append(rpattern[i]) - - cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) - - with open("secret_plans.txt.asc", "wb") as afile: - afile.write(cipher[0]) - #+end_src - ** Decryption :PROPERTIES: ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 187 ++++++++++++-------------------- 1 file changed, 70 insertions(+), 117 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 19 00:44:10 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 19 Mar 2018 00:44:10 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-106-g1779d7b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 1779d7b9d6769b2e47f1e90260290e25c8c3aa02 (commit) from 64c5886132aceefc9d9600a3a6dbbbf404b95b81 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1779d7b9d6769b2e47f1e90260290e25c8c3aa02 Author: Ben McGinnes Date: Mon Mar 19 10:39:53 2018 +1100 doc: python bindings howto * deconstructing multi-recipient encryption. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index a960830..f5192f4 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -22,6 +22,7 @@ This document provides basic instruction in how to use the GPGME Python bindings to programmatically leverage the GPGME library. + ** Python 2 versus Python 3 :PROPERTIES: :CUSTOM_ID: py2-vs-py3 @@ -53,6 +54,7 @@ :CUSTOM_ID: gpgme-concepts :END: + ** A C API :PROPERTIES: :CUSTOM_ID: gpgme-c-api @@ -72,6 +74,7 @@ languages. This is where the need for bindings in various languages stems. + ** Python bindings :PROPERTIES: :CUSTOM_ID: gpgme-python-bindings @@ -88,6 +91,7 @@ tied to the exact same version of GPGME used to generate that copy of =gpgme.h=. + ** Difference between the Python bindings and other GnuPG Python packages :PROPERTIES: :CUSTOM_ID: gpgme-python-bindings-diffs @@ -97,6 +101,7 @@ over the years. Some of the most well known are listed here, along with what differentiates them. + *** The python-gnupg package maintained by Vinay Sajip :PROPERTIES: :CUSTOM_ID: diffs-python-gnupg @@ -116,6 +121,7 @@ The python-gnupg package is available under the MIT license. + *** The gnupg package created and maintained by Isis Lovecruft :PROPERTIES: :CUSTOM_ID: diffs-isis-gnupg @@ -136,6 +142,7 @@ The gnupg package is available under the GNU General Public License version 3.0 (or later). + *** The PyME package maintained by Martin Albrecht :PROPERTIES: :CUSTOM_ID: diffs-pyme @@ -168,6 +175,7 @@ :CUSTOM_ID: gpgme-python-install :END: + ** No PyPI :PROPERTIES: :CUSTOM_ID: do-not-use-pypi @@ -187,6 +195,7 @@ bundled with it or a full implementation of C for each architecture. + ** Requirements :PROPERTIES: :CUSTOM_ID: gpgme-python-requirements @@ -201,6 +210,7 @@ 3. GPGME itself. Which also means that all of GPGME's dependencies must be installed too. + ** Installation :PROPERTIES: :CUSTOM_ID: installation @@ -225,6 +235,7 @@ For Python 3 it checks for these executables in this order: =python3=, =python3.6=, =python3.5= and =python3.4=. + *** Installing GPGME :PROPERTIES: :CUSTOM_ID: install-gpgme @@ -243,6 +254,7 @@ regarding GPGME's design which hold true whether you're dealing with the C code directly or these Python bindings. + ** No REST :PROPERTIES: :CUSTOM_ID: no-rest-for-the-wicked @@ -266,6 +278,7 @@ direct bindings and it's this pythonic layer with which this HOWTO deals with. + ** Context :PROPERTIES: :CUSTOM_ID: howto-get-context @@ -294,6 +307,7 @@ :CUSTOM_ID: howto-keys :END: + ** Key selection :PROPERTIES: :CUSTOM_ID: howto-keys-selection @@ -560,10 +574,11 @@ if rpattern[i].can_encrypt == 1: logrus.append(rpattern[i]) - cipher = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, sign=False, + always_trust=True) with open("secret_plans.txt.asc", "wb") as afile: - afile.write(cipher[0]) + afile.write(ciphertext) #+end_src All it would take to change the above example to sign the message @@ -571,8 +586,9 @@ be to change the =c.encrypt= line to this: #+begin_src python - cipher = c.encrypt(text, recipients=logrus, always_trust=True, - add_encrypt_to=True) + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, + always_trust=True, + add_encrypt_to=True) #+end_src The only keyword arguments requiring modification are those for @@ -600,7 +616,7 @@ logrus.append(rpattern[i]) try: - cipher = c.encrypt(text, recipients=logrus, add_encrypt_to=True) + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True) except gpg.errors.InvalidRecipients as e: for i in range(len(e.recipients)): for n in range(len(logrus)): @@ -609,12 +625,12 @@ else: pass try: - cipher = c.encrypt(text, recipients=logrus, add_encrypt_to=True) + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True) except: pass with open("secret_plans.txt.asc", "wb") as afile: - afile.write(cipher[0]) + afile.write(ciphertext) #+end_src This will attempt to encrypt to all the keys searched for, then @@ -721,7 +737,7 @@ text = text0.encode() c = gpg.Context(armor=True, signers=sig_src) - signed = c.sign(text, mode=0) + signed = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) with open("/path/to/statement.txt.asc", "w") as afile: for line in signed[0]: @@ -740,7 +756,7 @@ text = tfile.read() c = gpg.Context() - signed = c.sign(text, mode=0) + signed = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) with open("/path/to/statement.txt.sig", "wb") as afile: afile.write(signed[0]) @@ -766,7 +782,7 @@ text = text0.encode() c = gpg.Context(armor=True) - signed = c.sign(text, mode=1) + signed = c.sign(text, mode=gpg.constants.sig.mode.DETACH) with open("/path/to/statement.txt.asc", "w") as afile: for line in signed[0].splitlines(): @@ -783,7 +799,7 @@ text = tfile.read() c = gpg.Context(signers=sig_src) - signed = c.sign(text, mode=1) + signed = c.sign(text, mode=gpg.constants.sig.mode.DETACH) with open("/path/to/statement.txt.sig", "wb") as afile: afile.write(signed[0]) @@ -809,7 +825,7 @@ text = text0.encode() c = gpg.Context() - signed = c.sign(text, mode=2) + signed = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) with open("/path/to/statement.txt.asc", "w") as afile: for line in signed[0].splitlines(): @@ -826,7 +842,7 @@ text = tfile.read() c = gpg.Context() - signed = c.sign(text, mode=2) + signed = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) with open("/path/to/statement.txt.asc", "wb") as afile: afile.write(signed[0]) @@ -856,14 +872,15 @@ c = gpg.Context() try: - verified = c.verify(open(gpg_file)) + data, result = c.verify(open(gpg_file)) + verified = True except gpg.errors.BadSignatures as e: - verified = None + verified = False print(e) - if verified is not None: - for i in range(len(verified[1].signatures)): - sign = verified[1].signatures[i] + if verified is True: + for i in range(len(result.signatures)): + sign = result.signatures[i] print("""Good signature from: {0} with key {1} @@ -887,14 +904,15 @@ c = gpg.Context() try: - verified = c.verify(open(asc_file)) + data, result = c.verify(open(asc_file)) + verified = True except gpg.errors.BadSignatures as e: - verified = None + verified = False print(e) - if verified is not None: - for i in range(len(verified[1].signatures)): - sign = verified[1].signatures[i] + if verified is True: + for i in range(len(result.signatures)): + sign = result.signatures[i] print("""Good signature from: {0} with key {1} @@ -906,15 +924,14 @@ #+end_src In both of the previous examples it is also possible to compare the - original data that was signed against the signed data in - =verified[0]= to see if it matches with something like this: + original data that was signed against the signed data in =data= to + see if it matches with something like this: #+begin_src python - afile = open(filename, "rb") - text = afile.read() - afile.close() + with open(filename, "rb") as afile: + text = afile.read() - if text == verified[0]: + if text == data: print("Good signature.") else: pass @@ -923,8 +940,8 @@ The following two examples, however, deal with detached signatures. With his method of verification the data that was signed does not get returned since it is already being explicitly referenced in the - first argument of =c.verify=. So =verified[0]= is None and only - the data in =verified[1]= is available. + first argument of =c.verify=. So =data= is =None= and only the + information in =result= is available. #+begin_src python import gpg @@ -936,14 +953,15 @@ c = gpg.Context() try: - verified = c.verify(open(filename), open(sig_file)) + data, result = c.verify(open(filename), open(sig_file)) + verified = True except gpg.errors.BadSignatures as e: - verified = None + verified = False print(e) - if verified is not None: - for i in range(len(verified[1].signatures)): - sign = verified[1].signatures[i] + if verified is True: + for i in range(len(result.signatures)): + sign = result.signatures[i] print("""Good signature from: {0} with key {1} @@ -964,14 +982,15 @@ c = gpg.Context() try: - verified = c.verify(open(filename), open(asc_file)) + data, result = c.verify(open(filename), open(asc_file)) + verified = True except gpg.errors.BadSignatures as e: - verified = None + verified = False print(e) if verified is not None: - for i in range(len(verified[1].signatures)): - sign = verified[1].signatures[i] + for i in range(len(result.signatures)): + sign = result.signatures[i] print("""Good signature from: {0} with key {1} @@ -1008,11 +1027,8 @@ allow-secret-key-import trust-model tofu+pgp tofu-default-policy unknown - # no-auto-check-trustdb enable-large-rsa enable-dsa2 - # no-emit-version - # no-comments # cert-digest-algo SHA256 cert-digest-algo SHA512 default-preference-list TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 ZLIB BZIP2 ZIP Uncompressed ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 102 ++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 43 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 19 02:51:47 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 19 Mar 2018 02:51:47 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-107-gbf67cf4 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via bf67cf433fe82924ed40e79785e95403c07cc068 (commit) from 1779d7b9d6769b2e47f1e90260290e25c8c3aa02 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bf67cf433fe82924ed40e79785e95403c07cc068 Author: Ben McGinnes Date: Mon Mar 19 12:46:41 2018 +1100 doc: python bindings todo list * Checked off several points of howto coverage as completed. * Reorganised to move S/MIME coverage to its own separate group of tasks. * Noted only revocation remains for howto completion. diff --git a/lang/python/docs/TODO.org b/lang/python/docs/TODO.org index e85315a..add8f4f 100644 --- a/lang/python/docs/TODO.org +++ b/lang/python/docs/TODO.org @@ -28,6 +28,7 @@ to produce reST versions via Pandoc and DITA XML can be reached through converting to either Markdown or XHTML first. + ** STARTED Documentation HOWTO :PROPERTIES: :CUSTOM_ID: todo-docs-howto @@ -43,48 +44,57 @@ :CUSTOM_ID: howto-start :END: + *** STARTED Include certain specific instructions in the HOWTO :PROPERTIES: :CUSTOM_ID: howto-requests :END: + Note: moved the S/MIME bits out to their own section of the TODO + list and may be served better by separate HOWTO documentation + anyway. + - State "STARTED" from "TODO" [2018-03-09 Fri 15:27] Some functions can be worked out from the handful of examples available, but many more can't and I've already begun receiving requests for certain functions to be explained. -**** STARTED Standard scenarios + +**** DONE Standard scenarios + CLOSED: [2018-03-19 Mon 12:34] :PROPERTIES: :CUSTOM_ID: howto-the-basics :END: + - State "DONE" from "STARTED" [2018-03-19 Mon 12:34] \\ + All four of those are done. - State "STARTED" from "TODO" [2018-03-09 Fri 15:26] \\ Began with the example code, now to add the text. What everyone expects: encryption, decryption, signing and verifying. -**** TODO Key control + +**** STARTED Key control :PROPERTIES: :CUSTOM_ID: howto-key-control :END: + - State "STARTED" from "TODO" [2018-03-19 Mon 12:35] \\ + Generating keys and subkeys are done, but revocation is still to be done. Generating keys, adding subkeys, revoking subkeys (and keeping the cert key), adding and revoking UIDs, signing/certifying keys. -**** TODO More key control + +**** DONE More key control + CLOSED: [2018-03-19 Mon 12:36] :PROPERTIES: :CUSTOM_ID: howto-key-selection :END: + - State "DONE" from "TODO" [2018-03-19 Mon 12:36] \\ + Key selection, searching, matching and counting is done. Selecting keys to encrypt to or manipulate in other ways (e.g. as with key control or the basics). -**** TODO S/MIME - :PROPERTIES: - :CUSTOM_ID: howto-s-mime - :END: - - Eventually add some of this, but the OpenPGP details are far more - important at the moment. ** TODO Documentation SWIG :PROPERTIES: @@ -98,6 +108,7 @@ something to be used in conjunction with the existing GPGME documentation which makes it easier for Python developers to use. + ** TODO GUI examples :PROPERTIES: :CUSTOM_ID: todo-gui-examples @@ -107,6 +118,7 @@ to either match or be similar to the old GTK2 examples available with PyME. + ** TODO Replace SWIG :PROPERTIES: :CUSTOM_ID: todo-replace-swig @@ -122,6 +134,7 @@ bindings using a more suitable means of interfacing with the GPGME C source code. + *** TODO Replacement for SWIG :PROPERTIES: :CUSTOM_ID: todo-replace-swig-replacement @@ -131,6 +144,7 @@ the most viable candidate, but some additional testing and checks are yet to be completed. + ** TODO API for an API :PROPERTIES: :CUSTOM_ID: todo-api-squared @@ -146,6 +160,15 @@ bindings. +** TODO S/MIME + :PROPERTIES: + :CUSTOM_ID: s-mime + :END: + + Eventually add some of this, but the OpenPGP details are far more + important at the moment. + + * Project Task Details :PROPERTIES: :CUSTOM_ID: detailed-tasks ----------------------------------------------------------------------- Summary of changes: lang/python/docs/TODO.org | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 19 03:16:51 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 19 Mar 2018 03:16:51 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-108-g0fb8a5d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 0fb8a5d45c1c77a5928d6e356271da055aa55994 (commit) from bf67cf433fe82924ed40e79785e95403c07cc068 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0fb8a5d45c1c77a5928d6e356271da055aa55994 Author: Ben McGinnes Date: Mon Mar 19 13:09:46 2018 +1100 doc: python bindings howto * Adjusted the python-gnupg so the comments regarding insecure invocation of commands via subprocess (shell=True) were a major historical issue and not a a current issue. * Not including Vinay Sajip's requested change to say it is now secure since no audit of the current code base has been performed and my last major inspection of that code was around the time I first ported PyME to Python 3 in 2015. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index f5192f4..4a21554 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -117,7 +117,11 @@ 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. + command line via the =subprocess= calls. While some effort has + been made over the last two to three years (as of 2018) to + mitigate this, particularly by no longer providing shell access + through those subprocess calls, the wrapper is still somewhat + limited in the scope of its GnuPG features coverage. The python-gnupg package is available under the MIT license. @@ -132,15 +136,15 @@ package also relied on subprocess to call the =gpg= or =gpg2= binaries, but did so somewhat more securely. - However the naming and version numbering selected for this package - resulted in conflicts with the original python-gnupg and since its - functions were called in a different manner, the release of this - package also resulted in a great deal of consternation when people - installed what they thought was an upgrade that subsequently broke - the code relying on it. + The naming and version numbering selected for this package, + however, resulted in conflicts with the original python-gnupg and + since its functions were called in a different manner to + python-gnupg, the release of this package also resulted in a great + deal of consternation when people installed what they thought was + an upgrade that subsequently broke the code relying on it. The gnupg package is available under the GNU General Public - License version 3.0 (or later). + License version 3.0 (or any later version). *** The PyME package maintained by Martin Albrecht ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 19 05:05:33 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 19 Mar 2018 05:05:33 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-109-gd5f6dec Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via d5f6dec048d3d4d94f1fcdb3f4249cf6e71c4b92 (commit) from 0fb8a5d45c1c77a5928d6e356271da055aa55994 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d5f6dec048d3d4d94f1fcdb3f4249cf6e71c4b92 Author: Ben McGinnes Date: Mon Mar 19 15:03:00 2018 +1100 doc: python bindings howto * Slight python-gnupg clarification. See also this thread: https://lists.gnupg.org/pipermail/gnupg-devel/2018-March/033528.html diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 4a21554..b364b51 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -115,11 +115,11 @@ The popularity of this package stemmed from its ease of use and capability in providing the most commonly required features. - 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. While some effort has - been made over the last two to three years (as of 2018) to - mitigate this, particularly by no longer providing shell access + Unfortunately it has been beset by a number of security issues in + the past; most of which stemmed from using unsafe methods of + accessing the command line via the =subprocess= calls. While some + effort has been made over the last two to three years (as of 2018) + to mitigate this, particularly by no longer providing shell access through those subprocess calls, the wrapper is still somewhat limited in the scope of its GnuPG features coverage. ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 19 08:39:22 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 19 Mar 2018 08:39:22 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-17-g11bbd99 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 11bbd99477ef5ba5b7db0c17607b10af03c68afb (commit) from 2c85e202bc30231b9555100dec0c490c60d7b88c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 11bbd99477ef5ba5b7db0c17607b10af03c68afb Author: NIIBE Yutaka Date: Mon Mar 19 16:36:30 2018 +0900 scd: signal mask should be set just after npth_init. * scd/scdaemon.c (setup_signal_mask): New. (main): Call setup_signal_mask. (handle_connections): Remove signal mask setup. -- For new thread, signal mask is inherited by thread creation. Thus, it is best to setup signal mask just after npth_init. Signed-off-by: NIIBE Yutaka diff --git a/scd/scdaemon.c b/scd/scdaemon.c index e63aca7..8f8a026 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -393,7 +393,21 @@ cleanup (void) } } - +static void +setup_signal_mask (void) +{ +#ifndef HAVE_W32_SYSTEM + npth_sigev_init (); + npth_sigev_add (SIGHUP); + npth_sigev_add (SIGUSR1); + npth_sigev_add (SIGUSR2); + npth_sigev_add (SIGINT); + npth_sigev_add (SIGCONT); + npth_sigev_add (SIGTERM); + npth_sigev_fini (); + main_thread_pid = getpid (); +#endif +} int main (int argc, char **argv ) @@ -744,6 +758,7 @@ main (int argc, char **argv ) #endif npth_init (); + setup_signal_mask (); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); /* If --debug-allow-core-dump has been given we also need to @@ -884,6 +899,7 @@ main (int argc, char **argv ) /* This is the child. */ npth_init (); + setup_signal_mask (); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); /* Detach from tty and put process into a new session. */ @@ -1290,16 +1306,6 @@ handle_connections (int listen_fd) events[0] = the_event = h2; } } -#else - npth_sigev_init (); - npth_sigev_add (SIGHUP); - npth_sigev_add (SIGUSR1); - npth_sigev_add (SIGUSR2); - npth_sigev_add (SIGINT); - npth_sigev_add (SIGCONT); - npth_sigev_add (SIGTERM); - npth_sigev_fini (); - main_thread_pid = getpid (); #endif FD_ZERO (&fdset); ----------------------------------------------------------------------- Summary of changes: scd/scdaemon.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 19 22:10:28 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 19 Mar 2018 22:10:28 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-110-g3e0f68f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 3e0f68fdff1998dae9cb6f8510a3e945a268d1f6 (commit) from d5f6dec048d3d4d94f1fcdb3f4249cf6e71c4b92 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3e0f68fdff1998dae9cb6f8510a3e945a268d1f6 Author: Ben McGinnes Date: Tue Mar 20 08:07:22 2018 +1100 example: python bindings encryption * Since we don't want to encourage accessing the low level functions (e.g. op_encrypt), but since this example can still be useful to understand, renaming it and will add new encryption examples to match the instructions in the HOWTO. diff --git a/lang/python/examples/encrypt-to-all.py b/lang/python/examples/low_level-encrypt_to_all.py similarity index 100% rename from lang/python/examples/encrypt-to-all.py rename to lang/python/examples/low_level-encrypt_to_all.py ----------------------------------------------------------------------- Summary of changes: lang/python/examples/{encrypt-to-all.py => low_level-encrypt_to_all.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lang/python/examples/{encrypt-to-all.py => low_level-encrypt_to_all.py} (100%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 19 22:41:37 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 19 Mar 2018 22:41:37 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-113-gb30ebf8 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via b30ebf89725641018b3b08f77876530f9b983fa2 (commit) via 8f7672ad1b267f122f647bb5f984734d0ff66a5c (commit) via 6950a63e63d60685ddb6f4cbff7b826b8acb5b13 (commit) from 3e0f68fdff1998dae9cb6f8510a3e945a268d1f6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b30ebf89725641018b3b08f77876530f9b983fa2 Author: Ben McGinnes Date: Tue Mar 20 08:39:49 2018 +1100 doc: python bindings examples * Explicitly stated that all this code is released under the GPLv2+ and the LGPLv2.1+. diff --git a/lang/python/examples/howto/README.org b/lang/python/examples/howto/README.org index 604037f..b74ae7e 100644 --- a/lang/python/examples/howto/README.org +++ b/lang/python/examples/howto/README.org @@ -28,6 +28,12 @@ :CUSTOM_ID: copyright-and-license :END: + Unless otherwise stated, all the examples in this directory are + released under the same terms as GPGME itself; that is they are dual + licensed under the terms of both the GNU General Public License + version 2.0 (or any later version) *and* the GNU Lesser General + Public License version 2.1 (or any later version). + ** Copyright (C) The GnuPG Project, 2018 :PROPERTIES: commit 8f7672ad1b267f122f647bb5f984734d0ff66a5c Author: Ben McGinnes Date: Tue Mar 20 08:31:53 2018 +1100 doc: python bindings example README * Added the same license as used with the HOWTO. * Since these examples are so basic, they'll be dual licensed the same as GPGME itself (otherwise it would slip too dangerously against the need for permissive licensing of crypto libraries). diff --git a/lang/python/examples/howto/README.org b/lang/python/examples/howto/README.org index ee8c986..604037f 100644 --- a/lang/python/examples/howto/README.org +++ b/lang/python/examples/howto/README.org @@ -22,3 +22,31 @@ guarantees. They will include the relevant imports from the =__future__= module to facilitate that if possible. + +* Copyright and Licensing + :PROPERTIES: + :CUSTOM_ID: copyright-and-license + :END: + + +** Copyright (C) The GnuPG Project, 2018 + :PROPERTIES: + :CUSTOM_ID: copyright + :END: + + Copyright ? The GnuPG Project, 2018. + + +** License GPL compatible + :PROPERTIES: + :CUSTOM_ID: license + :END: + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. commit 6950a63e63d60685ddb6f4cbff7b826b8acb5b13 Author: Ben McGinnes Date: Tue Mar 20 08:26:57 2018 +1100 docs: python bindings examples * Added reference to location where all the examples included in the HOWTO will be available as executable scripts. * Included a short README file in that location. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index b364b51..770c278 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1,4 +1,4 @@ -#+TITLE: GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English) +#+TITLE: GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English) #+LATEX_COMPILER: xelatex #+LATEX_CLASS: article #+LATEX_CLASS_OPTIONS: [12pt] @@ -49,6 +49,15 @@ data types with which GPGME deals considerably easier. +** Examples + :PROPERTIES: + :CUSTOM_ID: howto-python3-examples + :END: + + All of the examples found in this document can be found as Python 3 + scripts in the =lang/python/examples/howto= directory. + + * GPGME Concepts :PROPERTIES: :CUSTOM_ID: gpgme-concepts diff --git a/lang/python/examples/howto/README.org b/lang/python/examples/howto/README.org new file mode 100644 index 0000000..ee8c986 --- /dev/null +++ b/lang/python/examples/howto/README.org @@ -0,0 +1,24 @@ +#+TITLE: GPGME Python Bindings HOWTO Examples +#+LATEX_COMPILER: xelatex +#+LATEX_CLASS: article +#+LATEX_CLASS_OPTIONS: [12pt] +#+LATEX_HEADER: \usepackage{xltxtra} +#+LATEX_HEADER: \usepackage[margin=1in]{geometry} +#+LATEX_HEADER: \setmainfont[Ligatures={Common}]{Times New Roman} +#+LATEX_HEADER: \author{Ben McGinnes } + + +* Examples + :PROPERTIES: + :CUSTOM_ID: gpgme-python3-examples + :END: + + The contents of this directory are the examples included in the /GNU + Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO/ file. Each + script is explicitly for Python 3 and specifically for Python 3.4 or + later. + + Some of these scripts may work with Python 2.7, but there are no + guarantees. They will include the relevant imports from the + =__future__= module to facilitate that if possible. + ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 11 ++++++- lang/python/examples/howto/README.org | 58 +++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 lang/python/examples/howto/README.org hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 19 22:56:42 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 19 Mar 2018 22:56:42 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-114-gcfbdcb7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via cfbdcb7fb3fa438cafba82e4fb8f327df596f98e (commit) from b30ebf89725641018b3b08f77876530f9b983fa2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cfbdcb7fb3fa438cafba82e4fb8f327df596f98e Author: Ben McGinnes Date: Tue Mar 20 08:55:01 2018 +1100 example: python bindings key count * Added script wo count the number of keys in both the public and secret key stores. diff --git a/lang/python/examples/howto/keycount.py b/lang/python/examples/howto/keycount.py new file mode 100755 index 0000000..7dd5e77 --- /dev/null +++ b/lang/python/examples/howto/keycount.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg + +c = gpg.Context() +seckeys = c.keylist(pattern=None, secret=True) +pubkeys = c.keylist(pattern=None, secret=False) + +seclist = list(seckeys) +secnum = len(seclist) + +publist = list(pubkeys) +pubnum = len(publist) + +print(""" +Number of secret keys: {0} +Number of public keys: {1} +""".format(secnum, pubnum) ----------------------------------------------------------------------- Summary of changes: lang/python/examples/howto/keycount.py | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100755 lang/python/examples/howto/keycount.py hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 19 23:29:23 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 19 Mar 2018 23:29:23 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-115-g7ab42e7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 7ab42e79ade89f28507ea42d51148a40b4bfc736 (commit) from cfbdcb7fb3fa438cafba82e4fb8f327df596f98e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7ab42e79ade89f28507ea42d51148a40b4bfc736 Author: Ben McGinnes Date: Tue Mar 20 09:25:34 2018 +1100 example: encrypt file * Example to encrypt a file to a single key. * Takes key ID and/or fpr as a CLI parameter. * Takes path and filename as a CLI parameter. * Encrypts to specified key only, no signing and writes the output in both ASCII armoured and GPG binary formats with output filenames based on input filename. diff --git a/lang/python/examples/howto/encrypt-file.py b/lang/python/examples/howto/encrypt-file.py new file mode 100755 index 0000000..718c715 --- /dev/null +++ b/lang/python/examples/howto/encrypt-file.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys + +""" +Encrypts a file to a specified key. If entering both the key and the filename +on the command line, the key must be entered first. + +Will produce both an ASCII armoured and GPG binary format copy of the encrypted file. +""" + +if len(sys.argv) > 3: + a_key = sys.argv[1] + filename = " ".join(sys.argv[2:]) +elif len(sys.argv) == 3: + a_key = sys.argv[1] + filename = sys.argv[2] +elif len(sys.argv) == 2: + a_key = sys.argv[1] + filename = input("Enter the path and filename to encrypt: ") +else: + a_key = input("Enter the fingerprint or key ID to encrypt to: ") + filename = input("Enter the path and filename to encrypt: ") + +rkey = list(c.keylist(pattern=a_key, secret=False)) +with open(filename, "rb") as f: + text = f.read() + +with gpg.Context(armor=True) as ca: + ciphertext, result, sign_result = ca.encrypt(text, recipients=rkey, + sign=False) + with open("{0}.asc".format(filename), "wb") as fa: + fa.write(ciphertext) + +with gpg.Context() as cg: + ciphertext, result, sign_result = ca.encrypt(text, recipients=rkey, + sign=False) + with open("{0}.gpg".format(filename), "wb") as fg: + fg.write(ciphertext) ----------------------------------------------------------------------- Summary of changes: lang/python/examples/howto/encrypt-file.py | 64 ++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100755 lang/python/examples/howto/encrypt-file.py hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 19 23:54:55 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 19 Mar 2018 23:54:55 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-118-g7221bb6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 7221bb67642eb01a07957d66d0cbcd4ef8aadbf8 (commit) via f3fe47e8fd2e7bc748016befcae494421223368c (commit) via f0790f224d7af9521efe96e69a8f719fb89a5af2 (commit) from 7ab42e79ade89f28507ea42d51148a40b4bfc736 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7221bb67642eb01a07957d66d0cbcd4ef8aadbf8 Author: Ben McGinnes Date: Tue Mar 20 09:53:27 2018 +1100 example: encrypt file * Nested encryption in try/except statement in case recipient key is untrusted or invalid. diff --git a/lang/python/examples/howto/encrypt-file.py b/lang/python/examples/howto/encrypt-file.py index 8aee52a..017a342 100755 --- a/lang/python/examples/howto/encrypt-file.py +++ b/lang/python/examples/howto/encrypt-file.py @@ -52,13 +52,19 @@ with open(filename, "rb") as f: text = f.read() with gpg.Context(armor=True) as ca: - ciphertext, result, sign_result = ca.encrypt(text, recipients=rkey, - sign=False) - with open("{0}.asc".format(filename), "wb") as fa: - fa.write(ciphertext) + try: + ciphertext, result, sign_result = ca.encrypt(text, recipients=rkey, + sign=False) + with open("{0}.asc".format(filename), "wb") as fa: + fa.write(ciphertext) + except gpg.errors.InvalidRecipients as e: + print(e) with gpg.Context() as cg: - ciphertext, result, sign_result = cg.encrypt(text, recipients=rkey, - sign=False) - with open("{0}.gpg".format(filename), "wb") as fg: - fg.write(ciphertext) + try: + ciphertext, result, sign_result = cg.encrypt(text, recipients=rkey, + sign=False) + with open("{0}.gpg".format(filename), "wb") as fg: + fg.write(ciphertext) + except gpg.errors.InvalidRecipients as e: + print(e) commit f3fe47e8fd2e7bc748016befcae494421223368c Author: Ben McGinnes Date: Tue Mar 20 09:47:39 2018 +1100 example: sign and encrypt file * Example to sign and encrypt a file. * Similar to encrypt-file.py except all keys are considered trusted and signs with the default key. * Also encrypts to the default key. diff --git a/lang/python/examples/howto/encrypt-sign-file.py b/lang/python/examples/howto/encrypt-sign-file.py new file mode 100755 index 0000000..c8850b2 --- /dev/null +++ b/lang/python/examples/howto/encrypt-sign-file.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys + +""" +Signs and encrypts a file to a specified key. If entering both the key and the +filename on the command line, the key must be entered first. + +Signs with and also encrypts to the default key of the user invoking the +script. Will treat all recipients as trusted to permit encryption. + +Will produce both an ASCII armoured and GPG binary format copy of the encrypted +file. +""" + +if len(sys.argv) > 3: + a_key = sys.argv[1] + filename = " ".join(sys.argv[2:]) +elif len(sys.argv) == 3: + a_key = sys.argv[1] + filename = sys.argv[2] +elif len(sys.argv) == 2: + a_key = sys.argv[1] + filename = input("Enter the path and filename to encrypt: ") +else: + a_key = input("Enter the fingerprint or key ID to encrypt to: ") + filename = input("Enter the path and filename to encrypt: ") + +rkey = list(c.keylist(pattern=a_key, secret=False)) +with open(filename, "rb") as f: + text = f.read() + +with gpg.Context(armor=True) as ca: + ciphertext, result, sign_result = ca.encrypt(text, recipients=rkey, + always_trust=True, + add_encrypt_to=True) + with open("{0}.asc".format(filename), "wb") as fa: + fa.write(ciphertext) + +with gpg.Context() as cg: + ciphertext, result, sign_result = cg.encrypt(text, recipients=rkey, + always_trust=True, + add_encrypt_to=True) + with open("{0}.gpg".format(filename), "wb") as fg: + fg.write(ciphertext) commit f0790f224d7af9521efe96e69a8f719fb89a5af2 Author: Ben McGinnes Date: Tue Mar 20 09:39:48 2018 +1100 example: encrypt file * Fixed typo in second encryption call. diff --git a/lang/python/examples/howto/encrypt-file.py b/lang/python/examples/howto/encrypt-file.py index 718c715..8aee52a 100755 --- a/lang/python/examples/howto/encrypt-file.py +++ b/lang/python/examples/howto/encrypt-file.py @@ -58,7 +58,7 @@ with gpg.Context(armor=True) as ca: fa.write(ciphertext) with gpg.Context() as cg: - ciphertext, result, sign_result = ca.encrypt(text, recipients=rkey, + ciphertext, result, sign_result = cg.encrypt(text, recipients=rkey, sign=False) with open("{0}.gpg".format(filename), "wb") as fg: fg.write(ciphertext) ----------------------------------------------------------------------- Summary of changes: lang/python/examples/howto/encrypt-file.py | 22 ++++++++++++++-------- .../{encrypt-file.py => encrypt-sign-file.py} | 18 ++++++++++++------ 2 files changed, 26 insertions(+), 14 deletions(-) copy lang/python/examples/howto/{encrypt-file.py => encrypt-sign-file.py} (75%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 20 04:21:59 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Tue, 20 Mar 2018 04:21:59 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-119-g29e9181 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 29e918171f352c71a90a16c04d4a3dcafa5db682 (commit) from 7221bb67642eb01a07957d66d0cbcd4ef8aadbf8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 29e918171f352c71a90a16c04d4a3dcafa5db682 Author: Ben McGinnes Date: Tue Mar 20 14:19:16 2018 +1100 example: groups work-around * Added groups selection work around code. * Intended for use as a module to be imported by other scripts, usually with "from groups import group_lists" or "from groups import group_lines" or similar. diff --git a/lang/python/examples/howto/groups.py b/lang/python/examples/howto/groups.py new file mode 100644 index 0000000..67fd783 --- /dev/null +++ b/lang/python/examples/howto/groups.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import subprocess + +lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines() + +for i in range(len(lines)): + if lines[i].startswith("group") is True: + line = lines[i] + else: + pass + +groups = line.split(":")[-1].replace('"', '').split(',') + +group_lines = groups +for i in range(len(group_lines)): + group_lines[i] = group_lines[i].split("=") + +group_lists = group_lines +for i in range(len(group_lists)): + group_lists[i][1] = group_lists[i][1].split() ----------------------------------------------------------------------- Summary of changes: .../examples/howto/{keycount.py => groups.py} | 28 ++++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) copy lang/python/examples/howto/{keycount.py => groups.py} (69%) mode change 100755 => 100644 hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 20 04:34:17 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Tue, 20 Mar 2018 04:34:17 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-120-g5125897 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 51258975d763c9471859d635e6080c2ec02e8647 (commit) from 29e918171f352c71a90a16c04d4a3dcafa5db682 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 51258975d763c9471859d635e6080c2ec02e8647 Author: Ben McGinnes Date: Tue Mar 20 14:32:53 2018 +1100 example: decrypt file * Decrypts a file taking file names as command line parameters. diff --git a/lang/python/examples/howto/decrypt-file.py b/lang/python/examples/howto/decrypt-file.py new file mode 100755 index 0000000..60a050b --- /dev/null +++ b/lang/python/examples/howto/decrypt-file.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys + +if len(sys.argv) == 3: + ciphertext = sys.argv[1] + newfile = sys.argv[2] +elif len(sys.argv) == 2: + ciphertext = sys.argv[1] + newfile = input("Enter path and filename of file to save decrypted data to: ") +else: + ciphertext = input("Enter path and filename of encrypted file: ") + newfile = input("Enter path and filename of file to save decrypted data to: ") + +with open(ciphertext, "rb") as cfile: + plaintext, result, verify_result = gpg.Context().decrypt(cfile) + +with open(newfile, "wb") as nfile: + nfile.write(plaintext) ----------------------------------------------------------------------- Summary of changes: .../howto/{keycount.py => decrypt-file.py} | 26 ++++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) copy lang/python/examples/howto/{keycount.py => decrypt-file.py} (67%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 20 04:58:41 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Tue, 20 Mar 2018 04:58:41 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-122-g52e2629 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 52e262991f1fdf7da93882c3b22c05537376cf49 (commit) via 96d0395bccbbff91f73c06cb7bd6c131f04b8a9a (commit) from 51258975d763c9471859d635e6080c2ec02e8647 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 52e262991f1fdf7da93882c3b22c05537376cf49 Author: Ben McGinnes Date: Tue Mar 20 14:57:26 2018 +1100 doc: python bindings howto * Fixed typos in examples. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 770c278..2a200bb 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -406,7 +406,7 @@ print(""" Number of secret keys: {0} Number of public keys: {1} - """.format(secnum, pubnum) + """.format(secnum, pubnum)) #+end_src @@ -671,7 +671,7 @@ newfile = input("Enter path and filename of file to save decrypted data to: ") with open(ciphertext, "rb") as cfile: plaintext, result, verify_result = gpg.Context().decrypt(cfile) - with open(newfile, "wb" as nfile: + with open(newfile, "wb") as nfile: nfile.write(plaintext) #+end_src commit 96d0395bccbbff91f73c06cb7bd6c131f04b8a9a Author: Ben McGinnes Date: Tue Mar 20 14:55:05 2018 +1100 example: keycount * Fixed missing parenthesis. diff --git a/lang/python/examples/howto/keycount.py b/lang/python/examples/howto/keycount.py index 7dd5e77..8e25454 100755 --- a/lang/python/examples/howto/keycount.py +++ b/lang/python/examples/howto/keycount.py @@ -39,4 +39,4 @@ pubnum = len(publist) print(""" Number of secret keys: {0} Number of public keys: {1} -""".format(secnum, pubnum) +""".format(secnum, pubnum)) ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 4 ++-- lang/python/examples/howto/keycount.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 20 08:45:07 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 20 Mar 2018 08:45:07 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-96-geb340dd Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via eb340dd8330139da31124732d18b5f2d11f72d2f (commit) from a6bf8ef284d98f87a9e64ce326e2a0a55633213c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit eb340dd8330139da31124732d18b5f2d11f72d2f Author: Andre Heinecke Date: Tue Mar 20 08:43:45 2018 +0100 Provide parent wid for certificate details * src/ribbon-callbacks.cpp (launch_cert_details): Add --parent-wid. -- This helps Kleopatra not to open the certificate details in the background. GnuPG-Bug-Id: T3845 diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp index 07b5ba7..99eaf60 100644 --- a/src/ribbon-callbacks.cpp +++ b/src/ribbon-callbacks.cpp @@ -1740,9 +1740,12 @@ HRESULT launch_cert_details (LPDISPATCH ctrl) log_error ("%s:%s: No spawn engine.", SRCNAME, __func__); } + std::string parentWid = std::to_string ((unsigned int) get_active_hwnd ()); const char *argv[] = {path.c_str(), "--query", mail->get_sig_fpr(), + "--parent-windowid", + parentWid.c_str(), NULL }; log_debug ("%s:%s: Starting %s %s %s", SRCNAME, __func__, path.c_str(), argv[1], argv[2]); ----------------------------------------------------------------------- Summary of changes: src/ribbon-callbacks.cpp | 3 +++ 1 file changed, 3 insertions(+) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 20 09:16:06 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 20 Mar 2018 09:16:06 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-97-g130d9ab Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 130d9ab498d42934b2fad5a26946ed3e031a9982 (commit) from eb340dd8330139da31124732d18b5f2d11f72d2f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 130d9ab498d42934b2fad5a26946ed3e031a9982 Author: Andre Heinecke Date: Tue Mar 20 09:14:28 2018 +0100 Add proper spawn flags to kleopatra initial start * src/ribbon-callbacks.cpp (launch_cert_details): Add spawn flags to fix initial show. -- This allows the initial start to show a window / foreground window and fixes a bug that the initial cert details was not shown. GnuPG-Bug-Id: T3845 diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp index 99eaf60..67cb7cc 100644 --- a/src/ribbon-callbacks.cpp +++ b/src/ribbon-callbacks.cpp @@ -1751,7 +1751,9 @@ HRESULT launch_cert_details (LPDISPATCH ctrl) SRCNAME, __func__, path.c_str(), argv[1], argv[2]); Data d(Data::null); ctx->spawnAsync(path.c_str(), argv, d, d, - d, Context::SpawnNone); + d, (GpgME::Context::SpawnFlags) ( + GpgME::Context::SpawnAllowSetFg | + GpgME::Context::SpawnShowWindow)); } else { ----------------------------------------------------------------------- Summary of changes: src/ribbon-callbacks.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 20 11:19:04 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 20 Mar 2018 11:19:04 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-54-g343d3e2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 343d3e2232a22d0999e1693f0f95e5e290005829 (commit) via 9e1e6554834d0e803dd0889deaef4f11047c7e47 (commit) from ad95288d3b3efc38998841add4fe658c84701f98 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 343d3e2232a22d0999e1693f0f95e5e290005829 Author: Werner Koch Date: Tue Mar 20 10:41:18 2018 +0100 core: Do not clobber R_KEY in gpgme_get_key on error. * src/keylist.c (gpgme_get_key): Assign a value to the return parameter only on success. -- This problem could be triggered by an ambiguous key. The problem is that the key returned in that case is for one not expected and worse it has not been ref-ed. Signed-off-by: Werner Koch diff --git a/src/keylist.c b/src/keylist.c index 24a9b0b..7956935 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -1261,7 +1261,7 @@ gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key, { gpgme_ctx_t listctx; gpgme_error_t err; - gpgme_key_t key; + gpgme_key_t result, key; TRACE_BEG2 (DEBUG_CTX, "gpgme_get_key", ctx, "fpr=%s, secret=%i", fpr, secret); @@ -1295,7 +1295,7 @@ gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key, err = gpgme_op_keylist_start (listctx, fpr, secret); if (!err) - err = gpgme_op_keylist_next (listctx, r_key); + err = gpgme_op_keylist_next (listctx, &result); if (!err) { try_next_key: @@ -1305,9 +1305,9 @@ gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key, else { if (!err - && *r_key && (*r_key)->subkeys && (*r_key)->subkeys->fpr + && result && result->subkeys && result->subkeys->fpr && key && key->subkeys && key->subkeys->fpr - && !strcmp ((*r_key)->subkeys->fpr, key->subkeys->fpr)) + && !strcmp (result->subkeys->fpr, key->subkeys->fpr)) { /* The fingerprint is identical. We assume that this is the same key and don't mark it as an ambiguous. This @@ -1323,12 +1323,14 @@ gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key, gpgme_key_unref (key); err = gpg_error (GPG_ERR_AMBIGUOUS_NAME); } - gpgme_key_unref (*r_key); + gpgme_key_unref (result); + result = NULL; } } gpgme_release (listctx); if (! err) { + *r_key = result; TRACE_LOG2 ("key=%p (%s)", *r_key, ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ? (*r_key)->subkeys->fpr : "invalid"); commit 9e1e6554834d0e803dd0889deaef4f11047c7e47 Author: Werner Koch Date: Tue Mar 20 10:34:56 2018 +0100 core: Fix ABI regression in recent commit. * src/gpgme.h.in (_gpgme_op_import_result): Move new field 'skipped_v3_keys' to the end. -- The ABI break has not made it into a release. Also document the new field. Fixes-commit: a630a1e3e74c926163864b013cb164b4cd1866fc Signed-off-by: Werner Koch diff --git a/doc/gpgme.texi b/doc/gpgme.texi index cd7bb4b..37cf16a 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -4811,6 +4811,12 @@ The number of keys not imported. @item gpgme_import_status_t imports A list of gpgme_import_status_t objects which contain more information about the keys for which an import was attempted. + + at item int skipped_v3_keys +For security reasons modern versions of GnuPG do not anymore support +v3 keys (created with PGP 2.x) and ignores them on import. This +counter provides the number of such skipped v3 keys. + @end table @end deftp diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 73f2c94..e319879 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1637,11 +1637,11 @@ struct _gpgme_op_import_result /* Number of keys not imported. */ int not_imported; - /* Number of v3 keys skipped. */ - int skipped_v3_keys; - /* List of keys for which an import was attempted. */ gpgme_import_status_t imports; + + /* Number of v3 keys skipped. */ + int skipped_v3_keys; }; typedef struct _gpgme_op_import_result *gpgme_import_result_t; ----------------------------------------------------------------------- Summary of changes: doc/gpgme.texi | 6 ++++++ src/gpgme.h.in | 6 +++--- src/keylist.c | 12 +++++++----- 3 files changed, 16 insertions(+), 8 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 20 11:25:25 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 20 Mar 2018 11:25:25 +0100 Subject: [git] GPGME - branch, json-tool, updated. gpgme-1.10.0-59-g6073789 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, json-tool has been updated via 6073789a6d3514263404c93fa795a398bfd93d91 (commit) via 44f9e80ea99733f373d75c3632273f763e6f5853 (commit) via 343d3e2232a22d0999e1693f0f95e5e290005829 (commit) via 9e1e6554834d0e803dd0889deaef4f11047c7e47 (commit) via ad95288d3b3efc38998841add4fe658c84701f98 (commit) via a630a1e3e74c926163864b013cb164b4cd1866fc (commit) from d2b31d8c106423bd0eaa5fffaa39b0983c9ae525 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6073789a6d3514263404c93fa795a398bfd93d91 Author: Werner Koch Date: Tue Mar 20 11:14:26 2018 +0100 json: Implement op:encrypt Signed-off-by: Werner Koch diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 4251f2b..00d8110 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -46,10 +46,10 @@ static void xoutofcore (const char *type) GPGRT_ATTR_NORETURN; -static cjson_t error_object_v (const char *message, - va_list arg_ptr) GPGRT_ATTR_PRINTF(1,0); -static cjson_t error_object (const char *message, - ...) GPGRT_ATTR_PRINTF(1,2); +static cjson_t error_object_v (cjson_t json, const char *message, + va_list arg_ptr) GPGRT_ATTR_PRINTF(2,0); +static cjson_t error_object (cjson_t json, const char *message, + ...) GPGRT_ATTR_PRINTF(2,3); static char *error_object_string (const char *message, ...) GPGRT_ATTR_PRINTF(1,2); @@ -64,6 +64,16 @@ static int opt_interactive; */ #define xtrymalloc(a) gpgrt_malloc ((a)) +#define xmalloc(a) ({ \ + void *_r = gpgrt_malloc ((a)); \ + if (!_r) \ + xoutofcore ("malloc"); \ + _r; }) +#define xcalloc(a,b) ({ \ + void *_r = gpgrt_calloc ((a), (b)); \ + if (!_r) \ + xoutofcore ("calloc"); \ + _r; }) #define xstrdup(a) ({ \ char *_r = gpgrt_strdup ((a)); \ if (!_r) \ @@ -100,7 +110,7 @@ xjson_CreateObject (void) /* Wrapper around cJSON_AddStringToObject which returns an gpg-error - * code instead of the NULL or the object. */ + * code instead of the NULL or the new object. */ static gpg_error_t cjson_AddStringToObject (cjson_t object, const char *name, const char *string) { @@ -111,7 +121,7 @@ cjson_AddStringToObject (cjson_t object, const char *name, const char *string) /* Same as cjson_AddStringToObject but prints an error message and - * terminates. the process. */ + * terminates the process. */ static void xjson_AddStringToObject (cjson_t object, const char *name, const char *string) { @@ -120,19 +130,40 @@ xjson_AddStringToObject (cjson_t object, const char *name, const char *string) } -/* Create a JSON error object. */ +/* Wrapper around cJSON_AddBoolToObject which terminates the process + * in case of an error. */ +static void +xjson_AddBoolToObject (cjson_t object, const char *name, int abool) +{ + if (!cJSON_AddBoolToObject (object, name, abool)) + xoutofcore ("cJSON_AddStringToObject"); + return ; +} + + +/* Create a JSON error object. If JSON is not NULL the error message + * is appended to that object. An existing "type" item will be replaced. */ static cjson_t -error_object_v (const char *message, va_list arg_ptr) +error_object_v (cjson_t json, const char *message, va_list arg_ptr) { - cjson_t response; + cjson_t response, j_tmp; char *msg; msg = gpgrt_vbsprintf (message, arg_ptr); if (!msg) xoutofcore ("error_object"); - response = xjson_CreateObject (); - xjson_AddStringToObject (response, "type", "error"); + response = json? json : xjson_CreateObject (); + + if (!(j_tmp = cJSON_GetObjectItem (response, "type"))) + xjson_AddStringToObject (response, "type", "error"); + else /* Replace existing "type". */ + { + j_tmp = cJSON_CreateString ("error"); + if (!j_tmp) + xoutofcore ("cJSON_CreateString"); + cJSON_ReplaceItemInObject (response, "type", j_tmp); + } xjson_AddStringToObject (response, "msg", msg); xfree (msg); @@ -153,13 +184,13 @@ xjson_Print (cjson_t object) static cjson_t -error_object (const char *message, ...) +error_object (cjson_t json, const char *message, ...) { cjson_t response; va_list arg_ptr; va_start (arg_ptr, message); - response = error_object_v (message, arg_ptr); + response = error_object_v (json, message, arg_ptr); va_end (arg_ptr); return response; } @@ -173,7 +204,7 @@ error_object_string (const char *message, ...) char *msg; va_start (arg_ptr, message); - response = error_object_v (message, arg_ptr); + response = error_object_v (NULL, message, arg_ptr); va_end (arg_ptr); msg = xjson_Print (response); @@ -182,6 +213,179 @@ error_object_string (const char *message, ...) } +/* Get the boolean property NAME from the JSON object and store true + * or valse at R_VALUE. If the name is unknown the value of DEF_VALUE + * is returned. If the type of the value is not boolean, + * GPG_ERR_INV_VALUE is returned and R_VALUE set to DEF_VALUE. */ +static gpg_error_t +get_boolean_flag (cjson_t json, const char *name, int def_value, int *r_value) +{ + cjson_t j_item; + + j_item = cJSON_GetObjectItem (json, name); + if (!j_item) + *r_value = def_value; + else if (cjson_is_true (j_item)) + *r_value = 1; + else if (cjson_is_false (j_item)) + *r_value = 0; + else + { + *r_value = def_value; + return gpg_error (GPG_ERR_INV_VALUE); + } + + return 0; +} + + +/* Get the boolean property PROTOCOL from the JSON object and store + * its value at R_PROTOCOL. The default is OpenPGP. */ +static gpg_error_t +get_protocol (cjson_t json, gpgme_protocol_t *r_protocol) +{ + cjson_t j_item; + + *r_protocol = GPGME_PROTOCOL_OpenPGP; + j_item = cJSON_GetObjectItem (json, "protocol"); + if (!j_item) + ; + else if (!cjson_is_string (j_item)) + return gpg_error (GPG_ERR_INV_VALUE); + else if (!strcmp(j_item->valuestring, "openpgp")) + ; + else if (!strcmp(j_item->valuestring, "cms")) + *r_protocol = GPGME_PROTOCOL_CMS; + else + return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL); + + return 0; +} + + +/* Extract the keys from the KEYS array in the JSON object. CTX is a + * GPGME context object. On success an array with the keys is stored + * at R_KEYS. In failure an error code is returned. */ +static gpg_error_t +get_keys (gpgme_ctx_t ctx, cjson_t json, gpgme_key_t **r_keys) +{ + gpg_error_t err; + cjson_t j_keys, j_item; + int i, nkeys; + gpgme_key_t *keys; + + *r_keys = NULL; + + j_keys = cJSON_GetObjectItem (json, "keys"); + if (!j_keys) + return gpg_error (GPG_ERR_NO_KEY); + if (!cjson_is_array (j_keys) && !cjson_is_string (j_keys)) + return gpg_error (GPG_ERR_INV_VALUE); + + if (cjson_is_string (j_keys)) + nkeys = 1; + else + { + nkeys = cJSON_GetArraySize (j_keys); + if (!nkeys) + return gpg_error (GPG_ERR_NO_KEY); + for (i=0; i < nkeys; i++) + { + j_item = cJSON_GetArrayItem (j_keys, i); + if (!j_item || !cjson_is_string (j_item)) + return gpg_error (GPG_ERR_INV_VALUE); + } + } + + /* Now allocate an array to store the gpgme key objects. */ + keys = xcalloc (nkeys + 1, sizeof *keys); + + if (cjson_is_string (j_keys)) + { + err = gpgme_get_key (ctx, j_keys->valuestring, &keys[0], 0); + if (err) + goto leave; + } + else + { + for (i=0; i < nkeys; i++) + { + j_item = cJSON_GetArrayItem (j_keys, i); + err = gpgme_get_key (ctx, j_item->valuestring, &keys[i], 0); + if (err) + goto leave; + } + } + err = 0; + *r_keys = keys; + keys = NULL; + + leave: + if (keys) + { + for (i=0; keys[i]; i++) + gpgme_key_unref (keys[i]); + xfree (keys); + } + return err; +} + + + +/* + * GPGME support functions. + */ + +/* Helper for get_context. */ +static gpgme_ctx_t +_create_new_context (gpgme_protocol_t proto) +{ + gpg_error_t err; + gpgme_ctx_t ctx; + + err = gpgme_new (&ctx); + if (err) + log_fatal ("error creating GPGME context: %s\n", gpg_strerror (err)); + gpgme_set_protocol (ctx, proto); + return ctx; +} + + +/* Return a context object for protocol PROTO. This is currently a + * statuically allocated context initialized for PROTO. Termnates + * process on failure. */ +static gpgme_ctx_t +get_context (gpgme_protocol_t proto) +{ + static gpgme_ctx_t ctx_openpgp, ctx_cms; + + if (proto == GPGME_PROTOCOL_OpenPGP) + { + if (!ctx_openpgp) + ctx_openpgp = _create_new_context (proto); + return ctx_openpgp; + } + else if (proto == GPGME_PROTOCOL_CMS) + { + if (!ctx_cms) + ctx_cms = _create_new_context (proto); + return ctx_cms; + } + else + log_bug ("invalid protocol %d requested\n", proto); +} + + + +/* Free context object retrieved by get_context. */ +static void +release_context (gpgme_ctx_t ctx) +{ + /* Nothing to do right now. */ + (void)ctx; +} + + /* * Implementaion of the commands. @@ -193,12 +397,13 @@ static const char hlp_encrypt[] = "keys: Array of strings with the fingerprints or user-ids\n" " of the keys to encrypt the data. For a single key\n" " a String may be used instead of an array.\n" - "data: Base64 encoded input data.\n" + "data: Input data. \n" "\n" "Optional parameters:\n" "protocol: Either \"openpgp\" (default) or \"cms\".\n" "\n" "Optional boolean flags (default is false):\n" + "base64: Input data is base64 encoded.\n" "armor: Request output in armored format.\n" "always-trust: Request --always-trust option.\n" "no-encrypt-to: Do not use a default recipient.\n" @@ -213,11 +418,144 @@ static const char hlp_encrypt[] = " OpenPGP or a PEM message.\n" "base64: Boolean indicating whether data is base64 encoded."; static gpg_error_t -op_encrypt (cjson_t request, cjson_t *r_result) +op_encrypt (cjson_t request, cjson_t result) { + gpg_error_t err; + gpgme_ctx_t ctx = NULL; + gpgme_protocol_t protocol; + int opt_base64; + gpgme_key_t *keys = NULL; + cjson_t j_input; + gpgme_data_t input = NULL; + gpgme_data_t output = NULL; + int abool, i; + gpgme_encrypt_flags_t encrypt_flags = 0; + + if ((err = get_protocol (request, &protocol))) + goto leave; + ctx = get_context (protocol); + + if ((err = get_boolean_flag (request, "base64", 0, &opt_base64))) + goto leave; + + if ((err = get_boolean_flag (request, "armor", 0, &abool))) + goto leave; + gpgme_set_armor (ctx, abool); + if ((err = get_boolean_flag (request, "always-trust", 0, &abool))) + goto leave; + if (abool) + encrypt_flags |= GPGME_ENCRYPT_ALWAYS_TRUST; + if ((err = get_boolean_flag (request, "no-encrypt-to", 0,&abool))) + goto leave; + if (abool) + encrypt_flags |= GPGME_ENCRYPT_NO_ENCRYPT_TO; + if ((err = get_boolean_flag (request, "no-compress", 0, &abool))) + goto leave; + if (abool) + encrypt_flags |= GPGME_ENCRYPT_NO_COMPRESS; + if ((err = get_boolean_flag (request, "throw-keyids", 0, &abool))) + goto leave; + if (abool) + encrypt_flags |= GPGME_ENCRYPT_THROW_KEYIDS; + if ((err = get_boolean_flag (request, "wrap", 0, &abool))) + goto leave; + if (abool) + encrypt_flags |= GPGME_ENCRYPT_WRAP; + + + /* Get the keys. */ + err = get_keys (ctx, request, &keys); + if (err) + { + /* Provide a custom error response. */ + error_object (result, "Error getting keys: %s", gpg_strerror (err)); + goto leave; + } + /* Get the data. Note that INPUT is a shallow data object with the + * storage hold in REQUEST. */ + j_input = cJSON_GetObjectItem (request, "data"); + if (!j_input) + { + err = gpg_error (GPG_ERR_NO_DATA); + goto leave; + } + if (!cjson_is_string (j_input)) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + if (opt_base64) + { + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + goto leave; + } + err = gpgme_data_new_from_mem (&input, j_input->valuestring, + strlen (j_input->valuestring), 0); + if (err) + { + error_object (result, "Error creating input data object: %s", + gpg_strerror (err)); + goto leave; + } - return 0; + /* Create an output data object. */ + err = gpgme_data_new (&output); + if (err) + { + error_object (result, "Error creating output data object: %s", + gpg_strerror (err)); + goto leave; + } + + /* Encrypt. */ + err = gpgme_op_encrypt (ctx, keys, encrypt_flags, input, output); + /* encrypt_result = gpgme_op_encrypt_result (ctx); */ + if (err) + { + error_object (result, "Encryption failed: %s", gpg_strerror (err)); + goto leave; + } + gpgme_data_release (input); + input = NULL; + + xjson_AddStringToObject (result, "type", "ciphertext"); + /* If armoring is used we do not need to base64 the output. */ + xjson_AddBoolToObject (result, "base64", !gpgme_get_armor (ctx)); + if (gpgme_get_armor (ctx)) + { + char *buffer; + + /* Make sure that we really have a string. */ + gpgme_data_write (output, "", 1); + buffer = gpgme_data_release_and_get_mem (output, NULL); + if (!buffer) + { + err = gpg_error_from_syserror (); + goto leave; + } + err = cjson_AddStringToObject (result, "data", buffer); + gpgme_free (buffer); + if (err) + goto leave; + } + else + { + error_object (result, "Binary output is not yet supported"); + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + goto leave; + } + + leave: + if (keys) + { + for (i=0; keys[i]; i++) + gpgme_key_unref (keys[i]); + xfree (keys); + } + release_context (ctx); + gpgme_data_release (input); + return err; } @@ -233,10 +571,8 @@ static const char hlp_help[] = " encrypt Encrypt data.\n" " help Help overview."; static gpg_error_t -op_help (cjson_t request, cjson_t *r_result) +op_help (cjson_t request, cjson_t result) { - gpg_error_t err = 0; - cjson_t result = NULL; cjson_t j_tmp; char *buffer = NULL; const char *msg; @@ -247,20 +583,11 @@ op_help (cjson_t request, cjson_t *r_result) else msg = hlp_help; - result = cJSON_CreateObject (); - if (!result) - err = gpg_error_from_syserror (); - if (!err) - err = cjson_AddStringToObject (result, "type", "help"); - if (!err) - err = cjson_AddStringToObject (result, "msg", msg); + xjson_AddStringToObject (result, "type", "help"); + xjson_AddStringToObject (result, "msg", msg); xfree (buffer); - if (err) - xfree (result); - else - *r_result = result; - return err; + return 0; } @@ -272,7 +599,7 @@ process_request (const char *request) { static struct { const char *op; - gpg_error_t (*handler)(cjson_t request, cjson_t *r_result); + gpg_error_t (*handler)(cjson_t request, cjson_t result); const char * const helpstr; } optbl[] = { { "encrypt", op_encrypt, hlp_encrypt }, @@ -281,22 +608,23 @@ process_request (const char *request) { "help", op_help, hlp_help }, { NULL } }; - gpg_error_t err = 0; size_t erroff; cjson_t json; cjson_t j_tmp, j_op; - cjson_t response = NULL; + cjson_t response; int helpmode; const char *op; char *res; int idx; + response = xjson_CreateObject (); + json = cJSON_Parse (request, &erroff); if (!json) { log_string (GPGRT_LOGLVL_INFO, request); log_info ("invalid JSON object at offset %zu\n", erroff); - response = error_object ("invalid JSON object at offset %zu\n", erroff); + error_object (response, "invalid JSON object at offset %zu\n", erroff); goto leave; } @@ -308,7 +636,7 @@ process_request (const char *request) { if (!helpmode) { - response = error_object ("Property \"op\" missing"); + error_object (response, "Property \"op\" missing"); goto leave; } op = "help"; /* Help summary. */ @@ -323,40 +651,44 @@ process_request (const char *request) { if (helpmode && strcmp (op, "help")) { - response = cJSON_CreateObject (); - if (!response) - err = gpg_error_from_syserror (); - if (!err) - err = cjson_AddStringToObject (response, "type", "help"); - if (!err) - err = cjson_AddStringToObject (response, "op", op); - if (!err) - err = cjson_AddStringToObject (response, "msg", optbl[idx].helpstr); + xjson_AddStringToObject (response, "type", "help"); + xjson_AddStringToObject (response, "op", op); + xjson_AddStringToObject (response, "msg", optbl[idx].helpstr); } else - err = optbl[idx].handler (json, &response); + { + gpg_error_t err; + + err = optbl[idx].handler (json, response); + if (err) + { + if (!(j_tmp = cJSON_GetObjectItem (response, "type")) + || !cjson_is_string (j_tmp) + || strcmp (j_tmp->valuestring, "error")) + { + /* No error type response - provide a generic one. */ + error_object (response, "Operation failed: %s", + gpg_strerror (err)); + } + + xjson_AddStringToObject (response, "op", op); + } + + } } else /* Operation not supported. */ { - response = error_object ("Unknown operation '%s'", op); - err = cjson_AddStringToObject (response, "op", op); + error_object (response, "Unknown operation '%s'", op); + xjson_AddStringToObject (response, "op", op); } leave: cJSON_Delete (json); json = NULL; - if (err) - log_error ("failed to create the response: %s\n", gpg_strerror (err)); - if (response) - { - res = cJSON_Print (response); - if (!res) - log_error ("Printing JSON data failed\n"); - cJSON_Delete (response); - } - else - res = NULL; - + res = cJSON_Print (response); + if (!res) + log_error ("Printing JSON data failed\n"); + cJSON_Delete (response); return res; } commit 44f9e80ea99733f373d75c3632273f763e6f5853 Merge: d2b31d8 343d3e2 Author: Werner Koch Date: Tue Mar 20 11:13:14 2018 +0100 Merge branch 'master' into json-tool ----------------------------------------------------------------------- Summary of changes: NEWS | 3 +- doc/gpgme.texi | 6 + lang/cpp/src/importresult.cpp | 5 + lang/cpp/src/importresult.h | 1 + src/gpgme-json.c | 454 ++++++++++++++++++++++++++++++++++++------ src/gpgme.h.in | 3 + src/import.c | 9 +- src/keylist.c | 12 +- tests/gpg/t-support.h | 6 +- tests/run-support.h | 6 +- 10 files changed, 432 insertions(+), 73 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 21 02:30:47 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 21 Mar 2018 02:30:47 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-123-g0390ede Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 0390ede18696520be9cc1a42f628e23159b7c2eb (commit) from 52e262991f1fdf7da93882c3b22c05537376cf49 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0390ede18696520be9cc1a42f628e23159b7c2eb Author: Ben McGinnes Date: Wed Mar 21 12:28:03 2018 +1100 example: sign file * Similar to encrypt file except for signing a file in normal mode. * Noticed additional changes to be made to the howto to match this, but they will have to wait due to a power outage (currently running on battery and a mobile connection, but that won't last). diff --git a/lang/python/examples/howto/sign-file.py b/lang/python/examples/howto/sign-file.py new file mode 100755 index 0000000..8e2cdc2 --- /dev/null +++ b/lang/python/examples/howto/sign-file.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys + +""" +Signs a file with a specified key. If entering both the key and the filename +on the command line, the key must be entered first. + +Will produce both an ASCII armoured and GPG binary format copy of the encrypted file. +""" + +if len(sys.argv) > 3: + logrus = sys.argv[1] + filename = " ".join(sys.argv[2:]) +elif len(sys.argv) == 3: + logrus = sys.argv[1] + filename = sys.argv[2] +elif len(sys.argv) == 2: + logrus = sys.argv[1] + filename = input("Enter the path and filename to sign: ") +else: + logrus = input("Enter the fingerprint or key ID to sign with: ") + filename = input("Enter the path and filename to sign: ") + +with open(filename, "rb") as f: + text = f.read() + +key = list(gpg.Context().keylist(pattern=logrus)) + +with gpg.Context(armor=True, signers=key) as ca: + signed_data, result = ca.sign(text, mode=gpg.constants.sig.mode.NORMAL) + with open("{0}.asc".format(filename), "wb") as fa: + fa.write(signed_data) + +with gpg.Context(signers=key) as cg: + signed_data, result = cg.sign(text, mode=gpg.constants.sig.mode.NORMAL) + with open("{0}.gpg".format(filename), "wb") as fg: + fg.write(signed_data) ----------------------------------------------------------------------- Summary of changes: .../howto/{encrypt-file.py => sign-file.py} | 41 +++++++++------------- 1 file changed, 17 insertions(+), 24 deletions(-) copy lang/python/examples/howto/{encrypt-file.py => sign-file.py} (58%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 21 09:26:30 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 21 Mar 2018 09:26:30 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.5-122-gfa0ed1c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via fa0ed1c7e2eee7c559026696e6b21acc882a97aa (commit) from b32de1bf3e5114eb29472c301f2d5bb9ffd2f4fa (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fa0ed1c7e2eee7c559026696e6b21acc882a97aa Author: Werner Koch Date: Wed Mar 21 09:15:13 2018 +0100 Change license of argparse.c back to LGPLv2.1 * common/argparse.c, common/argparse.h: Change license -- On 2011-09-30 the license of these two files were changed from LGPLv2.1 to LGPLv3+/GPLv2+. This was part of a general change from files with either GPLv3+ or LGPv2.1+ to this combination so to allow the use of these files with GPLv2only code. Since then the code was only modified by employees of g10 Code GmbH under my direction and myself. The following changes commit 7249ab0f95d1f6cb8ee61eefedc79801bb56398f Author: Daniel Kahn Gillmor AuthorDate: Tue Jan 10 15:59:36 2017 -0500 commit eed16ccebf8fd1fdf9709affbd5c831f6957b8ae Author: Daniel Kahn Gillmor AuthorDate: Fri Nov 21 17:04:42 2014 -0500 and a few typo fixes are minor and thus not copyright-able. Signed-off-by: Werner Koch diff --git a/common/argparse.c b/common/argparse.c index 90d0ff7..331998b 100644 --- a/common/argparse.c +++ b/common/argparse.c @@ -1,32 +1,23 @@ -/* [argparse.c wk 17.06.97] Argument Parser for option handling - * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc. +/* argparse.c - Argument Parser for option handling * Copyright (C) 1997-2001, 2006-2008, 2013-2017 Werner Koch + * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc. + * Copyright (C) 2015-2017 g10 Code GmbH * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute and/or modify this - * part of GnuPG under the terms of either - * - * - the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 3 of the License, or (at - * your option) any later version. - * - * or - * - * - the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * or both in parallel, as here. + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. * - * GnuPG is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copies of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, see . + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1+ */ /* This file may be used as part of GnuPG or standalone. A GnuPG diff --git a/common/argparse.h b/common/argparse.h index cdd18d9..4167d66 100644 --- a/common/argparse.h +++ b/common/argparse.h @@ -1,31 +1,23 @@ /* argparse.h - Argument parser for option handling. - * Copyright (C) 1998,1999,2000,2001,2006 Free Software Foundation, Inc. + * Copyright (C) 1997-2001, 2006-2008, 2013-2017 Werner Koch + * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc. + * Copyright (C) 2015-2017 g10 Code GmbH * * This file is part of GnuPG. * - * GnuPG is free software; you can redistribute and/or modify this - * part of GnuPG under the terms of either + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. * - * - the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 3 of the License, or (at - * your option) any later version. + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * or - * - * - the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * or both in parallel, as here. - * - * GnuPG is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copies of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, see . + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1+ */ #ifndef GNUPG_COMMON_ARGPARSE_H ----------------------------------------------------------------------- Summary of changes: common/argparse.c | 37 ++++++++++++++----------------------- common/argparse.h | 36 ++++++++++++++---------------------- 2 files changed, 28 insertions(+), 45 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 21 13:57:13 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 21 Mar 2018 13:57:13 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-99-gca8f18f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via ca8f18f401185af0e3a1e0a66ef08f4f49566e90 (commit) via c61df392935ef82e245debe3ce93a562fcafc249 (commit) from 130d9ab498d42934b2fad5a26946ed3e031a9982 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ca8f18f401185af0e3a1e0a66ef08f4f49566e90 Author: Andre Heinecke Date: Wed Mar 21 13:55:13 2018 +0100 Fix w64 build * src/ribbon-callbacks.cpp (launch_cert_details): Cast HWND w64 compatible. diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp index 67cb7cc..ee427e5 100644 --- a/src/ribbon-callbacks.cpp +++ b/src/ribbon-callbacks.cpp @@ -1740,7 +1740,7 @@ HRESULT launch_cert_details (LPDISPATCH ctrl) log_error ("%s:%s: No spawn engine.", SRCNAME, __func__); } - std::string parentWid = std::to_string ((unsigned int) get_active_hwnd ()); + std::string parentWid = std::to_string ((int) (intptr_t) get_active_hwnd ()); const char *argv[] = {path.c_str(), "--query", mail->get_sig_fpr(), commit c61df392935ef82e245debe3ce93a562fcafc249 Author: Andre Heinecke Date: Wed Mar 21 13:03:02 2018 +0100 Auto update translations * po/*: update. diff --git a/po/de.po b/po/de.po index d58fd75..5cbec20 100644 --- a/po/de.po +++ b/po/de.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL 1.0.0\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-07 10:01+0100\n" +"POT-Creation-Date: 2018-03-21 13:02+0100\n" "PO-Revision-Date: 2018-03-07 08:59+0100\n" "Last-Translator: Andre Heinecke \n" "Language-Team: English \n" @@ -77,7 +77,7 @@ msgstr "Die Benutzeroberfl?che zu ?ndern erfordert einen Neustart von Outlook" #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:303 +#: src/gpgoladdin.cpp:1338 src/mail.cpp:761 src/main.c:467 src/message.cpp:303 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -86,7 +86,7 @@ msgstr "Die Benutzeroberfl?che zu ?ndern erfordert einen Neustart von Outlook" #: src/ribbon-callbacks.cpp:736 src/ribbon-callbacks.cpp:796 #: src/ribbon-callbacks.cpp:1078 src/ribbon-callbacks.cpp:1112 #: src/ribbon-callbacks.cpp:1124 src/ribbon-callbacks.cpp:1149 -#: src/ribbon-callbacks.cpp:1712 src/ribbon-callbacks.cpp:1762 +#: src/ribbon-callbacks.cpp:1718 src/ribbon-callbacks.cpp:1773 #: src/wks-helper.cpp:442 msgid "GpgOL" msgstr "GpgOL" @@ -175,11 +175,11 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "M?chten Sie diesen Ordner von GpgOL befreien?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1685 src/mail.cpp:1756 msgid "GpgOL: Encrypted Message" msgstr "GpgOL: Verschl?sselte Nachricht" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1686 src/mail.cpp:1757 msgid "GpgOL: Trusted Sender Address" msgstr "GpgOL: Vertraute Absenderadresse" @@ -383,7 +383,7 @@ msgstr "" "Dies ist eine verschl?sselte Nachricht.\n" "Klicken Sie hier um weitere Informationen zu erhalten. " -#: src/mail.cpp:310 +#: src/mail.cpp:323 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" @@ -393,7 +393,7 @@ msgstr "" "Die unsignierten / unverschl?sselten Anh?nge sind:\n" "\n" -#: src/mail.cpp:315 +#: src/mail.cpp:328 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" @@ -403,7 +403,7 @@ msgstr "" "Die unsignierten Anh?nge sind:\n" "\n" -#: src/mail.cpp:320 +#: src/mail.cpp:333 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" @@ -413,7 +413,7 @@ msgstr "" "Die unverschl?sselten Anh?nge sind:\n" "\n" -#: src/mail.cpp:360 +#: src/mail.cpp:373 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." @@ -421,15 +421,15 @@ msgstr "" "Note: Die Anh?nge k?nnten auf Dateiebene verschl?sselt oder singiert sein, " "aber GpgOL kann deren Kryptostatus nicht anzeigen." -#: src/mail.cpp:363 +#: src/mail.cpp:376 msgid "GpgOL Warning" msgstr "GpgOL Warnung" -#: src/mail.cpp:811 +#: src/mail.cpp:843 msgid "Pubkey directory confirmation" msgstr "?schl Verzeichnis Best?tigung" -#: src/mail.cpp:812 +#: src/mail.cpp:844 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -443,19 +443,19 @@ msgstr "" "

Wenn sie dies nicht angefordert haben, k?nnen Sie diese Mail ignorieren.\n" -#: src/mail.cpp:820 src/mail.cpp:1967 +#: src/mail.cpp:852 src/mail.cpp:2000 msgid "Encrypted message" msgstr "Verschl?sselte Nachricht" -#: src/mail.cpp:821 +#: src/mail.cpp:853 msgid "Please wait while the message is being decrypted / verified..." msgstr "Bitte warten Sie w?hrend die Nachricht entschl?sselt / gepr?ft wird..." -#: src/mail.cpp:1097 +#: src/mail.cpp:1132 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "GpgOL: Oops, G Suite Sync Konto erkannt" -#: src/mail.cpp:1099 +#: src/mail.cpp:1134 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -468,93 +468,93 @@ msgstr "" "\n" "Details siehe: https://dev.gnupg.org/T3545" -#: src/mail.cpp:1912 +#: src/mail.cpp:1945 msgid "Security Level 4" msgstr "Sicherheit Stufe 4" -#: src/mail.cpp:1916 +#: src/mail.cpp:1949 msgid "Trust Level 4" msgstr "Vertrauen Stufe 4" -#: src/mail.cpp:1920 +#: src/mail.cpp:1953 msgid "Security Level 3" msgstr "Sicherheit Stufe 3" -#: src/mail.cpp:1924 +#: src/mail.cpp:1957 msgid "Trust Level 3" msgstr "Vertrauen Stufe 3" -#: src/mail.cpp:1928 +#: src/mail.cpp:1961 msgid "Security Level 2" msgstr "Sicherheit Stufe 2" -#: src/mail.cpp:1932 +#: src/mail.cpp:1965 msgid "Trust Level 2" msgstr "Vertrauen Stufe 2" -#: src/mail.cpp:1936 +#: src/mail.cpp:1969 msgid "Encrypted" msgstr "Verschl?sselt" -#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1978 src/mail.cpp:1980 src/ribbon-callbacks.cpp:1631 msgid "Insecure" msgstr "Unsicher" -#: src/mail.cpp:1959 +#: src/mail.cpp:1992 msgid "Signed and encrypted message" msgstr "Signierte und verschl?sselte Nachricht" -#: src/mail.cpp:1963 +#: src/mail.cpp:1996 msgid "Signed message" msgstr "Signierte Nachricht" -#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2003 src/ribbon-callbacks.cpp:1654 msgid "Insecure message" msgstr "Unsichere Nachricht" -#: src/mail.cpp:1981 src/mail.cpp:1992 +#: src/mail.cpp:2014 src/mail.cpp:2025 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" "Sie k?nnen nicht sicher sein wer die Nachricht gesendet, modifiziert oder " "w?hrend der ?bertragung gelesen hat." -#: src/mail.cpp:1984 +#: src/mail.cpp:2017 msgid "The message was signed but the verification failed with:" msgstr "Die Nachricht ist signiert aber die ?berpr?fung schlug fehl mit:" -#: src/mail.cpp:2002 +#: src/mail.cpp:2035 msgid "The encryption was VS-NfD-compliant." msgstr "Diese Verschl?sselung war VS-NfD-konform." -#: src/mail.cpp:2006 +#: src/mail.cpp:2039 msgid "The encryption was not VS-NfD-compliant." msgstr "Diese Verschl?sselung war nicht VS-NfD-konform." -#: src/mail.cpp:2010 +#: src/mail.cpp:2043 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" "Aber Sie k?nnen nicht sicher sein wer der Absender der Nachricht ist da " "diese nicht signiert wurde. " -#: src/mail.cpp:2033 +#: src/mail.cpp:2066 msgid "You signed this message." msgstr "Sie haben diese Nachricht signiert." -#: src/mail.cpp:2037 +#: src/mail.cpp:2070 msgid "The senders identity was certified by yourself." msgstr "Die Idenit?t des Absenders wurde von ihnen selbst beglaubigt." -#: src/mail.cpp:2041 +#: src/mail.cpp:2074 msgid "The sender is allowed to certify identities for you." msgstr "Der Absender ist berechtigt f?r Sie Identit?ten zu beglaubigen." -#: src/mail.cpp:2054 +#: src/mail.cpp:2087 msgid "The senders identity was certified by several trusted people." msgstr "" "Die Identit?t des Absenders wurde von mehreren vertrauensw?rdigen Personen " "beglaubigt." -#: src/mail.cpp:2059 +#: src/mail.cpp:2092 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" @@ -563,12 +563,12 @@ msgstr "" "Die Idenit?t des Absenders wurde best?tigt von:\n" "'%s'\n" -#: src/mail.cpp:2067 +#: src/mail.cpp:2100 msgid "Some trusted people have certified the senders identity." msgstr "" "Einige vertrauensw?rde Personen haben die Identit?t des Absenders beglaubigt." -#: src/mail.cpp:2077 +#: src/mail.cpp:2110 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -580,11 +580,11 @@ msgstr "" "Seit %s haben Sie %i Nachrichten an diesen Absender verschl?sselt und %i " "Signaturen gepr?ft." -#: src/mail.cpp:2093 +#: src/mail.cpp:2126 msgid "The senders signature was verified for the first time." msgstr "The Signatur des Absenders wurde das erste mal verifiziert." -#: src/mail.cpp:2100 +#: src/mail.cpp:2133 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " @@ -594,70 +594,70 @@ msgstr "" "Nachrichten von diesem absender verifziert und %i Nachrichten verschl?ssel " "haben. Seit dem %s." -#: src/mail.cpp:2114 +#: src/mail.cpp:2147 msgid "But the sender address is not trustworthy because:" msgstr "Aber die Absenderadresse ist nicht vertrauensw?rdig da:" -#: src/mail.cpp:2115 +#: src/mail.cpp:2148 msgid "The sender address is not trustworthy because:" msgstr "Die Absenderadresse ist nicht vertrauensw?rdig da:" -#: src/mail.cpp:2123 +#: src/mail.cpp:2156 msgid "The signature is invalid: \n" msgstr "Die Signatur ist ung?ltig: \n" -#: src/mail.cpp:2128 +#: src/mail.cpp:2161 msgid "There was an error verifying the signature.\n" msgstr "Beim ?berpr?fen der Signatur ist ein Fehler aufgetreten.\n" -#: src/mail.cpp:2132 +#: src/mail.cpp:2165 msgid "The signature is expired.\n" msgstr "Die Signatur ist abgelaufen.\n" -#: src/mail.cpp:2136 +#: src/mail.cpp:2169 msgid "The used key" msgstr "Der verwendete Schl?ssel" -#: src/mail.cpp:2136 +#: src/mail.cpp:2169 msgid "The used certificate" msgstr "Das verwendete Zertifikat" -#: src/mail.cpp:2144 +#: src/mail.cpp:2177 msgid "is not available." msgstr "ist nicht verf?gbar." -#: src/mail.cpp:2148 +#: src/mail.cpp:2181 msgid "is revoked." msgstr "wurde zur?ckgezogen." -#: src/mail.cpp:2152 +#: src/mail.cpp:2185 msgid "is expired." msgstr "ist veraltet. " -#: src/mail.cpp:2156 +#: src/mail.cpp:2189 msgid "is not meant for signing." msgstr "ist nicht zum signieren vorgesehen. " -#: src/mail.cpp:2160 src/mail.cpp:2164 +#: src/mail.cpp:2193 src/mail.cpp:2197 msgid "could not be checked for revocation." msgstr "wurde m?glicherweise zur?ckgezogen." -#: src/mail.cpp:2169 +#: src/mail.cpp:2202 msgid "is not the same as the key that was used for this address in the past." msgstr "" "ist nicht der gleiche Schl?ssel der in der vergangenheit f?r diese Adresse " "verwendet wurde." -#: src/mail.cpp:2175 +#: src/mail.cpp:2208 #, c-format msgid "does not claim the address: \"%s\"." msgstr "passt nicht zu der mailaddresse: \"%s\". " -#: src/mail.cpp:2188 +#: src/mail.cpp:2221 msgid "is not certified by any trustworthy key." msgstr "wurde von keinem vertrauensw?rdigen Schl?ssel beglaubigt." -#: src/mail.cpp:2192 +#: src/mail.cpp:2225 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." @@ -665,59 +665,59 @@ msgstr "" "wurde von keiner vertrauensw?rdigen Zertifizierungsstelle beglaubigt oder " "die Zertifizierungsstelle ist unbekannt." -#: src/mail.cpp:2197 +#: src/mail.cpp:2230 msgid "The sender marked this address as revoked." msgstr "Der Absender hat diese Adresse zur?ckgezogen." -#: src/mail.cpp:2201 +#: src/mail.cpp:2234 msgid "is marked as not trustworthy." msgstr "ist als nicht vertrauensw?rdig markiert." -#: src/mail.cpp:2211 +#: src/mail.cpp:2244 msgid "The signature is VS-NfD-compliant." msgstr "Die Signatur ist VS-NfD-konform." -#: src/mail.cpp:2215 +#: src/mail.cpp:2248 msgid "The signature is not VS-NfD-compliant." msgstr "Die Signatur ist nicht VS-NfD-konform." -#: src/mail.cpp:2223 +#: src/mail.cpp:2256 msgid "The encryption is VS-NfD-compliant." msgstr "Diese Verschl?sselung ist VS-NfD-konform." -#: src/mail.cpp:2227 +#: src/mail.cpp:2260 msgid "The encryption is not VS-NfD-compliant." msgstr "Diese Verschl?sselung ist nicht VS-NfD-konform." -#: src/mail.cpp:2238 +#: src/mail.cpp:2271 msgid "Click here to change the key used for this address." msgstr "Klicken Sie hier um den Schl?ssel f?r diese Adresse zu ?ndern." -#: src/mail.cpp:2242 +#: src/mail.cpp:2275 msgid "Click here for details about the key." msgstr "Klicken Sie hier f?r Details zu dem Schl?ssel" -#: src/mail.cpp:2243 +#: src/mail.cpp:2276 msgid "Click here for details about the certificate." msgstr "Klicken Sie hier f?r Details zu dem Zertifiakt." -#: src/mail.cpp:2247 +#: src/mail.cpp:2280 msgid "Click here to search the key on the configured keyserver." msgstr "" "Klicken Sie hier um den Schl?ssel auf dem konfigurierten Schl?sselserver zu " "suchen. " -#: src/mail.cpp:2248 +#: src/mail.cpp:2281 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" "Klicken Sie hier um das Zertifikat auf dem konfigurierten X509 " "Schl?sselserver zu suchen." -#: src/mail.cpp:2476 +#: src/mail.cpp:2509 msgid "GpgOL: Encryption not possible!" msgstr "GpgOL: Verschl?sselung nicht m?glich!" -#: src/mail.cpp:2478 +#: src/mail.cpp:2511 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -1036,11 +1036,11 @@ msgstr "Daten konnten nicht entschl?sselt werden: " msgid "Failed to parse the mail." msgstr "Konnte die Mail nicht verarbeiten." -#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:266 +#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:268 msgid "Encrypted message (decryption not possible)" msgstr "Verschl?sselte Nachricht (Entschl?sselung nicht m?glich)" -#: src/parsecontroller.cpp:267 +#: src/parsecontroller.cpp:269 msgid "" "Failed to find GnuPG please ensure that GnuPG or Gpg4win is properly " "installed." @@ -1084,11 +1084,11 @@ msgstr "Signierter Text" msgid "Select file to encrypt" msgstr "Ausw?hlen der zu verschl?sselnden Datei" -#: src/ribbon-callbacks.cpp:1652 +#: src/ribbon-callbacks.cpp:1658 msgid "No message selected" msgstr "Keine Nachricht ausgew?hlt" -#: src/ribbon-callbacks.cpp:1709 +#: src/ribbon-callbacks.cpp:1715 #, c-format msgid "" "The message was not cryptographically signed.\n" @@ -1099,7 +1099,7 @@ msgstr "" "Es gibt keine zus?tzliche Information dar?ber ob sie wirklich von '%s' " "gesendet wurde oder ob jemand die Absenderadresse vort?uscht." -#: src/ribbon-callbacks.cpp:1760 +#: src/ribbon-callbacks.cpp:1771 msgid "" "Could not find Kleopatra.\n" "Please reinstall Gpg4win with the Kleopatra component enabled." @@ -1147,40 +1147,40 @@ msgstr "" msgid "GpgOL: Registration request sent!" msgstr "GpgOL: Registrierungs-Anfrage gesendet." -#: src/wks-helper.cpp:687 +#: src/wks-helper.cpp:693 msgid "Confirm registration?" msgstr "Eintragung best?tigen?" -#: src/wks-helper.cpp:688 +#: src/wks-helper.cpp:694 msgid "GpgOL: Pubkey directory confirmation" msgstr "GpgOL: ?schl Verzeichnis Best?tigung" -#: src/wks-helper.cpp:741 +#: src/wks-helper.cpp:747 msgid "GpgOL: Confirmation failed" msgstr "GpgOL: Eintragung fehlgeschlagen" -#: src/wks-helper.cpp:753 +#: src/wks-helper.cpp:759 msgid "Your Pubkey can soon be retrieved from your domain." msgstr "" "Ihr ?ffentlicher Schl?ssel kann bald aus dem Verzeichnis abgerufen werden." -#: src/wks-helper.cpp:754 +#: src/wks-helper.cpp:760 msgid "GpgOL: Request confirmed!" msgstr "GpgOL: Eintragung best?tigt." -#: src/cryptcontroller.cpp:394 +#: src/cryptcontroller.cpp:393 msgid "Resolving recipients..." msgstr "Empf?nger aufl?sen..." -#: src/cryptcontroller.cpp:398 +#: src/cryptcontroller.cpp:397 msgid "Resolving signers..." msgstr "Signierer aufl?sen..." -#: src/cryptcontroller.cpp:994 +#: src/cryptcontroller.cpp:1004 msgid "Encrypting..." msgstr "Verschl?sseln..." -#: src/cryptcontroller.cpp:998 +#: src/cryptcontroller.cpp:1008 msgid "Signing..." msgstr "Signieren..." diff --git a/po/fr.po b/po/fr.po index f69b207..77ffe1c 100644 --- a/po/fr.po +++ b/po/fr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-07 10:01+0100\n" +"POT-Creation-Date: 2018-03-21 13:02+0100\n" "PO-Revision-Date: 2015-10-01 17:05+0200\n" "Last-Translator: Olivier Serve \n" "Language-Team: French \n" @@ -75,7 +75,7 @@ msgstr "" #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:303 +#: src/gpgoladdin.cpp:1338 src/mail.cpp:761 src/main.c:467 src/message.cpp:303 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -84,7 +84,7 @@ msgstr "" #: src/ribbon-callbacks.cpp:736 src/ribbon-callbacks.cpp:796 #: src/ribbon-callbacks.cpp:1078 src/ribbon-callbacks.cpp:1112 #: src/ribbon-callbacks.cpp:1124 src/ribbon-callbacks.cpp:1149 -#: src/ribbon-callbacks.cpp:1712 src/ribbon-callbacks.cpp:1762 +#: src/ribbon-callbacks.cpp:1718 src/ribbon-callbacks.cpp:1773 #: src/wks-helper.cpp:442 msgid "GpgOL" msgstr "GpgOL" @@ -172,12 +172,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "Voulez-vous r?cup?rer ce dossier ?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1685 src/mail.cpp:1756 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "D?chiffrer le message" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1686 src/mail.cpp:1757 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -378,42 +378,42 @@ msgstr "" "Ceci est un message chiffr?.\n" "Veuillez le s?lectionner pour plus d'informations." -#: src/mail.cpp:310 +#: src/mail.cpp:323 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:315 +#: src/mail.cpp:328 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:320 +#: src/mail.cpp:333 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:360 +#: src/mail.cpp:373 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." msgstr "" -#: src/mail.cpp:363 +#: src/mail.cpp:376 msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:811 +#: src/mail.cpp:843 msgid "Pubkey directory confirmation" msgstr "" -#: src/mail.cpp:812 +#: src/mail.cpp:844 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -422,20 +422,20 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:820 src/mail.cpp:1967 +#: src/mail.cpp:852 src/mail.cpp:2000 #, fuzzy msgid "Encrypted message" msgstr "D?chiffrer le message" -#: src/mail.cpp:821 +#: src/mail.cpp:853 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1097 +#: src/mail.cpp:1132 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1099 +#: src/mail.cpp:1134 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -443,105 +443,105 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1912 +#: src/mail.cpp:1945 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1916 +#: src/mail.cpp:1949 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1920 +#: src/mail.cpp:1953 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1924 +#: src/mail.cpp:1957 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1928 +#: src/mail.cpp:1961 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1932 +#: src/mail.cpp:1965 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1936 +#: src/mail.cpp:1969 #, fuzzy msgid "Encrypted" msgstr "Chiffrer" -#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1978 src/mail.cpp:1980 src/ribbon-callbacks.cpp:1631 msgid "Insecure" msgstr "" -#: src/mail.cpp:1959 +#: src/mail.cpp:1992 #, fuzzy msgid "Signed and encrypted message" msgstr "D?chiffrer le message" -#: src/mail.cpp:1963 +#: src/mail.cpp:1996 #, fuzzy msgid "Signed message" msgstr "D?chiffrer le message" -#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2003 src/ribbon-callbacks.cpp:1654 #, fuzzy msgid "Insecure message" msgstr "D?chiffrer le message" -#: src/mail.cpp:1981 src/mail.cpp:1992 +#: src/mail.cpp:2014 src/mail.cpp:2025 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:1984 +#: src/mail.cpp:2017 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2002 +#: src/mail.cpp:2035 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2006 +#: src/mail.cpp:2039 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2010 +#: src/mail.cpp:2043 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2033 +#: src/mail.cpp:2066 #, fuzzy msgid "You signed this message." msgstr "D?chiffrer le message" -#: src/mail.cpp:2037 +#: src/mail.cpp:2070 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2074 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2054 +#: src/mail.cpp:2087 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2059 +#: src/mail.cpp:2092 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2067 +#: src/mail.cpp:2100 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2077 +#: src/mail.cpp:2110 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -549,142 +549,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2126 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2100 +#: src/mail.cpp:2133 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2114 +#: src/mail.cpp:2147 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2115 +#: src/mail.cpp:2148 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2123 +#: src/mail.cpp:2156 #, fuzzy msgid "The signature is invalid: \n" msgstr "Cette signature est valide\n" -#: src/mail.cpp:2128 +#: src/mail.cpp:2161 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2165 #, fuzzy msgid "The signature is expired.\n" msgstr "Cette signature est valide\n" -#: src/mail.cpp:2136 +#: src/mail.cpp:2169 msgid "The used key" msgstr "" -#: src/mail.cpp:2136 +#: src/mail.cpp:2169 #, fuzzy msgid "The used certificate" msgstr "Erreur de v?rification" -#: src/mail.cpp:2144 +#: src/mail.cpp:2177 #, fuzzy msgid "is not available." msgstr "La liste de r?vocation (CRL) n'est pas disponible\n" -#: src/mail.cpp:2148 +#: src/mail.cpp:2181 msgid "is revoked." msgstr "" -#: src/mail.cpp:2152 +#: src/mail.cpp:2185 msgid "is expired." msgstr "" -#: src/mail.cpp:2156 +#: src/mail.cpp:2189 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2160 src/mail.cpp:2164 +#: src/mail.cpp:2193 src/mail.cpp:2197 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2169 +#: src/mail.cpp:2202 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2208 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2188 +#: src/mail.cpp:2221 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2192 +#: src/mail.cpp:2225 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2197 +#: src/mail.cpp:2230 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2201 +#: src/mail.cpp:2234 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2211 +#: src/mail.cpp:2244 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2215 +#: src/mail.cpp:2248 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2223 +#: src/mail.cpp:2256 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2227 +#: src/mail.cpp:2260 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2238 +#: src/mail.cpp:2271 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2242 +#: src/mail.cpp:2275 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2243 +#: src/mail.cpp:2276 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2247 +#: src/mail.cpp:2280 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2248 +#: src/mail.cpp:2281 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2476 +#: src/mail.cpp:2509 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "D?chiffrer le message" -#: src/mail.cpp:2478 +#: src/mail.cpp:2511 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -953,12 +953,12 @@ msgstr "" msgid "Failed to parse the mail." msgstr "" -#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:266 +#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:268 #, fuzzy msgid "Encrypted message (decryption not possible)" msgstr "Il n'est pas possible de chiffrer ou signer un message vide." -#: src/parsecontroller.cpp:267 +#: src/parsecontroller.cpp:269 msgid "" "Failed to find GnuPG please ensure that GnuPG or Gpg4win is properly " "installed." @@ -1000,12 +1000,12 @@ msgstr "Texte sign?" msgid "Select file to encrypt" msgstr "S?lectionner le fichier ? chiffrer" -#: src/ribbon-callbacks.cpp:1652 +#: src/ribbon-callbacks.cpp:1658 #, fuzzy msgid "No message selected" msgstr "Ce message n'est pas chiffr?" -#: src/ribbon-callbacks.cpp:1709 +#: src/ribbon-callbacks.cpp:1715 #, c-format msgid "" "The message was not cryptographically signed.\n" @@ -1013,7 +1013,7 @@ msgid "" "or if someone faked the sender address." msgstr "" -#: src/ribbon-callbacks.cpp:1760 +#: src/ribbon-callbacks.cpp:1771 msgid "" "Could not find Kleopatra.\n" "Please reinstall Gpg4win with the Kleopatra component enabled." @@ -1049,41 +1049,41 @@ msgstr "" msgid "GpgOL: Registration request sent!" msgstr "" -#: src/wks-helper.cpp:687 +#: src/wks-helper.cpp:693 msgid "Confirm registration?" msgstr "" -#: src/wks-helper.cpp:688 +#: src/wks-helper.cpp:694 msgid "GpgOL: Pubkey directory confirmation" msgstr "" -#: src/wks-helper.cpp:741 +#: src/wks-helper.cpp:747 msgid "GpgOL: Confirmation failed" msgstr "" -#: src/wks-helper.cpp:753 +#: src/wks-helper.cpp:759 msgid "Your Pubkey can soon be retrieved from your domain." msgstr "" -#: src/wks-helper.cpp:754 +#: src/wks-helper.cpp:760 msgid "GpgOL: Request confirmed!" msgstr "" -#: src/cryptcontroller.cpp:394 +#: src/cryptcontroller.cpp:393 #, fuzzy msgid "Resolving recipients..." msgstr "Destinataires s?lectionn?s?:" -#: src/cryptcontroller.cpp:398 +#: src/cryptcontroller.cpp:397 msgid "Resolving signers..." msgstr "" -#: src/cryptcontroller.cpp:994 +#: src/cryptcontroller.cpp:1004 #, fuzzy msgid "Encrypting..." msgstr "Chiffrement" -#: src/cryptcontroller.cpp:998 +#: src/cryptcontroller.cpp:1008 msgid "Signing..." msgstr "" diff --git a/po/pt.po b/po/pt.po index 712f14a..7b03a14 100644 --- a/po/pt.po +++ b/po/pt.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL 1.1.1\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-07 13:37+0100\n" +"POT-Creation-Date: 2018-03-21 13:02+0100\n" "PO-Revision-Date: 2018-03-09 11:00+0000\n" "Last-Translator: Marco A.G.Pinto \n" "Language-Team: Portuguese \n" @@ -78,7 +78,7 @@ msgstr "Mudar a interface necessita reiniciar o Outlook." #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/mail.cpp:745 src/main.c:467 src/message.cpp:303 +#: src/gpgoladdin.cpp:1338 src/mail.cpp:761 src/main.c:467 src/message.cpp:303 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -87,7 +87,7 @@ msgstr "Mudar a interface necessita reiniciar o Outlook." #: src/ribbon-callbacks.cpp:736 src/ribbon-callbacks.cpp:796 #: src/ribbon-callbacks.cpp:1078 src/ribbon-callbacks.cpp:1112 #: src/ribbon-callbacks.cpp:1124 src/ribbon-callbacks.cpp:1149 -#: src/ribbon-callbacks.cpp:1712 src/ribbon-callbacks.cpp:1762 +#: src/ribbon-callbacks.cpp:1718 src/ribbon-callbacks.cpp:1773 #: src/wks-helper.cpp:442 msgid "GpgOL" msgstr "GpgOL" @@ -175,11 +175,11 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "Queres reverter esta pasta?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1660 src/mail.cpp:1731 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1685 src/mail.cpp:1756 msgid "GpgOL: Encrypted Message" msgstr "GpgOL: Mensagem Encriptada" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1661 src/mail.cpp:1732 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1686 src/mail.cpp:1757 msgid "GpgOL: Trusted Sender Address" msgstr "GpgOL: Endere?o de Remetente Confi?vel" @@ -383,7 +383,7 @@ msgstr "" "Esta ? uma mensagem encriptada.\n" "Clica para mais informa??o. " -#: src/mail.cpp:310 +#: src/mail.cpp:323 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" @@ -393,7 +393,7 @@ msgstr "" "Os anexos n?o-assinados / n?o-encriptados s?o:\n" "\n" -#: src/mail.cpp:315 +#: src/mail.cpp:328 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" @@ -403,7 +403,7 @@ msgstr "" "Os anexos n?o-assinados s?o:\n" "\n" -#: src/mail.cpp:320 +#: src/mail.cpp:333 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" @@ -413,7 +413,7 @@ msgstr "" "Os anexos n?o-encriptados s?o:\n" "\n" -#: src/mail.cpp:360 +#: src/mail.cpp:373 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." @@ -421,15 +421,15 @@ msgstr "" "Nota: Os anexos podem ser encriptados ou assinados ao n?vel de ficheiro, mas " "o status do GpgOL n?o se aplica a eles." -#: src/mail.cpp:363 +#: src/mail.cpp:376 msgid "GpgOL Warning" msgstr "Aviso do GpgOL" -#: src/mail.cpp:819 +#: src/mail.cpp:843 msgid "Pubkey directory confirmation" msgstr "Confirma??o de diretoria Pubkey" -#: src/mail.cpp:820 +#: src/mail.cpp:844 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -443,21 +443,21 @@ msgstr "" "

Se n?o pediste para publicar a tua Pubkey na diretoria do teu provedor, " "simplesmente ignora esta mensagem.

\n" -#: src/mail.cpp:828 src/mail.cpp:1975 +#: src/mail.cpp:852 src/mail.cpp:2000 msgid "Encrypted message" msgstr "Mensagem encriptada" -#: src/mail.cpp:829 +#: src/mail.cpp:853 msgid "Please wait while the message is being decrypted / verified..." msgstr "" "Por favor, aguarda enquanto a mensagem est? a ser desencriptada / " "verificada..." -#: src/mail.cpp:1105 +#: src/mail.cpp:1132 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "GpgOL: Oops, conta G Suite Sync detetada" -#: src/mail.cpp:1107 +#: src/mail.cpp:1134 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -469,91 +469,91 @@ msgstr "" "\n" "V?: https://dev.gnupg.org/T3545 para detalhes." -#: src/mail.cpp:1920 +#: src/mail.cpp:1945 msgid "Security Level 4" msgstr "N?vel de seguran?a 4" -#: src/mail.cpp:1924 +#: src/mail.cpp:1949 msgid "Trust Level 4" msgstr "N?vel de Confian?a 4" -#: src/mail.cpp:1928 +#: src/mail.cpp:1953 msgid "Security Level 3" msgstr "N?vel de Seguran?a 3" -#: src/mail.cpp:1932 +#: src/mail.cpp:1957 msgid "Trust Level 3" msgstr "N?vel de Confian?a 3" -#: src/mail.cpp:1936 +#: src/mail.cpp:1961 msgid "Security Level 2" msgstr "N?vel de Seguran?a 2" -#: src/mail.cpp:1940 +#: src/mail.cpp:1965 msgid "Trust Level 2" msgstr "N?vel de Confian?a 2" -#: src/mail.cpp:1944 +#: src/mail.cpp:1969 msgid "Encrypted" msgstr "Encriptada" -#: src/mail.cpp:1953 src/mail.cpp:1955 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1978 src/mail.cpp:1980 src/ribbon-callbacks.cpp:1631 msgid "Insecure" msgstr "Insegura" -#: src/mail.cpp:1967 +#: src/mail.cpp:1992 msgid "Signed and encrypted message" msgstr "Mensagem assinada e encriptada" -#: src/mail.cpp:1971 +#: src/mail.cpp:1996 msgid "Signed message" msgstr "Mensagem assinada" -#: src/mail.cpp:1978 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2003 src/ribbon-callbacks.cpp:1654 msgid "Insecure message" msgstr "Mensagem insegura" -#: src/mail.cpp:1989 src/mail.cpp:2000 +#: src/mail.cpp:2014 src/mail.cpp:2025 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" "N?o podes ter a certeza de quem enviou, modificou e leu a mensagem em " "tr?nsito." -#: src/mail.cpp:1992 +#: src/mail.cpp:2017 msgid "The message was signed but the verification failed with:" msgstr "A mensagem foi assinada, mas a verifica??o falhou com:" -#: src/mail.cpp:2010 +#: src/mail.cpp:2035 msgid "The encryption was VS-NfD-compliant." msgstr "A encripta??o est? em conformidade com VS-NfD." -#: src/mail.cpp:2014 +#: src/mail.cpp:2039 msgid "The encryption was not VS-NfD-compliant." msgstr "A encripta??o n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2018 +#: src/mail.cpp:2043 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" "N?o podes ter certeza de quem enviou a mensagem, porque n?o est? assinada." -#: src/mail.cpp:2041 +#: src/mail.cpp:2066 msgid "You signed this message." msgstr "Assinaste esta mensagem." -#: src/mail.cpp:2045 +#: src/mail.cpp:2070 msgid "The senders identity was certified by yourself." msgstr "A identidade dos remetentes foi certificada por ti pr?prio." -#: src/mail.cpp:2049 +#: src/mail.cpp:2074 msgid "The sender is allowed to certify identities for you." msgstr "O remetente pode certificar identidades para ti." -#: src/mail.cpp:2062 +#: src/mail.cpp:2087 msgid "The senders identity was certified by several trusted people." msgstr "" "A identidade dos remetentes foi certificada por v?rias pessoas confi?veis." -#: src/mail.cpp:2067 +#: src/mail.cpp:2092 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" @@ -562,11 +562,11 @@ msgstr "" "A identidade dos remetentes ? certificada pelo emissor confi?vel:\n" "'%s'\n" -#: src/mail.cpp:2075 +#: src/mail.cpp:2100 msgid "Some trusted people have certified the senders identity." msgstr "Algumas pessoas confi?veis certificaram a identidade dos remetentes." -#: src/mail.cpp:2085 +#: src/mail.cpp:2110 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -577,11 +577,11 @@ msgstr "" "comunica??o com este endere?o desde %s.\n" "Encriptaste %i e verificaste %i mensagens desde ent?o." -#: src/mail.cpp:2101 +#: src/mail.cpp:2126 msgid "The senders signature was verified for the first time." msgstr "A assinatura dos remetentes foi verificada pela primeira vez." -#: src/mail.cpp:2108 +#: src/mail.cpp:2133 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " @@ -590,68 +590,68 @@ msgstr "" "O endere?o dos remetentes ainda n?o ? confi?vel porque apenas verificaste %i " "mensagens e encriptaste %i mensagens a eles desde %s." -#: src/mail.cpp:2122 +#: src/mail.cpp:2147 msgid "But the sender address is not trustworthy because:" msgstr "Mas o endere?o do remetente n?o ? confi?vel porque:" -#: src/mail.cpp:2123 +#: src/mail.cpp:2148 msgid "The sender address is not trustworthy because:" msgstr "O endere?o do remetente n?o ? confi?vel porque:" -#: src/mail.cpp:2131 +#: src/mail.cpp:2156 msgid "The signature is invalid: \n" msgstr "A assinatura ? inv?lida: \n" -#: src/mail.cpp:2136 +#: src/mail.cpp:2161 msgid "There was an error verifying the signature.\n" msgstr "Houve um erro ao verificar a assinatura.\n" -#: src/mail.cpp:2140 +#: src/mail.cpp:2165 msgid "The signature is expired.\n" msgstr "A assinatura expirou.\n" -#: src/mail.cpp:2144 +#: src/mail.cpp:2169 msgid "The used key" msgstr "A chave usada" -#: src/mail.cpp:2144 +#: src/mail.cpp:2169 msgid "The used certificate" msgstr "O certificado usado" -#: src/mail.cpp:2152 +#: src/mail.cpp:2177 msgid "is not available." msgstr "n?o est? dispon?vel." -#: src/mail.cpp:2156 +#: src/mail.cpp:2181 msgid "is revoked." msgstr "est? revogado." -#: src/mail.cpp:2160 +#: src/mail.cpp:2185 msgid "is expired." msgstr "expirou." -#: src/mail.cpp:2164 +#: src/mail.cpp:2189 msgid "is not meant for signing." msgstr "n?o ? destinado a assinar." -#: src/mail.cpp:2168 src/mail.cpp:2172 +#: src/mail.cpp:2193 src/mail.cpp:2197 msgid "could not be checked for revocation." msgstr "n?o pode ser verificado para revoga??o." -#: src/mail.cpp:2177 +#: src/mail.cpp:2202 msgid "is not the same as the key that was used for this address in the past." msgstr "n?o ? o mesmo que a chave usada para este endere?o no passado." -#: src/mail.cpp:2183 +#: src/mail.cpp:2208 #, c-format msgid "does not claim the address: \"%s\"." msgstr "n?o reivindica o endere?o: \"%s\"." -#: src/mail.cpp:2196 +#: src/mail.cpp:2221 msgid "is not certified by any trustworthy key." msgstr "n?o est? certificado por qualquer chave confi?vel." -#: src/mail.cpp:2200 +#: src/mail.cpp:2225 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." @@ -659,57 +659,57 @@ msgstr "" "n?o est? certificado por uma Autoridade de Certifica??o confi?vel ou a " "Autoridade de Certifica??o ? desconhecida." -#: src/mail.cpp:2205 +#: src/mail.cpp:2230 msgid "The sender marked this address as revoked." msgstr "O remetente marcou este endere?o como revogado." -#: src/mail.cpp:2209 +#: src/mail.cpp:2234 msgid "is marked as not trustworthy." msgstr "est? marcado como n?o confi?vel." -#: src/mail.cpp:2219 +#: src/mail.cpp:2244 msgid "The signature is VS-NfD-compliant." msgstr "A assinatura est? em conformidade com VS-NfD." -#: src/mail.cpp:2223 +#: src/mail.cpp:2248 msgid "The signature is not VS-NfD-compliant." msgstr "A assinatura n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2231 +#: src/mail.cpp:2256 msgid "The encryption is VS-NfD-compliant." msgstr "A encripta??o est? em conformidade com VS-NfD." -#: src/mail.cpp:2235 +#: src/mail.cpp:2260 msgid "The encryption is not VS-NfD-compliant." msgstr "A encripta??o n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2246 +#: src/mail.cpp:2271 msgid "Click here to change the key used for this address." msgstr "Clica aqui para alterar a chave usada para este endere?o." -#: src/mail.cpp:2250 +#: src/mail.cpp:2275 msgid "Click here for details about the key." msgstr "Clica aqui para obter detalhes sobre a chave." -#: src/mail.cpp:2251 +#: src/mail.cpp:2276 msgid "Click here for details about the certificate." msgstr "Clica aqui para obter detalhes sobre o certificado." -#: src/mail.cpp:2255 +#: src/mail.cpp:2280 msgid "Click here to search the key on the configured keyserver." msgstr "Clica aqui para localizar a chave no servidor de chaves configurado." -#: src/mail.cpp:2256 +#: src/mail.cpp:2281 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" "Clica aqui para localizar o certificado no servidor de chaves X509 " "configurado." -#: src/mail.cpp:2484 +#: src/mail.cpp:2509 msgid "GpgOL: Encryption not possible!" msgstr "GpgOL: Encripta??o n?o poss?vel!" -#: src/mail.cpp:2486 +#: src/mail.cpp:2511 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -1017,11 +1017,11 @@ msgstr "N?o foi poss?vel desencriptar os dados: " msgid "Failed to parse the mail." msgstr "Falha ao analisar o e-mail." -#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:266 +#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:268 msgid "Encrypted message (decryption not possible)" msgstr "Mensagem encriptada (desencripta??o n?o poss?vel)" -#: src/parsecontroller.cpp:267 +#: src/parsecontroller.cpp:269 msgid "" "Failed to find GnuPG please ensure that GnuPG or Gpg4win is properly " "installed." @@ -1065,11 +1065,11 @@ msgstr "Texto assinado" msgid "Select file to encrypt" msgstr "Seleciona o ficheiro a encriptar" -#: src/ribbon-callbacks.cpp:1652 +#: src/ribbon-callbacks.cpp:1658 msgid "No message selected" msgstr "Nenhuma mensagem selecionada" -#: src/ribbon-callbacks.cpp:1709 +#: src/ribbon-callbacks.cpp:1715 #, c-format msgid "" "The message was not cryptographically signed.\n" @@ -1080,7 +1080,7 @@ msgstr "" "N?o h? nenhuma informa??o adicional dispon?vel se ela realmente foi enviada " "por '%s' ou se algu?m falsificou o endere?o do remetente." -#: src/ribbon-callbacks.cpp:1760 +#: src/ribbon-callbacks.cpp:1771 msgid "" "Could not find Kleopatra.\n" "Please reinstall Gpg4win with the Kleopatra component enabled." @@ -1128,23 +1128,23 @@ msgstr "" msgid "GpgOL: Registration request sent!" msgstr "GpgOL: Pedido de registo enviado!" -#: src/wks-helper.cpp:687 +#: src/wks-helper.cpp:693 msgid "Confirm registration?" msgstr "Confirmar o registo?" -#: src/wks-helper.cpp:688 +#: src/wks-helper.cpp:694 msgid "GpgOL: Pubkey directory confirmation" msgstr "GpgOL: Confirma??o da diretoria de Pubkey" -#: src/wks-helper.cpp:741 +#: src/wks-helper.cpp:747 msgid "GpgOL: Confirmation failed" msgstr "GpgOL: Confirma??o falhou" -#: src/wks-helper.cpp:753 +#: src/wks-helper.cpp:759 msgid "Your Pubkey can soon be retrieved from your domain." msgstr "A tua Pubkey pode ser brevemente recuperada do teu dom?nio." -#: src/wks-helper.cpp:754 +#: src/wks-helper.cpp:760 msgid "GpgOL: Request confirmed!" msgstr "GpgOL: Pedido confirmado!" @@ -1156,11 +1156,11 @@ msgstr "A resolver destinat?rios..." msgid "Resolving signers..." msgstr "A resolver assinantes..." -#: src/cryptcontroller.cpp:1007 +#: src/cryptcontroller.cpp:1004 msgid "Encrypting..." msgstr "A encriptar..." -#: src/cryptcontroller.cpp:1011 +#: src/cryptcontroller.cpp:1008 msgid "Signing..." msgstr "A assinar..." diff --git a/po/sv.po b/po/sv.po index 28f8ce9..9ba884a 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GPGol\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-07 10:01+0100\n" +"POT-Creation-Date: 2018-03-21 13:02+0100\n" "PO-Revision-Date: 2006-12-12 23:52+0100\n" "Last-Translator: Daniel Nylander \n" "Language-Team: Swedish \n" @@ -75,7 +75,7 @@ msgstr "" #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:303 +#: src/gpgoladdin.cpp:1338 src/mail.cpp:761 src/main.c:467 src/message.cpp:303 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -84,7 +84,7 @@ msgstr "" #: src/ribbon-callbacks.cpp:736 src/ribbon-callbacks.cpp:796 #: src/ribbon-callbacks.cpp:1078 src/ribbon-callbacks.cpp:1112 #: src/ribbon-callbacks.cpp:1124 src/ribbon-callbacks.cpp:1149 -#: src/ribbon-callbacks.cpp:1712 src/ribbon-callbacks.cpp:1762 +#: src/ribbon-callbacks.cpp:1718 src/ribbon-callbacks.cpp:1773 #: src/wks-helper.cpp:442 msgid "GpgOL" msgstr "" @@ -164,12 +164,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1685 src/mail.cpp:1756 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "Dekryptera och validera meddelandet." -#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1686 src/mail.cpp:1757 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -367,42 +367,42 @@ msgid "" "Click for more information. " msgstr "" -#: src/mail.cpp:310 +#: src/mail.cpp:323 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:315 +#: src/mail.cpp:328 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:320 +#: src/mail.cpp:333 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:360 +#: src/mail.cpp:373 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." msgstr "" -#: src/mail.cpp:363 +#: src/mail.cpp:376 msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:811 +#: src/mail.cpp:843 msgid "Pubkey directory confirmation" msgstr "" -#: src/mail.cpp:812 +#: src/mail.cpp:844 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -411,20 +411,20 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:820 src/mail.cpp:1967 +#: src/mail.cpp:852 src/mail.cpp:2000 #, fuzzy msgid "Encrypted message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:821 +#: src/mail.cpp:853 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1097 +#: src/mail.cpp:1132 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1099 +#: src/mail.cpp:1134 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -432,105 +432,105 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1912 +#: src/mail.cpp:1945 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1916 +#: src/mail.cpp:1949 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1920 +#: src/mail.cpp:1953 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1924 +#: src/mail.cpp:1957 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1928 +#: src/mail.cpp:1961 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1932 +#: src/mail.cpp:1965 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1936 +#: src/mail.cpp:1969 #, fuzzy msgid "Encrypted" msgstr "Kryptering" -#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1978 src/mail.cpp:1980 src/ribbon-callbacks.cpp:1631 msgid "Insecure" msgstr "" -#: src/mail.cpp:1959 +#: src/mail.cpp:1992 #, fuzzy msgid "Signed and encrypted message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:1963 +#: src/mail.cpp:1996 #, fuzzy msgid "Signed message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2003 src/ribbon-callbacks.cpp:1654 #, fuzzy msgid "Insecure message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:1981 src/mail.cpp:1992 +#: src/mail.cpp:2014 src/mail.cpp:2025 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:1984 +#: src/mail.cpp:2017 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2002 +#: src/mail.cpp:2035 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2006 +#: src/mail.cpp:2039 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2010 +#: src/mail.cpp:2043 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2033 +#: src/mail.cpp:2066 #, fuzzy msgid "You signed this message." msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2037 +#: src/mail.cpp:2070 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2074 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2054 +#: src/mail.cpp:2087 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2059 +#: src/mail.cpp:2092 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2067 +#: src/mail.cpp:2100 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2077 +#: src/mail.cpp:2110 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -538,142 +538,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2126 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2100 +#: src/mail.cpp:2133 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2114 +#: src/mail.cpp:2147 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2115 +#: src/mail.cpp:2148 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2123 +#: src/mail.cpp:2156 #, fuzzy msgid "The signature is invalid: \n" msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2128 +#: src/mail.cpp:2161 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2165 #, fuzzy msgid "The signature is expired.\n" msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2136 +#: src/mail.cpp:2169 msgid "The used key" msgstr "" -#: src/mail.cpp:2136 +#: src/mail.cpp:2169 #, fuzzy msgid "The used certificate" msgstr "Validering" -#: src/mail.cpp:2144 +#: src/mail.cpp:2177 #, fuzzy msgid "is not available." msgstr "Sp?rrlistan ?r inte tillg?nglig\n" -#: src/mail.cpp:2148 +#: src/mail.cpp:2181 msgid "is revoked." msgstr "" -#: src/mail.cpp:2152 +#: src/mail.cpp:2185 msgid "is expired." msgstr "" -#: src/mail.cpp:2156 +#: src/mail.cpp:2189 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2160 src/mail.cpp:2164 +#: src/mail.cpp:2193 src/mail.cpp:2197 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2169 +#: src/mail.cpp:2202 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2208 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2188 +#: src/mail.cpp:2221 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2192 +#: src/mail.cpp:2225 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2197 +#: src/mail.cpp:2230 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2201 +#: src/mail.cpp:2234 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2211 +#: src/mail.cpp:2244 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2215 +#: src/mail.cpp:2248 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2223 +#: src/mail.cpp:2256 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2227 +#: src/mail.cpp:2260 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2238 +#: src/mail.cpp:2271 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2242 +#: src/mail.cpp:2275 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2243 +#: src/mail.cpp:2276 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2247 +#: src/mail.cpp:2280 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2248 +#: src/mail.cpp:2281 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2476 +#: src/mail.cpp:2509 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2478 +#: src/mail.cpp:2511 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -909,11 +909,11 @@ msgstr "" msgid "Failed to parse the mail." msgstr "" -#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:266 +#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:268 msgid "Encrypted message (decryption not possible)" msgstr "" -#: src/parsecontroller.cpp:267 +#: src/parsecontroller.cpp:269 msgid "" "Failed to find GnuPG please ensure that GnuPG or Gpg4win is properly " "installed." @@ -960,11 +960,11 @@ msgstr "" msgid "Select file to encrypt" msgstr "V?lj ?tminstone en mottagarnyckel." -#: src/ribbon-callbacks.cpp:1652 +#: src/ribbon-callbacks.cpp:1658 msgid "No message selected" msgstr "" -#: src/ribbon-callbacks.cpp:1709 +#: src/ribbon-callbacks.cpp:1715 #, c-format msgid "" "The message was not cryptographically signed.\n" @@ -972,7 +972,7 @@ msgid "" "or if someone faked the sender address." msgstr "" -#: src/ribbon-callbacks.cpp:1760 +#: src/ribbon-callbacks.cpp:1771 msgid "" "Could not find Kleopatra.\n" "Please reinstall Gpg4win with the Kleopatra component enabled." @@ -1008,40 +1008,40 @@ msgstr "" msgid "GpgOL: Registration request sent!" msgstr "" -#: src/wks-helper.cpp:687 +#: src/wks-helper.cpp:693 msgid "Confirm registration?" msgstr "" -#: src/wks-helper.cpp:688 +#: src/wks-helper.cpp:694 msgid "GpgOL: Pubkey directory confirmation" msgstr "" -#: src/wks-helper.cpp:741 +#: src/wks-helper.cpp:747 msgid "GpgOL: Confirmation failed" msgstr "" -#: src/wks-helper.cpp:753 +#: src/wks-helper.cpp:759 msgid "Your Pubkey can soon be retrieved from your domain." msgstr "" -#: src/wks-helper.cpp:754 +#: src/wks-helper.cpp:760 msgid "GpgOL: Request confirmed!" msgstr "" -#: src/cryptcontroller.cpp:394 +#: src/cryptcontroller.cpp:393 msgid "Resolving recipients..." msgstr "" -#: src/cryptcontroller.cpp:398 +#: src/cryptcontroller.cpp:397 msgid "Resolving signers..." msgstr "" -#: src/cryptcontroller.cpp:994 +#: src/cryptcontroller.cpp:1004 #, fuzzy msgid "Encrypting..." msgstr "Kryptering" -#: src/cryptcontroller.cpp:998 +#: src/cryptcontroller.cpp:1008 msgid "Signing..." msgstr "" diff --git a/po/zh_CN.po b/po/zh_CN.po index c47d904..dba6840 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-07 10:01+0100\n" +"POT-Creation-Date: 2018-03-21 13:02+0100\n" "PO-Revision-Date: 2015-08-15 21:58+0800\n" "Last-Translator: Mingye Wang (Arthur2e5) \n" "Language-Team: \n" @@ -76,7 +76,7 @@ msgstr "" #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:303 +#: src/gpgoladdin.cpp:1338 src/mail.cpp:761 src/main.c:467 src/message.cpp:303 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -85,7 +85,7 @@ msgstr "" #: src/ribbon-callbacks.cpp:736 src/ribbon-callbacks.cpp:796 #: src/ribbon-callbacks.cpp:1078 src/ribbon-callbacks.cpp:1112 #: src/ribbon-callbacks.cpp:1124 src/ribbon-callbacks.cpp:1149 -#: src/ribbon-callbacks.cpp:1712 src/ribbon-callbacks.cpp:1762 +#: src/ribbon-callbacks.cpp:1718 src/ribbon-callbacks.cpp:1773 #: src/wks-helper.cpp:442 msgid "GpgOL" msgstr "GpgOL" @@ -168,12 +168,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "????????????" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1685 src/mail.cpp:1756 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "????" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1686 src/mail.cpp:1757 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -366,42 +366,42 @@ msgstr "" "???????\n" "???????????" -#: src/mail.cpp:310 +#: src/mail.cpp:323 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:315 +#: src/mail.cpp:328 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:320 +#: src/mail.cpp:333 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:360 +#: src/mail.cpp:373 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." msgstr "" -#: src/mail.cpp:363 +#: src/mail.cpp:376 msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:811 +#: src/mail.cpp:843 msgid "Pubkey directory confirmation" msgstr "" -#: src/mail.cpp:812 +#: src/mail.cpp:844 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -410,20 +410,20 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:820 src/mail.cpp:1967 +#: src/mail.cpp:852 src/mail.cpp:2000 #, fuzzy msgid "Encrypted message" msgstr "????" -#: src/mail.cpp:821 +#: src/mail.cpp:853 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1097 +#: src/mail.cpp:1132 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1099 +#: src/mail.cpp:1134 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -431,105 +431,105 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1912 +#: src/mail.cpp:1945 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1916 +#: src/mail.cpp:1949 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1920 +#: src/mail.cpp:1953 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1924 +#: src/mail.cpp:1957 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1928 +#: src/mail.cpp:1961 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1932 +#: src/mail.cpp:1965 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1936 +#: src/mail.cpp:1969 #, fuzzy msgid "Encrypted" msgstr "??" -#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1978 src/mail.cpp:1980 src/ribbon-callbacks.cpp:1631 msgid "Insecure" msgstr "" -#: src/mail.cpp:1959 +#: src/mail.cpp:1992 #, fuzzy msgid "Signed and encrypted message" msgstr "????" -#: src/mail.cpp:1963 +#: src/mail.cpp:1996 #, fuzzy msgid "Signed message" msgstr "????" -#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2003 src/ribbon-callbacks.cpp:1654 #, fuzzy msgid "Insecure message" msgstr "????" -#: src/mail.cpp:1981 src/mail.cpp:1992 +#: src/mail.cpp:2014 src/mail.cpp:2025 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:1984 +#: src/mail.cpp:2017 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2002 +#: src/mail.cpp:2035 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2006 +#: src/mail.cpp:2039 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2010 +#: src/mail.cpp:2043 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2033 +#: src/mail.cpp:2066 #, fuzzy msgid "You signed this message." msgstr "????" -#: src/mail.cpp:2037 +#: src/mail.cpp:2070 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2074 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2054 +#: src/mail.cpp:2087 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2059 +#: src/mail.cpp:2092 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2067 +#: src/mail.cpp:2100 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2077 +#: src/mail.cpp:2110 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -537,142 +537,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2126 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2100 +#: src/mail.cpp:2133 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2114 +#: src/mail.cpp:2147 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2115 +#: src/mail.cpp:2148 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2123 +#: src/mail.cpp:2156 #, fuzzy msgid "The signature is invalid: \n" msgstr "????\n" -#: src/mail.cpp:2128 +#: src/mail.cpp:2161 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2165 #, fuzzy msgid "The signature is expired.\n" msgstr "????\n" -#: src/mail.cpp:2136 +#: src/mail.cpp:2169 msgid "The used key" msgstr "" -#: src/mail.cpp:2136 +#: src/mail.cpp:2169 #, fuzzy msgid "The used certificate" msgstr "????" -#: src/mail.cpp:2144 +#: src/mail.cpp:2177 #, fuzzy msgid "is not available." msgstr "???????CRL????\n" -#: src/mail.cpp:2148 +#: src/mail.cpp:2181 msgid "is revoked." msgstr "" -#: src/mail.cpp:2152 +#: src/mail.cpp:2185 msgid "is expired." msgstr "" -#: src/mail.cpp:2156 +#: src/mail.cpp:2189 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2160 src/mail.cpp:2164 +#: src/mail.cpp:2193 src/mail.cpp:2197 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2169 +#: src/mail.cpp:2202 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2208 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2188 +#: src/mail.cpp:2221 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2192 +#: src/mail.cpp:2225 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2197 +#: src/mail.cpp:2230 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2201 +#: src/mail.cpp:2234 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2211 +#: src/mail.cpp:2244 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2215 +#: src/mail.cpp:2248 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2223 +#: src/mail.cpp:2256 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2227 +#: src/mail.cpp:2260 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2238 +#: src/mail.cpp:2271 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2242 +#: src/mail.cpp:2275 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2243 +#: src/mail.cpp:2276 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2247 +#: src/mail.cpp:2280 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2248 +#: src/mail.cpp:2281 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2476 +#: src/mail.cpp:2509 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "????" -#: src/mail.cpp:2478 +#: src/mail.cpp:2511 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -938,12 +938,12 @@ msgstr "" msgid "Failed to parse the mail." msgstr "" -#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:266 +#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:268 #, fuzzy msgid "Encrypted message (decryption not possible)" msgstr "???????????" -#: src/parsecontroller.cpp:267 +#: src/parsecontroller.cpp:269 msgid "" "Failed to find GnuPG please ensure that GnuPG or Gpg4win is properly " "installed." @@ -985,12 +985,12 @@ msgstr "??????" msgid "Select file to encrypt" msgstr "????????" -#: src/ribbon-callbacks.cpp:1652 +#: src/ribbon-callbacks.cpp:1658 #, fuzzy msgid "No message selected" msgstr "????????" -#: src/ribbon-callbacks.cpp:1709 +#: src/ribbon-callbacks.cpp:1715 #, c-format msgid "" "The message was not cryptographically signed.\n" @@ -998,7 +998,7 @@ msgid "" "or if someone faked the sender address." msgstr "" -#: src/ribbon-callbacks.cpp:1760 +#: src/ribbon-callbacks.cpp:1771 msgid "" "Could not find Kleopatra.\n" "Please reinstall Gpg4win with the Kleopatra component enabled." @@ -1034,41 +1034,41 @@ msgstr "" msgid "GpgOL: Registration request sent!" msgstr "" -#: src/wks-helper.cpp:687 +#: src/wks-helper.cpp:693 msgid "Confirm registration?" msgstr "" -#: src/wks-helper.cpp:688 +#: src/wks-helper.cpp:694 msgid "GpgOL: Pubkey directory confirmation" msgstr "" -#: src/wks-helper.cpp:741 +#: src/wks-helper.cpp:747 msgid "GpgOL: Confirmation failed" msgstr "" -#: src/wks-helper.cpp:753 +#: src/wks-helper.cpp:759 msgid "Your Pubkey can soon be retrieved from your domain." msgstr "" -#: src/wks-helper.cpp:754 +#: src/wks-helper.cpp:760 msgid "GpgOL: Request confirmed!" msgstr "" -#: src/cryptcontroller.cpp:394 +#: src/cryptcontroller.cpp:393 #, fuzzy msgid "Resolving recipients..." msgstr "??????" -#: src/cryptcontroller.cpp:398 +#: src/cryptcontroller.cpp:397 msgid "Resolving signers..." msgstr "" -#: src/cryptcontroller.cpp:994 +#: src/cryptcontroller.cpp:1004 #, fuzzy msgid "Encrypting..." msgstr "??" -#: src/cryptcontroller.cpp:998 +#: src/cryptcontroller.cpp:1008 msgid "Signing..." msgstr "" diff --git a/po/zh_TW.po b/po/zh_TW.po index f3e9ff5..465e359 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2018-03-07 10:01+0100\n" +"POT-Creation-Date: 2018-03-21 13:02+0100\n" "PO-Revision-Date: 2015-08-15 21:58+0800\n" "Last-Translator: Mingye Wang (Arthur2e5) \n" "Language-Team: \n" @@ -76,7 +76,7 @@ msgstr "" #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:303 +#: src/gpgoladdin.cpp:1338 src/mail.cpp:761 src/main.c:467 src/message.cpp:303 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -85,7 +85,7 @@ msgstr "" #: src/ribbon-callbacks.cpp:736 src/ribbon-callbacks.cpp:796 #: src/ribbon-callbacks.cpp:1078 src/ribbon-callbacks.cpp:1112 #: src/ribbon-callbacks.cpp:1124 src/ribbon-callbacks.cpp:1149 -#: src/ribbon-callbacks.cpp:1712 src/ribbon-callbacks.cpp:1762 +#: src/ribbon-callbacks.cpp:1718 src/ribbon-callbacks.cpp:1773 #: src/wks-helper.cpp:442 msgid "GpgOL" msgstr "GpgOL" @@ -168,12 +168,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "????????????" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1652 src/mail.cpp:1723 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1685 src/mail.cpp:1756 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "????" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1653 src/mail.cpp:1724 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1686 src/mail.cpp:1757 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -366,42 +366,42 @@ msgstr "" "???????\n" "???????????" -#: src/mail.cpp:310 +#: src/mail.cpp:323 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:315 +#: src/mail.cpp:328 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:320 +#: src/mail.cpp:333 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:360 +#: src/mail.cpp:373 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." msgstr "" -#: src/mail.cpp:363 +#: src/mail.cpp:376 msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:811 +#: src/mail.cpp:843 msgid "Pubkey directory confirmation" msgstr "" -#: src/mail.cpp:812 +#: src/mail.cpp:844 msgid "" "This is a confirmation request to publish your Pubkey in the directory for " "your domain.\n" @@ -410,20 +410,20 @@ msgid "" "directory, simply ignore this message.

\n" msgstr "" -#: src/mail.cpp:820 src/mail.cpp:1967 +#: src/mail.cpp:852 src/mail.cpp:2000 #, fuzzy msgid "Encrypted message" msgstr "????" -#: src/mail.cpp:821 +#: src/mail.cpp:853 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1097 +#: src/mail.cpp:1132 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1099 +#: src/mail.cpp:1134 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -431,105 +431,105 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1912 +#: src/mail.cpp:1945 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1916 +#: src/mail.cpp:1949 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1920 +#: src/mail.cpp:1953 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1924 +#: src/mail.cpp:1957 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1928 +#: src/mail.cpp:1961 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1932 +#: src/mail.cpp:1965 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1936 +#: src/mail.cpp:1969 #, fuzzy msgid "Encrypted" msgstr "??" -#: src/mail.cpp:1945 src/mail.cpp:1947 src/ribbon-callbacks.cpp:1625 +#: src/mail.cpp:1978 src/mail.cpp:1980 src/ribbon-callbacks.cpp:1631 msgid "Insecure" msgstr "" -#: src/mail.cpp:1959 +#: src/mail.cpp:1992 #, fuzzy msgid "Signed and encrypted message" msgstr "????" -#: src/mail.cpp:1963 +#: src/mail.cpp:1996 #, fuzzy msgid "Signed message" msgstr "????" -#: src/mail.cpp:1970 src/ribbon-callbacks.cpp:1648 +#: src/mail.cpp:2003 src/ribbon-callbacks.cpp:1654 #, fuzzy msgid "Insecure message" msgstr "????" -#: src/mail.cpp:1981 src/mail.cpp:1992 +#: src/mail.cpp:2014 src/mail.cpp:2025 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:1984 +#: src/mail.cpp:2017 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:2002 +#: src/mail.cpp:2035 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2006 +#: src/mail.cpp:2039 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2010 +#: src/mail.cpp:2043 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2033 +#: src/mail.cpp:2066 #, fuzzy msgid "You signed this message." msgstr "????" -#: src/mail.cpp:2037 +#: src/mail.cpp:2070 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2074 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2054 +#: src/mail.cpp:2087 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2059 +#: src/mail.cpp:2092 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2067 +#: src/mail.cpp:2100 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2077 +#: src/mail.cpp:2110 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -537,142 +537,142 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2093 +#: src/mail.cpp:2126 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2100 +#: src/mail.cpp:2133 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2114 +#: src/mail.cpp:2147 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2115 +#: src/mail.cpp:2148 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2123 +#: src/mail.cpp:2156 #, fuzzy msgid "The signature is invalid: \n" msgstr "????\n" -#: src/mail.cpp:2128 +#: src/mail.cpp:2161 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2132 +#: src/mail.cpp:2165 #, fuzzy msgid "The signature is expired.\n" msgstr "????\n" -#: src/mail.cpp:2136 +#: src/mail.cpp:2169 msgid "The used key" msgstr "" -#: src/mail.cpp:2136 +#: src/mail.cpp:2169 #, fuzzy msgid "The used certificate" msgstr "????" -#: src/mail.cpp:2144 +#: src/mail.cpp:2177 #, fuzzy msgid "is not available." msgstr "???????CRL????\n" -#: src/mail.cpp:2148 +#: src/mail.cpp:2181 msgid "is revoked." msgstr "" -#: src/mail.cpp:2152 +#: src/mail.cpp:2185 msgid "is expired." msgstr "" -#: src/mail.cpp:2156 +#: src/mail.cpp:2189 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2160 src/mail.cpp:2164 +#: src/mail.cpp:2193 src/mail.cpp:2197 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2169 +#: src/mail.cpp:2202 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2208 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2188 +#: src/mail.cpp:2221 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2192 +#: src/mail.cpp:2225 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2197 +#: src/mail.cpp:2230 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2201 +#: src/mail.cpp:2234 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2211 +#: src/mail.cpp:2244 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2215 +#: src/mail.cpp:2248 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2223 +#: src/mail.cpp:2256 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2227 +#: src/mail.cpp:2260 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2238 +#: src/mail.cpp:2271 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2242 +#: src/mail.cpp:2275 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2243 +#: src/mail.cpp:2276 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2247 +#: src/mail.cpp:2280 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2248 +#: src/mail.cpp:2281 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" -#: src/mail.cpp:2476 +#: src/mail.cpp:2509 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "????" -#: src/mail.cpp:2478 +#: src/mail.cpp:2511 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -940,12 +940,12 @@ msgstr "" msgid "Failed to parse the mail." msgstr "" -#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:266 +#: src/parsecontroller.cpp:211 src/parsecontroller.cpp:268 #, fuzzy msgid "Encrypted message (decryption not possible)" msgstr "???????????" -#: src/parsecontroller.cpp:267 +#: src/parsecontroller.cpp:269 msgid "" "Failed to find GnuPG please ensure that GnuPG or Gpg4win is properly " "installed." @@ -987,12 +987,12 @@ msgstr "??????" msgid "Select file to encrypt" msgstr "????????" -#: src/ribbon-callbacks.cpp:1652 +#: src/ribbon-callbacks.cpp:1658 #, fuzzy msgid "No message selected" msgstr "????????" -#: src/ribbon-callbacks.cpp:1709 +#: src/ribbon-callbacks.cpp:1715 #, c-format msgid "" "The message was not cryptographically signed.\n" @@ -1000,7 +1000,7 @@ msgid "" "or if someone faked the sender address." msgstr "" -#: src/ribbon-callbacks.cpp:1760 +#: src/ribbon-callbacks.cpp:1771 msgid "" "Could not find Kleopatra.\n" "Please reinstall Gpg4win with the Kleopatra component enabled." @@ -1036,41 +1036,41 @@ msgstr "" msgid "GpgOL: Registration request sent!" msgstr "" -#: src/wks-helper.cpp:687 +#: src/wks-helper.cpp:693 msgid "Confirm registration?" msgstr "" -#: src/wks-helper.cpp:688 +#: src/wks-helper.cpp:694 msgid "GpgOL: Pubkey directory confirmation" msgstr "" -#: src/wks-helper.cpp:741 +#: src/wks-helper.cpp:747 msgid "GpgOL: Confirmation failed" msgstr "" -#: src/wks-helper.cpp:753 +#: src/wks-helper.cpp:759 msgid "Your Pubkey can soon be retrieved from your domain." msgstr "" -#: src/wks-helper.cpp:754 +#: src/wks-helper.cpp:760 msgid "GpgOL: Request confirmed!" msgstr "" -#: src/cryptcontroller.cpp:394 +#: src/cryptcontroller.cpp:393 #, fuzzy msgid "Resolving recipients..." msgstr "??????" -#: src/cryptcontroller.cpp:398 +#: src/cryptcontroller.cpp:397 msgid "Resolving signers..." msgstr "" -#: src/cryptcontroller.cpp:994 +#: src/cryptcontroller.cpp:1004 #, fuzzy msgid "Encrypting..." msgstr "??" -#: src/cryptcontroller.cpp:998 +#: src/cryptcontroller.cpp:1008 msgid "Signing..." msgstr "" ----------------------------------------------------------------------- Summary of changes: po/de.po | 168 +++++++++++++++++++++++------------------------ po/fr.po | 168 +++++++++++++++++++++++------------------------ po/pt.po | 164 ++++++++++++++++++++++----------------------- po/sv.po | 168 +++++++++++++++++++++++------------------------ po/zh_CN.po | 168 +++++++++++++++++++++++------------------------ po/zh_TW.po | 168 +++++++++++++++++++++++------------------------ src/ribbon-callbacks.cpp | 2 +- 7 files changed, 503 insertions(+), 503 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 21 15:20:08 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 21 Mar 2018 15:20:08 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-125-g1fdd1f3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 1fdd1f306d45f6aeee91c7f016f7c37286ee3b3b (commit) via 1d2746433c9632fc0c7bc10b59280fca15895545 (commit) from 0390ede18696520be9cc1a42f628e23159b7c2eb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1fdd1f306d45f6aeee91c7f016f7c37286ee3b3b Author: Ben McGinnes Date: Thu Mar 22 01:18:37 2018 +1100 example: clear signing * Added example to clear sign a file with signing key selection. diff --git a/lang/python/examples/howto/clear-sign-file.py b/lang/python/examples/howto/clear-sign-file.py new file mode 100755 index 0000000..597bbc5 --- /dev/null +++ b/lang/python/examples/howto/clear-sign-file.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys + +""" +Clear-signs a file with a specified key. If entering both the key and the +filename on the command line, the key must be entered first. +""" + +if len(sys.argv) > 3: + logrus = sys.argv[1] + filename = " ".join(sys.argv[2:]) +elif len(sys.argv) == 3: + logrus = sys.argv[1] + filename = sys.argv[2] +elif len(sys.argv) == 2: + logrus = sys.argv[1] + filename = input("Enter the path and filename to sign: ") +else: + logrus = input("Enter the fingerprint or key ID to sign with: ") + filename = input("Enter the path and filename to sign: ") + +with open(filename, "rb") as f: + text = f.read() + +key = list(gpg.Context().keylist(pattern=logrus)) + +with gpg.Context(armor=True, signers=key) as c: + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) + with open("{0}.asc".format(filename), "wb") as f: + f.write(signed_data) commit 1d2746433c9632fc0c7bc10b59280fca15895545 Author: Ben McGinnes Date: Thu Mar 22 01:12:36 2018 +1100 doc: python bindings howto * deconstructed and fixed all three signing methods. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 2a200bb..0c15149 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -750,11 +750,10 @@ text = text0.encode() c = gpg.Context(armor=True, signers=sig_src) - signed = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) with open("/path/to/statement.txt.asc", "w") as afile: - for line in signed[0]: - afile.write("{0}\n".format(line.decode())) + afile.write(signed_data.decode()) #+end_src Though everything in this example is accurate, it is more likely @@ -769,10 +768,10 @@ text = tfile.read() c = gpg.Context() - signed = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) with open("/path/to/statement.txt.sig", "wb") as afile: - afile.write(signed[0]) + afile.write(signed_data) #+end_src @@ -795,11 +794,10 @@ text = text0.encode() c = gpg.Context(armor=True) - signed = c.sign(text, mode=gpg.constants.sig.mode.DETACH) + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) with open("/path/to/statement.txt.asc", "w") as afile: - for line in signed[0].splitlines(): - afile.write("{0}\n".format(line.decode())) + afile.write(signed_data.decode()) #+end_src As with normal signatures, detached signatures are best handled as @@ -812,10 +810,10 @@ text = tfile.read() c = gpg.Context(signers=sig_src) - signed = c.sign(text, mode=gpg.constants.sig.mode.DETACH) + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) with open("/path/to/statement.txt.sig", "wb") as afile: - afile.write(signed[0]) + afile.write(signed_data) #+end_src @@ -838,11 +836,10 @@ text = text0.encode() c = gpg.Context() - signed = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) with open("/path/to/statement.txt.asc", "w") as afile: - for line in signed[0].splitlines(): - afile.write("{0}\n".format(line.decode())) + afile.write(signed_data.decode()) #+end_src In spite of the appearance of a clear-signed message, the data @@ -855,10 +852,10 @@ text = tfile.read() c = gpg.Context() - signed = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) with open("/path/to/statement.txt.asc", "wb") as afile: - afile.write(signed[0]) + afile.write(signed_data) #+end_src ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 27 ++++++++++------------ .../howto/{sign-file.py => clear-sign-file.py} | 19 +++++---------- 2 files changed, 18 insertions(+), 28 deletions(-) copy lang/python/examples/howto/{sign-file.py => clear-sign-file.py} (72%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 21 15:32:16 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 21 Mar 2018 15:32:16 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-128-gac6a552 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via ac6a552c37147a000de74f49d1bff34dad52252e (commit) via af6cbba18ba5e2bbecce5f8268c146282cd12367 (commit) via 6fa2a344282e369e6aca8155bc77dd2c12a29414 (commit) from 1fdd1f306d45f6aeee91c7f016f7c37286ee3b3b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ac6a552c37147a000de74f49d1bff34dad52252e Author: Ben McGinnes Date: Thu Mar 22 01:30:32 2018 +1100 example: detach sign file * Added example to make detached signatures of a file with key selection. diff --git a/lang/python/examples/howto/detach-sign-file.py b/lang/python/examples/howto/detach-sign-file.py new file mode 100755 index 0000000..99fbe65 --- /dev/null +++ b/lang/python/examples/howto/detach-sign-file.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys + +""" +Signs a file with a specified key. If entering both the key and the filename +on the command line, the key must be entered first. + +Will produce both an ASCII armoured and GPG binary format copy of the detached +signature file. +""" + +if len(sys.argv) > 3: + logrus = sys.argv[1] + filename = " ".join(sys.argv[2:]) +elif len(sys.argv) == 3: + logrus = sys.argv[1] + filename = sys.argv[2] +elif len(sys.argv) == 2: + logrus = sys.argv[1] + filename = input("Enter the path and filename to sign: ") +else: + logrus = input("Enter the fingerprint or key ID to sign with: ") + filename = input("Enter the path and filename to sign: ") + +with open(filename, "rb") as f: + text = f.read() + +key = list(gpg.Context().keylist(pattern=logrus)) + +with gpg.Context(armor=True, signers=key) as ca: + signed_data, result = ca.sign(text, mode=gpg.constants.sig.mode.DETACH) + with open("{0}.asc".format(filename), "wb") as fa: + fa.write(signed_data) + +with gpg.Context(signers=key) as cb: + signed_data, result = cb.sign(text, mode=gpg.constants.sig.mode.DETACH) + with open("{0}.sig".format(filename), "wb") as fb: + fb.write(signed_data) commit af6cbba18ba5e2bbecce5f8268c146282cd12367 Author: Ben McGinnes Date: Thu Mar 22 01:26:43 2018 +1100 example: encrypt-sign-file.py * Adjusted the doc string. diff --git a/lang/python/examples/howto/encrypt-sign-file.py b/lang/python/examples/howto/encrypt-sign-file.py index c8850b2..4b29b27 100755 --- a/lang/python/examples/howto/encrypt-sign-file.py +++ b/lang/python/examples/howto/encrypt-sign-file.py @@ -34,8 +34,8 @@ filename on the command line, the key must be entered first. Signs with and also encrypts to the default key of the user invoking the script. Will treat all recipients as trusted to permit encryption. -Will produce both an ASCII armoured and GPG binary format copy of the encrypted -file. +Will produce both an ASCII armoured and GPG binary format copy of the signed +and encrypted file. """ if len(sys.argv) > 3: commit 6fa2a344282e369e6aca8155bc77dd2c12a29414 Author: Ben McGinnes Date: Thu Mar 22 01:24:52 2018 +1100 examples: doc strings * Fixed minor errors in two doc strings. diff --git a/lang/python/examples/howto/encrypt-file.py b/lang/python/examples/howto/encrypt-file.py index 017a342..877226d 100755 --- a/lang/python/examples/howto/encrypt-file.py +++ b/lang/python/examples/howto/encrypt-file.py @@ -31,7 +31,8 @@ import sys Encrypts a file to a specified key. If entering both the key and the filename on the command line, the key must be entered first. -Will produce both an ASCII armoured and GPG binary format copy of the encrypted file. +Will produce both an ASCII armoured and GPG binary format copy of the encrypted +file. """ if len(sys.argv) > 3: diff --git a/lang/python/examples/howto/sign-file.py b/lang/python/examples/howto/sign-file.py index 8e2cdc2..01006df 100755 --- a/lang/python/examples/howto/sign-file.py +++ b/lang/python/examples/howto/sign-file.py @@ -31,7 +31,8 @@ import sys Signs a file with a specified key. If entering both the key and the filename on the command line, the key must be entered first. -Will produce both an ASCII armoured and GPG binary format copy of the encrypted file. +Will produce both an ASCII armoured and GPG binary format copy of the signed +file. """ if len(sys.argv) > 3: ----------------------------------------------------------------------- Summary of changes: .../examples/howto/{sign-file.py => detach-sign-file.py} | 13 +++++++------ lang/python/examples/howto/encrypt-file.py | 3 ++- lang/python/examples/howto/encrypt-sign-file.py | 4 ++-- lang/python/examples/howto/sign-file.py | 3 ++- 4 files changed, 13 insertions(+), 10 deletions(-) copy lang/python/examples/howto/{sign-file.py => detach-sign-file.py} (89%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 21 19:32:46 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 21 Mar 2018 19:32:46 +0100 Subject: [git] GPGME - branch, json-tool, updated. gpgme-1.10.0-60-ge14f1f6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, json-tool has been updated via e14f1f687ff618716ed17e309a0475df95e1c0aa (commit) from 6073789a6d3514263404c93fa795a398bfd93d91 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e14f1f687ff618716ed17e309a0475df95e1c0aa Author: Werner Koch Date: Wed Mar 21 19:26:03 2018 +0100 json: Use gpgrt_argparse instead of argsparse.c * src/gpgme-json.c: Remove header argparse.h. Define GPGRT_ENABLE_ARGPARSE_MACROS. (interactive_repl): Replace strusage by gpgrt_strusage. (my_strusage): Add SPDX level. (main): Switch to gpgrt_argparse stuff but keep very limited functionality when building with an older libgpg-error. Signed-off-by: Werner Koch diff --git a/src/Makefile.am b/src/Makefile.am index b5941fc..c2d4a84 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -102,10 +102,10 @@ AM_CFLAGS = @LIBASSUAN_CFLAGS@ @GLIB_CFLAGS@ gpgme_tool_SOURCES = gpgme-tool.c argparse.c argparse.h gpgme_tool_LDADD = libgpgme.la @LIBASSUAN_LIBS@ -gpgme_json_SOURCES = gpgme-json.c argparse.c argparse.h cJSON.c cJSON.h +gpgme_json_SOURCES = gpgme-json.c cJSON.c cJSON.h gpgme_json_LDADD = -lm libgpgme.la $(GPG_ERROR_LIBS) -## We use -no-install temporary during development. -#gpgme_json_LDFLAGS = -no-install +# We use -no-install temporary during development. +gpgme_json_LDFLAGS = -no-install if HAVE_W32_SYSTEM diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 00d8110..75f1a09 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -36,8 +36,8 @@ #define GPGRT_ENABLE_ES_MACROS 1 #define GPGRT_ENABLE_LOG_MACROS 1 +#define GPGRT_ENABLE_ARGPARSE_MACROS 1 #include "gpgme.h" -#include "argparse.h" #include "cJSON.h" @@ -828,8 +828,10 @@ interactive_repl (void) int first; es_setvbuf (es_stdin, NULL, _IONBF, 0); +#if GPGRT_VERSION_NUMBER >= 0x011d00 /* 1.29 */ es_fprintf (es_stderr, "%s %s ready (enter \",help\" for help)\n", - strusage (11), strusage (13)); + gpgrt_strusage (11), gpgrt_strusage (13)); +#endif do { es_fputs ("> ", es_stderr); @@ -1064,6 +1066,7 @@ my_strusage( int level ) switch (level) { + case 9: p = "LGPL-2.1-or-later"; break; case 11: p = "gpgme-json"; break; case 13: p = PACKAGE_VERSION; break; case 14: p = "Copyright (C) 2018 g10 Code GmbH"; break; @@ -1083,24 +1086,30 @@ my_strusage( int level ) return p; } - int main (int argc, char *argv[]) { +#if GPGRT_VERSION_NUMBER < 0x011d00 /* 1.29 */ + + fprintf (stderr, "WARNING: Old libgpg-error - using limited mode\n"); + native_messaging_repl (); + +#else /* This is a modern libgp-error. */ + enum { CMD_DEFAULT = 0, CMD_INTERACTIVE = 'i', CMD_SINGLE = 's', CMD_LIBVERSION = 501 } cmd = CMD_DEFAULT; - static ARGPARSE_OPTS opts[] = { + static gpgrt_opt_t opts[] = { ARGPARSE_c (CMD_INTERACTIVE, "interactive", "Interactive REPL"), ARGPARSE_c (CMD_SINGLE, "single", "Single request mode"), ARGPARSE_c (CMD_LIBVERSION, "lib-version", "Show library version"), ARGPARSE_end() }; - ARGPARSE_ARGS pargs = { &argc, &argv, 0 }; + gpgrt_argparse_t pargs = { &argc, &argv}; - set_strusage (my_strusage); + gpgrt_set_strusage (my_strusage); #ifdef HAVE_SETLOCALE setlocale (LC_ALL, ""); @@ -1113,7 +1122,7 @@ main (int argc, char *argv[]) gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); #endif - while (arg_parse (&pargs, opts)) + while (gpgrt_argparse (NULL, &pargs, opts)) { switch (pargs.r_opt) { @@ -1130,6 +1139,7 @@ main (int argc, char *argv[]) break; } } + gpgrt_argparse (NULL, &pargs, NULL); switch (cmd) { @@ -1153,5 +1163,6 @@ main (int argc, char *argv[]) break; } +#endif /* This is a modern libgp-error. */ return 0; } ----------------------------------------------------------------------- Summary of changes: src/Makefile.am | 6 +++--- src/gpgme-json.c | 25 ++++++++++++++++++------- 2 files changed, 21 insertions(+), 10 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 21 19:54:21 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 21 Mar 2018 19:54:21 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-19-g34ec012 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 34ec0125614674725cb78cf9f8d5e6b0f8c64064 (commit) via 983f7b2acbd1e7580652bbeb0c3d64f9dd19d9e4 (commit) from 11bbd99477ef5ba5b7db0c17607b10af03c68afb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 34ec0125614674725cb78cf9f8d5e6b0f8c64064 Author: Werner Koch Date: Wed Mar 21 19:45:31 2018 +0100 doc: Typo fix in comment. -- diff --git a/g10/parse-packet.c b/g10/parse-packet.c index db4e3ab..a64d4f7 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -964,10 +964,10 @@ skip_packet (IOBUF inp, int pkttype, unsigned long pktlen, int partial) } -/* Read PKTLEN bytes form INP and return them in a newly allocated - buffer. In case of an error (including reading fewer than PKTLEN - bytes from INP before EOF is returned), NULL is returned and an - error message is logged. */ +/* Read PKTLEN bytes from INP and return them in a newly allocated + * buffer. In case of an error (including reading fewer than PKTLEN + * bytes from INP before EOF is returned), NULL is returned and an + * error message is logged. */ static void * read_rest (IOBUF inp, size_t pktlen) { commit 983f7b2acbd1e7580652bbeb0c3d64f9dd19d9e4 Author: Werner Koch Date: Thu Mar 15 08:44:52 2018 +0100 gpg: Fix out-of-bound read in subpacket enumeration * g10/parse-packet.c (enum_sig_subpkt): Check buflen before reading the type octet. Print diagnostic. -- If the final subpacket has only a length header evaluating to zero and missing the type octet, a read could happen right behind the buffer. Valgrind detected this. Fix is obvious. Note that the further parsing of the subpacket is still okay because it always checks the length. Note further that --list-packets uses a different code path and already reported an error. Reported-by: Philippe Antoine He provided a test file copied below. Running "gpg -v --verify" on it triggered the bug. -----BEGIN PGP ARMORED FILE----- Comment: Use "gpg --dearmor" for unpacking kA0DAAoBov87N383R0QBrQJhYgZsb2wucHlaqTVWYnl0ZXMgPSBbMHg1LCAweDY0 LCAweDRjLCAweGM0LCAweDMsIDB4MCwgMHg0LCAweDAsIDB4YWMsIDB4YSwgMHhj MSwgMHhjMSwgMHgyLCAweDEsIDB4MiwgMHg3LCAweDQwLCAweDIsIDB4MiwgMHgy LCAweDIsIDB4MiwgMHgyLCAweDIsIDB4MiwgMHgyLCAweDJkLCAweGRkLCAweDIs IDB4MiwgMHgyLCAweDIsIDB4MiwgMHgyLCAweDIsIDB4MiwgMHgyLCAweDIsIDB4 MiwgMHgyLCAweDIsIDB4MiwgMHgyLCAweDIsIDB4NzcsIDB4ODcsIDB4MiwgMHgy LCAweDIsIDB4MiwgMHgyLCAweDIsIDB4MiwgMHgyLCAweDIsIDB4MiwgMHgyLCAw eDIsIDB4MiwgMHgyLCAweDIsIDB4MiwgMHg3NywgMHg4NywgMHgyLCAweDIsIDB4 MiwgMHgyLCAweDIsIDB4MiwgMHgyLCAweDIsIDB4MiwgMHgyLCAweDIsIDB4Miwg MHgyLCAweDIsIDB4MiwgMHgyLCAweDc3LCAweDg3LCAweDIsIDB4MiwgMHgyLCAw eDIsIDB4MiwgMHgyLCAweDIsIDB4MCwgMHhhZF0KCmZvciBpIGluIHJhbmdlKGxl bihieXRlcykpOgogICAgaWYgaSUxNiA9PSAwOgogICAgICAgIHByaW50CiAgICAg ICAgcHJpbnQgIiUwNngiICUgaSwKICAgIHByaW50ICIlMDJ4ICIgJSBieXRlc1tp XSwKiQJNBAABCgAeFiEEU+Y3aLjDLA3x+9Epov87N383R0QFAlqpNVYAAAoJEKL/ Ozd/N0dElccP/jBAcFHyeMl7kop71Q7/5NPu3DNULmdUzOZPle8PVjNURT4PSELF qpJ8bd9PAsO4ZkUGwssY4Kfb1iG5cR/a8ADknNd0Cj9/QA2KMVNmgYtReuttAjvn hQRm2VY0tvDCVAPI/z8OnV/NpOcbk8kSwE+shLsP7EwqL5MJNMXKqzm1uRxGNYxr 8TNuECo3DO64O2NZLkMDXqq6lg+lSxvDtXKxzKXgVC+GMtOE56lDwxWLqr39f9Ae Pn0q2fVBKhJfpUODeEbYSYUp2hhmMUIJL/ths9MvyRZ9Z/bHCseFPT58Pgx6g+MP q+iHnVZEIVb38XG+rTYW9hvctkRZP/azhpa7eO8JAZuFNeBGr4IGapwzFPvQSF4B wBXBu0+PPrV9VJVe98P4nw2xcuJmkn6mgZhRVYSqDIhY64bSTgQxb/pdtGwrTjtL WoUKVI+joLRPnDmwexH9+QJCB+uA6RsN/LqsQfDseyr40Z6dHJRqWGgP3ll6iZgw WF768uiIDJD8d4fegVnkpcH98Hm0I/dKsMR1MGV/sBxYC8mAOcOWwSPNGDqPlwwR eWPdr1O6CoYEWwiZMicSe0b5TsjB5nkAWMy7c9RyhtMJzCQ/hFpycpj0A0Zs+OGa eJQMZZV0s8AQZ04JzoX0zRpe0RcTyJn3Tr6QGbVi9tr+QdKHFuDMUqoX =qYZP -----END PGP ARMORED FILE----- Signed-off-by: Werner Koch diff --git a/g10/parse-packet.c b/g10/parse-packet.c index eee14f6..db4e3ab 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1702,6 +1702,8 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype, } if (buflen < n) goto too_short; + if (!buflen) + goto no_type_byte; type = *buffer; if (type & 0x80) { @@ -1776,6 +1778,13 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype, if (start) *start = -1; return NULL; + + no_type_byte: + if (opt.verbose) + log_info ("type octet missing in subpacket\n"); + if (start) + *start = -1; + return NULL; } ----------------------------------------------------------------------- Summary of changes: g10/parse-packet.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 21 19:56:36 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 21 Mar 2018 19:56:36 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-137-gc6a0395 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via c6a0395f0a3a57071f0c943f7815f58a02f9d2f3 (commit) via 0a0d57fd41380cd797d29e11cec8a77c7404e960 (commit) via 0ccc57c9512246d82d46e7732bfb0f95c18ca9d3 (commit) via 8b401bfc76eac762553f76faab53c2f4cd117a8d (commit) via 6c6af9a7b0ae4e7182d669bec282c6edaaa7eaa1 (commit) via a4e3f827652c59d850b4e5506a92c1ecd190c1bb (commit) via ad6cb4f9b8b97a2bc501c17fc542a84b725dedea (commit) via ae2767eb27b6a76284ee4403e575869afe2e80a8 (commit) via e57388a69f61d14e3df3c842d227fb450c96c807 (commit) from ac6a552c37147a000de74f49d1bff34dad52252e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c6a0395f0a3a57071f0c943f7815f58a02f9d2f3 Author: Ben McGinnes Date: Thu Mar 22 05:55:53 2018 +1100 example: key selection * Removed extraneous blank line. diff --git a/lang/python/examples/howto/key-selection.py b/lang/python/examples/howto/key-selection.py index 8c2d7b5..a007219 100755 --- a/lang/python/examples/howto/key-selection.py +++ b/lang/python/examples/howto/key-selection.py @@ -49,4 +49,3 @@ keys = [] for i in range(len(key_ids)): logrus = key_ids[i] keys.append(gpg.Context().keylist(pattern=logrus)) - commit 0a0d57fd41380cd797d29e11cec8a77c7404e960 Author: Ben McGinnes Date: Thu Mar 22 05:52:55 2018 +1100 example: key selection * Similar to group-key-selection.py, but does not use an existing group from gpg.conf; instead takes multiple key IDs, fingerprints or patterns on the command line and adds them to a keylist object. diff --git a/lang/python/examples/howto/key-selection.py b/lang/python/examples/howto/key-selection.py new file mode 100755 index 0000000..8c2d7b5 --- /dev/null +++ b/lang/python/examples/howto/key-selection.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys + +""" +Uses key IDs, fingerprints or other patterns as space separated input and +creates a keylist object for use by the gpg module. + +Similar to the group-key-selection.py script, but does not require an existing +group in the gpg.conf file. +""" + +if len(sys.argv) < 2: + key_ids_str = sys.argv[1:] +elif len(sys.argv) == 2: + key_ids_str = sys.argv[1] +elif len(sys.argv) == 1: + key_ids_str = input("Enter the keys to select by key ID or fingerprint: ") +else: + key_ids_str = input("Enter the keys to select by key ID or fingerprint: ") + +key_ids = key_ids_str.split() +keys = [] +for i in range(len(key_ids)): + logrus = key_ids[i] + keys.append(gpg.Context().keylist(pattern=logrus)) + commit 0ccc57c9512246d82d46e7732bfb0f95c18ca9d3 Author: Ben McGinnes Date: Thu Mar 22 05:40:02 2018 +1100 example: sign and encrypt to group * Begins to string together some of the simpler examples to do more useful things. * Signs and encrypts a file while encrypting to every key in a group specified in the gpg.conf file. diff --git a/lang/python/examples/howto/group-encrypt-sign-file.py b/lang/python/examples/howto/group-encrypt-sign-file.py new file mode 100755 index 0000000..920e50d --- /dev/null +++ b/lang/python/examples/howto/group-encrypt-sign-file.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys + +from groups import group_lists + +""" +Signs and encrypts a file to a specified group of keys. If entering both the +group and the filename on the command line, the group must be entered first. + +Signs with and also encrypts to the default key of the user invoking the +script. Will treat all recipients as trusted to permit encryption. + +Will produce both an ASCII armoured and GPG binary format copy of the signed +and encrypted file. +""" + +if len(sys.argv) > 3: + group = sys.argv[1] + filename = " ".join(sys.argv[2:]) +elif len(sys.argv) == 3: + group = sys.argv[1] + filename = sys.argv[2] +elif len(sys.argv) == 2: + group = sys.argv[1] + filename = input("Enter the path and filename to encrypt: ") +else: + group = input("Enter the name of the group to select keys for: ") + filename = input("Enter the path and filename to encrypt: ") + +keys = [] +a = [] + +for i in range(len(group_lists)): + a.append(group_lists[i][0]) + +b = a.index(group) + +for i in range(len(group_lists[b][1])): + logrus = group_lists[b][1][i] + keys.append(gpg.Context().keylist(pattern=logrus)) + +with open(filename, "rb") as f: + text = f.read() + +with gpg.Context(armor=True) as ca: + ciphertext, result, sign_result = ca.encrypt(text, recipients=keys, + always_trust=True, + add_encrypt_to=True) + with open("{0}.asc".format(filename), "wb") as fa: + fa.write(ciphertext) + +with gpg.Context() as cg: + ciphertext, result, sign_result = cg.encrypt(text, recipients=keys, + always_trust=True, + add_encrypt_to=True) + with open("{0}.gpg".format(filename), "wb") as fg: + fg.write(ciphertext) commit 8b401bfc76eac762553f76faab53c2f4cd117a8d Author: Ben McGinnes Date: Thu Mar 22 05:20:51 2018 +1100 example: group key selection * Example of preparing a keylist object using an existing group line from the gpg.conf file. diff --git a/lang/python/examples/howto/group-key-selection.py b/lang/python/examples/howto/group-key-selection.py new file mode 100755 index 0000000..2e3d2eb --- /dev/null +++ b/lang/python/examples/howto/group-key-selection.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys + +from groups import group_lists + +""" +Takes an existing group specified as a command line parameter and converts it +to a list object 'keys' as expected by the gpg module. + +Requires the groups module in this directory. +""" + +if len(sys.argv) == 2: + group = sys.argv[1] +elif len(sys.argv) == 1: + group = input("Enter the name of the group to select keys for: ") +else: + group = input("Enter the name of the group to select keys for: ") + +keys = [] +a = [] + +for i in range(len(group_lists)): + a.append(group_lists[i][0]) + +b = a.index(group) + +for i in range(len(group_lists[b][1])): + logrus = group_lists[b][1][i] + keys.append(gpg.Context().keylist(pattern=logrus)) commit 6c6af9a7b0ae4e7182d669bec282c6edaaa7eaa1 Author: Ben McGinnes Date: Thu Mar 22 05:07:56 2018 +1100 example groups work around * Updated usage so it only references importing the final list of lists produced. Trying to use some of the mid-points can have unpredictable results (this is part of the problem with work arounds). diff --git a/lang/python/examples/howto/groups.py b/lang/python/examples/howto/groups.py index e7adc44..5e7fdf6 100644 --- a/lang/python/examples/howto/groups.py +++ b/lang/python/examples/howto/groups.py @@ -28,7 +28,7 @@ import subprocess """ Intended for use with other scripts. -Usage: from groups import group_lines, group_lists +Usage: from groups import group_lists """ lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines() commit a4e3f827652c59d850b4e5506a92c1ecd190c1bb Author: Ben McGinnes Date: Thu Mar 22 04:04:05 2018 +1100 example: groups * Added a docstring. diff --git a/lang/python/examples/howto/groups.py b/lang/python/examples/howto/groups.py index 67fd783..e7adc44 100644 --- a/lang/python/examples/howto/groups.py +++ b/lang/python/examples/howto/groups.py @@ -25,6 +25,12 @@ from __future__ import absolute_import, division, unicode_literals import subprocess +""" +Intended for use with other scripts. + +Usage: from groups import group_lines, group_lists +""" + lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines() for i in range(len(lines)): commit ad6cb4f9b8b97a2bc501c17fc542a84b725dedea Author: Ben McGinnes Date: Thu Mar 22 03:58:58 2018 +1100 example: verify signatures * Added example for verifying detached signatures against the files they're the signatures for. diff --git a/lang/python/examples/howto/verify-signatures.py b/lang/python/examples/howto/verify-signatures.py new file mode 100755 index 0000000..8aafc3b --- /dev/null +++ b/lang/python/examples/howto/verify-signatures.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys +import time + +""" +Verifies a signed file which has been signed with a detached signature. +""" + +if len(sys.argv) > 2: + filename = sys.argv[1] + sig_file = sys.argv[2] +elif len(sys.argv) == 2: + filename = sys.argv[1] + sig_file = input("Enter the path and filename of the detached signature: ") +else: + filename = input("Enter the path and filename to verify: ") + sig_file = input("Enter the path and filename of the detached signature: ") + +c = gpg.Context() + +try: + data, result = c.verify(open(filename), open(sig_file)) + verified = True +except gpg.errors.BadSignatures as e: + verified = False + print(e) + +if verified is True: + for i in range(len(result.signatures)): + sign = result.signatures[i] + print("""Good signature from: +{0} +with key {1} +made at {2} +""".format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, + time.ctime(sign.timestamp))) +else: + pass commit ae2767eb27b6a76284ee4403e575869afe2e80a8 Author: Ben McGinnes Date: Thu Mar 22 01:50:08 2018 +1100 example: verify signed file * Added example to verify normal and clearsigned files. diff --git a/lang/python/examples/howto/verify-signed-file.py b/lang/python/examples/howto/verify-signed-file.py new file mode 100755 index 0000000..9f8702f --- /dev/null +++ b/lang/python/examples/howto/verify-signed-file.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys +import time + +""" +Verifies a signed file which has been signed with either NORMAL or CLEAR modes. +""" + +if len(sys.argv) > 2: + filename = " ".join(sys.argv[1:]) +elif len(sys.argv) == 2: + filename = sys.argv[1] +else: + filename = input("Enter the path and filename to sign: ") + +c = gpg.Context() + +try: + data, result = c.verify(open(filename)) + verified = True +except gpg.errors.BadSignatures as e: + verified = False + print(e) + +if verified is True: + for i in range(len(result.signatures)): + sign = result.signatures[i] + print("""Good signature from: +{0} +with key {1} +made at {2} +""".format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, + time.ctime(sign.timestamp))) +else: + pass commit e57388a69f61d14e3df3c842d227fb450c96c807 Author: Ben McGinnes Date: Thu Mar 22 01:48:41 2018 +1100 doc: python bindings howto * Fixed minor error in one of the verification examples. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 0c15149..655209a 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -898,7 +898,7 @@ """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, time.ctime(sign.timestamp))) else: - pass(e) + pass #+end_src Whereas this next example, which is almost identical would work ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 2 +- ...ypt-sign-file.py => group-encrypt-sign-file.py} | 31 ++++++++++----- .../{decrypt-file.py => group-key-selection.py} | 36 +++++++++++------ lang/python/examples/howto/groups.py | 6 +++ .../howto/{decrypt-file.py => key-selection.py} | 31 +++++++++------ .../{clear-sign-file.py => verify-signatures.py} | 46 +++++++++++++--------- .../{decrypt-file.py => verify-signed-file.py} | 39 ++++++++++++------ 7 files changed, 127 insertions(+), 64 deletions(-) copy lang/python/examples/howto/{encrypt-sign-file.py => group-encrypt-sign-file.py} (80%) copy lang/python/examples/howto/{decrypt-file.py => group-key-selection.py} (63%) copy lang/python/examples/howto/{decrypt-file.py => key-selection.py} (64%) copy lang/python/examples/howto/{clear-sign-file.py => verify-signatures.py} (58%) copy lang/python/examples/howto/{decrypt-file.py => verify-signed-file.py} (63%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 21 20:06:17 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 21 Mar 2018 20:06:17 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-138-g7ddff71 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 7ddff71908a85111c8e0da41312197b3b1a77da6 (commit) from c6a0395f0a3a57071f0c943f7815f58a02f9d2f3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7ddff71908a85111c8e0da41312197b3b1a77da6 Author: Ben McGinnes Date: Thu Mar 22 06:05:10 2018 +1100 examples: encryption * Fixed two incorrect Context() objects. diff --git a/lang/python/examples/howto/encrypt-file.py b/lang/python/examples/howto/encrypt-file.py index 877226d..ad4e1ce 100755 --- a/lang/python/examples/howto/encrypt-file.py +++ b/lang/python/examples/howto/encrypt-file.py @@ -48,7 +48,7 @@ else: a_key = input("Enter the fingerprint or key ID to encrypt to: ") filename = input("Enter the path and filename to encrypt: ") -rkey = list(c.keylist(pattern=a_key, secret=False)) +rkey = list(gpg.Context().keylist(pattern=a_key, secret=False)) with open(filename, "rb") as f: text = f.read() diff --git a/lang/python/examples/howto/encrypt-sign-file.py b/lang/python/examples/howto/encrypt-sign-file.py index 4b29b27..41aaac8 100755 --- a/lang/python/examples/howto/encrypt-sign-file.py +++ b/lang/python/examples/howto/encrypt-sign-file.py @@ -51,7 +51,7 @@ else: a_key = input("Enter the fingerprint or key ID to encrypt to: ") filename = input("Enter the path and filename to encrypt: ") -rkey = list(c.keylist(pattern=a_key, secret=False)) +rkey = list(gpg.Context().keylist(pattern=a_key, secret=False)) with open(filename, "rb") as f: text = f.read() ----------------------------------------------------------------------- Summary of changes: lang/python/examples/howto/encrypt-file.py | 2 +- lang/python/examples/howto/encrypt-sign-file.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 21 20:23:24 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 21 Mar 2018 20:23:24 +0100 Subject: [git] GPGME - branch, ben/docs/2018-03, updated. gpgme-1.10.0-140-g05e5993 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/docs/2018-03 has been updated via 05e59933056ee8ef8ba7579351a58ed25dd7f754 (commit) via 61a988036bd3f0d43f7d55bfa43f5f05bec978c4 (commit) from 7ddff71908a85111c8e0da41312197b3b1a77da6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 05e59933056ee8ef8ba7579351a58ed25dd7f754 Author: Ben McGinnes Date: Thu Mar 22 06:19:36 2018 +1100 examples: multi-key selection operations * Temporarily removing multi-key selection based examples. * There are a few issues with getting the key selections to play nicely with gpg.Context().keylist object types. * Will troubleshoot them separately and restore them when that's worked out, but I don't want these more complicated examples to delay merging the HOWTO with master. diff --git a/lang/python/examples/howto/group-encrypt-sign-file.py b/lang/python/examples/howto/group-encrypt-sign-file.py deleted file mode 100755 index da73e4c..0000000 --- a/lang/python/examples/howto/group-encrypt-sign-file.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -from __future__ import absolute_import, division, unicode_literals - -# Copyright (C) 2018 Ben McGinnes -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 2.1 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU -# Lesser General Public Licensefor more details. -# -# You should have received a copy of the GNU General Public License and the GNU -# Lesser General Public along with this program; if not, see -# . - -import gpg -import sys - -from groups import group_lists - -""" -Signs and encrypts a file to a specified group of keys. If entering both the -group and the filename on the command line, the group must be entered first. - -Signs with and also encrypts to the default key of the user invoking the -script. Will treat all recipients as trusted to permit encryption. - -Will produce both an ASCII armoured and GPG binary format copy of the signed -and encrypted file. -""" - -if len(sys.argv) > 3: - group = sys.argv[1] - filename = " ".join(sys.argv[2:]) -elif len(sys.argv) == 3: - group = sys.argv[1] - filename = sys.argv[2] -elif len(sys.argv) == 2: - group = sys.argv[1] - filename = input("Enter the path and filename to encrypt: ") -else: - group = input("Enter the name of the group to select keys for: ") - filename = input("Enter the path and filename to encrypt: ") - -keys = [] -a = [] - -for i in range(len(group_lists)): - a.append(group_lists[i][0]) - -b = a.index(group) - -for i in range(len(group_lists[b][1])): - logrus = group_lists[b][1][i] - keys.append(list(gpg.Context().keylist(pattern=logrus))) - -with open(filename, "rb") as f: - text = f.read() - -with gpg.Context(armor=True) as ca: - ciphertext, result, sign_result = ca.encrypt(text, recipients=keys, - always_trust=True, - add_encrypt_to=True) - with open("{0}.asc".format(filename), "wb") as fa: - fa.write(ciphertext) - -with gpg.Context() as cg: - ciphertext, result, sign_result = cg.encrypt(text, recipients=keys, - always_trust=True, - add_encrypt_to=True) - with open("{0}.gpg".format(filename), "wb") as fg: - fg.write(ciphertext) diff --git a/lang/python/examples/howto/group-key-selection.py b/lang/python/examples/howto/group-key-selection.py deleted file mode 100755 index 2e3d2eb..0000000 --- a/lang/python/examples/howto/group-key-selection.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -from __future__ import absolute_import, division, unicode_literals - -# Copyright (C) 2018 Ben McGinnes -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 2.1 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU -# Lesser General Public Licensefor more details. -# -# You should have received a copy of the GNU General Public License and the GNU -# Lesser General Public along with this program; if not, see -# . - -import gpg -import sys - -from groups import group_lists - -""" -Takes an existing group specified as a command line parameter and converts it -to a list object 'keys' as expected by the gpg module. - -Requires the groups module in this directory. -""" - -if len(sys.argv) == 2: - group = sys.argv[1] -elif len(sys.argv) == 1: - group = input("Enter the name of the group to select keys for: ") -else: - group = input("Enter the name of the group to select keys for: ") - -keys = [] -a = [] - -for i in range(len(group_lists)): - a.append(group_lists[i][0]) - -b = a.index(group) - -for i in range(len(group_lists[b][1])): - logrus = group_lists[b][1][i] - keys.append(gpg.Context().keylist(pattern=logrus)) diff --git a/lang/python/examples/howto/key-selection.py b/lang/python/examples/howto/key-selection.py deleted file mode 100755 index a007219..0000000 --- a/lang/python/examples/howto/key-selection.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -from __future__ import absolute_import, division, unicode_literals - -# Copyright (C) 2018 Ben McGinnes -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 2.1 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU -# Lesser General Public Licensefor more details. -# -# You should have received a copy of the GNU General Public License and the GNU -# Lesser General Public along with this program; if not, see -# . - -import gpg -import sys - -""" -Uses key IDs, fingerprints or other patterns as space separated input and -creates a keylist object for use by the gpg module. - -Similar to the group-key-selection.py script, but does not require an existing -group in the gpg.conf file. -""" - -if len(sys.argv) < 2: - key_ids_str = sys.argv[1:] -elif len(sys.argv) == 2: - key_ids_str = sys.argv[1] -elif len(sys.argv) == 1: - key_ids_str = input("Enter the keys to select by key ID or fingerprint: ") -else: - key_ids_str = input("Enter the keys to select by key ID or fingerprint: ") - -key_ids = key_ids_str.split() -keys = [] -for i in range(len(key_ids)): - logrus = key_ids[i] - keys.append(gpg.Context().keylist(pattern=logrus)) commit 61a988036bd3f0d43f7d55bfa43f5f05bec978c4 Author: Ben McGinnes Date: Thu Mar 22 06:18:13 2018 +1100 example: group encryption * Troubleshooting. diff --git a/lang/python/examples/howto/group-encrypt-sign-file.py b/lang/python/examples/howto/group-encrypt-sign-file.py index 920e50d..da73e4c 100755 --- a/lang/python/examples/howto/group-encrypt-sign-file.py +++ b/lang/python/examples/howto/group-encrypt-sign-file.py @@ -63,7 +63,7 @@ b = a.index(group) for i in range(len(group_lists[b][1])): logrus = group_lists[b][1][i] - keys.append(gpg.Context().keylist(pattern=logrus)) + keys.append(list(gpg.Context().keylist(pattern=logrus))) with open(filename, "rb") as f: text = f.read() ----------------------------------------------------------------------- Summary of changes: .../examples/howto/group-encrypt-sign-file.py | 83 ---------------------- lang/python/examples/howto/group-key-selection.py | 56 --------------- lang/python/examples/howto/key-selection.py | 51 ------------- 3 files changed, 190 deletions(-) delete mode 100755 lang/python/examples/howto/group-encrypt-sign-file.py delete mode 100755 lang/python/examples/howto/group-key-selection.py delete mode 100755 lang/python/examples/howto/key-selection.py hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 21 20:42:49 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 21 Mar 2018 20:42:49 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-146-g5722148 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 5722148bacab5862b40a027861d64683a0f214ea (commit) via 76055dd5c7d755c6f8a242b701aeadba621fbc0f (commit) via 05e59933056ee8ef8ba7579351a58ed25dd7f754 (commit) via 61a988036bd3f0d43f7d55bfa43f5f05bec978c4 (commit) via 7ddff71908a85111c8e0da41312197b3b1a77da6 (commit) via c6a0395f0a3a57071f0c943f7815f58a02f9d2f3 (commit) via 0a0d57fd41380cd797d29e11cec8a77c7404e960 (commit) via 0ccc57c9512246d82d46e7732bfb0f95c18ca9d3 (commit) via 8b401bfc76eac762553f76faab53c2f4cd117a8d (commit) via 6c6af9a7b0ae4e7182d669bec282c6edaaa7eaa1 (commit) via a4e3f827652c59d850b4e5506a92c1ecd190c1bb (commit) via ad6cb4f9b8b97a2bc501c17fc542a84b725dedea (commit) via ae2767eb27b6a76284ee4403e575869afe2e80a8 (commit) via e57388a69f61d14e3df3c842d227fb450c96c807 (commit) via ac6a552c37147a000de74f49d1bff34dad52252e (commit) via af6cbba18ba5e2bbecce5f8268c146282cd12367 (commit) via 6fa2a344282e369e6aca8155bc77dd2c12a29414 (commit) via 1fdd1f306d45f6aeee91c7f016f7c37286ee3b3b (commit) via 1d2746433c9632fc0c7bc10b59280fca15895545 (commit) via 0390ede18696520be9cc1a42f628e23159b7c2eb (commit) via 52e262991f1fdf7da93882c3b22c05537376cf49 (commit) via 96d0395bccbbff91f73c06cb7bd6c131f04b8a9a (commit) via 51258975d763c9471859d635e6080c2ec02e8647 (commit) via 29e918171f352c71a90a16c04d4a3dcafa5db682 (commit) via 7221bb67642eb01a07957d66d0cbcd4ef8aadbf8 (commit) via f3fe47e8fd2e7bc748016befcae494421223368c (commit) via f0790f224d7af9521efe96e69a8f719fb89a5af2 (commit) via 7ab42e79ade89f28507ea42d51148a40b4bfc736 (commit) via cfbdcb7fb3fa438cafba82e4fb8f327df596f98e (commit) via b30ebf89725641018b3b08f77876530f9b983fa2 (commit) via 8f7672ad1b267f122f647bb5f984734d0ff66a5c (commit) via 6950a63e63d60685ddb6f4cbff7b826b8acb5b13 (commit) via 3e0f68fdff1998dae9cb6f8510a3e945a268d1f6 (commit) via d5f6dec048d3d4d94f1fcdb3f4249cf6e71c4b92 (commit) via 0fb8a5d45c1c77a5928d6e356271da055aa55994 (commit) via bf67cf433fe82924ed40e79785e95403c07cc068 (commit) via 1779d7b9d6769b2e47f1e90260290e25c8c3aa02 (commit) via 64c5886132aceefc9d9600a3a6dbbbf404b95b81 (commit) via 4811ff7b6c8ef97c7d4858ce235e9bf8227f4917 (commit) via 82c5af225f2bdf3acc6fc652a96ee61c9b057395 (commit) via b549f69d0520bb74957b95cec9ea918dba2374f6 (commit) via 431897a4c48fe1bc9d37f655097aabaf5b685d11 (commit) via 22e2445beee46ed1e527a98e635153c7cf03786f (commit) via 94a95ac12364989db7f4be333107f3c023551857 (commit) via 3d0c7a2202c8e9bd4f284fd00069d34b8d3d3d4c (commit) via 961aea212ef48914ecbfa169addf951b0854b0b4 (commit) via 7ac65b10837740caf68cdade791b8c5ce4eb1b03 (commit) via 9e3e4a835c64f5d06de821b1fd648af37827ff26 (commit) via b02d9d0a7b96b186eb3063d94bde369339181461 (commit) via 5432e5f9d1dfc02812d0b181f8d88cdf4a2bfbfb (commit) via 5d1dd2abe5cf787875d12afe46c78c75385d7b31 (commit) via 1d05e6aa4ea467c8c5926b827cfcfba357d03312 (commit) via b35aaef7a3b793b8f6f5b42596c0a6a51e87f78c (commit) via 6bc12a0eeb20409770cb8b923d08c18c2b730cb8 (commit) via e5c85fba25de1187949697e2dae0e89345b71e89 (commit) via ada059b07178147821b1598c935aa70ae45e3e6c (commit) via ef27f3781a37e264d0eb7d1745eb2c804ec062c4 (commit) via 423fdcd4653cb01f07f2b0e72cfcf49554930f70 (commit) via a71205dc3b58970adf591b4e4553824a33f353db (commit) via a10dcb4f138eb5a21881cdbc4806c25129d4ae4e (commit) via 952b6042f78017c476452088261af8d352cfa729 (commit) via c92da2c7eb148ce9fb06495a8470dd9caf662f9a (commit) via e489ddd08af29fdad8db8aa0aec0c314daa3678c (commit) via f29bda8d7146b4bc0bf73d6e613131545ff86b73 (commit) via c27a7a3f994dad0eccee890185582f4350fbf233 (commit) via f81adeba992a9fd3b5a199e9a2e242a0f53cf639 (commit) via 36dfbdffea60c529a6d1e1ff3e507be016b6a0f6 (commit) via 484e9a6229ac9c80c6be4df638bce711f08a74c6 (commit) via a8f48b6f577d562c25fd0191c0cc2cc8e96078c1 (commit) via 83b1336ceebb86e13a55bbf220df2d750f6b3ec6 (commit) via 0e1300ce777dd0c87f31ac8bc49846b9df242df9 (commit) via 7ebc5a357057d01b7ef965521ab68b7cb7e20a8f (commit) via 172baaf4d3e4ed03a4d3437be9efa3dfe6a847bc (commit) via f2c1e8d8d54068a7f072efa178fc30460821eff3 (commit) via 01686463948ac6096dd8579a110c478d3a1f9a83 (commit) via 93252df9dc4c9932467814745655350a8cab900e (commit) via ab81c2d868bba79fdb8f8d7f576b6bd88c6bdf3c (commit) via f685cda281c6148072e8a6cd139c990cb041ea3d (commit) via fa4927146b68dd045903285f1c45fb64deb2e361 (commit) via c767a4a3590bd8a224d0268746df443942cb28c2 (commit) via 75463d589522cba427f9e5a3a408192ffad8bb21 (commit) via a98f2c556fe6e33a9cd38279e64e4b09f05cc675 (commit) via e8adab68f8c0cd865ff220f06dfaff7fe183e8a1 (commit) via 47d401d159852ea08e90af21d91bb4b93be9000d (commit) via 8a76deb11efd7dadfde6e8e7e69fbcd92577982f (commit) via 5215d58ae2521d81c3db0b45dfbdce01a679acab (commit) via 8f2c0f4534ea2a07f071f360a63e877f60dc52f2 (commit) via d4778bb23d0817ee6fbcbe4f0ff0ff0429bf3669 (commit) via 3a746d5d46ffd7d332dc24fd6a4d24efc5fc1230 (commit) via 13d2164cd9f313b409b2210d9e63465681cccc99 (commit) via 1516c56ee4da28eb720bbacb026892393d10b24a (commit) via f61d4f585f27c13fabf7a23ad295bdc8bea7c838 (commit) from 343d3e2232a22d0999e1693f0f95e5e290005829 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5722148bacab5862b40a027861d64683a0f214ea Author: Ben McGinnes Date: Thu Mar 22 06:37:02 2018 +1100 doc and examples: python bindings HOWTO * Added GPGME Python bindings HOWTO in Australian/British English. ** en-US "translation" still to be done. * Added several example scripts comprised of the "Basic Functions" section of the HOWTO (plus the work-around at the end). ** As these scripts are very basic examples they are released under both the GPLv2+ and the LGPLv2.1+ (just like GPGME itself). Signed-off-by: Ben McGinnes diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 655209a..ab3cfdf 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -13,7 +13,7 @@ :CUSTOM_ID: intro :END: - | Version: | 0.1.0-draft | + | Version: | 0.1.0 | | Author: | Ben McGinnes | | Author GPG Key: | DB4724E6FA4286C92B4E55C4321E4E2373590E5D | | Language: | Australian English, British English | commit 76055dd5c7d755c6f8a242b701aeadba621fbc0f Merge: 343d3e2 05e5993 Author: Ben McGinnes Date: Thu Mar 22 06:33:16 2018 +1100 Merge branch 'ben/docs/2018-03' of ssh+git://playfair.gnupg.org/git/gpgme into ben/docs/2018-03 ----------------------------------------------------------------------- Summary of changes: .gitignore | 1 - TODO | 157 ++- lang/python/docs/GPGMEpythonHOWTOen.org | 1370 ++++++++++++++++++++ lang/python/docs/TODO.org | 77 +- lang/python/examples/howto/README.org | 58 + lang/python/examples/howto/clear-sign-file.py | 56 + lang/python/examples/howto/decrypt-file.py | 44 + lang/python/examples/howto/detach-sign-file.py | 64 + lang/python/examples/howto/encrypt-file.py | 71 + lang/python/examples/howto/encrypt-sign-file.py | 70 + lang/python/examples/howto/groups.py | 50 + lang/python/examples/howto/keycount.py | 42 + lang/python/examples/howto/sign-file.py | 64 + lang/python/examples/howto/verify-signatures.py | 64 + lang/python/examples/howto/verify-signed-file.py | 61 + ...crypt-to-all.py => low_level-encrypt_to_all.py} | 0 src/gpgme-tool.c | 2 +- 17 files changed, 2209 insertions(+), 42 deletions(-) create mode 100644 lang/python/docs/GPGMEpythonHOWTOen.org create mode 100644 lang/python/examples/howto/README.org create mode 100755 lang/python/examples/howto/clear-sign-file.py create mode 100755 lang/python/examples/howto/decrypt-file.py create mode 100755 lang/python/examples/howto/detach-sign-file.py create mode 100755 lang/python/examples/howto/encrypt-file.py create mode 100755 lang/python/examples/howto/encrypt-sign-file.py create mode 100644 lang/python/examples/howto/groups.py create mode 100755 lang/python/examples/howto/keycount.py create mode 100755 lang/python/examples/howto/sign-file.py create mode 100755 lang/python/examples/howto/verify-signatures.py create mode 100755 lang/python/examples/howto/verify-signed-file.py rename lang/python/examples/{encrypt-to-all.py => low_level-encrypt_to_all.py} (100%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 00:07:45 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 22 Mar 2018 00:07:45 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-147-g65ed4ac Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 65ed4ac82598734551b87fc89deab3cee010bd37 (commit) from 5722148bacab5862b40a027861d64683a0f214ea (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 65ed4ac82598734551b87fc89deab3cee010bd37 Author: Ben McGinnes Date: Thu Mar 22 10:06:53 2018 +1100 doc: python bindings howto * Fixed table. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index ab3cfdf..1e8dd9f 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -13,7 +13,7 @@ :CUSTOM_ID: intro :END: - | Version: | 0.1.0 | + | Version: | 0.1.0 | | Author: | Ben McGinnes | | Author GPG Key: | DB4724E6FA4286C92B4E55C4321E4E2373590E5D | | Language: | Australian English, British English | ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 01:26:56 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 22 Mar 2018 01:26:56 +0100 Subject: [git] gnupg-doc - branch, master, updated. 8cf29941c754d386f1d81fc4a52450cd2a9e0f7b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 8cf29941c754d386f1d81fc4a52450cd2a9e0f7b (commit) via 89ca96b83eadb31171b750a3bfd31da009a20db4 (commit) from 8aaa4d783f38be7ad5d72df0451a8208b0712dbd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8cf29941c754d386f1d81fc4a52450cd2a9e0f7b Merge: 89ca96b 8aaa4d7 Author: Ben McGinnes Date: Thu Mar 22 11:26:28 2018 +1100 Merge branch 'master' of ssh+git://playfair.gnupg.org/git/gnupg-doc commit 89ca96b83eadb31171b750a3bfd31da009a20db4 Author: Ben McGinnes Date: Thu Mar 22 11:24:02 2018 +1100 GPGME Python bindings HOWTO * Added links from howtos page. * Added HTML version to howtos.gnupg.org. diff --git a/misc/howtos.gnupg.org/en/GPGMEpythonHOWTOen.html b/misc/howtos.gnupg.org/en/GPGMEpythonHOWTOen.html new file mode 100644 index 0000000..8b503d3 --- /dev/null +++ b/misc/howtos.gnupg.org/en/GPGMEpythonHOWTOen.html @@ -0,0 +1,2003 @@ + + + + + + + +GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English) + + + + + + +
+

GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English)

+ + + +
+

1 Introduction

+
+ + + +++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Version:0.1.0
Author:Ben McGinnes <ben at gnupg.org>
Author GPG Key:DB4724E6FA4286C92B4E55C4321E4E2373590E5D
Language:Australian English, British English
xml:lang:en-AU, en-GB, en
+ +

+This document provides basic instruction in how to use the GPGME +Python bindings to programmatically leverage the GPGME library. +

+
+ + +
+

1.1 Python 2 versus Python 3

+
+

+Though the GPGME Python bindings themselves provide support for +both Python 2 and 3, the focus is unequivocally on Python 3 and +specifically from Python 3.4 and above. As a consequence all the +examples and instructions in this guide use Python 3 code. +

+ +

+Much of it will work with Python 2, but much of it also deals with +Python 3 byte literals, particularly when reading and writing data. +Developers concentrating on Python 2.7, and possibly even 2.6, will +need to make the appropriate modifications to support the older +string and unicode types as opposed to bytes. +

+ +

+There are multiple reasons for concentrating on Python 3; some of +which relate to the immediate integration of these bindings, some +of which relate to longer term plans for both GPGME and the python +bindings and some of which relate to the impending EOL period for +Python 2.7. Essentially, though, there is little value in tying +the bindings to a version of the language which is a dead end and +the advantages offered by Python 3 over Python 2 make handling the +data types with which GPGME deals considerably easier. +

+
+
+ + +
+

1.2 Examples

+
+

+All of the examples found in this document can be found as Python 3 +scripts in the lang/python/examples/howto directory. +

+
+
+
+ + +
+

2 GPGME Concepts

+
+
+ + +
+

2.1 A C API

+
+

+Unlike many modern APIs with which programmers will be more +familiar with these days, the GPGME API is a C API. The API is +intended for use by C coders who would be able to access its +features by including the gpgme.h header file with their own C +source code and then access its functions just as they would any +other C headers. +

+ +

+This is a very effective method of gaining complete access to the +API and in the most efficient manner possible. It does, however, +have the drawback that it cannot be directly used by other +languages without some means of providing an interface to those +languages. This is where the need for bindings in various +languages stems. +

+
+
+ + +
+

2.2 Python bindings

+
+

+The Python bindings for GPGME provide a higher level means of +accessing the complete feature set of GPGME itself. It also +provides a more pythonic means of calling these API functions. +

+ +

+The bindings are generated dynamically with SWIG and the copy of +gpgme.h generated when GPGME is compiled. +

+ +

+This means that a version of the Python bindings is fundamentally +tied to the exact same version of GPGME used to generate that copy +of gpgme.h. +

+
+
+ + +
+

2.3 Difference between the Python bindings and other GnuPG Python packages

+
+

+There have been numerous attempts to add GnuPG support to Python +over the years. Some of the most well known are listed here, along +with what differentiates them. +

+
+ + +
+

2.3.1 The python-gnupg package maintained by Vinay Sajip

+
+

+This is arguably the most popular means of integrating GPG with +Python. The package utilises the subprocess module to implement +wrappers for the gpg and gpg2 executables normally invoked on +the command line (gpg.exe and gpg2.exe on Windows). +

+ +

+The popularity of this package stemmed from its ease of use and +capability in providing the most commonly required features. +

+ +

+Unfortunately it has been beset by a number of security issues in +the past; most of which stemmed from using unsafe methods of +accessing the command line via the subprocess calls. While some +effort has been made over the last two to three years (as of 2018) +to mitigate this, particularly by no longer providing shell access +through those subprocess calls, the wrapper is still somewhat +limited in the scope of its GnuPG features coverage. +

+ +

+The python-gnupg package is available under the MIT license. +

+
+
+ + +
+

2.3.2 The gnupg package created and maintained by Isis Lovecruft

+
+

+In 2015 Isis Lovecruft from the Tor Project forked and then +re-implemented the python-gnupg package as just gnupg. This new +package also relied on subprocess to call the gpg or gpg2 +binaries, but did so somewhat more securely. +

+ +

+The naming and version numbering selected for this package, +however, resulted in conflicts with the original python-gnupg and +since its functions were called in a different manner to +python-gnupg, the release of this package also resulted in a great +deal of consternation when people installed what they thought was +an upgrade that subsequently broke the code relying on it. +

+ +

+The gnupg package is available under the GNU General Public +License version 3.0 (or any later version). +

+
+
+ + +
+

2.3.3 The PyME package maintained by Martin Albrecht

+
+

+This package is the origin of these bindings, though they are +somewhat different now. For details of when and how the PyME +package was folded back into GPGME itself see the Short History +document1 in this Python bindings docs directory.2 +

+ +

+The PyME package was first released in 2002 and was also the first +attempt to implement a low level binding to GPGME. In doing so it +provided access to considerably more functionality than either the +python-gnupg or gnupg packages. +

+ +

+The PyME package is only available for Python 2.6 and 2.7. +

+ +

+Porting the PyME package to Python 3.4 in 2015 is what resulted in +it being folded into the GPGME project and the current bindings +are the end result of that effort. +

+ +

+The PyME package is available under the same dual licensing as +GPGME itself: the GNU General Public License version 2.0 (or any +later version) and the GNU Lesser General Public License version +2.1 (or any later version). +

+
+
+
+
+ + +
+

3 GPGME Python bindings installation

+
+
+ + +
+

3.1 No PyPI

+
+

+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. +

+ +

+This is because the bindings use SWIG to dynamically generate C +bindings against gpgme.h and gpgme.h is generated from +gpgme.h.in 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. +

+
+
+ + +
+

3.2 Requirements

+
+

+The GPGME Python bindings only have three requirements: +

+ +
    +
  1. A suitable version of Python 2 or Python 3. With Python 2 that +means Python 2.7 and with Python 3 that means Python 3.4 or +higher.
  2. +
  3. SWIG.
  4. +
  5. GPGME itself. Which also means that all of GPGME's dependencies +must be installed too.
  6. +
+
+
+ + +
+

3.3 Installation

+
+

+Installing the Python bindings is effectively achieved by compiling +and installing GPGME itself. +

+ +

+Once SWIG is installed with Python and all the dependencies for +GPGME are installed you only need to confirm that the version(s) of +Python you want the bindings installed for are in your $PATH. +

+ +

+By default GPGME will attempt to install the bindings for the most +recent or highest version number of Python 2 and Python 3 it +detects in $PATH. It specifically checks for the python and +python3 executables first and then checks for specific version +numbers. +

+ +

+For Python 2 it checks for these executables in this order: +python, python2 and python2.7. +

+ +

+For Python 3 it checks for these executables in this order: +python3, python3.6, python3.5 and python3.4. +

+
+ + +
+

3.3.1 Installing GPGME

+
+

+See the GPGME README file for details of how to install GPGME from +source. +

+
+
+
+
+ + +
+

4 Fundamentals

+
+

+Before we can get to the fun stuff, there are a few matters +regarding GPGME's design which hold true whether you're dealing with +the C code directly or these Python bindings. +

+
+ + +
+

4.1 No REST

+
+

+The first part of which is or will be fairly blatantly obvious upon +viewing the first example, but it's worth reiterating anyway. That +being that this API is not a REST API. Nor indeed could it +ever be one. +

+ +

+Most, if not all, Python programmers (and not just Python +programmers) know how easy it is to work with a RESTful API. In +fact they've become so popular that many other APIs attempt to +emulate REST-like behaviour as much as they are able. Right down +to the use of JSON formatted output to facilitate the use of their +API without having to retrain developers. +

+ +

+This API does not do that. It would not be able to do that and +also provide access to the entire C API on which it's built. It +does, however, provide a very pythonic interface on top of the +direct bindings and it's this pythonic layer with which this HOWTO +deals with. +

+
+
+ + +
+

4.2 Context

+
+

+One of the reasons which prevents this API from being RESTful is +that most operations require more than one instruction to the API +to perform the task. Sure, there are certain functions which can +be performed simultaneously, particularly if the result known or +strongly anticipated (e.g. selecting and encrypting to a key known +to be in the public keybox). +

+ +

+There are many more, however, which cannot be manipulated so +readily: they must be performed in a specific sequence and the +result of one operation has a direct bearing on the outcome of +subsequent operations. Not merely by generating an error either. +

+ +

+When dealing with this type of persistent state on the web, full of +both the RESTful and REST-like, it's most commonly referred to as a +session. In GPGME, however, it is called a context and every +operation type has one. +

+
+
+
+ + +
+

5 Working with keys

+
+
+ + +
+

5.1 Key selection

+
+

+Selecting keys to encrypt to or to sign with will be a common +occurrence when working with GPGMe and the means available for +doing so are quite simple. +

+ +

+They do depend on utilising a Context; however once the data is +recorded in another variable, that Context does not need to be the +same one which subsequent operations are performed. +

+ +

+The easiest way to select a specific key is by searching for that +key's key ID or fingerprint, preferably the full fingerprint +without any spaces in it. A long key ID will probably be okay, but +is not advised and short key IDs are already a problem with some +being generated to match specific patterns. It does not matter +whether the pattern is upper or lower case. +

+ +

+So this is the best method: +

+ +
+
import gpg
+
+k = gpg.Context().keylist(pattern="258E88DCBD3CD44D8E7AB43F6ECB6AF0DEADBEEF")
+keys = list(k)
+
+
+ +

+This is passable and very likely to be common: +

+ +
+
import gpg
+
+k = gpg.Context().keylist(pattern="0x6ECB6AF0DEADBEEF")
+keys = list(k)
+
+
+ +

+And this is a really bad idea: +

+ +
+
import gpg
+
+k = gpg.Context().keylist(pattern="0xDEADBEEF")
+keys = list(k)
+
+
+ +

+Alternatively it may be that the intention is to create a list of +keys which all match a particular search string. For instance all +the addresses at a particular domain, like this: +

+ +
+
import gpg
+
+ncsc = gpg.Context().keylist(pattern="ncsc.mil")
+nsa = list(ncsc)
+
+
+
+ + +
+

5.1.1 Counting keys

+
+

+Counting the number of keys in your public keybox (pubring.kbx), +the format which has superseded the old keyring format +(pubring.gpg and secring.gpg), or the number of secret keys is +a very simple task. +

+ +
+
import gpg
+
+c = gpg.Context()
+seckeys = c.keylist(pattern=None, secret=True)
+pubkeys = c.keylist(pattern=None, secret=False)
+
+seclist = list(seckeys)
+secnum = len(seclist)
+
+publist = list(pubkeys)
+pubnum = len(publist)
+
+print("""
+Number of secret keys:  {0}
+Number of public keys:  {1}
+""".format(secnum, pubnum))
+
+
+
+
+
+ + +
+

5.2 Get key

+
+

+An alternative method of getting a single key via its fingerprint +is available directly within a Context with Context().get_key. +This is the preferred method of selecting a key in order to modify +it, sign or certify it and for obtaining relevant data about a +single key as a part of other functions; when verifying a signature +made by that key, for instance. +

+ +

+By default this method will select public keys, but it can select +secret keys as well. +

+ +

+This first example demonstrates selecting the current key of Werner +Koch, which is due to expire at the end of 2018: +

+ +
+
import gpg
+
+fingerprint = "80615870F5BAD690333686D0F2AD85AC1E42B367"
+key = gpg.Context().get_key(fingerprint)
+
+
+ +

+Whereas this example demonstrates selecting the author's current +key with the secret key word argument set to True: +

+ +
+
import gpg
+
+fingerprint = "DB4724E6FA4286C92B4E55C4321E4E2373590E5D"
+key = gpg.Context().get_key(fingerprint, secret=True)
+
+
+ +

+It is, of course, quite possible to select expired, disabled and +revoked keys with this function, but only to effectively display +information about those keys. +

+ +

+It is also possible to use both unicode or string literals and byte +literals with the fingerprint when getting a key in this way. +

+
+
+
+ + +
+

6 Basic Functions

+
+

+The most frequently called features of any cryptographic library +will be the most fundamental tasks for encryption software. In this +section we will look at how to programmatically encrypt data, +decrypt it, sign it and verify signatures. +

+
+ + +
+

6.1 Encryption

+
+

+Encrypting is very straight forward. In the first example below +the message, text, is encrypted to a single recipient's key. In +the second example the message will be encrypted to multiple +recipients. +

+
+ + +
+

6.1.1 Encrypting to one key

+
+

+Once the the Context is set the main issues with encrypting data +is essentially reduced to key selection and the keyword arguments +specified in the gpg.Context().encrypt() method. +

+ +

+Those keyword arguments are: recipients, a list of keys +encrypted to (covered in greater detail in the following section); +sign, whether or not to sign the plaintext data, see subsequent +sections on signing and verifying signatures below (defaults to +True); sink, to write results or partial results to a secure +sink instead of returning it (defaults to None); passphrase, +only used when utilising symmetric encryption (defaults to +None); always_trust, used to override the trust model settings +for recipient keys (defaults to False); add_encrypt_to, +utilises any preconfigured encrypt-to or default-key settings +in the user's gpg.conf file (defaults to False); prepare, +prepare for encryption (defaults to False); expect_sign, +prepare for signing (defaults to False); compress, compresses +the plaintext prior to encryption (defaults to True). +

+ +
+
import gpg
+
+a_key = "0x12345678DEADBEEF"
+text = b"""Some text to test with.
+
+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)
+rkey = list(c.keylist(pattern=a_key, secret=False))
+ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=False)
+
+with open("secret_plans.txt.asc", "wb") as afile:
+    afile.write(ciphertext)
+
+
+ +

+Though this is even more likely to be used like this; with the +plaintext input read from a file, the recipient keys used for +encryption regardless of key trust status and the encrypted output +also encrypted to any preconfigured keys set in the gpg.conf +file: +

+ +
+
import gpg
+
+a_key = "0x12345678DEADBEEF"
+
+with open("secret_plans.txt", "rb") as afile:
+    text = afile.read()
+
+c = gpg.Context(armor=True)
+rkey = list(c.keylist(pattern=a_key, secret=False))
+ciphertext, result, sign_result = c.encrypt(text, recipients=rkey,
+                        sign=True, always_trust=True,
+                        add_encrypt_to=True)
+
+with open("secret_plans.txt.asc", "wb") as afile:
+    afile.write(ciphertext)
+
+
+ +

+If the recipients paramater is empty then the plaintext is +encrypted symmetrically. If no passphrase is supplied as a +parameter or via a callback registered with the Context() then +an out-of-band prompt for the passphrase via pinentry will be +invoked. +

+
+
+ + +
+

6.1.2 Encrypting to multiple keys

+
+

+Encrypting to multiple keys essentially just expands upon the key +selection process and the recipients from the previous examples. +

+ +

+The following example encrypts a message (text) to everyone with +an email address on the gnupg.org domain,3 but does not encrypt +to a default key or other key which is configured to normally +encrypt to. +

+ +
+
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])
+
+ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, sign=False,
+                        always_trust=True)
+
+with open("secret_plans.txt.asc", "wb") as afile:
+    afile.write(ciphertext)
+
+
+ +

+All it would take to change the above example to sign the message +and also encrypt the message to any configured default keys would +be to change the c.encrypt line to this: +

+ +
+
ciphertext, result, sign_result = c.encrypt(text, recipients=logrus,
+                        always_trust=True,
+                        add_encrypt_to=True)
+
+
+ +

+The only keyword arguments requiring modification are those for +which the default values are changing. The default value of +sign is True, the default of always_trust is False, the +default of add_encrypt_to is False. +

+ +

+If always_trust is not set to True and any of the recipient +keys are not trusted (e.g. not signed or locally signed) then the +encryption will raise an error. It is possible to mitigate this +somewhat with something more like this: +

+ +
+
import gpg
+
+with open("secret_plans.txt.asc", "rb") as afile:
+    text = afile.read()
+
+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])
+
+try:
+    ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True)
+except gpg.errors.InvalidRecipients as e:
+    for i in range(len(e.recipients)):
+    for n in range(len(logrus)):
+        if logrus[n].fpr == e.recipients[i].fpr:
+        logrus.remove(logrus[n])
+        else:
+        pass
+    try:
+    ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True)
+    except:
+    pass
+
+with open("secret_plans.txt.asc", "wb") as afile:
+    afile.write(ciphertext)
+
+
+ +

+This will attempt to encrypt to all the keys searched for, then +remove invalid recipients if it fails and try again. +

+
+
+
+ + +
+

6.2 Decryption

+
+

+Decrypting something encrypted to a key in one's secret keyring is +fairly straight forward. +

+ +

+In this example code, however, preconfiguring either +gpg.Context() or gpg.core.Context() as c is unnecessary +because there is no need to modify the Context prior to conducting +the decryption and since the Context is only used once, setting it +to c simply adds lines for no gain. +

+ +
+
import gpg
+
+ciphertext = input("Enter path and filename of encrypted file: ")
+newfile = input("Enter path and filename of file to save decrypted data to: ")
+with open(ciphertext, "rb") as cfile:
+    plaintext, result, verify_result = gpg.Context().decrypt(cfile)
+with open(newfile, "wb") as nfile:
+    nfile.write(plaintext)
+
+
+ +

+The data available in plaintext in this example is the decrypted +content as a byte object in plaintext[0], the recipient key IDs +and algorithms in plaintext[1] and the results of verifying any +signatures of the data in plaintext[0]. +

+
+
+ + +
+

6.3 Signing text and files

+
+

+The following sections demonstrate how to specify keys to sign with. +

+
+ + +
+

6.3.1 Signing key selection

+
+

+By default GPGME and the Python bindings will use the default key +configured for the user invoking the GPGME API. If there is no +default key specified and there is more than one secret key +available it may be necessary to specify the key or keys with +which to sign messages and files. +

+ +
+
import gpg
+
+logrus = input("Enter the email address or string to match signing keys to: ")
+hancock = gpg.Context().keylist(pattern=logrus, secret=True)
+sig_src = list(hancock)
+
+
+ +

+The signing examples in the following sections include the +explicitly designated signers parameter in two of the five +examples; once where the resulting signature would be ASCII +armoured and once where it would not be armoured. +

+ +

+While it would be possible to enter a key ID or fingerprint here +to match a specific key, it is not possible to enter two +fingerprints and match two keys since the patten expects a string, +bytes or None and not a list. A string with two fingerprints +won't match any single key. +

+
+
+ + +
+

6.3.2 Normal or default signing messages or files

+
+

+The normal or default signing process is essentially the same as +is most often invoked when also encrypting a message or file. So +when the encryption component is not utilised, the result is to +produce an encoded and signed output which may or may not be ASCII +armoured and which may or may not also be compressed. +

+ +

+By default compression will be used unless GnuPG detects that the +plaintext is already compressed. ASCII armouring will be +determined according to the value of gpg.Context().armor. +

+ +

+The compression algorithm is selected in much the same way as the +symmetric encryption algorithm or the hash digest algorithm is +when multiple keys are involved; from the preferences saved into +the key itself or by comparison with the preferences with all +other keys involved. +

+ +
+
import gpg
+
+text0 = """Declaration of ... something.
+
+"""
+text = text0.encode()
+
+c = gpg.Context(armor=True, signers=sig_src)
+signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL)
+
+with open("/path/to/statement.txt.asc", "w") as afile:
+    afile.write(signed_data.decode())
+
+
+ +

+Though everything in this example is accurate, it is more likely +that reading the input data from another file and writing the +result to a new file will be performed more like the way it is done +in the next example. Even if the output format is ASCII armoured. +

+ +
+
import gpg
+
+with open("/path/to/statement.txt", "rb") as tfile:
+    text = tfile.read()
+
+c = gpg.Context()
+signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL)
+
+with open("/path/to/statement.txt.sig", "wb") as afile:
+    afile.write(signed_data)
+
+
+
+
+ + +
+

6.3.3 Detached signing messages and files

+
+

+Detached signatures will often be needed in programmatic uses of +GPGME, either for signing files (e.g. tarballs of code releases) +or as a component of message signing (e.g. PGP/MIME encoded +email). +

+ +
+
import gpg
+
+text0 = """Declaration of ... something.
+
+"""
+text = text0.encode()
+
+c = gpg.Context(armor=True)
+signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH)
+
+with open("/path/to/statement.txt.asc", "w") as afile:
+    afile.write(signed_data.decode())
+
+
+ +

+As with normal signatures, detached signatures are best handled as +byte literals, even when the output is ASCII armoured. +

+ +
+
import gpg
+
+with open("/path/to/statement.txt", "rb") as tfile:
+    text = tfile.read()
+
+c = gpg.Context(signers=sig_src)
+signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH)
+
+with open("/path/to/statement.txt.sig", "wb") as afile:
+    afile.write(signed_data)
+
+
+
+
+ + +
+

6.3.4 Clearsigning messages or text

+
+

+Though PGP/in-line messages are no longer encouraged in favour of +PGP/MIME, there is still sometimes value in utilising in-line +signatures. This is where clear-signed messages or text is of +value. +

+ +
+
import gpg
+
+text0 = """Declaration of ... something.
+
+"""
+text = text0.encode()
+
+c = gpg.Context()
+signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR)
+
+with open("/path/to/statement.txt.asc", "w") as afile:
+    afile.write(signed_data.decode())
+
+
+ +

+In spite of the appearance of a clear-signed message, the data +handled by GPGME in signing it must still be byte literals. +

+ +
+
import gpg
+
+with open("/path/to/statement.txt", "rb") as tfile:
+    text = tfile.read()
+
+c = gpg.Context()
+signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR)
+
+with open("/path/to/statement.txt.asc", "wb") as afile:
+    afile.write(signed_data)
+
+
+
+
+
+ + +
+

6.4 Signature verification

+
+

+Essentially there are two principal methods of verification of a +signature. The first of these is for use with the normal or +default signing method and for clear-signed messages. The second is +for use with files and data with detached signatures. +

+ +

+The following example is intended for use with the default signing +method where the file was not ASCII armoured: +

+ +
+
import gpg
+import time
+
+filename = "statement.txt"
+gpg_file = "statement.txt.gpg"
+
+c = gpg.Context()
+
+try:
+    data, result = c.verify(open(gpg_file))
+    verified = True
+except gpg.errors.BadSignatures as e:
+    verified = False
+    print(e)
+
+if verified is True:
+    for i in range(len(result.signatures)):
+    sign = result.signatures[i]
+    print("""Good signature from:
+{0}
+with key {1}
+made at {2}
+""".format(c.get_key(sign.fpr).uids[0].uid,
+       sign.fpr, time.ctime(sign.timestamp)))
+else:
+    pass
+
+
+ +

+Whereas this next example, which is almost identical would work +with normal ASCII armoured files and with clear-signed files: +

+ +
+
import gpg
+import time
+
+filename = "statement.txt"
+asc_file = "statement.txt.asc"
+
+c = gpg.Context()
+
+try:
+    data, result = c.verify(open(asc_file))
+    verified = True
+except gpg.errors.BadSignatures as e:
+    verified = False
+    print(e)
+
+if verified is True:
+    for i in range(len(result.signatures)):
+    sign = result.signatures[i]
+    print("""Good signature from:
+{0}
+with key {1}
+made at {2}
+""".format(c.get_key(sign.fpr).uids[0].uid,
+       sign.fpr, time.ctime(sign.timestamp)))
+else:
+    pass
+
+
+ +

+In both of the previous examples it is also possible to compare the +original data that was signed against the signed data in data to +see if it matches with something like this: +

+ +
+
with open(filename, "rb") as afile:
+    text = afile.read()
+
+if text == data:
+    print("Good signature.")
+else:
+    pass
+
+
+ +

+The following two examples, however, deal with detached signatures. +With his method of verification the data that was signed does not +get returned since it is already being explicitly referenced in the +first argument of c.verify. So data is None and only the +information in result is available. +

+ +
+
import gpg
+import time
+
+filename = "statement.txt"
+sig_file = "statement.txt.sig"
+
+c = gpg.Context()
+
+try:
+    data, result = c.verify(open(filename), open(sig_file))
+    verified = True
+except gpg.errors.BadSignatures as e:
+    verified = False
+    print(e)
+
+if verified is True:
+    for i in range(len(result.signatures)):
+    sign = result.signatures[i]
+    print("""Good signature from:
+{0}
+with key {1}
+made at {2}
+""".format(c.get_key(sign.fpr).uids[0].uid,
+       sign.fpr, time.ctime(sign.timestamp)))
+else:
+    pass
+
+
+ +
+
import gpg
+import time
+
+filename = "statement.txt"
+asc_file = "statement.txt.asc"
+
+c = gpg.Context()
+
+try:
+    data, result = c.verify(open(filename), open(asc_file))
+    verified = True
+except gpg.errors.BadSignatures as e:
+    verified = False
+    print(e)
+
+if verified is not None:
+    for i in range(len(result.signatures)):
+    sign = result.signatures[i]
+    print("""Good signature from:
+{0}
+with key {1}
+made at {2}
+""".format(c.get_key(sign.fpr).uids[0].uid,
+       sign.fpr, time.ctime(sign.timestamp)))
+else:
+    pass
+
+
+
+
+
+ + +
+

7 Creating keys and subkeys

+
+

+The one thing, aside from GnuPG itself, that GPGME depends on, of +course, is the keys themselves. So it is necessary to be able to +generate them and modify them by adding subkeys, revoking or +disabling them, sometimes deleting them and doing the same for user +IDs. +

+ +

+In the following examples a key will be created for the world's +greatest secret agent, Danger Mouse. Since Danger Mouse is a secret +agent he needs to be able to protect information to SECRET level +clearance, so his keys will be 3072-bit keys. +

+ +

+The pre-configured gpg.conf file which sets cipher, digest and +other preferences contains the following configuration parameters: +

+ +
+
expert
+allow-freeform-uid
+allow-secret-key-import
+trust-model tofu+pgp
+tofu-default-policy unknown
+enable-large-rsa
+enable-dsa2
+# cert-digest-algo SHA256
+cert-digest-algo SHA512
+default-preference-list TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 ZLIB BZIP2 ZIP Uncompressed
+personal-cipher-preferences TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES
+personal-digest-preferences SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1
+personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
+
+
+
+ + +
+

7.1 Primary key

+
+

+Generating a primary key uses the create_key method in a Context. +It contains multiple arguments and keyword arguments, including: +userid, algorithm, expires_in, expires, sign, encrypt, +certify, authenticate, passphrase and force. The defaults +for all of those except userid, algorithm, expires_in, +expires and passphrase is False. The defaults for +algorithm and passphrase is None. The default for +expires_in is 0. The default for expires is True. There +is no default for userid. +

+ +

+If passphrase is left as None then the key will not be +generated with a passphrase, if passphrase is set to a string +then that will be the passphrase and if passphrase is set to +True then gpg-agent will launch pinentry to prompt for a +passphrase. For the sake of convenience, these examples will keep +passphrase set to None. +

+ +
+
import gpg
+
+c = gpg.Context()
+
+c.home_dir = "~/.gnupg-dm"
+userid = "Danger Mouse <dm at secret.example.net>"
+
+dmkey = c.create_key(userid, algorithm = "rsa3072", expires_in = 31536000,
+             sign = True, certify = True)
+
+
+ +

+One thing to note here is the use of setting the c.home_dir +parameter. This enables generating the key or keys in a different +location. In this case to keep the new key data created for this +example in a separate location rather than adding it to existing +and active key store data. As with the default directory, +~/.gnupg, any temporary or separate directory needs the +permissions set to only permit access by the directory owner. On +posix systems this means setting the directory permissions to 700. +

+ +

+The successful generation of the key can be confirmed via the +returned GenkeyResult object, which includes the following data: +

+ +
+
print("""
+Fingerprint:  {0}
+Primary Key:  {1}
+ Public Key:  {2}
+ Secret Key:  {3}
+    Sub Key:  {4}
+   User IDs:  {5}
+""".format(dmkey.fpr, dmkey.primary, dmkey.pubkey, dmkey.seckey, dmkey.sub,
+       dmkey.uid))
+
+
+ +

+Alternatively the information can be confirmed using the command +line program: +

+ +
+
bash-4.4$ gpg --homedir ~/.gnupg-dm -K
+~/.gnupg-dm/pubring.kbx
+----------------------
+sec   rsa3072 2018-03-15 [SC] [expires: 2019-03-15]
+      177B7C25DB99745EE2EE13ED026D2F19E99E63AA
+uid           [ultimate] Danger Mouse <dm at secret.example.net>
+
+bash-4.4$
+
+
+ +

+As with generating keys manually, to preconfigure expanded +preferences for the cipher, digest and compression algorithms, the +gpg.conf file must contain those details in the home directory in +which the new key is being generated. I used a cut down version of +my own gpg.conf file in order to be able to generate this: +

+ +
+
bash-4.4$ gpg --homedir ~/.gnupg-dm --edit-key 177B7C25DB99745EE2EE13ED026D2F19E99E63AA showpref quit
+Secret key is available.
+
+sec  rsa3072/026D2F19E99E63AA
+     created: 2018-03-15  expires: 2019-03-15  usage: SC
+     trust: ultimate      validity: ultimate
+[ultimate] (1). Danger Mouse <dm at secret.example.net>
+
+[ultimate] (1). Danger Mouse <dm at secret.example.net>
+     Cipher: TWOFISH, CAMELLIA256, AES256, CAMELLIA192, AES192, CAMELLIA128, AES, BLOWFISH, IDEA, CAST5, 3DES
+     Digest: SHA512, SHA384, SHA256, SHA224, RIPEMD160, SHA1
+     Compression: ZLIB, BZIP2, ZIP, Uncompressed
+     Features: MDC, Keyserver no-modify
+
+bash-4.4$
+
+
+
+
+ + +
+

7.2 Subkeys

+
+

+Adding subkeys to a primary key is fairly similar to creating the +primary key with the create_subkey method. Most of the arguments +are the same, but not quite all. Instead of the userid argument +there is now a key argument for selecting which primary key to +add the subkey to. +

+ +

+In the following example an encryption subkey will be added to the +primary key. Since Danger Mouse is a security conscious secret +agent, this subkey will only be valid for about six months, half +the length of the primary key. +

+ +
+
import gpg
+
+c = gpg.Context()
+c.home_dir = "~/.gnupg-dm"
+
+key = c.get_key(dmkey.fpr, secret = True)
+dmsub = c.create_subkey(key, algorithm = "rsa3072", expires_in = 15768000,
+            encrypt = True)
+
+
+ +

+As with the primary key, the results here can be checked with: +

+ +
+
print("""
+Fingerprint:  {0}
+Primary Key:  {1}
+ Public Key:  {2}
+ Secret Key:  {3}
+    Sub Key:  {4}
+   User IDs:  {5}
+""".format(dmsub.fpr, dmsub.primary, dmsub.pubkey, dmsub.seckey, dmsub.sub,
+       dmsub.uid))
+
+
+ +

+As well as on the command line with: +

+ +
+
bash-4.4$ gpg --homedir ~/.gnupg-dm -K
+~/.gnupg-dm/pubring.kbx
+----------------------
+sec   rsa3072 2018-03-15 [SC] [expires: 2019-03-15]
+      177B7C25DB99745EE2EE13ED026D2F19E99E63AA
+uid           [ultimate] Danger Mouse <dm at secret.example.net>
+ssb   rsa3072 2018-03-15 [E] [expires: 2018-09-13]
+
+bash-4.4$
+
+
+
+
+ + +
+

7.3 User IDs

+
+

+By comparison to creating primary keys and subkeys, adding a new +user ID to an existing key is much simpler. The method used to do +this is key_add_uid and the only arguments it takes are for the +key and the new uid. +

+ +
+
import gpg
+
+c = gpg.Context()
+c.home_dir = "~/.gnupg-dm"
+
+dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA"
+key = c.get_key(dmfpr, secret = True)
+uid = "Danger Mouse <danger.mouse at secret.example.net>"
+
+c.key_add_uid(key, uid)
+
+
+ +

+Unsurprisingly the result of this is: +

+ +
+
bash-4.4$ gpg --homedir ~/.gnupg-dm -K
+~/.gnupg-dm/pubring.kbx
+----------------------
+sec   rsa3072 2018-03-15 [SC] [expires: 2019-03-15]
+      177B7C25DB99745EE2EE13ED026D2F19E99E63AA
+uid           [ultimate] Danger Mouse <danger.mouse at secret.example.net>
+uid           [ultimate] Danger Mouse <dm at secret.example.net>
+ssb   rsa3072 2018-03-15 [E] [expires: 2018-09-13]
+
+bash-4.4$
+
+
+
+
+ + +
+

7.4 Key certification

+
+

+Since key certification is more frequently referred to as key +signing, the method used to perform this function is key_sign. +

+ +

+The key_sign method takes four arguments: key, uids, +expires_in and local. The default value of uids is None +and which results in all user IDs being selected. The default +values of expires_in snd local is False; which result in the +signature never expiring and being able to be exported. +

+ +

+The key is the key being signed rather than the key doing the +signing. To change the key doing the signing refer to the signing +key selection above for signing messages and files. +

+ +

+If the uids value is not None then it must either be a string +to match a single user ID or a list of strings to match multiple +user IDs. In this case the matching of those strings must be +precise and it is case sensitive. +

+ +

+To sign Danger Mouse's key for just the initial user ID with a +signature which will last a little over a month, do this: +

+ +
+
import gpg
+
+c = gpg.Context()
+uid = "Danger Mouse <dm at secret.example.net>"
+
+dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA"
+key = c.get_key(dmfpr, secret = True)
+c.key_sign(key, uids = uid, expires_in = 2764800)
+
+
+
+
+
+ + +
+

8 Miscellaneous work-arounds

+
+
+ + +
+

8.1 Group lines

+
+

+There is not yet an easy way to access groups configured in the +gpg.conf file from within GPGME. As a consequence these central +groupings of keys cannot be shared amongst multiple programs, such +as MUAs readily. +

+ +

+The following code, however, provides a work-around for obtaining +this information in Python. +

+ +
+
import subprocess
+
+lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines()
+
+for i in range(len(lines)):
+    if lines[i].startswith("group") is True:
+    line = lines[i]
+    else:
+    pass
+
+groups = line.split(":")[-1].replace('"', '').split(',')
+
+group_lines = groups
+for i in range(len(group_lines)):
+    group_lines[i] = group_lines[i].split("=")
+
+group_lists = group_lines
+for i in range(len(group_lists)):
+    group_lists[i][1] = group_lists[i][1].split()
+
+
+ +

+The result of that code is that group_lines is a list of lists +where group_lines[i][0] is the name of the group and +group_lines[i][1] is the key IDs of the group as a string. +

+ +

+The group_lists result is very similar in that it is a list of +lists. The first part, group_lists[i][0] matches +group_lines[i][0] as the name of the group, but +group_lists[i][1] is the key IDs of the group as a string. +

+
+
+
+ + +
+ + + + +
+ + +
+ + +
+

9.2 License GPL compatible

+
+

+This file is free software; as a special exception the author gives +unlimited permission to copy and/or distribute it, with or without +modifications, as long as this notice is preserved. +

+ +

+This file is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY, to the extent permitted by law; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. +

+
+
+
+
+

Footnotes:

+
+ +
1

+Short_History.org and/or Short_History.html. +

+ +
2

+The lang/python/docs/ directory in the GPGME source. +

+ +
3

+You probably don't really want to do this. Searching the +keyservers for "gnupg.org" produces over 400 results, the majority of +which aren't actually at the gnupg.org domain, but just included a +comment regarding the project in their key somewhere. +

+ + +
+
+
+

Author: Ben McGinnes

+

Created: 2018-03-22 Thu 10:59

+

Validate

+
+ + diff --git a/web/documentation/howtos.org b/web/documentation/howtos.org index 264f425..ec81daa 100644 --- a/web/documentation/howtos.org +++ b/web/documentation/howtos.org @@ -118,3 +118,14 @@ This HOWTO is available: - as an online HTML article ( [[https://maslosoft.com/blog/2017/09/12/using-gpg-with-php-on-server/][en]] ) + +** GPGME Python Bindings HOWTO + + Written "in house" by the GnuPG Project core team, the GPGME Python + Bindings HOWTO provides detailed instructions and examples for + using the Python bindings of the GPGME API with Python 3 code. + + This HOWTO is available: + + - in its original Emacs Org Mode source form in the GPGME repository ( [[https://dev.gnupg.org/source/gpgme/browse/master/lang/python/docs/GPGMEpythonHOWTOen.org][en]] ) + - as an online HTML file ( [[../howtos/en/GPGMEpythonHOWTOen.html][en]] ) ----------------------------------------------------------------------- Summary of changes: misc/howtos.gnupg.org/en/GPGMEpythonHOWTOen.html | 2003 ++++++++++++++++++++++ web/documentation/howtos.org | 11 + 2 files changed, 2014 insertions(+) create mode 100644 misc/howtos.gnupg.org/en/GPGMEpythonHOWTOen.html hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 01:38:47 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 22 Mar 2018 01:38:47 +0100 Subject: [git] gnupg-doc - branch, master, updated. ce7ba56dfdd69f431af32a0638b2a108a02c663b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via ce7ba56dfdd69f431af32a0638b2a108a02c663b (commit) from 8cf29941c754d386f1d81fc4a52450cd2a9e0f7b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ce7ba56dfdd69f431af32a0638b2a108a02c663b Author: Ben McGinnes Date: Thu Mar 22 11:36:54 2018 +1100 HOWTO path adjustment * Adjusted howto to just load from the docs dir for now. diff --git a/web/documentation/GPGMEpythonHOWTOen.org b/web/documentation/GPGMEpythonHOWTOen.org new file mode 100644 index 0000000..1e8dd9f --- /dev/null +++ b/web/documentation/GPGMEpythonHOWTOen.org @@ -0,0 +1,1370 @@ +#+TITLE: GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English) +#+LATEX_COMPILER: xelatex +#+LATEX_CLASS: article +#+LATEX_CLASS_OPTIONS: [12pt] +#+LATEX_HEADER: \usepackage{xltxtra} +#+LATEX_HEADER: \usepackage[margin=1in]{geometry} +#+LATEX_HEADER: \setmainfont[Ligatures={Common}]{Times New Roman} +#+LATEX_HEADER: \author{Ben McGinnes } + + +* Introduction + :PROPERTIES: + :CUSTOM_ID: intro + :END: + + | Version: | 0.1.0 | + | Author: | Ben McGinnes | + | Author GPG Key: | DB4724E6FA4286C92B4E55C4321E4E2373590E5D | + | Language: | Australian English, British English | + | xml:lang: | en-AU, en-GB, en | + + This document provides basic instruction in how to use the GPGME + Python bindings to programmatically leverage the GPGME library. + + +** Python 2 versus Python 3 + :PROPERTIES: + :CUSTOM_ID: py2-vs-py3 + :END: + + Though the GPGME Python bindings themselves provide support for + both Python 2 and 3, the focus is unequivocally on Python 3 and + specifically from Python 3.4 and above. As a consequence all the + examples and instructions in this guide use Python 3 code. + + Much of it will work with Python 2, but much of it also deals with + Python 3 byte literals, particularly when reading and writing data. + Developers concentrating on Python 2.7, and possibly even 2.6, will + need to make the appropriate modifications to support the older + string and unicode types as opposed to bytes. + + There are multiple reasons for concentrating on Python 3; some of + which relate to the immediate integration of these bindings, some + of which relate to longer term plans for both GPGME and the python + bindings and some of which relate to the impending EOL period for + Python 2.7. Essentially, though, there is little value in tying + the bindings to a version of the language which is a dead end and + the advantages offered by Python 3 over Python 2 make handling the + data types with which GPGME deals considerably easier. + + +** Examples + :PROPERTIES: + :CUSTOM_ID: howto-python3-examples + :END: + + All of the examples found in this document can be found as Python 3 + scripts in the =lang/python/examples/howto= directory. + + +* GPGME Concepts + :PROPERTIES: + :CUSTOM_ID: gpgme-concepts + :END: + + +** A C API + :PROPERTIES: + :CUSTOM_ID: gpgme-c-api + :END: + + Unlike many modern APIs with which programmers will be more + familiar with these days, the GPGME API is a C API. The API is + intended for use by C coders who would be able to access its + features by including the =gpgme.h= header file with their own C + source code and then access its functions just as they would any + other C headers. + + This is a very effective method of gaining complete access to the + API and in the most efficient manner possible. It does, however, + have the drawback that it cannot be directly used by other + languages without some means of providing an interface to those + languages. This is where the need for bindings in various + languages stems. + + +** Python bindings + :PROPERTIES: + :CUSTOM_ID: gpgme-python-bindings + :END: + + The Python bindings for GPGME provide a higher level means of + accessing the complete feature set of GPGME itself. It also + provides a more pythonic means of calling these API functions. + + The bindings are generated dynamically with SWIG and the copy of + =gpgme.h= generated when GPGME is compiled. + + This means that a version of the Python bindings is fundamentally + tied to the exact same version of GPGME used to generate that copy + of =gpgme.h=. + + +** Difference between the Python bindings and other GnuPG Python packages + :PROPERTIES: + :CUSTOM_ID: gpgme-python-bindings-diffs + :END: + + There have been numerous attempts to add GnuPG support to Python + over the years. Some of the most well known are listed here, along + with what differentiates them. + + +*** The python-gnupg package maintained by Vinay Sajip + :PROPERTIES: + :CUSTOM_ID: diffs-python-gnupg + :END: + + This is arguably the most popular means of integrating GPG with + Python. The package utilises the =subprocess= module to implement + wrappers for the =gpg= and =gpg2= executables normally invoked on + the command line (=gpg.exe= and =gpg2.exe= on Windows). + + The popularity of this package stemmed from its ease of use and + capability in providing the most commonly required features. + + Unfortunately it has been beset by a number of security issues in + the past; most of which stemmed from using unsafe methods of + accessing the command line via the =subprocess= calls. While some + effort has been made over the last two to three years (as of 2018) + to mitigate this, particularly by no longer providing shell access + through those subprocess calls, the wrapper is still somewhat + limited in the scope of its GnuPG features coverage. + + The python-gnupg package is available under the MIT license. + + +*** The gnupg package created and maintained by Isis Lovecruft + :PROPERTIES: + :CUSTOM_ID: diffs-isis-gnupg + :END: + + In 2015 Isis Lovecruft from the Tor Project forked and then + re-implemented the python-gnupg package as just gnupg. This new + package also relied on subprocess to call the =gpg= or =gpg2= + binaries, but did so somewhat more securely. + + The naming and version numbering selected for this package, + however, resulted in conflicts with the original python-gnupg and + since its functions were called in a different manner to + python-gnupg, the release of this package also resulted in a great + deal of consternation when people installed what they thought was + an upgrade that subsequently broke the code relying on it. + + The gnupg package is available under the GNU General Public + License version 3.0 (or any later version). + + +*** The PyME package maintained by Martin Albrecht + :PROPERTIES: + :CUSTOM_ID: diffs-pyme + :END: + + This package is the origin of these bindings, though they are + somewhat different now. For details of when and how the PyME + package was folded back into GPGME itself see the /Short History/ + document[fn:1] in this Python bindings =docs= directory.[fn:2] + + The PyME package was first released in 2002 and was also the first + attempt to implement a low level binding to GPGME. In doing so it + provided access to considerably more functionality than either the + =python-gnupg= or =gnupg= packages. + + The PyME package is only available for Python 2.6 and 2.7. + + Porting the PyME package to Python 3.4 in 2015 is what resulted in + it being folded into the GPGME project and the current bindings + are the end result of that effort. + + The PyME package is available under the same dual licensing as + GPGME itself: the GNU General Public License version 2.0 (or any + later version) and the GNU Lesser General Public License version + 2.1 (or any later version). + + +* GPGME Python bindings installation + :PROPERTIES: + :CUSTOM_ID: gpgme-python-install + :END: + + +** No PyPI + :PROPERTIES: + :CUSTOM_ID: do-not-use-pypi + :END: + + 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. + + This is because the bindings use SWIG to dynamically generate C + bindings against =gpgme.h= and =gpgme.h= is generated from + =gpgme.h.in= 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. + + +** Requirements + :PROPERTIES: + :CUSTOM_ID: gpgme-python-requirements + :END: + + The GPGME Python bindings only have three requirements: + + 1. A suitable version of Python 2 or Python 3. With Python 2 that + means Python 2.7 and with Python 3 that means Python 3.4 or + higher. + 2. SWIG. + 3. GPGME itself. Which also means that all of GPGME's dependencies + must be installed too. + + +** Installation + :PROPERTIES: + :CUSTOM_ID: installation + :END: + + Installing the Python bindings is effectively achieved by compiling + and installing GPGME itself. + + Once SWIG is installed with Python and all the dependencies for + GPGME are installed you only need to confirm that the version(s) of + Python you want the bindings installed for are in your =$PATH=. + + By default GPGME will attempt to install the bindings for the most + recent or highest version number of Python 2 and Python 3 it + detects in =$PATH=. It specifically checks for the =python= and + =python3= executables first and then checks for specific version + numbers. + + For Python 2 it checks for these executables in this order: + =python=, =python2= and =python2.7=. + + For Python 3 it checks for these executables in this order: + =python3=, =python3.6=, =python3.5= and =python3.4=. + + +*** Installing GPGME + :PROPERTIES: + :CUSTOM_ID: install-gpgme + :END: + + See the GPGME =README= file for details of how to install GPGME from + source. + + +* Fundamentals + :PROPERTIES: + :CUSTOM_ID: howto-fund-a-mental + :END: + + Before we can get to the fun stuff, there are a few matters + regarding GPGME's design which hold true whether you're dealing with + the C code directly or these Python bindings. + + +** No REST + :PROPERTIES: + :CUSTOM_ID: no-rest-for-the-wicked + :END: + + The first part of which is or will be fairly blatantly obvious upon + viewing the first example, but it's worth reiterating anyway. That + being that this API is /*not*/ a REST API. Nor indeed could it + ever be one. + + Most, if not all, Python programmers (and not just Python + programmers) know how easy it is to work with a RESTful API. In + fact they've become so popular that many other APIs attempt to + emulate REST-like behaviour as much as they are able. Right down + to the use of JSON formatted output to facilitate the use of their + API without having to retrain developers. + + This API does not do that. It would not be able to do that and + also provide access to the entire C API on which it's built. It + does, however, provide a very pythonic interface on top of the + direct bindings and it's this pythonic layer with which this HOWTO + deals with. + + +** Context + :PROPERTIES: + :CUSTOM_ID: howto-get-context + :END: + + One of the reasons which prevents this API from being RESTful is + that most operations require more than one instruction to the API + to perform the task. Sure, there are certain functions which can + be performed simultaneously, particularly if the result known or + strongly anticipated (e.g. selecting and encrypting to a key known + to be in the public keybox). + + There are many more, however, which cannot be manipulated so + readily: they must be performed in a specific sequence and the + result of one operation has a direct bearing on the outcome of + subsequent operations. Not merely by generating an error either. + + When dealing with this type of persistent state on the web, full of + both the RESTful and REST-like, it's most commonly referred to as a + session. In GPGME, however, it is called a context and every + operation type has one. + + +* Working with keys + :PROPERTIES: + :CUSTOM_ID: howto-keys + :END: + + +** Key selection + :PROPERTIES: + :CUSTOM_ID: howto-keys-selection + :END: + + Selecting keys to encrypt to or to sign with will be a common + occurrence when working with GPGMe and the means available for + doing so are quite simple. + + They do depend on utilising a Context; however once the data is + recorded in another variable, that Context does not need to be the + same one which subsequent operations are performed. + + The easiest way to select a specific key is by searching for that + key's key ID or fingerprint, preferably the full fingerprint + without any spaces in it. A long key ID will probably be okay, but + is not advised and short key IDs are already a problem with some + being generated to match specific patterns. It does not matter + whether the pattern is upper or lower case. + + So this is the best method: + + #+begin_src python + import gpg + + k = gpg.Context().keylist(pattern="258E88DCBD3CD44D8E7AB43F6ECB6AF0DEADBEEF") + keys = list(k) + #+end_src + + This is passable and very likely to be common: + + #+begin_src python + import gpg + + k = gpg.Context().keylist(pattern="0x6ECB6AF0DEADBEEF") + keys = list(k) + #+end_src + + And this is a really bad idea: + + #+begin_src python + import gpg + + k = gpg.Context().keylist(pattern="0xDEADBEEF") + keys = list(k) + #+end_src + + Alternatively it may be that the intention is to create a list of + keys which all match a particular search string. For instance all + the addresses at a particular domain, like this: + + #+begin_src python + import gpg + + ncsc = gpg.Context().keylist(pattern="ncsc.mil") + nsa = list(ncsc) + #+end_src + + +*** Counting keys + :PROPERTIES: + :CUSTOM_ID: howto-keys-counting + :END: + + Counting the number of keys in your public keybox (=pubring.kbx=), + the format which has superseded the old keyring format + (=pubring.gpg= and =secring.gpg=), or the number of secret keys is + a very simple task. + + #+begin_src python + import gpg + + c = gpg.Context() + seckeys = c.keylist(pattern=None, secret=True) + pubkeys = c.keylist(pattern=None, secret=False) + + seclist = list(seckeys) + secnum = len(seclist) + + publist = list(pubkeys) + pubnum = len(publist) + + print(""" + Number of secret keys: {0} + Number of public keys: {1} + """.format(secnum, pubnum)) + #+end_src + + +** Get key + :PROPERTIES: + :CUSTOM_ID: howto-get-key + :END: + + An alternative method of getting a single key via its fingerprint + is available directly within a Context with =Context().get_key=. + This is the preferred method of selecting a key in order to modify + it, sign or certify it and for obtaining relevant data about a + single key as a part of other functions; when verifying a signature + made by that key, for instance. + + By default this method will select public keys, but it can select + secret keys as well. + + This first example demonstrates selecting the current key of Werner + Koch, which is due to expire at the end of 2018: + + #+begin_src python + import gpg + + fingerprint = "80615870F5BAD690333686D0F2AD85AC1E42B367" + key = gpg.Context().get_key(fingerprint) + #+end_src + + Whereas this example demonstrates selecting the author's current + key with the =secret= key word argument set to =True=: + + #+begin_src python + import gpg + + fingerprint = "DB4724E6FA4286C92B4E55C4321E4E2373590E5D" + key = gpg.Context().get_key(fingerprint, secret=True) + #+end_src + + It is, of course, quite possible to select expired, disabled and + revoked keys with this function, but only to effectively display + information about those keys. + + It is also possible to use both unicode or string literals and byte + literals with the fingerprint when getting a key in this way. + + +* Basic Functions + :PROPERTIES: + :CUSTOM_ID: howto-the-basics + :END: + + The most frequently called features of any cryptographic library + will be the most fundamental tasks for encryption software. In this + section we will look at how to programmatically encrypt data, + decrypt it, sign it and verify signatures. + + +** Encryption + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption + :END: + + Encrypting is very straight forward. In the first example below + the message, =text=, is encrypted to a single recipient's key. In + the second example the message will be encrypted to multiple + recipients. + + +*** Encrypting to one key + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption-single + :END: + + Once the the Context is set the main issues with encrypting data + is essentially reduced to key selection and the keyword arguments + specified in the =gpg.Context().encrypt()= method. + + Those keyword arguments are: =recipients=, a list of keys + encrypted to (covered in greater detail in the following section); + =sign=, whether or not to sign the plaintext data, see subsequent + sections on signing and verifying signatures below (defaults to + =True=); =sink=, to write results or partial results to a secure + sink instead of returning it (defaults to =None=); =passphrase=, + only used when utilising symmetric encryption (defaults to + =None=); =always_trust=, used to override the trust model settings + for recipient keys (defaults to =False=); =add_encrypt_to=, + utilises any preconfigured =encrypt-to= or =default-key= settings + in the user's =gpg.conf= file (defaults to =False=); =prepare=, + prepare for encryption (defaults to =False=); =expect_sign=, + prepare for signing (defaults to =False=); =compress=, compresses + the plaintext prior to encryption (defaults to =True=). + + #+begin_src python + import gpg + + a_key = "0x12345678DEADBEEF" + text = b"""Some text to test with. + + 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) + rkey = list(c.keylist(pattern=a_key, secret=False)) + ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=False) + + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(ciphertext) + #+end_src + + Though this is even more likely to be used like this; with the + plaintext input read from a file, the recipient keys used for + encryption regardless of key trust status and the encrypted output + also encrypted to any preconfigured keys set in the =gpg.conf= + file: + + #+begin_src python + import gpg + + a_key = "0x12345678DEADBEEF" + + with open("secret_plans.txt", "rb") as afile: + text = afile.read() + + c = gpg.Context(armor=True) + rkey = list(c.keylist(pattern=a_key, secret=False)) + ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, + sign=True, always_trust=True, + add_encrypt_to=True) + + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(ciphertext) + #+end_src + + If the =recipients= paramater is empty then the plaintext is + encrypted symmetrically. If no =passphrase= is supplied as a + parameter or via a callback registered with the =Context()= then + an out-of-band prompt for the passphrase via pinentry will be + invoked. + + +*** Encrypting to multiple keys + :PROPERTIES: + :CUSTOM_ID: howto-basic-encryption-multiple + :END: + + Encrypting to multiple keys essentially just expands upon the key + selection process and the recipients from the previous examples. + + The following example encrypts a message (=text=) to everyone with + an email address on the =gnupg.org= domain,[fn:3] but does /not/ encrypt + to a default key or other key which is configured to normally + encrypt to. + + #+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]) + + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, sign=False, + always_trust=True) + + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(ciphertext) + #+end_src + + All it would take to change the above example to sign the message + and also encrypt the message to any configured default keys would + be to change the =c.encrypt= line to this: + + #+begin_src python + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, + always_trust=True, + add_encrypt_to=True) + #+end_src + + The only keyword arguments requiring modification are those for + which the default values are changing. The default value of + =sign= is =True=, the default of =always_trust= is =False=, the + default of =add_encrypt_to= is =False=. + + If =always_trust= is not set to =True= and any of the recipient + keys are not trusted (e.g. not signed or locally signed) then the + encryption will raise an error. It is possible to mitigate this + somewhat with something more like this: + + #+begin_src python + import gpg + + with open("secret_plans.txt.asc", "rb") as afile: + text = afile.read() + + 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]) + + try: + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True) + except gpg.errors.InvalidRecipients as e: + for i in range(len(e.recipients)): + for n in range(len(logrus)): + if logrus[n].fpr == e.recipients[i].fpr: + logrus.remove(logrus[n]) + else: + pass + try: + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True) + except: + pass + + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(ciphertext) + #+end_src + + This will attempt to encrypt to all the keys searched for, then + remove invalid recipients if it fails and try again. + + +** Decryption + :PROPERTIES: + :CUSTOM_ID: howto-basic-decryption + :END: + + Decrypting something encrypted to a key in one's secret keyring is + fairly straight forward. + + In this example code, however, preconfiguring either + =gpg.Context()= or =gpg.core.Context()= as =c= is unnecessary + because there is no need to modify the Context prior to conducting + the decryption and since the Context is only used once, setting it + to =c= simply adds lines for no gain. + + #+begin_src python + import gpg + + ciphertext = input("Enter path and filename of encrypted file: ") + newfile = input("Enter path and filename of file to save decrypted data to: ") + with open(ciphertext, "rb") as cfile: + plaintext, result, verify_result = gpg.Context().decrypt(cfile) + with open(newfile, "wb") as nfile: + nfile.write(plaintext) + #+end_src + + The data available in plaintext in this example is the decrypted + content as a byte object in =plaintext[0]=, the recipient key IDs + and algorithms in =plaintext[1]= and the results of verifying any + signatures of the data in =plaintext[0]=. + + +** Signing text and files + :PROPERTIES: + :CUSTOM_ID: howto-basic-signing + :END: + + The following sections demonstrate how to specify keys to sign with. + + +*** Signing key selection + :PROPERTIES: + :CUSTOM_ID: howto-basic-signing-signers + :END: + + By default GPGME and the Python bindings will use the default key + configured for the user invoking the GPGME API. If there is no + default key specified and there is more than one secret key + available it may be necessary to specify the key or keys with + which to sign messages and files. + + #+begin_src python + import gpg + + logrus = input("Enter the email address or string to match signing keys to: ") + hancock = gpg.Context().keylist(pattern=logrus, secret=True) + sig_src = list(hancock) + #+end_src + + The signing examples in the following sections include the + explicitly designated =signers= parameter in two of the five + examples; once where the resulting signature would be ASCII + armoured and once where it would not be armoured. + + While it would be possible to enter a key ID or fingerprint here + to match a specific key, it is not possible to enter two + fingerprints and match two keys since the patten expects a string, + bytes or None and not a list. A string with two fingerprints + won't match any single key. + + +*** Normal or default signing messages or files + :PROPERTIES: + :CUSTOM_ID: howto-basic-signing-normal + :END: + + The normal or default signing process is essentially the same as + is most often invoked when also encrypting a message or file. So + when the encryption component is not utilised, the result is to + produce an encoded and signed output which may or may not be ASCII + armoured and which may or may not also be compressed. + + By default compression will be used unless GnuPG detects that the + plaintext is already compressed. ASCII armouring will be + determined according to the value of =gpg.Context().armor=. + + The compression algorithm is selected in much the same way as the + symmetric encryption algorithm or the hash digest algorithm is + when multiple keys are involved; from the preferences saved into + the key itself or by comparison with the preferences with all + other keys involved. + + #+begin_src python + import gpg + + text0 = """Declaration of ... something. + + """ + text = text0.encode() + + c = gpg.Context(armor=True, signers=sig_src) + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) + + with open("/path/to/statement.txt.asc", "w") as afile: + afile.write(signed_data.decode()) + #+end_src + + Though everything in this example is accurate, it is more likely + that reading the input data from another file and writing the + result to a new file will be performed more like the way it is done + in the next example. Even if the output format is ASCII armoured. + + #+begin_src python + import gpg + + with open("/path/to/statement.txt", "rb") as tfile: + text = tfile.read() + + c = gpg.Context() + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) + + with open("/path/to/statement.txt.sig", "wb") as afile: + afile.write(signed_data) + #+end_src + + +*** Detached signing messages and files + :PROPERTIES: + :CUSTOM_ID: howto-basic-signing-detached + :END: + + Detached signatures will often be needed in programmatic uses of + GPGME, either for signing files (e.g. tarballs of code releases) + or as a component of message signing (e.g. PGP/MIME encoded + email). + + #+begin_src python + import gpg + + text0 = """Declaration of ... something. + + """ + text = text0.encode() + + c = gpg.Context(armor=True) + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) + + with open("/path/to/statement.txt.asc", "w") as afile: + afile.write(signed_data.decode()) + #+end_src + + As with normal signatures, detached signatures are best handled as + byte literals, even when the output is ASCII armoured. + + #+begin_src python + import gpg + + with open("/path/to/statement.txt", "rb") as tfile: + text = tfile.read() + + c = gpg.Context(signers=sig_src) + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) + + with open("/path/to/statement.txt.sig", "wb") as afile: + afile.write(signed_data) + #+end_src + + +*** Clearsigning messages or text + :PROPERTIES: + :CUSTOM_ID: howto-basic-signing-clear + :END: + + Though PGP/in-line messages are no longer encouraged in favour of + PGP/MIME, there is still sometimes value in utilising in-line + signatures. This is where clear-signed messages or text is of + value. + + #+begin_src python + import gpg + + text0 = """Declaration of ... something. + + """ + text = text0.encode() + + c = gpg.Context() + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) + + with open("/path/to/statement.txt.asc", "w") as afile: + afile.write(signed_data.decode()) + #+end_src + + In spite of the appearance of a clear-signed message, the data + handled by GPGME in signing it must still be byte literals. + + #+begin_src python + import gpg + + with open("/path/to/statement.txt", "rb") as tfile: + text = tfile.read() + + c = gpg.Context() + signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) + + with open("/path/to/statement.txt.asc", "wb") as afile: + afile.write(signed_data) + #+end_src + + +** Signature verification + :PROPERTIES: + :CUSTOM_ID: howto-basic-verification + :END: + + Essentially there are two principal methods of verification of a + signature. The first of these is for use with the normal or + default signing method and for clear-signed messages. The second is + for use with files and data with detached signatures. + + The following example is intended for use with the default signing + method where the file was not ASCII armoured: + + #+begin_src python + import gpg + import time + + filename = "statement.txt" + gpg_file = "statement.txt.gpg" + + c = gpg.Context() + + try: + data, result = c.verify(open(gpg_file)) + verified = True + except gpg.errors.BadSignatures as e: + verified = False + print(e) + + if verified is True: + for i in range(len(result.signatures)): + sign = result.signatures[i] + print("""Good signature from: + {0} + with key {1} + made at {2} + """.format(c.get_key(sign.fpr).uids[0].uid, + sign.fpr, time.ctime(sign.timestamp))) + else: + pass + #+end_src + + Whereas this next example, which is almost identical would work + with normal ASCII armoured files and with clear-signed files: + + #+begin_src python + import gpg + import time + + filename = "statement.txt" + asc_file = "statement.txt.asc" + + c = gpg.Context() + + try: + data, result = c.verify(open(asc_file)) + verified = True + except gpg.errors.BadSignatures as e: + verified = False + print(e) + + if verified is True: + for i in range(len(result.signatures)): + sign = result.signatures[i] + print("""Good signature from: + {0} + with key {1} + made at {2} + """.format(c.get_key(sign.fpr).uids[0].uid, + sign.fpr, time.ctime(sign.timestamp))) + else: + pass + #+end_src + + In both of the previous examples it is also possible to compare the + original data that was signed against the signed data in =data= to + see if it matches with something like this: + + #+begin_src python + with open(filename, "rb") as afile: + text = afile.read() + + if text == data: + print("Good signature.") + else: + pass + #+end_src + + The following two examples, however, deal with detached signatures. + With his method of verification the data that was signed does not + get returned since it is already being explicitly referenced in the + first argument of =c.verify=. So =data= is =None= and only the + information in =result= is available. + + #+begin_src python + import gpg + import time + + filename = "statement.txt" + sig_file = "statement.txt.sig" + + c = gpg.Context() + + try: + data, result = c.verify(open(filename), open(sig_file)) + verified = True + except gpg.errors.BadSignatures as e: + verified = False + print(e) + + if verified is True: + for i in range(len(result.signatures)): + sign = result.signatures[i] + print("""Good signature from: + {0} + with key {1} + made at {2} + """.format(c.get_key(sign.fpr).uids[0].uid, + sign.fpr, time.ctime(sign.timestamp))) + else: + pass + #+end_src + + #+begin_src python + import gpg + import time + + filename = "statement.txt" + asc_file = "statement.txt.asc" + + c = gpg.Context() + + try: + data, result = c.verify(open(filename), open(asc_file)) + verified = True + except gpg.errors.BadSignatures as e: + verified = False + print(e) + + if verified is not None: + for i in range(len(result.signatures)): + sign = result.signatures[i] + print("""Good signature from: + {0} + with key {1} + made at {2} + """.format(c.get_key(sign.fpr).uids[0].uid, + sign.fpr, time.ctime(sign.timestamp))) + else: + pass + #+end_src + + +* Creating keys and subkeys + :PROPERTIES: + :CUSTOM_ID: key-generation + :END: + + The one thing, aside from GnuPG itself, that GPGME depends on, of + course, is the keys themselves. So it is necessary to be able to + generate them and modify them by adding subkeys, revoking or + disabling them, sometimes deleting them and doing the same for user + IDs. + + In the following examples a key will be created for the world's + greatest secret agent, Danger Mouse. Since Danger Mouse is a secret + agent he needs to be able to protect information to =SECRET= level + clearance, so his keys will be 3072-bit keys. + + The pre-configured =gpg.conf= file which sets cipher, digest and + other preferences contains the following configuration parameters: + + #+begin_src conf + expert + allow-freeform-uid + allow-secret-key-import + trust-model tofu+pgp + tofu-default-policy unknown + enable-large-rsa + enable-dsa2 + # cert-digest-algo SHA256 + cert-digest-algo SHA512 + default-preference-list TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 ZLIB BZIP2 ZIP Uncompressed + personal-cipher-preferences TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES + personal-digest-preferences SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 + personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed + #+end_src + + +** Primary key + :PROPERTIES: + :CUSTOM_ID: keygen-primary + :END: + + Generating a primary key uses the =create_key= method in a Context. + It contains multiple arguments and keyword arguments, including: + =userid=, =algorithm=, =expires_in=, =expires=, =sign=, =encrypt=, + =certify=, =authenticate=, =passphrase= and =force=. The defaults + for all of those except =userid=, =algorithm=, =expires_in=, + =expires= and =passphrase= is =False=. The defaults for + =algorithm= and =passphrase= is =None=. The default for + =expires_in= is =0=. The default for =expires= is =True=. There + is no default for =userid=. + + If =passphrase= is left as =None= then the key will not be + generated with a passphrase, if =passphrase= is set to a string + then that will be the passphrase and if =passphrase= is set to + =True= then gpg-agent will launch pinentry to prompt for a + passphrase. For the sake of convenience, these examples will keep + =passphrase= set to =None=. + + #+begin_src python + import gpg + + c = gpg.Context() + + c.home_dir = "~/.gnupg-dm" + userid = "Danger Mouse " + + dmkey = c.create_key(userid, algorithm = "rsa3072", expires_in = 31536000, + sign = True, certify = True) + #+end_src + + One thing to note here is the use of setting the =c.home_dir= + parameter. This enables generating the key or keys in a different + location. In this case to keep the new key data created for this + example in a separate location rather than adding it to existing + and active key store data. As with the default directory, + =~/.gnupg=, any temporary or separate directory needs the + permissions set to only permit access by the directory owner. On + posix systems this means setting the directory permissions to 700. + + The successful generation of the key can be confirmed via the + returned =GenkeyResult= object, which includes the following data: + + #+begin_src python + print(""" + Fingerprint: {0} + Primary Key: {1} + Public Key: {2} + Secret Key: {3} + Sub Key: {4} + User IDs: {5} + """.format(dmkey.fpr, dmkey.primary, dmkey.pubkey, dmkey.seckey, dmkey.sub, + dmkey.uid)) + #+end_src + + Alternatively the information can be confirmed using the command + line program: + + #+begin_src shell + bash-4.4$ gpg --homedir ~/.gnupg-dm -K + ~/.gnupg-dm/pubring.kbx + ---------------------- + sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] + 177B7C25DB99745EE2EE13ED026D2F19E99E63AA + uid [ultimate] Danger Mouse + + bash-4.4$ + #+end_src + + As with generating keys manually, to preconfigure expanded + preferences for the cipher, digest and compression algorithms, the + =gpg.conf= file must contain those details in the home directory in + which the new key is being generated. I used a cut down version of + my own =gpg.conf= file in order to be able to generate this: + + #+begin_src shell + bash-4.4$ gpg --homedir ~/.gnupg-dm --edit-key 177B7C25DB99745EE2EE13ED026D2F19E99E63AA showpref quit + Secret key is available. + + sec rsa3072/026D2F19E99E63AA + created: 2018-03-15 expires: 2019-03-15 usage: SC + trust: ultimate validity: ultimate + [ultimate] (1). Danger Mouse + + [ultimate] (1). Danger Mouse + Cipher: TWOFISH, CAMELLIA256, AES256, CAMELLIA192, AES192, CAMELLIA128, AES, BLOWFISH, IDEA, CAST5, 3DES + Digest: SHA512, SHA384, SHA256, SHA224, RIPEMD160, SHA1 + Compression: ZLIB, BZIP2, ZIP, Uncompressed + Features: MDC, Keyserver no-modify + + bash-4.4$ + #+end_src + + +** Subkeys + :PROPERTIES: + :CUSTOM_ID: keygen-subkeys + :END: + + Adding subkeys to a primary key is fairly similar to creating the + primary key with the =create_subkey= method. Most of the arguments + are the same, but not quite all. Instead of the =userid= argument + there is now a =key= argument for selecting which primary key to + add the subkey to. + + In the following example an encryption subkey will be added to the + primary key. Since Danger Mouse is a security conscious secret + agent, this subkey will only be valid for about six months, half + the length of the primary key. + + #+begin_src python + import gpg + + c = gpg.Context() + c.home_dir = "~/.gnupg-dm" + + key = c.get_key(dmkey.fpr, secret = True) + dmsub = c.create_subkey(key, algorithm = "rsa3072", expires_in = 15768000, + encrypt = True) + #+end_src + + As with the primary key, the results here can be checked with: + + #+begin_src python + print(""" + Fingerprint: {0} + Primary Key: {1} + Public Key: {2} + Secret Key: {3} + Sub Key: {4} + User IDs: {5} + """.format(dmsub.fpr, dmsub.primary, dmsub.pubkey, dmsub.seckey, dmsub.sub, + dmsub.uid)) + #+end_src + + As well as on the command line with: + + #+begin_src shell + bash-4.4$ gpg --homedir ~/.gnupg-dm -K + ~/.gnupg-dm/pubring.kbx + ---------------------- + sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] + 177B7C25DB99745EE2EE13ED026D2F19E99E63AA + uid [ultimate] Danger Mouse + ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13] + + bash-4.4$ + #+end_src + + +** User IDs + :PROPERTIES: + :CUSTOM_ID: keygen-uids + :END: + + By comparison to creating primary keys and subkeys, adding a new + user ID to an existing key is much simpler. The method used to do + this is =key_add_uid= and the only arguments it takes are for the + =key= and the new =uid=. + + #+begin_src python + import gpg + + c = gpg.Context() + c.home_dir = "~/.gnupg-dm" + + dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" + key = c.get_key(dmfpr, secret = True) + uid = "Danger Mouse " + + c.key_add_uid(key, uid) + #+end_src + + Unsurprisingly the result of this is: + + #+begin_src shell + bash-4.4$ gpg --homedir ~/.gnupg-dm -K + ~/.gnupg-dm/pubring.kbx + ---------------------- + sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] + 177B7C25DB99745EE2EE13ED026D2F19E99E63AA + uid [ultimate] Danger Mouse + uid [ultimate] Danger Mouse + ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13] + + bash-4.4$ + #+end_src + + +** Key certification + :PROPERTIES: + :CUSTOM_ID: key-sign + :END: + + Since key certification is more frequently referred to as key + signing, the method used to perform this function is =key_sign=. + + The =key_sign= method takes four arguments: =key=, =uids=, + =expires_in= and =local=. The default value of =uids= is =None= + and which results in all user IDs being selected. The default + values of =expires_in= snd =local= is =False=; which result in the + signature never expiring and being able to be exported. + + The =key= is the key being signed rather than the key doing the + signing. To change the key doing the signing refer to the signing + key selection above for signing messages and files. + + If the =uids= value is not =None= then it must either be a string + to match a single user ID or a list of strings to match multiple + user IDs. In this case the matching of those strings must be + precise and it is case sensitive. + + To sign Danger Mouse's key for just the initial user ID with a + signature which will last a little over a month, do this: + + #+begin_src python + import gpg + + c = gpg.Context() + uid = "Danger Mouse " + + dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" + key = c.get_key(dmfpr, secret = True) + c.key_sign(key, uids = uid, expires_in = 2764800) + #+end_src + + +* Miscellaneous work-arounds + :PROPERTIES: + :CUSTOM_ID: cheats-and-hacks + :END: + + +** Group lines + :PROPERTIES: + :CUSTOM_ID: group-lines + :END: + + There is not yet an easy way to access groups configured in the + gpg.conf file from within GPGME. As a consequence these central + groupings of keys cannot be shared amongst multiple programs, such + as MUAs readily. + + The following code, however, provides a work-around for obtaining + this information in Python. + + #+begin_src python + import subprocess + + lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines() + + for i in range(len(lines)): + if lines[i].startswith("group") is True: + line = lines[i] + else: + pass + + groups = line.split(":")[-1].replace('"', '').split(',') + + group_lines = groups + for i in range(len(group_lines)): + group_lines[i] = group_lines[i].split("=") + + group_lists = group_lines + for i in range(len(group_lists)): + group_lists[i][1] = group_lists[i][1].split() + #+end_src + + The result of that code is that =group_lines= is a list of lists + where =group_lines[i][0]= is the name of the group and + =group_lines[i][1]= is the key IDs of the group as a string. + + The =group_lists= result is very similar in that it is a list of + lists. The first part, =group_lists[i][0]= matches + =group_lines[i][0]= as the name of the group, but + =group_lists[i][1]= is the key IDs of the group as a string. + + +* Copyright and Licensing + :PROPERTIES: + :CUSTOM_ID: copyright-and-license + :END: + + +** Copyright (C) The GnuPG Project, 2018 + :PROPERTIES: + :CUSTOM_ID: copyright + :END: + + Copyright ? The GnuPG Project, 2018. + + +** License GPL compatible + :PROPERTIES: + :CUSTOM_ID: license + :END: + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + +* Footnotes + +[fn:1] =Short_History.org= and/or =Short_History.html=. + +[fn:2] The =lang/python/docs/= directory in the GPGME source. + +[fn:3] You probably don't really want to do this. Searching the +keyservers for "gnupg.org" produces over 400 results, the majority of +which aren't actually at the gnupg.org domain, but just included a +comment regarding the project in their key somewhere. diff --git a/web/documentation/howtos.org b/web/documentation/howtos.org index ec81daa..2c49e29 100644 --- a/web/documentation/howtos.org +++ b/web/documentation/howtos.org @@ -128,4 +128,4 @@ This HOWTO is available: - in its original Emacs Org Mode source form in the GPGME repository ( [[https://dev.gnupg.org/source/gpgme/browse/master/lang/python/docs/GPGMEpythonHOWTOen.org][en]] ) - - as an online HTML file ( [[../howtos/en/GPGMEpythonHOWTOen.html][en]] ) + - as an online HTML file ( [[GPGMEpythonHOWTOen.html][en]] ) ----------------------------------------------------------------------- Summary of changes: web/documentation/GPGMEpythonHOWTOen.org | 1370 ++++++++++++++++++++++++++++++ web/documentation/howtos.org | 2 +- 2 files changed, 1371 insertions(+), 1 deletion(-) create mode 100644 web/documentation/GPGMEpythonHOWTOen.org hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 01:46:34 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 22 Mar 2018 01:46:34 +0100 Subject: [git] gnupg-doc - branch, master, updated. 58c0da6fc6ed19fbce053f50231cd048ff7b9071 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 58c0da6fc6ed19fbce053f50231cd048ff7b9071 (commit) via bfe16208c988dc61fee827c5c11f92018c4a3a77 (commit) from ce7ba56dfdd69f431af32a0638b2a108a02c663b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 58c0da6fc6ed19fbce053f50231cd048ff7b9071 Author: Ben McGinnes Date: Thu Mar 22 11:46:04 2018 +1100 rm blank line. diff --git a/web/documentation/howtos.org b/web/documentation/howtos.org index 0fd1a8a..8b887ca 100644 --- a/web/documentation/howtos.org +++ b/web/documentation/howtos.org @@ -128,4 +128,3 @@ This HOWTO is available: - in its original Emacs Org Mode source form in the GPGME repository ( [[https://dev.gnupg.org/source/gpgme/browse/master/lang/python/docs/GPGMEpythonHOWTOen.org][en]] ) - commit bfe16208c988dc61fee827c5c11f92018c4a3a77 Author: Ben McGinnes Date: Thu Mar 22 11:44:04 2018 +1100 Nope. * Not leaving it in the docs directory after all, will sort this out later. diff --git a/web/documentation/GPGMEpythonHOWTOen.org b/web/documentation/GPGMEpythonHOWTOen.org deleted file mode 100644 index 1e8dd9f..0000000 --- a/web/documentation/GPGMEpythonHOWTOen.org +++ /dev/null @@ -1,1370 +0,0 @@ -#+TITLE: GNU Privacy Guard (GnuPG) Made Easy Python Bindings HOWTO (English) -#+LATEX_COMPILER: xelatex -#+LATEX_CLASS: article -#+LATEX_CLASS_OPTIONS: [12pt] -#+LATEX_HEADER: \usepackage{xltxtra} -#+LATEX_HEADER: \usepackage[margin=1in]{geometry} -#+LATEX_HEADER: \setmainfont[Ligatures={Common}]{Times New Roman} -#+LATEX_HEADER: \author{Ben McGinnes } - - -* Introduction - :PROPERTIES: - :CUSTOM_ID: intro - :END: - - | Version: | 0.1.0 | - | Author: | Ben McGinnes | - | Author GPG Key: | DB4724E6FA4286C92B4E55C4321E4E2373590E5D | - | Language: | Australian English, British English | - | xml:lang: | en-AU, en-GB, en | - - This document provides basic instruction in how to use the GPGME - Python bindings to programmatically leverage the GPGME library. - - -** Python 2 versus Python 3 - :PROPERTIES: - :CUSTOM_ID: py2-vs-py3 - :END: - - Though the GPGME Python bindings themselves provide support for - both Python 2 and 3, the focus is unequivocally on Python 3 and - specifically from Python 3.4 and above. As a consequence all the - examples and instructions in this guide use Python 3 code. - - Much of it will work with Python 2, but much of it also deals with - Python 3 byte literals, particularly when reading and writing data. - Developers concentrating on Python 2.7, and possibly even 2.6, will - need to make the appropriate modifications to support the older - string and unicode types as opposed to bytes. - - There are multiple reasons for concentrating on Python 3; some of - which relate to the immediate integration of these bindings, some - of which relate to longer term plans for both GPGME and the python - bindings and some of which relate to the impending EOL period for - Python 2.7. Essentially, though, there is little value in tying - the bindings to a version of the language which is a dead end and - the advantages offered by Python 3 over Python 2 make handling the - data types with which GPGME deals considerably easier. - - -** Examples - :PROPERTIES: - :CUSTOM_ID: howto-python3-examples - :END: - - All of the examples found in this document can be found as Python 3 - scripts in the =lang/python/examples/howto= directory. - - -* GPGME Concepts - :PROPERTIES: - :CUSTOM_ID: gpgme-concepts - :END: - - -** A C API - :PROPERTIES: - :CUSTOM_ID: gpgme-c-api - :END: - - Unlike many modern APIs with which programmers will be more - familiar with these days, the GPGME API is a C API. The API is - intended for use by C coders who would be able to access its - features by including the =gpgme.h= header file with their own C - source code and then access its functions just as they would any - other C headers. - - This is a very effective method of gaining complete access to the - API and in the most efficient manner possible. It does, however, - have the drawback that it cannot be directly used by other - languages without some means of providing an interface to those - languages. This is where the need for bindings in various - languages stems. - - -** Python bindings - :PROPERTIES: - :CUSTOM_ID: gpgme-python-bindings - :END: - - The Python bindings for GPGME provide a higher level means of - accessing the complete feature set of GPGME itself. It also - provides a more pythonic means of calling these API functions. - - The bindings are generated dynamically with SWIG and the copy of - =gpgme.h= generated when GPGME is compiled. - - This means that a version of the Python bindings is fundamentally - tied to the exact same version of GPGME used to generate that copy - of =gpgme.h=. - - -** Difference between the Python bindings and other GnuPG Python packages - :PROPERTIES: - :CUSTOM_ID: gpgme-python-bindings-diffs - :END: - - There have been numerous attempts to add GnuPG support to Python - over the years. Some of the most well known are listed here, along - with what differentiates them. - - -*** The python-gnupg package maintained by Vinay Sajip - :PROPERTIES: - :CUSTOM_ID: diffs-python-gnupg - :END: - - This is arguably the most popular means of integrating GPG with - Python. The package utilises the =subprocess= module to implement - wrappers for the =gpg= and =gpg2= executables normally invoked on - the command line (=gpg.exe= and =gpg2.exe= on Windows). - - The popularity of this package stemmed from its ease of use and - capability in providing the most commonly required features. - - Unfortunately it has been beset by a number of security issues in - the past; most of which stemmed from using unsafe methods of - accessing the command line via the =subprocess= calls. While some - effort has been made over the last two to three years (as of 2018) - to mitigate this, particularly by no longer providing shell access - through those subprocess calls, the wrapper is still somewhat - limited in the scope of its GnuPG features coverage. - - The python-gnupg package is available under the MIT license. - - -*** The gnupg package created and maintained by Isis Lovecruft - :PROPERTIES: - :CUSTOM_ID: diffs-isis-gnupg - :END: - - In 2015 Isis Lovecruft from the Tor Project forked and then - re-implemented the python-gnupg package as just gnupg. This new - package also relied on subprocess to call the =gpg= or =gpg2= - binaries, but did so somewhat more securely. - - The naming and version numbering selected for this package, - however, resulted in conflicts with the original python-gnupg and - since its functions were called in a different manner to - python-gnupg, the release of this package also resulted in a great - deal of consternation when people installed what they thought was - an upgrade that subsequently broke the code relying on it. - - The gnupg package is available under the GNU General Public - License version 3.0 (or any later version). - - -*** The PyME package maintained by Martin Albrecht - :PROPERTIES: - :CUSTOM_ID: diffs-pyme - :END: - - This package is the origin of these bindings, though they are - somewhat different now. For details of when and how the PyME - package was folded back into GPGME itself see the /Short History/ - document[fn:1] in this Python bindings =docs= directory.[fn:2] - - The PyME package was first released in 2002 and was also the first - attempt to implement a low level binding to GPGME. In doing so it - provided access to considerably more functionality than either the - =python-gnupg= or =gnupg= packages. - - The PyME package is only available for Python 2.6 and 2.7. - - Porting the PyME package to Python 3.4 in 2015 is what resulted in - it being folded into the GPGME project and the current bindings - are the end result of that effort. - - The PyME package is available under the same dual licensing as - GPGME itself: the GNU General Public License version 2.0 (or any - later version) and the GNU Lesser General Public License version - 2.1 (or any later version). - - -* GPGME Python bindings installation - :PROPERTIES: - :CUSTOM_ID: gpgme-python-install - :END: - - -** No PyPI - :PROPERTIES: - :CUSTOM_ID: do-not-use-pypi - :END: - - 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. - - This is because the bindings use SWIG to dynamically generate C - bindings against =gpgme.h= and =gpgme.h= is generated from - =gpgme.h.in= 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. - - -** Requirements - :PROPERTIES: - :CUSTOM_ID: gpgme-python-requirements - :END: - - The GPGME Python bindings only have three requirements: - - 1. A suitable version of Python 2 or Python 3. With Python 2 that - means Python 2.7 and with Python 3 that means Python 3.4 or - higher. - 2. SWIG. - 3. GPGME itself. Which also means that all of GPGME's dependencies - must be installed too. - - -** Installation - :PROPERTIES: - :CUSTOM_ID: installation - :END: - - Installing the Python bindings is effectively achieved by compiling - and installing GPGME itself. - - Once SWIG is installed with Python and all the dependencies for - GPGME are installed you only need to confirm that the version(s) of - Python you want the bindings installed for are in your =$PATH=. - - By default GPGME will attempt to install the bindings for the most - recent or highest version number of Python 2 and Python 3 it - detects in =$PATH=. It specifically checks for the =python= and - =python3= executables first and then checks for specific version - numbers. - - For Python 2 it checks for these executables in this order: - =python=, =python2= and =python2.7=. - - For Python 3 it checks for these executables in this order: - =python3=, =python3.6=, =python3.5= and =python3.4=. - - -*** Installing GPGME - :PROPERTIES: - :CUSTOM_ID: install-gpgme - :END: - - See the GPGME =README= file for details of how to install GPGME from - source. - - -* Fundamentals - :PROPERTIES: - :CUSTOM_ID: howto-fund-a-mental - :END: - - Before we can get to the fun stuff, there are a few matters - regarding GPGME's design which hold true whether you're dealing with - the C code directly or these Python bindings. - - -** No REST - :PROPERTIES: - :CUSTOM_ID: no-rest-for-the-wicked - :END: - - The first part of which is or will be fairly blatantly obvious upon - viewing the first example, but it's worth reiterating anyway. That - being that this API is /*not*/ a REST API. Nor indeed could it - ever be one. - - Most, if not all, Python programmers (and not just Python - programmers) know how easy it is to work with a RESTful API. In - fact they've become so popular that many other APIs attempt to - emulate REST-like behaviour as much as they are able. Right down - to the use of JSON formatted output to facilitate the use of their - API without having to retrain developers. - - This API does not do that. It would not be able to do that and - also provide access to the entire C API on which it's built. It - does, however, provide a very pythonic interface on top of the - direct bindings and it's this pythonic layer with which this HOWTO - deals with. - - -** Context - :PROPERTIES: - :CUSTOM_ID: howto-get-context - :END: - - One of the reasons which prevents this API from being RESTful is - that most operations require more than one instruction to the API - to perform the task. Sure, there are certain functions which can - be performed simultaneously, particularly if the result known or - strongly anticipated (e.g. selecting and encrypting to a key known - to be in the public keybox). - - There are many more, however, which cannot be manipulated so - readily: they must be performed in a specific sequence and the - result of one operation has a direct bearing on the outcome of - subsequent operations. Not merely by generating an error either. - - When dealing with this type of persistent state on the web, full of - both the RESTful and REST-like, it's most commonly referred to as a - session. In GPGME, however, it is called a context and every - operation type has one. - - -* Working with keys - :PROPERTIES: - :CUSTOM_ID: howto-keys - :END: - - -** Key selection - :PROPERTIES: - :CUSTOM_ID: howto-keys-selection - :END: - - Selecting keys to encrypt to or to sign with will be a common - occurrence when working with GPGMe and the means available for - doing so are quite simple. - - They do depend on utilising a Context; however once the data is - recorded in another variable, that Context does not need to be the - same one which subsequent operations are performed. - - The easiest way to select a specific key is by searching for that - key's key ID or fingerprint, preferably the full fingerprint - without any spaces in it. A long key ID will probably be okay, but - is not advised and short key IDs are already a problem with some - being generated to match specific patterns. It does not matter - whether the pattern is upper or lower case. - - So this is the best method: - - #+begin_src python - import gpg - - k = gpg.Context().keylist(pattern="258E88DCBD3CD44D8E7AB43F6ECB6AF0DEADBEEF") - keys = list(k) - #+end_src - - This is passable and very likely to be common: - - #+begin_src python - import gpg - - k = gpg.Context().keylist(pattern="0x6ECB6AF0DEADBEEF") - keys = list(k) - #+end_src - - And this is a really bad idea: - - #+begin_src python - import gpg - - k = gpg.Context().keylist(pattern="0xDEADBEEF") - keys = list(k) - #+end_src - - Alternatively it may be that the intention is to create a list of - keys which all match a particular search string. For instance all - the addresses at a particular domain, like this: - - #+begin_src python - import gpg - - ncsc = gpg.Context().keylist(pattern="ncsc.mil") - nsa = list(ncsc) - #+end_src - - -*** Counting keys - :PROPERTIES: - :CUSTOM_ID: howto-keys-counting - :END: - - Counting the number of keys in your public keybox (=pubring.kbx=), - the format which has superseded the old keyring format - (=pubring.gpg= and =secring.gpg=), or the number of secret keys is - a very simple task. - - #+begin_src python - import gpg - - c = gpg.Context() - seckeys = c.keylist(pattern=None, secret=True) - pubkeys = c.keylist(pattern=None, secret=False) - - seclist = list(seckeys) - secnum = len(seclist) - - publist = list(pubkeys) - pubnum = len(publist) - - print(""" - Number of secret keys: {0} - Number of public keys: {1} - """.format(secnum, pubnum)) - #+end_src - - -** Get key - :PROPERTIES: - :CUSTOM_ID: howto-get-key - :END: - - An alternative method of getting a single key via its fingerprint - is available directly within a Context with =Context().get_key=. - This is the preferred method of selecting a key in order to modify - it, sign or certify it and for obtaining relevant data about a - single key as a part of other functions; when verifying a signature - made by that key, for instance. - - By default this method will select public keys, but it can select - secret keys as well. - - This first example demonstrates selecting the current key of Werner - Koch, which is due to expire at the end of 2018: - - #+begin_src python - import gpg - - fingerprint = "80615870F5BAD690333686D0F2AD85AC1E42B367" - key = gpg.Context().get_key(fingerprint) - #+end_src - - Whereas this example demonstrates selecting the author's current - key with the =secret= key word argument set to =True=: - - #+begin_src python - import gpg - - fingerprint = "DB4724E6FA4286C92B4E55C4321E4E2373590E5D" - key = gpg.Context().get_key(fingerprint, secret=True) - #+end_src - - It is, of course, quite possible to select expired, disabled and - revoked keys with this function, but only to effectively display - information about those keys. - - It is also possible to use both unicode or string literals and byte - literals with the fingerprint when getting a key in this way. - - -* Basic Functions - :PROPERTIES: - :CUSTOM_ID: howto-the-basics - :END: - - The most frequently called features of any cryptographic library - will be the most fundamental tasks for encryption software. In this - section we will look at how to programmatically encrypt data, - decrypt it, sign it and verify signatures. - - -** Encryption - :PROPERTIES: - :CUSTOM_ID: howto-basic-encryption - :END: - - Encrypting is very straight forward. In the first example below - the message, =text=, is encrypted to a single recipient's key. In - the second example the message will be encrypted to multiple - recipients. - - -*** Encrypting to one key - :PROPERTIES: - :CUSTOM_ID: howto-basic-encryption-single - :END: - - Once the the Context is set the main issues with encrypting data - is essentially reduced to key selection and the keyword arguments - specified in the =gpg.Context().encrypt()= method. - - Those keyword arguments are: =recipients=, a list of keys - encrypted to (covered in greater detail in the following section); - =sign=, whether or not to sign the plaintext data, see subsequent - sections on signing and verifying signatures below (defaults to - =True=); =sink=, to write results or partial results to a secure - sink instead of returning it (defaults to =None=); =passphrase=, - only used when utilising symmetric encryption (defaults to - =None=); =always_trust=, used to override the trust model settings - for recipient keys (defaults to =False=); =add_encrypt_to=, - utilises any preconfigured =encrypt-to= or =default-key= settings - in the user's =gpg.conf= file (defaults to =False=); =prepare=, - prepare for encryption (defaults to =False=); =expect_sign=, - prepare for signing (defaults to =False=); =compress=, compresses - the plaintext prior to encryption (defaults to =True=). - - #+begin_src python - import gpg - - a_key = "0x12345678DEADBEEF" - text = b"""Some text to test with. - - 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) - rkey = list(c.keylist(pattern=a_key, secret=False)) - ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=False) - - with open("secret_plans.txt.asc", "wb") as afile: - afile.write(ciphertext) - #+end_src - - Though this is even more likely to be used like this; with the - plaintext input read from a file, the recipient keys used for - encryption regardless of key trust status and the encrypted output - also encrypted to any preconfigured keys set in the =gpg.conf= - file: - - #+begin_src python - import gpg - - a_key = "0x12345678DEADBEEF" - - with open("secret_plans.txt", "rb") as afile: - text = afile.read() - - c = gpg.Context(armor=True) - rkey = list(c.keylist(pattern=a_key, secret=False)) - ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, - sign=True, always_trust=True, - add_encrypt_to=True) - - with open("secret_plans.txt.asc", "wb") as afile: - afile.write(ciphertext) - #+end_src - - If the =recipients= paramater is empty then the plaintext is - encrypted symmetrically. If no =passphrase= is supplied as a - parameter or via a callback registered with the =Context()= then - an out-of-band prompt for the passphrase via pinentry will be - invoked. - - -*** Encrypting to multiple keys - :PROPERTIES: - :CUSTOM_ID: howto-basic-encryption-multiple - :END: - - Encrypting to multiple keys essentially just expands upon the key - selection process and the recipients from the previous examples. - - The following example encrypts a message (=text=) to everyone with - an email address on the =gnupg.org= domain,[fn:3] but does /not/ encrypt - to a default key or other key which is configured to normally - encrypt to. - - #+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]) - - ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, sign=False, - always_trust=True) - - with open("secret_plans.txt.asc", "wb") as afile: - afile.write(ciphertext) - #+end_src - - All it would take to change the above example to sign the message - and also encrypt the message to any configured default keys would - be to change the =c.encrypt= line to this: - - #+begin_src python - ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, - always_trust=True, - add_encrypt_to=True) - #+end_src - - The only keyword arguments requiring modification are those for - which the default values are changing. The default value of - =sign= is =True=, the default of =always_trust= is =False=, the - default of =add_encrypt_to= is =False=. - - If =always_trust= is not set to =True= and any of the recipient - keys are not trusted (e.g. not signed or locally signed) then the - encryption will raise an error. It is possible to mitigate this - somewhat with something more like this: - - #+begin_src python - import gpg - - with open("secret_plans.txt.asc", "rb") as afile: - text = afile.read() - - 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]) - - try: - ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True) - except gpg.errors.InvalidRecipients as e: - for i in range(len(e.recipients)): - for n in range(len(logrus)): - if logrus[n].fpr == e.recipients[i].fpr: - logrus.remove(logrus[n]) - else: - pass - try: - ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True) - except: - pass - - with open("secret_plans.txt.asc", "wb") as afile: - afile.write(ciphertext) - #+end_src - - This will attempt to encrypt to all the keys searched for, then - remove invalid recipients if it fails and try again. - - -** Decryption - :PROPERTIES: - :CUSTOM_ID: howto-basic-decryption - :END: - - Decrypting something encrypted to a key in one's secret keyring is - fairly straight forward. - - In this example code, however, preconfiguring either - =gpg.Context()= or =gpg.core.Context()= as =c= is unnecessary - because there is no need to modify the Context prior to conducting - the decryption and since the Context is only used once, setting it - to =c= simply adds lines for no gain. - - #+begin_src python - import gpg - - ciphertext = input("Enter path and filename of encrypted file: ") - newfile = input("Enter path and filename of file to save decrypted data to: ") - with open(ciphertext, "rb") as cfile: - plaintext, result, verify_result = gpg.Context().decrypt(cfile) - with open(newfile, "wb") as nfile: - nfile.write(plaintext) - #+end_src - - The data available in plaintext in this example is the decrypted - content as a byte object in =plaintext[0]=, the recipient key IDs - and algorithms in =plaintext[1]= and the results of verifying any - signatures of the data in =plaintext[0]=. - - -** Signing text and files - :PROPERTIES: - :CUSTOM_ID: howto-basic-signing - :END: - - The following sections demonstrate how to specify keys to sign with. - - -*** Signing key selection - :PROPERTIES: - :CUSTOM_ID: howto-basic-signing-signers - :END: - - By default GPGME and the Python bindings will use the default key - configured for the user invoking the GPGME API. If there is no - default key specified and there is more than one secret key - available it may be necessary to specify the key or keys with - which to sign messages and files. - - #+begin_src python - import gpg - - logrus = input("Enter the email address or string to match signing keys to: ") - hancock = gpg.Context().keylist(pattern=logrus, secret=True) - sig_src = list(hancock) - #+end_src - - The signing examples in the following sections include the - explicitly designated =signers= parameter in two of the five - examples; once where the resulting signature would be ASCII - armoured and once where it would not be armoured. - - While it would be possible to enter a key ID or fingerprint here - to match a specific key, it is not possible to enter two - fingerprints and match two keys since the patten expects a string, - bytes or None and not a list. A string with two fingerprints - won't match any single key. - - -*** Normal or default signing messages or files - :PROPERTIES: - :CUSTOM_ID: howto-basic-signing-normal - :END: - - The normal or default signing process is essentially the same as - is most often invoked when also encrypting a message or file. So - when the encryption component is not utilised, the result is to - produce an encoded and signed output which may or may not be ASCII - armoured and which may or may not also be compressed. - - By default compression will be used unless GnuPG detects that the - plaintext is already compressed. ASCII armouring will be - determined according to the value of =gpg.Context().armor=. - - The compression algorithm is selected in much the same way as the - symmetric encryption algorithm or the hash digest algorithm is - when multiple keys are involved; from the preferences saved into - the key itself or by comparison with the preferences with all - other keys involved. - - #+begin_src python - import gpg - - text0 = """Declaration of ... something. - - """ - text = text0.encode() - - c = gpg.Context(armor=True, signers=sig_src) - signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) - - with open("/path/to/statement.txt.asc", "w") as afile: - afile.write(signed_data.decode()) - #+end_src - - Though everything in this example is accurate, it is more likely - that reading the input data from another file and writing the - result to a new file will be performed more like the way it is done - in the next example. Even if the output format is ASCII armoured. - - #+begin_src python - import gpg - - with open("/path/to/statement.txt", "rb") as tfile: - text = tfile.read() - - c = gpg.Context() - signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) - - with open("/path/to/statement.txt.sig", "wb") as afile: - afile.write(signed_data) - #+end_src - - -*** Detached signing messages and files - :PROPERTIES: - :CUSTOM_ID: howto-basic-signing-detached - :END: - - Detached signatures will often be needed in programmatic uses of - GPGME, either for signing files (e.g. tarballs of code releases) - or as a component of message signing (e.g. PGP/MIME encoded - email). - - #+begin_src python - import gpg - - text0 = """Declaration of ... something. - - """ - text = text0.encode() - - c = gpg.Context(armor=True) - signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) - - with open("/path/to/statement.txt.asc", "w") as afile: - afile.write(signed_data.decode()) - #+end_src - - As with normal signatures, detached signatures are best handled as - byte literals, even when the output is ASCII armoured. - - #+begin_src python - import gpg - - with open("/path/to/statement.txt", "rb") as tfile: - text = tfile.read() - - c = gpg.Context(signers=sig_src) - signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) - - with open("/path/to/statement.txt.sig", "wb") as afile: - afile.write(signed_data) - #+end_src - - -*** Clearsigning messages or text - :PROPERTIES: - :CUSTOM_ID: howto-basic-signing-clear - :END: - - Though PGP/in-line messages are no longer encouraged in favour of - PGP/MIME, there is still sometimes value in utilising in-line - signatures. This is where clear-signed messages or text is of - value. - - #+begin_src python - import gpg - - text0 = """Declaration of ... something. - - """ - text = text0.encode() - - c = gpg.Context() - signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) - - with open("/path/to/statement.txt.asc", "w") as afile: - afile.write(signed_data.decode()) - #+end_src - - In spite of the appearance of a clear-signed message, the data - handled by GPGME in signing it must still be byte literals. - - #+begin_src python - import gpg - - with open("/path/to/statement.txt", "rb") as tfile: - text = tfile.read() - - c = gpg.Context() - signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) - - with open("/path/to/statement.txt.asc", "wb") as afile: - afile.write(signed_data) - #+end_src - - -** Signature verification - :PROPERTIES: - :CUSTOM_ID: howto-basic-verification - :END: - - Essentially there are two principal methods of verification of a - signature. The first of these is for use with the normal or - default signing method and for clear-signed messages. The second is - for use with files and data with detached signatures. - - The following example is intended for use with the default signing - method where the file was not ASCII armoured: - - #+begin_src python - import gpg - import time - - filename = "statement.txt" - gpg_file = "statement.txt.gpg" - - c = gpg.Context() - - try: - data, result = c.verify(open(gpg_file)) - verified = True - except gpg.errors.BadSignatures as e: - verified = False - print(e) - - if verified is True: - for i in range(len(result.signatures)): - sign = result.signatures[i] - print("""Good signature from: - {0} - with key {1} - made at {2} - """.format(c.get_key(sign.fpr).uids[0].uid, - sign.fpr, time.ctime(sign.timestamp))) - else: - pass - #+end_src - - Whereas this next example, which is almost identical would work - with normal ASCII armoured files and with clear-signed files: - - #+begin_src python - import gpg - import time - - filename = "statement.txt" - asc_file = "statement.txt.asc" - - c = gpg.Context() - - try: - data, result = c.verify(open(asc_file)) - verified = True - except gpg.errors.BadSignatures as e: - verified = False - print(e) - - if verified is True: - for i in range(len(result.signatures)): - sign = result.signatures[i] - print("""Good signature from: - {0} - with key {1} - made at {2} - """.format(c.get_key(sign.fpr).uids[0].uid, - sign.fpr, time.ctime(sign.timestamp))) - else: - pass - #+end_src - - In both of the previous examples it is also possible to compare the - original data that was signed against the signed data in =data= to - see if it matches with something like this: - - #+begin_src python - with open(filename, "rb") as afile: - text = afile.read() - - if text == data: - print("Good signature.") - else: - pass - #+end_src - - The following two examples, however, deal with detached signatures. - With his method of verification the data that was signed does not - get returned since it is already being explicitly referenced in the - first argument of =c.verify=. So =data= is =None= and only the - information in =result= is available. - - #+begin_src python - import gpg - import time - - filename = "statement.txt" - sig_file = "statement.txt.sig" - - c = gpg.Context() - - try: - data, result = c.verify(open(filename), open(sig_file)) - verified = True - except gpg.errors.BadSignatures as e: - verified = False - print(e) - - if verified is True: - for i in range(len(result.signatures)): - sign = result.signatures[i] - print("""Good signature from: - {0} - with key {1} - made at {2} - """.format(c.get_key(sign.fpr).uids[0].uid, - sign.fpr, time.ctime(sign.timestamp))) - else: - pass - #+end_src - - #+begin_src python - import gpg - import time - - filename = "statement.txt" - asc_file = "statement.txt.asc" - - c = gpg.Context() - - try: - data, result = c.verify(open(filename), open(asc_file)) - verified = True - except gpg.errors.BadSignatures as e: - verified = False - print(e) - - if verified is not None: - for i in range(len(result.signatures)): - sign = result.signatures[i] - print("""Good signature from: - {0} - with key {1} - made at {2} - """.format(c.get_key(sign.fpr).uids[0].uid, - sign.fpr, time.ctime(sign.timestamp))) - else: - pass - #+end_src - - -* Creating keys and subkeys - :PROPERTIES: - :CUSTOM_ID: key-generation - :END: - - The one thing, aside from GnuPG itself, that GPGME depends on, of - course, is the keys themselves. So it is necessary to be able to - generate them and modify them by adding subkeys, revoking or - disabling them, sometimes deleting them and doing the same for user - IDs. - - In the following examples a key will be created for the world's - greatest secret agent, Danger Mouse. Since Danger Mouse is a secret - agent he needs to be able to protect information to =SECRET= level - clearance, so his keys will be 3072-bit keys. - - The pre-configured =gpg.conf= file which sets cipher, digest and - other preferences contains the following configuration parameters: - - #+begin_src conf - expert - allow-freeform-uid - allow-secret-key-import - trust-model tofu+pgp - tofu-default-policy unknown - enable-large-rsa - enable-dsa2 - # cert-digest-algo SHA256 - cert-digest-algo SHA512 - default-preference-list TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 ZLIB BZIP2 ZIP Uncompressed - personal-cipher-preferences TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES - personal-digest-preferences SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 - personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed - #+end_src - - -** Primary key - :PROPERTIES: - :CUSTOM_ID: keygen-primary - :END: - - Generating a primary key uses the =create_key= method in a Context. - It contains multiple arguments and keyword arguments, including: - =userid=, =algorithm=, =expires_in=, =expires=, =sign=, =encrypt=, - =certify=, =authenticate=, =passphrase= and =force=. The defaults - for all of those except =userid=, =algorithm=, =expires_in=, - =expires= and =passphrase= is =False=. The defaults for - =algorithm= and =passphrase= is =None=. The default for - =expires_in= is =0=. The default for =expires= is =True=. There - is no default for =userid=. - - If =passphrase= is left as =None= then the key will not be - generated with a passphrase, if =passphrase= is set to a string - then that will be the passphrase and if =passphrase= is set to - =True= then gpg-agent will launch pinentry to prompt for a - passphrase. For the sake of convenience, these examples will keep - =passphrase= set to =None=. - - #+begin_src python - import gpg - - c = gpg.Context() - - c.home_dir = "~/.gnupg-dm" - userid = "Danger Mouse " - - dmkey = c.create_key(userid, algorithm = "rsa3072", expires_in = 31536000, - sign = True, certify = True) - #+end_src - - One thing to note here is the use of setting the =c.home_dir= - parameter. This enables generating the key or keys in a different - location. In this case to keep the new key data created for this - example in a separate location rather than adding it to existing - and active key store data. As with the default directory, - =~/.gnupg=, any temporary or separate directory needs the - permissions set to only permit access by the directory owner. On - posix systems this means setting the directory permissions to 700. - - The successful generation of the key can be confirmed via the - returned =GenkeyResult= object, which includes the following data: - - #+begin_src python - print(""" - Fingerprint: {0} - Primary Key: {1} - Public Key: {2} - Secret Key: {3} - Sub Key: {4} - User IDs: {5} - """.format(dmkey.fpr, dmkey.primary, dmkey.pubkey, dmkey.seckey, dmkey.sub, - dmkey.uid)) - #+end_src - - Alternatively the information can be confirmed using the command - line program: - - #+begin_src shell - bash-4.4$ gpg --homedir ~/.gnupg-dm -K - ~/.gnupg-dm/pubring.kbx - ---------------------- - sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] - 177B7C25DB99745EE2EE13ED026D2F19E99E63AA - uid [ultimate] Danger Mouse - - bash-4.4$ - #+end_src - - As with generating keys manually, to preconfigure expanded - preferences for the cipher, digest and compression algorithms, the - =gpg.conf= file must contain those details in the home directory in - which the new key is being generated. I used a cut down version of - my own =gpg.conf= file in order to be able to generate this: - - #+begin_src shell - bash-4.4$ gpg --homedir ~/.gnupg-dm --edit-key 177B7C25DB99745EE2EE13ED026D2F19E99E63AA showpref quit - Secret key is available. - - sec rsa3072/026D2F19E99E63AA - created: 2018-03-15 expires: 2019-03-15 usage: SC - trust: ultimate validity: ultimate - [ultimate] (1). Danger Mouse - - [ultimate] (1). Danger Mouse - Cipher: TWOFISH, CAMELLIA256, AES256, CAMELLIA192, AES192, CAMELLIA128, AES, BLOWFISH, IDEA, CAST5, 3DES - Digest: SHA512, SHA384, SHA256, SHA224, RIPEMD160, SHA1 - Compression: ZLIB, BZIP2, ZIP, Uncompressed - Features: MDC, Keyserver no-modify - - bash-4.4$ - #+end_src - - -** Subkeys - :PROPERTIES: - :CUSTOM_ID: keygen-subkeys - :END: - - Adding subkeys to a primary key is fairly similar to creating the - primary key with the =create_subkey= method. Most of the arguments - are the same, but not quite all. Instead of the =userid= argument - there is now a =key= argument for selecting which primary key to - add the subkey to. - - In the following example an encryption subkey will be added to the - primary key. Since Danger Mouse is a security conscious secret - agent, this subkey will only be valid for about six months, half - the length of the primary key. - - #+begin_src python - import gpg - - c = gpg.Context() - c.home_dir = "~/.gnupg-dm" - - key = c.get_key(dmkey.fpr, secret = True) - dmsub = c.create_subkey(key, algorithm = "rsa3072", expires_in = 15768000, - encrypt = True) - #+end_src - - As with the primary key, the results here can be checked with: - - #+begin_src python - print(""" - Fingerprint: {0} - Primary Key: {1} - Public Key: {2} - Secret Key: {3} - Sub Key: {4} - User IDs: {5} - """.format(dmsub.fpr, dmsub.primary, dmsub.pubkey, dmsub.seckey, dmsub.sub, - dmsub.uid)) - #+end_src - - As well as on the command line with: - - #+begin_src shell - bash-4.4$ gpg --homedir ~/.gnupg-dm -K - ~/.gnupg-dm/pubring.kbx - ---------------------- - sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] - 177B7C25DB99745EE2EE13ED026D2F19E99E63AA - uid [ultimate] Danger Mouse - ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13] - - bash-4.4$ - #+end_src - - -** User IDs - :PROPERTIES: - :CUSTOM_ID: keygen-uids - :END: - - By comparison to creating primary keys and subkeys, adding a new - user ID to an existing key is much simpler. The method used to do - this is =key_add_uid= and the only arguments it takes are for the - =key= and the new =uid=. - - #+begin_src python - import gpg - - c = gpg.Context() - c.home_dir = "~/.gnupg-dm" - - dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" - key = c.get_key(dmfpr, secret = True) - uid = "Danger Mouse " - - c.key_add_uid(key, uid) - #+end_src - - Unsurprisingly the result of this is: - - #+begin_src shell - bash-4.4$ gpg --homedir ~/.gnupg-dm -K - ~/.gnupg-dm/pubring.kbx - ---------------------- - sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] - 177B7C25DB99745EE2EE13ED026D2F19E99E63AA - uid [ultimate] Danger Mouse - uid [ultimate] Danger Mouse - ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13] - - bash-4.4$ - #+end_src - - -** Key certification - :PROPERTIES: - :CUSTOM_ID: key-sign - :END: - - Since key certification is more frequently referred to as key - signing, the method used to perform this function is =key_sign=. - - The =key_sign= method takes four arguments: =key=, =uids=, - =expires_in= and =local=. The default value of =uids= is =None= - and which results in all user IDs being selected. The default - values of =expires_in= snd =local= is =False=; which result in the - signature never expiring and being able to be exported. - - The =key= is the key being signed rather than the key doing the - signing. To change the key doing the signing refer to the signing - key selection above for signing messages and files. - - If the =uids= value is not =None= then it must either be a string - to match a single user ID or a list of strings to match multiple - user IDs. In this case the matching of those strings must be - precise and it is case sensitive. - - To sign Danger Mouse's key for just the initial user ID with a - signature which will last a little over a month, do this: - - #+begin_src python - import gpg - - c = gpg.Context() - uid = "Danger Mouse " - - dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" - key = c.get_key(dmfpr, secret = True) - c.key_sign(key, uids = uid, expires_in = 2764800) - #+end_src - - -* Miscellaneous work-arounds - :PROPERTIES: - :CUSTOM_ID: cheats-and-hacks - :END: - - -** Group lines - :PROPERTIES: - :CUSTOM_ID: group-lines - :END: - - There is not yet an easy way to access groups configured in the - gpg.conf file from within GPGME. As a consequence these central - groupings of keys cannot be shared amongst multiple programs, such - as MUAs readily. - - The following code, however, provides a work-around for obtaining - this information in Python. - - #+begin_src python - import subprocess - - lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines() - - for i in range(len(lines)): - if lines[i].startswith("group") is True: - line = lines[i] - else: - pass - - groups = line.split(":")[-1].replace('"', '').split(',') - - group_lines = groups - for i in range(len(group_lines)): - group_lines[i] = group_lines[i].split("=") - - group_lists = group_lines - for i in range(len(group_lists)): - group_lists[i][1] = group_lists[i][1].split() - #+end_src - - The result of that code is that =group_lines= is a list of lists - where =group_lines[i][0]= is the name of the group and - =group_lines[i][1]= is the key IDs of the group as a string. - - The =group_lists= result is very similar in that it is a list of - lists. The first part, =group_lists[i][0]= matches - =group_lines[i][0]= as the name of the group, but - =group_lists[i][1]= is the key IDs of the group as a string. - - -* Copyright and Licensing - :PROPERTIES: - :CUSTOM_ID: copyright-and-license - :END: - - -** Copyright (C) The GnuPG Project, 2018 - :PROPERTIES: - :CUSTOM_ID: copyright - :END: - - Copyright ? The GnuPG Project, 2018. - - -** License GPL compatible - :PROPERTIES: - :CUSTOM_ID: license - :END: - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. - - -* Footnotes - -[fn:1] =Short_History.org= and/or =Short_History.html=. - -[fn:2] The =lang/python/docs/= directory in the GPGME source. - -[fn:3] You probably don't really want to do this. Searching the -keyservers for "gnupg.org" produces over 400 results, the majority of -which aren't actually at the gnupg.org domain, but just included a -comment regarding the project in their key somewhere. diff --git a/web/documentation/howtos.org b/web/documentation/howtos.org index 2c49e29..0fd1a8a 100644 --- a/web/documentation/howtos.org +++ b/web/documentation/howtos.org @@ -128,4 +128,4 @@ This HOWTO is available: - in its original Emacs Org Mode source form in the GPGME repository ( [[https://dev.gnupg.org/source/gpgme/browse/master/lang/python/docs/GPGMEpythonHOWTOen.org][en]] ) - - as an online HTML file ( [[GPGMEpythonHOWTOen.html][en]] ) + ----------------------------------------------------------------------- Summary of changes: web/documentation/GPGMEpythonHOWTOen.org | 1370 ------------------------------ web/documentation/howtos.org | 1 - 2 files changed, 1371 deletions(-) delete mode 100644 web/documentation/GPGMEpythonHOWTOen.org hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 03:19:44 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 22 Mar 2018 03:19:44 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-10-g4dc6d4d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 4dc6d4d2067c726cdb13593bf151637319ff65e6 (commit) from 5b963d2f954bd978f69e391155cb9b337936ba75 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4dc6d4d2067c726cdb13593bf151637319ff65e6 Author: NIIBE Yutaka Date: Thu Mar 22 11:15:15 2018 +0900 doc: Fix build and installation of yat2m. * configure.ac (YAT2M): Require it when cross compiling. * doc/Makefile.am (bin_PROGRAMS): Add yat2m. -- Before 1.28, yat2m used to be an internal tool. Now, it's a standard tool. For native build, it is built and used for initial installation. For cross build, it is required on the build system. Signed-off-by: NIIBE Yutaka diff --git a/configure.ac b/configure.ac index 12abb48..8d11998 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,13 @@ 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 ----------------------------------------------------------------------- Summary of changes: configure.ac | 8 ++++++++ doc/Makefile.am | 31 ++++++++----------------------- 2 files changed, 16 insertions(+), 23 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 07:54:59 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 22 Mar 2018 07:54:59 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-20-g0152ba7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 0152ba7c987443d641ce1091c79f90ef2cc46498 (commit) from 34ec0125614674725cb78cf9f8d5e6b0f8c64064 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0152ba7c987443d641ce1091c79f90ef2cc46498 Author: NIIBE Yutaka Date: Thu Mar 22 15:50:31 2018 +0900 scd: Support KDF DO setup. * g10/call-agent.c (learn_status_cb): Parse the capability for KDF. * g10/card-util.c (gen_kdf_data, kdf_setup): New. (card_edit): New admin command cmdKDFSETUP to call kdf_setup. * scd/app-openpgp.c (do_getattr): Emit KDF capability. -- GnuPG-bug-id: 3823 Signed-off-by: NIIBE Yutaka diff --git a/g10/call-agent.c b/g10/call-agent.c index ea530e7..fdacf6a 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -591,6 +591,8 @@ learn_status_cb (void *opaque, const char *line) parm->extcap.ki = abool; else if (!strcmp (p, "aac")) parm->extcap.aac = abool; + else if (!strcmp (p, "kdf")) + parm->extcap.kdf = abool; else if (!strcmp (p, "si")) parm->status_indicator = strtoul (p2, NULL, 10); } diff --git a/g10/call-agent.h b/g10/call-agent.h index 53775c5..8de0d13 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -67,6 +67,7 @@ struct agent_card_info_s struct { unsigned int ki:1; /* Key import available. */ unsigned int aac:1; /* Algorithm attributes are changeable. */ + unsigned int kdf:1; /* KDF object to support PIN hashing available. */ } extcap; unsigned int status_indicator; }; diff --git a/g10/card-util.c b/g10/card-util.c index 7616dbb..d78e9bd 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -1897,6 +1897,104 @@ factory_reset (void) } +#define USER_PIN_DEFAULT "123456" +#define ADMIN_PIN_DEFAULT "12345678" +#define KDF_DATA_LENGTH 110 + +/* Generate KDF data. */ +static gpg_error_t +gen_kdf_data (unsigned char *data) +{ + const unsigned char h0[] = { 0x81, 0x01, 0x03, + 0x82, 0x01, 0x08, + 0x83, 0x04 }; + const unsigned char h1[] = { 0x84, 0x08 }; + const unsigned char h2[] = { 0x85, 0x08 }; + const unsigned char h3[] = { 0x86, 0x08 }; + const unsigned char h4[] = { 0x87, 0x20 }; + const unsigned char h5[] = { 0x88, 0x20 }; + unsigned char *p, *salt_user, *salt_admin; + unsigned char s2k_char; + unsigned int iterations; + unsigned char count_4byte[4]; + gpg_error_t err = 0; + + p = data; + + s2k_char = encode_s2k_iterations (0); + iterations = S2K_DECODE_COUNT (s2k_char); + count_4byte[0] = (iterations >> 24) & 0xff; + count_4byte[1] = (iterations >> 16) & 0xff; + count_4byte[2] = (iterations >> 8) & 0xff; + count_4byte[3] = (iterations & 0xff); + + memcpy (p, h0, sizeof h0); + p += sizeof h0; + memcpy (p, count_4byte, sizeof count_4byte); + p += sizeof count_4byte; + memcpy (p, h1, sizeof h1); + salt_user = (p += sizeof h1); + gcry_randomize (p, 8, GCRY_STRONG_RANDOM); + p += 8; + memcpy (p, h2, sizeof h2); + p += sizeof h2; + gcry_randomize (p, 8, GCRY_STRONG_RANDOM); + p += 8; + memcpy (p, h3, sizeof h3); + salt_admin = (p += sizeof h3); + gcry_randomize (p, 8, GCRY_STRONG_RANDOM); + p += 8; + memcpy (p, h4, sizeof h4); + p += sizeof h4; + err = gcry_kdf_derive (USER_PIN_DEFAULT, strlen (USER_PIN_DEFAULT), + GCRY_KDF_ITERSALTED_S2K, DIGEST_ALGO_SHA256, + salt_user, 8, iterations, 32, p); + p += 32; + if (!err) + { + memcpy (p, h5, sizeof h5); + p += sizeof h5; + err = gcry_kdf_derive (ADMIN_PIN_DEFAULT, strlen (ADMIN_PIN_DEFAULT), + GCRY_KDF_ITERSALTED_S2K, DIGEST_ALGO_SHA256, + salt_admin, 8, iterations, 32, p); + } + + return err; +} + +/* Setup KDF data object which is used for PIN authentication. */ +static void +kdf_setup (void) +{ + struct agent_card_info_s info; + gpg_error_t err; + unsigned char kdf_data[KDF_DATA_LENGTH]; + + memset (&info, 0, sizeof info); + + err = agent_scd_getattr ("EXTCAP", &info); + if (err) + { + log_error (_("error getting card info: %s\n"), gpg_strerror (err)); + return; + } + + if (!info.extcap.kdf) + { + log_error (_("This command is not supported by this card\n")); + goto leave; + } + + if (!(err = gen_kdf_data (kdf_data)) + && !(err = agent_scd_setattr ("KDF", kdf_data, KDF_DATA_LENGTH, NULL))) + err = agent_scd_getattr ("KDF", &info); + + if (err) + log_error (_("error for setup KDF: %s\n"), gpg_strerror (err)); + + leave: + agent_release_card_info (&info); +} /* Data used by the command parser. This needs to be outside of the function scope to allow readline based command completion. */ @@ -1906,7 +2004,7 @@ enum cmdids cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY, cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR, cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT, - cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET, + cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET, cmdKDFSETUP, cmdINVCMD }; @@ -1939,6 +2037,7 @@ static struct { "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")}, { "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") }, { "factory-reset", cmdFACTORYRESET, 1, N_("destroy all keys and data")}, + { "kdf-setup", cmdKDFSETUP, 1, N_("setup KDF for PIN authentication")}, /* Note, that we do not announce these command yet. */ { "privatedo", cmdPRIVATEDO, 0, NULL }, { "readcert", cmdREADCERT, 0, NULL }, @@ -2222,6 +2321,10 @@ card_edit (ctrl_t ctrl, strlist_t commands) factory_reset (); break; + case cmdKDFSETUP: + kdf_setup (); + break; + case cmdQUIT: goto leave; diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index f3065ed..e0c9d59 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1018,7 +1018,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) snprintf (tmp, sizeof tmp, "gc=%d ki=%d fc=%d pd=%d mcl3=%u aac=%d " - "sm=%d si=%u dec=%d bt=%d", + "sm=%d si=%u dec=%d bt=%d kdf=%d", app->app_local->extcap.get_challenge, app->app_local->extcap.key_import, app->app_local->extcap.change_force_chv, @@ -1032,7 +1032,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) : 0), app->app_local->status_indicator, app->app_local->extcap.has_decrypt, - app->app_local->extcap.has_button); + app->app_local->extcap.has_button, + app->app_local->extcap.kdf_do); send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0); return 0; } ----------------------------------------------------------------------- Summary of changes: g10/call-agent.c | 2 ++ g10/call-agent.h | 1 + g10/card-util.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++- scd/app-openpgp.c | 5 +-- 4 files changed, 110 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 10:31:00 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 22 Mar 2018 10:31:00 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-21-g165bc38 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 165bc38cefbc03515403b60b704cabf4dc0b71f4 (commit) from 0152ba7c987443d641ce1091c79f90ef2cc46498 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 165bc38cefbc03515403b60b704cabf4dc0b71f4 Author: Werner Koch Date: Thu Mar 22 10:23:00 2018 +0100 gpg: Implement --dry-run for --passwd. * g10/keyedit.c (change_passphrase): Take care of --dry-run. Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index e3c3662..ad044ff 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1126,7 +1126,9 @@ all affected self-signatures is set one second ahead. @opindex passwd Change the passphrase of the secret key belonging to the certificate specified as @var{user-id}. This is a shortcut for the sub-command - at code{passwd} of the edit key menu. + at code{passwd} of the edit key menu. When using together with the +option @option{--dry-run} this will not actually change the passphrase +but check that the current passphrase is correct. @end table diff --git a/g10/keyedit.c b/g10/keyedit.c index 17cf7d6..4ade5cd 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1134,8 +1134,10 @@ change_passphrase (ctrl_t ctrl, kbnode_t keyblock) if (err) goto leave; + /* Note that when using --dry-run we don't change the + * passphrase but merely verify the current passphrase. */ desc = gpg_format_keydesc (ctrl, pk, FORMAT_KEYDESC_NORMAL, 1); - err = agent_passwd (ctrl, hexgrip, desc, 0, + err = agent_passwd (ctrl, hexgrip, desc, !!opt.dry_run, &cache_nonce, &passwd_nonce); xfree (desc); ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 4 +++- g10/keyedit.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 15:35:41 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 22 Mar 2018 15:35:41 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-46-g92fd86e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 92fd86e9956ef3fea51d72495fd0da09522e57a1 (commit) from 0b3ec359e2279c3b46b171372b1b7733bba20cd7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 92fd86e9956ef3fea51d72495fd0da09522e57a1 Author: Werner Koch Date: Thu Mar 22 15:28:04 2018 +0100 doc: Clarify the value range of the use-rsa-e parameter. -- Signed-off-by: Werner Koch diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index bba07a4..967745f 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -2905,7 +2905,9 @@ Use the given value. @noindent If this parameter is not used, Libgcrypt uses for historic reasons -65537. +65537. Note that the value must fit into a 32 bit unsigned variable +and that the usual C prefixes are considered (e.g. 017 gives 15). + @item qbits @var{n} This is only meanigful for DSA keys. If it is given the DSA key is diff --git a/src/sexp.c b/src/sexp.c index 0462d92..9d89268 100644 --- a/src/sexp.c +++ b/src/sexp.c @@ -401,7 +401,7 @@ _gcry_sexp_vlist( const gcry_sexp_t a, ... ) /**************** * Append n to the list a - * Returns: a new ist (which maybe a) + * Returns: a new list (which maybe a) */ gcry_sexp_t _gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n ) ----------------------------------------------------------------------- Summary of changes: doc/gcrypt.texi | 4 +++- src/sexp.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 17:49:40 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 22 Mar 2018 17:49:40 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-14-g30621ee Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 30621ee4c13006d08881994c32c89f60604c0188 (commit) via 72b70167ea433d6bb46226b1008e2d8e911146a7 (commit) via ffc8f805165a13d16ed227051c59d732117ec9d4 (commit) via b3df10d6620894bc4047af1e14239b258e440803 (commit) from 4dc6d4d2067c726cdb13593bf151637319ff65e6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 30621ee4c13006d08881994c32c89f60604c0188 Author: Werner Koch Date: Thu Mar 22 17:42:20 2018 +0100 yat2m: Avoid compiler warnings * doc/yat2m.c (evaluate_conditions): Mark args unused (proc_texi_cmd): Avoid shadowing warning. Signed-off-by: Werner Koch diff --git a/doc/yat2m.c b/doc/yat2m.c index 8c6319c..a509d1b 100644 --- a/doc/yat2m.c +++ b/doc/yat2m.c @@ -486,6 +486,9 @@ evaluate_conditions (const char *fname, int lnr) { int i; + (void)fname; + (void)lnr; + /* for (i=0; i < condition_stack_idx; i++) */ /* inf ("%s:%d: stack[%d] %s %s %c", */ /* fname, lnr, i, condition_stack[i]->isset? "set":"clr", */ @@ -857,18 +860,20 @@ proc_texi_cmd (FILE *fp, const char *command, const char *rest, size_t len, } else { - size_t len = s - (rest + 1); + size_t rlen = s - (rest + 1); macro_t m; for (m = variablelist; m; m = m->next) - if (strlen (m->name) == len - &&!strncmp (m->name, rest+1, len)) - break; + { + if (strlen (m->name) == rlen + && !strncmp (m->name, rest+1, rlen)) + break; + } if (m) fputs (m->value, fp); else inf ("texinfo variable '%.*s' is not set", - (int)len, rest+1); + (int)rlen, rest+1); } } break; commit 72b70167ea433d6bb46226b1008e2d8e911146a7 Author: Werner Koch Date: Thu Mar 22 17:21:32 2018 +0100 core: Remove outdated comments. -- diff --git a/src/argparse.c b/src/argparse.c index c5a942f..00ba68c 100644 --- a/src/argparse.c +++ b/src/argparse.c @@ -144,48 +144,6 @@ map_fixed_string (const char *string) } - -/********************************* - * @Summary arg_parse - * #include "argparse.h" - * - * You do not need to process the options 'h', '--help' or '--version' - * because this function includes standard help processing; but if you - * specify '-h', '--help' or '--version' you have to do it yourself. - * The option '--' stops argument processing; if bit 1 is set the function - * continues to return normal arguments. - * To process float args or unsigned args you must use a string args and do - * the conversion yourself. - * @Example - * - * gpgrt_opt_t opts[] = { - * { 'v', "verbose", 0 }, - * { 'd', "debug", 0 }, - * { 'o', "output", 2 }, - * { 'c', "cross-ref", 2|8 }, - * { 'm', "my-option", 1|8 }, - * { 300, "ignored-long-option, ARGPARSE_OP_IGNORE}, - * { 500, "have-no-short-option-for-this-long-option", 0 }, - * {0} }; - * gpgrt_argparse_t pargs = { &argc, &argv, 0 } - * - * while( ArgParse( &pargs, &opts) ) { - * switch( pargs.r_opt ) { - * case 'v': opt.verbose++; break; - * case 'd': opt.debug++; break; - * case 'o': opt.outfile = pargs.r.ret_str; break; - * case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break; - * case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break; - * case 500: opt.a_long_one++; break - * default : pargs.err = 1; break; -- force warning output -- - * } - * } - * if( argc > 1 ) - * log_fatal( "Too many args"); - * - */ - - /* Write STRING and all following const char * arguments either to stdout or, if IS_ERROR is set, to stderr. The list of strings must be terminated by a NULL. */ diff --git a/tests/t-argparse.c b/tests/t-argparse.c index 177992a..277d860 100644 --- a/tests/t-argparse.c +++ b/tests/t-argparse.c @@ -103,7 +103,8 @@ main (int argc, char **argv) } for (i=0; i < argc; i++ ) printf ("%3d -> (%s)\n", i, argv[i] ); - puts ("Options:"); + if (opt.verbose) + puts ("Options:"); if (opt.verbose) printf (" verbose=%d\n", opt.verbose ); if (opt.debug) commit ffc8f805165a13d16ed227051c59d732117ec9d4 Author: Werner Koch Date: Thu Mar 22 17:20:52 2018 +0100 core: Add Base-64 encoder. * src/b64enc.c: Change to fit into libgpg-error. * src/Makefile.am: Add b64enc.c * src/b64dec.c: Use xtrymalloc etc. Always use gpg_err_code_t. (_gpgrt_b64dec_start): Set decoder flag (_gpgrt_b64dec_finish): Check for conflict. (_gpgrt_b64state): Move to ... * src/gpgrt-int.h: here. Add new fields. * src/visibility.c (gpgrt_b64enc_start): New. (gpgrt_b64enc_write): New. (gpgrt_b64enc_finish): New. * src/gpg-error.vers, src/gpg-error.def.in: Add new functions. * src/gpg-error.h.in: Ditto. * src/visibility.h: Ditto. * tests/t-b64dec.c: Remove. * tests/t-b64.c: New. * tests/Makefile.am (TESTS): Replace t-b64dec by t-b64. -- Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index e21f534..de551f4 100644 --- a/NEWS +++ b/NEWS @@ -4,13 +4,16 @@ Noteworthy changes in version 1.29 (unreleased) [C23/A23/R_] * Interface changes relative to the 1.28 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - gpgrt_argparse New API. - gpgrt_usage New API. - gpgrt_strusage New API. - gpgrt_set_strusage New API. - gpgrt_set_usage_outfnc New API. - gpgrt_set_fixed_string_mapper New API. + gpgrt_argparse New. + gpgrt_usage New. + gpgrt_strusage New. + gpgrt_set_strusage New. + gpgrt_set_usage_outfnc New. + gpgrt_set_fixed_string_mapper New. GPGRT_ENABLE_ARGPARSE_MACROS New macro. + gpgrt_b64enc_start New. + gpgrt_b64enc_write New. + gpgrt_b64enc_finish New. Noteworthy changes in version 1.28 (2018-03-13) [C23/A23/R0] diff --git a/src/Makefile.am b/src/Makefile.am index 66c4414..42998e4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -190,7 +190,7 @@ libgpg_error_la_SOURCES = gettext.h $(arch_sources) \ sysutils.c \ syscall-clamp.c \ logging.c \ - b64dec.c \ + b64dec.c b64enc.c \ argparse.c diff --git a/src/b64dec.c b/src/b64dec.c index a8a8351..1235406 100644 --- a/src/b64dec.c +++ b/src/b64dec.c @@ -2,7 +2,7 @@ * Copyright (C) 2008, 2011 Free Software Foundation, Inc. * Copyright (C) 2008, 2011, 2016 g10 Code GmbH * - * This file is part of GnuPG. + * This file is part of Libgpg-error. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as @@ -16,26 +16,18 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This file was originally a part of GnuPG. */ #include #include #include #include -#include #include "gpgrt-int.h" -struct _gpgrt_b64state -{ - int idx; - int quad_count; - char *title; - unsigned char radbuf[4]; - int stop_seen:1; - int invalid_encoding:1; - gpg_error_t lasterr; -}; /* The reverse base-64 list used for base-64 decoding. */ static unsigned char const asctobin[128] = @@ -79,15 +71,15 @@ _gpgrt_b64dec_start (const char *title) if (title) { - t = strdup (title); + t = xtrystrdup (title); if (!t) return NULL; } - state = calloc (1, sizeof (struct _gpgrt_b64state)); + state = xtrycalloc (1, sizeof (struct _gpgrt_b64state)); if (!state) { - free (t); + xfree (t); return NULL; } @@ -99,13 +91,15 @@ _gpgrt_b64dec_start (const char *title) else state->idx = s_b64_0; + state->using_decoder = 1; + return state; } /* Do in-place decoding of base-64 data of LENGTH in BUFFER. Stores the new length of the buffer at R_NBYTES. */ -gpg_error_t +gpg_err_code_t _gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer, size_t length, size_t *r_nbytes) { @@ -120,8 +114,8 @@ _gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer, size_t length, if (state->stop_seen) { *r_nbytes = 0; - state->lasterr = gpg_error (GPG_ERR_EOF); - free (state->title); + state->lasterr = GPG_ERR_EOF; + xfree (state->title); state->title = NULL; return state->lasterr; } @@ -247,7 +241,7 @@ _gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer, size_t length, state->stop_seen = 1; break; default: - assert (!"invalid state"); + gpgrt_assert (!"invalid state"); } } @@ -262,17 +256,22 @@ _gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer, size_t length, /* Return an error code in case an encoding error has been found during decoding. */ -gpg_error_t +gpg_err_code_t _gpgrt_b64dec_finish (gpgrt_b64state_t state) { gpg_error_t err; - if (state->lasterr) + if (!state) + return 0; /* Already released. */ + + if (!state->using_decoder) + err = GPG_ERR_CONFLICT; /* State was allocated for the encoder. */ + else if (state->lasterr) err = state->lasterr; else { free (state->title); - err = state->invalid_encoding? gpg_error(GPG_ERR_BAD_DATA): 0; + err = state->invalid_encoding? GPG_ERR_BAD_DATA : 0; } free (state); diff --git a/src/b64enc.c b/src/b64enc.c index 91960c7..571f4ec 100644 --- a/src/b64enc.c +++ b/src/b64enc.c @@ -2,9 +2,9 @@ * Copyright (C) 2001, 2003, 2004, 2008, 2010, * 2011 Free Software Foundation, Inc. * Copyright (C) 2001, 2003, 2004, 2008, 2010, - * 2011 g10 Code GmbH + * 2011, 2018 g10 Code GmbH * - * This file is part of GnuPG. + * This file is part of Libgpg-error. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as @@ -18,17 +18,20 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This file was originally a part of GnuPG. */ #include #include +#include #include #include #include -#include -#include "i18n.h" -#include "util.h" +#include "gpgrt-int.h" + #define B64ENC_DID_HEADER 1 #define B64ENC_DID_TRAILER 2 @@ -36,9 +39,9 @@ #define B64ENC_USE_PGPCRC 32 /* The base-64 character list */ -static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; +static unsigned char const bintoasc[64] = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"); /* Stuff required to create the OpenPGP CRC. This crc_table has been created using this code: @@ -92,7 +95,7 @@ static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" } */ #define CRCINIT 0xB704CE -static const u32 crc_table[256] = { +static const uint32_t crc_table[256] = { 0x00000000, 0x00864cfb, 0x018ad50d, 0x010c99f6, 0x0393e6e1, 0x0315aa1a, 0x021933ec, 0x029f7f17, 0x07a18139, 0x0727cdc2, 0x062b5434, 0x06ad18cf, 0x043267d8, 0x04b42b23, 0x05b8b2d5, 0x053efe2e, 0x0fc54e89, 0x0f430272, @@ -139,14 +142,28 @@ static const u32 crc_table[256] = { }; -static gpg_error_t -enc_start (struct b64state *state, FILE *fp, estream_t stream, - const char *title) +/* Prepare for Base-64 writing to STREAM. If TITLE is not NULL and + * not an empty string, that string will be used as the title for the + * armor lines, with TITLE being an empty string, we don't write the + * header lines and furthermore even don't write any linefeeds. If + * TITLE starts with "PGP " the OpenPGP CRC checksum will be written + * as well. With TITLE being NULL, we merely don't write header but + * make sure that lines are not too long. Note, that we don't write + * anything unless at least one byte is written using b64enc_write. + * On success an enoder object is returned which needs to be released + * using _gpgrt_b64dec_finish. On error NULL is returned an ERRNO is + * set. + */ +gpgrt_b64state_t +_gpgrt_b64enc_start (estream_t stream, const char *title) { - memset (state, 0, sizeof *state); - state->fp = fp; + gpgrt_b64state_t state; + + state = xtrycalloc (1, sizeof *state); + if (!state) + return NULL; + state->stream = stream; - state->lasterr = 0; if (title && !*title) state->flags |= B64ENC_NO_LINEFEEDS; else if (title) @@ -158,50 +175,21 @@ enc_start (struct b64state *state, FILE *fp, estream_t stream, } state->title = xtrystrdup (title); if (!state->title) - state->lasterr = gpg_error_from_syserror (); + { + xfree (state); + return NULL; + } } - return state->lasterr; -} - - -/* Prepare for base-64 writing to the stream FP. If TITLE is not NULL - and not an empty string, this string will be used as the title for - the armor lines, with TITLE being an empty string, we don't write - the header lines and furthermore even don't write any linefeeds. - If TITLE starts with "PGP " the OpenPGP CRC checksum will be - written as well. With TITLE being NULL, we merely don't write - header but make sure that lines are not too long. Note, that we - don't write any output unless at least one byte get written using - b64enc_write. */ -gpg_error_t -b64enc_start (struct b64state *state, FILE *fp, const char *title) -{ - return enc_start (state, fp, NULL, title); -} - -/* Same as b64enc_start but takes an estream. */ -gpg_error_t -b64enc_start_es (struct b64state *state, estream_t fp, const char *title) -{ - return enc_start (state, NULL, fp, title); -} - -static int -my_fputs (const char *string, struct b64state *state) -{ - if (state->stream) - return es_fputs (string, state->stream); - else - return fputs (string, state->fp); + return state; } -/* Write NBYTES from BUFFER to the Base 64 stream identified by - STATE. With BUFFER and NBYTES being 0, merely do a fflush on the - stream. */ -gpg_error_t -b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) +/* Write NBYTES from BUFFER to the Base 64 stream identified by STATE. + * With BUFFER and NBYTES being 0, merely do a fflush on the stream. + */ +gpg_err_code_t +_gpgrt_b64enc_write (gpgrt_b64state_t state, const void *buffer, size_t nbytes) { unsigned char radbuf[4]; int idx, quad_count; @@ -213,7 +201,7 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) if (!nbytes) { if (buffer) - if (state->stream? es_fflush (state->stream) : fflush (state->fp)) + if (_gpgrt_fflush (state->stream)) goto write_error; return 0; } @@ -222,12 +210,12 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) { if (state->title) { - if ( my_fputs ("-----BEGIN ", state) == EOF - || my_fputs (state->title, state) == EOF - || my_fputs ("-----\n", state) == EOF) + if ( _gpgrt_fputs ("-----BEGIN ", state->stream) == EOF + || _gpgrt_fputs (state->title, state->stream) == EOF + || _gpgrt_fputs ("-----\n", state->stream) == EOF) goto write_error; if ( (state->flags & B64ENC_USE_PGPCRC) - && my_fputs ("\n", state) == EOF) + && _gpgrt_fputs ("\n", state->stream) == EOF) goto write_error; } @@ -236,16 +224,16 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) idx = state->idx; quad_count = state->quad_count; - assert (idx < 4); + gpgrt_assert (idx < 4); memcpy (radbuf, state->radbuf, idx); if ( (state->flags & B64ENC_USE_PGPCRC) ) { size_t n; - u32 crc = state->crc; + uint32_t crc = state->crc; for (p=buffer, n=nbytes; n; p++, n-- ) - crc = ((u32)crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ *p]; + crc = ((uint32_t)crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ *p]; state->crc = (crc & 0x00ffffff); } @@ -260,27 +248,17 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; tmp[3] = bintoasc[radbuf[2]&077]; - if (state->stream) - { - for (idx=0; idx < 4; idx++) - es_putc (tmp[idx], state->stream); - idx = 0; - if (es_ferror (state->stream)) - goto write_error; - } - else - { - for (idx=0; idx < 4; idx++) - putc (tmp[idx], state->fp); - idx = 0; - if (ferror (state->fp)) - goto write_error; - } + for (idx=0; idx < 4; idx++) + _gpgrt_fputc (tmp[idx], state->stream); + idx = 0; + if (_gpgrt_ferror (state->stream)) + goto write_error; + if (++quad_count >= (64/4)) { quad_count = 0; if (!(state->flags & B64ENC_NO_LINEFEEDS) - && my_fputs ("\n", state) == EOF) + && _gpgrt_fputs ("\n", state->stream) == EOF) goto write_error; } } @@ -291,7 +269,7 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) return 0; write_error: - state->lasterr = gpg_error_from_syserror (); + state->lasterr = _gpg_err_code_from_syserror (); if (state->title) { xfree (state->title); @@ -301,16 +279,28 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) } -gpg_error_t -b64enc_finish (struct b64state *state) +gpg_err_code_t +_gpgrt_b64enc_finish (gpgrt_b64state_t state) { - gpg_error_t err = 0; + gpg_err_code_t err = 0; unsigned char radbuf[4]; int idx, quad_count; char tmp[4]; + if (!state) + return 0; /* Already released. */ + + if (state->using_decoder) + { + err = GPG_ERR_CONFLICT; /* State was created for the decoder. */ + goto cleanup; + } + if (state->lasterr) - return state->lasterr; + { + err = state->lasterr; + goto cleanup; + } if (!(state->flags & B64ENC_DID_HEADER)) goto cleanup; @@ -318,7 +308,7 @@ b64enc_finish (struct b64state *state) /* Flush the base64 encoding */ idx = state->idx; quad_count = state->quad_count; - assert (idx < 4); + gpgrt_assert (idx < 4); memcpy (radbuf, state->radbuf, idx); if (idx) @@ -336,26 +326,16 @@ b64enc_finish (struct b64state *state) tmp[2] = bintoasc[((radbuf[1] << 2) & 074) & 077]; tmp[3] = '='; } - if (state->stream) - { - for (idx=0; idx < 4; idx++) - es_putc (tmp[idx], state->stream); - if (es_ferror (state->stream)) - goto write_error; - } - else - { - for (idx=0; idx < 4; idx++) - putc (tmp[idx], state->fp); - if (ferror (state->fp)) - goto write_error; - } + for (idx=0; idx < 4; idx++) + _gpgrt_fputc (tmp[idx], state->stream); + if (_gpgrt_ferror (state->stream)) + goto write_error; if (++quad_count >= (64/4)) { quad_count = 0; if (!(state->flags & B64ENC_NO_LINEFEEDS) - && my_fputs ("\n", state) == EOF) + && _gpgrt_fputs ("\n", state->stream) == EOF) goto write_error; } } @@ -363,13 +343,13 @@ b64enc_finish (struct b64state *state) /* Finish the last line and write the trailer. */ if (quad_count && !(state->flags & B64ENC_NO_LINEFEEDS) - && my_fputs ("\n", state) == EOF) + && _gpgrt_fputs ("\n", state->stream) == EOF) goto write_error; if ( (state->flags & B64ENC_USE_PGPCRC) ) { /* Write the CRC. */ - my_fputs ("=", state); + _gpgrt_fputs ("=", state->stream); radbuf[0] = state->crc >>16; radbuf[1] = state->crc >> 8; radbuf[2] = state->crc; @@ -377,46 +357,30 @@ b64enc_finish (struct b64state *state) tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; tmp[3] = bintoasc[radbuf[2]&077]; - if (state->stream) - { - for (idx=0; idx < 4; idx++) - es_putc (tmp[idx], state->stream); - if (es_ferror (state->stream)) - goto write_error; - } - else - { - for (idx=0; idx < 4; idx++) - putc (tmp[idx], state->fp); - if (ferror (state->fp)) - goto write_error; - } + for (idx=0; idx < 4; idx++) + _gpgrt_fputc (tmp[idx], state->stream); + if (_gpgrt_ferror (state->stream)) + goto write_error; + if (!(state->flags & B64ENC_NO_LINEFEEDS) - && my_fputs ("\n", state) == EOF) + && _gpgrt_fputs ("\n", state->stream) == EOF) goto write_error; } if (state->title) { - if ( my_fputs ("-----END ", state) == EOF - || my_fputs (state->title, state) == EOF - || my_fputs ("-----\n", state) == EOF) + if ( _gpgrt_fputs ("-----END ", state->stream) == EOF + || _gpgrt_fputs (state->title, state->stream) == EOF + || _gpgrt_fputs ("-----\n", state->stream) == EOF) goto write_error; } - goto cleanup; + cleanup: + xfree (state->title); + xfree (state); + return err; write_error: err = gpg_error_from_syserror (); - - cleanup: - if (state->title) - { - xfree (state->title); - state->title = NULL; - } - state->fp = NULL; - state->stream = NULL; - state->lasterr = err; - return err; + goto cleanup; } diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in index 33ef794..67bb12e 100644 --- a/src/gpg-error.def.in +++ b/src/gpg-error.def.in @@ -214,5 +214,9 @@ EXPORTS gpgrt_set_usage_outfnc @164 gpgrt_set_fixed_string_mapper @165 + gpgrt_b64enc_start @166 + gpgrt_b64enc_write @167 + gpgrt_b64enc_finish @168 + ;; end of file with public symbols for Windows. diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index c0656e2..a36e8b1 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -908,16 +908,22 @@ int gpgrt_vsnprintf (char *buf,size_t bufsize, /* - * Base64 decode functions. + * Base64 encode and decode functions. */ struct _gpgrt_b64state; typedef struct _gpgrt_b64state *gpgrt_b64state_t; +gpgrt_b64state_t gpgrt_b64enc_start (gpgrt_stream_t stream, const char *title); +gpg_err_code_t gpgrt_b64enc_write (gpgrt_b64state_t state, + const void *buffer, size_t nbytes); +gpg_err_code_t gpgrt_b64enc_finish (gpgrt_b64state_t state); + gpgrt_b64state_t gpgrt_b64dec_start (const char *title); -gpg_error_t gpgrt_b64dec_proc (gpgrt_b64state_t state, - void *buffer, size_t length, size_t *r_nbytes); -gpg_error_t gpgrt_b64dec_finish (gpgrt_b64state_t state); +gpg_error_t gpgrt_b64dec_proc (gpgrt_b64state_t state, + void *buffer, size_t length, + size_t *r_nbytes); +gpg_error_t gpgrt_b64dec_finish (gpgrt_b64state_t state); diff --git a/src/gpg-error.vers b/src/gpg-error.vers index c7de3c4..201b784 100644 --- a/src/gpg-error.vers +++ b/src/gpg-error.vers @@ -186,6 +186,11 @@ GPG_ERROR_1.0 { gpgrt_set_usage_outfnc; gpgrt_set_fixed_string_mapper; + gpgrt_b64enc_start; + gpgrt_b64enc_write; + gpgrt_b64enc_finish; + + local: *; }; diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h index 5d54a51..34e494c 100644 --- a/src/gpgrt-int.h +++ b/src/gpgrt-int.h @@ -480,10 +480,30 @@ int _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout); * Local prototypes for the encoders. */ +struct _gpgrt_b64state +{ + int idx; + int quad_count; + estream_t stream; + char *title; + unsigned char radbuf[4]; + unsigned int crc; + gpg_err_code_t lasterr; + unsigned int flags; + int stop_seen:1; + int invalid_encoding:1; + int using_decoder:1; +}; + +gpgrt_b64state_t _gpgrt_b64enc_start (estream_t stream, const char *title); +gpg_err_code_t _gpgrt_b64enc_write (gpgrt_b64state_t state, + const void *buffer, size_t nbytes); +gpg_err_code_t _gpgrt_b64enc_finish (gpgrt_b64state_t state); + gpgrt_b64state_t _gpgrt_b64dec_start (const char *title); -gpg_error_t _gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer, - size_t length, size_t *r_nbytes); -gpg_error_t _gpgrt_b64dec_finish (gpgrt_b64state_t state); +gpg_err_code_t _gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer, + size_t length, size_t *r_nbytes); +gpg_err_code_t _gpgrt_b64dec_finish (gpgrt_b64state_t state); diff --git a/src/visibility.c b/src/visibility.c index 315bf32..6f8bb24 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -790,6 +790,24 @@ gpgrt_getcwd (void) gpgrt_b64state_t +gpgrt_b64enc_start (estream_t stream, const char *title) +{ + return _gpgrt_b64enc_start (stream, title); +} + +gpg_err_code_t +gpgrt_b64enc_write (gpgrt_b64state_t state, const void *buffer, size_t nbytes) +{ + return _gpgrt_b64enc_write (state, buffer, nbytes); +} + +gpg_err_code_t +gpgrt_b64enc_finish (gpgrt_b64state_t state) +{ + return _gpgrt_b64enc_finish (state); +} + +gpgrt_b64state_t gpgrt_b64dec_start (const char *title) { return _gpgrt_b64dec_start (title); diff --git a/src/visibility.h b/src/visibility.h index eae0f81..cfa32e5 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -161,6 +161,9 @@ MARK_VISIBLE (gpgrt_getcwd) MARK_VISIBLE (gpgrt_b64dec_start) MARK_VISIBLE (gpgrt_b64dec_proc) MARK_VISIBLE (gpgrt_b64dec_finish) +MARK_VISIBLE (gpgrt_b64enc_start) +MARK_VISIBLE (gpgrt_b64enc_write) +MARK_VISIBLE (gpgrt_b64enc_finish) MARK_VISIBLE (gpgrt_get_errorcount) MARK_VISIBLE (gpgrt_inc_errorcount) @@ -327,6 +330,9 @@ MARK_VISIBLE (gpgrt_set_usage_outfnc); #define gpgrt_get_syscall_clamp _gpgrt_USE_UNDERSCORED_FUNCTION #define gpgrt_set_alloc_func _gpgrt_USE_UNDERSCORED_FUNCTION +#define gpgrt_b64enc_start _gpgrt_USE_UNDERSCORED_FUNCTION +#define gpgrt_b64enc_write _gpgrt_USE_UNDERSCORED_FUNCTION +#define gpgrt_b64enc_finish _gpgrt_USE_UNDERSCORED_FUNCTION #define gpgrt_b64dec_start _gpgrt_USE_UNDERSCORED_FUNCTION #define gpgrt_b64dec_proc _gpgrt_USE_UNDERSCORED_FUNCTION #define gpgrt_b64dec_finish _gpgrt_USE_UNDERSCORED_FUNCTION diff --git a/tests/Makefile.am b/tests/Makefile.am index cc3a2ad..b14fdc8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -27,7 +27,7 @@ endif gpg_error_lib = ../src/libgpg-error.la -TESTS = t-version t-strerror t-syserror t-lock t-printf t-poll t-b64dec \ +TESTS = t-version t-strerror t-syserror t-lock t-printf t-poll t-b64 \ t-argparse AM_CPPFLAGS = -I$(top_builddir)/src $(extra_includes) diff --git a/tests/t-b64.c b/tests/t-b64.c new file mode 100644 index 0000000..96e8fa4 --- /dev/null +++ b/tests/t-b64.c @@ -0,0 +1,373 @@ +/* t-b64.c - b64dec tests. + * Copyright (C) 2017, 2018 g10 Code GmbH + * + * This file is part of Libgpg-error. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#if HAVE_STDLIB_H +#include +#endif + +#define PGM "t-b64" +#include "t-common.h" + +static const char *test_string = "libgpg-error is free software; " + "you can redistribute it and/or modify it under the terms of " + "the GNU Lesser General Public License as published by the Free " + "Software Foundation; either version 2.1 of the License, or " + "(at your option) any later version."; + +static const char *test_string_b64_0 = "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29" + "mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgd" + "W5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIEx" + "pY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb" + "247IGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXI" + "gb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4="; + +static const char *test_string_b64_1 = + "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmli\n" + "dXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBH\n" + "TlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5\n" + "IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIu\n" + "MSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg\n" + "dmVyc2lvbi4=\n"; + +static const char *test_string_b64_2 = + "-----BEGIN DATA-----\n" + "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmli\n" + "dXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBH\n" + "TlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5\n" + "IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIu\n" + "MSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg\n" + "dmVyc2lvbi4=\n" + "-----END DATA-----\n"; + +static const char *test_string_b64_3 = + "-----BEGIN PGP ARMORED FILE-----\n" + "\n" + "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmli\n" + "dXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBH\n" + "TlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5\n" + "IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIu\n" + "MSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg\n" + "dmVyc2lvbi4=\n" + "=4BMJ\n" + "-----END PGP ARMORED FILE-----\n"; + +static const char *test_blob_1 = "\x01\x03\x04\xff"; +static const char *test_blob_1_b64_0 = "AQME/w=="; +static const char *test_blob_2 = "\x01\x03\x04\xff""A"; +static const char *test_blob_2_b64_0 = "AQME/0E="; +static const char *test_blob_3 = "\x01\x03\x04\xff""AB"; +static const char *test_blob_3_b64_0 = "AQME/0FC"; + + +#define FAIL(a) do { fail ("line %d: test %d failed\n", __LINE__, (a)); \ + } while(0) + +static gpg_error_t +test_b64enc_string (const char *string, const char *expected, const char *title) +{ + gpg_err_code_t err; + estream_t fp; + gpgrt_b64state_t state; + char *result; + + fp = es_fopenmem (0, "rwb"); + if (!fp) + die ("es_fopenmem failed: %s\n", gpg_strerror (gpg_error_from_syserror ())); + + state = gpgrt_b64enc_start (fp, title); + if (!state) + { + err = gpg_err_code_from_syserror (); + fail ("gpgrt_b64enc_start failed: %s\n", gpg_strerror (err)); + return err; + } + + err = gpgrt_b64enc_write (state, string, strlen (string)); + if (err) + { + fail ("gpgrt_b64enc_write failed: %s\n", gpg_strerror (err)); + return err; + } + + err = gpgrt_b64enc_finish (state); + if (err) + { + fail ("gpgrt_b64enc_finish failed: %s\n", gpg_strerror (err)); + return err; + } + + es_fputc (0, fp); + if (es_fclose_snatch (fp, (void**)&result, NULL)) + die ("es_fclose_snatch failed: %s\n", + gpg_strerror (gpg_error_from_syserror ())); + + if (strcmp (result, expected)) + { + if (verbose) + { + gpgrt_log_debug_string (result, "result: "); + gpgrt_log_debug_string (expected, "expect: "); + } + return GPG_ERR_FALSE; + } + + es_free (result); + return 0; +} + + +static gpg_error_t +test_b64dec_string (const char *string, const char *expected, const char *title) +{ + gpg_error_t err; + gpgrt_b64state_t state; + char *buffer; + size_t len; + + len = strlen (string); + buffer = malloc (strlen (string) + 1); + if (!buffer) + { + err = gpg_error_from_syserror (); + return err; + } + strcpy (buffer, string); + + state = gpgrt_b64dec_start (title); + if (!state) + { + err = gpg_err_code_from_syserror (); + fail ("gpgrt_b64dec_start failed: %s\n", gpg_strerror (err)); + return err; + } + + err = gpgrt_b64dec_proc (state, buffer, len, &len); + if (err) + { + if (gpg_err_code (err) != GPG_ERR_EOF) + { + free (buffer); + free (state); + return err; + } + } + + err = gpgrt_b64dec_finish (state); + if (err) + { + free (buffer); + return err; + } + + if (len != strlen (expected) || strncmp (buffer, expected, len)) + { + if (verbose) + { + gpgrt_log_debug_string (buffer, "result(len=%zu): ", len); + gpgrt_log_debug_string (expected, "expect(len=%zu): ", + strlen (expected)); + } + return GPG_ERR_FALSE; + } + + free (buffer); + return 0; +} + + +static void +encoder_tests (void) +{ + gpg_err_code_t err; + + if (verbose) + show ("running encoder tests\n"); + + err = test_b64enc_string (test_string, test_string_b64_0, ""); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + err = test_b64enc_string (test_string, test_string_b64_1, NULL); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + err = test_b64enc_string (test_string, test_string_b64_2, "DATA"); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + err = test_b64enc_string (test_string, test_string_b64_3, "PGP ARMORED FILE"); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + + /* Note that the _test_ function dows not allow to provide a string + * with an empdded Nul. */ + err = test_b64enc_string (test_blob_1, test_blob_1_b64_0, ""); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + err = test_b64enc_string (test_blob_2, test_blob_2_b64_0, ""); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + err = test_b64enc_string (test_blob_3, test_blob_3_b64_0, ""); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + + err = test_b64enc_string ("@", "QA==", ""); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + err = test_b64enc_string ("@", "QA==\n", NULL); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + err = test_b64enc_string ("@", + "-----BEGIN PGP SOMETHING-----\n" + "\n" + "QA==\n" + "=eMoB\n" + "-----END PGP SOMETHING-----\n", + "PGP SOMETHING"); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + + err = test_b64enc_string ("", "", ""); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + err = test_b64enc_string ("", "", NULL); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + err = test_b64enc_string ("", "", "PGP SOMETHING"); + if (err) + fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); +} + + +static void +decoder_tests (void) +{ + gpg_err_code_t err; + + if (verbose) + show ("running decoder tests\n"); + + err = test_b64dec_string (test_string_b64_0, test_string, NULL); + if (err) + fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + + err = test_b64dec_string (test_string_b64_1, test_string, NULL); + if (err) + fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + + err = test_b64dec_string (test_string_b64_2, test_string, ""); + if (err) + fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + + err = test_b64dec_string (test_string_b64_2, test_string, NULL); + if (err != GPG_ERR_BAD_DATA) + fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); + +} + + +static gpg_error_t +extra_tests (void) +{ + gpg_err_code_t err; + gpgrt_b64state_t state; + + if (verbose) + show ("running extra tests\n"); + + /* Check that we detect mismacthed use of enc and dec functions. */ + state = gpgrt_b64enc_start (es_stdout, NULL); + if (!state) + { + err = gpg_err_code_from_syserror (); + fail ("gpgrt_b64enc_start failed: %s\n", gpg_strerror (err)); + return err; + } + + err = gpgrt_b64dec_finish (state); + if (err != GPG_ERR_CONFLICT) + { + fail ("gpgrt_b64dec_finish failed: %s\n", gpg_strerror (err)); + return err; + } + + state = gpgrt_b64dec_start (NULL); + if (!state) + { + err = gpg_err_code_from_syserror (); + fail ("gpgrt_b64dec_start failed: %s\n", gpg_strerror (err)); + return err; + } + + err = gpgrt_b64enc_finish (state); + if (err != GPG_ERR_CONFLICT) + { + fail ("gpgrt_b64enc_finish failed: %s\n", gpg_strerror (err)); + return err; + } + + return 0; +} + + +int +main (int argc, char **argv) +{ + int last_argc = -1; + + if (argc) + { + argc--; argv++; + } + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--help")) + { + puts ( +"usage: ./" PGM " [options]\n" +"\n" +"Options:\n" +" --verbose Show what is going on\n" +" --debug Flyswatter\n" +); + exit (0); + } + if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--debug")) + { + verbose = debug = 1; + argc--; argv++; + } + } + + encoder_tests (); + decoder_tests (); + extra_tests (); + + return !!errorcount; +} diff --git a/tests/t-b64dec.c b/tests/t-b64dec.c deleted file mode 100644 index aae208b..0000000 --- a/tests/t-b64dec.c +++ /dev/null @@ -1,123 +0,0 @@ -/* t-b64dec.c - b64dec test. - Copyright (C) 2017 g10 Code GmbH - - This file is part of libgpg-error. - - libgpg-error is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - libgpg-error is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with libgpgme-error; if not, write to the Free - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#if HAVE_CONFIG_H -#include -#endif - -#include -#include -#if HAVE_STDLIB_H -#include -#endif - -#include - -static const char *test_b64_string = "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29" - "mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgd" - "W5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIEx" - "pY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb" - "247IGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXI" - "gb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4="; - -static const char *test_string = "libgpg-error is free software; " - "you can redistribute it and/or modify it under the terms of " - "the GNU Lesser General Public License as published by the Free " - "Software Foundation; either version 2.1 of the License, or " - "(at your option) any later version."; - -#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ - __FILE__,__LINE__, (a)); \ - errcount++; \ - } while(0) - -static int errcount; - -static gpg_error_t -test_b64dec_string (const char *string, const char *expected) -{ - gpg_error_t err; - gpgrt_b64state_t state; - char *buffer; - size_t len; - - len = strlen (string); - buffer = malloc (strlen (string) + 1); - if (!buffer) - { - err = gpg_error_from_syserror (); - return err; - } - - state = gpgrt_b64dec_start (""); - if (!state) - { - err = gpg_error_from_syserror (); - free (buffer); - return err; - } - - err = gpgrt_b64dec_proc (state, buffer, len, &len); - if (err) - { - if (gpg_err_code (err) != GPG_ERR_EOF) - { - free (buffer); - free (state); - return err; - } - } - - err = gpgrt_b64dec_finish (state); - if (err) - { - free (buffer); - return err; - } - - if (strncmp (buffer, expected, len) == 0) - err = 0; - else - err = GPG_ERR_INTERNAL; - - free (buffer); - return err; -} - - - -int -main (int argc, char **argv) -{ - gpg_error_t err; - - (void)argc; - (void)argv; - - err = test_b64dec_string (test_b64_string, test_string); - - if (err) - { - fail (1); - return 1; - } - else - return 0; -} commit b3df10d6620894bc4047af1e14239b258e440803 Author: Werner Koch Date: Thu Mar 22 08:26:51 2018 +0100 core: Add file b64enc.c from gnupg -- This is from GnuPG commit fa0ed1c7e2eee7c559026696e6b21acc882a97aa with two tabs replaced by spaces. Signed-off-by: Werner Koch diff --git a/src/b64enc.c b/src/b64enc.c new file mode 100644 index 0000000..91960c7 --- /dev/null +++ b/src/b64enc.c @@ -0,0 +1,422 @@ +/* b64enc.c - Simple Base64 encoder. + * Copyright (C) 2001, 2003, 2004, 2008, 2010, + * 2011 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2004, 2008, 2010, + * 2011 g10 Code GmbH + * + * This file is part of GnuPG. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "i18n.h" +#include "util.h" + +#define B64ENC_DID_HEADER 1 +#define B64ENC_DID_TRAILER 2 +#define B64ENC_NO_LINEFEEDS 16 +#define B64ENC_USE_PGPCRC 32 + +/* The base-64 character list */ +static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +/* Stuff required to create the OpenPGP CRC. This crc_table has been + created using this code: + + #include + #include + + #define CRCPOLY 0x864CFB + + int + main (void) + { + int i, j; + uint32_t t; + uint32_t crc_table[256]; + + crc_table[0] = 0; + for (i=j=0; j < 128; j++ ) + { + t = crc_table[j]; + if ( (t & 0x00800000) ) + { + t <<= 1; + crc_table[i++] = t ^ CRCPOLY; + crc_table[i++] = t; + } + else + { + t <<= 1; + crc_table[i++] = t; + crc_table[i++] = t ^ CRCPOLY; + } + } + + puts ("static const u32 crc_table[256] = {"); + for (i=j=0; i < 256; i++) + { + printf ("%s 0x%08lx", j? "":" ", (unsigned long)crc_table[i]); + if (i != 255) + { + putchar (','); + if ( ++j > 5) + { + j = 0; + putchar ('\n'); + } + } + } + puts ("\n};"); + return 0; + } +*/ +#define CRCINIT 0xB704CE +static const u32 crc_table[256] = { + 0x00000000, 0x00864cfb, 0x018ad50d, 0x010c99f6, 0x0393e6e1, 0x0315aa1a, + 0x021933ec, 0x029f7f17, 0x07a18139, 0x0727cdc2, 0x062b5434, 0x06ad18cf, + 0x043267d8, 0x04b42b23, 0x05b8b2d5, 0x053efe2e, 0x0fc54e89, 0x0f430272, + 0x0e4f9b84, 0x0ec9d77f, 0x0c56a868, 0x0cd0e493, 0x0ddc7d65, 0x0d5a319e, + 0x0864cfb0, 0x08e2834b, 0x09ee1abd, 0x09685646, 0x0bf72951, 0x0b7165aa, + 0x0a7dfc5c, 0x0afbb0a7, 0x1f0cd1e9, 0x1f8a9d12, 0x1e8604e4, 0x1e00481f, + 0x1c9f3708, 0x1c197bf3, 0x1d15e205, 0x1d93aefe, 0x18ad50d0, 0x182b1c2b, + 0x192785dd, 0x19a1c926, 0x1b3eb631, 0x1bb8faca, 0x1ab4633c, 0x1a322fc7, + 0x10c99f60, 0x104fd39b, 0x11434a6d, 0x11c50696, 0x135a7981, 0x13dc357a, + 0x12d0ac8c, 0x1256e077, 0x17681e59, 0x17ee52a2, 0x16e2cb54, 0x166487af, + 0x14fbf8b8, 0x147db443, 0x15712db5, 0x15f7614e, 0x3e19a3d2, 0x3e9fef29, + 0x3f9376df, 0x3f153a24, 0x3d8a4533, 0x3d0c09c8, 0x3c00903e, 0x3c86dcc5, + 0x39b822eb, 0x393e6e10, 0x3832f7e6, 0x38b4bb1d, 0x3a2bc40a, 0x3aad88f1, + 0x3ba11107, 0x3b275dfc, 0x31dced5b, 0x315aa1a0, 0x30563856, 0x30d074ad, + 0x324f0bba, 0x32c94741, 0x33c5deb7, 0x3343924c, 0x367d6c62, 0x36fb2099, + 0x37f7b96f, 0x3771f594, 0x35ee8a83, 0x3568c678, 0x34645f8e, 0x34e21375, + 0x2115723b, 0x21933ec0, 0x209fa736, 0x2019ebcd, 0x228694da, 0x2200d821, + 0x230c41d7, 0x238a0d2c, 0x26b4f302, 0x2632bff9, 0x273e260f, 0x27b86af4, + 0x252715e3, 0x25a15918, 0x24adc0ee, 0x242b8c15, 0x2ed03cb2, 0x2e567049, + 0x2f5ae9bf, 0x2fdca544, 0x2d43da53, 0x2dc596a8, 0x2cc90f5e, 0x2c4f43a5, + 0x2971bd8b, 0x29f7f170, 0x28fb6886, 0x287d247d, 0x2ae25b6a, 0x2a641791, + 0x2b688e67, 0x2beec29c, 0x7c3347a4, 0x7cb50b5f, 0x7db992a9, 0x7d3fde52, + 0x7fa0a145, 0x7f26edbe, 0x7e2a7448, 0x7eac38b3, 0x7b92c69d, 0x7b148a66, + 0x7a181390, 0x7a9e5f6b, 0x7801207c, 0x78876c87, 0x798bf571, 0x790db98a, + 0x73f6092d, 0x737045d6, 0x727cdc20, 0x72fa90db, 0x7065efcc, 0x70e3a337, + 0x71ef3ac1, 0x7169763a, 0x74578814, 0x74d1c4ef, 0x75dd5d19, 0x755b11e2, + 0x77c46ef5, 0x7742220e, 0x764ebbf8, 0x76c8f703, 0x633f964d, 0x63b9dab6, + 0x62b54340, 0x62330fbb, 0x60ac70ac, 0x602a3c57, 0x6126a5a1, 0x61a0e95a, + 0x649e1774, 0x64185b8f, 0x6514c279, 0x65928e82, 0x670df195, 0x678bbd6e, + 0x66872498, 0x66016863, 0x6cfad8c4, 0x6c7c943f, 0x6d700dc9, 0x6df64132, + 0x6f693e25, 0x6fef72de, 0x6ee3eb28, 0x6e65a7d3, 0x6b5b59fd, 0x6bdd1506, + 0x6ad18cf0, 0x6a57c00b, 0x68c8bf1c, 0x684ef3e7, 0x69426a11, 0x69c426ea, + 0x422ae476, 0x42aca88d, 0x43a0317b, 0x43267d80, 0x41b90297, 0x413f4e6c, + 0x4033d79a, 0x40b59b61, 0x458b654f, 0x450d29b4, 0x4401b042, 0x4487fcb9, + 0x461883ae, 0x469ecf55, 0x479256a3, 0x47141a58, 0x4defaaff, 0x4d69e604, + 0x4c657ff2, 0x4ce33309, 0x4e7c4c1e, 0x4efa00e5, 0x4ff69913, 0x4f70d5e8, + 0x4a4e2bc6, 0x4ac8673d, 0x4bc4fecb, 0x4b42b230, 0x49ddcd27, 0x495b81dc, + 0x4857182a, 0x48d154d1, 0x5d26359f, 0x5da07964, 0x5cace092, 0x5c2aac69, + 0x5eb5d37e, 0x5e339f85, 0x5f3f0673, 0x5fb94a88, 0x5a87b4a6, 0x5a01f85d, + 0x5b0d61ab, 0x5b8b2d50, 0x59145247, 0x59921ebc, 0x589e874a, 0x5818cbb1, + 0x52e37b16, 0x526537ed, 0x5369ae1b, 0x53efe2e0, 0x51709df7, 0x51f6d10c, + 0x50fa48fa, 0x507c0401, 0x5542fa2f, 0x55c4b6d4, 0x54c82f22, 0x544e63d9, + 0x56d11cce, 0x56575035, 0x575bc9c3, 0x57dd8538 +}; + + +static gpg_error_t +enc_start (struct b64state *state, FILE *fp, estream_t stream, + const char *title) +{ + memset (state, 0, sizeof *state); + state->fp = fp; + state->stream = stream; + state->lasterr = 0; + if (title && !*title) + state->flags |= B64ENC_NO_LINEFEEDS; + else if (title) + { + if (!strncmp (title, "PGP ", 4)) + { + state->flags |= B64ENC_USE_PGPCRC; + state->crc = CRCINIT; + } + state->title = xtrystrdup (title); + if (!state->title) + state->lasterr = gpg_error_from_syserror (); + } + return state->lasterr; +} + + +/* Prepare for base-64 writing to the stream FP. If TITLE is not NULL + and not an empty string, this string will be used as the title for + the armor lines, with TITLE being an empty string, we don't write + the header lines and furthermore even don't write any linefeeds. + If TITLE starts with "PGP " the OpenPGP CRC checksum will be + written as well. With TITLE being NULL, we merely don't write + header but make sure that lines are not too long. Note, that we + don't write any output unless at least one byte get written using + b64enc_write. */ +gpg_error_t +b64enc_start (struct b64state *state, FILE *fp, const char *title) +{ + return enc_start (state, fp, NULL, title); +} + +/* Same as b64enc_start but takes an estream. */ +gpg_error_t +b64enc_start_es (struct b64state *state, estream_t fp, const char *title) +{ + return enc_start (state, NULL, fp, title); +} + + +static int +my_fputs (const char *string, struct b64state *state) +{ + if (state->stream) + return es_fputs (string, state->stream); + else + return fputs (string, state->fp); +} + + +/* Write NBYTES from BUFFER to the Base 64 stream identified by + STATE. With BUFFER and NBYTES being 0, merely do a fflush on the + stream. */ +gpg_error_t +b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) +{ + unsigned char radbuf[4]; + int idx, quad_count; + const unsigned char *p; + + if (state->lasterr) + return state->lasterr; + + if (!nbytes) + { + if (buffer) + if (state->stream? es_fflush (state->stream) : fflush (state->fp)) + goto write_error; + return 0; + } + + if (!(state->flags & B64ENC_DID_HEADER)) + { + if (state->title) + { + if ( my_fputs ("-----BEGIN ", state) == EOF + || my_fputs (state->title, state) == EOF + || my_fputs ("-----\n", state) == EOF) + goto write_error; + if ( (state->flags & B64ENC_USE_PGPCRC) + && my_fputs ("\n", state) == EOF) + goto write_error; + } + + state->flags |= B64ENC_DID_HEADER; + } + + idx = state->idx; + quad_count = state->quad_count; + assert (idx < 4); + memcpy (radbuf, state->radbuf, idx); + + if ( (state->flags & B64ENC_USE_PGPCRC) ) + { + size_t n; + u32 crc = state->crc; + + for (p=buffer, n=nbytes; n; p++, n-- ) + crc = ((u32)crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ *p]; + state->crc = (crc & 0x00ffffff); + } + + for (p=buffer; nbytes; p++, nbytes--) + { + radbuf[idx++] = *p; + if (idx > 2) + { + char tmp[4]; + + tmp[0] = bintoasc[(*radbuf >> 2) & 077]; + tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; + tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; + tmp[3] = bintoasc[radbuf[2]&077]; + if (state->stream) + { + for (idx=0; idx < 4; idx++) + es_putc (tmp[idx], state->stream); + idx = 0; + if (es_ferror (state->stream)) + goto write_error; + } + else + { + for (idx=0; idx < 4; idx++) + putc (tmp[idx], state->fp); + idx = 0; + if (ferror (state->fp)) + goto write_error; + } + if (++quad_count >= (64/4)) + { + quad_count = 0; + if (!(state->flags & B64ENC_NO_LINEFEEDS) + && my_fputs ("\n", state) == EOF) + goto write_error; + } + } + } + memcpy (state->radbuf, radbuf, idx); + state->idx = idx; + state->quad_count = quad_count; + return 0; + + write_error: + state->lasterr = gpg_error_from_syserror (); + if (state->title) + { + xfree (state->title); + state->title = NULL; + } + return state->lasterr; +} + + +gpg_error_t +b64enc_finish (struct b64state *state) +{ + gpg_error_t err = 0; + unsigned char radbuf[4]; + int idx, quad_count; + char tmp[4]; + + if (state->lasterr) + return state->lasterr; + + if (!(state->flags & B64ENC_DID_HEADER)) + goto cleanup; + + /* Flush the base64 encoding */ + idx = state->idx; + quad_count = state->quad_count; + assert (idx < 4); + memcpy (radbuf, state->radbuf, idx); + + if (idx) + { + tmp[0] = bintoasc[(*radbuf>>2)&077]; + if (idx == 1) + { + tmp[1] = bintoasc[((*radbuf << 4) & 060) & 077]; + tmp[2] = '='; + tmp[3] = '='; + } + else + { + tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; + tmp[2] = bintoasc[((radbuf[1] << 2) & 074) & 077]; + tmp[3] = '='; + } + if (state->stream) + { + for (idx=0; idx < 4; idx++) + es_putc (tmp[idx], state->stream); + if (es_ferror (state->stream)) + goto write_error; + } + else + { + for (idx=0; idx < 4; idx++) + putc (tmp[idx], state->fp); + if (ferror (state->fp)) + goto write_error; + } + + if (++quad_count >= (64/4)) + { + quad_count = 0; + if (!(state->flags & B64ENC_NO_LINEFEEDS) + && my_fputs ("\n", state) == EOF) + goto write_error; + } + } + + /* Finish the last line and write the trailer. */ + if (quad_count + && !(state->flags & B64ENC_NO_LINEFEEDS) + && my_fputs ("\n", state) == EOF) + goto write_error; + + if ( (state->flags & B64ENC_USE_PGPCRC) ) + { + /* Write the CRC. */ + my_fputs ("=", state); + radbuf[0] = state->crc >>16; + radbuf[1] = state->crc >> 8; + radbuf[2] = state->crc; + tmp[0] = bintoasc[(*radbuf>>2)&077]; + tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; + tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; + tmp[3] = bintoasc[radbuf[2]&077]; + if (state->stream) + { + for (idx=0; idx < 4; idx++) + es_putc (tmp[idx], state->stream); + if (es_ferror (state->stream)) + goto write_error; + } + else + { + for (idx=0; idx < 4; idx++) + putc (tmp[idx], state->fp); + if (ferror (state->fp)) + goto write_error; + } + if (!(state->flags & B64ENC_NO_LINEFEEDS) + && my_fputs ("\n", state) == EOF) + goto write_error; + } + + if (state->title) + { + if ( my_fputs ("-----END ", state) == EOF + || my_fputs (state->title, state) == EOF + || my_fputs ("-----\n", state) == EOF) + goto write_error; + } + + goto cleanup; + + write_error: + err = gpg_error_from_syserror (); + + cleanup: + if (state->title) + { + xfree (state->title); + state->title = NULL; + } + state->fp = NULL; + state->stream = NULL; + state->lasterr = err; + return err; +} ----------------------------------------------------------------------- Summary of changes: NEWS | 15 +- doc/yat2m.c | 15 +- src/Makefile.am | 2 +- src/argparse.c | 42 ------ src/b64dec.c | 43 +++--- src/b64enc.c | 386 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/gpg-error.def.in | 4 + src/gpg-error.h.in | 14 +- src/gpg-error.vers | 5 + src/gpgrt-int.h | 26 +++- src/visibility.c | 18 +++ src/visibility.h | 6 + tests/Makefile.am | 2 +- tests/t-argparse.c | 3 +- tests/t-b64.c | 373 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/t-b64dec.c | 123 ---------------- 16 files changed, 869 insertions(+), 208 deletions(-) create mode 100644 src/b64enc.c create mode 100644 tests/t-b64.c delete mode 100644 tests/t-b64dec.c hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 18:43:45 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 22 Mar 2018 18:43:45 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-15-geeb1334 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via eeb1334fdddb48090fe0b98b8e2b6b805acaa136 (commit) from 30621ee4c13006d08881994c32c89f60604c0188 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit eeb1334fdddb48090fe0b98b8e2b6b805acaa136 Author: Werner Koch Date: Thu Mar 22 18:37:13 2018 +0100 doc: Update NEWS -- diff --git a/NEWS b/NEWS index de551f4..44da9ee 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,15 @@ Noteworthy changes in version 1.29 (unreleased) [C23/A23/R_] ----------------------------------------------- + * The yat2m tool is during cross-compile now also installed on the + host platform. + + * New option parser and associated functions similar to the one used + by GnuPG. + + * New Base-64 encoder. + + * Fixes regression in 1.28 for arm64 and w64 builds. * Interface changes relative to the 1.28 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ----------------------------------------------------------------------- Summary of changes: NEWS | 9 +++++++++ 1 file changed, 9 insertions(+) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 20:02:25 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 22 Mar 2018 20:02:25 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-18-g1bf46d0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 1bf46d047c60d3dc2cb21f0b321f7299b1611580 (commit) via 1b30d21c8780f5510815d4fb2523afad9fff85dc (commit) via 020c2fbb2871b34b16c62b31c7cb91aa5f750532 (commit) from eeb1334fdddb48090fe0b98b8e2b6b805acaa136 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1bf46d047c60d3dc2cb21f0b321f7299b1611580 Author: Werner Koch Date: Thu Mar 22 19:55:51 2018 +0100 build: Update travis configuration. -- diff --git a/.travis.yml b/.travis.yml index 08bba01..b009106 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ { "language": "c", "compiler": "gcc", + "script": "./autogen.sh --git-build", "os": "linux", "group": "stable", "dist": "trusty" commit 1b30d21c8780f5510815d4fb2523afad9fff85dc Author: Werner Koch Date: Thu Mar 22 19:55:31 2018 +0100 build: Add option --git-build to autogen.sh diff --git a/autogen.sh b/autogen.sh index 4b511bf..23d27f3 100755 --- a/autogen.sh +++ b/autogen.sh @@ -85,9 +85,10 @@ if test x"$1" = x"--help"; then echo " --silent Silent operation" echo " --force Pass --force to autoconf" echo " --find-version Helper for configure.ac" - echo " --build-TYPE Configure to cross build for TYPE" + echo " --git-build Run all commands to build from a Git" echo " --print-host Print only the host triplet" echo " --print-build Print only the build platform triplet" + echo " --build-TYPE Configure to cross build for TYPE" echo "" echo " ARGS are passed to configure in --build-TYPE mode." echo " Configuration for this script is expected in autogen.rc" @@ -159,6 +160,10 @@ case "$1" in SILENT=" --silent" shift ;; + --git-build) + myhost="git-build" + shift + ;; --build-w32) myhost="w32" shift @@ -187,6 +192,25 @@ esac die_p +# **** GIT BUILD **** +# This is a helper to build from git. +if [ "$myhost" = "git-build" ]; then + tmp="$(pwd)" + cd "$tsdir" || fatal "error cd-ing to $tsdir" + ./autogen.sh || fatal "error running ./autogen.sh" + cd "$tmp" || fatal "error cd-ing back to $tmp" + die_p + "$tsdir"/configure || fatal "error running $tsdir/configure" + die_p + make || fatal "error running make" + die_p + make check || fatal "error running male check" + die_p + exit 0 +fi +# **** end GIT BUILD **** + + # Source our configuration if [ -f "${tsdir}/autogen.rc" ]; then . "${tsdir}/autogen.rc" commit 020c2fbb2871b34b16c62b31c7cb91aa5f750532 Author: Werner Koch Date: Thu Mar 22 19:32:59 2018 +0100 build: Testing travis. -- diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..08bba01 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +{ + "language": "c", + "compiler": "gcc", + "os": "linux", + "group": "stable", + "dist": "trusty" +} ----------------------------------------------------------------------- Summary of changes: .travis.yml | 8 ++++++++ autogen.sh | 26 +++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 .travis.yml hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 20:36:42 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 22 Mar 2018 20:36:42 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-19-gd4faf67 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via d4faf67b6367a972af18e8b7a02935bc84f3f678 (commit) from 1bf46d047c60d3dc2cb21f0b321f7299b1611580 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d4faf67b6367a972af18e8b7a02935bc84f3f678 Author: Werner Koch Date: Thu Mar 22 20:28:38 2018 +0100 build: More travis.yml tweaking -- diff --git a/.travis.yml b/.travis.yml index b009106..6ae94b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,22 @@ -{ - "language": "c", - "compiler": "gcc", - "script": "./autogen.sh --git-build", - "os": "linux", - "group": "stable", - "dist": "trusty" -} +language: c + +os: + - linux + dist: trusty + sudo: required + - osx + +compiler: + - gcc + - clang + +before_install: +- echo "Building for $TRAVIS_OS_NAME\n"; + +#Linux +if [ $TRAVIS_OS_NAME == linux ]; then + sudo apt-get update -qq; + sudo apt-get install gettext; +fi + +script: ./autogen.sh --git-build ----------------------------------------------------------------------- Summary of changes: .travis.yml | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 20:50:40 2018 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Thu, 22 Mar 2018 20:50:40 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-49-g617f5e7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 617f5e746f8295cc36d1002c8c53edc95d04d0f6 (commit) via 3841b23c0ccb24d555b7570083bba958e3126d26 (commit) via a1127dbbada4302abf09eec90fbaceca87bfcdf0 (commit) from 92fd86e9956ef3fea51d72495fd0da09522e57a1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 617f5e746f8295cc36d1002c8c53edc95d04d0f6 Author: Jussi Kivilinna Date: Thu Mar 22 21:42:23 2018 +0200 bench-slope: add CPU frequency auto-detection * tests/bench-slope.c (bench_obj): Add 'hd'. (bench_encrypt_init, bench_encrypt_free, bench_encrypt_do_bench) (bench_decrypt_do_bench, bench_xts_encrypt_init) (bench_xts_encrypt_do_bench, bench_xts_decrypt_do_bench) (bench_ccm_encrypt_init, bench_ccm_encrypt_do_bench) (bench_ccm_decrypt_do_bench, bench_aead_encrypt_init) (bench_aead_encrypt_do_bench, bench_aead_decrypt_do_bench) (bench_hash_init, bench_hash_free, bench_hash_do_bench) (bench_mac_init, bench_mac_free, bench_mac_do_bench): Use 'obj->hd' for storing pointer to crypto context. (auto_ghz): New. (do_slope_benchmark): Rename to... (slope_benchmark): ...this. (auto_ghz_init, auto_ghz_free, auto_ghz_bench, auto_ghz_detect_ops) (get_auto_ghz, do_slope_benchmark): New. (double_to_str): Round number larger than 1000 to integer. (bench_print_result_csv, bench_print_result_std) (bench_print_result, bench_print_header, cipher_bench_one) (hash_bench_one, mac_bench_one, kdf_bench_one, kdf_bench): Add auto-detected frequency printing. (print_help): Help for CPU speed auto-detection mode. (main): Add parsing for "--cpu-mhz auto". -- Signed-off-by: Jussi Kivilinna diff --git a/tests/bench-slope.c b/tests/bench-slope.c index e34104f..5c64f22 100644 --- a/tests/bench-slope.c +++ b/tests/bench-slope.c @@ -50,6 +50,9 @@ static int num_measurement_repetitions; results. */ static double cpu_ghz = -1; +/* Attempt to autodetect CPU Ghz. */ +static int auto_ghz; + /* Whether we are running as part of the regression test suite. */ static int in_regression_test; @@ -220,6 +223,7 @@ struct bench_obj unsigned int step_size; void *priv; + void *hd; }; typedef int (*const bench_initialize_t) (struct bench_obj * obj); @@ -383,7 +387,7 @@ adjust_loop_iterations_to_timer_accuracy (struct bench_obj *obj, void *buffer, /* Benchmark and return linear regression slope in nanoseconds per byte. */ double -do_slope_benchmark (struct bench_obj *obj) +slope_benchmark (struct bench_obj *obj) { unsigned int num_measurements; double *measurements = NULL; @@ -464,6 +468,122 @@ err_free: return -1; } +/********************************************* CPU frequency auto-detection. */ + +static int +auto_ghz_init (struct bench_obj *obj) +{ + obj->min_bufsize = 16; + obj->max_bufsize = 64 + obj->min_bufsize; + obj->step_size = 8; + obj->num_measure_repetitions = 16; + + return 0; +} + +static void +auto_ghz_free (struct bench_obj *obj) +{ + (void)obj; +} + +static void +auto_ghz_bench (struct bench_obj *obj, void *buf, size_t buflen) +{ + (void)obj; + (void)buf; + + buflen *= 1024; + + /* Turbo frequency detection benchmark. Without CPU turbo-boost, this + * function will give cycles/iteration result 1024.0 on high-end CPUs. + * With turbo, result will be less and can be used detect turbo-clock. */ + + do + { +#ifdef HAVE_GCC_ASM_VOLATILE_MEMORY + /* Use memory barrier to prevent compiler from optimizing this loop + * away. */ + + asm volatile ("":::"memory"); +#else + /* TODO: Needs alternative way. */ +#endif + } + while (--buflen); +} + +static struct bench_ops auto_ghz_detect_ops = { + &auto_ghz_init, + &auto_ghz_free, + &auto_ghz_bench +}; + + +double +get_auto_ghz (void) +{ + struct bench_obj obj = { 0 }; + double nsecs_per_iteration; + double cycles_per_iteration; + + obj.ops = &auto_ghz_detect_ops; + + nsecs_per_iteration = slope_benchmark (&obj); + + cycles_per_iteration = nsecs_per_iteration * cpu_ghz; + + /* Adjust CPU Ghz so that cycles per iteration would give '1024.0'. */ + + return cpu_ghz * 1024 / cycles_per_iteration; +} + + +double +do_slope_benchmark (struct bench_obj *obj, double *bench_ghz) +{ + double ret; + + if (!auto_ghz) + { + /* Perform measurement without autodetection of CPU frequency. */ + + ret = slope_benchmark (obj); + + *bench_ghz = cpu_ghz; + } + else + { + double cpu_auto_ghz_before; + double cpu_auto_ghz_after; + double nsecs_per_iteration; + double diff; + + /* Perform measurement with CPU frequency autodetection. */ + + do + { + /* Repeat measurement until CPU turbo frequency has stabilized. */ + + cpu_auto_ghz_before = get_auto_ghz (); + + nsecs_per_iteration = slope_benchmark (obj); + + cpu_auto_ghz_after = get_auto_ghz (); + + diff = 1.0 - (cpu_auto_ghz_before / cpu_auto_ghz_after); + diff = diff < 0 ? -diff : diff; + } + while (diff > 5e-5); + + ret = nsecs_per_iteration; + + *bench_ghz = cpu_auto_ghz_after; + } + + return ret; +} + /********************************************************** Printing results. */ @@ -476,29 +596,34 @@ double_to_str (char *out, size_t outlen, double value) fmt = "%.3f"; else if (value < 100.0) fmt = "%.2f"; - else + else if (value < 1000.0) fmt = "%.1f"; + else + fmt = "%.0f"; snprintf (out, outlen, fmt, value); } static void -bench_print_result_csv (double nsecs_per_byte) +bench_print_result_csv (double nsecs_per_byte, double bench_ghz) { double cycles_per_byte, mbytes_per_sec; char nsecpbyte_buf[16]; char mbpsec_buf[16]; char cpbyte_buf[16]; + char mhz_buf[16]; *cpbyte_buf = 0; + *mhz_buf = 0; double_to_str (nsecpbyte_buf, sizeof (nsecpbyte_buf), nsecs_per_byte); /* If user didn't provide CPU speed, we cannot show cycles/byte results. */ - if (cpu_ghz > 0.0) + if (bench_ghz > 0.0) { - cycles_per_byte = nsecs_per_byte * cpu_ghz; + cycles_per_byte = nsecs_per_byte * bench_ghz; double_to_str (cpbyte_buf, sizeof (cpbyte_buf), cycles_per_byte); + double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000); } mbytes_per_sec = @@ -506,50 +631,76 @@ bench_print_result_csv (double nsecs_per_byte) double_to_str (mbpsec_buf, sizeof (mbpsec_buf), mbytes_per_sec); /* We print two empty fields to allow for future enhancements. */ - printf ("%s,%s,%s,,,%s,ns/B,%s,MiB/s,%s,c/B\n", - current_section_name, - current_algo_name? current_algo_name : "", - current_mode_name? current_mode_name : "", - nsecpbyte_buf, - mbpsec_buf, - cpbyte_buf); - + if (auto_ghz) + { + printf ("%s,%s,%s,,,%s,ns/B,%s,MiB/s,%s,c/B,%s,Mhz\n", + current_section_name, + current_algo_name? current_algo_name : "", + current_mode_name? current_mode_name : "", + nsecpbyte_buf, + mbpsec_buf, + cpbyte_buf, + mhz_buf); + } + else + { + printf ("%s,%s,%s,,,%s,ns/B,%s,MiB/s,%s,c/B\n", + current_section_name, + current_algo_name? current_algo_name : "", + current_mode_name? current_mode_name : "", + nsecpbyte_buf, + mbpsec_buf, + cpbyte_buf); + } } static void -bench_print_result_std (double nsecs_per_byte) +bench_print_result_std (double nsecs_per_byte, double bench_ghz) { double cycles_per_byte, mbytes_per_sec; char nsecpbyte_buf[16]; char mbpsec_buf[16]; char cpbyte_buf[16]; + char mhz_buf[16]; double_to_str (nsecpbyte_buf, sizeof (nsecpbyte_buf), nsecs_per_byte); /* If user didn't provide CPU speed, we cannot show cycles/byte results. */ - if (cpu_ghz > 0.0) + if (bench_ghz > 0.0) { - cycles_per_byte = nsecs_per_byte * cpu_ghz; + cycles_per_byte = nsecs_per_byte * bench_ghz; double_to_str (cpbyte_buf, sizeof (cpbyte_buf), cycles_per_byte); + double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000); } else - strcpy (cpbyte_buf, "-"); + { + strcpy (cpbyte_buf, "-"); + strcpy (mhz_buf, "-"); + } mbytes_per_sec = (1000.0 * 1000.0 * 1000.0) / (nsecs_per_byte * 1024 * 1024); double_to_str (mbpsec_buf, sizeof (mbpsec_buf), mbytes_per_sec); - printf ("%9s ns/B %9s MiB/s %9s c/B\n", - nsecpbyte_buf, mbpsec_buf, cpbyte_buf); + if (auto_ghz) + { + printf ("%9s ns/B %9s MiB/s %9s c/B %9s\n", + nsecpbyte_buf, mbpsec_buf, cpbyte_buf, mhz_buf); + } + else + { + printf ("%9s ns/B %9s MiB/s %9s c/B\n", + nsecpbyte_buf, mbpsec_buf, cpbyte_buf); + } } static void -bench_print_result (double nsecs_per_byte) +bench_print_result (double nsecs_per_byte, double bench_ghz) { if (csv_mode) - bench_print_result_csv (nsecs_per_byte); + bench_print_result_csv (nsecs_per_byte, bench_ghz); else - bench_print_result_std (nsecs_per_byte); + bench_print_result_std (nsecs_per_byte, bench_ghz); } static void @@ -578,8 +729,13 @@ bench_print_header (int algo_width, const char *algo_name) printf (" %-*s | ", -algo_width, algo_name); else printf (" %-*s | ", algo_width, algo_name); - printf ("%14s %15s %13s\n", "nanosecs/byte", "mebibytes/sec", - "cycles/byte"); + + if (auto_ghz) + printf ("%14s %15s %13s %9s\n", "nanosecs/byte", "mebibytes/sec", + "cycles/byte", "auto Mhz"); + else + printf ("%14s %15s %13s\n", "nanosecs/byte", "mebibytes/sec", + "cycles/byte"); } } @@ -684,7 +840,7 @@ bench_encrypt_init (struct bench_obj *obj) exit (1); } - obj->priv = hd; + obj->hd = hd; return 0; } @@ -692,7 +848,7 @@ bench_encrypt_init (struct bench_obj *obj) static void bench_encrypt_free (struct bench_obj *obj) { - gcry_cipher_hd_t hd = obj->priv; + gcry_cipher_hd_t hd = obj->hd; gcry_cipher_close (hd); } @@ -700,7 +856,7 @@ bench_encrypt_free (struct bench_obj *obj) static void bench_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen) { - gcry_cipher_hd_t hd = obj->priv; + gcry_cipher_hd_t hd = obj->hd; int err; err = gcry_cipher_encrypt (hd, buf, buflen, buf, buflen); @@ -716,7 +872,7 @@ bench_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen) static void bench_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen) { - gcry_cipher_hd_t hd = obj->priv; + gcry_cipher_hd_t hd = obj->hd; int err; err = gcry_cipher_decrypt (hd, buf, buflen, buf, buflen); @@ -790,7 +946,7 @@ bench_xts_encrypt_init (struct bench_obj *obj) exit (1); } - obj->priv = hd; + obj->hd = hd; return 0; } @@ -798,7 +954,7 @@ bench_xts_encrypt_init (struct bench_obj *obj) static void bench_xts_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen) { - gcry_cipher_hd_t hd = obj->priv; + gcry_cipher_hd_t hd = obj->hd; unsigned int pos; static const char tweak[16] = { 0xff, 0xff, 0xfe, }; size_t sectorlen = obj->step_size; @@ -825,7 +981,7 @@ bench_xts_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen) static void bench_xts_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen) { - gcry_cipher_hd_t hd = obj->priv; + gcry_cipher_hd_t hd = obj->hd; unsigned int pos; static const char tweak[16] = { 0xff, 0xff, 0xfe, }; size_t sectorlen = obj->step_size; @@ -865,7 +1021,7 @@ static struct bench_ops xts_decrypt_ops = { static void bench_ccm_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen) { - gcry_cipher_hd_t hd = obj->priv; + gcry_cipher_hd_t hd = obj->hd; int err; char tag[8]; char nonce[11] = { 0x80, 0x01, }; @@ -909,7 +1065,7 @@ bench_ccm_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen) static void bench_ccm_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen) { - gcry_cipher_hd_t hd = obj->priv; + gcry_cipher_hd_t hd = obj->hd; int err; char tag[8] = { 0, }; char nonce[11] = { 0x80, 0x01, }; @@ -956,7 +1112,7 @@ static void bench_ccm_authenticate_do_bench (struct bench_obj *obj, void *buf, size_t buflen) { - gcry_cipher_hd_t hd = obj->priv; + gcry_cipher_hd_t hd = obj->hd; int err; char tag[8] = { 0, }; char nonce[11] = { 0x80, 0x01, }; @@ -1030,7 +1186,7 @@ static void bench_aead_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen, const char *nonce, size_t noncelen) { - gcry_cipher_hd_t hd = obj->priv; + gcry_cipher_hd_t hd = obj->hd; int err; char tag[16]; @@ -1060,7 +1216,7 @@ static void bench_aead_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen, const char *nonce, size_t noncelen) { - gcry_cipher_hd_t hd = obj->priv; + gcry_cipher_hd_t hd = obj->hd; int err; char tag[16] = { 0, }; @@ -1093,7 +1249,7 @@ bench_aead_authenticate_do_bench (struct bench_obj *obj, void *buf, size_t buflen, const char *nonce, size_t noncelen) { - gcry_cipher_hd_t hd = obj->priv; + gcry_cipher_hd_t hd = obj->hd; int err; char tag[16] = { 0, }; char data = 0xff; @@ -1360,6 +1516,7 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode) struct bench_cipher_mode mode = *pmode; struct bench_obj obj = { 0 }; double result; + double bench_ghz; unsigned int blklen; mode.algo = algo; @@ -1404,9 +1561,9 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode) obj.ops = mode.ops; obj.priv = &mode; - result = do_slope_benchmark (&obj); + result = do_slope_benchmark (&obj, &bench_ghz); - bench_print_result (result); + bench_print_result (result, bench_ghz); } @@ -1483,7 +1640,7 @@ bench_hash_init (struct bench_obj *obj) exit (1); } - obj->priv = hd; + obj->hd = hd; return 0; } @@ -1491,7 +1648,7 @@ bench_hash_init (struct bench_obj *obj) static void bench_hash_free (struct bench_obj *obj) { - gcry_md_hd_t hd = obj->priv; + gcry_md_hd_t hd = obj->hd; gcry_md_close (hd); } @@ -1499,7 +1656,7 @@ bench_hash_free (struct bench_obj *obj) static void bench_hash_do_bench (struct bench_obj *obj, void *buf, size_t buflen) { - gcry_md_hd_t hd = obj->priv; + gcry_md_hd_t hd = obj->hd; gcry_md_reset (hd); gcry_md_write (hd, buf, buflen); @@ -1524,6 +1681,7 @@ hash_bench_one (int algo, struct bench_hash_mode *pmode) { struct bench_hash_mode mode = *pmode; struct bench_obj obj = { 0 }; + double bench_ghz; double result; mode.algo = algo; @@ -1536,9 +1694,9 @@ hash_bench_one (int algo, struct bench_hash_mode *pmode) obj.ops = mode.ops; obj.priv = &mode; - result = do_slope_benchmark (&obj); + result = do_slope_benchmark (&obj, &bench_ghz); - bench_print_result (result); + bench_print_result (result, bench_ghz); } static void @@ -1645,7 +1803,7 @@ bench_mac_init (struct bench_obj *obj) break; } - obj->priv = hd; + obj->hd = hd; free (key); return 0; @@ -1654,7 +1812,7 @@ bench_mac_init (struct bench_obj *obj) static void bench_mac_free (struct bench_obj *obj) { - gcry_mac_hd_t hd = obj->priv; + gcry_mac_hd_t hd = obj->hd; gcry_mac_close (hd); } @@ -1662,7 +1820,7 @@ bench_mac_free (struct bench_obj *obj) static void bench_mac_do_bench (struct bench_obj *obj, void *buf, size_t buflen) { - gcry_mac_hd_t hd = obj->priv; + gcry_mac_hd_t hd = obj->hd; size_t bs; char b; @@ -1690,6 +1848,7 @@ mac_bench_one (int algo, struct bench_mac_mode *pmode) { struct bench_mac_mode mode = *pmode; struct bench_obj obj = { 0 }; + double bench_ghz; double result; mode.algo = algo; @@ -1702,9 +1861,9 @@ mac_bench_one (int algo, struct bench_mac_mode *pmode) obj.ops = mode.ops; obj.priv = &mode; - result = do_slope_benchmark (&obj); + result = do_slope_benchmark (&obj, &bench_ghz); - bench_print_result (result); + bench_print_result (result, bench_ghz); } static void @@ -1807,9 +1966,11 @@ kdf_bench_one (int algo, int subalgo) struct bench_obj obj = { 0 }; double nsecs_per_iteration; double cycles_per_iteration; + double bench_ghz; char algo_name[32]; char nsecpiter_buf[16]; char cpiter_buf[16]; + char mhz_buf[16]; mode.algo = algo; mode.subalgo = subalgo; @@ -1843,31 +2004,45 @@ kdf_bench_one (int algo, int subalgo) obj.ops = mode.ops; obj.priv = &mode; - nsecs_per_iteration = do_slope_benchmark (&obj); + nsecs_per_iteration = do_slope_benchmark (&obj, &bench_ghz); strcpy(cpiter_buf, csv_mode ? "" : "-"); + strcpy(mhz_buf, csv_mode ? "" : "-"); double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration); /* If user didn't provide CPU speed, we cannot show cycles/iter results. */ - if (cpu_ghz > 0.0) + if (bench_ghz > 0.0) { - cycles_per_iteration = nsecs_per_iteration * cpu_ghz; + cycles_per_iteration = nsecs_per_iteration * bench_ghz; double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration); + double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000); } if (csv_mode) { - printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n", - current_section_name, - current_algo_name ? current_algo_name : "", - current_mode_name ? current_mode_name : "", - nsecpiter_buf, - cpiter_buf); + if (auto_ghz) + printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n", + current_section_name, + current_algo_name ? current_algo_name : "", + current_mode_name ? current_mode_name : "", + nsecpiter_buf, + cpiter_buf, + mhz_buf); + else + printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n", + current_section_name, + current_algo_name ? current_algo_name : "", + current_mode_name ? current_mode_name : "", + nsecpiter_buf, + cpiter_buf); } else { - printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf); + if (auto_ghz) + printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf); + else + printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf); } } @@ -1882,7 +2057,10 @@ kdf_bench (char **argv, int argc) if (!csv_mode) { printf (" %-*s | ", 24, ""); - printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter"); + if (auto_ghz) + printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz"); + else + printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter"); } if (argv && argc) @@ -1923,7 +2101,8 @@ print_help (void) "", " options:", " --cpu-mhz Set CPU speed for calculating cycles", - " per bytes results.", + " per bytes results. Set as \"auto\"", + " for auto-detection of CPU speed.", " --disable-hwf Disable hardware acceleration feature(s)", " for benchmarking.", " --repetitions Use N repetitions (default " @@ -2039,8 +2218,15 @@ main (int argc, char **argv) argv++; if (argc) { - cpu_ghz = atof (*argv); - cpu_ghz /= 1000; /* Mhz => Ghz */ + if (!strcmp (*argv, "auto")) + { + auto_ghz = 1; + } + else + { + cpu_ghz = atof (*argv); + cpu_ghz /= 1000; /* Mhz => Ghz */ + } argc--; argv++; commit 3841b23c0ccb24d555b7570083bba958e3126d26 Author: Jussi Kivilinna Date: Thu Mar 22 21:42:23 2018 +0200 _gcry_burn_stack: use memset for clearing memory * src/misc.c (__gcry_burn_stack) [HAVE_VLA]: Use 'memset' for clearing stack. -- Patch switches stacking burning to use faster memset instead of wipememory. Memset is accessed through volatile function pointer, so that compiler will not optimize away the call. Signed-off-by: Jussi Kivilinna diff --git a/src/misc.c b/src/misc.c index 002a84f..47d2dc7 100644 --- a/src/misc.c +++ b/src/misc.c @@ -501,11 +501,12 @@ void __gcry_burn_stack (unsigned int bytes) { #ifdef HAVE_VLA + static void *(*volatile memset_ptr)(void *, int, size_t) = (void *)memset; /* (bytes == 0 ? 1 : bytes) == (!bytes + bytes) */ unsigned int buflen = ((!bytes + bytes) + 63) & ~63; - volatile char buf[buflen]; + char buf[buflen]; - wipememory (buf, sizeof buf); + memset_ptr (buf, 0, sizeof buf); #else volatile char buf[64]; commit a1127dbbada4302abf09eec90fbaceca87bfcdf0 Author: Jussi Kivilinna Date: Thu Mar 22 21:42:22 2018 +0200 Improve constant-time buffer compare * cipher/bufhelp.h (buf_eq_const): Rewrite logic. -- New implementation for constant-time buffer comparing that avoids generating conditional code in comparison loop. Signed-off-by: Jussi Kivilinna diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h index b854bc0..83d3f53 100644 --- a/cipher/bufhelp.h +++ b/cipher/bufhelp.h @@ -290,13 +290,19 @@ buf_eq_const(const void *_a, const void *_b, size_t len) { const byte *a = _a; const byte *b = _b; - size_t diff, i; + int ab, ba; + size_t i; /* Constant-time compare. */ - for (i = 0, diff = 0; i < len; i++) - diff -= !!(a[i] - b[i]); + for (i = 0, ab = 0, ba = 0; i < len; i++) + { + /* If a[i] != b[i], either ab or ba will be negative. */ + ab |= a[i] - b[i]; + ba |= b[i] - a[i]; + } - return !diff; + /* 'ab | ba' is negative when buffers are not equal. */ + return (ab | ba) >= 0; } ----------------------------------------------------------------------- Summary of changes: cipher/bufhelp.h | 14 ++- src/misc.c | 5 +- tests/bench-slope.c | 312 +++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 262 insertions(+), 69 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 21:07:27 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 22 Mar 2018 21:07:27 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-20-g0cc0ba7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 0cc0ba764eae79f05b33a203c405e1d88278159e (commit) from d4faf67b6367a972af18e8b7a02935bc84f3f678 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0cc0ba764eae79f05b33a203c405e1d88278159e Author: Werner Koch Date: Thu Mar 22 21:00:51 2018 +0100 build: And more travis.yml tweaking -- diff --git a/.travis.yml b/.travis.yml index 6ae94b3..4ab8ff1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,19 +4,17 @@ os: - linux dist: trusty sudo: required - - osx +# - osx compiler: - gcc - - clang +# - clang before_install: -- echo "Building for $TRAVIS_OS_NAME\n"; - -#Linux -if [ $TRAVIS_OS_NAME == linux ]; then - sudo apt-get update -qq; - sudo apt-get install gettext; -fi + - echo "Building for $TRAVIS_OS_NAME\n"; + - if [ $TRAVIS_OS_NAME == linux ]; then + sudo apt-get update -qq; + sudo apt-get install gettext; + fi script: ./autogen.sh --git-build ----------------------------------------------------------------------- Summary of changes: .travis.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 21:15:15 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 22 Mar 2018 21:15:15 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-21-g67a80ad Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 67a80ad2e706c41377d0c5ccfd48f73dbb151818 (commit) from 0cc0ba764eae79f05b33a203c405e1d88278159e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 67a80ad2e706c41377d0c5ccfd48f73dbb151818 Author: Werner Koch Date: Thu Mar 22 21:08:45 2018 +0100 build: And even more travis.yml tweaking -- diff --git a/.travis.yml b/.travis.yml index 4ab8ff1..13f6e56 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,17 +4,14 @@ os: - linux dist: trusty sudo: required -# - osx compiler: - gcc -# - clang before_install: - - echo "Building for $TRAVIS_OS_NAME\n"; - - if [ $TRAVIS_OS_NAME == linux ]; then - sudo apt-get update -qq; - sudo apt-get install gettext; - fi + - echo "Building for $TRAVIS_OS_NAME" + - sudo apt-get update -qq; + - sudo apt-get install gettext; -script: ./autogen.sh --git-build +script: + - ./autogen.sh --git-build ----------------------------------------------------------------------- Summary of changes: .travis.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 21:24:03 2018 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Thu, 22 Mar 2018 21:24:03 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-51-g885f031 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 885f031fbd17abc1c0fedbb98df22823b647fc11 (commit) via 330ec66e0babdabb658dc7d6db78f37b2a1b996e (commit) from 617f5e746f8295cc36d1002c8c53edc95d04d0f6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 885f031fbd17abc1c0fedbb98df22823b647fc11 Author: Jussi Kivilinna Date: Thu Mar 22 21:54:20 2018 +0200 tests/aeswrap: add in-place encryption/decryption testing * tests/aeswrap.c (check): Rename to... (check_one): ...this and add in-place testing. (check): New. -- Signed-off-by: Jussi Kivilinna diff --git a/tests/aeswrap.c b/tests/aeswrap.c index 90add11..dbbd7dd 100644 --- a/tests/aeswrap.c +++ b/tests/aeswrap.c @@ -31,10 +31,11 @@ static void -check (int algo, - const void *kek, size_t keklen, - const void *data, size_t datalen, - const void *expected, size_t expectedlen) +check_one (int algo, + const void *kek, size_t keklen, + const void *data, size_t datalen, + const void *expected, size_t expectedlen, + int inplace) { gcry_error_t err; gcry_cipher_hd_t hd; @@ -57,9 +58,19 @@ check (int algo, outbuflen = datalen + 8; if (outbuflen > sizeof outbuf) - err = gpg_error (GPG_ERR_INTERNAL); + { + err = gpg_error (GPG_ERR_INTERNAL); + } + else if (inplace) + { + memcpy (outbuf, data, datalen); + err = gcry_cipher_encrypt (hd, outbuf, outbuflen, outbuf, datalen); + } else - err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, datalen); + { + err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, datalen); + } + if (err) { fail ("gcry_cipher_encrypt failed: %s\n", gpg_strerror (err)); @@ -71,7 +82,7 @@ check (int algo, const unsigned char *s; int i; - fail ("mismatch at encryption!\n"); + fail ("mismatch at encryption!%s\n", inplace ? " (inplace)" : ""); fprintf (stderr, "computed: "); for (i = 0; i < outbuflen; i++) fprintf (stderr, "%02x ", outbuf[i]); @@ -84,9 +95,19 @@ check (int algo, outbuflen = expectedlen - 8; if (outbuflen > sizeof outbuf) - err = gpg_error (GPG_ERR_INTERNAL); + { + err = gpg_error (GPG_ERR_INTERNAL); + } + else if (inplace) + { + memcpy (outbuf, expected, expectedlen); + err = gcry_cipher_decrypt (hd, outbuf, outbuflen, outbuf, expectedlen); + } else - err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); + { + err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); + } + if (err) { fail ("gcry_cipher_decrypt failed: %s\n", gpg_strerror (err)); @@ -98,7 +119,7 @@ check (int algo, const unsigned char *s; int i; - fail ("mismatch at decryption!\n"); + fail ("mismatch at decryption!%s\n", inplace ? " (inplace)" : ""); fprintf (stderr, "computed: "); for (i = 0; i < outbuflen; i++) fprintf (stderr, "%02x ", outbuf[i]); @@ -113,9 +134,19 @@ check (int algo, outbuflen = expectedlen - 8; if (outbuflen > sizeof outbuf) - err = gpg_error (GPG_ERR_INTERNAL); + { + err = gpg_error (GPG_ERR_INTERNAL); + } + else if (inplace) + { + memcpy (outbuf, expected, expectedlen); + err = gcry_cipher_decrypt (hd, outbuf, outbuflen, outbuf, expectedlen); + } else - err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); + { + err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); + } + if (err) { fail ("gcry_cipher_decrypt(2) failed: %s\n", gpg_strerror (err)); @@ -123,14 +154,24 @@ check (int algo, } if (outbuflen != datalen || memcmp (outbuf, data, datalen)) - fail ("mismatch at decryption(2)!\n"); + fail ("mismatch at decryption(2)!%s\n", inplace ? " (inplace)" : ""); - /* And once ore without a key reset. */ + /* And once more without a key reset. */ outbuflen = expectedlen - 8; if (outbuflen > sizeof outbuf) - err = gpg_error (GPG_ERR_INTERNAL); + { + err = gpg_error (GPG_ERR_INTERNAL); + } + else if (inplace) + { + memcpy (outbuf, expected, expectedlen); + err = gcry_cipher_decrypt (hd, outbuf, outbuflen, outbuf, expectedlen); + } else - err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); + { + err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); + } + if (err) { fail ("gcry_cipher_decrypt(3) failed: %s\n", gpg_strerror (err)); @@ -138,13 +179,24 @@ check (int algo, } if (outbuflen != datalen || memcmp (outbuf, data, datalen)) - fail ("mismatch at decryption(3)!\n"); + fail ("mismatch at decryption(3)!%s\n", inplace ? " (inplace)" : ""); gcry_cipher_close (hd); } static void +check (int algo, + const void *kek, size_t keklen, + const void *data, size_t datalen, + const void *expected, size_t expectedlen) +{ + check_one (algo, kek, keklen, data, datalen, expected, expectedlen, 0); + check_one (algo, kek, keklen, data, datalen, expected, expectedlen, 1); +} + + +static void check_all (void) { if (verbose) commit 330ec66e0babdabb658dc7d6db78f37b2a1b996e Author: Stephan Mueller Date: Mon Mar 12 22:24:37 2018 +0100 AES-KW: fix in-place encryption * cipher/cipher-aeswrap.c: move memmove call before KW IV setting -- In case AES-KW in-place encryption is performed, the plaintext must be moved to the correct destination location before the first semiblock of the destination buffer is modified. Without the patch, the first semiblock of the plaintext is overwritten with a6a6a6a6a6a6a6a6. Signed-off-by: Stephan Mueller diff --git a/cipher/cipher-aeswrap.c b/cipher/cipher-aeswrap.c index 698742d..a8d0e03 100644 --- a/cipher/cipher-aeswrap.c +++ b/cipher/cipher-aeswrap.c @@ -70,6 +70,9 @@ _gcry_cipher_aeswrap_encrypt (gcry_cipher_hd_t c, a = outbuf; /* We store A directly in OUTBUF. */ b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */ + /* Copy the inbuf to the outbuf. */ + memmove (r+8, inbuf, inbuflen); + /* If an IV has been set we use that IV as the Alternative Initial Value; if it has not been set we use the standard value. */ if (c->marks.iv) @@ -77,9 +80,6 @@ _gcry_cipher_aeswrap_encrypt (gcry_cipher_hd_t c, else memset (a, 0xa6, 8); - /* Copy the inbuf to the outbuf. */ - memmove (r+8, inbuf, inbuflen); - memset (t, 0, sizeof t); /* t := 0. */ for (j = 0; j <= 5; j++) ----------------------------------------------------------------------- Summary of changes: cipher/cipher-aeswrap.c | 6 ++-- tests/aeswrap.c | 86 +++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 72 insertions(+), 20 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 22 21:35:28 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 22 Mar 2018 21:35:28 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-23-g157130b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 157130befaacfcc417ddfc98d8f0238f6756b2cc (commit) via 22b293fe7922bfd70e0990ca89333ab168ad1808 (commit) from 67a80ad2e706c41377d0c5ccfd48f73dbb151818 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 157130befaacfcc417ddfc98d8f0238f6756b2cc Author: Werner Koch Date: Thu Mar 22 21:26:24 2018 +0100 build: Okay travis, take this -- diff --git a/.travis.yml b/.travis.yml index 558b15d..c22ee46 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,8 +11,8 @@ compiler: before_install: - echo "Building for $TRAVIS_OS_NAME" - - sudo apt-get update -qq; - - sudo apt-get install gettext; + - wget -q http://de.archive.ubuntu.com/ubuntu/pool/main/g/gettext/gettext_0.19.7-2ubuntu3_amd64.deb + - sudo dpkg -i gettext_0.19.7-2ubuntu3_amd64.deb script: - ./autogen.sh --git-build commit 22b293fe7922bfd70e0990ca89333ab168ad1808 Author: Werner Koch Date: Thu Mar 22 21:10:21 2018 +0100 build: Another try on travis.yml -- Why don't they return useful error messages???? diff --git a/.travis.yml b/.travis.yml index 13f6e56..558b15d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,9 @@ language: c os: - linux - dist: trusty - sudo: required + +# dist: trusty +# sudo: required compiler: - gcc ----------------------------------------------------------------------- Summary of changes: .travis.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 07:29:33 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 23 Mar 2018 07:29:33 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-22-g5400a5b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 5400a5bb77bddcb14c94d9405312d6181322b090 (commit) from 165bc38cefbc03515403b60b704cabf4dc0b71f4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5400a5bb77bddcb14c94d9405312d6181322b090 Author: NIIBE Yutaka Date: Fri Mar 23 15:16:16 2018 +0900 build: Fix the manual source field. Signed-off-by: NIIBE Yutaka diff --git a/doc/Makefile.am b/doc/Makefile.am index aba84ba..a857c8e 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -85,7 +85,7 @@ DVIPS = TEXINPUTS="$(srcdir)$(PATH_SEPARATOR)$$TEXINPUTS" dvips AM_MAKEINFOFLAGS = -I $(srcdir) --css-ref=/share/site.css YAT2M_OPTIONS = -I $(srcdir) \ - --release "GnuPG @PACKAGE_VERSION@" --source "GNU Privacy Guard 2.1" + --release "GnuPG @PACKAGE_VERSION@" --source "GNU Privacy Guard 2.2" myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \ dirmngr.texi scdaemon.texi tools.texi wks.texi ----------------------------------------------------------------------- Summary of changes: doc/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 09:12:59 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 23 Mar 2018 09:12:59 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-24-g2cd35df Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 2cd35df5db3c4dfe37616dcfb1fcc644959449ef (commit) via 05c55ee260edc07cd19da56dfd00347bfe3f529c (commit) from 5400a5bb77bddcb14c94d9405312d6181322b090 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2cd35df5db3c4dfe37616dcfb1fcc644959449ef Author: Werner Koch Date: Fri Mar 23 09:06:20 2018 +0100 gpg,sm: New option --request-origin. * g10/gpg.c (oRequestOrigin): New const. (opts): New option --request-origin. (main): Parse that option. * g10/options.h (struct opt): Add field request_origin. * g10/call-agent.c (start_agent): Send option to the agent. * sm/gpgsm.c (oRequestOrigin): New const. (opts): New option --request-origin. (main): Parse that option. * sm/gpgsm.h (struct opt): Add field request_origin. * sm/call-agent.c (start_agent): Send option to the agent. Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index ad044ff..d840b85 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -3131,6 +3131,15 @@ are: Pinentry the user is not prompted again if he enters a bad password. @end table + at item --request-origin @var{origin} + at opindex request-origin +Tell gpg to assume that the operation ultimately originated at + at var{origin}. Depending on the origin certain restrictions are applied +and the Pinentry may include an extra note on the origin. Supported +values for @var{origin} are: @code{local} which is the default, + at code{remote} to indicate a remote origin or @code{browser} for an +operation requested by a web browser. + @item --command-fd @var{n} @opindex command-fd This is a replacement for the deprecated shared-memory IPC mode. diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 7c6c315..ebe58bc 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -765,6 +765,15 @@ are: Pinentry the user is not prompted again if he enters a bad password. @end table + at item --request-origin @var{origin} + at opindex request-origin +Tell gpgsm to assume that the operation ultimately originated at + at var{origin}. Depending on the origin certain restrictions are applied +and the Pinentry may include an extra note on the origin. Supported +values for @var{origin} are: @code{local} which is the default, + at code{remote} to indicate a remote origin or @code{browser} for an +operation requested by a web browser. + @item --no-common-certs-import @opindex no-common-certs-import Suppress the import of common certificates on keybox creation. diff --git a/g10/call-agent.c b/g10/call-agent.c index fdacf6a..6ee82a5 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -289,6 +289,23 @@ start_agent (ctrl_t ctrl, int flag_for_card) } } + /* Pass on the request origin. */ + if (opt.request_origin) + { + char *tmp = xasprintf ("OPTION pretend-request-origin=%s", + str_request_origin (opt.request_origin)); + rc = assuan_transact (agent_ctx, tmp, + NULL, NULL, NULL, NULL, NULL, NULL); + xfree (tmp); + if (rc) + { + log_error ("setting request origin '%s' failed: %s\n", + str_request_origin (opt.request_origin), + gpg_strerror (rc)); + write_status_error ("set_request_origin", rc); + } + } + /* In DE_VS mode under Windows we require that the JENT RNG * is active. */ #ifdef HAVE_W32_SYSTEM diff --git a/g10/gpg.c b/g10/gpg.c index 62d6131..bfff7a5 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -422,6 +422,7 @@ enum cmd_and_opt_values oDisableSignerUID, oSender, oKeyOrigin, + oRequestOrigin, oNoop }; @@ -708,6 +709,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oPassphraseFile, "passphrase-file", "@"), ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"), ARGPARSE_s_s (oPinentryMode, "pinentry-mode", "@"), + ARGPARSE_s_s (oRequestOrigin, "request-origin", "@"), ARGPARSE_s_i (oCommandFD, "command-fd", "@"), ARGPARSE_s_s (oCommandFile, "command-file", "@"), ARGPARSE_s_n (oQuickRandom, "debug-quick-random", "@"), @@ -3096,6 +3098,12 @@ main (int argc, char **argv) log_error (_("invalid pinentry mode '%s'\n"), pargs.r.ret_str); break; + case oRequestOrigin: + opt.request_origin = parse_request_origin (pargs.r.ret_str); + if (opt.request_origin == -1) + log_error (_("invalid request origin '%s'\n"), pargs.r.ret_str); + break; + case oCommandFD: opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); if (! gnupg_fd_valid (opt.command_fd)) diff --git a/g10/options.h b/g10/options.h index 130bec8..e1bf97f 100644 --- a/g10/options.h +++ b/g10/options.h @@ -271,6 +271,7 @@ struct int passphrase_repeat; int pinentry_mode; + int request_origin; int unwrap_encryption; int only_sign_text_ids; diff --git a/sm/call-agent.c b/sm/call-agent.c index 772c9c3..20d879f 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -179,6 +179,20 @@ start_agent (ctrl_t ctrl) gpg_strerror (rc)); } + /* Pass on the request origin. */ + if (opt.request_origin) + { + char *tmp = xasprintf ("OPTION pretend-request-origin=%s", + str_request_origin (opt.request_origin)); + rc = assuan_transact (agent_ctx, tmp, + NULL, NULL, NULL, NULL, NULL, NULL); + xfree (tmp); + if (rc) + log_error ("setting request origin '%s' failed: %s\n", + str_request_origin (opt.request_origin), + gpg_strerror (rc)); + } + /* In DE_VS mode under Windows we require that the JENT RNG * is active. */ #ifdef HAVE_W32_SYSTEM diff --git a/sm/gpgsm.c b/sm/gpgsm.c index ab08a52..b81e3b6 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -125,6 +125,7 @@ enum cmd_and_opt_values { oPassphraseFD, oPinentryMode, + oRequestOrigin, oAssumeArmor, oAssumeBase64, @@ -254,6 +255,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_i (oPassphraseFD, "passphrase-fd", "@"), ARGPARSE_s_s (oPinentryMode, "pinentry-mode", "@"), + ARGPARSE_s_s (oRequestOrigin, "request-origin", "@"), ARGPARSE_s_n (oAssumeArmor, "assume-armor", N_("assume input is in PEM format")), @@ -1160,6 +1162,12 @@ main ( int argc, char **argv) log_error (_("invalid pinentry mode '%s'\n"), pargs.r.ret_str); break; + case oRequestOrigin: + opt.request_origin = parse_request_origin (pargs.r.ret_str); + if (opt.request_origin == -1) + log_error (_("invalid request origin '%s'\n"), pargs.r.ret_str); + break; + /* Input encoding selection. */ case oAssumeArmor: ctrl.autodetect_encoding = 0; diff --git a/sm/gpgsm.h b/sm/gpgsm.h index cd4fc99..325948a 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -86,6 +86,7 @@ struct int with_keygrip; /* Option --with-keygrip active. */ int pinentry_mode; + int request_origin; int armor; /* force base64 armoring (see also ctrl.with_base64) */ int no_armor; /* don't try to figure out whether data is base64 armored*/ commit 05c55ee260edc07cd19da56dfd00347bfe3f529c Author: Werner Koch Date: Fri Mar 23 08:14:58 2018 +0100 agent: New OPTION pretend-request-origin * common/shareddefs.h (request_origin_t): New. * common/agent-opt.c (parse_request_origin): New. (str_request_origin): New. * agent/command.c (option_handler): Implement new option. -- This allows to pretend that a request originated from the extra or browser socket. Signed-off-by: Werner Koch diff --git a/agent/command.c b/agent/command.c index f9bc6ca..8bb9b6a 100644 --- a/agent/command.c +++ b/agent/command.c @@ -3101,6 +3101,21 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) ctrl->s2k_count = 0; } } + else if (!strcmp (key, "pretend-request-origin")) + { + log_assert (!ctrl->restricted); + switch (parse_request_origin (value)) + { + case REQUEST_ORIGIN_LOCAL: ctrl->restricted = 0; break; + case REQUEST_ORIGIN_REMOTE: ctrl->restricted = 1; break; + case REQUEST_ORIGIN_BROWSER: ctrl->restricted = 2; break; + default: + err = gpg_error (GPG_ERR_INV_VALUE); + /* Better pretend to be remote in case of a bad value. */ + ctrl->restricted = 1; + break; + } + } else err = gpg_error (GPG_ERR_UNKNOWN_OPTION); diff --git a/common/agent-opt.c b/common/agent-opt.c index b324482..6d9f9e7 100644 --- a/common/agent-opt.c +++ b/common/agent-opt.c @@ -69,3 +69,38 @@ str_pinentry_mode (pinentry_mode_t mode) } return "?"; } + + +/* Parse VALUE and return an integer representing a request_origin_t. + * (-1) is returned for an invalid VALUE. */ +int +parse_request_origin (const char *value) +{ + int result; + + if (!strcmp (value, "none") || !strcmp (value, "local")) + result = REQUEST_ORIGIN_LOCAL; + else if (!strcmp (value, "remote")) + result = REQUEST_ORIGIN_REMOTE; + else if (!strcmp (value, "browser")) + result = REQUEST_ORIGIN_BROWSER; + else + result = -1; + + return result; +} + + +/* Return the string representation for the request origin. Returns + * "?" for an invalid mode. */ +const char * +str_request_origin (request_origin_t mode) +{ + switch (mode) + { + case REQUEST_ORIGIN_LOCAL: return "local"; + case REQUEST_ORIGIN_REMOTE: return "remote"; + case REQUEST_ORIGIN_BROWSER: return "browser"; + } + return "?"; +} diff --git a/common/shareddefs.h b/common/shareddefs.h index 1594f66..4b14421 100644 --- a/common/shareddefs.h +++ b/common/shareddefs.h @@ -39,10 +39,23 @@ typedef enum pinentry_mode_t; +/* Values for the request origin. */ +typedef enum + { + REQUEST_ORIGIN_LOCAL = 0, + REQUEST_ORIGIN_REMOTE, + REQUEST_ORIGIN_BROWSER + } +request_origin_t; + + /*-- agent-opt.c --*/ int parse_pinentry_mode (const char *value); const char *str_pinentry_mode (pinentry_mode_t mode); +int parse_request_origin (const char *value); +const char *str_request_origin (request_origin_t mode); + #endif /*GNUPG_COMMON_SHAREDDEFS_H*/ diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 4781bbd..bcce033 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -1581,6 +1581,27 @@ option is valid for the entire session or until reset to 0. This option is useful if the key is later used on boxes which are either much slower or faster than the actual box. + at item pretend-request-origin +This option switches the connection into a restricted mode which +handles all further commands in the same way as they would be handled +when originating from the extra or browser socket. Note that this +option is not available in the restricted mode. Valid values for this +option are: + + @table @code + @item none + @itemx local + This is a NOP and leaves the connection in the standard way. + + @item remote + Pretend to come from a remote origin in the same way as connections + from the @option{--extra-socket}. + + @item browser + Pretend to come from a local web browser in the same way as connections + from the @option{--browser-socket}. + @end table + @end table ----------------------------------------------------------------------- Summary of changes: agent/command.c | 15 +++++++++++++++ common/agent-opt.c | 35 +++++++++++++++++++++++++++++++++++ common/shareddefs.h | 13 +++++++++++++ doc/gpg-agent.texi | 21 +++++++++++++++++++++ doc/gpg.texi | 9 +++++++++ doc/gpgsm.texi | 9 +++++++++ g10/call-agent.c | 17 +++++++++++++++++ g10/gpg.c | 8 ++++++++ g10/options.h | 1 + sm/call-agent.c | 14 ++++++++++++++ sm/gpgsm.c | 8 ++++++++ sm/gpgsm.h | 1 + 12 files changed, 151 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 11:35:13 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 23 Mar 2018 11:35:13 +0100 Subject: [git] GPGME - branch, json-tool, updated. gpgme-1.10.0-62-gd83482a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, json-tool has been updated via d83482a1d768fc5afd3aa4836f2fefe5c549d02e (commit) via 6525d78d0a1d303c449762082942e71d3002b9ca (commit) from e14f1f687ff618716ed17e309a0475df95e1c0aa (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d83482a1d768fc5afd3aa4836f2fefe5c549d02e Author: Werner Koch Date: Fri Mar 23 11:27:59 2018 +0100 json: Finish op:encrypt. * src/gpgme-json.c (add_base64_to_object): New. (data_from_base64_string): New. (op_encrypt): Employ them. (process_request): Print unformated json. -- Signed-off-by: Werner Koch diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 75f1a09..6ba79e5 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -64,6 +64,7 @@ static int opt_interactive; */ #define xtrymalloc(a) gpgrt_malloc ((a)) +#define xtrystrdup(a) gpgrt_strdup ((a)) #define xmalloc(a) ({ \ void *_r = gpgrt_malloc ((a)); \ if (!_r) \ @@ -140,6 +141,87 @@ xjson_AddBoolToObject (cjson_t object, const char *name, int abool) return ; } +/* This is similar to cJSON_AddStringToObject but takes a gpgme DATA + * object and adds it under NAME as a base 64 encoded string to + * OBJECT. Ownership of DATA is transferred to this function. */ +static gpg_error_t +add_base64_to_object (cjson_t object, const char *name, gpgme_data_t data) +{ + gpg_err_code_t err; + estream_t fp = NULL; + gpgrt_b64state_t state = NULL; + cjson_t j_str = NULL; + void *buffer = NULL; + size_t buflen; + + fp = es_fopenmem (0, "rwb"); + if (!fp) + { + err = gpg_err_code_from_syserror (); + goto leave; + } + state = gpgrt_b64enc_start (fp, ""); + if (!state) + { + err = gpg_err_code_from_syserror (); + goto leave; + } + + gpgme_data_write (data, "", 1); /* Make sure we have a string. */ + buffer = gpgme_data_release_and_get_mem (data, &buflen); + data = NULL; + if (!buffer) + { + err = gpg_error_from_syserror (); + goto leave; + } + + err = gpgrt_b64enc_write (state, buffer, buflen); + if (err) + goto leave; + xfree (buffer); + buffer = NULL; + + err = gpgrt_b64enc_finish (state); + state = NULL; + if (err) + return err; + + es_fputc (0, fp); + if (es_fclose_snatch (fp, &buffer, NULL)) + { + fp = NULL; + err = gpg_error_from_syserror (); + goto leave; + } + fp = NULL; + + j_str = cJSON_CreateStringConvey (buffer); + if (!j_str) + { + err = gpg_error_from_syserror (); + goto leave; + } + buffer = NULL; + + if (!cJSON_AddItemToObject (object, name, j_str)) + { + err = gpg_error_from_syserror (); + cJSON_Delete (j_str); + j_str = NULL; + goto leave; + } + j_str = NULL; + + leave: + xfree (buffer); + cJSON_Delete (j_str); + gpgrt_b64enc_finish (state); + es_fclose (fp); + gpgme_data_release (data); + return err; +} + /* Create a JSON error object. If JSON is not NULL the error message * is appended to that object. An existing "type" item will be replaced. */ @@ -386,6 +468,72 @@ release_context (gpgme_ctx_t ctx) } + +/* Given a Base-64 encoded string object in JSON return a gpgme data + * object at R_DATA. */ +static gpg_error_t +data_from_base64_string (gpgme_data_t *r_data, cjson_t json) +{ +#if GPGRT_VERSION_NUMBER < 0x011d00 /* 1.29 */ + *r_data = NULL; + return gpg_error (GPG_ERR_NOT_SUPPORTED); +#else + gpg_error_t err; + size_t len; + char *buf = NULL; + gpgrt_b64state_t state = NULL; + gpgme_data_t data = NULL; + + *r_data = NULL; + + /* A quick check on the JSON. */ + if (!cjson_is_string (json)) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + + state = gpgrt_b64dec_start (NULL); + if (!state) + { + err = gpg_err_code_from_syserror (); + goto leave; + } + + /* Fixme: Data duplication - we should see how to snatch the memory + * from the json object. */ + len = strlen (json->valuestring); + buf = xtrystrdup (json->valuestring); + if (!buf) + { + err = gpg_error_from_syserror (); + goto leave; + } + + err = gpgrt_b64dec_proc (state, buf, len, &len); + if (err) + goto leave; + + err = gpgrt_b64dec_finish (state); + state = NULL; + if (err) + goto leave; + + err = gpgme_data_new_from_mem (&data, buf, len, 1); + if (err) + goto leave; + *r_data = data; + data = NULL; + + leave: + xfree (data); + xfree (buf); + gpgrt_b64dec_finish (state); + return err; +#endif +} + + /* * Implementaion of the commands. @@ -487,16 +635,23 @@ op_encrypt (cjson_t request, cjson_t result) } if (opt_base64) { - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); - goto leave; + err = data_from_base64_string (&input, j_input); + if (err) + { + error_object (result, "Error decoding Base-64 encoded 'data': %s", + gpg_strerror (err)); + goto leave; + } } - err = gpgme_data_new_from_mem (&input, j_input->valuestring, - strlen (j_input->valuestring), 0); - if (err) + else { - error_object (result, "Error creating input data object: %s", - gpg_strerror (err)); - goto leave; + err = gpgme_data_new_from_mem (&input, j_input->valuestring, + strlen (j_input->valuestring), 0); + if (err) + { + error_object (result, "Error getting 'data': %s", gpg_strerror (err)); + goto leave; + } } /* Create an output data object. */ @@ -541,9 +696,10 @@ op_encrypt (cjson_t request, cjson_t result) } else { - error_object (result, "Binary output is not yet supported"); - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); - goto leave; + err = add_base64_to_object (result, "data", output); + output = NULL; + if (err) + goto leave; } leave: @@ -685,7 +841,10 @@ process_request (const char *request) leave: cJSON_Delete (json); json = NULL; - res = cJSON_Print (response); + if (opt_interactive) + res = cJSON_Print (response); + else + res = cJSON_PrintUnformatted (response); if (!res) log_error ("Printing JSON data failed\n"); cJSON_Delete (response); commit 6525d78d0a1d303c449762082942e71d3002b9ca Author: Werner Koch Date: Fri Mar 23 11:26:36 2018 +0100 json: Add a new function to cJSON. * src/cJSON.c (cJSON_CreateStringConvey): New. diff --git a/src/cJSON.c b/src/cJSON.c index 1941d11..cf0cb13 100644 --- a/src/cJSON.c +++ b/src/cJSON.c @@ -1200,6 +1200,18 @@ cJSON_CreateString (const char *string) } cJSON * +cJSON_CreateStringConvey (char *string) +{ + cJSON *item = cJSON_New_Item (); + if (item) + { + item->type = cJSON_String; + item->valuestring = string; + } + return item; +} + +cJSON * cJSON_CreateArray (void) { cJSON *item = cJSON_New_Item (); diff --git a/src/cJSON.h b/src/cJSON.h index 69c3056..a200c31 100644 --- a/src/cJSON.h +++ b/src/cJSON.h @@ -113,6 +113,7 @@ extern cJSON *cJSON_CreateFalse(void); extern cJSON *cJSON_CreateBool(int b); extern cJSON *cJSON_CreateNumber(double num); extern cJSON *cJSON_CreateString(const char *string); +extern cJSON *cJSON_CreateStringConvey (char *string); extern cJSON *cJSON_CreateArray(void); extern cJSON *cJSON_CreateObject(void); ----------------------------------------------------------------------- Summary of changes: src/cJSON.c | 12 ++++ src/cJSON.h | 1 + src/gpgme-json.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 184 insertions(+), 12 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 11:38:54 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 23 Mar 2018 11:38:54 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-156-gc7bb12d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via c7bb12da5297a7e188766d9759f700dd771faff8 (commit) via d83482a1d768fc5afd3aa4836f2fefe5c549d02e (commit) via 6525d78d0a1d303c449762082942e71d3002b9ca (commit) via e14f1f687ff618716ed17e309a0475df95e1c0aa (commit) via 6073789a6d3514263404c93fa795a398bfd93d91 (commit) via 44f9e80ea99733f373d75c3632273f763e6f5853 (commit) via d2b31d8c106423bd0eaa5fffaa39b0983c9ae525 (commit) via 81c90d0cd0f959fd5e01baed9b4af0ec35ecb85c (commit) via 8eb08b318913644d918002f3195f7ec0e75ae239 (commit) from 65ed4ac82598734551b87fc89deab3cee010bd37 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c7bb12da5297a7e188766d9759f700dd771faff8 Merge: 65ed4ac d83482a Author: Werner Koch Date: Fri Mar 23 11:31:20 2018 +0100 Merge branch 'json-tool' ----------------------------------------------------------------------- Summary of changes: lang/README | 1 + src/Makefile.am | 9 +- src/cJSON.c | 1404 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cJSON.h | 187 ++++++++ src/cJSON.readme | 270 +++++++++++ src/gpgme-json.c | 1327 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 3196 insertions(+), 2 deletions(-) create mode 100644 src/cJSON.c create mode 100644 src/cJSON.h create mode 100644 src/cJSON.readme create mode 100644 src/gpgme-json.c hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 11:43:53 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 23 Mar 2018 11:43:53 +0100 Subject: [git] GPGME - branch, javascript-binding, created. gpgme-1.10.0-62-gd83482a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been created at d83482a1d768fc5afd3aa4836f2fefe5c549d02e (commit) - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 11:47:39 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 23 Mar 2018 11:47:39 +0100 Subject: [git] GPGME - branch, json-tool, deleted. gpgme-1.10.0-62-gd83482a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, json-tool has been deleted was d83482a1d768fc5afd3aa4836f2fefe5c549d02e ----------------------------------------------------------------------- d83482a1d768fc5afd3aa4836f2fefe5c549d02e json: Finish op:encrypt. ----------------------------------------------------------------------- hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 12:42:51 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 23 Mar 2018 12:42:51 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-157-geee68c1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via eee68c1b13fbe21c123f469712817e0c81f16383 (commit) from c7bb12da5297a7e188766d9759f700dd771faff8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit eee68c1b13fbe21c123f469712817e0c81f16383 Author: Werner Koch Date: Fri Mar 23 12:36:19 2018 +0100 build: Allow building with released libgpg-error. * src/gpgme-json.c (add_base64_to_object): Return an error if building with an older libgpg-error. Signed-off-by: Werner Koch diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 6ba79e5..09b34bb 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -147,6 +147,9 @@ xjson_AddBoolToObject (cjson_t object, const char *name, int abool) static gpg_error_t add_base64_to_object (cjson_t object, const char *name, gpgme_data_t data) { +#if GPGRT_VERSION_NUMBER < 0x011d00 /* 1.29 */ + return gpg_error (GPG_ERR_NOT_SUPPORTED); +#else gpg_err_code_t err; estream_t fp = NULL; gpgrt_b64state_t state = NULL; @@ -220,6 +223,7 @@ add_base64_to_object (cjson_t object, const char *name, gpgme_data_t data) es_fclose (fp); gpgme_data_release (data); return err; +#endif } ----------------------------------------------------------------------- Summary of changes: src/gpgme-json.c | 4 ++++ 1 file changed, 4 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 14:37:48 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 23 Mar 2018 14:37:48 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-100-g88e76e1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 88e76e1675dc10ab88d5541f716ea54e00d61b40 (commit) from ca8f18f401185af0e3a1e0a66ef08f4f49566e90 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 88e76e1675dc10ab88d5541f716ea54e00d61b40 Author: Andre Heinecke Date: Fri Mar 23 14:37:22 2018 +0100 Spellcheck german localisation * po/de.po: Spellcheck. -- GnuPG-Bug-Id: T3859 diff --git a/po/de.po b/po/de.po index 5cbec20..9d29005 100644 --- a/po/de.po +++ b/po/de.po @@ -114,7 +114,7 @@ msgstr "" "\n" "Bitten benutzen Sie den \"Entschl?sseln/?berpr?fen\" Men?punkt\n" "um die gesamte Nachricht nochmal zu entschl?sseln. Danach k?nnen\n" -"Sie das Attachment wieder ?ffenen." +"Sie das Attachment wieder ?ffnen." #: src/cmdbarcontrols.cpp:104 msgid "Could not start certificate manager" @@ -349,7 +349,7 @@ msgstr "Nachricht signieren" #: src/inspectors.cpp:730 msgid "GpgOL Decrypt/Verify" -msgstr "GpgOL Enschl?sseln/Pr?fen" +msgstr "GpgOL Entschl?sseln/Pr?fen" #: src/inspectors.cpp:791 msgid "Encrypt message with GnuPG" @@ -389,7 +389,7 @@ msgid "" "The unsigned / unencrypted attachments are:\n" "\n" msgstr "" -"Nicht alle Anh?nge waren verschl?sselt order signiert.\n" +"Nicht alle Anh?nge waren verschl?sselt oder signiert.\n" "Die unsignierten / unverschl?sselten Anh?nge sind:\n" "\n" @@ -418,7 +418,7 @@ msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." msgstr "" -"Note: Die Anh?nge k?nnten auf Dateiebene verschl?sselt oder singiert sein, " +"Note: Die Anh?nge k?nnten auf Dateiebene verschl?sselt oder signiert sein, " "aber GpgOL kann deren Kryptostatus nicht anzeigen." #: src/mail.cpp:376 @@ -437,7 +437,7 @@ msgid "" "

If you did not request to publish your Pubkey in your providers " "directory, simply ignore this message.

\n" msgstr "" -"Dies ist eine Best?tigungmail um ihren ?schl in dem Verzeichnis f?r ihre " +"Dies ist eine Best?tigungsmail um ihren ?schl in dem Verzeichnis f?r ihre " "Maildom?ne einzutragen.\n" "\n" "

Wenn sie dies nicht angefordert haben, k?nnen Sie diese Mail ignorieren.Optionen->GpgOL.\n" +"Hauptmen? unter: Extras->Optionen->GpgOL.\n" #: src/olflange.cpp:796 msgid "" ----------------------------------------------------------------------- Summary of changes: po/de.po | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 15:14:42 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 23 Mar 2018 15:14:42 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-25-g137644c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 137644c9cb58deaaba6850f2763d9c5f9241cb0b (commit) from 2cd35df5db3c4dfe37616dcfb1fcc644959449ef (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 137644c9cb58deaaba6850f2763d9c5f9241cb0b Author: Werner Koch Date: Fri Mar 23 15:07:56 2018 +0100 sm: Add OPTION request-origin. * sm/server.c: Include shareddefs.h. (option_handler): Add option. -- This is required when running gpgsm in server mode as done by GPGME. Noet that a command line option takes precedence. Signed-off-by: Werner Koch diff --git a/sm/server.c b/sm/server.c index 721f3fa..98505e2 100644 --- a/sm/server.c +++ b/sm/server.c @@ -32,6 +32,7 @@ #include "../common/sysutils.h" #include "../common/server-help.h" #include "../common/asshelp.h" +#include "../common/shareddefs.h" #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) @@ -289,6 +290,17 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) ctrl->offline = i; } } + else if (!strcmp (key, "request-origin")) + { + if (!opt.request_origin) + { + int i = parse_request_origin (value); + if (i == -1) + err = gpg_error (GPG_ERR_INV_VALUE); + else + opt.request_origin = i; + } + } else err = gpg_error (GPG_ERR_UNKNOWN_OPTION); ----------------------------------------------------------------------- Summary of changes: sm/server.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 15:34:35 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 23 Mar 2018 15:34:35 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-158-gb9000bc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via b9000bc293164ff62efa7e91e5cf6d5fc19d482f (commit) from eee68c1b13fbe21c123f469712817e0c81f16383 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b9000bc293164ff62efa7e91e5cf6d5fc19d482f Author: Werner Koch Date: Fri Mar 23 15:27:32 2018 +0100 core: New gpgme_set_ctx_flag "request-origin". * src/context.h (gpgme_context): Add 'request_origin'. * src/gpgme.c (gpgme_release): Free that field. (gpgme_set_ctx_flag, gpgme_get_ctx_flag): Add "request-origin". * src/engine-backend.h (engine_ops): Add 'set_engine_ops' func ptr and adjust all users. * src/engine.c (_gpgme_engine_set_engine_flags): New. * src/op-support.c (_gpgme_op_reset): Call that func. * src/engine-gpg.c (struct engine_gpg): Add 'request_origin'. (gpg_set_engine_flags): New. (_gpgme_engine_ops_gpg): Hook it. (build_argv): Use command line option --request-origin. * src/engine-gpgsm.c (struct engine_gpgsm): Add 'request_origin'. (gpgsm_set_engine_flags): New. (_gpgme_engine_ops_gpgsm): Hook it. (start): Send OPTION "request-origin". * src/engine-assuan.c (struct engine_llass): Add 'request_origin'. (gpgsm_set_engine_flags): New. (_gpgme_engine_ops_assuan): Hook it. (start): Send OPTION "pretend-request-origin". Signed-off-by: Werner Koch diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 37cf16a..ab554d8 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -3065,6 +3065,11 @@ a message signed by a brand new key (which you naturally will not have on your local keyring), the operator can tell both your IP address and the time when you verified the signature. + at item "request-origin" +The string given in @var{value} is passed to the GnuPG engines to +request restrictions based on the origin of the request. Valid values +are documented in the GnuPG manual and the gpg man page under the +option ``--request-origin''. @end table diff --git a/src/context.h b/src/context.h index 1e763d2..202cf16 100644 --- a/src/context.h +++ b/src/context.h @@ -145,6 +145,9 @@ struct gpgme_context /* The gpg specific override session key or NULL. */ char *override_session_key; + /* The optional request origin. */ + char *request_origin; + /* The locale for the pinentry. */ char *lc_ctype; char *lc_messages; diff --git a/src/engine-assuan.c b/src/engine-assuan.c index bb2290a..6e603d9 100644 --- a/src/engine-assuan.c +++ b/src/engine-assuan.c @@ -96,6 +96,7 @@ struct engine_llass int gpg_agent:1; /* Assume this is a gpg-agent connection. */ } opt; + char request_origin[10]; /* Copy from the CTX. */ }; typedef struct engine_llass *engine_llass_t; @@ -365,6 +366,24 @@ llass_new (void **engine, const char *file_name, const char *home_dir, } +/* Copy flags from CTX into the engine object. */ +static void +llass_set_engine_flags (void *engine, const gpgme_ctx_t ctx) +{ + engine_llass_t llass = engine; + + if (ctx->request_origin) + { + if (strlen (ctx->request_origin) + 1 > sizeof llass->request_origin) + strcpy (llass->request_origin, "xxx"); /* Too long - force error */ + else + strcpy (llass->request_origin, ctx->request_origin); + } + else + *llass->request_origin = 0; +} + + static gpgme_error_t llass_set_locale (void *engine, int category, const char *value) { @@ -660,6 +679,21 @@ start (engine_llass_t llass, const char *command) int nfds; int i; + if (*llass->request_origin && llass->opt.gpg_agent) + { + char *cmd; + + cmd = _gpgme_strconcat ("OPTION pretend-request-origin=", + llass->request_origin, NULL); + if (!cmd) + return gpg_error_from_syserror (); + err = assuan_transact (llass->assuan_ctx, cmd, NULL, NULL, NULL, + NULL, NULL, NULL); + free (cmd); + if (err && gpg_err_code (err) != GPG_ERR_UNKNOWN_OPTION) + return err; + } + /* We need to know the fd used by assuan for reads. We do this by using the assumption that the first returned fd from assuan_get_active_fds() is always this one. */ @@ -775,6 +809,7 @@ struct engine_ops _gpgme_engine_ops_assuan = NULL, /* set_colon_line_handler */ llass_set_locale, NULL, /* set_protocol */ + llass_set_engine_flags, NULL, /* decrypt */ NULL, /* delete */ NULL, /* edit */ diff --git a/src/engine-backend.h b/src/engine-backend.h index 421eb16..97cf6a1 100644 --- a/src/engine-backend.h +++ b/src/engine-backend.h @@ -61,6 +61,7 @@ struct engine_ops void *fnc_value); gpgme_error_t (*set_locale) (void *engine, int category, const char *value); gpgme_error_t (*set_protocol) (void *engine, gpgme_protocol_t protocol); + void (*set_engine_flags) (void *engine, gpgme_ctx_t ctx); gpgme_error_t (*decrypt) (void *engine, gpgme_decrypt_flags_t flags, gpgme_data_t ciph, diff --git a/src/engine-g13.c b/src/engine-g13.c index f8f3178..ec2f7af 100644 --- a/src/engine-g13.c +++ b/src/engine-g13.c @@ -790,6 +790,7 @@ struct engine_ops _gpgme_engine_ops_g13 = NULL, /* set_colon_line_handler */ g13_set_locale, NULL, /* set_protocol */ + NULL, /* set_engine_flags */ NULL, /* decrypt */ NULL, /* delete */ NULL, /* edit */ diff --git a/src/engine-gpg.c b/src/engine-gpg.c index bfe7d13..22d327e 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -143,6 +143,7 @@ struct engine_gpg struct gpgme_io_cbs io_cbs; gpgme_pinentry_mode_t pinentry_mode; + char request_origin[10]; /* NULL or the data object fed to --override_session_key-fd. */ gpgme_data_t override_session_key; @@ -628,6 +629,24 @@ gpg_new (void **engine, const char *file_name, const char *home_dir, } +/* Copy flags from CTX into the engine object. */ +static void +gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx) +{ + engine_gpg_t gpg = engine; + + if (ctx->request_origin && have_gpg_version (gpg, "2.2.6")) + { + if (strlen (ctx->request_origin) + 1 > sizeof gpg->request_origin) + strcpy (gpg->request_origin, "xxx"); /* Too long - force error */ + else + strcpy (gpg->request_origin, ctx->request_origin); + } + else + *gpg->request_origin = 0; +} + + static gpgme_error_t gpg_set_locale (void *engine, int category, const char *value) { @@ -904,6 +923,20 @@ build_argv (engine_gpg_t gpg, const char *pgmname) argc++; } + if (*gpg->request_origin) + { + argv[argc] = _gpgme_strconcat ("--request-origin=", + gpg->request_origin, NULL); + if (!argv[argc]) + { + int saved_err = gpg_error_from_syserror (); + free (fd_data_map); + free_argv (argv); + return saved_err; + } + argc++; + } + if (gpg->pinentry_mode && have_gpg_version (gpg, "2.1.0")) { const char *s = NULL; @@ -3090,6 +3123,7 @@ struct engine_ops _gpgme_engine_ops_gpg = gpg_set_colon_line_handler, gpg_set_locale, NULL, /* set_protocol */ + gpg_set_engine_flags, /* set_engine_flags */ gpg_decrypt, gpg_delete, gpg_edit, diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c index 94ae67f..24867c7 100644 --- a/src/engine-gpgconf.c +++ b/src/engine-gpgconf.c @@ -1287,6 +1287,7 @@ struct engine_ops _gpgme_engine_ops_gpgconf = NULL, /* set_colon_line_handler */ NULL, /* set_locale */ NULL, /* set_protocol */ + NULL, /* set_engine_flags */ NULL, /* decrypt */ NULL, /* delete */ NULL, /* edit */ diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index e337fed..b8e44e7 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -107,6 +107,8 @@ struct engine_gpgsm gpgme_data_t inline_data; /* Used to collect D lines. */ + char request_origin[10]; + struct gpgme_io_cbs io_cbs; }; @@ -521,6 +523,24 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir, } +/* Copy flags from CTX into the engine object. */ +static void +gpgsm_set_engine_flags (void *engine, const gpgme_ctx_t ctx) +{ + engine_gpgsm_t gpgsm = engine; + + if (ctx->request_origin) + { + if (strlen (ctx->request_origin) + 1 > sizeof gpgsm->request_origin) + strcpy (gpgsm->request_origin, "xxx"); /* Too long - force error */ + else + strcpy (gpgsm->request_origin, ctx->request_origin); + } + else + *gpgsm->request_origin = 0; +} + + static gpgme_error_t gpgsm_set_locale (void *engine, int category, const char *value) { @@ -1058,6 +1078,20 @@ start (engine_gpgsm_t gpgsm, const char *command) int nfds; int i; + if (*gpgsm->request_origin) + { + char *cmd; + + cmd = _gpgme_strconcat ("OPTION request-origin=", + gpgsm->request_origin, NULL); + if (!cmd) + return gpg_error_from_syserror (); + err = gpgsm_assuan_simple_command (gpgsm, cmd, NULL, NULL); + free (cmd); + if (err && gpg_err_code (err) != GPG_ERR_UNKNOWN_OPTION) + return err; + } + /* We need to know the fd used by assuan for reads. We do this by using the assumption that the first returned fd from assuan_get_active_fds() is always this one. */ @@ -2102,6 +2136,7 @@ struct engine_ops _gpgme_engine_ops_gpgsm = gpgsm_set_colon_line_handler, gpgsm_set_locale, NULL, /* set_protocol */ + gpgsm_set_engine_flags, gpgsm_decrypt, gpgsm_delete, /* decrypt_verify */ NULL, /* edit */ diff --git a/src/engine-spawn.c b/src/engine-spawn.c index 7f78bb5..7b7a9cd 100644 --- a/src/engine-spawn.c +++ b/src/engine-spawn.c @@ -449,6 +449,7 @@ struct engine_ops _gpgme_engine_ops_spawn = NULL, /* set_colon_line_handler */ NULL, /* set_locale */ NULL, /* set_protocol */ + NULL, /* set_engine_flags */ NULL, /* decrypt */ NULL, /* delete */ NULL, /* edit */ diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c index bc3f3fb..fd5ac17 100644 --- a/src/engine-uiserver.c +++ b/src/engine-uiserver.c @@ -1368,6 +1368,7 @@ struct engine_ops _gpgme_engine_ops_uiserver = uiserver_set_colon_line_handler, uiserver_set_locale, uiserver_set_protocol, + NULL, /* set_engine_flags */ uiserver_decrypt, NULL, /* delete */ NULL, /* edit */ diff --git a/src/engine.c b/src/engine.c index 28ba9fd..e51384f 100644 --- a/src/engine.c +++ b/src/engine.c @@ -651,6 +651,26 @@ _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol) } +/* Pass information about the current context to the engine. The + * engine may use this context to retrieve context specific flags. + * Important: The engine is required to immediately copy the required + * flags to its own context! + * + * This function will eventually be used to reduce the number of + * explicit passed flags. */ +void +_gpgme_engine_set_engine_flags (engine_t engine, gpgme_ctx_t ctx) +{ + if (!engine) + return; + + if (!engine->ops->set_engine_flags) + return; + + (*engine->ops->set_engine_flags) (engine->engine, ctx); +} + + gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine, gpgme_decrypt_flags_t flags, diff --git a/src/engine.h b/src/engine.h index 0bf1bb2..34bf8e9 100644 --- a/src/engine.h +++ b/src/engine.h @@ -69,6 +69,7 @@ gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category, const char *value); gpgme_error_t _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol); +void _gpgme_engine_set_engine_flags (engine_t engine, gpgme_ctx_t ctx); void _gpgme_engine_release (engine_t engine); void _gpgme_engine_set_status_cb (engine_t engine, gpgme_status_cb_t cb, void *cb_value); diff --git a/src/gpgme.c b/src/gpgme.c index d0a5afe..9e65c50 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -248,6 +248,7 @@ gpgme_release (gpgme_ctx_t ctx) free (ctx->lc_ctype); free (ctx->lc_messages); free (ctx->override_session_key); + free (ctx->request_origin); _gpgme_engine_info_release (ctx->engine_info); ctx->engine_info = NULL; DESTROY_LOCK (ctx->lock); @@ -486,13 +487,8 @@ gpgme_get_armor (gpgme_ctx_t ctx) } -/* Set the flag NAME for CTX to VALUE. The supported flags are: - * - * - full-status :: With a value of "1" the status callback set by - * gpgme_set_status_cb returns all status lines - * except for PROGRESS lines. With the default of - * "0" the status callback is only called in certain - * situations. +/* Set the flag NAME for CTX to VALUE. Please consult the manual for + * a description of the flags. */ gpgme_error_t gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value) @@ -535,6 +531,13 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value) { ctx->auto_key_retrieve = abool; } + else if (!strcmp (name, "request-origin")) + { + free (ctx->request_origin); + ctx->request_origin = strdup (value); + if (!ctx->request_origin) + err = gpg_error_from_syserror (); + } else err = gpg_error (GPG_ERR_UNKNOWN_NAME); @@ -576,6 +579,10 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name) { return ctx->auto_key_retrieve? "1":""; } + else if (!strcmp (name, "request-origin")) + { + return ctx->request_origin? ctx->request_origin : ""; + } else return NULL; } diff --git a/src/op-support.c b/src/op-support.c index 817c569..43cb1c7 100644 --- a/src/op-support.c +++ b/src/op-support.c @@ -141,6 +141,8 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type) if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED) err = 0; + _gpgme_engine_set_engine_flags (ctx->engine, ctx); + if (!err) { err = _gpgme_engine_set_pinentry_mode (ctx->engine, diff --git a/tests/run-decrypt.c b/tests/run-decrypt.c index e961293..f4c4754 100644 --- a/tests/run-decrypt.c +++ b/tests/run-decrypt.c @@ -81,6 +81,7 @@ show_usage (int ex) " --cms use the CMS protocol\n" " --export-session-key show the session key\n" " --override-session-key STRING use STRING as session key\n" + " --request-origin STRING use STRING as request origin\n" " --unwrap remove only the encryption layer\n" , stderr); exit (ex); @@ -102,6 +103,7 @@ main (int argc, char **argv) int print_status = 0; int export_session_key = 0; const char *override_session_key = NULL; + const char *request_origin = NULL; int raw_output = 0; if (argc) @@ -150,6 +152,14 @@ main (int argc, char **argv) override_session_key = *argv; argc--; argv++; } + else if (!strcmp (*argv, "--request-origin")) + { + argc--; argv++; + if (!argc) + show_usage (1); + request_origin = *argv; + argc--; argv++; + } else if (!strcmp (*argv, "--unwrap")) { flags |= GPGME_DECRYPT_UNWRAP; @@ -199,7 +209,18 @@ main (int argc, char **argv) override_session_key); if (err) { - fprintf (stderr, PGM ": error overriding session key: %s\n", + fprintf (stderr, PGM ": error setting overriding session key: %s\n", + gpgme_strerror (err)); + exit (1); + } + } + + if (request_origin) + { + err = gpgme_set_ctx_flag (ctx, "request-origin", request_origin); + if (err) + { + fprintf (stderr, PGM ": error setting request_origin: %s\n", gpgme_strerror (err)); exit (1); } ----------------------------------------------------------------------- Summary of changes: doc/gpgme.texi | 5 +++++ src/context.h | 3 +++ src/engine-assuan.c | 35 +++++++++++++++++++++++++++++++++++ src/engine-backend.h | 1 + src/engine-g13.c | 1 + src/engine-gpg.c | 34 ++++++++++++++++++++++++++++++++++ src/engine-gpgconf.c | 1 + src/engine-gpgsm.c | 35 +++++++++++++++++++++++++++++++++++ src/engine-spawn.c | 1 + src/engine-uiserver.c | 1 + src/engine.c | 20 ++++++++++++++++++++ src/engine.h | 1 + src/gpgme.c | 21 ++++++++++++++------- src/op-support.c | 2 ++ tests/run-decrypt.c | 23 ++++++++++++++++++++++- 15 files changed, 176 insertions(+), 8 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 15:41:20 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 23 Mar 2018 15:41:20 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-159-ge5abf48 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via e5abf4827aead50437bbdff8cfdd5e9fdc6ed72d (commit) from b9000bc293164ff62efa7e91e5cf6d5fc19d482f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e5abf4827aead50437bbdff8cfdd5e9fdc6ed72d Author: Werner Koch Date: Fri Mar 23 15:32:06 2018 +0100 json: Use a request origin of "browser". * src/gpgme-json.c (_create_new_context): Set flag. Signed-off-by: Werner Koch diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 09b34bb..e38f9d8 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -433,6 +433,7 @@ _create_new_context (gpgme_protocol_t proto) if (err) log_fatal ("error creating GPGME context: %s\n", gpg_strerror (err)); gpgme_set_protocol (ctx, proto); + gpgme_set_ctx_flag (ctx, "request-origin", "browser"); return ctx; } ----------------------------------------------------------------------- Summary of changes: src/gpgme-json.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 15:53:01 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 23 Mar 2018 15:53:01 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-160-g4763974 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 4763974ef6932c503e35c3d14fe47a66a5323f48 (commit) from e5abf4827aead50437bbdff8cfdd5e9fdc6ed72d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4763974ef6932c503e35c3d14fe47a66a5323f48 Author: Werner Koch Date: Fri Mar 23 15:46:18 2018 +0100 core: Need to increase an array in the gpg engine. * src/engine-gpg.c (build_argv): Allcate one slot more for ARGV. -- Fixes-commit: b9000bc293164ff62efa7e91e5cf6d5fc19d482f diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 22d327e..3b9a6ff 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -875,7 +875,7 @@ build_argv (engine_gpg_t gpg, const char *pgmname) argc++; if (!gpg->cmd.used) argc++; /* --batch */ - argc += 1; /* --no-sk-comments */ + argc += 2; /* --no-sk-comments, --request-origin */ argv = calloc (argc + 1, sizeof *argv); if (!argv) ----------------------------------------------------------------------- Summary of changes: src/engine-gpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 23 19:06:16 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Fri, 23 Mar 2018 19:06:16 +0100 Subject: [git] gnupg-doc - branch, master, updated. 377a56b4db99d4c3efa9df4ffc615640f3d76532 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 377a56b4db99d4c3efa9df4ffc615640f3d76532 (commit) from 58c0da6fc6ed19fbce053f50231cd048ff7b9071 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 377a56b4db99d4c3efa9df4ffc615640f3d76532 Author: Ben McGinnes Date: Sat Mar 24 05:02:41 2018 +1100 howto: gpgme python bindings * linkage work-around interim measure. * Added links to XHTML copies on an Amazon S3 instance; one is ordinary and the other uses dark background with light text (basically the default Org Mode export produced with the modified zenburn theme I use). diff --git a/web/documentation/howtos.org b/web/documentation/howtos.org index 8b887ca..0df53a8 100644 --- a/web/documentation/howtos.org +++ b/web/documentation/howtos.org @@ -128,3 +128,5 @@ This HOWTO is available: - in its original Emacs Org Mode source form in the GPGME repository ( [[https://dev.gnupg.org/source/gpgme/browse/master/lang/python/docs/GPGMEpythonHOWTOen.org][en]] ) + - as a single HTML file ( [[http://files.au.adversary.org/crypto/GPGMEpythonHOWTOen.html][en]] ) + - as a single HTML file with dark background and light text ( [[http://files.au.adversary.org/crypto/GPGMEpythonHOWTOen-dark.html][en]] ) ----------------------------------------------------------------------- Summary of changes: web/documentation/howtos.org | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sun Mar 25 00:03:52 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sun, 25 Mar 2018 00:03:52 +0100 Subject: [git] GPGME - branch, howto-update-01, created. gpgme-1.10.0-161-g22247f6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, howto-update-01 has been created at 22247f658ce2f8e527c26746358cfc2643c4832f (commit) - Log ----------------------------------------------------------------- commit 22247f658ce2f8e527c26746358cfc2643c4832f Author: Ben McGinnes Date: Sun Mar 25 10:01:14 2018 +1100 doc: python bindings howto * Fixed the plaintext, result and verify_result references in the decryption section. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 1e8dd9f..4d1124f 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -675,10 +675,10 @@ nfile.write(plaintext) #+end_src - The data available in plaintext in this example is the decrypted - content as a byte object in =plaintext[0]=, the recipient key IDs - and algorithms in =plaintext[1]= and the results of verifying any - signatures of the data in =plaintext[0]=. + The data available in =plaintext= in this example is the decrypted + content as a byte object, the recipient key IDs and algorithms in + =result= and the results of verifying any signatures of the data in + =verify_result=. ** Signing text and files ----------------------------------------------------------------------- hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sun Mar 25 03:13:10 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sun, 25 Mar 2018 03:13:10 +0200 Subject: [git] GPGME - branch, howto-update-01, updated. gpgme-1.10.0-164-g40a9dea Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, howto-update-01 has been updated via 40a9dea5d56506400b67b0c11f6e55a1629dc6fe (commit) via 3b724aae423f2de01812165d54df2a7b524c82f6 (commit) via dde1aae312958776fab475d6c0cdfa19cc255863 (commit) from 22247f658ce2f8e527c26746358cfc2643c4832f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 40a9dea5d56506400b67b0c11f6e55a1629dc6fe Author: Ben McGinnes Date: Sun Mar 25 11:54:05 2018 +1100 script: temp homedir * Fixed whitespace. diff --git a/lang/python/examples/howto/temp-homedir-config.py b/lang/python/examples/howto/temp-homedir-config.py index f49de63..368cace 100755 --- a/lang/python/examples/howto/temp-homedir-config.py +++ b/lang/python/examples/howto/temp-homedir-config.py @@ -51,7 +51,7 @@ existing data. If the directory already exists, the script will terminate with a message telling you to specify a new directory name. There is no -default directory name. +default directory name. """ gpgconf = """# gpg.conf settings for key generation: commit 3b724aae423f2de01812165d54df2a7b524c82f6 Author: Ben McGinnes Date: Sun Mar 25 11:35:11 2018 +1100 doc: python bindings howto * Added a reference to new script which will setup a temporary homedir for a user. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 4d1124f..08f9ef7 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1091,6 +1091,10 @@ permissions set to only permit access by the directory owner. On posix systems this means setting the directory permissions to 700. + The =temp-homedir-config.py= script in the HOWTO examples directory + will create an alternative homedir with these configuration options + already set and the correct directory and file permissions. + The successful generation of the key can be confirmed via the returned =GenkeyResult= object, which includes the following data: commit dde1aae312958776fab475d6c0cdfa19cc255863 Author: Ben McGinnes Date: Sun Mar 25 11:26:26 2018 +1100 script: temporary homedir creation * Script to create a temporary gnupg homedir in the user's directory for testing or scripting purposes. * Creates a hidden directory on POSIX systems with the correct permissions (700). * Creates a gpg.conf in that directory containing the same configuration options as used in the "Danger Mouse" example in the HOWTO with the correct permissions (600). diff --git a/lang/python/examples/howto/temp-homedir-config.py b/lang/python/examples/howto/temp-homedir-config.py new file mode 100755 index 0000000..f49de63 --- /dev/null +++ b/lang/python/examples/howto/temp-homedir-config.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import os +import os.path +import sys + +intro = """ +This script creates a temporary directory to use as a homedir for +testing key generation tasks with the correct permissions, along +with a gpg.conf file containing the same configuration options +listed in the HOWTO. + +You may wish to change the order of the cipher preferences or +remove those not relevant to your installation. These +configuration parameters assume that all ciphers and digests are +installed and available rather than limiting to the default +ciphers and digests. + +The script prompts for a directory name to be installed as a hidden +directory in the user's home directory on POSIX systems. So if you +enter "gnupg-temp" on a Linux, BSD or OS X system, it will create +"~/.gnupg-temp" (you do not need to enter the leading dot). + +This script has not been tested on Windows systems and may have +unpredictable results. That said, it will not delete or copy over +existing data. + +If the directory already exists, the script will terminate with a +message telling you to specify a new directory name. There is no +default directory name. +""" + +gpgconf = """# gpg.conf settings for key generation: +expert +allow-freeform-uid +allow-secret-key-import +trust-model tofu+pgp +tofu-default-policy unknown +enable-large-rsa +enable-dsa2 +cert-digest-algo SHA512 +default-preference-list TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 ZLIB BZIP2 ZIP Uncompressed +personal-cipher-preferences TWOFISH CAMELLIA256 AES256 CAMELLIA192 AES192 CAMELLIA128 AES BLOWFISH IDEA CAST5 3DES +personal-digest-preferences SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 +personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed +""" + +if len(sys.argv) == 1: + print(intro) + new_homedir = input("Enter the temporary gnupg homedir name: ") +elif len(sys.argv) == 2: + new_homedir = sys.argv[1] +else: + new_homedir = " ".join(sys.argv[1:]) + +userdir = os.path.expanduser("~") + +if new_homedir.startswith("~"): + new_homdir.replace("~", "") +else: + pass + +if new_homedir.startswith("/"): + new_homdir.replace("/", "") +else: + pass + +if new_homedir.startswith("."): + new_homdir.replace(".", "_") +else: + pass + +if new_homedir.count(" ") > 0: + new_homedir.replace(" ", "_") +else: + pass + +nh = "{0}/.{1}".format(userdir, new_homedir) + +if os.path.exists(nh) is True: + print("The {0} directory already exists.".format(nh)) +else: + print("Creating the {0} directory.".format(nh)) + os.mkdir(nh) + os.chmod(nh, 0o700) + with open("{0}/{1}".format(nh, "gpg.conf"), "w") as f: + f.write(gpgconf) + os.chmod("{0}/{1}".format(nh, "gpg.conf"), 0o600) + print("""You may now use the {0} directory as an alternative GPG homedir: + +gpg --homedir {0} +gpg --homedir --full-gen-key + +Or with GPGME scripts, including the GPGME Python bindings. +""") ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 4 + lang/python/examples/howto/temp-homedir-config.py | 119 ++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100755 lang/python/examples/howto/temp-homedir-config.py hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sun Mar 25 03:15:58 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sun, 25 Mar 2018 03:15:58 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-164-g40a9dea Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 40a9dea5d56506400b67b0c11f6e55a1629dc6fe (commit) via 3b724aae423f2de01812165d54df2a7b524c82f6 (commit) via dde1aae312958776fab475d6c0cdfa19cc255863 (commit) via 22247f658ce2f8e527c26746358cfc2643c4832f (commit) from 4763974ef6932c503e35c3d14fe47a66a5323f48 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 12 ++- lang/python/examples/howto/temp-homedir-config.py | 119 ++++++++++++++++++++++ 2 files changed, 127 insertions(+), 4 deletions(-) create mode 100755 lang/python/examples/howto/temp-homedir-config.py hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sun Mar 25 13:30:18 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sun, 25 Mar 2018 13:30:18 +0200 Subject: [git] GPGME - branch, ben/howto-update-02, created. gpgme-1.10.0-165-g5b32efb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/howto-update-02 has been created at 5b32efbaf37920b2e99d4bb87cb383b2809b1688 (commit) - Log ----------------------------------------------------------------- commit 5b32efbaf37920b2e99d4bb87cb383b2809b1688 Author: Ben McGinnes Date: Sun Mar 25 22:25:52 2018 +1100 doc: python bindings howto * Testing the addition of a HTML header set in org-mode in order to had RSS update links for files. * This should work with any [X]HTML export from current versions of Org-Mode, but if it also works on website generated pages then it'll tick off one of the wishlist itmes. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 08f9ef7..77ddba2 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -6,6 +6,7 @@ #+LATEX_HEADER: \usepackage[margin=1in]{geometry} #+LATEX_HEADER: \setmainfont[Ligatures={Common}]{Times New Roman} #+LATEX_HEADER: \author{Ben McGinnes } +#+HTML_HEAD_EXTRA: * Introduction ----------------------------------------------------------------------- hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sun Mar 25 13:38:39 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sun, 25 Mar 2018 13:38:39 +0200 Subject: [git] gnupg-doc - branch, preview, updated. e72def2e66614c9fe90024556716b31809cc2fb2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, preview has been updated via e72def2e66614c9fe90024556716b31809cc2fb2 (commit) via 04d85f58fcbbaad00a7202d370c36f899d1c544e (commit) via 5c1e39ab92b3f8b0e331374d22bfaf2ecf7a194e (commit) via b05ad05ae599e642e6e1b13b39f1cfa59f8e376d (commit) via 0ef0b2c638fc1ca47c63c91734d1d75407012c4a (commit) via 03fabb28f25c8f1446ab40811d5c188f3b4c280f (commit) from 2393be191afba40884d51865cac08fb3a05b70d3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e72def2e66614c9fe90024556716b31809cc2fb2 Author: Ben McGinnes Date: Sun Mar 25 22:36:47 2018 +1100 testing: HTML header link elements * Testing to see if we can knock something small, but useful off the wishlist. ;) diff --git a/web/index.org b/web/index.org index db0271e..6cb1d1f 100644 --- a/web/index.org +++ b/web/index.org @@ -2,6 +2,7 @@ #+STARTUP: showall #+SETUPFILE: "share/setup.inc" #+GPGWEB-NEED-SWDB +#+HTML_HEAD_EXTRA: * The GNU Privacy Guard #+index: GnuPG commit 04d85f58fcbbaad00a7202d370c36f899d1c544e Merge: 5c1e39a 2393be1 Author: Ben McGinnes Date: Sat Dec 30 05:49:54 2017 +1100 Merge branch 'preview' of ssh+git://playfair.gnupg.org/git/gnupg-doc into preview ----------------------------------------------------------------------- Summary of changes: web/download/index.org | 13 ++----------- web/faq/gnupg-faq.org | 22 +++++++++------------- web/faq/whats-new-in-2.1.org | 6 +++--- web/index.org | 9 +++++---- web/swdb.mac | 22 +++++++--------------- 5 files changed, 26 insertions(+), 46 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 26 17:03:55 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 26 Mar 2018 17:03:55 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-27-g456a3a8 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 456a3a8e93ea14f821e0e98fb515f284ece98685 (commit) via 5f00531463ebc0e606c502696962426007545bb7 (commit) from 137644c9cb58deaaba6850f2763d9c5f9241cb0b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 456a3a8e93ea14f821e0e98fb515f284ece98685 Author: Werner Koch Date: Mon Mar 26 16:57:04 2018 +0200 gpg: Fix trustdb updates without lock held. * g10/tdbio.c (is_locked): Turn into a counter. (take_write_lock, release_write_lock): Implement recursive locks. -- On trustdb creation we have this call sequence: init_trustdb -> takes lock tdbio_set_dbname create_version_record tdbio_write_record put_record_into_cache -> takes lock put_record_into_cache -> releases lock init_trustdb -> releases lock The second take lock does noting but the first release lock has already released the lock and the second release lock is a thus a NOP. This is likely the cause for the corrupted trustdb as reported in GnuPG-bug-id: 3839 Signed-off-by: Werner Koch diff --git a/g10/tdbio.c b/g10/tdbio.c index fb3cf15..4940c5c 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -105,10 +105,11 @@ struct cmp_xdir_struct /* The name of the trustdb file. */ static char *db_name; -/* The handle for locking the trustdb file and a flag to record - whether a lock has been taken. */ +/* The handle for locking the trustdb file and a counter to record how + * often this lock has been taken. That counter is required becuase + * dotlock does not implemen recursive locks. */ static dotlock_t lockhandle; -static int is_locked; +static unsigned int is_locked; /* The file descriptor of the trustdb. */ static int db_fd = -1; @@ -135,6 +136,8 @@ static void create_hashtable (ctrl_t ctrl, TRUSTREC *vr, int type); static int take_write_lock (void) { + int rc; + if (!lockhandle) lockhandle = dotlock_create (db_name, 0); if (!lockhandle) @@ -144,12 +147,16 @@ take_write_lock (void) { if (dotlock_take (lockhandle, -1) ) log_fatal ( _("can't lock '%s'\n"), db_name ); - else - is_locked = 1; - return 0; + rc = 0; } else - return 1; + rc = 1; + + if (opt.lock_once) + is_locked = 1; + else + is_locked++; + return rc; } @@ -160,10 +167,22 @@ take_write_lock (void) static void release_write_lock (void) { - if (!opt.lock_once) - if (!dotlock_release (lockhandle)) - is_locked = 0; + if (opt.lock_once) + return; /* Don't care; here IS_LOCKED is fixed to 1. */ + + if (!is_locked) + { + log_error ("Ooops, tdbio:release_write_lock with no lock held\n"); + return; + } + if (--is_locked) + return; + + if (dotlock_release (lockhandle)) + log_error ("Oops, tdbio:release_write_locked failed\n"); } + + /************************************* ************* record cache ********** commit 5f00531463ebc0e606c502696962426007545bb7 Author: Werner Koch Date: Mon Mar 26 16:26:46 2018 +0200 gpg: Disable unused code parts in tdbio.c * g10/tdbio.c (in_transaction): Comment this var. (put_record_into_cache): Comment the transaction code. (tdbio_sync): Ditto Signed-off-by: Werner Koch diff --git a/g10/tdbio.c b/g10/tdbio.c index 7572b9a..fb3cf15 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -114,7 +114,7 @@ static int is_locked; static int db_fd = -1; /* A flag indicating that a transaction is active. */ -static int in_transaction; +/* static int in_transaction; Not yet used. */ @@ -125,7 +125,7 @@ static void create_hashtable (ctrl_t ctrl, TRUSTREC *vr, int type); /* * Take a lock on the trustdb file name. I a lock file can't be - * created the function terminates the process. Excvept for a + * created the function terminates the process. Except for a * different return code the function does nothing if the lock has * already been taken. * @@ -329,6 +329,7 @@ put_record_into_cache (ulong recno, const char *data) } /* No clean entries: We have to flush some dirty entries. */ +#if 0 /* Transactions are not yet used. */ if (in_transaction) { /* But we can't do this while in a transaction. Thus we @@ -352,6 +353,7 @@ put_record_into_cache (ulong recno, const char *data) log_info (_("trustdb transaction too large\n")); return GPG_ERR_RESOURCE_LIMIT; } +#endif if (dirty_count) { @@ -418,8 +420,10 @@ tdbio_sync() if( db_fd == -1 ) open_db(); +#if 0 /* Transactions are not yet used. */ if( in_transaction ) log_bug("tdbio: syncing while in transaction\n"); +#endif if( !cache_is_dirty ) return 0; @@ -560,7 +564,7 @@ tdbio_update_version_record (ctrl_t ctrl) /* * Create and write the trustdb version record. - * + * This is called with the writelock activ. * Returns: 0 on success or an error code. */ static int ----------------------------------------------------------------------- Summary of changes: g10/tdbio.c | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 26 17:42:46 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 26 Mar 2018 17:42:46 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-111-g97ee667 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 97ee667a0c24649233554cd6df9572cb2406bf91 (commit) via 2f05d4ed802a62c0cc0d8f4632ff5cfe4b4c6ea1 (commit) via 4c5eed30882963283caa1b82626d8ccd6a682490 (commit) via e67c03636889a1ef81de3601788f25dcf4d39370 (commit) via 9d10ff22928a089347d4ad1393aea08366917659 (commit) via e62b003f83bc41375edd421d0ee0046f129accfe (commit) via 71334bacf78074889138d9328a18a205e8fd86cd (commit) via b2727a00c02520ca603f5c1dad0d181348f2c63f (commit) via a683aac7f165e2fb97006e634afd53639bf57fef (commit) via 52c80aec174d6c0329e0dce0acf72e282e3b6c9a (commit) via a80c7502c45b2fc516b9b31e90dc3b858527850a (commit) from 88e76e1675dc10ab88d5541f716ea54e00d61b40 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 97ee667a0c24649233554cd6df9572cb2406bf91 Author: Andre Heinecke Date: Mon Mar 26 17:41:39 2018 +0200 s/is_inline_response/async_crypt_disabled/ -- This should make it more clear and avoid a PGP/Inline <> Inline Editor misunderstanding. diff --git a/src/mail.cpp b/src/mail.cpp index 4acc4e8..9d96bb6 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -92,7 +92,7 @@ Mail::Mail (LPDISPATCH mailitem) : m_is_gsuite(false), m_crypt_state(NoCryptMail), m_window(nullptr), - m_is_inline_response(false), + m_async_crypt_disabled(false), m_is_forwarded_crypto_mail(false) { if (get_mail_for_item (mailitem)) @@ -704,7 +704,7 @@ do_parsing (LPVOID arg) /* How encryption is done: There are two modes of encryption. Synchronous and Async. - If async is used depends on the value of mail->is_inline_response. + If async is used depends on the value of mail->async_crypt_disabled. Synchronous crypto: @@ -841,7 +841,7 @@ do_crypt (LPVOID arg) return rc; } - if (!mail->is_inline_response ()) + if (!mail->async_crypt_disabled ()) { mail->set_crypt_state (Mail::NeedsUpdateInOOM); gpgrt_lock_unlock (&dtor_lock); @@ -1230,7 +1230,7 @@ Mail::encrypt_sign_start () return -1; } - if (!m_is_inline_response) + if (!m_async_crypt_disabled) { CloseHandle(CreateThread (NULL, 0, do_crypt, (LPVOID) this, 0, @@ -2537,7 +2537,7 @@ Mail::update_crypt_mapi() } /** If sync we need the crypter in update_crypt_oom */ - if (!is_inline_response ()) + if (!async_crypt_disabled ()) { // We don't need the crypter anymore. reset_crypter (); @@ -2594,7 +2594,7 @@ Mail::update_crypt_oom() } /** When doing async update_crypt_mapi follows and needs the crypter. */ - if (is_inline_response ()) + if (async_crypt_disabled ()) { reset_crypter (); } @@ -2650,7 +2650,7 @@ Mail::check_inline_response () * For now we treat every mail as an inline response to disable async * encryption. :-( For more details see: T3838 */ #ifdef DO_ASYNC_CRYPTO - m_is_inline_response = false; + m_async_crypt_disabled = false; LPDISPATCH app = GpgolAddin::get_instance ()->get_application (); if (!app) { @@ -2686,14 +2686,14 @@ Mail::check_inline_response () { log_debug ("%s:%s: Detected inline response for '%p'", SRCNAME, __func__, this); - m_is_inline_response = true; + m_async_crypt_disabled = true; } xfree (inlineSubject); #else - m_is_inline_response = true; + m_async_crypt_disabled = true; #endif - return m_is_inline_response; + return m_async_crypt_disabled; } // static diff --git a/src/mail.h b/src/mail.h index 37b9efd..d267d8b 100644 --- a/src/mail.h +++ b/src/mail.h @@ -424,13 +424,13 @@ public: from the OOM. We need synchronous encryption for inline responses. */ - bool is_inline_response () { return m_is_inline_response; } + bool async_crypt_disabled () { return m_async_crypt_disabled; } /** Check through OOM if the current mail is an inline response. Caches the state which can then be queried through - is_inline_response + async_crypt_disabled */ bool check_inline_response (); @@ -510,7 +510,7 @@ private: std::string m_inline_body; CryptState m_crypt_state; HWND m_window; - bool m_is_inline_response; + bool m_async_crypt_disabled; std::string m_mime_data; bool m_is_forwarded_crypto_mail; /* Is this a forward of a crypto mail */ }; diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 9ebe696..2a96166 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -365,7 +365,7 @@ EVENT_SINK_INVOKE(MailItemEvents) // Save the Mail invoke_oom_method (m_object, "Save", NULL); - if (!m_mail->is_inline_response ()) + if (!m_mail->async_crypt_disabled ()) { // The afterwrite in the save should have triggered // the encryption. We cancel send for our asyncness. commit 2f05d4ed802a62c0cc0d8f4632ff5cfe4b4c6ea1 Author: Andre Heinecke Date: Mon Mar 26 17:39:51 2018 +0200 s/should_inline_crypt/do_pgp_inline/ -- Make it more clear. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index 3e343e0..34b3af3 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -68,7 +68,7 @@ CryptController::CryptController (Mail *mail, bool encrypt, bool sign, m_proto (proto) { log_debug ("%s:%s: CryptController ctor for %p encrypt %i sign %i inline %i.", - SRCNAME, __func__, mail, encrypt, sign, mail->should_inline_crypt ()); + SRCNAME, __func__, mail, encrypt, sign, mail->do_pgp_inline ()); m_recipient_addrs = mail->take_cached_recipients (); } @@ -119,7 +119,7 @@ CryptController::collect_data () return -1; } - bool do_inline = m_mail->should_inline_crypt (); + bool do_inline = m_mail->do_pgp_inline (); if (n_att_usable && do_inline) { @@ -127,7 +127,7 @@ CryptController::collect_data () " Using PGP MIME", SRCNAME, __func__); do_inline = false; - m_mail->set_should_inline_crypt (false); + m_mail->set_do_pgp_inline (false); } else if (do_inline) { @@ -528,14 +528,14 @@ CryptController::do_crypto () // Cancel return -2; } - bool do_inline = m_mail->should_inline_crypt (); + bool do_inline = m_mail->do_pgp_inline (); if (m_proto == GpgME::CMS && do_inline) { log_debug ("%s:%s: Inline for S/MIME not supported. Switching to mime.", SRCNAME, __func__); do_inline = false; - m_mail->set_should_inline_crypt (false); + m_mail->set_do_pgp_inline (false); m_bodyInput = GpgME::Data(GpgME::Data::null); } @@ -864,7 +864,7 @@ CryptController::update_mail_mapi () { log_debug ("%s:%s", SRCNAME, __func__); - if (m_mail->should_inline_crypt ()) + if (m_mail->do_pgp_inline ()) { // Nothing to do for inline. log_debug ("%s:%s: Inline mail. No MAPI update.", @@ -952,7 +952,7 @@ std::string CryptController::get_inline_data () { std::string ret; - if (!m_mail->should_inline_crypt ()) + if (!m_mail->do_pgp_inline ()) { return ret; } diff --git a/src/mail.cpp b/src/mail.cpp index 9dda977..4acc4e8 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -2581,7 +2581,7 @@ Mail::update_crypt_oom() return; } - if (should_inline_crypt ()) + if (do_pgp_inline ()) { if (inline_body_to_body ()) { diff --git a/src/mail.h b/src/mail.h index e295188..37b9efd 100644 --- a/src/mail.h +++ b/src/mail.h @@ -383,10 +383,10 @@ public: int check_attachments () const; /** Check if the mail should be encrypted "inline" */ - bool should_inline_crypt () const {return m_do_inline;} + bool do_pgp_inline () const {return m_do_inline;} /** Check if the mail should be encrypted "inline" */ - void set_should_inline_crypt (bool value) {m_do_inline = value;} + void set_do_pgp_inline (bool value) {m_do_inline = value;} /** Append data to a cached inline body. Helper to do this on MAPI level and later add it through OOM */ diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 55a4ebe..9ebe696 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -385,7 +385,7 @@ EVENT_SINK_INVOKE(MailItemEvents) { m_mail->set_crypt_state (Mail::WantsSendMIME); } - if (m_mail->should_inline_crypt () && m_mail->crypt_state () != Mail::WantsSendInline) + if (m_mail->do_pgp_inline () && m_mail->crypt_state () != Mail::WantsSendInline) { log_debug ("%s:%s: Message %p mail %p cancelling send - " "Invalid state.", diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index 449a74e..2108230 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -1972,7 +1972,7 @@ mime_encrypt (LPMESSAGE message, HWND hwnd, int n_att_usable; engine_filter_t filter = NULL; char *my_sender = NULL; - bool is_inline = mail && mail->should_inline_crypt (); + bool is_inline = mail && mail->do_pgp_inline (); memset (sink, 0, sizeof *sink); memset (encsink, 0, sizeof *encsink); commit 4c5eed30882963283caa1b82626d8ccd6a682490 Author: Andre Heinecke Date: Mon Mar 26 17:35:16 2018 +0200 Fix sending PGP/Inline synchronously * src/common.h: Add error code. * src/mail.cpp (Mail::update_crypt_mapi): Don't reset crypter if in sync mode. (Mail::update_crypt_oom): Reset crypter in sync mode. * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Check that states for inline mail are as expected or bug out. -- For synchonous inline encrypted the cryptcontroller was deleted too early. This caused body_to_body to fail and ultimately lead to an unencrypted mail. This fixes: GnuPG-Bug-Id: T3863 diff --git a/src/common.h b/src/common.h index e9cdb2a..bd55a13 100644 --- a/src/common.h +++ b/src/common.h @@ -158,6 +158,7 @@ void gpgol_bug (HWND parent, int code); #define ERR_WANTS_SEND_MIME_BODY 2 #define ERR_WANTS_SEND_INLINE_BODY 3 #define ERR_INLINE_BODY_TO_BODY 4 +#define ERR_INLINE_BODY_INV_STATE 5 #ifdef __cplusplus } #endif diff --git a/src/mail.cpp b/src/mail.cpp index dc11082..9dda977 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -2535,8 +2535,13 @@ Mail::update_crypt_mapi() { m_crypt_state = WantsSendMIME; } - // We don't need the crypter anymore. - reset_crypter (); + + /** If sync we need the crypter in update_crypt_oom */ + if (!is_inline_response ()) + { + // We don't need the crypter anymore. + reset_crypter (); + } } /** Checks in OOM if the body is either @@ -2572,6 +2577,7 @@ Mail::update_crypt_oom() { log_debug ("%s:%s: invalid state %i", SRCNAME, __func__, m_crypt_state); + reset_crypter (); return; } @@ -2586,6 +2592,12 @@ Mail::update_crypt_oom() return; } } + /** When doing async update_crypt_mapi follows and needs + the crypter. */ + if (is_inline_response ()) + { + reset_crypter (); + } const auto pair = has_crypt_or_empty_body_oom (this); if (pair.first) diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 611c6ec..55a4ebe 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -385,6 +385,16 @@ EVENT_SINK_INVOKE(MailItemEvents) { m_mail->set_crypt_state (Mail::WantsSendMIME); } + if (m_mail->should_inline_crypt () && m_mail->crypt_state () != Mail::WantsSendInline) + { + log_debug ("%s:%s: Message %p mail %p cancelling send - " + "Invalid state.", + SRCNAME, __func__, m_object, m_mail); + gpgol_bug (m_mail->get_window (), + ERR_INLINE_BODY_INV_STATE); + *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; + break; + } } } commit e67c03636889a1ef81de3601788f25dcf4d39370 Author: Andre Heinecke Date: Mon Mar 26 17:16:40 2018 +0200 Add bug error if body_to_body failed * src/mail.cpp (Mail::update_crypt_oom): Check for and handle error in inline_body_to_body. -- GnuPG-Bug-Id: T3863 diff --git a/src/common.h b/src/common.h index 7f13d04..e9cdb2a 100644 --- a/src/common.h +++ b/src/common.h @@ -157,6 +157,7 @@ void gpgol_bug (HWND parent, int code); #define ERR_CRYPT_RESOLVER_FAILED 1 #define ERR_WANTS_SEND_MIME_BODY 2 #define ERR_WANTS_SEND_INLINE_BODY 3 +#define ERR_INLINE_BODY_TO_BODY 4 #ifdef __cplusplus } #endif diff --git a/src/mail.cpp b/src/mail.cpp index 4431eab..dc11082 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -2579,8 +2579,11 @@ Mail::update_crypt_oom() { if (inline_body_to_body ()) { - log_debug ("%s:%s: Inline body to body failed %p.", + log_error ("%s:%s: Inline body to body failed %p.", SRCNAME, __func__, this); + gpgol_bug (get_active_hwnd(), ERR_INLINE_BODY_TO_BODY); + m_crypt_state = NoCryptMail; + return; } } commit 9d10ff22928a089347d4ad1393aea08366917659 Author: Andre Heinecke Date: Mon Mar 26 16:57:20 2018 +0200 Add safety check to prevent unencrypted send * src/mail.cpp (Mail::has_crypted_or_empty_body): New. (Mail::update_crypt_oom): Use it. (has_crypt_or_empty_body_oom): New helper. * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Check if body is empty or a crypt message before passing send on a crypto mail. -- GnuPG-Bug-Id: T3863 The idea is to check as a last ditch if before sending a mail that "should" be encrypted if it has either an empty body or a PGP/Inline body. This won't help of course for empty mails with attachments but should work in most cases. The codepath is never hit intentional so the error message points to a bug. It's just an additional saveguard. diff --git a/src/mail.cpp b/src/mail.cpp index 3855300..4431eab 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -2539,6 +2539,30 @@ Mail::update_crypt_mapi() reset_crypter (); } +/** Checks in OOM if the body is either + empty or contains the -----BEGIN tag. + pair.first -> true if body starts with -----BEGIN + pair.second -> true if body is empty. */ +static std::pair +has_crypt_or_empty_body_oom (Mail *mail) +{ + auto body = mail->get_body(); + std::pair ret; + ret.first = false; + ret.second = false; + ltrim (body); + if (body.size() > 10 && !strncmp (body.c_str(), "-----BEGIN", 10)) + { + ret.first = true; + return ret; + } + if (!body.size()) + { + ret.second = true; + } + return ret; +} + void Mail::update_crypt_oom() { @@ -2559,8 +2583,9 @@ Mail::update_crypt_oom() SRCNAME, __func__, this); } } - const auto body = get_body(); - if (body.size() > 10 && !strncmp (body.c_str(), "-----BEGIN", 10)) + + const auto pair = has_crypt_or_empty_body_oom (this); + if (pair.first) { log_debug ("%s:%s: Looks like inline body. You can pass %p.", SRCNAME, __func__, this); @@ -2752,3 +2777,64 @@ Mail::remove_our_attachments () } return ret; } + +/* We are very verbose because if we fail it might mean + that we have leaked plaintext -> critical. */ +bool +Mail::has_crypted_or_empty_body () +{ + const auto pair = has_crypt_or_empty_body_oom (this); + + if (pair.first /* encrypted marker */) + { + log_debug ("%s:%s: Crypt Marker detected in OOM body. Return true %p.", + SRCNAME, __func__, this); + return true; + } + + if (!pair.second) + { + log_debug ("%s:%s: Unexpected content detected. Return false %p.", + SRCNAME, __func__, this); + return false; + } + + // Pair second == true (is empty) can happen on OOM error. + LPMESSAGE message = get_oom_base_message (m_mailitem); + if (!message && pair.second) + { + if (message) + { + gpgol_release (message); + } + return true; + } + + size_t r_nbytes = 0; + char *mapi_body = mapi_get_body (message, &r_nbytes); + gpgol_release (message); + + if (!mapi_body || !r_nbytes) + { + // Body or bytes are null. we are empty. + xfree (mapi_body); + log_debug ("%s:%s: MAPI error or empty message. Return true. %p.", + SRCNAME, __func__, this); + return true; + } + if (r_nbytes > 10 && !strncmp (mapi_body, "-----BEGIN", 10)) + { + // Body is crypt. + log_debug ("%s:%s: MAPI Crypt marker detected. Return true. %p.", + SRCNAME, __func__, this); + xfree (mapi_body); + return true; + } + + xfree (mapi_body); + + log_debug ("%s:%s: Found mapi body. Return false. %p.", + SRCNAME, __func__, this); + + return false; +} diff --git a/src/mail.h b/src/mail.h index 51604d0..e295188 100644 --- a/src/mail.h +++ b/src/mail.h @@ -460,6 +460,18 @@ public: Returns 0 on success. Works in OOM. */ int remove_our_attachments (); + /** Check both OOM and MAPI if the body is either empty or + encrypted. Won't abort on OOM or MAPI errors, so it can be + used in both states. But will return false if a body + was detected or in the OOM the MAPI Base Message. This + is intended as a saveguard before sending a mail. + + This function should not be used to detected the necessity + of encryption and is only an extra check to catch unexpected + errors. + */ + bool has_crypted_or_empty_body (); + void update_body (); private: void update_categories (); diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 2dbde79..611c6ec 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -390,6 +390,17 @@ EVENT_SINK_INVOKE(MailItemEvents) if (m_mail->crypt_state () == Mail::WantsSendInline) { + if (!m_mail->has_crypted_or_empty_body()) + { + log_debug ("%s:%s: Message %p mail %p cancelling send - " + "not encrypted or not empty body detected.", + SRCNAME, __func__, m_object, m_mail); + gpgol_bug (m_mail->get_window (), + ERR_WANTS_SEND_INLINE_BODY); + m_mail->set_crypt_state (Mail::NoCryptMail); + *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; + break; + } log_debug ("%s:%s: Passing send event for no-mime message %p.", SRCNAME, __func__, m_object); break; @@ -397,6 +408,17 @@ EVENT_SINK_INVOKE(MailItemEvents) if (m_mail->crypt_state () == Mail::WantsSendMIME) { + if (!m_mail->has_crypted_or_empty_body()) + { + gpgol_bug (m_mail->get_window (), + ERR_WANTS_SEND_MIME_BODY); + log_debug ("%s:%s: Message %p mail %p cancelling send mime - " + "not encrypted or not empty body detected.", + SRCNAME, __func__, m_object, m_mail); + m_mail->set_crypt_state (Mail::NoCryptMail); + *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; + break; + } /* Now we adress T3656 if Outlooks internal S/MIME is somehow * mixed in (even if it is enabled and then disabled) it might * cause strange behavior in that it sends the plain message commit e62b003f83bc41375edd421d0ee0046f129accfe Author: Andre Heinecke Date: Mon Mar 26 16:56:28 2018 +0200 Check for error on encrypt_sign_start * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Check error of encrypt_sign_start. diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 273c842..2dbde79 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -577,7 +577,12 @@ EVENT_SINK_INVOKE(MailItemEvents) { /* Seen the first after write. Advance the state */ m_mail->set_crypt_state (Mail::NeedsActualCrypt); - m_mail->encrypt_sign_start (); + if (m_mail->encrypt_sign_start ()) + { + log_debug ("%s:%s: Encrypt sign start failes.", + SRCNAME, __func__); + m_mail->set_crypt_state (Mail::NoCryptMail); + } return S_OK; } if (m_mail->crypt_state () == Mail::NeedsSecondAfterWrite) commit 71334bacf78074889138d9328a18a205e8fd86cd Author: Andre Heinecke Date: Mon Mar 26 16:55:35 2018 +0200 Handle encrypt / sign on empty message * src/cryptcontroller.cpp (CryptController::collect_data): Handle empty message. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index da2454f..3e343e0 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -111,7 +111,9 @@ CryptController::collect_data () int n_att_usable = count_usable_attachments (att_table); if (!n_att_usable && !body) { - log_error ("%s:%s: encrypt empty message", SRCNAME, __func__); + gpgol_message_box (m_mail->get_window(), + utf8_gettext ("Can't encrypt / sign an empty message."), + utf8_gettext ("GpgOL"), MB_OK); gpgol_release (message); xfree (body); return -1; commit b2727a00c02520ca603f5c1dad0d181348f2c63f Author: Andre Heinecke Date: Mon Mar 26 16:41:00 2018 +0200 Abort if mail has no body and no attachments * src/cryptcontroller.cpp (CryptController::collect_data): Abort if no body and no attachments. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index d26501d..da2454f 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -97,7 +97,7 @@ CryptController::collect_data () if (body && !*body) { xfree (body); - body = NULL; + body = nullptr; } LPMESSAGE message = get_oom_base_message (m_mail->item ()); @@ -111,7 +111,10 @@ CryptController::collect_data () int n_att_usable = count_usable_attachments (att_table); if (!n_att_usable && !body) { - log_debug ("%s:%s: encrypt empty message", SRCNAME, __func__); + log_error ("%s:%s: encrypt empty message", SRCNAME, __func__); + gpgol_release (message); + xfree (body); + return -1; } bool do_inline = m_mail->should_inline_crypt (); commit a683aac7f165e2fb97006e634afd53639bf57fef Author: Andre Heinecke Date: Mon Mar 26 16:13:36 2018 +0200 Add gpgol_bug helper function * src/common.c, src/common.h (gpgol_bug): New. * src/mail.cpp (do_crypt): Use it. -- This is a little helper to reuse the same message if we think a user visible error / bug should be done. diff --git a/src/common.c b/src/common.c index adda352..6f1ac56 100644 --- a/src/common.c +++ b/src/common.c @@ -1058,6 +1058,22 @@ gpgol_message_box (HWND parent, const char *utf8_text, return ret; } +void +gpgol_bug (HWND parent, int code) +{ + const char *bugmsg = utf8_gettext ("Operation failed.\n\n" + "This is usually caused by a bug in GpgOL or an error in your setup.\n" + "Please see https://www.gpg4win.org/reporting-bugs.html " + "or ask your Administrator for support."); + char *with_code; + gpgrt_asprintf (&with_code, "%s\nCode: %i", bugmsg, code); + gpgol_message_box (parent, + with_code, + _("GpgOL Error"), MB_OK); + xfree (with_code); + return; +} + static char* expand_path (const char *path) { diff --git a/src/common.h b/src/common.h index c8e32df..7f13d04 100644 --- a/src/common.h +++ b/src/common.h @@ -150,6 +150,13 @@ void bring_to_front (HWND wid); int gpgol_message_box (HWND parent, const char *utf8_text, const char *utf8_caption, UINT type); + +/* Show a bug message with the code. */ +void gpgol_bug (HWND parent, int code); + +#define ERR_CRYPT_RESOLVER_FAILED 1 +#define ERR_WANTS_SEND_MIME_BODY 2 +#define ERR_WANTS_SEND_INLINE_BODY 3 #ifdef __cplusplus } #endif diff --git a/src/mail.cpp b/src/mail.cpp index 0cd9259..3855300 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -824,12 +824,8 @@ do_crypt (LPVOID arg) { mail->reset_crypter (); crypter = nullptr; - gpgol_message_box (mail->get_window (), - utf8_gettext ("Sign / Encrypt failed.\n\n" - "This is usually caused by an error in your system.\n" - "Please refer to the Gpg4win compendium how to enable debugging in GpgOL," - "or ask your Administrator for support."), - _("GpgOL"), MB_OK); + gpgol_bug (mail->get_window (), + ERR_CRYPT_RESOLVER_FAILED); } mail->set_window_enabled (true); commit 52c80aec174d6c0329e0dce0acf72e282e3b6c9a Author: Andre Heinecke Date: Mon Mar 26 16:12:40 2018 +0200 Document how encryption is done in do_crypt * src/mail.cpp (do_crypt): Add explaining comment about the states. diff --git a/src/mail.cpp b/src/mail.cpp index 6e0a8c8..0cd9259 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -701,6 +701,77 @@ do_parsing (LPVOID arg) return 0; } +/* How encryption is done: + + There are two modes of encryption. Synchronous and Async. + If async is used depends on the value of mail->is_inline_response. + + Synchronous crypto: + + > Send Event < | State NoCryptMail + Needs Crypto ? (get_gpgol_draft_info_flags != 0) + + -> No: + Pass send -> unencrypted mail. + + -> Yes: + mail->update_oom_data + State = Mail::NeedsFirstAfterWrite + check_inline_response + invoke_oom_method (m_object, "Save", NULL); + + > Write Event < + Pass because is_crypto_mail is false (not a decrypted mail) + + > AfterWrite Event < | State NeedsFirstAfterWrite + State = NeedsActualCrypo + encrypt_sign_start + collect_input_data + -> Check if Inline PGP should be used + do_crypt + -> Resolve keys / do crypto + + State = NeedsUpdateInMAPI + update_crypt_mapi + crypter->update_mail_mapi + if (inline) (Meaning PGP/Inline) + <-- do nothing. + else + build MSOXSMIME attachment and clear body / attachments. + + State = NeedsUpdateInOOM + <- Back to Send Event + update_crypt_oom + -> Cleans body or sets PGP/Inline body. (inline_body_to_body) + State = WantsSendMIME or WantsSendInline + + -> Saftey check "has_crypted_or_empty_body" + -> If MIME Mail do the T3656 check. + + Send. + + State order for "inline_response" (sync) Mails. + NoCryptMail + NeedsFirstAfterWrite + NeedsActualCrypto + NeedsUpdateInMAPI + NeedsUpdateInOOM + WantsSendMIME (or inline for PGP Inline) + -> Send. + + State order for async Mails + NoCryptMail + NeedsFirstAfterWrite + NeedsActualCrypto + -> Cancel Send. + Windowmessages -> Crypto Done + NeedsUpdateInOOM + NeedsSecondAfterWrite + trigger Save. + NeedsUpdateInMAPI + WantsSendMIME + trigger Send. +*/ static DWORD WINAPI do_crypt (LPVOID arg) { @@ -724,7 +795,7 @@ do_crypt (LPVOID arg) return -1; } - /* This takes a shared ptr of parser. So the parser is + /* This takes a shared ptr of crypter. So the crypter is still valid when the mail is deleted. */ auto crypter = mail->crypter(); gpgrt_lock_unlock (&dtor_lock); commit a80c7502c45b2fc516b9b31e90dc3b858527850a Author: Andre Heinecke Date: Mon Mar 26 08:47:57 2018 +0200 Don't carry around inline crypt state twice * src/cryptcontroller.cpp, src/cryptcontroller.h: Replace m_inline member variable with access to Mail::should_inline_crypt. * src/mail.h: Add set_should_inline_crypt. * src/mail.cpp: Update callers. -- Having two inline states adds complexity and might lead to wrong results. E.g. Mail::should_inline_crypt would not change when the cryptcontroller detected attachments. GnuPG-Bug-Id: T3863 diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index dc07146..d26501d 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -60,16 +60,15 @@ create_sign_attach (sink_t sink, protocol_t protocol, from this. */ CryptController::CryptController (Mail *mail, bool encrypt, bool sign, - bool doInline, GpgME::Protocol proto): + GpgME::Protocol proto): m_mail (mail), m_encrypt (encrypt), m_sign (sign), - m_inline (doInline), m_crypto_success (false), m_proto (proto) { log_debug ("%s:%s: CryptController ctor for %p encrypt %i sign %i inline %i.", - SRCNAME, __func__, mail, encrypt, sign, doInline); + SRCNAME, __func__, mail, encrypt, sign, mail->should_inline_crypt ()); m_recipient_addrs = mail->take_cached_recipients (); } @@ -115,14 +114,17 @@ CryptController::collect_data () log_debug ("%s:%s: encrypt empty message", SRCNAME, __func__); } - if (n_att_usable && m_inline) + bool do_inline = m_mail->should_inline_crypt (); + + if (n_att_usable && do_inline) { log_debug ("%s:%s: PGP Inline not supported for attachments." " Using PGP MIME", SRCNAME, __func__); - m_inline = false; + do_inline = false; + m_mail->set_should_inline_crypt (false); } - else if (m_inline) + else if (do_inline) { /* Inline. Use Body as input. We need to collect also our mime structure for S/MIME @@ -521,12 +523,14 @@ CryptController::do_crypto () // Cancel return -2; } + bool do_inline = m_mail->should_inline_crypt (); - if (m_proto == GpgME::CMS && m_inline) + if (m_proto == GpgME::CMS && do_inline) { log_debug ("%s:%s: Inline for S/MIME not supported. Switching to mime.", SRCNAME, __func__); - m_inline = false; + do_inline = false; + m_mail->set_should_inline_crypt (false); m_bodyInput = GpgME::Data(GpgME::Data::null); } @@ -549,11 +553,11 @@ CryptController::do_crypto () ctx->setTextMode (m_proto == GpgME::OpenPGP); ctx->setArmor (m_proto == GpgME::OpenPGP); - if (m_encrypt && m_sign && m_inline) + if (m_encrypt && m_sign && do_inline) { // Sign encrypt combined const auto result_pair = ctx->signAndEncrypt (m_recipients, - m_inline ? m_bodyInput : m_input, + do_inline ? m_bodyInput : m_input, m_output, GpgME::Context::AlwaysTrust); @@ -634,7 +638,7 @@ CryptController::do_crypto () } else if (m_encrypt) { - const auto result = ctx->encrypt (m_recipients, m_inline ? m_bodyInput : m_input, + const auto result = ctx->encrypt (m_recipients, do_inline ? m_bodyInput : m_input, m_output, GpgME::Context::AlwaysTrust); if (result.error()) @@ -652,8 +656,8 @@ CryptController::do_crypto () } else if (m_sign) { - const auto result = ctx->sign (m_inline ? m_bodyInput : m_input, m_output, - m_inline ? GpgME::Clearsigned : + const auto result = ctx->sign (do_inline ? m_bodyInput : m_input, m_output, + do_inline ? GpgME::Clearsigned : GpgME::Detached); if (result.error()) { @@ -855,7 +859,7 @@ CryptController::update_mail_mapi () { log_debug ("%s:%s", SRCNAME, __func__); - if (m_inline) + if (m_mail->should_inline_crypt ()) { // Nothing to do for inline. log_debug ("%s:%s: Inline mail. No MAPI update.", @@ -943,7 +947,7 @@ std::string CryptController::get_inline_data () { std::string ret; - if (!m_inline) + if (!m_mail->should_inline_crypt ()) { return ret; } diff --git a/src/cryptcontroller.h b/src/cryptcontroller.h index 9398c5b..67b67c4 100644 --- a/src/cryptcontroller.h +++ b/src/cryptcontroller.h @@ -40,7 +40,7 @@ class CryptController public: /** @brief Construct a Crypthelper for a Mail object. */ CryptController (Mail *mail, bool encrypt, bool sign, - bool inlineCrypt, GpgME::Protocol proto); + GpgME::Protocol proto); ~CryptController (); /** @brief Collect the data from the mail into the internal @@ -79,7 +79,7 @@ private: Mail *m_mail; GpgME::Data m_input, m_bodyInput, m_signedData, m_output; std::string m_micalg; - bool m_encrypt, m_sign, m_inline, m_crypto_success; + bool m_encrypt, m_sign, m_crypto_success; GpgME::Protocol m_proto; GpgME::Key m_signer_key; std::vector m_recipients; diff --git a/src/mail.cpp b/src/mail.cpp index 7e8360f..6e0a8c8 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1150,7 +1150,7 @@ Mail::encrypt_sign_start () GpgME::Protocol proto = opt.enable_smime ? GpgME::UnknownProtocol: GpgME::OpenPGP; m_crypter = std::shared_ptr (new CryptController (this, flags & 1, flags & 2, - m_do_inline, proto)); + proto)); // Careful from here on we have to check every // error condition with window enabling again. @@ -2447,7 +2447,7 @@ Mail::update_crypt_mapi() SRCNAME, __func__); m_crypter = std::shared_ptr (new CryptController (this, false, false, - false, GpgME::UnknownProtocol)); + GpgME::UnknownProtocol)); } else { diff --git a/src/mail.h b/src/mail.h index 7410f61..51604d0 100644 --- a/src/mail.h +++ b/src/mail.h @@ -385,6 +385,9 @@ public: /** Check if the mail should be encrypted "inline" */ bool should_inline_crypt () const {return m_do_inline;} + /** Check if the mail should be encrypted "inline" */ + void set_should_inline_crypt (bool value) {m_do_inline = value;} + /** Append data to a cached inline body. Helper to do this on MAPI level and later add it through OOM */ void append_to_inline_body (const std::string &data); ----------------------------------------------------------------------- Summary of changes: src/common.c | 16 ++++ src/common.h | 9 ++ src/cryptcontroller.cpp | 43 ++++++---- src/cryptcontroller.h | 4 +- src/mail.cpp | 212 +++++++++++++++++++++++++++++++++++++++++++----- src/mail.h | 23 +++++- src/mailitem-events.cpp | 41 +++++++++- src/mimemaker.cpp | 2 +- 8 files changed, 302 insertions(+), 48 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 26 18:28:35 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 26 Mar 2018 18:28:35 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-30-geb68c2d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via eb68c2d3d1b03a18cd24406fa46d4c30cb13d9f7 (commit) via a750ebebf35a392f1c72d6aee5618df0d9f25ff7 (commit) via 403aa70c52e56614d65490dea9344113f9cf3d29 (commit) from 456a3a8e93ea14f821e0e98fb515f284ece98685 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit eb68c2d3d1b03a18cd24406fa46d4c30cb13d9f7 Author: Werner Koch Date: Mon Mar 26 18:20:16 2018 +0200 gpg: Auto-fix a broken trustdb with just the version record. * g10/tdbio.c (get_trusthashrec): Create hashtable on error. GnuPG-bug-id: 3839 Signed-off-by: Werner Koch diff --git a/g10/tdbio.c b/g10/tdbio.c index 1e45486..fed0cf5 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -990,6 +990,20 @@ get_trusthashrec (ctrl_t ctrl) log_fatal (_("%s: error reading version record: %s\n"), db_name, gpg_strerror (rc) ); + if (!vr.r.ver.trusthashtbl) + { + /* Oops: the trustdb is corrupt because the hashtable is + * always created along with the version record. However, + * if something went initially wrong it may happen that + * there is just the version record. We try to fix it here. + * If we can't do that we return 0 - this is the version + * record and thus the actual read will detect the mismatch + * and bail out. Note that create_hashtable updates VR. */ + take_write_lock (); + if (lseek (db_fd, 0, SEEK_END) == TRUST_RECORD_LEN) + create_hashtable (ctrl, &vr, 0); + release_write_lock (); + } trusthashtbl = vr.r.ver.trusthashtbl; } commit a750ebebf35a392f1c72d6aee5618df0d9f25ff7 Author: Werner Koch Date: Mon Mar 26 18:06:43 2018 +0200 gpg: Pass CTRL arg to get_trusthashrec. * g10/tdbio.c (get_trusthashrec): Add arg CTRL. (tdbio_search_trust_byfpr): Ditto. (tdbio_search_trust_bypk): Ditto. Signed-off-by: Werner Koch diff --git a/g10/tdbdump.c b/g10/tdbdump.c index 5ea903f..2c6f5c2 100644 --- a/g10/tdbdump.c +++ b/g10/tdbdump.c @@ -189,7 +189,7 @@ import_ownertrust (ctrl_t ctrl, const char *fname ) while (fprlen < 20) fpr[fprlen++] = 0; - rc = tdbio_search_trust_byfpr (fpr, &rec); + rc = tdbio_search_trust_byfpr (ctrl, fpr, &rec); if( !rc ) { /* found: update */ if (rec.r.trust.ownertrust != otrust) { diff --git a/g10/tdbio.c b/g10/tdbio.c index 7314143..1e45486 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -974,10 +974,12 @@ tdbio_write_nextcheck (ctrl_t ctrl, ulong stamp) * Return: record number */ static ulong -get_trusthashrec(void) +get_trusthashrec (ctrl_t ctrl) { static ulong trusthashtbl; /* Record number of the trust hashtable. */ + (void)ctrl; + if (!trusthashtbl) { TRUSTREC vr; @@ -1388,7 +1390,7 @@ lookup_hashtable (ulong table, const byte *key, size_t keylen, static int update_trusthashtbl (ctrl_t ctrl, TRUSTREC *tr) { - return upd_hashtable (ctrl, get_trusthashrec (), + return upd_hashtable (ctrl, get_trusthashrec (ctrl), tr->r.trust.fingerprint, 20, tr->recnum); } @@ -1730,7 +1732,7 @@ tdbio_delete_record (ctrl_t ctrl, ulong recnum) ; else if (rec.rectype == RECTYPE_TRUST) { - rc = drop_from_hashtable (ctrl, get_trusthashrec(), + rc = drop_from_hashtable (ctrl, get_trusthashrec (ctrl), rec.r.trust.fingerprint, 20, rec.recnum); } @@ -1852,12 +1854,12 @@ cmp_trec_fpr ( const void *fpr, const TRUSTREC *rec ) * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code. */ gpg_error_t -tdbio_search_trust_byfpr (const byte *fingerprint, TRUSTREC *rec) +tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fingerprint, TRUSTREC *rec) { int rc; /* Locate the trust record using the hash table */ - rc = lookup_hashtable (get_trusthashrec(), fingerprint, 20, + rc = lookup_hashtable (get_trusthashrec (ctrl), fingerprint, 20, cmp_trec_fpr, fingerprint, rec ); return rc; } @@ -1870,7 +1872,7 @@ tdbio_search_trust_byfpr (const byte *fingerprint, TRUSTREC *rec) * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code. */ gpg_error_t -tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec) +tdbio_search_trust_bypk (ctrl_t ctrl, PKT_public_key *pk, TRUSTREC *rec) { byte fingerprint[MAX_FINGERPRINT_LEN]; size_t fingerlen; @@ -1878,7 +1880,7 @@ tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec) fingerprint_from_pk( pk, fingerprint, &fingerlen ); for (; fingerlen < 20; fingerlen++) fingerprint[fingerlen] = 0; - return tdbio_search_trust_byfpr (fingerprint, rec); + return tdbio_search_trust_byfpr (ctrl, fingerprint, rec); } diff --git a/g10/tdbio.h b/g10/tdbio.h index beaa308..267a3797 100644 --- a/g10/tdbio.h +++ b/g10/tdbio.h @@ -110,8 +110,10 @@ int tdbio_end_transaction(void); int tdbio_cancel_transaction(void); int tdbio_delete_record (ctrl_t ctrl, ulong recnum); ulong tdbio_new_recnum (ctrl_t ctrl); -gpg_error_t tdbio_search_trust_byfpr (const byte *fingerprint, TRUSTREC *rec); -gpg_error_t tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec); +gpg_error_t tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fingerprint, + TRUSTREC *rec); +gpg_error_t tdbio_search_trust_bypk (ctrl_t ctrl, PKT_public_key *pk, + TRUSTREC *rec); void tdbio_how_to_fix (void); void tdbio_invalid(void); diff --git a/g10/trustdb.c b/g10/trustdb.c index 0a98c12..2c2d239 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -649,7 +649,7 @@ read_trust_record (ctrl_t ctrl, PKT_public_key *pk, TRUSTREC *rec) int rc; init_trustdb (ctrl, 0); - rc = tdbio_search_trust_bypk (pk, rec); + rc = tdbio_search_trust_bypk (ctrl, pk, rec); if (rc) { if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND) commit 403aa70c52e56614d65490dea9344113f9cf3d29 Author: Werner Koch Date: Mon Mar 26 17:43:40 2018 +0200 gpg: Return better error codes in case of a too short trustdb. * g10/tdbio.c (tdbio_read_record): Return GPG_ERR_EOF. (tdbio_new_recnum): Never return on error. (lookup_hashtable): Print a more descriptive error in case of !TABLE. -- Also: tdbio_new_recnum had a bug in that it returned an error code and not a record number in the error case. The function is expected to always return a valid new record number. Signed-off-by: Werner Koch diff --git a/g10/tdbio.c b/g10/tdbio.c index 4940c5c..7314143 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -1292,6 +1292,13 @@ lookup_hashtable (ulong table, const byte *key, size_t keylen, int msb; int level = 0; + if (!table) + { + rc = gpg_error (GPG_ERR_INV_RECORD); + log_error("lookup_hashtable failed: %s\n", "request for record 0"); + return rc; + } + hashrec = table; next_level: msb = key[level]; @@ -1464,7 +1471,7 @@ tdbio_dump_record (TRUSTREC *rec, estream_t fp) * EXPECTED is not 0 reading any other record type will return an * error. * - * Return: 0 on success, -1 on EOF, or an error code. + * Return: 0 on success or an error code. */ int tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected) @@ -1489,7 +1496,7 @@ tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected) n = read (db_fd, readbuf, TRUST_RECORD_LEN); if (!n) { - return -1; /* eof */ + return gpg_error (GPG_ERR_EOF); } else if (n != TRUST_RECORD_LEN) { @@ -1769,20 +1776,14 @@ tdbio_new_recnum (ctrl_t ctrl) recnum = vr.r.ver.firstfree; rc = tdbio_read_record (recnum, &rec, RECTYPE_FREE); if (rc) - { - log_error (_("%s: error reading free record: %s\n"), - db_name, gpg_strerror (rc)); - return rc; - } + log_fatal (_("%s: error reading free record: %s\n"), + db_name, gpg_strerror (rc)); /* Update dir record. */ vr.r.ver.firstfree = rec.r.free.next; rc = tdbio_write_record (ctrl, &vr); if (rc) - { - log_error (_("%s: error writing dir record: %s\n"), - db_name, gpg_strerror (rc)); - return rc; - } + log_fatal (_("%s: error writing dir record: %s\n"), + db_name, gpg_strerror (rc)); /* Zero out the new record. */ memset (&rec, 0, sizeof rec); rec.rectype = 0; /* Mark as unused record (actually already done @@ -1799,7 +1800,7 @@ tdbio_new_recnum (ctrl_t ctrl) if (offset == (off_t)(-1)) log_fatal ("trustdb: lseek to end failed: %s\n", strerror (errno)); recnum = offset / TRUST_RECORD_LEN; - log_assert (recnum); /* this is will never be the first record */ + log_assert (recnum); /* This will never be the first record */ /* We must write a record, so that the next call to this * function returns another recnum. */ memset (&rec, 0, sizeof rec); @@ -1821,13 +1822,13 @@ tdbio_new_recnum (ctrl_t ctrl) { rc = gpg_error_from_syserror (); log_error (_("trustdb rec %lu: write failed (n=%d): %s\n"), - recnum, n, strerror (errno)); + recnum, n, gpg_strerror (rc)); } } if (rc) log_fatal (_("%s: failed to append a record: %s\n"), - db_name, gpg_strerror (rc)); + db_name, gpg_strerror (rc)); } return recnum ; ----------------------------------------------------------------------- Summary of changes: g10/tdbdump.c | 2 +- g10/tdbio.c | 61 ++++++++++++++++++++++++++++++++++++++--------------------- g10/tdbio.h | 6 ++++-- g10/trustdb.c | 2 +- 4 files changed, 45 insertions(+), 26 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 27 02:57:33 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 27 Mar 2018 02:57:33 +0200 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-24-gefc4769 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via efc4769339d42a4a399c040c146cf4a29c02ea4f (commit) from 157130befaacfcc417ddfc98d8f0238f6756b2cc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit efc4769339d42a4a399c040c146cf4a29c02ea4f Author: NIIBE Yutaka Date: Tue Mar 27 09:53:42 2018 +0900 doc: Support cross compilation for yat2m. * configure.ac (HAVE_YAT2M): New. * doc/Makefile.am [CROSS_COMPILING]: Supported. -- Makefile portability is also improved. Fixes-commit: 4dc6d4d2067c726cdb13593bf151637319ff65e6 Signed-off-by: NIIBE Yutaka diff --git a/configure.ac b/configure.ac index 8d11998..0214fb6 100644 --- a/configure.ac +++ b/configure.ac @@ -80,7 +80,6 @@ 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. @@ -139,13 +138,9 @@ 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 +AC_PATH_PROG(YAT2M, yat2m) +AC_ARG_VAR(YAT2M, [tool to convert texi to man pages]) +AM_CONDITIONAL(HAVE_YAT2M, test -n "$ac_cv_path_YAT2M") 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 328089a..d1b494d 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -37,15 +37,32 @@ myman_pages = gpg-error-config.1 man_MANS = $(myman_pages) +if HAVE_YAT2M +YAT2M_CMD = $(YAT2M) +YAT2M_DEP = $(YAT2M)$(EXEEXT) +else +if CROSS_COMPILING +YAT2M_CMD = ./yat2m-for-build +YAT2M_DEP = yat2m-for-build$(EXEEXT) +CLEANFILES += yat2m-for-build$(EXEEXT) + +yat2m-for-build$(EXEEXT): yat2m.c + $(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c +else +YAT2M_CMD = ./yat2m +YAT2M_DEP = yat2m$(EXEEXT) +endif +endif + yat2m-stamp: $(myman_sources) @rm -f yat2m-stamp.tmp @touch yat2m-stamp.tmp for file in $(myman_sources) ; do \ - $(YAT2M) $(YAT2M_OPTIONS) --store \ + $(YAT2M_CMD) $(YAT2M_OPTIONS) --store \ `test -f '$$file' || echo '$(srcdir)/'`$$file ; done @mv -f yat2m-stamp.tmp $@ -yat2m-stamp: $(YAT2M) +yat2m-stamp: $(YAT2M_DEP) $(myman_pages) : yat2m-stamp @if test -f $@; then :; else \ ----------------------------------------------------------------------- Summary of changes: configure.ac | 11 +++-------- doc/Makefile.am | 21 +++++++++++++++++++-- 2 files changed, 22 insertions(+), 10 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 27 03:33:56 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Tue, 27 Mar 2018 03:33:56 +0200 Subject: [git] GPGME - branch, ben/howto-update-02, updated. gpgme-1.10.0-167-gf9159b1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/howto-update-02 has been updated via f9159b1d75d3209b1c22bbb0ed4472800b60a522 (commit) via 1b5da37a47ceef41545e0b2474738613f36be949 (commit) from 5b32efbaf37920b2e99d4bb87cb383b2809b1688 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f9159b1d75d3209b1c22bbb0ed4472800b60a522 Author: Ben McGinnes Date: Tue Mar 27 12:29:08 2018 +1100 example: key creation * Script to generate a new key with encryption subkey taking input from interactive prompts. * Will also take a passphrase via pinentry and uses passphrase caching of five minutes when used in conjunction with the temp homedir script. diff --git a/lang/python/examples/howto/create-key.py b/lang/python/examples/howto/create-key.py new file mode 100755 index 0000000..429ab1f --- /dev/null +++ b/lang/python/examples/howto/create-key.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path + +print(""" +This script generates a new key which does not expire. + +The gpg-agent and pinentry are invoked to set the passphrase. +""") + +c = gpg.Context() + +homedir = input("Enter the GPG configuration directory path (optional): ") +uid_name = input("Enter the name of the user ID: ") +uid_email = input("Enter the email address of the user ID: ") +uid_cmnt = input("Enter a comment to include (optional): ") +key_algo = input("Enter the key algorithm, RSA or DSA (default is RSA): ") +key_size = input("Enter the key size (2048-4096, default is 2048): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +if len(uid_cmnt) > 0: + userid = "{0} ({1}) <{2}>".format(uid_name, uid_cmnt, uid_email) +else: + userid = "{0} <{2}>".format(uid_name, uid_email) + +if key_algo.lower() == "dsa": + ka = "dsa" +else: + ka = "rsa" + +if len(key_size) == 4: + try: + ks0 = int(key_size) + except ValueError: + ks0 = None + if ks0 is None: + ks = "2048" + else: + if ks0 < 2048: + ks = "2048" + elif ka == "dsa" and ks0 > 3072: + ks = "3072" + elif ka == "rsa" and ks0 > 4096: + ks = "4096" + else: + ks = key_size +else: + ks = "2048" + +keyalgo = "{0}{1}".format(ka, ks) + +newkey = c.create_key(userid, algorithm=keyalgo, expires=False, + passphrase=True, certify=True) +key = c.get_key(newkey.fpr, secret=True) + +if ka == "rsa": + newsub = c.create_subkey(key, algorithm=keyalgo, expires=False, + passphrase=True, encrypt=True) +else: + newsub = c.create_subkey(key, expires=False, passphrase=True, + encrypt=True) commit 1b5da37a47ceef41545e0b2474738613f36be949 Author: Ben McGinnes Date: Tue Mar 27 12:16:29 2018 +1100 script: temp homedir config * added passphrase caching of 5 minutes. diff --git a/lang/python/examples/howto/temp-homedir-config.py b/lang/python/examples/howto/temp-homedir-config.py index 368cace..ddd7932 100755 --- a/lang/python/examples/howto/temp-homedir-config.py +++ b/lang/python/examples/howto/temp-homedir-config.py @@ -69,6 +69,10 @@ personal-digest-preferences SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed """ +agentconf = """# gpg-agent.conf settings for key generation: +default-cache-ttl 300 +""" + if len(sys.argv) == 1: print(intro) new_homedir = input("Enter the temporary gnupg homedir name: ") @@ -107,9 +111,12 @@ else: print("Creating the {0} directory.".format(nh)) os.mkdir(nh) os.chmod(nh, 0o700) - with open("{0}/{1}".format(nh, "gpg.conf"), "w") as f: - f.write(gpgconf) + with open("{0}/{1}".format(nh, "gpg.conf"), "w") as f1: + f1.write(gpgconf) os.chmod("{0}/{1}".format(nh, "gpg.conf"), 0o600) + with open("{0}/{1}".format(nh, "gpg-agent.conf"), "w") as f2: + f2.write(gpgconf) + os.chmod("{0}/{1}".format(nh, "gpg-agent.conf"), 0o600) print("""You may now use the {0} directory as an alternative GPG homedir: gpg --homedir {0} ----------------------------------------------------------------------- Summary of changes: lang/python/examples/howto/create-key.py | 95 +++++++++++++++++++++++ lang/python/examples/howto/temp-homedir-config.py | 11 ++- 2 files changed, 104 insertions(+), 2 deletions(-) create mode 100755 lang/python/examples/howto/create-key.py hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 27 03:43:47 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Tue, 27 Mar 2018 03:43:47 +0200 Subject: [git] GPGME - branch, ben/howto-update-02, updated. gpgme-1.10.0-168-ga2eedef Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/howto-update-02 has been updated via a2eedef630891397f8eccb5bb426a0728588bf41 (commit) from f9159b1d75d3209b1c22bbb0ed4472800b60a522 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a2eedef630891397f8eccb5bb426a0728588bf41 Author: Ben McGinnes Date: Tue Mar 27 12:42:06 2018 +1100 doc: python bindings howto * Fixed some minor PEP8 compliance issues in the key creation examples. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 77ddba2..5e1e0ab 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1079,8 +1079,8 @@ c.home_dir = "~/.gnupg-dm" userid = "Danger Mouse " - dmkey = c.create_key(userid, algorithm = "rsa3072", expires_in = 31536000, - sign = True, certify = True) + dmkey = c.create_key(userid, algorithm="rsa3072", expires_in=31536000, + sign=True, certify=True) #+end_src One thing to note here is the use of setting the =c.home_dir= @@ -1173,8 +1173,8 @@ c.home_dir = "~/.gnupg-dm" key = c.get_key(dmkey.fpr, secret = True) - dmsub = c.create_subkey(key, algorithm = "rsa3072", expires_in = 15768000, - encrypt = True) + dmsub = c.create_subkey(key, algorithm="rsa3072", expires_in=15768000, + encrypt=True) #+end_src As with the primary key, the results here can be checked with: @@ -1278,8 +1278,8 @@ uid = "Danger Mouse " dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" - key = c.get_key(dmfpr, secret = True) - c.key_sign(key, uids = uid, expires_in = 2764800) + key = c.get_key(dmfpr, secret=True) + c.key_sign(key, uids=uid, expires_in=2764800) #+end_src ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 27 05:16:56 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 27 Mar 2018 05:16:56 +0200 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.28-25-g99e976b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 99e976be723ebbf7fe5c73671dd916bd4a067727 (commit) from efc4769339d42a4a399c040c146cf4a29c02ea4f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 99e976be723ebbf7fe5c73671dd916bd4a067727 Author: NIIBE Yutaka Date: Tue Mar 27 12:16:20 2018 +0900 doc: Fix previous commit. -- Fixes-commit: efc4769339d42a4a399c040c146cf4a29c02ea4f Signed-off-by: NIIBE Yutaka diff --git a/doc/Makefile.am b/doc/Makefile.am index d1b494d..d5eb886 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -39,18 +39,18 @@ man_MANS = $(myman_pages) if HAVE_YAT2M YAT2M_CMD = $(YAT2M) -YAT2M_DEP = $(YAT2M)$(EXEEXT) +YAT2M_DEP = $(YAT2M) else if CROSS_COMPILING YAT2M_CMD = ./yat2m-for-build -YAT2M_DEP = yat2m-for-build$(EXEEXT) -CLEANFILES += yat2m-for-build$(EXEEXT) +YAT2M_DEP = yat2m-for-build +CLEANFILES += yat2m-for-build yat2m-for-build$(EXEEXT): yat2m.c $(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c else YAT2M_CMD = ./yat2m -YAT2M_DEP = yat2m$(EXEEXT) +YAT2M_DEP = yat2m endif endif ----------------------------------------------------------------------- Summary of changes: doc/Makefile.am | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 27 07:30:54 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 27 Mar 2018 07:30:54 +0200 Subject: [git] Assuan - branch, master, updated. libassuan-2.5.1-5-gb270f2e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPC library used by GnuPG". The branch, master has been updated via b270f2ec21b67f5728edae4b2ddf6fe17a0fd25a (commit) from 6c736325c028647dc3283bf723e2e28199e7f45b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b270f2ec21b67f5728edae4b2ddf6fe17a0fd25a Author: NIIBE Yutaka Date: Tue Mar 27 14:26:43 2018 +0900 tests: Exclude tests for Windows build. * tests/Makefile.am [HAVE_W32_SYSTEM] (TESTS, testtools): Fix. -- pipeconnect and socks5 should be changed if we run it on Windows. If so, pipeconnect should use _open_osfhandle to get HANDLE for pipe. Signed-off-by: NIIBE Yutaka diff --git a/tests/Makefile.am b/tests/Makefile.am index c9044a4..7712a89 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -25,14 +25,19 @@ EXTRA_DIST = motd ce-createpipe.c BUILT_SOURCES = CLEANFILES = -testtools = socks5 - -TESTS = version pipeconnect +TESTS = version if HAVE_W32CE_SYSTEM w32cetools = ce-createpipe ce-server endif +if HAVE_W32_SYSTEM +testtools = +else +TESTS += pipeconnect +testtools = socks5 +endif + if USE_DESCRIPTOR_PASSING TESTS += fdpassing endif ----------------------------------------------------------------------- Summary of changes: tests/Makefile.am | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) hooks/post-receive -- IPC library used by GnuPG http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 27 08:48:22 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 27 Mar 2018 08:48:22 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-31-g02dce8c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 02dce8c0cc57deb2095a9b06aeb8f4dea34eef7e (commit) from eb68c2d3d1b03a18cd24406fa46d4c30cb13d9f7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 02dce8c0cc57deb2095a9b06aeb8f4dea34eef7e Author: Werner Koch Date: Tue Mar 27 08:40:58 2018 +0200 agent: Make the request origin a part of the cache items. * agent/cache.c (agent_put_cache): Add arg 'ctrl' and change all callers to pass it. (agent_get_cache): Ditto. * agent/cache.c (struct cache_items_s): Add field 'restricted'. (housekeeping): Adjust debug output. (agent_flush_cache): Ditto. (agent_put_cache): Ditto. Take RESTRICTED into account. (agent_get_cache): Ditto. -- If requests are coming from different sources they should not share the same cache. This way we make sure that a Pinentry pops up for a remote request to a key we have already used locally. GnuPG-bug-id: 3858 Signed-off-by: Werner Koch diff --git a/agent/agent.h b/agent/agent.h index 743b765..cf50d92 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -452,9 +452,9 @@ void initialize_module_cache (void); void deinitialize_module_cache (void); void agent_cache_housekeeping (void); void agent_flush_cache (void); -int agent_put_cache (const char *key, cache_mode_t cache_mode, +int agent_put_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode, const char *data, int ttl); -char *agent_get_cache (const char *key, cache_mode_t cache_mode); +char *agent_get_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode); void agent_store_cache_hit (const char *key); diff --git a/agent/cache.c b/agent/cache.c index ed5c97c..238b6e2 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -58,6 +58,7 @@ struct cache_item_s { int ttl; /* max. lifetime given in seconds, -1 one means infinite */ struct secret_data_s *pw; cache_mode_t cache_mode; + int restricted; /* The value of ctrl->restricted is part of the key. */ char key[1]; }; @@ -202,8 +203,8 @@ housekeeping (void) if (r->pw && r->ttl >= 0 && r->accessed + r->ttl < current) { if (DBG_CACHE) - log_debug (" expired '%s' (%ds after last access)\n", - r->key, r->ttl); + log_debug (" expired '%s'.%d (%ds after last access)\n", + r->key, r->restricted, r->ttl); release_data (r->pw); r->pw = NULL; r->accessed = current; @@ -224,8 +225,8 @@ housekeeping (void) if (r->pw && r->created + maxttl < current) { if (DBG_CACHE) - log_debug (" expired '%s' (%lus after creation)\n", - r->key, opt.max_cache_ttl); + log_debug (" expired '%s'.%d (%lus after creation)\n", + r->key, r->restricted, opt.max_cache_ttl); release_data (r->pw); r->pw = NULL; r->accessed = current; @@ -233,15 +234,15 @@ housekeeping (void) } /* Third, make sure that we don't have too many items in the list. - Expire old and unused entries after 30 minutes */ + * Expire old and unused entries after 30 minutes. */ for (rprev=NULL, r=thecache; r; ) { if (!r->pw && r->ttl >= 0 && r->accessed + 60*30 < current) { ITEM r2 = r->next; if (DBG_CACHE) - log_debug (" removed '%s' (mode %d) (slot not used for 30m)\n", - r->key, r->cache_mode); + log_debug (" removed '%s'.%d (mode %d) (slot not used for 30m)\n", + r->key, r->restricted, r->cache_mode); xfree (r); if (!rprev) thecache = r2; @@ -296,7 +297,7 @@ agent_flush_cache (void) if (r->pw) { if (DBG_CACHE) - log_debug (" flushing '%s'\n", r->key); + log_debug (" flushing '%s'.%d\n", r->key, r->restricted); release_data (r->pw); r->pw = NULL; r->accessed = 0; @@ -326,20 +327,21 @@ cache_mode_equal (cache_mode_t a, cache_mode_t b) set infinite timeout. CACHE_MODE is stored with the cache entry and used to select different timeouts. */ int -agent_put_cache (const char *key, cache_mode_t cache_mode, +agent_put_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode, const char *data, int ttl) { gpg_error_t err = 0; ITEM r; int res; + int restricted = ctrl? ctrl->restricted : -1; res = npth_mutex_lock (&cache_lock); if (res) log_fatal ("failed to acquire cache mutex: %s\n", strerror (res)); if (DBG_CACHE) - log_debug ("agent_put_cache '%s' (mode %d) requested ttl=%d\n", - key, cache_mode, ttl); + log_debug ("agent_put_cache '%s'.%d (mode %d) requested ttl=%d\n", + key, restricted, cache_mode, ttl); housekeeping (); if (!ttl) @@ -358,6 +360,7 @@ agent_put_cache (const char *key, cache_mode_t cache_mode, if (((cache_mode != CACHE_MODE_USER && cache_mode != CACHE_MODE_NONCE) || cache_mode_equal (r->cache_mode, cache_mode)) + && r->restricted == restricted && !strcmp (r->key, key)) break; } @@ -386,6 +389,7 @@ agent_put_cache (const char *key, cache_mode_t cache_mode, else { strcpy (r->key, key); + r->restricted = restricted; r->created = r->accessed = gnupg_get_time (); r->ttl = ttl; r->cache_mode = cache_mode; @@ -415,13 +419,14 @@ agent_put_cache (const char *key, cache_mode_t cache_mode, make use of CACHE_MODE except for CACHE_MODE_NONCE and CACHE_MODE_USER. */ char * -agent_get_cache (const char *key, cache_mode_t cache_mode) +agent_get_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode) { gpg_error_t err; ITEM r; char *value = NULL; int res; int last_stored = 0; + int restricted = ctrl? ctrl->restricted : -1; if (cache_mode == CACHE_MODE_IGNORE) return NULL; @@ -439,8 +444,8 @@ agent_get_cache (const char *key, cache_mode_t cache_mode) } if (DBG_CACHE) - log_debug ("agent_get_cache '%s' (mode %d)%s ...\n", - key, cache_mode, + log_debug ("agent_get_cache '%s'.%d (mode %d)%s ...\n", + key, ctrl->restricted, cache_mode, last_stored? " (stored cache key)":""); housekeeping (); @@ -450,6 +455,7 @@ agent_get_cache (const char *key, cache_mode_t cache_mode) && ((cache_mode != CACHE_MODE_USER && cache_mode != CACHE_MODE_NONCE) || cache_mode_equal (r->cache_mode, cache_mode)) + && r->restricted == restricted && !strcmp (r->key, key)) { /* Note: To avoid races KEY may not be accessed anymore below. */ @@ -472,8 +478,8 @@ agent_get_cache (const char *key, cache_mode_t cache_mode) { xfree (value); value = NULL; - log_error ("retrieving cache entry '%s' failed: %s\n", - key, gpg_strerror (err)); + log_error ("retrieving cache entry '%s'.%d failed: %s\n", + key, restricted, gpg_strerror (err)); } break; } diff --git a/agent/command-ssh.c b/agent/command-ssh.c index e0b7238..517231a 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -3140,7 +3140,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec, goto out; /* Cache this passphrase. */ - err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl); + err = agent_put_cache (ctrl, key_grip, CACHE_MODE_SSH, pi->pin, ttl); if (err) goto out; diff --git a/agent/command.c b/agent/command.c index 8bb9b6a..f2d0389 100644 --- a/agent/command.c +++ b/agent/command.c @@ -199,14 +199,14 @@ clear_nonce_cache (ctrl_t ctrl) { if (ctrl->server_local->last_cache_nonce) { - agent_put_cache (ctrl->server_local->last_cache_nonce, + agent_put_cache (ctrl, ctrl->server_local->last_cache_nonce, CACHE_MODE_NONCE, NULL, 0); xfree (ctrl->server_local->last_cache_nonce); ctrl->server_local->last_cache_nonce = NULL; } if (ctrl->server_local->last_passwd_nonce) { - agent_put_cache (ctrl->server_local->last_passwd_nonce, + agent_put_cache (ctrl, ctrl->server_local->last_passwd_nonce, CACHE_MODE_NONCE, NULL, 0); xfree (ctrl->server_local->last_passwd_nonce); ctrl->server_local->last_passwd_nonce = NULL; @@ -930,7 +930,7 @@ cmd_genkey (assuan_context_t ctx, char *line) } else if (passwd_nonce) - newpasswd = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE); + newpasswd = agent_get_cache (ctrl, passwd_nonce, CACHE_MODE_NONCE); rc = agent_genkey (ctrl, cache_nonce, (char*)value, valuelen, no_protection, newpasswd, opt_preset, &outbuf); @@ -1179,7 +1179,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, /* Here we have a little race by doing the cache check separately from the retrieval function. Given that the cache flag is only a hint, it should not really matter. */ - pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL); + pw = agent_get_cache (ctrl, hexgrip, CACHE_MODE_NORMAL); cached = pw ? "1" : "-"; xfree (pw); @@ -1484,7 +1484,7 @@ cmd_get_passphrase (assuan_context_t ctx, char *line) if (!strcmp (desc, "X")) desc = NULL; - pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_USER) : NULL; + pw = cacheid ? agent_get_cache (ctrl, cacheid, CACHE_MODE_USER) : NULL; if (pw) { rc = send_back_passphrase (ctx, opt_data, pw); @@ -1551,7 +1551,7 @@ cmd_get_passphrase (assuan_context_t ctx, char *line) if (!rc) { if (cacheid) - agent_put_cache (cacheid, CACHE_MODE_USER, response, 0); + agent_put_cache (ctrl, cacheid, CACHE_MODE_USER, response, 0); rc = send_back_passphrase (ctx, opt_data, response); } xfree (response); @@ -1593,7 +1593,8 @@ cmd_clear_passphrase (assuan_context_t ctx, char *line) if (!*cacheid || strlen (cacheid) > 50) return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID"); - agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER, + agent_put_cache (ctrl, cacheid, + opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER, NULL, 0); agent_clear_passphrase (ctrl, cacheid, @@ -1770,7 +1771,7 @@ cmd_passwd (assuan_context_t ctx, char *line) passwd_nonce = bin2hex (buf, 12, NULL); } if (passwd_nonce - && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE, + && !agent_put_cache (ctrl, passwd_nonce, CACHE_MODE_NONCE, passphrase, CACHE_TTL_NONCE)) { assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce); @@ -1785,7 +1786,7 @@ cmd_passwd (assuan_context_t ctx, char *line) char *newpass = NULL; if (passwd_nonce) - newpass = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE); + newpass = agent_get_cache (ctrl, passwd_nonce, CACHE_MODE_NONCE); err = agent_protect_and_store (ctrl, s_skey, &newpass); if (!err && passphrase) { @@ -1800,7 +1801,7 @@ cmd_passwd (assuan_context_t ctx, char *line) cache_nonce = bin2hex (buf, 12, NULL); } if (cache_nonce - && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE, + && !agent_put_cache (ctrl, cache_nonce, CACHE_MODE_NONCE, passphrase, CACHE_TTL_NONCE)) { assuan_write_status (ctx, "CACHE_NONCE", cache_nonce); @@ -1820,7 +1821,7 @@ cmd_passwd (assuan_context_t ctx, char *line) passwd_nonce = bin2hex (buf, 12, NULL); } if (passwd_nonce - && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE, + && !agent_put_cache (ctrl, passwd_nonce, CACHE_MODE_NONCE, newpass, CACHE_TTL_NONCE)) { assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce); @@ -1834,7 +1835,7 @@ cmd_passwd (assuan_context_t ctx, char *line) { char hexgrip[40+1]; bin2hex(grip, 20, hexgrip); - err = agent_put_cache (hexgrip, CACHE_MODE_ANY, newpass, + err = agent_put_cache (ctrl, hexgrip, CACHE_MODE_ANY, newpass, ctrl->cache_ttl_opt_preset); } xfree (newpass); @@ -1939,7 +1940,7 @@ cmd_preset_passphrase (assuan_context_t ctx, char *line) if (!rc) { - rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl); + rc = agent_put_cache (ctrl, grip_clear, CACHE_MODE_ANY, passphrase, ttl); if (opt_inquire) xfree (passphrase); } @@ -2174,7 +2175,7 @@ cmd_import_key (assuan_context_t ctx, char *line) cache_nonce = bin2hex (buf, 12, NULL); } if (cache_nonce - && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE, + && !agent_put_cache (ctrl, cache_nonce, CACHE_MODE_NONCE, passphrase, CACHE_TTL_NONCE)) assuan_write_status (ctx, "CACHE_NONCE", cache_nonce); } @@ -2336,7 +2337,7 @@ cmd_export_key (assuan_context_t ctx, char *line) cache_nonce = bin2hex (buf, 12, NULL); } if (cache_nonce - && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE, + && !agent_put_cache (ctrl, cache_nonce, CACHE_MODE_NONCE, passphrase, CACHE_TTL_NONCE)) { assuan_write_status (ctx, "CACHE_NONCE", cache_nonce); diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index ee12221..bf05174 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -951,7 +951,7 @@ convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp, int dontcare_exist, { char *cache_value; - cache_value = agent_get_cache (cache_nonce, CACHE_MODE_NONCE); + cache_value = agent_get_cache (ctrl, cache_nonce, CACHE_MODE_NONCE); if (cache_value) { if (strlen (cache_value) < pi->max_length) diff --git a/agent/findkey.c b/agent/findkey.c index e3e9a12..78c3b1a 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -511,7 +511,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, { char *pw; - pw = agent_get_cache (cache_nonce, CACHE_MODE_NONCE); + pw = agent_get_cache (ctrl, cache_nonce, CACHE_MODE_NONCE); if (pw) { rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen); @@ -536,7 +536,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, char *pw; retry: - pw = agent_get_cache (hexgrip, cache_mode); + pw = agent_get_cache (ctrl, hexgrip, cache_mode); if (pw) { rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen); @@ -574,7 +574,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, We can often avoid the passphrase entry in the second step. We do this only in normal mode, so not to interfere with unrelated cache entries. */ - pw = agent_get_cache (NULL, cache_mode); + pw = agent_get_cache (ctrl, NULL, cache_mode); if (pw) { rc = agent_unprotect (ctrl, *keybuf, pw, NULL, @@ -670,7 +670,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, else { /* Passphrase is fine. */ - agent_put_cache (hexgrip, cache_mode, pi->pin, + agent_put_cache (ctrl, hexgrip, cache_mode, pi->pin, lookup_ttl? lookup_ttl (hexgrip) : 0); agent_store_cache_hit (hexgrip); if (r_passphrase && *pi->pin) diff --git a/agent/genkey.c b/agent/genkey.c index a3e37ee..d5c80d0 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -468,7 +468,7 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, passphrase = NULL; else { - passphrase_buffer = agent_get_cache (cache_nonce, CACHE_MODE_NONCE); + passphrase_buffer = agent_get_cache (ctrl, cache_nonce, CACHE_MODE_NONCE); passphrase = passphrase_buffer; } @@ -528,7 +528,7 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, } if (cache_nonce && !no_protection - && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE, + && !agent_put_cache (ctrl, cache_nonce, CACHE_MODE_NONCE, passphrase, ctrl->cache_ttl_opt_preset)) agent_write_status (ctrl, "CACHE_NONCE", cache_nonce, NULL); if (preset && !no_protection) @@ -538,7 +538,7 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, if (gcry_pk_get_keygrip (s_private, grip)) { bin2hex(grip, 20, hexgrip); - rc = agent_put_cache (hexgrip, CACHE_MODE_ANY, passphrase, + rc = agent_put_cache (ctrl, hexgrip, CACHE_MODE_ANY, passphrase, ctrl->cache_ttl_opt_preset); } } diff --git a/agent/protect-tool.c b/agent/protect-tool.c index a193e49..ec7b476 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -749,8 +749,9 @@ agent_key_available (const unsigned char *grip) } char * -agent_get_cache (const char *key, cache_mode_t cache_mode) +agent_get_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode) { + (void)ctrl; (void)key; (void)cache_mode; return NULL; ----------------------------------------------------------------------- Summary of changes: agent/agent.h | 4 ++-- agent/cache.c | 38 ++++++++++++++++++++++---------------- agent/command-ssh.c | 2 +- agent/command.c | 31 ++++++++++++++++--------------- agent/cvt-openpgp.c | 2 +- agent/findkey.c | 8 ++++---- agent/genkey.c | 6 +++--- agent/protect-tool.c | 3 ++- 8 files changed, 51 insertions(+), 43 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 27 09:26:42 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 27 Mar 2018 09:26:42 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-32-g9691834 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 96918346beeca7a46de9f03f19502373994c21bc (commit) from 02dce8c0cc57deb2095a9b06aeb8f4dea34eef7e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 96918346beeca7a46de9f03f19502373994c21bc Author: NIIBE Yutaka Date: Tue Mar 27 16:24:17 2018 +0900 agent,scd: Use pointer to represent HANDLE. * agent/call-scd.c [HAVE_W32_SYSTEM] (start_scd): Format with %p. * scd/command.c [HAVE_W32_SYSTEM] (option_handler): Use void *. Signed-off-by: NIIBE Yutaka diff --git a/agent/call-scd.c b/agent/call-scd.c index cf61a35..16139fd 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -404,8 +404,8 @@ start_scd (ctrl_t ctrl) char buf[100]; #ifdef HAVE_W32_SYSTEM - snprintf (buf, sizeof buf, "OPTION event-signal=%lx", - (unsigned long)get_agent_scd_notify_event ()); + snprintf (buf, sizeof buf, "OPTION event-signal=%p", + get_agent_scd_notify_event ()); #else snprintf (buf, sizeof buf, "OPTION event-signal=%d", SIGUSR2); #endif diff --git a/scd/command.c b/scd/command.c index 7011518..66d9fb9 100644 --- a/scd/command.c +++ b/scd/command.c @@ -79,7 +79,7 @@ struct server_local_s assuan_context_t assuan_ctx; #ifdef HAVE_W32_SYSTEM - unsigned long event_signal; /* Or 0 if not used. */ + void *event_signal; /* Or NULL if not used. */ #else int event_signal; /* Or 0 if not used. */ #endif @@ -178,7 +178,11 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) #ifdef HAVE_W32_SYSTEM if (!*value) return gpg_error (GPG_ERR_ASS_PARAMETER); - ctrl->server_local->event_signal = strtoul (value, NULL, 16); +#ifdef _WIN64 + ctrl->server_local->event_signal = (void *)strtoull (value, NULL, 16); +#else + ctrl->server_local->event_signal = (void *)strtoul (value, NULL, 16); +#endif #else int i = *value? atoi (value) : -1; if (i < 0) @@ -1933,20 +1937,20 @@ send_client_notifications (app_t app, int removal) pid = assuan_get_pid (sl->assuan_ctx); #ifdef HAVE_W32_SYSTEM - handle = (void *)sl->event_signal; + handle = sl->event_signal; for (kidx=0; kidx < killidx; kidx++) if (killed[kidx].pid == pid && killed[kidx].handle == handle) break; if (kidx < killidx) - log_info ("event %lx (%p) already triggered for client %d\n", + log_info ("event %p (%p) already triggered for client %d\n", sl->event_signal, handle, (int)pid); else { - log_info ("triggering event %lx (%p) for client %d\n", + log_info ("triggering event %p (%p) for client %d\n", sl->event_signal, handle, (int)pid); if (!SetEvent (handle)) - log_error ("SetEvent(%lx) failed: %s\n", + log_error ("SetEvent(%p) failed: %s\n", sl->event_signal, w32_strerror (-1)); if (killidx < DIM (killed)) { ----------------------------------------------------------------------- Summary of changes: agent/call-scd.c | 4 ++-- scd/command.c | 16 ++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 27 09:50:28 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 27 Mar 2018 09:50:28 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.5-147-gd4dc424 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via d4dc4245bf0221d2db4118718fc2528ecf43b97b (commit) via 02dce8c0cc57deb2095a9b06aeb8f4dea34eef7e (commit) via eb68c2d3d1b03a18cd24406fa46d4c30cb13d9f7 (commit) via a750ebebf35a392f1c72d6aee5618df0d9f25ff7 (commit) via 403aa70c52e56614d65490dea9344113f9cf3d29 (commit) via 456a3a8e93ea14f821e0e98fb515f284ece98685 (commit) via 5f00531463ebc0e606c502696962426007545bb7 (commit) via 137644c9cb58deaaba6850f2763d9c5f9241cb0b (commit) via 2cd35df5db3c4dfe37616dcfb1fcc644959449ef (commit) via 05c55ee260edc07cd19da56dfd00347bfe3f529c (commit) via 5400a5bb77bddcb14c94d9405312d6181322b090 (commit) via 165bc38cefbc03515403b60b704cabf4dc0b71f4 (commit) via 0152ba7c987443d641ce1091c79f90ef2cc46498 (commit) via 34ec0125614674725cb78cf9f8d5e6b0f8c64064 (commit) via 983f7b2acbd1e7580652bbeb0c3d64f9dd19d9e4 (commit) via 11bbd99477ef5ba5b7db0c17607b10af03c68afb (commit) via 2c85e202bc30231b9555100dec0c490c60d7b88c (commit) via fd23a0524d8060ed12d87c679b7823686614aaee (commit) via c84bae69e9e02923f7180e09d161cb0b13257436 (commit) via 71e5282c25ba812c7091e587edd721839bc4c2ac (commit) via 655f0b9ad0138e6f960bf4befaf0eea569256614 (commit) via 1e27c0e04cd3280d498dc8b72d2e410f6287f656 (commit) via f8b8b6aac2ca1cb34d7a346aee1d874e7650557b (commit) via 334b94898112b5d2c7c97ff0496b9a67b3de0d26 (commit) via 7e40c5efbea65c7804b06d62dfcd7f991557bfaa (commit) from fa0ed1c7e2eee7c559026696e6b21acc882a97aa (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d4dc4245bf0221d2db4118718fc2528ecf43b97b Merge: fa0ed1c 02dce8c Author: Werner Koch Date: Tue Mar 27 08:48:00 2018 +0200 Merge branch 'STABLE-BRANCH-2-2' into master diff --cc g10/tdbdump.c index 37bf78b,2c6f5c2..73a6c2c --- a/g10/tdbdump.c +++ b/g10/tdbdump.c @@@ -183,15 -183,13 +183,15 @@@ import_ownertrust (ctrl_t ctrl, const c } if( !otrust ) continue; /* no otrust defined - no need to update or insert */ - /* convert the ascii fingerprint to binary */ - for(p=line, fprlen=0; fprlen < 20 && *p != ':'; p += 2 ) - fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]); - while (fprlen < 20) + /* Convert the ascii fingerprint to binary */ + for(p=line, fprlen=0; + fprlen < MAX_FINGERPRINT_LEN && *p != ':'; + p += 2 ) + fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]); + while (fprlen < MAX_FINGERPRINT_LEN) fpr[fprlen++] = 0; - rc = tdbio_search_trust_byfpr (fpr, &rec); + rc = tdbio_search_trust_byfpr (ctrl, fpr, &rec); if( !rc ) { /* found: update */ if (rec.r.trust.ownertrust != otrust) { diff --cc sm/gpgsm.h index 3e2f95f,325948a..d3fbde5 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@@ -85,9 -85,8 +85,10 @@@ struc int with_keygrip; /* Option --with-keygrip active. */ + int with_key_screening; /* Option --with-key-screening active. */ + int pinentry_mode; + int request_origin; int armor; /* force base64 armoring (see also ctrl.with_base64) */ int no_armor; /* don't try to figure out whether data is base64 armored*/ ----------------------------------------------------------------------- Summary of changes: agent/agent.h | 4 +- agent/cache.c | 38 ++++++++------- agent/command-ssh.c | 2 +- agent/command.c | 46 ++++++++++++------ agent/cvt-openpgp.c | 2 +- agent/findkey.c | 8 ++-- agent/genkey.c | 6 +-- agent/protect-tool.c | 3 +- common/agent-opt.c | 35 ++++++++++++++ common/shareddefs.h | 13 +++++ configure.ac | 3 +- doc/Makefile.am | 2 +- doc/gpg-agent.texi | 21 ++++++++ doc/gpg.texi | 17 +++++-- doc/gpgsm.texi | 9 ++++ g10/call-agent.c | 19 ++++++++ g10/call-agent.h | 1 + g10/card-util.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++--- g10/gpg.c | 8 ++++ g10/gpg.h | 4 ++ g10/keyedit.c | 4 +- g10/misc.c | 1 + g10/options.h | 1 + g10/parse-packet.c | 17 +++++-- g10/tdbdump.c | 2 +- g10/tdbio.c | 110 ++++++++++++++++++++++++++++-------------- g10/tdbio.h | 6 ++- g10/trustdb.c | 2 +- scd/apdu.c | 56 +++++++++++++++------- scd/app-openpgp.c | 5 +- scd/ccid-driver.c | 3 +- scd/scdaemon.c | 36 ++++++++------ sm/call-agent.c | 14 ++++++ sm/gpgsm.c | 8 ++++ sm/gpgsm.h | 1 + sm/server.c | 12 +++++ 36 files changed, 516 insertions(+), 135 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 27 11:29:39 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 27 Mar 2018 11:29:39 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-165-g7c220e3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 7c220e387d511b0cf66f99370759c36b729cc444 (commit) from 40a9dea5d56506400b67b0c11f6e55a1629dc6fe (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7c220e387d511b0cf66f99370759c36b729cc444 Author: Andre Heinecke Date: Tue Mar 27 11:24:55 2018 +0200 core: Initialize key return value in gpgme_get_key * src/keylist.c (gpgme_get_key): Set r_key to NULL. -- The c++ bindings and others assumed that r_key is set to NULL on error. This is the behavior gpgme_op_keylist_next also has. Even if it is not specified what happens to r_key on error setting it to NULL should not hurt and is more expected behavior. This directly fixes an uninitialized memory access error in the c++ bindings / Kleopatra: GnuPG-Bug-Id: T3865 And will fix some additional random crashes in Kleopatra and GpgOL. diff --git a/src/keylist.c b/src/keylist.c index 7956935..9c5bd4e 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -1269,6 +1269,8 @@ gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key, if (!ctx || !r_key || !fpr) return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); + *r_key = NULL; + if (strlen (fpr) < 8) /* We have at least a key ID. */ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); ----------------------------------------------------------------------- Summary of changes: src/keylist.c | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 28 11:12:22 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 28 Mar 2018 11:12:22 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-112-gf79f337 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via f79f3379aba5949941c320b6cd2d9a1e95785ca1 (commit) from 97ee667a0c24649233554cd6df9572cb2406bf91 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f79f3379aba5949941c320b6cd2d9a1e95785ca1 Author: Andre Heinecke Date: Wed Mar 28 11:12:10 2018 +0200 Fix S/MIME encryption with latest Exchange 2016 * src/cryptcontroller.cpp (CryptController::update_mail_mapi): Set overrideMimeTag to application/pkcs7-mime for smime enc. * src/mimemaker.cpp (create_mapi_attachmend): Add overrideMimeTag paramenter. (create_top_encryption_header): Rearrange header for S/MIME enc. -- Comparing outlooks own S/MIME mails with GpgOL mails lead to this. Tests show that this way the mails do pass the exchange server. With only slight variations we get errors. GnuPG-Bug-Id: T3853 diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index 34b3af3..eddc9f7 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -889,7 +889,18 @@ CryptController::update_mail_mapi () sink->cb_data = &m_input; sink->writefnc = sink_data_write; - LPATTACH attach = create_mapi_attachment (message, sink); + // For S/MIME encrypted mails we have to use the multipart/encrypted + // content type. Otherwise newer (2016) exchange servers will throw + // an M2MCVT.StorageError.Exeption (See GnuPG-Bug-Id: T3853 ) + std::string overrideMimeTag; + if (m_proto == GpgME::CMS && m_encrypt) + { + overrideMimeTag = "application/pkcs7-mime"; + } + + LPATTACH attach = create_mapi_attachment (message, sink, + overrideMimeTag.empty() ? nullptr : + overrideMimeTag.c_str()); if (!attach) { log_error ("%s:%s: Failed to create moss attach.", diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index 2108230..a7e9959 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -153,7 +153,8 @@ check_protocol (protocol_t protocol) returned. The caller needs to call SaveChanges. Returns NULL on failure in which case STREAM will be set to NULL. */ LPATTACH -create_mapi_attachment (LPMESSAGE message, sink_t sink) +create_mapi_attachment (LPMESSAGE message, sink_t sink, + const char *overrideMimeTag) { HRESULT hr; ULONG pos; @@ -217,7 +218,13 @@ create_mapi_attachment (LPMESSAGE message, sink_t sink) if (!hr) { prop.ulPropTag = PR_ATTACH_MIME_TAG_A; - prop.Value.lpszA = strdup("multipart/signed"); + prop.Value.lpszA = overrideMimeTag ? strdup (overrideMimeTag) : + strdup ("multipart/signed"); + if (overrideMimeTag) + { + log_debug ("%s:%s: using override mimetag: %s\n", + SRCNAME, __func__, overrideMimeTag); + } hr = HrSetOneProp ((LPMAPIPROP)att, &prop); xfree (prop.Value.lpszA); } @@ -1909,11 +1916,12 @@ create_top_encryption_header (sink_t sink, protocol_t protocol, char *boundary, { *boundary = 0; rc = write_multistring (sink, - "MIME-Version: 1.0\r\n" - "Content-Type: application/pkcs7-mime;\r\n" - "\tsmime-type=enveloped-data;\r\n" + "Content-Type: application/pkcs7-mime; " + "smime-type=enveloped-data;\r\n" "\tname=\"smime.p7m\"\r\n" + "Content-Disposition: attachment; filename=\"smime.p7m\"\r\n" "Content-Transfer-Encoding: base64\r\n" + "MIME-Version: 1.0\r\n" "\r\n", NULL); } diff --git a/src/mimemaker.h b/src/mimemaker.h index 32415fb..4758bfd 100644 --- a/src/mimemaker.h +++ b/src/mimemaker.h @@ -83,7 +83,8 @@ int create_top_encryption_header (sink_t sink, protocol_t protocol, char *bounda will be written as well. */ int write_boundary (sink_t sink, const char *boundary, int lastone); -LPATTACH create_mapi_attachment (LPMESSAGE message, sink_t sink); +LPATTACH create_mapi_attachment (LPMESSAGE message, sink_t sink, + const char *overrideMimeTag = nullptr); int close_mapi_attachment (LPATTACH *attach, sink_t sink); int finalize_message (LPMESSAGE message, mapi_attach_item_t *att_table, protocol_t protocol, int encrypt, bool is_inline = false); ----------------------------------------------------------------------- Summary of changes: src/cryptcontroller.cpp | 13 ++++++++++++- src/mimemaker.cpp | 18 +++++++++++++----- src/mimemaker.h | 3 ++- 3 files changed, 27 insertions(+), 7 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 28 11:59:35 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 28 Mar 2018 11:59:35 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-33-ge610d51 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via e610d51f0de11154050915b951bcc5c53c940f5e (commit) from 96918346beeca7a46de9f03f19502373994c21bc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e610d51f0de11154050915b951bcc5c53c940f5e Author: NIIBE Yutaka Date: Wed Mar 28 18:44:45 2018 +0900 g10: Change ask_curve so that it can be used outside. * g10/call-agent.h (struct key_attr): New. * g10/keygen.c (ask_curve): Return const char *. No allocation. (quick_generate_keypair): Follow the change. (generate_keypair, generate_subkeypair): Likewise. (parse_algo_usage_expire): Return const char *. -- This change is intended for using ask_curve from card-util.c. Signed-off-by: NIIBE Yutaka diff --git a/g10/call-agent.h b/g10/call-agent.h index 8de0d13..7314ae8 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -19,6 +19,13 @@ #ifndef GNUPG_G10_CALL_AGENT_H #define GNUPG_G10_CALL_AGENT_H +struct key_attr { + int algo; /* Algorithm identifier. */ + union { + unsigned int nbits; /* Supported keysize. */ + const char *curve; /* Name of curve. */ + }; +}; struct agent_card_info_s { @@ -57,13 +64,7 @@ struct agent_card_info_s int is_v2; /* True if this is a v2 card. */ int chvmaxlen[3]; /* Maximum allowed length of a CHV. */ int chvretry[3]; /* Allowed retries for the CHV; 0 = blocked. */ - struct { /* Array with key attributes. */ - int algo; /* Algorithm identifier. */ - union { - unsigned int nbits; /* Supported keysize. */ - const char *curve; /* Name of curve. */ - }; - } key_attr[3]; + struct key_attr key_attr[3]; struct { unsigned int ki:1; /* Key import available. */ unsigned int aac:1; /* Algorithm attributes are changeable. */ diff --git a/g10/keygen.c b/g10/keygen.c index 8de6538..1098798 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -141,8 +141,8 @@ static gpg_error_t parse_algo_usage_expire (ctrl_t ctrl, int for_subkey, const char *algostr, const char *usagestr, const char *expirestr, int *r_algo, unsigned int *r_usage, - u32 *r_expire, - unsigned int *r_nbits, char **r_curve); + u32 *r_expire, unsigned int *r_nbits, + const char **r_curve); static void do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, struct output_control_s *outctrl, int card ); static int write_keyblock (iobuf_t out, kbnode_t node); @@ -2233,9 +2233,9 @@ ask_keysize (int algo, unsigned int primary_keysize) /* Ask for the curve. ALGO is the selected algorithm which this - function may adjust. Returns a malloced string with the name of - the curve. BOTH tells that gpg creates a primary and subkey. */ -static char * + function may adjust. Returns a const string of the name of the + curve. */ +static const char * ask_curve (int *algo, int *subkey_algo) { /* NB: We always use a complete algo list so that we have stable @@ -2267,7 +2267,7 @@ ask_curve (int *algo, int *subkey_algo) #undef MY_USE_ECDSADH int idx; char *answer; - char *result = NULL; + const char *result = NULL; gcry_sexp_t keyparms; tty_printf (_("Please select which elliptic curve you want:\n")); @@ -2358,16 +2358,16 @@ ask_curve (int *algo, int *subkey_algo) if (subkey_algo && *subkey_algo == PUBKEY_ALGO_ECDSA) *subkey_algo = PUBKEY_ALGO_EDDSA; *algo = PUBKEY_ALGO_EDDSA; - result = xstrdup (curves[idx].eddsa_curve); + result = curves[idx].eddsa_curve; } else - result = xstrdup (curves[idx].name); + result = curves[idx].name; break; } } if (!result) - result = xstrdup (curves[0].name); + result = curves[0].name; return result; } @@ -4058,7 +4058,7 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr, unsigned int use; u32 expire; unsigned int nbits; - char *curve; + const char *curve; err = parse_algo_usage_expire (ctrl, 0, algostr, usagestr, expirestr, &algo, &use, &expire, &nbits, &curve); @@ -4253,7 +4253,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, } else { - char *curve = NULL; + const char *curve = NULL; if (subkey_algo) { @@ -4316,8 +4316,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, { /* Need to switch to a different curve for the encryption key. */ - xfree (curve); - curve = xstrdup ("Curve25519"); + curve = "Curve25519"; } r = xmalloc_clear (sizeof *r + strlen (curve)); r->key = pSUBKEYCURVE; @@ -4377,8 +4376,6 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, r->next = para; para = r; } - - xfree (curve); } } else /* Default key generation. */ @@ -4921,7 +4918,7 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey, const char *algostr, const char *usagestr, const char *expirestr, int *r_algo, unsigned int *r_usage, u32 *r_expire, - unsigned int *r_nbits, char **r_curve) + unsigned int *r_nbits, const char **r_curve) { gpg_error_t err; int algo; @@ -4979,11 +4976,7 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey, return gpg_error (GPG_ERR_INV_VALUE); if (curve) - { - *r_curve = xtrystrdup (curve); - if (!*r_curve) - return gpg_error_from_syserror (); - } + *r_curve = curve; *r_algo = algo; *r_usage = use; *r_expire = expire; @@ -5008,7 +5001,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr, unsigned int use; u32 expire; unsigned int nbits = 0; - char *curve = NULL; + const char *curve = NULL; u32 cur_time; char *key_from_hexgrip = NULL; char *hexgrip = NULL; @@ -5160,7 +5153,6 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr, leave: xfree (key_from_hexgrip); - xfree (curve); xfree (hexgrip); xfree (serialno); xfree (cache_nonce); ----------------------------------------------------------------------- Summary of changes: g10/call-agent.h | 15 ++++++++------- g10/keygen.c | 38 +++++++++++++++----------------------- 2 files changed, 23 insertions(+), 30 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 28 19:40:21 2018 From: cvs at cvs.gnupg.org (by Martin Storsjö) Date: Wed, 28 Mar 2018 19:40:21 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-57-g0de2191 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 0de2191a07d69ef1fa34ca4c5d5fc4985ff7b4c4 (commit) via 4e1b628f492643d4e9b830bcdab7b49daaec5854 (commit) via 36e916fc332eda74963192b1c0bf6860a3e5d67b (commit) via ec0a2f25c0f64a7b65b373508ce9081e10461965 (commit) via ed41d6d6fb4551342b22ef763de1bd60e964e186 (commit) via 8ee38806245ca8452051b1a245f44082323f37f6 (commit) from 885f031fbd17abc1c0fedbb98df22823b647fc11 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0de2191a07d69ef1fa34ca4c5d5fc4985ff7b4c4 Author: Martin Storsj? Date: Thu Mar 22 23:32:40 2018 +0200 aarch64: Enable building the aarch64 cipher assembly for windows * cipher/asm-common-aarch64.h: New. * cipher/camellia-aarch64.S: Use ELF macro, use x19 instead of x18. * cipher/chacha20-aarch64.S: Use ELF macro, don't use GOT on windows. * cipher/cipher-gcm-armv8-aarch64-ce.S: Use ELF macro. * cipher/rijndael-aarch64.S: Use ELF macro. * cipher/rijndael-armv8-aarch64-ce.S: Use ELF macro. * cipher/sha1-armv8-aarch64-ce.S: Use ELF macro. * cipher/sha256-armv8-aarch64-ce.S: Use ELF macro. * cipher/twofish-aarch64.S: Use ELF macro. * configure.ac: Don't require .size and .type in aarch64 assembly check. -- Don't require .type and .size in configure; we can make them optional via a preprocessor macro. This is mostly a mechanical change, wrapping the .type and .size directives in an ELF() macro, with two actual manual changes: (when targeting windows): - Don't load global symbols via a GOT (in chacha20) - Don't use the x18 register (in camellia); back up and restore x19 in the prologue/epilogue and use that instead. x18 is a platform specific register; on linux, it's free to be used by user code, while it's reserved for platform use on windows and darwin. Always use x19 instead of x18 for consistency. Signed-off-by: Martin Storsj? diff --git a/cipher/asm-common-aarch64.h b/cipher/asm-common-aarch64.h new file mode 100644 index 0000000..814b7ad --- /dev/null +++ b/cipher/asm-common-aarch64.h @@ -0,0 +1,32 @@ +/* asm-common-aarch64.h - Common macros for AArch64 assembly + * + * Copyright (C) 2018 Martin Storsj? + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#ifndef GCRY_ASM_COMMON_AARCH64_H +#define GCRY_ASM_COMMON_AARCH64_H + +#include + +#ifdef __ELF__ +# define ELF(...) __VA_ARGS__ +#else +# define ELF(...) /*_*/ +#endif + +#endif /* GCRY_ASM_COMMON_AARCH64_H */ diff --git a/cipher/camellia-aarch64.S b/cipher/camellia-aarch64.S index 68d2a7d..c3cc463 100644 --- a/cipher/camellia-aarch64.S +++ b/cipher/camellia-aarch64.S @@ -19,7 +19,7 @@ * License along with this program; if not, see . */ -#include +#include "asm-common-aarch64.h" #if defined(__AARCH64EL__) #ifdef HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS @@ -55,12 +55,12 @@ #define RT0 w15 #define RT1 w16 #define RT2 w17 -#define RT3 w18 +#define RT3 w19 #define xRT0 x15 #define xRT1 x16 #define xRT2 x17 -#define xRT3 x18 +#define xRT3 x19 #ifdef __AARCH64EL__ #define host_to_be(reg, rtmp) \ @@ -198,9 +198,10 @@ str_output_be(RDST, YL, YR, XL, XR, RT0, RT1); .globl _gcry_camellia_arm_encrypt_block -.type _gcry_camellia_arm_encrypt_block, at function; +ELF(.type _gcry_camellia_arm_encrypt_block, at function;) _gcry_camellia_arm_encrypt_block: + stp x19, x30, [sp, #-16]! /* input: * x0: keytable * x1: dst @@ -227,6 +228,7 @@ _gcry_camellia_arm_encrypt_block: outunpack(24); + ldp x19, x30, [sp], #16 ret; .ltorg @@ -236,14 +238,16 @@ _gcry_camellia_arm_encrypt_block: outunpack(32); + ldp x19, x30, [sp], #16 ret; .ltorg -.size _gcry_camellia_arm_encrypt_block,.-_gcry_camellia_arm_encrypt_block; +ELF(.size _gcry_camellia_arm_encrypt_block,.-_gcry_camellia_arm_encrypt_block;) .globl _gcry_camellia_arm_decrypt_block -.type _gcry_camellia_arm_decrypt_block, at function; +ELF(.type _gcry_camellia_arm_decrypt_block, at function;) _gcry_camellia_arm_decrypt_block: + stp x19, x30, [sp, #-16]! /* input: * x0: keytable * x1: dst @@ -271,6 +275,7 @@ _gcry_camellia_arm_decrypt_block: outunpack(0); + ldp x19, x30, [sp], #16 ret; .ltorg @@ -281,11 +286,11 @@ _gcry_camellia_arm_decrypt_block: b .Ldec_128; .ltorg -.size _gcry_camellia_arm_decrypt_block,.-_gcry_camellia_arm_decrypt_block; +ELF(.size _gcry_camellia_arm_decrypt_block,.-_gcry_camellia_arm_decrypt_block;) /* Encryption/Decryption tables */ .globl _gcry_camellia_arm_tables -.type _gcry_camellia_arm_tables, at object; +ELF(.type _gcry_camellia_arm_tables, at object;) .balign 32 _gcry_camellia_arm_tables: .Lcamellia_sp1110: @@ -551,7 +556,7 @@ _gcry_camellia_arm_tables: .long 0xc7c7c700, 0x008f8f8f, 0xe300e3e3, 0xf4f400f4 .long 0x80808000, 0x00010101, 0x40004040, 0xc7c700c7 .long 0x9e9e9e00, 0x003d3d3d, 0x4f004f4f, 0x9e9e009e -.size _gcry_camellia_arm_tables,.-_gcry_camellia_arm_tables; +ELF(.size _gcry_camellia_arm_tables,.-_gcry_camellia_arm_tables;) #endif /*HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS*/ #endif /*__AARCH64EL__*/ diff --git a/cipher/chacha20-aarch64.S b/cipher/chacha20-aarch64.S index 5990a08..3844d4e 100644 --- a/cipher/chacha20-aarch64.S +++ b/cipher/chacha20-aarch64.S @@ -27,7 +27,7 @@ * Public domain. */ -#include +#include "asm-common-aarch64.h" #if defined(__AARCH64EL__) && \ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \ @@ -38,9 +38,15 @@ .text +#ifdef _WIN32 +#define GET_DATA_POINTER(reg, name) \ + adrp reg, name ; \ + add reg, reg, #:lo12:name ; +#else #define GET_DATA_POINTER(reg, name) \ adrp reg, :got:name ; \ ldr reg, [reg, #:got_lo12:name] ; +#endif /* register macros */ #define INPUT x0 @@ -148,7 +154,7 @@ chacha20_data: .align 3 .globl _gcry_chacha20_aarch64_blocks4 -.type _gcry_chacha20_aarch64_blocks4,%function; +ELF(.type _gcry_chacha20_aarch64_blocks4,%function;) _gcry_chacha20_aarch64_blocks4: /* input: @@ -303,6 +309,6 @@ _gcry_chacha20_aarch64_blocks4: eor x0, x0, x0 ret -.size _gcry_chacha20_aarch64_blocks4, .-_gcry_chacha20_aarch64_blocks4; +ELF(.size _gcry_chacha20_aarch64_blocks4, .-_gcry_chacha20_aarch64_blocks4;) #endif diff --git a/cipher/cipher-gcm-armv8-aarch64-ce.S b/cipher/cipher-gcm-armv8-aarch64-ce.S index 0cfaf1c..b6c4f59 100644 --- a/cipher/cipher-gcm-armv8-aarch64-ce.S +++ b/cipher/cipher-gcm-armv8-aarch64-ce.S @@ -17,7 +17,7 @@ * License along with this program; if not, see . */ -#include +#include "asm-common-aarch64.h" #if defined(__AARCH64EL__) && \ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \ @@ -174,7 +174,7 @@ gcry_gcm_reduction_constant: */ .align 3 .globl _gcry_ghash_armv8_ce_pmull -.type _gcry_ghash_armv8_ce_pmull,%function; +ELF(.type _gcry_ghash_armv8_ce_pmull,%function;) _gcry_ghash_armv8_ce_pmull: /* input: * x0: gcm_key @@ -360,7 +360,7 @@ _gcry_ghash_armv8_ce_pmull: .Ldo_nothing: mov x0, #0 ret -.size _gcry_ghash_armv8_ce_pmull,.-_gcry_ghash_armv8_ce_pmull; +ELF(.size _gcry_ghash_armv8_ce_pmull,.-_gcry_ghash_armv8_ce_pmull;) /* @@ -368,7 +368,7 @@ _gcry_ghash_armv8_ce_pmull: */ .align 3 .globl _gcry_ghash_setup_armv8_ce_pmull -.type _gcry_ghash_setup_armv8_ce_pmull,%function; +ELF(.type _gcry_ghash_setup_armv8_ce_pmull,%function;) _gcry_ghash_setup_armv8_ce_pmull: /* input: * x0: gcm_key @@ -408,6 +408,6 @@ _gcry_ghash_setup_armv8_ce_pmull: st1 {rh5.16b-rh6.16b}, [x1] ret -.size _gcry_ghash_setup_armv8_ce_pmull,.-_gcry_ghash_setup_armv8_ce_pmull; +ELF(.size _gcry_ghash_setup_armv8_ce_pmull,.-_gcry_ghash_setup_armv8_ce_pmull;) #endif diff --git a/cipher/rijndael-aarch64.S b/cipher/rijndael-aarch64.S index e533bbe..aad7487 100644 --- a/cipher/rijndael-aarch64.S +++ b/cipher/rijndael-aarch64.S @@ -18,7 +18,7 @@ * License along with this program; if not, see . */ -#include +#include "asm-common-aarch64.h" #if defined(__AARCH64EL__) #ifdef HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS @@ -206,7 +206,7 @@ addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy); .globl _gcry_aes_arm_encrypt_block -.type _gcry_aes_arm_encrypt_block,%function; +ELF(.type _gcry_aes_arm_encrypt_block,%function;) _gcry_aes_arm_encrypt_block: /* input: @@ -285,7 +285,7 @@ _gcry_aes_arm_encrypt_block: lastencround(11, RNA, RNB, RNC, RND, RA, RB, RC, RD); b .Lenc_done; -.size _gcry_aes_arm_encrypt_block,.-_gcry_aes_arm_encrypt_block; +ELF(.size _gcry_aes_arm_encrypt_block,.-_gcry_aes_arm_encrypt_block;) #define addroundkey_dec(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \ ldr rna, [CTX, #(((round) * 16) + 0 * 4)]; \ @@ -429,7 +429,7 @@ _gcry_aes_arm_encrypt_block: addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy); .globl _gcry_aes_arm_decrypt_block -.type _gcry_aes_arm_decrypt_block,%function; +ELF(.type _gcry_aes_arm_decrypt_block,%function;) _gcry_aes_arm_decrypt_block: /* input: @@ -504,7 +504,7 @@ _gcry_aes_arm_decrypt_block: decround(9, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key); b .Ldec_tail; -.size _gcry_aes_arm_decrypt_block,.-_gcry_aes_arm_decrypt_block; +ELF(.size _gcry_aes_arm_decrypt_block,.-_gcry_aes_arm_decrypt_block;) #endif /*HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS*/ #endif /*__AARCH64EL__ */ diff --git a/cipher/rijndael-armv8-aarch64-ce.S b/cipher/rijndael-armv8-aarch64-ce.S index 40097a7..5859557 100644 --- a/cipher/rijndael-armv8-aarch64-ce.S +++ b/cipher/rijndael-armv8-aarch64-ce.S @@ -17,7 +17,7 @@ * License along with this program; if not, see . */ -#include +#include "asm-common-aarch64.h" #if defined(__AARCH64EL__) && \ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \ @@ -239,7 +239,7 @@ */ .align 3 .globl _gcry_aes_enc_armv8_ce -.type _gcry_aes_enc_armv8_ce,%function; +ELF(.type _gcry_aes_enc_armv8_ce,%function;) _gcry_aes_enc_armv8_ce: /* input: * x0: keysched @@ -291,7 +291,7 @@ _gcry_aes_enc_armv8_ce: CLEAR_REG(vk13) CLEAR_REG(vk14) b .Lenc1_tail -.size _gcry_aes_enc_armv8_ce,.-_gcry_aes_enc_armv8_ce; +ELF(.size _gcry_aes_enc_armv8_ce,.-_gcry_aes_enc_armv8_ce;) /* @@ -301,7 +301,7 @@ _gcry_aes_enc_armv8_ce: */ .align 3 .globl _gcry_aes_dec_armv8_ce -.type _gcry_aes_dec_armv8_ce,%function; +ELF(.type _gcry_aes_dec_armv8_ce,%function;) _gcry_aes_dec_armv8_ce: /* input: * x0: keysched @@ -353,7 +353,7 @@ _gcry_aes_dec_armv8_ce: CLEAR_REG(vk13) CLEAR_REG(vk14) b .Ldec1_tail -.size _gcry_aes_dec_armv8_ce,.-_gcry_aes_dec_armv8_ce; +ELF(.size _gcry_aes_dec_armv8_ce,.-_gcry_aes_dec_armv8_ce;) /* @@ -366,7 +366,7 @@ _gcry_aes_dec_armv8_ce: .align 3 .globl _gcry_aes_cbc_enc_armv8_ce -.type _gcry_aes_cbc_enc_armv8_ce,%function; +ELF(.type _gcry_aes_cbc_enc_armv8_ce,%function;) _gcry_aes_cbc_enc_armv8_ce: /* input: * x0: keysched @@ -419,7 +419,7 @@ _gcry_aes_cbc_enc_armv8_ce: .Lcbc_enc_skip: ret -.size _gcry_aes_cbc_enc_armv8_ce,.-_gcry_aes_cbc_enc_armv8_ce; +ELF(.size _gcry_aes_cbc_enc_armv8_ce,.-_gcry_aes_cbc_enc_armv8_ce;) /* * void _gcry_aes_cbc_dec_armv8_ce (const void *keysched, @@ -430,7 +430,7 @@ _gcry_aes_cbc_enc_armv8_ce: .align 3 .globl _gcry_aes_cbc_dec_armv8_ce -.type _gcry_aes_cbc_dec_armv8_ce,%function; +ELF(.type _gcry_aes_cbc_dec_armv8_ce,%function;) _gcry_aes_cbc_dec_armv8_ce: /* input: * x0: keysched @@ -515,7 +515,7 @@ _gcry_aes_cbc_dec_armv8_ce: .Lcbc_dec_skip: ret -.size _gcry_aes_cbc_dec_armv8_ce,.-_gcry_aes_cbc_dec_armv8_ce; +ELF(.size _gcry_aes_cbc_dec_armv8_ce,.-_gcry_aes_cbc_dec_armv8_ce;) /* @@ -527,7 +527,7 @@ _gcry_aes_cbc_dec_armv8_ce: .align 3 .globl _gcry_aes_ctr_enc_armv8_ce -.type _gcry_aes_ctr_enc_armv8_ce,%function; +ELF(.type _gcry_aes_ctr_enc_armv8_ce,%function;) _gcry_aes_ctr_enc_armv8_ce: /* input: * r0: keysched @@ -669,7 +669,7 @@ _gcry_aes_ctr_enc_armv8_ce: .Lctr_enc_skip: ret -.size _gcry_aes_ctr_enc_armv8_ce,.-_gcry_aes_ctr_enc_armv8_ce; +ELF(.size _gcry_aes_ctr_enc_armv8_ce,.-_gcry_aes_ctr_enc_armv8_ce;) /* @@ -681,7 +681,7 @@ _gcry_aes_ctr_enc_armv8_ce: .align 3 .globl _gcry_aes_cfb_enc_armv8_ce -.type _gcry_aes_cfb_enc_armv8_ce,%function; +ELF(.type _gcry_aes_cfb_enc_armv8_ce,%function;) _gcry_aes_cfb_enc_armv8_ce: /* input: * r0: keysched @@ -732,7 +732,7 @@ _gcry_aes_cfb_enc_armv8_ce: .Lcfb_enc_skip: ret -.size _gcry_aes_cfb_enc_armv8_ce,.-_gcry_aes_cfb_enc_armv8_ce; +ELF(.size _gcry_aes_cfb_enc_armv8_ce,.-_gcry_aes_cfb_enc_armv8_ce;) /* @@ -744,7 +744,7 @@ _gcry_aes_cfb_enc_armv8_ce: .align 3 .globl _gcry_aes_cfb_dec_armv8_ce -.type _gcry_aes_cfb_dec_armv8_ce,%function; +ELF(.type _gcry_aes_cfb_dec_armv8_ce,%function;) _gcry_aes_cfb_dec_armv8_ce: /* input: * r0: keysched @@ -829,7 +829,7 @@ _gcry_aes_cfb_dec_armv8_ce: .Lcfb_dec_skip: ret -.size _gcry_aes_cfb_dec_armv8_ce,.-_gcry_aes_cfb_dec_armv8_ce; +ELF(.size _gcry_aes_cfb_dec_armv8_ce,.-_gcry_aes_cfb_dec_armv8_ce;) /* @@ -846,7 +846,7 @@ _gcry_aes_cfb_dec_armv8_ce: .align 3 .globl _gcry_aes_ocb_enc_armv8_ce -.type _gcry_aes_ocb_enc_armv8_ce,%function; +ELF(.type _gcry_aes_ocb_enc_armv8_ce,%function;) _gcry_aes_ocb_enc_armv8_ce: /* input: * x0: keysched @@ -979,7 +979,7 @@ _gcry_aes_ocb_enc_armv8_ce: CLEAR_REG(v16) ret -.size _gcry_aes_ocb_enc_armv8_ce,.-_gcry_aes_ocb_enc_armv8_ce; +ELF(.size _gcry_aes_ocb_enc_armv8_ce,.-_gcry_aes_ocb_enc_armv8_ce;) /* @@ -996,7 +996,7 @@ _gcry_aes_ocb_enc_armv8_ce: .align 3 .globl _gcry_aes_ocb_dec_armv8_ce -.type _gcry_aes_ocb_dec_armv8_ce,%function; +ELF(.type _gcry_aes_ocb_dec_armv8_ce,%function;) _gcry_aes_ocb_dec_armv8_ce: /* input: * x0: keysched @@ -1129,7 +1129,7 @@ _gcry_aes_ocb_dec_armv8_ce: CLEAR_REG(v16) ret -.size _gcry_aes_ocb_dec_armv8_ce,.-_gcry_aes_ocb_dec_armv8_ce; +ELF(.size _gcry_aes_ocb_dec_armv8_ce,.-_gcry_aes_ocb_dec_armv8_ce;) /* @@ -1145,7 +1145,7 @@ _gcry_aes_ocb_dec_armv8_ce: .align 3 .globl _gcry_aes_ocb_auth_armv8_ce -.type _gcry_aes_ocb_auth_armv8_ce,%function; +ELF(.type _gcry_aes_ocb_auth_armv8_ce,%function;) _gcry_aes_ocb_auth_armv8_ce: /* input: * x0: keysched @@ -1273,7 +1273,7 @@ _gcry_aes_ocb_auth_armv8_ce: CLEAR_REG(v16) ret -.size _gcry_aes_ocb_auth_armv8_ce,.-_gcry_aes_ocb_auth_armv8_ce; +ELF(.size _gcry_aes_ocb_auth_armv8_ce,.-_gcry_aes_ocb_auth_armv8_ce;) /* @@ -1285,7 +1285,7 @@ _gcry_aes_ocb_auth_armv8_ce: .align 3 .globl _gcry_aes_xts_enc_armv8_ce -.type _gcry_aes_xts_enc_armv8_ce,%function; +ELF(.type _gcry_aes_xts_enc_armv8_ce,%function;) _gcry_aes_xts_enc_armv8_ce: /* input: * r0: keysched @@ -1410,7 +1410,7 @@ _gcry_aes_xts_enc_armv8_ce: .Lxts_enc_skip: ret -.size _gcry_aes_xts_enc_armv8_ce,.-_gcry_aes_xts_enc_armv8_ce; +ELF(.size _gcry_aes_xts_enc_armv8_ce,.-_gcry_aes_xts_enc_armv8_ce;) /* @@ -1422,7 +1422,7 @@ _gcry_aes_xts_enc_armv8_ce: .align 3 .globl _gcry_aes_xts_dec_armv8_ce -.type _gcry_aes_xts_dec_armv8_ce,%function; +ELF(.type _gcry_aes_xts_dec_armv8_ce,%function;) _gcry_aes_xts_dec_armv8_ce: /* input: * r0: keysched @@ -1547,7 +1547,7 @@ _gcry_aes_xts_dec_armv8_ce: .Lxts_dec_skip: ret -.size _gcry_aes_xts_dec_armv8_ce,.-_gcry_aes_xts_dec_armv8_ce; +ELF(.size _gcry_aes_xts_dec_armv8_ce,.-_gcry_aes_xts_dec_armv8_ce;) /* @@ -1555,7 +1555,7 @@ _gcry_aes_xts_dec_armv8_ce: */ .align 3 .globl _gcry_aes_sbox4_armv8_ce -.type _gcry_aes_sbox4_armv8_ce,%function; +ELF(.type _gcry_aes_sbox4_armv8_ce,%function;) _gcry_aes_sbox4_armv8_ce: /* See "Gouv?a, C. P. L. & L?pez, J. Implementing GCM on ARMv8. Topics in * Cryptology ? CT-RSA 2015" for details. @@ -1568,7 +1568,7 @@ _gcry_aes_sbox4_armv8_ce: mov w0, v0.S[0] CLEAR_REG(v0) ret -.size _gcry_aes_sbox4_armv8_ce,.-_gcry_aes_sbox4_armv8_ce; +ELF(.size _gcry_aes_sbox4_armv8_ce,.-_gcry_aes_sbox4_armv8_ce;) /* @@ -1576,13 +1576,13 @@ _gcry_aes_sbox4_armv8_ce: */ .align 3 .globl _gcry_aes_invmixcol_armv8_ce -.type _gcry_aes_invmixcol_armv8_ce,%function; +ELF(.type _gcry_aes_invmixcol_armv8_ce,%function;) _gcry_aes_invmixcol_armv8_ce: ld1 {v0.16b}, [x1] aesimc v0.16b, v0.16b st1 {v0.16b}, [x0] CLEAR_REG(v0) ret -.size _gcry_aes_invmixcol_armv8_ce,.-_gcry_aes_invmixcol_armv8_ce; +ELF(.size _gcry_aes_invmixcol_armv8_ce,.-_gcry_aes_invmixcol_armv8_ce;) #endif diff --git a/cipher/sha1-armv8-aarch64-ce.S b/cipher/sha1-armv8-aarch64-ce.S index ec1810d..aeb67a1 100644 --- a/cipher/sha1-armv8-aarch64-ce.S +++ b/cipher/sha1-armv8-aarch64-ce.S @@ -17,7 +17,7 @@ * License along with this program; if not, see . */ -#include +#include "asm-common-aarch64.h" #if defined(__AARCH64EL__) && \ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \ @@ -103,7 +103,7 @@ gcry_sha1_aarch64_ce_K_VEC: */ .align 3 .globl _gcry_sha1_transform_armv8_ce -.type _gcry_sha1_transform_armv8_ce,%function; +ELF(.type _gcry_sha1_transform_armv8_ce,%function;) _gcry_sha1_transform_armv8_ce: /* input: * x0: ctx, CTX @@ -199,6 +199,6 @@ _gcry_sha1_transform_armv8_ce: .Ldo_nothing: mov x0, #0 ret -.size _gcry_sha1_transform_armv8_ce,.-_gcry_sha1_transform_armv8_ce; +ELF(.size _gcry_sha1_transform_armv8_ce,.-_gcry_sha1_transform_armv8_ce;) #endif diff --git a/cipher/sha256-armv8-aarch64-ce.S b/cipher/sha256-armv8-aarch64-ce.S index a4575da..6b3ad32 100644 --- a/cipher/sha256-armv8-aarch64-ce.S +++ b/cipher/sha256-armv8-aarch64-ce.S @@ -17,7 +17,7 @@ * License along with this program; if not, see . */ -#include +#include "asm-common-aarch64.h" #if defined(__AARCH64EL__) && \ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \ @@ -113,7 +113,7 @@ gcry_sha256_aarch64_ce_K: */ .align 3 .globl _gcry_sha256_transform_armv8_ce -.type _gcry_sha256_transform_armv8_ce,%function; +ELF(.type _gcry_sha256_transform_armv8_ce,%function;) _gcry_sha256_transform_armv8_ce: /* input: * r0: ctx, CTX @@ -213,6 +213,6 @@ _gcry_sha256_transform_armv8_ce: .Ldo_nothing: mov x0, #0 ret -.size _gcry_sha256_transform_armv8_ce,.-_gcry_sha256_transform_armv8_ce; +ELF(.size _gcry_sha256_transform_armv8_ce,.-_gcry_sha256_transform_armv8_ce;) #endif diff --git a/cipher/twofish-aarch64.S b/cipher/twofish-aarch64.S index 99c4675..adee412 100644 --- a/cipher/twofish-aarch64.S +++ b/cipher/twofish-aarch64.S @@ -18,7 +18,7 @@ * License along with this program; if not, see . */ -#include +#include "asm-common-aarch64.h" #if defined(__AARCH64EL__) #ifdef HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS @@ -217,7 +217,7 @@ ror1(RD); .globl _gcry_twofish_arm_encrypt_block -.type _gcry_twofish_arm_encrypt_block,%function; +ELF(.type _gcry_twofish_arm_encrypt_block,%function;) _gcry_twofish_arm_encrypt_block: /* input: @@ -263,10 +263,10 @@ _gcry_twofish_arm_encrypt_block: ret; .ltorg -.size _gcry_twofish_arm_encrypt_block,.-_gcry_twofish_arm_encrypt_block; +ELF(.size _gcry_twofish_arm_encrypt_block,.-_gcry_twofish_arm_encrypt_block;) .globl _gcry_twofish_arm_decrypt_block -.type _gcry_twofish_arm_decrypt_block,%function; +ELF(.type _gcry_twofish_arm_decrypt_block,%function;) _gcry_twofish_arm_decrypt_block: /* input: @@ -311,7 +311,7 @@ _gcry_twofish_arm_decrypt_block: str_output_le(RDST, RA, RB, RC, RD, RT0, RT1); ret; -.size _gcry_twofish_arm_decrypt_block,.-_gcry_twofish_arm_decrypt_block; +ELF(.size _gcry_twofish_arm_decrypt_block,.-_gcry_twofish_arm_decrypt_block;) #endif /*HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS*/ #endif /*__AARCH64EL__*/ diff --git a/configure.ac b/configure.ac index b5d7211..330485f 100644 --- a/configure.ac +++ b/configure.ac @@ -1119,10 +1119,6 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for ARMv8/Aarch64 assembly i "eor x0, x0, x30, ror #12;\n\t" "add x0, x0, x30, asr #12;\n\t" "eor v0.16b, v0.16b, v31.16b;\n\t" - - /* Test if '.type' and '.size' are supported. */ - ".size asmfunc,.-asmfunc;\n\t" - ".type asmfunc, at function;\n\t" );]])], [gcry_cv_gcc_aarch64_platform_as_ok=yes])]) if test "$gcry_cv_gcc_aarch64_platform_as_ok" = "yes" ; then commit 4e1b628f492643d4e9b830bcdab7b49daaec5854 Author: Martin Storsj? Date: Thu Mar 22 23:32:39 2018 +0200 aarch64: camellia: Only use the lower 32 bit of an int parameter * cipher/camellia-aarch64.S: Use 'w3' instead of 'x3'. -- The keybits parameter is declared as int, and in those cases, the upper half of a register is undefined, not guaranteed to be zero. Signed-off-by: Martin Storsj? diff --git a/cipher/camellia-aarch64.S b/cipher/camellia-aarch64.S index 440f69f..68d2a7d 100644 --- a/cipher/camellia-aarch64.S +++ b/cipher/camellia-aarch64.S @@ -33,7 +33,7 @@ #define CTX x0 #define RDST x1 #define RSRC x2 -#define RKEYBITS x3 +#define RKEYBITS w3 #define RTAB1 x4 #define RTAB2 x5 commit 36e916fc332eda74963192b1c0bf6860a3e5d67b Author: Martin Storsj? Date: Thu Mar 22 23:32:38 2018 +0200 aarch64: Fix assembling chacha20-aarch64.S with clang/llvm * cipher/chacha20-aarch64.S: Remove superfluous lane counts. -- When referring to a specific lane, one doesn't need to specify the total number of lanes of the register. With GNU binutils, both forms are accepted, while clang/llvm rejects the form with the unnecessary number of lanes. Signed-off-by: Martin Storsj? diff --git a/cipher/chacha20-aarch64.S b/cipher/chacha20-aarch64.S index 739ddde..5990a08 100644 --- a/cipher/chacha20-aarch64.S +++ b/cipher/chacha20-aarch64.S @@ -170,27 +170,27 @@ _gcry_chacha20_aarch64_blocks4: mov ROUND, #20; ld1 {VTMP1.16b-VTMP3.16b}, [INPUT_POS]; - dup X12.4s, X15.4s[0]; - dup X13.4s, X15.4s[1]; + dup X12.4s, X15.s[0]; + dup X13.4s, X15.s[1]; ldr CTR, [INPUT_CTR]; add X12.4s, X12.4s, VCTR.4s; - dup X0.4s, VTMP1.4s[0]; - dup X1.4s, VTMP1.4s[1]; - dup X2.4s, VTMP1.4s[2]; - dup X3.4s, VTMP1.4s[3]; - dup X14.4s, X15.4s[2]; + dup X0.4s, VTMP1.s[0]; + dup X1.4s, VTMP1.s[1]; + dup X2.4s, VTMP1.s[2]; + dup X3.4s, VTMP1.s[3]; + dup X14.4s, X15.s[2]; cmhi VTMP0.4s, VCTR.4s, X12.4s; - dup X15.4s, X15.4s[3]; + dup X15.4s, X15.s[3]; add CTR, CTR, #4; /* Update counter */ - dup X4.4s, VTMP2.4s[0]; - dup X5.4s, VTMP2.4s[1]; - dup X6.4s, VTMP2.4s[2]; - dup X7.4s, VTMP2.4s[3]; + dup X4.4s, VTMP2.s[0]; + dup X5.4s, VTMP2.s[1]; + dup X6.4s, VTMP2.s[2]; + dup X7.4s, VTMP2.s[3]; sub X13.4s, X13.4s, VTMP0.4s; - dup X8.4s, VTMP3.4s[0]; - dup X9.4s, VTMP3.4s[1]; - dup X10.4s, VTMP3.4s[2]; - dup X11.4s, VTMP3.4s[3]; + dup X8.4s, VTMP3.s[0]; + dup X9.4s, VTMP3.s[1]; + dup X10.4s, VTMP3.s[2]; + dup X11.4s, VTMP3.s[3]; mov X12_TMP.16b, X12.16b; mov X13_TMP.16b, X13.16b; str CTR, [INPUT_CTR]; @@ -208,19 +208,19 @@ _gcry_chacha20_aarch64_blocks4: PLUS(X12, X12_TMP); /* INPUT + 12 * 4 + counter */ PLUS(X13, X13_TMP); /* INPUT + 13 * 4 + counter */ - dup VTMP2.4s, VTMP0.4s[0]; /* INPUT + 0 * 4 */ - dup VTMP3.4s, VTMP0.4s[1]; /* INPUT + 1 * 4 */ - dup X12_TMP.4s, VTMP0.4s[2]; /* INPUT + 2 * 4 */ - dup X13_TMP.4s, VTMP0.4s[3]; /* INPUT + 3 * 4 */ + dup VTMP2.4s, VTMP0.s[0]; /* INPUT + 0 * 4 */ + dup VTMP3.4s, VTMP0.s[1]; /* INPUT + 1 * 4 */ + dup X12_TMP.4s, VTMP0.s[2]; /* INPUT + 2 * 4 */ + dup X13_TMP.4s, VTMP0.s[3]; /* INPUT + 3 * 4 */ PLUS(X0, VTMP2); PLUS(X1, VTMP3); PLUS(X2, X12_TMP); PLUS(X3, X13_TMP); - dup VTMP2.4s, VTMP1.4s[0]; /* INPUT + 4 * 4 */ - dup VTMP3.4s, VTMP1.4s[1]; /* INPUT + 5 * 4 */ - dup X12_TMP.4s, VTMP1.4s[2]; /* INPUT + 6 * 4 */ - dup X13_TMP.4s, VTMP1.4s[3]; /* INPUT + 7 * 4 */ + dup VTMP2.4s, VTMP1.s[0]; /* INPUT + 4 * 4 */ + dup VTMP3.4s, VTMP1.s[1]; /* INPUT + 5 * 4 */ + dup X12_TMP.4s, VTMP1.s[2]; /* INPUT + 6 * 4 */ + dup X13_TMP.4s, VTMP1.s[3]; /* INPUT + 7 * 4 */ ld1 {VTMP0.16b, VTMP1.16b}, [INPUT_POS]; mov INPUT_POS, INPUT; PLUS(X4, VTMP2); @@ -228,12 +228,12 @@ _gcry_chacha20_aarch64_blocks4: PLUS(X6, X12_TMP); PLUS(X7, X13_TMP); - dup VTMP2.4s, VTMP0.4s[0]; /* INPUT + 8 * 4 */ - dup VTMP3.4s, VTMP0.4s[1]; /* INPUT + 9 * 4 */ - dup X12_TMP.4s, VTMP0.4s[2]; /* INPUT + 10 * 4 */ - dup X13_TMP.4s, VTMP0.4s[3]; /* INPUT + 11 * 4 */ - dup VTMP0.4s, VTMP1.4s[2]; /* INPUT + 14 * 4 */ - dup VTMP1.4s, VTMP1.4s[3]; /* INPUT + 15 * 4 */ + dup VTMP2.4s, VTMP0.s[0]; /* INPUT + 8 * 4 */ + dup VTMP3.4s, VTMP0.s[1]; /* INPUT + 9 * 4 */ + dup X12_TMP.4s, VTMP0.s[2]; /* INPUT + 10 * 4 */ + dup X13_TMP.4s, VTMP0.s[3]; /* INPUT + 11 * 4 */ + dup VTMP0.4s, VTMP1.s[2]; /* INPUT + 14 * 4 */ + dup VTMP1.4s, VTMP1.s[3]; /* INPUT + 15 * 4 */ PLUS(X8, VTMP2); PLUS(X9, VTMP3); PLUS(X10, X12_TMP); commit ec0a2f25c0f64a7b65b373508ce9081e10461965 Author: Martin Storsj? Date: Thu Mar 22 23:32:37 2018 +0200 aarch64: mpi: Fix building the mpi aarch64 assembly for windows * mpi/aarch64/mpih-add1.S: Use ELF macro. * mpi/aarch64/mpih-mul1.S: Use ELF macro. * mpi/aarch64/mpih-mul2.S: Use ELF macro. * mpi/aarch64/mpih-mul3.S: Use ELF macro. * mpi/aarch64/mpih-sub1.S: Use ELF macro. * mpi/asm-common-aarch64.h: New. -- The mpi aarch64 assembly is enabled as soon as the compiler supports inline assembly, without checking for .type and .size, as is done for the rest of the assembly in cipher/*.S. (The .type and .size directives are only supported on ELF.) Signed-off-by: Martin Storsj? diff --git a/mpi/aarch64/mpih-add1.S b/mpi/aarch64/mpih-add1.S index fa8cd01..4ead1c2 100644 --- a/mpi/aarch64/mpih-add1.S +++ b/mpi/aarch64/mpih-add1.S @@ -22,6 +22,7 @@ #include "sysdep.h" #include "asm-syntax.h" +#include "asm-common-aarch64.h" /******************* * mpi_limb_t @@ -34,7 +35,7 @@ .text .globl _gcry_mpih_add_n -.type _gcry_mpih_add_n,%function +ELF(.type _gcry_mpih_add_n,%function) _gcry_mpih_add_n: and x5, x3, #3; adds xzr, xzr, xzr; /* clear carry flag */ @@ -68,4 +69,4 @@ _gcry_mpih_add_n: .Lend: adc x0, xzr, xzr; ret; -.size _gcry_mpih_add_n,.-_gcry_mpih_add_n; +ELF(.size _gcry_mpih_add_n,.-_gcry_mpih_add_n;) diff --git a/mpi/aarch64/mpih-mul1.S b/mpi/aarch64/mpih-mul1.S index 65e98fe..8a86269 100644 --- a/mpi/aarch64/mpih-mul1.S +++ b/mpi/aarch64/mpih-mul1.S @@ -22,6 +22,7 @@ #include "sysdep.h" #include "asm-syntax.h" +#include "asm-common-aarch64.h" /******************* * mpi_limb_t @@ -34,7 +35,7 @@ .text .globl _gcry_mpih_mul_1 -.type _gcry_mpih_mul_1,%function +ELF(.type _gcry_mpih_mul_1,%function) _gcry_mpih_mul_1: and x5, x2, #3; mov x4, xzr; @@ -93,4 +94,4 @@ _gcry_mpih_mul_1: .Lend: mov x0, x4; ret; -.size _gcry_mpih_mul_1,.-_gcry_mpih_mul_1; +ELF(.size _gcry_mpih_mul_1,.-_gcry_mpih_mul_1;) diff --git a/mpi/aarch64/mpih-mul2.S b/mpi/aarch64/mpih-mul2.S index bd3b2c9..c7c08e5 100644 --- a/mpi/aarch64/mpih-mul2.S +++ b/mpi/aarch64/mpih-mul2.S @@ -22,6 +22,7 @@ #include "sysdep.h" #include "asm-syntax.h" +#include "asm-common-aarch64.h" /******************* * mpi_limb_t @@ -34,7 +35,7 @@ .text .globl _gcry_mpih_addmul_1 -.type _gcry_mpih_addmul_1,%function +ELF(.type _gcry_mpih_addmul_1,%function) _gcry_mpih_addmul_1: and x5, x2, #3; mov x6, xzr; @@ -105,4 +106,4 @@ _gcry_mpih_addmul_1: .Lend: mov x0, x6; ret; -.size _gcry_mpih_addmul_1,.-_gcry_mpih_addmul_1; +ELF(.size _gcry_mpih_addmul_1,.-_gcry_mpih_addmul_1;) diff --git a/mpi/aarch64/mpih-mul3.S b/mpi/aarch64/mpih-mul3.S index a58bc53..ccc961e 100644 --- a/mpi/aarch64/mpih-mul3.S +++ b/mpi/aarch64/mpih-mul3.S @@ -22,6 +22,7 @@ #include "sysdep.h" #include "asm-syntax.h" +#include "asm-common-aarch64.h" /******************* * mpi_limb_t @@ -34,7 +35,7 @@ .text .globl _gcry_mpih_submul_1 -.type _gcry_mpih_submul_1,%function +ELF(.type _gcry_mpih_submul_1,%function) _gcry_mpih_submul_1: and x5, x2, #3; mov x7, xzr; @@ -118,4 +119,4 @@ _gcry_mpih_submul_1: .Loop_end: cinc x0, x7, cc; ret; -.size _gcry_mpih_submul_1,.-_gcry_mpih_submul_1; +ELF(.size _gcry_mpih_submul_1,.-_gcry_mpih_submul_1;) diff --git a/mpi/aarch64/mpih-sub1.S b/mpi/aarch64/mpih-sub1.S index cbf2f08..4a66373 100644 --- a/mpi/aarch64/mpih-sub1.S +++ b/mpi/aarch64/mpih-sub1.S @@ -22,6 +22,7 @@ #include "sysdep.h" #include "asm-syntax.h" +#include "asm-common-aarch64.h" /******************* * mpi_limb_t @@ -34,7 +35,7 @@ .text .globl _gcry_mpih_sub_n -.type _gcry_mpih_sub_n,%function +ELF(.type _gcry_mpih_sub_n,%function) _gcry_mpih_sub_n: and x5, x3, #3; subs xzr, xzr, xzr; /* prepare carry flag for sub */ @@ -68,4 +69,4 @@ _gcry_mpih_sub_n: .Lend: cset x0, cc; ret; -.size _gcry_mpih_sub_n,.-_gcry_mpih_sub_n; +ELF(.size _gcry_mpih_sub_n,.-_gcry_mpih_sub_n;) diff --git a/mpi/asm-common-aarch64.h b/mpi/asm-common-aarch64.h new file mode 100644 index 0000000..1269413 --- /dev/null +++ b/mpi/asm-common-aarch64.h @@ -0,0 +1,30 @@ +/* asm-common-aarch64.h - Common macros for AArch64 assembly + * + * Copyright (C) 2018 Martin Storsj? + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#ifndef MPI_ASM_COMMON_AARCH64_H +#define MPI_ASM_COMMON_AARCH64_H + +#ifdef __ELF__ +# define ELF(...) __VA_ARGS__ +#else +# define ELF(...) /*_*/ +#endif + +#endif /* MPI_ASM_COMMON_AARCH64_H */ commit ed41d6d6fb4551342b22ef763de1bd60e964e186 Author: Martin Storsj? Date: Thu Mar 22 23:32:36 2018 +0200 random: Don't assume that _WIN64 implies x86_64 * random/rndw32.c: Change _WIN64 ifdef into __x86_64__. -- This fixes building this file for windows on aarch64. Signed-off-by: Martin Storsj? diff --git a/random/rndw32.c b/random/rndw32.c index 7e9ac50..08a8867 100644 --- a/random/rndw32.c +++ b/random/rndw32.c @@ -986,7 +986,7 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, On AMD64, TSC is always available and intrinsic is provided for accessing it. */ -#ifdef __WIN64__ +#ifdef __x86_64__ { unsigned __int64 aint64; @@ -1024,7 +1024,7 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, (*add) (&aword, sizeof (aword), origin ); } } -#endif /*__WIN64__*/ +#endif /*__x86_64__*/ } commit 8ee38806245ca8452051b1a245f44082323f37f6 Author: Jussi Kivilinna Date: Wed Mar 28 20:32:56 2018 +0300 Register DCO for Martin Storsj? -- Signed-off-by: Jussi Kivilinna diff --git a/AUTHORS b/AUTHORS index 8c553e6..49ab941 100644 --- a/AUTHORS +++ b/AUTHORS @@ -172,6 +172,9 @@ Jussi Kivilinna Markus Teich 2014-10-08:20141008180509.GA2770 at trolle: +Martin Storsj? +2018-03-28:dc1605ce-a47d-34c5-8851-d9569f9ea5d3 at martin.st: + Mathias L. Baumann 2017-01-30:07c06d79-0828-b564-d604-fd16c7c86ebe at sociomantic.com: ----------------------------------------------------------------------- Summary of changes: AUTHORS | 3 ++ mpi/ec-ed25519.c => cipher/asm-common-aarch64.h | 29 +++++----- cipher/camellia-aarch64.S | 25 +++++---- cipher/chacha20-aarch64.S | 72 +++++++++++++------------ cipher/cipher-gcm-armv8-aarch64-ce.S | 10 ++-- cipher/rijndael-aarch64.S | 10 ++-- cipher/rijndael-armv8-aarch64-ce.S | 58 ++++++++++---------- cipher/sha1-armv8-aarch64-ce.S | 6 +-- cipher/sha256-armv8-aarch64-ce.S | 6 +-- cipher/twofish-aarch64.S | 10 ++-- configure.ac | 4 -- mpi/aarch64/mpih-add1.S | 5 +- mpi/aarch64/mpih-mul1.S | 5 +- mpi/aarch64/mpih-mul2.S | 5 +- mpi/aarch64/mpih-mul3.S | 5 +- mpi/aarch64/mpih-sub1.S | 5 +- mpi/{ec-internal.h => asm-common-aarch64.h} | 17 +++--- random/rndw32.c | 4 +- 18 files changed, 147 insertions(+), 132 deletions(-) copy mpi/ec-ed25519.c => cipher/asm-common-aarch64.h (68%) copy mpi/{ec-internal.h => asm-common-aarch64.h} (69%) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 28 21:15:40 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 28 Mar 2018 21:15:40 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-166-g4b2fa65 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 4b2fa657d195382d14ac99be40b66327e0fc855c (commit) from 7c220e387d511b0cf66f99370759c36b729cc444 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4b2fa657d195382d14ac99be40b66327e0fc855c Author: Werner Koch Date: Wed Mar 28 20:50:54 2018 +0200 json: Make native messaging work. * src/gpgme-json.c (opt_debug): New. (process_request): Add optional arg nm_mode. In this mode take the request from a "message" object. (native_messaging_repl): Add debug output and call process_request in NM_MODE. (main): Add option --debug. Parse envvar GPGME_JSON_DEBUG as an alternative way to enable this. Use a default log file. -- Note that the default log file is ~/.gnupg/S.gpgme-json.log . Thus to debug a javascript application you should start watchgnupg --time-only --force ~/.gnupg/S.gpgme-json.log in a separate tty and then use GPGME_JSON_DEBUG=1 firefox & to run firefox. Signed-off-by: Werner Koch diff --git a/src/gpgme-json.c b/src/gpgme-json.c index e38f9d8..e5c84bb 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -56,7 +56,8 @@ static char *error_object_string (const char *message, /* True if interactive mode is active. */ static int opt_interactive; - +/* True is debug mode is active. */ +static int opt_debug; /* @@ -754,9 +755,10 @@ op_help (cjson_t request, cjson_t result) /* Process a request and return the response. The response is a newly - * allocated staring or NULL in case of an error. */ + * allocated staring or NULL in case of an error. With NM_MODE set + * the actual request is taken from a "message" object. */ static char * -process_request (const char *request) +process_request (const char *request, int nm_mode) { static struct { const char *op; @@ -770,6 +772,7 @@ process_request (const char *request) { NULL } }; size_t erroff; + cjson_t json_orig; cjson_t json; cjson_t j_tmp, j_op; cjson_t response; @@ -780,7 +783,7 @@ process_request (const char *request) response = xjson_CreateObject (); - json = cJSON_Parse (request, &erroff); + json = json_orig = cJSON_Parse (request, &erroff); if (!json) { log_string (GPGRT_LOGLVL_INFO, request); @@ -788,6 +791,16 @@ process_request (const char *request) error_object (response, "invalid JSON object at offset %zu\n", erroff); goto leave; } + if (nm_mode) + { + json = cJSON_GetObjectItem (json, "message"); + if (!json) + { + log_info ("no \"message\" object in request\n"); + error_object (response, "no \"message\" object in request\n"); + goto leave; + } + } j_tmp = cJSON_GetObjectItem (json, "help"); helpmode = (j_tmp && cjson_is_true (j_tmp)); @@ -844,8 +857,7 @@ process_request (const char *request) } leave: - cJSON_Delete (json); - json = NULL; + cJSON_Delete (json_orig); if (opt_interactive) res = cJSON_Print (response); else @@ -930,7 +942,7 @@ process_meta_commands (const char *request) "\"\\nMeta commands:\\n" " ,help This help\\n" " ,quit Terminate process\"" - "}"); + "}", 0); else if (!strncmp (request, "quit", 4) && (spacep (request+4) || !request[4])) exit (0); else @@ -1029,7 +1041,7 @@ interactive_repl (void) } else if (request) { - response = process_request (request); + response = process_request (request, 0); } xfree (request); request = NULL; @@ -1072,7 +1084,7 @@ interactive_repl (void) } -/* Read and process asingle request. */ +/* Read and process a single request. */ static void read_and_process_single_request (void) { @@ -1093,7 +1105,7 @@ read_and_process_single_request (void) if (request) { xfree (response); - response = process_request (request); + response = process_request (request, 0); if (response) { es_fputs (response, es_stdout); @@ -1126,6 +1138,7 @@ native_messaging_repl (void) * binary mode. */ es_set_binary (es_stdin); es_set_binary (es_stdout); + es_setbuf (es_stdin, NULL); for (;;) { @@ -1149,7 +1162,7 @@ native_messaging_repl (void) { log_error ("error reading request: request too long (%zu MiB)\n", (size_t)nrequest / (1024*1024)); - /* Fixme: Shall we read the request t the bit bucket and + /* Fixme: Shall we read the request to the bit bucket and * return an error reponse or just return an error reponse * and terminate? Needs some testing. */ break; @@ -1181,8 +1194,12 @@ native_messaging_repl (void) } else /* Process request */ { + if (opt_debug) + log_debug ("request='%s'\n", request); xfree (response); - response = process_request (request); + response = process_request (request, 1); + if (opt_debug) + log_debug ("response='%s'\n", response); } nresponse = strlen (response); @@ -1263,12 +1280,18 @@ main (int argc, char *argv[]) enum { CMD_DEFAULT = 0, CMD_INTERACTIVE = 'i', CMD_SINGLE = 's', - CMD_LIBVERSION = 501 + CMD_LIBVERSION = 501, } cmd = CMD_DEFAULT; + enum { + OPT_DEBUG = 600 + }; + static gpgrt_opt_t opts[] = { ARGPARSE_c (CMD_INTERACTIVE, "interactive", "Interactive REPL"), ARGPARSE_c (CMD_SINGLE, "single", "Single request mode"), ARGPARSE_c (CMD_LIBVERSION, "lib-version", "Show library version"), + ARGPARSE_s_n(OPT_DEBUG, "debug", "Flyswatter"), + ARGPARSE_end() }; gpgrt_argparse_t pargs = { &argc, &argv}; @@ -1298,6 +1321,8 @@ main (int argc, char *argv[]) cmd = pargs.r_opt; break; + case OPT_DEBUG: opt_debug = 1; break; + default: pargs.err = ARGPARSE_PRINT_WARNING; break; @@ -1305,6 +1330,29 @@ main (int argc, char *argv[]) } gpgrt_argparse (NULL, &pargs, NULL); + if (!opt_debug) + { + const char *s = getenv ("GPGME_JSON_DEBUG"); + if (s && atoi (s) > 0) + opt_debug = 1; + } + + if (opt_debug) + { + const char *home = getenv ("HOME"); + char *file = xstrconcat ("socket://", + home? home:"/tmp", + "/.gnupg/S.gpgme-json.log", NULL); + log_set_file (file); + xfree (file); + } + + if (opt_debug) + { int i; + for (i=0; argv[i]; i++) + log_debug ("argv[%d]='%s'\n", i, argv[i]); + } + switch (cmd) { case CMD_DEFAULT: @@ -1327,6 +1375,9 @@ main (int argc, char *argv[]) break; } + if (opt_debug) + log_debug ("ready"); + #endif /* This is a modern libgp-error. */ return 0; } ----------------------------------------------------------------------- Summary of changes: src/gpgme-json.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 13 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 28 21:28:07 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 28 Mar 2018 21:28:07 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-167-g3345a17 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 3345a17dda2222e3c1592235e8a1cd9493192777 (commit) from 4b2fa657d195382d14ac99be40b66327e0fc855c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3345a17dda2222e3c1592235e8a1cd9493192777 Author: Werner Koch Date: Wed Mar 28 21:21:10 2018 +0200 json: Remove the "message" object thingy again. * src/gpgme-json.c (process_request): Remove 'nm_mode'. -- This was an error in the javascript testing code. Thus the Mozilla specs are correct that the request is send verbatim. Signed-off-by: Werner Koch diff --git a/src/gpgme-json.c b/src/gpgme-json.c index e5c84bb..5f16daf 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -755,10 +755,9 @@ op_help (cjson_t request, cjson_t result) /* Process a request and return the response. The response is a newly - * allocated staring or NULL in case of an error. With NM_MODE set - * the actual request is taken from a "message" object. */ + * allocated string or NULL in case of an error. */ static char * -process_request (const char *request, int nm_mode) +process_request (const char *request) { static struct { const char *op; @@ -772,7 +771,6 @@ process_request (const char *request, int nm_mode) { NULL } }; size_t erroff; - cjson_t json_orig; cjson_t json; cjson_t j_tmp, j_op; cjson_t response; @@ -783,7 +781,7 @@ process_request (const char *request, int nm_mode) response = xjson_CreateObject (); - json = json_orig = cJSON_Parse (request, &erroff); + json = cJSON_Parse (request, &erroff); if (!json) { log_string (GPGRT_LOGLVL_INFO, request); @@ -791,16 +789,6 @@ process_request (const char *request, int nm_mode) error_object (response, "invalid JSON object at offset %zu\n", erroff); goto leave; } - if (nm_mode) - { - json = cJSON_GetObjectItem (json, "message"); - if (!json) - { - log_info ("no \"message\" object in request\n"); - error_object (response, "no \"message\" object in request\n"); - goto leave; - } - } j_tmp = cJSON_GetObjectItem (json, "help"); helpmode = (j_tmp && cjson_is_true (j_tmp)); @@ -857,7 +845,7 @@ process_request (const char *request, int nm_mode) } leave: - cJSON_Delete (json_orig); + cJSON_Delete (json); if (opt_interactive) res = cJSON_Print (response); else @@ -942,7 +930,7 @@ process_meta_commands (const char *request) "\"\\nMeta commands:\\n" " ,help This help\\n" " ,quit Terminate process\"" - "}", 0); + "}"); else if (!strncmp (request, "quit", 4) && (spacep (request+4) || !request[4])) exit (0); else @@ -1041,7 +1029,7 @@ interactive_repl (void) } else if (request) { - response = process_request (request, 0); + response = process_request (request); } xfree (request); request = NULL; @@ -1105,7 +1093,7 @@ read_and_process_single_request (void) if (request) { xfree (response); - response = process_request (request, 0); + response = process_request (request); if (response) { es_fputs (response, es_stdout); @@ -1138,7 +1126,7 @@ native_messaging_repl (void) * binary mode. */ es_set_binary (es_stdin); es_set_binary (es_stdout); - es_setbuf (es_stdin, NULL); + es_setbuf (es_stdin, NULL); /* stdin needs to be unbuffered! */ for (;;) { @@ -1197,7 +1185,7 @@ native_messaging_repl (void) if (opt_debug) log_debug ("request='%s'\n", request); xfree (response); - response = process_request (request, 1); + response = process_request (request); if (opt_debug) log_debug ("response='%s'\n", response); } ----------------------------------------------------------------------- Summary of changes: src/gpgme-json.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 28 22:28:08 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 28 Mar 2018 22:28:08 +0200 Subject: [git] GPGME - branch, ben/howto-update-02, updated. gpgme-1.10.0-170-g2f507b0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/howto-update-02 has been updated via 2f507b045909d32bf29d23da04db02b078e5fb9d (commit) via 5cd419341807d8ae23fec7bd9bb7025a8a2dcb3c (commit) from a2eedef630891397f8eccb5bb426a0728588bf41 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2f507b045909d32bf29d23da04db02b078e5fb9d Author: Ben McGinnes Date: Thu Mar 29 07:22:37 2018 +1100 docs python bindings howto * PEP8 compliance: a collection of minor edits across multiple example code snippets. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 5e1e0ab..1be9369 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -165,7 +165,7 @@ This package is the origin of these bindings, though they are somewhat different now. For details of when and how the PyME package was folded back into GPGME itself see the /Short History/ - document[fn:1] in this Python bindings =docs= directory.[fn:2] + document[fn:1] in the Python bindings =docs= directory.[fn:2] The PyME package was first released in 2002 and was also the first attempt to implement a low level binding to GPGME. In doing so it @@ -537,8 +537,7 @@ c = gpg.Context(armor=True) rkey = list(c.keylist(pattern=a_key, secret=False)) ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, - sign=True, always_trust=True, - add_encrypt_to=True) + sign=True, always_trust=True, add_encrypt_to=True) with open("secret_plans.txt.asc", "wb") as afile: afile.write(ciphertext) @@ -589,10 +588,10 @@ logrus.append(rpattern[i]) ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, sign=False, - always_trust=True) + always_trust=True) with open("secret_plans.txt.asc", "wb") as afile: - afile.write(ciphertext) + afile.write(ciphertext) #+end_src All it would take to change the above example to sign the message @@ -601,7 +600,7 @@ #+begin_src python ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, - always_trust=True, + always_trust=True, add_encrypt_to=True) #+end_src @@ -619,7 +618,7 @@ import gpg with open("secret_plans.txt.asc", "rb") as afile: - text = afile.read() + text = afile.read() c = gpg.Context(armor=True) rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) @@ -630,21 +629,23 @@ logrus.append(rpattern[i]) try: - ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True) + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, + add_encrypt_to=True) except gpg.errors.InvalidRecipients as e: for i in range(len(e.recipients)): for n in range(len(logrus)): if logrus[n].fpr == e.recipients[i].fpr: logrus.remove(logrus[n]) - else: - pass + else: + pass try: - ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True) + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, + add_encrypt_to=True) except: pass with open("secret_plans.txt.asc", "wb") as afile: - afile.write(ciphertext) + afile.write(ciphertext) #+end_src This will attempt to encrypt to all the keys searched for, then @@ -670,10 +671,12 @@ ciphertext = input("Enter path and filename of encrypted file: ") newfile = input("Enter path and filename of file to save decrypted data to: ") + with open(ciphertext, "rb") as cfile: - plaintext, result, verify_result = gpg.Context().decrypt(cfile) + plaintext, result, verify_result = gpg.Context().decrypt(cfile) + with open(newfile, "wb") as nfile: - nfile.write(plaintext) + nfile.write(plaintext) #+end_src The data available in =plaintext= in this example is the decrypted @@ -1172,7 +1175,7 @@ c = gpg.Context() c.home_dir = "~/.gnupg-dm" - key = c.get_key(dmkey.fpr, secret = True) + key = c.get_key(dmkey.fpr, secret=True) dmsub = c.create_subkey(key, algorithm="rsa3072", expires_in=15768000, encrypt=True) #+end_src @@ -1223,7 +1226,7 @@ c.home_dir = "~/.gnupg-dm" dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" - key = c.get_key(dmfpr, secret = True) + key = c.get_key(dmfpr, secret=True) uid = "Danger Mouse " c.key_add_uid(key, uid) commit 5cd419341807d8ae23fec7bd9bb7025a8a2dcb3c Author: Ben McGinnes Date: Thu Mar 29 06:36:14 2018 +1100 example: add user ID * Added script to add a UID to an existing key. diff --git a/lang/python/examples/howto/add-userid.py b/lang/python/examples/howto/add-userid.py new file mode 100755 index 0000000..b868979 --- /dev/null +++ b/lang/python/examples/howto/add-userid.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path + +print(""" +This script adds a new user ID to an existing key. + +The gpg-agent and pinentry are invoked to enter the passphrase. +""") + +c = gpg.Context() + +homedir = input("Enter the GPG configuration directory path (optional): ") +fpr0 = input("Enter the fingerprint of the key to modify: ") +uid_name = input("Enter the name of the user ID: ") +uid_email = input("Enter the email address of the user ID: ") +uid_cmnt = input("Enter a comment to include (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +fpr = "".join(fpr0.split()) + +if len(uid_cmnt) > 0: + userid = "{0} ({1}) <{2}>".format(uid_name, uid_cmnt, uid_email) +else: + userid = "{0} <{2}>".format(uid_name, uid_email) + +key = c.get_key(fpr, secret=True) +c.key_add_uid(key, userid) ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 35 ++++++++-------- .../howto/{create-key.py => add-userid.py} | 47 ++++------------------ 2 files changed, 26 insertions(+), 56 deletions(-) copy lang/python/examples/howto/{create-key.py => add-userid.py} (61%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 29 00:51:26 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 29 Mar 2018 00:51:26 +0200 Subject: [git] GPGME - branch, ben/howto-update-02, updated. gpgme-1.10.0-172-g56bbfd3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/howto-update-02 has been updated via 56bbfd39acea90eb87a28b11a515b0314cdda54c (commit) via 5a553f5a317e5ad5ab0274d58854df1ecf390e0d (commit) from 2f507b045909d32bf29d23da04db02b078e5fb9d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 56bbfd39acea90eb87a28b11a515b0314cdda54c Author: Ben McGinnes Date: Thu Mar 29 09:49:08 2018 +1100 example: key signing * Added script for signing or certifying keys. diff --git a/lang/python/examples/howto/sign-key.py b/lang/python/examples/howto/sign-key.py new file mode 100755 index 0000000..b1afe13 --- /dev/null +++ b/lang/python/examples/howto/sign-key.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path + +print(""" +This script signs or certifies a key. + +The gpg-agent and pinentry are invoked to enter the passphrase. +""") + +c = gpg.Context() + +homedir = input("Enter the GPG configuration directory path (optional): ") +fpr0 = input("Enter the fingerprint of the key to sign: ") +userid = input("Enter the UID to sign (case sensitive, optional): ") +sig_type = input("Enter the certification type (local or normal): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +fpr = "".join(fpr0.split()) +key = c.get_key(fpr, secret=False) + +if len(userid) > 0 and sig_type.lower() == "local": + c.key_sign(key, uids=userid, local=True) +elif len(userid) > 0 and sig_type.lower() != "local": + c.key_sign(key, uids=userid) +elif len(userid) == 0 and sig_type.lower() == "local": + c.key_sign(key, local=True) +else: + c.key_sign(key) commit 5a553f5a317e5ad5ab0274d58854df1ecf390e0d Author: Ben McGinnes Date: Thu Mar 29 09:22:17 2018 +1100 doc: python bindings howto * Fixed a typo. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 1be9369..4cd4098 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1259,7 +1259,7 @@ The =key_sign= method takes four arguments: =key=, =uids=, =expires_in= and =local=. The default value of =uids= is =None= and which results in all user IDs being selected. The default - values of =expires_in= snd =local= is =False=; which result in the + values of =expires_in= and =local= is =False=; which result in the signature never expiring and being able to be exported. The =key= is the key being signed rather than the key doing the ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 2 +- .../examples/howto/{add-userid.py => sign-key.py} | 25 +++++++++++----------- 2 files changed, 14 insertions(+), 13 deletions(-) copy lang/python/examples/howto/{add-userid.py => sign-key.py} (74%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 29 01:26:08 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 29 Mar 2018 01:26:08 +0200 Subject: [git] GPGME - branch, ben/howto-update-02, updated. gpgme-1.10.0-174-g3b91f6a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/howto-update-02 has been updated via 3b91f6af378ccc37dcf8924cbc157894c35b5192 (commit) via d65864989c0560b5f51cb8d05d9ea9f1957b453e (commit) from 56bbfd39acea90eb87a28b11a515b0314cdda54c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3b91f6af378ccc37dcf8924cbc157894c35b5192 Author: Ben McGinnes Date: Thu Mar 29 10:21:52 2018 +1100 example: revoke UID * Script to revoke a UID on an existing key. diff --git a/lang/python/examples/howto/revoke-userid.py b/lang/python/examples/howto/revoke-userid.py new file mode 100755 index 0000000..7a3d190 --- /dev/null +++ b/lang/python/examples/howto/revoke-userid.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path + +print(""" +This script revokes a user ID on an existing key. + +The gpg-agent and pinentry are invoked to enter the passphrase. +""") + +c = gpg.Context() + +homedir = input("Enter the GPG configuration directory path (optional): ") +fpr0 = input("Enter the fingerprint of the key to modify: ") +uid_name = input("Enter the name of the user ID: ") +uid_email = input("Enter the email address of the user ID: ") +uid_cmnt = input("Enter a comment to include (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +fpr = "".join(fpr0.split()) + +if len(uid_cmnt) > 0: + userid = "{0} ({1}) <{2}>".format(uid_name, uid_cmnt, uid_email) +else: + userid = "{0} <{2}>".format(uid_name, uid_email) + +key = c.get_key(fpr, secret=True) +c.key_revoke_uid(key, userid) commit d65864989c0560b5f51cb8d05d9ea9f1957b453e Author: Ben McGinnes Date: Thu Mar 29 10:16:07 2018 +1100 docs: python bindings howto * Added section on revoking UIDs. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 4cd4098..d51eb11 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1214,38 +1214,66 @@ :CUSTOM_ID: keygen-uids :END: - By comparison to creating primary keys and subkeys, adding a new - user ID to an existing key is much simpler. The method used to do - this is =key_add_uid= and the only arguments it takes are for the - =key= and the new =uid=. - #+begin_src python - import gpg +*** Adding User IDs + :PROPERTIES: + :CUSTOM_ID: keygen-uids-add + :END: - c = gpg.Context() - c.home_dir = "~/.gnupg-dm" + By comparison to creating primary keys and subkeys, adding a new + user ID to an existing key is much simpler. The method used to do + this is =key_add_uid= and the only arguments it takes are for the + =key= and the new =uid=. - dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" - key = c.get_key(dmfpr, secret=True) - uid = "Danger Mouse " + #+begin_src python + import gpg - c.key_add_uid(key, uid) - #+end_src + c = gpg.Context() + c.home_dir = "~/.gnupg-dm" - Unsurprisingly the result of this is: + dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" + key = c.get_key(dmfpr, secret=True) + uid = "Danger Mouse " - #+begin_src shell - bash-4.4$ gpg --homedir ~/.gnupg-dm -K - ~/.gnupg-dm/pubring.kbx - ---------------------- - sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] - 177B7C25DB99745EE2EE13ED026D2F19E99E63AA - uid [ultimate] Danger Mouse - uid [ultimate] Danger Mouse - ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13] + c.key_add_uid(key, uid) + #+end_src - bash-4.4$ - #+end_src + Unsurprisingly the result of this is: + + #+begin_src shell + bash-4.4$ gpg --homedir ~/.gnupg-dm -K + ~/.gnupg-dm/pubring.kbx + ---------------------- + sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] + 177B7C25DB99745EE2EE13ED026D2F19E99E63AA + uid [ultimate] Danger Mouse + uid [ultimate] Danger Mouse + ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13] + + bash-4.4$ + #+end_src + + +*** Revokinging User IDs + :PROPERTIES: + :CUSTOM_ID: keygen-uids-revoke + :END: + + Revoking a user ID is a fairly similar process, except that it + uses the =key_revoke_uid= method. + + #+begin_src python + import gpg + + c = gpg.Context() + c.home_dir = "~/.gnupg-dm" + + dmfpr = "177B7C25DB99745EE2EE13ED026D2F19E99E63AA" + key = c.get_key(dmfpr, secret=True) + uid = "Danger Mouse " + + c.key_revoke_uid(key, uid) + #+end_src ** Key certification ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 78 +++++++++++++++------- .../howto/{add-userid.py => revoke-userid.py} | 4 +- 2 files changed, 55 insertions(+), 27 deletions(-) copy lang/python/examples/howto/{add-userid.py => revoke-userid.py} (96%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 29 01:29:39 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 29 Mar 2018 01:29:39 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-178-g75a1a1c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 75a1a1c33efe952986bba56494b81e2f4835b8c4 (commit) via 3b91f6af378ccc37dcf8924cbc157894c35b5192 (commit) via d65864989c0560b5f51cb8d05d9ea9f1957b453e (commit) via 56bbfd39acea90eb87a28b11a515b0314cdda54c (commit) via 5a553f5a317e5ad5ab0274d58854df1ecf390e0d (commit) via 2f507b045909d32bf29d23da04db02b078e5fb9d (commit) via 5cd419341807d8ae23fec7bd9bb7025a8a2dcb3c (commit) via a2eedef630891397f8eccb5bb426a0728588bf41 (commit) via f9159b1d75d3209b1c22bbb0ed4472800b60a522 (commit) via 1b5da37a47ceef41545e0b2474738613f36be949 (commit) via 5b32efbaf37920b2e99d4bb87cb383b2809b1688 (commit) from 3345a17dda2222e3c1592235e8a1cd9493192777 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 75a1a1c33efe952986bba56494b81e2f4835b8c4 Merge: 3345a17 3b91f6a Author: Ben McGinnes Date: Thu Mar 29 10:27:41 2018 +1100 Merge branch 'ben/howto-update-02' of ssh+git://playfair.gnupg.org/git/gpgme ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 126 +++++++++++++-------- .../howto/{verify-signed-file.py => add-userid.py} | 55 ++++----- lang/python/examples/howto/create-key.py | 95 ++++++++++++++++ .../{verify-signed-file.py => revoke-userid.py} | 55 ++++----- .../howto/{verify-signed-file.py => sign-key.py} | 56 ++++----- lang/python/examples/howto/temp-homedir-config.py | 11 +- 6 files changed, 268 insertions(+), 130 deletions(-) copy lang/python/examples/howto/{verify-signed-file.py => add-userid.py} (56%) create mode 100755 lang/python/examples/howto/create-key.py copy lang/python/examples/howto/{verify-signed-file.py => revoke-userid.py} (56%) copy lang/python/examples/howto/{verify-signed-file.py => sign-key.py} (54%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 29 05:04:38 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 29 Mar 2018 05:04:38 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-35-ga1515b3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via a1515b3bbc10a210040dda3b482bcdb933fa8d7c (commit) via 02d7bb819ff44cc90212568dd6ce24ae1dc5d17f (commit) from e610d51f0de11154050915b951bcc5c53c940f5e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a1515b3bbc10a210040dda3b482bcdb933fa8d7c Author: NIIBE Yutaka Date: Thu Mar 29 11:56:02 2018 +0900 g10: Support key attribute change at --card-edit/generate. * g10/card-util.c (ask_card_rsa_keysize): Drop support for magic number 25519 for ed25519/cv25519. Rename from ask_card_keyattr. (ask_card_keyattr): Support ECC, as well as RSA. (do_change_keyattr): Support ECC dropping magical number 25519. * g10/keygen.c (ask_curve): Allow call from outside, adding last arg of CURRENT. (generate_keypair): Follow the change of ask_curve. (generate_subkeypair): Likewise. -- GnuPG-bug-id: 3781 Signed-off-by: NIIBE Yutaka diff --git a/g10/card-util.c b/g10/card-util.c index 2aa9c3f..263ab4e 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -1355,11 +1355,10 @@ show_keysize_warning (void) /* Ask for the size of a card key. NBITS is the current size - configured for the card. KEYNO is the number of the key used to - select the prompt. Returns 0 to use the default size (i.e. NBITS) - or the selected size. */ + configured for the card. Returns 0 to use the default size + (i.e. NBITS) or the selected size. */ static unsigned int -ask_card_keyattr (int keyno, unsigned int nbits) +ask_card_rsa_keysize (unsigned int nbits) { unsigned int min_nbits = 1024; unsigned int max_nbits = 4096; @@ -1368,78 +1367,175 @@ ask_card_keyattr (int keyno, unsigned int nbits) for (;;) { - prompt = xasprintf - (keyno == 0? - _("What keysize do you want for the Signature key? (%u) "): - keyno == 1? - _("What keysize do you want for the Encryption key? (%u) "): - _("What keysize do you want for the Authentication key? (%u) "), - nbits); + prompt = xasprintf (_("What keysize do you want? (%u) "), nbits); answer = cpr_get ("cardedit.genkeys.size", prompt); cpr_kill_prompt (); req_nbits = *answer? atoi (answer): nbits; xfree (prompt); xfree (answer); - if (req_nbits == 25519) + if (req_nbits != nbits && (req_nbits % 32) ) { - if (req_nbits == nbits) - return 0; /* Use default. */ + req_nbits = ((req_nbits + 31) / 32) * 32; + tty_printf (_("rounded up to %u bits\n"), req_nbits); + } + + if (req_nbits == nbits) + return 0; /* Use default. */ + if (req_nbits < min_nbits || req_nbits > max_nbits) + { + tty_printf (_("%s keysizes must be in the range %u-%u\n"), + "RSA", min_nbits, max_nbits); + } + else + { tty_printf (_("The card will now be re-configured" - " to generate a key of type: %s\n"), - keyno==1? "cv25519":"ed25519"); + " to generate a key of %u bits\n"), req_nbits); show_keysize_warning (); return req_nbits; } + } +} + +/* Ask for the key attribute of a card key. CURRENT is the current + attribute configured for the card. KEYNO is the number of the key + used to select the prompt. Returns NULL to use the default + attribute or the selected attribute structure. */ +static struct key_attr * +ask_card_keyattr (int keyno, const struct key_attr *current) +{ + struct key_attr *key_attr = NULL; + char *answer = NULL; + int algo; + + tty_printf (_("Changing card key attribute for: ")); + if (keyno == 0) + tty_printf (_("Signature key\n")); + else if (keyno == 1) + tty_printf (_("Encryption key\n")); + else + tty_printf (_("Authentication key\n")); + + tty_printf (_("Please select what kind of key you want:\n")); + tty_printf (_(" (%d) RSA\n"), 1 ); + tty_printf (_(" (%d) ECC\n"), 2 ); + + for (;;) + { + xfree (answer); + answer = cpr_get ("cardedit.genkeys.algo", _("Your selection? ")); + cpr_kill_prompt (); + algo = *answer? atoi (answer) : 0; + + if (!*answer || algo == 1 || algo == 2) + break; else - { - if (req_nbits != nbits && (req_nbits % 32) ) - { - req_nbits = ((req_nbits + 31) / 32) * 32; - tty_printf (_("rounded up to %u bits\n"), req_nbits); - } + tty_printf (_("Invalid selection.\n")); + } + + if (algo == 0) + got leave; - if (req_nbits == nbits) - return 0; /* Use default. */ + key_attr = xmalloc (sizeof (struct key_attr)); - if (req_nbits < min_nbits || req_nbits > max_nbits) + if (algo == 1) + { + unsigned int nbits, result_nbits; + + if (current->algo == PUBKEY_ALGO_RSA) + nbits = current->nbits; + else + nbits = 2048; + + result_nbits = ask_card_rsa_keysize (nbits); + if (result_nbits == 0) + { + if (current->algo == PUBKEY_ALGO_RSA) { - tty_printf (_("%s keysizes must be in the range %u-%u\n"), - "RSA", min_nbits, max_nbits); + xfree (key_attr); + key_attr = NULL; } else - { - tty_printf (_("The card will now be re-configured" - " to generate a key of %u bits\n"), req_nbits); - show_keysize_warning (); - return req_nbits; - } + result_nbits = nbits; + } + + if (key_attr) + { + key_attr->algo = PUBKEY_ALGO_RSA; + key_attr->nbits = result_nbits; + } + } + else + { + const char *curve; + const char *oid_str; + + if (current->algo == PUBKEY_ALGO_RSA) + { + if (keyno == 1) + /* Encryption key */ + algo = PUBKEY_ALGO_ECDH; + else /* Signature key or Authentication key */ + algo = PUBKEY_ALGO_ECDSA; + curve = NULL; + } + else + { + algo = current->algo; + curve = current->curve; + } + + curve = ask_curve (&algo, NULL, curve); + if (curve) + { + key_attr->algo = algo; + oid_str = openpgp_curve_to_oid (curve, NULL); + key_attr->curve = openpgp_oid_to_curve (oid_str, 0); + } + else + { + xfree (key_attr); + key_attr = NULL; } } + + leave: + if (!key_attr) + tty_printf (_("No change.")); + + return key_attr; } -/* Change the size of key KEYNO (0..2) to NBITS and show an error - * message if that fails. Using the magic value 25519 for NBITS - * switches to ed25519 or cv25519 depending on the KEYNO. */ + +/* Change the key attribute of key KEYNO (0..2) and show an error + * message if that fails. */ static gpg_error_t -do_change_keyattr (int keyno, unsigned int nbits) +do_change_keyattr (int keyno, const struct key_attr *key_attr) { - gpg_error_t err; + gpg_error_t err = 0; char args[100]; - if (nbits == 25519) + if (key_attr->algo == PUBKEY_ALGO_RSA) + snprintf (args, sizeof args, "--force %d 1 rsa%u", keyno+1, + key_attr->nbits); + else if (key_attr->algo == PUBKEY_ALGO_ECDH + || key_attr->algo == PUBKEY_ALGO_ECDSA + || key_attr->algo == PUBKEY_ALGO_EDDSA) snprintf (args, sizeof args, "--force %d %d %s", - keyno+1, - keyno == 1? PUBKEY_ALGO_ECDH : PUBKEY_ALGO_EDDSA, - keyno == 1? "cv25519" : "ed25519"); + keyno+1, key_attr->algo, key_attr->curve); else - snprintf (args, sizeof args, "--force %d 1 rsa%u", keyno+1, nbits); + { + log_error (_("public key algorithm %d (%s) is not supported\n"), + key_attr->algo, gcry_pk_algo_name (key_attr->algo)); + return gpg_error (GPG_ERR_PUBKEY_ALGO); + } + err = agent_scd_setattr ("KEY-ATTR", args, strlen (args), NULL); if (err) - log_error (_("error changing size of key %d to %u bits: %s\n"), - keyno+1, nbits, gpg_strerror (err)); + log_error (_("error changing key attribute for key %d: %s\n"), + keyno+1, gpg_strerror (err)); return err; } @@ -1502,26 +1598,21 @@ generate_card_keys (ctrl_t ctrl) key size. */ if (info.is_v2 && info.extcap.aac) { - unsigned int nbits; - for (keyno = 0; keyno < DIM (info.key_attr); keyno++) { - if (info.key_attr[keyno].algo == PUBKEY_ALGO_RSA - || info.key_attr[keyno].algo == PUBKEY_ALGO_ECDH - || info.key_attr[keyno].algo == PUBKEY_ALGO_EDDSA) - { - if (info.key_attr[keyno].algo == PUBKEY_ALGO_RSA) - nbits = ask_card_keyattr (keyno, info.key_attr[keyno].nbits); - else - nbits = ask_card_keyattr (keyno, 25519 /* magic */); + struct key_attr *key_attr; - if (nbits && do_change_keyattr (keyno, nbits)) + if ((key_attr = ask_card_keyattr (keyno, &info.key_attr[keyno]))) + { + gpg_error_t err = do_change_keyattr (keyno, key_attr); + xfree (key_attr); + if (err) { - /* Error: Better read the default key size again. */ + /* Error: Better read the default key attribute again. */ agent_release_card_info (&info); if (get_info_for_key_operation (&info)) goto leave; - /* Ask again for this key size. */ + /* Ask again for this key. */ keyno--; } } @@ -1591,21 +1682,16 @@ card_generate_subkey (ctrl_t ctrl, kbnode_t pub_keyblock) key size. */ if (info.is_v2 && info.extcap.aac) { - if (info.key_attr[keyno-1].algo == PUBKEY_ALGO_RSA - || info.key_attr[keyno].algo == PUBKEY_ALGO_ECDH - || info.key_attr[keyno].algo == PUBKEY_ALGO_EDDSA) - { - unsigned int nbits; - - ask_again: - if (info.key_attr[keyno].algo == PUBKEY_ALGO_RSA) - nbits = ask_card_keyattr (keyno-1, info.key_attr[keyno-1].nbits); - else - nbits = ask_card_keyattr (keyno-1, 25519); + struct key_attr *key_attr; - if (nbits && do_change_keyattr (keyno-1, nbits)) + ask_again: + if ((key_attr = ask_card_keyattr (keyno-1, &info.key_attr[keyno-1]))) + { + err = do_change_keyattr (keyno-1, key_attr); + xfree (key_attr); + if (err) { - /* Error: Better read the default key size again. */ + /* Error: Better read the default key attribute again. */ agent_release_card_info (&info); err = get_info_for_key_operation (&info); if (err) diff --git a/g10/keygen.c b/g10/keygen.c index 1098798..a4949f4 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2235,8 +2235,8 @@ ask_keysize (int algo, unsigned int primary_keysize) /* Ask for the curve. ALGO is the selected algorithm which this function may adjust. Returns a const string of the name of the curve. */ -static const char * -ask_curve (int *algo, int *subkey_algo) +const char * +ask_curve (int *algo, int *subkey_algo, const char *current) { /* NB: We always use a complete algo list so that we have stable numbers in the menu regardless on how Gpg was configured. */ @@ -2327,7 +2327,12 @@ ask_curve (int *algo, int *subkey_algo) answer = cpr_get ("keygen.curve", _("Your selection? ")); cpr_kill_prompt (); idx = *answer? atoi (answer) : 1; - if (*answer && !idx) + if (!*answer && current) + { + xfree(answer); + return NULL; + } + else if (*answer && !idx) { /* See whether the user entered the name of the curve. */ for (idx=0; idx < DIM(curves); idx++) @@ -4263,7 +4268,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH) { - curve = ask_curve (&algo, &subkey_algo); + curve = ask_curve (&algo, &subkey_algo, NULL); r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYTYPE; sprintf( r->u.value, "%d", algo); @@ -4333,7 +4338,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH) { - curve = ask_curve (&algo, NULL); + curve = ask_curve (&algo, NULL, NULL); r = xmalloc_clear (sizeof *r + strlen (curve)); r->key = pKEYCURVE; strcpy (r->u.value, curve); @@ -5075,7 +5080,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr, else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH) - curve = ask_curve (&algo, NULL); + curve = ask_curve (&algo, NULL, NULL); else nbits = ask_keysize (algo, 0); diff --git a/g10/main.h b/g10/main.h index 6c15a2a..af25d55 100644 --- a/g10/main.h +++ b/g10/main.h @@ -292,6 +292,7 @@ u32 parse_expire_string(const char *string); u32 ask_expire_interval(int object,const char *def_expire); u32 ask_expiredate(void); unsigned int ask_key_flags (int algo, int subkey, unsigned int current); +const char *ask_curve (int *algo, int *subkey_algo, const char *current); void quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr, const char *usagestr, const char *expirestr); void generate_keypair (ctrl_t ctrl, int full, const char *fname, commit 02d7bb819ff44cc90212568dd6ce24ae1dc5d17f Author: NIIBE Yutaka Date: Thu Mar 29 10:48:37 2018 +0900 g10: check_pin_for_key_operation should be just before genkey. * g10/card-util.c (generate_card_keys): Check PIN later. (card_generate_subkey): Likewise. -- Changing key attribute resets PIN authentication status. So, CHECKPIN should be after that, before key generation. Note that CHECKPIN is done for binding signature. Signed-off-by: NIIBE Yutaka diff --git a/g10/card-util.c b/g10/card-util.c index d78e9bd..2aa9c3f 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -1498,9 +1498,6 @@ generate_card_keys (ctrl_t ctrl) tty_printf ("\n"); } - if (check_pin_for_key_operation (&info, &forced_chv1)) - goto leave; - /* If the cards features changeable key attributes, we ask for the key size. */ if (info.is_v2 && info.extcap.aac) @@ -1533,6 +1530,9 @@ generate_card_keys (ctrl_t ctrl) the serialnumber and thus it won't harm. */ } + if (check_pin_for_key_operation (&info, &forced_chv1)) + goto leave; + generate_keypair (ctrl, 1, NULL, info.serialno, want_backup); leave: @@ -1587,10 +1587,6 @@ card_generate_subkey (ctrl_t ctrl, kbnode_t pub_keyblock) goto leave; } - err = check_pin_for_key_operation (&info, &forced_chv1); - if (err) - goto leave; - /* If the cards features changeable key attributes, we ask for the key size. */ if (info.is_v2 && info.extcap.aac) @@ -1621,6 +1617,10 @@ card_generate_subkey (ctrl_t ctrl, kbnode_t pub_keyblock) the serialnumber and thus it won't harm. */ } + err = check_pin_for_key_operation (&info, &forced_chv1); + if (err) + goto leave; + err = generate_card_subkeypair (ctrl, pub_keyblock, keyno, info.serialno); leave: ----------------------------------------------------------------------- Summary of changes: g10/card-util.c | 242 ++++++++++++++++++++++++++++++++++++++------------------ g10/keygen.c | 17 ++-- g10/main.h | 1 + 3 files changed, 176 insertions(+), 84 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 29 12:03:12 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 29 Mar 2018 12:03:12 +0200 Subject: [git] GpgEX - branch, master, updated. gpgex-1.0.5-3-g4fbbd13 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnupG extension for the Windows Explorer". The branch, master has been updated via 4fbbd134b865b1203b1914eb1623fa65aab8cb75 (commit) from 1f6817197c17c1bd92b7547860b4a8119774f902 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4fbbd134b865b1203b1914eb1623fa65aab8cb75 Author: Andre Heinecke Date: Thu Mar 29 11:59:19 2018 +0200 Use PNG icon and update to modern GpgEX icon * src/bitmaps.cc, src/bitmaps.h: Removed. * src/gpgex.cc (getBitmap, getBitmapCached, setupContextMenuIcon): New. (gpgex_t::QueryContextMenu): Use new helpers. * src/Makefile.am: Update accordingly. * src/gpgex.h: Rmeove bitmap code. * src/icon*.bmp: Removed. * src/standalone.svg, src/gpgex_logo.svg: New. * src/versioninfo.rc.in: Update accordingly. -- This fixes white background uglyness and should be more flexible in the future to just update an image by using a PNG. GnuPG-Bug-Id: T3851 diff --git a/po/pt.po b/po/pt.po index 9486899..697ecc4 100644 --- a/po/pt.po +++ b/po/pt.po @@ -17,7 +17,6 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Generator: Poedit 2.0.4\n" -"POT-Creation-Date: \n" #, c-format msgid "" diff --git a/src/Makefile.am b/src/Makefile.am index d7dfe7a..54329a8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,14 +13,14 @@ bin_PROGRAMS = gpgex EXTRA_DIST = versioninfo.rc.in gpgex.manifest.in \ - GNU.GnuPG.Gcc64Support.manifest gnupg.ico + GNU.GnuPG.Gcc64Support.manifest gnupg.ico \ + gpgex_logo.svg standalone.svg EXEEXT = .dll AM_CFLAGS = $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS) -shared AM_CXXFLAGS = $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS) -shared -ICONS = icon-key-12.bmp icon-key-16.bmp \ - icon-lock-12.bmp icon-lock-16.bmp +ICONS = icon-16.png nodist_gpgex_SOURCES = versioninfo.rc gpgex.manifest gpgex_SOURCES = \ @@ -29,10 +29,10 @@ gpgex_SOURCES = \ exechelp.h exechelp.c \ gpgex-class.h gpgex-class.cc \ gpgex-factory.h gpgex-factory.cc \ - bitmaps.h bitmaps.cc \ gpgex.h gpgex.cc \ client.h client.cc \ main.h debug.h main.cc \ + resource.h \ $(ICONS) libgpg-error.a: @@ -50,7 +50,7 @@ clean-local: gpgex_LDFLAGS = -static-libgcc -static-libstdc++ # We need -loleaut32 for start_help() in gpgex.cc. gpgex_LDADD = $(srcdir)/gpgex.def -L . \ - -lshell32 -lgdi32 -lole32 -luuid \ + -lshell32 -lgdi32 -lole32 -luuid -lgdiplus \ ./libassuan.a ./libgpg-error.a -lws2_32 -loleaut32 .rc.o: diff --git a/src/bitmaps.cc b/src/bitmaps.cc deleted file mode 100644 index 4928412..0000000 --- a/src/bitmaps.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* bitmaps.cc - gpgex bitmap implementation - Copyright (C) 2007 g10 Code GmbH - - This file is part of GpgEX. - - GpgEX is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - GpgEX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#if HAVE_CONFIG_H -#include -#endif - -#include -#include - -using std::string; - -#include - -#include "main.h" - -#include "bitmaps.h" - - -/* The size of the icons. */ -int gpgex_bitmaps_t::size; - -/* The available bitmap sizes in ascending order. */ -int gpgex_bitmaps_t::available_sizes[] = { 12, 16 }; - - -/* The global singleton object. */ -class gpgex_bitmaps_t gpgex_bitmaps; - - -gpgex_bitmaps_t::gpgex_bitmaps_t (void) -{ - /* Note about bitmaps: The required size is given by - GetSystemMetrics and can vary depending on the display size. A - typical value is 12x12. The color depth should be 8 bits. The - upper left corner pixel color is replaced by transparent - automatically. */ - int width = GetSystemMetrics (SM_CXMENUCHECK); - int height = GetSystemMetrics (SM_CYMENUCHECK); - - /* All our images are square, so take the minimum and look for the - biggest available size that fits in there. */ - int max_size = (width < height) ? width : height; - - for (unsigned int i = 0; i < (sizeof (this->available_sizes) - / sizeof (this->available_sizes[0])); i++) - if (max_size >= this->available_sizes[i]) - this->size = this->available_sizes[i]; - else - break; - - (void) TRACE3 (DEBUG_INIT, "gpgex_bitmaps_t::gpgex_bitmaps_t", this, - "GetSystemMetrics: %ix%i (using %i)", width, height, - this->size); -} - - -/* Load the bitmap with name NAME. */ -HBITMAP gpgex_bitmaps_t::load_bitmap (string name) -{ - HBITMAP bmap; - std::ostringstream out; - - out << name << "_" << this->size; - bmap = LoadBitmap (gpgex_server::instance, out.str().c_str()); - if (bmap == NULL) - (void) TRACE2 (DEBUG_INIT, "gpgex_bitmaps_t::load_bitmap", this, - "LoadImage %s failed: ec=%x", - out.str().c_str(), GetLastError ()); - else - (void) TRACE1 (DEBUG_INIT, "gpgex_bitmaps_t::load_bitmap", this, - "loaded image %s", out.str().c_str()); - - /* FIXME: Create cache of images. */ - return bmap; -} - diff --git a/src/gpgex.cc b/src/gpgex.cc index 84e9901..bdac2d0 100644 --- a/src/gpgex.cc +++ b/src/gpgex.cc @@ -25,11 +25,15 @@ #include #include #include +#include using std::vector; using std::string; #include +#include +#include +#include /* For the start_help() function. */ #include @@ -40,6 +44,8 @@ using std::string; #include "gpgex.h" +#include "resource.h" + /* For context menus. */ #define ID_CMD_HELP 0 @@ -235,6 +241,126 @@ gpgex_t::Initialize (LPCITEMIDLIST pIDFolder, IDataObject *pDataObj, return TRACE_RES (err); } +static HBITMAP +getBitmap (int id) +{ + TRACE_BEG0 (DEBUG_CONTEXT_MENU, __func__, nullptr, "get bitmap"); + PICTDESC pdesc; + Gdiplus::GdiplusStartupInput gdiplusStartupInput; + Gdiplus::Bitmap* pbitmap; + ULONG_PTR gdiplusToken; + HRSRC hResource; + DWORD imageSize; + const void* pResourceData; + HGLOBAL hBuffer; + + memset (&pdesc, 0, sizeof pdesc); + pdesc.cbSizeofstruct = sizeof pdesc; + pdesc.picType = PICTYPE_BITMAP; + + /* Initialize GDI */ + gdiplusStartupInput.DebugEventCallback = NULL; + gdiplusStartupInput.SuppressBackgroundThread = FALSE; + gdiplusStartupInput.SuppressExternalCodecs = FALSE; + gdiplusStartupInput.GdiplusVersion = 1; + GdiplusStartup (&gdiplusToken, &gdiplusStartupInput, NULL); + + /* Get the image from the resource file */ + hResource = FindResource (gpgex_server::instance, MAKEINTRESOURCE(id), RT_RCDATA); + if (!hResource) + { + TRACE1 (DEBUG_CONTEXT_MENU, __func__, nullptr, "Failed to find id: %i", + id); + return nullptr; + } + + imageSize = SizeofResource (gpgex_server::instance, hResource); + if (!imageSize) + { + TRACE1 (DEBUG_CONTEXT_MENU, __func__, nullptr, "WTF: %i", + __LINE__); + return nullptr; + } + + pResourceData = LockResource (LoadResource (gpgex_server::instance, hResource)); + + if (!pResourceData) + { + TRACE1 (DEBUG_CONTEXT_MENU, __func__, nullptr, "WTF: %i", + __LINE__); + return nullptr; + } + + hBuffer = GlobalAlloc (GMEM_MOVEABLE, imageSize); + + if (hBuffer) + { + void* pBuffer = GlobalLock (hBuffer); + if (pBuffer) + { + IStream* pStream = NULL; + CopyMemory (pBuffer, pResourceData, imageSize); + + if (CreateStreamOnHGlobal (hBuffer, FALSE, &pStream) == S_OK) + { + pbitmap = Gdiplus::Bitmap::FromStream (pStream); + pStream->Release(); + if (!pbitmap || pbitmap->GetHBITMAP (0, &pdesc.bmp.hbitmap)) + { + TRACE1 (DEBUG_CONTEXT_MENU, __func__, nullptr, "WTF: %i", + __LINE__); + return nullptr; + } + } + } + GlobalUnlock (pBuffer); + } + GlobalFree (hBuffer); + + Gdiplus::GdiplusShutdown (gdiplusToken); + + return pdesc.bmp.hbitmap; +} + +static HBITMAP +getBitmapCached (int id) +{ + static std::map s_id_map; + + const auto it = s_id_map.find (id); + if (it == s_id_map.end ()) + { + const HBITMAP icon = getBitmap (id); + s_id_map.insert (std::make_pair (id, icon)); + return icon; + } + return it->second; +} + +static bool +setupContextMenuIcon (int id, HMENU hMenu, UINT indexMenu) +{ + TRACE_BEG2 (DEBUG_CONTEXT_MENU, __func__, nullptr, "Start. menu: %p index %u", + hMenu, indexMenu); + int width = GetSystemMetrics (SM_CXMENUCHECK); + int height = GetSystemMetrics (SM_CYMENUCHECK); + + TRACE2 (DEBUG_CONTEXT_MENU, __func__, nullptr, "width %i height %i", + width, height); + + HBITMAP bmp = getBitmapCached (id); + + if (!bmp) + { + TRACE1 (DEBUG_CONTEXT_MENU, __func__, nullptr, "WTF: %i", + __LINE__); + return false; + } + + return SetMenuItemBitmaps (hMenu, indexMenu - 1, MF_BYPOSITION, + bmp, bmp); +} + /* IContextMenu methods. */ @@ -304,12 +430,8 @@ gpgex_t::QueryContextMenu (HMENU hMenu, UINT indexMenu, UINT idCmdFirst, return TRACE_RES (HRESULT_FROM_WIN32 (last_error)); } - if (this->key_bitmap) - { - // indexMenu - 1!!! - res = SetMenuItemBitmaps (hMenu, indexMenu - 1, MF_BYPOSITION, - this->key_bitmap, this->key_bitmap); - } + res = setupContextMenuIcon (IDI_ICON_16, hMenu, indexMenu); + if (res) res = InsertMenu (hMenu, indexMenu++, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); diff --git a/src/gpgex.h b/src/gpgex.h index 6402dce..9f5e5e0 100644 --- a/src/gpgex.h +++ b/src/gpgex.h @@ -30,8 +30,6 @@ using std::string; #include #include -#include "bitmaps.h" - /* Our shell extension interface. We use multiple inheritance to achieve polymorphy. @@ -88,9 +86,6 @@ class gpgex_t : public IShellExtInit, public IContextMenu3 /* TRUE if all files in filenames are directly related to GPG. */ BOOL all_files_gpg; - /* Support for the context menu. */ - HBITMAP key_bitmap; - public: /* Constructors and destructors. For these, we update the global component reference counter. */ @@ -101,8 +96,6 @@ class gpgex_t : public IShellExtInit, public IContextMenu3 gpgex_server::add_ref (); - this->key_bitmap = gpgex_bitmaps.load_bitmap ("Lock"); - (void) TRACE_SUC (); } @@ -110,9 +103,6 @@ class gpgex_t : public IShellExtInit, public IContextMenu3 { TRACE_BEG (DEBUG_INIT, "gpgex_t::~gpgex_t", this); - if (this->key_bitmap != NULL) - DeleteObject (this->key_bitmap); - gpgex_server::release (); (void) TRACE_SUC (); diff --git a/src/gpgex_logo.svg b/src/gpgex_logo.svg new file mode 100644 index 0000000..149047f --- /dev/null +++ b/src/gpgex_logo.svg @@ -0,0 +1,191 @@ + + + + + + image/svg+xml + + GpgEX finnished Logo + + + + + + + + + + GpgEX finnished Logo + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icon-16.png b/src/icon-16.png new file mode 100644 index 0000000..4c59692 Binary files /dev/null and b/src/icon-16.png differ diff --git a/src/icon-key-12.bmp b/src/icon-key-12.bmp deleted file mode 100644 index d61baac..0000000 Binary files a/src/icon-key-12.bmp and /dev/null differ diff --git a/src/icon-key-16.bmp b/src/icon-key-16.bmp deleted file mode 100644 index f2888b7..0000000 Binary files a/src/icon-key-16.bmp and /dev/null differ diff --git a/src/icon-lock-12.bmp b/src/icon-lock-12.bmp deleted file mode 100644 index dec900d..0000000 Binary files a/src/icon-lock-12.bmp and /dev/null differ diff --git a/src/icon-lock-16.bmp b/src/icon-lock-16.bmp deleted file mode 100644 index ac458a3..0000000 Binary files a/src/icon-lock-16.bmp and /dev/null differ diff --git a/src/bitmaps.h b/src/resource.h similarity index 55% rename from src/bitmaps.h rename to src/resource.h index 40115a9..d9e36a6 100644 --- a/src/bitmaps.h +++ b/src/resource.h @@ -1,5 +1,5 @@ -/* bitmaps.h - gpgex bitmap prototypes - Copyright (C) 2007 g10 Code GmbH +/* resource.h - resource ids + Copyright (C) 2018 Intevation GmbH This file is part of GpgEX. @@ -18,35 +18,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef GPGEX_BITMAPS_H -#define GPGEX_BITMAPS_H +#ifndef RESOURCE_H +#define RESOURCE_H -#include +#define IDI_ICON_16 0x1000 -using std::string; - -#include - - -/* The class used to load bitmap resources. */ -class gpgex_bitmaps_t -{ - /* The icon size used. */ - static int size; - - /* The available sizes. */ - static int available_sizes[]; - - public: - /* Constructor. */ - gpgex_bitmaps_t (void); - - /* Load the bitmap with name NAME. */ - HBITMAP load_bitmap (string name); -}; - - -/* The global singleton object. */ -extern gpgex_bitmaps_t gpgex_bitmaps; - -#endif /* ! GPGEX_BITMAPS_H */ +#endif // RESOURCE_H diff --git a/src/standalone.svg b/src/standalone.svg new file mode 100644 index 0000000..c30e24a --- /dev/null +++ b/src/standalone.svg @@ -0,0 +1,100 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in index 6528dc8..6454bfd 100644 --- a/src/versioninfo.rc.in +++ b/src/versioninfo.rc.in @@ -14,6 +14,8 @@ #line __LINE__ "versioninfo.rc.in" +#include "resource.h" + #include 1 ICON "./gnupg.ico" @@ -75,7 +77,4 @@ or (at your option) any later version.\0" /* * Our bitmaps. */ -Key_12 BITMAP "icon-key-12.bmp" -Key_16 BITMAP "icon-key-16.bmp" -Lock_12 BITMAP "icon-lock-12.bmp" -Lock_16 BITMAP "icon-lock-16.bmp" +IDI_ICON_16 RCDATA "icon-16.png" ----------------------------------------------------------------------- Summary of changes: po/pt.po | 1 - src/Makefile.am | 10 +-- src/bitmaps.cc | 94 --------------------- src/gpgex.cc | 134 +++++++++++++++++++++++++++-- src/gpgex.h | 10 --- src/gpgex_logo.svg | 191 ++++++++++++++++++++++++++++++++++++++++++ src/icon-16.png | Bin 0 -> 531 bytes src/icon-key-12.bmp | Bin 374 -> 0 bytes src/icon-key-16.bmp | Bin 594 -> 0 bytes src/icon-lock-12.bmp | Bin 630 -> 0 bytes src/icon-lock-16.bmp | Bin 1078 -> 0 bytes src/{bitmaps.h => resource.h} | 38 ++------- src/standalone.svg | 100 ++++++++++++++++++++++ src/versioninfo.rc.in | 7 +- 14 files changed, 433 insertions(+), 152 deletions(-) delete mode 100644 src/bitmaps.cc create mode 100644 src/gpgex_logo.svg create mode 100644 src/icon-16.png delete mode 100644 src/icon-key-12.bmp delete mode 100644 src/icon-key-16.bmp delete mode 100644 src/icon-lock-12.bmp delete mode 100644 src/icon-lock-16.bmp rename src/{bitmaps.h => resource.h} (55%) create mode 100644 src/standalone.svg hooks/post-receive -- GnupG extension for the Windows Explorer http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 29 15:13:39 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 29 Mar 2018 15:13:39 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-179-g60d7a1e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 60d7a1e8f625ea0db455bff989534dd52f0650c7 (commit) from 75a1a1c33efe952986bba56494b81e2f4835b8c4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 60d7a1e8f625ea0db455bff989534dd52f0650c7 Author: Werner Koch Date: Thu Mar 29 15:06:47 2018 +0200 json: Build only a dummy if libgpg-error is < 1.28 Signed-off-by: Werner Koch diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 5f16daf..b54d9a8 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -41,6 +41,10 @@ #include "cJSON.h" +#if GPGRT_VERSION_NUMBER < 0x011c00 /* 1.28 */ +int main (void){fputs ("Build with Libgpg-error >= 1.28!\n", stderr);return 1;} +#else /* libgpg-error >= 1.28 */ + /* We don't allow a request with more than 64 MiB. */ #define MAX_REQUEST_SIZE (64 * 1024 * 1024) @@ -1369,3 +1373,4 @@ main (int argc, char *argv[]) #endif /* This is a modern libgp-error. */ return 0; } +#endif /* libgpg-error >= 1.28 */ ----------------------------------------------------------------------- Summary of changes: src/gpgme-json.c | 5 +++++ 1 file changed, 5 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 29 16:57:04 2018 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Thu, 29 Mar 2018 16:57:04 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-59-g9b58e4a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 9b58e4a03ba3aeff7bae3f40da706977870c9649 (commit) via 8cdb010f04528703a502344e00d52447de12547d (commit) from 0de2191a07d69ef1fa34ca4c5d5fc4985ff7b4c4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9b58e4a03ba3aeff7bae3f40da706977870c9649 Author: Jussi Kivilinna Date: Sat Mar 24 17:49:16 2018 +0200 aarch64/assembly: only use the lower 32 bit of an int parameters * cipher/camellia-aarch64.S (_gcry_camellia_arm_encrypt_block) (__gcry_camellia_arm_decrypt_block): Make comment section about input registers match usage. * cipher/rijndael-armv8-aarch64-ce.S (_gcry_aes_ocb_auth_armv8_ce): Use 'w12' and 'w7' instead of 'x12' and 'x7'. (_gcry_aes_xts_enc_armv8_ce, _gcry_aes_xts_dec_armv8_ce): Fix function prototype in comments. * mpi/aarch64/mpih-add1.S: Use 32-bit registers for 32-bit mpi_size_t parameters. * mpi/aarch64/mpih-mul1.S: Ditto. * mpi/aarch64/mpih-mul2.S: Ditto. * mpi/aarch64/mpih-mul3.S: Ditto. * mpi/aarch64/mpih-sub1.S: Ditto. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/camellia-aarch64.S b/cipher/camellia-aarch64.S index c3cc463..b0e9a03 100644 --- a/cipher/camellia-aarch64.S +++ b/cipher/camellia-aarch64.S @@ -206,7 +206,7 @@ _gcry_camellia_arm_encrypt_block: * x0: keytable * x1: dst * x2: src - * x3: keybitlen + * w3: keybitlen */ adr RTAB1, _gcry_camellia_arm_tables; @@ -252,7 +252,7 @@ _gcry_camellia_arm_decrypt_block: * x0: keytable * x1: dst * x2: src - * x3: keybitlen + * w3: keybitlen */ adr RTAB1, _gcry_camellia_arm_tables; diff --git a/cipher/rijndael-armv8-aarch64-ce.S b/cipher/rijndael-armv8-aarch64-ce.S index 5859557..f0012c2 100644 --- a/cipher/rijndael-armv8-aarch64-ce.S +++ b/cipher/rijndael-armv8-aarch64-ce.S @@ -1157,8 +1157,8 @@ _gcry_aes_ocb_auth_armv8_ce: * w6: nrounds => w7 * w7: blkn => w12 */ - mov x12, x7 - mov x7, x6 + mov w12, w7 + mov w7, w6 mov x6, x5 mov x5, x4 mov x4, x3 @@ -1280,7 +1280,9 @@ ELF(.size _gcry_aes_ocb_auth_armv8_ce,.-_gcry_aes_ocb_auth_armv8_ce;) * void _gcry_aes_xts_enc_armv8_ce (const void *keysched, * unsigned char *outbuf, * const unsigned char *inbuf, - * unsigned char *tweak, unsigned int nrounds); + * unsigned char *tweak, + * size_t nblocks, + * unsigned int nrounds); */ .align 3 @@ -1417,7 +1419,9 @@ ELF(.size _gcry_aes_xts_enc_armv8_ce,.-_gcry_aes_xts_enc_armv8_ce;) * void _gcry_aes_xts_dec_armv8_ce (const void *keysched, * unsigned char *outbuf, * const unsigned char *inbuf, - * unsigned char *tweak, unsigned int nrounds); + * unsigned char *tweak, + * size_t nblocks, + * unsigned int nrounds); */ .align 3 diff --git a/mpi/aarch64/mpih-add1.S b/mpi/aarch64/mpih-add1.S index 4ead1c2..3370320 100644 --- a/mpi/aarch64/mpih-add1.S +++ b/mpi/aarch64/mpih-add1.S @@ -29,7 +29,7 @@ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, x0 * mpi_ptr_t s1_ptr, x1 * mpi_ptr_t s2_ptr, x2 - * mpi_size_t size) x3 + * mpi_size_t size) w3 */ .text @@ -37,34 +37,34 @@ .globl _gcry_mpih_add_n ELF(.type _gcry_mpih_add_n,%function) _gcry_mpih_add_n: - and x5, x3, #3; + and w5, w3, #3; adds xzr, xzr, xzr; /* clear carry flag */ - cbz x5, .Large_loop; + cbz w5, .Large_loop; .Loop: ldr x4, [x1], #8; - sub x3, x3, #1; + sub w3, w3, #1; ldr x11, [x2], #8; - and x5, x3, #3; + and w5, w3, #3; adcs x4, x4, x11; str x4, [x0], #8; - cbz x3, .Lend; - cbnz x5, .Loop; + cbz w3, .Lend; + cbnz w5, .Loop; .Large_loop: ldp x4, x6, [x1], #16; ldp x5, x7, [x2], #16; ldp x8, x10, [x1], #16; ldp x9, x11, [x2], #16; - sub x3, x3, #4; + sub w3, w3, #4; adcs x4, x4, x5; adcs x6, x6, x7; adcs x8, x8, x9; adcs x10, x10, x11; stp x4, x6, [x0], #16; stp x8, x10, [x0], #16; - cbnz x3, .Large_loop; + cbnz w3, .Large_loop; .Lend: adc x0, xzr, xzr; diff --git a/mpi/aarch64/mpih-mul1.S b/mpi/aarch64/mpih-mul1.S index 8a86269..8830845 100644 --- a/mpi/aarch64/mpih-mul1.S +++ b/mpi/aarch64/mpih-mul1.S @@ -28,7 +28,7 @@ * mpi_limb_t * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, x0 * mpi_ptr_t s1_ptr, x1 - * mpi_size_t s1_size, x2 + * mpi_size_t s1_size, w2 * mpi_limb_t s2_limb) x3 */ @@ -37,27 +37,27 @@ .globl _gcry_mpih_mul_1 ELF(.type _gcry_mpih_mul_1,%function) _gcry_mpih_mul_1: - and x5, x2, #3; + and w5, w2, #3; mov x4, xzr; - cbz x5, .Large_loop; + cbz w5, .Large_loop; .Loop: ldr x5, [x1], #8; - sub x2, x2, #1; + sub w2, w2, #1; mul x9, x5, x3; umulh x10, x5, x3; - and x5, x2, #3; + and w5, w2, #3; adds x4, x4, x9; str x4, [x0], #8; adc x4, x10, xzr; - cbz x2, .Lend; - cbnz x5, .Loop; + cbz w2, .Lend; + cbnz w5, .Loop; .Large_loop: ldp x5, x6, [x1]; - sub x2, x2, #4; + sub w2, w2, #4; mul x9, x5, x3; ldp x7, x8, [x1, #16]; @@ -89,7 +89,7 @@ _gcry_mpih_mul_1: str x4, [x0], #8; adc x4, x16, xzr; - cbnz x2, .Large_loop; + cbnz w2, .Large_loop; .Lend: mov x0, x4; diff --git a/mpi/aarch64/mpih-mul2.S b/mpi/aarch64/mpih-mul2.S index c7c08e5..5d73699 100644 --- a/mpi/aarch64/mpih-mul2.S +++ b/mpi/aarch64/mpih-mul2.S @@ -28,7 +28,7 @@ * mpi_limb_t * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, x0 * mpi_ptr_t s1_ptr, x1 - * mpi_size_t s1_size, x2 + * mpi_size_t s1_size, w2 * mpi_limb_t s2_limb) x3 */ @@ -37,11 +37,11 @@ .globl _gcry_mpih_addmul_1 ELF(.type _gcry_mpih_addmul_1,%function) _gcry_mpih_addmul_1: - and x5, x2, #3; + and w5, w2, #3; mov x6, xzr; mov x7, xzr; - cbz x5, .Large_loop; + cbz w5, .Large_loop; .Loop: ldr x5, [x1], #8; @@ -49,21 +49,21 @@ _gcry_mpih_addmul_1: mul x12, x5, x3; ldr x4, [x0]; umulh x13, x5, x3; - sub x2, x2, #1; + sub w2, w2, #1; adds x12, x12, x4; - and x5, x2, #3; + and w5, w2, #3; adc x13, x13, x7; adds x12, x12, x6; str x12, [x0], #8; adc x6, x7, x13; - cbz x2, .Lend; - cbnz x5, .Loop; + cbz w2, .Lend; + cbnz w5, .Loop; .Large_loop: ldp x5, x9, [x1], #16; - sub x2, x2, #4; + sub w2, w2, #4; ldp x4, x8, [x0]; mul x12, x5, x3; @@ -101,7 +101,7 @@ _gcry_mpih_addmul_1: str x14, [x0], #8; adc x6, x7, x15; - cbnz x2, .Large_loop; + cbnz w2, .Large_loop; .Lend: mov x0, x6; diff --git a/mpi/aarch64/mpih-mul3.S b/mpi/aarch64/mpih-mul3.S index ccc961e..f785e5e 100644 --- a/mpi/aarch64/mpih-mul3.S +++ b/mpi/aarch64/mpih-mul3.S @@ -28,7 +28,7 @@ * mpi_limb_t * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, x0 * mpi_ptr_t s1_ptr, x1 - * mpi_size_t s1_size, x2 + * mpi_size_t s1_size, w2 * mpi_limb_t s2_limb) x3 */ @@ -37,9 +37,9 @@ .globl _gcry_mpih_submul_1 ELF(.type _gcry_mpih_submul_1,%function) _gcry_mpih_submul_1: - and x5, x2, #3; + and w5, w2, #3; mov x7, xzr; - cbz x5, .Large_loop; + cbz w5, .Large_loop; subs xzr, xzr, xzr; @@ -47,26 +47,26 @@ _gcry_mpih_submul_1: ldr x4, [x1], #8; cinc x7, x7, cc; ldr x5, [x0]; - sub x2, x2, #1; + sub w2, w2, #1; mul x6, x4, x3; subs x5, x5, x7; umulh x4, x4, x3; - and x10, x2, #3; + and w10, w2, #3; cset x7, cc; subs x5, x5, x6; add x7, x7, x4; str x5, [x0], #8; - cbz x2, .Loop_end; - cbnz x10, .Loop; + cbz w2, .Loop_end; + cbnz w10, .Loop; cinc x7, x7, cc; .Large_loop: ldp x4, x8, [x1], #16; - sub x2, x2, #4; + sub w2, w2, #4; ldp x5, x9, [x0]; mul x6, x4, x3; @@ -111,7 +111,7 @@ _gcry_mpih_submul_1: str x9, [x0], #8; cinc x7, x7, cc; - cbnz x2, .Large_loop; + cbnz w2, .Large_loop; mov x0, x7; ret; diff --git a/mpi/aarch64/mpih-sub1.S b/mpi/aarch64/mpih-sub1.S index 4a66373..45a7b04 100644 --- a/mpi/aarch64/mpih-sub1.S +++ b/mpi/aarch64/mpih-sub1.S @@ -29,7 +29,7 @@ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, x0 * mpi_ptr_t s1_ptr, x1 * mpi_ptr_t s2_ptr, x2 - * mpi_size_t size) x3 + * mpi_size_t size) w3 */ .text @@ -37,34 +37,34 @@ .globl _gcry_mpih_sub_n ELF(.type _gcry_mpih_sub_n,%function) _gcry_mpih_sub_n: - and x5, x3, #3; + and w5, w3, #3; subs xzr, xzr, xzr; /* prepare carry flag for sub */ - cbz x5, .Large_loop; + cbz w5, .Large_loop; .Loop: ldr x4, [x1], #8; - sub x3, x3, #1; + sub w3, w3, #1; ldr x11, [x2], #8; - and x5, x3, #3; + and w5, w3, #3; sbcs x4, x4, x11; str x4, [x0], #8; - cbz x3, .Lend; - cbnz x5, .Loop; + cbz w3, .Lend; + cbnz w5, .Loop; .Large_loop: ldp x4, x6, [x1], #16; ldp x5, x7, [x2], #16; ldp x8, x10, [x1], #16; ldp x9, x11, [x2], #16; - sub x3, x3, #4; + sub w3, w3, #4; sbcs x4, x4, x5; sbcs x6, x6, x7; sbcs x8, x8, x9; sbcs x10, x10, x11; stp x4, x6, [x0], #16; stp x8, x10, [x0], #16; - cbnz x3, .Large_loop; + cbnz w3, .Large_loop; .Lend: cset x0, cc; commit 8cdb010f04528703a502344e00d52447de12547d Author: Jussi Kivilinna Date: Sat Mar 24 17:22:45 2018 +0200 poly1305: silence compiler warning on clang/aarch64 * cipher/poly1305.c (MUL_MOD_1305_64): cast zero constant to 64-bits. -- This patch fixes "value size does not match register size specified by the constraint and modifier [-Wasm-operand-widths]" warnings when building with clang/aarch64. Signed-off-by: Jussi Kivilinna diff --git a/cipher/poly1305.c b/cipher/poly1305.c index 68d9b90..571f828 100644 --- a/cipher/poly1305.c +++ b/cipher/poly1305.c @@ -130,7 +130,7 @@ static void poly1305_init (poly1305_context_t *ctx, /* carry propagation */ \ H2 = H0 & 3; \ H0 = (H0 >> 2) * 5; /* msb mod 2^130-5 */ \ - ADD_1305_64(H2, H1, H0, 0, x0_hi, x0_lo); \ + ADD_1305_64(H2, H1, H0, (u64)0, x0_hi, x0_lo); \ } while (0) unsigned int ----------------------------------------------------------------------- Summary of changes: cipher/camellia-aarch64.S | 4 ++-- cipher/poly1305.c | 2 +- cipher/rijndael-armv8-aarch64-ce.S | 12 ++++++++---- mpi/aarch64/mpih-add1.S | 18 +++++++++--------- mpi/aarch64/mpih-mul1.S | 18 +++++++++--------- mpi/aarch64/mpih-mul2.S | 18 +++++++++--------- mpi/aarch64/mpih-mul3.S | 18 +++++++++--------- mpi/aarch64/mpih-sub1.S | 18 +++++++++--------- 8 files changed, 56 insertions(+), 52 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 30 01:40:42 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Fri, 30 Mar 2018 01:40:42 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-182-gfed024e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via fed024eff1091056647296ac589a0c88c2be41bb (commit) via d0bb4ec4ecdfae4dfd9dd84aef905afb490013d5 (commit) via e6180f2b36cc8a6c6154e5f3d702324af573132a (commit) from 60d7a1e8f625ea0db455bff989534dd52f0650c7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fed024eff1091056647296ac589a0c88c2be41bb Merge: d0bb4ec 60d7a1e Author: Ben McGinnes Date: Fri Mar 30 10:38:31 2018 +1100 Merge branch 'master' of ssh+git://playfair.gnupg.org/git/gpgme * Also fixed a small grammatical error highlighted by a merge conflict (in the python bindings howto). diff --cc lang/python/docs/GPGMEpythonHOWTOen.org index 219f602,d51eb11..cb85b61 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@@ -1251,8 -1287,8 +1287,8 @@@ The =key_sign= method takes four arguments: =key=, =uids=, =expires_in= and =local=. The default value of =uids= is =None= and which results in all user IDs being selected. The default - values of =expires_in= and =local= is =False=; which results in the - values of =expires_in= and =local= is =False=; which result in the -- signature never expiring and being able to be exported. ++ value of both =expires_in= and =local= is =False=; which results in ++ the signature never expiring and being able to be exported. The =key= is the key being signed rather than the key doing the signing. To change the key doing the signing refer to the signing commit d0bb4ec4ecdfae4dfd9dd84aef905afb490013d5 Merge: e6180f2 4763974 Author: Ben McGinnes Date: Sun Mar 25 09:44:51 2018 +1100 Merge branch 'master' of ssh+git://playfair.gnupg.org/git/gpgme commit e6180f2b36cc8a6c6154e5f3d702324af573132a Author: Ben McGinnes Date: Sat Mar 24 06:41:36 2018 +1100 doc: python bindings howto * Fixed a minor spelling error and a minor grammatical error. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 1e8dd9f..219f602 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1251,7 +1251,7 @@ The =key_sign= method takes four arguments: =key=, =uids=, =expires_in= and =local=. The default value of =uids= is =None= and which results in all user IDs being selected. The default - values of =expires_in= snd =local= is =False=; which result in the + values of =expires_in= and =local= is =False=; which results in the signature never expiring and being able to be exported. The =key= is the key being signed rather than the key doing the ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 30 04:02:14 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 30 Mar 2018 04:02:14 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-37-g8203803 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 820380335a20391e0998fb1ba32ebfb9accedc5b (commit) via 29692718768c28c524be6306081ab1852e75fe07 (commit) from a1515b3bbc10a210040dda3b482bcdb933fa8d7c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 820380335a20391e0998fb1ba32ebfb9accedc5b Author: NIIBE Yutaka Date: Fri Mar 30 10:59:10 2018 +0900 g10: Add "key-attr" command for --card-edit. * g10/card-util.c (key_attr): New explicit command. (generate_card_keys, card_generate_subkey): Don't ask key attr change. (card_edit): Add for cmdKEYATTR. -- GnuPG-bug-id: 3781 Signed-off-by: NIIBE Yutaka diff --git a/g10/card-util.c b/g10/card-util.c index 263ab4e..055c9fb 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -1435,7 +1435,7 @@ ask_card_keyattr (int keyno, const struct key_attr *current) } if (algo == 0) - got leave; + goto leave; key_attr = xmalloc (sizeof (struct key_attr)); @@ -1541,12 +1541,56 @@ do_change_keyattr (int keyno, const struct key_attr *key_attr) static void +key_attr (void) +{ + struct agent_card_info_s info; + gpg_error_t err; + int keyno; + + err = get_info_for_key_operation (&info); + if (err) + { + log_error (_("error getting card info: %s\n"), gpg_strerror (err)); + return; + } + + if (!(info.is_v2 && info.extcap.aac)) + { + log_error (_("This command is not supported by this card\n")); + goto leave; + } + + for (keyno = 0; keyno < DIM (info.key_attr); keyno++) + { + struct key_attr *key_attr; + + if ((key_attr = ask_card_keyattr (keyno, &info.key_attr[keyno]))) + { + err = do_change_keyattr (keyno, key_attr); + xfree (key_attr); + if (err) + { + /* Error: Better read the default key attribute again. */ + agent_release_card_info (&info); + if (get_info_for_key_operation (&info)) + goto leave; + /* Ask again for this key. */ + keyno--; + } + } + } + + leave: + agent_release_card_info (&info); +} + + +static void generate_card_keys (ctrl_t ctrl) { struct agent_card_info_s info; int forced_chv1; int want_backup; - int keyno; if (get_info_for_key_operation (&info)) return; @@ -1594,32 +1638,6 @@ generate_card_keys (ctrl_t ctrl) tty_printf ("\n"); } - /* If the cards features changeable key attributes, we ask for the - key size. */ - if (info.is_v2 && info.extcap.aac) - { - for (keyno = 0; keyno < DIM (info.key_attr); keyno++) - { - struct key_attr *key_attr; - - if ((key_attr = ask_card_keyattr (keyno, &info.key_attr[keyno]))) - { - gpg_error_t err = do_change_keyattr (keyno, key_attr); - xfree (key_attr); - if (err) - { - /* Error: Better read the default key attribute again. */ - agent_release_card_info (&info); - if (get_info_for_key_operation (&info)) - goto leave; - /* Ask again for this key. */ - keyno--; - } - } - } - /* Note that INFO has not be synced. However we will only use - the serialnumber and thus it won't harm. */ - } if (check_pin_for_key_operation (&info, &forced_chv1)) goto leave; @@ -1678,31 +1696,6 @@ card_generate_subkey (ctrl_t ctrl, kbnode_t pub_keyblock) goto leave; } - /* If the cards features changeable key attributes, we ask for the - key size. */ - if (info.is_v2 && info.extcap.aac) - { - struct key_attr *key_attr; - - ask_again: - if ((key_attr = ask_card_keyattr (keyno-1, &info.key_attr[keyno-1]))) - { - err = do_change_keyattr (keyno-1, key_attr); - xfree (key_attr); - if (err) - { - /* Error: Better read the default key attribute again. */ - agent_release_card_info (&info); - err = get_info_for_key_operation (&info); - if (err) - goto leave; - goto ask_again; - } - } - /* Note that INFO has not be synced. However we will only use - the serialnumber and thus it won't harm. */ - } - err = check_pin_for_key_operation (&info, &forced_chv1); if (err) goto leave; @@ -2091,6 +2084,7 @@ enum cmdids cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR, cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT, cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET, cmdKDFSETUP, + cmdKEYATTR, cmdINVCMD }; @@ -2124,6 +2118,7 @@ static struct { "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") }, { "factory-reset", cmdFACTORYRESET, 1, N_("destroy all keys and data")}, { "kdf-setup", cmdKDFSETUP, 1, N_("setup KDF for PIN authentication")}, + { "key-attr", cmdKEYATTR, 1, N_("change the key attribute")}, /* Note, that we do not announce these command yet. */ { "privatedo", cmdPRIVATEDO, 0, NULL }, { "readcert", cmdREADCERT, 0, NULL }, @@ -2411,6 +2406,10 @@ card_edit (ctrl_t ctrl, strlist_t commands) kdf_setup (); break; + case cmdKEYATTR: + key_attr (); + break; + case cmdQUIT: goto leave; commit 29692718768c28c524be6306081ab1852e75fe07 Author: NIIBE Yutaka Date: Fri Mar 30 09:59:09 2018 +0900 scd: Support changing key attribute back to RSA. * scd/app-openpgp.c (change_rsa_keyattr): Try usual RSA. -- In the OpenPGP card specification, there are multiple options to support RSA (having P and Q or not, etc.), and it is implementation dependent. Since GnuPG doesn't have knowledge which card implementation support which option and there is no way (yet) for card to express itself which key attributes are supported, we haven't supported key attribute change back to RSA. But, many card implementation uses P and Q, try this option. If other cases, factory-reset would be easier option. Signed-off-by: NIIBE Yutaka diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index e0c9d59..7bbec03 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -3208,21 +3208,33 @@ change_rsa_keyattr (app_t app, int keyno, unsigned int nbits, relptr = get_one_do (app, 0xC1+keyno, &buf, &buflen, NULL); if (!relptr) err = gpg_error (GPG_ERR_CARD); - else if (buflen < 6 || buf[0] != PUBKEY_ALGO_RSA) + else if (buflen < 6) { - /* Attriutes too short or not an RSA key. */ + /* Attributes too short. */ xfree (relptr); err = gpg_error (GPG_ERR_CARD); } else { - /* We only change n_bits and don't touch anything else. Before we - do so, we round up NBITS to a sensible way in the same way as - gpg's key generation does it. This may help to sort out problems - with a few bits too short keys. */ + /* If key attribute was RSA, we only change n_bits and don't + touch anything else. Before we do so, we round up NBITS to a + sensible way in the same way as gpg's key generation does it. + This may help to sort out problems with a few bits too short + keys. */ nbits = ((nbits + 31) / 32) * 32; buf[1] = (nbits >> 8); buf[2] = nbits; + + /* If it was not RSA, we need to fill other parts. */ + if (buf[0] != PUBKEY_ALGO_RSA) + { + buf[0] = PUBKEY_ALGO_RSA; + buf[3] = 0; + buf[4] = 32; + buf[5] = 0; + buflen = 6; + } + err = change_keyattr (app, keyno, buf, buflen, pincb, pincb_arg); xfree (relptr); } ----------------------------------------------------------------------- Summary of changes: g10/card-util.c | 105 +++++++++++++++++++++++++++--------------------------- scd/app-openpgp.c | 24 +++++++++---- 2 files changed, 70 insertions(+), 59 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 30 05:14:14 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Fri, 30 Mar 2018 05:14:14 +0200 Subject: [git] GPGME - branch, ben/howto-update-03, created. gpgme-1.10.0-184-g6a527a6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/howto-update-03 has been created at 6a527a640744990af582ffff4759591afefdbc9a (commit) - Log ----------------------------------------------------------------- commit 6a527a640744990af582ffff4759591afefdbc9a Author: Ben McGinnes Date: Fri Mar 30 14:12:42 2018 +1100 script: groups work-around * Updated script to match the methods in the HOWTO. diff --git a/lang/python/examples/howto/groups.py b/lang/python/examples/howto/groups.py index 5e7fdf6..c6f67d2 100644 --- a/lang/python/examples/howto/groups.py +++ b/lang/python/examples/howto/groups.py @@ -23,6 +23,7 @@ from __future__ import absolute_import, division, unicode_literals # Lesser General Public along with this program; if not, see # . +import gpg import subprocess """ @@ -31,7 +32,9 @@ Intended for use with other scripts. Usage: from groups import group_lists """ -lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines() +gpgconf = gpg.core.get_engine_info()[2].file_name +gpgconf_cmd "{0} --list-options gpg".format(gpgconf) +lines = subprocess.getoutput(gpgconf_cmd).splitlines() for i in range(len(lines)): if lines[i].startswith("group") is True: commit de11f557a8698976faa3b6cfcead6eb8c9e5384f Author: Ben McGinnes Date: Fri Mar 30 14:10:24 2018 +1100 docs: python bindings howto * Updated groups work around example to make sure it uses the correct version of gpgconf for the user invoking it (determined by the engine info). diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index cb85b61..e0a2664 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -1334,9 +1334,12 @@ this information in Python. #+begin_src python + import gpg import subprocess - lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines() + gpgconf = gpg.core.get_engine_info()[2].file_name + gpgconf_cmd "{0} --list-options gpg".format(gpgconf) + lines = subprocess.getoutput(gpgconf_cmd).splitlines() for i in range(len(lines)): if lines[i].startswith("group") is True: ----------------------------------------------------------------------- hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 30 05:52:41 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 30 Mar 2018 05:52:41 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-38-g0c09757 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 0c097575a9cd923f648fb5bb695893d46400c3ad (commit) from 820380335a20391e0998fb1ba32ebfb9accedc5b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0c097575a9cd923f648fb5bb695893d46400c3ad Author: NIIBE Yutaka Date: Fri Mar 30 12:48:04 2018 +0900 g10,scd: Support single salt for KDF data object. * g10/card-util.c (gen_kdf_data): Support single salt. (kdf_setup): Can have argument for single salt. * scd/app-openpgp.c (pin2hash_if_kdf): Support single salt. -- Gnuk has "admin-less" mode. To support "admin-less" mode with KDF feature, salt should be same for user and admin. Thus, I introduce a valid use of single salt. Signed-off-by: NIIBE Yutaka diff --git a/g10/card-util.c b/g10/card-util.c index 055c9fb..367e315 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -1978,11 +1978,12 @@ factory_reset (void) #define USER_PIN_DEFAULT "123456" #define ADMIN_PIN_DEFAULT "12345678" -#define KDF_DATA_LENGTH 110 +#define KDF_DATA_LENGTH_MIN 90 +#define KDF_DATA_LENGTH_MAX 110 /* Generate KDF data. */ static gpg_error_t -gen_kdf_data (unsigned char *data) +gen_kdf_data (unsigned char *data, int single_salt) { const unsigned char h0[] = { 0x81, 0x01, 0x03, 0x82, 0x01, 0x08, @@ -2015,14 +2016,19 @@ gen_kdf_data (unsigned char *data) salt_user = (p += sizeof h1); gcry_randomize (p, 8, GCRY_STRONG_RANDOM); p += 8; - memcpy (p, h2, sizeof h2); - p += sizeof h2; - gcry_randomize (p, 8, GCRY_STRONG_RANDOM); - p += 8; - memcpy (p, h3, sizeof h3); - salt_admin = (p += sizeof h3); - gcry_randomize (p, 8, GCRY_STRONG_RANDOM); - p += 8; + + if (!single_salt) + { + memcpy (p, h2, sizeof h2); + p += sizeof h2; + gcry_randomize (p, 8, GCRY_STRONG_RANDOM); + p += 8; + memcpy (p, h3, sizeof h3); + salt_admin = (p += sizeof h3); + gcry_randomize (p, 8, GCRY_STRONG_RANDOM); + p += 8; + } + memcpy (p, h4, sizeof h4); p += sizeof h4; err = gcry_kdf_derive (USER_PIN_DEFAULT, strlen (USER_PIN_DEFAULT), @@ -2043,11 +2049,12 @@ gen_kdf_data (unsigned char *data) /* Setup KDF data object which is used for PIN authentication. */ static void -kdf_setup (void) +kdf_setup (const char *args) { struct agent_card_info_s info; gpg_error_t err; - unsigned char kdf_data[KDF_DATA_LENGTH]; + unsigned char kdf_data[KDF_DATA_LENGTH_MAX]; + int single = (*args != 0); memset (&info, 0, sizeof info); @@ -2064,10 +2071,19 @@ kdf_setup (void) goto leave; } - if (!(err = gen_kdf_data (kdf_data)) - && !(err = agent_scd_setattr ("KDF", kdf_data, KDF_DATA_LENGTH, NULL))) - err = agent_scd_getattr ("KDF", &info); + err = gen_kdf_data (kdf_data, single); + if (err) + goto leave_error; + + err = agent_scd_setattr ("KDF", kdf_data, + single ? KDF_DATA_LENGTH_MIN : KDF_DATA_LENGTH_MAX, + NULL); + if (err) + goto leave_error; + + err = agent_scd_getattr ("KDF", &info); + leave_error: if (err) log_error (_("error for setup KDF: %s\n"), gpg_strerror (err)); @@ -2403,7 +2419,7 @@ card_edit (ctrl_t ctrl, strlist_t commands) break; case cmdKDFSETUP: - kdf_setup (); + kdf_setup (arg_string); break; case cmdKEYATTR: diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 7bbec03..ab57d90 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -2061,6 +2061,9 @@ get_prompt_info (app_t app, int chvno, unsigned long sigcount, int remaining) return result; } +#define KDF_DATA_LENGTH_MIN 90 +#define KDF_DATA_LENGTH_MAX 110 + /* Compute hash if KDF-DO is available. CHVNO must be 0 for reset code, 1 or 2 for user pin and 3 for admin pin. */ @@ -2068,21 +2071,33 @@ static gpg_error_t pin2hash_if_kdf (app_t app, int chvno, char *pinvalue, int *r_pinlen) { gpg_error_t err = 0; - void *relptr; + void *relptr = NULL; unsigned char *buffer; size_t buflen; if (app->app_local->extcap.kdf_do && (relptr = get_one_do (app, 0x00F9, &buffer, &buflen, NULL)) - && buflen == 110 && (buffer[2] == 0x03)) + && buflen >= KDF_DATA_LENGTH_MIN && (buffer[2] == 0x03)) { - char *salt; + const char *salt; unsigned long s2k_count; char dek[32]; + int salt_index; - salt = &buffer[(chvno==3 ? 34 : (chvno==0 ? 24 : 14))]; s2k_count = (((unsigned int)buffer[8] << 24) | (buffer[9] << 16) | (buffer[10] << 8) | buffer[11]); + + if (buflen == KDF_DATA_LENGTH_MIN) + salt_index =14; + else if (buflen == KDF_DATA_LENGTH_MAX) + salt_index = (chvno==3 ? 34 : (chvno==0 ? 24 : 14)); + else + { + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + + salt = &buffer[salt_index]; err = gcry_kdf_derive (pinvalue, strlen (pinvalue), GCRY_KDF_ITERSALTED_S2K, DIGEST_ALGO_SHA256, salt, 8, @@ -2094,12 +2109,12 @@ pin2hash_if_kdf (app_t app, int chvno, char *pinvalue, int *r_pinlen) memcpy (pinvalue, dek, *r_pinlen); wipememory (dek, *r_pinlen); } - - xfree (relptr); - } + } else *r_pinlen = strlen (pinvalue); + leave: + xfree (relptr); return err; } ----------------------------------------------------------------------- Summary of changes: g10/card-util.c | 48 ++++++++++++++++++++++++++++++++---------------- scd/app-openpgp.c | 29 ++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 23 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 30 06:08:21 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Fri, 30 Mar 2018 06:08:21 +0200 Subject: [git] GPGME - branch, ben/howto-update-03, updated. gpgme-1.10.0-185-gb97ee3e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/howto-update-03 has been updated via b97ee3e0aacaade37371c1be58f0ce7b1d9c0732 (commit) from 6a527a640744990af582ffff4759591afefdbc9a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b97ee3e0aacaade37371c1be58f0ce7b1d9c0732 Author: Ben McGinnes Date: Fri Mar 30 14:49:26 2018 +1100 docs: python bindings howto * Added a section on checking the version details of GPGME and the underlying engines. * This is a component of the updated workaround in the previous commit(s). diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index e0a2664..62d807a 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -316,6 +316,46 @@ operation type has one. +** GPGME and Python Bindings Versions + :PROPERTIES: + :CUSTOM_ID: howto-get-version-info + :END: + + Essentially there are two methods for checking useful version + information. + + The first, =gpg.core.check_version=, returns the version of GPGME + installed. This should match the version of the Python bindings + themselves, but if the bindings have been installed separately from + GPGME (e.g. via PyPI, in spite of the current recommendations) then + a mismatch is possible and the effects may be unpredictable. + + #+begin_src python + import gpg + + print(gpg.core.check_version(version=None)) + #+end_src + + The quick way to see whether the output of =gpg.core.check_version()= + matches the GPGME library installed is to see if the version number + reported matches the first header produced by the =gpgme-tool= + installed with the library. + + The second method, =gpg.core.get_engine_info=, returns version + information for the underlying engines, libraries and relevant + components. It also returns the full paths of certain important + executables, particularly =gpg= or =gpg.exe= for the OpenPGP engine + and =gpgsm= or =gpgsm.exe= for the S/MIME engine. + + #+begin_src python + import gpg + + for i in range(len(gpg.core.get_engine_info())): + print("{0}: version {1}".format(gpg.core.get_engine_info()[i].file_name, + gpg.core.get_engine_info()[i].version)) + #+end_src + + * Working with keys :PROPERTIES: :CUSTOM_ID: howto-keys ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 30 10:02:40 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 30 Mar 2018 10:02:40 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-39-g130ad98 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 130ad98240c066383fa0a99bcf5e0ec72bc0dff9 (commit) from 0c097575a9cd923f648fb5bb695893d46400c3ad (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 130ad98240c066383fa0a99bcf5e0ec72bc0dff9 Author: NIIBE Yutaka Date: Fri Mar 30 16:55:01 2018 +0900 g10: Fix card-edit/kdf-setup for single salt. * g10/card-util.c (gen_kdf_data): Use SALT_USER. Signed-off-by: NIIBE Yutaka diff --git a/g10/card-util.c b/g10/card-util.c index 367e315..e33a417 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -2017,7 +2017,9 @@ gen_kdf_data (unsigned char *data, int single_salt) gcry_randomize (p, 8, GCRY_STRONG_RANDOM); p += 8; - if (!single_salt) + if (single_salt) + salt_admin = salt_user; + else { memcpy (p, h2, sizeof h2); p += sizeof h2; ----------------------------------------------------------------------- Summary of changes: g10/card-util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 30 12:34:07 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 30 Mar 2018 12:34:07 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.5-40-g6705ee4 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 6705ee42a4bd89eea3f959f75d3c14a69c1249a3 (commit) from 130ad98240c066383fa0a99bcf5e0ec72bc0dff9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6705ee42a4bd89eea3f959f75d3c14a69c1249a3 Author: NIIBE Yutaka Date: Fri Mar 30 19:32:02 2018 +0900 po: Update Japanese translation. -- Signed-off-by: NIIBE Yutaka diff --git a/po/ja.po b/po/ja.po index ac4ad78..98979f8 100644 --- a/po/ja.po +++ b/po/ja.po @@ -8,9 +8,9 @@ # msgid "" msgstr "" -"Project-Id-Version: gnupg 2.2.3\n" +"Project-Id-Version: gnupg 2.2.6\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2017-12-18 14:07+0900\n" +"PO-Revision-Date: 2018-03-30 19:31+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -1325,21 +1325,8 @@ msgstr "" " ??????????????????\n" #, c-format -msgid "What keysize do you want for the Signature key? (%u) " -msgstr "???????? (%u) " - -#, c-format -msgid "What keysize do you want for the Encryption key? (%u) " -msgstr "????????? (%u) " - -#, c-format -msgid "What keysize do you want for the Authentication key? (%u) " -msgstr "???????? (%u) " - -#, c-format -msgid "The card will now be re-configured to generate a key of type: %s\n" -msgstr "" -"???????????????????????????????????: %s\n" +msgid "What keysize do you want? (%u) " +msgstr "???? (%u) " #, c-format msgid "rounded up to %u bits\n" @@ -1353,9 +1340,45 @@ msgstr "%s ??? %u-%u ?????????????\n" msgid "The card will now be re-configured to generate a key of %u bits\n" msgstr "??%u????????????????????????????\n" +msgid "Changing card key attribute for: " +msgstr "?????????????????: " + +msgid "Signature key\n" +msgstr "???\n" + +msgid "Encryption key\n" +msgstr "????\n" + +msgid "Authentication key\n" +msgstr "???\n" + +msgid "Please select what kind of key you want:\n" +msgstr "?????????????????:\n" + #, c-format -msgid "error changing size of key %d to %u bits: %s\n" -msgstr "?%d????%u bit ??????????: %s\n" +msgid " (%d) RSA\n" +msgstr " (%d) RSA\n" + +#, c-format +msgid " (%d) ECC\n" +msgstr " (%d) ECC\n" + +msgid "Invalid selection.\n" +msgstr "????????\n" + +msgid "No change." +msgstr "?????" + +#, c-format +msgid "error changing key attribute for key %d: %s\n" +msgstr "?%d?????????????: %s\n" + +#, c-format +msgid "error getting card info: %s\n" +msgstr "?????????: %s\n" + +msgid "This command is not supported by this card\n" +msgstr "???????????????????????????\n" msgid "Make off-card backup of encryption key? (Y/n) " msgstr "??????????????????????? (Y/n) " @@ -1388,9 +1411,6 @@ msgstr " (2) ????\n" msgid " (3) Authentication key\n" msgstr " (3) ???\n" -msgid "Invalid selection.\n" -msgstr "????????\n" - msgid "Please select where to store the key:\n" msgstr "?????????????????:\n" @@ -1398,9 +1418,6 @@ msgstr "?????????????????:\n" msgid "KEYTOCARD failed: %s\n" msgstr "KEYTOCARD???????: %s\n" -msgid "This command is not supported by this card\n" -msgstr "???????????????????????????\n" - msgid "Note: This command destroys all keys stored on the card!\n" msgstr "*??*: ????????????????????????????!\n" @@ -1410,6 +1427,10 @@ msgstr "?????? (y/N) " msgid "Really do a factory reset? (enter \"yes\") " msgstr "??????????????? (???? \"yes\" ???) " +#, c-format +msgid "error for setup KDF: %s\n" +msgstr "KDF??????: %s\n" + msgid "quit this menu" msgstr "?????????" @@ -1461,6 +1482,12 @@ msgstr "PIN???????????????????" msgid "destroy all keys and data" msgstr "???????????????" +msgid "setup KDF for PIN authentication" +msgstr "PIN???KDF?????" + +msgid "change the key attribute" +msgstr "???????" + msgid "gpg/card> " msgstr "gpg/card> " @@ -2081,6 +2108,10 @@ msgid "invalid pinentry mode '%s'\n" msgstr "??? pinentry mode '%s'??\n" #, c-format +msgid "invalid request origin '%s'\n" +msgstr "???????? '%s' ??\n" + +#, c-format msgid "'%s' is not a valid character set\n" msgstr "'%s'????????????????\n" @@ -3099,12 +3130,12 @@ msgstr "" msgid "Key is revoked." msgstr "????????????" -msgid "Really sign all user IDs? (y/N) " -msgstr "???????ID???????? (y/N) " - msgid "Really sign all text user IDs? (y/N) " msgstr "?????????????ID???????? (y/N) " +msgid "Really sign all user IDs? (y/N) " +msgstr "???????ID???????? (y/N) " + msgid "Hint: Select the user IDs to sign\n" msgstr "???: ?????????ID??????\n" @@ -3643,9 +3674,6 @@ msgstr " (%c) ?????????\n" msgid " (%c) Finished\n" msgstr " (%c) ??\n" -msgid "Please select what kind of key you want:\n" -msgstr "?????????????????:\n" - #, c-format msgid " (%d) RSA and RSA (default)\n" msgstr " (%d) RSA ? RSA (?????)\n" @@ -3720,10 +3748,6 @@ msgid "What keysize do you want for the subkey? (%u) " msgstr "??????? (%u) " #, c-format -msgid "What keysize do you want? (%u) " -msgstr "???? (%u) " - -#, c-format msgid "Requested keysize is %u bits\n" msgstr "????????%u???\n" @@ -6342,10 +6366,6 @@ msgstr "" "???\n" #, c-format -msgid " (%d) RSA\n" -msgstr " (%d) RSA\n" - -#, c-format msgid " (%d) Existing key\n" msgstr " (%d) ????\n" @@ -8319,6 +8339,20 @@ msgstr "" "??: gpg-check-pattern [?????] ????????\n" "????????????????????????????\n" +#~ msgid "What keysize do you want for the Signature key? (%u) " +#~ msgstr "???????? (%u) " + +#~ msgid "What keysize do you want for the Encryption key? (%u) " +#~ msgstr "????????? (%u) " + +#~ msgid "What keysize do you want for the Authentication key? (%u) " +#~ msgstr "???????? (%u) " + +#~ msgid "The card will now be re-configured to generate a key of type: %s\n" +#~ msgstr "" +#~ "???????????????????????????????????: " +#~ "%s\n" + #~ msgid "listen() failed: %s\n" #~ msgstr "listen() ???????: %s\n" ----------------------------------------------------------------------- Summary of changes: po/ja.po | 112 +++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 73 insertions(+), 39 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org