the purpose of this little thing is to explain how to set up a "jar-signer" principal that digitally signs java jar files, which then allows them to be launched as remote applications on client workstations with the help of the java WebStart stuff. ------------------------------------------------------------------------------------- 1. (first, generate your keypair; NOTE: MUST use the java tool for this, `openssl', e.g., won't work) % keytool -genkey -alias jarsigner -keyalg RSA -sigalg MD5withRSA -keysize 1024 -storetype JKS \ -dname "cn=CITI Jarsigner,ou=CITI Production KCA,o=University of Michigan,l=Ann Arbor,st=MI,c=US" 2. (next, make a certreq based on the keys) % keytool -certreq -alias jarsigner -sigalg MD5withRSA -file jarsigner.csr 3. (schlep that over to babylon and get it signed by the KCA) [babylon:/home/richterd/bin] % sudo ./certreqtifier jarsigner ## MUST first read and maybe edit the script -OR- you can do it manually, like: % sudo openssl x509 -req -in -out -days 365 \ -CAserial /var/kca/conf/kca_serial \ -CA /var/kca/conf/citi-production-kca.crt \ -CAkey /var/kca/conf/citi-production-kca.key \ -extfile /var/kca/extensions/extfile.server 4. (back on your machine, get your hands on the KCA's cert, in our case 'citi_ca.crt' and import it) % keytool -import -alias citi_ca -file citi_ca.crt 5. (next, import the cert you got signed by the KCA, in our case 'jarsigner.crt') % keytool -import -alias jarsigner -file jarsigner.crt 6. (finally, verify that everything got in there right) % keytool -v -list ## which gives the following output: [richterd@pugna keysigner-temp]$ keytool -v -list Keystore type: jks Keystore provider: SUN Your keystore contains 2 entries Alias name: jarsigner Creation date: Dec 3, 2004 Entry type: keyEntry Certificate chain length: 2 Certificate[1]: Owner: CN=CITI Jarsigner, OU=CITI Production KCA, O=University of Michigan, L=Ann Arbor, ST=MI, C=US Issuer: CN=CITI Production KCA, O=University of Michigan, L=Ann Arbor, ST=Michigan, C=US Serial number: cfb Valid from: Fri Dec 03 15:30:14 EST 2004 until: Sat Dec 03 15:30:14 EST 2005 Certificate fingerprints: MD5: 0C:37:9A:92:E4:94:56:B2:95:BC:95:FD:40:0F:0C:FC SHA1: 52:FF:6E:46:74:DC:B3:9E:37:D9:F6:FC:5C:04:72:DD:21:96:D6:86 Certificate[2]: Owner: CN=CITI Production KCA, O=University of Michigan, L=Ann Arbor, ST=Michigan, C=US Issuer: CN=CITI Production KCA, O=University of Michigan, L=Ann Arbor, ST=Michigan, C=US Serial number: 0 Valid from: Tue Oct 16 00:00:00 EDT 2001 until: Thu Oct 25 00:00:00 EDT 2007 Certificate fingerprints: MD5: 88:21:30:E3:F4:8D:94:FB:3A:96:4C:CC:31:92:DC:62 SHA1: 1D:02:A7:74:2F:D0:32:DB:23:BA:B3:FC:C1:07:E0:D2:D0:70:98:C6 ******************************************* ******************************************* Alias name: citi_ca Creation date: Dec 2, 2004 Entry type: trustedCertEntry Owner: CN=CITI Production KCA, O=University of Michigan, L=Ann Arbor, ST=Michigan, C=US Issuer: CN=CITI Production KCA, O=University of Michigan, L=Ann Arbor, ST=Michigan, C=US Serial number: 0 Valid from: Tue Oct 16 00:00:00 EDT 2001 until: Thu Oct 25 00:00:00 EDT 2007 Certificate fingerprints: MD5: 88:21:30:E3:F4:8D:94:FB:3A:96:4C:CC:31:92:DC:62 SHA1: 1D:02:A7:74:2F:D0:32:DB:23:BA:B3:FC:C1:07:E0:D2:D0:70:98:C6 ___________________________________________________________________________________________ ... you want to see that (1) your jarsigner chain goes all the way up to the signing CA (see "Certificate chain length: 2"? it should never be 1 -- that's self-signed). you also want to see that the jarsigner's "Owner" DN is right, and that the "Issuer" DN really is the CA's DN. one problem i had was that without the keyalg/sigalg command-line args, the keytool SOMEHOW would mangle the cert after importing the CA's reply to the certreq. i noticed this because the chain-length was too short and the serial number of the certificate CHANGED after it was imported into the keystore. 7. (now actually construct and sign a jar) % jar cvf jarsignerdemo.jar JarsignerDemo.class (make a jar) % jarsigner jarsignerdemo.jar jarsigner (sign said .jar file using the cert in the keystore under alias 'jarsigner') % jarsigner -verbose -verify -certs jarsignerdemo.jar (verify that the resulting modified jar is well-formed) ////////////////////////////////////////////////////////////////////////////// // at this point, the document isn't really about jarsigning specifically // any longer -- this is NTAP-specific Java WebStart setup. ////////////////////////////////////////////////////////////////////////////// 8. okay, now to make the Java WebStart stuff a lot easier to develop and use, move the main JWS jarfile into the system-default classpath-catchall. this is something like /usr/java/j2sdk1.4.2_05/jre/lib/etc/ -- it's always /jre/lib/ext/ . so, locate javaws.jar (`locate javaws.jar`; mine is /usr/java/j2sdk1.4.2_05/jre/javaws/javaws.jar) and copy it into the jre/lib/ext/ directory. this will save you from having to manually specify a classpath option whenever you compile a JWS app or when you run it locally to test it. pre-9. if you have to make the webserver, download current apache 1.3 (1.3.33, now). i unpacked it in /opt. % ln -s /opt/apache_1.3.33 /opt/apache % cd /opt/apache % ./configure --prefix=/opt/apache --enable-module=so % make && make install now, you'll need PHP, too. i downloaded 4.3.4, also unpacked it in /opt/. % cd /opt/php-4.3.4 % ./configure --enable-sockets --with-mysql --with-ldap --with-apxs=/opt/apache/bin/apxs % make % sudo make install now look in /opt/apache/libexec/ and make sure that libphp4.so appeared there. if not, something went wrong with building PHP (it's likely NOT apache's fault). lastly, teach apache to grok JNLP files. crack open /opt/apache/conf/mime.types and add the line (anywhere is fine): application/x-java-jnlp-file JNLP shazam. 9. now, when it comes time to integrate this stuff into your webserver, don't forget to notify Apache about the new mime-type that Java's WebStart stuff requires -- the JNLP mime-type. i modified my Apache's mime-type conf file by adding the line: application/x-java-jnlp-file JNLP .. along with the others. 10. now, one problem with this whole deal is that the portals are now set up only to do SSL, which is okay -- JWS can handle that. however, the portals also have mod_kct, which wants mutual authentication, but the JWS client doesn't present a cert back to the portal, so mod_kct drops the request. suck. so, i'm stop-gap hosting the JWS client on a non-portal webserver. hmm. to this end, la0:/opt//root/ntap/ is a directory containing the the .java/.jnlp/.jar files. these are in CVS under ntap2/webserver/php/src/ ////////////////////////////////////////////////////////////////////////////// // this is now about how to SETUP NDT ////////////////////////////////////////////////////////////////////////////// a. on the NDT server, there should be /usr/local/sbin/fakewww , which is the webserver that NDT utilizes (normally on port 7123). its logfile is /var/log/fakewww.log . the NDT server itself is normally /usr/local/sbin/web100srv . the normal logs/gen'd html/etc reside in /usr/local/ndt/ (on ntap1.merit.edu, anyway). to start the server: sudo fakewww &; sudo web100srv -a & b. the parts of an NDT setup are: - the modified Web100 kernel, from web100.org (i used an RPM) http://www.web100.org/download/rpms/RPMS/alpha2.3.8/i686/kernel-web100-2.4.26-2.3.8.i686.rpm - the userland Web100 library, from web100.org http://www.web100.org/download/userland/alpha1.4/web100_userland-alpha1.4.tar.gz - the NDT software and uses the Web100 library: http://e2epi.internet2.edu/ndt/download/ndt-built-3.0.23.tar.gz c. getting started: - handle the kernel RPM: sudo rpm -ivh - install the library: . unpack and cd in . ./configure; make; sudo make install . MAKE SURE that /usr/local/lib is in ld.so.conf and re-run ldconfig if you have to add it - install libpcap.so [www.tcpdump.org] - make sure that Java's installed - now, install the NDT software (configure/make/make install) . the NDT install docs also say to run conf/create-html.sh. . actually, i had to move create-html.sh up a level (out of the conf directory) to make it work. . read the scripts in the conf/ directory -- they're helpful. - i used the conf/ndt script (it's an init script, so i put it in /etc/init.d) to start the stuff. worked fine. ////////////////////////////////////////////////////////////////////////////// // this is now about the MODIFICATIONS we (CITI) made to NDT ////////////////////////////////////////////////////////////////////////////// a. web100srv.c: (all in "#ifdef CITI" blocks) - around line 900: the part that gets the raw data from web100_get_data() and writes it to the NTAP output file (that's the 1st half of the data). also, declares and constructs the NTAP output filename. - around line 1100: the part that gets the calculated data and appends it to the NTAP output file (that's the 2nd half of the data). PROBLEM: web100srv-util.c::web100_get_data() never returns an error if one happens. funny, 'cause web100srv.c::run_test() checks the rc. *WE* really should know about an error in web100_get_data(), so that we don't try to write out malformed data back to the portal. PROBLEM: we need to import the web100 stuff into our CVS somehow. these modified files are (temporarily) in ntap2/webserver/jarsigner/ . PROBLEM: the outfiles are `/tmp/citi_ndt-XXXXXX' -- these should prolly go into a better directory, a la gara-1.2.2/logs/ NEW PROBLEM: this way doesn't work. we get ALL data except the timing data, so we can't actually calculate what the real throughput (in or out) was. great. two solutions: 1) add code to the NDT server to try and log start/stop times for the in- and outbound tests. 2) go BACK to having the applet send its output back (joy) to the NDT server. at the least, we can have my hacked applet send back its CITI-formatted data instead of what the lusers see in their browser window. the applet itself, of course, knows the timing data. so, test runs as normal. hacked applet runs its data through my added formatting method. hacked applet then tries opening one last socket to the server -- over this, the formatted data is sent. X hack applet to open socket at end. 2) hack server to open socket at end. 3) hack server to flushtofile, as currently. 4) hack server to ... prolly send it right back to the portal. b. Makefile: - added "-DCITI" to CFLAGS. c. ndt (init script; minor): it didn't do a very good job of detecting running programs.