                                    CRYPTLINK Encrypted server link protocol
                                    ========================================
   (Loosely Based on draft by A1kmm)
   (Rewritten by David-T and einride)

0.1 - Conventions of this document
----------------------------------

        * MUST means that a server is not "compliant" unless it does this.
        * MUST NOT means that a server is not "compliant" if it does this.
        * SHOULD means that a server is at most "conditionally compliant"
          if it does not do this.
        * SHOULD NOT means that a server is at most "conditionally compliant"
          if it does this.
        * MAY means that a server may choose whether or not to do this.

1.1 - Goal of this protocol
---------------------------

	To reduce the risk of attacks relating to password sniffing,
	replay attacks, or connection hijacking allowing unauthorised
	access to server priviledges.

1.2 - Background of this protocol
---------------------------------

	This protocol is based on the IRC protocol as described in RFC1459,
	and extensions implemented on Efnet as described in other documents
	available in this directory, and on the WWW.

	Any encrypted strings which are transmitted in IRC commands in
	accordance with this document shall be BASE64 encoded, with the
	most significant bits of the most significant byte transmitted
	first, followed by bits/bytes of decreasing significance.  However,
	the encrypted link itself will be 8-bit, without any encoding.
  
2.1 - Configuration changes
---------------------------

	Every server which supports CRYPTLINK links has a 2048-bit RSA
	private key stored in a configuration file.  Care must be taken
	to ensure this file is accessible only to the ircd user.  For every
	link to another server with CRYPTLINK support, the public component
	of that server's RSA key is stored instead of the traditional
	password or password hash.

	A server which is configured to make a CRYPTLINK link to another
	server MUST NOT fall back on to any other server authentification
	scheme regardless of what the remote server sends.

3.1 - Changes to the CAPAB command
----------------------------------

	The first command sent by a server over a CRYPTLINK link MUST
	be a CAPAB command.  The CAPAB command MUST include the
	ENC capability, which also indictes the supported symmetric
	ciphers, as shown:
	
	CAPAB <other supported capabilities> ENC:c1/k1,c2/k2,k3

	Where c1,c2,c3 are supported ciphers, and k1,k2,k3 are the key
	lengths required by ciphers c1,c2,c3 respectively.

	The currently defined ciphers are:

		Name (<9 chars)	Cipher

		BF/128		Blowfish	128bit key (cfb64)
		BF/256		Blowfish	256bit key (cfb64)
		CAST/128	CAST		128bit key (cfb64)
		DES/56		DES		 56bit key (cfb64)
		3DES/168	Triple DES	168bit key (ede3_cbc)
		IDEA/128	IDEA		128bit key (cfb64)
		RC5.8/128	RC5, 8 rounds	128bit key (cfb64)
		RC5.12/128	RC5, 12 rounds	128bit key (cfb64)
		RC5.16/128	RC5, 16 rounds  128bit key (cfb64)

	The maximum allowable key length for the symmetric encryption
	cipher is 512 bits, as only 64 bytes of random data for the
	key is available.

	All servers MUST, at minimum, support BF/128 encryption, but
	MAY allow admins to disable this cipher (and thus remove it from
	the list sent in the CAPAB command).  If no ciphers are supported
	on BOTH servers, the link should be aborted at this point.

	Servers which support regeneration of session keys MAY also
	include the DK ('Dynamic Key') capability.

3.2 - Key generation
--------------------

	To initiate a CRYPTLINK link to another server, each server
	is required to generate a 512-bit (64 byte) random key, of which
	a portion will be used to decrypt all data received by the server.
	This key MUST be generated by a cryptographically strong PRNG.

	This key should be stored, then encrypted to the other server's
	public key, and base64 encoded.

3.3 - Link Establishment
------------------------

	Once the initiating server (server A) has connected to the
	remote server (server B), it SHOULD send the CAPAB command,
	listing its capabilities (including the new ENC capability).

	It MUST then send a CRYPTSERV command as follows:

		CRYPTSERV <irc.server.name> <key> :<server info>

	(where <key> is the encoded, encrypted key)

	Servers MUST NOT send a PASS or initial SERVER command over
	a CRYPTLINK link.  However, SERVER commands are still used
	to introduce remote servers.  All CRYPTLINK links MUST
	support the TS protocol (as normally indicated by
	PASS ... :TS).

	On receiving this command, server B MUST send its own
	CAPAB/CRYPTSERV commands, and then decrypt the key.

	Server B should then select a cipher supported by both ends
	to be used to encrypt its outgoing data, and extract the
	required number of bytes from the data received from server A.
	It must then (using RSA) encrypt the session key to Server A's
	public key and base64 encode it.

	It should then send a CRYPTAUTH command as follows:

		CRYPTAUTH <cipher> <base64 encoded key>

	Once this command has been sent, the link MUST switch to being
	encrypted.  All future data sent over the link will be
	encrypted using the selected symmetric encryption cipher, with the
	key received from the remote server, using only the first N bits,
	where N is the key length of the negotiated cipher.
	At this point, Server B SHOULD send an SVINFO command,
	followed by a normal netburst.

	If the CAPAB lines exchanged indicated that both servers support
	ZIPLINKS for this link, the data will be zipped immediately
	before encrypting it.  The data will start to be zipped after
	the CRYPTAUTH command is sent (i.e., at the same time as
	encryption).

	After receiving a CRYPTAUTH command Server A MUST decrypt the
	session key returned by Server B and ensure it is correct.  If
	it is not, the server SHOULD notify online admins/IRCops, and
	MUST drop the link.

	Server A will then send its own CRYPTAUTH command, and switch to
	an encrypted link as above.  It SHOULD then send an SVINFO command,
	and a normal netburst.

	Server B MUST also validate the CRYPTAUTH response as above.

3.4 - Key regeneration
----------------------

	The servers MAY regenerate the session key they use to
	encrypt outgoing data at any point during a link, if
	the link supports the DK ('Dynamic Key') capability.

	They should generate a new key, encode it to the remote server's
	public key as in the initial key exchange, then send a CRYPTKEY
	command as follows:

	:<servername> CRYPTKEY <key>

	This command should (obviously) be encrypted by the original key
	the next line should be encrypted with the new key.

Last modified:	2001-05-12
