|
||||||||||||||||||||||||
|
SecretLove
Secret Love - A Secure P2P Private Messaging System
Preamble
The Internet is fast becoming the primary medium for human communication -
both business related and personal. However, this medium presents serious security
challenges that mainly stem from the fact that although it is much more complex
and powerful than traditional communications media, the opportunities, for phenomenal
corporate profits, that it presents have driven pioneering companies in the
field to quickly (and sometimes irresponsibly) adopt and disseminate:
- technologies where security is either non existent or weak.
- metaphors that, although functionally adequate, can be quite misleading
in the security assumptions that they imply.
At the end of the 20th century, Internet security technologies started enjoying
wider acceptance and penetration in the PC market - the market that is of interest
to the average citizen. Today, more than ever, software that promises strong
security and has the technological muscle to deliver it, is available in the
market. A lot of this software is freeware. Secret Love is the latest
addition to the growing number of freeware applications that offer strong security
services to the average citizen.
Secret Love Overview
"Secret Love" is a temporary and tentatively humorous name for the Alpha 1
version of a "peer-to-peer chat" type of desktop application for win32 boxes
that utilizes strong encryption to encode exchanged messages - thus guaranteeing
the privacy of the contained information to a significant degree.
Secret Love is a multithreaded TCP/IP application
that makes use of MFC, winsock, CryptoAPI and low level win32 APIs (threads,
synchronization, etc.) In future versions Secret Love will also offer strong
authentication and non-repudiation services.
"Secret Love" is being developed by the coders at Weird Computing Inc (currently
only one coder by the name of Fotios). The guys at Weird Computing are dedicated
to protecting the body, mind and psyche of citizens, cattle and other unfortunate
creatures - we are vegetarian coders.
The purpose of Secret Love is manifold:
- To provide the average citizen with an easy and strongly secure way to exchange
messages (and later on even files) on the Internet. - To provide corporate bosses with an easy way to privately plot their domination
of the world for the next 100 years. - To provide loving employees with a secure channel of communication between
them and their bosses' wives.
Here is what the "Secret Love" application
window looks like:

