RFC 2947 SPKM3 UserLand Implementation 

General Notes
------------- 
this code is pre-pre-alpha, only a portion of the gss context creation 
has been completed. i've enabled the mit-krb-1.2.1/lib/gssapi/mechglue 
mechanism glue layer that allows switching between gssapi mechanisms, 
and have added the spkm3 directory to the kerberos v5 distribution.
since spkm3 calls SSLeay functions, spkm3 joins the kerberos and SSL 
code via the gssapi layer.

asn1 encoding and decoding has by far been the biggest challenge
to coding SPKM3.  i've used the asn1parser from valicert which 
produces the asn1 code for SSLeay-0.9.0b, and therefore produces
code that links against SSLeay-0.9.0b functions. the valicert asn1parser
is designed to handle the asn1 syntax requirements of SSLeay, which
is a subset of asn1 syntax.  naturally, SPKM3 asn1 sytax requirements
extend beyond the parser's design. the valicert asn1parser team has been
quite helpful in this effort and i believe they are extending the 
parser capabilities for the openssl release.

one of the first tasks is to construct a .asn file to feed the asn1parser. 
i lifted the asn1 definitions come from rfc's.
SPKM3 (rfc2847) depends heavily on rfc2025 which defines SPKM1 and SPKM2. 
there is considerable time between rfc2847 - june2000 and rfc2025 - oct 1996
during which i think the asn1 syntax changed. the spkm3.asn file contains
all the relevant asn1 definitions i could find, with -- ALERT showing 
all the syntax that the asn1parser didn't like.

Divide and Conquer
------------------
the first goal is context establishment, which for SPKM3 means sending 
a SPKM-REQ token and responding with a SPKM-REP-TI token to carry the
diffie-hellman key exchange.

the messages consisit of an InitialTokenHeader, followed by a CHOICE
of tokens - SPKM-REQ, SPIM-REP-TI, etc. (see spkm3.asn)
the asn1parser couldn't parse the InitialTokenHeader syntax. so, i turned to 
the Kerberos V5 code, which also encodes the header, and used it's routines. 

i have intentionally excluded the SPKM-REQ and SPKM-REP-TI structures
with the CertificationData declarations, because the asn1parser
can't handle the asn1 syntax of the. so, i skip the SPKM-XXX structure and
simply encode the REQ_TOKEN and reply with the REP-TI-TOKEN, leaving 
the parsing of the CertificateData for a later day. 

i carved out the pieces of spkm3.asn that i needed and placed them in
spkm_req_rep.asn for the input to asn1parser. i had to hand code
a bunch of stuff in the output spkm_req_rep.c/.h.

init_sec_context and accept_sec_context exchange diffie-hellman parameters 
and public keys, and create (the same!) shared key. Note that there are
no Certificates exchanged....

OIDs
----
SPKM3 defines several ciphers and digests that do not appear in SSLeay-0.9.0b.
SSLeay provides a method of calculating OIDs, but it is not clear how to add
new OIDs to this method.  the kerberos v5 gssapi code uses hard coded OIDs.
OpenSSL extends and clarifies the SSLeay method of adding OIDs.
the SPKM3 code uses hard coded OIDs, generated by using OpenSSL tools, and 
stored in the Kerberos V5 manner. i anticipate moving to OpenSSL along with
valicerts asn1parser, and will revisit the OID situation at that time.

Naming
------
Req_contents->target_name. this is the name of the server - more specifically,
this name needs to match the distinguished name (DN) in the server's 
certificate.
the DN will eventually be looked up in a naming service (?).

according to rfc3010 (NFSv4 spec) server names will be of the form
nfs@hostname - and it is recommended that this  be stored as nfs/hostname.

so, the server's certificate subject name consists of two parts:
1) preamble - everything up the to common name (CN).
2) CN

looking at my certificates subject name:

/C=US/ST=Michigan/L=Ann Arbor/O=University of Michigan/OU=TEST -- CITI Client CA v1/CN=andros

for now, i've hardwired the UMICH preamble into the code.

Testing
-------
the rpcsec_gss/rpcsec_tests/ test program along with the rpcsec_gss/rpc code 
has been modified to be able to switch between Kerberos V5 and SPKM3 
mechanisms.

the client is called as follows:

% client <server host name> nfs -m <x>  where x = 1 is krb5, x = 2 is spkm3.

the server just needs to be started (no arguments needed).
% list_svc

the rpcsec_gss/rpc Makefile needs the -DSPKM flag added to the CFLAGs
to enable the spkm4 mechanism. the rpc code also needs to linked against the
SPKM enabled kerberos v5 gss libraries and libspkm3 described below.

Building kerberos 5 with spkm3 support
--------------------------------------
1) # tar -zxvf mit-krb5.1.2.1-mech.tar.gz into MIT_K5_DIR, a location of your 
     choice, I use /usr/local/src. 
   % ./configure --with-cc=gcc
   % cd MIT_K5+DIR/lib/gssapi/mechglue; ln -s Makefile.static Makefile
   edit Makefile - set BUILDTOP = MIT_K5_DIR
   % cd MIT_K5_DIR;  make.


2) download, build, and install SSLeay-0.9.0b into a location of your 
   choice, I use /usr/local/src.

3) # add valicert asn1 macro's to SSL's asn1_mac.h 
   # (SSL_INSTALL_DIR default is /usr/local/ssl)
   % cd MIT_K5_DIR/mit-krb5-1.2.1-mech/lib/gssapi/spkm3
   % tail -19  valicert_asn1_mac.h >> SSL_INSTALL_DIR/include/asn1_mac.h

   # as per asn1parser instructions, add ERR_LIB_SpkmGssTokens define to 
   # SSL_INSTALL_DIR/include/err.h

   err.h: ~ line 120
   #define ERR_LIB_SpkmGssTokens 34


4) % cd MIT_K5_DIR/mit-krb5-1.2.1-mech/lib/gssapi/mechglue
   edit Makefile.static, 
   add -DSPKM to CPPFLAGS
   % make clean (in mechglue)
   % cd MIT_K5_DIR/mit-krb5-1.2.1-mech/lib/gssapi
   % make
   
6) % cd MIT_K5_DIR/mit-krb5-1.2.1-mech/lib/gssapi/spkm3
   edit Makefile
   set KRBDIR and SSLDIR as per instructions
   % make

NOTE: to build without SPKM support:
   % cd MIT_K5_DIR/lib/gssapi/mechglue
   edit Makefile, remove -DSPKM from CPPFLAGS
   % make clean
   % cd ..
   % make

