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).