RFC 2847 Simple Public Key Mechanism 3 Implementation
This code is pre-pre-alpha, only a portion of the gss context creation has been completed.
Andy Adamson - email@example.com
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. SPKM3 ASN1 sytax requirements extend beyond the parser's design. The Valicert asn1parser team has been quite helpful in helping with using their parser, and I believe they are extending it's capabilities for the upcoming 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 the string "-- 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. 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 and spkm_req_rep.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....
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.
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. 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=androsFor now, I've hardwired the UMICH preamble into the code.
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 rpcsec_gss/rpc Makefile needs the -DSPKM flag added to the CFLAG variable to enable the spkm3 mechanism. the rpc code also needs to linked against the SPKM enabled kerberos v5 gss libraries and libspkm3 described below. Please read the README file accompanying the test suite.
The client is called as follows:
% client [server host name] nfs -m [x] where x = 1 uses the Kerberos V5 mechanism x = 2 uses the SPKM3 mechanism.
The server just needs to be started (no arguments needed).
Building kerberos 5 with spkm3 support
1) # tar -zxvf mit-krb220.127.116.11-mech-spkm3.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 add to 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