added new feed item types and logic to show connection attempts from forged certificates (e.g. bad signature, bad certificate)

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7018 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2014-01-15 20:19:17 +00:00
parent 3bb98a2424
commit 613f822133
6 changed files with 187 additions and 130 deletions

View File

@ -52,6 +52,15 @@
#include <iomanip>
/* SSL connection diagnostic */
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN = 0x00 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_OK = 0x01 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID = 0x02 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN = 0x03 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR = 0x04 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE = 0x05 ;
/****
* #define AUTHSSL_DEBUG 1
***/
@ -477,8 +486,10 @@ bool AuthSSLimpl::validateOwnCertificate(X509 *x509, EVP_PKEY *pkey)
{
(void) pkey; /* remove unused parameter warning */
uint32_t diagnostic ;
/* standard authentication */
if (!AuthX509WithGPG(x509))
if (!AuthX509WithGPG(x509,diagnostic))
{
return false;
}
@ -863,26 +874,28 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long days)
* this is important - as it allows non-friends messages to be validated.
*/
bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
{
#ifdef AUTHSSL_DEBUG
#ifdef AUTHSSL_DEBUG
fprintf(stderr, "AuthSSLimpl::AuthX509WithGPG() called\n");
#endif
#endif
if (!CheckX509Certificate(x509))
{
std::cerr << "AuthSSLimpl::AuthX509() X509 NOT authenticated : Certificate failed basic checks" << std::endl;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID ;
return false;
}
/* extract CN for peer Id */
std::string issuer = getX509CNString(x509->cert_info->issuer);
RsPeerDetails pd;
#ifdef AUTHSSL_DEBUG
#ifdef AUTHSSL_DEBUG
std::cerr << "Checking GPG issuer : " << issuer << std::endl ;
#endif
#endif
if (!AuthGPG::getAuthGPG()->getGPGDetails(issuer, pd)) {
std::cerr << "AuthSSLimpl::AuthX509() X509 NOT authenticated : AuthGPG::getAuthGPG()->getGPGDetails() returned false." << std::endl;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN ;
return false;
}
@ -913,24 +926,25 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
sigoutl=2048; //hashoutl; //EVP_PKEY_size(pkey);
buf_sigout=(unsigned char *)OPENSSL_malloc((unsigned int)sigoutl);
#ifdef AUTHSSL_DEBUG
#ifdef AUTHSSL_DEBUG
std::cerr << "Buffer Sizes: in: " << inl;
std::cerr << " HashOut: " << hashoutl;
std::cerr << " SigOut: " << sigoutl;
std::cerr << std::endl;
#endif
#endif
if ((buf_in == NULL) || (buf_hashout == NULL) || (buf_sigout == NULL)) {
hashoutl=0;
sigoutl=0;
fprintf(stderr, "AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n");
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err;
}
p=buf_in;
#ifdef AUTHSSL_DEBUG
#ifdef AUTHSSL_DEBUG
std::cerr << "Buffers Allocated" << std::endl;
#endif
#endif
i2d(data,&p);
/* data in buf_in, ready to be hashed */
@ -941,12 +955,13 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
{
hashoutl=0;
fprintf(stderr, "AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n");
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err;
}
#ifdef AUTHSSL_DEBUG
#ifdef AUTHSSL_DEBUG
std::cerr << "Digest Applied: len: " << hashoutl << std::endl;
#endif
#endif
/* copy data into signature */
sigoutl = signature->length;
@ -954,29 +969,32 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
/* NOW check sign via GPG Functions */
//get the fingerprint of the key that is supposed to sign
#ifdef AUTHSSL_DEBUG
#ifdef AUTHSSL_DEBUG
std::cerr << "AuthSSLimpl::AuthX509() verifying the gpg sig with keyprint : " << pd.fpr << std::endl;
std::cerr << "Sigoutl = " << sigoutl << std::endl ;
std::cerr << "pd.fpr = " << pd.fpr << std::endl ;
std::cerr << "hashoutl = " << hashoutl << std::endl ;
#endif
#endif
if (!AuthGPG::getAuthGPG()->VerifySignBin(buf_hashout, hashoutl, buf_sigout, (unsigned int) sigoutl, pd.fpr)) {
sigoutl = 0;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE ;
goto err;
}
#ifdef AUTHSSL_DEBUG
#ifdef AUTHSSL_DEBUG
std::cerr << "AuthSSLimpl::AuthX509() X509 authenticated" << std::endl;
#endif
#endif
OPENSSL_free(buf_in) ;
OPENSSL_free(buf_hashout) ;
OPENSSL_free(buf_sigout) ;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_OK ;
return true;
err:
err:
std::cerr << "AuthSSLimpl::AuthX509() X509 NOT authenticated" << std::endl;
if(buf_in != NULL)
@ -993,8 +1011,10 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
/* validate + get id */
bool AuthSSLimpl::ValidateCertificate(X509 *x509, std::string &peerId)
{
uint32_t auth_diagnostic ;
/* check self signed */
if (!AuthX509WithGPG(x509))
if (!AuthX509WithGPG(x509,auth_diagnostic))
{
#ifdef AUTHSSL_DEBUG
std::cerr << "AuthSSLimpl::ValidateCertificate() bad certificate.";
@ -1099,12 +1119,15 @@ int AuthSSLimpl::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx)
#ifdef AUTHSSL_DEBUG
fprintf(stderr, "Doing REAL PGP Certificates\n");
#endif
uint32_t auth_diagnostic ;
/* do the REAL Authentication */
if (!AuthX509WithGPG(X509_STORE_CTX_get_current_cert(ctx)))
if (!AuthX509WithGPG(X509_STORE_CTX_get_current_cert(ctx),auth_diagnostic))
{
#ifdef AUTHSSL_DEBUG
fprintf(stderr, "AuthSSLimpl::VerifyX509Callback() X509 not authenticated.\n");
#endif
std::cerr << "(WW) Certificate was rejected because authentication failed. Diagnostic = " << auth_diagnostic << std::endl;
return false;
}
std::string pgpid = getX509CNString(X509_STORE_CTX_get_current_cert(ctx)->cert_info->issuer);
@ -1382,8 +1405,9 @@ bool AuthSSLimpl::FailedCertificate(X509 *x509, const std::string& gpgid,
{
std::string ip_address ;
rs_sprintf_append(ip_address, "%s:%u", rs_inet_ntoa(addr.sin_addr).c_str(), ntohs(addr.sin_port));
uint32_t auth_diagnostic = 0 ;
bool authed = (x509 != NULL && AuthX509WithGPG(x509)) ;
bool authed = (x509 != NULL && AuthX509WithGPG(x509,auth_diagnostic)) ;
if(authed)
LocalStoreCert(x509);
@ -1394,7 +1418,22 @@ bool AuthSSLimpl::FailedCertificate(X509 *x509, const std::string& gpgid,
if (incoming)
{
RsServer::notify()->AddPopupMessage(RS_POPUP_CONNECT_ATTEMPT, gpgid, sslcn, sslid);
switch(auth_diagnostic)
{
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_BAD_CERTIFICATE, gpgid, sslid, sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_UNKNOWN_IN , gpgid, sslid, sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_INTERNAL_ERROR , gpgid, sslid, sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_WRONG_SIGNATURE, gpgid, sslid, sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_OK:
case RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN:
default:
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_CONNECT_ATTEMPT, gpgid, sslid, sslcn, ip_address);
}
#ifdef AUTHSSL_DEBUG
std::cerr << " Incoming from: ";
@ -1424,8 +1463,9 @@ bool AuthSSLimpl::CheckCertificate(std::string id, X509 *x509)
{
(void) id; /* remove unused parameter warning */
uint32_t diagnos ;
/* if auths -> store */
if (AuthX509WithGPG(x509))
if (AuthX509WithGPG(x509,diagnos))
{
LocalStoreCert(x509);
return true;
@ -1598,7 +1638,8 @@ bool AuthSSLimpl::loadList(std::list<RsItem*>& load)
X509 *peer = loadX509FromPEM(kit->value);
/* authenticate it */
if (AuthX509WithGPG(peer))
uint32_t diagnos ;
if (AuthX509WithGPG(peer,diagnos))
{
LocalStoreCert(peer);
}

View File

@ -140,7 +140,7 @@ virtual bool decrypt(void *&out, int &outlen, const void *in, int inlen) = 0
virtual X509* SignX509ReqWithGPG(X509_REQ *req, long days) = 0;
virtual bool AuthX509WithGPG(X509 *x509) = 0;
virtual bool AuthX509WithGPG(X509 *x509,uint32_t& auth_diagnostic)=0;
virtual int VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx) = 0;
@ -211,7 +211,7 @@ virtual bool decrypt(void *&out, int &outlen, const void *in, int inlen);
virtual X509* SignX509ReqWithGPG(X509_REQ *req, long days);
virtual bool AuthX509WithGPG(X509 *x509);
virtual bool AuthX509WithGPG(X509 *x509,uint32_t& auth_diagnostic);
virtual int VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx);

View File

@ -80,6 +80,9 @@ const uint32_t RS_FEED_ITEM_SEC_CONNECT_ATTEMPT = RS_FEED_TYPE_SECURITY | 0x00
const uint32_t RS_FEED_ITEM_SEC_AUTH_DENIED = RS_FEED_TYPE_SECURITY | 0x0002;
const uint32_t RS_FEED_ITEM_SEC_UNKNOWN_IN = RS_FEED_TYPE_SECURITY | 0x0003;
const uint32_t RS_FEED_ITEM_SEC_UNKNOWN_OUT = RS_FEED_TYPE_SECURITY | 0x0004;
const uint32_t RS_FEED_ITEM_SEC_WRONG_SIGNATURE = RS_FEED_TYPE_SECURITY | 0x0005;
const uint32_t RS_FEED_ITEM_SEC_BAD_CERTIFICATE = RS_FEED_TYPE_SECURITY | 0x0006;
const uint32_t RS_FEED_ITEM_SEC_INTERNAL_ERROR = RS_FEED_TYPE_SECURITY | 0x0007;
const uint32_t RS_FEED_ITEM_CHAN_NEW = RS_FEED_TYPE_CHAN | 0x0001;
const uint32_t RS_FEED_ITEM_CHAN_UPDATE = RS_FEED_TYPE_CHAN | 0x0002;

View File

@ -214,6 +214,7 @@ void NewsFeed::updateDisplay()
addFeedItemFilesNew(fi);
break;
default:
std::cerr << "(EE) Unknown type " << std::hex << fi.mType << std::dec << " in news feed." << std::endl;
break;
}
} else {
@ -557,12 +558,12 @@ void NewsFeed::addFeedItemPeerNew(RsFeedItem &fi)
void NewsFeed::addFeedItemSecurityConnectAttempt(RsFeedItem &fi)
{
/* make new widget */
SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, fi.mId1, fi.mId2, fi.mId3, fi.mId4, SEC_TYPE_CONNECT_ATTEMPT, false);
SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, fi.mId1, fi.mId2, fi.mId3, fi.mId4, fi.mType, false);
/* store */
/* add to layout */
addFeedItemIfUnique(pi, SEC_TYPE_CONNECT_ATTEMPT, fi.mId2, false);
addFeedItemIfUnique(pi, fi.mType, fi.mId2, false);
#ifdef NEWS_DEBUG
std::cerr << "NewsFeed::addFeedItemSecurityConnectAttempt()";
@ -573,12 +574,12 @@ void NewsFeed::addFeedItemSecurityConnectAttempt(RsFeedItem &fi)
void NewsFeed::addFeedItemSecurityAuthDenied(RsFeedItem &fi)
{
/* make new widget */
SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, fi.mId1, fi.mId2, fi.mId3, fi.mId4, SEC_TYPE_AUTH_DENIED, false);
SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, fi.mId1, fi.mId2, fi.mId3, fi.mId4, fi.mType, false);
/* store */
/* add to layout */
addFeedItemIfUnique(pi, SEC_TYPE_AUTH_DENIED, fi.mId2, false);
addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_AUTH_DENIED, fi.mId2, false);
#ifdef NEWS_DEBUG
std::cerr << "NewsFeed::addFeedItemSecurityAuthDenied()";
@ -589,12 +590,12 @@ void NewsFeed::addFeedItemSecurityAuthDenied(RsFeedItem &fi)
void NewsFeed::addFeedItemSecurityUnknownIn(RsFeedItem &fi)
{
/* make new widget */
SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, fi.mId1, fi.mId2, fi.mId3, fi.mId4, SEC_TYPE_UNKNOWN_IN, false);
SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, fi.mId1, fi.mId2, fi.mId3, fi.mId4, RS_FEED_ITEM_SEC_UNKNOWN_IN, false);
/* store */
/* add to layout */
addFeedItemIfUnique(pi, SEC_TYPE_UNKNOWN_IN, fi.mId2, false);
addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_UNKNOWN_IN, fi.mId2, false);
#ifdef NEWS_DEBUG
std::cerr << "NewsFeed::addFeedItemSecurityUnknownIn()";
@ -605,12 +606,12 @@ void NewsFeed::addFeedItemSecurityUnknownIn(RsFeedItem &fi)
void NewsFeed::addFeedItemSecurityUnknownOut(RsFeedItem &fi)
{
/* make new widget */
SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, fi.mId1, fi.mId2, fi.mId3, fi.mId4, SEC_TYPE_UNKNOWN_OUT, false);
SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, fi.mId1, fi.mId2, fi.mId3, fi.mId4, RS_FEED_ITEM_SEC_UNKNOWN_OUT, false);
/* store */
/* add to layout */
addFeedItemIfUnique(pi, SEC_TYPE_UNKNOWN_OUT, fi.mId2, false);
addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_UNKNOWN_OUT, fi.mId2, false);
#ifdef NEWS_DEBUG
std::cerr << "NewsFeed::addFeedItemSecurityUnknownOut()";

