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> #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 * #define AUTHSSL_DEBUG 1
***/ ***/
@ -477,8 +486,10 @@ bool AuthSSLimpl::validateOwnCertificate(X509 *x509, EVP_PKEY *pkey)
{ {
(void) pkey; /* remove unused parameter warning */ (void) pkey; /* remove unused parameter warning */
uint32_t diagnostic ;
/* standard authentication */ /* standard authentication */
if (!AuthX509WithGPG(x509)) if (!AuthX509WithGPG(x509,diagnostic))
{ {
return false; return false;
} }
@ -863,7 +874,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long days)
* this is important - as it allows non-friends messages to be validated. * 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"); fprintf(stderr, "AuthSSLimpl::AuthX509WithGPG() called\n");
@ -872,6 +883,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
if (!CheckX509Certificate(x509)) if (!CheckX509Certificate(x509))
{ {
std::cerr << "AuthSSLimpl::AuthX509() X509 NOT authenticated : Certificate failed basic checks" << std::endl; std::cerr << "AuthSSLimpl::AuthX509() X509 NOT authenticated : Certificate failed basic checks" << std::endl;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID ;
return false; return false;
} }
@ -883,6 +895,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
#endif #endif
if (!AuthGPG::getAuthGPG()->getGPGDetails(issuer, pd)) { if (!AuthGPG::getAuthGPG()->getGPGDetails(issuer, pd)) {
std::cerr << "AuthSSLimpl::AuthX509() X509 NOT authenticated : AuthGPG::getAuthGPG()->getGPGDetails() returned false." << std::endl; std::cerr << "AuthSSLimpl::AuthX509() X509 NOT authenticated : AuthGPG::getAuthGPG()->getGPGDetails() returned false." << std::endl;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN ;
return false; return false;
} }
@ -924,6 +937,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
hashoutl=0; hashoutl=0;
sigoutl=0; sigoutl=0;
fprintf(stderr, "AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n"); fprintf(stderr, "AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n");
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err; goto err;
} }
p=buf_in; p=buf_in;
@ -941,6 +955,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
{ {
hashoutl=0; hashoutl=0;
fprintf(stderr, "AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n"); fprintf(stderr, "AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n");
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err; goto err;
} }
@ -963,6 +978,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
if (!AuthGPG::getAuthGPG()->VerifySignBin(buf_hashout, hashoutl, buf_sigout, (unsigned int) sigoutl, pd.fpr)) { if (!AuthGPG::getAuthGPG()->VerifySignBin(buf_hashout, hashoutl, buf_sigout, (unsigned int) sigoutl, pd.fpr)) {
sigoutl = 0; sigoutl = 0;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE ;
goto err; goto err;
} }
@ -974,6 +990,8 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
OPENSSL_free(buf_hashout) ; OPENSSL_free(buf_hashout) ;
OPENSSL_free(buf_sigout) ; OPENSSL_free(buf_sigout) ;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_OK ;
return true; return true;
err: err:
@ -993,8 +1011,10 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509)
/* validate + get id */ /* validate + get id */
bool AuthSSLimpl::ValidateCertificate(X509 *x509, std::string &peerId) bool AuthSSLimpl::ValidateCertificate(X509 *x509, std::string &peerId)
{ {
uint32_t auth_diagnostic ;
/* check self signed */ /* check self signed */
if (!AuthX509WithGPG(x509)) if (!AuthX509WithGPG(x509,auth_diagnostic))
{ {
#ifdef AUTHSSL_DEBUG #ifdef AUTHSSL_DEBUG
std::cerr << "AuthSSLimpl::ValidateCertificate() bad certificate."; std::cerr << "AuthSSLimpl::ValidateCertificate() bad certificate.";
@ -1099,12 +1119,15 @@ int AuthSSLimpl::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx)
#ifdef AUTHSSL_DEBUG #ifdef AUTHSSL_DEBUG
fprintf(stderr, "Doing REAL PGP Certificates\n"); fprintf(stderr, "Doing REAL PGP Certificates\n");
#endif #endif
uint32_t auth_diagnostic ;
/* do the REAL Authentication */ /* 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 #ifdef AUTHSSL_DEBUG
fprintf(stderr, "AuthSSLimpl::VerifyX509Callback() X509 not authenticated.\n"); fprintf(stderr, "AuthSSLimpl::VerifyX509Callback() X509 not authenticated.\n");
#endif #endif
std::cerr << "(WW) Certificate was rejected because authentication failed. Diagnostic = " << auth_diagnostic << std::endl;
return false; return false;
} }
std::string pgpid = getX509CNString(X509_STORE_CTX_get_current_cert(ctx)->cert_info->issuer); 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 ; std::string ip_address ;
rs_sprintf_append(ip_address, "%s:%u", rs_inet_ntoa(addr.sin_addr).c_str(), ntohs(addr.sin_port)); 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) if(authed)
LocalStoreCert(x509); LocalStoreCert(x509);
@ -1394,7 +1418,22 @@ bool AuthSSLimpl::FailedCertificate(X509 *x509, const std::string& gpgid,
if (incoming) if (incoming)
{ {
RsServer::notify()->AddPopupMessage(RS_POPUP_CONNECT_ATTEMPT, gpgid, sslcn, sslid); 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); RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_CONNECT_ATTEMPT, gpgid, sslid, sslcn, ip_address);
}
#ifdef AUTHSSL_DEBUG #ifdef AUTHSSL_DEBUG
std::cerr << " Incoming from: "; std::cerr << " Incoming from: ";
@ -1424,8 +1463,9 @@ bool AuthSSLimpl::CheckCertificate(std::string id, X509 *x509)
{ {
(void) id; /* remove unused parameter warning */ (void) id; /* remove unused parameter warning */
uint32_t diagnos ;
/* if auths -> store */ /* if auths -> store */
if (AuthX509WithGPG(x509)) if (AuthX509WithGPG(x509,diagnos))
{ {
LocalStoreCert(x509); LocalStoreCert(x509);
return true; return true;
@ -1598,7 +1638,8 @@ bool AuthSSLimpl::loadList(std::list<RsItem*>& load)
X509 *peer = loadX509FromPEM(kit->value); X509 *peer = loadX509FromPEM(kit->value);
/* authenticate it */ /* authenticate it */
if (AuthX509WithGPG(peer)) uint32_t diagnos ;
if (AuthX509WithGPG(peer,diagnos))
{ {
LocalStoreCert(peer); 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 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; 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 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); 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_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_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_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_NEW = RS_FEED_TYPE_CHAN | 0x0001;
const uint32_t RS_FEED_ITEM_CHAN_UPDATE = RS_FEED_TYPE_CHAN | 0x0002; const uint32_t RS_FEED_ITEM_CHAN_UPDATE = RS_FEED_TYPE_CHAN | 0x0002;

View File

@ -214,6 +214,7 @@ void NewsFeed::updateDisplay()
addFeedItemFilesNew(fi); addFeedItemFilesNew(fi);
break; break;
default: default:
std::cerr << "(EE) Unknown type " << std::hex << fi.mType << std::dec << " in news feed." << std::endl;
break; break;
} }
} else { } else {
@ -557,12 +558,12 @@ void NewsFeed::addFeedItemPeerNew(RsFeedItem &fi)
void NewsFeed::addFeedItemSecurityConnectAttempt(RsFeedItem &fi) void NewsFeed::addFeedItemSecurityConnectAttempt(RsFeedItem &fi)
{ {
/* make new widget */ /* 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 */ /* store */
/* add to layout */ /* add to layout */
addFeedItemIfUnique(pi, SEC_TYPE_CONNECT_ATTEMPT, fi.mId2, false); addFeedItemIfUnique(pi, fi.mType, fi.mId2, false);
#ifdef NEWS_DEBUG #ifdef NEWS_DEBUG
std::cerr << "NewsFeed::addFeedItemSecurityConnectAttempt()"; std::cerr << "NewsFeed::addFeedItemSecurityConnectAttempt()";
@ -573,12 +574,12 @@ void NewsFeed::addFeedItemSecurityConnectAttempt(RsFeedItem &fi)
void NewsFeed::addFeedItemSecurityAuthDenied(RsFeedItem &fi) void NewsFeed::addFeedItemSecurityAuthDenied(RsFeedItem &fi)
{ {
/* make new widget */ /* 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 */ /* store */
/* add to layout */ /* 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 #ifdef NEWS_DEBUG
std::cerr << "NewsFeed::addFeedItemSecurityAuthDenied()"; std::cerr << "NewsFeed::addFeedItemSecurityAuthDenied()";
@ -589,12 +590,12 @@ void NewsFeed::addFeedItemSecurityAuthDenied(RsFeedItem &fi)
void NewsFeed::addFeedItemSecurityUnknownIn(RsFeedItem &fi) void NewsFeed::addFeedItemSecurityUnknownIn(RsFeedItem &fi)
{ {
/* make new widget */ /* 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 */ /* store */
/* add to layout */ /* 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 #ifdef NEWS_DEBUG
std::cerr << "NewsFeed::addFeedItemSecurityUnknownIn()"; std::cerr << "NewsFeed::addFeedItemSecurityUnknownIn()";
@ -605,12 +606,12 @@ void NewsFeed::addFeedItemSecurityUnknownIn(RsFeedItem &fi)
void NewsFeed::addFeedItemSecurityUnknownOut(RsFeedItem &fi) void NewsFeed::addFeedItemSecurityUnknownOut(RsFeedItem &fi)
{ {
/* make new widget */ /* 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 */ /* store */
/* add to layout */ /* 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 #ifdef NEWS_DEBUG
std::cerr << "NewsFeed::addFeedItemSecurityUnknownOut()"; std::cerr << "NewsFeed::addFeedItemSecurityUnknownOut()";

View File

@ -116,25 +116,37 @@ void SecurityItem::updateItemStatic()
switch(mType) switch(mType)
{ {
case SEC_TYPE_CONNECT_ATTEMPT: case RS_FEED_ITEM_SEC_CONNECT_ATTEMPT:
title = tr("Connect Attempt"); title = tr("Connect Attempt");
requestLabel->show(); requestLabel->show();
avatar->setDefaultAvatar(":images/avatar_request.png"); avatar->setDefaultAvatar(":images/avatar_request.png");
break; break;
case SEC_TYPE_AUTH_DENIED: case RS_FEED_ITEM_SEC_AUTH_DENIED:
title = tr("Connection refused by remote peer"); title = tr("Connection refused by remote peer");
requestLabel->hide(); requestLabel->hide();
avatar->setDefaultAvatar(":images/avatar_refused.png"); avatar->setDefaultAvatar(":images/avatar_refused.png");
break; break;
case SEC_TYPE_UNKNOWN_IN: case RS_FEED_ITEM_SEC_UNKNOWN_IN:
title = tr("Unknown (Incoming) Connect Attempt"); title = tr("Unknown (Incoming) Connect Attempt");
requestLabel->hide(); requestLabel->hide();
avatar->setDefaultAvatar(":images/avatar_request_unknown.png"); avatar->setDefaultAvatar(":images/avatar_request_unknown.png");
break; break;
case SEC_TYPE_UNKNOWN_OUT: case RS_FEED_ITEM_SEC_UNKNOWN_OUT:
title = tr("Unknown (Outgoing) Connect Attempt"); title = tr("Unknown (Outgoing) Connect Attempt");
requestLabel->hide(); requestLabel->hide();
break; 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: default:
title = tr("Unknown Security Issue"); title = tr("Unknown Security Issue");
requestLabel->hide(); requestLabel->hide();

View File

@ -25,10 +25,10 @@
#include "ui_SecurityItem.h" #include "ui_SecurityItem.h"
#include <stdint.h> #include <stdint.h>
const uint32_t SEC_TYPE_CONNECT_ATTEMPT = 0x0001; /* failed Connect Attempt */ //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_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_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_UNKNOWN_OUT = 0x0004; /* failed outgoing with unknown peer */
class FeedHolder; class FeedHolder;