Features
- Symmetric encryption of messages based on a shared - between peers - customizable
secret key. - Customizable encryption type and strength - 40bit RC2, 128bit RC2, DES (56bit),
3DES (168bit) - 3-threaded, for responsiveness and efficiency: client thread, server thread
and GUI thread. - Communication over 2 separate sockets
- Peer auto-connect
- Configurable local port
- Configurable remote port
- Just 116KB size - a single win32 exe file
How it works
SL uses two sockets to communicate with a peer - a copy
of itself. Each socket is on a separate thread - there is a server thread and
a client thread. It starts by binding a socket and listening at a customizable
port on your local IP address. Then the user enters an IP address or domain
name and the port that the peer on that address will be listening at. Pressing
the "Connect" button creates a second socket and connects it to the remote ip:port.
Once a non busy listening client receives a connection it responds by connecting
its own client socket to the remote IP (and the specified remote peer server
port which you still need to know).
The full-duplex functionality of both sockets
is reserved for the implementation of the application level protocol - for the
time being messages are exchanged as plain text with \x0D\x0A message delimiters.
The application achieves responsiveness and efficiency by using multithreading.
Thread shared resources - like the chat conversation log - are secured from
corruption via the use of critical sections. The interface is implemented using
an MFC CDialog subclass. No MFC threads or MFC sockets are used. This is done
deliberately in order to retain freedom of coding expression and demonstrate
knowledge of low level winsock and thread coding.
Encryption is done using Microsoft's comprehensive
CryptoAPI.
Custom classes are implemented to encapsulate low level structures
and functions (e.g. there is a custom socket class)
Firewall Considerations
SL has been tested successfully behind a NATing ISA firewall. Of course you
will need to publish your server port and put together a protocol definition
that will allow the internal client to connect to the remote peer's open port.
Using SL on the firewall box itself will require definition of appropriate packet
filters.
Coding Highlights
Here is a snippet of code that demonstrates a polling interaction between two threads.
The GUI thread delivers the message, that the user typed in the text box, into a buffer that
the client thread reads byte by byte, sleeping as appropriate to wait for more chars.
The message is considered complete when the new line sequence is encountered.
initInsBuffer();
initSendBuffer();//Initialize client's message buffer
char* c = ins;
int i = 0;
while (1)
{
if (*c != '\x0A' && *c !='\x00')
{
*(SendBuffer + i++) = *c++;
continue;
}
else if (*c == '\x00')
{
Sleep(10L);
continue;
}
else if (*c == '\x0A')
{
*(SendBuffer + i) = *c;
break;
}
}
Length = strlen(SendBuffer);
///////////////////////////////////////////////////////////////////////////////////////////////
Here is the class destructor for the chatter subsystem:
chatter::~chatter()
{
delete fc;
delete cs;
delete cc;
CloseHandle(ClientThread);
CloseHandle(ServerThread);
WSACleanup();
}
/////////////////////////////////////////////////////////////////////////////////////////////
Here is the method that is responsible for creating a session key.
As you can see, the actual code that does the key creation is a member of the FCrypto object.
FCrypto is a custom class that encapsulates MS CryptoAPI functionality.
BOOL chatter::createSessionKey(char* sCipher, int BitLength)
{
fc = new FCrypto();
char* pass = (char*) malloc(1024);
((MyDialog *) Di)->GetDlgItem(IDC_EDIT1)->GetWindowText(pass, 1024);
if (fc->createSessionKey(pass, sCipher, BitLength))
{
return TRUE;
}
else
{
error("failed to create a key");
return FALSE;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
Here is the FCrypto method that does the message encryption based on an already
created session key:
DWORD FCrypto::encrypt(char* in, char* out)
{
strcpy((char*) pbBuffer, in);
dwCount = strlen(in);
dwBufferLen = CRYPT_BUF;
if(!CryptEncrypt(
hKey,
0,
TRUE,
0,
pbBuffer,
&dwCount,
dwBufferLen))
{
error("encrypt failure!");
return 0;
}
memcpy((void*) out, (const void*) pbBuffer, dwCount);
*(out + dwCount) = '\x0D';
*(out + dwCount + 1) = '\x0A';
return dwCount + 2;
}
/////////////////////////////////////////////////////////////////////////////////////////////
Here is the LogMsg method, of the subclassed MFC CDialog, that logs the
chat messages (conversation log) and protects the shared CEdit resource
with a critical section thread synchronization artefact.
void MyDialog::LogMsg(char *user, char *msg)
{
__try
{
// Request ownership of the critical section (CEdit)
EnterCriticalSection(&CriticalSection3);
CEdit *e = (CEdit*) GetDlgItem(IDC_EDIT5);
convo += user;
convo += "> ";
convo += msg;
if (convo.GetAt(convo.GetLength() - 1) != '\n')
convo += "\r\n";
e->SetWindowText(convo);
int lines = e->GetLineCount();
e->LineScroll(lines);
}
__finally
{
// Release ownership of the critical section.
LeaveCriticalSection(&CriticalSection3);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
Customization of the subclassed CDialog's message processing
BOOL MyDialog::PreTranslateMessage(MSG * pMsg)
{
if ( pMsg -> message == WM_KEYDOWN && pMsg->wParam == 13 )
{
CWnd *foc = this->GetFocus();
int ID = foc->GetDlgCtrlID();
if (ID == IDC_EDIT2)
{
if (mc != NULL && connected){
//Send Msg
char* msg = (char*) malloc(32767);
foc->GetWindowText(msg, 32766);
strcpy(mc->cc->ins, msg);
strcat(mc->cc->ins, "\x0D\x0A");
free(msg);
//and clear edit ctrl
foc->SetWindowText("");
}
}
return TRUE;
}
return CDialog::PreTranslateMessage(pMsg);
}
/////////////////////////////////////////////////////////////////////////////////////////////
Part of the server thread's routine loop
//Loop for incoming connections, forever
while(1)
{
char rAddress[1024];
New_Socket = f->f_accept(rAddress);
if (New_Socket == SOCKET_ERROR)
{
error("accept()");
continue;
}
char* conmsg = (char*) malloc(1024);
strcpy(conmsg, "Remote peer connected from ");
((MyDialog*) this->D)->LogMsg("", strcat(conmsg, rAddress));
free(conmsg);
//Create new F_Socket_Stream object for the new accepting socket
F_Socket_Stream *f_new = new F_Socket_Stream(1, New_Socket, D);
while(1) //keep receiving msgs until a disconnection msg is received
{
initReceiveBuffer();
Length = f_new->f_recv(0, 0, 0, 0, 1);
//Copy new socket's receive buffer to server object's receive buffer
if (Length > 0)
{
char* out = (char*) malloc(MAXBUF);
f_new->f_read(&out, Length);
fc->decrypt(out, ReceiveBuffer, Length - 2);
free(out);
}
else
{
error("abnormal disconnection");
//Destroy connection socket object
delete f_new;
closesocket(New_Socket);
//Reset client too
*Abnormal = 1; //Set Abnormal disconnection semaphore to true
break; //out of connection loop
}
displayReceiveBuffer(Length);
}//End connection while
}//End server while
/////////////////////////////////////////////////////////////////////////////////////////////
Technical disclaimer
This is a *very* alpha version that I put together (from scratch) in 5 days
in order to demonstrate skills to a potential employer. There may be bugs, memory
leaks, etc. but I do not expect anything too serious. Please report bugs to
f_bass@yahoo.com
User's Manual
- Start SL.
- Notice that SL auto starts its server and starts listening to port 4711.
I chose 4711 because I have this recurring dream of a city block with a 711
store at each corner - never seen one, but if you show me one I will buy an
apartment there. - If you wish to listen at a different port, type it in the appropriate text
box and click "Listen" - notice that server restarts. - Have a friend start his own peer - or start a peer yourself on another box
in your LAN. - Type the IP or domain name of the remote peer, in the appropriate text
box. - Type the port number that the remote peer is listening at
- Click the "Connect" button - notice that you connect to the peer and the
peer auto-connects back to you (and your IP text-box reflects the remote IP).
I call this, the "Hit Me Back Bro" functionality. - Start exchanging messages with the remote peer.
- You can change your secret pass and encryption type or strength on the
fly (press "Set" after making changes to the relevant GUI controls and continue
with your next message to the connected peer)
ToDo
The following are to be implemented in future versions:
- Implement authentication and non-repudiation (Kerberos - Message Signing)
- Custom Application-Level protocol that among other things will provide
message delivery verification (so that you know for sure that your "Secret
Love" is deliberately ignoring you). - Use of asymmetric encryption and retrieval of public keys from key distribution
servers and authorities.
Download
Fearlessly chat with your secret love today: slove.exe
Have Fun!
Weird
Computing Inc.




Post new comment