Hello community, here is the log from the commit of package opmsg for openSUSE:Factory checked in at 2017-11-14 12:57:39 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/opmsg (Old) and /work/SRC/openSUSE:Factory/.opmsg.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "opmsg" Tue Nov 14 12:57:39 2017 rev:3 rq:541255 version:1.77s Changes: -------- --- /work/SRC/openSUSE:Factory/opmsg/opmsg.changes 2017-03-31 15:08:05.696197214 +0200 +++ /work/SRC/openSUSE:Factory/.opmsg.new/opmsg.changes 2017-11-14 12:57:43.157857865 +0100 @@ -1,0 +2,10 @@ +Mon Nov 13 10:45:36 UTC 2017 - [email protected] + +- opmsg 1.77s: + * opmsg: correct error msg handling for libcrypto error queue + * opmsg: speeding up keystore load by introducing load flags + * opmsg: dont generate Kex keys in null crypto/signing case + * opmsg: allow to selfsign generated personas, so peer can also + --decrypt it and check sig + +------------------------------------------------------------------- Old: ---- opmsg-1.75s.tar.gz New: ---- opmsg-1.77s.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ opmsg.spec ++++++ --- /var/tmp/diff_new_pack.pol96j/_old 2017-11-14 12:57:44.277816915 +0100 +++ /var/tmp/diff_new_pack.pol96j/_new 2017-11-14 12:57:44.285816623 +0100 @@ -1,7 +1,7 @@ # # spec file for package opmsg # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,20 +16,18 @@ # -%define gittag rel-1.75s Name: opmsg -Version: 1.75s +Version: 1.77s Release: 0 Summary: File encryption, sign and verify utility License: GPL-3.0+ Group: Productivity/Security Url: https://github.com/stealth/opmsg -Source0: https://github.com/stealth/opmsg/archive/%{gittag}.tar.gz#/%{name}-%{version}.tar.gz +Source0: https://github.com/stealth/opmsg/archive/rel-%{version}.tar.gz#/%{name}-%{version}.tar.gz BuildRequires: gcc-c++ #BuildRequires: help2man -BuildRequires: pkg-config +BuildRequires: pkgconfig BuildRequires: pkgconfig(openssl) -BuildRoot: %{_tmppath}/%{name}-%{version}-build %description opmsg is a replacement for gpg which can encrypt/sign/verify your mails or @@ -48,7 +46,7 @@ * Optional cross-domain ECDH Kex. %prep -%setup -q -n %{name}-%{gittag} +%setup -q -n %{name}-rel-%{version} %build pushd src @@ -64,7 +62,6 @@ #help2man ./%{name} --no-info --output %{buildroot}/%{_mandir}/man1/%{name}.1 %files -%defattr(-,root,root) %doc README.md LICENSE sample.config GPL3 %{_bindir}/%{name} %{_bindir}/opmux ++++++ opmsg-1.75s.tar.gz -> opmsg-1.77s.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opmsg-rel-1.75s/README.md new/opmsg-rel-1.77s/README.md --- old/opmsg-rel-1.75s/README.md 2016-11-11 11:48:40.000000000 +0100 +++ new/opmsg-rel-1.77s/README.md 2017-11-09 14:47:16.000000000 +0100 @@ -35,6 +35,8 @@ _opmsg_ builds fine with any of the OpenSSL, LibreSSL and BoringSSL libcrypto libraries. Building against BoringSSL is not recommended due to missing blowfish and ripemd algorithms. +You can use various transports with _opmsg_ such as Mail or [drops](https://github.com/stealth/drops). + Build ----- @@ -376,7 +378,13 @@ MUA integration --------------- -There are two ways to integrate _opmsg_ into your MUA. For cool +First, add to your _~/.gnupg/options_ file the following line: + +``` +keyid-format long +``` + +Next, there are two possible ways to integrate _opmsg_ into your MUA. For cool MUAs like __mutt__, you may build a dedicated _.muttrc_ by adding: ``` @@ -432,11 +440,18 @@ _opmux_ is a wrapper for _opmsg_ and _gpg_, which transparently forwards encryption and decryption requests to the right program, by checking message markers and persona ids. +This way you may use your _opmsg_ and _gpg_ setup in parallel and the correct (de)crypt program is +automagically invoked. When you send a Mail and an _opmsg_ persona is found for the destination, +_opmsg_ is used for encryption, otherwise _gpg_ is used. This requires your personas to be properly `--link`ed or having a valid `my_id` in your -_opmsg_ config. _opmux_ may miss recipients with Cc/Bcc for gpg in above mutt setup. +_opmsg_ config. + +For __enigmail__ or other MUAs you would just configure the gpg-path to be `/path/to/opmux` and you +are done (but dont forget the `keyid-format long` from the first step). -For __enigmail__ or other MUAs you would just configure the gpg-path to be `/usr/local/bin/opmux` and add -`keyid-format long` to your _~/.gnupg/config_ file and you are done. +_opmux_ prefers the _gpg2_ over the _gpg_ binary if both gpg versions are installed. If you +have both gpg versions installed in parallel but for whatever reason want to work with your (old) gpg1 keys, +you have to change the call order in `opmux.c` _gpg()_ function. All this however is just for convenience. The more GUI and layering you add to your _opmsg_ setup, the more chance you have to use wrong destination or source personas. So @@ -600,13 +615,8 @@ Meta data --------- -As _opmsg_ adds additional ids to the mail, it is possible to send all -mail to random address of the destination persona provider who then -could route it to the real mailbox or even offer everything as a single -blob to download for everyone. -This may be useful to defeat mail meta data collection. op-messages are -self contained and ASCII-armored, so they could also be pasted to OTR, -newsgroups, chats or paste-sites and picked up by the target persona from within -a swarm. Also see above discussion of persona linking. - +If you care about meta data collection and want to reduce your data-tracks +even further, check out [drops](https://github.com/stealth/drops). +_drops_ is a p2p transport network for _opmsg_. It allows you to anonymously +drop end2end encrypted op-messages without leaking meta-data such as mail headers. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opmsg-rel-1.75s/src/Makefile new/opmsg-rel-1.77s/src/Makefile --- old/opmsg-rel-1.75s/src/Makefile 2016-11-11 11:48:40.000000000 +0100 +++ new/opmsg-rel-1.77s/src/Makefile 2017-11-09 14:47:16.000000000 +0100 @@ -1,3 +1,9 @@ +# On most Linux distros, this should do. For BSD, please check +# README.md about the defines that you have to pass when invoking "make". +# For OSX or if you want to use non-default distro crypto libs (libressl, +# openssl-dev, openssl-asan etc.), adjust the path names below accordingly. +# + CXX=c++ DEFS= INC= @@ -8,8 +14,12 @@ # Cygwin was reported to require this: #DEFS+=-U__STRICT_ANSI__ +# reported to work with OSX brew +#INC+=-I/opt/local/include +#LIBS+=-L/opt/local/lib + -# this worked for me on OSX +# my alternate openssl path for 1.1.0 #INC+=-I/usr/local/ssl/include #LIBS+=-L/usr/local/ssl/lib #LIBS+=-Wl,--rpath=/usr/local/ssl/lib @@ -36,6 +46,12 @@ # Enable chacha20-poly1305 if avail #DEFS+=-DCHACHA20 + +### +### No editing should be needed below this line. +### + + CXXFLAGS=-Wall -O2 -pedantic -std=c++11 $(INC) $(DEFS) LD=c++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opmsg-rel-1.75s/src/contrib/opmux.cc new/opmsg-rel-1.77s/src/contrib/opmux.cc --- old/opmsg-rel-1.75s/src/contrib/opmux.cc 2016-11-11 11:48:40.000000000 +0100 +++ new/opmsg-rel-1.77s/src/contrib/opmux.cc 2017-11-09 14:47:16.000000000 +0100 @@ -168,7 +168,7 @@ // hash algo not relevant for searching unique_ptr<keystore> ks(new (nothrow) keystore("sha256", cfg)); - if (!ks.get() || ks->load() < 0) + if (!ks.get() || ks->load("", LFLAGS_ALL & ~LFLAGS_KEX) < 0) return 0; // if hex id as rcpt, try right away diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opmsg-rel-1.75s/src/keystore.cc new/opmsg-rel-1.77s/src/keystore.cc --- old/opmsg-rel-1.75s/src/keystore.cc 2016-11-11 11:48:40.000000000 +0100 +++ new/opmsg-rel-1.77s/src/keystore.cc 2017-11-09 14:47:16.000000000 +0100 @@ -1,7 +1,7 @@ /* * This file is part of the opmsg crypto message framework. * - * (C) 2015-2016 by Sebastian Krahmer, + * (C) 2015-2017 by Sebastian Krahmer, * sebastian [dot] krahmer [at] gmail [dot] com * * opmsg is free software: you can redistribute it and/or modify @@ -165,7 +165,7 @@ } -int keystore::load(const string &hex) +int keystore::load(const string &hex, uint32_t how) { if (hex.size() > 0) { if (!is_hex_hash(hex) || hex.size() < 16) @@ -182,7 +182,7 @@ unique_ptr<persona> p(new (nothrow) persona(cfgbase, hex)); if (!p.get()) return build_error("keystore::load:: OOM", -1); - if (p->load() < 0) + if (p->load("", how) < 0) return build_error("keystore::load::" + string(p->why()), -1); personas[hex] = p.release(); return 0; @@ -195,14 +195,11 @@ if (!d) return build_error("load::opendir:", -1); - dirent de, *result = nullptr; + dirent *de = nullptr; for (;;) { - memset(&de, 0, sizeof(de)); - if (readdir_r(d, &de, &result) < 0) + if ((de = readdir(d)) == nullptr) break; - if (!result) - break; - dhex = result->d_name; + dhex = de->d_name; if (!is_hex_hash(dhex)) continue; @@ -218,7 +215,7 @@ break; // might have stale DH keys or so, so dont abort on -1 - if (p->load() < 0) { + if (p->load("", how) < 0) { delete p; continue; } @@ -707,7 +704,7 @@ } -int persona::load(const std::string &dh_hex) +int persona::load(const std::string &dh_hex, uint32_t how) { size_t r = 0; char buf[8192], *fr = nullptr; @@ -785,7 +782,7 @@ unlockf(f.get()); } - // load EC/RSA keys + // load EC/RSA persona key string pub_pem = "", priv_pem = ""; file = dir + "/" + ptype + ".pub.pem"; @@ -831,26 +828,26 @@ } // if a certain dh_hex was given, only load this one. A dh_hex of special kind, only - // make us load RSA keys + // make us load persona keys if (dh_hex.size() > 0) { if (dh_hex == marker::rsa_kex_id || dh_hex == marker::ec_kex_id) return 0; return this->load_dh(dh_hex); } + if (!(how & LFLAGS_KEX)) + return 0; + // otherwise, add all DH keys that are available DIR *d = opendir(dir.c_str()); if (!d) return build_error("load_keys::opendir:", -1); - dirent de, *result = nullptr; + dirent *de = nullptr; for (;;) { - memset(&de, 0, sizeof(de)); - if (readdir_r(d, &de, &result) < 0) - break; - if (!result) + if ((de = readdir(d)) == nullptr) break; - hex = result->d_name; + hex = de->d_name; if (!is_hex_hash(hex)) continue; this->load_dh(hex); @@ -1145,8 +1142,8 @@ pub = ""; priv = ""; - BIGNUM *pub_key = nullptr; - DH_get0_key(dh.get(), &pub_key, nullptr); + const BIGNUM *pub_key = nullptr; + opmsg::DH_get0_key(dh.get(), &pub_key, nullptr); if (bn2hexhash(md, pub_key, hex) < 0) return build_error("gen_dh_key::bn2hexhash: Error hashing DH key.", -1); @@ -1240,8 +1237,8 @@ if (i > 0) return build_error("add_dh_key:: Trying to add multiple DH keys as one.", v0); unique_ptr<DH, DH_del> dh(EVP_PKEY_get1_DH(evp_pub.get()), DH_free); - BIGNUM *pub_key = nullptr; - DH_get0_key(dh.get(), &pub_key, nullptr); + const BIGNUM *pub_key = nullptr; + opmsg::DH_get0_key(dh.get(), &pub_key, nullptr); if (!dh.get() || bn2hexhash(md, pub_key, hex) < 0) return build_error("add_dh_key::bn2hexhash: Error hashing DH pubkey.", v0); } else if (keytype == EVP_PKEY_EC) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opmsg-rel-1.75s/src/keystore.h new/opmsg-rel-1.77s/src/keystore.h --- old/opmsg-rel-1.75s/src/keystore.h 2016-11-11 11:48:40.000000000 +0100 +++ new/opmsg-rel-1.77s/src/keystore.h 2017-11-09 14:47:16.000000000 +0100 @@ -145,6 +145,15 @@ }; +typedef enum : uint32_t { + LFLAGS_NONE = 0, + LFLAGS_NAME = 1, + LFLAGS_KEY = 2, + LFLAGS_KEX = 4, + LFLAGS_ALL = LFLAGS_NAME|LFLAGS_KEY|LFLAGS_KEX +} load_flags; + + class persona { std::string id, name, link_src, ptype; @@ -163,11 +172,13 @@ template<class T> T build_error(const std::string &msg, T r) { + int e = 0; err = "persona::"; err += msg; - if (ERR_get_error()) { + if ((e = ERR_get_error())) { + ERR_load_crypto_strings(); err += ":"; - err += ERR_error_string(ERR_get_error(), nullptr); + err += ERR_error_string(e, nullptr); ERR_clear_error(); } else if (errno) { err += ":"; @@ -292,7 +303,7 @@ void used_key(const std::string &hex, bool); - int load(const std::string &hex = ""); + int load(const std::string &hex = "", uint32_t how = LFLAGS_ALL); int link(const std::string &hex); @@ -364,7 +375,7 @@ return md; } - int load(const std::string &id = ""); + int load(const std::string &id = "", uint32_t how = LFLAGS_ALL); int gen_rsa(std::string &pub, std::string &priv); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opmsg-rel-1.75s/src/message.cc new/opmsg-rel-1.77s/src/message.cc --- old/opmsg-rel-1.75s/src/message.cc 2016-11-11 11:48:40.000000000 +0100 +++ new/opmsg-rel-1.77s/src/message.cc 2017-11-09 14:47:16.000000000 +0100 @@ -263,7 +263,7 @@ return build_error("encrypt: OOM", -1); if (!ec_dh.empty() && (EVP_PKEY_base_id(ec_dh[0]->pub) == EVP_PKEY_DH)) { - BIGNUM *his_pub_key = nullptr, *my_pub_key = nullptr; + const BIGNUM *his_pub_key = nullptr, *my_pub_key = nullptr; unique_ptr<DH, DH_del> dh(EVP_PKEY_get1_DH(ec_dh[0]->pub), DH_free); if (!dh.get()) return build_error("encrypt: OOM", -1); @@ -273,11 +273,11 @@ // re-calculate size for secret in the DH case; it differs slen = DH_size(mydh.get()); secret.reset(new (nothrow) unsigned char[slen]); - DH_get0_key(dh.get(), &his_pub_key, nullptr); + opmsg::DH_get0_key(dh.get(), &his_pub_key, nullptr); if (!secret.get() || DH_compute_key(secret.get(), his_pub_key, mydh.get()) != slen) return build_error("encrypt::DH_compute_key: Cannot compute DH key ", -1); - DH_get0_key(mydh.get(), &my_pub_key, nullptr); + opmsg::DH_get0_key(mydh.get(), &my_pub_key, nullptr); int binlen = BN_num_bytes(my_pub_key); unique_ptr<unsigned char[]> bin(new (nothrow) unsigned char[binlen]); if (!bin.get() || BN_bn2bin(my_pub_key, bin.get()) != binlen) @@ -831,7 +831,7 @@ return build_error("decrypt: OOM", -1); if (DH_check_pub_key(dh.get(), bn.get(), &ecode) != 1) return build_error("decrypt: DH_check_pub_key failed.", -1); - DH_set0_key(dh.get(), bn.release(), nullptr); + opmsg::DH_set0_key(dh.get(), bn.release(), nullptr); EVP_PKEY_assign_DH(peer_key.get(), dh.release()); // ...and a compressed EC_POINT pubkey in ECDH case } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opmsg-rel-1.75s/src/misc.cc new/opmsg-rel-1.77s/src/misc.cc --- old/opmsg-rel-1.75s/src/misc.cc 2016-11-11 11:48:40.000000000 +0100 +++ new/opmsg-rel-1.77s/src/misc.cc 2017-11-09 14:47:16.000000000 +0100 @@ -1,8 +1,8 @@ /* * This file is part of the opmsg crypto message framework. * - * (C) 2015 by Sebastian Krahmer, - * sebastian [dot] krahmer [at] gmail [dot] com + * (C) 2015-2017 by Sebastian Krahmer, + * sebastian [dot] krahmer [at] gmail [dot] com * * opmsg is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opmsg-rel-1.75s/src/missing.cc new/opmsg-rel-1.77s/src/missing.cc --- old/opmsg-rel-1.75s/src/missing.cc 2016-11-11 11:48:40.000000000 +0100 +++ new/opmsg-rel-1.77s/src/missing.cc 2017-11-09 14:47:16.000000000 +0100 @@ -91,26 +91,31 @@ #endif -#if OPENSSL_VERSION_NUMBER <= 0x10100000L || defined HAVE_LIBRESSL || defined HAVE_BORINGSSL -void DH_get0_key(const DH *dh, BIGNUM **pub_key, BIGNUM **priv_key) +void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) { +#if OPENSSL_VERSION_NUMBER <= 0x10100000L || defined HAVE_LIBRESSL || defined HAVE_BORINGSSL if (pub_key) *pub_key = dh->pub_key; if (priv_key) *priv_key = dh->priv_key; -} +#elif OPENSSL_VERSION_NUMBER >= 0x1010001fL // 1.1.0a + ::DH_get0_key(dh, pub_key, priv_key); +#else + ::DH_get0_key(dh, const_cast<BIGNUM **>(pub_key), const_cast<BIGNUM **>(priv_key)); #endif +} -#if OPENSSL_VERSION_NUMBER <= 0x10100000L || defined HAVE_LIBRESSL || defined HAVE_BORINGSSL int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { +#if OPENSSL_VERSION_NUMBER <= 0x10100000L || defined HAVE_LIBRESSL || defined HAVE_BORINGSSL dh->pub_key = pub_key; dh->priv_key = priv_key; +#else + ::DH_set0_key(dh, pub_key, priv_key); +#endif return 1; } -#endif - } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opmsg-rel-1.75s/src/missing.h new/opmsg-rel-1.77s/src/missing.h --- old/opmsg-rel-1.75s/src/missing.h 2016-11-11 11:48:40.000000000 +0100 +++ new/opmsg-rel-1.77s/src/missing.h 2017-11-09 14:47:16.000000000 +0100 @@ -55,11 +55,9 @@ int EVP_PKEY_base_id(const EVP_PKEY *pkey); #endif -#if OPENSSL_VERSION_NUMBER <= 0x10100000L || defined HAVE_LIBRESSL || defined HAVE_BORINGSSL -void DH_get0_key(const DH *dh, BIGNUM **pub_key, BIGNUM **priv_key); +void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key); int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); -#endif } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/opmsg-rel-1.75s/src/opmsg.cc new/opmsg-rel-1.77s/src/opmsg.cc --- old/opmsg-rel-1.75s/src/opmsg.cc 2016-11-11 11:48:40.000000000 +0100 +++ new/opmsg-rel-1.77s/src/opmsg.cc 2017-11-09 14:47:16.000000000 +0100 @@ -1,7 +1,7 @@ /* * This file is part of the opmsg crypto message framework. * - * (C) 2015-2016 by Sebastian Krahmer, + * (C) 2015-2017 by Sebastian Krahmer, * sebastian [dot] krahmer [at] gmail [dot] com * * opmsg is free software: you can redistribute it and/or modify @@ -77,7 +77,7 @@ }; -const string banner = "\nopmsg: version=1.75 -- (C) 2016 opmsg-team: https://github.com/stealth/opmsg\n\n"; +const string banner = "\nopmsg: version=1.77 -- (C) 2017 opmsg-team: https://github.com/stealth/opmsg\n\n"; /* The iostream lib works not very well wrt customized buffering and flushing * (unlike C's setbuffer), so we use string streams and flush ourself when we need to. @@ -397,7 +397,7 @@ // Add new (EC)DH keys for upcoming Kex in future vector<string> newdh; - for (int i = 0; src_p->can_kex_gen() && i < config::new_dh_keys; ++i) { + for (int i = 0; config::calgo != "null" && src_p->can_kex_gen() && i < config::new_dh_keys; ++i) { vector<PKEYbox *> vpbox = src_p->gen_kex_key(config::khash, dst_p->get_id()); if (vpbox.size() > 0) { newdh.push_back(vpbox[0]->hex); @@ -582,7 +582,7 @@ } -int do_newpersona(const string &name, const string &type) +int do_newpersona(const string &name, const string &type, bool sign) { keystore ks(config::phash, config::cfgbase); @@ -621,11 +621,35 @@ estr<<" --deniable"; estr<<"\n\n"; eflush(); + ostr<<pub; if (config::deniable) ostr<<priv; + + // (self-)sign output data shown to user with the freshly generated persona; + // output can be --imported and verified via --decrypt + if (sign) { + string s = ostr.str(); + message msg(config::version, config::cfgbase, config::phash, config::khash, config::shash, "null"); + msg.src_id(p->get_id()); + msg.dst_id(p->get_id()); + + if (p->get_type() == marker::ec) + msg.kex_id(marker::ec_kex_id); + else + msg.kex_id(marker::rsa_kex_id); + + if (msg.encrypt(s, p, p) < 0) { + estr<<prefix<<"ERROR: Signing freshly generated persona key: "<<msg.why()<<endl; eflush(); + return -1; + } + ostr.str(""); + ostr<<s; + } + ostr<<endl; oflush(); + estr<<prefix<<"Check (by phone, otr, twitter, id-selfie etc.) that above id matches\n"; estr<<prefix<<"the import message from your peer.\n"; estr<<prefix<<"AFTER THAT, you can go ahead, safely exchanging op-messages.\n\n"; @@ -634,15 +658,15 @@ } -int do_new_rsa_persona(const string &name) +int do_new_rsa_persona(const string &name, bool sign) { - return do_newpersona(name, marker::rsa); + return do_newpersona(name, marker::rsa, sign); } -int do_new_ec_persona(const string &name) +int do_new_ec_persona(const string &name, bool sign) { - return do_newpersona(name, marker::ec); + return do_newpersona(name, marker::ec, sign); } @@ -716,7 +740,7 @@ search = name; keystore ks(config::phash, config::cfgbase); - if (ks.load(search) < 0) + if (ks.load(search, LFLAGS_ALL & ~LFLAGS_KEX) < 0) // speedup: no Kex keys needed for listing return -1; for (auto i = ks.first_pers(); i != ks.end_pers(); i = ks.next_pers(i)) { @@ -748,7 +772,7 @@ int do_import(const string &name) { if (config::infile == "/dev/stdin") { - estr<<prefix<<"Paste the EC/RSA pubkey here. End with <Ctrl-C>\n\n"; + estr<<prefix<<"Paste the EC/RSA pubkey here. End with <Return> followed by <Ctrl-C>\n\n"; eflush(); } @@ -772,7 +796,9 @@ persona *p = nullptr; if (!(p = ks.add_persona(name, pub, priv, ""))) { - estr<<prefix<<"ERROR: Importing persona: "<<ks.why()<<endl; eflush(); + estr<<prefix<<"ERROR: Importing persona: "<<ks.why()<<endl; + estr<<prefix<<"ERROR: Not a PEM pubkey, missing newline at end of pubkey, or missing Brainpool EC curves? Check 'opmsg -D -C list' with your peer.\n"; + eflush(); return -1; } if (config::deniable) { @@ -786,7 +812,8 @@ estr<<prefix<<"Check with your peer (phone, otr, twitter, selfie, ...) whether above id matches\n"; estr<<prefix<<"with the id that your peer got printed when generating that persona.\n"; estr<<prefix<<"If they do not match, you can delete this persona by removing the subdirectory\n"; - estr<<prefix<<"of obove id inside your ~/.opmsg directory.\n"; + estr<<prefix<<"of obove id inside your ~/.opmsg directory.\n\n"; + estr<<prefix<<"Do not forget to 'opmsg --link' this persona to have a valid sender-id.\n"; // add_persona() also sets persona type. Check for RSA personas which need also DH params // in the deniable case since it also generates new DH Kex keys @@ -855,6 +882,7 @@ struct option lopts[] = { {"confdir", required_argument, nullptr, 'c'}, + {"help", no_argument, nullptr, 'h'}, {"native", no_argument, nullptr, 'R'}, {"encrypt", required_argument, nullptr, 'E'}, {"decrypt", no_argument, nullptr, 'D'}, @@ -906,7 +934,7 @@ usage(argv[0]); // first, try to find out any --config option - if (strcmp(argv[1], "-c") == 0 || strcmp(argv[1], "--config") == 0) { + if (strcmp(argv[1], "-c") == 0 || strcmp(argv[1], "--confdir") == 0) { if (!argv[2]) usage(argv[0]); config::cfgbase = argv[2]; @@ -941,11 +969,14 @@ } - while ((c = getopt_long(argc, argv, "RLlIn:NP:C:p:SE:DV:i:o:c:", lopts, &opt_idx)) != -1) { + while ((c = getopt_long(argc, argv, "hRLlIn:NP:C:p:SE:DV:i:o:c:", lopts, &opt_idx)) != -1) { switch (c) { case 'c': // was already handled break; + case 'h': + usage(argv[0]); + break; case 'i': config::infile = optarg; break; @@ -988,7 +1019,7 @@ cmode = CMODE_DECRYPT; break; case 'S': - cmode = CMODE_SIGN; + cmode |= CMODE_SIGN; break; case 'P': config::my_id = optarg; @@ -998,7 +1029,7 @@ verify_file = optarg; break; case 'N': - cmode = CMODE_NEWP; + cmode |= CMODE_NEWP; break; case 'I': cmode = CMODE_IMPORT; @@ -1022,7 +1053,7 @@ cmode = CMODE_NEWDHP; break; case NEWECP: - cmode = CMODE_NEWECP; + cmode |= CMODE_NEWECP; break; case ID_FORMAT_LONG: config::idformat = "long"; @@ -1123,16 +1154,18 @@ r = do_verify(verify_file); break; case CMODE_NEWP: + case CMODE_NEWP|CMODE_SIGN: estr<<prefix<<"creating new persona (RSA "<<config::rsa_len<<", DH "<<config::dh_plen<<")\n\n"; eflush(); - r = do_new_rsa_persona(name); + r = do_new_rsa_persona(name, (cmode & CMODE_SIGN) == CMODE_SIGN); break; case CMODE_NEWDHP: estr<<prefix<<"creating new DHparams for persona "<<idformat(config::my_id)<<"\n\n"; eflush(); r = do_newdhparams(); break; case CMODE_NEWECP: + case CMODE_NEWECP|CMODE_SIGN: estr<<prefix<<"creating new EC persona (curve "<<config::curves[0]<<")\n\n"; eflush(); - r = do_new_ec_persona(name); + r = do_new_ec_persona(name, (cmode & CMODE_SIGN) == CMODE_SIGN); break; case CMODE_IMPORT: estr<<prefix<<"importing persona\n"; eflush(); @@ -1149,6 +1182,8 @@ case CMODE_PGPLIST: r = do_pgplist(name); break; + default: + estr<<prefix<<"Invalid combination of options?\n"; } if (cmode != CMODE_PGPLIST) {
