mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-22 07:41:20 -04:00
Merged branch v0.5-OpenPGP into trunk:
User-level changes: ================== - libgpgme is not used anymore; it is replaced by a built-in piece of code called OpenPGP-SDK (http://openpgp.nominet.org.uk/cgi-bin/trac.cgi) that was improved to be used by RetroShare for handling PGP keys. - the gnupg keyring is not used anymore. Now, RetroShare has it's own gpg keyring, shared by all instances. On linux it's located in ~/.retroshare/pgp/. A lock system prevents multiple locations to read/write keyrings simultaneously. - the trust database from gnupg is not documented, so RetroShare cannot import it. This comes from the fact that the GPG standard (RFC4880) asks explicitly not to export trust information. So RetroShare has it's own trust DB shared by locations. This means you need to re-trust people. Sorry for that! - at start, if no keyring is found, RS will propose to copy the gnupg keyring to use your existing keys. Clicking on "OK" will do the copy, and you should find back all existing locations, except for DSA keys. - locations for which the suitable keypair is not in the keyring will not be displayed in the login window - locations for which the suitable keypair is not a RSA/RSA key will not be displayed. RetroShare does not support DSA/Elgamal keypairs yet. - a key import/export exchange function has been added in the certificate creation window (you go there from the login window by clicking on "manage keys/locations". This allows to easily create a new location with the same pgp key on another computer. To obtain a suitable keypair using gnupg, you need to concatenate the encrypted private key and the public key into an ascii file. This can be done using: gpg -a --export-secret-keys [your ID] > mykey.asc gpg -a --export [your ID] >> mykey.asc - importing a key with subkeys in not yet possible. Please remove subkeys before importing. - The code has been tested for a reasonnable amount of time, but it's not possible to prevent some new bugs to appear. Please report them asap supplying: call-stacks if possible, and terminal output. In particular, openpgp has some assert()'s that should not be triggered unless RetroShare is calling it in an improper way. Internal changes ================ - a specific component, PGPHandler, takes care of the interface between openpgp-sdk and RetroShare openpgp-sdk is c-code, with it's own memory management, which has been kept well separated from RetroShare. - GPG Ids are now a specific class (not a std::string anymore) for code consistency reasons. As strings are still used in many places, this requires a few conversions. In particular, AuthGPG takes strings as function params and calls GPGHandler with the proper PGPIdType class. In the future, RetroShare should only use PGPIdType. The same will be done for SSL ids. - signature cleaning is still handled by the Retroshare built-in function, not by openpgp, but we will do this later. Still to do =========== - DSA needs subkey handling, since the encryption is performed by a Elgamal subkey. Not sure this will be done. - GPGIds/SSLIds cleaning (meaning replace strings by appropriate types). Lots of confusion throughout the code in retroshare-gui in particular. - key removal from keyring. This is a challenge to keep locations synchronised. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@5293 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
commit
fc8dfcf65b
109 changed files with 26549 additions and 2997 deletions
32
libretroshare/src/tests/pgp/Makefile
Normal file
32
libretroshare/src/tests/pgp/Makefile
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
RS_TOP_DIR = ../..
|
||||
DHT_TOP_DIR = ../../../../libbitdht/src
|
||||
OPENPGP_INCLUDE_DIR = ../../../../openpgpsdk/src
|
||||
|
||||
##### Define any flags that are needed for this section #######
|
||||
###############################################################
|
||||
|
||||
###############################################################
|
||||
include $(RS_TOP_DIR)/tests/scripts/config.mk
|
||||
###############################################################
|
||||
|
||||
TESTOBJ = test_pgp_handler.o test_pgp_signature_parsing.o test_key_parsing.o
|
||||
TESTS = test_pgp_handler test_pgp_signature_parsing test_key_parsing
|
||||
|
||||
#rsbaseitem_test
|
||||
|
||||
all: tests
|
||||
|
||||
test_pgp_handler : test_pgp_handler.o
|
||||
$(CC) $(CFLAGS) -o test_pgp_handler test_pgp_handler.o $(OBJ) $(LIBS) -L../../../../openpgpsdk/src/lib/ -lops -lbz2
|
||||
|
||||
test_pgp_signature_parsing : test_pgp_signature_parsing.o
|
||||
$(CC) $(CFLAGS) -o test_pgp_signature_parsing test_pgp_signature_parsing.o $(OBJ) $(LIBS) -L../../../../openpgpsdk/src/lib/ -lops -lbz2
|
||||
|
||||
test_key_parsing : test_key_parsing.o
|
||||
$(CC) $(CFLAGS) -o test_key_parsing test_key_parsing.o ../../../../openpgpsdk/src/lib/libops.a -lssl -lcrypto -lbz2
|
||||
|
||||
###############################################################
|
||||
include $(RS_TOP_DIR)/scripts/rules.mk
|
||||
###############################################################
|
||||
|
814
libretroshare/src/tests/pgp/argstream.h
Normal file
814
libretroshare/src/tests/pgp/argstream.h
Normal file
|
@ -0,0 +1,814 @@
|
|||
/* Copyright (C) 2004 Xavier Décoret <Xavier.Decoret@imag.fr>
|
||||
*
|
||||
* argsteam 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.
|
||||
*
|
||||
* Foobar 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 General Public License
|
||||
* along with Foobar; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef ARGSTREAM_H
|
||||
#define ARGSTREAM_H
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
class argstream;
|
||||
|
||||
template<class T>
|
||||
class ValueHolder;
|
||||
|
||||
template <typename T>
|
||||
argstream& operator>> (argstream&, const ValueHolder<T>&);
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Interface of ValueHolder<T>
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
template<class T>
|
||||
class ValueHolder
|
||||
{
|
||||
public:
|
||||
ValueHolder(char s,
|
||||
const char* l,
|
||||
T& b,
|
||||
const char* desc,
|
||||
bool mandatory);
|
||||
ValueHolder(const char* l,
|
||||
T& b,
|
||||
const char* desc,
|
||||
bool mandatory);
|
||||
ValueHolder(char s,
|
||||
T& b,
|
||||
const char* desc,
|
||||
bool mandatory);
|
||||
friend argstream& operator>><>(argstream& s,const ValueHolder<T>& v);
|
||||
std::string name() const;
|
||||
std::string description() const;
|
||||
private:
|
||||
std::string shortName_;
|
||||
std::string longName_;
|
||||
T* value_;
|
||||
T initialValue_;
|
||||
std::string description_;
|
||||
bool mandatory_;
|
||||
};
|
||||
template <class T>
|
||||
inline ValueHolder<T>
|
||||
parameter(char s,
|
||||
const char* l,
|
||||
T& b,
|
||||
const char* desc="",
|
||||
bool mandatory = true)
|
||||
{
|
||||
return ValueHolder<T>(s,l,b,desc,mandatory);
|
||||
}
|
||||
template <class T>
|
||||
inline ValueHolder<T>
|
||||
parameter(char s,
|
||||
T& b,
|
||||
const char* desc="",
|
||||
bool mandatory = true)
|
||||
{
|
||||
return ValueHolder<T>(s,b,desc,mandatory);
|
||||
}
|
||||
template <class T>
|
||||
inline ValueHolder<T>
|
||||
parameter(const char* l,
|
||||
T& b,
|
||||
const char* desc="",
|
||||
bool mandatory = true)
|
||||
{
|
||||
return ValueHolder<T>(l,b,desc,mandatory);
|
||||
}
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Interface of OptionHolder
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
class OptionHolder
|
||||
{
|
||||
public:
|
||||
inline OptionHolder(char s,
|
||||
const char* l,
|
||||
bool& b,
|
||||
const char* desc);
|
||||
inline OptionHolder(const char* l,
|
||||
bool& b,
|
||||
const char* desc);
|
||||
inline OptionHolder(char s,
|
||||
bool& b,
|
||||
const char* desc);
|
||||
friend argstream& operator>>(argstream& s,const OptionHolder& v);
|
||||
inline std::string name() const;
|
||||
inline std::string description() const;
|
||||
protected:
|
||||
inline OptionHolder(char s,
|
||||
const char* l,
|
||||
const char* desc);
|
||||
friend OptionHolder help(char s='h',
|
||||
const char* l="help",
|
||||
const char* desc="Display this help");
|
||||
private:
|
||||
std::string shortName_;
|
||||
std::string longName_;
|
||||
bool* value_;
|
||||
std::string description_;
|
||||
};
|
||||
inline OptionHolder
|
||||
option(char s,
|
||||
const char* l,
|
||||
bool& b,
|
||||
const char* desc="")
|
||||
{
|
||||
return OptionHolder(s,l,b,desc);
|
||||
}
|
||||
inline OptionHolder
|
||||
option(char s,
|
||||
bool& b,
|
||||
const char* desc="")
|
||||
{
|
||||
return OptionHolder(s,b,desc);
|
||||
}
|
||||
inline OptionHolder
|
||||
option(const char* l,
|
||||
bool& b,
|
||||
const char* desc="")
|
||||
{
|
||||
return OptionHolder(l,b,desc);
|
||||
}
|
||||
inline OptionHolder
|
||||
help(char s,
|
||||
const char* l,
|
||||
const char* desc)
|
||||
{
|
||||
return OptionHolder(s,l,desc);
|
||||
}
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Interface of ValuesHolder
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
template<class T,class O>
|
||||
class ValuesHolder
|
||||
{
|
||||
public:
|
||||
ValuesHolder(const O& o,
|
||||
const char* desc,
|
||||
int len);
|
||||
template<class A,class B> friend argstream& operator>>(argstream& s,const ValuesHolder<A,B>& v);
|
||||
std::string name() const;
|
||||
std::string description() const;
|
||||
typedef T value_type;
|
||||
private:
|
||||
mutable O value_;
|
||||
std::string description_;
|
||||
int len_;
|
||||
char letter_;
|
||||
};
|
||||
template<class T,class O>
|
||||
inline ValuesHolder<T,O>
|
||||
values(const O& o,
|
||||
const char* desc="",
|
||||
int len=-1)
|
||||
{
|
||||
return ValuesHolder<T,O>(o,desc,len);
|
||||
}
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Interface of ValueParser
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
template <class T>
|
||||
class ValueParser
|
||||
{
|
||||
public:
|
||||
inline T operator()(const std::string& s) const
|
||||
{
|
||||
std::istringstream is(s);
|
||||
T t;
|
||||
is>>t;
|
||||
return t;
|
||||
}
|
||||
};
|
||||
// We need to specialize for string otherwise parsing of a value that
|
||||
// contains space (for example a string with space passed in quotes on the
|
||||
// command line) would parse only the first element of the value!!!
|
||||
template <>
|
||||
class ValueParser<std::string>
|
||||
{
|
||||
public:
|
||||
inline std::string operator()(const std::string& s) const
|
||||
{
|
||||
return s;
|
||||
}
|
||||
};
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Interface of argstream
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
class argstream
|
||||
{
|
||||
public:
|
||||
inline argstream(int argc,char** argv);
|
||||
inline argstream(const char* c);
|
||||
template<class T>
|
||||
friend argstream& operator>>(argstream& s,const ValueHolder<T>& v);
|
||||
friend inline argstream& operator>>(argstream& s,const OptionHolder& v);
|
||||
template<class T,class O>
|
||||
friend argstream& operator>>(argstream& s,const ValuesHolder<T,O>& v);
|
||||
|
||||
inline bool helpRequested() const;
|
||||
inline bool isOk() const;
|
||||
inline std::string errorLog() const;
|
||||
inline std::string usage() const;
|
||||
inline void defaultErrorHandling(bool ignoreUnused=false) const;
|
||||
static inline char uniqueLetter();
|
||||
protected:
|
||||
void parse(int argc,char** argv);
|
||||
private:
|
||||
typedef std::list<std::string>::iterator value_iterator;
|
||||
typedef std::pair<std::string,std::string> help_entry;
|
||||
std::string progName_;
|
||||
std::map<std::string,value_iterator> options_;
|
||||
std::list<std::string> values_;
|
||||
bool minusActive_;
|
||||
bool isOk_;
|
||||
std::deque<help_entry> argHelps_;
|
||||
std::string cmdLine_;
|
||||
std::deque<std::string> errors_;
|
||||
bool helpRequested_;
|
||||
};
|
||||
//************************************************************
|
||||
// Implementation of ValueHolder<T>
|
||||
//************************************************************
|
||||
template<class T>
|
||||
ValueHolder<T>::ValueHolder(char s,
|
||||
const char* l,
|
||||
T& v,
|
||||
const char* desc,
|
||||
bool mandatory)
|
||||
: shortName_(1,s),
|
||||
longName_(l),
|
||||
value_(&v),
|
||||
initialValue_(v),
|
||||
description_(desc),
|
||||
mandatory_(mandatory)
|
||||
{
|
||||
}
|
||||
template<class T>
|
||||
ValueHolder<T>::ValueHolder(const char* l,
|
||||
T& v,
|
||||
const char* desc,
|
||||
bool mandatory)
|
||||
: longName_(l),
|
||||
value_(&v),
|
||||
initialValue_(v),
|
||||
description_(desc),
|
||||
mandatory_(mandatory)
|
||||
{
|
||||
}
|
||||
template<class T>
|
||||
ValueHolder<T>::ValueHolder(char s,
|
||||
T& v,
|
||||
const char* desc,
|
||||
bool mandatory)
|
||||
: shortName_(1,s),
|
||||
value_(&v),
|
||||
initialValue_(v),
|
||||
description_(desc),
|
||||
mandatory_(mandatory)
|
||||
{
|
||||
}
|
||||
template<class T>
|
||||
std::string
|
||||
ValueHolder<T>::name() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
if (!shortName_.empty()) os<<'-'<<shortName_;
|
||||
if (!longName_.empty()) {
|
||||
if (!shortName_.empty()) os<<'/';
|
||||
os<<"--"<<longName_;
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
template<class T>
|
||||
std::string
|
||||
ValueHolder<T>::description() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os<<description_;
|
||||
if (mandatory_)
|
||||
{
|
||||
os<<"(mandatory)";
|
||||
}
|
||||
else
|
||||
{
|
||||
os<<"(default="<<initialValue_<<")";
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
//************************************************************
|
||||
// Implementation of OptionHolder
|
||||
//************************************************************
|
||||
inline OptionHolder::OptionHolder(char s,
|
||||
const char* l,
|
||||
bool& b,
|
||||
const char* desc)
|
||||
: shortName_(1,s),
|
||||
longName_(l),
|
||||
value_(&b),
|
||||
description_(desc)
|
||||
{
|
||||
}
|
||||
inline OptionHolder::OptionHolder(const char* l,
|
||||
bool& b,
|
||||
const char* desc)
|
||||
: longName_(l),
|
||||
value_(&b),
|
||||
description_(desc)
|
||||
{
|
||||
}
|
||||
inline OptionHolder::OptionHolder(char s,
|
||||
bool& b,
|
||||
const char* desc)
|
||||
: shortName_(1,s),
|
||||
value_(&b),
|
||||
description_(desc)
|
||||
{
|
||||
}
|
||||
inline OptionHolder::OptionHolder(char s,
|
||||
const char* l,
|
||||
const char* desc)
|
||||
: shortName_(1,s),
|
||||
longName_(l),
|
||||
value_(NULL),
|
||||
description_(desc)
|
||||
{
|
||||
}
|
||||
inline std::string
|
||||
OptionHolder::name() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
if (!shortName_.empty()) os<<'-'<<shortName_;
|
||||
if (!longName_.empty())
|
||||
{
|
||||
if (!shortName_.empty()) os<<'/';
|
||||
os<<"--"<<longName_;
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
inline std::string
|
||||
OptionHolder::description() const
|
||||
{
|
||||
return description_;
|
||||
}
|
||||
//************************************************************
|
||||
// Implementation of ValuesHolder<T,O>
|
||||
//************************************************************
|
||||
template<class T,class O>
|
||||
ValuesHolder<T,O>::ValuesHolder(const O& o,
|
||||
const char* desc,
|
||||
int len)
|
||||
: value_(o),
|
||||
description_(desc),
|
||||
len_(len)
|
||||
{
|
||||
letter_ = argstream::uniqueLetter();
|
||||
}
|
||||
template <class T,class O>
|
||||
std::string
|
||||
ValuesHolder<T,O>::name() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os<<letter_<<"i";
|
||||
return os.str();
|
||||
}
|
||||
template <class T,class O>
|
||||
std::string
|
||||
ValuesHolder<T,O>::description() const
|
||||
{
|
||||
return description_;
|
||||
}
|
||||
//************************************************************
|
||||
// Implementation of argstream
|
||||
//************************************************************
|
||||
inline
|
||||
argstream::argstream(int argc,char** argv)
|
||||
: progName_(argv[0]),
|
||||
minusActive_(true),
|
||||
isOk_(true)
|
||||
{
|
||||
parse(argc,argv);
|
||||
}
|
||||
inline
|
||||
argstream::argstream(const char* c)
|
||||
: progName_(""),
|
||||
minusActive_(true),
|
||||
isOk_(true)
|
||||
{
|
||||
std::string s(c);
|
||||
// Build argc, argv from s. We must add a dummy first element for
|
||||
// progName because parse() expects it!!
|
||||
std::deque<std::string> args;
|
||||
args.push_back("");
|
||||
std::istringstream is(s);
|
||||
while (is.good())
|
||||
{
|
||||
std::string t;
|
||||
is>>t;
|
||||
args.push_back(t);
|
||||
}
|
||||
char* pargs[args.size()];
|
||||
char** p = pargs;
|
||||
for (std::deque<std::string>::const_iterator
|
||||
iter = args.begin();
|
||||
iter != args.end();++iter)
|
||||
{
|
||||
*p++ = const_cast<char*>(iter->c_str());
|
||||
}
|
||||
parse(args.size(),pargs);
|
||||
}
|
||||
inline void
|
||||
argstream::parse(int argc,char** argv)
|
||||
{
|
||||
// Run thru all arguments.
|
||||
// * it has -- in front : it is a long name option, if remainder is empty,
|
||||
// it is an error
|
||||
// * it has - in front : it is a sequence of short name options, if
|
||||
// remainder is empty, deactivates option (- will
|
||||
// now be considered a char).
|
||||
// * if any other char, or if option was deactivated
|
||||
// : it is a value. Values are split in parameters
|
||||
// (immediately follow an option) and pure values.
|
||||
// Each time a value is parsed, if the previously parsed argument was an
|
||||
// option, then the option is linked to the value in case of it is a
|
||||
// option with parameter. The subtle point is that when several options
|
||||
// are given with short names (ex: -abc equivalent to -a -b -c), the last
|
||||
// parsed option is -c).
|
||||
// Since we use map for option, any successive call overides the previous
|
||||
// one: foo -a -b -a hello is equivalent to foo -b -a hello
|
||||
// For values it is not true since we might have several times the same
|
||||
// value.
|
||||
value_iterator* lastOption = NULL;
|
||||
for (char** a = argv,**astop=a+argc;++a!=astop;)
|
||||
{
|
||||
std::string s(*a);
|
||||
if (minusActive_ && s[0] == '-')
|
||||
{
|
||||
if (s.size() > 1 && s[1] == '-')
|
||||
{
|
||||
if (s.size() == 2)
|
||||
{
|
||||
minusActive_ = false;
|
||||
continue;
|
||||
}
|
||||
lastOption = &(options_[s.substr(2)] = values_.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s.size() > 1)
|
||||
{
|
||||
// Parse all chars, if it is a minus we have an error
|
||||
for (std::string::const_iterator cter = s.begin();
|
||||
++cter != s.end();)
|
||||
{
|
||||
if (*cter == '-')
|
||||
{
|
||||
isOk_ = false;
|
||||
std::ostringstream os;
|
||||
os<<"- in the middle of a switch "<<a;
|
||||
errors_.push_back(os.str());
|
||||
break;
|
||||
}
|
||||
lastOption = &(options_[std::string(1,*cter)] = values_.end());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isOk_ = false;
|
||||
errors_.push_back("Invalid argument -");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
values_.push_back(s);
|
||||
if (lastOption != NULL)
|
||||
{
|
||||
*lastOption = --values_.end();
|
||||
}
|
||||
lastOption = NULL;
|
||||
}
|
||||
}
|
||||
#ifdef ARGSTREAM_DEBUG
|
||||
for (std::map<std::string,value_iterator>::const_iterator
|
||||
iter = options_.begin();iter != options_.end();++iter)
|
||||
{
|
||||
std::cout<<"DEBUG: option "<<iter->first;
|
||||
if (iter->second != values_.end())
|
||||
{
|
||||
std::cout<<" -> "<<*(iter->second);
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
for (std::list<std::string>::const_iterator
|
||||
iter = values_.begin();iter != values_.end();++iter)
|
||||
{
|
||||
std::cout<<"DEBUG: value "<<*iter<<std::endl;
|
||||
}
|
||||
#endif // ARGSTREAM_DEBUG
|
||||
}
|
||||
inline bool
|
||||
argstream::isOk() const
|
||||
{
|
||||
return isOk_;
|
||||
}
|
||||
inline bool
|
||||
argstream::helpRequested() const
|
||||
{
|
||||
return helpRequested_;
|
||||
}
|
||||
inline std::string
|
||||
argstream::usage() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os<<"usage: "<<progName_<<cmdLine_<<'\n';
|
||||
unsigned int lmax = 0;
|
||||
for (std::deque<help_entry>::const_iterator
|
||||
iter = argHelps_.begin();iter != argHelps_.end();++iter)
|
||||
{
|
||||
if (lmax<iter->first.size()) lmax = iter->first.size();
|
||||
}
|
||||
for (std::deque<help_entry>::const_iterator
|
||||
iter = argHelps_.begin();iter != argHelps_.end();++iter)
|
||||
{
|
||||
os<<'\t'<<iter->first<<std::string(lmax-iter->first.size(),' ')
|
||||
<<" : "<<iter->second<<'\n';
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
inline std::string
|
||||
argstream::errorLog() const
|
||||
{
|
||||
std::string s;
|
||||
for(std::deque<std::string>::const_iterator iter = errors_.begin();
|
||||
iter != errors_.end();++iter)
|
||||
{
|
||||
s += *iter;
|
||||
s += '\n';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
inline char
|
||||
argstream::uniqueLetter()
|
||||
{
|
||||
static unsigned int c = 'a';
|
||||
return c++;
|
||||
}
|
||||
template<class T>
|
||||
argstream&
|
||||
operator>>(argstream& s,const ValueHolder<T>& v)
|
||||
{
|
||||
// Search in the options if there is any such option defined either with a
|
||||
// short name or a long name. If both are found, only the last one is
|
||||
// used.
|
||||
#ifdef ARGSTREAM_DEBUG
|
||||
std::cout<<"DEBUG: searching "<<v.shortName_<<" "<<v.longName_<<std::endl;
|
||||
#endif
|
||||
s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
|
||||
if (v.mandatory_)
|
||||
{
|
||||
if (!v.shortName_.empty())
|
||||
{
|
||||
s.cmdLine_ += " -";
|
||||
s.cmdLine_ += v.shortName_;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.cmdLine_ += " --";
|
||||
s.cmdLine_ += v.longName_;
|
||||
}
|
||||
s.cmdLine_ += " value";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!v.shortName_.empty())
|
||||
{
|
||||
s.cmdLine_ += " [-";
|
||||
s.cmdLine_ += v.shortName_;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.cmdLine_ += " [--";
|
||||
s.cmdLine_ += v.longName_;
|
||||
}
|
||||
s.cmdLine_ += " value]";
|
||||
|
||||
}
|
||||
std::map<std::string,argstream::value_iterator>::iterator iter =
|
||||
s.options_.find(v.shortName_);
|
||||
if (iter == s.options_.end())
|
||||
{
|
||||
iter = s.options_.find(v.longName_);
|
||||
}
|
||||
if (iter != s.options_.end())
|
||||
{
|
||||
// If we find counterpart for value holder on command line, either it
|
||||
// has an associated value in which case we assign it, or it has not, in
|
||||
// which case we have an error.
|
||||
if (iter->second != s.values_.end())
|
||||
{
|
||||
#ifdef ARGSTREAM_DEBUG
|
||||
std::cout<<"DEBUG: found value "<<*(iter->second)<<std::endl;
|
||||
#endif
|
||||
ValueParser<T> p;
|
||||
*(v.value_) = p(*(iter->second));
|
||||
// The option and its associated value are removed, the subtle thing
|
||||
// is that someother options might have this associated value too,
|
||||
// which we must invalidate.
|
||||
s.values_.erase(iter->second);
|
||||
for (std::map<std::string,argstream::value_iterator>::iterator
|
||||
jter = s.options_.begin();jter != s.options_.end();++jter)
|
||||
{
|
||||
if (jter->second == iter->second)
|
||||
{
|
||||
jter->second = s.values_.end();
|
||||
}
|
||||
}
|
||||
s.options_.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
s.isOk_ = false;
|
||||
std::ostringstream os;
|
||||
os<<"No value following switch "<<iter->first
|
||||
<<" on command line";
|
||||
s.errors_.push_back(os.str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v.mandatory_)
|
||||
{
|
||||
s.isOk_ = false;
|
||||
std::ostringstream os;
|
||||
os<<"Mandatory parameter ";
|
||||
if (!v.shortName_.empty()) os<<'-'<<v.shortName_;
|
||||
if (!v.longName_.empty())
|
||||
{
|
||||
if (!v.shortName_.empty()) os<<'/';
|
||||
os<<"--"<<v.longName_;
|
||||
}
|
||||
os<<" missing";
|
||||
s.errors_.push_back(os.str());
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
inline argstream&
|
||||
operator>>(argstream& s,const OptionHolder& v)
|
||||
{
|
||||
// Search in the options if there is any such option defined either with a
|
||||
// short name or a long name. If both are found, only the last one is
|
||||
// used.
|
||||
#ifdef ARGSTREAM_DEBUG
|
||||
std::cout<<"DEBUG: searching "<<v.shortName_<<" "<<v.longName_<<std::endl;
|
||||
#endif
|
||||
s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
|
||||
{
|
||||
std::string c;
|
||||
if (!v.shortName_.empty())
|
||||
{
|
||||
c += " [-";
|
||||
c += v.shortName_;
|
||||
}
|
||||
else
|
||||
{
|
||||
c += " [--";
|
||||
c += v.longName_;
|
||||
}
|
||||
c += "]";
|
||||
s.cmdLine_ = c+s.cmdLine_;
|
||||
}
|
||||
std::map<std::string,argstream::value_iterator>::iterator iter =
|
||||
s.options_.find(v.shortName_);
|
||||
if (iter == s.options_.end())
|
||||
{
|
||||
iter = s.options_.find(v.longName_);
|
||||
}
|
||||
if (iter != s.options_.end())
|
||||
{
|
||||
// If we find counterpart for value holder on command line then the
|
||||
// option is true and if an associated value was found, it is ignored
|
||||
if (v.value_ != NULL)
|
||||
{
|
||||
*(v.value_) = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.helpRequested_ = true;
|
||||
}
|
||||
// The option only is removed
|
||||
s.options_.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v.value_ != NULL)
|
||||
{
|
||||
*(v.value_) = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.helpRequested_ = false;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
template<class T,class O>
|
||||
argstream&
|
||||
operator>>(argstream& s,const ValuesHolder<T,O>& v)
|
||||
{
|
||||
s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
|
||||
{
|
||||
std::ostringstream os;
|
||||
os<<' '<<v.letter_<<'1';
|
||||
switch (v.len_)
|
||||
{
|
||||
case -1:
|
||||
os<<"...";
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
os<<"..."<<v.letter_<<v.len_;
|
||||
break;
|
||||
}
|
||||
s.cmdLine_ += os.str();
|
||||
}
|
||||
std::list<std::string>::iterator first = s.values_.begin();
|
||||
// We add to the iterator as much values as we can, limited to the length
|
||||
// specified (if different of -1)
|
||||
int n = v.len_ != -1?v.len_:s.values_.size();
|
||||
while (first != s.values_.end() && n-->0)
|
||||
{
|
||||
// Read the value from the string *first
|
||||
ValueParser<T> p;
|
||||
*(v.value_++) = p(*first );
|
||||
s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
|
||||
// The value we just removed was maybe "remembered" by an option so we
|
||||
// remove it now.
|
||||
for (std::map<std::string,argstream::value_iterator>::iterator
|
||||
jter = s.options_.begin();jter != s.options_.end();++jter)
|
||||
{
|
||||
if (jter->second == first)
|
||||
{
|
||||
jter->second = s.values_.end();
|
||||
}
|
||||
}
|
||||
++first;
|
||||
}
|
||||
// Check if we have enough values
|
||||
if (n != 0)
|
||||
{
|
||||
s.isOk_ = false;
|
||||
std::ostringstream os;
|
||||
os<<"Expecting "<<v.len_<<" values";
|
||||
s.errors_.push_back(os.str());
|
||||
}
|
||||
// Erase the values parsed
|
||||
s.values_.erase(s.values_.begin(),first);
|
||||
return s;
|
||||
}
|
||||
inline void
|
||||
argstream::defaultErrorHandling(bool ignoreUnused) const
|
||||
{
|
||||
if (helpRequested_)
|
||||
{
|
||||
std::cout<<usage();
|
||||
exit(1);
|
||||
}
|
||||
if (!isOk_)
|
||||
{
|
||||
std::cerr<<errorLog();
|
||||
exit(1);
|
||||
}
|
||||
if (!ignoreUnused &&
|
||||
(!values_.empty() || !options_.empty()))
|
||||
{
|
||||
std::cerr<<"Unused arguments"<<std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif // ARGSTREAM_H
|
||||
|
60
libretroshare/src/tests/pgp/test_key_parsing.cc
Normal file
60
libretroshare/src/tests/pgp/test_key_parsing.cc
Normal file
|
@ -0,0 +1,60 @@
|
|||
// COMPILE_LINE: g++ -o test_key_parsing test_key_parsing.cc -g -I../../../openpgpsdk/include -I../ -L../lib ../../../openpgpsdk/src/lib/libops.a -lssl -lcrypto -lbz2
|
||||
//
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <openpgpsdk/std_print.h>
|
||||
#include <openpgpsdk/keyring_local.h>
|
||||
#include <openpgpsdk/util.h>
|
||||
}
|
||||
|
||||
#include "argstream.h"
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// test PGPHandler
|
||||
//
|
||||
// 0 - init
|
||||
|
||||
bool armoured = false ;
|
||||
std::string keyfile ;
|
||||
|
||||
argstream as(argc,argv) ;
|
||||
|
||||
as >> parameter('i',"input-key",keyfile,"input key file.",true)
|
||||
>> option('a',"armoured",armoured,"input is armoured")
|
||||
>> help() ;
|
||||
|
||||
as.defaultErrorHandling() ;
|
||||
|
||||
ops_keyring_t *kr = (ops_keyring_t*)malloc(sizeof(ops_keyring_t)) ;
|
||||
kr->nkeys = 0 ;
|
||||
kr->nkeys_allocated = 0 ;
|
||||
kr->keys = 0 ;
|
||||
|
||||
if(ops_false == ops_keyring_read_from_file(kr,armoured, keyfile.c_str()))
|
||||
throw std::runtime_error("PGPHandler::readKeyRing(): cannot read key file. File corrupted, or missing/superfluous armour parameter.") ;
|
||||
|
||||
for(int i=0;i<kr->nkeys;++i)
|
||||
{
|
||||
ops_print_public_keydata(&kr->keys[i]) ;
|
||||
ops_print_public_keydata_verbose(&kr->keys[i]) ;
|
||||
ops_print_public_key(&kr->keys[i].key.pkey) ;
|
||||
}
|
||||
|
||||
ops_list_packets(const_cast<char *>(keyfile.c_str()),armoured,kr,NULL) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
std::cerr << "Caught exception: " << e.what() << std::endl;
|
||||
return 1 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
155
libretroshare/src/tests/pgp/test_pgp_handler.cc
Normal file
155
libretroshare/src/tests/pgp/test_pgp_handler.cc
Normal file
|
@ -0,0 +1,155 @@
|
|||
// COMPILE_LINE: g++ -o test_pgp_handler test_pgp_handler.cc -I../../../openpgpsdk/include -I../ -L../lib -lretroshare ../../../libbitdht/src/lib/libbitdht.a ../../../openpgpsdk/lib/libops.a -lgnome-keyring -lupnp -lssl -lcrypto -lbz2
|
||||
//
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <pgp/pgphandler.h>
|
||||
|
||||
static std::string passphrase_callback(void *data,const char *uid_info,const char *what,int prev_was_bad)
|
||||
{
|
||||
return std::string(getpass(what)) ;
|
||||
}
|
||||
|
||||
static std::string stringFromBytes(unsigned char *bytes,size_t len)
|
||||
{
|
||||
static const char out[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ;
|
||||
|
||||
std::string res ;
|
||||
|
||||
for(int j = 0; j < len; j++)
|
||||
{
|
||||
res += out[ (bytes[j]>>4) ] ;
|
||||
res += out[ bytes[j] & 0xf ] ;
|
||||
}
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
// test pgp ids.
|
||||
//
|
||||
PGPIdType id = PGPIdType(std::string("3e5b22140ef56abb")) ;
|
||||
|
||||
//std::cerr << "Id is : " << std::hex << id.toUInt64() << std::endl;
|
||||
std::cerr << "Id st : " << id.toStdString() << std::endl;
|
||||
|
||||
// test PGPHandler
|
||||
//
|
||||
// 0 - init
|
||||
|
||||
static const std::string pubring = "pubring.gpg" ;
|
||||
static const std::string secring = "secring.gpg" ;
|
||||
static const std::string trustdb = "trustdb.gpg" ;
|
||||
static const std::string lockfile = "lock" ;
|
||||
|
||||
PGPHandler::setPassphraseCallback(&passphrase_callback) ;
|
||||
PGPHandler pgph(pubring,secring,trustdb,lockfile) ;
|
||||
|
||||
// std::cerr << "Writing public keyring to file tmp_keyring.asc" << std::endl;
|
||||
// pgph.writePublicKeyring("tmp_keyring.asc") ;
|
||||
|
||||
pgph.printKeys() ;
|
||||
|
||||
std::cerr << std::endl ;
|
||||
std::cerr << std::endl ;
|
||||
|
||||
std::cerr << "Looking for keys with complete secret/public key pair: " << std::endl;
|
||||
|
||||
std::list<PGPIdType> lst ;
|
||||
pgph.availableGPGCertificatesWithPrivateKeys(lst) ;
|
||||
|
||||
for(std::list<PGPIdType>::const_iterator it(lst.begin());it!=lst.end();++it)
|
||||
std::cerr << "Found id : " << (*it).toStdString() << std::endl;
|
||||
|
||||
std::string email_str("test@gmail.com") ;
|
||||
std::string name_str("test") ;
|
||||
std::string passw_str("test00") ;
|
||||
|
||||
std::cerr << "Now generating a new PGP certificate: " << std::endl;
|
||||
std::cerr << " email: " << email_str << std::endl;
|
||||
std::cerr << " passw: " << passw_str << std::endl;
|
||||
std::cerr << " name : " << name_str << std::endl;
|
||||
|
||||
PGPIdType newid ;
|
||||
std::string errString ;
|
||||
|
||||
if(!pgph.GeneratePGPCertificate(name_str, email_str, passw_str, newid, errString))
|
||||
std::cerr << "Generation of certificate returned error: " << errString << std::endl;
|
||||
else
|
||||
std::cerr << "Certificate generation success. New id = " << newid.toStdString() << std::endl;
|
||||
|
||||
PGPIdType id2 = PGPIdType(std::string("618E54CF7670FF5E")) ;
|
||||
std::cerr << "Now extracting key " << id2.toStdString() << " from keyring:" << std::endl ;
|
||||
std::string cert = pgph.SaveCertificateToString(id2,false) ;
|
||||
|
||||
std::cerr << "Now, trying to re-read this cert from the string:" << std::endl;
|
||||
|
||||
PGPIdType id3 ;
|
||||
std::string error_string ;
|
||||
pgph.LoadCertificateFromString(cert,id3,error_string) ;
|
||||
|
||||
std::cerr << "Loaded cert id: " << id3.toStdString() << ", Error string=\"" << error_string << "\"" << std::endl;
|
||||
|
||||
std::cerr << cert << std::endl;
|
||||
|
||||
std::cerr << "Testing password callback: " << std::endl;
|
||||
|
||||
std::string pass = passphrase_callback(NULL,newid.toStdString().c_str(),"Please enter password: ",false) ;
|
||||
|
||||
std::cerr << "Password = \"" << pass << "\"" << std::endl;
|
||||
|
||||
std::cerr << "Testing signature with keypair " << newid.toStdString() << std::endl;
|
||||
|
||||
static const size_t BUFF_LEN = 25 ;
|
||||
unsigned char *test_bin = new unsigned char[BUFF_LEN] ;
|
||||
for(size_t i=0;i<BUFF_LEN;++i)
|
||||
test_bin[i] = rand()%26 + 'a' ;
|
||||
|
||||
std::cerr << "Text = \"" << std::string((char *)test_bin,BUFF_LEN) << "\"" << std::endl;
|
||||
|
||||
unsigned char sign[1000] ;
|
||||
uint32_t signlen = 1000 ;
|
||||
|
||||
if(!pgph.SignDataBin(newid,test_bin,BUFF_LEN,sign,&signlen))
|
||||
std::cerr << "Signature error." << std::endl;
|
||||
else
|
||||
std::cerr << "Signature success." << std::endl;
|
||||
|
||||
std::cerr << "Signature length: " << signlen << std::endl;
|
||||
std::cerr << "Signature: " << stringFromBytes(sign,signlen) << std::endl;
|
||||
std::cerr << "Now verifying signature..." << std::endl;
|
||||
|
||||
PGPFingerprintType fingerprint ;
|
||||
if(!pgph.getKeyFingerprint(newid,fingerprint) )
|
||||
std::cerr << "Cannot find fingerprint of key id " << newid.toStdString() << std::endl;
|
||||
|
||||
if(!pgph.VerifySignBin(test_bin,BUFF_LEN,sign,signlen,fingerprint))
|
||||
std::cerr << "Signature verification failed." << std::endl;
|
||||
else
|
||||
std::cerr << "Signature verification worked!" << std::endl;
|
||||
|
||||
delete[] test_bin ;
|
||||
|
||||
std::string outfile = "crypted_toto.pgp" ;
|
||||
std::string text_to_encrypt = "this is a secret message" ;
|
||||
|
||||
std::cerr << "Checking encrypted file creation: streaming chain \"" << text_to_encrypt << "\" to file " << outfile << " with key " << id2.toStdString() << std::endl;
|
||||
|
||||
if(!pgph.encryptTextToFile(id2,text_to_encrypt,outfile))
|
||||
std::cerr << "Encryption failed" << std::endl;
|
||||
else
|
||||
std::cerr << "Encryption success" << std::endl;
|
||||
|
||||
std::string decrypted_text = "" ;
|
||||
outfile = "crypted_toto2.pgp" ;
|
||||
|
||||
if(!pgph.decryptTextFromFile(id2,decrypted_text,outfile))
|
||||
std::cerr << "Decryption failed" << std::endl;
|
||||
else
|
||||
std::cerr << "Decryption success" << std::endl;
|
||||
|
||||
std::cerr << "Decrypted text: \"" << decrypted_text << "\"" << std::endl;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
49
libretroshare/src/tests/pgp/test_pgp_signature_parsing.cc
Normal file
49
libretroshare/src/tests/pgp/test_pgp_signature_parsing.cc
Normal file
|
@ -0,0 +1,49 @@
|
|||
// COMPILE_LINE: g++ -o test_pgp_signature_parsing test_pgp_signature_parsing.cc -g -I../../../openpgpsdk/include -I../ -L../lib -lretroshare ../../../libbitdht/src/lib/libbitdht.a ../../../openpgpsdk/lib/libops.a -lgnome-keyring -lupnp -lssl -lcrypto -lbz2
|
||||
//
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <pgp/pgphandler.h>
|
||||
|
||||
static std::string passphrase_callback(void *data,const char *uid_info,const char *what,int prev_was_bad)
|
||||
{
|
||||
return std::string(getpass(what)) ;
|
||||
}
|
||||
|
||||
static std::string stringFromBytes(unsigned char *bytes,size_t len)
|
||||
{
|
||||
static const char out[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ;
|
||||
|
||||
std::string res ;
|
||||
|
||||
for(int j = 0; j < len; j++)
|
||||
{
|
||||
res += out[ (bytes[j]>>4) ] ;
|
||||
res += out[ bytes[j] & 0xf ] ;
|
||||
}
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
// test pgp ids.
|
||||
//
|
||||
PGPIdType id("3e5b22140ef56abb") ;
|
||||
|
||||
std::cerr << "Id st : " << id.toStdString() << std::endl;
|
||||
|
||||
// test PGPHandler
|
||||
//
|
||||
// 0 - init
|
||||
|
||||
static const std::string pubring = "pubring.gpg" ;
|
||||
static const std::string secring = "secring.gpg" ;
|
||||
static const std::string trustdb = "trustdb.gpg" ;
|
||||
static const std::string lockfil = "lock" ;
|
||||
|
||||
PGPHandler::setPassphraseCallback(&passphrase_callback) ;
|
||||
PGPHandler pgph(pubring,secring,trustdb,lockfil) ;
|
||||
|
||||
pgph.printKeys() ;
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ BITDIR = $(DHT_TOP_DIR)/lib
|
|||
LIBRS = $(LIBDIR)/libretroshare.a
|
||||
BITDHT = $(BITDIR)/libbitdht.a
|
||||
# Unix: Linux/Cygwin
|
||||
INCLUDE = -I $(RS_TOP_DIR)
|
||||
INCLUDE = -I $(RS_TOP_DIR) -I$(OPENPGP_INCLUDE_DIR)
|
||||
CFLAGS = -Wall -g $(INCLUDE)
|
||||
#CFLAGS += -fprofile-arcs -ftest-coverage
|
||||
CFLAGS += ${DEFINES}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue