implemented the sign, trust and validitty functionnality in authGPG. Fix a singleton bug for authGPG and authSSL

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2007 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
joss17 2010-01-13 21:05:38 +00:00
parent 6055c30832
commit 9c17aced37
8 changed files with 103 additions and 204 deletions

View File

@ -24,41 +24,15 @@
*
*/
/****
* At an SSL Certificate level:
* Processx509() calls (virtual) ValidateCertificate() to check if it correctly
* signed by an known PGP certificate.
*
* this will return true - even if the pgp cert is not authed.
*
* a connection will cause VerifyX509Callback to be called. This is a virtual fn.
*
* AuthCertificate() is called to make a certificate authenticated.
* this does nothing but set a flag at the SSL level
* no real auth at SSL only level.
*
* GPG Functions:
* ValidateCertificate() calls,
* bool AuthGPG::AuthX509(X509 *x509)
* VerifySignature()
*
* VerifyX509Callback()
* calls AuthX509().
* calls isPGPAuthenticated(std::string id)
*
* AuthCertificate().
* check isPGPAuthenticated().
* if not - sign PGP certificate.
*
* access to local data is protected via pgpMtx.
*/
#include "authgpg.h"
#include <rsiface/rsiface.h>
#include <iostream>
#include <sstream>
#include <algorithm>
// initialisation du pointeur de singleton à zéro
AuthGPG *AuthGPG::instance_gpg = new AuthGPG();
/* Turn a set of parameters into a string */
static std::string setKeyPairParams(bool useRsa, unsigned int blen,
std::string name, std::string comment, std::string email,
@ -120,11 +94,6 @@ gpg_error_t pgp_pwd_callback(void *hook, const char *uid_hint, const char *passp
static char *PgpPassword = NULL;
AuthGPG *AuthGPG::getAuthGPG()
{
return &instance_gpgroot;
}
bool AuthGPG::setPGPPassword_locked(std::string pwd)
{
/* reset it while we change it */
@ -216,20 +185,9 @@ AuthGPG::AuthGPG()
/* if we get to here -> we have inited okay */
gpgmeInit = true;
storeAllKeys_locked();
printAllKeys_locked();
updateTrustAllKeys_locked();
}
bool AuthGPG::getPGPEngineFileName(std::string &fileName)
{
if (!INFO) {
return false;
} else {
fileName = std::string(INFO->file_name);
std :: cerr << "AuthGPG::getPGPEngineFileName() : " << fileName << std::endl;
return true;
}
storeAllKeys_locked();
printAllKeys_locked();
//updateTrustAllKeys_locked();
}
/* This function is called when retroshare is first started
@ -239,7 +197,6 @@ bool AuthGPG::getPGPEngineFileName(std::string &fileName)
*
* returns false if GnuPG is not available.
*/
bool AuthGPG::availablePGPCertificates(std::list<std::string> &ids)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
@ -311,13 +268,6 @@ int AuthGPG::GPGInit(std::string ownId)
return 0;
}
/*****
if (!isOwnCert(ownId))
{
return 0;
}
*****/
if(GPG_ERR_NO_ERROR != (ERR = gpgme_get_key(CTX, ownId.c_str(), &newKey, 1))) {
std::cerr << "Error reading the key from keyring" << std::endl;
return 0;
@ -329,14 +279,14 @@ int AuthGPG::GPGInit(std::string ownId)
mOwnGpgCert.id = ownId;
mOwnGpgCert.key = newKey;
mOwnId = ownId;
mOwnGpgId = ownId;
gpgmeKeySelected = true;
storeAllKeys_locked();
printAllKeys_locked();
// Password set in different fn.
//this->passphrase = passphrase;
//setPGPPassword_locked(passphrase);
std::cerr << "AuthGPG::GPGInit finished." << std::endl;
return true;
return true;
}
int AuthGPG::GPGInit(std::string name, std::string comment,
@ -376,9 +326,12 @@ int AuthGPG::GPGInit(std::string name, std::string comment,
this->passphrase = inPassphrase;
setPGPPassword_locked(inPassphrase);
mOwnId = mOwnGpgCert.id;
mOwnGpgId = mOwnGpgCert.id;
gpgmeKeySelected = true;
storeAllKeys_locked();
printAllKeys_locked();
return 1;
}
@ -486,6 +439,7 @@ bool AuthGPG::storeAllKeys_locked()
nu.name = mainuid->name;
nu.email = mainuid->email;
gpgme_key_sig_t mainsiglist = mainuid->signatures;
nu.ownsign = false;
while(mainsiglist != NULL)
{
if (mainsiglist->status == GPG_ERR_NO_ERROR)
@ -494,7 +448,6 @@ bool AuthGPG::storeAllKeys_locked()
* we haven't go the peer yet.
* (might be yet to come).
*/
std::string keyid = mainsiglist->keyid;
if (nu.signers.end() == std::find(
nu.signers.begin(),
@ -502,6 +455,11 @@ bool AuthGPG::storeAllKeys_locked()
{
nu.signers.push_back(keyid);
}
std::cerr << "keyid: " << keyid << std::endl;
std::cerr << "mOwnGpgId: " << mOwnGpgId << std::endl;
if (keyid == mOwnGpgId) {
nu.ownsign = true;
}
}
mainsiglist = mainsiglist->next;
}
@ -534,11 +492,8 @@ bool AuthGPG::storeAllKeys_locked()
* if GPGME_KEYLIST_MODE_SIGS is on.
* signature notation supplied is GPGME_KEYLIST_MODE_SIG_NOTATION is on
*/
nu.trustLvl = KEY->owner_trust;
nu.ownsign = KEY->can_sign;
nu.validLvl = mainuid->validity;
nu.trusted = (mainuid->validity > GPGME_VALIDITY_MARGINAL);
/* grab a reference, so the key remains */
gpgme_key_ref(KEY);
@ -633,6 +588,7 @@ bool AuthGPG::updateTrustAllKeys_locked()
return true;
}
bool AuthGPG::printAllKeys_locked()
{
@ -647,12 +603,12 @@ bool AuthGPG::printAllKeys_locked()
std::cerr << "\tEmail: " << it->second.email;
std::cerr << std::endl;
std::cerr << "\townsign: " << it->second.ownsign;
std::cerr << std::endl;
std::cerr << "\ttrustLvl: " << it->second.trustLvl;
std::cerr << std::endl;
std::cerr << "\townsign?: " << it->second.ownsign;
std::cerr << std::endl;
std::cerr << "\ttrusted/valid: " << it->second.trusted;
std::cerr << std::endl;
std::cerr << "\tvalidLvl: " << it->second.validLvl;
std::cerr << std::endl;
std::cerr << "\tEmail: " << it->second.email;
std::cerr << std::endl;
@ -971,7 +927,7 @@ std::string AuthGPG::PGPOwnId()
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
return mOwnId;
return mOwnGpgId;
}
bool AuthGPG::getPGPAllList(std::list<std::string> &ids)
@ -1020,14 +976,14 @@ bool AuthGPG::encryptText(gpgme_data_t PLAIN, gpgme_data_t CIPHER) {
return true;
}
bool AuthGPG::getPGPAuthenticatedList(std::list<std::string> &ids)
bool AuthGPG::getPGPSignedList(std::list<std::string> &ids)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
certmap::iterator it;
for(it = mKeyList.begin(); it != mKeyList.end(); it++)
{
if (it->second.trusted)
if (it->second.ownsign)
{
ids.push_back(it->first);
}
@ -1035,43 +991,28 @@ bool AuthGPG::getPGPAuthenticatedList(std::list<std::string> &ids)
return true;
}
bool AuthGPG::getPGPUnknownList(std::list<std::string> &ids)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
certmap::iterator it;
for(it = mKeyList.begin(); it != mKeyList.end(); it++)
{
if (!(it->second.trusted))
{
ids.push_back(it->first);
}
}
return true;
}
bool AuthGPG::isPGPValid(GPG_id id)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
certmap::iterator it;
return (mKeyList.end() != mKeyList.find(id));
certmap::iterator it;
if (mKeyList.end() != (it = mKeyList.find(id))) {
return (it->second.validLvl >= GPGME_VALIDITY_MARGINAL);
} else {
return false;
}
}
bool AuthGPG::isPGPAuthenticated(GPG_id id)
bool AuthGPG::isPGPSigned(GPG_id id)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
certmap::iterator it;
certmap::iterator it;
if (mKeyList.end() != (it = mKeyList.find(id)))
{
/* trustLvl... is just that ... we are interested in validity.
* which is the 'trusted' flag.
*/
return (it->second.trusted);
return (it->second.ownsign);
}
return false;
}
@ -1225,27 +1166,11 @@ bool AuthGPG::LoadCertificateFromString(std::string str)
/*************************************/
/* Auth takes SSL Certificate */
bool AuthGPG::AuthCertificate(GPG_id pgpid)
{
if (isPGPAuthenticated(pgpid))
{
return true;
}
if (!isPGPValid(pgpid))
{
return false;
}
return SignCertificate(pgpid);
}
/* These take PGP Ids */
bool AuthGPG::SignCertificate(GPG_id id)
bool AuthGPG::SignCertificateLevel0(GPG_id id)
{
std::cerr << "AuthGPG::SignCertificate(" << id << ")";
std::cerr << "AuthGPG::SignCertificat(" << id << ")";
std::cerr << std::endl;
@ -1272,12 +1197,13 @@ bool AuthGPG::RevokeCertificate(std::string id)
return false;
}
bool AuthGPG::TrustCertificate(std::string id, bool trust)
bool AuthGPG::TrustCertificateMarginally(std::string id)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
std::cerr << "AuthGPG::TrustCertificate(" << id << "," << trust << ")";
std::cerr << "AuthGPG::TrustCertificateMarginally(" << id << ")";
std::cerr << std::endl;
//TODO implement it
return false;
}
@ -1328,7 +1254,7 @@ int AuthGPG::privateSignCertificate(std::string id)
gpgme_key_t signKey = it->second.key;
gpgme_key_t ownKey = mOwnGpgCert.key;
class SignParams sparams("0", passphrase);
class SignParams sparams("0", passphrase);
class EditParams params(SIGN_START, &sparams);
gpgme_data_t out;
gpg_error_t ERR;
@ -1367,7 +1293,7 @@ int AuthGPG::privateTrustCertificate(std::string id, int trustlvl)
/* The certificate should be in Peers list ??? */
if(!isPGPAuthenticated(id)) {
if(!isPGPSigned(id)) {
std::cerr << "Invalid Certificate" << std::endl;
return 0;
}

View File

@ -27,6 +27,15 @@
*
*/
/****
* Here's GPG policy :
* By default, all pgpg keys imported via a RS user (make friend and accept friend action) are signed at level 0.
* All signed keys by RS are set to be trusted marginally. You can change it to full or no trust in the friend profile
* For a key to be marginaly valid, it has to be signed by one fully trusted key, or at least by 3 marginally trusted keys.
* All keys that have at least marginal validity are designed as valid in RS. They are shown in the RS gui in order to be signed.
* If there is no validity then the key is not shown.
*/
#ifndef RS_GPG_AUTH_HEADER
#define RS_GPG_AUTH_HEADER
@ -52,10 +61,6 @@ class gpgcert
std::string id;
std::string name;
std::string email;
// std::string location;
// std::string org;
//
// std::string issuer;
std::string fpr; /* fingerprint */
std::list<std::string> signers;
@ -64,7 +69,6 @@ class gpgcert
uint32_t validLvl;
bool ownsign;
bool trusted; // means valid in pgp world.
gpgme_key_t key;
};
@ -100,13 +104,8 @@ class AuthGPG
AuthGPG();
~AuthGPG();
static AuthGPG *getAuthGPG();
bool availablePGPCertificates(std::list<std::string> &ids);
//get the pgpg engine used by the pgp functions
bool getPGPEngineFileName(std::string &fileName);
int GPGInit(std::string ownId);
int GPGInit(std::string name, std::string comment,
std::string email, std::string passwd); /* create it */
@ -132,8 +131,6 @@ class AuthGPG
* (see storage at the end of the class)
*
****/
/* initialisation -> done by derived classes */
bool active();
/* Init by generating new Own PGP Cert, or selecting existing PGP Cert */
@ -152,19 +149,16 @@ class AuthGPG
* provide access to details in cache list.
*
****/
/* get Details from the Certificates */
std::string getPGPName(GPG_id pgp_id);
std::string getPGPEmail(GPG_id pgp_id);
/* PGP versions of Certificate Fns */
/* PGP web of trust management */
GPG_id PGPOwnId();
bool getPGPAllList(std::list<std::string> &ids);
bool getPGPAuthenticatedList(std::list<std::string> &ids);
bool getPGPUnknownList(std::list<std::string> &ids);
bool getPGPSignedList(std::list<std::string> &ids);
bool getPGPValidList(std::list<std::string> &ids);
bool isPGPValid(std::string id);
bool isPGPAuthenticated(std::string id);
bool isPGPSigned(std::string id);
/*********************************************************************************/
/************************* STAGE 4 ***********************************************/
@ -173,9 +167,6 @@ class AuthGPG
* STAGE 4: Loading and Saving Certificates. (Strings and Files)
*
****/
/* Load/Save certificates */
bool LoadCertificateFromString(std::string pem);
std::string SaveCertificateToString(std::string id);
@ -189,12 +180,11 @@ class AuthGPG
* done in gpgroot already.
*
****/
/* Signatures */
bool AuthCertificate(std::string uid);
bool SignCertificate(std::string id);
bool SignCertificateLevel0(std::string id);
bool RevokeCertificate(std::string id); /* Particularly hard - leave for later */
bool TrustCertificate(std::string id, bool trust);
bool TrustCertificateNone(std::string id);
bool TrustCertificateMarginally(std::string id);
bool TrustCertificateFully(std::string id);
/*********************************************************************************/
/************************* STAGE 7 ***********************************************/
@ -205,8 +195,6 @@ class AuthGPG
* There should also be Encryption Functions... (do later).
*
****/
bool SignData(std::string input, std::string &sign);
bool SignData(const void *data, const uint32_t len, std::string &sign);
bool SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen);
@ -214,42 +202,36 @@ class AuthGPG
bool VerifySignBin(const void*, uint32_t, unsigned char*, unsigned int);
bool decryptText(gpgme_data_t CIPHER, gpgme_data_t PLAIN);
bool encryptText(gpgme_data_t PLAIN, gpgme_data_t CIPHER);
//END of PGP public functions
static AuthGPG *getAuthGPG() throw() // pour obtenir l'instance
{ return instance_gpg; }
/*********************************************************************************/
/************************* PGP Specific functions ********************************/
/*********************************************************************************/
private:
static AuthGPG *instance_gpg; // pointeur vers le singleton
bool checkSignature(std::string id, std::string hash, std::string signature);
RsMutex pgpMtx;
/* Below is protected via the mutex */
private:
certmap mKeyList;
RsMutex pgpMtx;
/* Below is protected via the mutex */
bool gpgmeInit;
bool gpgmeKeySelected;
bool gpgmeX509Selected;
certmap mKeyList;
gpgme_engine_info_t INFO;
gpgme_ctx_t CTX;
bool gpgmeInit;
bool gpgmeKeySelected;
bool gpgmeX509Selected;
std::string mOwnGpgId;
std::string mX509id;
gpgme_engine_info_t INFO;
gpgme_ctx_t CTX;
gpgcert mOwnGpgCert;
std::string mOwnId;
std::string mX509id;
gpgcert mOwnGpgCert;
std::string passphrase;
std::string passphrase;
};
// the single instance of this
static AuthGPG instance_gpgroot;
/* Sign a key */
typedef enum
{
SIGN_START,
@ -266,7 +248,6 @@ typedef enum
/* Change the key ownertrust */
typedef enum
{
TRUST_START,
@ -286,7 +267,6 @@ typedef enum
* each callback, to keep track of states, errors
* and other data.
*/
class EditParams
{
public:
@ -310,7 +290,6 @@ class EditParams
};
/* Data specific to key signing */
class SignParams
{
public:
@ -324,5 +303,4 @@ class SignParams
}
};
#endif

View File

@ -49,6 +49,9 @@
/********************************************************************************/
/********************************************************************************/
// initialisation du pointeur de singleton à zéro
AuthSSL *AuthSSL::instance_ssl = new AuthSSL();
sslcert::sslcert(X509 *x509, std::string pid)
{
certificate = x509;
@ -399,12 +402,6 @@ AuthSSL::AuthSSL()
{
}
AuthSSL *AuthSSL::getAuthSSL()
{
return &instance_sslroot;
//return NULL;
}
bool AuthSSL::active()
{
return init;
@ -2041,10 +2038,11 @@ bool AuthSSL::AuthX509(X509 *x509)
sigoutl = 0;
goto err;
}
std::cerr << "AuthSSL::AuthX509() X509 authenticated" << std::endl;
return true;
err:
std::cerr << "AuthSSL::AuthX509() X509 NOT authenticated" << std::endl;
return false;
}
/* validate + get id */
@ -2200,11 +2198,13 @@ int AuthSSL::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx)
/* do the REAL Authentication */
if (!AuthX509(X509_STORE_CTX_get_current_cert(ctx)))
{
fprintf(stderr, "AuthSSL::VerifyX509Callback() X509 not authenticated.\n");
return false;
}
std::string pgpid = getX509CNString(X509_STORE_CTX_get_current_cert(ctx)->cert_info->issuer);
if (!AuthGPG::getAuthGPG()->isPGPAuthenticated(pgpid))
if (!AuthGPG::getAuthGPG()->isPGPSigned(pgpid))
{
fprintf(stderr, "AuthSSL::VerifyX509Callback() pgp key not signed by ourself.\n");
return false;
}
preverify_ok = true;
@ -2213,8 +2213,9 @@ int AuthSSL::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx)
(err == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE))
{
std::string pgpid = getX509CNString(X509_STORE_CTX_get_current_cert(ctx)->cert_info->issuer);
if (!AuthGPG::getAuthGPG()->isPGPAuthenticated(pgpid))
if (!AuthGPG::getAuthGPG()->isPGPSigned(pgpid))
{
fprintf(stderr, "AuthSSL::VerifyX509Callback() pgp key not signed by ourself.\n");
return false;
}
preverify_ok = true;

View File

@ -87,9 +87,6 @@ class AuthSSL
{
public:
// the single instance of this
static AuthSSL *getAuthSSL();
/* Initialisation Functions (Unique) */
AuthSSL();
bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey);
@ -185,9 +182,14 @@ bool CheckCertificate(std::string peerId, X509 *x509); /* check that they are e
/* Special Config Loading (backwards compatibility) */
bool loadCertificates(bool &oldFormat, std::map<std::string, std::string> &keyValueMap);
static AuthSSL *getAuthSSL() throw() // pour obtenir l'instance
{ return instance_ssl; }
private:
// the single instance of this
static AuthSSL *instance_ssl;
/* Helper Functions */
bool ProcessX509(X509 *x509, std::string &id);
@ -221,9 +223,6 @@ bool locked_FindCert(std::string id, sslcert **cert);
};
// the single instance of this
static AuthSSL instance_sslroot;
X509_REQ *GenerateX509Req(
std::string pkey_file, std::string passwd,
std::string name, std::string email, std::string org,

View File

@ -87,8 +87,7 @@ class RsPeerDetails
uint32_t trustLvl;
uint32_t validLvl;
bool ownsign; /* we have signed certificate */
bool trusted; /* we trust their signature on others */
bool ownsign; /* we have signed certificate */
/* Network details (only valid if friend) */
uint32_t state;

View File

@ -318,7 +318,7 @@ bool p3Peers::getPeerDetails(std::string id, RsPeerDetails &d)
d.issuer = authDetail.issuer;
d.trusted = AuthGPG::getAuthGPG()->isPGPAuthenticated(AuthSSL::getAuthSSL()->getGPGId(id));
d.ownsign = AuthGPG::getAuthGPG()->isPGPSigned(AuthSSL::getAuthSSL()->getGPGId(id));
/* generate */
@ -954,7 +954,7 @@ int ensureExtension(std::string &name, std::string def_ext)
RsPeerDetails::RsPeerDetails()
:trustLvl(0), ownsign(false), trusted(false), state(0), netMode(0),
:trustLvl(0), ownsign(false), state(0), netMode(0),
lastConnect(0), connectPeriod(0)
{
return;
@ -987,8 +987,7 @@ std::ostream &operator<<(std::ostream &out, const RsPeerDetails &detail)
out << std::endl;
out << " trustLvl: " << detail.trustLvl;
out << " ownSign: " << detail.ownsign;
out << " trusted: " << detail.trusted;
out << " ownSign: " << detail.ownsign;
out << std::endl;
out << " state: " << detail.state;

View File

@ -769,10 +769,6 @@ int RsInit::GetPGPLogins(std::list<std::string> &pgpIds) {
return 1;
}
bool RsInit::getPGPEngineFileName(std::string &fileName) {
return AuthGPG::getAuthGPG()->getPGPEngineFileName(fileName);
}
int RsInit::GetPGPLoginDetails(std::string id, std::string &name, std::string &email)
{
std::cerr << "RsInit::GetPGPLoginDetails for \"" << id << "\"";

View File

@ -30,6 +30,7 @@
#include "services/p3disc.h"
#include "pqi/authssl.h"
#include "pqi/authgpg.h"
#include "pqi/p3connmgr.h"
#include <iostream>
@ -561,7 +562,7 @@ void p3disc::sendPeerIssuer(std::string to, std::string about)
#endif
}
std::string aboutIssuerId = AuthSSL::getAuthSSL()->getIssuerName(about);
std::string aboutIssuerId = AuthSSL::getAuthSSL()->getGPGId(about);
if (aboutIssuerId == "")
{
/* major error! */
@ -575,7 +576,7 @@ void p3disc::sendPeerIssuer(std::string to, std::string about)
// Set Target as input cert.
di -> PeerId(to);
di -> issuerCert = AuthSSL::getAuthSSL()->SaveCertificateToString(aboutIssuerId);
di -> issuerCert = AuthGPG::getAuthGPG()->SaveCertificateToString(aboutIssuerId);
#ifdef P3DISC_DEBUG
std::cerr << "Saved certificate to string in RsDiscIssuer. " << std::endl ;
@ -800,7 +801,7 @@ void p3disc::recvPeerIssuerMsg(RsDiscIssuer *item)
/* load certificate */
std::string peerId;
//bool loaded = AuthSSL::getAuthSSL()->LoadCertificateFromString(item->issuerCert, peerId);
bool loaded = AuthGPG::getAuthGPG()->LoadCertificateFromString(item->issuerCert);
/* cleanup (handled by caller) */