UnrealIRCd Encryption Protocol version 1.0 by Carsten V. Munk (stskeeps@tspre.org) 1. Introduction --------------- As of UnrealIRCd version 3.1 we have included capability for secure connections (Encrypted IRC connections). This was done after I read an "Ask Slashdot" article at slashdot.org, (http://slashdot.org/askslashdot/00/04/19/0443251.shtml) where a guy asked: cylent asks: "I have a close-knit group of acquaintances that like to communicate with each other often. Public IRC servers are fine for chit-chat, although for more in-depth discussions a more secure form of communication is preferred. I'm wondering what GPL'd software exists to provide for a secure form of realtime multi-party communication. Are there any IRC servers/clients that support any form of public key cryptography? Blowfish? 3DES? Are there any other proprietary "chat" programs available with a forte in cryptography?". I sat down, did some thoughts. The thing would not be public key, as I believe client and server should have a keyfile, picked up by SSL, SSH whatever. The communication would be client<->server, so that the stream would be encrypted. Safest way to ensure 100% secure communications would be to set up the IRC server, and join in with only secure communications to same channel where no non secure clients were and set it +is. Server<->server communications are not encrypted (yet), but we're working on it. However, here is a description of the protocol: 2. System Requiriments -------------------------------- * OpenSSL (with libcrypto), win32 port also availible, read unreal.tspre.org for more information. Read http://www.openssl.org for more information (you need the openssl/ directory in includes to compile) 3. Negotiating the secure connection ------------------------------------ The client connects, and sends: (normal irc with \r\n as terminates) CRYPTO | | | | | \--- Unused currently, use "*" | \--- The name of the file in keys/ containing the key \--- This is algoritm name, in uppercase (see algoritm list) NOTE: the keyfilename must not contain a / or a \ Until connection is negotiated the connection is in non-secure mode (normal irc protocol, see RFC 1459) The server then responds, if the key was acknowledged: CRYPTO ON \---- (see algoritm list, this is in uppercase) and the connecting is marked as secure, sending secure packets now. The server responds, if an error has occoured: CRYPTO ERROR :test And the secure connection is disabled Some example errors: CRYPTO ERROR :Illegal keypath - Means that keyfilename in CRYPTO command was illegal CRYPTO ERROR :Failed to open keyfile - Means that the IRCd failed to open the keyfile CRYPTO ERROR :Unable to read keyfile - Means that the IRCd failed to read the keyfile CRYPTO ERROR :No such method/command - Means that the method (algoritm) or command does not exist 4. The stream packets --------------------- When secure mode (CRYPTO ON), is acknowledged the IRCd sends, and expects to recieve packets with the encrypted data. The packet is started with a header struct crypto_header { unsigned char highbyte; unsigned char lowbyte; }; after the header, a buffer with exact length ((highbyte * 256) + lowbyte) is coming after (binary buffer). When the string is recieved, decrypt using the cipher. Example function: (this decrypts a buffer), wont work with direct paste, but you can see the principle: char *ep_decrypt(aClient *cptr, char *string) { static char decryptbuffer[8192]; int num; char ivec[9]; int length; if (!cptr->cryptinfo) return string; bzero(decryptbuffer, sizeof(decryptbuffer)); bzero(ivec, sizeof(ivec)); num = 0; length = (*(string) * 256) + (*(string + 1)); if (cptr->cryptinfo->method == METHOD_BLOWFISH) { BF_cfb64_encrypt(string + 2, decryptbuffer, length, cptr->cryptinfo->key, ivec, &num, BF_DECRYPT); return (decryptbuffer); } } The IRCd expects same format back, here is what the ircd encrypts with: char *ep_encrypt(aClient *cptr, char *string, int *len) { static unsigned char cryptobuffer[8192]; char ivec[9]; int length; char *c; int num; if (!cptr->cryptinfo) return string; bzero(cryptobuffer, sizeof(cryptobuffer)); bzero(ivec, sizeof(ivec)); num = 0; if ((c = (char *)strchr(string, '\n'))) *c = '\0'; if ((c = (char *)strchr(string, '\r'))) *c = '\0'; length = strlen(string) + 1; cryptobuffer[0] = (unsigned char) length / 256; cryptobuffer[1] = (unsigned char) length - (cryptobuffer[0] * 256); if (cptr->cryptinfo->method == METHOD_BLOWFISH) { BF_cfb64_encrypt(string, &cryptobuffer[2], length, cptr->cryptinfo->key, ivec, &num, BF_ENCRYPT); *len = length + 2; return (cryptobuffer); } } To abort the secure connection, either QUIT (to exit completely), or send CRYPT OFF. 5. Algoritms ------------ As of Unreal3.1 only BLOWFISH is implemented, but there will be patches for extended algoritms. We use the include at the moment. Mail stskeeps@tspre.org if you show interest in other algoritms 6. Credits ---------- Credits to the UnrealIRCd team (me, codemastr, DrBin) Credits to slashdot.org as well. This product includes software developed by Eric Young (eay@cryptsoft.com) 7. Contact info ---------------- Mail stskeeps@tspre.org for any questions