#* Design of new, multi-subnet secnet protocol Like the first version, we're tunnelling IP packets inside UDP packets. To defeat various restrictions which may be imposed on us by network providers (like the prohibition of incoming TCP connections) we're sticking with UDP for everything this time, including key setup. Other new features include being able to deal with subnets hidden behind changing 'real' IP addresses, and the ability to choose algorithms and keys per pair of communicating sites. ** Configuration and structure The network is made up from a number of 'sites'. These are collections of machines with private IP addresses. The new secnet code runs on machines which have interfaces on the private site network and some way of accessing the 'real' internet. Each end of a tunnel is identified by a name. Often it will be convenient for every gateway machine to use the same name for each tunnel endpoint, but this is not vital. Individual tunnels are identified by their two endpoint names. The configuration is held in memory as a data structure as follows: The root is a Dictionary. Dictionaries hold (key,value) pairs. Keys are atoms. Values are lists, dictionaries or closures. Lists can hold the following types: string, number. Closures cannot be constructed directly; they are added to the 'default' dictionary before the configuration file is read. Invocation of a closure can return any type of value. Configuration file format: the file describes a dictionary. key value; value is item[,item...] item can be "string", number, path (looks up in dictionary), {dictionary}, value(value), value{dictionary}. If item is a list it is copied into the list - we can't have lists of lists. A path is [/]key[\[index\]][/key[\[index\]]...], defining a lookup from the current dictionary (or parents) or the root. If a key refers to a list of more than one item then an index number (base 0) in square brackets can be used to specify the list item number. Items of the form value1(value2) invoke executable value1 with an argument of value2. The return value can be a string or dictionary, but not a list. (Invocation happens after the entire configuration file has been read.) Items of the form value{dict} invoke executable value with an argument of a single-element list, containing dict. It's just syntactic sugar for value({dict}). When a key is used (rather than defined) it is looked up in the current dictionary, and if it isn't found it is looked up in the (lexical) parent, until the root is reached. What sorts of crypto-related things do we need to define? sources of randomness block algorithms block cipher modes? hash functions padding functions public key signature algorithms public key crypto key stores key setup algorithms ** Protocols *** Protocol environment: Each gateway machine serves a particular, well-known set of private IP addresses (i.e. the agreement over which addresses it serves is outside the scope of this discussion). Each gateway machine has an IP address on the interconnecting network (usually the Internet), which may be dynamically allocated and may change at any point. Each gateway knows the RSA public keys of the other gateways with which it wishes to communicate. The mechanism by which this happens is outside the scope of this discussion. There exists a means by which each gateway can look up the probable IP address of any other. *** Protocol goals: The ultimate goal of the protocol is for the originating gateway machine to be able to forward packets from its section of the private network to the appropriate gateway machine for the destination machine, in such a way that it can be sure that the packets are being sent to the correct destination machine, the destination machine can be sure that the source of the packets is the originating gateway machine, and the contents of the packets cannot be understood other than by the two communicating gateways. XXX not sure about the address-change stuff; leave it out of the first version of the protocol. From experience, IP addresses seem to be quite stable so the feature doesn't gain us much. **** Protocol sub-goal 1: establish a shared key Definitions: A is the originating gateway machine B is the destination gateway machine PK_A is the public RSA key of A PK_B is the public RSA key of B PK_A^-1 is the private RSA key of A PK_B^-1 is the private RSA key of B x is the fresh private DH key of A y is the fresh private DH key of B k is g^xy mod m g and m are generator and modulus for Diffie-Hellman nA is a nonce generated by A nB is a nonce generated by B iA is an index generated by A, to be used in packets sent from B to A iB is an index generated by B, to be used in packets sent from A to B i? is appropriate index for receiver Note that 'i' may be re-used from one session to the next, whereas 'n' is always fresh. Messages: 1) A->B: *,iA,msg1,A,B,nA 2) B->A: iA,iB,msg2,B,A,nB,nA (The order of B and A reverses in alternate messages so that the same code can be used to construct them...) 3) A->B: {iB,iA,msg3,A,B,nA,nB,g^x mod m}_PK_A^-1 If message 1 was a replay then A will not generate message 3, because it doesn't recognise nA. If message 2 was from an attacker then B will not generate message 4, because it doesn't recognise nB. 4) B->A: {iA,iB,msg4,B,A,nB,nA,g^y mod m}_PK_B^-1 At this point, A and B share a key, k. B must keep retransmitting message 4 until it receives a packet encrypted using key k. 5) A: iB,iA,msg5,(ping/msg5)_k 6) B: iA,iB,msg6,(pong/msg6)_k (Note that these are encrypted using the same transform that's used for normal traffic, so they include sequence number, MAC, etc.) The ping and pong messages can be used by either end of the tunnel at any time, but using msg0 as the unencrypted message type indicator. **** Protocol sub-goal 2: end the use of a shared key 7) i?,i?,msg0,(end-session/msg7,A,B)_k This message can be sent by either party. Once sent, k can be forgotten. Once received and checked, k can be forgotten. No need to retransmit or confirm reception. It is suggested that this message be sent when a key times out, or the tunnel is forcibly terminated for some reason. 8) i?,i?,NAK/msg8 If the link-layer can't work out what to do with a packet (session has gone away, etc.) it can transmit a NAK back to the sender. The sender can then try to verify whether the session is alive by sending ping packets, and forget the key if it isn't. Potential denial-of-service if the attacker can stop the ping/pong packets getting through (the key will be forgotten and another key setup must take place), but if they can delete packets then we've lost anyway... The attacker can of course forge NAKs since they aren't protected. But if they can only forge packets then they won't be able to stop the ping/pong working. Trust in NAKs can be rate-limited... Alternative idea: if you receive a packet you can't decode, because there's no key established, then initiate key setup... **** Protocol sub-goal 3: send a packet 9) i?,i?,msg0,(send-packet/msg9,packet)_k