View File

@ -116,25 +116,37 @@ void SecurityItem::updateItemStatic()
switch(mType)
{
case SEC_TYPE_CONNECT_ATTEMPT:
case RS_FEED_ITEM_SEC_CONNECT_ATTEMPT:
title = tr("Connect Attempt");
requestLabel->show();
avatar->setDefaultAvatar(":images/avatar_request.png");
break;
case SEC_TYPE_AUTH_DENIED:
case RS_FEED_ITEM_SEC_AUTH_DENIED:
title = tr("Connection refused by remote peer");
requestLabel->hide();
avatar->setDefaultAvatar(":images/avatar_refused.png");
break;
case SEC_TYPE_UNKNOWN_IN:
case RS_FEED_ITEM_SEC_UNKNOWN_IN:
title = tr("Unknown (Incoming) Connect Attempt");
requestLabel->hide();
avatar->setDefaultAvatar(":images/avatar_request_unknown.png");
break;
case SEC_TYPE_UNKNOWN_OUT:
case RS_FEED_ITEM_SEC_UNKNOWN_OUT:
title = tr("Unknown (Outgoing) Connect Attempt");
requestLabel->hide();
break;
case RS_FEED_ITEM_SEC_WRONG_SIGNATURE:
title = tr("Certificate has wrong signature!! Probably a forged certificate.");
requestLabel->hide();
break;
case RS_FEED_ITEM_SEC_BAD_CERTIFICATE:
title = tr("Certificate is invalid.");
requestLabel->hide();
break;
case RS_FEED_ITEM_SEC_INTERNAL_ERROR:
title = tr("Certificate caused an internal error.");
requestLabel->hide();
break;
default:
title = tr("Unknown Security Issue");
requestLabel->hide();

View File

@ -25,10 +25,10 @@
#include "ui_SecurityItem.h"
#include <stdint.h>
const uint32_t SEC_TYPE_CONNECT_ATTEMPT = 0x0001; /* failed Connect Attempt */
const uint32_t SEC_TYPE_AUTH_DENIED = 0x0002; /* failed outgoing attempt */
const uint32_t SEC_TYPE_UNKNOWN_IN = 0x0003; /* failed incoming with unknown peer */
const uint32_t SEC_TYPE_UNKNOWN_OUT = 0x0004; /* failed outgoing with unknown peer */
//const uint32_t SEC_TYPE_CONNECT_ATTEMPT = 0x0001; /* failed Connect Attempt */
//const uint32_t SEC_TYPE_AUTH_DENIED = 0x0002; /* failed outgoing attempt */
//const uint32_t SEC_TYPE_UNKNOWN_IN = 0x0003; /* failed incoming with unknown peer */
//const uint32_t SEC_TYPE_UNKNOWN_OUT = 0x0004; /* failed outgoing with unknown peer */
class FeedHolder;