Modifying isakmpd to make use of the compliance-checking architecture for policy resolution proved straightforward. isakmpd was initially designed with a rudimentary mechanism for verifying security associations proposed by the remote peer. The set of acceptable security associations was read from the configuration file, and then consulted when examining the proposed SA. However, this scheme lacked flexibility and extensibility. In particular, it was not possible to delegate authority, allow for very fine-grained SA specification without an explosion in the size of the configuration file, take into consideration information not directly relevant to the SA (such as time of day, or system security level), nor allow for flexible packet selectors (an exact match was required).
Since this verification mechanism was implemented as a procedure call, we only had to modify the invoking code to call another procedure that ultimately invoked KeyNote. This change occurred in two places:
When invoked, the procedure converts information taken from the exchange and sa structures to a format suitable for use by KeyNote. Such information contains the IPsec protocols to be used, the cryptographic algorithms to be used, the packet selectors requested (Phase 2 User IDs), the cryptographic identifier used in Phase 1 by the remote peer, etc.
This cryptographic identifier is used by the compliance checker to determine which part of the security policy is relevant to a specific request. If public key authentication was used, then our security policy may directly refer to said public key, and the same applies for passphrase authentication. For X.509-based authentication, we have a number of options as to who policy may refer to:
The assembled information is passed on to KeyNote, and the response indicates whether the SA should be accepted or dropped. In effect, KeyNote is verifying that the combination of remote peer, IPsec protocols (and algorithms, lifetimes, etc. used by those protocols), and packet selectors are acceptable by policy. This policy may be expressed solely in terms of local policy or as a combination of local policy and (signed) credentials. These credentials may be acquired during the Phase 1 exchange (provided by the remote peer) or at any point in time afterwards (e.g., fetched on-demand through some out-of-band protocol). As soon as an SA is accepted, the search is concluded.
The procedure is called once for each distinct SA proposal received from the peer (since there is no way to efficiently encode all the SA proposals in one action attribute set and have KeyNote make a decision on which one to select - this is a drawback of using KeyNote instead of a more complex policy language). Note however that each such invocation is very ``lightweight'' in processing terms: converting the relevant information is straightforward, and any cryptographic operations are only performed once and their results cached for future use. The policy assertions are loaded once at startup time (and reloaded if isakmpd is asked to re-initialize). Some simple experiments show that the cost of invoking KeyNote increases linearly with the number of assertions in use, and that for a simple setup of 3-4 assertions/credentials the cost is in the order of 150 sec.
Here, we wish to make two additional observations:
In terms of code size, the ``glue'' code between isakmpd and KeyNote was about 1200 lines, almost exclusively dealing with the conversion of information from isakmpd's internal structures to KeyNote action attributes. We also had to add about 50 lines of code in different parts of KeyNote, dealing with initialization and record keeping. The code displaced by KeyNote was approximately 500 lines long. The KeyNote library itself is about 5000 lines (not including the cryptographic functions, where libcrypto is used).