This repository has been archived on 2025-02-12. You can view files and clone it, but cannot push or open issues or pull requests.
NeoStats-NeoIRCd/doc/technical/cryptlink.txt
2002-08-13 14:45:13 +00:00

339 lines
13 KiB
Text

CRYPTLINK Encrypted Server Link Protocol
========================================
(Loosely based on draft by A1kmm)
(Rewritten by David-T, einride, vulture, and jdc)
0.1 - Conventions of this document
----------------------------------
* "MUST" means that a server is not compliant unless it does this.
* "MUST NOT" means 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, in turn permitting
unauthorised access to server privileges.
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 (doc/), 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 no encoding.
2.1 - Configuration changes
---------------------------
Every server which supports encrypted 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 that supports encrypted links, 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 an encrypted link to another
MUST NOT fall back on any other authentication scheme, regardless
of what the remote server sends or does.
3.1 - Changes to the CAPAB command
----------------------------------
The first command sent by a server over an encrypted link MUST
be a CAPAB command. The CAPAB command MUST include the
ENC capability. The syntax would be as follows:
CAPAB :<other supported capabilities> ENC
An example CAPAB could be the following:
CAPAB :QS EX CHW IE EOB KLN HOPS HUB AOPS ENC ZIP
Note that ENC is not required to be the last capab.
The maximum allowable key length permitted for the encryption
cipher is 512 bits, as only 64 bytes of random data for the
key is available.
Servers which support regeneration of session keys MAY also
include the DK ('Dynamic Key') capability.
3.2 - New 'CRYPTLINK CIPHERS' command
-------------------------------------
To prevent admins having to identically configure each end of
the link, the ircd SHOULD allow the admin to specify a list
of ciphers to be supported on a per link basis and/or a global
default.
The second command sent over a CRYPTLINK enabled link MUST be the
CRYPTLINK CIPHERS command, to inform the remote server what ciphers
are supported by this end of the link:
CRYPTLINK CIPHERS :cipher1/keylen cipher2/keylen, ...
For example:
CRYPTLINK CIPHERS :BF/256 BF/128 3DES/156
The ciphers which are available as of the date this document was
written are listed in doc/README.openssl.
All servers MUST, as minimum, support BF/128 encryption; admins
MAY choose to use another cipher which is available.
If no ciphers are supported on BOTH servers, the receiving
server (the server which was connected to) should send back an
error response, instead of returning a CRYPTLINK CIPHERS command
of its own. See Section 3.5 ("Error Responses") for more
information on the process for doing this.
3.3 - Key Generation
--------------------
To initiate an encrypted link to another server, each server
is required to generate a 512-bit 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 server's private
key, encrypted to the remote server's public key, then base64 encoded
for transmission to the remote server.
3.3 - Link Establishment
------------------------
Once the initiating server (server A) has connected to the
remote server (server B), it MUST send the CAPAB command,
listing its capabilities (including the new ENC capability).
It MUST then send a CRYPTLINK CIPHER command, as described above.
It MUST then send a CRYPTLINK SERV command using the following
syntax:
CRYPTLINK SERV <irc.server.name> <key> :server info
"<irc.server.name>" should be self-explanatory. "<key>" is the
base64-encoded key. "server info" is the server's M-line.
Servers MUST NOT send a PASS or initial SERVER command over an
encrypted link. However, SERVER commands are still used to
introduce remote servers during the net burst, and as they link
to the network. All encrypted links MUST support the
TS protocol (as normally indicated by PASS ... :TS).
On receiving the CAPAB command, server B MUST send its own
CAPAB/CRYPTLINK CIPHER/CRYPTLINK SERV commands and decrypt and
verify the signature on the key, unless there is an error
processing one of the received commands, in which case, an error
should be sent instead -- see Section 3.5 ("Error Responses").
Server B should then select a cipher to be used bi-directionally
for data encryption. The server MAY determine the 'preferred'
cipher by using the order in which the ciphers were listed in
each CRYPTLINK CIPHER command, or simply select the first cipher
found to be compatible with both ends.
Then Server B must interleave the received 64 byte key with its
generated 64 byte key as follows:
R[0]G[0]R[1]G[2] ... R[62]G[62]R[63]G[64]
It must then (using RSA) encrypt this key to its own private key
(to sign the data), then encrypt it to Server A's public key.
It should then send a CRYPTLINK AUTH command as follows:
CRYPTLINK AUTH <cipher>/<keylen> <base64-encoded new 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
used to encrypt data being generated by using the first N bits,
where N is the key length of the negotiated cipher, from:
R[0]G[1]R[2]G[3] ... R[60]G[61]R[62]G[63]
At this point, Server B SHOULD send an SVINFO command, followed by
a normal net-burst.
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 CRYPTLINK AUTH command is sent (i.e., at the same time as
encryption).
After receiving a CRYPTLINK AUTH command Server A MUST decrypt the
key returned by Server B and ensure it is correct - taking care
to use the correct key to compare (i.e. G[0]R[0] ... G[63]R[63]).
If it is not, the server SHOULD notify online admins/IRCops, and
MUST drop the link.
Server A will then send its own CRYPTLINK AUTH command, and switch
to an encrypted link as above. It SHOULD then send an SVINFO
command, and a normal net-burst.
Server B MUST also validate the CRYPTLINK AUTH response as above.
3.4 - Key Regeneration
----------------------
Although a capability (DK) to indicate support for dynamic key
regeneration has been defined, the protocol extensions required
to support this ability have not yet been defined.
3.5 - Error Responses
---------------------
There are many possibilities of failure/error during the
negotiation process. Due to the vast diversity of these
errors, a generic error response mechanism should be implemented.
The stock ERROR command is used to spit out errors regarding
all sorts of errors. Example:
Example:
ERROR :No compatible ciphers enabled. Aborting Link.
This response MUST be sent immediately after any error is
encountered. For example, if the cipher negotiation phase
fails, the receiving server MUST send an ERROR response once this
is detected, and the socket MUST be closed.
The output to the ERROR command can be anything. Do not assume
all ERROR messages for CRYPTLINK failures will be the same; they
MAY be changed by administrators.
See Section 4.0 ("Communication Phase Examples") for some more
examples.
3.6 - The Validation Mechanism
------------------------------
It is important to understand how the validation process
works. Section 3.2 ("Key Generation") briefly touches on
this subject.
Both servers have a pair of keys on their file system: a PUBLIC
key, and a PRIVATE key.
Each server should have a copy of the others' PUBLIC key.
Herein we will refer to each server individually as "Server A" and
"Server B." In this example, Server A is connecting to Server B.
Server A connects to Server B, and sends CAPAB, followed by
CRYPTLINK CIPHER.
Server A then generates a unique 512-bit key phrase. This key phrase
is generated from a 64 bytes of random data taken from what is
referred to as a PRNG ("Pseudo-Random Number Generator"). A PRNG
could be something like /dev/urandom or something like the EGD
("Entropy Gathering Daemon").
The key phrase is encrypted to Server A's own PRIVATE key, to sign
the data. They key is then encrypted using Server 2's PUBLIC
key to prevent anyone sniffing the connecting from determining
the session key.
This keyphrase is sent to Server B during the CRYPTLINK SERV
phase.
After selecting a cipher, Server B takes the keyphrase, and
decrypts it using it's own PRIVATE key. If the decryption fails,
an ERROR is sent, and the connection is dropped. The signature
is then verified by decrypting the data with Server A's PUBLIC key.
Server B then sends its own CRYPTLINK SERV command as above.
Server B then combines the data with the locally generated
key with the received key as defined above[1], and signs
and encrypts this new key in the same way as the original, and
sends it to Server A.
Server A then decrypts the key, and verifies it matches the
expected values, based on the key it generated, and the key
received from Server B. If it mismatches, Server A assumes
Server B could not decrypt Server A's data, and thus is not
in possession of Server B's private key.
If the data matches, the authentication is legitimate, and
the servers officially link up.
If the data does NOT match, then someone is being naughty.
In this case, an ERROR is sent, and the connection is dropped.
4.0 - Communication Phase Examples
----------------------------------
Server #1 connects to Server #2
===============================
1. Server #1 initiates connection to Server #2 on port 6667.
2. Server #2 answers on port 6667.
3. Server #1 sends:
CAPAB :QS EX CHW IE EOB KLN GLN HOPS AOPS UID ZIP ENC.
CRYPTLINK CIPHERS :BF/256
CRYPTLINK SERV irc.server1 <keyphase> :We like IRC! Woo hoo!
4. Server #2 checks to see if it supports BF/256. It does.
5. Server #2 sends:
CAPAB :QS EX CHW IE EOB KLN GLN HOPS HUB AOPS UID ZIP ENC
CRYPTLINK CIPHERS :BF/256 BF/128
CRYPTLINK SERV irc.server2 <key> :My server is better than yours!
CRYPTLINK AUTH BF/256 <base64-encoded verification key>
6. Server #1 checks to see if it supports one of BF/256 or BF/128,
and selects an outgoing cipher (BF/128).
7. Server #1 decrypts the key, and validates it. It's correct.
8. Server #1 sends:
CRYPTLINK AUTH BF/128 <base64-encoded verification key>
12. Server #1 now enters zip/encryption mode, and sends a net burst.
13. Server #2 decrypts the key, and validates it. It's correct.
14. Server #2 now enters zip/encryption mode, and sends a net burst.
Server #1 connects to server #2, cipher fails
=============================================
1. Same as Steps 1-3 of the above example.
4. Server #2 checks to see if it supports BF/256. It does NOT.
5. Server #2 sends:
ERROR :CRYPTLINK - No compatible ciphers enabled. Aborting Link.
6. Server #1 is aware of the error, logs it, and/or informs
administrators/IRCops on the server of the cipher failure.
7. Server #2 closes the socket.
Server #1 connects to server #2, CRYPTAUTH fails
================================================
1. Same as Steps 1-6 of the above example.
11. Server #1 decrypts the key, and validates it. It's INCORRECT.
12. Server #1 sends:
ERROR :CRYPTLINK - Verification failed. Home, James.
13. Server #1 is aware of the error, logs it, and/or informs
administrators/IRCops on the server of the key mismatch.
14. Server #1 closes the socket.
$Id: cryptlink.txt,v 1.2 2002/08/13 14:45:05 fishwaldo Exp $