diff -BbruN freeswan-1.91.orig/CHANGELOG.pkix freeswan-1.91/CHANGELOG.pkix --- freeswan-1.91.orig/CHANGELOG.pkix Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/CHANGELOG.pkix Sat Aug 18 11:22:56 2001 @@ -0,0 +1,50 @@ +Release freeswan-1.91-pkix6b +-- 20010818 - Removed missed debugging output used during coding. One + of the such outputs contained the passphrase. (oops?) + +Release freeswan-1.91-pkix6 +-- 20010817 - Fixed pkcs8 passphrase bug. FreeSWAN's chunks are not + NULL terminated strings. Fixed that. + - Updated fswcert to display DN for proper use. Will be + fswcert-0.4-pkix2. +-- 20010816 - Added text DN support for ID. A cert's subject line will + work fine. + +Release freeswan-1.91-pkix5 +-- 20010803 - Created and integrated manpages for dir2hash, fswcert and + rehashcertdir. +-- 20010729 - Draft manpages for dir2hash, fswcert and rehashcertdir. +-- 20010725 - Added PKCS7 and PKCS8 support to fswcert. + +Release freeswan-1.91-pkix4 +-- 20010723 - Fixed broken reading x509 keys. +-- 20010720 - Added PKCS12 support. +-- 20010719 - fixed 'klink' in main Makefile. + - Added -DDONT_BE_FASCIST in pluto's Makefile. + +Release freeswan-1.91-pkix3 +-- 20010717 - renamed 5 functions in libdes to avoid conflicts with openssl: + des_check_key -> des_check_key_pluto + des_set_odd_parity -> des_set_odd_parity_pluto + des_is_weak_key -> des_is_weak_key_pluto + des_set_key -> des_set_key_pluto + des_key_sched -> des_key_sched_pluto +-- 20010716 - When loading PKCS#7, it checks with id from config to file + which cert in the chain is the one it wants. +-- 20010711 - Got PKCS8 to load a certficate key with a passphrase stored + in /etc/ipsec.secrets + +Release freeswan-1.91-pkix1 +-- 20010707 - Release of freeswan-1.91-pkix2 patch to the world. +-- 20010706 - DES is reimplemented, but optional via a -DDES flag. Check + root Makefile to turn it on/off. Default=on with patch. +-- 20010705 - FreeSWAN uses a new pubkey method with a char string. + Adapted secrets creation to contain both the old and new formats + of pubkey. Use old format by default for compatibility. +-- 20010704 - Added in support for OpenSSL 0.9.6 + +Release freeswan-1.91-pkix1 +-- 20010702 - Merged FreeSWAN 1.91 with PKIX patch. Create + "freeswan-1.91-pkix1.patch" + - Also decided to start tracking changes in a Changelog. So + I'm disorganized. ;> diff -BbruN freeswan-1.91.orig/CREDITS.pkix freeswan-1.91/CREDITS.pkix --- freeswan-1.91.orig/CREDITS.pkix Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/CREDITS.pkix Fri Aug 3 11:49:05 2001 @@ -0,0 +1,27 @@ +Please read 'CREDITS' for work done onto FreeSWAN itself. + + +The fswcert utility was written by Andreas Gruenbacher, +. + + +Parts of FreeSWAN/PKIX have been inspired from work on +http://www.strongsec.com/freeswan: + +"Originally based on a PGPnet patch written by Kai Martius , i +the X.509 patch has been developped with the help of the third year students +Marco Bertossa, Andreas Hess, Patric Lichtsteiner, Andreas Schleiss +and Roger Wegmann of the Zurich University of Applied Sciences in +Winterthur (Switzerland). The X.509 patch is maintained by Andreas +Steffen ." + + +FreeSWAN/PKIX has been based on the works of Neil Dunbar's 'pluto-openssl.diff' +for FreeSWAN 1.1. Most of FreeSWAN/PKIX has been a mere update of Neil's work. + + +FreeSWAN/PKIX is maintained by Luc Lanthier, . + + +-- Luc Lanthier +Last updated: 20010803 diff -BbruN freeswan-1.91.orig/INSTALL.pkix freeswan-1.91/INSTALL.pkix --- freeswan-1.91.orig/INSTALL.pkix Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/INSTALL.pkix Fri Aug 3 11:40:51 2001 @@ -0,0 +1,46 @@ +Documentation on how to use the PKIX extension for IPSec can be found under +'doc/pkix'. Within that directory, you will also find working examples I +have preserved to test the various connection modes I have successfully +connection with FreeSWAN. There are also some scripts you might (will?) +find useful. + +Requirements: +OpenLDAP 1.2 or better +OpenSSL 0.9.5a with Shared Libraries compiled. + + + If you have to compile OpenSSL 0.9.5a yourself, here's how you should +compile it. Don't forget to add '/usr/local/ssl/lib' (or whatever your SSL +path is going to be) to '/etc/ld.so.conf'. This following script will let +you create '.so' shared library files. Of course, Run it as Root.: +------------------------------------------------------- +./config +make +if [ ! -d shlib_dir ]; +then + mkdir shlib_dir +else + rm -f shlib_dir/* +fi +cd shlib_dir +ar -x ../libcrypto.a && gcc -shared ./*.o -Wl,-soname \ + -Wl,libcrypto.so -o ./libcrypto.so.0.9.5a && rm *.o +ar -x ../libssl.a && gcc -shared ./*.o -Wl,-soname \ + -Wl,libssl.so -o ./libssl.so.0.9.5a && rm *.o +cp libssl.so.0.9.5a /usr/local/ssl/lib +cp libcrypto.so.0.9.5a /usr/local/ssl/lib +cd .. +make install +ldconfig +------------------------------------------------------- + +NOTE: +Don't forget to edit the root Makefile for OPENSSLROOT and LDAPROOT if their +include paths are non-standard (ie: not under /usr/include/). + + +Otherwise, just follow FreeSWAN's own INSTALL file normally. + +-- Luc Lanthier +firesoul@pet.dhs.org +Last updated: 20010803 diff -BbruN freeswan-1.91.orig/LICENSE.pkix freeswan-1.91/LICENSE.pkix --- freeswan-1.91.orig/LICENSE.pkix Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/LICENSE.pkix Fri Aug 3 11:31:15 2001 @@ -0,0 +1,5 @@ +This program is released under the GPL with the additional exemption +that compiling, linking and/or using OpenSSL is allowed. + +-- Luc Lanthier +firesoul@pet.dhs.org diff -BbruN freeswan-1.91.orig/Makefile freeswan-1.91/Makefile --- freeswan-1.91.orig/Makefile Wed May 30 02:18:44 2001 +++ freeswan-1.91/Makefile Thu Jul 19 13:38:15 2001 @@ -13,21 +13,44 @@ # # RCSID $Id: Makefile,v 1.128 2001/05/30 06:18:44 henry Exp $ -# install pathnames; DESTDIR can be used to supply a prefix to them all -# PUBDIR is where the "ipsec" command goes; beware, many things define PATH -# settings which are assumed to include it (or at least, to include *some* -# copy of the "ipsec" command). -PUBDIR=$(DESTDIR)/usr/local/sbin -# PRIVDIR is where commands get put, REALPRIVDIR is where they think they -# will be run from in the end (currently only used by utils/ipsec) + +# change this to 0 if you don't want OPENSSL support turned on +# it will turn off all pkix support also +# check the paths for the OPENSSLROOT and LDAPROOT +export USEOPENSSL=1 +ifeq "$(USEOPENSSL)" "1" +export OPENSSLROOT=/usr/local/ssl +export OPENSSLINCLS=-I$(OPENSSLROOT)/include +export OPENSSLLIBS=-L$(OPENSSLROOT)/lib -lcrypto + +export LDAPROOT=/usr/local +export LDAPINCS=-I$(LDAPROOT)/include +endif + +# change this to 0 if you don't want DES support turned on in pluto. +export USEDES=1 + +# PREFIX controls where everything gets installed to. This is intended +# only for use by RPM, which installs everything into a temporary root +# prior to creating the package. +export PREFIX ?= / + +# public and private command directories +# Beware, many things define PATH settings which are assumed to include +# PUBDIR (or at least, to include *some* copy of the "ipsec" command). +PUBDIR=$(PREFIX)/usr/local/sbin + +# PRIVDIR is where things get put, FINALPRIVDIR is where they think they +# will be put (currently only used by utils/ipsec) +PRIVDIR=/usr/local/lib/ipsec +FINALPRIVDIR=/usr/local/lib/ipsec REALPRIVDIR=/usr/local/lib/ipsec -PRIVDIR=$(DESTDIR)$(REALPRIVDIR) # where manpages go -MANTREE=$(DESTDIR)/usr/local/man +MANTREE=/usr/local/man # all relevant manpage subdirectories MANPLACES=man3 man5 man8 # where configuration files go -CONFDIR=$(DESTDIR)/etc +CONFDIR=$(PREFIX)/etc # RCDIR is where boot/shutdown scripts go (first RCDIRS that exists gets it); # REALRCDIR is where they think they will ultimately be (for utils/Makefile) RCDIRS=/etc/rc.d/init.d /etc/rc.d /etc/init.d /sbin/init.d @@ -38,7 +61,7 @@ RCDIR=$(DESTDIR)$(REALRCDIR) # kernel location, and location of kernel patches in the distribution -KERNELSRC=/usr/src/linux +KERNELSRC?=/usr/src/linux DIRIN22=$(KERNELSRC)/net/netlink FILIN24=$(KERNELSRC)/net/khttpd/main.c KERNELREL=$(shell { test -f $(FILIN24) && echo 2.3; } || { test -d $(DIRIN22) && echo 2.2; } ) @@ -48,10 +71,12 @@ # note, some of the patches know the last part of this path KERNELKLIPS=$(KERNELSRC)/net/ipsec + + # kernel make name: zImage for 2.0.xx, bzImage for 2.2.xx and later, and -# boot elsewhere (what ever happened to standards?) +# different foolishness on the Alpha (what ever happened to standards?) B=$(shell test -d $(DIRIN22) && echo b) -KERNEL=$(shell if expr " `uname -m`" : ' i.86' >/dev/null ; then echo $(B)zImage ; else echo boot ; fi) +KERNEL=$(shell if test " `uname -m`" = " alpha" ; then echo boot ; else echo $(B)zImage ; fi) # pass pathnames etc. down SETTINGS=BINDIR=$(PRIVDIR) PUBDIR=$(PUBDIR) PRIVDIR=$(PRIVDIR) \ @@ -71,7 +96,7 @@ @false # everything that's necessary to put Klips into the kernel -insert: patches klink klipsdefaults +insert: patches kcopy klipsdefaults klink: rm -rf $(KERNELKLIPS) @@ -91,11 +116,28 @@ ln -s `pwd`/zlib/Makefile $(KERNELKLIPS)/zlib ln -s `pwd`/zlib/*.[chS] $(KERNELKLIPS)/zlib +kcopy: + rm -rf $(KERNELKLIPS) + mkdir -p $(KERNELKLIPS)/libdes/asm + mkdir -p $(KERNELKLIPS)/libfreeswan + mkdir -p $(KERNELKLIPS)/zlib + cp -R --verbose `pwd`/klips/net/ipsec/Makefile $(KERNELKLIPS) + cp -R --verbose `pwd`/klips/net/ipsec/Config.in $(KERNELKLIPS) + cp -R --verbose `pwd`/klips/net/ipsec/defconfig $(KERNELKLIPS) + cp -R --verbose `pwd`/klips/net/ipsec/*.[ch] $(KERNELKLIPS) + cp -R --verbose `pwd`/lib/Makefile.kernel $(KERNELKLIPS)/libfreeswan/Makefile + cp -R --verbose `pwd`/lib/*.[ch] $(KERNELKLIPS)/libfreeswan + cp -R --verbose `pwd`/libdes/Makefile $(KERNELKLIPS)/libdes + cp -R --verbose `pwd`/libdes/*.[ch] $(KERNELKLIPS)/libdes + cp -R --verbose `pwd`/libdes/asm/*.pl $(KERNELKLIPS)/libdes/asm + cp -R --verbose `pwd`/libdes/asm/perlasm $(KERNELKLIPS)/libdes/asm + cp -R --verbose `pwd`/zlib/Makefile $(KERNELKLIPS)/zlib + cp -R --verbose `pwd`/zlib/*.[chS] $(KERNELKLIPS)/zlib + PATCHER=utils/patcher patches: - echo "===============" >>out.kpatch - echo "`date` `cd $(KERNELSRC) ; pwd`" >>out.kpatch - $(MAKE) _patches$(KERNELREL) $(SETTINGS) >>out.kpatch + rm -f out.kpatch + $(MAKE) _patches$(KERNELREL) $(SETTINGS) >out.kpatch # Linux-2.0.x version _patches: @@ -122,14 +164,13 @@ @$(PATCHER) -v $(KERNELSRC) drivers/isdn/isdn_net.c # Linux-2.2.x version -PATCHES24=klips/patches2.3 _patches2.2: @$(PATCHER) -v $(KERNELSRC) Documentation/Configure.help \ 'CONFIG_IPSEC' $(PATCHES)/Documentation.Configure.help @$(PATCHER) -v $(KERNELSRC) include/linux/in.h \ 'IPPROTO_ESP' $(PATCHES)/include.linux.in.h @$(PATCHER) -v $(KERNELSRC) net/Config.in \ - 'CONFIG_IPSEC' $(PATCHES24)/net.Config.in + 'CONFIG_IPSEC' $(PATCHES)/net.Config.in @$(PATCHER) -v $(KERNELSRC) net/Makefile \ 'CONFIG_IPSEC' $(PATCHES)/net.Makefile @$(PATCHER) -v $(KERNELSRC) net/ipv4/af_inet.c \ @@ -212,8 +253,8 @@ cd utils ; $(MAKE) $(SETTINGS) install: - mkdir -p $(PRIVDIR) $(PUBDIR) - for m in $(MANPLACES) ; do mkdir -p $(MANTREE)/$$m ; done + mkdir -p $(PREFIX)/$(PRIVDIR) $(PREFIX)/$(PUBDIR) + for m in $(MANPLACES) ; do mkdir -p $(PREFIX)/$(MANTREE)/$$m ; done cd lib ; $(MAKE) install $(SETTINGS) cd klips/utils ; $(MAKE) install $(SETTINGS) cd pluto ; $(MAKE) install $(SETTINGS) @@ -224,11 +265,7 @@ cd klips/utils ; $(MAKE) clean $(SETTINGS) cd pluto ; $(MAKE) clean $(SETTINGS) cd utils ; $(MAKE) clean $(SETTINGS) - rm -f out.kbuild out.kinstall - -# out.kpatch contents are usually worth retaining -spotless: clean - rm -f out.kpatch + rm -f out.kbuild out.kinstall out.kpatch @@ -239,10 +276,6 @@ oldgo: precheck insert ocf confcheck programs install kernel menugo: precheck insert mcf confcheck programs install kernel xgo: precheck insert xcf confcheck programs install kernel -omod: precheck insert pcf confcheck programs install module -oldmod: precheck insert ocf confcheck programs install module -menumod: precheck insert mcf confcheck programs install module -xmod: precheck insert xcf confcheck programs install module # preliminaries precheck: @@ -291,15 +324,6 @@ fi utils/errcheck out.kbuild -# module-only building, with error checks -module: - rm -f out.kbuild out.kinstall - egrep -q '^CONFIG_MODULES=y' $(KCFILE) - egrep -q '^CONFIG_IPSEC=m' $(KCFILE) - ( cd $(KERNELSRC) ; \ - $(MAKE) modules 2>&1 ) | tee out.kbuild - utils/errcheck out.kbuild - # kernel install, with error checks kinstall: rm -f out.kinstall @@ -311,15 +335,6 @@ fi utils/errcheck out.kinstall -# module-only install, with error checks -minstall: - rm -f out.kinstall - egrep -q '^CONFIG_MODULES=y' $(KCFILE) - egrep -q '^CONFIG_IPSEC=m' $(KCFILE) - ( cd $(KERNELSRC) ; \ - $(MAKE) modules_install 2>&1 ) | tee out.kinstall - utils/errcheck out.kinstall - # backup of (almost) everything an install touches @@ -357,3 +372,9 @@ ctags `find lib pluto klips/utils klips/net/ipsec -name '*.[ch]'` dummy: + +patchclean: + find $(KERNELSRC) -name '*.preipsec' -exec rm {} \; + find $(KERNELSRC) -name '*.wipsec' -exec rm {} \; + find $(KERNELSRC) -name '*.ipsecmd5' -exec rm {} \; + diff -BbruN freeswan-1.91.orig/README.pkix freeswan-1.91/README.pkix --- freeswan-1.91.orig/README.pkix Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/README.pkix Fri Aug 3 11:42:08 2001 @@ -0,0 +1,29 @@ +For those who are impatient, take a look at 'INSTALL.pkix' for quick +instructions to get up and going using FreeSWAN/PKIX. + + +Look in 'doc/pkix' for quick notes I gathered while putting this package +together. Some of these documents will instruct you on how to set up +your own certificate Authority (CA), generate your certificates, sign and +revoke them. Original documentation by Neil Dunbar written for his +pluto_openssl.diff patch for FreeS/WAN 1.1 have been preserved. + +Look in 'doc/pkix/ldap' for quick notes on how to create a basic LDAP +interface to the CA mentioned above. + +Look in 'doc/pkix/examples' for the many examples and test cases I have gone +through during the testing of these acumulated works. + +Some extra manpages were created for the additional commands provided +by this patched FreeS/WAN. Look for 'ipsec_rehashcertdir', 'ipsec_dir2hash' +and most importantly 'ipsec_fswcert'. + + +Last and not least: + .. be aware I readded DES back into FreeSWAN in this package. You can turn +off compile-time options in the root Makefile. Look for 'USE_DES'. + + +-- Luc Lanthier +firesoul@pet.dhs.org +Last updated: 20010803 diff -BbruN freeswan-1.91.orig/doc/README.DES freeswan-1.91/doc/README.DES --- freeswan-1.91.orig/doc/README.DES Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/README.DES Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +Although I agree that DES is too weak for crypto, I don't agree with a +lock-out policy, removing it from FreeSWAN completely (except for what is +needed to run 3DES.) + +I have reinstated it into FreeSWAN. It is active but less prioritive than +3DES during authenticate and connection negotiations. You can force the +use of DES by adding the following to your connection config +(on a per-connection basis) + + force_encrypt_cypher = des + +Available cyphers are: +des, 3des + + +-- Luc Lanthier diff -BbruN freeswan-1.91.orig/doc/pkix/CA-regenerate-flatfile.sh freeswan-1.91/doc/pkix/CA-regenerate-flatfile.sh --- freeswan-1.91.orig/doc/pkix/CA-regenerate-flatfile.sh Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/CA-regenerate-flatfile.sh Mon Jul 16 23:26:30 2001 @@ -0,0 +1,20 @@ +#!/bin/sh +if [ -d /var/lib/ssl ]; then + cd /var/lib/ssl +elif [ -d /usr/lib/ssl ]; then + cd /usr/lib/ssl +elif [ -d /usr/local/lib/ssl ]; then + cd /usr/local/lib/ssl +elif [ -d /usr/share/ssl ]; then + cd /usr/share/ssl +else + echo "ERROR: Cannot determine location of ssl directory." + exit 1 +fi + +for ii in certs/*.pem cacert.pem crl.pem; +do + cat $ii | \ + perl -e '$printme = 0; while (<>) { if (/---BEGIN/) {$printme = 1;}; if ($printme) {print STDOUT $_;} }; print STDOUT "\n";' \ + >> flatfile.txt +done diff -BbruN freeswan-1.91.orig/doc/pkix/README.certificates freeswan-1.91/doc/pkix/README.certificates --- freeswan-1.91.orig/doc/pkix/README.certificates Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/README.certificates Mon Jul 16 23:26:30 2001 @@ -0,0 +1,452 @@ + Readme for certificate setup under FreeS/WAN + + Neil Dunbar + 5th November, 1999 + +The certificate patches are (almost) always against the most recent +snapshots available from +ftp://ftp.xs4all.nl/~freeswan/snapshot.tar.gz. The patches are +available from ftp://hplose.hpl.hp.com/pub/nd/pluto-openssl.tar.gz. + +The patches count on your having OpenSSL-0.9.3 or above installed on +your system. Check out http://www.openssl.org for details on how to +get OpenSSL. NB: the patches will *not* work on OpenSSL-0.9.2 or +below. + +1. Applying the patches + +To apply the patches, cd to the build directory for the snapshot, +which is generally freeswan-snap1999MonthDayb, and untar the +pluto-openssl.tar.gz. + +Then type 'patch -p0 < pluto.diff', followed by 'patch -p0 < +utils.diff'. + +2. Building and Installing FreeS/WAN + +Go to the pluto directory in the snapshot source directory, and edit +the Makefile. Find the line OPENSSLROOT=.... and change the value of +that variable to be the location of where you have installed the +includes and libraries for OpenSSL. By default this is set to +/usr/local/ssl. + +After that, build the system as per the FreeS/WAN installation notes. + +Installation, similarly, is no different to the normal method. + +3. Configuring FreeS/WAN + +In order to allow Pluto to use digital signatures, rather than +preshared secrets to generate key material for IPsec, there are +several options within the connection section of the file +/etc/ipsec.conf which need to be set. + +For examples, we assume the host to host connection as follows + + west === westhop ...... easthop ==== east + +3.1 certfile + +The certfile setting should be set to the full path name of the file +which contains the certificate whose private key will be used to +perform the digital signatures. This file must be set in order for +pluto to send the certificate to the other side, if requested. The +certificate can be in PEM or DER format. + +Example : /etc/ipsec/west.certificate.pem + +3.2 keyfile + +This setting should be set to the full path name to the file which +contains the key which will be used to perform the digital +signature. + +The key file can be stored in several formats, but at the moment, only +unencrypted private keys can be used. If you use an encrypted one, the +key load will fail, and signature/public key modes will cease to be +available. + +The key files can be stored in DER or PEM format, using the OpenSSL +private key format, which is specific to OpenSSL. Alternatively, the +key can be stored in PKCS-8 format, which is system independent. The +problem is that, for the moment, the OpenSSL key generation +applications only store keys in OpenSSL format. To convert a key file +into PKCS-8 form, use the following command (assuming that the file +key.pem stores the OpenSSL private key in PEM format). + +openssl -nocrypt -topk8 -in key.pem -inform PEM -outform DER \ + -out key.pk8 + +(If the original key is in DER format, change '-inform PEM' to +'-inform DER'. Similarly, if you want a PEM PKCS-8 file, change +'-outform DER' to '-outform PEM). + +The key can be either an RSA or DSA key. Note that if an RSA key is +loaded, DSS signature modes will not be offered (or accepted) from the +other side. Similarly, a DSA key will prevent RSA modes from being +selected. + +Example : /etc/ipsec/west.key.pk8 + +3.3 peerfile + +This option is obsolete. It used to specify the path to certificates +used to start public key authentication mode. This function has been +subsumed by the certpath option. + +Do not use peerfile any more. + +3.4 certpath + +This gives a comma separated list of maps (see README.xmap) which can +be used to look up certificates and/or CRLs by specifying their +subject names, issuer names and such like. + +At the moment, the XMAP types are file, dir, db, ldap. + +Example : ldap:/etc/ldap.conf:ldap_ipsec,dir:/etc/ipsec + +(The first item specifies an LDAP directory lookup, whose details are +specified in the file /etc/ldap.conf, and the identifier of which LDAP +lookup to use within that file is 'ldap_ipsec'. The second specifies a +local directory called /etc/ipsec, which should have files and +symbolic links which index the relevant certificates in the +directory). + +For the format of ldap files, and certificate directories, read the +file README.xmap. + +3.5 certopts + +This setting is a comma separated list which gives a set of switches +which control the behaviour of the public key encryption/signatures +within pluto. + +To set an option in the list, one simply includes its name. + +To clear an option in the list, one includes its name, with a '!' +symbol before the name. + +Example : !send,!pkcs7,!pk,strict,dss-sha,dss-alt + +The example means: turn ON the options 'strict', 'dss-sha' and +'dss-alt', but turn OFF the options 'send', 'pkcs7' and 'pk'. + +The options are as follows + +3.5.1 'send' + +Set this option if you want your side of the connection to send its +certificate to the other side as part of the main mode +negotiations. This certificate must be in the set of certificates +which the other side is expecting on this connection. + +3.5.2 'pkcs7' + +***NOT IMPLEMENTED YET*** + +When sending a certificate, if this option is set, a PKCS7 encoding +for the certificate will be chosen. If not set, a standard DER +encoding of the X.509 certificate will be used. + +3.5.3 'pk' + +When choosing between digital signature and public key encryption +ISAKMP methods, this option forces pluto to select public key +encryption. If not set, pluto will choose digital signature methods. + +Note that this option used to be called 'rsa', but this name makes +little sense, since both RSA and El Gamal encryption methods are +selected by this option. + +3.5.3 'rev' + +If using public key encryption for Phase 1 negotiations, this option +makes pluto prefer to use the revised mode method, rather than the +standard public key mode. Revised public key mode uses fewer public +key encryptions and transmits fewer bytes in the protocol (since +public key ciphertexts are much larger than their symmetric key +counterparts). Probably not a bad idea to use this one all the time if +you want ID protection. + +3.5.4 'strict' + +This option forces verification to be very strict on the acceptability +of certificates from the peer. If 'strict' mode is on, the following +conditions must apply to the peer's certificate -- + +1. For every signing certificate in the chain up to the root CA + certificate a valid CRL *must* be present. If a CRL is not + available, or the CRL is not valid (badly signed, expired, etc), + the verification of the certificate will fail. + +2. The name on the certificate must bear some relation to the name of + the peer, as given in the ISAKMP ID field. Assuming that the name + of the peer is an IPv4 address, which is the only supported one, + then the Common Name on the subject of the certificate must start + with the fully qualified domain name of the peer. Failing that, the + subjectAltName extension must contain an entry of type IP, which is + equal to the IP address given as the peer's name, or it must + contain an entry of type DNS, which must be equal to the name of + the resoved FQDN of the IP address given as the peer's name. If any + of these conditions are met, the certificate will be accepted. If + none of these conditions succeed, the verification will fail. + +If strict mode is not set, and these conditions fail, then debugging +warnings will be logged, but verification will succeed. Be warned that +this makes the setup less secure than would strict mode. + +3.5.5 'dss-sha' + +RFC2409 stipulates that the DSS signature method requires the output +of a SHA1 hash to sign and send to the other side. It does not say +whether this hash is a keyed one (eg HMAC) or unkeyed (ie plain SHA1). + +A subsequent document, draft-ietf-ipsec-ike-01.txt, given a formula +for the plain SHA1 output. However, as Tero Kivinen of SSH has pointed +out, most implementations of IKE use the standard HMAC method. + +This option forces pluto to use the plain SHA1 method outlined in the +draft document. Clearing this option forces the HMAC method to be +used. + +3.5.6 'dss-alt' + +RFC2409 stipulates that the encoding of a DSS signature should be 'r +followed by s'. It does not say what format this should take. ANSI +document X9.30 states that DSS output should be the DER encoding of +the ASN.1 construct - + + SEQUENCE { + r INTEGER; + s INTEGER; + }; + +This puts some wrapper bytes around the 160 bit integers r and s, so +that the signature is some 45-48 bytes long (depending on leading +zeros within the integers). + +draft-ietf-ipsec-ike-01.txt states that the signature should be a +single 320 bit string, with r occupying the first 160 bits and s +occupying the next 160, without wrappers, such that all signatures are +exactly 40 bytes long. + +By using the 'dss-alt' option, pluto is forced into the draft document +mode of operation. By clearing it, the X9.30 implementation is used. + +4. Creating the certificates + +This section summarises the far more useful guide within the OpenSSL +documentation, but should serve to generate the certificates and keys +required for a connection. The document assumes that OpenSSL has been +compiled and installed in /usr/local/ssl. Furthermore, it assumes that +that configuration file for OpenSSL is stored in +/usr/local/ssl/lib/openssl.cnf. If this is not the case, all 'openssl +' entries should be replaced by 'openssl -config +/path/to/openssl.cnf'. + +I am heavily indebted to Peter Onion of BT Labs for his efforts to +debug and clarify this documentation. Peter: Your efforts are much +appreciated. + +NB: This isn't the "correct" way to generate certs/CRLs. It's just my +own recipe (largely from memory - it's been a while!) for doing +so. It's not efficient, and you really should read the OpenSSL docs +for better guidance. + +4.1 Edit openssl.cnf + +Ensure that the following settings for the CA_default section are more +or less as follows - + +dir = /usr/local/ssl +certs = $dir/certs +crl_dir = $dir/crl +database = $dir/index.txt +new_certs_dir = $dir/newcerts + +certificate = $dir/cacert.pem +serial = $dir/serial +crl = $dir/crl.pem +private_key = $dir/private/cakey.pem +RANDFILE = $dir/private/.rand + +Fill in the default fields (country, organization, etc) as seems right +for your setup. + +Create a file ca.ext containing the following - + +----------------------------------- +# Extensions for a typical CA - PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer:always +basicConstraints = CA:true +keyUsage = cRLSign, keyCertSign +nsCertType = sslCA, emailCA +subjectAltName=email:copy +---------------------------------- + +4.2 Make the CA certificate + +Go to the directory /usr/local/ssl + +Generate your CA cert by the usual method + +openssl req -new -newkey rsa:1024 \ + -keyout /usr/local/ssl/private/cakey.pem \ + -out careq.pem + +Now sign the CA cert, citing the extensions for [v3_ca] + +openssl x509 -CAcreateserial -signkey private/cakey.pem -req \ + -in careq.pem -out cacert.pem -days 2000 -extfile ca.ext + +This creates the self signed certificate which can be used to sign +further certificates. Ensure that this cacert.pem file is made widely +available to all hosts which will communicate via IPsec. + +4.3 Make an empty certificate database + +Execute the following commands, whilst in the directory /usr/local/ssl + +touch index.txt + +echo "01" > serial + +This creates the database, and starts issued certificates with the +serial number starting at 1. + +4.4 Generate a CRL + +Use the command + +openssl ca -gencrl -out crl.pem + +to generate an (initially empty) CRL. You should always have a +current CRL, even if nothing has been revoked, since that proves +*actively* that no certificates have been cancelled. Without a CRL, +you are forced into the assumption that no certificates have been +revoked. + +The CRL is placed in /usr/local/ssl/crl.pem. Distribute this file to +all hosts holding the cacert.pem file. (Or, if you have an LDAP +directory handy, publish the CRL there, so that all hosts can contact +it). + +4.5 Generate the host certificate requests. + +On each host, generate a key and certificate request with the +following command (I'll assume that ipsec certificates are in the +directory /etc/ipsec, which must exist beforehand). + +I'll assume that the host is called foo, and lives in .mydomain.com, +and has IP address aa.bb.cc.dd. + +openssl req -new -newkey rsa:1024 \ + -nodes -keyout /etc/ipsec/foo.key -out foo.req.pem + +Fill in the fields for the subject name, and ensure that the common +name section is set to 'foo.mydomain.com IPsec certificate #1', or +some such thing - either way, it should start with foo.mydomain.com. + +See section 3.2 (keyfile) on converting private key files to the +standard PKCS-8 format (which pluto can also understand). If you do +this, you can delete the original private key file 'foo.key', once you +have a PKCS-8 equivalent of it. + +Change the file permissions on foo.key to be 400 - Owner read only, +and change to owner to be root. + +Transport the file foo.req.pem to the host which will sign certificate +requests. This should be done via some secure method of +transmission. In an ideal setup, your CA host shouldn't be connected +to any network at all - but that's a site specific decision) + +4.6 Sign the certificate requests. + +On the CA host, edit the openssl.cnf file such that there is a section +[svr_cert] at the bottom of the file with the following contents. + +[ svr_cert ] +basicConstraints=CA:FALSE +nsCertType = server +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +nsComment = $ENV::NSCOMMENT +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always +subjectAltName=email:copy,DNS:$ENV::HOSTFQDN,IP:$ENV::HOSTIP +issuerAltName=issuer:copy + +If this is not already done, alter the x509_extensions in the +[CA_default] section such that it looks like - + +x509_extensions = $ENV::EXTENSION + +Now sign the request with the wrapper script 'signIPSEC', which +is produced below. The script was written by Peter Onion. + +-----------------8<-------CUT HERE------8<---------------------------- +#! /bin/bash + +# Simple wrapper for "openssl ca" that sets environment to pass in +# values for the svr_cert extension +# P.J.Onion 23/9/1999 + +if test $# -ne 3 ; then + echo "Usage: signIPSEC hostname ipaddress reqfile" + exit 1 +fi + + +HOSTFQDN=$1 +HOSTIP=$2 +NSCOMMENT="IPsec Certificate for $1" +EXTENSION=svr_cert + +export HOSTFQDN HOSTIP NSCOMMENT EXTENSION +# Change /usr/local/ssl to be the directory in which OpenSSL +# is installed. + +/usr/local/ssl/bin/openssl ca -in $3 + +-----------8<----------CUT TO HERE --------8<------------------------- + + +In the case above, you would do + +signIPSEC foo.mydomain.com 192.168.1.5 foo.req + +(assuming that foo.mydomain.com has the IP address 192.168.1.5, and +that foo.req contains the PEM certificate request). + +Check the details that it prints, and commit the new certificate to +the database. The new certificate will be in the directory +/usr/local/ssl/newcerts. Tranport this file back to the requesting +host and place it in the file /etc/ipsec/foo.pem. You can delete the +file foo.req.pem now. + +Once the certificate has been delivered, move the file from newcerts +into certs and run the command + +c_rehash /usr/local/ssl/certs + +to create the hashed directory. + +4.7 Renewing a certificate + +When you want to replace a certificate stored in file foo.pem, issue +the command + +openssl ca -revoke foo.pem + +This changes the database to reflect the fact that the certificate has +been cancelled, but does not update the CRL. Do that with the +instructions in section 4.4. Make sure that the new CRL is propagated +to all participating hosts. + +Now create the key/request/certificate as per sections 4.5 onwards. + + ******************* End of document ******************** + diff -BbruN freeswan-1.91.orig/doc/pkix/README.certopts freeswan-1.91/doc/pkix/README.certopts --- freeswan-1.91.orig/doc/pkix/README.certopts Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/README.certopts Mon Jul 16 23:26:30 2001 @@ -0,0 +1,22 @@ +The current options available within this PKIX package are: + +send -> If using RSASIG or RPKE, send your certificate to the peer. + This option is usually optional. + +pk -> Use PKE authentication + +pk,rev -> Use RPKE authentication + +strict -> Strict authenticate. There _must_ be a CRL available, and it + must be valid. + +I recommend always sending the optional certificate to the peer, as well +as using "strict" at all times to make sure the connection is truly +fully authenticated. + certopts=send,strict,pk,rev + +For more information on these certopts options, please refer to Neil Dunbar's +README.certificates document. + +-- Luc Lanthier +luc.lanthier@rebel.com diff -BbruN freeswan-1.91.orig/doc/pkix/README.pkcs freeswan-1.91/doc/pkix/README.pkcs --- freeswan-1.91.orig/doc/pkix/README.pkcs Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/README.pkcs Sat Jul 21 21:03:33 2001 @@ -0,0 +1,11 @@ +Support for a passphrase to decrypt PKCS8 or PKCS12 data has been added. To +use it, add a PKCS section to /etc/ipsec.secrets much like the following: + +: PKCS8 { passphrase: "ipsecsecret" } + +PKCS12 uses PKCS8 methods, thus why I chose to use PKCS8 as the keyphrase. +Much like with RSA, you can put in some ID data (like an IP, or a copy of +the ID_DER_ASN1_DN) to narrow when to use this passphrase. + +-- Luc +Last Update: 20010721 diff -BbruN freeswan-1.91.orig/doc/pkix/README.xmap freeswan-1.91/doc/pkix/README.xmap --- freeswan-1.91.orig/doc/pkix/README.xmap Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/README.xmap Mon Jul 16 23:26:30 2001 @@ -0,0 +1,398 @@ + README.xmap + + Neil Dunbar + 21st October, 1999 + +1. Introduction + +As of the October release of the pluto-openssl patches, the +certificate paths parameter has been replaced by a list of +XMAPs. XMAPs are an abstraction of a dictionary lookup, which are +designed to look up public key information. This includes X.509 +certificates, X.509 certificate revocation lists, and, in theory, +simple public key values (NB: raw public keys are not supported yet). + +An XMAP is similar to the X509_LOOKUP system employed within OpenSSL +to specify file and directory lookup. Indeed, XMAP has two mechanisms +for lookup via file and directory, as well as others. + +The specification for an XMAP consists of a text string of the format +:
. The type denotes the sort of search which the XMAP +library will carry out, and the details give appropriate parameter +information so that the search can execute. As an example, a file XMAP +on the file /etc/ipsec/certs.txt would have the form +"file:/etc/ipsec/certs.txt". + +2. XMAP lookup + +(Programmer stuff - ignore if not interested) + +A lookup is a search which is identified by three parameters: the type +of the thing being looked for, the search identifier and a search +parameter (which is governed by the search identifier). + +The result of the search is a list (actually an OpenSSL STACK) of type +X509_OBJECT (all of which fit the search criteria specified, sorted to +be age order [most recent first, oldest last]. The type X509_OBJECT is +defined in the OpenSSL header file x509_vfy.h. Note: this is NOT the +same as the file X509_OBJECTS defined in x509.h. The C type +declaration is reproduced here. + +typedef struct x509_object_st { + /* one of the above types */ + int type; + union { + char *ptr; + X509 *x509; + X509_CRL *crl; + EVP_PKEY *pkey; + } data; +} X509_OBJECT; + +Thus, if an X.509 certificate is stored in such an object, the type +field will be set to X509_LU_X509, and .data.x509 holds a +pointer to the actual certificate data. + +Thus, to iterate through all certificates returned in a search, a C +program fragment would look like the following. + +XMAP *xmap; +int i; +STACK_OF(X509_OBJECT) *sk; +X509_OBJECT *obj; +X509 *x; + : + : +sk = XMAP_lookup(xmap, X509_LU_X509, , ); +for (i=0; idata.x509; + + /* Operations on the certificate 'x' */ +} + +3. XMAP Search types + +The various search types are detailed in the following sections. The +list of items are sorted (if possible) in date descending order, ie +the most recent object is first in the return list, and the oldest +object comes last. All duplicates are removed from the return list. + +3.1 "subject" (returns X.509 cert) + +The search looks for a certificate whose name is the the same as the +X.509 name given in the parameter to the search. + +3.2 "issuer" (returns X.509 CRL) + +The search looks for a certificate revocation list (CRL) whose issuer +is the same as the X.509 given as a search parameter. + +3.3 "uid" (returns X.509 cert) + +The search looks for the certificates which are listed as belonging to +the user whose ID is given by the null terminated character string +given as the search parameter. + +3.4 "dns" (returns X.509 cert) + +The search returns a list of the certificates which are listed as +belonging to the fully qualified domain name (FQDN) as given in the +search parameter, which is a null terminated character string. + +NB: Any certificate MUST have a subjectAltName which includes a DNS +entry which is the same as the search string. This requirement is in +addition to any indexing which is required for the individual XMAP +search type. + +3.5 "ip" (returns X.509 cert) + +The search returns a list of the certificates which are listed as +belonging to the IPv4 address given as a search parameter. The search +parameter is a 4 octet string, which gives the IP address in network +order; for example the ip address 15.144.59.30 would have the search +parameter (in hex) 0F903B1E. + +As with DNS indexed certificates, the certificates must contain a +subjectAltName with the correct IP entry within it. + +3.6 "ca" (returns X.509 cert) + +This search returns all CA certificates indexed in the list. A CA +certificate is one which has a basicConstraints extension with the CA +flag set to true. Also the CA has the subjectName and issuerName set +to be the same. + +There is no search parameter for this search. It should be set to NULL +in the XMAP_lookup() call. + +4. XMAP Types + +There are currently four types of XMAP: File, Directory, Berkeley DB +and LDAP. Respectively, their type specifiers are "file", "dir", "db" +and "ldap". Each subsection will detail the exact representation and +expectations of the XMAP. + +4.1 File + +Type Specifier: "file" +Syntax: file: + +This implements a simple flat file structure for lookups. The file can +contain as many certificates in PEM format as desired. In order to +index them, certain fields should be prepended to the certificates. + +For example a file might look like this. + +-----BEGIN CERTIFICATE----- +MIIEHzCCAwegAwIBAgIBADANBgkqhkiG9w0BAQQFADCBpzELMAkGA1UEBhMCR0Ix +HQ0Qb72dPlXYO20xtdMR9fX92PfSQSgAulNITYzusd8KE6yvJ8+HEbUuwXLHXZh4 + : + : + : +pk/Bv8iFUiZhH8EAr6SvF0AkpULi46bVcoQlr36Ax59uQ8OcJeNmljKYdbrN5uFL +62In +-----END CERTIFICATE----- + +uid: nd +-----BEGIN CERTIFICATE----- +MIIETDCCA7WgAwIBAgIQE9hfeRmSr51Wzgvm4B19JjANBgkqhkiG9w0BAQQFADCB +njEPMA0GA1UEChMGaHAuY29tMRowGAYDVQQLExFJVCBJbmZyYXN0cnVjdHVyZTEL + : + : + : +6pZk+pEpZ5S55lFP1QspTsBVbrBgsEuGFyGpHTo9sIEaQYxfRGNEvW+ZaEPU1HKo +YVkAahuv5T21GdvouWdelA6l6uWMK/hfsQo9PdpBLDaUrwH5lkDuXcNk+LHZvVDt +-----END CERTIFICATE----- + +-----BEGIN X509 CRL----- +MIICLTCCARUwDQYJKoZIhvcNAQEEBQAwgacxCzAJBgNVBAYTAkdCMR4wHAYDVQQI +ExVTb3V0aCBHbG91Y2VzdGVyc2hpcmUxEDAOBgNVBAcTB0JyaXN0b2wxJTAjBgNV + : + : + : +++lOGcX1WTtZ2dnV6Lb5r5xQ3IGavf2TKnu1/nCyAKFlF34+j7/+fIxT4iQiEDjk +Z8Q76UEWVRMw7Tk63aAf0Yf5qaI1Tpd+SKhSTgc4arJH +-----END X509 CRL----- + +ip: 15.144.59.30 +dns: pinky.hpl.hp.com +-----BEGIN CERTIFICATE----- +MIIHgTCCBmmgAwIBAgIBCjANBgkqhkiG9w0BAQQFADCBpzELMAkGA1UEBhMCR0Ix +HjAcBgNVBAgTFVNvdXRoIEdsb3VjZXN0ZXJzaGlyZTEQMA4GA1UEBxMHQnJpc3Rv + : + : + : +KkW/kYOxRrmg9KGnSVOolD1ueLYg9D4CtY30r1JGE/wixmIvQEP8JEv+X6Cr4Wiu +VfENrF8= +-----END CERTIFICATE----- + +This example indexes the fourth certificate as belonging to the IP +address 15.144.59.30, as well as the DNS name "pinky.hpl.hp.com". The +second certificate belongs to the user ID "nd". + +The file also contains a CRL embedded within it. + +Note: indexed searches in files are done by simple linear search. It's +not an efficient means for searching serious amounts of data - use the +other types for anything other than trivial data. + + +4.2 Directory + +Type Specifier: "dir" +Syntax: dir: + +The directory type is a derivation of the hashed directory used in the +OpenSSL applications. The certificates are stored within a single +level directory. Each certificate (or CRL) is stored in exactly one +file in the directory. These files can be in either DER or PEM format, +unlike the flat file above. To index the files for subject and issuer +searches, you need to make a symbolic link from a hashed +representation of the X.509 name of the certificate subject name (or +CRL issuer name). + +To do this, you should execute the command - + +[for certificate files -- all on one line] + +ln -s certificate.pem + `openssl x509 -noout -hash -in certificate.pem`.cert.0 + +NB: The .0 on the end is an arbitrary extension to the link name in +case there might be a hash clash in the directory. You can call it +anythin you like, but the ".cert" extension MUST be present -- unlike +standard OpenSSL hash directories. + +[ for CRL files ] +ln -s crl.pem + `openssl crl -noout -hash -in certificate.pem`.crl.0 + +Again, the .0 is a differentiating extension, but the ".crl" is +mandatory for marking out certificates. + +To index other attributes, you should make links which have the +following appearance - + +uid-.cert.0 [ denotes a user file ] +dns-.cert.0 [ a DNS indexed cert ] +ip-.cert.0 [ an IP indexed cert ] + +For example, assume that file pinky.pem held the certificate for DNS +pinky.hpl.hp.com and/or IP address 15.144.59.30, the links would look +like - + +dns-pinky.hpl.hp.com.cert.0 )__________\. pinky.pem +ip-15.144.59.30.cert.0 ) / + +CA certificates don't need to be indexed. CA searches are performed by +loading every certificate file in the directory and checking for a CA +certificate, so it's failrly slow for this type of search. + +What Directories *are* good for is converting into a Berkeley DB file +database - which is the fastest of all searches. + +-- ADDENDUM -- 20001016, Luc Lanthier + +I've created a short and ugly shell script 'rehashcertdir' which will +do this work for you. Usage: + + ipsec rehashcertdir + + + +3.3 - Berkeley DB searches + +Type Specifier: "db" +Syntax: db: + +Assuming you have a Berkeley DB 1.85 library available on your system, +you can index the certificates/CRLs in a DB hash file, which provides +the fastest lookup of any of the methods. + +The internal details of the DB file are maintained in a separate file +(README.XMAP.DB -- to be written -- nd). To make a DB file, you should +create a directory as in the above section, then run the utility +command "dir2hash" as follows, assuming that the directory to be +hashed is called "my_dir" and the output DB file should be called +certs.db :- + + ipsec dir2hash -o dbhash.db my_dir + +Note: You don't have to make the hashed, DNS or IP links as in the +directory above (they are automatically figured out by the dir2hash +program from the subjectNames and subjectAltNames of the +certificates/CRLs). You DO have to index the uid entries manually, +since the certificates don't necessarily have the means of +indentifying which users they belong to. + +Note that IPsec knows nothing of uid's and doesn;t use them yet, so a +perfectly valid IPsec DB file can be mafe by putting all the +certificates into a directory without any links at all, then running +dir2hash on the directory. + +However, this still creates a single file which must be copied to all +hosts participating in the IPsec process. Therefore, this mechanism +will not scale past a few, easily managed hosts. For scalability you +should use LDAP. + +3.4 - LDAP searches + +Type Specifier: "ldap" +Syntax: ldap:: + +Assuming that you have at least one LDAP server available on your +network, you can make a config file (which is NOT the same as +ipsec.conf) to specify how to search for entries in one or more LDAP +servers. A single ldap configuration file can hold search details for +many ldap servers. Each server specification must be identified by a +unique ldap ID. This ID can be any alphanumeric string. If the LDAP +identifier is omitted, then the first specification in the file will +be used by default. + +The entries in the configuration file can be of the following form: + +_host_name: + +_port: + +_base: + +_timeout: + +_bindDN: + +_bindPW: + +Note that you MUST supply a base search string: the software cannot +guess a reasonable default. Also, the bind DN and password is the only +supported authentication mechanism. PLEASE don't put the LDAP server +on a host which needs to reached via IPsec. If you're relying on it to +serve all certificates, the LDAP connection won't work (since the +IPsec connection might not be up yet). + +For each search type, you must specify the filter string and +attributes which should be searched for from the LDAP directory. + +The filter string specification has the form + +_filter::: + +where is either "uid", "subject", "issuer", "dns" or +"ip" as above, and is either "cert" (for X.509 +certificates) or "crl" for CRL searches. Either the or + can be set to "*", which is a wildcard, meaning any +index or any return type. + +Similarly, the attribute specification looks like: + +_attributes::: + +The and are as above, with the list of +attributes a comma separated list of attributes. + +For an example, let us use the following file + +ldapnd_host_name = ldap.hpl.hp.com +ldapnd_base = o=Hewlett-Packard Laboratories, c=GB +ldapnd_filter:uid = (uid=%s) + +ldapnd_attributes:*:crl = certificaterevocationlist, certificaterevocationlist;binary + +ldapnd_filter:*:crl = (&(objectclass=certificationAuthority)(cn=%s)) + +ldapnd_filter:ca = (objectclass=certificationauthority) + +ldapnd_filter:dns = (&(objectclass=hostRecord)(dNSRecord=%s)) +ldapnd_attributes:dns = servercertificate, servercertificate;binary + +ldapnd_filter:ip = (&(objectclass=hostRecord)(ipv4Address=%s)) +ldapnd_attributes:ip = servercertificate, servercertificate;binary + +This stipulates an anonymous bind search of the LDAP server on +ldap.hpl.hp.com port 389 (the default), whose base for searches is +"o=Hewlett-Packard Laboratories,c=GB". + +For DNS searches, the filter used will be + +"(&(objectClass=hostRecord)(dNSRecord=%s))" + +where "%s" will be replaced by the DNS name being searched for. In the +case of a search for pinky.hpl.hp.com, the search string will be - + +"(&(objectClass=hostRecord)(dNSRecord=pinky.hpl.hp.com))" + +For IP address searches, the filter used will be + +"(&(objectclass=hostRecord)(ipv4Address=%s))" + +Again, searching for the host with IP address 15.144.59.30, the host +search filter will be - + +"(&(objectclass=hostRecord)(ipv4Address=15.144.59.30))" + +In both DNS and IP searches, the search will return the attributes +"serverCertificate" and "serverCertificate;binary". + +Note that the return type is missing from many of the +specifications. Return types default to "cert". diff -BbruN freeswan-1.91.orig/doc/pkix/examples/arm-devel.key freeswan-1.91/doc/pkix/examples/arm-devel.key --- freeswan-1.91.orig/doc/pkix/examples/arm-devel.key Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/arm-devel.key Mon Jul 16 23:26:30 2001 @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQCoqQwsIfybAtb0mMfD3NGNMZH7ckGrCehSm741ddjw9rW6igzZ +AptaqQ2Y5raPl0XrF+MQI8SQkfTtzP92/ZU9eqbEWbBFRfYLqckMd21eU9GHDVl5 +UPmUwWSOXuE4lK58f2heEFE975yf9CsIvOuas33FsiuYtO5UEmzapAVAnQIDAQAB +AoGAXUzWvPs4IBAcFUcHCyR2j6LiXLTB+voKGNirCivdDL+NnFmN7eZxRl/Kc9D9 +IMXQGdMm+uCudkMnuPz0PUDeczQST46jiTlG5vkQdj3zpmz/x73t5I4E8vFSX6A4 +gKREFeGxSCEm0THNusBKk1Q+huHUDKw4mFh85MTopy32McECQQDVWcc3BMlDICG2 +6bFc3+1ieeVIKoD2GnJR7b/GU57umLFyDmSFwOkTTt7VWp3jV/81Oy+xBe3cC8Fm +mFC/e45VAkEAymA9ke8XFduafs2Q+nsbfx4QI+f8lAd51pBR4A4J+W50JLO1/WqC +PwOXwVPRCPyzHiY9B8L9KPrFKSwVedihKQJBAKnGCl/+wAVZcVqztf649pbRdyGp +KPwt6WDGtz+j1Sn6eeHQEC/bZd2Geo3+0PtTT/NVCMtuc2wSMrFobYEiWg0CQQCl +lf9qw5049jlAHYTNXiNObFO6fVuN51wKcoV7dSE2JOkFCsISuq4dTxxBRApadyE7 +vv/atPGdMSpXGMntq5GZAkEA1PJ0w4WSC3sW3guq4WzDLWqmbK2pOvC40ATZR67y +lYC1okanKDsRam0remPY7xWZ8WACJx5KOIvYgXhX+dNXPg== +-----END RSA PRIVATE KEY----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/arm-devel.pem freeswan-1.91/doc/pkix/examples/arm-devel.pem --- freeswan-1.91.orig/doc/pkix/examples/arm-devel.pem Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/arm-devel.pem Mon Jul 16 23:26:30 2001 @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=CA, ST=Ontario, L=Ottawa, O=Rebel.com, OU=SoftEng, CN=CA_arm-devel/Email=luc.lanthier@rebel.com + Validity + Not Before: Feb 14 20:59:13 2001 GMT + Not After : Feb 14 20:59:13 2002 GMT + Subject: C=CA, ST=Ontario, O=Rebel.com, OU=SoftEng, CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:a8:a9:0c:2c:21:fc:9b:02:d6:f4:98:c7:c3:dc: + d1:8d:31:91:fb:72:41:ab:09:e8:52:9b:be:35:75: + d8:f0:f6:b5:ba:8a:0c:d9:02:9b:5a:a9:0d:98:e6: + b6:8f:97:45:eb:17:e3:10:23:c4:90:91:f4:ed:cc: + ff:76:fd:95:3d:7a:a6:c4:59:b0:45:45:f6:0b:a9: + c9:0c:77:6d:5e:53:d1:87:0d:59:79:50:f9:94:c1: + 64:8e:5e:e1:38:94:ae:7c:7f:68:5e:10:51:3d:ef: + 9c:9f:f4:2b:08:bc:eb:9a:b3:7d:c5:b2:2b:98:b4: + ee:54:12:6c:da:a4:05:40:9d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + IPsec Certificate for arm-devel.netwinder.org + X509v3 Subject Key Identifier: + 98:76:ED:A5:41:7C:28:3C:C8:63:0F:09:F7:DE:9E:B2:00:B6:36:FE + X509v3 Authority Key Identifier: + keyid:7A:38:75:E9:B9:94:AB:B6:00:C5:36:81:EA:A5:60:3E:FA:FE:E4:E1 + DirName:/C=CA/ST=Ontario/L=Ottawa/O=Rebel.com/OU=SoftEng/CN=CA_arm-devel/Email=luc.lanthier@rebel.com + serial:00 + + X509v3 Subject Alternative Name: + email:luc.lanthier@rebel.com, DNS:arm-devel.netwinder.org, IP Address:10.8.49.122 + X509v3 Issuer Alternative Name: + email:luc.lanthier@rebel.com + Signature Algorithm: md5WithRSAEncryption + bb:a9:1a:f4:e3:55:c8:f6:e7:d6:32:cb:a2:2f:6d:58:a3:5d: + 8f:5a:0d:95:53:c7:bf:06:e7:3b:ca:99:48:99:2f:55:28:5a: + 9e:37:ef:3b:44:73:1e:e0:61:93:43:f8:04:6b:06:1e:68:e5: + 3e:a2:10:53:94:2f:66:76:fc:66:93:d4:5e:76:cf:2d:18:e2: + ff:eb:c0:77:c9:d5:4d:00:60:34:50:59:69:b9:7d:07:fb:ca: + 8b:6e:ee:5c:d2:d9:06:2f:ee:df:d8:09:12:76:bc:b5:17:80: + a8:d6:a7:25:59:5c:b4:65:cb:29:b1:cd:77:29:e9:c4:03:00: + ea:c4 +-----BEGIN CERTIFICATE----- +MIIEUTCCA7qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjA1OTEzWhcNMDIwMjE0MjA1OTEzWjCBjjELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEg +MB4GA1UEAxMXYXJtLWRldmVsLm5ldHdpbmRlci5vcmcxJTAjBgkqhkiG9w0BCQEW +Fmx1Yy5sYW50aGllckByZWJlbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +AoGBAKipDCwh/JsC1vSYx8Pc0Y0xkftyQasJ6FKbvjV12PD2tbqKDNkCm1qpDZjm +to+XResX4xAjxJCR9O3M/3b9lT16psRZsEVF9gupyQx3bV5T0YcNWXlQ+ZTBZI5e +4TiUrnx/aF4QUT3vnJ/0Kwi865qzfcWyK5i07lQSbNqkBUCdAgMBAAGjggG1MIIB +sTAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwPAYJ +YIZIAYb4QgENBC8WLUlQc2VjIENlcnRpZmljYXRlIGZvciBhcm0tZGV2ZWwubmV0 +d2luZGVyLm9yZzAdBgNVHQ4EFgQUmHbtpUF8KDzIYw8J996esgC2Nv4wgcEGA1Ud +IwSBuTCBtoAUejh16bmUq7YAxTaB6qVgPvr+5OGhgZqkgZcwgZQxCzAJBgNVBAYT +AkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoT +CVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEVMBMGA1UEAxQMQ0FfYXJtLWRl +dmVsMSUwIwYJKoZIhvcNAQkBFhZsdWMubGFudGhpZXJAcmViZWwuY29tggEAMEAG +A1UdEQQ5MDeBFmx1Yy5sYW50aGllckByZWJlbC5jb22CF2FybS1kZXZlbC5uZXR3 +aW5kZXIub3JnhwQKCDF6MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5j +b20wDQYJKoZIhvcNAQEEBQADgYEAu6ka9ONVyPbn1jLLoi9tWKNdj1oNlVPHvwbn +O8qZSJkvVShanjfvO0RzHuBhk0P4BGsGHmjlPqIQU5QvZnb8ZpPUXnbPLRji/+vA +d8nVTQBgNFBZabl9B/vKi27uXNLZBi/u39gJEna8tReAqNanJVlctGXLKbHNdynp +xAMA6sQ= +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/arm-devel.req.pem freeswan-1.91/doc/pkix/examples/arm-devel.req.pem --- freeswan-1.91.orig/doc/pkix/examples/arm-devel.req.pem Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/arm-devel.req.pem Mon Jul 16 23:26:30 2001 @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIB4DCCAUkCAQAwgZ8xCzAJBgNVBAYTAkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8w +DQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29m +dEVuZzEgMB4GA1UEAxMXYXJtLWRldmVsLm5ldHdpbmRlci5vcmcxJTAjBgkqhkiG +9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD +gY0AMIGJAoGBAKipDCwh/JsC1vSYx8Pc0Y0xkftyQasJ6FKbvjV12PD2tbqKDNkC +m1qpDZjmto+XResX4xAjxJCR9O3M/3b9lT16psRZsEVF9gupyQx3bV5T0YcNWXlQ ++ZTBZI5e4TiUrnx/aF4QUT3vnJ/0Kwi865qzfcWyK5i07lQSbNqkBUCdAgMBAAGg +ADANBgkqhkiG9w0BAQQFAAOBgQCNEgKfb3Qwtk7rgHcLiUCcXA4w4XFyHxRA8GEO +N/sJVOFq6mV2wVHEmhYalMQTXs3KXNucppQ3ZtHhiLCxzuHSe1Cs6q3iBXPaOPsY +L6I2gJ/wQ49E11HYtMSzDjcAbxV3zWWd42Xk8mNNrhT2r1h+g30DQEgFjXkXhbpt +1R+0uA== +-----END CERTIFICATE REQUEST----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/db-pk-rw.conf freeswan-1.91/doc/pkix/examples/db-pk-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/db-pk-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/db-pk-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=db:/etc/ipsec/dir_dbhash.db + certopts=send,strict,pk + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/db-pk.conf freeswan-1.91/doc/pkix/examples/db-pk.conf --- freeswan-1.91.orig/doc/pkix/examples/db-pk.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/db-pk.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=db:/etc/ipsec/dir_dbhash.db + certopts=send,strict,pk + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/db-rpk-rw.conf freeswan-1.91/doc/pkix/examples/db-rpk-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/db-rpk-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/db-rpk-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=db:/etc/ipsec/dir_dbhash.db + certopts=send,strict,pk,rev + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/db-rpk.conf freeswan-1.91/doc/pkix/examples/db-rpk.conf --- freeswan-1.91.orig/doc/pkix/examples/db-rpk.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/db-rpk.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=db:/etc/ipsec/dir_dbhash.db + certopts=send,strict,pk,rev + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/db-rsasig-rw.conf freeswan-1.91/doc/pkix/examples/db-rsasig-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/db-rsasig-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/db-rsasig-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=db:/etc/ipsec/dir_dbhash.db + certopts=send + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/db-rsasig.conf freeswan-1.91/doc/pkix/examples/db-rsasig.conf --- freeswan-1.91.orig/doc/pkix/examples/db-rsasig.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/db-rsasig.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=db:/etc/ipsec/dir_dbhash.db + certopts=send + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/60601ae4.cert.0 freeswan-1.91/doc/pkix/examples/dir/60601ae4.cert.0 --- freeswan-1.91.orig/doc/pkix/examples/dir/60601ae4.cert.0 Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/60601ae4.cert.0 Mon Jul 16 23:26:30 2001 @@ -0,0 +1,78 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=CA, ST=Ontario, L=Ottawa, O=Rebel.com, OU=SoftEng, CN=CA_arm-devel/Email=luc.lanthier@rebel.com + Validity + Not Before: Feb 14 21:00:11 2001 GMT + Not After : Feb 14 21:00:11 2002 GMT + Subject: C=CA, ST=Ontario, O=Rebel.com, OU=SoftEng, CN=arm1.netwinder.org/Email=firesoul@netwinder.org + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:e2:2b:ad:70:6b:29:e7:83:be:af:12:50:4b:a4: + 26:02:60:ed:f9:bd:49:51:86:96:18:9c:10:f1:0c: + 7d:bd:b9:22:8e:66:6a:f4:96:e5:8d:e2:c4:11:1e: + 64:8e:59:1e:b1:a2:64:15:fa:a6:17:9a:59:f3:9f: + 9f:c8:c9:17:b8:a7:87:55:70:8f:de:25:78:e6:e0: + 4c:82:ae:f1:47:14:77:fa:5b:3e:4d:e5:05:5e:31: + 09:62:56:f8:3b:94:51:b2:e3:7e:bb:8f:6e:dc:ea: + 64:2e:2f:65:8e:41:18:0e:cf:9d:8a:b8:0a:86:6c: + 6a:88:be:58:ce:be:b3:32:c1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + IPsec Certificate for arm1.netwinder.org + X509v3 Subject Key Identifier: + 82:A2:6E:58:0D:B6:98:EF:D9:A0:68:9D:D0:C0:70:59:B3:6A:32:99 + X509v3 Authority Key Identifier: + keyid:7A:38:75:E9:B9:94:AB:B6:00:C5:36:81:EA:A5:60:3E:FA:FE:E4:E1 + DirName:/C=CA/ST=Ontario/L=Ottawa/O=Rebel.com/OU=SoftEng/CN=CA_arm-devel/Email=luc.lanthier@rebel.com + serial:00 + + X509v3 Subject Alternative Name: + email:firesoul@netwinder.org, DNS:arm1.netwinder.org, IP Address:10.1.49.124 + X509v3 Issuer Alternative Name: + email:luc.lanthier@rebel.com + Signature Algorithm: md5WithRSAEncryption + c3:68:19:5f:60:12:18:6f:48:87:f9:97:d2:a3:0f:bc:e4:d0: + 59:37:69:17:28:32:55:7d:5c:7a:35:ff:e1:67:05:f5:31:80: + 27:cc:3a:37:28:47:46:ec:d9:b0:f9:69:ac:ce:6d:89:94:19: + 16:38:64:bb:da:67:68:c5:e3:26:e3:66:98:b2:45:bf:0d:16: + 2b:95:0c:1a:cc:65:8c:c5:f4:ba:2f:2b:5a:f4:ad:9a:71:92: + de:e5:77:c4:08:96:7c:c3:25:25:fe:43:b0:f3:f9:65:1f:fa: + 6c:2d:2e:e2:1f:18:75:03:51:33:94:61:29:59:1a:9c:7c:71: + 42:e1 +-----BEGIN CERTIFICATE----- +MIIEQjCCA6ugAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjEwMDExWhcNMDIwMjE0MjEwMDExWjCBiTELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEb +MBkGA1UEAxMSYXJtMS5uZXR3aW5kZXIub3JnMSUwIwYJKoZIhvcNAQkBFhZmaXJl +c291bEBuZXR3aW5kZXIub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDi +K61waynng76vElBLpCYCYO35vUlRhpYYnBDxDH29uSKOZmr0luWN4sQRHmSOWR6x +omQV+qYXmlnzn5/IyRe4p4dVcI/eJXjm4EyCrvFHFHf6Wz5N5QVeMQliVvg7lFGy +4367j27c6mQuL2WOQRgOz52KuAqGbGqIvljOvrMywQIDAQABo4IBqzCCAacwCQYD +VR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwCwYDVR0PBAQDAgXgMDcGCWCGSAGG ++EIBDQQqFihJUHNlYyBDZXJ0aWZpY2F0ZSBmb3IgYXJtMS5uZXR3aW5kZXIub3Jn +MB0GA1UdDgQWBBSCom5YDbaY79mgaJ3QwHBZs2oymTCBwQYDVR0jBIG5MIG2gBR6 +OHXpuZSrtgDFNoHqpWA++v7k4aGBmqSBlzCBlDELMAkGA1UEBhMCQ0ExEDAOBgNV +BAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmViZWwuY29t +MRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwxJTAjBgkq +hkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb22CAQAwOwYDVR0RBDQwMoEW +ZmlyZXNvdWxAbmV0d2luZGVyLm9yZ4ISYXJtMS5uZXR3aW5kZXIub3JnhwQKATF8 +MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5jb20wDQYJKoZIhvcNAQEE +BQADgYEAw2gZX2ASGG9Ih/mX0qMPvOTQWTdpFygyVX1cejX/4WcF9TGAJ8w6NyhH +RuzZsPlprM5tiZQZFjhku9pnaMXjJuNmmLJFvw0WK5UMGsxljMX0ui8rWvStmnGS +3uV3xAiWfMMlJf5DsPP5ZR/6bC0u4h8YdQNRM5RhKVkanHxxQuE= +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/arm-devel.pem freeswan-1.91/doc/pkix/examples/dir/arm-devel.pem --- freeswan-1.91.orig/doc/pkix/examples/dir/arm-devel.pem Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/arm-devel.pem Mon Jul 16 23:26:30 2001 @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=CA, ST=Ontario, L=Ottawa, O=Rebel.com, OU=SoftEng, CN=CA_arm-devel/Email=luc.lanthier@rebel.com + Validity + Not Before: Feb 14 20:59:13 2001 GMT + Not After : Feb 14 20:59:13 2002 GMT + Subject: C=CA, ST=Ontario, O=Rebel.com, OU=SoftEng, CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:a8:a9:0c:2c:21:fc:9b:02:d6:f4:98:c7:c3:dc: + d1:8d:31:91:fb:72:41:ab:09:e8:52:9b:be:35:75: + d8:f0:f6:b5:ba:8a:0c:d9:02:9b:5a:a9:0d:98:e6: + b6:8f:97:45:eb:17:e3:10:23:c4:90:91:f4:ed:cc: + ff:76:fd:95:3d:7a:a6:c4:59:b0:45:45:f6:0b:a9: + c9:0c:77:6d:5e:53:d1:87:0d:59:79:50:f9:94:c1: + 64:8e:5e:e1:38:94:ae:7c:7f:68:5e:10:51:3d:ef: + 9c:9f:f4:2b:08:bc:eb:9a:b3:7d:c5:b2:2b:98:b4: + ee:54:12:6c:da:a4:05:40:9d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + IPsec Certificate for arm-devel.netwinder.org + X509v3 Subject Key Identifier: + 98:76:ED:A5:41:7C:28:3C:C8:63:0F:09:F7:DE:9E:B2:00:B6:36:FE + X509v3 Authority Key Identifier: + keyid:7A:38:75:E9:B9:94:AB:B6:00:C5:36:81:EA:A5:60:3E:FA:FE:E4:E1 + DirName:/C=CA/ST=Ontario/L=Ottawa/O=Rebel.com/OU=SoftEng/CN=CA_arm-devel/Email=luc.lanthier@rebel.com + serial:00 + + X509v3 Subject Alternative Name: + email:luc.lanthier@rebel.com, DNS:arm-devel.netwinder.org, IP Address:10.8.49.122 + X509v3 Issuer Alternative Name: + email:luc.lanthier@rebel.com + Signature Algorithm: md5WithRSAEncryption + bb:a9:1a:f4:e3:55:c8:f6:e7:d6:32:cb:a2:2f:6d:58:a3:5d: + 8f:5a:0d:95:53:c7:bf:06:e7:3b:ca:99:48:99:2f:55:28:5a: + 9e:37:ef:3b:44:73:1e:e0:61:93:43:f8:04:6b:06:1e:68:e5: + 3e:a2:10:53:94:2f:66:76:fc:66:93:d4:5e:76:cf:2d:18:e2: + ff:eb:c0:77:c9:d5:4d:00:60:34:50:59:69:b9:7d:07:fb:ca: + 8b:6e:ee:5c:d2:d9:06:2f:ee:df:d8:09:12:76:bc:b5:17:80: + a8:d6:a7:25:59:5c:b4:65:cb:29:b1:cd:77:29:e9:c4:03:00: + ea:c4 +-----BEGIN CERTIFICATE----- +MIIEUTCCA7qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjA1OTEzWhcNMDIwMjE0MjA1OTEzWjCBjjELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEg +MB4GA1UEAxMXYXJtLWRldmVsLm5ldHdpbmRlci5vcmcxJTAjBgkqhkiG9w0BCQEW +Fmx1Yy5sYW50aGllckByZWJlbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +AoGBAKipDCwh/JsC1vSYx8Pc0Y0xkftyQasJ6FKbvjV12PD2tbqKDNkCm1qpDZjm +to+XResX4xAjxJCR9O3M/3b9lT16psRZsEVF9gupyQx3bV5T0YcNWXlQ+ZTBZI5e +4TiUrnx/aF4QUT3vnJ/0Kwi865qzfcWyK5i07lQSbNqkBUCdAgMBAAGjggG1MIIB +sTAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwPAYJ +YIZIAYb4QgENBC8WLUlQc2VjIENlcnRpZmljYXRlIGZvciBhcm0tZGV2ZWwubmV0 +d2luZGVyLm9yZzAdBgNVHQ4EFgQUmHbtpUF8KDzIYw8J996esgC2Nv4wgcEGA1Ud +IwSBuTCBtoAUejh16bmUq7YAxTaB6qVgPvr+5OGhgZqkgZcwgZQxCzAJBgNVBAYT +AkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoT +CVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEVMBMGA1UEAxQMQ0FfYXJtLWRl +dmVsMSUwIwYJKoZIhvcNAQkBFhZsdWMubGFudGhpZXJAcmViZWwuY29tggEAMEAG +A1UdEQQ5MDeBFmx1Yy5sYW50aGllckByZWJlbC5jb22CF2FybS1kZXZlbC5uZXR3 +aW5kZXIub3JnhwQKCDF6MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5j +b20wDQYJKoZIhvcNAQEEBQADgYEAu6ka9ONVyPbn1jLLoi9tWKNdj1oNlVPHvwbn +O8qZSJkvVShanjfvO0RzHuBhk0P4BGsGHmjlPqIQU5QvZnb8ZpPUXnbPLRji/+vA +d8nVTQBgNFBZabl9B/vKi27uXNLZBi/u39gJEna8tReAqNanJVlctGXLKbHNdynp +xAMA6sQ= +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/arm1.pem freeswan-1.91/doc/pkix/examples/dir/arm1.pem --- freeswan-1.91.orig/doc/pkix/examples/dir/arm1.pem Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/arm1.pem Mon Jul 16 23:26:30 2001 @@ -0,0 +1,78 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=CA, ST=Ontario, L=Ottawa, O=Rebel.com, OU=SoftEng, CN=CA_arm-devel/Email=luc.lanthier@rebel.com + Validity + Not Before: Feb 14 21:00:11 2001 GMT + Not After : Feb 14 21:00:11 2002 GMT + Subject: C=CA, ST=Ontario, O=Rebel.com, OU=SoftEng, CN=arm1.netwinder.org/Email=firesoul@netwinder.org + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:e2:2b:ad:70:6b:29:e7:83:be:af:12:50:4b:a4: + 26:02:60:ed:f9:bd:49:51:86:96:18:9c:10:f1:0c: + 7d:bd:b9:22:8e:66:6a:f4:96:e5:8d:e2:c4:11:1e: + 64:8e:59:1e:b1:a2:64:15:fa:a6:17:9a:59:f3:9f: + 9f:c8:c9:17:b8:a7:87:55:70:8f:de:25:78:e6:e0: + 4c:82:ae:f1:47:14:77:fa:5b:3e:4d:e5:05:5e:31: + 09:62:56:f8:3b:94:51:b2:e3:7e:bb:8f:6e:dc:ea: + 64:2e:2f:65:8e:41:18:0e:cf:9d:8a:b8:0a:86:6c: + 6a:88:be:58:ce:be:b3:32:c1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + IPsec Certificate for arm1.netwinder.org + X509v3 Subject Key Identifier: + 82:A2:6E:58:0D:B6:98:EF:D9:A0:68:9D:D0:C0:70:59:B3:6A:32:99 + X509v3 Authority Key Identifier: + keyid:7A:38:75:E9:B9:94:AB:B6:00:C5:36:81:EA:A5:60:3E:FA:FE:E4:E1 + DirName:/C=CA/ST=Ontario/L=Ottawa/O=Rebel.com/OU=SoftEng/CN=CA_arm-devel/Email=luc.lanthier@rebel.com + serial:00 + + X509v3 Subject Alternative Name: + email:firesoul@netwinder.org, DNS:arm1.netwinder.org, IP Address:10.1.49.124 + X509v3 Issuer Alternative Name: + email:luc.lanthier@rebel.com + Signature Algorithm: md5WithRSAEncryption + c3:68:19:5f:60:12:18:6f:48:87:f9:97:d2:a3:0f:bc:e4:d0: + 59:37:69:17:28:32:55:7d:5c:7a:35:ff:e1:67:05:f5:31:80: + 27:cc:3a:37:28:47:46:ec:d9:b0:f9:69:ac:ce:6d:89:94:19: + 16:38:64:bb:da:67:68:c5:e3:26:e3:66:98:b2:45:bf:0d:16: + 2b:95:0c:1a:cc:65:8c:c5:f4:ba:2f:2b:5a:f4:ad:9a:71:92: + de:e5:77:c4:08:96:7c:c3:25:25:fe:43:b0:f3:f9:65:1f:fa: + 6c:2d:2e:e2:1f:18:75:03:51:33:94:61:29:59:1a:9c:7c:71: + 42:e1 +-----BEGIN CERTIFICATE----- +MIIEQjCCA6ugAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjEwMDExWhcNMDIwMjE0MjEwMDExWjCBiTELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEb +MBkGA1UEAxMSYXJtMS5uZXR3aW5kZXIub3JnMSUwIwYJKoZIhvcNAQkBFhZmaXJl +c291bEBuZXR3aW5kZXIub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDi +K61waynng76vElBLpCYCYO35vUlRhpYYnBDxDH29uSKOZmr0luWN4sQRHmSOWR6x +omQV+qYXmlnzn5/IyRe4p4dVcI/eJXjm4EyCrvFHFHf6Wz5N5QVeMQliVvg7lFGy +4367j27c6mQuL2WOQRgOz52KuAqGbGqIvljOvrMywQIDAQABo4IBqzCCAacwCQYD +VR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwCwYDVR0PBAQDAgXgMDcGCWCGSAGG ++EIBDQQqFihJUHNlYyBDZXJ0aWZpY2F0ZSBmb3IgYXJtMS5uZXR3aW5kZXIub3Jn +MB0GA1UdDgQWBBSCom5YDbaY79mgaJ3QwHBZs2oymTCBwQYDVR0jBIG5MIG2gBR6 +OHXpuZSrtgDFNoHqpWA++v7k4aGBmqSBlzCBlDELMAkGA1UEBhMCQ0ExEDAOBgNV +BAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmViZWwuY29t +MRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwxJTAjBgkq +hkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb22CAQAwOwYDVR0RBDQwMoEW +ZmlyZXNvdWxAbmV0d2luZGVyLm9yZ4ISYXJtMS5uZXR3aW5kZXIub3JnhwQKATF8 +MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5jb20wDQYJKoZIhvcNAQEE +BQADgYEAw2gZX2ASGG9Ih/mX0qMPvOTQWTdpFygyVX1cejX/4WcF9TGAJ8w6NyhH +RuzZsPlprM5tiZQZFjhku9pnaMXjJuNmmLJFvw0WK5UMGsxljMX0ui8rWvStmnGS +3uV3xAiWfMMlJf5DsPP5ZR/6bC0u4h8YdQNRM5RhKVkanHxxQuE= +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/b2dc4b6f.cert.0 freeswan-1.91/doc/pkix/examples/dir/b2dc4b6f.cert.0 --- freeswan-1.91.orig/doc/pkix/examples/dir/b2dc4b6f.cert.0 Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/b2dc4b6f.cert.0 Mon Jul 16 23:26:30 2001 @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=CA, ST=Ontario, L=Ottawa, O=Rebel.com, OU=SoftEng, CN=CA_arm-devel/Email=luc.lanthier@rebel.com + Validity + Not Before: Feb 14 20:59:13 2001 GMT + Not After : Feb 14 20:59:13 2002 GMT + Subject: C=CA, ST=Ontario, O=Rebel.com, OU=SoftEng, CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:a8:a9:0c:2c:21:fc:9b:02:d6:f4:98:c7:c3:dc: + d1:8d:31:91:fb:72:41:ab:09:e8:52:9b:be:35:75: + d8:f0:f6:b5:ba:8a:0c:d9:02:9b:5a:a9:0d:98:e6: + b6:8f:97:45:eb:17:e3:10:23:c4:90:91:f4:ed:cc: + ff:76:fd:95:3d:7a:a6:c4:59:b0:45:45:f6:0b:a9: + c9:0c:77:6d:5e:53:d1:87:0d:59:79:50:f9:94:c1: + 64:8e:5e:e1:38:94:ae:7c:7f:68:5e:10:51:3d:ef: + 9c:9f:f4:2b:08:bc:eb:9a:b3:7d:c5:b2:2b:98:b4: + ee:54:12:6c:da:a4:05:40:9d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + IPsec Certificate for arm-devel.netwinder.org + X509v3 Subject Key Identifier: + 98:76:ED:A5:41:7C:28:3C:C8:63:0F:09:F7:DE:9E:B2:00:B6:36:FE + X509v3 Authority Key Identifier: + keyid:7A:38:75:E9:B9:94:AB:B6:00:C5:36:81:EA:A5:60:3E:FA:FE:E4:E1 + DirName:/C=CA/ST=Ontario/L=Ottawa/O=Rebel.com/OU=SoftEng/CN=CA_arm-devel/Email=luc.lanthier@rebel.com + serial:00 + + X509v3 Subject Alternative Name: + email:luc.lanthier@rebel.com, DNS:arm-devel.netwinder.org, IP Address:10.8.49.122 + X509v3 Issuer Alternative Name: + email:luc.lanthier@rebel.com + Signature Algorithm: md5WithRSAEncryption + bb:a9:1a:f4:e3:55:c8:f6:e7:d6:32:cb:a2:2f:6d:58:a3:5d: + 8f:5a:0d:95:53:c7:bf:06:e7:3b:ca:99:48:99:2f:55:28:5a: + 9e:37:ef:3b:44:73:1e:e0:61:93:43:f8:04:6b:06:1e:68:e5: + 3e:a2:10:53:94:2f:66:76:fc:66:93:d4:5e:76:cf:2d:18:e2: + ff:eb:c0:77:c9:d5:4d:00:60:34:50:59:69:b9:7d:07:fb:ca: + 8b:6e:ee:5c:d2:d9:06:2f:ee:df:d8:09:12:76:bc:b5:17:80: + a8:d6:a7:25:59:5c:b4:65:cb:29:b1:cd:77:29:e9:c4:03:00: + ea:c4 +-----BEGIN CERTIFICATE----- +MIIEUTCCA7qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjA1OTEzWhcNMDIwMjE0MjA1OTEzWjCBjjELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEg +MB4GA1UEAxMXYXJtLWRldmVsLm5ldHdpbmRlci5vcmcxJTAjBgkqhkiG9w0BCQEW +Fmx1Yy5sYW50aGllckByZWJlbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +AoGBAKipDCwh/JsC1vSYx8Pc0Y0xkftyQasJ6FKbvjV12PD2tbqKDNkCm1qpDZjm +to+XResX4xAjxJCR9O3M/3b9lT16psRZsEVF9gupyQx3bV5T0YcNWXlQ+ZTBZI5e +4TiUrnx/aF4QUT3vnJ/0Kwi865qzfcWyK5i07lQSbNqkBUCdAgMBAAGjggG1MIIB +sTAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwPAYJ +YIZIAYb4QgENBC8WLUlQc2VjIENlcnRpZmljYXRlIGZvciBhcm0tZGV2ZWwubmV0 +d2luZGVyLm9yZzAdBgNVHQ4EFgQUmHbtpUF8KDzIYw8J996esgC2Nv4wgcEGA1Ud +IwSBuTCBtoAUejh16bmUq7YAxTaB6qVgPvr+5OGhgZqkgZcwgZQxCzAJBgNVBAYT +AkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoT +CVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEVMBMGA1UEAxQMQ0FfYXJtLWRl +dmVsMSUwIwYJKoZIhvcNAQkBFhZsdWMubGFudGhpZXJAcmViZWwuY29tggEAMEAG +A1UdEQQ5MDeBFmx1Yy5sYW50aGllckByZWJlbC5jb22CF2FybS1kZXZlbC5uZXR3 +aW5kZXIub3JnhwQKCDF6MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5j +b20wDQYJKoZIhvcNAQEEBQADgYEAu6ka9ONVyPbn1jLLoi9tWKNdj1oNlVPHvwbn +O8qZSJkvVShanjfvO0RzHuBhk0P4BGsGHmjlPqIQU5QvZnb8ZpPUXnbPLRji/+vA +d8nVTQBgNFBZabl9B/vKi27uXNLZBi/u39gJEna8tReAqNanJVlctGXLKbHNdynp +xAMA6sQ= +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/cacert.pem freeswan-1.91/doc/pkix/examples/dir/cacert.pem --- freeswan-1.91.orig/doc/pkix/examples/dir/cacert.pem Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/cacert.pem Mon Jul 16 23:26:30 2001 @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID2jCCA0OgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MTk0NTAyWhcNMDYwODA3MTk0NTAyWjCBlDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmViZWwuY29tMRAw +DgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwxJTAjBgkqhkiG +9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD +gY0AMIGJAoGBANWu/vkaR1M1bvP2Y80Dv105n3VHmOqZcyy9fnbaXXc92nKbBMib +bsuUdfWdjOuC34BjfNuC9DU3rP8jZNBg+qeyAie6G7Q1R3atroqYvaFFhEbU1OnZ +vBigB39dOIjfFiHbeqNCqlxLlrMJwkBJtkLdiktuf6Rqp+nnX6ymxz1BAgMBAAGj +ggE4MIIBNDAdBgNVHQ4EFgQUejh16bmUq7YAxTaB6qVgPvr+5OEwgcEGA1UdIwSB +uTCBtoAUejh16bmUq7YAxTaB6qVgPvr+5OGhgZqkgZcwgZQxCzAJBgNVBAYTAkNB +MRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoTCVJl +YmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEVMBMGA1UEAxQMQ0FfYXJtLWRldmVs +MSUwIwYJKoZIhvcNAQkBFhZsdWMubGFudGhpZXJAcmViZWwuY29tggEAMAwGA1Ud +EwQFMAMBAf8wCwYDVR0PBAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIBBjAhBgNVHREE +GjAYgRZsdWMubGFudGhpZXJAcmViZWwuY29tMA0GCSqGSIb3DQEBBAUAA4GBAHzh +QeKz7deGehWh7KtZ1tNNu1gWxeW4fwjHUT/xkoepd0XclIIRoKH+2h6w5QG3p2Up +9TLxWlS8SB0tR0FiVu1WD658vOZjDTqqL9EVdEgSCrWX26KaMhNLrYzT3nzqq9VR +QYqYZDAD3Z345UweqfCJBgxrim03x++bsEq9tP4Y +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/crl.pem freeswan-1.91/doc/pkix/examples/dir/crl.pem --- freeswan-1.91.orig/doc/pkix/examples/dir/crl.pem Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/crl.pem Mon Jul 16 23:26:30 2001 @@ -0,0 +1,10 @@ +-----BEGIN X509 CRL----- +MIIBWjCBxDANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmViZWwuY29tMRAw +DgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwxJTAjBgkqhkiG +9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20XDTAxMDIxNDE5NDUzN1oXDTAx +MDMxNjE5NDUzN1owDQYJKoZIhvcNAQEEBQADgYEAcM3oRcSVw2rf7AQbcX0WqsEh +YEHnMUNur13Wd2ai7b6KSKxHj+O/WWSupH3IDPL1TEKwdWLG9+MtbhKhBh8WNzQh +7Nl/NzTgdCh0xDBoJDGG7zN7WDNQ1WGbaAkjDUJm6ty92zlpFkF4Gg2B1dl8WwYK +LSSaMtj6/VV4CuhzFMg= +-----END X509 CRL----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/dns-arm-devel.netwinder.org.cert.0 freeswan-1.91/doc/pkix/examples/dir/dns-arm-devel.netwinder.org.cert.0 --- freeswan-1.91.orig/doc/pkix/examples/dir/dns-arm-devel.netwinder.org.cert.0 Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/dns-arm-devel.netwinder.org.cert.0 Mon Jul 16 23:26:30 2001 @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=CA, ST=Ontario, L=Ottawa, O=Rebel.com, OU=SoftEng, CN=CA_arm-devel/Email=luc.lanthier@rebel.com + Validity + Not Before: Feb 14 20:59:13 2001 GMT + Not After : Feb 14 20:59:13 2002 GMT + Subject: C=CA, ST=Ontario, O=Rebel.com, OU=SoftEng, CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:a8:a9:0c:2c:21:fc:9b:02:d6:f4:98:c7:c3:dc: + d1:8d:31:91:fb:72:41:ab:09:e8:52:9b:be:35:75: + d8:f0:f6:b5:ba:8a:0c:d9:02:9b:5a:a9:0d:98:e6: + b6:8f:97:45:eb:17:e3:10:23:c4:90:91:f4:ed:cc: + ff:76:fd:95:3d:7a:a6:c4:59:b0:45:45:f6:0b:a9: + c9:0c:77:6d:5e:53:d1:87:0d:59:79:50:f9:94:c1: + 64:8e:5e:e1:38:94:ae:7c:7f:68:5e:10:51:3d:ef: + 9c:9f:f4:2b:08:bc:eb:9a:b3:7d:c5:b2:2b:98:b4: + ee:54:12:6c:da:a4:05:40:9d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + IPsec Certificate for arm-devel.netwinder.org + X509v3 Subject Key Identifier: + 98:76:ED:A5:41:7C:28:3C:C8:63:0F:09:F7:DE:9E:B2:00:B6:36:FE + X509v3 Authority Key Identifier: + keyid:7A:38:75:E9:B9:94:AB:B6:00:C5:36:81:EA:A5:60:3E:FA:FE:E4:E1 + DirName:/C=CA/ST=Ontario/L=Ottawa/O=Rebel.com/OU=SoftEng/CN=CA_arm-devel/Email=luc.lanthier@rebel.com + serial:00 + + X509v3 Subject Alternative Name: + email:luc.lanthier@rebel.com, DNS:arm-devel.netwinder.org, IP Address:10.8.49.122 + X509v3 Issuer Alternative Name: + email:luc.lanthier@rebel.com + Signature Algorithm: md5WithRSAEncryption + bb:a9:1a:f4:e3:55:c8:f6:e7:d6:32:cb:a2:2f:6d:58:a3:5d: + 8f:5a:0d:95:53:c7:bf:06:e7:3b:ca:99:48:99:2f:55:28:5a: + 9e:37:ef:3b:44:73:1e:e0:61:93:43:f8:04:6b:06:1e:68:e5: + 3e:a2:10:53:94:2f:66:76:fc:66:93:d4:5e:76:cf:2d:18:e2: + ff:eb:c0:77:c9:d5:4d:00:60:34:50:59:69:b9:7d:07:fb:ca: + 8b:6e:ee:5c:d2:d9:06:2f:ee:df:d8:09:12:76:bc:b5:17:80: + a8:d6:a7:25:59:5c:b4:65:cb:29:b1:cd:77:29:e9:c4:03:00: + ea:c4 +-----BEGIN CERTIFICATE----- +MIIEUTCCA7qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjA1OTEzWhcNMDIwMjE0MjA1OTEzWjCBjjELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEg +MB4GA1UEAxMXYXJtLWRldmVsLm5ldHdpbmRlci5vcmcxJTAjBgkqhkiG9w0BCQEW +Fmx1Yy5sYW50aGllckByZWJlbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +AoGBAKipDCwh/JsC1vSYx8Pc0Y0xkftyQasJ6FKbvjV12PD2tbqKDNkCm1qpDZjm +to+XResX4xAjxJCR9O3M/3b9lT16psRZsEVF9gupyQx3bV5T0YcNWXlQ+ZTBZI5e +4TiUrnx/aF4QUT3vnJ/0Kwi865qzfcWyK5i07lQSbNqkBUCdAgMBAAGjggG1MIIB +sTAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwPAYJ +YIZIAYb4QgENBC8WLUlQc2VjIENlcnRpZmljYXRlIGZvciBhcm0tZGV2ZWwubmV0 +d2luZGVyLm9yZzAdBgNVHQ4EFgQUmHbtpUF8KDzIYw8J996esgC2Nv4wgcEGA1Ud +IwSBuTCBtoAUejh16bmUq7YAxTaB6qVgPvr+5OGhgZqkgZcwgZQxCzAJBgNVBAYT +AkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoT +CVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEVMBMGA1UEAxQMQ0FfYXJtLWRl +dmVsMSUwIwYJKoZIhvcNAQkBFhZsdWMubGFudGhpZXJAcmViZWwuY29tggEAMEAG +A1UdEQQ5MDeBFmx1Yy5sYW50aGllckByZWJlbC5jb22CF2FybS1kZXZlbC5uZXR3 +aW5kZXIub3JnhwQKCDF6MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5j +b20wDQYJKoZIhvcNAQEEBQADgYEAu6ka9ONVyPbn1jLLoi9tWKNdj1oNlVPHvwbn +O8qZSJkvVShanjfvO0RzHuBhk0P4BGsGHmjlPqIQU5QvZnb8ZpPUXnbPLRji/+vA +d8nVTQBgNFBZabl9B/vKi27uXNLZBi/u39gJEna8tReAqNanJVlctGXLKbHNdynp +xAMA6sQ= +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/dns-arm1.netwinder.org.cert.0 freeswan-1.91/doc/pkix/examples/dir/dns-arm1.netwinder.org.cert.0 --- freeswan-1.91.orig/doc/pkix/examples/dir/dns-arm1.netwinder.org.cert.0 Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/dns-arm1.netwinder.org.cert.0 Mon Jul 16 23:26:30 2001 @@ -0,0 +1,78 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=CA, ST=Ontario, L=Ottawa, O=Rebel.com, OU=SoftEng, CN=CA_arm-devel/Email=luc.lanthier@rebel.com + Validity + Not Before: Feb 14 21:00:11 2001 GMT + Not After : Feb 14 21:00:11 2002 GMT + Subject: C=CA, ST=Ontario, O=Rebel.com, OU=SoftEng, CN=arm1.netwinder.org/Email=firesoul@netwinder.org + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:e2:2b:ad:70:6b:29:e7:83:be:af:12:50:4b:a4: + 26:02:60:ed:f9:bd:49:51:86:96:18:9c:10:f1:0c: + 7d:bd:b9:22:8e:66:6a:f4:96:e5:8d:e2:c4:11:1e: + 64:8e:59:1e:b1:a2:64:15:fa:a6:17:9a:59:f3:9f: + 9f:c8:c9:17:b8:a7:87:55:70:8f:de:25:78:e6:e0: + 4c:82:ae:f1:47:14:77:fa:5b:3e:4d:e5:05:5e:31: + 09:62:56:f8:3b:94:51:b2:e3:7e:bb:8f:6e:dc:ea: + 64:2e:2f:65:8e:41:18:0e:cf:9d:8a:b8:0a:86:6c: + 6a:88:be:58:ce:be:b3:32:c1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + IPsec Certificate for arm1.netwinder.org + X509v3 Subject Key Identifier: + 82:A2:6E:58:0D:B6:98:EF:D9:A0:68:9D:D0:C0:70:59:B3:6A:32:99 + X509v3 Authority Key Identifier: + keyid:7A:38:75:E9:B9:94:AB:B6:00:C5:36:81:EA:A5:60:3E:FA:FE:E4:E1 + DirName:/C=CA/ST=Ontario/L=Ottawa/O=Rebel.com/OU=SoftEng/CN=CA_arm-devel/Email=luc.lanthier@rebel.com + serial:00 + + X509v3 Subject Alternative Name: + email:firesoul@netwinder.org, DNS:arm1.netwinder.org, IP Address:10.1.49.124 + X509v3 Issuer Alternative Name: + email:luc.lanthier@rebel.com + Signature Algorithm: md5WithRSAEncryption + c3:68:19:5f:60:12:18:6f:48:87:f9:97:d2:a3:0f:bc:e4:d0: + 59:37:69:17:28:32:55:7d:5c:7a:35:ff:e1:67:05:f5:31:80: + 27:cc:3a:37:28:47:46:ec:d9:b0:f9:69:ac:ce:6d:89:94:19: + 16:38:64:bb:da:67:68:c5:e3:26:e3:66:98:b2:45:bf:0d:16: + 2b:95:0c:1a:cc:65:8c:c5:f4:ba:2f:2b:5a:f4:ad:9a:71:92: + de:e5:77:c4:08:96:7c:c3:25:25:fe:43:b0:f3:f9:65:1f:fa: + 6c:2d:2e:e2:1f:18:75:03:51:33:94:61:29:59:1a:9c:7c:71: + 42:e1 +-----BEGIN CERTIFICATE----- +MIIEQjCCA6ugAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjEwMDExWhcNMDIwMjE0MjEwMDExWjCBiTELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEb +MBkGA1UEAxMSYXJtMS5uZXR3aW5kZXIub3JnMSUwIwYJKoZIhvcNAQkBFhZmaXJl +c291bEBuZXR3aW5kZXIub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDi +K61waynng76vElBLpCYCYO35vUlRhpYYnBDxDH29uSKOZmr0luWN4sQRHmSOWR6x +omQV+qYXmlnzn5/IyRe4p4dVcI/eJXjm4EyCrvFHFHf6Wz5N5QVeMQliVvg7lFGy +4367j27c6mQuL2WOQRgOz52KuAqGbGqIvljOvrMywQIDAQABo4IBqzCCAacwCQYD +VR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwCwYDVR0PBAQDAgXgMDcGCWCGSAGG ++EIBDQQqFihJUHNlYyBDZXJ0aWZpY2F0ZSBmb3IgYXJtMS5uZXR3aW5kZXIub3Jn +MB0GA1UdDgQWBBSCom5YDbaY79mgaJ3QwHBZs2oymTCBwQYDVR0jBIG5MIG2gBR6 +OHXpuZSrtgDFNoHqpWA++v7k4aGBmqSBlzCBlDELMAkGA1UEBhMCQ0ExEDAOBgNV +BAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmViZWwuY29t +MRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwxJTAjBgkq +hkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb22CAQAwOwYDVR0RBDQwMoEW +ZmlyZXNvdWxAbmV0d2luZGVyLm9yZ4ISYXJtMS5uZXR3aW5kZXIub3JnhwQKATF8 +MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5jb20wDQYJKoZIhvcNAQEE +BQADgYEAw2gZX2ASGG9Ih/mX0qMPvOTQWTdpFygyVX1cejX/4WcF9TGAJ8w6NyhH +RuzZsPlprM5tiZQZFjhku9pnaMXjJuNmmLJFvw0WK5UMGsxljMX0ui8rWvStmnGS +3uV3xAiWfMMlJf5DsPP5ZR/6bC0u4h8YdQNRM5RhKVkanHxxQuE= +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/eb7e7e69.cert.0 freeswan-1.91/doc/pkix/examples/dir/eb7e7e69.cert.0 --- freeswan-1.91.orig/doc/pkix/examples/dir/eb7e7e69.cert.0 Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/eb7e7e69.cert.0 Mon Jul 16 23:26:30 2001 @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID2jCCA0OgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MTk0NTAyWhcNMDYwODA3MTk0NTAyWjCBlDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmViZWwuY29tMRAw +DgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwxJTAjBgkqhkiG +9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD +gY0AMIGJAoGBANWu/vkaR1M1bvP2Y80Dv105n3VHmOqZcyy9fnbaXXc92nKbBMib +bsuUdfWdjOuC34BjfNuC9DU3rP8jZNBg+qeyAie6G7Q1R3atroqYvaFFhEbU1OnZ +vBigB39dOIjfFiHbeqNCqlxLlrMJwkBJtkLdiktuf6Rqp+nnX6ymxz1BAgMBAAGj +ggE4MIIBNDAdBgNVHQ4EFgQUejh16bmUq7YAxTaB6qVgPvr+5OEwgcEGA1UdIwSB +uTCBtoAUejh16bmUq7YAxTaB6qVgPvr+5OGhgZqkgZcwgZQxCzAJBgNVBAYTAkNB +MRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoTCVJl +YmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEVMBMGA1UEAxQMQ0FfYXJtLWRldmVs +MSUwIwYJKoZIhvcNAQkBFhZsdWMubGFudGhpZXJAcmViZWwuY29tggEAMAwGA1Ud +EwQFMAMBAf8wCwYDVR0PBAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIBBjAhBgNVHREE +GjAYgRZsdWMubGFudGhpZXJAcmViZWwuY29tMA0GCSqGSIb3DQEBBAUAA4GBAHzh +QeKz7deGehWh7KtZ1tNNu1gWxeW4fwjHUT/xkoepd0XclIIRoKH+2h6w5QG3p2Up +9TLxWlS8SB0tR0FiVu1WD658vOZjDTqqL9EVdEgSCrWX26KaMhNLrYzT3nzqq9VR +QYqYZDAD3Z345UweqfCJBgxrim03x++bsEq9tP4Y +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/eb7e7e69.crl.0 freeswan-1.91/doc/pkix/examples/dir/eb7e7e69.crl.0 --- freeswan-1.91.orig/doc/pkix/examples/dir/eb7e7e69.crl.0 Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/eb7e7e69.crl.0 Mon Jul 16 23:26:30 2001 @@ -0,0 +1,10 @@ +-----BEGIN X509 CRL----- +MIIBWjCBxDANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmViZWwuY29tMRAw +DgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwxJTAjBgkqhkiG +9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20XDTAxMDIxNDE5NDUzN1oXDTAx +MDMxNjE5NDUzN1owDQYJKoZIhvcNAQEEBQADgYEAcM3oRcSVw2rf7AQbcX0WqsEh +YEHnMUNur13Wd2ai7b6KSKxHj+O/WWSupH3IDPL1TEKwdWLG9+MtbhKhBh8WNzQh +7Nl/NzTgdCh0xDBoJDGG7zN7WDNQ1WGbaAkjDUJm6ty92zlpFkF4Gg2B1dl8WwYK +LSSaMtj6/VV4CuhzFMg= +-----END X509 CRL----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/ip-10.1.49.124.cert.0 freeswan-1.91/doc/pkix/examples/dir/ip-10.1.49.124.cert.0 --- freeswan-1.91.orig/doc/pkix/examples/dir/ip-10.1.49.124.cert.0 Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/ip-10.1.49.124.cert.0 Mon Jul 16 23:26:30 2001 @@ -0,0 +1,78 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=CA, ST=Ontario, L=Ottawa, O=Rebel.com, OU=SoftEng, CN=CA_arm-devel/Email=luc.lanthier@rebel.com + Validity + Not Before: Feb 14 21:00:11 2001 GMT + Not After : Feb 14 21:00:11 2002 GMT + Subject: C=CA, ST=Ontario, O=Rebel.com, OU=SoftEng, CN=arm1.netwinder.org/Email=firesoul@netwinder.org + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:e2:2b:ad:70:6b:29:e7:83:be:af:12:50:4b:a4: + 26:02:60:ed:f9:bd:49:51:86:96:18:9c:10:f1:0c: + 7d:bd:b9:22:8e:66:6a:f4:96:e5:8d:e2:c4:11:1e: + 64:8e:59:1e:b1:a2:64:15:fa:a6:17:9a:59:f3:9f: + 9f:c8:c9:17:b8:a7:87:55:70:8f:de:25:78:e6:e0: + 4c:82:ae:f1:47:14:77:fa:5b:3e:4d:e5:05:5e:31: + 09:62:56:f8:3b:94:51:b2:e3:7e:bb:8f:6e:dc:ea: + 64:2e:2f:65:8e:41:18:0e:cf:9d:8a:b8:0a:86:6c: + 6a:88:be:58:ce:be:b3:32:c1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + IPsec Certificate for arm1.netwinder.org + X509v3 Subject Key Identifier: + 82:A2:6E:58:0D:B6:98:EF:D9:A0:68:9D:D0:C0:70:59:B3:6A:32:99 + X509v3 Authority Key Identifier: + keyid:7A:38:75:E9:B9:94:AB:B6:00:C5:36:81:EA:A5:60:3E:FA:FE:E4:E1 + DirName:/C=CA/ST=Ontario/L=Ottawa/O=Rebel.com/OU=SoftEng/CN=CA_arm-devel/Email=luc.lanthier@rebel.com + serial:00 + + X509v3 Subject Alternative Name: + email:firesoul@netwinder.org, DNS:arm1.netwinder.org, IP Address:10.1.49.124 + X509v3 Issuer Alternative Name: + email:luc.lanthier@rebel.com + Signature Algorithm: md5WithRSAEncryption + c3:68:19:5f:60:12:18:6f:48:87:f9:97:d2:a3:0f:bc:e4:d0: + 59:37:69:17:28:32:55:7d:5c:7a:35:ff:e1:67:05:f5:31:80: + 27:cc:3a:37:28:47:46:ec:d9:b0:f9:69:ac:ce:6d:89:94:19: + 16:38:64:bb:da:67:68:c5:e3:26:e3:66:98:b2:45:bf:0d:16: + 2b:95:0c:1a:cc:65:8c:c5:f4:ba:2f:2b:5a:f4:ad:9a:71:92: + de:e5:77:c4:08:96:7c:c3:25:25:fe:43:b0:f3:f9:65:1f:fa: + 6c:2d:2e:e2:1f:18:75:03:51:33:94:61:29:59:1a:9c:7c:71: + 42:e1 +-----BEGIN CERTIFICATE----- +MIIEQjCCA6ugAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjEwMDExWhcNMDIwMjE0MjEwMDExWjCBiTELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEb +MBkGA1UEAxMSYXJtMS5uZXR3aW5kZXIub3JnMSUwIwYJKoZIhvcNAQkBFhZmaXJl +c291bEBuZXR3aW5kZXIub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDi +K61waynng76vElBLpCYCYO35vUlRhpYYnBDxDH29uSKOZmr0luWN4sQRHmSOWR6x +omQV+qYXmlnzn5/IyRe4p4dVcI/eJXjm4EyCrvFHFHf6Wz5N5QVeMQliVvg7lFGy +4367j27c6mQuL2WOQRgOz52KuAqGbGqIvljOvrMywQIDAQABo4IBqzCCAacwCQYD +VR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwCwYDVR0PBAQDAgXgMDcGCWCGSAGG ++EIBDQQqFihJUHNlYyBDZXJ0aWZpY2F0ZSBmb3IgYXJtMS5uZXR3aW5kZXIub3Jn +MB0GA1UdDgQWBBSCom5YDbaY79mgaJ3QwHBZs2oymTCBwQYDVR0jBIG5MIG2gBR6 +OHXpuZSrtgDFNoHqpWA++v7k4aGBmqSBlzCBlDELMAkGA1UEBhMCQ0ExEDAOBgNV +BAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmViZWwuY29t +MRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwxJTAjBgkq +hkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb22CAQAwOwYDVR0RBDQwMoEW +ZmlyZXNvdWxAbmV0d2luZGVyLm9yZ4ISYXJtMS5uZXR3aW5kZXIub3JnhwQKATF8 +MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5jb20wDQYJKoZIhvcNAQEE +BQADgYEAw2gZX2ASGG9Ih/mX0qMPvOTQWTdpFygyVX1cejX/4WcF9TGAJ8w6NyhH +RuzZsPlprM5tiZQZFjhku9pnaMXjJuNmmLJFvw0WK5UMGsxljMX0ui8rWvStmnGS +3uV3xAiWfMMlJf5DsPP5ZR/6bC0u4h8YdQNRM5RhKVkanHxxQuE= +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir/ip-10.8.49.122.cert.0 freeswan-1.91/doc/pkix/examples/dir/ip-10.8.49.122.cert.0 --- freeswan-1.91.orig/doc/pkix/examples/dir/ip-10.8.49.122.cert.0 Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir/ip-10.8.49.122.cert.0 Mon Jul 16 23:26:30 2001 @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=CA, ST=Ontario, L=Ottawa, O=Rebel.com, OU=SoftEng, CN=CA_arm-devel/Email=luc.lanthier@rebel.com + Validity + Not Before: Feb 14 20:59:13 2001 GMT + Not After : Feb 14 20:59:13 2002 GMT + Subject: C=CA, ST=Ontario, O=Rebel.com, OU=SoftEng, CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:a8:a9:0c:2c:21:fc:9b:02:d6:f4:98:c7:c3:dc: + d1:8d:31:91:fb:72:41:ab:09:e8:52:9b:be:35:75: + d8:f0:f6:b5:ba:8a:0c:d9:02:9b:5a:a9:0d:98:e6: + b6:8f:97:45:eb:17:e3:10:23:c4:90:91:f4:ed:cc: + ff:76:fd:95:3d:7a:a6:c4:59:b0:45:45:f6:0b:a9: + c9:0c:77:6d:5e:53:d1:87:0d:59:79:50:f9:94:c1: + 64:8e:5e:e1:38:94:ae:7c:7f:68:5e:10:51:3d:ef: + 9c:9f:f4:2b:08:bc:eb:9a:b3:7d:c5:b2:2b:98:b4: + ee:54:12:6c:da:a4:05:40:9d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + IPsec Certificate for arm-devel.netwinder.org + X509v3 Subject Key Identifier: + 98:76:ED:A5:41:7C:28:3C:C8:63:0F:09:F7:DE:9E:B2:00:B6:36:FE + X509v3 Authority Key Identifier: + keyid:7A:38:75:E9:B9:94:AB:B6:00:C5:36:81:EA:A5:60:3E:FA:FE:E4:E1 + DirName:/C=CA/ST=Ontario/L=Ottawa/O=Rebel.com/OU=SoftEng/CN=CA_arm-devel/Email=luc.lanthier@rebel.com + serial:00 + + X509v3 Subject Alternative Name: + email:luc.lanthier@rebel.com, DNS:arm-devel.netwinder.org, IP Address:10.8.49.122 + X509v3 Issuer Alternative Name: + email:luc.lanthier@rebel.com + Signature Algorithm: md5WithRSAEncryption + bb:a9:1a:f4:e3:55:c8:f6:e7:d6:32:cb:a2:2f:6d:58:a3:5d: + 8f:5a:0d:95:53:c7:bf:06:e7:3b:ca:99:48:99:2f:55:28:5a: + 9e:37:ef:3b:44:73:1e:e0:61:93:43:f8:04:6b:06:1e:68:e5: + 3e:a2:10:53:94:2f:66:76:fc:66:93:d4:5e:76:cf:2d:18:e2: + ff:eb:c0:77:c9:d5:4d:00:60:34:50:59:69:b9:7d:07:fb:ca: + 8b:6e:ee:5c:d2:d9:06:2f:ee:df:d8:09:12:76:bc:b5:17:80: + a8:d6:a7:25:59:5c:b4:65:cb:29:b1:cd:77:29:e9:c4:03:00: + ea:c4 +-----BEGIN CERTIFICATE----- +MIIEUTCCA7qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjA1OTEzWhcNMDIwMjE0MjA1OTEzWjCBjjELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEg +MB4GA1UEAxMXYXJtLWRldmVsLm5ldHdpbmRlci5vcmcxJTAjBgkqhkiG9w0BCQEW +Fmx1Yy5sYW50aGllckByZWJlbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +AoGBAKipDCwh/JsC1vSYx8Pc0Y0xkftyQasJ6FKbvjV12PD2tbqKDNkCm1qpDZjm +to+XResX4xAjxJCR9O3M/3b9lT16psRZsEVF9gupyQx3bV5T0YcNWXlQ+ZTBZI5e +4TiUrnx/aF4QUT3vnJ/0Kwi865qzfcWyK5i07lQSbNqkBUCdAgMBAAGjggG1MIIB +sTAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwPAYJ +YIZIAYb4QgENBC8WLUlQc2VjIENlcnRpZmljYXRlIGZvciBhcm0tZGV2ZWwubmV0 +d2luZGVyLm9yZzAdBgNVHQ4EFgQUmHbtpUF8KDzIYw8J996esgC2Nv4wgcEGA1Ud +IwSBuTCBtoAUejh16bmUq7YAxTaB6qVgPvr+5OGhgZqkgZcwgZQxCzAJBgNVBAYT +AkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoT +CVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEVMBMGA1UEAxQMQ0FfYXJtLWRl +dmVsMSUwIwYJKoZIhvcNAQkBFhZsdWMubGFudGhpZXJAcmViZWwuY29tggEAMEAG +A1UdEQQ5MDeBFmx1Yy5sYW50aGllckByZWJlbC5jb22CF2FybS1kZXZlbC5uZXR3 +aW5kZXIub3JnhwQKCDF6MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5j +b20wDQYJKoZIhvcNAQEEBQADgYEAu6ka9ONVyPbn1jLLoi9tWKNdj1oNlVPHvwbn +O8qZSJkvVShanjfvO0RzHuBhk0P4BGsGHmjlPqIQU5QvZnb8ZpPUXnbPLRji/+vA +d8nVTQBgNFBZabl9B/vKi27uXNLZBi/u39gJEna8tReAqNanJVlctGXLKbHNdynp +xAMA6sQ= +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir-pk-rw.conf freeswan-1.91/doc/pkix/examples/dir-pk-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/dir-pk-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir-pk-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=dir:/etc/ipsec/dir + certopts=send,strict,pk + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir-pk.conf freeswan-1.91/doc/pkix/examples/dir-pk.conf --- freeswan-1.91.orig/doc/pkix/examples/dir-pk.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir-pk.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=dir:/etc/ipsec/dir + certopts=send,strict,pk + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir-rpk-rw.conf freeswan-1.91/doc/pkix/examples/dir-rpk-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/dir-rpk-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir-rpk-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=dir:/etc/ipsec/dir + certopts=send,strict,pk,rev + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir-rpk.conf freeswan-1.91/doc/pkix/examples/dir-rpk.conf --- freeswan-1.91.orig/doc/pkix/examples/dir-rpk.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir-rpk.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=dir:/etc/ipsec/dir + certopts=send,strict,pk,rev + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir-rsasig-rw.conf freeswan-1.91/doc/pkix/examples/dir-rsasig-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/dir-rsasig-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir-rsasig-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=dir:/etc/ipsec/dir + certopts=send + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/dir-rsasig.conf freeswan-1.91/doc/pkix/examples/dir-rsasig.conf --- freeswan-1.91.orig/doc/pkix/examples/dir-rsasig.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/dir-rsasig.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=dir:/etc/ipsec/dir + certopts=send + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ff-pk-rw.conf freeswan-1.91/doc/pkix/examples/ff-pk-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/ff-pk-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ff-pk-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=file:/etc/ipsec/flatfile.txt + certopts=send,strict,pk + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ff-pk.conf freeswan-1.91/doc/pkix/examples/ff-pk.conf --- freeswan-1.91.orig/doc/pkix/examples/ff-pk.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ff-pk.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=file:/etc/ipsec/flatfile.txt + certopts=send,strict,pk + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ff-rpk-rw.conf freeswan-1.91/doc/pkix/examples/ff-rpk-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/ff-rpk-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ff-rpk-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=file:/etc/ipsec/flatfile.txt + certopts=send,strict,pk,rev + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ff-rpk.conf freeswan-1.91/doc/pkix/examples/ff-rpk.conf --- freeswan-1.91.orig/doc/pkix/examples/ff-rpk.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ff-rpk.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=file:/etc/ipsec/flatfile.txt + certopts=send,strict,pk,rev + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ff-rsasig-rw.conf freeswan-1.91/doc/pkix/examples/ff-rsasig-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/ff-rsasig-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ff-rsasig-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=file:/etc/ipsec/flatfile.txt + certopts=send + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ff-rsasig.conf freeswan-1.91/doc/pkix/examples/ff-rsasig.conf --- freeswan-1.91.orig/doc/pkix/examples/ff-rsasig.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ff-rsasig.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=file:/etc/ipsec/flatfile.txt + certopts=send + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/flatfile.txt freeswan-1.91/doc/pkix/examples/flatfile.txt --- freeswan-1.91.orig/doc/pkix/examples/flatfile.txt Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/flatfile.txt Mon Jul 16 23:26:30 2001 @@ -0,0 +1,92 @@ +ip: 10.8.49.122 +dns: arm-devel.netwinder.org +-----BEGIN CERTIFICATE----- +MIIEUTCCA7qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjA1OTEzWhcNMDIwMjE0MjA1OTEzWjCBjjELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEg +MB4GA1UEAxMXYXJtLWRldmVsLm5ldHdpbmRlci5vcmcxJTAjBgkqhkiG9w0BCQEW +Fmx1Yy5sYW50aGllckByZWJlbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +AoGBAKipDCwh/JsC1vSYx8Pc0Y0xkftyQasJ6FKbvjV12PD2tbqKDNkCm1qpDZjm +to+XResX4xAjxJCR9O3M/3b9lT16psRZsEVF9gupyQx3bV5T0YcNWXlQ+ZTBZI5e +4TiUrnx/aF4QUT3vnJ/0Kwi865qzfcWyK5i07lQSbNqkBUCdAgMBAAGjggG1MIIB +sTAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwPAYJ +YIZIAYb4QgENBC8WLUlQc2VjIENlcnRpZmljYXRlIGZvciBhcm0tZGV2ZWwubmV0 +d2luZGVyLm9yZzAdBgNVHQ4EFgQUmHbtpUF8KDzIYw8J996esgC2Nv4wgcEGA1Ud +IwSBuTCBtoAUejh16bmUq7YAxTaB6qVgPvr+5OGhgZqkgZcwgZQxCzAJBgNVBAYT +AkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoT +CVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEVMBMGA1UEAxQMQ0FfYXJtLWRl +dmVsMSUwIwYJKoZIhvcNAQkBFhZsdWMubGFudGhpZXJAcmViZWwuY29tggEAMEAG +A1UdEQQ5MDeBFmx1Yy5sYW50aGllckByZWJlbC5jb22CF2FybS1kZXZlbC5uZXR3 +aW5kZXIub3JnhwQKCDF6MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5j +b20wDQYJKoZIhvcNAQEEBQADgYEAu6ka9ONVyPbn1jLLoi9tWKNdj1oNlVPHvwbn +O8qZSJkvVShanjfvO0RzHuBhk0P4BGsGHmjlPqIQU5QvZnb8ZpPUXnbPLRji/+vA +d8nVTQBgNFBZabl9B/vKi27uXNLZBi/u39gJEna8tReAqNanJVlctGXLKbHNdynp +xAMA6sQ= +-----END CERTIFICATE----- + +ip: 10.1.49.124 +dns: arm1.netwinder.org +-----BEGIN CERTIFICATE----- +MIIEQjCCA6ugAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjEwMDExWhcNMDIwMjE0MjEwMDExWjCBiTELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEb +MBkGA1UEAxMSYXJtMS5uZXR3aW5kZXIub3JnMSUwIwYJKoZIhvcNAQkBFhZmaXJl +c291bEBuZXR3aW5kZXIub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDi +K61waynng76vElBLpCYCYO35vUlRhpYYnBDxDH29uSKOZmr0luWN4sQRHmSOWR6x +omQV+qYXmlnzn5/IyRe4p4dVcI/eJXjm4EyCrvFHFHf6Wz5N5QVeMQliVvg7lFGy +4367j27c6mQuL2WOQRgOz52KuAqGbGqIvljOvrMywQIDAQABo4IBqzCCAacwCQYD +VR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwCwYDVR0PBAQDAgXgMDcGCWCGSAGG ++EIBDQQqFihJUHNlYyBDZXJ0aWZpY2F0ZSBmb3IgYXJtMS5uZXR3aW5kZXIub3Jn +MB0GA1UdDgQWBBSCom5YDbaY79mgaJ3QwHBZs2oymTCBwQYDVR0jBIG5MIG2gBR6 +OHXpuZSrtgDFNoHqpWA++v7k4aGBmqSBlzCBlDELMAkGA1UEBhMCQ0ExEDAOBgNV +BAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmViZWwuY29t +MRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwxJTAjBgkq +hkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb22CAQAwOwYDVR0RBDQwMoEW +ZmlyZXNvdWxAbmV0d2luZGVyLm9yZ4ISYXJtMS5uZXR3aW5kZXIub3JnhwQKATF8 +MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5jb20wDQYJKoZIhvcNAQEE +BQADgYEAw2gZX2ASGG9Ih/mX0qMPvOTQWTdpFygyVX1cejX/4WcF9TGAJ8w6NyhH +RuzZsPlprM5tiZQZFjhku9pnaMXjJuNmmLJFvw0WK5UMGsxljMX0ui8rWvStmnGS +3uV3xAiWfMMlJf5DsPP5ZR/6bC0u4h8YdQNRM5RhKVkanHxxQuE= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID2jCCA0OgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MTk0NTAyWhcNMDYwODA3MTk0NTAyWjCBlDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmViZWwuY29tMRAw +DgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwxJTAjBgkqhkiG +9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD +gY0AMIGJAoGBANWu/vkaR1M1bvP2Y80Dv105n3VHmOqZcyy9fnbaXXc92nKbBMib +bsuUdfWdjOuC34BjfNuC9DU3rP8jZNBg+qeyAie6G7Q1R3atroqYvaFFhEbU1OnZ +vBigB39dOIjfFiHbeqNCqlxLlrMJwkBJtkLdiktuf6Rqp+nnX6ymxz1BAgMBAAGj +ggE4MIIBNDAdBgNVHQ4EFgQUejh16bmUq7YAxTaB6qVgPvr+5OEwgcEGA1UdIwSB +uTCBtoAUejh16bmUq7YAxTaB6qVgPvr+5OGhgZqkgZcwgZQxCzAJBgNVBAYTAkNB +MRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoTCVJl +YmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEVMBMGA1UEAxQMQ0FfYXJtLWRldmVs +MSUwIwYJKoZIhvcNAQkBFhZsdWMubGFudGhpZXJAcmViZWwuY29tggEAMAwGA1Ud +EwQFMAMBAf8wCwYDVR0PBAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIBBjAhBgNVHREE +GjAYgRZsdWMubGFudGhpZXJAcmViZWwuY29tMA0GCSqGSIb3DQEBBAUAA4GBAHzh +QeKz7deGehWh7KtZ1tNNu1gWxeW4fwjHUT/xkoepd0XclIIRoKH+2h6w5QG3p2Up +9TLxWlS8SB0tR0FiVu1WD658vOZjDTqqL9EVdEgSCrWX26KaMhNLrYzT3nzqq9VR +QYqYZDAD3Z345UweqfCJBgxrim03x++bsEq9tP4Y +-----END CERTIFICATE----- + +-----BEGIN X509 CRL----- +MIIBWjCBxDANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmViZWwuY29tMRAw +DgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwxJTAjBgkqhkiG +9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20XDTAxMDIxNDE5NDUzN1oXDTAx +MDMxNjE5NDUzN1owDQYJKoZIhvcNAQEEBQADgYEAcM3oRcSVw2rf7AQbcX0WqsEh +YEHnMUNur13Wd2ai7b6KSKxHj+O/WWSupH3IDPL1TEKwdWLG9+MtbhKhBh8WNzQh +7Nl/NzTgdCh0xDBoJDGG7zN7WDNQ1WGbaAkjDUJm6ty92zlpFkF4Gg2B1dl8WwYK +LSSaMtj6/VV4CuhzFMg= +-----END X509 CRL----- + diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ipsec.conf freeswan-1.91/doc/pkix/examples/ipsec.conf --- freeswan-1.91.orig/doc/pkix/examples/ipsec.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ipsec.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,60 @@ +# /etc/ipsec.conf - FreeS/WAN IPSEC configuration file + +# More elaborate and more varied sample configurations can be found +# in doc/examples. + +# basic configuration +config setup + # THIS SETTING MUST BE CORRECT or almost nothing will work; + # %defaultroute is okay for most simple cases. + interfaces=%defaultroute + # Debug-logging controls: "none" for (almost) none, "all" for lots. + klipsdebug=none + #plutodebug=all + #plutodebug=crypt + plutodebug=none + # Use auto= parameters in conn descriptions to control startup actions. + plutoload=%search + plutostart=%search + +# defaults for subsequent connection descriptions +conn %default + # How persistent to be in (re)keying negotiations (0 means very). + keyingtries=3 + # Authentication by RSA signature keys + authby=rsasig + +#Standard connection types. +#include /etc/ipsec/psk.conf +#include /etc/ipsec/rsasig.conf +#include /etc/ipsec/rsasig-rw.conf +# +# PKIX ######## +# LDAP lookups +#include /etc/ipsec/ldap-rsasig.conf +#include /etc/ipsec/ldap-rsasig-rw.conf +#include /etc/ipsec/ldap-pk.conf +include /etc/ipsec/ldap-pk-rw.conf +#include /etc/ipsec/ldap-rpk.conf +#include /etc/ipsec/ldap-rpk-rw.conf +# dir lookups +#include /etc/ipsec/dir-rsasig.conf +#include /etc/ipsec/dir-rsasig-rw.conf +#include /etc/ipsec/dir-pk.conf +#include /etc/ipsec/dir-pk-rw.conf +#include /etc/ipsec/dir-rpk.conf +#include /etc/ipsec/dir-rpk-rw.conf +# db lookups +#include /etc/ipsec/db-rsasig.conf +#include /etc/ipsec/db-rsasig-rw.conf +#include /etc/ipsec/db-pk.conf +#include /etc/ipsec/db-pk-rw.conf +#include /etc/ipsec/db-rpk.conf +#include /etc/ipsec/db-rpk-rw.conf +# flatfile lookups +#include /etc/ipsec/ff-rsasig.conf +#include /etc/ipsec/ff-rsasig-rw.conf +#include /etc/ipsec/ff-pk.conf +#include /etc/ipsec/ff-pk-rw.conf +#include /etc/ipsec/ff-rpk.conf +#include /etc/ipsec/ff-rpk-rw.conf diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ldap-pk-rw.conf freeswan-1.91/doc/pkix/examples/ldap-pk-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/ldap-pk-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ldap-pk-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=ldap:/etc/ipsec/ldap.cnf:ldapdevel + certopts=send,strict,pk + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ldap-pk.conf freeswan-1.91/doc/pkix/examples/ldap-pk.conf --- freeswan-1.91.orig/doc/pkix/examples/ldap-pk.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ldap-pk.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=ldap:/etc/ipsec/ldap.cnf:ldapdevel + certopts=send,strict,pk + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ldap-rpk-rw.conf freeswan-1.91/doc/pkix/examples/ldap-rpk-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/ldap-rpk-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ldap-rpk-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=ldap:/etc/ipsec/ldap.cnf:ldapdevel + certopts=send,strict,pk,rev + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ldap-rpk.conf freeswan-1.91/doc/pkix/examples/ldap-rpk.conf --- freeswan-1.91.orig/doc/pkix/examples/ldap-rpk.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ldap-rpk.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=ldap:/etc/ipsec/ldap.cnf:ldapdevel + certopts=send,strict,pk,rev + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ldap-rsasig-rw.conf freeswan-1.91/doc/pkix/examples/ldap-rsasig-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/ldap-rsasig-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ldap-rsasig-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,16 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=ldap:/etc/ipsec/ldap.cnf:ldapdevel + certopts=send + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ldap-rsasig.conf freeswan-1.91/doc/pkix/examples/ldap-rsasig.conf --- freeswan-1.91.orig/doc/pkix/examples/ldap-rsasig.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ldap-rsasig.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=cert + auto=add + certfile=/etc/ipsec/pubcert.pem + keyfile=/etc/ipsec/privkey.pem + certpath=ldap:/etc/ipsec/ldap.cnf:ldapdevel + certopts=send + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + rightid=@~30818E310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E673120301E0603550403131761726D2D646576656C2E6E657477696E6465722E6F72673125302306092A864886F70D01090116166C75632E6C616E746869657240726562656C2E636F6D + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + leftid=@~308189310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D3110300E060355040B1307536F6674456E67311B30190603550403131261726D312E6E657477696E6465722E6F72673125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 diff -BbruN freeswan-1.91.orig/doc/pkix/examples/ldap.cnf freeswan-1.91/doc/pkix/examples/ldap.cnf --- freeswan-1.91.orig/doc/pkix/examples/ldap.cnf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/ldap.cnf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,20 @@ +ldapdevel_host_name = 10.8.49.122 +ldapdevel_base = dc=netwinder,dc=org +ldapdevel_filter:uid = (uid=%s) + +ldapdevel_attributes:*:crl = certificaterevocationlist, certificaterevocationlist;binary +ldapdevel_filter:*:crl = (&(objectclass=certificationAuthority)(cn=CA)) + +ldapdevel_filter:ca = (objectclass=certificationauthority) + +ldapdevel_filter:dns = (&(objectclass=hostRecord)(dNSRecord=%s)) +ldapdevel_attributes:dns = servercertificate, servercertificate;binary + +ldapdevel_filter:ip = (&(objectclass=hostRecord)(ipv4Address=%s)) +ldapdevel_attributes:ip = servercertificate, servercertificate;binary + +ldapdevel_filter:subject = (&(objectclass=hostRecord)(subject=%s)) +ldapdevel_attributes:subject = servercertificate, servercertificate;binary + +ldapdevel_filter:issuer = (&(objectclass=hostRecord)(issuer=%s)) +ldapdevel_attributes:issuer = servercertificate, servercertificate;binary diff -BbruN freeswan-1.91.orig/doc/pkix/examples/privkey.pem freeswan-1.91/doc/pkix/examples/privkey.pem --- freeswan-1.91.orig/doc/pkix/examples/privkey.pem Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/privkey.pem Mon Jul 16 23:26:30 2001 @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQCoqQwsIfybAtb0mMfD3NGNMZH7ckGrCehSm741ddjw9rW6igzZ +AptaqQ2Y5raPl0XrF+MQI8SQkfTtzP92/ZU9eqbEWbBFRfYLqckMd21eU9GHDVl5 +UPmUwWSOXuE4lK58f2heEFE975yf9CsIvOuas33FsiuYtO5UEmzapAVAnQIDAQAB +AoGAXUzWvPs4IBAcFUcHCyR2j6LiXLTB+voKGNirCivdDL+NnFmN7eZxRl/Kc9D9 +IMXQGdMm+uCudkMnuPz0PUDeczQST46jiTlG5vkQdj3zpmz/x73t5I4E8vFSX6A4 +gKREFeGxSCEm0THNusBKk1Q+huHUDKw4mFh85MTopy32McECQQDVWcc3BMlDICG2 +6bFc3+1ieeVIKoD2GnJR7b/GU57umLFyDmSFwOkTTt7VWp3jV/81Oy+xBe3cC8Fm +mFC/e45VAkEAymA9ke8XFduafs2Q+nsbfx4QI+f8lAd51pBR4A4J+W50JLO1/WqC +PwOXwVPRCPyzHiY9B8L9KPrFKSwVedihKQJBAKnGCl/+wAVZcVqztf649pbRdyGp +KPwt6WDGtz+j1Sn6eeHQEC/bZd2Geo3+0PtTT/NVCMtuc2wSMrFobYEiWg0CQQCl +lf9qw5049jlAHYTNXiNObFO6fVuN51wKcoV7dSE2JOkFCsISuq4dTxxBRApadyE7 +vv/atPGdMSpXGMntq5GZAkEA1PJ0w4WSC3sW3guq4WzDLWqmbK2pOvC40ATZR67y +lYC1okanKDsRam0remPY7xWZ8WACJx5KOIvYgXhX+dNXPg== +-----END RSA PRIVATE KEY----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/psk.conf freeswan-1.91/doc/pkix/examples/psk.conf --- freeswan-1.91.orig/doc/pkix/examples/psk.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/psk.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,9 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + authby=psk + auto=add diff -BbruN freeswan-1.91.orig/doc/pkix/examples/pubcert.pem freeswan-1.91/doc/pkix/examples/pubcert.pem --- freeswan-1.91.orig/doc/pkix/examples/pubcert.pem Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/pubcert.pem Mon Jul 16 23:26:30 2001 @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=CA, ST=Ontario, L=Ottawa, O=Rebel.com, OU=SoftEng, CN=CA_arm-devel/Email=luc.lanthier@rebel.com + Validity + Not Before: Feb 14 20:59:13 2001 GMT + Not After : Feb 14 20:59:13 2002 GMT + Subject: C=CA, ST=Ontario, O=Rebel.com, OU=SoftEng, CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:a8:a9:0c:2c:21:fc:9b:02:d6:f4:98:c7:c3:dc: + d1:8d:31:91:fb:72:41:ab:09:e8:52:9b:be:35:75: + d8:f0:f6:b5:ba:8a:0c:d9:02:9b:5a:a9:0d:98:e6: + b6:8f:97:45:eb:17:e3:10:23:c4:90:91:f4:ed:cc: + ff:76:fd:95:3d:7a:a6:c4:59:b0:45:45:f6:0b:a9: + c9:0c:77:6d:5e:53:d1:87:0d:59:79:50:f9:94:c1: + 64:8e:5e:e1:38:94:ae:7c:7f:68:5e:10:51:3d:ef: + 9c:9f:f4:2b:08:bc:eb:9a:b3:7d:c5:b2:2b:98:b4: + ee:54:12:6c:da:a4:05:40:9d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + IPsec Certificate for arm-devel.netwinder.org + X509v3 Subject Key Identifier: + 98:76:ED:A5:41:7C:28:3C:C8:63:0F:09:F7:DE:9E:B2:00:B6:36:FE + X509v3 Authority Key Identifier: + keyid:7A:38:75:E9:B9:94:AB:B6:00:C5:36:81:EA:A5:60:3E:FA:FE:E4:E1 + DirName:/C=CA/ST=Ontario/L=Ottawa/O=Rebel.com/OU=SoftEng/CN=CA_arm-devel/Email=luc.lanthier@rebel.com + serial:00 + + X509v3 Subject Alternative Name: + email:luc.lanthier@rebel.com, DNS:arm-devel.netwinder.org, IP Address:10.8.49.122 + X509v3 Issuer Alternative Name: + email:luc.lanthier@rebel.com + Signature Algorithm: md5WithRSAEncryption + bb:a9:1a:f4:e3:55:c8:f6:e7:d6:32:cb:a2:2f:6d:58:a3:5d: + 8f:5a:0d:95:53:c7:bf:06:e7:3b:ca:99:48:99:2f:55:28:5a: + 9e:37:ef:3b:44:73:1e:e0:61:93:43:f8:04:6b:06:1e:68:e5: + 3e:a2:10:53:94:2f:66:76:fc:66:93:d4:5e:76:cf:2d:18:e2: + ff:eb:c0:77:c9:d5:4d:00:60:34:50:59:69:b9:7d:07:fb:ca: + 8b:6e:ee:5c:d2:d9:06:2f:ee:df:d8:09:12:76:bc:b5:17:80: + a8:d6:a7:25:59:5c:b4:65:cb:29:b1:cd:77:29:e9:c4:03:00: + ea:c4 +-----BEGIN CERTIFICATE----- +MIIEUTCCA7qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJUmVi +ZWwuY29tMRAwDgYDVQQLEwdTb2Z0RW5nMRUwEwYDVQQDFAxDQV9hcm0tZGV2ZWwx +JTAjBgkqhkiG9w0BCQEWFmx1Yy5sYW50aGllckByZWJlbC5jb20wHhcNMDEwMjE0 +MjA1OTEzWhcNMDIwMjE0MjA1OTEzWjCBjjELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT +B09udGFyaW8xEjAQBgNVBAoTCVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEg +MB4GA1UEAxMXYXJtLWRldmVsLm5ldHdpbmRlci5vcmcxJTAjBgkqhkiG9w0BCQEW +Fmx1Yy5sYW50aGllckByZWJlbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +AoGBAKipDCwh/JsC1vSYx8Pc0Y0xkftyQasJ6FKbvjV12PD2tbqKDNkCm1qpDZjm +to+XResX4xAjxJCR9O3M/3b9lT16psRZsEVF9gupyQx3bV5T0YcNWXlQ+ZTBZI5e +4TiUrnx/aF4QUT3vnJ/0Kwi865qzfcWyK5i07lQSbNqkBUCdAgMBAAGjggG1MIIB +sTAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwPAYJ +YIZIAYb4QgENBC8WLUlQc2VjIENlcnRpZmljYXRlIGZvciBhcm0tZGV2ZWwubmV0 +d2luZGVyLm9yZzAdBgNVHQ4EFgQUmHbtpUF8KDzIYw8J996esgC2Nv4wgcEGA1Ud +IwSBuTCBtoAUejh16bmUq7YAxTaB6qVgPvr+5OGhgZqkgZcwgZQxCzAJBgNVBAYT +AkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoT +CVJlYmVsLmNvbTEQMA4GA1UECxMHU29mdEVuZzEVMBMGA1UEAxQMQ0FfYXJtLWRl +dmVsMSUwIwYJKoZIhvcNAQkBFhZsdWMubGFudGhpZXJAcmViZWwuY29tggEAMEAG +A1UdEQQ5MDeBFmx1Yy5sYW50aGllckByZWJlbC5jb22CF2FybS1kZXZlbC5uZXR3 +aW5kZXIub3JnhwQKCDF6MCEGA1UdEgQaMBiBFmx1Yy5sYW50aGllckByZWJlbC5j +b20wDQYJKoZIhvcNAQEEBQADgYEAu6ka9ONVyPbn1jLLoi9tWKNdj1oNlVPHvwbn +O8qZSJkvVShanjfvO0RzHuBhk0P4BGsGHmjlPqIQU5QvZnb8ZpPUXnbPLRji/+vA +d8nVTQBgNFBZabl9B/vKi27uXNLZBi/u39gJEna8tReAqNanJVlctGXLKbHNdynp +xAMA6sQ= +-----END CERTIFICATE----- diff -BbruN freeswan-1.91.orig/doc/pkix/examples/rsasig-rw.conf freeswan-1.91/doc/pkix/examples/rsasig-rw.conf --- freeswan-1.91.orig/doc/pkix/examples/rsasig-rw.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/rsasig-rw.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,12 @@ +conn test + left=0.0.0.0 + leftupdown=/usr/lib/ipsec/updown.netwinder + leftrsasigkey=0x010383adc0c40d031b8b51445074a015b6f6575221df37a23c597acafa7b588eccaeac2a705ca95c7062b7808849728a9083daf7e8f73335ecfdbfe18dda96b4c6b9c47cc695d1d9c20a92ce652cb0cd8b71af87cfb84d4ef5e02f13ef2233da2c98e5147b9092a5ef9f2789defb0b45d47570c1662bf8f159ae8e82107850184055 + leftid="@arm1.netwinder.org" + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + rightrsasigkey=0x0103e39df4e5d9cdfb1bd781cc516b99053af9d39f97230e663ecdf77cb14764fcd7aadb274b2da2eaa6c8b7f3764e1b87a5ae5d9f7cafdad01dd95518da017794fcf7c86f435f7b7ce45429414d9c099ebb91d8a3f54514be78f9b801b02608e8299a5d19a3a4fa5510d0d318b692c649dc3b37287153852a9ac81891d140a38a0d + rightid="@arm-devel.netwinder.org" + authby=rsasig + auto=add diff -BbruN freeswan-1.91.orig/doc/pkix/examples/rsasig.conf freeswan-1.91/doc/pkix/examples/rsasig.conf --- freeswan-1.91.orig/doc/pkix/examples/rsasig.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/examples/rsasig.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,13 @@ +conn test + left=10.1.49.124 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.netwinder + leftrsasigkey=0x010383adc0c40d031b8b51445074a015b6f6575221df37a23c597acafa7b588eccaeac2a705ca95c7062b7808849728a9083daf7e8f73335ecfdbfe18dda96b4c6b9c47cc695d1d9c20a92ce652cb0cd8b71af87cfb84d4ef5e02f13ef2233da2c98e5147b9092a5ef9f2789defb0b45d47570c1662bf8f159ae8e82107850184055 + leftid="@arm1.netwinder.org" + right=10.8.49.122 + rightnexthop=10.8.54.1 + rightupdown=/usr/lib/ipsec/updown.netwinder + rightrsasigkey=0x0103e39df4e5d9cdfb1bd781cc516b99053af9d39f97230e663ecdf77cb14764fcd7aadb274b2da2eaa6c8b7f3764e1b87a5ae5d9f7cafdad01dd95518da017794fcf7c86f435f7b7ce45429414d9c099ebb91d8a3f54514be78f9b801b02608e8299a5d19a3a4fa5510d0d318b692c649dc3b37287153852a9ac81891d140a38a0d + rightid="@arm-devel.netwinder.org" + authby=rsasig + auto=add diff -BbruN freeswan-1.91.orig/doc/pkix/ldap/LDIF.sh freeswan-1.91/doc/pkix/ldap/LDIF.sh --- freeswan-1.91.orig/doc/pkix/ldap/LDIF.sh Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/ldap/LDIF.sh Mon Jul 16 23:26:30 2001 @@ -0,0 +1,89 @@ +#!/usr/bin/bash +if [ -d /var/lib/ssl ]; then + SSLDIR=/var/lib/ssl +elif [ -d /usr/lib/ssl ]; then + SSLDIR=/usr/lib/ssl +elif [ -d /usr/local/lib/ssl ]; then + SSLDIR=/usr/local/lib/ssl +elif [ -d /usr/share/ssl ]; then + SSLDIR=/usr/share/ssl +else + echo "ERROR: Cannot determine location of ssl directory." + exit 1 +fi + +function openssl_out () +{ + openssl x509 -in $1 -inform PEM -outform DER | \ + ldif -b servercertificate + openssl x509 -in $1 -noout -subject | \ + sed -e 's/^subject=/subject: /' + openssl x509 -in $1 -noout -issuer | \ + sed -e 's/^issuer=/issuer: /' +} +###### First, create entries for manager and CA. +cat <, dc= + objectclass: dcObject + objectclass: organization + o: + dc: + + dn: cn=Manager, dc=, dc= + objectclass: organizationalRole + cn: Manager + +Now, you may run ldapadd(1) to insert these entries into your directory. + ldapadd -D "cn=Manager, dc=, dc=" -W -f example.ldif + + +Now we're ready to verify the added entries are in your directory. You +can use any LDAP client to do this, but our example uses the +ldapsearch(1) tool. Remember to replace dc=example,dc=com with the correct +values for your site: + ldapsearch -b 'dc=example,dc=com' '(objectclass=*)' + +----------------------------------------------------------------- + + +3- How I created my own LDIF file +----------------------------------------------------------------- +Try to keep track of which certificate belongs to which host while +creating the CA. The CA will only store the certificates in a +simplified naming format. +ie: /usr/share/ssl/certs/01.pem + +If you forget, query the certificate, and look at the CN part of the +subject line. If created correctly, the CommonName will contain +the hostname. + +========================= +[root@arm-devel ipsec]# openssl x509 -in /usr/share/ssl/certs/01.pem \ + -noout -subject +subject=/C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm-devel.netwinder.org/Email=luc.lanthier@rebel.com +========================= + +To save me time, I created a shell script much like the following to speed up +the generation of LDIF files. +----------- LDIF.sh: +#!/usr/bin/bash + +function openssl_out () +{ + openssl x509 -in $1 -inform PEM -outform DER | \ + ldif -b servercertificate + openssl x509 -in $1 -noout -subject | \ + sed -e 's/^subject=/subject: /' + openssl x509 -in $1 -noout -issuer | \ + sed -e 's/^issuer=/issuer: /' +} + +###### First, create entries for manager and CA. +cat < LDIF +ldif2ldbm -i LDIF +slapd -s 1 +----------------------------------------------------------------- + + +6- How I access the ldap DB from freeswan, the config files: +----------------------------------------------------------------- +The following file is used by FreeSWAN's pkix ldap lookup. +"ldapnd" in the front of each name is the name of the server the lookup +is done on. If you wish to access 2 or more different ldap servers, just +copy the entire section a second time, while using the new header name. +Keep in mind to change the domain and server hostname IP address. +-- /etc/ipsec/ldap.cnf ------------------------------------------ +ldapnd_host_name = 10.8.49.100 +ldapnd_base = dc=netwinder,dc=org +ldapnd_filter:uid = (uid=%s) + +ldapnd_attributes:*:crl = certificaterevocationlist, certificaterevocationlist;binary +ldapnd_filter:*:crl = (&(objectclass=certificationAuthority)(cn=CA)) + +ldapnd_filter:ca = (objectclass=certificationauthority) + +ldapnd_filter:dns = (&(objectclass=hostRecord)(dNSRecord=%s)) +ldapnd_attributes:dns = servercertificate, servercertificate;binary + +ldapnd_filter:ip = (&(objectclass=hostRecord)(ipv4Address=%s)) +ldapnd_attributes:ip = servercertificate, servercertificate;binary + +ldapnd_filter:subject = (&(objectclass=hostRecord)(subject=%s)) +ldapnd_attributes:subject = servercertificate, servercertificate;binary + +ldapnd_filter:issuer = (&(objectclass=hostRecord)(issuer=%s)) +ldapnd_attributes:issuer = servercertificate, servercertificate;binary +----------------------------------------------------------------- + +The following is an example config entry for freeswan to use. You +can either enter these settings in '/etc/ipsec.conf', or create +a separate file with these settings to use. '/etc/ipsec.conf' can load +separate files with 'include ' commands. +-- freeswan config ---------------------------------------------- +conn test_host-host + left=10.1.49.233 + leftnexthop=10.1.1.7 + leftupdown=/usr/lib/ipsec/updown.firewall + right=10.8.49.101 + rightupdown=/usr/lib/ipsec/updown.firewall + rightnexthop=10.8.54.1 + auto=add + authby=cert + # certfile: full path to private key + certfile=/etc/ipsec/pubcert.pem + # keyfile: full path to public key in unencrypted format + keyfile=/etc/ipsec/privkey.pem + certpath=ldap:/etc/ipsec/ldap.cnf:ldapnd + certopts=send,pk,rev + #The certificate are found using IKE's ID_DER_ASN1_DN ID payload + #You can provide the info by running: + # ipsec fswcert -d a -l /etc/ipsec/[hostleft].pem + #left DN: /C=CA/ST=Ontario/O=Rebel.com/OU=x86eng/CN=Luc Lanthier/Email=firesoul@netwinder.org + leftid=@~308182310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D310F300D060355040B1306783836656E67311530130603550403130C4C7563204C616E74686965723125302306092A864886F70D010901161666697265736F756C406E657477696E6465722E6F7267 + # ipsec fswcert -d a -l /etc/ipsec/[hostright].pem + #right DN: /C=CA/ST=Ontario/O=Rebel.com/OU=SE/CN=Luc Lanthier/Email=firesoul@pet.notbsd.org + rightid=@~307F310B30090603550406130243413110300E060355040813074F6E746172696F31123010060355040A1309526562656C2E636F6D310B3009060355040B13025345311530130603550403130C4C7563204C616E74686965723126302406092A864886F70D010901161766697265736F756C407065742E6E6F746273642E6F7267 +----------------------------------------------------------------- + +The certificate are found using IKE's ID_DER_ASN1_DN ID payload +You can provide the info by running on each respective host: +----------------------------------------------------------------- +ipsec fswcert -d a -l /etc/ipsec/[hostleft].pem +ipsec fswcert -d a -r /etc/ipsec/[hostright].pem + + diff -BbruN freeswan-1.91.orig/doc/pkix/ldap/regen-ldap_ca.sh freeswan-1.91/doc/pkix/ldap/regen-ldap_ca.sh --- freeswan-1.91.orig/doc/pkix/ldap/regen-ldap_ca.sh Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/ldap/regen-ldap_ca.sh Mon Jul 16 23:26:30 2001 @@ -0,0 +1,8 @@ +#!/bin/sh +cd /usr/share/ssl/ +mkdir -p ldap-ldbm +killall slapd +rm -f ldap-ldbm/* +LDIF.sh > LDIF +ldif2ldbm -i LDIF +slapd -s 1 diff -BbruN freeswan-1.91.orig/doc/pkix/ldap/slapd.at-x509.conf freeswan-1.91/doc/pkix/ldap/slapd.at-x509.conf --- freeswan-1.91.orig/doc/pkix/ldap/slapd.at-x509.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/ldap/slapd.at-x509.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1 @@ +attribute servercertificate bin diff -BbruN freeswan-1.91.orig/doc/pkix/ldap/slapd.conf freeswan-1.91/doc/pkix/ldap/slapd.conf --- freeswan-1.91.orig/doc/pkix/ldap/slapd.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/ldap/slapd.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,39 @@ +# +# See slapd.conf(5) for details on configuration options. +# This file should NOT be world readable. +# +include /etc/openldap/slapd.at.conf +include /etc/openldap/slapd.oc.conf +schemacheck off +#referral ldap://root.openldap.org/ + +pidfile /var/run/slapd.pid +argsfile /var/run/slapd.args + +################# +# x509 +include /etc/openldap/slapd.at-x509.conf +include /etc/openldap/slapd.oc-x509.conf + + +####################################################################### +# ldbm database definitions +####################################################################### + +database ldbm +suffix "dc=netwinder, dc=org" +#suffix "o=My Organization Name, c=US" +rootdn "cn=Manager, dc=netwinder, dc=org" +#rootdn "cn=Manager, o=My Organization Name, c=US" +# cleartext passwords, especially for the rootdn, should +# be avoid. See slapd.conf(5) for details. +rootpw ipsecsecret +# database directory +# this directory MUST exist prior to running slapd AND +# should only be accessable by the slapd/tools Mode 700 recommended. +#directory /usr/local/var/openldap-ldbm +directory /usr/share/ssl/ldap-ldbm + +index default pres,eq +index objectClass,uid +index cn,sn eq,sub,approx diff -BbruN freeswan-1.91.orig/doc/pkix/ldap/slapd.oc-x509.conf freeswan-1.91/doc/pkix/ldap/slapd.oc-x509.conf --- freeswan-1.91.orig/doc/pkix/ldap/slapd.oc-x509.conf Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/ldap/slapd.oc-x509.conf Mon Jul 16 23:26:30 2001 @@ -0,0 +1,8 @@ +objectclass hostRecord + requires + objectClass + allows + dNSRecord, + ipv4Address, + servercertificate, + subject diff -BbruN freeswan-1.91.orig/doc/pkix/openssl-ca.quickstart freeswan-1.91/doc/pkix/openssl-ca.quickstart --- freeswan-1.91.orig/doc/pkix/openssl-ca.quickstart Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/openssl-ca.quickstart Thu Aug 16 15:10:52 2001 @@ -0,0 +1,272 @@ +This document is much like a quickstart, but in an even shorter form. +These are the steps I took to create an opensourced CA capable of signing +certificates. + +How I set up a CA on RedHat 6.2 and used it: + + +1- install openssl on the CA. +If the openssl package is already installed, then ignore this +section. Please note: requires 0.9.5a. I doubt FreeSWAN will +run with openssl 0.9.6. +---------------------------------------------------------------- +cd /usr/src/redhat/SRPMS +scp root@10.8.49.101:/usr/src/redhat/SRPMS/openssl*.src.rpm . +rpm --rebuild openssl-0.9.5a-1.src.rpm +cd ../RPMS/i386/ +rpm -i openssl-* + + +2- Setting up the openssl CA. +The openssl RPM already create a /var/lib/ssl directory. If you installed +openssl from source, look for it in either /usr/ssl, /usr/local/ssl, +or even /usr/share/ssl. +---------------------------------------------------------------- +cd /var/lib/ssl +# Note! Newer redhat openssl RPMs created the dir in /usr/share/ssl + +# see README.certificates, section 4.1, for instructions +# on the creation/addition of openssl.cnf +# Note! Since Redhat redid its openssl packages, openssl.cnf is present. +# Use it instead. +vi openssl.cnf + +# see README.certificates, section 4.1, for instructions +# on the CA extensions to define in ca.ext +vi ca.ext + +openssl req -new -newkey rsa:1024 -keyout \ + private/cakey.pem -out careq.pem +# Please enter in a password to be able to use the CA's signing cert once +# it is generated. Only that password will unlock it for use. +# Data may be asked of you to enter. +# ____________________________________________________________________ +# --- Country Name (2 letter code) [AU]: +# --- State or Province Name (full name) [Some-State]: +# --- Locality Name (eg, city) []: +# **important** The OrgName must match on ALL certs which will be signed +# by this self-signed cert. +# --- Organization Name (eg, company) [Internet Widgits Pty Ltd]: +# --- Organizational Unit Name (eg, section) []: +# **Note** Try to use the machine's FQDN as common name. Not your own +# name. : +# --- Common Name (eg, your name or your server's hostname) []: +# --- Email Address []: +# ____________________________________________________________________ +# +# Unimportant: +# Please enter the following 'extra' attributes +# to be sent with your certificate request +# A challenge password []: +# An optional company name []: + +# sign our own CA certificate. +openssl x509 -CAcreateserial -signkey private/cakey.pem -req \ + -in careq.pem -out cacert.pem -days 2000 -extfile ca.ext + +touch index.txt +echo "01" > serial + +# at this point we can create a CRL. There will be future modifications +# to openssl.cnf. Make a backup of it and use alternate for CRL generation. +cp openssl.cnf openssl.crl.cnf +openssl ca -config openssl.crl.cnf -gencrl -out crl.pem + + +3- adding cacert.pem and crl.pem to hosts (OPTIONAL) +Unless you are using LDAP lookup, you will have to make the certificate +available on all the client hosts. Of course, make sure the destination +directory exists. +---------------------------------------------------------------- +scp crl.pem 10.1.49.233:/etc/ipsec +scp cacert.pem 10.1.49.233:/etc/ipsec +scp crl.pem 10.8.49.101:/etc/ipsec +scp cacert.pem 10.8.49.101:/etc/ipsec + + +4- Each client host -- generate certificate requests. +The CA's signing certificate is ready. Now we can create the client +certificates. +NOTE: a CA can also be its own client if a separate certificate +is generated. Both the cacert.pem and the host certificates must be +made available as standard host certificates, as if they were 2 separate +hosts. +---------------------------------------------------------------- +mkdir -p /etc/ipsec +cd /etc/ipsec + +# Make sure the info entered for the "CommonName" for each client +# is DIFFERENT, usually containing the hostname. +# Make sure the "OrgName" used is the same as the one used +# for cacert.pem's creation. +# Make sure you don't create this certificate with a password. +# This certificate must be available for use without user intervention. +# (that includes password entry) +openssl req -new -newkey rsa:1024 -nodes -keyout \ + `hostname`.key -out `hostname`.req.pem +############################ +# OR DSA: (still unsupported. left note in to remember how to do it) +# openssl dsaparam 1024 -out dsa_params.txt +# chmod 400 dsa_params.txt +#openssl req -new -newkey dsa:dsa_params.txt -nodes -keyout \ +# /etc/ipsec/`hostname`.key -out /etc/ipsec/`hostname`.req.pem +#remember that all parties must use DSA +############################ + +# how about a generic name on each host for ease? +ln -fs `hostname`.key privkey.pem +ln -fs `hostname`.pem pubcert.pem; # will be created soon. + +# protect the private key. +chmod 400 `hostname`.key + + + +5- Signing certificates on the CA host +Signing the certificates is a necessary step in the pkix CA setup, +but first, you must give your CA the ability. +You may find the signIPSEC script handy. +---------------------------------------------------------------- +########################### +# Create/Undate the following ONCE. +# Once again, note the paths may be wrong. +vi /etc/openssl.cnf; # (see README.certificates section 4.6) + +# Either create signIPSEC, or copy it from the current directory. +# to /usr/local/bin on the CA host. +vi /usr/local/bin/signIPSEC; # (see README.certificates section 4.6) + +chmod 700 /usr/local/bin/signIPSEC +# use: signIPSEC foo.mydomain.com 192.168.1.5 foo.req + +# Once again, CD to the correct path. +cd /var/lib/ssl/ +mkdir -p newcerts + +# The following steps can be reused over and over, for each host to add +# +# 1- copy over the unsigned public cert from the host. +scp root@10.1.49.233:/etc/ipsec/*.req.pem . +# +# 2- sign it with the correct values. +signIPSEC sticky.netwinder.org 10.1.49.233 sticky.req.pem +# +# 3- copy the newly signed certificate to the host. +scp newcerts/`cat serial.old`.pem root@10.1.49.233:/etc/ipsec/sticky.pem +# +# 4- rehash the current database of certificates handled by the CA. +mv newcerts/* certs/ +c_rehash certs + + + +6- CA host: prepping flat file for client hosts +Here's a short script for quick generations of text flatfiles needed +by the various clients. LDAP lookup is prefered, but flatfile is available +for testing or simplicity. +The script is available as "CA-regenerate-flatfile.sh". +---------------------------------------------------------------- +#!/bin/sh -x + +if [ -d /var/lib/ssl ]; then + cd /var/lib/ssl +elif [ -d /usr/lib/ssl ]; then + cd /usr/lib/ssl +elif [ -d /usr/local/lib/ssl ]; then + cd /usr/local/lib/ssl +elif [ -d /usr/share/ssl ]; then + cd /usr/share/ssl +else + echo "ERROR: Cannot determine location of ssl directory." + exit 1 +fi + +cat /dev/null > flatfile.txt + +for ii in certs/*.pem cacert.pem crl.pem; +do + if [ "`basename $ii`" != "crl.pem" ] && [ "`basename $ii`" != "cacert.pem" ]; + then + perl -e "open(IN, \"openssl x509 -in $ii -noout -text \|\"); \ + @IN = ; \ + foreach (@IN) { \ + if (/IP Address:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})/) { \ + print \"ip: \$1\\n\"; \ + } \ + if (/DNS:([^, ]*).*$/) { \ + print \"dns: \$1\\n\"; \ + } \ + };" >> flatfile.txt + fi + cat $ii | \ + perl -e '$printme = 0; while (<>) { if (/---BEGIN/) {$printme = 1;}; if ($printme) {print STDOUT $_;} }; print STDOUT "\n";' \ + >> flatfile.txt +done +---------------------------------------------------------------- + +# the flatfile is created. Send to Client hosts. +scp flatfile.txt root@10.1.49.233:/etc/ipsec +scp flatfile.txt root@10.8.49.101:/etc/ipsec + + + +7- revoking a certificate +Sometimes it becomes necessary to revoke a certificate. +---------------------------------------------------------------- +# First, find out which certificate has to be revoked. If properly +# generated, the CommonName (CN) will be the certificate's owner +# hostname. Replace "WANTED_HOSTNAME" by the hostname to look for. +cd /var/lib/ssl/ +( +for certs in certs/*.pem; do + echo -n "$certs: " + openssl x509 -in $certs -noout -subject +done +) | grep WANTED_HOSTNAME + +# Example output: +# 02.pem: subject=/C=CA/ST=Ontario/O=Rebel.com/OU=SoftEng/CN=arm1.netwinder.org/Email=firesoul@netwinder.org + +# next, proceed to revoke the certificate. +# once again, double-check the paths. +openssl ca -revoke /var/lib/ssl/certs/02.pem +# remember to use config for CRL generation. +openssl ca -config openssl.crl.cnf -gencrl -out /var/lib/ssl/crl.pem + +# If we're using LDAP, the new crl.pem will be used automatically. +# Otherwise, it has to be copied to each one of the client hosts. +scp crl.pem root@10.1.49.233:/etc/ipsec +scp crl.pem root@10.8.49.101:/etc/ipsec + + +8- converting to and from PKCS#7 enveloped certificates + + From PKCS7 in PEM format to certificates: + openssl pkcs7 -in x86rack1.pk7 -print_certs -inform PEM + From PKCS7 in DER format to certificates: + openssl pkcs7 -in x86rack1.pk7 -print_certs -inform DER + + From certificate (with available CRL) to DER PKCS7: + openssl crl2pkcs7 -in dir/crl.pem -certfile x86rack1.pem -outform DER \ + -out x86rack1.pk7 + From certificate (no crl) to DER PKCS7: + openssl crl2pkcs7 -nocrl -certfile x86rack1.pem -outform DER \ + -out x86rack1.pk7 + +Sending with CRL gives an idea what your CA is from the other end's +perspective. Using that info, cross referencing can occur and a +connection be established despite being registered on different CAs. + + +9- converting to and from PKCS#12 "bag"s. + + Extracting private key from PKCS12 in DER format: + openssl pkcs12 -in x86rack1.p12 -nocerts -out x86rack1.key + Extracting public certificate(s) from PKCS12 in DER format: + openssl pkcs12 -in x86rack1.p12 -nokeys -out x86rack1.pem + + Creating a PKCS12 file: + openssl pkcs12 -export -in x86rack1.pem -inkey x86rack1.key \ + -des3 -name "my pkcs12" -out x86rack1.p12 + Extracting a PKCS12 file: + openssl pkcs12 -in x86rack1.p12 -nodes diff -BbruN freeswan-1.91.orig/doc/pkix/signIPSEC freeswan-1.91/doc/pkix/signIPSEC --- freeswan-1.91.orig/doc/pkix/signIPSEC Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/signIPSEC Mon Jul 16 23:26:30 2001 @@ -0,0 +1,38 @@ +#!/bin/bash + +# Simple wrapper for "openssl ca" that sets environment to pass in +# values for the svr_cert extension +# P.J.Onion 23/9/1999 +# updated by: Luc Lanthier 20010214 +if [ -d /var/lib/ssl ]; then + SSLDIR="/var/lib/ssl"; +elif [ -d /usr/lib/ssl ]; then + SSLDIR="/usr/lib/ssl"; +elif [ -d /usr/local/lib/ssl ]; then + SSLDIR="/usr/local/lib/ssl"; +elif [ -d /usr/share/ssl ]; then + SSLDIR="/usr/share/ssl"; +else + echo "ERROR: Cannot determine location of ssl directory." + exit 1 +fi + + +if test $# -ne 3 ; then + echo "Usage: $0 hostname ipaddress reqfile" + exit 1 +fi + + +HOSTFQDN=$1 +HOSTIP=$2 +NSCOMMENT="IPsec Certificate for $1" +EXTENSION=svr_cert + +export HOSTFQDN HOSTIP NSCOMMENT EXTENSION +if (which openssl &> /dev/null) ; then + openssl ca -in $3 +else + echo "ERROR: Cannot locate/execute openssl binary." + exit 1 +fi diff -BbruN freeswan-1.91.orig/klips/net/ipsec/Config.in freeswan-1.91/klips/net/ipsec/Config.in --- freeswan-1.91.orig/klips/net/ipsec/Config.in Thu Jun 14 15:35:07 2001 +++ freeswan-1.91/klips/net/ipsec/Config.in Mon Jul 16 23:26:30 2001 @@ -27,6 +27,7 @@ bool ' IPSEC: Encapsulating Security Payload' CONFIG_IPSEC_ESP if [ "$CONFIG_IPSEC_ESP" = "y" ]; then bool ' 3DES encryption algorithm' CONFIG_IPSEC_ENC_3DES + bool ' DES encryption algorithm' CONFIG_IPSEC_ENC_DES fi bool ' IPSEC: IP Compression' CONFIG_IPSEC_IPCOMP diff -BbruN freeswan-1.91.orig/klips/net/ipsec/Makefile freeswan-1.91/klips/net/ipsec/Makefile --- freeswan-1.91.orig/klips/net/ipsec/Makefile Thu Jun 14 15:35:07 2001 +++ freeswan-1.91/klips/net/ipsec/Makefile Mon Jul 16 23:26:30 2001 @@ -57,6 +57,7 @@ EXTRA_CFLAGS += -Wbad-function-cast obj-$(CONFIG_IPSEC_ENC_3DES) += libdes/libdes.a +obj-$(CONFIG_IPSEC_ENC_DES) += libdes/libdes.a obj-$(CONFIG_IPSEC_AUTH_HMAC_MD5) += ipsec_md5c.o obj-$(CONFIG_IPSEC_AUTH_HMAC_SHA1) += ipsec_sha1.o obj-$(CONFIG_IPSEC_IPCOMP) += ipcomp.o zlib/zlib.a diff -BbruN freeswan-1.91.orig/klips/net/ipsec/defconfig freeswan-1.91/klips/net/ipsec/defconfig --- freeswan-1.91.orig/klips/net/ipsec/defconfig Thu Nov 30 12:26:56 2000 +++ freeswan-1.91/klips/net/ipsec/defconfig Mon Jul 16 23:26:30 2001 @@ -43,6 +43,7 @@ # Encryption algorithm(s): CONFIG_IPSEC_ENC_3DES=y +CONFIG_IPSEC_ENC_DES=y # IP Compression: new, probably still has minor bugs. CONFIG_IPSEC_IPCOMP=y diff -BbruN freeswan-1.91.orig/klips/net/ipsec/ipsec_esp.h freeswan-1.91/klips/net/ipsec/ipsec_esp.h --- freeswan-1.91.orig/klips/net/ipsec/ipsec_esp.h Thu Jun 14 15:35:08 2001 +++ freeswan-1.91/klips/net/ipsec/ipsec_esp.h Mon Jul 16 23:26:30 2001 @@ -40,6 +40,27 @@ #define DB_ES_OH 0x0400 #define DB_ES_REPLAY 0x0800 +struct espdesold_xdata +{ + int edx_ivlen; /* 4 or 8 */ + union + { + __u8 Iv[8]; /* that's enough space */ + __u32 Ivl[2]; + __u64 Ivq; + }Iu; +#define edx_iv Iu.Iv +#define edx_ivl Iu.Ivl +#define edx_ivq Iu.Ivq + union + { + __u8 Rk[8]; + __u32 Eks[16][2]; + }Xu; +#define edx_rk Xu.Rk +#define edx_eks Xu.Eks +}; + struct espblkrply_edata { __u16 eme_klen; /* encryption key length */ @@ -64,6 +85,19 @@ }; #ifdef __KERNEL__ +struct espdesmd5_xdata +{ + __u8 edmx_flags; /* same as before */ + __u8 edmx_ooowin; /* out-of-order window size */ + __u16 edmx_ivlen; /* IV length */ + __u32 edmx_bitmap; /* this&next should be 4 bytes each */ + __u32 edmx_lastseq; /* in host order */ + __u32 edmx_eks[16][2]; /* the key schedule */ + __u32 edmx_iv[2]; /* constant IV */ + MD5_CTX edmx_ictx; /* derived from HMAC_key */ + MD5_CTX edmx_octx; /* ditto */ +}; + struct esp3desmd5_xdata { __u8 edmx_flags; /* same as before */ @@ -89,6 +123,19 @@ MD5_CTX edmx_octx; /* ditto */ }; +struct espdessha1_xdata +{ + __u8 edmx_flags; /* same as before */ + __u8 edmx_ooowin; /* out-of-order window size */ + __u16 edmx_ivlen; /* IV length */ + __u32 edmx_bitmap; /* this&next should be 4 bytes each */ + __u32 edmx_lastseq; /* in host order */ + __u32 edmx_eks[16][2]; /* the key schedule */ + __u32 edmx_iv[2]; /* constant IV */ + SHA1_CTX edmx_ictx; /* derived from HMAC_key */ + SHA1_CTX edmx_octx; /* ditto */ +}; + struct esp3dessha1_xdata { __u8 edmx_flags; /* same as before */ @@ -112,6 +159,17 @@ __u32 edmx_lastseq; /* in host order */ SHA1_CTX edmx_ictx; /* derived from HMAC_key */ SHA1_CTX edmx_octx; /* ditto */ +}; + +struct espdes_xdata +{ + __u8 edmx_flags; /* same as before */ + __u8 edmx_ooowin; /* out-of-order window size */ + __u16 edmx_ivlen; /* IV length */ + __u32 edmx_bitmap; /* this&next should be 4 bytes each */ + __u32 edmx_lastseq; /* in host order */ + __u32 edmx_eks[16][2]; /* the key schedule */ + __u32 edmx_iv[2]; /* constant IV */ }; struct esp3des_xdata diff -BbruN freeswan-1.91.orig/klips/net/ipsec/ipsec_rcv.c freeswan-1.91/klips/net/ipsec/ipsec_rcv.c --- freeswan-1.91.orig/klips/net/ipsec/ipsec_rcv.c Wed Jun 13 16:58:40 2001 +++ freeswan-1.91/klips/net/ipsec/ipsec_rcv.c Mon Jul 16 23:26:30 2001 @@ -77,6 +77,7 @@ int sysctl_ipsec_inbound_policy_check = 1; #ifdef CONFIG_IPSEC_ESP +extern void des_cbc_encrypt(caddr_t, caddr_t, int, caddr_t, caddr_t, int); extern void des_ede3_cbc_encrypt(caddr_t, caddr_t, int, caddr_t, caddr_t, caddr_t, caddr_t, int); #endif /* !CONFIG_IPSEC_ESP */ #if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) @@ -1026,6 +1027,7 @@ #ifdef CONFIG_IPSEC_ESP case IPPROTO_ESP: switch(tdbp->tdb_encalg) { + case ESP_DES: case ESP_3DES: iv[0] = *((__u32 *)(espp->esp_iv) ); iv[1] = *((__u32 *)(espp->esp_iv) + 1); @@ -1043,6 +1045,23 @@ ilen -= esphlen; switch(tdbp->tdb_encalg) { + case ESP_DES: + if ((ilen) % 8) { + tdbp->tdb_encsize_errs += 1; + spin_unlock(&tdb_lock); + printk("klips_error:ipsec_rcv: " + "got packet with esplen = %d from %s -- should be on 8 octet boundary, packet dropped\n", + ilen, + ipaddr_txt); + if(stats) { + stats->rx_errors++; + } + goto rcvleave; + } + des_cbc_encrypt(idat, idat, ilen, + tdbp->tdb_key_e, + (caddr_t)iv, 0); + break; case ESP_3DES: if ((ilen) % 8) { tdbp->tdb_encsize_errs += 1; diff -BbruN freeswan-1.91.orig/klips/net/ipsec/ipsec_tunnel.c freeswan-1.91/klips/net/ipsec/ipsec_tunnel.c --- freeswan-1.91.orig/klips/net/ipsec/ipsec_tunnel.c Thu Jun 14 15:35:10 2001 +++ freeswan-1.91/klips/net/ipsec/ipsec_tunnel.c Mon Jul 16 23:26:30 2001 @@ -103,6 +103,7 @@ #ifdef MSS_HACK #include /* TCP options */ #endif /* MSS_HACK */ +extern void des_cbc_encrypt(caddr_t, caddr_t, int, caddr_t, caddr_t, int); extern void des_ede3_cbc_encrypt(caddr_t, caddr_t, int, caddr_t, caddr_t, caddr_t, caddr_t, int); static __u32 zeroes[64]; @@ -1065,6 +1066,11 @@ #ifdef CONFIG_IPSEC_ESP case IPPROTO_ESP: switch(tdbp->tdb_encalg) { +#ifdef CONFIG_IPSEC_ENC_DES + case ESP_DES: + headroom += sizeof(struct esp); + break; +#endif /* CONFIG_IPSEC_ENC_DES */ #ifdef CONFIG_IPSEC_ENC_3DES case ESP_3DES: headroom += sizeof(struct esp); @@ -1350,6 +1356,11 @@ #ifdef CONFIG_IPSEC_ESP case IPPROTO_ESP: switch(tdbp->tdb_encalg) { +#ifdef CONFIG_IPSEC_ENC_DES + case ESP_DES: + headroom += sizeof(struct esp); + break; +#endif /* CONFIG_IPSEC_ENC_DES */ #ifdef CONFIG_IPSEC_ENC_3DES case ESP_3DES: headroom += sizeof(struct esp); @@ -1447,6 +1458,16 @@ espp->esp_rpl = htonl(++(tdbp->tdb_replaywin_lastseq)); switch(tdbp->tdb_encalg) { +#if defined(CONFIG_IPSEC_ENC_DES) +#ifdef CONFIG_IPSEC_ENC_DES + case ESP_DES: +#endif /* CONFIG_IPSEC_ENC_DES */ + iv[0] = *((__u32*)&(espp->esp_iv) ) = + ((__u32*)(tdbp->tdb_iv))[0]; + iv[1] = *((__u32*)&(espp->esp_iv) + 1) = + ((__u32*)(tdbp->tdb_iv))[1]; + break; +#endif /* defined(CONFIG_IPSEC_ENC_DES) */ #if defined(CONFIG_IPSEC_ENC_3DES) #ifdef CONFIG_IPSEC_ENC_3DES case ESP_3DES: @@ -1478,6 +1499,13 @@ iph->protocol = IPPROTO_ESP; switch(tdbp->tdb_encalg) { +#ifdef CONFIG_IPSEC_ENC_DES + case ESP_DES: + des_cbc_encrypt(idat, idat, ilen, + (caddr_t)tdbp->tdb_key_e, + (caddr_t)iv, 1); + break; +#endif /* CONFIG_IPSEC_ENC_DES */ #ifdef CONFIG_IPSEC_ENC_3DES case ESP_3DES: des_ede3_cbc_encrypt(idat, idat, ilen, @@ -1494,6 +1522,17 @@ } switch(tdbp->tdb_encalg) { +#if defined(CONFIG_IPSEC_ENC_DES) +#ifdef CONFIG_IPSEC_ENC_DES + case ESP_DES: +#endif /* CONFIG_IPSEC_ENC_DES */ + /* XXX update IV with the last 8 octets of the encryption */ + ((__u32*)(tdbp->tdb_iv))[0] = + ((__u32 *)(idat))[(ilen >> 2) - 2]; + ((__u32*)(tdbp->tdb_iv))[1] = + ((__u32 *)(idat))[(ilen >> 2) - 1]; + break; +#endif /* defined(CONFIG_IPSEC_ENC_DES) */ #if defined(CONFIG_IPSEC_ENC_3DES) #ifdef CONFIG_IPSEC_ENC_3DES case ESP_3DES: diff -BbruN freeswan-1.91.orig/klips/net/ipsec/ipsec_xform.c freeswan-1.91/klips/net/ipsec/ipsec_xform.c --- freeswan-1.91.orig/klips/net/ipsec/ipsec_xform.c Thu Jun 14 15:35:11 2001 +++ freeswan-1.91/klips/net/ipsec/ipsec_xform.c Tue Jul 17 14:36:45 2001 @@ -63,12 +63,15 @@ #define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) -extern int des_set_key(caddr_t, caddr_t); +extern int des_set_key_pluto(caddr_t, caddr_t); struct xformsw xformsw[] = { { XF_IP4, 0, "IPv4_Encapsulation"}, { XF_AHHMACMD5, XFT_AUTH, "HMAC_MD5_Authentication"}, { XF_AHHMACSHA1, XFT_AUTH, "HMAC_SHA-1_Authentication"}, +{ XF_ESPDES, XFT_CONF, "DES_Encryption"}, +{ XF_ESPDESMD596, XFT_CONF, "DES-MD5-96_Encryption"}, +{ XF_ESPDESSHA196, XFT_CONF, "DES-SHA1-96_Encryption"}, { XF_ESP3DES, XFT_CONF, "3DES_Encryption"}, { XF_ESP3DESMD596, XFT_CONF, "3DES-MD5-96_Encryption"}, { XF_ESP3DESSHA196, XFT_CONF, "3DES-SHA1-96_Encryption"}, @@ -313,9 +316,9 @@ struct xformsw *xsp; int error = 0; int i; -#if defined(CONFIG_IPSEC_ENC_3DES) +#if defined(CONFIG_IPSEC_ENC_DES) || if defined(CONFIG_IPSEC_ENC_3DES) int error; -#endif /* CONFIG_IPSEC_ENC_3DES */ +#endif /* CONFIG_IPSEC_ENC_{3,}DES */ char sa[SATOA_BUF]; size_t sa_len; @@ -568,6 +571,16 @@ #endif /* CONFIG_IPSEC_AH */ #ifdef CONFIG_IPSEC_ESP +#ifdef CONFIG_IPSEC_ENC_DES + case XF_ESPDES: +#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + case XF_ESPDESMD596: +#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + case XF_ESPDESSHA196: +#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ +#endif /* CONFIG_IPSEC_ENC_DES */ + #ifdef CONFIG_IPSEC_ENC_3DES case XF_ESP3DES: #ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 @@ -607,6 +620,10 @@ case XF_ESP3DES: case XF_ESP3DESMD596: case XF_ESP3DESSHA196: + case XF_ESPDES: + case XF_ESPDESMD596: + case XF_ESPDESSHA196: + if((tdbp->tdb_iv = (caddr_t) kmalloc((tdbp->tdb_iv_size = EMT_ESPDES_IV_SZ), GFP_ATOMIC)) == NULL) { SENDERR(ENOMEM); @@ -618,6 +635,44 @@ } switch(alg) { +#ifdef CONFIG_IPSEC_ENC_DES + case XF_ESPDES: + case XF_ESPDESMD596: + case XF_ESPDESSHA196: + tdbp->tdb_encalg = ESP_DES; + + if (ed->eme_klen != EMT_ESPDES_KEY_SZ) { + KLIPS_PRINT(debug_esp, + "klips_debug:tdb_init: " + "incorrect encryption key size: %d -- must be %d octets (bytes)\n", + ed->eme_klen, EMT_ESPDES_KEY_SZ); + SENDERR(EINVAL); + } + + tdbp->tdb_key_bits_e = ed->eme_klen; + + if((tdbp->tdb_key_e = (caddr_t) + kmalloc((tdbp->tdb_key_e_size = sizeof(struct des_eks)), + GFP_ATOMIC)) == NULL) { + SENDERR(ENOMEM); + } + + error = des_set_key_pluto((caddr_t)(ed->eme_key), + (caddr_t)&((struct des_eks*)(tdbp->tdb_key_e))); + if (error == -1) + printk("klips_debug:tdb_init: " + "parity error in des key\n"); + else if (error == -2) + printk("klips_debug:tdb_init: " + "illegal weak des key\n"); + if (error) { + memset(tdbp->tdb_key_e, 0, sizeof(struct des_eks)); + kfree(tdbp->tdb_key_e); + SENDERR(EINVAL); + } + + break; +#endif /* CONFIG_IPSEC_ENC_DES */ #ifdef CONFIG_IPSEC_ENC_3DES case XF_ESP3DES: case XF_ESP3DESMD596: @@ -649,7 +704,7 @@ ntohl(*((__u32 *)ed->eme_key + i * 2)), ntohl(*((__u32 *)ed->eme_key + i * 2 + 1))); #endif - error = des_set_key((caddr_t)(ed->eme_key) + EMT_ESPDES_KEY_SZ * i, + error = des_set_key_pluto((caddr_t)(ed->eme_key) + EMT_ESPDES_KEY_SZ * i, (caddr_t)&((struct des_eks*)(tdbp->tdb_key_e))[i]); if (error == -1) printk("klips_debug:tdb_init: " @@ -672,6 +727,7 @@ switch(alg) { #ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + case XF_ESPDESMD596: case XF_ESP3DESMD596: case XF_ESPNULLMD596: { @@ -748,6 +804,7 @@ #ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 case XF_ESPNULLSHA196: case XF_ESP3DESSHA196: + case XF_ESPDESSHA196: { SHA1_CTX *ictx; SHA1_CTX *octx; @@ -816,6 +873,7 @@ break; } #endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ + case XF_ESPDES: case XF_ESP3DES: tdbp->tdb_authalg = AH_NONE; break; diff -BbruN freeswan-1.91.orig/klips/net/ipsec/ipsec_xform.h freeswan-1.91/klips/net/ipsec/ipsec_xform.h --- freeswan-1.91.orig/klips/net/ipsec/ipsec_xform.h Thu Jun 14 15:35:11 2001 +++ freeswan-1.91/klips/net/ipsec/ipsec_xform.h Mon Jul 16 23:26:30 2001 @@ -22,16 +22,22 @@ #define XF_IP4 1 /* IPv4 inside IPv4 */ #define XF_AHMD5 2 /* AH MD5 */ #define XF_AHSHA 3 /* AH SHA */ +#define XF_ESPDESOLD 4 /* old ESP DES-CBC */ #define XF_ESP3DES 5 /* ESP DES3-CBC */ #define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */ #define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */ +#define XF_ESPDESMD5 8 /* DES, HMAC-MD-5, 128-bits of authentication */ #define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */ #define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */ +#define XF_ESPDESMD596 11 /* DES, HMAC-MD-5, 96-bits of authentication */ #define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */ #define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */ #define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */ -#define XF_IP6 15 /* IPv6 inside IPv6 */ -#define XF_COMPDEFLATE 16 /* IPCOMP deflate */ +#define XF_ESPDESSHA196 15 /* DES, HMAC-SHA-1, 96-bits of authentication */ +#define XF_ESPDES 16 /* ESP DES */ + +#define XF_IP6 17 /* IPv6 inside IPv6 */ +#define XF_COMPDEFLATE 18 /* IPCOMP deflate */ #define XF_CLR 126 /* Clear SA table */ #define XF_DEL 127 /* Delete SA */ @@ -44,16 +50,20 @@ #define AH_NONE 0 #define AH_MD5 2 #define AH_SHA 3 +#define AH_DES 3 /* IPsec ESP transform values */ #define ESP_NONE 0 +#define ESP_DES_IV64 1 +#define ESP_DES 2 #define ESP_3DES 3 #define ESP_RC5 4 #define ESP_IDEA 5 #define ESP_CAST 6 #define ESP_BLOWFISH 7 #define ESP_3IDEA 8 +#define ESP_DES_IV32 9 #define ESP_RC4 10 #define ESP_NULL 11 @@ -179,6 +189,7 @@ ((x)->tdb_encalg == SADB_X_CALG_DEFLATE ? \ "_DEFLATE" : "_UNKNOWN_comp") : \ (x)->tdb_encalg == ESP_NONE ? "" : \ + (x)->tdb_encalg == ESP_DES ? "_DES" : \ (x)->tdb_encalg == ESP_3DES ? "_3DES" : \ "_UNKNOWN_encr", \ (x)->tdb_authalg == AH_NONE ? "" : \ diff -BbruN freeswan-1.91.orig/klips/net/ipsec/pfkey_v2_parser.c freeswan-1.91/klips/net/ipsec/pfkey_v2_parser.c --- freeswan-1.91.orig/klips/net/ipsec/pfkey_v2_parser.c Fri Jun 15 00:57:02 2001 +++ freeswan-1.91/klips/net/ipsec/pfkey_v2_parser.c Tue Jul 17 14:37:13 2001 @@ -79,7 +79,7 @@ #define min(a,b) (((a)<(b))?(a):(b)) #endif -extern int des_set_key(caddr_t, caddr_t); +extern int des_set_key_pluto(caddr_t, caddr_t); struct sklist_t { struct socket *sk; @@ -1049,10 +1049,13 @@ unsigned int aks, eks; switch(tdbp->tdb_encalg) { +# ifdef CONFIG_IPSEC_ENC_DES + case ESP_DES: +# endif /* CONFIG_IPSEC_ENC_DES */ # ifdef CONFIG_IPSEC_ENC_3DES case ESP_3DES: # endif /* CONFIG_IPSEC_ENC_3DES */ -# if defined(CONFIG_IPSEC_ENC_3DES) +# if defined(CONFIG_IPSEC_ENC_DES) || defined(CONFIG_IPSEC_ENC_3DES) if((tdbp->tdb_iv = (caddr_t) kmalloc((tdbp->tdb_iv_size = EMT_ESPDES_IV_SZ), GFP_ATOMIC)) == NULL) { SENDERR(ENOMEM); @@ -1060,7 +1063,7 @@ get_random_bytes((void *)tdbp->tdb_iv, EMT_ESPDES_IV_SZ); tdbp->tdb_iv_bits = tdbp->tdb_iv_size * 8; break; -# endif /* defined(CONFIG_IPSEC_ENC_3DES) */ +# endif /* defined(CONFIG_IPSEC_ENC_DES) || defined(CONFIG_IPSEC_ENC_3DES) */ case ESP_NONE: break; default: @@ -1072,6 +1075,52 @@ } switch(tdbp->tdb_encalg) { +#ifdef CONFIG_IPSEC_ENC_DES + case ESP_DES: + if(tdbp->tdb_key_bits_e != (EMT_ESPDES_KEY_SZ * 8)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_tdb_init: " + "incorrect encryption key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, + tdbp->tdb_key_bits_e, EMT_ESPDES_KEY_SZ * 8); + SENDERR(EINVAL); + } + + /* save encryption key pointer */ + ekp = tdbp->tdb_key_e; + eks = tdbp->tdb_key_e_size; + + if((tdbp->tdb_key_e = (caddr_t) + kmalloc(sizeof(struct des_eks), GFP_ATOMIC)) == NULL) { + tdbp->tdb_key_e = ekp; + SENDERR(ENOMEM); + } + tdbp->tdb_key_e_size = sizeof(struct des_eks); + +#if 0 /* we don't really want to print these unless there are really big problems */ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_tdb_init: des key 1 is 0x%08lx%08lx\n", + ntohl(*((__u32 *)ed->eme_key)), + ntohl(*((__u32 *)ed->eme_key + 1))); +#endif + error = des_set_key_pluto((caddr_t)ekp, + (caddr_t)(tdbp->tdb_key_e)); + if (error == -1) + printk("klips_debug:pfkey_tdb_init: " + "parity error in des key\n"); + else if (error == -2) + printk("klips_debug:pfkey_tdb_init: " + "illegal weak des key\n"); + if (error) { + memset(ekp, 0, eks); + kfree(ekp); + SENDERR(EINVAL); + } + + /* paranoid */ + memset(ekp, 0, eks); + kfree(ekp); + break; +#endif /* CONFIG_IPSEC_ENC_DES */ # ifdef CONFIG_IPSEC_ENC_3DES case ESP_3DES: if(tdbp->tdb_key_bits_e != (EMT_ESP3DES_KEY_SZ * 8)) { @@ -1102,7 +1151,7 @@ ntohl(*((__u32 *)ekp + i * 2)), ntohl(*((__u32 *)ekp + i * 2 + 1))); # endif - error = des_set_key((caddr_t)ekp + EMT_ESPDES_KEY_SZ * i, + error = des_set_key_pluto((caddr_t)ekp + EMT_ESPDES_KEY_SZ * i, (caddr_t)&((struct des_eks*)(tdbp->tdb_key_e))[i]); if (error == -1) printk("klips_debug:pfkey_tdb_init: " @@ -3247,6 +3296,14 @@ /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */ /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */ /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */ + { SADB_AALG_MD5HMAC, SADB_EALG_DESCBC, SADB_SAFLAGS_PFS, + 128, 128, 56, 56, + 0, 0, 0, 0, 0, + 57600, 86400, 57600, 86400 }, + { SADB_AALG_SHA1HMAC, SADB_EALG_DESCBC, SADB_SAFLAGS_PFS, + 160, 160, 56, 56, + 0, 0, 0, 0, 0, + 57600, 86400, 57600, 86400 }, { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS, 128, 128, 168, 168, 0, 0, 0, 0, 0, diff -BbruN freeswan-1.91.orig/klips/net/ipsec/version.c freeswan-1.91/klips/net/ipsec/version.c --- freeswan-1.91.orig/klips/net/ipsec/version.c Wed May 30 09:02:20 2001 +++ freeswan-1.91/klips/net/ipsec/version.c Sat Aug 18 12:09:46 2001 @@ -1,2 +1 @@ -/* silly pointless RCSID $Id: version.c,v 1.19 2001/05/30 13:02:20 henry Exp $ */ -static const char freeswan_version[] = "1.91"; +static const char freeswan_version[] = "FreeSWAN-1.91-pkix6b"; diff -BbruN freeswan-1.91.orig/klips/utils/Makefile freeswan-1.91/klips/utils/Makefile --- freeswan-1.91.orig/klips/utils/Makefile Thu Jun 14 15:35:13 2001 +++ freeswan-1.91/klips/utils/Makefile Mon Jul 16 23:26:30 2001 @@ -31,8 +31,8 @@ CFLAGS+= -Wbad-function-cast ALL=spi eroute spigrp tncfg klipsdebug -BINDIR=/usr/local/lib/ipsec -MANTREE=/usr/local/man +BINDIR=/usr/lib/ipsec +MANTREE=/usr/man MANDIR8=$(MANTREE)/man8 MANDIR5=$(MANTREE)/man5 FREESWANLIB=../../lib/libfreeswan.a @@ -41,11 +41,11 @@ all: $(ALL) install: $(ALL) - $(INSTALL) $(ALL) $(BINDIR) + $(INSTALL) $(ALL) $(PREFIX)/$(BINDIR) for f in $(addsuffix .8, $(ALL)) ; do \ - $(INSTALL) $$f $(MANDIR8)/ipsec_$$f || exit 1 ; done + $(INSTALL) $$f $(PREFIX)/$(MANDIR8)/ipsec_$$f || exit 1 ; done for f in $(addsuffix .5, $(ALL) version pf_key) ; do \ - $(INSTALL) $$f $(MANDIR5)/ipsec_$$f || exit 1 ; done + $(INSTALL) $$f $(PREFIX)/$(MANDIR5)/ipsec_$$f || exit 1 ; done spi: spi.o $(CC) $(DFLAGS) -o $@ $? $(FREESWANLIB) diff -BbruN freeswan-1.91.orig/klips/utils/version.c freeswan-1.91/klips/utils/version.c --- freeswan-1.91.orig/klips/utils/version.c Wed May 30 09:02:20 2001 +++ freeswan-1.91/klips/utils/version.c Sat Aug 18 12:09:35 2001 @@ -1,2 +1 @@ -/* silly pointless RCSID $Id: version.c,v 1.19 2001/05/30 13:02:20 henry Exp $ */ -static const char freeswan_version[] = "1.91"; +static const char freeswan_version[] = "FreeSWAN-1.91-pkix6b"; diff -BbruN freeswan-1.91.orig/lib/Makefile freeswan-1.91/lib/Makefile --- freeswan-1.91.orig/lib/Makefile Wed Oct 25 19:58:57 2000 +++ freeswan-1.91/lib/Makefile Mon Jul 16 23:26:30 2001 @@ -60,8 +60,8 @@ mkdir -p $(MANDIR) for f in $(MANS) ; \ do \ - $(INSTALL) $$f $(MANDIR)/ipsec_$$f || exit 1 ; \ - ../utils/manlink $(MANDIR) ipsec_$$f ; \ + $(INSTALL) $$f $(PREFIX)/$(MANDIR)/ipsec_$$f || exit 1 ; \ + ../utils/manlink $(PREFIX)/$(MANDIR) ipsec_$$f ; \ done $(LIB): $(OBJS) diff -BbruN freeswan-1.91.orig/libdes/Makefile freeswan-1.91/libdes/Makefile --- freeswan-1.91.orig/libdes/Makefile Tue Oct 10 22:12:45 2000 +++ freeswan-1.91/libdes/Makefile Mon Jul 16 23:26:30 2001 @@ -59,10 +59,10 @@ #DES_ENC=asm/dx86-sol.o asm/yx86-sol.o # solaris format x86 #DES_ENC=asm/dx86bsdi.o asm/yx86basi.o # bsdi format x86 -LIBDIR=/usr/local/lib -BINDIR=/usr/local/bin -INCDIR=/usr/local/include -MANDIR=/usr/local/man +LIBDIR=/usr/lib +BINDIR=/usr/bin +INCDIR=/usr/include +MANDIR=/usr/man MAN1=1 MAN3=3 SHELL=/bin/sh diff -BbruN freeswan-1.91.orig/libdes/des.doc freeswan-1.91/libdes/des.doc --- freeswan-1.91.orig/libdes/des.doc Tue Apr 6 00:47:02 1999 +++ freeswan-1.91/libdes/des.doc Tue Jul 17 14:45:40 2001 @@ -20,24 +20,24 @@ The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to specify decryption. The functions and global variable are as follows: -int des_check_key; +int des_check_key_pluto; DES keys are supposed to be odd parity. If this variable is set to - a non-zero value, des_set_key() will check that the key has odd + a non-zero value, des_set_key_pluto() will check that the key has odd parity and is not one of the known weak DES keys. By default this variable is turned off; -void des_set_odd_parity( +void des_set_odd_parity_pluto( des_cblock *key ); This function takes a DES key (8 bytes) and sets the parity to odd. -int des_is_weak_key( +int des_is_weak_key_pluto( des_cblock *key ); This function returns a non-zero value if the DES key passed is a weak, DES key. If it is a weak key, don't use it, try a different one. If you are using 'random' keys, the chances of hitting a weak key are 1/2^52 so it is probably not worth checking for them. -int des_set_key( +int des_set_key_pluto( des_cblock *key, des_key_schedule schedule); Des_set_key converts an 8 byte DES key into a des_key_schedule. @@ -45,14 +45,14 @@ perform actual encryption. It can be regenerated from the DES key so it only needs to be kept when encryption or decryption is about to occur. Don't save or pass around des_key_schedule's since they - are CPU architecture dependent, DES keys are not. If des_check_key - is non zero, zero is returned if the key has the wrong parity or - the key is a weak key, else 1 is returned. + are CPU architecture dependent, DES keys are not. If + des_check_key_pluto is non zero, zero is returned if the key has + the wrong parity or the key is a weak key, else 1 is returned. -int des_key_sched( +int des_key_sched_pluto( des_cblock *key, des_key_schedule schedule); - An alternative name for des_set_key(). + An alternative name for des_set_key_pluto(). int des_rw_mode; /* defaults to DES_PCBC_MODE */ This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default). diff -BbruN freeswan-1.91.orig/libdes/des.h freeswan-1.91/libdes/des.h --- freeswan-1.91.orig/libdes/des.h Wed Oct 4 10:54:10 2000 +++ freeswan-1.91/libdes/des.h Tue Jul 17 14:46:21 2001 @@ -128,8 +128,8 @@ #define read_pw_string des_read_pw_string #define random_key des_random_key #define pcbc_encrypt des_pcbc_encrypt -#define set_key des_set_key -#define key_sched des_key_sched +#define set_key des_set_key_pluto +#define key_sched des_key_sched_pluto #define ecb_encrypt des_ecb_encrypt #define cbc_encrypt des_cbc_encrypt #define ncbc_encrypt des_ncbc_encrypt @@ -139,10 +139,10 @@ /* For compatibility with the MIT lib - eay 20/05/92 */ typedef des_key_schedule bit_64; -#define des_fixup_key_parity des_set_odd_parity +#define des_fixup_key_parity des_set_odd_parity_pluto #define des_check_key_parity check_parity -extern int des_check_key; /* defaults to false */ +extern int des_check_key_pluto; /* defaults to false */ extern int des_rw_mode; /* defaults to DES_PCBC_MODE */ /* The next line is used to disable full ANSI prototypes, if your @@ -216,10 +216,10 @@ int des_read_2passwords(des_cblock *key1,des_cblock *key2, char *prompt,int verify); int des_read_pw_string(char *buf,int length,char *prompt,int verify); -void des_set_odd_parity(des_cblock *key); -int des_is_weak_key(des_cblock *key); -int des_set_key(des_cblock *key,des_key_schedule schedule); -int des_key_sched(des_cblock *key,des_key_schedule schedule); +void des_set_odd_parity_pluto(des_cblock *key); +int des_is_weak_key_pluto(des_cblock *key); +int des_set_key_pluto(des_cblock *key,des_key_schedule schedule); +int des_key_sched_pluto(des_cblock *key,des_key_schedule schedule); void des_string_to_key(char *str,des_cblock *key); void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2); void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length, @@ -271,10 +271,10 @@ int des_read_password(); int des_read_2passwords(); int des_read_pw_string(); -void des_set_odd_parity(); -int des_is_weak_key(); -int des_set_key(); -int des_key_sched(); +void des_set_odd_parity_pluto(); +int des_is_weak_key_pluto(); +int des_set_key_pluto(); +int des_key_sched_pluto(); void des_string_to_key(); void des_string_to_2keys(); void des_cfb64_encrypt(); diff -BbruN freeswan-1.91.orig/libdes/des_crypt.man freeswan-1.91/libdes/des_crypt.man --- freeswan-1.91.orig/libdes/des_crypt.man Thu Feb 18 11:41:12 1999 +++ freeswan-1.91/libdes/des_crypt.man Tue Jul 17 14:46:56 2001 @@ -2,13 +2,13 @@ .SH NAME des_read_password, des_read_2password, des_string_to_key, des_string_to_2key, des_read_pw_string, -des_random_key, des_set_key, -des_key_sched, des_ecb_encrypt, des_ecb3_encrypt, des_cbc_encrypt, +des_random_key, des_set_key_pluto, +des_key_sched_pluto, des_ecb_encrypt, des_ecb3_encrypt, des_cbc_encrypt, des_3cbc_encrypt, des_pcbc_encrypt, des_cfb_encrypt, des_ofb_encrypt, des_cbc_cksum, des_quad_cksum, -des_enc_read, des_enc_write, des_set_odd_parity, -des_is_weak_key, crypt \- (non USA) DES encryption +des_enc_read, des_enc_write, des_set_odd_parity_pluto, +des_is_weak_key_pluto, crypt \- (non USA) DES encryption .SH SYNOPSIS .nf .nj @@ -42,11 +42,11 @@ .B int des_random_key(key) des_cblock *key; .PP -.B int des_set_key(key,schedule) +.B int des_set_key_pluto(key,schedule) des_cblock *key; des_key_schedule schedule; .PP -.B int des_key_sched(key,schedule) +.B int des_key_sched_pluto(key,schedule) des_cblock *key; des_key_schedule schedule; .PP @@ -118,7 +118,7 @@ int out_count; des_cblock *seed; .PP -.B int des_check_key; +.B int des_check_key_pluto; .PP .B int des_enc_read(fd,buf,len,sched,iv) int fd; @@ -136,10 +136,10 @@ .PP .B extern int des_rw_mode; .PP -.B void des_set_odd_parity(key) +.B void des_set_odd_parity_pluto(key) des_cblock *key; .PP -.B int des_is_weak_key(key) +.B int des_is_weak_key_pluto(key) des_cblock *key; .PP .B char *crypt(passwd,salt) @@ -215,12 +215,12 @@ Before a des key can be used it is converted into a .I des_key_schedule via the -.I des_set_key +.I des_set_key_pluto routine. If the -.I des_check_key +.I des_check_key_pluto flag is non-zero, -.I des_set_key +.I des_set_key_pluto will check that the key passed is of odd parity and is not a week or semi-weak key. If the parity is wrong, @@ -230,9 +230,9 @@ If an error is returned, the key schedule is not generated. .PP -.I des_key_sched +.I des_key_sched_pluto is another name for the -.I des_set_key +.I des_set_key_pluto function. .PP The following routines mostly operate on an input and output stream of @@ -261,7 +261,7 @@ .I schedule argument, previously set via -.I des_set_key. +.I des_set_key_pluto. If .I encrypt is zero (DES_DECRYPT), @@ -446,12 +446,12 @@ des_cbc_encrypt is used. These two routines and the variable are not part of the normal MIT library. .PP -.I des_set_odd_parity +.I des_set_odd_parity_pluto sets the parity of the passed .I key to odd. This routine is not part of the standard MIT library. .PP -.I des_is_weak_key +.I des_is_weak_key_pluto returns 1 is the passed key is a weak key (pick again :-), 0 if it is ok. This routine is not part of the standard MIT library. diff -BbruN freeswan-1.91.orig/libdes/des_opts.c freeswan-1.91/libdes/des_opts.c --- freeswan-1.91.orig/libdes/des_opts.c Thu Feb 18 11:41:13 1999 +++ freeswan-1.91/libdes/des_opts.c Tue Jul 17 14:39:29 2001 @@ -454,13 +454,13 @@ fprintf(stderr,"program when this computer is idle.\n"); #endif - des_set_key((C_Block *)key,sch); - des_set_key((C_Block *)key2,sch2); - des_set_key((C_Block *)key3,sch3); + des_set_key_pluto((C_Block *)key,sch); + des_set_key_pluto((C_Block *)key2,sch2); + des_set_key_pluto((C_Block *)key3,sch3); #ifndef SIGALRM fprintf(stderr,"First we calculate the approximate speed ...\n"); - des_set_key((C_Block *)key,sch); + des_set_key_pluto((C_Block *)key,sch); count=10; do { long i; diff -BbruN freeswan-1.91.orig/libdes/destest.c freeswan-1.91/libdes/destest.c --- freeswan-1.91.orig/libdes/destest.c Thu Feb 18 11:41:13 1999 +++ freeswan-1.91/libdes/destest.c Tue Jul 17 14:48:09 2001 @@ -318,7 +318,7 @@ printf("Doing ecb\n"); for (i=0; icert != NULL) X509_free((X509 *)(c->cert)); + if (c->key != NULL) EVP_PKEY_free((EVP_PKEY *)(c->key)); + if (c->lu != NULL) sk_XMAP_pop_free(c->lu, XMAP_free); + { + int i; + + for (i=0; iother[i].cert != NULL) { + X509_free((X509 *)(c->other[i].cert)); + } + } +#endif + /* find and delete c from connections list */ list_rm(struct connection, ac_next, c, connections); cur_connection = old_cur_connection; @@ -540,12 +563,42 @@ static void unshare_connection_strings(struct connection *c) { +#ifdef OPENSSL + void *tempcert, *tempkey; + STACK_OF(XMAP) *templu; +#endif c->name = clone_str(c->name, "connection name"); unshare_id_content(&c->this.id); c->this.updown = clone_str(c->this.updown, "updown"); unshare_id_content(&c->that.id); c->that.updown = clone_str(c->that.updown, "updown"); + +#ifdef OPENSSL + { + int i; + + for (i=0; iother[i].cert) { + tempcert = c->other[i].cert; + c->other[i].cert = X509_dup(tempcert); + } + } + + if (c->cert) { + tempcert = c->cert; + c->cert = X509_dup(tempcert); + } + + if (c->key) { + tempkey = c->key; + c->key = EVP_PKEY_dup(tempkey); + } + if (c->lu) { + templu = c->lu; + c->lu = clone_sk_XMAP(templu); + } +#endif } static void @@ -615,7 +668,11 @@ for (; c != NULL; c = c->hp_next) { +#ifndef OPENSSL if ((c->policy ^ wm->policy) & (POLICY_PSK | POLICY_RSASIG)) +#else + if ((c->policy ^ wm->policy) & (POLICY_PSK | POLICY_OPENSSL)) +#endif { loglog(RC_CLASH , "authentication method disagrees with \"%s\", which is also for an unspecified peer" @@ -631,6 +688,8 @@ void add_connection(const struct whack_message *wm) { + bool success = TRUE; + if (con_by_name(wm->name, FALSE) != NULL) { loglog(RC_DUPNAME, "attempt to redefine connection \"%s\"", wm->name); @@ -655,6 +714,17 @@ c->sa_rekey_fuzz = wm->sa_rekey_fuzz; c->sa_keying_tries = wm->sa_keying_tries; +#ifdef DES + c->block_cypher = wm->block_cypher; +#endif + +#ifdef OPENSSL + c->this.id.key_id.len = 0; + c->that.id.key_id.len = 0; + c->this.id.der_asn1_dn.len = 0; + c->that.id.der_asn1_dn.len = 0; +#endif + c->addr_family = wm->addr_family; c->tunnel_addr_family = wm->tunnel_addr_family; @@ -690,14 +760,62 @@ c->gw_info = NULL; - unshare_connection_strings(c); +#ifdef OPENSSL + { + int i; + + for(i=0; iother[i].cert = NULL; + c->other[i].type = 0; + } + } + c->cert_options = parse_options(wm->whack_certopts); + c->cert = NULL; + c->key = NULL; + + /* c->cert_options can tell us if we have to deal with + * X509 certs from now on. See function "use_openssl" + */ + if (c->cert_options != 0) + { + strcpy(c->certkeyfile, wm->whack_keyfile); + strcpy(c->certfile, wm->whack_certfile); + + load_cert(&c); + load_certkey(&c); + + /* if we are using a PKCS8/12 privkey cert, we will verify + * certs and keys during loading of ipsec.secrets: + * the passphrase will decrypt the key and populate the + * data then. + */ + if ((c->certtype & PUBCERT_NONE) && + (c->cert == NULL)) success = FALSE; + if ((c->certkeytype & PRIVCERT_NONE) && + (c->key == NULL)) success = FALSE; + } +#endif /* OPENSSL */ (void)orient(c); + unshare_connection_strings(c); + connect_to_host_pair(c); +#ifdef OPENSSL + if (c->cert_options != 0) { + + if (! make_lookups((STACK_OF(XMAP) **)(&(c->lu)), + wm->whack_certpath) ) { + success = FALSE; + } + strncpy(c->path, wm->whack_certpath, PATH_NAME_LIMIT); + } +#endif + possibly_some_oppo = TRUE; /* could be more careful about this */ - /* log all about this connection */ + /* log all about this connection, if successful */ + if (success) { log("added connection description \"%s\"", c->name); DBG(DBG_CONTROL, char lhs[SUBNETTOT_BUF + ADDRTOT_BUF + IDTOA_BUF + ADDRTOT_BUF]; @@ -706,7 +824,9 @@ (void) format_end(lhs, sizeof(lhs), &c->this, &c->that, TRUE); (void) format_end(rhs, sizeof(rhs), &c->that, &c->this, FALSE); + if (c->this.id.kind != ID_DER_ASN1_DN) { DBG_log("%s...%s", lhs, rhs); + } /* Make sure that address families can be correctly inferred * from printed ends. @@ -730,6 +850,15 @@ , (unsigned long) c->sa_keying_tries , bitnamesof(sa_policy_bit_names, c->policy)); ); + } else { + loglog(RC_LOG_SERIOUS, + "Adding connection description \"%s\" failed.", + c->name); + loglog(RC_LOG_SERIOUS, + "Deleting connection description \"%s\".", + c->name); + delete_connection(c); + } } } @@ -986,6 +1115,15 @@ { struct connection *c = con_by_name(name, TRUE); +#ifdef OPENSSL + if ((c != NULL) && use_openssl(c)) + { + if (!(c->certtype & PUBCERT_X509)) load_cert(&c); + if (!(c->certkeytype & PRIVCERT_X509)) load_certkey(&c); + load_pkcs(&c); + } +#endif + if (c != NULL) { SET_CUR_CONNECTION(c); @@ -1057,6 +1195,17 @@ { /* what should we do on failure? */ (void) assign_hold(c, our_client, peer_client); + + switch (c->routing){ + case RT_UNROUTED: + c->routing = RT_UNROUTED_HOLD; + break; + case RT_ROUTED_PROSPECTIVE: + c->routing = RT_ROUTED_HOLD; + break; + default: + passert(FALSE); + } } ipsecdoi_initiate(whackfd, c, c->policy, 1); whackfd = NULL_FD; /* protect from close */ @@ -1425,7 +1574,13 @@ break; case OAKLEY_RSA_SIG: +#ifndef OPENSSL auth_policy = POLICY_RSASIG; +#else + case OAKLEY_RSA_ENC: + case OAKLEY_RSA_ENC_REV: + auth_policy = POLICY_OPENSSL; +#endif if (initiator) { /* at this point, we've committed to our RSA private key: @@ -1436,7 +1591,14 @@ return NULL; /* cannot determine my RSA private key! */ } break; - +#ifdef OPENSSL + case OAKLEY_DSS_SIG: + case OAKLEY_ELGAMAL_ENC: + case OAKLEY_ELGAMAL_ENC_REV: + auth_policy = POLICY_OPENSSL; + /* Not implemented yet */ + break; +#endif default: passert(FALSE); } @@ -1461,6 +1623,27 @@ { bool exact = same_id(peer_id, &d->that.id); /* exact peer ID match? */ +#ifdef OPENSSL + /* fetch d's other cert, when applicable. */ + if (auth_policy == POLICY_OPENSSL) { + bool r; + switch(auth) { + case OAKLEY_RSA_SIG: + case OAKLEY_RSA_ENC: + case OAKLEY_RSA_ENC_REV: + r = have_othercert(d, EVP_PKEY_RSA); + break; + + case OAKLEY_DSS_SIG: + case OAKLEY_ELGAMAL_ENC: + case OAKLEY_ELGAMAL_ENC_REV: + r = have_othercert(d, EVP_PKEY_DSA); + break; + default: + passert(FALSE); + } /* END switch */ + } +#endif /* check if peer_id matches, exactly or after instantiation */ if (!exact && !(rw && d->that.id.kind == ID_NONE)) continue; @@ -1492,6 +1675,10 @@ break; case OAKLEY_RSA_SIG: +#ifdef OPENSSL + case OAKLEY_RSA_ENC: + case OAKLEY_RSA_ENC_REV: +#endif /* We must at least be able to find our private key. * If we initiated, it must match the one we * used in the SIG_I payload that we sent previously. @@ -1956,3 +2143,23 @@ delete_connection(c); } } + +#ifdef OPENSSL +extern void +load_certs_for_host_pair(struct host_pair *hp) +{ + struct host_pair *p = hp; + + for (; p != NULL; p = p->next) + { + struct connection *c; + + for (c = p->connections; c != NULL; c = c->hp_next) + if (use_openssl(c)) { + if (!(c->certtype & PUBCERT_X509)) (void )load_cert(&c); + if (!(c->certkeytype & PRIVCERT_X509)) (void )load_certkey(&c); + load_pkcs(&c); + } + } +} +#endif diff -BbruN freeswan-1.91.orig/pluto/connections.h freeswan-1.91/pluto/connections.h --- freeswan-1.91.orig/pluto/connections.h Mon May 28 15:18:17 2001 +++ freeswan-1.91/pluto/connections.h Wed Jul 18 14:50:19 2001 @@ -14,6 +14,10 @@ * RCSID $Id: connections.h,v 1.54 2001/05/28 19:18:17 dhr Exp $ */ +#ifdef OPENSSL +#include "openssl_defs.h" +#endif + /* There are two kinds of connections: * - ISAKMP connections, between hosts (for IKE communication) * - IPsec connections, between clients (for secure IP communication) @@ -87,6 +91,13 @@ * is a stat that uses it. */ +#ifdef OPENSSL +struct other_st { + u_int32_t type; /* type of certificate in 'cert': EVP_PKEY_RSA or EVP_PKEY_DSA */ + void *cert; +}; +#endif + struct end { struct id id; ip_address @@ -101,6 +112,28 @@ struct connection { char *name; +#ifdef OPENSSL + /* The declaration of these as void is truly horrific - they + * should be X509 and EVP_PKEY pointers. Unfortunately, if this + * is declared, the MD5 header files from OpenSSL conflict with those + * in the KLIPS source. Hence we cast these pointers to the right + * type at the time of use. It's disgusting, but I can't think of + * another way -- ND + */ + void *cert, *key, *lu; + struct other_st other[MAX_OTHER]; + u_char path[PATH_NAME_LIMIT]; + u_int32_t cert_options; + + char certfile[FILE_NAME_LIMIT]; + unsigned int certtype; + + char certkeyfile[FILE_NAME_LIMIT]; + unsigned int certkeytype; +#endif +#ifdef DES + lset_t block_cypher; +#endif lset_t policy; time_t sa_ike_life_seconds; time_t sa_ipsec_life_seconds; @@ -224,4 +257,8 @@ /* print connection status */ + extern void show_connections_status(void); +#ifdef OPENSSL +extern void load_certs_for_host_pair(struct host_pair *hp); +#endif diff -BbruN freeswan-1.91.orig/pluto/constants.c freeswan-1.91/pluto/constants.c --- freeswan-1.91.orig/pluto/constants.c Tue May 29 14:39:56 2001 +++ freeswan-1.91/pluto/constants.c Mon Jul 16 23:26:30 2001 @@ -311,13 +311,38 @@ enum_names ident_names = { ID_IPV4_ADDR, ID_KEY_ID, ident_name, NULL }; +#ifdef OPENSSL +/* Certificate type values */ +static const char *const cert_name[] = { + "CERT_TYPE_NONE", + "CERT_TYPE_PKCS7", + "CERT_TYPE_PGP", + "CERT_TYPE_DNSKEY", + "CERT_TYPE_X509_SIG", + "CERT_TYPE_X509_KEX", + "CERT_TYPE_KERBEROS", + "CERT_TYPE_CRL", + "CERT_TYPE_ARL", + "CERT_TYPE_SPKI", + "CERT_TYPE_X509_ATTR", + }; + +enum_names cert_names = + { CERT_TYPE_NONE, CERT_TYPE_X509_ATTR, cert_name, NULL }; +#endif + + /* Goal BITs for establishing an SA * Note: we drop the POLICY_ prefix so that logs are more concise. */ const char *const sa_policy_bit_names[] = { "PSK", +#ifndef OPENSSL "RSASIG", +#else + "OPENSSL", +#endif "ENCRYPT", "AUTHENTICATE", "COMPRESS", @@ -770,6 +795,26 @@ return p; } +void init_constants(void) +{ + err_t ugh; + + ugh = anyaddr(AF_INET, &ipv4_any); + passert(ugh == NULL); + ugh = anyaddr(AF_INET, &ipv6_any); + passert(ugh == NULL); + + ugh = rangetosubnet(&ipv4_any, &ipv4_any, &ipv4_wildcard); + passert(ugh == NULL); + ugh = rangetosubnet(&ipv6_any, &ipv6_any, &ipv6_wildcard); + passert(ugh == NULL); + + ugh = initsubnet(&ipv4_any, 0, '0', &ipv4_all); + passert(ugh == NULL); + ugh = initsubnet(&ipv6_any, 0, '0', &ipv6_all); + passert(ugh == NULL); +} + /* construct a string to name the bits on in a set * Result may be in STATIC buffer! */ @@ -864,24 +909,4 @@ p = buf; } return p; -} - -void init_constants(void) -{ - err_t ugh; - - ugh = anyaddr(AF_INET, &ipv4_any); - passert(ugh == NULL); - ugh = anyaddr(AF_INET, &ipv6_any); - passert(ugh == NULL); - - ugh = rangetosubnet(&ipv4_any, &ipv4_any, &ipv4_wildcard); - passert(ugh == NULL); - ugh = rangetosubnet(&ipv6_any, &ipv6_any, &ipv6_wildcard); - passert(ugh == NULL); - - ugh = initsubnet(&ipv4_any, 0, '0', &ipv4_all); - passert(ugh == NULL); - ugh = initsubnet(&ipv6_any, 0, '0', &ipv6_all); - passert(ugh == NULL); } diff -BbruN freeswan-1.91.orig/pluto/constants.h freeswan-1.91/pluto/constants.h --- freeswan-1.91.orig/pluto/constants.h Tue May 29 14:39:56 2001 +++ freeswan-1.91/pluto/constants.h Thu Jul 19 15:02:13 2001 @@ -509,6 +509,30 @@ #define ID_DER_ASN1_GN 10 #define ID_KEY_ID 11 +#ifdef OPENSSL +#define CERT_OPTION_SEND 0x01 +#define CERT_OPTION_PKCS7 0x02 +#define CERT_OPTION_PK 0x04 +#define CERT_OPTION_REV 0x08 +#define CERT_OPTION_STRICT 0x10 +#define CERT_OPTION_DSS_SHA 0x20 +#define CERT_OPTION_DSS_ALT 0x40 + +extern enum_names cert_names; + +#define CERT_TYPE_NONE 0 +#define CERT_TYPE_PKCS7 1 +#define CERT_TYPE_PGP 2 +#define CERT_TYPE_DNSKEY 3 +#define CERT_TYPE_X509_SIG 4 +#define CERT_TYPE_X509_KEX 5 +#define CERT_TYPE_KERBEROS 6 +#define CERT_TYPE_CRL 7 +#define CERT_TYPE_ARL 8 +#define CERT_TYPE_SPKI 9 +#define CERT_TYPE_X509_ATTR 10 +#endif + /* Policies for establishing an SA * * These are used to specify attributes (eg. encryption) and techniques @@ -519,10 +543,18 @@ /* ISAKMP auth techniques */ #define POLICY_PSK LELEM(0) +#ifndef OPENSSL #define POLICY_RSASIG LELEM(1) +#else +#define POLICY_OPENSSL LELEM(1) +#endif #define POLICY_ISAKMP_SHIFT 0 /* log2(POLICY_PSK) */ +#ifndef OPENSSL #define POLICY_ID_AUTH_MASK LRANGES(POLICY_PSK, POLICY_RSASIG) +#else +#define POLICY_ID_AUTH_MASK LRANGES(POLICY_PSK, POLICY_OPENSSL) +#endif #define POLICY_ISAKMP_MASK POLICY_ID_AUTH_MASK /* all so far */ /* Quick Mode (IPSEC) attributes */ @@ -624,6 +656,12 @@ #define SA_REPLACEMENT_RETRIES_DEFAULT 3 /* (IPSEC & IKE) */ #define SA_LIFE_DURATION_K_DEFAULT 0xFFFFFFFFlu + +/* DES support */ +#define ALL_BLOCK_CYPHER 1 +#define DES_BLOCK_CYPHER 2 +#define DES3_BLOCK_CYPHER 3 +#define FORCE_ENCRYPT_CYPHER_DEFAULT ALL_BLOCK_CYPHER /* Encapsulation Mode attribute */ diff -BbruN freeswan-1.91.orig/pluto/crypto.c freeswan-1.91/pluto/crypto.c --- freeswan-1.91.orig/pluto/crypto.c Mon Oct 2 23:31:05 2000 +++ freeswan-1.91/pluto/crypto.c Tue Jul 17 14:12:54 2001 @@ -88,6 +88,7 @@ * Each uses the state object's st_iv, and sets st_new_iv. */ +#ifdef DES /* encrypt or decrypt part of an IKE message using DES * See draft-ietf-ipsec-isakmp-oakley-07.txt Appendix B */ @@ -96,7 +97,7 @@ { des_key_schedule ks; - (void) des_set_key((des_cblock *)st->st_enc_key.ptr, ks); + (void) des_set_key_pluto((des_cblock *)st->st_enc_key.ptr, ks); passert(st->st_new_iv_len >= DES_CBC_BLOCK_SIZE); st->st_new_iv_len = DES_CBC_BLOCK_SIZE; /* truncate */ @@ -105,6 +106,7 @@ ks, (des_cblock *)st->st_new_iv, enc); } +#endif /* encrypt or decrypt part of an IKE message using 3DES * See draft-ietf-ipsec-isakmp-oakley-07.txt Appendix B @@ -114,9 +116,9 @@ { des_key_schedule ks[3]; - (void) des_set_key((des_cblock *)st->st_enc_key.ptr + 0, ks[0]); - (void) des_set_key((des_cblock *)st->st_enc_key.ptr + 1, ks[1]); - (void) des_set_key((des_cblock *)st->st_enc_key.ptr + 2, ks[2]); + (void) des_set_key_pluto((des_cblock *)st->st_enc_key.ptr + 0, ks[0]); + (void) des_set_key_pluto((des_cblock *)st->st_enc_key.ptr + 1, ks[1]); + (void) des_set_key_pluto((des_cblock *)st->st_enc_key.ptr + 2, ks[2]); passert(st->st_new_iv_len >= DES_CBC_BLOCK_SIZE); st->st_new_iv_len = DES_CBC_BLOCK_SIZE; /* truncate */ @@ -130,7 +132,11 @@ /* (none) */ { 0, 0, NULL }, /* OAKLEY_DES_CBC */ +#ifdef DES { DES_CBC_BLOCK_SIZE, DES_CBC_BLOCK_SIZE, do_des }, +#else + { 0, 0, NULL }, +#endif /* OAKLEY_IDEA_CBC */ { 0, 0, NULL }, /* OAKLEY_BLOWFISH_CBC */ diff -BbruN freeswan-1.91.orig/pluto/crypto.h freeswan-1.91/pluto/crypto.h --- freeswan-1.91.orig/pluto/crypto.h Sun Dec 12 19:40:50 1999 +++ freeswan-1.91/pluto/crypto.h Mon Jul 16 23:26:30 2001 @@ -56,7 +56,11 @@ /* unification of cryptographic hashing mechanisms */ union hash_ctx { +#ifndef OPENSSL MD5_CTX ctx_md5; +#else + PLUTO_MD5_CTX ctx_md5; +#endif SHA1_CTX ctx_sha1; }; diff -BbruN freeswan-1.91.orig/pluto/defs.c freeswan-1.91/pluto/defs.c --- freeswan-1.91.orig/pluto/defs.c Tue Mar 13 04:22:03 2001 +++ freeswan-1.91/pluto/defs.c Mon Jul 16 23:26:30 2001 @@ -24,6 +24,8 @@ #include "constants.h" #include "defs.h" #include "log.h" +#include "id.h" +#include "connections.h" /* needs id.h */ #include "whack.h" /* for RC_LOG_SERIOUS */ const chunk_t empty_chunk = { NULL, 0 }; diff -BbruN freeswan-1.91.orig/pluto/defs.h freeswan-1.91/pluto/defs.h --- freeswan-1.91.orig/pluto/defs.h Tue May 8 01:37:21 2001 +++ freeswan-1.91/pluto/defs.h Mon Jul 16 23:26:30 2001 @@ -59,6 +59,19 @@ #define pfreeany(p) { if ((p) != NULL) pfree(p); } #define replace(p, q) { pfreeany(p); (p) = (q); } +#ifdef OPENSSL +#include + +typedef union _keysched_u { + struct _des3_ks { des_key_schedule ks[3]; } des3_ks; + des_key_schedule des_ks; + +#ifdef NOTYET + /* Other ciphers, eg CAST, RC5, etc... */ +#endif + +} keysched; +#endif /* chunk is a simple pointer-and-size abstraction */ @@ -108,3 +121,31 @@ /* pad_up(n, m) is the amount to add to n to make it a multiple of m */ #define pad_up(n, m) (((m) - 1) - (((n) + (m) - 1) % (m))) + +/* writemem_short adds support to write to unaligned memory (arm). */ +#ifdef __arm__ +#define writemem_u_int16_t(addr, offset, n) do {\ + u_int16_t temp16 = htons((n)); \ + (addr)[(offset)] = temp16 & 0xff; \ + (addr)[(offset)+1] = temp16 >> 8; \ +} while (0) +#else +#define writemem_u_int16_t(addr, offset, n) do {\ + *((u_int16_t *)(&((addr)[(offset)]))) = htons((n)); \ +} while (0) +#endif + +/* readmem_short adds support to read from unaligned memory (arm). */ +#ifdef __arm__ +#define readmem_u_int16_t(addr, offset, var) do {\ + u_int16_t temp16 = 0; \ + temp16 += *((u_int8_t *)(&((addr)[(offset)]))) << 8; \ + temp16 += *((u_int8_t *)(&((addr)[(offset)+1]))); \ + (var) = temp16; \ +} while (0) +#else +#define readmem_u_int16_t(addr, offset, var) do {\ + u_int16_t temp16 = ntohs(*((u_int16_t *)(&((addr)[(offset)])))); \ + (var) = temp16; \ +} while (0) +#endif diff -BbruN freeswan-1.91.orig/pluto/demux.c freeswan-1.91/pluto/demux.c --- freeswan-1.91.orig/pluto/demux.c Sat Jun 16 12:31:40 2001 +++ freeswan-1.91/pluto/demux.c Tue Jul 17 14:15:47 2001 @@ -139,6 +139,10 @@ #include "whack.h" /* requires connections.h */ #include "server.h" +#ifdef OPENSSL +#include "openssl.h" +#endif + /* This file does basic header checking and demux of * incoming packets. */ @@ -242,11 +246,19 @@ { STATE_MAIN_R1, SMF_PKE_AUTH , P(KE) | P(ID) | P(NONCE), P(VID) | P(HASH), PT(KE) +#ifndef OPENSSL , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ }, +#else + , EVENT_RETRANSMIT, main_inI2_outR2_pk }, +#endif { STATE_MAIN_R1, SMF_RPKE_AUTH , P(NONCE) | P(KE) | P(ID), P(VID) | P(HASH) | P(CERT), PT(NONCE) +#ifndef OPENSSL , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ }, +#else + , EVENT_RETRANSMIT, main_inI2_outR2_rpk }, +#endif /* for states from here on, output message must be encrypted */ @@ -264,11 +276,20 @@ { STATE_MAIN_I2, SMF_PKE_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED , P(KE) | P(ID) | P(NONCE), P(VID), PT(HASH) +#ifndef OPENSSL , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ }, +#else + , EVENT_RETRANSMIT, main_inR2_outI3_pk /* ??? not yet implemented */ }, +#endif - { STATE_MAIN_I2, SMF_ALL_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED - , P(NONCE) | P(KE) | P(ID), P(VID), PT(HASH) + { STATE_MAIN_I2, SMF_RPKE_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED +/* , P(NONCE) | P(KE) | P(ID), P(VID), PT(HASH) */ + , P(NONCE) | P(KE) | P(ID), P(VID) | P(CERT), PT(HASH) +#ifndef OPENSSL , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ }, +#else + , EVENT_RETRANSMIT, main_inR2_outI3_rpk /* ??? not yet implemented */ }, +#endif /* for states from here on, input message must be encrypted */ @@ -283,11 +304,19 @@ { STATE_MAIN_R2, SMF_DS_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED , P(ID) | P(SIG), P(VID) | P(CERT), PT(ID) +#ifndef OPENSSL , EVENT_SA_REPLACE, main_inI3_outR3 }, +#else + , EVENT_SA_REPLACE, main_inI3_outR3_whichds}, +#endif { STATE_MAIN_R2, SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED , P(HASH), P(VID), PT(HASH) +#ifndef OPENSSL , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ }, +#else + , EVENT_SA_REPLACE, main_inI3_outR3_pk}, +#endif /* STATE_MAIN_I3: R3 --> done * SMF_PSK_AUTH: HDR*, IDr1, HASH_R --> done @@ -301,11 +330,20 @@ { STATE_MAIN_I3, SMF_DS_AUTH | SMF_INITIATOR | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED , P(ID) | P(SIG), P(VID) | P(CERT), PT(NONE) +#ifndef OPENSSL , EVENT_SA_REPLACE, main_inR3 }, +#else + , EVENT_SA_REPLACE, main_inR3_whichds }, +#endif { STATE_MAIN_I3, SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_INITIATOR | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED , P(HASH), P(VID), PT(NONE) +#ifndef OPENSSL , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ }, +#else + , EVENT_SA_REPLACE, main_inR3_pk }, +#endif + /* STATE_MAIN_R3: can only get here due to packet loss */ { STATE_MAIN_R3, SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE, LEMPTY, LEMPTY @@ -1245,6 +1283,9 @@ { lset_t s = LELEM(np); + loglog(RC_LOG_SERIOUS, "parsing: (%s)", + enum_show(&payload_names, np)); + if (0 == (s & (needed | smc->opt_payloads | LELEM(ISAKMP_NEXT_N) | LELEM(ISAKMP_NEXT_D)))) { @@ -1257,6 +1298,267 @@ needed &= ~s; } +#ifdef OPENSSL + { + /* This code really shouldn't be here - it should be in */ + /* the ipsec_doi code section with all the other protocol */ + /* spec. Unfortunately, the "syntax checking" of the payload */ + /* is done here, and the "semantic checking" of the payload */ + /* is over in ipsec_doi. Since the fields of the ID payload */ + /* are encrypted, and the ipsec_doi code checks those fields */ + /* before processing the ID payload, we must ensure that the */ + /* payload is decrypted and stored in the identification */ + /* structure *before* the main mode routines process it. So */ + /* the code is here. */ + + if ((IS_PHASE1(md.from_state)) && (md.st)) { + if ((md.st->st_oakley.auth == OAKLEY_RSA_ENC) || + (md.st->st_oakley.auth == OAKLEY_ELGAMAL_ENC)) { + if ((sd == &isakmp_identification_desc) || + (sd == &isakmp_nonce_desc)) { + /* We need to decrypt this packet */ + char cpl[65], ppl[65]; + u_int16_t paylen; + chunk_t ch; + + /* see macro in defs.h */ + readmem_u_int16_t(md.message_pbs.cur, 2, paylen); + + clonetochunk(ch, &(md.message_pbs.cur[4]), paylen-4, + "Ciphertext payload"); + + /* Make a copy chunk of the payload after the generic */ + /* header, which should be the ciphertext of */ + /* the ID payload */ + if (sd == &isakmp_identification_desc) { + snprintf(cpl, sizeof(cpl)-1, "ID payload (ciphertext): "); + snprintf(ppl, sizeof(ppl)-1, "ID payload (plaintext): "); + } else if (sd == &isakmp_nonce_desc) { + snprintf(cpl, sizeof(cpl)-1, + "Nonce payload (ciphertext): "); + snprintf(ppl, sizeof(ppl)-1, + "Nonce payload (plaintext): "); + } else { + snprintf(cpl, sizeof(cpl)-1, + "Unknown payload (ciphertext): "); + snprintf(ppl, sizeof(ppl)-1, + "Unknown payload (plaintext): "); + } + + if (!valid_ciphertext_length(paylen - 4, md.st->st_connection)) { + log("Ciphertext length not a multiple of key modulus length for %s", cpl ); + free_md(&md); + return; + } + + DBG(DBG_RAW, + DBG_dump_chunk(cpl, ch); + ); + + if (! privkey_decrypt_chunk( &ch, md.st )) { + log("Ciphertext for %s could not be decrypted.", cpl ); + free_md(&md); + return; + } + + if ((ch.len == 0) || (ch.len > paylen)) { + /* Error - the decryption has failed */ + log("Decryption failure - malformed payload in packet"); + free_md(&md); + return; + } + + DBG(DBG_RAW, + DBG_dump_chunk(ppl, ch); + ); + +/* ** a nice data dumper ** + * { + * int *ptr = (int *) md.message_pbs.cur; + * int length = md.message_pbs.roof - md.message_pbs.cur; + * int i; + * DBG_log("before memcopy: ---------------------- length %d", length); + * for (i=0; ist_oakley.auth == OAKLEY_RSA_ENC_REV) || + (md.st->st_oakley.auth == OAKLEY_ELGAMAL_ENC_REV)) { + if ((sd == &isakmp_identification_desc) || + (sd == &isakmp_nonce_desc) || + (sd == &isakmp_keyex_desc) || + (sd == &isakmp_ipsec_certificate_desc)) { + if (sd == &isakmp_nonce_desc) { + /* Nonce is public key encrypted */ + u_int16_t paylen; + chunk_t ch; + + /* see macro in defs.h */ + readmem_u_int16_t(md.message_pbs.cur, 2, paylen); + + clonetochunk(ch, &(md.message_pbs.cur[4]), paylen-4, + "Ciphertext payload"); + + if (!valid_ciphertext_length(paylen - 4, + md.st->st_connection)) { + log("Ciphertext length not a multiple of key modulus length for nonce" ); + free_md(&md); + return; + } + + DBG(DBG_PARSING | DBG_CRYPT, + DBG_dump_chunk("Nonce payload (ciphertext)", ch); + ); + + if (! privkey_decrypt_chunk( &ch, md.st )) { + log("Ciphertext for %s could not be decrypted.", + "Nonce payload (ciphertext)"); + free_md(&md); + return; + } + + if ((ch.len == 0) || (ch.len > paylen)) { + /* Error - the decryption has failed */ + log("Decryption failure - malformed payload in packet"); + free_md(&md); + return; + } + DBG(DBG_PARSING | DBG_CRYPT, + DBG_dump_chunk("Nonce payload (plaintext)", ch); + ); + + if ((md.st->st_state == STATE_MAIN_I1) || + (md.st->st_state == STATE_MAIN_I2) || + (md.st->st_state == STATE_MAIN_I3) || + (md.st->st_state == STATE_MAIN_I4)) { + if (derive_symmetric_key(md.st, ch, + md.st->st_rcookie, + COOKIE_SIZE, + &md.st->st_ks_r, + &md.st->st_ne_r) < 0) { + log("Unable to derive symmetric key"); + free(&md); + return; + } + memset(&md.st->st_ne_r_iv, 0, MAX_DIGEST_LEN); + DBG(DBG_PARSING, + DBG_dump_chunk("Received Ke_r:", md.st->st_ne_r); + ); + } else { + if (derive_symmetric_key(md.st, ch, + md.st->st_icookie, + COOKIE_SIZE, + &md.st->st_ks_i, + &md.st->st_ne_i) < 0) { + log("Unable to derive symmetric key"); + free(&md); + return; + } + memset(&md.st->st_ne_i_iv, 0, MAX_DIGEST_LEN); + DBG(DBG_PARSING, + DBG_dump_chunk("Received Ke_i:", md.st->st_ne_i); + ); + } + + /* Now restructure the message_pbs block, so that the */ + /* plaintext is now stored in the payload space */ + /* Adjust the length first */ + /* see macro in defs.h */ + writemem_u_int16_t(md.message_pbs.cur, 2, (ch.len + 4)); + + /* Now copy the plaintext */ + memcpy(&(md.message_pbs.cur[4]), ch.ptr, ch.len); + /* Clear the source plaintext */ + memset(ch.ptr, 0, ch.len); + /* Shift down all subsequent payloads */ + memmove(&(md.message_pbs.cur[ch.len+4]), + &(md.message_pbs.cur[paylen]), + md.message_pbs.roof - &(md.message_pbs.cur[paylen])); + /* Adjust the size of roof downwards */ + md.message_pbs.roof -= paylen - ch.len - 4; + + /* Discard the plaintext chunk */ + memset(ch.ptr, 0, ch.len); + freeanychunk(ch); + } else { + u_int16_t paylen; + chunk_t ch, pch; + + /* see macro in defs.h */ + readmem_u_int16_t(md.message_pbs.cur, 2, paylen); + + DBG(DBG_CRYPT, + DBG_log("Encrypted payload length = %d", paylen); + ); + clonetochunk(ch, &(md.message_pbs.cur[4]), paylen-4, "Ciphertext payload"); + setchunk(pch, NULL, 0); + if ((md.st->st_state == STATE_MAIN_I1) || + (md.st->st_state == STATE_MAIN_I2) || + (md.st->st_state == STATE_MAIN_I3) || + (md.st->st_state == STATE_MAIN_I4)) { + if (! decrypt_payload(md.st, &md.st->st_ks_r, + md.st->st_ne_r_iv, + ch, &pch) ) { + log("Unable to decrypt responder payload"); + free(&md); + return; + } + } else { + if (!decrypt_payload(md.st, &md.st->st_ks_i, + md.st->st_ne_i_iv, + ch, &pch) ) { + log("Unable to decrypt initiator payload"); + free(&md); + return; + } + } + /* see macro in defs.h */ + writemem_u_int16_t(md.message_pbs.cur, 2, (pch.len + 4)); + + /* Now copy the plaintext */ + memcpy(&(md.message_pbs.cur[4]), pch.ptr, pch.len); + /* Shift down all subsequent payloads */ + memmove(&(md.message_pbs.cur[pch.len+4]), + &(md.message_pbs.cur[paylen]), + md.message_pbs.roof - &(md.message_pbs.cur[paylen])); + /* Adjust the size of roof downwards */ + md.message_pbs.roof -= paylen - pch.len - 4; + + freeanychunk(ch); + memset(pch.ptr, 0, pch.len); + freeanychunk(pch); + } + } /* Otherwise, let everything else pass */ + } /* end if (revised PK mode ) */ + } /* end if Phase 1 */ + } /* end OPENSSL handling */ +#endif /* OPENSSL */ + if (!in_struct(&pd->payload, sd, &md.message_pbs, &pd->pbs)) { loglog(RC_LOG_SERIOUS, "%smalformed payload in packet", excuse); @@ -1666,3 +1968,298 @@ } free_md(&md); } + +#ifdef OPENSSL +int +derive_symmetric_key( struct state *st, const chunk_t nonce, + const u_char *seedptr, const size_t seedlen, + keysched *ks, + chunk_t *key ) +{ + struct hmac_ctx ctx; + chunk_t k, kk, kchain; + chunk_t ne; + char nestr[8]; + int needed_len; + + DBG(DBG_PARSING, + DBG_dump_chunk("Deriving symmetric key from: ", nonce); + DBG_dump("Initial Cookie:", seedptr, seedlen); + ); + switch(st->st_oakley.encrypt) { + /* We really shouldn't deal with DES, */ + /* uncomment this if you must have it */ + case OAKLEY_DES_CBC: + needed_len = DES_CBC_BLOCK_SIZE; + break; +#ifdef NOTYET + case OAKLEY_IDEA_CBC: + needed_len = IDEA_CBC_KEY_LEN; + break; + case OAKLEY_BLOWFISH_CBC: + needed_len = BLOWFISH_CBC_KEY_LEN; + break; + case OAKLEY_RC5_R16_B64_CBC: + needed_len = RC5_CBC_KEY_LEN; + break; +#endif + case OAKLEY_3DES_CBC: + needed_len = DES_CBC_BLOCK_SIZE * 3; + break; +#ifdef NOTYET + case OAKLEY_CAST_CBC: + needed_len = CAST_CBC_KEY_LEN; + break; +#endif + default: + log("Unknown block cipher ID for symmetric cipher"); + return -1; + } + + /* Generate initial decryption key material */ + /* key = prf(Nonce-X, Cookie-X); X={I,R} */ + ne.ptr = NULL; + hmac_init_chunk(&ctx, st->st_oakley.hasher, nonce); + hmac_update(&ctx, seedptr, seedlen); + hmac_final_chunk(ne, nestr, &ctx); + clonetochunk(*key, ne.ptr, ne.len, "Initial key material"); + + if (key->len < needed_len) { + freeanychunk(*key); + kchain.ptr = alloc_bytes(1, "initial zero octet"); + kchain.len = 1; + memset(kchain.ptr, 0, kchain.len); + while (key->len < needed_len) { + kk.ptr = NULL; + hmac_init_chunk(&ctx, st->st_oakley.hasher, ne); + hmac_update_chunk(&ctx, kchain); + hmac_final_chunk(kk, "extra key material", &ctx); + clonereplacechunk(kchain, kk.ptr, kk.len, "chain key material"); + /* Now append kk to key */ + if (! key->ptr ) { + clonetochunk(*key, kk.ptr, kk.len, "initial extra key material"); + } else { + k.ptr = alloc_bytes(key->len + kk.len, "appended key material"); + k.len = key->len + kk.len; + memcpy(k.ptr, key->ptr, key->len); + memcpy(&(k.ptr[key->len]), kk.ptr, kk.len); + freeanychunk(*key); + key->len = k.len; + key->ptr = k.ptr; + } + freeanychunk(kk); + } + freeanychunk(kchain); + } + + switch(st->st_oakley.encrypt) { + /* We really shouldn't deal with DES, */ + /* uncomment this if you must have it */ + case OAKLEY_DES_CBC: + (void)des_set_key_pluto((des_cblock *)key->ptr, ks->des_ks); + break; +#ifdef NOTYET + case OAKLEY_IDEA_CBC: + break; + case OAKLEY_BLOWFISH_CBC: + break; + case OAKLEY_RC5_R16_B64_CBC: + break; +#endif + case OAKLEY_3DES_CBC: + (void)des_set_key_pluto((des_cblock *)key->ptr + 0, ks->des3_ks.ks[0]); + (void)des_set_key_pluto((des_cblock *)key->ptr + 1, ks->des3_ks.ks[1]); + (void)des_set_key_pluto((des_cblock *)key->ptr + 2, ks->des3_ks.ks[2]); + break; +#ifdef NOTYET + case OAKLEY_CAST_CBC: + break; +#endif + } + + return 0; +} + +bool +encrypt_payload( struct state *st, keysched *ks, u_char *iv, + chunk_t inp, chunk_t *out ) +{ + chunk_t temp; + int blocklen; + u_char pv; + + switch(st->st_oakley.encrypt) { + case OAKLEY_DES_CBC: + blocklen = DES_CBC_BLOCK_SIZE; + break; +#ifdef NOTYET + case OAKLEY_IDEA_CBC: + break; + case OAKLEY_BLOWFISH_CBC: + break; + case OAKLEY_RC5_R16_B64_CBC: + break; +#endif + case OAKLEY_3DES_CBC: + blocklen = DES_CBC_BLOCK_SIZE; + break; +#ifdef NOTYET + case OAKLEY_CAST_CBC: + break; +#endif + } + + /* Pad the input up to a block size multiple */ + if (inp.len % blocklen == 0) { /* Add a full block for padding */ + pv = (u_char)blocklen; + temp.len = inp.len + (size_t)pv; + } else { + pv = (u_char)(blocklen - 1 - ((inp.len + blocklen - 1) % blocklen)); + temp.len = inp.len + (size_t)pv; + } + + temp.ptr = alloc_bytes(temp.len, "padded plaintext"); + memset(temp.ptr, 0, temp.len); + clonetochunk(*out, temp.ptr, temp.len, "ciphertext"); + memcpy(temp.ptr, inp.ptr, inp.len); + temp.ptr[temp.len-1] = pv; + + DBG(DBG_PARSING | DBG_CRYPT, + DBG_dump_chunk("Plaintext:", temp); + DBG_dump("Old IV: ", iv, blocklen); + ); + + switch(st->st_oakley.encrypt) { +#ifdef DES + case OAKLEY_DES_CBC: + des_ncbc_encrypt((des_cblock *)temp.ptr, (des_cblock *)out->ptr, + temp.len, ks->des_ks, (des_cblock *)iv, TRUE); + break; +#endif +#ifdef NOTYET + case OAKLEY_IDEA_CBC: + break; + case OAKLEY_BLOWFISH_CBC: + break; + case OAKLEY_RC5_R16_B64_CBC: + break; +#endif + case OAKLEY_3DES_CBC: + des_ede3_cbc_encrypt((des_cblock *)temp.ptr, (des_cblock *)out->ptr, + temp.len, + ks->des3_ks.ks[0], + ks->des3_ks.ks[1], + ks->des3_ks.ks[2], + (des_cblock *)iv, TRUE); + break; +#ifdef NOTYET + case OAKLEY_CAST_CBC: + break; +#endif + } + + DBG(DBG_PARSING | DBG_CRYPT, + DBG_dump_chunk("Ciphertext: ", *out); + DBG_dump("New IV: ", iv, blocklen); + ); + freeanychunk(temp); + return TRUE; +} + +bool +decrypt_payload( struct state *st, keysched *ks, u_char *iv, + chunk_t inp, chunk_t *out ) +{ + chunk_t temp; + int blocklen; + + switch(st->st_oakley.encrypt) { + case OAKLEY_DES_CBC: + blocklen = DES_CBC_BLOCK_SIZE; + break; +#ifdef NOTYET + case OAKLEY_IDEA_CBC: + break; + case OAKLEY_BLOWFISH_CBC: + break; + case OAKLEY_RC5_R16_B64_CBC: + break; +#endif + case OAKLEY_3DES_CBC: + blocklen = DES_CBC_BLOCK_SIZE; + break; +#ifdef NOTYET + case OAKLEY_CAST_CBC: + break; +#endif + } + + if (inp.len % blocklen != 0) { + log("Ciphertext is not a multiple of block length"); + return FALSE; + } + + DBG(DBG_PARSING | DBG_CRYPT, + DBG_dump_chunk("Ciphertext: ", inp); + DBG_dump("Old IV: ", iv, blocklen); + ); + + temp.ptr = alloc_bytes(inp.len, "temporary plaintext"); + temp.len = inp.len; + memset(temp.ptr, 0, temp.len); + + switch(st->st_oakley.encrypt) { +#ifdef DES + case OAKLEY_DES_CBC: + des_ncbc_encrypt((des_cblock *)inp.ptr, (des_cblock *)temp.ptr, + inp.len, ks->des_ks, (des_cblock *)iv, FALSE); + break; +#endif +#ifdef NOTYET + case OAKLEY_IDEA_CBC: + break; + case OAKLEY_BLOWFISH_CBC: + break; + case OAKLEY_RC5_R16_B64_CBC: + break; +#endif + case OAKLEY_3DES_CBC: + des_ede3_cbc_encrypt((des_cblock *)inp.ptr, (des_cblock *)temp.ptr, + inp.len, + ks->des3_ks.ks[0], + ks->des3_ks.ks[1], + ks->des3_ks.ks[2], + (des_cblock *)iv, FALSE); + break; +#ifdef NOTYET + case OAKLEY_CAST_CBC: + break; +#endif + } + + /* Strip padding from plaintext */ + if ((temp.ptr[temp.len-1] < (u_char)1) || + (temp.ptr[temp.len-1] > (u_char)blocklen) || + (temp.ptr[temp.len-1] > temp.len)) { + /* Impossible padding value */ + log("Impossible plaintext padding value: %d", temp.ptr[temp.len-1]); + memset(temp.ptr, 0, temp.len); + freeanychunk(temp); + return FALSE; + } + + out->len = temp.len - (size_t)(temp.ptr[temp.len-1]); + out->ptr = alloc_bytes(inp.len, "plaintext"); + memcpy(out->ptr, temp.ptr, out->len); + + DBG(DBG_PARSING | DBG_CRYPT, + DBG_dump_chunk("Plaintext: ", *out); + DBG_dump("New IV: ", iv, blocklen); + ); + + memset(temp.ptr, 0, temp.len); + freeanychunk(temp); + return TRUE; +} + +#endif diff -BbruN freeswan-1.91.orig/pluto/demux.h freeswan-1.91/pluto/demux.h --- freeswan-1.91.orig/pluto/demux.h Fri May 4 22:51:38 2001 +++ freeswan-1.91/pluto/demux.h Mon Jul 16 23:26:30 2001 @@ -77,3 +77,15 @@ } stf_status; typedef stf_status state_transition_fn(struct msg_digest *md); + +#ifdef OPENSSL +extern int derive_symmetric_key( struct state *st, const chunk_t nonce, + const u_char *seedptr, + const size_t seedlen, + keysched *ks, + chunk_t *key ); +extern bool encrypt_payload( struct state *st, keysched *ks, u_char *iv, + chunk_t inp, chunk_t *out ); +extern bool decrypt_payload( struct state *st, keysched *ks, u_char *iv, + chunk_t inp, chunk_t *out ); +#endif /* OPENSSL */ diff -BbruN freeswan-1.91.orig/pluto/dir2hash.8 freeswan-1.91/pluto/dir2hash.8 --- freeswan-1.91.orig/pluto/dir2hash.8 Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/dir2hash.8 Fri Aug 3 10:55:51 2001 @@ -0,0 +1,23 @@ +.TH "DIR2HASH" 8 +.SH NAME +ipsec dir2hash \- reparses a hashed directory to create a db file from the contents of same directory. +.SH SYNOPSIS +.B ipsec dir2hash + +.SH DESCRIPTION +dir2hash parses the contents of a hashed directory (by rehashcertdir) +and creates a db file with the same certificates as content. +This is merely a db implementation of hashed dirs, to speed up +access and lookups on a local host. +.SH HISTORY +Modified for Linux/FreeSWAN-PKIX by Luc Lanthier based on the +original work by Neil Dunbar in his pluto-openssl patch for +FreeSWAN 1.1. +.SH "SEE ALSO" +rehashcertdir +.SH BUGS +None known. +.SH TODO +Allow parsing PKCS7 and PKCS12 data in both DER and PEM formats. +Merge the rehashcert dir shell script and the dir2hash application into a single application. Maybe make it part of 'fswcert'. +Create additional options, such as --help, --outfile, etc.. diff -BbruN freeswan-1.91.orig/pluto/dir2hash.c freeswan-1.91/pluto/dir2hash.c --- freeswan-1.91.orig/pluto/dir2hash.c Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/dir2hash.c Thu Aug 2 20:01:04 2001 @@ -0,0 +1,1105 @@ +/* + * Convert an XMAP hash directory to a Berkeley DB hash file + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dir2hash.h" + +#ifdef HAVE_DB185 +#include +#else +#include +#endif + +#include +#include +#include +#include +#include + +#define VERSION_SIZE 4 +static unsigned char version_data[] = { '\00', '\00', '\00', '\01' }; + +#define TAGLEN 4 + +#define UID_PREFIX "uid-" + +#define X509_TYPE 0 +#define X509_CRL_TYPE 1 + +typedef struct _cert_st { + u_int8_t type; + union _inf { + X509 *x; + X509_CRL *c; + } info; + unsigned char *d; + size_t dlen; + unsigned char digest[SHA_DIGEST_LENGTH]; + struct _cert_st *next; +} CERT; + +typedef struct _xname_list_st { + unsigned char digest[SHA_DIGEST_LENGTH]; + struct _xname_list_st *next; +} XNAME_LIST; + +typedef struct _xname_st { + unsigned char *d; + size_t dlen; + int lcount; + XNAME_LIST *list; + struct _xname_st *next; +} XNAME; + +typedef unsigned long lset_t; + +const int NUM_X509V3_AltSubjectName = 2; + + +static const char *hashout = "certhash.db"; + +void *nalloc( size_t s ); +void dump( unsigned char *p, size_t l, const char *name ); +void free_xname_list_node( XNAME_LIST *node ); +void free_xname_node( XNAME *node ); +void free_xnames( XNAME **nl ); +XNAME *alloc_xname_node( const unsigned char *n, const size_t s ); +int add_unique_xname( XNAME **nl, X509_NAME *name, + const unsigned char *digest ); +int add_unique_xname( XNAME **nl, X509_NAME *name, + const unsigned char *digest ); +void add_unique_dns(XNAME **nl, X509 *x, const unsigned char *digest ); +void add_unique_ip(XNAME **nl, X509 *x, const unsigned char *digest ); +int isCA( X509 *x ); +void free_cert_node( CERT *c ); +int add_unique_xinf( CERT **cl, XNAME **xl, + XNAME **cal, XNAME **dnl, XNAME **ipl, + unsigned int type, void *x ); +void putcerts(DB *db, int start, int end, char *argv[], + CERT **cl, XNAME **xl, XNAME **cal, XNAME **dnl, XNAME **ipl); +void free_cert_list( CERT **cl ); +void putcrls(DB *db, int start, int end, char *argv[], CERT **cl, XNAME **xl); +int add_unique_uid(XNAME **ul, X509 *x, const char *uid); +void putuids(DB *db, int start, int end, char *argv[], XNAME **ul); + +void * +nalloc( size_t s ) +{ + void *t = malloc(s); + + if (!t) { + fprintf(stderr, "cannot allocate %d bytes\n", s); + exit(-1); + } + return t; +} + +void +dump( unsigned char *p, size_t l, const char *name ) +{ + int i; + + printf("%s: (length %d)\n", name, l); + for(i=0; id) free(node->d); + for(xl=node->list; xl;) { + p = xl->next; + free_xname_list_node(xl); + xl = p; + } + free(node); +} + +void +free_xnames( XNAME **nl ) +{ + XNAME *l, *p; + + if (!nl) return; + for(l = *nl; l; ) { + p = l->next; + free_xname_node(l); + l = p; + } + *nl = NULL; +} + +XNAME * +alloc_xname_node( const unsigned char *n, const size_t s ) +{ + /* Create an empty list for name store in n */ + XNAME *ret; + + ret = nalloc(sizeof(XNAME)); + ret->lcount = 0; + ret->list = NULL; + ret->dlen = s; + ret->d = nalloc(s); + memcpy(ret->d, n, s); + ret->next = NULL; + + return ret; +} + +int +add_unique_xname( XNAME **nl, X509_NAME *name, + const unsigned char *digest ) +{ + unsigned char *d, *dum; + size_t dlen; + XNAME *p; + int found, res = 1; + + /* Create DER form of name */ + + if (name == NULL) { + dlen = 1; + d = nalloc(dlen); + d[0] = '\0'; + } else { + dlen = i2d_X509_NAME(name, NULL); + d = nalloc(dlen); dum = d; + i2d_X509_NAME(name, &dum); + } + + /* Search nl for name */ + for (p=*nl, found = 0; ((!found) && (p)); + (!found) ? p=p->next : p) + if ((dlen == p->dlen) && (memcmp(d, p->d, dlen) == 0)) found = 1; + + if (found) { + XNAME_LIST *pp; + + /* add digest to list of names if not already there */ + for(pp = p->list, found = 0; ((!found) && (pp)); + (!found) ? pp=pp->next : pp) + if (memcmp(pp->digest, digest, SHA_DIGEST_LENGTH) == 0) found = 1; + + if (!found) { + XNAME_LIST *n = nalloc(sizeof(XNAME_LIST)); + n->next = p->list; + memcpy(n->digest, digest, SHA_DIGEST_LENGTH); + p->list = n; + p->lcount++; + } else + res = 0; + } else { + p = alloc_xname_node(d, dlen); + p->list = nalloc(sizeof(XNAME_LIST)); + p->list->next = NULL; + memcpy(p->list->digest, digest, SHA_DIGEST_LENGTH); + p->lcount = 1; + p->next = *nl; + *nl = p; + } + free(d); + return res; +} + +void +add_unique_dns(XNAME **nl, X509 *x, const unsigned char *digest ) +{ + unsigned char *d; + size_t dlen; + XNAME *p; + int found, res = 1; + int i, loc; + u_char *pp; + STACK_OF(GENERAL_NAME) *nsk = NULL; + X509_EXTENSION *ext; + GENERAL_NAME *gn; + + if ((loc = X509_get_ext_by_NID(x, NID_subject_alt_name, -1)) < 0) return; + if ((ext = X509_get_ext(x, loc)) == NULL) return; + pp = ext->value->data; + d2i_GENERAL_NAMES(&nsk, &pp, ext->value->length); + if (!nsk) return; + for(i=0; itype == GEN_DNS) { + dlen = gn->d.ia5->length; + d = nalloc(dlen); + memcpy(d, gn->d.ia5->data, dlen); + + for (p=*nl, found = 0; ((!found) && (p)); + (!found) ? p=p->next : p) + if ((dlen == p->dlen) && (memcmp(d, p->d, dlen) == 0)) found = 1; + + if (found) { + XNAME_LIST *pp; + + /* add digest to list of names if not already there */ + for(pp = p->list, found = 0; ((!found) && (pp)); + (!found) ? pp=pp->next : pp) + if (memcmp(pp->digest, digest, SHA_DIGEST_LENGTH) == 0) found = 1; + + if (!found) { + XNAME_LIST *n = nalloc(sizeof(XNAME_LIST)); + n->next = p->list; + memcpy(n->digest, digest, SHA_DIGEST_LENGTH); + p->list = n; + p->lcount++; + } else + res = 0; + } else { + p = alloc_xname_node(d, dlen); + p->list = nalloc(sizeof(XNAME_LIST)); + p->list->next = NULL; + memcpy(p->list->digest, digest, SHA_DIGEST_LENGTH); + p->lcount = 1; + p->next = *nl; + *nl = p; + } + free(d); + } + } + sk_GENERAL_NAME_free(nsk); +} + +void +add_unique_ip(XNAME **nl, X509 *x, const unsigned char *digest ) +{ + unsigned char *d; + size_t dlen; + XNAME *p; + int found, res = 1; + int i, loc; + u_char *pp; + STACK_OF(GENERAL_NAME) *nsk = NULL; + X509_EXTENSION *ext; + GENERAL_NAME *gn; + + if ((loc = X509_get_ext_by_NID(x, NID_subject_alt_name, -1)) < 0) return; + if ((ext = X509_get_ext(x, loc)) == NULL) return; + pp = ext->value->data; + d2i_GENERAL_NAMES(&nsk, &pp, ext->value->length); + if (!nsk) return; + for(i=0; itype == GEN_IPADD) { + dlen = gn->d.ip->length; + d = nalloc(dlen); + memcpy(d, gn->d.ip->data, dlen); + + for (p=*nl, found = 0; ((!found) && (p)); + (!found) ? p=p->next : p) + if ((dlen == p->dlen) && (memcmp(d, p->d, dlen) == 0)) found = 1; + + if (found) { + XNAME_LIST *pp; + + /* add digest to list of names if not already there */ + for(pp = p->list, found = 0; ((!found) && (pp)); + (!found) ? pp=pp->next : pp) + if (memcmp(pp->digest, digest, SHA_DIGEST_LENGTH) == 0) found = 1; + + if (!found) { + XNAME_LIST *n = nalloc(sizeof(XNAME_LIST)); + n->next = p->list; + memcpy(n->digest, digest, SHA_DIGEST_LENGTH); + p->list = n; + p->lcount++; + } else + res = 0; + } else { + p = alloc_xname_node(d, dlen); + p->list = nalloc(sizeof(XNAME_LIST)); + p->list->next = NULL; + memcpy(p->list->digest, digest, SHA_DIGEST_LENGTH); + p->lcount = 1; + p->next = *nl; + *nl = p; + } + free(d); + } + } + sk_GENERAL_NAME_free(nsk); +} + +int +isCA( X509 *x ) +{ + X509_EXTENSION *ext; + BASIC_CONSTRAINTS *p = NULL; + int loc; + + loc = X509_get_ext_by_NID(x, NID_basic_constraints, -1); + if (loc >= 0) { + ext = X509_get_ext(x, loc); + if (ext) { + p = X509V3_EXT_d2i(ext); + if (! p->ca) { + BASIC_CONSTRAINTS_free(p); + return 0; + } else { + BASIC_CONSTRAINTS_free(p); + return 1; /* This is a CA certificate */ + } + } else + return 0; + } else + return 0; +} + +void +free_cert_node( CERT *c ) +{ + if (c->d) free(c->d); + c->d = NULL; + switch(c->type) { + case X509_TYPE: if (c->info.x) X509_free(c->info.x); break; + case X509_CRL_TYPE: if (c->info.c) X509_CRL_free(c->info.c); break; + } + c->info.x = NULL; + memset(c->digest, 0, SHA_DIGEST_LENGTH); + c->next = NULL; + free(c); +} + +int +add_unique_xinf( CERT **cl, XNAME **xl, + XNAME **cal, XNAME **dnl, XNAME **ipl, + unsigned int type, void *x ) +{ + int f; + CERT *p, *node; + unsigned char *dum; + + if (!cl) return 0; + + node = nalloc(sizeof(CERT)); + node->next = NULL; + node->type = type; + switch(type) { + case X509_TYPE: + node->info.x = (X509 *)x; + node->dlen = i2d_X509((X509 *)x, NULL); + node->d = nalloc(node->dlen); + dum = node->d; + i2d_X509( (X509 *)x, &dum ); + break; + case X509_CRL_TYPE: + node->info.c = (X509_CRL *)x; + node->dlen = i2d_X509_CRL((X509_CRL *)x, NULL); + node->d = nalloc(node->dlen); + dum = node->d; + i2d_X509_CRL( (X509_CRL *)x, &dum ); + break; + default: + fprintf(stderr, "Unknown info type: %d\n", type); + free(node); + return 0; + } + + SHA1(node->d, node->dlen, node->digest); + + for(p=*cl, f=0; (!f) && (p); p=p->next) + if (memcmp(p->digest, node->digest, SHA_DIGEST_LENGTH) == 0) f=1; + /* found a duplicate */ + + if (!f) { + /* insert at head of list */ + node->next = *cl; + *cl = node; + switch(type) { + case X509_TYPE: + add_unique_xname(xl, X509_get_subject_name((X509 *)x), node->digest); + if (isCA(x)) add_unique_xname(cal, NULL, node->digest); + add_unique_dns(dnl, (X509 *)x, node->digest); + add_unique_ip(ipl, (X509 *)x, node->digest); + break; + case X509_CRL_TYPE: + add_unique_xname(xl, X509_CRL_get_issuer((X509_CRL *)x), node->digest); + break; + } + return 1; + } else + return 0; +} + +void +free_cert_list( CERT **cl ) +{ + CERT *c; + + if (!cl) return; + + for(c=*cl; c;) { + CERT *p = c->next; + + free_cert_node(c); + c = p; + } + *cl = NULL; +} + +static char dirname[PATH_MAX+1]; +static int +select_files(const struct dirent *de) +{ + struct stat st; + char path[PATH_MAX+1]; + + snprintf(path, sizeof(path), "%s/%s", dirname, de->d_name); + if (lstat(path, &st) == 0) { + if (S_ISREG(st.st_mode)) + return 1; + else + return 0; + } else { + perror("stat"); + return 0; + } +} + +static int +select_uid_files(const struct dirent *de) +{ + struct stat st; + char path[PATH_MAX+1]; + + if (strncasecmp(UID_PREFIX, de->d_name, strlen(UID_PREFIX)) != 0) return 0; + snprintf(path, sizeof(path), "%s/%s", dirname, de->d_name); + if (lstat(path, &st) == 0) { + if ((S_ISREG(st.st_mode)) || (S_ISLNK(st.st_mode))) + return 1; + else + return 0; + } else { + perror("stat"); + return 0; + } +} + +void +putcerts(DB *db, int start, int end, char *argv[], + CERT **cl, XNAME **xl, XNAME **cal, XNAME **dnl, XNAME **ipl) +{ + int i, j, n; + struct dirent **namelist = NULL; + char path[PATH_MAX+1]; + + for(i=start; i= 0) { + for(j=0; jd_name); + snprintf(path, sizeof(path), "%s/%s", argv[i], namelist[j]->d_name); + if ((b = BIO_new_file(path, "r")) != NULL) { + X509 *x; + + if (!(x = PEM_read_bio_X509(b, NULL, NULL, NULL))) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + x = d2i_X509_bio(b, NULL); + } + if ((x) && (!add_unique_xinf(cl, xl, cal, dnl, ipl, X509_TYPE, x))) + X509_free(x); + BIO_free(b); + } + } + free(namelist); + } else + perror("scandir"); + } +} + +void +putcrls(DB *db, int start, int end, char *argv[], CERT **cl, XNAME **xl) +{ + int i, j, n; + struct dirent **namelist = NULL; + char path[PATH_MAX+1]; + + for(i=start; i= 0) { + for(j=0; jd_name); + snprintf(path, sizeof(path), "%s/%s", argv[i], namelist[j]->d_name); + if ((b = BIO_new_file(path, "r")) != NULL) { + X509_CRL *c; + + if (!(c = PEM_read_bio_X509_CRL(b, NULL, NULL, NULL))) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + c = d2i_X509_CRL_bio(b, NULL); + } + if ((c) && + (!add_unique_xinf(cl, xl, NULL, NULL, NULL,X509_CRL_TYPE, c))) + X509_CRL_free(c); + + BIO_free(b); + } + } + free(namelist); + } else + perror("scandir"); + } +} + +int +add_unique_uid(XNAME **ul, X509 *x, const char *uid) +{ + int found; + XNAME *p; + unsigned char digest[SHA_DIGEST_LENGTH], *d, *dum; + size_t dlen; + + if (!x || !ul) return 0; + + dlen = i2d_X509(x, NULL); + d = nalloc(dlen); + dum = d; + i2d_X509( x, &dum ); + + SHA1(d, dlen, digest); + free(d); + + printf("Adding user id \"%s\"\n", uid); + for(found=0, p=*ul; ((!found) && (p)); + (!found) ? p=p->next : p) + if ((strlen(uid) == p->dlen) && (memcmp(p->d, uid, p->dlen) == 0)) + found = 1; + + if (found) { + XNAME_LIST *pp; + + for(pp = p->list, found = 0; ((!found) && (pp)); + pp=(!found) ? pp->next : pp) + if (memcmp(pp->digest, digest, SHA_DIGEST_LENGTH) == 0) found = 1; + + if (!found) { + XNAME_LIST *n = nalloc(sizeof(XNAME_LIST)); + n->next = p->list; + memcpy(n->digest, digest, SHA_DIGEST_LENGTH); + p->list = n; + p->lcount++; + } else + return 0; + } else { + p = alloc_xname_node(uid, strlen(uid)); + p->list = nalloc(sizeof(XNAME_LIST)); + p->list->next = NULL; + memcpy(p->list->digest, digest, SHA_DIGEST_LENGTH); + p->lcount = 1; + p->next = *ul; + *ul = p; + return 1; + } + return 0; +} + +static int +isuidchar( char c ) +{ + if (isalnum(c)) return 1; + if (c == '_') return 1; + return 0; +} + +void +putuids(DB *db, int start, int end, char *argv[], XNAME **ul) +{ + int i, j, n; + struct dirent **namelist = NULL; + char path[PATH_MAX+1]; + + for(i=start; i= 0) { + for(j=0; jd_name); + snprintf(path, sizeof(path), "%s/%s", argv[i], namelist[j]->d_name); + if ((b = BIO_new_file(path, "r")) != NULL) { + X509 *x; + + if (!(x = PEM_read_bio_X509(b, NULL, NULL, NULL))) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + x = d2i_X509_bio(b, NULL); + } + + n = nn = strdup(&(namelist[j]->d_name[strlen(UID_PREFIX)])); + while ((*nn) && (isuidchar(*nn))) nn++; + *nn = '\0'; + if ((x) && (!add_unique_uid(ul, x, n))) X509_free(x); + + BIO_free(b); + } + } + free(namelist); + } else + perror("scandir"); + } +} + +static void +help(char *argv[]) +{ + fprintf(stderr, "Usage: %s [OPTIONS] directory\n", argv[0]); + fprintf(stderr, + "\tOPTIONS:\n" + "\t-o --output\toutput DB filename to use\n" + "\t-h --help\tprint this help\n" + ); +} + +static int +create_db(int optind, int argc, char *argv[]) +{ + DB *db; + CERT *clist = NULL, *crlist = NULL; + XNAME *xlist = NULL, *nlist = NULL, *xcrlist = NULL, *calist = NULL; + XNAME *dnlist = NULL, *iplist = NULL; + + X509V3_add_standard_extensions(); + + if ((db = dbopen(hashout, O_CREAT | O_TRUNC | O_RDWR, 0644, DB_HASH, NULL)) == NULL) { + perror("dbopen"); + } else { + DBT k, v; + CERT *c; + XNAME *x; + unsigned char *kk, *vv; + + memset(&k, 0, sizeof(DBT)); + memset(&v, 0, sizeof(DBT)); + k.data = strdup("\xFF\xFF\xFF\xFFversion"); + k.size = strlen("version") + TAGLEN; + v.data = version_data; + v.size = VERSION_SIZE; + + if (db->put(db, &k, &v, 0) != 0) perror("dbput"); + db->sync(db, 0); + free(k.data); + + putcerts(db, optind, argc, argv, + &clist, &xlist, + &calist, &dnlist, &iplist); + putcrls(db, optind, argc, argv, &crlist, &xcrlist); + putuids(db, optind, argc, argv, &nlist); + + for(c=clist; c; c=c->next) { + k.size = SHA_DIGEST_LENGTH+TAGLEN; + k.data = nalloc(k.size); + v.size = c->dlen; + v.data = nalloc(v.size); + + kk = k.data; + vv = v.data; + memset(kk, 0, TAGLEN); + memcpy(&kk[TAGLEN], c->digest, SHA_DIGEST_LENGTH); + memcpy(vv, c->d, c->dlen); + + if (db->put(db, &k, &v, 0) != 0) perror("dbput"); + free(k.data); + free(v.data); + } + free_cert_list(&clist); + + for(x=xlist; x; x=x->next) { + u_int32_t cnt; + int i; + XNAME_LIST *p; + + k.size = x->dlen + TAGLEN; + k.data = nalloc(k.size); + v.size = TAGLEN + x->lcount * SHA_DIGEST_LENGTH; + v.data = nalloc(v.size); + kk = k.data; + vv = v.data; + + memset(kk, 0, TAGLEN-1); kk[TAGLEN-1] = '\01'; + memcpy(&kk[TAGLEN], x->d, x->dlen); + cnt = htonl(x->lcount); + memcpy(vv, (unsigned char *)&cnt, TAGLEN); + for(i=0, p=x->list; ilcount; i++, p=p->next) + memcpy(&vv[TAGLEN + i*SHA_DIGEST_LENGTH], + p->digest, SHA_DIGEST_LENGTH); + if (db->put(db, &k, &v, 0) < 0) perror("dbput"); + free(k.data); + free(v.data); + } + free_xnames(&xlist); + + for(x=calist; x; x=x->next) { + u_int32_t cnt; + int i; + XNAME_LIST *p; + + k.size = TAGLEN; + k.data = nalloc(k.size); + v.size = TAGLEN + x->lcount * SHA_DIGEST_LENGTH; + v.data = nalloc(v.size); + kk = k.data; + vv = v.data; + + memset(kk, 0, TAGLEN-1); kk[TAGLEN-1] = '\05'; + cnt = htonl(x->lcount); + memcpy(vv, (unsigned char *)&cnt, TAGLEN); + for(i=0, p=x->list; ilcount; i++, p=p->next) + memcpy(&vv[TAGLEN + i*SHA_DIGEST_LENGTH], + p->digest, SHA_DIGEST_LENGTH); + if (db->put(db, &k, &v, 0) != 0) perror("dbput"); + free(k.data); + free(v.data); + } + free_xnames(&calist); + + for(x=dnlist; x; x=x->next) { + u_int32_t cnt; + int i; + XNAME_LIST *p; + + k.size = x->dlen + TAGLEN; + k.data = nalloc(k.size); + v.size = TAGLEN + x->lcount * SHA_DIGEST_LENGTH; + v.data = nalloc(v.size); + kk = k.data; + vv = v.data; + + memset(kk, 0, TAGLEN-1); kk[TAGLEN-1] = '\06'; + memcpy(&kk[TAGLEN], x->d, x->dlen); + cnt = htonl(x->lcount); + memcpy(vv, (unsigned char *)&cnt, TAGLEN); + for(i=0, p=x->list; ilcount; i++, p=p->next) + memcpy(&vv[TAGLEN + i*SHA_DIGEST_LENGTH], + p->digest, SHA_DIGEST_LENGTH); + if (db->put(db, &k, &v, 0) != 0) perror("dbput"); + free(k.data); + free(v.data); + } + free_xnames(&dnlist); + + for(x=iplist; x; x=x->next) { + u_int32_t cnt; + int i; + XNAME_LIST *p; + + k.size = x->dlen + TAGLEN; + k.data = nalloc(k.size); + v.size = TAGLEN + x->lcount * SHA_DIGEST_LENGTH; + v.data = nalloc(v.size); + kk = k.data; + vv = v.data; + + memset(kk, 0, TAGLEN-1); kk[TAGLEN-1] = '\07'; + memcpy(&kk[TAGLEN], x->d, x->dlen); + cnt = htonl(x->lcount); + memcpy(vv, (unsigned char *)&cnt, TAGLEN); + for(i=0, p=x->list; ilcount; i++, p=p->next) + memcpy(&vv[TAGLEN + i*SHA_DIGEST_LENGTH], + p->digest, SHA_DIGEST_LENGTH); + if (db->put(db, &k, &v, 0) != 0) perror("dbput"); + free(k.data); + free(v.data); + } + free_xnames(&iplist); + + for(c=crlist; c; c=c->next) { + k.size = SHA_DIGEST_LENGTH+TAGLEN; + k.data = nalloc(k.size); + v.size = c->dlen; + v.data = nalloc(v.size); + + kk = k.data; + vv = v.data; + memset(kk, 0, TAGLEN-1); kk[TAGLEN-1] = '\04'; + memcpy(&kk[TAGLEN], c->digest, SHA_DIGEST_LENGTH); + memcpy(vv, c->d, c->dlen); + + if (db->put(db, &k, &v, 0) != 0) perror("dbput"); + free(k.data); + free(v.data); + } + free_cert_list(&crlist); + + for(x=xcrlist; x; x=x->next) { + u_int32_t cnt; + int i; + XNAME_LIST *p; + + k.size = x->dlen + TAGLEN; + k.data = nalloc(k.size); + v.size = TAGLEN + x->lcount * SHA_DIGEST_LENGTH; + v.data = nalloc(v.size); + kk = k.data; + vv = v.data; + + memset(kk, 0, TAGLEN-1); kk[TAGLEN-1] = '\02'; + memcpy(&kk[TAGLEN], x->d, x->dlen); + cnt = htonl(x->lcount); + memcpy(vv, (unsigned char *)&cnt, TAGLEN); + for(i=0, p=x->list; ilcount; i++, p=p->next) + memcpy(&vv[TAGLEN + i*SHA_DIGEST_LENGTH], + p->digest, SHA_DIGEST_LENGTH); + if (db->put(db, &k, &v, 0) != 0) perror("dbput"); + free(k.data); + free(v.data); + } + free_xnames(&xcrlist); + + for(x=nlist; x; x=x->next) { + u_int32_t cnt; + int i; + XNAME_LIST *p; + + k.size = x->dlen + TAGLEN; + k.data = nalloc(k.size); + v.size = TAGLEN + x->lcount * SHA_DIGEST_LENGTH; + v.data = nalloc(v.size); + kk = k.data; + vv = v.data; + + memset(kk, 0, TAGLEN-1); kk[TAGLEN-1] = '\03'; + memcpy(&kk[TAGLEN], x->d, x->dlen); + cnt = htonl(x->lcount); + memcpy(vv, (unsigned char *)&cnt, TAGLEN); + for(i=0, p=x->list; ilcount; i++, p=p->next) + memcpy(&vv[TAGLEN + i*SHA_DIGEST_LENGTH], + p->digest, SHA_DIGEST_LENGTH); + if (db->put(db, &k, &v, 0) != 0) perror("dbput"); + free(k.data); + free(v.data); + } + free_xnames(&nlist); + db->close(db); + } + + printf("Dumping keys from DB file\n"); + if ((db = dbopen(hashout, 0, 0, DB_HASH, NULL)) == NULL) { + perror("db_open"); + } else { + DBT k, v; + int i; + + memset(&k, 0, sizeof(k)); + memset(&v, 0, sizeof(v)); + while (db->seq(db, &k, &v, R_NEXT) == 0) { + if (k.size < TAGLEN) + fprintf(stderr, "Error: key value too short\n"); + else { + unsigned char *kk = k.data, *vv = v.data, *p; + u_int32_t c1, c2; + X509_NAME *xn; + + switch(kk[TAGLEN-1]) { + case 0: + printf("X509 Certificate\n"); + dump(&kk[TAGLEN], k.size-TAGLEN, "SHA-DIGEST"); + printf("Data Length %d\n", v.size); + break; + case 1: + printf("X509 Subject Name\n"); + p = &kk[TAGLEN]; + if ((xn = d2i_X509_NAME(NULL, &p, k.size-TAGLEN)) != NULL) { + char buf[256]; + + X509_NAME_oneline(xn, buf, sizeof(buf)); + printf("%s:\n", buf); + X509_NAME_free(xn); + memcpy((unsigned char *)(&c1), v.data, TAGLEN); + c2 = ntohl(c1); + if (v.size != TAGLEN + (SHA_DIGEST_LENGTH * c2)) { + fprintf(stderr, "X509 name length error\n"); + } else { + for(i=0; iclose(db); + } + printf("Done\n"); + + X509V3_EXT_cleanup(); + return 0; +} + +int +main( int argc, char *argv[] ) +{ + int c; + lset_t allopts = 0x00; + int option_index = 0; + int error = 0; + + while(1) { + static struct option long_options[] = { + { "output", 1, 0, 'o'}, + { "help", 0, 0, 'h'}, + { NULL, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "ho:r", + long_options, &option_index); + if (c == -1) break; + + switch(c) { + case 0: + if (strcasecmp(long_options[option_index].name, "output") == 0) + hashout = optarg; + allopts |= OPT_DB; + break; + case 'o': + hashout = optarg; + allopts |= OPT_DB; + break; + case 'h': + help(argv); + return 0; + default: + help(argv); + return 1; + } + } + + if (allopts & OPT_DB) { + error = create_db(optind, argc, argv); + if (error) return error; + } + + return 0; +} diff -BbruN freeswan-1.91.orig/pluto/dir2hash.h freeswan-1.91/pluto/dir2hash.h --- freeswan-1.91.orig/pluto/dir2hash.h Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/dir2hash.h Wed Aug 1 16:03:24 2001 @@ -0,0 +1,5 @@ +/* + * Convert an XMAP hash directory to a Berkeley DB hash file + */ +#define OPT_DB 0x01 +#define OPT_REHASH 0x02 diff -BbruN freeswan-1.91.orig/pluto/dsa.c freeswan-1.91/pluto/dsa.c --- freeswan-1.91.orig/pluto/dsa.c Mon Nov 1 16:52:39 1999 +++ freeswan-1.91/pluto/dsa.c Wed Dec 31 19:00:00 1969 @@ -1,476 +0,0 @@ -/* dsa.c - DSA signature scheme - * Copyright (C) 1998 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef PLUTO -#include -#include -#include "constants.h" -#include "defs.h" -#include "log.h" -#include "rnd.h" -#include "gcryptfix.h" -#else /*! PLUTO */ -/* #include */ -#endif /* !PLUTO */ - -#include -#include -#include - -#ifndef PLUTO -/* #include */ -/* #include "util.h" */ -/* #include "mpi.h" */ -/* #include "cipher.h" */ -#endif - -#include "dsa.h" - -typedef struct { - MPI p; /* prime */ - MPI q; /* group order */ - MPI g; /* group generator */ - MPI y; /* g^x mod p */ -} DSA_public_key; - - -typedef struct { - MPI p; /* prime */ - MPI q; /* group order */ - MPI g; /* group generator */ - MPI y; /* g^x mod p */ - MPI x; /* secret exponent */ -} DSA_secret_key; - - -static MPI gen_k( MPI q ); -static void test_keys( DSA_secret_key *sk, unsigned qbits ); -static int check_secret_key( DSA_secret_key *sk ); -static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors ); -static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey); -static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey); - -static void -progress( int c ) -{ - fputc( c, stderr ); -} - - -/**************** - * Generate a random secret exponent k less than q - */ -static MPI -gen_k( MPI q ) -{ - MPI k = mpi_alloc_secure( mpi_get_nlimbs(q) ); - unsigned int nbits = mpi_get_nbits(q); - unsigned int nbytes = (nbits+7)/8; - char *rndbuf = NULL; - - if( DBG_CIPHER ) - log_debug("choosing a random k "); - for(;;) { - if( DBG_CIPHER ) - progress('.'); - - if( !rndbuf || nbits < 32 ) { - m_free(rndbuf); - rndbuf = get_random_bits( nbits, 1, 1 ); - } - else { /* change only some of the higher bits */ - /* we could imporove this by directly requesting more memory - * at the first call to get_random_bits() and use this the here - * maybe it is easier to do this directly in random.c */ - char *pp = get_random_bits( 32, 1, 1 ); - memcpy( rndbuf,pp, 4 ); - m_free(pp); - } - mpi_set_buffer( k, rndbuf, nbytes, 0 ); - if( mpi_test_bit( k, nbits-1 ) ) - mpi_set_highbit( k, nbits-1 ); - else { - mpi_set_highbit( k, nbits-1 ); - mpi_clear_bit( k, nbits-1 ); - } - - if( !(mpi_cmp( k, q ) < 0) ) { /* check: k < q */ - if( DBG_CIPHER ) - progress('+'); - continue; /* no */ - } - if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */ - if( DBG_CIPHER ) - progress('-'); - continue; /* no */ - } - break; /* okay */ - } - m_free(rndbuf); - if( DBG_CIPHER ) - progress('\n'); - - return k; -} - - -static void -test_keys( DSA_secret_key *sk, unsigned qbits ) -{ - DSA_public_key pk; - MPI test = mpi_alloc( qbits / BITS_PER_MPI_LIMB ); - MPI out1_a = mpi_alloc( qbits / BITS_PER_MPI_LIMB ); - MPI out1_b = mpi_alloc( qbits / BITS_PER_MPI_LIMB ); - - pk.p = sk->p; - pk.q = sk->q; - pk.g = sk->g; - pk.y = sk->y; - /*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/ - { char *p = get_random_bits( qbits, 0, 0 ); - mpi_set_buffer( test, p, (qbits+7)/8, 0 ); - m_free(p); - } - - sign( out1_a, out1_b, test, sk ); - if( !verify( out1_a, out1_b, test, &pk ) ) - log_fatal("DSA:: sign, verify failed\n"); - - mpi_free( test ); - mpi_free( out1_a ); - mpi_free( out1_b ); -} - - - -/**************** - * Generate a DSA key pair with a key of size NBITS - * Returns: 2 structures filled with all needed values - * and an array with the n-1 factors of (p-1) - */ -static void -generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors ) -{ - MPI p; /* the prime */ - MPI q; /* the 160 bit prime factor */ - MPI g; /* the generator */ - MPI y; /* g^x mod p */ - MPI x; /* the secret exponent */ - MPI h, e; /* helper */ - unsigned qbits; - byte *rndbuf; - - assert( nbits >= 512 && nbits <= 1024 ); - - qbits = 160; - p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors ); - /* get q out of factors */ - q = mpi_copy((*ret_factors)[0]); - if( mpi_get_nbits(q) != qbits ) - BUG(); - - /* find a generator g (h and e are helpers)*/ - /* e = (p-1)/q */ - e = mpi_alloc( mpi_get_nlimbs(p) ); - mpi_sub_ui( e, p, 1 ); - mpi_fdiv_q( e, e, q ); - g = mpi_alloc( mpi_get_nlimbs(p) ); - h = mpi_alloc_set_ui( 1 ); /* we start with 2 */ - do { - mpi_add_ui( h, h, 1 ); - /* g = h^e mod p */ - mpi_powm( g, h, e, p ); - } while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */ - - /* select a random number which has these properties: - * 0 < x < q-1 - * This must be a very good random number because this - * is the secret part. */ - if( DBG_CIPHER ) - log_debug("choosing a random x "); - assert( qbits >= 160 ); - x = mpi_alloc_secure( mpi_get_nlimbs(q) ); - mpi_sub_ui( h, q, 1 ); /* put q-1 into h */ - rndbuf = NULL; - do { - if( DBG_CIPHER ) - progress('.'); - if( !rndbuf ) - rndbuf = get_random_bits( qbits, 2, 1 ); - else { /* change only some of the higher bits (= 2 bytes)*/ - char *r = get_random_bits( 16, 2, 1 ); - memcpy(rndbuf, r, 16/8 ); - m_free(r); - } - mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 ); - mpi_clear_highbit( x, qbits+1 ); - } while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) ); - m_free(rndbuf); - mpi_free( e ); - mpi_free( h ); - - /* y = g^x mod p */ - y = mpi_alloc( mpi_get_nlimbs(p) ); - mpi_powm( y, g, x, p ); - - if( DBG_CIPHER ) { - progress('\n'); - log_mpidump("dsa p= ", p ); - log_mpidump("dsa q= ", q ); - log_mpidump("dsa g= ", g ); - log_mpidump("dsa y= ", y ); - log_mpidump("dsa x= ", x ); - } - - /* copy the stuff to the key structures */ - sk->p = p; - sk->q = q; - sk->g = g; - sk->y = y; - sk->x = x; - - /* now we can test our keys (this should never fail!) */ - test_keys( sk, qbits ); -} - - - -/**************** - * Test whether the secret key is valid. - * Returns: if this is a valid key. - */ -static int -check_secret_key( DSA_secret_key *sk ) -{ - int rc; - MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) ); - - mpi_powm( y, sk->g, sk->x, sk->p ); - rc = !mpi_cmp( y, sk->y ); - mpi_free( y ); - return rc; -} - - - -/**************** - * Make a DSA signature from HASH and put it into r and s. - */ - -static void -sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey ) -{ - MPI k; - MPI kinv; - MPI tmp; - - /* select a random k with 0 < k < q */ - k = gen_k( skey->q ); - - /* r = (a^k mod p) mod q */ - mpi_powm( r, skey->g, k, skey->p ); - mpi_fdiv_r( r, r, skey->q ); - - /* kinv = k^(-1) mod q */ - kinv = mpi_alloc( mpi_get_nlimbs(k) ); - mpi_invm(kinv, k, skey->q ); - - /* s = (kinv * ( hash + x * r)) mod q */ - tmp = mpi_alloc( mpi_get_nlimbs(skey->p) ); - mpi_mul( tmp, skey->x, r ); - mpi_add( tmp, tmp, hash ); - mpi_mulm( s , kinv, tmp, skey->q ); - - mpi_free(k); - mpi_free(kinv); - mpi_free(tmp); -} - - -/**************** - * Returns true if the signature composed from R and S is valid. - */ -static int -verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey ) -{ - int rc; - MPI w, u1, u2, v; - MPI base[3]; - MPI exp[3]; - - - if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) ) - return 0; /* assertion 0 < r < q failed */ - if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) ) - return 0; /* assertion 0 < s < q failed */ - - w = mpi_alloc( mpi_get_nlimbs(pkey->q) ); - u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) ); - u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) ); - v = mpi_alloc( mpi_get_nlimbs(pkey->p) ); - - /* w = s^(-1) mod q */ - mpi_invm( w, s, pkey->q ); - - /* u1 = (hash * w) mod q */ - mpi_mulm( u1, hash, w, pkey->q ); - - /* u2 = r * w mod q */ - mpi_mulm( u2, r, w, pkey->q ); - - /* v = g^u1 * y^u2 mod p mod q */ - base[0] = pkey->g; exp[0] = u1; - base[1] = pkey->y; exp[1] = u2; - base[2] = NULL; exp[2] = NULL; - mpi_mulpowm( v, base, exp, pkey->p ); - mpi_fdiv_r( v, v, pkey->q ); - - rc = !mpi_cmp( v, r ); - - mpi_free(w); - mpi_free(u1); - mpi_free(u2); - mpi_free(v); - return rc; -} - - -/********************************************* - ************** interface ****************** - *********************************************/ - -int -dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) -{ - DSA_secret_key sk; - - if( algo != PUBKEY_ALGO_DSA ) - return G10ERR_PUBKEY_ALGO; - - generate( &sk, nbits, retfactors ); - skey[0] = sk.p; - skey[1] = sk.q; - skey[2] = sk.g; - skey[3] = sk.y; - skey[4] = sk.x; - return 0; -} - - -int -dsa_check_secret_key( int algo, MPI *skey ) -{ - DSA_secret_key sk; - - if( algo != PUBKEY_ALGO_DSA ) - return G10ERR_PUBKEY_ALGO; - if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] ) - return G10ERR_BAD_MPI; - - sk.p = skey[0]; - sk.q = skey[1]; - sk.g = skey[2]; - sk.y = skey[3]; - sk.x = skey[4]; - if( !check_secret_key( &sk ) ) - return G10ERR_BAD_SECKEY; - - return 0; -} - - - -int -dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey ) -{ - DSA_secret_key sk; - - if( algo != PUBKEY_ALGO_DSA ) - return G10ERR_PUBKEY_ALGO; - if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] ) - return G10ERR_BAD_MPI; - - sk.p = skey[0]; - sk.q = skey[1]; - sk.g = skey[2]; - sk.y = skey[3]; - sk.x = skey[4]; - resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) ); - resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) ); - sign( resarr[0], resarr[1], data, &sk ); - return 0; -} - -int -dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey, - int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED) -{ - DSA_public_key pk; - - if( algo != PUBKEY_ALGO_DSA ) - return G10ERR_PUBKEY_ALGO; - if( !data[0] || !data[1] || !hash - || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] ) - return G10ERR_BAD_MPI; - - pk.p = pkey[0]; - pk.q = pkey[1]; - pk.g = pkey[2]; - pk.y = pkey[3]; - if( !verify( data[0], data[1], hash, &pk ) ) - return G10ERR_BAD_SIGN; - return 0; -} - - - -unsigned -dsa_get_nbits( int algo, MPI *pkey ) -{ - if( algo != PUBKEY_ALGO_DSA ) - return 0; - return mpi_get_nbits( pkey[0] ); -} - - -/**************** - * Return some information about the algorithm. We need algo here to - * distinguish different flavors of the algorithm. - * Returns: A pointer to string describing the algorithm or NULL if - * the ALGO is invalid. - * Usage: Bit 0 set : allows signing - * 1 set : allows encryption - */ -const char * -dsa_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig, - int *use ) -{ - *npkey = 4; - *nskey = 5; - *nenc = 0; - *nsig = 2; - - switch( algo ) { - case PUBKEY_ALGO_DSA: *use = PUBKEY_USAGE_SIG; return "DSA"; - default: *use = 0; return NULL; - } -} - - diff -BbruN freeswan-1.91.orig/pluto/dsa.h freeswan-1.91/pluto/dsa.h --- freeswan-1.91.orig/pluto/dsa.h Mon Nov 1 16:48:08 1999 +++ freeswan-1.91/pluto/dsa.h Wed Dec 31 19:00:00 1969 @@ -1,32 +0,0 @@ -/* dsa.h - DSA signature scheme - * Copyright (C) 1998 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_DSA_H -#define G10_DSA_H - -int dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ); -int dsa_check_secret_key( int algo, MPI *skey ); -int dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey ); -int dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey, - int (*cmp)(void *, MPI), void *opaquev ); -unsigned dsa_get_nbits( int algo, MPI *pkey ); -const char *dsa_get_info( int algo, int *npkey, int *nskey, - int *nenc, int *nsig, int *use ); - -#endif /*G10_DSA_H*/ diff -BbruN freeswan-1.91.orig/pluto/g10_dsa.c freeswan-1.91/pluto/g10_dsa.c --- freeswan-1.91.orig/pluto/g10_dsa.c Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/g10_dsa.c Mon Jul 16 23:26:30 2001 @@ -0,0 +1,476 @@ +/* g10_dsa.c - DSA signature scheme + * Copyright (C) 1998 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef PLUTO +#include +#include +#include "constants.h" +#include "defs.h" +#include "log.h" +#include "rnd.h" +#include "gcryptfix.h" +#else /*! PLUTO */ +/* #include */ +#endif /* !PLUTO */ + +#include +#include +#include + +#ifndef PLUTO +/* #include */ +/* #include "util.h" */ +/* #include "mpi.h" */ +/* #include "cipher.h" */ +#endif + +#include "g10_dsa.h" + +typedef struct { + MPI p; /* prime */ + MPI q; /* group order */ + MPI g; /* group generator */ + MPI y; /* g^x mod p */ +} DSA_public_key; + + +typedef struct { + MPI p; /* prime */ + MPI q; /* group order */ + MPI g; /* group generator */ + MPI y; /* g^x mod p */ + MPI x; /* secret exponent */ +} DSA_secret_key; + + +static MPI gen_k( MPI q ); +static void test_keys( DSA_secret_key *sk, unsigned qbits ); +static int check_secret_key( DSA_secret_key *sk ); +static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors ); +static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey); +static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey); + +static void +progress( int c ) +{ + fputc( c, stderr ); +} + + +/**************** + * Generate a random secret exponent k less than q + */ +static MPI +gen_k( MPI q ) +{ + MPI k = mpi_alloc_secure( mpi_get_nlimbs(q) ); + unsigned int nbits = mpi_get_nbits(q); + unsigned int nbytes = (nbits+7)/8; + char *rndbuf = NULL; + + if( DBG_CIPHER ) + log_debug("choosing a random k "); + for(;;) { + if( DBG_CIPHER ) + progress('.'); + + if( !rndbuf || nbits < 32 ) { + m_free(rndbuf); + rndbuf = get_random_bits( nbits, 1, 1 ); + } + else { /* change only some of the higher bits */ + /* we could imporove this by directly requesting more memory + * at the first call to get_random_bits() and use this the here + * maybe it is easier to do this directly in random.c */ + char *pp = get_random_bits( 32, 1, 1 ); + memcpy( rndbuf,pp, 4 ); + m_free(pp); + } + mpi_set_buffer( k, rndbuf, nbytes, 0 ); + if( mpi_test_bit( k, nbits-1 ) ) + mpi_set_highbit( k, nbits-1 ); + else { + mpi_set_highbit( k, nbits-1 ); + mpi_clear_bit( k, nbits-1 ); + } + + if( !(mpi_cmp( k, q ) < 0) ) { /* check: k < q */ + if( DBG_CIPHER ) + progress('+'); + continue; /* no */ + } + if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */ + if( DBG_CIPHER ) + progress('-'); + continue; /* no */ + } + break; /* okay */ + } + m_free(rndbuf); + if( DBG_CIPHER ) + progress('\n'); + + return k; +} + + +static void +test_keys( DSA_secret_key *sk, unsigned qbits ) +{ + DSA_public_key pk; + MPI test = mpi_alloc( qbits / BITS_PER_MPI_LIMB ); + MPI out1_a = mpi_alloc( qbits / BITS_PER_MPI_LIMB ); + MPI out1_b = mpi_alloc( qbits / BITS_PER_MPI_LIMB ); + + pk.p = sk->p; + pk.q = sk->q; + pk.g = sk->g; + pk.y = sk->y; + /*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/ + { char *p = get_random_bits( qbits, 0, 0 ); + mpi_set_buffer( test, p, (qbits+7)/8, 0 ); + m_free(p); + } + + sign( out1_a, out1_b, test, sk ); + if( !verify( out1_a, out1_b, test, &pk ) ) + log_fatal("DSA:: sign, verify failed\n"); + + mpi_free( test ); + mpi_free( out1_a ); + mpi_free( out1_b ); +} + + + +/**************** + * Generate a DSA key pair with a key of size NBITS + * Returns: 2 structures filled with all needed values + * and an array with the n-1 factors of (p-1) + */ +static void +generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors ) +{ + MPI p; /* the prime */ + MPI q; /* the 160 bit prime factor */ + MPI g; /* the generator */ + MPI y; /* g^x mod p */ + MPI x; /* the secret exponent */ + MPI h, e; /* helper */ + unsigned qbits; + byte *rndbuf; + + assert( nbits >= 512 && nbits <= 1024 ); + + qbits = 160; + p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors ); + /* get q out of factors */ + q = mpi_copy((*ret_factors)[0]); + if( mpi_get_nbits(q) != qbits ) + BUG(); + + /* find a generator g (h and e are helpers)*/ + /* e = (p-1)/q */ + e = mpi_alloc( mpi_get_nlimbs(p) ); + mpi_sub_ui( e, p, 1 ); + mpi_fdiv_q( e, e, q ); + g = mpi_alloc( mpi_get_nlimbs(p) ); + h = mpi_alloc_set_ui( 1 ); /* we start with 2 */ + do { + mpi_add_ui( h, h, 1 ); + /* g = h^e mod p */ + mpi_powm( g, h, e, p ); + } while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */ + + /* select a random number which has these properties: + * 0 < x < q-1 + * This must be a very good random number because this + * is the secret part. */ + if( DBG_CIPHER ) + log_debug("choosing a random x "); + assert( qbits >= 160 ); + x = mpi_alloc_secure( mpi_get_nlimbs(q) ); + mpi_sub_ui( h, q, 1 ); /* put q-1 into h */ + rndbuf = NULL; + do { + if( DBG_CIPHER ) + progress('.'); + if( !rndbuf ) + rndbuf = get_random_bits( qbits, 2, 1 ); + else { /* change only some of the higher bits (= 2 bytes)*/ + char *r = get_random_bits( 16, 2, 1 ); + memcpy(rndbuf, r, 16/8 ); + m_free(r); + } + mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 ); + mpi_clear_highbit( x, qbits+1 ); + } while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) ); + m_free(rndbuf); + mpi_free( e ); + mpi_free( h ); + + /* y = g^x mod p */ + y = mpi_alloc( mpi_get_nlimbs(p) ); + mpi_powm( y, g, x, p ); + + if( DBG_CIPHER ) { + progress('\n'); + log_mpidump("dsa p= ", p ); + log_mpidump("dsa q= ", q ); + log_mpidump("dsa g= ", g ); + log_mpidump("dsa y= ", y ); + log_mpidump("dsa x= ", x ); + } + + /* copy the stuff to the key structures */ + sk->p = p; + sk->q = q; + sk->g = g; + sk->y = y; + sk->x = x; + + /* now we can test our keys (this should never fail!) */ + test_keys( sk, qbits ); +} + + + +/**************** + * Test whether the secret key is valid. + * Returns: if this is a valid key. + */ +static int +check_secret_key( DSA_secret_key *sk ) +{ + int rc; + MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) ); + + mpi_powm( y, sk->g, sk->x, sk->p ); + rc = !mpi_cmp( y, sk->y ); + mpi_free( y ); + return rc; +} + + + +/**************** + * Make a DSA signature from HASH and put it into r and s. + */ + +static void +sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey ) +{ + MPI k; + MPI kinv; + MPI tmp; + + /* select a random k with 0 < k < q */ + k = gen_k( skey->q ); + + /* r = (a^k mod p) mod q */ + mpi_powm( r, skey->g, k, skey->p ); + mpi_fdiv_r( r, r, skey->q ); + + /* kinv = k^(-1) mod q */ + kinv = mpi_alloc( mpi_get_nlimbs(k) ); + mpi_invm(kinv, k, skey->q ); + + /* s = (kinv * ( hash + x * r)) mod q */ + tmp = mpi_alloc( mpi_get_nlimbs(skey->p) ); + mpi_mul( tmp, skey->x, r ); + mpi_add( tmp, tmp, hash ); + mpi_mulm( s , kinv, tmp, skey->q ); + + mpi_free(k); + mpi_free(kinv); + mpi_free(tmp); +} + + +/**************** + * Returns true if the signature composed from R and S is valid. + */ +static int +verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey ) +{ + int rc; + MPI w, u1, u2, v; + MPI base[3]; + MPI exp[3]; + + + if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) ) + return 0; /* assertion 0 < r < q failed */ + if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) ) + return 0; /* assertion 0 < s < q failed */ + + w = mpi_alloc( mpi_get_nlimbs(pkey->q) ); + u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) ); + u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) ); + v = mpi_alloc( mpi_get_nlimbs(pkey->p) ); + + /* w = s^(-1) mod q */ + mpi_invm( w, s, pkey->q ); + + /* u1 = (hash * w) mod q */ + mpi_mulm( u1, hash, w, pkey->q ); + + /* u2 = r * w mod q */ + mpi_mulm( u2, r, w, pkey->q ); + + /* v = g^u1 * y^u2 mod p mod q */ + base[0] = pkey->g; exp[0] = u1; + base[1] = pkey->y; exp[1] = u2; + base[2] = NULL; exp[2] = NULL; + mpi_mulpowm( v, base, exp, pkey->p ); + mpi_fdiv_r( v, v, pkey->q ); + + rc = !mpi_cmp( v, r ); + + mpi_free(w); + mpi_free(u1); + mpi_free(u2); + mpi_free(v); + return rc; +} + + +/********************************************* + ************** interface ****************** + *********************************************/ + +int +dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) +{ + DSA_secret_key sk; + + if( algo != PUBKEY_ALGO_DSA ) + return G10ERR_PUBKEY_ALGO; + + generate( &sk, nbits, retfactors ); + skey[0] = sk.p; + skey[1] = sk.q; + skey[2] = sk.g; + skey[3] = sk.y; + skey[4] = sk.x; + return 0; +} + + +int +dsa_check_secret_key( int algo, MPI *skey ) +{ + DSA_secret_key sk; + + if( algo != PUBKEY_ALGO_DSA ) + return G10ERR_PUBKEY_ALGO; + if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] ) + return G10ERR_BAD_MPI; + + sk.p = skey[0]; + sk.q = skey[1]; + sk.g = skey[2]; + sk.y = skey[3]; + sk.x = skey[4]; + if( !check_secret_key( &sk ) ) + return G10ERR_BAD_SECKEY; + + return 0; +} + + + +int +dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey ) +{ + DSA_secret_key sk; + + if( algo != PUBKEY_ALGO_DSA ) + return G10ERR_PUBKEY_ALGO; + if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] ) + return G10ERR_BAD_MPI; + + sk.p = skey[0]; + sk.q = skey[1]; + sk.g = skey[2]; + sk.y = skey[3]; + sk.x = skey[4]; + resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) ); + resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) ); + sign( resarr[0], resarr[1], data, &sk ); + return 0; +} + +int +dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey, + int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED) +{ + DSA_public_key pk; + + if( algo != PUBKEY_ALGO_DSA ) + return G10ERR_PUBKEY_ALGO; + if( !data[0] || !data[1] || !hash + || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] ) + return G10ERR_BAD_MPI; + + pk.p = pkey[0]; + pk.q = pkey[1]; + pk.g = pkey[2]; + pk.y = pkey[3]; + if( !verify( data[0], data[1], hash, &pk ) ) + return G10ERR_BAD_SIGN; + return 0; +} + + + +unsigned +dsa_get_nbits( int algo, MPI *pkey ) +{ + if( algo != PUBKEY_ALGO_DSA ) + return 0; + return mpi_get_nbits( pkey[0] ); +} + + +/**************** + * Return some information about the algorithm. We need algo here to + * distinguish different flavors of the algorithm. + * Returns: A pointer to string describing the algorithm or NULL if + * the ALGO is invalid. + * Usage: Bit 0 set : allows signing + * 1 set : allows encryption + */ +const char * +dsa_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig, + int *use ) +{ + *npkey = 4; + *nskey = 5; + *nenc = 0; + *nsig = 2; + + switch( algo ) { + case PUBKEY_ALGO_DSA: *use = PUBKEY_USAGE_SIG; return "DSA"; + default: *use = 0; return NULL; + } +} + + diff -BbruN freeswan-1.91.orig/pluto/g10_dsa.h freeswan-1.91/pluto/g10_dsa.h --- freeswan-1.91.orig/pluto/g10_dsa.h Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/g10_dsa.h Mon Jul 16 23:26:30 2001 @@ -0,0 +1,32 @@ +/* dsa.h - DSA signature scheme + * Copyright (C) 1998 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#ifndef G10_DSA_H +#define G10_DSA_H + +int dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ); +int dsa_check_secret_key( int algo, MPI *skey ); +int dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey ); +int dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey, + int (*cmp)(void *, MPI), void *opaquev ); +unsigned dsa_get_nbits( int algo, MPI *pkey ); +const char *dsa_get_info( int algo, int *npkey, int *nskey, + int *nenc, int *nsig, int *use ); + +#endif /*G10_DSA_H*/ diff -BbruN freeswan-1.91.orig/pluto/id.c freeswan-1.91/pluto/id.c --- freeswan-1.91.orig/pluto/id.c Thu Apr 12 19:34:14 2001 +++ freeswan-1.91/pluto/id.c Thu Aug 16 15:41:27 2001 @@ -21,14 +21,25 @@ #include #include +#ifdef OPENSSL +#include /* needed by DER handling */ +#endif + #include #include "constants.h" #include "defs.h" #include "id.h" +#include "log.h" +#include "whack.h" /*loglog*/ #include "connections.h" /* needs id.h */ #include "packet.h" +#ifdef OPENSSL +#include "demux.h" /* needed by openssl.h */ +#include "openssl.h" +#endif + const struct id empty_id; /* all zeros and NULLs */ /* Convert textual form of id into a (temporary) struct id. @@ -38,9 +49,13 @@ atoid(char *src, struct id *id) { err_t ugh = NULL; +#ifdef OPENSSL + char *nptr, *kptr; + char s[4]; + u_int i; +#endif *id = empty_id; - if (strchr(src, '@') == NULL) { /* !!! this test is not sufficient for distinguishing address families. @@ -56,11 +71,108 @@ { if (*src == '@') { +#ifdef OPENSSL + /* if there is a second specifier (#) on the line + * we interprete this as ID_KEY_ID + */ + if (*(src+1) == '#') + { + id->key_id.ptr = NULL; + + id->kind = ID_KEY_ID; + id->name.ptr = src+2; + id->key_id.ptr = alloc_bytes(strlen(id->name.ptr)/2, "keyid-ptr"); + id->key_id.len = strlen(id->name.ptr)/2; + nptr = id->name.ptr; + kptr = id->key_id.ptr; + + for (i=0; i< strlen(id->name.ptr)/2; i++, kptr++) + { + snprintf(s, 3, "%s", nptr); + *kptr = strtol(s, NULL, 16); + nptr+=2; + } + DBG(DBG_PARSING, + DBG_dump("Key-ID: ", id->key_id.ptr, id->key_id.len); + ); + } + else if (*(src+1) == '~') + { + /* if there is a second specifier (~) on the line + * we interprete this as + * ID_DER_ASN1_DN -> Distinguished Name + * in ASN1 (Subject-Field in X.509) + */ + id->kind = ID_DER_ASN1_DN; + id->name.ptr = src+2; + id->der_asn1_dn.ptr = alloc_bytes(strlen(id->name.ptr)/2, "der_asn1_dn-ptr"); + id->der_asn1_dn.len = strlen(id->name.ptr)/2; + nptr = id->name.ptr; + kptr = id->der_asn1_dn.ptr; + + for (i=0; i< strlen(id->name.ptr)/2; i++, kptr++) + { + snprintf(s, 3, "%s", nptr); + *kptr = strtol(s, NULL, 16); + nptr+=2; + } + + DBG(DBG_PARSING, + DBG_dump("DER ASN1 DN: ", id->der_asn1_dn.ptr, + id->der_asn1_dn.len); + ); + + /* Check DN */ + ugh = check_der_asn1_dn(id); + } + else if (*(src+1) == '/') + { + /* if there is a second specifier (/) on the line + * we interprete this as human-readable DN from a public cert. + * There's a conversion to ID_DER_ASN1_DN for use with current + * code. + * + * ID_DER_ASN1_DN -> Distinguished Name + * in ASN1 (Subject-Field in X.509) + */ + X509_NAME *tmp_x509_name = NULL; + u_char *tmp_pointer; + + id->kind = ID_DER_ASN1_DN; + id->name.ptr = src+1; + + tmp_x509_name = X509_NAME_build_from_text_DN(id->name.ptr); + id->der_asn1_dn.len = i2d_X509_NAME(tmp_x509_name, NULL); + + tmp_pointer = malloc(id->der_asn1_dn.len); + id->der_asn1_dn.ptr = tmp_pointer; + + /* get data */ + id->der_asn1_dn.len=i2d_X509_NAME(tmp_x509_name, + &(id->der_asn1_dn.ptr) ); + + /* redo pointer */ + id->der_asn1_dn.ptr = tmp_pointer; + + X509_NAME_free(tmp_x509_name); + +// DBG(DBG_PARSING, + DBG_dump("DER ASN1 DN: ", id->der_asn1_dn.ptr, + id->der_asn1_dn.len); +// ); + + /* Check DN */ + ugh = check_der_asn1_dn(id); + } + else + { id->kind = ID_FQDN; id->name.ptr = src+1; /* discard @ */ } + } else { +#endif /* OPENSSL */ /* We leave in @, as per DOI 4.6.2.4 * (but DNS wants . instead). */ @@ -109,8 +221,17 @@ n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr); break; case ID_USER_FQDN: - n = snprintf(dst, dstlen, "%.*s", (int)id->name.len, id->name.ptr); + n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr); break; +#ifdef OPENSSL + case ID_KEY_ID: + n = snprintf(dst, dstlen, "@%.*s", (int)id->key_id.len, id->key_id.ptr); + break; + case ID_DER_ASN1_DN: + n = snprintf(dst, dstlen, "@%.*s", (int)id->der_asn1_dn.len, + id->der_asn1_dn.ptr); + break; +#endif default: n = snprintf(dst, dstlen, "unknown id kind %d", id->kind); break; @@ -139,8 +260,20 @@ { case ID_FQDN: case ID_USER_FQDN: - id->name.ptr = clone_bytes(id->name.ptr, id->name.len, "keep id name"); +#ifdef OPENSSL + case ID_KEY_ID: +#endif + id->name.ptr = clone_bytes(id->name.ptr, id->name.len, + "keep id name"); + break; +#ifdef OPENSSL + case ID_DER_ASN1_DN: + id->name.ptr = clone_bytes(id->name.ptr, id->name.len, + "keep id name"); + id->der_asn1_dn.ptr = clone_bytes(id->der_asn1_dn.ptr, + id->der_asn1_dn.len, "keep der_asn1_dn id"); break; +#endif case ID_NONE: case ID_IPV4_ADDR: case ID_IPV6_ADDR: @@ -150,6 +283,14 @@ } } +/* free a heap struct id */ +void +free_id(struct id *id) +{ + free_id_content(id); + pfree(id); +} + void free_id_content(struct id *id) { @@ -159,6 +300,16 @@ case ID_USER_FQDN: pfree(id->name.ptr); break; +#ifdef OPENSSL + case ID_KEY_ID: + pfree(id->name.ptr); + pfree(id->key_id.ptr); + break; + case ID_DER_ASN1_DN: + pfree(id->name.ptr); + pfree(id->der_asn1_dn.ptr); + break; +#endif /* OPENSSL */ case ID_NONE: case ID_IPV4_ADDR: case ID_IPV6_ADDR: @@ -185,10 +336,20 @@ case ID_FQDN: case ID_USER_FQDN: +#ifdef OPENSSL + case ID_KEY_ID: /* assumption: case should be ignored */ +#endif return a->name.len == b->name.len && strncasecmp(a->name.ptr, b->name.ptr, a->name.len) == 0; +#ifdef OPENSSL + case ID_DER_ASN1_DN: + /* assumption: case should be ignored */ + return (a->der_asn1_dn.len == b->der_asn1_dn.len) + && strncasecmp(a->der_asn1_dn.ptr, + b->der_asn1_dn.ptr, a->der_asn1_dn.len) == 0; +#endif /* OPENSSL */ default: passert(FALSE); } @@ -220,7 +381,50 @@ tl->len = addrbytesptr(&end->host_addr , (const unsigned char **)&tl->ptr); break; +#ifdef OPENSSL + case ID_KEY_ID: + *tl = end->id.key_id; + break; + case ID_DER_ASN1_DN: + *tl = end->id.der_asn1_dn; + break; +#endif /* OPENSSL */ default: passert(FALSE); } } + +#ifdef OPENSSL +err_t +check_der_asn1_dn(struct id *id) +{ + err_t ugh = NULL; + u_char *temp_ptr; + + X509_NAME *xn = X509_NAME_new(); + char dnout[256]; + + if (xn == NULL) { + ugh="Unable to malloc X509_NAME *xn"; + } + + /* temp_ptr because d2i_X509_NAME will mangle the pointer. */ + temp_ptr = id->der_asn1_dn.ptr; + xn = d2i_X509_NAME(&xn, &(id->der_asn1_dn.ptr), + (long)id->der_asn1_dn.len); + id->der_asn1_dn.ptr = temp_ptr; + + if (xn != NULL) { + DBG(DBG_PARSING, + X509_NAME_oneline(xn,dnout,256); + DBG_log("Valid DN == %s", dnout); + ); + } else { + ugh="Invalid DER string"; + } + + X509_NAME_free(xn); + return ugh; +} + +#endif /* OPENSSL */ diff -BbruN freeswan-1.91.orig/pluto/id.h freeswan-1.91/pluto/id.h --- freeswan-1.91.orig/pluto/id.h Mon Feb 26 18:50:11 2001 +++ freeswan-1.91/pluto/id.h Thu Aug 16 13:13:27 2001 @@ -17,6 +17,10 @@ struct id { int kind; /* ID_* value */ ip_address ip_addr; /* ID_IPV4_ADDR, ID_IPV6_ADDR */ +#ifdef OPENSSL + chunk_t key_id; /* ID_KEY_ID */ + chunk_t der_asn1_dn; /* ID_DER_ASN1_DN */ +#endif chunk_t name; /* ID_FQDN, ID_USER_FQDN (with @) */ }; @@ -25,9 +29,10 @@ extern err_t atoid(char *src, struct id *id); extern void iptoid(const ip_address *ip, struct id *id); extern int idtoa(const struct id *id, char *dst, size_t dstlen); -#define IDTOA_BUF 256 +#define IDTOA_BUF 512 struct end; /* forward declaration of tag (defined in connections.h) */ extern void unshare_id_content(struct id *id); +extern void free_id(struct id *id); extern void free_id_content(struct id *id); extern bool same_id(const struct id *a, const struct id *b); #define id_is_ipaddr(id) ((id)->kind == ID_IPV4_ADDR || (id)->kind == ID_IPV6_ADDR) @@ -35,3 +40,6 @@ struct isakmp_ipsec_id; /* forward declaration of tag (defined in packet.h) */ extern void build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end); +#ifdef OPENSSL +err_t check_der_asn1_dn(struct id *id); +#endif diff -BbruN freeswan-1.91.orig/pluto/ipsec_doi.c freeswan-1.91/pluto/ipsec_doi.c --- freeswan-1.91.orig/pluto/ipsec_doi.c Fri Jun 1 03:38:32 2001 +++ freeswan-1.91/pluto/ipsec_doi.c Tue Jul 17 14:34:30 2001 @@ -49,12 +49,26 @@ #include "md5.h" #include "crypto.h" /* requires sha1.h and md5.h */ +#ifdef OPENSSL +#include "openssl.h" +#endif + /* MAGIC: perform f, a function that returns notification_t * and return from the ENCLOSING stf_status returning function if it fails. */ #define RETURN_STF_FAILURE(f) \ { int r = (f); if (r != NOTHING_WRONG) return STF_FAIL + r; } +stf_status send_delete(struct state *p2st, ipsec_spi_t *spi, bool ESP); +static bool encrypt_message(pb_stream *pbs, struct state *st); +extern bool build_and_ship_KE(struct state *st, chunk_t *g, + const struct oakley_group_desc *group, pb_stream *outs, u_int8_t np); + +/* needed for PGPnet Vendor ID */ +char pgp_vid[] = { 0x4f, 0x70, 0x65, 0x6e, + 0x50, 0x47, 0x50, 0x31, + 0x30, 0x31, 0x37, 0x31}; + /* Compute DH shared secret from our local secret and the peer's public value. * We make the leap that the length should be that of the group * (see quoted passage at start of ACCEPT_KE). @@ -80,13 +94,92 @@ DBG_cond_dump_chunk(DBG_CRYPT, "DH shared secret:\n", st->st_shared); } +#ifdef OPENSSL +static bool +build_and_ship_KE_rpk(struct state *st, bool init, + chunk_t *g, + const struct oakley_group_desc *group, pb_stream *outs, + u_int8_t np) +{ + keysched *ks; + u_char *iv; + chunk_t op; + bool res; + + if (!st->st_sec_in_use) + { + u_char tmp[LOCALSECRETSIZE]; + MP_INT mp_g; + + get_rnd_bytes(tmp, LOCALSECRETSIZE); + st->st_sec_in_use = TRUE; + n_to_mpz(&st->st_sec, tmp, LOCALSECRETSIZE); + + mpz_init(&mp_g); + mpz_powm(&mp_g, &groupgenerator, &st->st_sec, group->modulus); + freeanychunk(*g); /* happens in odd error cases */ + *g = mpz_to_n(&mp_g, group->bytes); + mpz_clear(&mp_g); +#ifdef DODGE_DH_MISSING_ZERO_BUG + if (g->ptr[0] == 0) + { + /* generate a new secret to avoid this situation */ + log("regenerating DH private secret to avoid Pluto 1.0 bug" + " handling public value with leading zero"); + mpz_clear(&st->st_sec); + st->st_sec_in_use = FALSE; + return build_and_ship_KE_rpk(st, init, g, group, outs, np); + } + /* if we're the responder, we can compute the shared secret + * to see if it would turn out OK. + */ + if (g == &st->st_gr) + { + compute_dh_shared(st, st->st_gi + , IS_PHASE1(st->st_state) + ? st->st_oakley.group : st->st_pfs_group); + if (st->st_shared.ptr[0] == 0) + { + /* generate a new secret to avoid this situation */ + loglog(RC_LOG_SERIOUS, "regenerating DH private secret to avoid Pluto 1.0 bug" + " handling shared secret with leading zero"); + freeanychunk(st->st_shared); + mpz_clear(&st->st_sec); + st->st_sec_in_use = FALSE; + return build_and_ship_KE(st, g, group, outs, np); + } + } +#endif + + DBG(DBG_CRYPT, + DBG_dump("Local DH secret:\n", tmp, LOCALSECRETSIZE); + DBG_dump_chunk("Public DH value sent:\n", *g); + ); + } + /* Encrypt the chunk */ + if (init) { + ks = &st->st_ks_i; + iv = st->st_ne_i_iv; + } else { + ks = &st->st_ks_r; + iv = st->st_ne_r_iv; + } + setchunk(op, NULL, 0); + if (!encrypt_payload( st, ks, iv, *g, &op )) return FALSE; + res = out_generic_chunk(np, &isakmp_keyex_desc, outs, op, + "encrypted keyex value"); + freeanychunk(op); + return res; +} +#endif + /* if we haven't already done so, compute a local DH secret (st->st_sec) and * the corresponding public value (g). This is emitted as a KE payload. * KLUDGE: if DODGE_DH_MISSING_ZERO_BUG and we're the responder, * this routine computes the shared secret to see if it would * have a leading zero. If so, we try again. */ -static bool +extern bool build_and_ship_KE(struct state *st, chunk_t *g , const struct oakley_group_desc *group, pb_stream *outs, u_int8_t np) { @@ -137,7 +230,8 @@ DBG(DBG_CRYPT, DBG_dump("Local DH secret:\n", tmp, LOCALSECRETSIZE); - DBG_dump_chunk("Public DH value sent:\n", *g)); + DBG_dump_chunk("Public DH value sent:\n", *g); + ); } return out_generic_chunk(np, &isakmp_keyex_desc, outs, *g, "keyex value"); } @@ -220,6 +314,23 @@ return out_generic_chunk(np, &isakmp_nonce_desc, outs, *n, name); } +#ifdef OPENSSL +static bool +build_and_ship_nonce_pk(struct state *st, chunk_t *n, pb_stream *outs, u_int8_t np, const char *name) +{ + chunk_t c; + + setchunk(*n, alloc_bytes(DEFAULT_NONCE_SIZE, name), DEFAULT_NONCE_SIZE); + get_rnd_bytes(n->ptr, DEFAULT_NONCE_SIZE); + c.len = n->len; + c.ptr = clone_bytes(n->ptr, c.len, name); + if (! pubkey_encrypt_chunk(&c, st)) { + return FALSE; + } + return out_generic_chunk(np, &isakmp_nonce_desc, outs, c, name); +} +#endif + /* * Send a notification to the peer. We could make a decision on * whether to send the notification, based on the type and the @@ -282,11 +393,128 @@ // show_sa(&sa))); // else // { -// DBG(DBG_CONTROL, DBG_log("transmitted %d bytes", ntohl(isa->isa_length))); +// DBG(DBG_CONTROL, +// DBG_log("transmitted %d bytes", ntohl(isa->isa_length)); +// ); // } //} #endif /* not currently used */ + +stf_status +send_delete(struct state *p2st, ipsec_spi_t *spi, bool ESP) +{ + + pb_stream reply_pbs; + pb_stream r_hdr_pbs; + msgid_t msgid; + u_char old_new_iv[MAX_DIGEST_LEN]; + u_char old_iv[MAX_DIGEST_LEN]; + u_char buffer[8192]; + struct state *p1st; + + u_char spilen = sizeof(ipsec_spi_t); + u_char + *r_hashval, /* where in reply to jam hash value */ + *r_hash_start; /* start of what is to be hashed */ + + zero(buffer); + init_pbs(&reply_pbs, buffer, sizeof(buffer), "delete msg"); + + /* find the related P1-State to the calling P2-state */ + p1st = find_state(p2st->st_icookie, p2st->st_rcookie, + &(p2st->st_connection->that.host_addr), 0); + if (p1st == NULL) + { + DBG_log("no phase 1 state where one should be"); + return STF_INTERNAL_ERROR; + } + + msgid = generate_msgid(p1st); + + /* HDR* */ + { + struct isakmp_hdr hdr; + + hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION; + hdr.isa_np = ISAKMP_NEXT_HASH; + hdr.isa_xchg = ISAKMP_XCHG_INFO; + hdr.isa_msgid = msgid; + hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION; + memcpy(hdr.isa_icookie, p1st->st_icookie, COOKIE_SIZE); + memcpy(hdr.isa_rcookie, p1st->st_rcookie, COOKIE_SIZE); + if (!out_struct(&hdr, &isakmp_hdr_desc, &reply_pbs, &r_hdr_pbs)) + return STF_INTERNAL_ERROR; + } + + /* HASH -- space to be filled later */ + { + pb_stream hash_pbs; + + if (!out_generic(ISAKMP_NEXT_D, &isakmp_hash_desc, &r_hdr_pbs, &hash_pbs)) + return STF_INTERNAL_ERROR; + r_hashval = hash_pbs.cur; /* remember where to plant value */ + if (!out_zero(p1st->st_oakley.hasher->hash_digest_len, &hash_pbs, "HASH(1)")) + return STF_INTERNAL_ERROR; + close_output_pbs(&hash_pbs); + r_hash_start = r_hdr_pbs.cur; /* hash from after HASH(1) */ + } + + /* DELETE PAYLOAD */ + { + pb_stream del_pbs; + struct isakmp_delete isad; + + isad.isad_doi = ISAKMP_DOI_IPSEC; + isad.isad_np = ISAKMP_NEXT_NONE; + isad.isad_spisize = spilen; + if (ESP) isad.isad_protoid = PROTO_IPSEC_ESP; + else isad.isad_protoid = PROTO_IPSEC_AH; + isad.isad_nospi = 0x0001; + if (!out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, &del_pbs)) + return STF_INTERNAL_ERROR; + if (!out_raw(spi, spilen, &del_pbs, "delete payload")) + return STF_INTERNAL_ERROR;; + close_output_pbs(&del_pbs); + } + + { + struct hmac_ctx ctx; + hmac_init_chunk(&ctx, p1st->st_oakley.hasher, p1st->st_skeyid_a); + hmac_update(&ctx, (u_char *) &msgid, sizeof(msgid_t)); + hmac_update(&ctx, r_hash_start, r_hdr_pbs.cur-r_hash_start); + hmac_final(r_hashval, &ctx); + + DBG(DBG_CRYPT, + DBG_log("HASH(1) computed:"); + DBG_dump("", r_hashval, ctx.hmac_digest_len)); + } + + /* save old IV (this prevents from copying a whole new state object + * for NOTIFICATION / DELETE messages we don't need to maintain a state + * because there are no retransmissions... + */ + + memcpy(old_new_iv, p1st->st_new_iv, p1st->st_new_iv_len); + memcpy(old_iv, p1st->st_iv, p1st->st_iv_len); + init_phase2_iv(p1st, &msgid); + + if(!encrypt_message(&r_hdr_pbs, p1st)) passert(FALSE); + + clonetochunk(p1st->st_tpacket, reply_pbs.start, pbs_offset(&reply_pbs) + , "reply packet for main_outI1"); + + send_packet(p1st, "delete notify"); + + /* get back old IV for this state */ + memcpy(p1st->st_new_iv, old_new_iv, p1st->st_new_iv_len); + memcpy(p1st->st_iv, old_iv, p1st->st_iv_len); + + return STF_IGNORE; +} + + + /* The whole message must be a multiple of 4 octets. * I'm not sure where this is spelled out, but look at * rfc2408 3.6 Transform Payload. @@ -318,6 +546,10 @@ struct state *st; + DBG(DBG_PARSING, + DBG_log("in main_outI1"); + ); + /* set up new state */ cur_state = st = new_state(); st->st_connection = c; @@ -372,7 +604,11 @@ if (get_RSA_private_key(c) != NULL && get_his_RSA_public_key(c) != NULL) +#ifndef OPENSSL auth_policy |= POLICY_RSASIG; +#else + auth_policy |= POLICY_OPENSSL; +#endif /* Not clear what we should do if neither is possible. * Perhaps we should not have entered negotiations at all. */ @@ -383,6 +619,23 @@ return STF_INTERNAL_ERROR; } } + +#ifdef OPENSSL +if (use_openssl(c)) +{ + loglog(RC_LOG_SERIOUS, "Using OPENSSL sadb."); + if (!out_sa(&rbody + , &oakley_sadb2[auth_policy >> POLICY_ISAKMP_SHIFT] + , st, TRUE, ISAKMP_NEXT_NONE)) + { + cur_state = NULL; + return STF_INTERNAL_ERROR; + } +} +else +{ +#endif /* OPENSSL */ + loglog(RC_LOG_SERIOUS, "Using standard sadb."); if (!out_sa(&rbody , &oakley_sadb[auth_policy >> POLICY_ISAKMP_SHIFT] , st, TRUE, ISAKMP_NEXT_NONE)) @@ -390,6 +643,10 @@ cur_state = NULL; return STF_INTERNAL_ERROR; } +#ifdef OPENSSL +} +#endif /* ! OPENSSL */ + /* save initiator SA for later HASH */ passert(st->st_p1isa.ptr == NULL); /* no leak! (MUST be first time) */ @@ -564,6 +821,57 @@ return TRUE; } +#ifdef OPENSSL +#if 0 +static const chunk_t +chunk_concat( const chunk_t c1, const chunk_t c2 ) +{ + chunk_t cc; + + cc.len = c1.len + c2.len; + if ((cc.ptr = malloc(cc.len)) != NULL) { + memcpy(cc.ptr, c1.ptr, c1.len); + memcpy(&(cc.ptr[c1.len]), c2.ptr, c2.len); + } + return cc; +} +#endif + +static bool +skeyid_pke(struct state *st) +{ + /* This routine lifted straight from Kai Martius' patches */ + /* and updated to use chunks */ + struct hmac_ctx ctx; + union hash_ctx ictx; + const struct hash_desc *h = st->st_oakley.hasher; + u_char *nonce; + u_int16_t nonce_len; + chunk_t noncechunk, cky_i, cky_r; + + nonce_len = h->hash_digest_len; + nonce=alloc_bytes(nonce_len, "nonce in skeyid_pke()"); + + h->hash_init(&ictx); + h->hash_update(&ictx, st->st_ni.ptr, st->st_ni.len); + h->hash_update(&ictx, st->st_nr.ptr, st->st_nr.len); + h->hash_final(nonce, &ictx); + + setchunk(noncechunk, nonce, nonce_len); + setchunk(cky_i, st->st_icookie, COOKIE_SIZE); + setchunk(cky_r, st->st_rcookie, COOKIE_SIZE); + + hmac_init_chunk(&ctx, h, noncechunk); + hmac_update_chunk(&ctx, cky_i); + hmac_update_chunk(&ctx, cky_r); + hmac_final_chunk(st->st_skeyid, "st_skeyid in skeyid_pke()", &ctx); + + free(nonce); + + return TRUE; +} +#endif + /* Generate the SKEYID_* and new IV * See draft-ietf-ipsec-ike-01.txt 4.1 */ @@ -584,13 +892,21 @@ break; case OAKLEY_DSS_SIG: - /* XXX */ +#ifdef OPENSSL + if (!skeyid_digisig(st)) + return FALSE; + break; +#endif case OAKLEY_RSA_ENC: case OAKLEY_RSA_ENC_REV: case OAKLEY_ELGAMAL_ENC: case OAKLEY_ELGAMAL_ENC_REV: - /* XXX */ +#ifdef OPENSSL + if (!skeyid_pke(st)) + return FALSE; + break; +#endif default: exit_log("generate_skeyids_iv(): unsupported authentication method %s", @@ -779,7 +1095,7 @@ return ctx.hmac_digest_len; } -#if 0 /* only needed for DSS */ +#ifdef OPENSSL static void main_mode_sha1(struct state *st, u_char *hash_val, size_t *hash_len , bool hashi, bool hashus) @@ -987,6 +1303,13 @@ switch (st->st_oakley.auth) { case OAKLEY_PRESHARED_KEY: +#ifdef OPENSSL + case OAKLEY_RSA_ENC: + case OAKLEY_RSA_ENC_REV: + case OAKLEY_DSS_SIG: + case OAKLEY_ELGAMAL_ENC: + case OAKLEY_ELGAMAL_ENC_REV: +#endif { pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs; @@ -1246,6 +1569,10 @@ log("initiating Quick Mode %s", bitnamesof(sa_policy_bit_names, policy)); + DBG(DBG_PARSING, + DBG_log("starting quick_outI1"); + ); + /* set up reply */ init_pbs(&reply, space, sizeof(space), "reply packet"); @@ -1342,6 +1669,11 @@ whack_log(RC_NEW_STATE + STATE_QUICK_I1 , "%s: initiate", enum_name(&state_names, st->st_state)); cur_state = NULL; + + DBG(DBG_PARSING, + DBG_log("finished quick_outI1"); + ); + return STF_NO_REPLY; } @@ -1359,6 +1691,15 @@ struct isakmp_id *const id = &id_pld->payload.id; struct id peer; +#ifdef OPENSSL + const u_int max_len = 512; + u_char key_id[max_len]; + u_int i, len; + + peer.key_id.len = 0; + peer.der_asn1_dn.len = 0; +#endif + /* I think that RFC2407 (IPSEC DOI) 4.6.2 is confused. * It talks about the protocol ID and Port fields of the ID * Payload, but they don't exist as such in Phase 1. @@ -1411,8 +1752,8 @@ case ID_FQDN: if (memchr(id_pbs->cur, '\0', pbs_left(id_pbs)) != NULL) { - loglog(RC_LOG_SERIOUS, "Phase 1 ID Payload of type %s contains a NUL" - , enum_show(&ident_names, peer.kind)); + loglog(RC_LOG_SERIOUS, "Phase 1 ID Payload of type %s contains a NULL" + ,enum_show(&ident_names, peer.kind)); return FALSE; } @@ -1421,6 +1762,76 @@ setchunk(peer.name, id_pbs->cur, pbs_left(id_pbs)); break; +#ifdef OPENSSL + case ID_KEY_ID: + if (!(id->isaid_doi_specific_a == 0 && id->isaid_doi_specific_b == 0)) + { + log("protocol/port in Phase 1 ID Payload must be 0/0" + " but are %d/%d" + , id->isaid_doi_specific_a, id->isaid_doi_specific_b); + return FALSE; + } + + len = pbs_left(id_pbs); + + /* we need double size for ASCII representation of key id */ + if (2*len > max_len) + { + log("too large key id"); + return FALSE; + } + + DBG(DBG_PARSING, + DBG_dump("Received Key ID:", id_pbs->cur, pbs_left(id_pbs)); + ); + + /* hold the binary representation of KEY_ID */ + /* possible memory hole? */ + peer.key_id.ptr = alloc_bytes(len, "key_id"); + peer.key_id.len = len; + memcpy(peer.key_id.ptr, id_pbs->cur, len); + + for (i=0; icur++) + sprintf(&key_id[i*2], "%02x", *(id_pbs->cur)); + + peer.name.ptr = alloc_bytes(2*len, "name"); + peer.name.len = 2*len; + memcpy(peer.name.ptr, key_id, peer.name.len); + break; + + case ID_DER_ASN1_DN: + if (!(id->isaid_doi_specific_a == 0 && id->isaid_doi_specific_b == 0)) + { + log("protocol/port in Phase 1 ID Payload must be 0/0" + " but are %d/%d", id->isaid_doi_specific_a, + id->isaid_doi_specific_b); + return FALSE; + } + len = pbs_left(id_pbs); + + if (len > max_len) + { + log("too large DER ASN1 DN"); + return FALSE; + } + + if (id_pbs->cur == NULL) { + loglog(RC_LOG_SERIOUS, + "ID_DER_ASN1_DN received, but is 0 length."); + return FALSE; + } + + peer.der_asn1_dn.ptr = alloc_bytes(len,"der asn1 dn"); + peer.der_asn1_dn.len = len; + memcpy(peer.der_asn1_dn.ptr, id_pbs->cur, len); + + DBG(DBG_PARSING, + DBG_dump_chunk("Received peer.id (processed ID_DER_ASN1_DN):", + peer.der_asn1_dn); + ); + break; +#endif OPENSSL + default: /* XXX Could send notification back */ loglog(RC_LOG_SERIOUS, "Unacceptable identity type (%s) in Phase 1 ID Payload" @@ -1432,6 +1843,7 @@ st->st_peeridentity_protocol = id->isaid_doi_specific_a; st->st_peeridentity_port = id->isaid_doi_specific_b; +#if 0 /* Commented out because DER_AS1_DN creates LOTS of output here. */ DBG(DBG_PARSING, { char buf[IDTOA_BUF]; @@ -1441,6 +1853,7 @@ enum_show(&ident_names, id->isaid_idtype), buf); }); +#endif /* Now that we've decoded the ID payload, let's see if we * need to switch connections. @@ -1491,7 +1904,25 @@ st->st_connection = r; /* kill reference to c */ SET_CUR_CONNECTION(r); connection_discard(c); + + } +#ifdef OPENSSL + /* if we have a binary key_id, set it now into conn */ + if (peer.key_id.len) + { + r->that.id.key_id.ptr = clone_bytes(peer.key_id.ptr, + peer.key_id.len, "KEY-ID"); + r->that.id.key_id.len = peer.key_id.len; + } + + /* if we have a binary der_asn1_dn, set it now into conn */ + if (peer.der_asn1_dn.len) + { + r->that.id.der_asn1_dn.ptr = clone_bytes(peer.der_asn1_dn.ptr, + peer.der_asn1_dn.len, "ID_DER_ASN1_DN"); + r->that.id.der_asn1_dn.len = peer.der_asn1_dn.len; } +#endif /* OPENSSL */ } return TRUE; @@ -1863,6 +2294,10 @@ pb_stream r_sa_pbs; + DBG(DBG_PARSING, + DBG_log("in main_inI1_outR1"); + ); + if (c == NULL) { /* see if a wildcarded connection can be found */ @@ -1947,6 +2382,10 @@ /* save initiator SA for HASH */ clonereplacechunk(st->st_p1isa, sa_pd->pbs.start, pbs_room(&sa_pd->pbs), "sa in main_inI1_outR1()"); + DBG(DBG_PARSING, + DBG_log("finished main_inI1_outR1"); + ); + return STF_REPLY; } @@ -1964,15 +2403,30 @@ main_inR1_outI2(struct msg_digest *md) { struct state *const st = md->st; +#ifdef OPENSSL + u_int8_t np; +#endif + + DBG(DBG_PARSING, + DBG_log("in main_inR1_outI2"); + ); /* verify echoed SA */ { struct payload_digest *const sapd = md->chain[ISAKMP_NEXT_SA]; - RETURN_STF_FAILURE(parse_isakmp_sa_body(&sapd->pbs - , &sapd->payload.sa, NULL, TRUE, st)); + RETURN_STF_FAILURE(parse_isakmp_sa_body(&sapd->pbs, + &sapd->payload.sa, NULL, TRUE, st)); } + /* + * Here, we have to decide if the outgoing packet is going to be created + * for the classic RSASIG, or the OPENSSL functions. + */ +#ifdef OPENSSL + if (!use_openssl(st->st_connection)) + { +#endif /**************** build output packet HDR;KE;Ni ****************/ /* HDR out. @@ -1988,105 +2442,961 @@ } /* KE out */ - if (!build_and_ship_KE(st, &st->st_gi, st->st_oakley.group - , &md->rbody, ISAKMP_NEXT_NONCE)) + if (!build_and_ship_KE(st, &st->st_gi, st->st_oakley.group, + &md->rbody, ISAKMP_NEXT_NONCE)) return STF_INTERNAL_ERROR; /* Ni out */ if (!build_and_ship_nonce(&st->st_ni, &md->rbody, ISAKMP_NEXT_NONE, "Ni")) return STF_INTERNAL_ERROR; - /* finish message */ - close_message(&md->rbody); - - /* Reinsert the state, using the responder cookie we just received */ - unhash_state(st); - memcpy(st->st_rcookie, md->hdr.isa_rcookie, COOKIE_SIZE); - insert_state(st); /* needs cookies, connection, and msgid (0) */ +#ifdef OPENSSL + } + else /* use_openssl == TRUE */ + { + DBG(DBG_PARSING, + DBG_log("main_inR1_outI2: auth chosen is %s", + enum_show(&oakley_auth_names, st->st_oakley.auth)); + ); - st->st_state = STATE_MAIN_I2; + if ((st->st_oakley.auth == OAKLEY_RSA_ENC_REV) || + (st->st_oakley.auth == OAKLEY_ELGAMAL_ENC_REV)) { + struct isakmp_hdr r_hdr = md->hdr; - return STF_REPLY; -} + /* HDR out */ + r_hdr.isa_np = ISAKMP_NEXT_NONCE; + if (!out_struct(&r_hdr, &isakmp_hdr_desc, &md->reply, &md->rbody)) + return STF_INTERNAL_ERROR; -/* STATE_MAIN_R1: - * PSK_AUTH, DS_AUTH: HDR, KE, Ni --> HDR, KE, Nr - * - * The following are not yet implemented: - * PKE_AUTH: HDR, KE, [ HASH(1), ] PubKey_r, PubKey_r - * --> HDR, KE, PubKey_i, PubKey_i - * RPKE_AUTH: - * HDR, [ HASH(1), ] Pubkey_r, Ke_i, Ke_i [,<Ke_i] - * --> HDR, PubKey_i, Ke_r, Ke_r - */ -stf_status -main_inI2_outR2(struct msg_digest *md) -{ - struct state *const st = md->st; - pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs; + if (!build_and_ship_nonce_pk(st, &st->st_ni, &md->rbody, + ISAKMP_NEXT_KE, "PubKey_r")) + return STF_INTERNAL_ERROR; - /* KE in */ + if (derive_symmetric_key(st, st->st_ni, + st->st_icookie, COOKIE_SIZE, + &st->st_ks_i, + &st->st_ne_i) < 0) { + log("error while deriving symmetric key in revised mode"); + return STF_INTERNAL_ERROR; + } + memset(st->st_ne_i_iv, 0, MAX_DIGEST_LEN); + DBG(DBG_PARSING, + DBG_dump_chunk("Generated Ke_i:", st->st_ne_i); + ); + + /* KE out */ + if (!build_and_ship_KE_rpk(st, TRUE, &st->st_gi, st->st_oakley.group, + &md->rbody, ISAKMP_NEXT_ID)) + return STF_INTERNAL_ERROR; + + /* Ke_i,[Ke_i] out */ + { + chunk_t ch, out; + + /* + * Switch for different ID types to send + */ + if (st->st_connection->this.id.kind == ID_DER_ASN1_DN) { + ch.len = st->st_connection->this.id.der_asn1_dn.len + 4; + ch.ptr = alloc_bytes(ch.len, "encrypted der_asn1_dn identity"); + ch.ptr[0] = (u_int8_t)st->st_connection->this.id.kind; + memset(&(ch.ptr[1]), 0, 1); + memset(&(ch.ptr[2]), 0, 2); + memcpy(&(ch.ptr[4]), + st->st_connection->this.id.der_asn1_dn.ptr, + st->st_connection->this.id.der_asn1_dn.len); + } else { + ch.len = sizeof(st->st_connection->this.id.ip_addr) + 4; + ch.ptr = alloc_bytes(ch.len, "encrypted identity"); + ch.ptr[0] = (u_int8_t)st->st_connection->this.id.kind; + memset(&(ch.ptr[1]), 0, 1); + memset(&(ch.ptr[2]), 0, 2); + memcpy(&(ch.ptr[4]), &(st->st_connection->this.id.ip_addr), + sizeof(st->st_connection->this.id.ip_addr)); + } + + if (!encrypt_payload(st, &st->st_ks_i, st->st_ne_i_iv, + ch, &out)) + return STF_INTERNAL_ERROR; + freeanychunk(ch); + + /* Are we going to send CERT? */ + if ((st->st_connection->cert_options & CERT_OPTION_SEND) == 0) { + if (!out_generic_chunk(ISAKMP_NEXT_NONE, &isakmp_generic_desc, + &md->rbody, out, "my identity (ciphertext)")) + { + freeanychunk(out); + return STF_INTERNAL_ERROR; + } + } else { + if (!out_generic_chunk(ISAKMP_NEXT_CERT, &isakmp_generic_desc, + &md->rbody, out, "my identity (ciphertext)")) + { + freeanychunk(out); + return STF_INTERNAL_ERROR; + } + } + + /* Well, if we do send CERT, let's start on it from here */ + if ((st->st_connection->cert_options & CERT_OPTION_SEND) != 0) { + chunk_t crt, cx; + unsigned long ulen; + PKCS7 *p7 = NULL; + /* Send the signing certificate */ + + if ((st->st_connection->cert_options & CERT_OPTION_PKCS7) != 0) { + PKCS7_SIGNED *p7s = NULL; + X509_CRL *tempcrl=NULL; + X509 *tempcert = X509_dup(st->st_connection->cert); + STACK_OF(X509_CRL) *crl_stack=NULL; + STACK_OF(X509) *cert_stack=NULL; + + if ((p7=PKCS7_new()) == NULL) return STF_INTERNAL_ERROR; + if ((p7s=PKCS7_SIGNED_new()) == NULL) return STF_INTERNAL_ERROR; + p7->type=OBJ_nid2obj(NID_pkcs7_signed); + p7->d.sign=p7s; + p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data); + + if (!ASN1_INTEGER_set(p7s->version,1)) return STF_INTERNAL_ERROR; + + crl_stack=sk_X509_CRL_new(NULL); + if (crl_stack == NULL) return STF_INTERNAL_ERROR; + p7s->crl=crl_stack; + + /* DO crl lookup */ + tempcrl = lookup_crl(st->st_connection->lu, + X509_get_issuer_name(st->st_connection->cert)); + if (tempcrl != NULL) + { + sk_X509_CRL_push(crl_stack,tempcrl); + tempcrl=NULL; /* now part of p7 for Freeing */ + } else { + return STF_INTERNAL_ERROR; + } + + /* DO add cert chain ? */ + if ((cert_stack=sk_X509_new(NULL)) == NULL) + return STF_INTERNAL_ERROR; + p7s->cert=cert_stack; + if (tempcert != NULL) + { + sk_X509_push(cert_stack,tempcert); + tempcert=NULL; /* now part of p7 for Freeing */ + } else { + return STF_INTERNAL_ERROR; + } + + ulen = i2d_PKCS7(p7, NULL); + ulen++; + if ((cx.ptr = alloc_bytes(ulen, "ASN.1 PKCS7 cert chain")) == NULL) + { + return STF_INTERNAL_ERROR; + } + (cx.ptr)[0] = (u_char)(CERT_TYPE_PKCS7); + cx.len = ulen; + crt.ptr = &(cx.ptr[1]); + crt.len = i2d_PKCS7(p7, &(crt.ptr)); + + DBG(DBG_CRYPT, + DBG_log("plaintext PKCS7 chain length: %d", cx.len); + DBG_dump_chunk("plaintext PKCS7 chain", cx); + ); + + } else { /* not PKCS7. Send normal X.509 ASN.1 object */ + + ulen = i2d_X509(st->st_connection->cert, NULL); + ulen++; + if ((cx.ptr = alloc_bytes(ulen, "ASN.1 cert")) == NULL) + { + return STF_INTERNAL_ERROR; + } + (cx.ptr)[0] = (u_char)(CERT_TYPE_X509_SIG); + cx.len = ulen; + crt.ptr = &(cx.ptr[1]); + crt.len = i2d_X509(st->st_connection->cert, &(crt.ptr)); + + DBG(DBG_CRYPT, + DBG_log("plaintext Certificate length: %d", cx.len); + DBG_dump_chunk("plaintext Certificate", cx); + ); + } + + /* encrypt the certificate to send */ + if (!encrypt_payload(st, &st->st_ks_i, st->st_ne_i_iv, + cx, &out)) + return STF_INTERNAL_ERROR; + +/* test encryption */ + + if ((st->st_connection->cert_options & CERT_OPTION_PKCS7) != 0) { + DBG(DBG_CRYPT, + DBG_log("cyphertext PKCS7 chain length: %d", out.len); + DBG_dump_chunk("cyphertext PKCS7 chain", out); + if (p7 != NULL) PKCS7_free(p7); + ); + } else { + DBG(DBG_CRYPT, + DBG_log("cyphertext Certificate length: %d", out.len); + DBG_dump_chunk("cyphertext Certificate", out); + ); + } + + if (!out_generic_chunk(ISAKMP_NEXT_NONE, + &isakmp_ipsec_certificate_desc, + &md->rbody, out, "my certificate (ciphertext)")) + { + freeanychunk(out); + return STF_INTERNAL_ERROR; + } + } + /* end of sending out cert */ + + freeanychunk(out); + } + } else { + struct isakmp_hdr r_hdr = md->hdr; + + r_hdr.isa_np = ISAKMP_NEXT_KE; + if (!out_struct(&r_hdr, &isakmp_hdr_desc, &md->reply, &md->rbody)) + return STF_INTERNAL_ERROR; + + if ((st->st_oakley.auth == OAKLEY_RSA_ENC) || + (st->st_oakley.auth == OAKLEY_ELGAMAL_ENC)) + np = ISAKMP_NEXT_ID; + else /* Digital Sig or Preshared key */ + np = ISAKMP_NEXT_NONCE; + + /* KE out */ + if (!build_and_ship_KE(st, &st->st_gi, st->st_oakley.group, + &md->rbody, np)) + return STF_INTERNAL_ERROR; + + if ((st->st_oakley.auth == OAKLEY_RSA_ENC) || + (st->st_oakley.auth == OAKLEY_ELGAMAL_ENC)) { + + /* PubKey_r out */ + chunk_t ch; + + /* Switch for different ID types to send */ + if (st->st_connection->this.id.kind == ID_DER_ASN1_DN) { + ch.len = st->st_connection->this.id.der_asn1_dn.len + 4; + ch.ptr = alloc_bytes(ch.len, "plaintext der_asn1_dn identity"); + ch.ptr[0] = (u_int8_t)st->st_connection->this.id.kind; + memset(&(ch.ptr[1]), 0, 1); + memset(&(ch.ptr[2]), 0, 2); + memcpy(&(ch.ptr[4]), + st->st_connection->this.id.der_asn1_dn.ptr, + st->st_connection->this.id.der_asn1_dn.len); + } else { + ch.len = sizeof(st->st_connection->this.id.ip_addr) + 4; + ch.ptr = alloc_bytes(ch.len, "my identity (plaintext)"); + ch.ptr[0] = (u_int8_t)st->st_connection->this.id.kind; + memset(&(ch.ptr[1]), 0, 1); + memset(&(ch.ptr[2]), 0, 2); + memcpy(&(ch.ptr[4]), &(st->st_connection->this.id.ip_addr), + sizeof(st->st_connection->this.id.ip_addr)); + } + + /* PK encrypt this */ + if (! pubkey_encrypt_chunk( &ch, st )) { + return STF_INTERNAL_ERROR; + } + if (!out_generic_chunk(ISAKMP_NEXT_NONCE, &isakmp_generic_desc, + &md->rbody, ch, "my identity (ciphertext)")) + return STF_INTERNAL_ERROR; + memset(ch.ptr, 0, ch.len); + freeanychunk(ch); + + if (!build_and_ship_nonce_pk(st, &st->st_ni, &md->rbody, + ISAKMP_NEXT_NONE, "PubKey_r")) + return STF_INTERNAL_ERROR; + } else { + DBG(DBG_PARSING, + DBG_log("Shipping nonce_i"); + ); + if (!build_and_ship_nonce(&st->st_ni, &md->rbody, + ISAKMP_NEXT_NONE, "Ni")) + return STF_INTERNAL_ERROR; + } + } + } +#endif + + /* finish message */ + close_message(&md->rbody); + + /* Reinsert the state, using the responder cookie we just received */ + unhash_state(st); + memcpy(st->st_rcookie, md->hdr.isa_rcookie, COOKIE_SIZE); + insert_state(st); /* needs cookies, connection, and msgid (0) */ + + st->st_state = STATE_MAIN_I2; + + DBG(DBG_PARSING, + DBG_log("finished main_inR1_outI2"); + ); + + return STF_REPLY; +} + +/* STATE_MAIN_R1: + * PSK_AUTH, DS_AUTH: HDR, KE, Ni --> HDR, KE, Nr + * + * The following are not yet implemented: + * PKE_AUTH: HDR, KE, [ HASH(1), ] PubKey_r, PubKey_r + * --> HDR, KE, PubKey_i, PubKey_i + * RPKE_AUTH: + * HDR, [ HASH(1), ] Pubkey_r, Ke_i, Ke_i [,<Ke_i] + * --> HDR, PubKey_i, Ke_r, Ke_r + */ +stf_status +main_inI2_outR2(struct msg_digest *md) +{ + struct state *const st = md->st; + pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs; + + DBG(DBG_PARSING, + DBG_log("in main_inI2_outR2"); + ); + + /* KE in */ RETURN_STF_FAILURE(accept_KE(&st->st_gi, "Gi", st->st_oakley.group, keyex_pbs)); - /* Ni in */ - RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "Ni")); + /* Ni in */ + RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "Ni")); + + + /**************** build output packet HDR;KE;Nr ****************/ + + /* HDR out done */ + + /* KE out */ + if (!build_and_ship_KE(st, &st->st_gr, st->st_oakley.group + , &md->rbody, ISAKMP_NEXT_NONCE)) + return STF_INTERNAL_ERROR; + + /* Nr out */ + if (!build_and_ship_nonce(&st->st_nr, &md->rbody, ISAKMP_NEXT_NONE, "Nr")) + return STF_INTERNAL_ERROR; + + /* finish message */ + close_message(&md->rbody); + + /* next message will be encrypted, but not this one. + * We could defer this calculation. + */ + compute_dh_shared(st, st->st_gi, st->st_oakley.group); +#ifdef DODGE_DH_MISSING_ZERO_BUG + if (st->st_shared.ptr[0] == 0) + return STF_REPLACE_DOOMED_EXCHANGE; +#endif + + if (!generate_skeyids_iv(st)) + return STF_FAIL + AUTHENTICATION_FAILED; + update_iv(st); + + /* Advance state */ + st->st_state = STATE_MAIN_R2; + + DBG(DBG_PARSING, + DBG_log("finished main_inI2_outR2"); + ); + + return STF_REPLY; +} + +#ifdef OPENSSL +/* Handle HDR;KE;PubKey_r;PubKey_r from Initiator. + * Send a HDR;KE;PubKey_i;PubKey_i back. + */ +stf_status +main_inI2_outR2_pk(struct msg_digest *md) +{ + struct state *const st = md->st; + pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs; + + DBG(DBG_PARSING, + DBG_log("in main_inI2_outR2_pk"); + ); + + /* KE in */ + RETURN_STF_FAILURE(accept_KE(&st->st_gi, "Gi", + st->st_oakley.group, keyex_pbs)); + + if (!decode_peer_id(md, FALSE)) + return STF_FAIL + INVALID_ID_INFORMATION; + + /* Ni_b in */ + RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "PubKey_r")); + + /** build output packet HDR;KE;_PubKey_i;PubKey_i*********/ + + /* HDR out done */ + + /* KE out */ + if (!build_and_ship_KE(st, &st->st_gr, st->st_oakley.group, + &md->rbody, ISAKMP_NEXT_ID)) + return STF_INTERNAL_ERROR; + + { + /* PubKey_i out */ + chunk_t ch; + + if (st->st_connection->this.id.kind == ID_DER_ASN1_DN) { + ch.len = st->st_connection->this.id.der_asn1_dn.len + 4; + ch.ptr = alloc_bytes(ch.len, "plaintext der_asn1_dn identity"); + ch.ptr[0] = (u_int8_t)st->st_connection->this.id.kind; + memset(&(ch.ptr[1]), 0, 1); + memset(&(ch.ptr[2]), 0, 2); + memcpy(&(ch.ptr[4]), + st->st_connection->this.id.der_asn1_dn.ptr, + st->st_connection->this.id.der_asn1_dn.len); + } else { + ch.len = sizeof(st->st_connection->this.id.ip_addr) + 4; + ch.ptr = alloc_bytes(ch.len, "plaintext identity"); + ch.ptr[0] = (u_int8_t)st->st_connection->this.id.kind; + memset(&(ch.ptr[1]), 0, 1); + memset(&(ch.ptr[2]), 0, 2); + memcpy(&(ch.ptr[4]), &(st->st_connection->this.id.ip_addr), + sizeof(st->st_connection->this.id.ip_addr)); + } + + + /* PK encrypt this */ + if (! pubkey_encrypt_chunk( &ch, st )) { + return STF_INTERNAL_ERROR; + } + if (!out_generic_chunk(ISAKMP_NEXT_NONCE, &isakmp_generic_desc, &md->rbody, ch, "my identity (ciphertext)")) + return STF_INTERNAL_ERROR; + memset(ch.ptr, 0, ch.len); + freeanychunk(ch); + } + + /* Nr out */ + if (!build_and_ship_nonce_pk(st, &st->st_nr, &md->rbody, ISAKMP_NEXT_NONE, "PubKey_i")) + return STF_INTERNAL_ERROR; + + /* finish message */ + close_message(&md->rbody); + + /* next message will be encrypted, but not this one. + * We could defer this calculation. + */ +#ifndef DODGE_DH_MISSING_ZERO_BUG + compute_dh_shared(st, st->st_gi, st->st_oakley.group); +#endif + if (!generate_skeyids_iv(st)) + return STF_FAIL + AUTHENTICATION_FAILED; + update_iv(st); + + /* Advance state */ + st->st_state = STATE_MAIN_R2; + + DBG(DBG_PARSING, + DBG_log("finished main_inI2_outR2_pk"); + ); + + return STF_REPLY; +} +#endif /* OPENSSL */ + +#ifdef OPENSSL +/* Handle HDR;Pubkey_r;Ke_i;Ke_i[;Ke_r] from Initiator + * Send a HDR;Pubkey_i;Ke_r;Ke_r[;Ke_r] back. + */ +stf_status +main_inI2_outR2_rpk(struct msg_digest *md) +{ + struct state *const st = md->st; + pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs; + + DBG(DBG_PARSING, + DBG_log("in main_inI2_outR2_rpk"); + ); + + /* Ni_b in */ + RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "PubKey_r")); + + /* KE in */ + RETURN_STF_FAILURE(accept_KE(&st->st_gi, "Gi", + st->st_oakley.group, keyex_pbs)); + + if (!decode_peer_id(md, FALSE)) + return STF_FAIL + INVALID_ID_INFORMATION; + + /**************** build output packet ****************/ + + /* HDR out done */ + + /* Nr out */ + if (!build_and_ship_nonce_pk(st, &st->st_nr, &md->rbody, + ISAKMP_NEXT_KE, "PubKey_i")) + return STF_INTERNAL_ERROR; + + if (derive_symmetric_key(st, st->st_nr, + st->st_rcookie, COOKIE_SIZE, + &st->st_ks_r, + &st->st_ne_r) < 0) { + log("error while deriving symmetric key in revised mode"); + return STF_INTERNAL_ERROR; + } + memset(st->st_ne_r_iv, 0, MAX_DIGEST_LEN); + + DBG(DBG_PARSING, + DBG_dump_chunk("Generated Ke_r:", st->st_ne_r); + ); + + /* KE out */ + if (!build_and_ship_KE_rpk(st, FALSE, &st->st_gr, st->st_oakley.group + , &md->rbody, ISAKMP_NEXT_ID)) + return STF_INTERNAL_ERROR; + + /* Ke_r[Ke_r] out */ + { + chunk_t ch, out; + + if (st->st_connection->this.id.kind == ID_DER_ASN1_DN) { + ch.len = st->st_connection->this.id.der_asn1_dn.len + 4; + ch.ptr = alloc_bytes(ch.len, "encrypted der_asn1_dn identity"); + ch.ptr[0] = (u_int8_t)st->st_connection->this.id.kind; + memset(&(ch.ptr[1]), 0, 1); + memset(&(ch.ptr[2]), 0, 2); + memcpy(&(ch.ptr[4]), + st->st_connection->this.id.der_asn1_dn.ptr, + st->st_connection->this.id.der_asn1_dn.len); + } else { + ch.len = sizeof(st->st_connection->this.id.ip_addr) + 4; + ch.ptr = alloc_bytes(ch.len, "encrypted identity"); + ch.ptr[0] = (u_int8_t)st->st_connection->this.id.kind; + memset(&(ch.ptr[1]), 0, 1); + memset(&(ch.ptr[2]), 0, 2); + memcpy(&(ch.ptr[4]), &(st->st_connection->this.id.ip_addr), + sizeof(st->st_connection->this.id.ip_addr)); + } + + if (!encrypt_payload(st, &st->st_ks_r, st->st_ne_r_iv, + ch, &out)) + return STF_INTERNAL_ERROR; + freeanychunk(ch); + + /* Are we going to send CERT? */ + if ((st->st_connection->cert_options & CERT_OPTION_SEND) == 0) { + if (!out_generic_chunk(ISAKMP_NEXT_NONE, &isakmp_generic_desc, + &md->rbody, out, "my identity (ciphertext)")) + { + freeanychunk(out); + return STF_INTERNAL_ERROR; + } + } else { + if (!out_generic_chunk(ISAKMP_NEXT_CERT, &isakmp_generic_desc, + &md->rbody, out, "my identity (ciphertext)")) + { + freeanychunk(out); + return STF_INTERNAL_ERROR; + } + } + freeanychunk(out); + } + + /* Well, if we do send CERT, let's start on it from here */ + if ((st->st_connection->cert_options & CERT_OPTION_SEND) != 0) { + + chunk_t crt, cx, out; + unsigned long ulen; + /* Send the signing certificate */ + + ulen = i2d_X509(st->st_connection->cert, NULL); + ulen++; + if ((cx.ptr = alloc_bytes(ulen, "ASN.1 cert")) == NULL) + { + return STF_INTERNAL_ERROR; + } + (cx.ptr)[0] = (u_char)(CERT_TYPE_X509_SIG); + cx.len = ulen; + crt.ptr = &(cx.ptr[1]); + crt.len = i2d_X509(st->st_connection->cert, &(crt.ptr)); + + DBG(DBG_CRYPT, + DBG_log("plaintext Certificate length: %d", cx.len); + DBG_dump_chunk("plaintext Certificate", cx); + ); + + /* encrypt the certificate to send */ + if (!encrypt_payload(st, &st->st_ks_r, st->st_ne_r_iv, + cx, &out)) + return STF_INTERNAL_ERROR; + + DBG(DBG_CRYPT, + DBG_log("cyphertext Certificate length: %d", out.len); + DBG_dump_chunk("cyphertext Certificate", out); + ); + + if (!out_generic_chunk(ISAKMP_NEXT_NONE, + &isakmp_ipsec_certificate_desc, + &md->rbody, out, "my certificate (ciphertext)")) + { + freeanychunk(out); + return STF_INTERNAL_ERROR; + } + } + /* end of sending out cert */ + + /* finish message */ + close_message(&md->rbody); + + /* next message will be encrypted, but not this one. + * We could defer this calculation. + */ +#ifndef DODGE_DH_MISSING_ZERO_BUG + compute_dh_shared(st, st->st_gi, st->st_oakley.group); +#endif + if (!generate_skeyids_iv(st)) + return STF_FAIL + AUTHENTICATION_FAILED; + update_iv(st); + + /* Advance state */ + st->st_state = STATE_MAIN_R2; + + DBG(DBG_PARSING, + DBG_log("finished main_inI2_outR2_rpk"); + ); + + return STF_REPLY; +} +#endif /* OPENSSL */ + + +/* STATE_MAIN_I2: + * SMF_PSK_AUTH: HDR, KE, Nr --> HDR*, IDi1, HASH_I + * SMF_DS_AUTH: HDR, KE, Nr --> HDR*, IDi1, [ CERT, ] SIG_I + * + * The following are not yet implemented. + * SMF_PKE_AUTH: HDR, KE, PubKey_i, PubKey_i + * --> HDR*, HASH_I + * SMF_RPKE_AUTH: HDR, PubKey_i, Ke_r, Ke_r + * --> HDR*, HASH_I + */ +stf_status +main_inR2_outI3(struct msg_digest *md) +{ + struct state *const st = md->st; +#ifdef OPENSSL + struct connection *c = st->st_connection; +#endif + + pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs; + + int auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY + ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG; + + DBG(DBG_PARSING, + DBG_log("in main_inR2_outI3"); + ); + + /* KE in */ + RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", + st->st_oakley.group, keyex_pbs)); + + /* Nr in */ + RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr")); + + /* done parsing; initialize crypto */ + + compute_dh_shared(st, st->st_gr, st->st_oakley.group); +#ifdef DODGE_DH_MISSING_ZERO_BUG + if (st->st_shared.ptr[0] == 0) + return STF_REPLACE_DOOMED_EXCHANGE; +#endif + if (!generate_skeyids_iv(st)) + return STF_FAIL + AUTHENTICATION_FAILED; + + /*************** build output packet HDR*;IDii;HASH/SIG_I ***************/ + /* ??? NOTE: this is almost the same as main_inI3_outR3's code */ + + /* HDR* out done */ + + /* IDii out */ + { + struct isakmp_ipsec_id id_hd; + chunk_t id_b; + pb_stream id_pbs; + + build_id_payload(&id_hd, &id_b, &st->st_connection->this); +#ifdef OPENSSL +if (use_openssl(st->st_connection)) +{ + switch(st->st_oakley.auth) { + case OAKLEY_RSA_SIG: + case OAKLEY_DSS_SIG: + if ((c->cert_options & CERT_OPTION_SEND) == 0) + id_hd.isaiid_np = ISAKMP_NEXT_SIG; + else + id_hd.isaiid_np = ISAKMP_NEXT_CERT; + break; + case OAKLEY_RSA_ENC: + case OAKLEY_RSA_ENC_REV: + log("RSA method not supported yet"); + return STF_INTERNAL_ERROR; + break; + default: + id_hd.isaiid_np = ISAKMP_NEXT_HASH; + break; + } +} +else +{ +#endif /* OPENSSL */ + id_hd.isaiid_np = auth_payload; +#ifdef OPENSSL +} +#endif /* OPENSSL */ + + if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &id_pbs) + || !out_chunk(id_b, &id_pbs, "my identity")) + return STF_INTERNAL_ERROR; + close_output_pbs(&id_pbs); + } /* IDii out done */ + +#ifdef OPENSSL +if (use_openssl(st->st_connection)) +{ + if (((c->cert_options & CERT_OPTION_SEND) != 0) && + ((st->st_oakley.auth == OAKLEY_RSA_SIG) || + (st->st_oakley.auth == OAKLEY_DSS_SIG))) { + u_char *crt, *cx; + unsigned long ulen; + /* Send the signing certificate */ + + ulen = i2d_X509(c->cert, NULL); + ulen++; + if ((cx = alloc_bytes(ulen, "ASN.1 cert")) == NULL) + { return STF_INTERNAL_ERROR; } + cx[0] = (u_char)(CERT_TYPE_X509_SIG); + crt = &(cx[1]); + i2d_X509(c->cert, &crt); + if (!out_generic_raw(ISAKMP_NEXT_SIG, &isakmp_ipsec_certificate_desc + , &md->rbody, cx, ulen, "CERT_I")) + return STF_INTERNAL_ERROR; + pfree(cx); + } + + /* HASH_I out, OPENSSL */ + { + u_char hash_val[MAX_DIGEST_LEN]; + size_t hash_len = main_mode_hash(st, hash_val, TRUE, TRUE); + u_char *buf; + u_int elen; + bool ok; + + /* Output the signature/hash as defined by the selected Oakley transform */ + + switch (st->st_oakley.auth) { + case OAKLEY_RSA_SIG: /* output signed HASH_I */ + if ((buf = alloc_bytes(EVP_PKEY_size(c->key) + 32 /* bit of slack */, + "RSA signature")) == NULL) + return STF_INTERNAL_ERROR; + elen = RSA_private_encrypt(hash_len, hash_val, buf, + ((EVP_PKEY *)(c->key))->pkey.rsa, + RSA_PKCS1_PADDING); + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc, &md->rbody + , buf, elen, "SIG_I")) + return STF_INTERNAL_ERROR; + pfree(buf); + + DBG(DBG_PARSING, + DBG_log("Selected auth mechanism is %s", + enum_show(&oakley_auth_names, st->st_oakley.auth)); + ) + break; + + case OAKLEY_DSS_SIG: + /* We don't have to check whether the hash is a SHA1 */ + /* one, since the ciphersuite offering DSA is only */ + /* configured with SHA1. Don't change this configuration */ + if (c->cert_options & CERT_OPTION_DSS_SHA) + main_mode_sha1(st, hash_val, &hash_len, TRUE, TRUE); + + buf = alloc_bytes(EVP_PKEY_size(c->key) + 32 /* bit of slack */, + "DSA signature"); + if (buf) { + ok = (c->cert_options & CERT_OPTION_DSS_ALT) + ? DSA_sign_raw(hash_val, hash_len, + buf, &elen, ((EVP_PKEY *)(c->key))->pkey.dsa) + : DSA_sign(EVP_PKEY_DSA, hash_val, hash_len, + buf, &elen, ((EVP_PKEY *)(c->key))->pkey.dsa); + if (!ok) { + /* DSA signing failed */ + log_err(); + return STF_INTERNAL_ERROR; + } + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc, + &md->rbody, buf, elen, "SIG_I")) + return STF_INTERNAL_ERROR; + pfree(buf); + } else + return STF_INTERNAL_ERROR; + + DBG(DBG_PARSING | DBG_CONTROL, + DBG_log("Selected auth mechanism is %s", + enum_show(&oakley_auth_names, st->st_oakley.auth)); + ); + break; + /* If we get to any of these, something has gone WAY wrong */ + case OAKLEY_RSA_ENC: + return STF_INTERNAL_ERROR; + case OAKLEY_ELGAMAL_ENC: + return STF_INTERNAL_ERROR; + case OAKLEY_RSA_ENC_REV: + return STF_INTERNAL_ERROR; + case OAKLEY_ELGAMAL_ENC_REV: + return STF_INTERNAL_ERROR; + default: + } /* switch done */ + } /* HASH_I out, openssl done. */ +} +else +{ +#endif /* OPENSSL */ + /* HASH_I or SIG_I out, !OPENSSL */ + { + u_char hash_val[MAX_DIGEST_LEN]; + size_t hash_len = main_mode_hash(st, hash_val, TRUE, TRUE); + + if (auth_payload == ISAKMP_NEXT_HASH) + { + /* HASH_I out */ + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody + , hash_val, hash_len, "HASH_I")) + return STF_INTERNAL_ERROR; + } + else + { + /* SIG_I out */ + u_char sig_val[RSA_MAX_OCTETS]; + size_t sig_len = RSA_sign_hash(st->st_connection, + sig_val, hash_val, hash_len); + + if (sig_len == 0) + { + loglog(RC_LOG_SERIOUS, "unable to locate my private key for RSA Signature"); + return STF_FAIL + AUTHENTICATION_FAILED; + } + + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc + , &md->rbody, sig_val, sig_len, "SIG_I")) + return STF_INTERNAL_ERROR; + } + } +#ifdef OPENSSL +} +#endif /* OPENSSL */ + + /* encrypt message, except for fixed part of header */ + + /* st_new_iv was computed by generate_skeyids_iv */ + if (!encrypt_message(&md->rbody, st)) + return STF_INTERNAL_ERROR; /* ??? we may be partly committed */ + + /* Advance state */ + st->st_state = STATE_MAIN_I3; + + DBG(DBG_PARSING, + DBG_log("finished main_inR2_outI3"); + ); + + return STF_REPLY; +} + +#ifdef OPENSSL +/* + * Handle HDR;KE;PubKey_i;PubKey_i from responder. + * Send a HDR*;HASH_I back. + */ +stf_status main_inR2_outI3_pk(struct msg_digest *md) +{ + struct state *const st = md->st; + pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs; + + DBG(DBG_PARSING, + DBG_log("in main_inR2_outI3_pk"); + ); + + /* KE in */ + RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", + st->st_oakley.group, keyex_pbs)); + + /* IDir in */ + if (!decode_peer_id(md, TRUE)) + return STF_FAIL + INVALID_ID_INFORMATION; + + /* Nr in */ + RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "PubKey_i")); + /* done parsing; initialize crypto */ - /**************** build output packet HDR;KE;Nr ****************/ + compute_dh_shared(st, st->st_gr, st->st_oakley.group); +#ifdef DODGE_DH_MISSING_ZERO_BUG + if (st->st_shared.ptr[0] == 0) + return STF_REPLACE_DOOMED_EXCHANGE; +#endif + if (!generate_skeyids_iv(st)) + return STF_FAIL + AUTHENTICATION_FAILED; - /* HDR out done */ + /**************** build output packet HDR*;HASH_I ****************/ - /* KE out */ - if (!build_and_ship_KE(st, &st->st_gr, st->st_oakley.group - , &md->rbody, ISAKMP_NEXT_NONCE)) - return STF_INTERNAL_ERROR; + /* HDR* out done */ - /* Nr out */ - if (!build_and_ship_nonce(&st->st_nr, &md->rbody, ISAKMP_NEXT_NONE, "Nr")) + /* HASH_I out */ + { + u_char hash_val[MAX_DIGEST_LEN]; + size_t hash_len = main_mode_hash(st, hash_val, TRUE, TRUE); + + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody + , hash_val, hash_len, "HASH_I")) return STF_INTERNAL_ERROR; + } - /* finish message */ - close_message(&md->rbody); + /* encrypt message, except for fixed part of header */ - /* next message will be encrypted, but not this one. - * We could defer this calculation. - */ -#ifndef DODGE_DH_MISSING_ZERO_BUG - compute_dh_shared(st, st->st_gi, st->st_oakley.group); -#endif - if (!generate_skeyids_iv(st)) - return STF_FAIL + AUTHENTICATION_FAILED; - update_iv(st); + /* st_new_iv was computed by generate_skeyids_iv */ + if (!encrypt_message(&md->rbody, st)) + return STF_INTERNAL_ERROR; /* ??? we may be partly committed */ /* Advance state */ - st->st_state = STATE_MAIN_R2; + st->st_state = STATE_MAIN_I3; + + DBG(DBG_PARSING, + DBG_log("finished main_inR2_outI3_pk"); + ); return STF_REPLY; } +#endif /* OPENSSL */ -/* STATE_MAIN_I2: - * SMF_PSK_AUTH: HDR, KE, Nr --> HDR*, IDi1, HASH_I - * SMF_DS_AUTH: HDR, KE, Nr --> HDR*, IDi1, [ CERT, ] SIG_I - * - * The following are not yet implemented. - * SMF_PKE_AUTH: HDR, KE, PubKey_i, PubKey_i - * --> HDR*, HASH_I - * SMF_RPKE_AUTH: HDR, PubKey_i, Ke_r, Ke_r - * --> HDR*, HASH_I +#ifdef OPENSSL +/* Handle HDR;KE;PubKey_i;Ke_r;Ke_r from responder. + * Send a HDR*;HASH_I back. */ stf_status -main_inR2_outI3(struct msg_digest *md) +main_inR2_outI3_rpk(struct msg_digest *md) { struct state *const st = md->st; pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs; - int auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY - ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG; - /* KE in */ - RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", st->st_oakley.group, keyex_pbs)); + DBG(DBG_PARSING, + DBG_log("in main_inR2_outI3_rpk"); + ); /* Nr in */ - RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr")); + RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "PubKey_i")); + + /* KE in */ + RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", + st->st_oakley.group, keyex_pbs)); + + /* IDir in */ + if (!decode_peer_id(md, TRUE)) + return STF_FAIL + INVALID_ID_INFORMATION; /* done parsing; initialize crypto */ @@ -2098,55 +3408,20 @@ if (!generate_skeyids_iv(st)) return STF_FAIL + AUTHENTICATION_FAILED; - /*************** build output packet HDR*;IDii;HASH/SIG_I ***************/ - /* ??? NOTE: this is almost the same as main_inI3_outR3's code */ + /**************** build output packet HDR*;HASH_I ****************/ /* HDR* out done */ - /* IDii out */ - { - struct isakmp_ipsec_id id_hd; - chunk_t id_b; - pb_stream id_pbs; - - build_id_payload(&id_hd, &id_b, &st->st_connection->this); - id_hd.isaiid_np = auth_payload; - if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &id_pbs) - || !out_chunk(id_b, &id_pbs, "my identity")) - return STF_INTERNAL_ERROR; - close_output_pbs(&id_pbs); - } - - /* HASH_I or SIG_I out */ - { - u_char hash_val[MAX_DIGEST_LEN]; - size_t hash_len = main_mode_hash(st, hash_val, TRUE, TRUE); - - if (auth_payload == ISAKMP_NEXT_HASH) - { /* HASH_I out */ - if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody - , hash_val, hash_len, "HASH_I")) - return STF_INTERNAL_ERROR; - } - else { - /* SIG_I out */ - u_char sig_val[RSA_MAX_OCTETS]; - size_t sig_len = RSA_sign_hash(st->st_connection - , sig_val, hash_val, hash_len); + u_char hash_val[MAX_DIGEST_LEN]; - if (sig_len == 0) - { - loglog(RC_LOG_SERIOUS, "unable to locate my private key for RSA Signature"); - return STF_FAIL + AUTHENTICATION_FAILED; - } + size_t hash_len = main_mode_hash(st, hash_val, TRUE, TRUE); - if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc - , &md->rbody, sig_val, sig_len, "SIG_I")) + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody, + hash_val, hash_len, "HASH_I")) return STF_INTERNAL_ERROR; } - } /* encrypt message, except for fixed part of header */ @@ -2157,8 +3432,30 @@ /* Advance state */ st->st_state = STATE_MAIN_I3; + DBG(DBG_PARSING, + DBG_log("fnished main_inR2_outI3_rpk"); + ); + return STF_REPLY; } +#endif /* OPENSSL */ + + +#ifdef OPENSSL +/* STATE_MAIN_R2: + * Which type of DS are we currently handling? + * Classic? OPENSSL? + */ +stf_status +main_inI3_outR3_whichds(struct msg_digest *md) +{ + if (! use_openssl(md->st->st_connection)) { + return main_inI3_outR3(md); + } else { + return main_inI3_outR3_ds(md); + } +} +#endif /* OPENSSL */ /* STATE_MAIN_R2: * PSK_AUTH: HDR*, IDi1, HASH_I --> HDR*, IDr1, HASH_R @@ -2172,6 +3469,10 @@ int auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG; + DBG(DBG_PARSING, + DBG_log("in main_inI3_outR3"); + ); + /* input code similar to main_inR3 -- should be factored */ /* IDii in */ @@ -2219,52 +3520,394 @@ if (sig_len == 0) { - loglog(RC_LOG_SERIOUS, "unable to locate my private key for RSA Signature"); - return STF_FAIL + AUTHENTICATION_FAILED; + loglog(RC_LOG_SERIOUS, "unable to locate my private key for RSA Signature"); + return STF_FAIL + AUTHENTICATION_FAILED; + } + + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc + , &md->rbody, sig_val, sig_len, "SIG_R")) + return STF_INTERNAL_ERROR; + } + } + + /* encrypt message, sans fixed part of header */ + + if (!encrypt_message(&md->rbody, st)) + return STF_INTERNAL_ERROR; /* ??? we may be partly committed */ + + /* Last block of Phase 1 (R3), kept for Phase 2 IV generation */ + DBG_cond_dump(DBG_CRYPT, "last encrypted block of Phase 1:" + , st->st_new_iv, st->st_new_iv_len); + + /* Advance state */ + st->st_state = STATE_MAIN_R3; + ISAKMP_SA_established(st->st_connection, st->st_serialno); + + /* ??? If st->st_connectionc->gw_info != NULL, + * we should keep the public key -- it tested out. + */ + + return STF_REPLY; +} + +/* STATE_MAIN_I3: + * Handle HDR*;IDir;HASH/SIG_R from responder. + */ +stf_status +main_inR3(struct msg_digest *md) +{ + struct state *const st = md->st; + struct connection *c = st->st_connection; + + DBG(DBG_PARSING, + DBG_log("in main_inR3"); + ); + + /* input code similar to main_inI3_outR3 -- should be factored */ + + /* IDir in */ + if (!decode_peer_id(md, TRUE)) + return STF_FAIL + INVALID_ID_INFORMATION; + + /* HASH_R or SIG_R in */ + RETURN_STF_FAILURE(check_main_authenticator(md, FALSE)); + + /**************** done input ****************/ + + /* Advance state */ + st->st_state = STATE_MAIN_I4; + ISAKMP_SA_established(c, st->st_serialno); + + /* ??? If c->gw_info != NULL, + * we should keep the public key -- it tested out. + */ + + update_iv(st); /* finalize our Phase 1 IV */ + + DBG(DBG_PARSING, + DBG_log("finished main_inR3"); + ); + + return STF_UNPEND_QUICK; +} + +#ifdef OPENSSL +/* Handle HDR*;IDir;[CERT];SIG_R from responder. + */ +stf_status +main_inR3_ds(struct msg_digest *md) +{ + struct state *const st = md->st; + struct connection *c = st->st_connection; + u_char hash_val[MAX_DIGEST_LEN], *buf; + pb_stream *sig_pbs; + unsigned int dlen; + struct payload_digest *id_pld; + size_t hash_len = main_mode_hash(st, hash_val, FALSE, FALSE); + // size_t hash_len; + // main_mode_hash(st, hash_val, &hash_len, FALSE, FALSE); + + /* input code similar to main_inI3_outR3 -- should be factored */ + + DBG(DBG_PARSING, + DBG_log("in main_inR3_ds"); + ); + + /* IDir in */ + if (!decode_peer_id(md, TRUE)) + return STF_FAIL + INVALID_ID_INFORMATION; + + switch (st->st_oakley.auth) { + case OAKLEY_RSA_SIG: /* check SIG_I */ + { + RSA *rsa; + STACK_OF(X509) *peerlist; + X509 *recv_cert, *cert; + pb_stream *cert_pbs; + int i, success; + + recv_cert = NULL; + /* First check to see if we have a certificate sent to us */ + if ((md->chain[ISAKMP_NEXT_CERT] != NULL) && + ((cert_pbs = &md->chain[ISAKMP_NEXT_CERT]->pbs) != NULL)) { + u_char *crt; + unsigned long len; + + switch(cert_pbs->cur[0]) { + case CERT_TYPE_X509_SIG: + crt = &(cert_pbs->cur[1]); + len = pbs_left(cert_pbs)-1; + recv_cert = d2i_X509(NULL, &crt, len); + break; + default: + DBG(DBG_PARSING, + DBG_log("Unhandled certificate encoding: %s", + enum_show(&cert_names, cert_pbs->cur[0])); + ); + break; + } + } + + if (recv_cert) { + char buf[200]; + + X509_NAME_oneline(X509_get_subject_name(recv_cert) + , buf, sizeof(buf)); + DBG(DBG_PARSING, + DBG_log("Sent certificate \"%s\"", buf); + ); + } + + id_pld = md->chain[ISAKMP_NEXT_ID]; + if ((peerlist = + peer_cert_list((STACK_OF(XMAP) *)c->lu, + EVP_PKEY_RSA, recv_cert, id_pld, + (c->cert_options & CERT_OPTION_STRICT) ? TRUE : FALSE)) == NULL) { + log("Verification certificate(s) unavailable to check signature in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + + if (sk_X509_num(peerlist) == 0) { + log("Unable to get any certificate for peer in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + + if ((md->chain[ISAKMP_NEXT_SIG] == NULL) || + ((sig_pbs = &md->chain[ISAKMP_NEXT_SIG]->pbs) == NULL)) { + log("Signature not present in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + DBG(DBG_PARSING, + DBG_dump("Computed hash", hash_val, hash_len); + ); + /* Iterate through all certificates in the peer list until */ + /* we have one which verifies the signature, or we have no */ + /* more certificates to verify with */ + for(i=0, success=0, buf = NULL; ((success == 0) && (i < sk_X509_num(peerlist))); i++) { + rsa = X509_get_pubkey(sk_X509_value(peerlist, i))->pkey.rsa; + if ((buf = alloc_bytes(EVP_PKEY_size(X509_get_pubkey(sk_X509_value(peerlist, i))), + "RSA decrypt sig")) != NULL) { + dlen = RSA_public_decrypt(pbs_left(sig_pbs), sig_pbs->cur, buf, rsa + , RSA_PKCS1_PADDING); + DBG(DBG_PARSING, + DBG_dump("Decrypted hash", buf, (dlen > hash_len) + ? hash_len : dlen); + ); + if ((dlen == hash_len) && (memcmp(buf, hash_val, hash_len) == 0)) { + DBG(DBG_PARSING, + DBG_log("SIG_R matches computed hash"); + ) + success = 1; + cert = X509_dup(sk_X509_value(peerlist, i)); + } else { + DBG(DBG_PARSING, + DBG_log("SIG_R does not match computed hash"); + ); + } + pfree(buf); + buf = NULL; + } + } + if (buf) pfree(buf); + + if (!success) { + log_err(); + DBG_cond_dump(DBG_CRYPT, + "received SIG_R does not match computed value in Main R3:" + , sig_pbs->cur, pbs_left(sig_pbs)); + sk_X509_pop_free(peerlist, X509_free); + return STF_FAIL + INVALID_SIGNATURE; + } else { + /* We know that certificate 'cert' was used to */ + /* sign the accurate hash which accompanied the method */ + /* Now we have to verify that it is a valid certificate */ + /* to be signing anything */ + DBG(DBG_PARSING, + DBG_log("Verifying certificate along path %s", c->path); + ); + if (verify_certificate( cert, c->lu, c->path, + (c->cert_options & CERT_OPTION_STRICT) ? TRUE : FALSE )) + { + DBG(DBG_PARSING, + DBG_log("Signing certificate is valid"); + ); + } else { + sk_X509_pop_free(peerlist, X509_free); + return STF_FAIL + INVALID_CERTIFICATE; + } + } + sk_X509_pop_free(peerlist, X509_free); + } + break; + case OAKLEY_DSS_SIG: + { + DSA *dsa; + STACK_OF(X509) *peerlist; + X509 *recv_cert, *cert; + pb_stream *cert_pbs; + int i, success; + + if (c->cert_options & CERT_OPTION_DSS_SHA) + main_mode_sha1(st, hash_val, &hash_len, FALSE, FALSE); + recv_cert = NULL; + /* First check to see if we have a certificate sent to us */ + if ((md->chain[ISAKMP_NEXT_CERT] != NULL) && + ((cert_pbs = &md->chain[ISAKMP_NEXT_CERT]->pbs) != NULL)) { + u_char *crt; + unsigned long len; + + switch(cert_pbs->cur[0]) { + case CERT_TYPE_X509_SIG: + crt = &(cert_pbs->cur[1]); + len = pbs_left(cert_pbs)-1; + recv_cert = d2i_X509(NULL, &crt, len); + break; + default: + DBG(DBG_PARSING, + DBG_log("Unhandled certificate encoding: %s", + enum_show(&cert_names, cert_pbs->cur[0])); + ); + break; + } + } + + if (recv_cert) { + char buf[200]; + + X509_NAME_oneline(X509_get_subject_name(recv_cert) + , buf, sizeof(buf)); + DBG(DBG_PARSING, + DBG_log("Sent certificate \"%s\"", buf); + ); + } + + /* We know this field is legitimate, because the */ + /* decode_peer_id has been called before */ + id_pld = md->chain[ISAKMP_NEXT_ID]; + + if ((peerlist = + peer_cert_list((STACK_OF(XMAP) *)c->lu, + EVP_PKEY_DSA, recv_cert, + id_pld, + (c->cert_options & CERT_OPTION_STRICT) ? TRUE : FALSE )) == NULL) { + log("Verification certificate(s) unavailable to check signature in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + + if (sk_X509_num(peerlist) == 0) { + log("Unable to get any certificate for peer in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + + if ((md->chain[ISAKMP_NEXT_SIG] == NULL) || + ((sig_pbs = &md->chain[ISAKMP_NEXT_SIG]->pbs) == NULL)) { + log("Signature not present in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + DBG(DBG_PARSING, + DBG_dump("Computed hash", hash_val, hash_len); + ); + /* Iterate through all certificates in the peer list until */ + /* we have one which verifies the signature, or we have no */ + /* more certificates to verify with */ + for(i=0, success=0, buf=NULL; ((success == 0) && (i < sk_X509_num(peerlist))); i++) { + dsa = X509_get_pubkey(sk_X509_value(peerlist, i))->pkey.dsa; + if ((buf = alloc_bytes(SHA1_DIGEST_SIZE, "DSA decrypt sig")) != NULL) { + success = (c->cert_options & CERT_OPTION_DSS_ALT) + ? DSA_verify_raw(hash_val, hash_len, + sig_pbs->cur, pbs_left(sig_pbs), + dsa) + : DSA_verify(EVP_PKEY_DSA, + hash_val, hash_len, + sig_pbs->cur, pbs_left(sig_pbs), + dsa); + if (success == 1) { + DBG(DBG_PARSING, + DBG_log("SIG_I matches computed hash"); + ); + cert = X509_dup(sk_X509_value(peerlist, i));; + } else if (success == 0) { + DBG(DBG_PARSING, + DBG_log("SIG_I does not match computed hash"); + ); + } else { + DBG(DBG_PARSING, + DBG_log("Verification error"); + ); + log_err(); + } + pfree(buf); + buf = NULL; + } + } + if (buf) pfree(buf); + if (!success) { + log_err(); + DBG_cond_dump(DBG_CRYPT, "received SIG_I does not match computed value in Main I3:" + , sig_pbs->cur, pbs_left(sig_pbs)); + sk_X509_pop_free(peerlist, X509_free); + return STF_FAIL + INVALID_SIGNATURE; + } else { + /* We know that certificate 'cert' was used to */ + /* sign the accurate hash which accompanied the method */ + /* Now we have to verify that it is a valid certificate */ + /* to be signing anything */ + DBG(DBG_PARSING, + DBG_log("Verifying certificate along path %s", c->path); + ); + if (verify_certificate( cert, c->lu, c->path, (c->cert_options & CERT_OPTION_STRICT) ? TRUE : FALSE )) + { + DBG(DBG_PARSING, + DBG_log("Signing certificate is valid"); + ); } - - if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc - , &md->rbody, sig_val, sig_len, "SIG_R")) - return STF_INTERNAL_ERROR; + else { + sk_X509_pop_free(peerlist, X509_free); + return STF_FAIL + INVALID_CERTIFICATE; } } + sk_X509_pop_free(peerlist, X509_free); + } + break; + default: + return STF_INTERNAL_ERROR; + break; + } - /* encrypt message, sans fixed part of header */ - - if (!encrypt_message(&md->rbody, st)) - return STF_INTERNAL_ERROR; /* ??? we may be partly committed */ - - /* Last block of Phase 1 (R3), kept for Phase 2 IV generation */ - DBG_cond_dump(DBG_CRYPT, "last encrypted block of Phase 1:" - , st->st_new_iv, st->st_new_iv_len); + /**************** done input ****************/ /* Advance state */ - st->st_state = STATE_MAIN_R3; - ISAKMP_SA_established(st->st_connection, st->st_serialno); + st->st_state = STATE_MAIN_I4; + ISAKMP_SA_established(c, st->st_serialno); - /* ??? If st->st_connectionc->gw_info != NULL, - * we should keep the public key -- it tested out. - */ + update_iv(st); /* finalize our Phase 1 IV */ + + DBG(DBG_PARSING, + DBG_log("finished main_inR3_ds"); + ); - return STF_REPLY_UNPEND_QUICK; + return STF_UNPEND_QUICK; } +#endif -/* STATE_MAIN_I3: - * Handle HDR*;IDir;HASH/SIG_R from responder. +#ifdef OPENSSL +/* Handle HDR*;HASH_R from responder. */ stf_status -main_inR3(struct msg_digest *md) +main_inR3_pk(struct msg_digest *md) { struct state *const st = md->st; struct connection *c = st->st_connection; /* input code similar to main_inI3_outR3 -- should be factored */ - /* IDir in */ - if (!decode_peer_id(md, TRUE)) - return STF_FAIL + INVALID_ID_INFORMATION; + DBG(DBG_PARSING, + DBG_log("in main_inR3_pk"); + ); - /* HASH_R or SIG_R in */ + /* HASH_R in */ + // CHECK_HASH(main_mode_hash(st, hash_val, &hash_len, FALSE, FALSE) + // , "HASH_R", "Main R3"); RETURN_STF_FAILURE(check_main_authenticator(md, FALSE)); /**************** done input ****************/ @@ -2273,14 +3916,16 @@ st->st_state = STATE_MAIN_I4; ISAKMP_SA_established(c, st->st_serialno); - /* ??? If c->gw_info != NULL, - * we should keep the public key -- it tested out. - */ - update_iv(st); /* finalize our Phase 1 IV */ + DBG(DBG_PARSING, + DBG_log("finished main_inR3_pk"); + ); + return STF_UNPEND_QUICK; } +#endif + /* Handle first message of Phase 2 -- Quick Mode. * HDR*, HASH(1), SA, Ni [, KE ] [, IDci, IDcr ] --> @@ -2413,6 +4058,8 @@ } else if (p != c) { + /* use p, not c */ + /* We've got a better connection: it can support the * specified clients. But it may need instantiation. */ @@ -2420,8 +4067,7 @@ { /* Yup, it needs instantiation. How much? * Is it a Road Warrior connection (simple) - * or is it an Opportunistic connection (needing gw validation)? - */ + * or is it an Opportunistic connection (needing gw validation)? */ if (HasWildcardClient(p)) { /* Opportunistic. @@ -2721,8 +4367,510 @@ if (c->gw_info != NULL) c->gw_info->last_worked_time = now(); + DBG(DBG_PARSING, + DBG_log("finished main_inI3_outR3"); + ); + + return STF_REPLY; +} + +#ifdef OPENSSL +/* + * Handle HDR*;IDii;HASH_I from initiator. Send a HDR*;IDir;HASH_R back. + */ +stf_status +main_inI3_outR3_ds(struct msg_digest *md) +{ + struct state *const st = md->st; + + struct connection *c = st->st_connection; + u_char hash_val[MAX_DIGEST_LEN], *buf; + pb_stream *sig_pbs; + unsigned int dlen; + struct payload_digest *id_pld; + size_t hash_len = main_mode_hash(st, hash_val, TRUE, FALSE); + + DBG(DBG_PARSING, + DBG_log("in main_inI3_outR3_ds"); + ); + + /* input code similar to main_inR3 -- should be factored */ + + /* IDii in */ + if (!decode_peer_id(md, FALSE)) + return STF_FAIL + INVALID_ID_INFORMATION; + + switch (st->st_oakley.auth) { + case OAKLEY_RSA_SIG: /* check SIG_I */ + { + RSA *rsa; + STACK_OF(X509) *peerlist; + X509 *recv_cert, *cert; + pb_stream *cert_pbs; + int i, success; + + recv_cert = NULL; + /* First check to see if we have a certificate sent to us */ + if ((md->chain[ISAKMP_NEXT_CERT] != NULL) && + ((cert_pbs = &md->chain[ISAKMP_NEXT_CERT]->pbs) != NULL)) { + u_char *crt; + unsigned long len; + + switch(cert_pbs->cur[0]) { + case CERT_TYPE_X509_SIG: + crt = &(cert_pbs->cur[1]); + len = pbs_left(cert_pbs)-1; + recv_cert = d2i_X509(NULL, &crt, len); + break; + default: + DBG(DBG_PARSING, + DBG_log("Unhandled certificate encoding: %s", + enum_show(&cert_names, cert_pbs->cur[0])); + ); + break; + } + } + + if (recv_cert) { + char buf[200]; + + X509_NAME_oneline(X509_get_subject_name(recv_cert) + , buf, sizeof(buf)); + DBG(DBG_PARSING, + DBG_log("Received certificate \"%s\"", buf); + ); + } + + /* We know this field is legitimate, because the */ + /* decode_peer_id has been called before */ + id_pld = md->chain[ISAKMP_NEXT_ID]; + + if ((peerlist = peer_cert_list((STACK_OF(XMAP) *)(c->lu), + EVP_PKEY_RSA, + recv_cert, + id_pld, + (c->cert_options & CERT_OPTION_STRICT) + ? TRUE : FALSE)) == NULL) { + log("Verification certificate(s) unavailable to check signature in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + + if (sk_X509_num(peerlist) == 0) { + log("Unable to get any certificate for peer in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + + if ((md->chain[ISAKMP_NEXT_SIG] == NULL) || + ((sig_pbs = &md->chain[ISAKMP_NEXT_SIG]->pbs) == NULL)) { + log("Signature not present in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + DBG(DBG_PARSING, + DBG_dump("Computed hash", hash_val, hash_len); + ); + /* Iterate through all certificates in the peer list until */ + /* we have one which verifies the signature, or we have no */ + /* more certificates to verify with */ + for (i=0, success = 0; (success == 0) && (ipkey.rsa; + if ((buf = alloc_bytes(EVP_PKEY_size(X509_get_pubkey(xx)), + "RSA decrypt sig")) != NULL) { + dlen = RSA_public_decrypt(pbs_left(sig_pbs), sig_pbs->cur, buf, + rsa, RSA_PKCS1_PADDING); + DBG(DBG_PARSING, + DBG_dump("Decrypted hash", buf, (dlen > hash_len) + ? hash_len : dlen); + ); + if ((dlen == hash_len) && (memcmp(buf, hash_val, hash_len) == 0)) { + DBG(DBG_PARSING, + DBG_log("SIG_I matches computed hash"); + ); + success = 1; + cert = X509_dup(xx); + } else { + DBG(DBG_PARSING, + DBG_log("SIG_I does not computed hash"); + ); + } + pfree(buf); + } + } + if (!success) { + log_err(); + DBG_cond_dump(DBG_CRYPT, + "received SIG_I does not match computed value in Main I3:" + , sig_pbs->cur, pbs_left(sig_pbs)); + sk_X509_pop_free(peerlist, X509_free); + return STF_FAIL + INVALID_SIGNATURE; + } else { + /* We know that certificate 'cert' was used to */ + /* sign the accurate hash which accompanied the method */ + /* Now we have to verify that it is a valid certificate */ + /* to be signing anything */ + DBG(DBG_PARSING, + DBG_log("Verifying certificate along path %s", c->path); + ); + if (verify_certificate( cert, c->lu, c->path, + (c->cert_options & CERT_OPTION_STRICT) ? TRUE : FALSE )) + { + DBG(DBG_PARSING, + DBG_log("Signing certificate is valid."); + ); + } else { + DBG(DBG_PARSING, + DBG_log("Signing certificate NOT valid."); + ); + sk_X509_pop_free(peerlist, X509_free); + return STF_FAIL + INVALID_CERTIFICATE; + } + } + sk_X509_pop_free(peerlist, X509_free); + } + break; + case OAKLEY_DSS_SIG: + { + DSA *dsa; + STACK_OF(X509) *peerlist; + X509 *recv_cert, *cert; + pb_stream *cert_pbs; + int i, success; + + if (c->cert_options & CERT_OPTION_DSS_SHA) + main_mode_sha1(st, hash_val, &hash_len, TRUE, FALSE); + recv_cert = NULL; + /* First check to see if we have a certificate sent to us */ + if ((md->chain[ISAKMP_NEXT_CERT] != NULL) && + ((cert_pbs = &md->chain[ISAKMP_NEXT_CERT]->pbs) != NULL)) { + u_char *crt; + unsigned long len; + + switch(cert_pbs->cur[0]) { + case CERT_TYPE_X509_SIG: + crt = &(cert_pbs->cur[1]); + len = pbs_left(cert_pbs)-1; + recv_cert = d2i_X509(NULL, &crt, len); + break; + default: + DBG(DBG_PARSING, + DBG_log("Unhandled certificate encoding: %s", + enum_show(&cert_names, cert_pbs->cur[0])); + ); + break; + } + } + + if (recv_cert) { + char buf[200]; + + X509_NAME_oneline(X509_get_subject_name(recv_cert) + , buf, sizeof(buf)); + DBG(DBG_PARSING, + DBG_log("Received certificate \"%s\"", buf); + ); + } + + /* We know this field is legitimate, because the */ + /* decode_peer_id has been called before */ + id_pld = md->chain[ISAKMP_NEXT_ID]; + + if ((peerlist = + peer_cert_list((STACK_OF(XMAP) *)(c->lu), EVP_PKEY_DSA, + recv_cert, id_pld, + (c->cert_options & CERT_OPTION_STRICT) ? TRUE : FALSE)) == NULL) { + log("Verification certificate(s) unavailable to check signature in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + + if (sk_X509_num(peerlist) == 0) { + log("Unable to get any certificate for peer in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + + if ((md->chain[ISAKMP_NEXT_SIG] == NULL) || + ((sig_pbs = &md->chain[ISAKMP_NEXT_SIG]->pbs) == NULL)) { + log("Signature not present in Main R3"); + return STF_FAIL + INVALID_SIGNATURE; + } + + DBG(DBG_PARSING, + DBG_dump("Computed hash", hash_val, hash_len); + ); + /* Iterate through all certificates in the peer list until */ + /* we have one which verifies the signature, or we have no */ + /* more certificates to verify with */ + for(i=0, success=0, buf = NULL; + ((success == 0) && (i < sk_X509_num(peerlist))); i++) { + dsa = X509_get_pubkey(sk_X509_value(peerlist, i))->pkey.dsa; + if ((buf = alloc_bytes(SHA1_DIGEST_SIZE, "DSA sig space")) != NULL) { + success = (c->cert_options & CERT_OPTION_DSS_ALT) + ? DSA_verify_raw(hash_val, hash_len, + sig_pbs->cur, pbs_left(sig_pbs), + dsa) + : DSA_verify(EVP_PKEY_DSA, + hash_val, hash_len, + sig_pbs->cur, pbs_left(sig_pbs), + dsa) + ; + if (success == 1) { + DBG(DBG_PARSING, + DBG_log("SIG_I matches computed hash"); + ); + cert = X509_dup(sk_X509_value(peerlist, i)); + } else if (success == 0) { + DBG(DBG_PARSING, + DBG_log("SIG_I does not computed hash"); + ); + } else { + DBG(DBG_PARSING, + DBG_log("Verification error"); + ); + log_err(); + } + pfree(buf); + buf = NULL; + } + } + if (buf) pfree(buf); + if (!success) { + log_err(); + DBG_cond_dump(DBG_CRYPT, "received SIG_I does not match computed value in Main I3:" + , sig_pbs->cur, pbs_left(sig_pbs)); + sk_X509_pop_free(peerlist, X509_free); + return STF_FAIL + INVALID_SIGNATURE; + } else { + /* We know that certificate 'cert' was used to */ + /* sign the accurate hash which accompanied the method */ + /* Now we have to verify that it is a valid certificate */ + /* to be signing anything */ + DBG(DBG_PARSING, + DBG_log("Verifying certificate along path %s", c->path); + ); + if (verify_certificate( cert, c->lu, c->path, + (c->cert_options & CERT_OPTION_STRICT) ? TRUE : FALSE )) + { + DBG(DBG_PARSING, + DBG_log("Signing certificate is valid"); + ); + } else { + sk_X509_pop_free(peerlist, X509_free); + return STF_FAIL + INVALID_CERTIFICATE; + } + } + sk_X509_pop_free(peerlist, X509_free); + } + break; + /* Should never get here */ + default: + return STF_INTERNAL_ERROR; + } + + /************* build output packet HDR*;IDir;[CERT];SIG_R ******/ + /* ??? NOTE: this is almost the same as main_inR2_outI3's code */ + + /* IDir out */ + { + struct isakmp_ipsec_id r_id; + pb_stream r_id_pbs; + chunk_t r_id_chunk; + + // r_id.isaiid_idtype = st->st_myidentity_type; + r_id.isaiid_idtype = st->st_connection->this.id.kind; + r_id.isaiid_protoid = 0; /* ??? is this right? */ + r_id.isaiid_port = 0; /* ??? is this right? */ + + build_id_payload(&r_id, &r_id_chunk, &st->st_connection->this); + + if ((c->cert_options & CERT_OPTION_SEND) == 0) + r_id.isaiid_np = ISAKMP_NEXT_SIG; + else + r_id.isaiid_np = ISAKMP_NEXT_CERT; + + if (!out_struct(&r_id, &isakmp_ipsec_identification_desc, &md->rbody, + &r_id_pbs) || !out_chunk(r_id_chunk, &r_id_pbs, "my identity")) + return STF_INTERNAL_ERROR; + close_output_pbs(&r_id_pbs); + +#if 0 + /* if a permanent cast is needed, we'll need to rethink this. */ + r_id_chunk.len = sizeof(st->st_connection->this.id.ip_addr); + memcpy(&(r_id_chunk.ptr), &(st->st_connection->this.id.ip_addr), r_id_chunk.len); + + if (!out_struct(&r_id, &isakmp_ipsec_identification_desc, + &md->rbody, &r_id_pbs) + || !out_chunk(r_id_chunk, &r_id_pbs, "my identity")) + return STF_INTERNAL_ERROR; + close_output_pbs(&r_id_pbs); +#endif + } + + if ((c->cert_options & CERT_OPTION_SEND) != 0) { + /* Send the signing certificate */ + u_char *crt, *cx; + unsigned long ulen; + /* Send the signing certificate */ + + ulen = i2d_X509(c->cert, NULL); + ulen++; + if ((cx = alloc_bytes(ulen, "ASN.1 cert")) == NULL) + { return STF_INTERNAL_ERROR; } + cx[0] = (u_char)(CERT_TYPE_X509_SIG); + crt = &(cx[1]); + i2d_X509(c->cert, &crt); + if (!out_generic_raw(ISAKMP_NEXT_SIG, &isakmp_ipsec_certificate_desc + , &md->rbody, cx, ulen, "CERT_R")) + return STF_INTERNAL_ERROR; + pfree(cx); + } + + /* SIG_R out */ + { + u_char hash_val[MAX_DIGEST_LEN]; + u_int elen; + bool ok; + + // size_t hash_len; + // main_mode_hash(st, hash_val, &hash_len, FALSE, TRUE); + size_t hash_len = main_mode_hash(st, hash_val, FALSE, TRUE); + + /* Output the signature/hash as defined by the selected Oakley transform */ + switch (st->st_oakley.auth) { + case OAKLEY_RSA_SIG: /* output signed HASH_R */ + if ((buf = alloc_bytes(EVP_PKEY_size(c->key) + 32 /* bit of slack */, + "RSA sig")) == NULL) + return STF_INTERNAL_ERROR; + elen = RSA_private_encrypt(hash_len, hash_val, buf, + ((EVP_PKEY *)(c->key))->pkey.rsa, + RSA_PKCS1_PADDING); + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc, + &md->rbody, buf, elen, "SIG_R")) + return STF_INTERNAL_ERROR; + break; + case OAKLEY_DSS_SIG: + if (c->cert_options & CERT_OPTION_DSS_SHA) + main_mode_sha1(st, hash_val, &hash_len, FALSE, TRUE); + + if ((buf = alloc_bytes(EVP_PKEY_size(c->key) + 32 /* bit of slack */, + "DSA sig")) == NULL) + return STF_INTERNAL_ERROR; + ok = (c->cert_options & CERT_OPTION_DSS_ALT) + ? DSA_sign_raw(hash_val, hash_len, + buf, &elen, + ((EVP_PKEY *)(c->key))->pkey.dsa) + : DSA_sign(EVP_PKEY_DSA, hash_val, hash_len, + buf, &elen, + ((EVP_PKEY *)(c->key))->pkey.dsa); + if (!ok) { + log_err(); + return STF_INTERNAL_ERROR; + } + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc, + &md->rbody, buf, elen, "SIG_I")) + return STF_INTERNAL_ERROR; + + DBG(DBG_PARSING, + DBG_log("Selected auth mechanism is %s", + enum_show(&oakley_auth_names, st->st_oakley.auth)); + ); + break; + default: + return STF_INTERNAL_ERROR; + } + pfree(buf); + } + + /* encrypt message, sans fixed part of header */ + + if (!encrypt_message(&md->rbody, st)) + return STF_INTERNAL_ERROR; /* ??? we may be partly committed */ + + /* Last block of Phase 1 (R3), kept for Phase 2 IV generation */ + DBG_cond_dump(DBG_CRYPT, "last encrypted block of Phase 1:" + , st->st_new_iv, st->st_new_iv_len); + + /* Advance state */ + st->st_state = STATE_MAIN_R3; + ISAKMP_SA_established(st->st_connection, st->st_serialno); + + DBG(DBG_PARSING, + DBG_log("finished main_inI3_outR3_ds"); + ); + + return STF_REPLY; +} +#endif /* OPENSSL */ + +#ifdef OPENSSL +/* + * Handle HDR*;HASH_I from initiator. Send a HDR*;HASH_R back. + */ +stf_status +main_inI3_outR3_pk(struct msg_digest *md) +{ + struct state *const st = md->st; + + /* input code similar to main_inR3 -- should be factored */ + + DBG(DBG_PARSING, + DBG_log("in main_inI3_outR3_pk"); + ); + + /* HASH_I in */ + // CHECK_HASH(main_mode_hash(st, hash_val, &hash_len, TRUE, FALSE) + // , "HASH_I", "Main I3"); + RETURN_STF_FAILURE(check_main_authenticator(md, TRUE)); + + /**************** build output packet HDR*;HASH_R ****************/ + + /* HASH_R out */ + { + u_char hash_val[MAX_DIGEST_LEN]; + + // size_t hash_len; + // main_mode_hash(st, hash_val, &hash_len, FALSE, TRUE); + size_t hash_len = main_mode_hash(st, hash_val, FALSE, TRUE); + + if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody + , hash_val, hash_len, "HASH_R")) + return STF_INTERNAL_ERROR; + } + + /* encrypt message, sans fixed part of header */ + if (!encrypt_message(&md->rbody, st)) + return STF_INTERNAL_ERROR; /* ??? we may be partly committed */ + + /* Last block of Phase 1 (R3), kept for Phase 2 IV generation */ + DBG_cond_dump(DBG_CRYPT, "last encrypted block of Phase 1:" + , st->st_new_iv, st->st_new_iv_len); + + /* Advance state */ + st->st_state = STATE_MAIN_R3; + ISAKMP_SA_established(st->st_connection, st->st_serialno); + + DBG(DBG_PARSING, + DBG_log("finished main_inI3_outR3_pk"); + ); + return STF_REPLY; } +#endif + +#ifdef OPENSSL +/* STATE_MAIN_I3: + * Handle HDR*;IDir;HASH/SIG_R from responder. + */ +stf_status +main_inR3_whichds(struct msg_digest *md) +{ + if (!use_openssl(md->st->st_connection)) { + return main_inR3(md); + } else { + return main_inR3_ds(md); + } +} +#endif /* OPENSSL */ + /* Handle last message of Quick Mode. * HDR*, HASH(3) -> done diff -BbruN freeswan-1.91.orig/pluto/ipsec_doi.h freeswan-1.91/pluto/ipsec_doi.h --- freeswan-1.91.orig/pluto/ipsec_doi.h Tue May 8 01:37:22 2001 +++ freeswan-1.91/pluto/ipsec_doi.h Mon Jul 16 23:26:30 2001 @@ -28,9 +28,27 @@ main_inI1_outR1, main_inR1_outI2, main_inI2_outR2, +#ifdef OPENSSL + main_inI2_outR2_pk, + main_inI2_outR2_rpk, +#endif main_inR2_outI3, +#ifdef OPENSSL + main_inR2_outI3_pk, + main_inR2_outI3_rpk, +#endif main_inI3_outR3, +#ifdef OPENSSL + main_inI3_outR3_whichds, + main_inI3_outR3_ds, + main_inI3_outR3_pk, +#endif main_inR3, +#ifdef OPENSSL + main_inR3_whichds, + main_inR3_ds, + main_inR3_pk, +#endif quick_inI1_outR1, quick_inR1_outI2, quick_inI2; diff -BbruN freeswan-1.91.orig/pluto/kernel.c freeswan-1.91/pluto/kernel.c --- freeswan-1.91.orig/pluto/kernel.c Sat Jun 16 18:02:39 2001 +++ freeswan-1.91/pluto/kernel.c Mon Jul 16 23:26:30 2001 @@ -50,6 +50,7 @@ #include "server.h" #include "whack.h" /* for RC_LOG_SERIOUS */ +extern int send_delete(struct state *st, ipsec_spi_t *spi, bool ESP); bool can_do_IPcomp = TRUE; /* can system actually perform IPCOMP? */ @@ -1866,6 +1867,7 @@ 0, HMAC_SHA1_KEY_LEN, SADB_EALG_NULL, SADB_AALG_SHA1HMAC }, +#ifdef DES { ESP_DES, AUTH_ALGORITHM_NONE, DES_CBC_BLOCK_SIZE, 0, SADB_EALG_DESCBC, SADB_AALG_NONE }, @@ -1875,6 +1877,7 @@ { ESP_DES, AUTH_ALGORITHM_HMAC_SHA1, DES_CBC_BLOCK_SIZE, HMAC_SHA1_KEY_LEN, SADB_EALG_DESCBC, SADB_AALG_SHA1HMAC }, +#endif { ESP_3DES, AUTH_ALGORITHM_NONE, DES_CBC_BLOCK_SIZE * 3, 0, @@ -2145,6 +2148,8 @@ passert(FALSE); /* neither AH nor ESP in outbound SA bundle! */ } + send_delete(st, &f->our_spi, proto==SA_ESP?TRUE:FALSE); + return inbound ? del_spi(f->our_spi, proto, &c->that.host_addr, &c->this.host_addr) : del_spi(f->attrs.spi, proto, &c->this.host_addr, &c->that.host_addr); @@ -2242,9 +2247,6 @@ eroute_installed = st == NULL ? shunt_eroute(c, ERO_REPLACE, "replace") : sag_eroute(st, ERO_REPLACE, "replace"); - - if (eroute_installed && bspp != NULL) - free_bare_shunt(bspp); } else { @@ -2252,6 +2254,9 @@ eroute_installed = st == NULL ? shunt_eroute(c, ERO_ADD, "add") : sag_eroute(st, ERO_ADD, "add"); + + if (eroute_installed && bspp != NULL) + free_bare_shunt(bspp); } /* notify the firewall of a new tunnel */ diff -BbruN freeswan-1.91.orig/pluto/main.c freeswan-1.91/pluto/main.c --- freeswan-1.91.orig/pluto/main.c Tue Jun 12 17:40:38 2001 +++ freeswan-1.91/pluto/main.c Mon Jul 16 23:26:30 2001 @@ -29,6 +29,11 @@ #include +#ifdef OPENSSL +#include +#include +#endif + #include "constants.h" #include "defs.h" #include "id.h" @@ -42,6 +47,20 @@ #include "rnd.h" #include "state.h" +#ifdef OPENSSL +#include "openssl.h" +#include "xmap_dir.h" +#include "xmap_file.h" +#ifdef HAVE_DB +#include "xmap_db.h" +#endif +#ifdef HAVE_LDAP +#include "xmap_ldap.h" +#endif +#include "xmap.h" + +#endif /* OPENSSL */ + #include "sha1.h" #include "md5.h" #include "crypto.h" /* requires sha1.h and md5.h */ @@ -166,6 +185,21 @@ bool log_to_stderr_desired = FALSE; int lockfd; +#ifdef OPENSSL + SSLeay_add_all_algorithms(); + X509V3_add_standard_extensions(); + ERR_load_crypto_strings(); + ERR_load_ElGamal_strings(); + XMAP_register(XMAP_METHOD_file()); + XMAP_register(XMAP_METHOD_dir()); +#ifdef HAVE_DB + XMAP_register(XMAP_METHOD_db()); +#endif /* HAVE_DB */ +#ifdef HAVE_LDAP + XMAP_register(XMAP_METHOD_ldap()); +#endif /* HAVE_LDAP */ +#endif + /* handle arguments */ for (;;) { @@ -405,6 +439,8 @@ abort(); } + close(lockfd); + init_constants(); init_log(); /* Note: some scripts may look for this exact message -- don't change */ @@ -439,6 +475,10 @@ #ifdef LEAK_DETECTIVE report_leaks(); #endif /* LEAK_DETECTIVE */ +#ifdef OPENSSL + X509V3_EXT_cleanup(); + ERR_free_strings(); +#endif close_log(); exit(status); } diff -BbruN freeswan-1.91.orig/pluto/md5.c freeswan-1.91/pluto/md5.c --- freeswan-1.91.orig/pluto/md5.c Sat Dec 11 20:31:36 1999 +++ freeswan-1.91/pluto/md5.c Mon Jul 16 23:26:30 2001 @@ -139,7 +139,11 @@ /* MD5 initialization. Begins an MD5 operation, writing a new context. */ void MD5Init (context) +#ifndef OPENSSL MD5_CTX *context; /* context */ +#else +PLUTO_MD5_CTX *context; /* context */ +#endif { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. @@ -155,7 +159,11 @@ context. */ void MD5Update (context, input, inputLen) +#ifndef OPENSSL MD5_CTX *context; /* context */ +#else +PLUTO_MD5_CTX *context; /* context */ +#endif unsigned char *input; /* input block */ UINT4 inputLen; /* length of input block */ { @@ -194,7 +202,11 @@ */ void MD5Final (digest, context) unsigned char digest[16]; /* message digest */ +#ifndef OPENSSL MD5_CTX *context; /* context */ +#else +PLUTO_MD5_CTX *context; +#endif /* OPENSSL */ { unsigned char bits[8]; unsigned int index, padLen; diff -BbruN freeswan-1.91.orig/pluto/md5.h freeswan-1.91/pluto/md5.h --- freeswan-1.91.orig/pluto/md5.h Sat Dec 11 20:31:36 1999 +++ freeswan-1.91/pluto/md5.h Mon Jul 16 23:26:30 2001 @@ -61,11 +61,22 @@ UINT4 state[4]; /* state (ABCD) */ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ unsigned char buffer[64]; /* input buffer */ +#ifndef OPENSSL } MD5_CTX; +#else +} PLUTO_MD5_CTX; +#endif /* OPENSSL */ +#ifndef OPENSSL void MD5Init PROTO_LIST ((MD5_CTX *)); void MD5Update PROTO_LIST ((MD5_CTX *, unsigned char *, UINT4)); void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); +#else +void MD5Init PROTO_LIST ((PLUTO_MD5_CTX *)); +void MD5Update PROTO_LIST + ((PLUTO_MD5_CTX *, unsigned char *, unsigned int)); +void MD5Final PROTO_LIST ((unsigned char [16], PLUTO_MD5_CTX *)); +#endif /* OPENSSL */ #define _MD5_H_ diff -BbruN freeswan-1.91.orig/pluto/openssl.c freeswan-1.91/pluto/openssl.c --- freeswan-1.91.orig/pluto/openssl.c Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/openssl.c Sat Aug 18 11:17:49 2001 @@ -0,0 +1,3117 @@ +#ifdef OPENSSL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include "constants.h" +#include "defs.h" +#include "id.h" +#include "connections.h" /* needs id.h */ +#include "state.h" +#include "kernel.h" +#include "log.h" +#include "packet.h" +#include "preshared.h" /* for RSA_public_key used in FreeS/WAN */ +#include "spdb.h" +#include "demux.h" +#include "openssl.h" +#include "xmap.h" + +#include "whack.h" /* for RC_LOG_SERIOUS value, for loglog()s. */ + +struct _tok_node { + char *s; + struct _tok_node *next; +}; + +typedef struct _tok_node *tok_list; + +enum tok_state { TOK_NORMAL, TOK_QUOTE, TOK_BACKSLASH, TOK_BACKSLASH_Q }; + +void tok_append(tok_list *t, const char *s); +tok_list tokenize( const char *s, const char sep ); +void tok_free( tok_list t ); +static STACK_OF(X509) *lookup_certs_by_subject(STACK_OF(XMAP) *lu, + X509_NAME *name); + +#if 0 /* not used */ +static STACK_OF(X509) *lookup_certs_by_issuer(STACK_OF(XMAP) *lu, + X509_NAME *name); +#endif + +void build_cert_chain( STACK_OF(X509) **ch, STACK_OF(XMAP) *lu, X509 *x ); +static int cert_compare(X509 *a, X509 *b); +static STACK_OF(X509) *lookup_certs_by_ip(STACK_OF(XMAP) *lu, + const char *id, + const size_t len); +static int ASN1_UTCTIME_cmp(ASN1_UTCTIME *a, ASN1_UTCTIME *b); +static int cb( int ok, X509_STORE_CTX *ctx ); + +static void *extract_certs_pkeys_bags (STACK *bags, + chunk_t p8pass, bool privcert_type); +static void *extract_certs_pkeys_bag (PKCS12_SAFEBAG *bag, chunk_t p8pass, + bool privcert_type); +static EVP_PKEY *extract_pkey_using_p8inf(PKCS8_PRIV_KEY_INFO *p8inf); +static X509 *find_pubcert_in_stack( struct connection **c, + STACK_OF(X509) *x509_stack); + +void +tok_append(tok_list *t, const char *s) { + tok_list p, pp; + + if (!t) return; + if ((p = malloc(sizeof(struct _tok_node))) == NULL) return; + if ((p->s = strdup(s)) == NULL) { free(p); return; } + p->next = NULL; + + if (*t == NULL) { *t = p; return; }; /* Empty list */ + pp = *t; + while (pp->next != NULL) pp = pp->next; + pp->next = p; +} + +tok_list +tokenize( const char *s, const char sep ) +{ + tok_list t = NULL; + int len, i, cnt, size; + char *buf; + enum tok_state st = TOK_NORMAL; + + cnt = 0; + len = strlen(s); + size = 256; /* Initial size */ + if ((buf = malloc(size)) == NULL) return t; + memset(buf, 0, size); + for(i=0; inext; + + free(p->s); + free(p); + p = pp; + } +} + +void +log_err( void ) +{ + unsigned long l; + char buf[200]; + const char *file, *data; + int line, flags; + unsigned long es; + + es=CRYPTO_thread_id(); + while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0) + { + log("%lu:%s:%s:%d:%s\n",es,ERR_error_string(l,buf), + file,line,(flags&ERR_TXT_STRING)?data:""); + } +} + +bool +make_lookups( STACK_OF(XMAP) **lu, const char *spec ) +{ +#define MAXSPEC 10 + const char *delim = ", "; + char *s, *p, *specs[MAXSPEC]; + int i; + XMAP *xm; + bool retval = TRUE; + + for(i=0; icertfile; + X509 *x = NULL; + char *conn_name = d->name; + + BIO *b = NULL; + PKCS7 *p7 = NULL; + PKCS12 *p12 = NULL; + STACK_OF(X509) *p7_stack = NULL; + bool pub_PKCS7_found = FALSE; + + + DBG(DBG_PARSING, + if (conn_name[0] != '\0') { + DBG_log("Loading certificate for connection \"%s\"", conn_name); + } else { + DBG_log("Loading certificate"); + } + ); + + x = NULL; + d->certtype = PUBCERT_NONE; + + /* if the filepaths are null, return */ + if (cert[0] == '\0') return; + + if ((b = BIO_new_file(cert, "r")) == NULL) { + log_err(); + return; + } + + if (!x) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + DBG(DBG_CRYPT, + DBG_log("Attempting to load a DER PKCS12 cert."); + ); + if ((p12 = d2i_PKCS12_bio(b, NULL)) != NULL) + { + PKCS12_free(p12); + BIO_free(b); + d->certtype = PUBCERT_PKCS12; + return; + } + } + + if (!x) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + DBG(DBG_CRYPT, + DBG_log("Attempting to load a PEM PKCS7 cert."); + ); + /* Start with trying to load PKCS7, unencrypted */ +#if OPENSSL_VERSION_NUMBER > 0x00903000L + p7 = PEM_read_bio_PKCS7(b, NULL, NULL, NULL); +#else + p7 = PEM_read_bio_PKCS7(b, NULL, NULL); +#endif + if (p7 == NULL) { + /* Try DER read */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + DBG(DBG_CRYPT, + DBG_log("Attempting to load a DER PKCS7 cert."); + ); + if ((p7 = d2i_PKCS7_bio(b, NULL)) != NULL) pub_PKCS7_found = TRUE; + } else { + pub_PKCS7_found = TRUE; + } + + if (pub_PKCS7_found) + { + if ((p7_stack = extract_STACK_OF_X509_from_PKCS7(p7)) == NULL) + { + log_err(); + PKCS7_free(p7); + BIO_free(b); + return; + } else { + /* now we must go through the stack to find which is the + * right cert. Compare ID_DER_ASN1_DN from what was given + * as ID in connection entry. + */ + if (sk_X509_num(p7_stack) == 0) { + loglog(RC_LOG_SERIOUS, "No certificates in PKCS7 chain"); + PKCS7_free(p7); + BIO_free(b); + return; + } + else + { + if ((x = find_pubcert_in_stack(&d, p7_stack)) == NULL) + { + PKCS7_free(p7); + BIO_free(b); + d->certtype = PUBCERT_NONE; + return; + } + d->certtype = PUBCERT_X509; + PKCS7_free(p7); + } + } + } + } + + if (!x) + { + DBG(DBG_CRYPT, + DBG_log("Attempting to load a PEM X509 cert."); + ); + /* Now for non PKCS7, loading direct x509 cert. */ +#if OPENSSL_VERSION_NUMBER > 0x00903000L + x = PEM_read_bio_X509(b, NULL, NULL, NULL); +#else + x = PEM_read_bio_X509(b, NULL, NULL); +#endif + if (x == NULL) { + /* Try DER read */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + DBG(DBG_CRYPT, + DBG_log("Attempting to load a DER X509 cert."); + ); + if ((x = d2i_X509_bio(b, NULL)) == NULL) { + log_err(); + BIO_free(b); + d->certtype = PUBCERT_NONE; + return; + } + } + } + + if (x) { + d->cert = (void *)x; + d->certtype = PUBCERT_X509; + } else { + BIO_free(b); + d->certkeytype = PUBCERT_NONE; + DBG(DBG_PARSING | DBG_CRYPT, + DBG_log("No cert found from %s", cert); + ); + return; + } + + DBG(DBG_PARSING | DBG_CRYPT, + DBG_log("Read certificate from %s", cert); + ); + BIO_free(b); + return; +} + + +void +load_certkey( struct connection **c ) +{ + struct connection *d = *c; + + char *key = d->certkeyfile; + EVP_PKEY *k = NULL; + char *conn_name = d->name; + + BIO *b = NULL; + X509_SIG *p8 = NULL; + PKCS12 *p12 = NULL; + bool pub_PKCS8_found = FALSE; + char keystr[32] = "PEM private key"; + + DBG(DBG_PARSING, + if (conn_name[0] != '\0') { + DBG_log("Loading key for connection \"%s\"", conn_name); + } else { + DBG_log("Loading key"); + } + ); + + k = NULL; + d->certkeytype = PRIVCERT_NONE; + + /* if the filepaths are null, return */ + if (key[0] == '\0') return; + + if ((b = BIO_new_file(key, "r")) == NULL) { + log_err(); + return; + } + + if (!k) { + DBG(DBG_CRYPT, + DBG_log("Attempting to load a DER PKCS12 privkey."); + ); + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + if ((p12 = d2i_PKCS12_bio(b, NULL)) != NULL) + { + PKCS12_free(p12); + BIO_free(b); + d->certkeytype = PRIVCERT_PKCS12; + return; + } + } + + if (!k) { + DBG(DBG_CRYPT, + DBG_log("Attempting to load a PEM PKCS8 privkey."); + ); + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + /* start with PKCS8 PEM */ +#if OPENSSL_VERSION_NUMBER > 0x00903000L + p8 = PEM_read_bio_PKCS8(b, NULL, NULL, NULL); +#else + p8 = PEM_read_bio_PKCS8(b, NULL, NULL); +#endif + if (p8 == NULL) { + /* Try DER read */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + DBG(DBG_CRYPT, + DBG_log("Attempting to load a DER PKCS8 privkey."); + ); + if ((p8 = d2i_PKCS8_bio(b, NULL)) != NULL) { + pub_PKCS8_found = TRUE; + } + } else { + pub_PKCS8_found = TRUE; + } + + if (pub_PKCS8_found) { + PKCS8_PRIV_KEY_INFO *p8inf; + + /* Try unencrypted PKCS8 key */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(b,NULL,NULL, NULL); + if (p8inf == NULL) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + if ((p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(b, NULL)) == NULL) { + /* it's a PKCS8 key, and it's encrypted. Return */ + d->certkeytype = PRIVCERT_PKCS8_ENC; + + DBG(DBG_PARSING, + DBG_log("Found encrypted PKCS8 key."); + ); + + PKCS8_PRIV_KEY_INFO_free (p8inf); + BIO_free(b); + return; + } + } + else + { + + /* it's a PKCS8 key, but it's unencrypted */ + DBG(DBG_PARSING, + DBG_log("Found unencrypted PKCS8 key."); + ); + + d->certkeytype = PRIVCERT_PKCS8; + PKCS8_PRIV_KEY_INFO_free (p8inf); + BIO_free(b); + + load_pkcs(&d); + return; + } + } + } + + if (!k) { + DBG(DBG_CRYPT, + DBG_log("Attempting to load a PEM X509 privkey."); + ); + + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + /* read in an unencrypted priv key */ +#if OPENSSL_VERSION_NUMBER > 0x00903000L + k = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL); +#else + k = PEM_read_bio_PrivateKey(b, NULL, NULL); +#endif + if (!k) { + RSA *rsa; + + /* Try DER reading of RSA Key */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + + DBG(DBG_CRYPT, + DBG_log("Attempting to load a DER X509 privkey."); + ); + + rsa = d2i_RSAPrivateKey_bio(b, NULL); + if (rsa) { + if ((k = EVP_PKEY_new()) != NULL) { + (k)->type = EVP_PKEY_RSA; + (k)->pkey.rsa = rsa; + strncpy(keystr, "DER RSA private key", sizeof(keystr)-1); + } else { + RSA_free(rsa); + } + } + } + } + + if (!k) { + DSA *dsa; + + DBG(DBG_CRYPT, + DBG_log("Attempting to load a DER X509 DSA privkey."); + ); + + /* Try DER reading of DSA/El Gamal Key */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + dsa = d2i_DSAPrivateKey_bio(b, NULL); + if (dsa) { + if ((k = EVP_PKEY_new()) != NULL) { + (k)->type = EVP_PKEY_DSA; + (k)->pkey.dsa = dsa; + strncpy(keystr, "DER DSA private key", sizeof(keystr)-1); + } else + DSA_free(dsa); + } + } + + if (k) { + d->key = (void *)k; + d->certkeytype = PRIVCERT_X509; + } else { + BIO_free(b); + d->certkeytype = PRIVCERT_NONE; + DBG(DBG_PARSING | DBG_CRYPT, + DBG_log("No key found from %s", key); + ); + return; + } + + DBG(DBG_PARSING | DBG_CRYPT, + DBG_log("Read %s from %s", keystr, key); + ); + BIO_free(b); + return; +} + + +static int +cert_compare(X509 *a, X509 *b) +{ + /* Check for equality of 2 X509 certificates */ + /* certs are equal if their issuers, serial numbers */ + /* subject names and public keys are the same */ + /* We could probably do all of this by converting the */ + /* certs to DER format and comparing the byte streams */ + /* but that's likely to be inefficient -- nd */ + int c; + EVP_PKEY *ka, *kb; + + if ((c = X509_issuer_and_serial_cmp(a, b)) != 0) + return c; + if ((c = X509_NAME_cmp(X509_get_issuer_name(a), + X509_get_issuer_name(b))) != 0) + return c; + ka = X509_get_pubkey(a); + kb = X509_get_pubkey(b); + if (ka->type != kb->type) return 1; + switch (ka->type) { + case EVP_PKEY_RSA: + { + /* RSA compare - if public exponent and modulus are equal, return 0 */ + RSA *ra, *rb; + + ra = ka->pkey.rsa; + rb = ka->pkey.rsa; + + if (BN_cmp(ra->e, rb->e) != 0) return 1; + if (BN_cmp(ra->n, rb->n) != 0) return 1; + } + break; + case EVP_PKEY_DSA: + { + /* DSA compare, g, modulus and pubkey must be equal */ + DSA *da, *db; + + da = ka->pkey.dsa; + db = ka->pkey.dsa; + + if (BN_cmp(da->g, db->g) != 0) return 1; + if (BN_cmp(da->p, db->p) != 0) return 1; + if (BN_cmp(da->pub_key, db->pub_key) != 0) return 1; + } + break; + default: + DBG(DBG_PARSING, + DBG_log("Unknown key type presented: %d", ka->type); + ); + return 1; + break; + } + return 0; +} + +static STACK_OF(X509) * +lookup_certs_by_ip(STACK_OF(XMAP) *lu, + const char *id, + const size_t len) +{ + STACK_OF(X509) *osk = sk_X509_new_null(); + int i; + + for(i=0; idata.x509); + int k, found; + + for(k=0, found=0; (!found) && (k < sk_X509_num(osk)); k++) { + if (cert_compare(sk_X509_value(osk, k), c) == 0) + found = 1; + } + + if (!found) { + if (sk_X509_num(osk) == 0) { + sk_X509_push(osk, c); + } else { + ASN1_UTCTIME *new_notBefore = X509_get_notBefore(c); + ASN1_UTCTIME *new_notAfter = X509_get_notAfter(c); + + for(k=0; k 0) break; + } else + /* insert here is c start date is later than tx */ + if (c1 > 0) break; + /* else move on to the next certificate in the + current output stack */ + } + sk_X509_insert(osk, c, k); /* Insert into the output stack */ + } + } + } + sk_X509_OBJECT_pop_free(op, X509_OBJECT_free); + pfree(cl); + } + } + if (osk) DBG(DBG_PARSING, + DBG_log("Returning %d certs in list", sk_X509_num(osk)) + ); + return osk; +} + +/* peer_cert_list takes a supplied list of XMAPs */ +/* and adds all of the X509 certificates whose */ +/* public key matches 'type' into a safe stack certificates */ +/* If the parameter 'cert' is non-NULL, only the certificate */ +/* which matches it will be added to the list */ +STACK_OF(X509) * +peer_cert_list( STACK_OF(XMAP) *lu, int type, X509 *cert, + struct payload_digest *const id_pld, + bool strict ) +{ + STACK_OF(X509) *sk = NULL, *osk = NULL; + pb_stream *const id_pbs = &id_pld->pbs; + struct isakmp_id *const id = &id_pld->payload.id; + int i, found; + + switch(id->isaid_idtype) { + case ID_IPV4_ADDR: + if (pbs_left(id_pbs) != sizeof(struct in_addr)) { + DBG(DBG_PARSING, + DBG_log("ID size is not equal to that of an IPv4 address"); + ); + return NULL; + } + /* + * lookup_certs_by_ip(STACK_OF(XMAP) *lu, + * const char *id, const size_t len) + */ + if ((sk = lookup_certs_by_ip(lu, + id_pbs->cur, + sizeof(struct in_addr))) == NULL) { + DBG(DBG_PARSING, + DBG_log("No certs for this IP address"); + ); + return NULL; + } + break; + case ID_DER_ASN1_DN: + { + X509_NAME *xn = NULL; + long derlen; + unsigned char *der; + + derlen = (long)pbs_left(id_pbs); + der = (unsigned char *)(id_pbs->cur); + + xn = d2i_X509_NAME(&xn, &der, derlen); + + if (xn != NULL) { + if ((sk = lookup_certs_by_subject(lu, xn)) == NULL) { + DBG(DBG_PARSING, + DBG_log("No certs for this ID_DER_ASN1_DN"); + ); + return NULL; + } + } else { + DBG(DBG_PARSING, + DBG_log("Error in DER string. (Not a DER string?)"); + ); + return NULL; + } + X509_NAME_free(xn); + break; + } + default: + DBG(DBG_PARSING, + DBG_log("No means to check certificates for ID type = %s", + enum_show(&ident_names, id->isaid_idtype)); + ); + return NULL; + } + + /* Now filter out any certificates not of type 'type' */ + if ((osk = sk_X509_new_null()) != NULL) { + for(i=0; itype == type) { + sk_X509_push(osk, X509_dup(x)); + } else { + DBG(DBG_PARSING, + DBG_log("Rejecting certificate: wrong type: %d", pk->type); + ); + } + } + sk_X509_pop_free(sk, X509_free); + sk = osk; /* Make sk the new filtered list */ + } else { + DBG(DBG_PARSING, + DBG_log("Error in allocating new sk_X509"); + ); + sk_X509_pop_free(sk, X509_free); + sk = NULL; + } + + if ((sk) && (cert)) { + /* If a certificate was presupplied, we want to check */ + /* whether it is in the list of acceptable certificates */ + /* for this connection. If no certificate is presupplied */ + /* then it is assumed that one of the certificates in */ + /* the list will correctly decrypt the signature/nonces */ + + for(i=0, found=0; ((!found) && (i < sk_X509_num(sk))); i++) + if (cert_compare(sk_X509_value(sk, i), cert) == 0) found = 1; + + if (found) { + DBG(DBG_PARSING, + DBG_log("Certificate supplied is in list"); + ); + } else { + DBG(DBG_PARSING, + DBG_log("Certificate supplied is NOT in list"); + ); + + /* If strict is not set, this certificate will be allowed */ + /* to pass, even though the host cannot recognise it as */ + /* in the list of known certificates for this ID. Otherwise */ + /* we erase the list and return NULL -- an error condition */ + if (strict) { + sk_X509_pop_free(sk, X509_free); + sk = NULL; + } + } + } + + return sk; +} + +bool +have_rsa_key( struct state *st ) +{ + struct connection *c = st->st_connection; + + if (c->key == NULL) { + DBG(DBG_PARSING, + DBG_log("No key present"); + ); + return FALSE; + } + if ( ((EVP_PKEY *)(c->key))->type != EVP_PKEY_RSA ) { return FALSE; } + return TRUE; +} + +bool +have_dss_key( struct state *st ) +{ + struct connection *c = st->st_connection; + + if (c->key == NULL) { + DBG(DBG_PARSING, + DBG_log("No key present"); + ); + return FALSE; + } + if ( ((EVP_PKEY *)(c->key))->type != EVP_PKEY_DSA ) { return FALSE; } + return TRUE; +} + +bool +have_othercert( struct connection *c, int type ) +{ + struct end *that = &c->that; + STACK_OF(X509) *op = NULL; + X509 *x; + int i; + bool found; + + /* First check to see if we've already done */ + /* this lookup and stored the certificate in */ + /* c->other[] */ + + for(i=0; iother[i].type == type) && + (c->other[i].cert != NULL)) { + DBG(DBG_PARSING, + DBG_log("Already stored a type %d cert", type); + ); + return TRUE; + } + + switch (c->that.id.kind) + { + case ID_IPV4_ADDR: + op = lookup_certs_by_ip((STACK_OF(XMAP) *)c->lu, + (const char *)&that->host_addr, + sizeof(that->host_addr)); + break; + + case ID_DER_ASN1_DN: + { + +/* + * The 'd2i' function copies a binary representation into a C structure. It + * operates as follows. 'a' is a pointer to a pointer to + * the structure to populate, 'pp' is a pointer to a pointer to where the DER + * byte string is located and 'length' is the length of the '*pp' data. + * If there are no errors, a pointer to the populated structure is returned. + * + * X509_NAME * X509_NAME_new(void); + * void X509_NAME_free(X509_NAME *a); + * int i2d_X509_NAME(X509_NAME *a,unsigned char **pp); + * X509_NAME * d2i_X509_NAME(X509_NAME **a,unsigned char **pp,long length); + * int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + */ + X509_NAME *xn = X509_NAME_new(); + chunk_t temp_ptr = c->that.id.der_asn1_dn; + + xn = d2i_X509_NAME(&xn, &(c->that.id.der_asn1_dn.ptr), + (long)c->that.id.der_asn1_dn.len); + c->that.id.der_asn1_dn = temp_ptr; + + if (xn != NULL) { + op = lookup_certs_by_subject((STACK_OF(XMAP) *)c->lu, xn); + } else { + DBG(DBG_PARSING, + DBG_log("Error in DER string. (Not a DER string?)"); + ); + } + + X509_NAME_free(xn); + } + break; + } + + if (!op) { + DBG(DBG_PARSING, + DBG_log("Lookup returns NULL"); + ); + } else { + int i; + + for(i=0, found = FALSE; ((!found) && (i < sk_X509_num(op))); i++) { + x = sk_X509_value(op, i); + if (X509_get_pubkey(x)->type == type) { + found = TRUE; + for(i=0; iother[i].cert == NULL) { + DBG(DBG_PARSING, + DBG_log("Storing type %d cert at position %d", type, i); + ); + c->other[i].type = type; + c->other[i].cert = (void *)X509_dup(x); + break; + } + } + } + } + + if (found) { + DBG(DBG_PARSING, + DBG_log("Found type %d cert at position %d:", + type, i+1); + ); + } + sk_X509_pop_free(op, X509_free); + } + return (found); +} + +bool +have_rsa_keypair( struct state *st ) +{ + bool r = have_othercert(st->st_connection, EVP_PKEY_RSA); + if (r) r = have_rsa_key(st); + + DBG(DBG_PARSING, + DBG_log("Have RSA other cert = %s", r ? "TRUE" : "FALSE"); + ); + return r; +} + +bool +have_elgamal_keypair( struct state *st ) +{ + bool r = have_othercert(st->st_connection, EVP_PKEY_DSA); + if (r) r = have_dss_key(st); + + DBG(DBG_PARSING, + DBG_log("Have El Gamal other cert = %s", r ? "TRUE" : "FALSE"); + ); + return r; +} + +static int +cb( int ok, X509_STORE_CTX *ctx ) +{ + char buf[200]; + + if (!ok) { + if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) { + /* Check to see if it is a CA certificate, ie with */ + /* basicConstraints, and perhaps other checks */ + /* For the moment, we just let it slide */ + ok = 1; + } else { + X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf)); + + DBG(DBG_PARSING, + DBG_log("Error for certificate: %s", buf); + DBG_log("Error %d: Depth %d: %s", + ctx->error, + ctx->error_depth, + X509_verify_cert_error_string(ctx->error)); + ); + } + } + return (ok); +} + +static int +ASN1_UTCTIME_cmp(ASN1_UTCTIME *a, ASN1_UTCTIME *b) +{ + char buff1[14],buff2[14],*p; + int i,j; + + /* Degenerate cases */ + if (!a && !b) return 0; + if (a && !b) return 1; + if (!a && b) return -1; + + memset(buff1, 0, sizeof(buff1)); + memset(buff2, 0, sizeof(buff2)); + + p=buff1; + i=a->length; + if ((i < 11) || (i > 17)) return(0); + memcpy(p,a->data,12); + + p=buff2; + j=b->length; + if ((j < 11) || (j > 17)) return(0); + memcpy(p,b->data,12); + + /* Correct for Y2K */ + i=(buff1[0]-'0')*10+(buff1[1]-'0'); + if (i < 50) i+=100; /* cf. RFC 2459 */ + j=(buff2[0]-'0')*10+(buff2[1]-'0'); + if (j < 50) j+=100; + + if (i < j) return (-1); + if (i > j) return (1); + + i=strcmp(buff1,buff2); + + if (i == 0) + return 0; + else if (i < 0) + return(-1); + else + return(1); +} + +extern X509_CRL * +lookup_crl(STACK_OF(XMAP) *lu, X509_NAME *name) +{ + X509_CRL *x = NULL; + STACK_OF(X509_CRL) *osk = sk_X509_CRL_new_null(); + int i, j, k, found; + + for(i=0; idata.crl); + + for(k=0, found = 0; (!found) && (k 0) + /* insert here if last Update is newer than current crl */ + break; + } + /* Insert into the output stack */ + sk_X509_CRL_insert(osk, xx, k); + } + } else + X509_CRL_free(xx); + } + /* drop search return values */ + sk_X509_OBJECT_pop_free(xo, X509_OBJECT_free); + } + } + } + + if (sk_X509_CRL_num(osk) > 0) + /* use first certificate in stack */ + x = X509_CRL_dup(sk_X509_CRL_value(osk, 0)); + /* get rid of output stack */ + sk_X509_CRL_pop_free(osk, X509_CRL_free); + return x; +} + +static STACK_OF(XMAP) *lookups = NULL; +static bool verify_strict; +/* only way I can think to get the verify function (which is) */ +/* used as a callback to access the 'strict verification' flag */ +/* The problem is that there isn't any space in the parameters */ +/* to the verify_func in which to add this flag. Pity, because */ +/* a static global controlling verification policy is a fairly */ +/* stinky idea -- nd */ + + +/* The following code is simply the code from x509_vfy.c */ +/* with CRL checking added, and basicConstraints checking */ +static int +verify_func(X509_STORE_CTX *ctx) +{ + int i,ok=0,n; + X509 *xs,*xi; + EVP_PKEY *pkey=NULL; + int (*cb)(); + X509_CRL *crl; + + cb=ctx->ctx->verify_cb; + + n=sk_X509_num(ctx->chain); + DBG(DBG_PARSING, + DBG_log("%d certs in chain", n); + ); + ctx->error_depth=n-1; + n--; + xi=sk_X509_value(ctx->chain,n); + + if (X509_NAME_cmp(X509_get_subject_name(xi), + X509_get_issuer_name(xi)) == 0) + xs=xi; + else { + if (n <= 0) { + ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; + ctx->current_cert=xi; + ok=cb(0,ctx); + goto end; + } else { + n--; + ctx->error_depth=n; + xs=sk_X509_value(ctx->chain,n); + } + } + + while (n >= 0) { + ctx->error_depth=n; + if (!xs->valid) { + if ((pkey=X509_get_pubkey(xi)) == NULL) + { + ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ctx->current_cert=xi; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + if (X509_verify(xs,pkey) <= 0) { + EVP_PKEY_free(pkey); + ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE; + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + EVP_PKEY_free(pkey); + pkey=NULL; + + i=X509_cmp_current_time(X509_get_notBefore(xs)); + if (i == 0) { + ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + if (i > 0) { + ctx->error=X509_V_ERR_CERT_NOT_YET_VALID; + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + xs->valid=1; + } + + i=X509_cmp_current_time(X509_get_notAfter(xs)); + if (i == 0) { + ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + + if (i < 0) { + ctx->error=X509_V_ERR_CERT_HAS_EXPIRED; + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + + if (n == sk_X509_num(ctx->chain)-1) { + /* This is the root certificate */ + int loc = X509_get_ext_by_NID(xs, NID_basic_constraints, -1); + if (loc >= 0) { + X509_EXTENSION *ext; + BASIC_CONSTRAINTS *p = NULL; + + ext = X509_get_ext(xs, loc); + if (ext) { + p = X509V3_EXT_d2i(ext); + if (! p->ca) { + BASIC_CONSTRAINTS_free(p); + ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } else { + DBG(DBG_PARSING, + DBG_log("Root certificate has CA = True"); + ); + BASIC_CONSTRAINTS_free(p); + } + } else { + /* The cert has a basicConstraints extension, but */ + /* we couldn't get it */ + ctx->error=X509_V_ERR_APPLICATION_VERIFICATION; + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } +#ifndef DONT_BE_FASCIST + } else { + ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; +#endif + } + } + + /* CRL CHECK */ + if ((crl = lookup_crl(lookups, X509_get_issuer_name(xs))) != NULL) { + EVP_PKEY *pkey = X509_get_pubkey(xi); + STACK_OF(X509_REVOKED) *rev; + int nrev; + + DBG(DBG_PARSING, + DBG_log("Checking CRL for issuer"); + ); + + if (pkey == NULL) { + ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + X509_CRL_free(crl); + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + + if (X509_CRL_verify(crl, pkey) <= 0) { + ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE; + X509_CRL_free(crl); + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + + i = X509_cmp_current_time(X509_CRL_get_lastUpdate(crl)); + if (i == 0) { + ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; + X509_CRL_free(crl); + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + if (i > 0) { + ctx->error=X509_V_ERR_CRL_NOT_YET_VALID; + X509_CRL_free(crl); + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + + i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)); + if (i == 0) { + ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; + X509_CRL_free(crl); + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + if (i < 0) { + ctx->error=X509_V_ERR_CRL_HAS_EXPIRED; + X509_CRL_free(crl); + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + + rev = X509_CRL_get_REVOKED(crl); + nrev = sk_X509_REVOKED_num(rev); + DBG(DBG_PARSING, + DBG_log("%d certificates revoked in CRL", nrev); + ); + for(i=0; iserialNumber) == 0) { + /* It's this certificate that's been revoked */ + int c = X509_cmp_current_time(rv->revocationDate); + if (c < 0) { + ctx->error=X509_V_ERR_CERT_REVOKED; + X509_CRL_free(crl); + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + DBG(DBG_PARSING, + DBG_log("Serial Number matches"); + ); + } + } + + X509_CRL_free(crl); + } else { + char buf[200]; + + X509_NAME_oneline(X509_get_issuer_name(xs), buf, sizeof(buf)); + DBG(DBG_PARSING, + DBG_log("Cant locate a CRL for issuer %s", buf); + ); + /* If we're being paranoid here, we really should fail */ + /* the verification. An attacker capable of mounting */ + /* a denial of service attack could cause us fail to */ + /* load the CRL, and use a revoked, but otherwise valid */ + /* certificate in the exchange to set up a valid SA */ + /* In this case, we let it go, but an idea might be */ + /* to have an ipsec.conf specified policy on how mandatory */ + /* CRLs are in the verification sequence -- nd */ + if (verify_strict) { + ctx->error=X509_V_ERR_UNABLE_TO_GET_CRL; + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + } + + /* The last error (if any) is still in the error value */ + ctx->current_cert=xs; + ok=(*cb)(1,ctx); + if (!ok) goto end; + + n--; + if (n >= 0) { + xi=xs; + xs=sk_X509_value(ctx->chain,n); + } + } + ok=1; + end: + return(ok); +} + +static STACK_OF(X509) * +lookup_certs_by_subject(STACK_OF(XMAP) *lu, X509_NAME *xn) +{ + /* output stack - concatenation of certificates */ + /* return value */ + STACK_OF(X509) *osk = sk_X509_new_null(); + int i, j, k, found; + + DBG(DBG_PARSING, + DBG_log("Looking up certificate by subject"); + ); + for(i=0; ipmap) { + DBG(DBG_PARSING, + DBG_log("by_subject: Searching map %d", i+1); + ); + if ((xo = XMAP_lookup( xm, X509_LU_X509, "subject", xn)) != NULL) { + DBG(DBG_PARSING, + DBG_log("by_subject: Got %d certificates", sk_X509_OBJECT_num(xo)); + ); + for(j=0; jdata.x509); + + for(k=0, found = 0; (!found) && (k 0) break; + } else + /* insert here is xx start date is later than tx */ + if (c1 > 0) break; + /* else move on to the next certificate + * in the current output stack */ + } + /* Insert into the output stack */ + sk_X509_insert(osk, xx, k); + } + } else + X509_free(xx); + } + sk_X509_OBJECT_pop_free(xo, X509_OBJECT_free); + } /* if (xo != NULL) */ + else + { + DBG(DBG_PARSING, + DBG_log("xo = XMAP_lookup( xm, X509_LU_X509, + \"subject\", xn) == NULL."); + ); + } + } /* if (xm->pmap) */ + } /* if (xm) */ + } /* for */ + DBG(DBG_PARSING, + DBG_log("by_subject: Finished lookups"); + ); + + if (osk) DBG(DBG_PARSING, + DBG_log("by_subject: Returning %d certs in list", sk_X509_num(osk))); + return osk; +} + +#if 0 /* not currently used */ +static STACK_OF(X509) * +lookup_certs_by_issuer(STACK_OF(XMAP) *lu, X509_NAME *xn) +{ + STACK_OF(X509) *osk = sk_X509_new_null(); + int i, j, k, found; + + DBG(DBG_PARSING, + DBG_log("Looking up certificate by issuer"); + ); + for(i=0; idata.x509); + + for(k=0, found = 0; (!found) && (k 0) break; + } else + /* insert here is xx start date is later than tx */ + if (c1 > 0) break; + /* else move on to the next certificate + * in the current output stack */ + } + /* Insert into the output stack */ + sk_X509_insert(osk, xx, k); + } + } else + X509_free(xx); + } + sk_X509_OBJECT_pop_free(xo, X509_OBJECT_free); + } /* if (xo != NULL) */ + else + { + DBG(DBG_PARSING, + DBG_log("xo = XMAP_lookup( xm, X509_LU_X509, + \"issuer\", xn) == NULL."); + ); + } + } /* if (xm) */ + } /* for */ + DBG(DBG_PARSING, + DBG_log("by_issuer: Finished lookups"); + ); + + if (osk) DBG(DBG_PARSING, + DBG_log("by_issuer: Returning %d certs in list", sk_X509_num(osk))); + return osk; +} +#endif /* not used */ + +void +build_cert_chain( STACK_OF(X509) **ch, STACK_OF(XMAP) *lu, X509 *x ) +{ + int done = 0; + X509 *xx; + + if (!ch) return; + if ((*ch = sk_X509_new_null()) == NULL) return; + xx = x; + + sk_X509_push(*ch, X509_dup(xx)); + while (!done) { + X509 *xi; + + /* look for self-signed cert. It would have issuer data + * same as subject field */ + if ((xi = sk_X509_value(lookup_certs_by_subject(lu, + X509_get_issuer_name(xx)), 0)) != NULL) + { + sk_X509_push(*ch, xi); + if (X509_NAME_cmp(X509_get_subject_name(xi), + X509_get_issuer_name(xi)) == 0) { + DBG(DBG_PARSING, + DBG_log("Found the issuer's self-signed cert."); + ); + done = 1; + } else { + /* the 2 fields are not exactly the same. Narrowing search. */ + xx = xi; + } + } else + /* Did not find self-signed certificate */ + DBG(DBG_PARSING, + DBG_log("Did not find the issuer's self-signed cert."); + ); + done = 1; + } +} + +bool +verify_certificate( X509 *x, STACK_OF(XMAP) *lu, + const char *path, bool strict ) +{ + X509_STORE *ctx = NULL; + X509_STORE_CTX csc; + int ver; + + + if ((ctx = X509_STORE_new()) == NULL) { + DBG(DBG_PARSING, + DBG_log("Cant allocate file lookup"); + ); + log_err(); + return 0; + } + + X509_STORE_set_verify_cb_func(ctx, cb); + + ERR_clear_error(); + verify_strict = strict; + lookups = lu; + X509_STORE_CTX_init(&csc, ctx, x, NULL); + + build_cert_chain(&(csc.chain), lu, x); + ver = verify_func(&csc); + X509_STORE_CTX_cleanup(&csc); + + if (ctx) X509_STORE_free(ctx); + + if (ver) { + DBG(DBG_PARSING, + DBG_log("Certificate verification succeeded"); + ); + } else { + DBG(DBG_PARSING, + DBG_log("Verification failed"); + ); + log_err(); + } + + return ver; +} + +struct cert_options { + const char *opt; + u_int32_t optflag; +}; + +static struct cert_options certopts[] = { + { "send", CERT_OPTION_SEND }, + { "pkcs7", CERT_OPTION_PKCS7 }, + { "pk", CERT_OPTION_PK }, + { "rev", CERT_OPTION_REV }, + { "strict", CERT_OPTION_STRICT }, + { "dss-sha", CERT_OPTION_DSS_SHA }, + { "dss-alt", CERT_OPTION_DSS_ALT }, + { NULL, 0 } +}; + +u_int32_t +parse_options( const char *s ) +{ + tok_list tl, p; + u_int32_t i, ret = 0, b4; + + tl = tokenize(s, ','); + for(p=tl; p; p=p->next) { + int found = 0; + char *st = p->s; + + while (isspace(*st)) st++; /* skip whitespace */ + for(i=0; (!found) && (certopts[i].opt != NULL); i++) { + if ((st[0] == '!') && + (strncasecmp(&(st[1]), certopts[i].opt, + strlen(certopts[i].opt)) == 0)) { + found = 1; + b4 = ret; + ret &= ~certopts[i].optflag; + + DBG(DBG_PARSING, + DBG_log("Cert option: Clearing option %s: %08x -> %08x", + certopts[i].opt, b4, ret); + ); + } else if (strncasecmp(st, certopts[i].opt, + strlen(certopts[i].opt)) == 0) { + found = 1; + b4 = ret; + ret |= certopts[i].optflag; + + DBG(DBG_PARSING, + DBG_log("Cert option: Setting option %s: %08x -> %08x", + certopts[i].opt, b4, ret); + ); + } + } + } + tok_free(tl); + + /* now for a few special cases: + * if "rev", then turn on "pk". + * if "pkcs7", then turn on "send". + */ + if (((ret & CERT_OPTION_REV) != 0) && ((ret & CERT_OPTION_PK) == 0)) + ret |= CERT_OPTION_PK; + if (((ret & CERT_OPTION_PKCS7) != 0) && ((ret & CERT_OPTION_SEND) == 0)) + ret |= CERT_OPTION_SEND; + + return ret; +} + +int +DSA_sign_raw(unsigned char *dgst,int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa) +{ + DSA_SIG *s; + int offset; + + DBG(DBG_PARSING, + DBG_log("DSA_sign_raw called"); + ); + s= DSA_do_sign(dgst, dlen, dsa); + if (s == NULL) { + *siglen=0; + return 0; + } + memset(sig, 0, SHA1_DIGEST_SIZE * 2); + offset = SHA1_DIGEST_SIZE - BN_num_bytes(s->r); + BN_bn2bin(s->r, &(sig[offset])); + offset = SHA1_DIGEST_SIZE - BN_num_bytes(s->s); + BN_bn2bin(s->s, &(sig[SHA1_DIGEST_SIZE + offset])); + *siglen = SHA1_DIGEST_SIZE * 2; + DSA_SIG_free(s); + return 1; +} + +int DSA_verify_raw(const unsigned char *dgst,int dgst_len, + unsigned char *sigbuf, int siglen, DSA *dsa) +{ + DSA_SIG *s; + int ret = -1; + + DBG(DBG_PARSING, + DBG_log("DSA_verify_raw called"); + ); + if (siglen != (2 * SHA1_DIGEST_SIZE)) return ret; + s = DSA_SIG_new(); + if (s == NULL) return ret; + s->r = BN_bin2bn(sigbuf, SHA1_DIGEST_SIZE, + s->r); + s->s = BN_bin2bn(&(sigbuf[SHA1_DIGEST_SIZE]), + SHA1_DIGEST_SIZE, + s->s); + ret=DSA_do_verify(dgst, dgst_len,s,dsa); + DSA_SIG_free(s); + return ret; +} + +/* + * The following code implements ElGamal encryption using DSA keys + * in a (hopefully) OpenSSL compatible fashion. It really belongs in + * OpenSSL itself, when the code approaches being both tested and + * more efficient. In order to make things a bit faster, the modular + * operations use montogomery representation. + * + * NB - this implementation is pretty naive, and contains just the + * simplest implementation of ElGamal as per HAC, Ch8, Section 8.4, + * pp 294-295. + */ + +static ERR_STRING_DATA ElGamal_str_functs[] = +{ + {ERR_PACK(0,ELGAMAL_F_ELGAMAL_PUBLIC_ENCRYPT,0), "ElGamal_public_encrypt"}, + {ERR_PACK(0,ELGAMAL_F_ELGAMAL_PRIVATE_DECRYPT,0), "ElGamal_private_decrypt"}, + { 0, NULL } +}; + +static ERR_STRING_DATA ElGamal_str_reasons[] = +{ + { ELGAMAL_R_UNKNOWN_PADDING_TYPE, "unknown padding type" }, + { ELGAMAL_R_DATA_GREATER_THAN_MOD_LEN, "data longer than modulus length" }, + { ELGAMAL_R_PADDING_CHECK_FAILED, "padding check failed" }, + { 0, NULL } +}; + +void +ERR_load_ElGamal_strings( void ) +{ + static int init = 1; + + if (init) + { + init = 0; + + ERR_load_strings(ERR_LIB_ELGAMAL, ElGamal_str_functs); + ERR_load_strings(ERR_LIB_ELGAMAL, ElGamal_str_reasons); + } +} + +int +ElGamal_public_check( DSA *dsa ) +{ + BIGNUM res; + BN_MONT_CTX *mont; + BN_CTX *ctx; + int r = 0; + + /* Check that g^q = 1 (mod p), and that y^q = 1 (mod p) */ + /* to avoid attacks involving generators which produce small */ + /* subgroups */ + + BN_init(&res); + if ((ctx = BN_CTX_new()) == NULL) goto err; + if ((mont = BN_MONT_CTX_new()) == NULL) goto err; + if (! BN_MONT_CTX_set(mont, dsa->p, ctx)) goto err; + + if (! BN_mod_exp_mont(&res, dsa->g, dsa->q, dsa->p, ctx, mont)) goto err; + if (! BN_is_one(&res)) goto err; + if (! BN_mod_exp_mont(&res, dsa->pub_key, dsa->q, dsa->p, ctx, mont)) goto err; + if (! BN_is_one(&res)) goto err; + r = 1; /* Key is OK */ + + err: + BN_clear_free(&res); + if (ctx) BN_CTX_free(ctx); + if (mont) BN_MONT_CTX_free(mont); + + return r; +} + +int +ElGamal_public_encrypt( int flen, unsigned char *from, + unsigned char *to, + DSA *dsa, int padding ) + +{ + unsigned char *buf, *p; + int num = 0, i, j, k, r = -1; + BIGNUM kappa, alpha, beta, f; + BIGNUM BETA, F; + BN_MONT_CTX *pmont; + BN_CTX *ctx = NULL; + + num = BN_num_bytes(dsa->p) ; + BN_init(&alpha); + BN_init(&beta); + BN_init(&kappa); + BN_init(&f); + BN_init(&BETA); + BN_init(&F); + + if ((ctx = BN_CTX_new()) == NULL) goto err; + if ((pmont = BN_MONT_CTX_new()) == NULL) goto err; + if (! BN_MONT_CTX_set(pmont, dsa->p, ctx)) goto err; + if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL) { + ElGamalerr(ELGAMAL_F_ELGAMAL_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* generate k s.t. 1 <= k <= q-1 */ + do { + if (! BN_rand(&kappa, BN_num_bits(dsa->q), 1, 1)) goto err; + } while (BN_cmp(&kappa, dsa->q) < 0); + + switch (padding) { + case ELGAMAL_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); + break; + case ELGAMAL_PKCS1_OAEP_PADDING: + i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); + break; + case ELGAMAL_NO_PADDING: + i = RSA_padding_add_none(buf, num, from, flen); + break; + default: + ElGamalerr( ELGAMAL_F_ELGAMAL_PUBLIC_ENCRYPT, + ELGAMAL_R_UNKNOWN_PADDING_TYPE ); + goto err; + } + + if (i <= 0) goto err; + + if (BN_bin2bn(buf, num, &f) == NULL) goto err; + + /* Set alpha = g^k (mod p) */ + if (!BN_mod_exp_mont(&alpha, dsa->g, &kappa, dsa->p, ctx, pmont)) goto err; + + /* Set beta = M * y^k (mod p) */ + if (!BN_mod_exp_mont(&beta, dsa->pub_key, &kappa, dsa->p, ctx, + pmont)) goto err; + + BN_to_montgomery(&F, &f, pmont, ctx); + BN_to_montgomery(&BETA, &beta, pmont, ctx); + if (!BN_mod_mul_montgomery(&BETA, &BETA, &F, pmont, ctx)) goto err; + BN_from_montgomery(&beta, &BETA, pmont, ctx); + + /* Squirt out alpha, left padded to modulus size with zero bytes */ + j = BN_num_bytes(&alpha); + i = BN_bn2bin(&alpha, &(to[num-j])); + for(k=0; k<(num-i); k++) to[k]=0; + + /* Follow this with beta */ + p = &(to[num]); + j = BN_num_bytes(&beta); + i = BN_bn2bin(&beta, &(p[num-j])); + for(k=0; k<(num-i); k++) p[k]=0; + + r = num*2; + + err: + if (ctx != NULL) BN_CTX_free(ctx); + if (pmont != NULL) BN_MONT_CTX_free(pmont); + BN_clear_free(&alpha); + BN_clear_free(&beta); + BN_clear_free(&beta); + BN_clear_free(&kappa); + BN_clear_free(&f); + BN_clear_free(&BETA); + BN_clear_free(&F); + if (buf != NULL) { + memset(buf, 0, num); + OPENSSL_free(buf); + } + return r; +} + +int ElGamal_private_decrypt( int flen, unsigned char *from, + unsigned char *to, + DSA *dsa, int padding ) +{ + + BIGNUM alpha, beta, gamma, delta, p1a; + BIGNUM BETA, GAMMA, DELTA; + BN_CTX *ctx; + BN_MONT_CTX *pmont; + unsigned char *p, *buf = NULL; + int j, r = -1, num; + + BN_init(&alpha); + BN_init(&beta); + BN_init(&gamma); + BN_init(&delta); + BN_init(&p1a); + BN_init(&BETA); + BN_init(&GAMMA); + BN_init(&DELTA); + if ((ctx = BN_CTX_new()) == NULL) goto err; + if ((pmont = BN_MONT_CTX_new()) == NULL) goto err; + if (! BN_MONT_CTX_set(pmont, dsa->p, ctx)) goto err; + + num = BN_num_bytes(dsa->p); + + /* set p1a to be equal to p-1-x, where x is the private key */ + if (BN_copy(&p1a, dsa->p) == NULL) goto err; + if (! BN_sub_word(&p1a, 1)) goto err; + if (! BN_sub(&p1a, &p1a, dsa->priv_key)) goto err; + + if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL) { + ElGamalerr(ELGAMAL_F_ELGAMAL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (flen > num*2) { + ElGamalerr(ELGAMAL_F_ELGAMAL_PRIVATE_DECRYPT, ELGAMAL_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + /* Copy the cipher text into the two numbers alpha and beta */ + if (BN_bin2bn(from, flen / 2, &alpha) == NULL) goto err; + if (BN_bin2bn(&(from[flen/2]), flen / 2, &beta) == NULL) goto err; + + if (! BN_mod_exp_mont(&gamma, &alpha, &p1a, dsa->p, ctx, pmont)) goto err; + BN_to_montgomery(&GAMMA, &gamma, pmont, ctx); + BN_to_montgomery(&BETA, &beta, pmont, ctx); + if (! BN_mod_mul_montgomery(&DELTA, &GAMMA, &BETA, pmont, ctx)) goto err; + BN_from_montgomery(&delta, &DELTA, pmont, ctx); + + /* Now delta should contain the (possibly padded) plaintext */ + p = buf; + j = BN_bn2bin(&delta, p); + + switch( padding ) { + case ELGAMAL_PKCS1_PADDING: + r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); + break; + case ELGAMAL_PKCS1_OAEP_PADDING: + r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); + break; + case ELGAMAL_NO_PADDING: + r = RSA_padding_check_none(to, num, buf, j, num); + break; + default: + ElGamalerr(ELGAMAL_F_ELGAMAL_PRIVATE_DECRYPT, + ELGAMAL_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (r < 0) + ElGamalerr(ELGAMAL_F_ELGAMAL_PRIVATE_DECRYPT, + ELGAMAL_R_PADDING_CHECK_FAILED); + + err: + if (ctx != NULL) BN_CTX_free(ctx); + if (pmont != NULL) BN_MONT_CTX_free(pmont); + BN_clear_free(&alpha); + BN_clear_free(&beta); + BN_clear_free(&gamma); + BN_clear_free(&delta); + BN_clear_free(&p1a); + BN_clear_free(&BETA); + BN_clear_free(&GAMMA); + BN_clear_free(&DELTA); + if (buf != NULL) { + memset(buf, 0, num); + OPENSSL_free(buf); + } + return r; +} +bool +valid_ciphertext_length( const u_int32_t len, struct connection *c ) +{ + EVP_PKEY *pk = c->key; + bool ret = FALSE; + + if ((!pk) || (len == 0)) return FALSE; + switch(pk->type) { + case EVP_PKEY_RSA: + if (len % BN_num_bytes(pk->pkey.rsa->n) == 0) ret = TRUE; + break; + case EVP_PKEY_DSA: + if (len % (2 * BN_num_bytes(pk->pkey.dsa->p)) == 0) ret = TRUE; + break; + default: + return FALSE; + } + + return ret; +} + +static void +alloc_ciphertext( const u_int32_t len, + EVP_PKEY *pk, + u_char **c, + u_int32_t *ms, + u_int32_t *bsize, + u_int32_t *bl ) +{ + int modsize, chunksize, blocks; + u_int32_t clen; + + switch(pk->type) + { + case EVP_PKEY_RSA: + { + RSA *rsa = pk->pkey.rsa; + modsize = BN_num_bytes(rsa->n); + } + break; + case EVP_PKEY_DSA: + { + DSA *dsa = pk->pkey.dsa; + modsize = BN_num_bytes(dsa->p) * 2; + } + break; + } + chunksize = modsize - 2 * SHA1_DIGEST_SIZE - 1; + blocks = (len + chunksize - 1) / chunksize; + clen = blocks * modsize; + *c = malloc(clen); + memset(*c, 0, clen); + *bsize = chunksize - 1; + *bl = blocks; + *ms = modsize; +} + +bool +pubkey_encrypt_chunk( chunk_t *ch, struct state *st ) +{ + struct connection *c = st->st_connection; + u_char *str = ch->ptr; + u_int32_t len = ch->len; + EVP_PKEY *pk = NULL; + u_char *ciph; + u_int32_t ms, bs, bl; + u_int16_t auth = st->st_oakley.auth; + int i; + long clen = 0; + + switch(auth) { + case OAKLEY_RSA_ENC: + case OAKLEY_RSA_ENC_REV: + for(i=0; iother[i].type == EVP_PKEY_RSA) && + (c->other[i].cert != NULL)) { + pk = X509_get_pubkey((X509 *)c->other[i].cert); + break; + } + } + break; + case OAKLEY_ELGAMAL_ENC: + case OAKLEY_ELGAMAL_ENC_REV: + for(i=0; iother[i].type == EVP_PKEY_DSA) && + (c->other[i].cert != NULL)) { + pk = X509_get_pubkey((X509 *)c->other[i].cert); + break; + } + } + break; + default: + log("Non PK authentication scheme in state"); + return FALSE; + } + + if (!pk) { + log("Unable to select an encryption key"); + return FALSE; + } + + switch(pk->type) { + case EVP_PKEY_RSA: + { + alloc_ciphertext(len, pk, &ciph, &ms, &bs, &bl); + } + break; + case EVP_PKEY_DSA: + { + alloc_ciphertext(len, pk, &ciph, &ms, &bs, &bl); + } + break; + default: + log("Unknown key type: %d", pk->type); + break; + } + + for(i=0; ((i=0)); i++) { + u_char *pst = &str[i * bs]; + u_char *cst = &ciph[i * ms]; + u_int32_t plen = (i < bl-1) ? bs : len % bs; + + switch(pk->type) { + case EVP_PKEY_RSA: + { + RSA *rsa = pk->pkey.rsa; + + clen = RSA_public_encrypt(plen, pst, cst, rsa, RSA_PKCS1_OAEP_PADDING); + } + break; + case EVP_PKEY_DSA: + { + DSA *dsa = pk->pkey.dsa; + + clen = ElGamal_public_encrypt(plen, pst, cst, dsa, ELGAMAL_PKCS1_OAEP_PADDING); + } + break; + default: + log("Unknown cert type: %d", pk->type); + return FALSE; + break; + } + } + + memset(ch->ptr, 0, ch->len); + if (clen < 0) { + log("Failed to encrypt payload with certificate's public key."); + return FALSE; + } else { + freeanychunk(*ch); + ch->len=bl*ms; + ch->ptr=ciph; + return TRUE; + } +} + +bool +privkey_decrypt_chunk( chunk_t *ch, struct state *st ) +{ + u_int32_t i, bl, bs, clen; + struct connection *c = st->st_connection; + EVP_PKEY *pk = c->key; + u_char *str = ch->ptr; + u_char *pst; + u_int32_t ptr, plen; + + switch(pk->type) { + case EVP_PKEY_RSA: + { + RSA *rsa = pk->pkey.rsa; + bs = BN_num_bytes(rsa->n); + } + break; + case EVP_PKEY_DSA: + { + DSA *dsa = pk->pkey.dsa; + bs = 2 * BN_num_bytes(dsa->p); + } + break; + default: + log("Unknown key type: %d", pk->type); + break; + } + + clen = ch->len; + bl = clen / bs; + + pst = malloc(clen); + ptr = 0; + plen = 0; + + for(i=0; ((i= 0)); i++) { + switch(pk->type) { + case EVP_PKEY_RSA: + { + RSA *rsa = pk->pkey.rsa; + + if (clen >= bs) { +/* + * int RSA_private_decrypt(int flen, unsigned char *from, + * unsigned char *to, RSA *rsa,int padding); + * + * This function implements RSA private decryption, the rsa variable + * should be a private key. 'from_len' bytes are taken + * from 'from' and decrypted. The decrypted data is + * put into 'to'. The number of bytes encrypted is returned. -1 is + * returned to indicate an error. The operation performed is + * to = from^rsa->d mod rsa->n. + */ + + plen = RSA_private_decrypt( bs, &(str[i * bs]), &(pst[ptr]), rsa, + RSA_PKCS1_OAEP_PADDING ); + if (plen == -1) { + log_err(); + } + } else /* Ciphertext is too short */ + plen = 0; + } + break; + case EVP_PKEY_DSA: + { + DSA *dsa = pk->pkey.dsa; + + if (clen >= bs) { + plen = ElGamal_private_decrypt( bs, &str[i * bs], &pst[ptr], + dsa, ELGAMAL_PKCS1_OAEP_PADDING ); + if (plen == -1 ) { + log_err(); + } + } else /* Short ciphertext - don't try and decrypt */ + plen = 0; + } + break; + default: + log("Unknown key type: %d", pk->type); + plen = 0; + break; + } + ptr += plen; + } + + if (plen != -1) { + freeanychunk(*ch); + ch->ptr = pst; + ch->len = ptr; + return TRUE; + } else { + pfree(pst); + return FALSE; + } +} + +bool +use_openssl( struct connection *c ) +{ + /* Using data from connection *c, we can determine if we are + * currently using the openssl-related functions or not. + * ie: + * c->cert + * c->key + * c->cert_options + * + * also use c->policy to determine policy. + * + * Return 0 if openssl, otherwise 1. + */ + + if (c->policy & POLICY_OPENSSL) { + if ((c->cert != NULL) || + (c->key != NULL) || + (c->cert_options != 0)) + { + // OPENSSL + return 1; + } + else + { + // RSASIG only + return 0; + } + } + else + { + // PSK + return 0; + } +} + +bool +check_idtype_and_path( struct connection *c, const char *spec ) +{ + + return TRUE; +} + +const struct RSA_public_key * +fs_RSA ( EVP_PKEY *evp_pkey ) { + struct RSA_public_key *fs_rsa; + + /* + * MP_INT: + * int _mp_alloc; + * int _mp_size; + * mp_limb_t *_mp_d; + */ + + /* BIGNUM + * BN_ULONG *d; + * int top; + * int max; + * int neg; + * int flags; + */ + +/* So: + mp_limb_t *_mp_d = BN_ULONG *d + int _mp_alloc = int max + int _mp_size = int top +*/ + +/* fs_rsa->n = (MP_INT)(evp_pkey->pkey.rsa->n); */ + { + BIGNUM *temp_bignum; + MP_INT *temp_mp_int; + + temp_bignum = evp_pkey->pkey.rsa->n; + temp_mp_int->_mp_d = (mp_limb_t *)&(temp_bignum->d); +#if OPENSSL_VERSION_NUMBER < 0x00906000L + temp_mp_int->_mp_alloc = temp_bignum->max; +#else + temp_mp_int->_mp_alloc = temp_bignum->dmax; +#endif + temp_mp_int->_mp_size = temp_bignum->top; + fs_rsa->n = *(temp_mp_int); + } + + { +/* fs_rsa->e = (MP_INT)(evp_pkey->pkey.rsa->e); */ + BIGNUM *temp_bignum; + MP_INT *temp_mp_int; + + temp_bignum = evp_pkey->pkey.rsa->e; + temp_mp_int->_mp_d = (mp_limb_t *)&(temp_bignum->d); +#if OPENSSL_VERSION_NUMBER < 0x00906000L + temp_mp_int->_mp_alloc = temp_bignum->max; +#else + temp_mp_int->_mp_alloc = temp_bignum->dmax; +#endif + temp_mp_int->_mp_size = temp_bignum->top; + fs_rsa->e = *(temp_mp_int); + } + + fs_rsa->k = mpz_sizeinbase(&fs_rsa->n, 2); /* size in bits, for a start */ + fs_rsa->k = (fs_rsa->k + BITS_PER_BYTE - 1) / BITS_PER_BYTE; /* now octets */ + + return fs_rsa; +} + +STACK_OF(X509) * +extract_STACK_OF_X509_from_PKCS7 (PKCS7 *p7) +{ + STACK_OF(X509) *certs=NULL; + int i=OBJ_obj2nid(p7->type); + + switch (i) + { + case NID_pkcs7_signed: + certs=p7->d.sign->cert; + break; + case NID_pkcs7_signedAndEnveloped: + certs=p7->d.signed_and_enveloped->cert; + break; + default: + break; + } + + return certs; +} + +STACK_OF(X509_CRL) * +extract_STACK_OF_X509_CRL_from_PKCS7 (PKCS7 *p7) +{ + STACK_OF(X509_CRL) *crls=NULL; + int i=OBJ_obj2nid(p7->type); + + switch (i) + { + case NID_pkcs7_signed: + crls=p7->d.sign->crl; + break; + case NID_pkcs7_signedAndEnveloped: + crls=p7->d.signed_and_enveloped->crl; + break; + default: + break; + } + + return crls; +} + +extern +bool load_pkcs(struct connection **c) +{ + /* We now have to check to see if there are any keycert + * or/and pubcert to extract from PKCS data. + */ + struct connection *d = *c; + const chunk_t *pkcs_passphrase = NULL; + bool result = TRUE; + + /* exit if we have nothing to do with OPENSSL with this connection */ + if (!use_openssl(d)) { + loglog(RC_LOG_SERIOUS, "load_pkcs: why am I here? This connection " + "does not use certificates."); + return TRUE; + } + + if ((are_secrets_loaded()) && (d->certkeytype != PRIVCERT_NONE)) { + switch (d->certkeytype) { + + case PRIVCERT_X509: + result = TRUE; + break; + + case PRIVCERT_PKCS8: + case PRIVCERT_PKCS8_ENC: + pkcs_passphrase = get_PKCS8_secret(d); + if (pkcs_passphrase != NULL) { + d->key = get_PrivKey_from_PKCS8(*pkcs_passphrase, d->certkeyfile); + if (d->key == NULL) { + loglog(RC_LOG_SERIOUS, "Could not decrypt PKCS8 data"); + d->certkeytype = PRIVCERT_NONE; + result = FALSE; + } else { + DBG(DBG_CRYPT, + DBG_log("Decrypted PKCS8 data"); + ); + d->certkeytype = PRIVCERT_X509; + } + } + else + { + loglog(RC_LOG_SERIOUS, "No passphrase to decrypt PKCS8 data."); + result = FALSE; + } + break; + + case PRIVCERT_PKCS12: + pkcs_passphrase = get_PKCS8_secret(d); + if (pkcs_passphrase != NULL) { + d->key = get_data_from_PKCS12(&d, *pkcs_passphrase, d->certkeyfile, + TRUE); + if (d->key == NULL) { + loglog(RC_LOG_SERIOUS, "Could not decrypt private key" + " from PKCS12 data"); + d->certkeytype = PRIVCERT_NONE; + result = FALSE; + } else { + DBG(DBG_CRYPT, + DBG_log("Decrypted PKCS12 privkey data"); + ); + d->certkeytype = PRIVCERT_X509; + } + } + else + { + loglog(RC_LOG_SERIOUS, "No passphrase to decrypt PKCS12 data."); + result = FALSE; + } + break; + + default: + loglog(RC_LOG_SERIOUS, + "Cannot decrypt key for \"%s\": unsupported PKCS format", + d->name); + result = FALSE; + break; + } + } + else if ((!are_secrets_loaded()) && (d->certkeytype != PRIVCERT_NONE)) { + DBG(DBG_CRYPT, + DBG_log("Cannot decrypt key for \"%s\":" + " secrets not loaded (no passphrase)", d->name); + ); + result = FALSE; + } else if (d->certkeytype != PRIVCERT_NONE) { + /* d->certkeytype = PRIVCERT_NONE, so no conversion needed */ + DBG(DBG_CRYPT, + DBG_log("\"%s\": d->certkeytype = PRIVCERT_NONE", d->name); + ); + result = FALSE; + } + + + /* now for public_keys */ + if ((are_secrets_loaded()) && (d->certtype != PRIVCERT_NONE)) { + switch (d->certtype) { + case PUBCERT_X509: + result = TRUE; + break; + + case PUBCERT_PKCS12: + pkcs_passphrase = get_PKCS8_secret(d); + if (pkcs_passphrase != NULL) { + d->cert = get_data_from_PKCS12(&d, *pkcs_passphrase, d->certfile, + FALSE); + if (d->cert == NULL) { + loglog(RC_LOG_SERIOUS, "Could not decrypt public data from PKCS12"); + d->certtype = PUBCERT_NONE; + result = FALSE; + } else { + DBG(DBG_CRYPT, + DBG_log("Decrypted PKCS12 pubkey data"); + ); + d->certtype = PUBCERT_X509; + } + } + else + { + loglog(RC_LOG_SERIOUS, "No passphrase to decrypt PKCS12 data."); + result = FALSE; + } + break; + + default: + DBG(DBG_CRYPT, + DBG_log("Cannot decrypt publickey for \"%s\": unsupported PKCS format", + d->name); + ); + result = FALSE; + break; + } + } + else if ((!are_secrets_loaded()) && (d->certtype != PUBCERT_NONE)) { + DBG(DBG_CRYPT, + DBG_log("Cannot decrypt public key for \"%s\":" + " secrets not loaded (no passphrase)", + d->name); + ); + result = FALSE; + } else if (d->certtype != PRIVCERT_NONE) { + /* d->certtype = PUBCERT_NONE, so no conversion needed */ + DBG(DBG_CRYPT, + DBG_log("\"%s\": d->certtype = PUBCERT_NONE", d->name); + ); + result = FALSE; + } + + return result; +} + + +/* the following function is based on OpenSSL's pkcs8 code. */ +void * +get_PrivKey_from_PKCS8( const chunk_t p8pass, char *keyfile ) { + + X509_SIG *p8; + BIO *b = NULL; + PKCS8_PRIV_KEY_INFO *p8inf; + EVP_PKEY *pkey; + + if (p8pass.ptr == NULL) { + return NULL; + } + + /* We open the file. */ + if ((b = BIO_new_file(keyfile, "r")) == NULL) { + log_err(); + return NULL; + } + + /* try unencrypted format */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(b, NULL, NULL, NULL); + if (!p8inf) { + /* Try reading PKCS8 in DER format */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(b, NULL); + } + + /* now we try encrypted */ + if (!p8inf) { + /* We read the file. This should take care of both PEM and DER formats */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); +#if OPENSSL_VERSION_NUMBER > 0x00903000L + p8 = PEM_read_bio_PKCS8(b, NULL, NULL, NULL); +#else + p8 = PEM_read_bio_PKCS8(b, NULL, NULL); +#endif + if (!p8) { + /* Try DER read */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + p8 = d2i_PKCS8_bio(b, NULL); + if (!p8) { + log_err(); + BIO_free(b); + } + } + + /* We handle the p8pass, and decrypt p8 */ + p8inf = M_PKCS8_decrypt(p8, p8pass.ptr, p8pass.len); + } + + if (!p8inf) { + loglog(RC_LOG_SERIOUS, "Error decrypting keyfile \"%s\"", keyfile); + return NULL; + } + + pkey = extract_pkey_using_p8inf(p8inf); + + /* we clean up */ + X509_SIG_free(p8); + PKCS8_PRIV_KEY_INFO_free(p8inf); + + /* We close the file */ + if ((b = BIO_new_file(keyfile, "r")) == NULL) { + log_err(); + return NULL; + } + + log("Read key from %s", keyfile); + + BIO_free(b); + + return (void *)pkey; +} + + +/* the following function is based on OpenSSL's pkcs12 code. */ +/* NOTE: + * - 'privcert_type' controls whether we're looking for a public cert + * or a private certkey + * - based on 'privcert_type', build 'STACK_OF(X509)' or 'STACK_OF(EVP_PKEY)'. + * - process stack as needed and return wanted data. + */ +void * +get_data_from_PKCS12( struct connection **c, const chunk_t p8pass, + char *file, bool privcert_type ) { + + struct connection *d = *c; + BIO *b = NULL; + PKCS12 *p12 = NULL; + + STACK *asafes, *bags; + int i, j, bagnid; + PKCS7 *p7; + + /* we can expect multiple certs to process and match the + * required cert, but we can also expect a single EVP_PKEY + */ + STACK_OF(X509) *pub_stack = sk_X509_new_null(); + EVP_PKEY *pkey = NULL; + X509 *x509 = NULL; + + if (p8pass.ptr == NULL) { + loglog(RC_LOG_SERIOUS, "No passphrase passed to decrypt PKCS12 data."); + return NULL; + } + + /* We open the file. */ + if ((b = BIO_new_file(file, "r")) == NULL) { + loglog(RC_LOG_SERIOUS, "Unable to open PKCS12 file."); + return NULL; + } + + /* only found DER support for PKCS12 */ + /* read in p12 */ + if (!(p12 = d2i_PKCS12_bio (b, NULL))) { + loglog(RC_LOG_SERIOUS, "Unable to read PKCS12 file."); + BIO_free(b); + return NULL; + } + + if (!( asafes = M_PKCS12_unpack_authsafes(p12))) + { + DBG(DBG_CRYPT, + DBG_log("Could not unpack PKCS12 authsafes from file"); + ); + return NULL; + } + + for (i = 0; i < sk_num(asafes); i++) + { + p7 = (PKCS7 *)sk_value (asafes, i); + bagnid = OBJ_obj2nid (p7->type); + + if (bagnid == NID_pkcs7_data) { + bags = M_PKCS12_unpack_p7data (p7); + } else if (bagnid == NID_pkcs7_encrypted) { + bags = M_PKCS12_unpack_p7encdata (p7, p8pass.ptr, p8pass.len); + } else continue; + + if (!bags) { + loglog(RC_LOG_SERIOUS, "PKCS12 file: No \"bags\" to process."); + return NULL; + } + + /* here's where we create the stacks */ + if (privcert_type) { + pkey = (EVP_PKEY *)extract_certs_pkeys_bags(bags, p8pass, privcert_type); + if (pkey == NULL) + { + sk_pop_free(bags, PKCS12_SAFEBAG_free); + } + } else { + STACK_OF(X509) *temp_pub_stack = extract_certs_pkeys_bags(bags, + p8pass, privcert_type); + + if (temp_pub_stack == NULL) + { + sk_pop_free(bags, PKCS12_SAFEBAG_free); + } + + /* merge temp_pub_stack into pub_stack */ + for (j = 0; j < sk_X509_num(temp_pub_stack); j++) + { + sk_X509_push(pub_stack, sk_X509_value(temp_pub_stack, j)); + } + sk_X509_free(temp_pub_stack); + } + } + + if (!privcert_type) { + + /* Here, we process pub_stack and find the needed cert */ + if ((x509 = X509_dup(find_pubcert_in_stack(&d, pub_stack))) == NULL) + { + d->certtype = PUBCERT_NONE; + } + else + { + d->certtype = PUBCERT_X509; + } + /* this stack was allocated only if privcert_type = FALSE */ + sk_X509_free(pub_stack); + } + + /* clean up */ + sk_pop_free(asafes, PKCS7_free); + PKCS12_free(p12); + BIO_free(b); + + if (privcert_type) { + return (void *)pkey; + } else { + return (void *)x509; + } +} + + +static void * +extract_certs_pkeys_bags(STACK *bags, chunk_t p8pass, bool privcert_type) +{ + EVP_PKEY *pkey = NULL; + STACK_OF(X509) *x509_stack = NULL; + int i; + + if (privcert_type) + { + for (i = 0; i < sk_num(bags); i++) + { + EVP_PKEY *temp_pkey = NULL; + + temp_pkey = (EVP_PKEY *)extract_certs_pkeys_bag( + (PKCS12_SAFEBAG *)sk_value(bags, i), p8pass, privcert_type); + if (pkey && temp_pkey) { + loglog(RC_LOG_SERIOUS, "More than 1 private key found in PKCS12 cert"); + EVP_PKEY_free(pkey); + EVP_PKEY_free(temp_pkey); + return NULL; + } + else if (!pkey && temp_pkey) { + pkey = temp_pkey; + } + } + return pkey; + } + else + { + if (!(x509_stack = sk_X509_new(NULL))) + { + loglog(RC_LOG_SERIOUS, + "load_pkcs: Error allocating memory to x509_stack"); + } + for (i = 0; i < sk_num (bags); i++) + { + X509 *temp_x509 = NULL; + + temp_x509 = (X509 *)extract_certs_pkeys_bag( + (PKCS12_SAFEBAG *)sk_value(bags, i), p8pass, privcert_type); + if (temp_x509) + { + DBG(DBG_CRYPT, + char buf[200]; + X509_NAME_oneline(X509_get_subject_name(temp_x509), + buf, sizeof(buf)); + DBG_log("Found in PKCS12: \"%s\"", buf); + ); + + sk_X509_push(x509_stack, X509_dup(temp_x509)); + } + } + return x509_stack; + } +} + + +static void * +extract_certs_pkeys_bag(PKCS12_SAFEBAG *bag, chunk_t p8pass, + bool privcert_type) +{ + EVP_PKEY *pkey = NULL; + PKCS8_PRIV_KEY_INFO *p8inf; + X509 *x509; + + + switch (M_PKCS12_bag_type(bag)) + { + case NID_keyBag: + DBG(DBG_CRYPT, + DBG_log("Processing PKCS12 bag: NID_keyBag"); + ); + if (privcert_type) { + p8inf = bag->value.keybag; + /* no need to free p8inf at the end of this */ + if ((pkey = extract_pkey_using_p8inf(p8inf)) == NULL) + { + DBG(DBG_CRYPT, + DBG_log("Unencrypted PKCS12 bag: Could not extract pkey using p8inf"); + ); + } + return (void *)pkey; + } + break; + + case NID_pkcs8ShroudedKeyBag: + DBG(DBG_CRYPT, + DBG_log("Processing PKCS12 bag: NID_pkcs8ShroudedKeyBag"); + ); + if (privcert_type) { + if (!(p8inf = M_PKCS12_decrypt_skey(bag, p8pass.ptr, p8pass.len))) + { + DBG(DBG_CRYPT, + DBG_log("Encrypted PKCS12 bag: Could not prepare p8inf"); + ); + return NULL; + } + if ((pkey = extract_pkey_using_p8inf(p8inf)) == NULL) + { + DBG(DBG_CRYPT, + DBG_log("Encrypted PKCS12 bag: Could not extract pkey using p8inf"); + ); + } + /* clean up */ + PKCS8_PRIV_KEY_INFO_free(p8inf); + return (void *)pkey; + } + break; + + case NID_certBag: + DBG(DBG_CRYPT, + DBG_log("Processing PKCS12 bag: NID_certBag"); + ); + if (!privcert_type) { + if (!(x509 = M_PKCS12_certbag2x509(bag))) + { + DBG(DBG_CRYPT, + DBG_log("PKCS12 certbag: could not extract x509 certificate"); + ); + return NULL; + } + return (void *)x509; + } + break; + + case NID_safeContentsBag: + DBG(DBG_CRYPT, + DBG_log("Processing PKCS12 bag: NID_safeContentsBag"); + ); + return extract_certs_pkeys_bags(bag->value.safes, + p8pass, privcert_type); + break; + + default: + { + const int TMP_BUF_LEN = 256; + char tmperr[TMP_BUF_LEN]; + + DBG(DBG_CRYPT, + i2t_ASN1_OBJECT (tmperr, TMP_BUF_LEN, bag->type); + DBG_log("Warning unsupported PKCS12 bag type: %s", tmperr); + ); + } + break; + } + + return NULL; +} + + +static EVP_PKEY * +extract_pkey_using_p8inf(PKCS8_PRIV_KEY_INFO *p8inf) +{ + EVP_PKEY *pkey = NULL; + + if (!(pkey = EVP_PKCS82PKEY(p8inf))) { + loglog(RC_LOG_SERIOUS, "Error converting PKCS8 data"); + return NULL; + } + + if (p8inf->broken) { + switch (p8inf->broken) { + case PKCS8_NO_OCTET: + loglog(RC_LOG_SERIOUS, "Warning: broken key encoding: " + "No Octet String in PrivateKey"); + break; + + case PKCS8_EMBEDDED_PARAM: + loglog(RC_LOG_SERIOUS, "Warning: broken key encoding: " + "DSA parameters included in PrivateKey"); + break; + + case PKCS8_NS_DB: + loglog(RC_LOG_SERIOUS, "Warning: broken key encoding: " + "DSA public key include in PrivateKey"); + break; + + default: + loglog(RC_LOG_SERIOUS, "Warning: broken key encoding: " + "Unknown broken type"); + break; + } + } + return pkey; +} + + +static X509 * +find_pubcert_in_stack( struct connection **c, STACK_OF(X509) *x509_stack) { + struct connection *d = *c; + int i; + bool foundcert = FALSE; + X509 *x = NULL; + X509 *tempcert = NULL; + + for (i = 1; i <= sk_X509_num(x509_stack); i++) + { + tempcert = sk_X509_value(x509_stack,i-1); + + /* - Find cert based on ID_DER_DNs found in ipsec.conf file + * - If Cert found, continue looking anyways. + * - If more certs match, then we have a problem, and we should + * report the error. + * - if No certs match, then we have a problem and we should report + * the error. + * + * - the Cert's DN and one of the ID_DER_DNs __must__ match if it's PKCS7 + */ + if (tempcert) + { + if (d->this.id.kind == ID_DER_ASN1_DN) { + X509_NAME *thisxn = X509_NAME_new(); + chunk_t temp_ptr = d->this.id.der_asn1_dn; + + X509_NAME *thatxn = X509_NAME_new(); + chunk_t temp_ptr2 = d->that.id.der_asn1_dn; + + thisxn = d2i_X509_NAME(&thisxn, &(d->this.id.der_asn1_dn.ptr), + (long)d->this.id.der_asn1_dn.len); + d->this.id.der_asn1_dn = temp_ptr; + + thatxn = d2i_X509_NAME(&thatxn, &(d->that.id.der_asn1_dn.ptr), + (long)d->that.id.der_asn1_dn.len); + d->that.id.der_asn1_dn = temp_ptr2; + + if (!foundcert) + { + if ( (X509_NAME_cmp(X509_get_subject_name(tempcert), + thisxn) == 0) || + (X509_NAME_cmp(X509_get_subject_name(tempcert), + thatxn) == 0) ) + { + foundcert = TRUE; + x = X509_dup(tempcert); + } + if (foundcert) + { + DBG(DBG_CRYPT, + DBG_log("Matched cert found in file\'s chain"); + ); + } + } + else + { + if ( (X509_NAME_cmp(X509_get_subject_name(tempcert), + thisxn) == 0) || + (X509_NAME_cmp(X509_get_subject_name(tempcert), + thatxn) == 0) ) + { + DBG(DBG_CRYPT, + DBG_log("Error: Another matching Cert found in file's chain."); + ); + X509_free(x); + x = NULL; + } + } + X509_NAME_free(thisxn); + X509_NAME_free(thatxn); + } /* end if DER_ASN1_DN */ + } + } /* end for */ + + return x; +} + + +extern X509_NAME_ENTRY * +X509_NAME_ENTRY_create(char *parse) +{ + X509_NAME_ENTRY *ne = NULL; + char *delimpos = NULL, *item = NULL, *data = NULL; + int l, m; + + if ((delimpos = index(parse, '='))) { + /* l = length of beginning to '=' */ + l = delimpos - parse; + /* m = length from after = to end */ + m = strlen(parse) - (l+1); + + item = malloc(l); + memset(item, '\0', l); + item = memcpy(item, &(parse[1]), l-1); + + data = malloc(m+1); + memset(data, '\0', m+1); + data = memcpy(data, &(parse[l+1]), m); + + ne = X509_NAME_ENTRY_create_by_txt(&ne, item, MBSTRING_ASC, data, -1); + + free(item); + free(data); + } + return ne; +} + + +/* used to convert from text Subject name or AltSubjectName + * to ID_DER_ASN1_DN + */ +extern X509_NAME * +X509_NAME_build_from_text_DN(char *name) +{ + X509_NAME *x509_name = NULL; + X509_NAME_ENTRY *ne = NULL; + + char *curpos = NULL, *lastpos = NULL; + char *subparse = NULL; + char *parse = name; + int l,m; + + x509_name = X509_NAME_new(); + + /* todo: split off contents of text DN/Subject into identifier/data pairs */ + while ((curpos = index(parse, '/'))) + { + if (!lastpos) { + lastpos = curpos; + parse = &(curpos[1]); + } else { + m = curpos - lastpos; + + subparse = malloc(m+1); + memset(subparse, '\0', m+1); + subparse = memcpy(subparse, lastpos, m); + ne = X509_NAME_ENTRY_create(subparse); + X509_NAME_add_entry(x509_name, ne, -1, 0); + free(subparse); + + l = curpos - name; + if (l == strlen(name)) break; + + lastpos = curpos; + parse = &(curpos[1]); + } + } + curpos = index(parse, '\0'); + m = curpos - lastpos; + + subparse = malloc(m+1); + memset(subparse, '\0', m+1); + subparse = memcpy(subparse, lastpos, m); + ne = X509_NAME_ENTRY_create(subparse); + X509_NAME_add_entry(x509_name, ne, -1, 0); + free(subparse); + + return x509_name; +} + + +#endif /* OPENSSL */ diff -BbruN freeswan-1.91.orig/pluto/openssl.h freeswan-1.91/pluto/openssl.h --- freeswan-1.91.orig/pluto/openssl.h Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/openssl.h Thu Aug 16 13:14:08 2001 @@ -0,0 +1,138 @@ +#ifdef OPENSSL +#ifndef OPENSSL_INC_H +#define OPENSSL_INC_H + +#include +#include +#include +#include +#include +#include + +#include + +#include "xmap.h" + + +struct _x509_cert_node { + X509 *x; + struct _x509_cert_node *next; +}; + +typedef struct _x509_cert_node *X509_cert_list; + +typedef bool discrim_fn( X509 *x, STACK_OF(XMAP) *lu, + struct payload_digest *const id_pld, bool strict); + +extern bool make_lookups(STACK_OF(XMAP) **lu, const char *spec ); +extern bool check_idtype_and_path( struct connection *c, const char *spec ); + +extern void log_err( void ); +extern void load_cert( struct connection **c ); +extern void load_certkey( struct connection **c ); + +extern bool use_openssl( struct connection *c ); +extern STACK_OF(X509) * + peer_cert_list( STACK_OF(XMAP) *lu, + int type, + X509 *cert, struct payload_digest *const id_pld, + bool strict ); +extern STACK_OF(X509) *extract_STACK_OF_X509_from_PKCS7 (PKCS7 *p7); +extern STACK_OF(X509_CRL) *extract_STACK_OF_X509_CRL_from_PKCS7 (PKCS7 *p7); + +extern bool have_rsa_key( struct state *st ); +extern bool have_dss_key( struct state *st ); +extern bool have_rsa_keypair( struct state *st ); +extern bool have_elgamal_keypair( struct state *st ); + +extern bool verify_certificate( X509 *x, STACK_OF(XMAP) *lu, + const char *path, bool strict ); + +extern u_int32_t parse_options( const char *s ); + +extern int DSA_sign_raw(unsigned char *dgst,int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa); + +extern int DSA_verify_raw(const unsigned char *dgst,int dgst_len, + unsigned char *sigbuf, int siglen, DSA *dsa); + +#define ERR_LIB_ELGAMAL 127 + +#define ELGAMAL_F_ELGAMAL_PRIVATE_DECRYPT 100 +#define ELGAMAL_F_ELGAMAL_PUBLIC_ENCRYPT 101 + +#define ELGAMAL_R_UNKNOWN_PADDING_TYPE 100 +#define ELGAMAL_R_DATA_GREATER_THAN_MOD_LEN 101 +#define ELGAMAL_R_PADDING_CHECK_FAILED 102 + +#define ELGAMAL_PKCS1_PADDING RSA_PKCS1_PADDING +#define ELGAMAL_PKCS1_OAEP_PADDING RSA_PKCS1_OAEP_PADDING +#define ELGAMAL_NO_PADDING RSA_NO_PADDING + +#define ElGamalerr(f, r) ERR_PUT_error(ERR_LIB_ELGAMAL, (f), (r), ERR_file_name, __LINE__) + +void ERR_load_ElGamal_strings( void ); +int ElGamal_public_check( DSA *dsa ); +int ElGamal_public_encrypt( int flen, unsigned char *from, + unsigned char *to, + DSA *dsa, int padding ); +int ElGamal_private_decrypt( int flen, unsigned char *from, + unsigned char *to, + DSA *dsa, int padding ); + +/* Function pointer pointing to an encryption routine */ +typedef void encryptor_fn( chunk_t *ch, struct state *c ); + +extern bool valid_ciphertext_length( const u_int32_t len, + struct connection *c ); +extern bool privkey_decrypt_chunk ( chunk_t *ch, struct state *c ); +extern bool pubkey_encrypt_chunk ( chunk_t *ch, struct state *c ); + +/* get the other end's cert based */ +extern bool have_othercert( struct connection *c, int type ); + +/* Macro to duplicate Private key. Used in unshare_connection_strings */ +#define EVP_PKEY_dup(pkey) \ + (EVP_PKEY *)ASN1_dup((int (*)())i2d_PrivateKey, \ + (char *(*)())d2i_AutoPrivateKey,(char *)pkey) + +/* convert EVP_PKEY to freeswan's RSA_public_key */ +extern const struct RSA_public_key *fs_RSA ( EVP_PKEY *evp_pkey ); + +/* to lookup CRLs */ +extern X509_CRL *lookup_crl(STACK_OF(XMAP) *lu, X509_NAME *name); + +extern void *get_PrivKey_from_PKCS8( const chunk_t passphrase, char *keyfile); +extern void *get_data_from_PKCS12( struct connection **c, + const chunk_t passphrase, char *keyfile, bool privcert_type); +extern bool load_pkcs(struct connection **c); + + +/* types of public key certificates we may encounter */ +/* This is used with c->certtype */ +/* passphrase to decrypt to be found in /etc/ipsec.secrets */ +#define PUBCERT_NONE 0x00 +#define PUBCERT_X509 0x01 +#define PUBCERT_X509_ENC 0x02 +#define PUBCERT_PKCS7 0x04 +#define PUBCERT_PKCS7_ENC 0x08 +#define PUBCERT_PKCS12 0x10 + +/* types of private key certificates we may encounter */ +/* This is used with c->keycerttype */ +/* passphrase to decrypt to be found in /etc/ipsec.secrets */ +#define PRIVCERT_NONE 0x00 +#define PRIVCERT_X509 0x01 +#define PRIVCERT_X509_ENC 0x02 +#define PRIVCERT_PKCS8 0x04 +#define PRIVCERT_PKCS8_ENC 0x08 +#define PRIVCERT_PKCS12 0x10 + +extern X509_NAME_ENTRY *X509_NAME_ENTRY_create(char *parse); +extern X509_NAME *X509_NAME_build_from_text_DN(char *name); + + +#endif +#endif + + diff -BbruN freeswan-1.91.orig/pluto/openssl_defs.h freeswan-1.91/pluto/openssl_defs.h --- freeswan-1.91.orig/pluto/openssl_defs.h Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/openssl_defs.h Mon Jul 16 23:26:30 2001 @@ -0,0 +1,5 @@ + +#define FILE_NAME_LIMIT 80 +#define PATH_NAME_LIMIT 256 +#define CERT_OPTIONS_LIMIT 128 +#define MAX_OTHER 2 /* only know about two type of certificate at the moment (RSA,DSA) */ diff -BbruN freeswan-1.91.orig/pluto/preshared.c freeswan-1.91/pluto/preshared.c --- freeswan-1.91.orig/pluto/preshared.c Mon Apr 9 15:48:42 2001 +++ freeswan-1.91/pluto/preshared.c Sat Aug 18 11:16:39 2001 @@ -59,6 +59,14 @@ { "Coefficient", offsetof(struct RSA_private_key, qInv) }, }; +#ifdef OPENSSL +static bool secrets_loaded = FALSE; +static const struct fld pkcs8_field[] = +{ + { "passphrase", offsetof(struct PKCS8_key, passphrase) }, +}; +#endif + #ifdef DEBUG static void RSA_show_key_fields(struct RSA_private_key *k, int fieldcnt) @@ -187,6 +195,9 @@ union { chunk_t preshared_secret; struct RSA_private_key RSA_private_key; +#ifdef OPENSSL + struct PKCS8_key PKCS8_key; +#endif } u; struct secret *next; }; @@ -291,6 +302,15 @@ same = same_RSA_public_key(&s->u.RSA_private_key.pub , &best->u.RSA_private_key.pub); break; +#ifdef OPENSSL + case PPK_PKCS8: + same = s->u.PKCS8_key.passphrase.len == + best->u.PKCS8_key.passphrase.len + && memcmp(s->u.PKCS8_key.passphrase.ptr, + best->u.PKCS8_key.passphrase.ptr, + s->u.PKCS8_key.passphrase.len) == 0; + break; +#endif default: passert(FALSE); } @@ -333,6 +353,28 @@ return s == NULL? NULL : &s->u.preshared_secret; } +#ifdef OPENSSL +/* find the appropriate PKCS8 decryption data (see get_secret). + * Failure is indicated by a NULL pointer. + * Note: the result is not to be freed by the caller. + */ +const chunk_t * +get_PKCS8_secret(struct connection *c) +{ + const struct secret *s = get_secret(c, PPK_PKCS8, TRUE); + +#ifdef DEBUG + DBG(DBG_PRIVATE, + if (s == NULL) + DBG_log("no PKCS8 decryption data Found"); + else + DBG_dump_chunk("PKCS8 passphrase", s->u.PKCS8_key.passphrase); + ); +#endif + return s == NULL? NULL : &s->u.PKCS8_key.passphrase; +} +#endif + /* find the appropriate RSA private key (see get_secret). * Failure is indicated by a NULL pointer. */ @@ -659,6 +701,95 @@ } } } +#ifdef OPENSSL + else if (tokeqword("pkcs8")) + { + /* We want to flag this as information for PKCS8, for use later */ + /* loading of PKCS8 cert occurs in load_cert_and_key */ + s->kind = PPK_PKCS8; + if (!(shift() && tokeq("{"))) + { + ugh = "bad PKCS8 decryption data syntax"; + } + else + { + const struct fld *p; + + for (p = pkcs8_field; + ugh == NULL && p < &pkcs8_field[elemsof(pkcs8_field)]; + p++) + { + if (!shift()) + { + ugh = "premature end of PKCS8 decryption data syntax"; + } + else if (!tokeqword(p->name)) + { + ugh = builddiag( + "%s keyword not found where expected in PKCS8 decryption data", + p->name); + } + else if (!(shift() + && (!tokeq(":") || shift()))) /* ignore optional ":" */ + { + ugh = "premature end of PKCS8 decryption data"; + } + else if (*tok == '"' || *tok == '\'') + { + /* this clonetochunk would work well, + * but we need to null-terminate the string + * the length is normally "sfp->cur - tok - 2" + */ +#if 0 + clonetochunk(s->u.PKCS8_key.passphrase, tok+1, + sfp->cur - tok - 1, "PKCS8"); + s->u.PKCS8_key.passphrase.ptr[sfp->cur - tok] = '\0'; +#endif + + s->u.PKCS8_key.passphrase.len = sfp->cur - tok - 2; + s->u.PKCS8_key.passphrase.ptr = + malloc(s->u.PKCS8_key.passphrase.len+1); + memcpy(s->u.PKCS8_key.passphrase.ptr, tok+1, + s->u.PKCS8_key.passphrase.len); + s->u.PKCS8_key.passphrase.ptr[s->u.PKCS8_key.passphrase.len] + = '\0'; + } + else + { + size_t sz; + + ugh = atobytes(tok, sfp->cur - tok, buf, sizeof(buf), &sz); + if (ugh != NULL) + { + /* atobytes didn't like PKCS8 data */ + ugh = builddiag("PKCS8 decryption data malformed (%s): %s", ugh, tok); + } + else + { +#if 0 /* this may be broken at this time. Reverting to old methods */ + clonetochunk(s->u.PKCS8_key.passphrase, buf, sz+1, "PKCS8"); + s->u.PKCS8_key.passphrase.ptr[sz] = '\0'; +#endif + s->u.PKCS8_key.passphrase.len = sz+1; + s->u.PKCS8_key.passphrase.ptr = malloc(sz+1); + memcpy(s->u.PKCS8_key.passphrase.ptr, buf, + s->u.PKCS8_key.passphrase.len); + s->u.PKCS8_key.passphrase.ptr[sz] = '\0'; + } + } + } /* for */ + + if (ugh == NULL) + { + /* note: the following requires a boundary after "}" */ + if (!(shift() && tokeq("}") && !shift())) + { + ugh = "malformed end of PKCS8 decryption data"; + } + } + } + } +#endif else { ugh = builddiag("unrecognized key format: %s", tok); @@ -925,6 +1056,11 @@ mpz_clear(&s->u.RSA_private_key.dQ); mpz_clear(&s->u.RSA_private_key.qInv); break; +#ifdef OPENSSL + case PPK_PKCS8: + pfree(s->u.PKCS8_key.passphrase.ptr); + break; +#endif default: passert(FALSE); } @@ -939,7 +1075,27 @@ { free_preshared_secrets(); (void) process_secrets_file(shared_secrets_file); + +#ifdef OPENSSL + /* - go through all connections, and find all which have PPK_PKCS flag + * turned on. + * - for each, read PKCS file and make sure c->cert and c->key + * are populated. + * - clear PKCS flag and proceed. + * - a global flag for "secrets have been loaded" is needed. + * - if any future connections are "added" with PKCS flag on, + * check for this flag, and decrypt PKCS data at load time. + */ + secrets_loaded = TRUE; +#endif } + +#ifdef OPENSSL +extern bool are_secrets_loaded(void) +{ + return secrets_loaded; +} +#endif /* public key machinery */ diff -BbruN freeswan-1.91.orig/pluto/preshared.h freeswan-1.91/pluto/preshared.h --- freeswan-1.91.orig/pluto/preshared.h Fri Aug 18 01:20:18 2000 +++ freeswan-1.91/pluto/preshared.h Mon Jul 16 23:26:30 2001 @@ -30,7 +30,10 @@ enum PrivateKeyKind { PPK_PSK, /* PPK_DSS, */ /* not implemented */ - PPK_RSA + PPK_RSA, +#ifdef OPENSSL + PPK_PKCS8, /* information to decrypt PKCS8 key with given hash */ +#endif }; extern const chunk_t *get_preshared_secret(struct connection *c); @@ -73,3 +76,12 @@ extern bool same_RSA_public_key(const struct RSA_public_key *a , const struct RSA_public_key *b); + +#ifdef OPENSSL +struct PKCS8_key { + chunk_t passphrase; /* certificate's passphrase */ +}; +extern bool are_secrets_loaded(void); +extern const chunk_t *get_PKCS8_secret(struct connection *c); +#endif + diff -BbruN freeswan-1.91.orig/pluto/spdb.c freeswan-1.91/pluto/spdb.c --- freeswan-1.91.orig/pluto/spdb.c Mon Apr 9 15:48:43 2001 +++ freeswan-1.91/pluto/spdb.c Mon Jul 16 23:26:30 2001 @@ -39,6 +39,11 @@ #include "md5.h" #include "crypto.h" /* requires sha1.h and md5.h */ +#ifdef OPENSSL +#include "demux.h" +#include "openssl.h" +#endif + #define AD(x) x, elemsof(x) /* Array Description */ #define AD_NULL NULL, 0 @@ -46,6 +51,14 @@ /* arrays of attributes for transforms, preshared key */ +#ifdef DES +static struct db_attr otpsk1024desmd5[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif static struct db_attr otpsk1024des3md5[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, @@ -53,6 +66,14 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, }; +#ifdef DES +static struct db_attr otpsk1536desmd5[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif static struct db_attr otpsk1536des3md5[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, @@ -60,6 +81,14 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, }; +#ifdef DES +static struct db_attr otpsk1024dessha[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif static struct db_attr otpsk1024des3sha[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, @@ -67,6 +96,14 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, }; +#ifdef DES +static struct db_attr otpsk1536dessha[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif static struct db_attr otpsk1536des3sha[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, @@ -76,6 +113,14 @@ /* arrays of attributes for transforms, RSA signatures */ +#ifdef DES +static struct db_attr otrsasig1024desmd5[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif static struct db_attr otrsasig1024des3md5[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, @@ -83,6 +128,14 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, }; +#ifdef DES +static struct db_attr otrsasig1536desmd5[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif static struct db_attr otrsasig1536des3md5[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, @@ -90,6 +143,14 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, }; +#ifdef DES +static struct db_attr otrsasig1024dessha[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif static struct db_attr otrsasig1024des3sha[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, @@ -97,6 +158,14 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, }; +#ifdef DES +static struct db_attr otrsasig1536dessha[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif static struct db_attr otrsasig1536des3sha[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, @@ -104,11 +173,350 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, }; +#ifdef OPENSSL /* OPENSSL */ +#ifdef DES +static struct db_attr ot1024desmd5_ds_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif +static struct db_attr ot1024des3md5_ds_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; + +#ifdef DES +static struct db_attr ot1024dessha_ds_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif +static struct db_attr ot1024des3sha_ds_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; + +#ifdef DES +static struct db_attr ot1024dessha_ds_dss[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_DSS_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif +static struct db_attr ot1024des3sha_ds_dss[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_DSS_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; + +#ifdef DES +static struct db_attr ot1024desmd5_pk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif +static struct db_attr ot1024des3md5_pk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; + +#ifdef DES +static struct db_attr ot1024dessha_pk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif +static struct db_attr ot1024des3sha_pk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; + +#ifdef DES +static struct db_attr ot1024dessha_pk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif +static struct db_attr ot1024des3sha_pk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; + +#ifdef DES +static struct db_attr ot1024desmd5_pk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif +static struct db_attr ot1024des3md5_pk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#ifdef DES +static struct db_attr ot1024desmd5_rpk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif +static struct db_attr ot1024des3md5_rpk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; + +#ifdef DES +static struct db_attr ot1024dessha_rpk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif +static struct db_attr ot1024des3sha_rpk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; + +#ifdef DES +static struct db_attr ot1024dessha_rpk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif +static struct db_attr ot1024des3sha_rpk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; + +#ifdef DES +static struct db_attr ot1024desmd5_rpk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif +static struct db_attr ot1024des3md5_rpk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; + +#ifdef DES +static struct db_attr ot1536desmd5_ds_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif +static struct db_attr ot1536des3md5_ds_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; + +#ifdef DES +static struct db_attr ot1536dessha_ds_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif +static struct db_attr ot1536des3sha_ds_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; + +#ifdef DES +static struct db_attr ot1536dessha_ds_dss[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_DSS_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif +static struct db_attr ot1536des3sha_ds_dss[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_DSS_SIG }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; + +#ifdef DES +static struct db_attr ot1536desmd5_pk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif +static struct db_attr ot1536des3md5_pk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; + +#ifdef DES +static struct db_attr ot1536dessha_pk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif +static struct db_attr ot1536des3sha_pk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; + +#ifdef DES +static struct db_attr ot1536dessha_pk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif +static struct db_attr ot1536des3sha_pk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; + +#ifdef DES +static struct db_attr ot1536desmd5_pk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif +static struct db_attr ot1536des3md5_pk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; + +#ifdef DES +static struct db_attr ot1536desmd5_rpk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif +static struct db_attr ot1536des3md5_rpk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; + +#ifdef DES +static struct db_attr ot1536dessha_rpk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif +static struct db_attr ot1536des3sha_rpk_rsa[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; + +#ifdef DES +static struct db_attr ot1536dessha_rpk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif +static struct db_attr ot1536des3sha_rpk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; + +#ifdef DES +static struct db_attr ot1536desmd5_rpk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif +static struct db_attr ot1536des3md5_rpk_elgamal[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_ELGAMAL_ENC_REV }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, + }; +#endif /* OPENSSL */ + /* We won't accept this, but by proposing it, we get to test * our rejection. We better not propose it to an IKE daemon * that will accept it! */ #ifdef TEST_INDECENT_PROPOSAL +#ifdef DES +static struct db_attr otpsk1024destiger[] = { + { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_DES_CBC }, + { OAKLEY_HASH_ALGORITHM, OAKLEY_TIGER }, + { OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY }, + { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, + }; +#endif static struct db_attr otpsk1024des3tiger[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_TIGER }, @@ -127,6 +535,15 @@ { KEY_IKE, AD(otpsk1024des3md5) }, { KEY_IKE, AD(otpsk1536des3md5) }, { KEY_IKE, AD(otpsk1536des3sha) }, +#ifdef DES +#ifdef TEST_INDECENT_PROPOSAL + { KEY_IKE, AD(otpsk1024destiger) }, +#endif + { KEY_IKE, AD(otpsk1024dessha) }, + { KEY_IKE, AD(otpsk1024desmd5) }, + { KEY_IKE, AD(otpsk1536desmd5) }, + { KEY_IKE, AD(otpsk1536dessha) }, +#endif }; static struct db_trans oakley_trans_rsasig[] = { @@ -134,7 +551,142 @@ { KEY_IKE, AD(otrsasig1024des3md5) }, { KEY_IKE, AD(otrsasig1536des3md5) }, { KEY_IKE, AD(otrsasig1536des3sha) }, +#ifdef DES + { KEY_IKE, AD(otrsasig1024dessha) }, + { KEY_IKE, AD(otrsasig1024desmd5) }, + { KEY_IKE, AD(otrsasig1536desmd5) }, + { KEY_IKE, AD(otrsasig1536dessha) }, +#endif + }; + +#ifdef OPENSSL +static struct db_trans oakley_trans_psk2[] = { +#ifdef TEST_INDECENT_PROPOSAL + { KEY_IKE, AD(otpsk1024des3tiger), NULL }, +#endif + { KEY_IKE, AD(otpsk1024des3sha), NULL }, + { KEY_IKE, AD(otpsk1024des3md5), NULL }, + { KEY_IKE, AD(otpsk1536des3md5), NULL }, + { KEY_IKE, AD(otpsk1536des3sha), NULL }, +#ifdef DES +#ifdef TEST_INDECENT_PROPOSAL + { KEY_IKE, AD(otpsk1024destiger), NULL }, +#endif + { KEY_IKE, AD(otpsk1024dessha), NULL }, + { KEY_IKE, AD(otpsk1024desmd5), NULL }, + { KEY_IKE, AD(otpsk1536desmd5), NULL }, + { KEY_IKE, AD(otpsk1536dessha), NULL }, +#endif + }; + +static struct db_trans oakley_trans_openssl[] = { + { KEY_IKE, AD(ot1024des3sha_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024des3sha_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024des3md5_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024des3md5_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024des3sha_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024des3sha_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024des3md5_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024des3md5_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024des3sha_ds_dss), have_dss_key }, + { KEY_IKE, AD(ot1024des3sha_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(ot1024des3md5_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(ot1536des3sha_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536des3sha_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536des3md5_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536des3md5_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536des3sha_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536des3sha_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536des3md5_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536des3md5_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536des3sha_ds_dss), have_dss_key }, + { KEY_IKE, AD(ot1536des3sha_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(ot1536des3md5_ds_rsa), have_rsa_key }, +#ifdef DES + { KEY_IKE, AD(ot1024dessha_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024dessha_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024desmd5_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024desmd5_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024dessha_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024dessha_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024desmd5_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024desmd5_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024dessha_ds_dss), have_dss_key }, + { KEY_IKE, AD(ot1024dessha_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(ot1024desmd5_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(ot1536dessha_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536dessha_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536desmd5_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536desmd5_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536dessha_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536dessha_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536desmd5_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536desmd5_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536dessha_ds_dss), have_dss_key }, + { KEY_IKE, AD(ot1536dessha_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(ot1536desmd5_ds_rsa), have_rsa_key }, +#endif + }; + +static struct db_trans oakley_trans_psk2openssl[] = { + { KEY_IKE, AD(ot1024des3sha_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024des3sha_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024des3md5_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024des3md5_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024des3sha_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024des3sha_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024des3md5_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024des3md5_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024des3sha_ds_dss), have_dss_key }, + { KEY_IKE, AD(ot1024des3sha_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(ot1024des3md5_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(otpsk1024des3sha), NULL }, + { KEY_IKE, AD(otpsk1024des3md5), NULL }, + { KEY_IKE, AD(ot1536des3sha_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536des3sha_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536des3md5_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536des3md5_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536des3sha_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536des3sha_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536des3md5_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536des3md5_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536des3sha_ds_dss), have_dss_key }, + { KEY_IKE, AD(ot1536des3sha_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(ot1536des3md5_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(otpsk1536des3md5), NULL }, + { KEY_IKE, AD(otpsk1536des3sha), NULL }, +#ifdef DES + { KEY_IKE, AD(ot1024dessha_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024dessha_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024desmd5_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024desmd5_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024dessha_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024dessha_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024desmd5_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1024desmd5_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1024dessha_ds_dss), have_dss_key }, + { KEY_IKE, AD(ot1024dessha_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(ot1024desmd5_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(otpsk1024dessha), NULL }, + { KEY_IKE, AD(otpsk1024desmd5), NULL }, + + { KEY_IKE, AD(ot1536dessha_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536dessha_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536desmd5_rpk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536desmd5_rpk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536dessha_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536dessha_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536desmd5_pk_elgamal), have_elgamal_keypair }, + { KEY_IKE, AD(ot1536desmd5_pk_rsa), have_rsa_keypair }, + { KEY_IKE, AD(ot1536dessha_ds_dss), have_dss_key }, + { KEY_IKE, AD(ot1536dessha_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(ot1536desmd5_ds_rsa), have_rsa_key }, + { KEY_IKE, AD(otpsk1536desmd5), NULL }, + { KEY_IKE, AD(otpsk1536dessha), NULL }, +#endif }; +#endif /* #ifdef OPENSSL */ + /* In this table, either PSK or RSA sig is accepted. * The order matters, but I don't know what would be best. @@ -151,6 +703,19 @@ { KEY_IKE, AD(otpsk1536des3md5) }, { KEY_IKE, AD(otrsasig1536des3sha) }, { KEY_IKE, AD(otpsk1536des3sha) }, +#ifdef DES +#ifdef TEST_INDECENT_PROPOSAL + { KEY_IKE, AD(otpsk1024destiger) }, +#endif + { KEY_IKE, AD(otrsasig1024dessha) }, + { KEY_IKE, AD(otpsk1024dessha) }, + { KEY_IKE, AD(otrsasig1024desmd5) }, + { KEY_IKE, AD(otpsk1024desmd5) }, + { KEY_IKE, AD(otrsasig1536desmd5) }, + { KEY_IKE, AD(otpsk1536desmd5) }, + { KEY_IKE, AD(otrsasig1536dessha) }, + { KEY_IKE, AD(otpsk1536dessha) }, +#endif }; /* array of proposals to be conjoined (can only be one for Oakley) */ @@ -164,6 +729,17 @@ static struct db_prop oakley_pc_pskrsasig[] = { { PROTO_ISAKMP, AD(oakley_trans_pskrsasig) } }; +#ifdef OPENSSL +static struct db_prop oakley_pc_psk2[] = + { { PROTO_ISAKMP, AD(oakley_trans_psk2) } }; + +static struct db_prop oakley_pc_openssl[] = + { { PROTO_ISAKMP, AD(oakley_trans_openssl) } }; + +static struct db_prop oakley_pc_psk2openssl[] = + { { PROTO_ISAKMP, AD(oakley_trans_psk2openssl) } }; +#endif + /* array of proposal conjuncts (can only be one) */ static struct db_prop_conj oakley_props_psk[] = { { AD(oakley_pc_psk) } }; @@ -172,6 +748,14 @@ static struct db_prop_conj oakley_props_pskrsasig[] = { { AD(oakley_pc_pskrsasig) } }; +#ifdef OPENSSL +static struct db_prop_conj oakley_props_psk2[] = { { AD(oakley_pc_psk2) } }; + +static struct db_prop_conj oakley_props_openssl[] = { { AD(oakley_pc_openssl) } }; + +static struct db_prop_conj oakley_props_psk2openssl[] = { { AD(oakley_pc_psk2openssl) } }; +#endif + /* the sadb entry, subscripted by POLICY_PSK and POLICY_RSASIG bits */ struct db_sa oakley_sadb[] = { { AD_NULL }, /* none */ @@ -180,6 +764,16 @@ { AD(oakley_props_pskrsasig) }, /* POLICY_PSK + POLICY_RSASIG */ }; +#ifdef OPENSSL +/* the sadb entry, subscripted by POLICY_PSK and POLICY_OPENSSL bits */ +struct db_sa oakley_sadb2[] = { + { NULL, 0 }, /* none */ + { AD(oakley_props_psk2) }, /* POLICY_PSK */ + { AD(oakley_props_openssl) }, /* POLICY_OPENSSL */ + { AD(oakley_props_psk2openssl) }, /* POLICY_PSK + POLICY_OPENSSL */ + }; +#endif + /**************** IPsec (quick mode) SA database ****************/ /* arrays of attributes for transforms */ @@ -203,12 +797,28 @@ /* arrays of transforms, each in in preference order */ static struct db_trans espa_trans[] = { +#ifndef OPENSSL { ESP_3DES, AD(espmd5_attr) }, { ESP_3DES, AD(espsha1_attr) }, +#ifdef DES + { ESP_DES, AD(espmd5_attr) }, + { ESP_DES, AD(espsha1_attr) }, +#endif +#else + { ESP_3DES, AD(espmd5_attr), NULL }, + { ESP_3DES, AD(espsha1_attr), NULL }, +#ifdef DES + { ESP_DES, AD(espmd5_attr), NULL }, + { ESP_DES, AD(espsha1_attr), NULL }, +#endif +#endif }; static struct db_trans esp_trans[] = { { ESP_3DES, AD_NULL }, +#ifdef DES + { ESP_DES, AD_NULL }, +#endif }; #ifdef SUPPORT_ESP_NULL @@ -219,8 +829,13 @@ #endif /* SUPPORT_ESP_NULL */ static struct db_trans ah_trans[] = { +#ifndef OPENSSL { AH_MD5, AD(ah_HMAC_MD5_attr) }, { AH_SHA, AD(ah_HMAC_SHA1_attr) }, +#else + { AH_MD5, AD(ah_HMAC_MD5_attr), NULL }, + { AH_SHA, AD(ah_HMAC_SHA1_attr), NULL }, +#endif }; static struct db_trans ipcomp_trans[] = { @@ -434,7 +1049,19 @@ proposal.isap_spisize = oakley_mode ? 0 : p->protoid == PROTO_IPCOMP ? IPCOMP_CPI_SIZE : IPSEC_DOI_SPI_SIZE; + +#ifndef OPENSSL proposal.isap_notrans = p->trans_cnt; +#else + proposal.isap_notrans = 0; + for(tn = 0; tn < p->trans_cnt; tn++) { + struct db_trans *t = &(p->trans[tn]); + if (t->offer == NULL) + proposal.isap_notrans++; + else if ((t->offer(st))) /* only offer a propsal if we can carry it out */ + proposal.isap_notrans++; + } +#endif if (!out_struct(&proposal, &isakmp_proposal_desc, &sa_pbs, &proposal_pbs)) return FALSE; @@ -533,6 +1160,14 @@ trans.isat_np = (tn == p->trans_cnt - 1) ? ISAKMP_NEXT_NONE : ISAKMP_NEXT_T; +#ifdef OPENSSL + if ((t->offer != NULL) && ((t->offer)(st) == FALSE)) { + DBG(DBG_PARSING, + DBG_log("Skipping unavailable cipher: %d", tn); + ); + continue; /* skip unavailable cipher */ + } +#endif trans.isat_transnum = tn; trans.isat_transid = t->transid; if (!out_struct(&trans, trans_desc, &proposal_pbs, &trans_pbs)) @@ -645,6 +1280,180 @@ return val; } +#ifdef OPENSSL +struct _trans_node { + struct oakley_trans_attrs ta; + struct isakmp_transform trans; + u_char *attr_start; + size_t attr_len; + bool elim; /* has this node been eliminated from the selection process */ + struct _trans_node *next; +}; + +typedef struct _trans_node *trans_list; + +/* Free a list of Oakley transforms */ +static void +trans_list_free( trans_list *l ) +{ + trans_list p; + + if (!l) return; + while (*l) { + p = *l; + *l = p->next; + pfree(p->attr_start); + pfree(p); + } +} + +static void +trans_list_append(trans_list *l, + struct oakley_trans_attrs *ta, + struct isakmp_transform *trans, + u_char *attr_start, + size_t attr_len) { + trans_list p, pp; + + if (!l) return; + if ((p = alloc_bytes(sizeof(struct _trans_node), + "transformation node")) == NULL) return; + p->ta = *ta; + p->trans = *trans; + p->attr_len = attr_len; + if ((p->attr_start = alloc_bytes(attr_len, "attribute")) == NULL) { + pfree(p); + return; + } + memcpy(p->attr_start, attr_start, attr_len); + p->elim = FALSE; + p->next = NULL; + if (*l == NULL) { + *l = p; + } else { + for(pp = *l; pp->next ; pp = pp->next); + pp->next = p; + } +} + +static bool +select_trans_candidate(trans_list l, + struct oakley_trans_attrs *ta, + struct isakmp_transform *trans, + u_char **attr_start, + size_t *attr_len, + u_int32_t opts) +{ + bool ret = FALSE; + trans_list auth[OAKLEY_ELGAMAL_ENC_REV+1], p; + uint i, numprefs, pref[10]; + + if (!l) { + DBG(DBG_PARSING, + DBG_log("No candidate transforms to choose from"); + ); + return FALSE; + } + + if ((!ta) || (!attr_len) || (!trans) || (!attr_start)) { + DBG(DBG_PARSING, + DBG_log("No space to store selected transform"); + ); + return FALSE; + } + + /* Separate all elements of the list by authentication method */ + + for(i=OAKLEY_PRESHARED_KEY; i<=OAKLEY_ELGAMAL_ENC_REV; i++) + auth[i] = NULL; + for(p=l; p; p=p->next) + if ((p->ta.auth >= OAKLEY_PRESHARED_KEY) && + (p->ta.auth <= OAKLEY_ELGAMAL_ENC_REV )) { + trans_list_append(&(auth[p->ta.auth]), + &(p->ta), + &(p->trans), + p->attr_start, + p->attr_len); + } + + numprefs = 7; + pref[numprefs-1] = OAKLEY_PRESHARED_KEY; + DBG(DBG_PARSING | DBG_CRYPT, + DBG_log("select_trans_candidate: %08x", opts); + ); + if (opts & CERT_OPTION_PK) { + if (opts & CERT_OPTION_REV) { + DBG(DBG_PARSING | DBG_CRYPT, + DBG_log("Preferring revised PK encryption schemes"); + ); + pref[0] = OAKLEY_ELGAMAL_ENC_REV; + pref[1] = OAKLEY_RSA_ENC_REV; + pref[2] = OAKLEY_ELGAMAL_ENC; + pref[3] = OAKLEY_RSA_ENC; + pref[4] = OAKLEY_RSA_SIG; + pref[5] = OAKLEY_DSS_SIG; + } else { + DBG(DBG_PARSING | DBG_CRYPT, + DBG_log("Preferring standard PK encryption schemes"); + ); + pref[0] = OAKLEY_ELGAMAL_ENC; + pref[1] = OAKLEY_RSA_ENC; + pref[2] = OAKLEY_ELGAMAL_ENC_REV; + pref[3] = OAKLEY_RSA_ENC_REV; + pref[4] = OAKLEY_RSA_SIG; + pref[5] = OAKLEY_DSS_SIG; + } + } else { + if (opts & CERT_OPTION_REV) { + DBG(DBG_PARSING | DBG_CRYPT, + DBG_log("Preferring digisig schemes, then revised pk"); + ); + pref[0] = OAKLEY_RSA_SIG; + pref[1] = OAKLEY_DSS_SIG; + pref[2] = OAKLEY_ELGAMAL_ENC_REV; + pref[3] = OAKLEY_RSA_ENC_REV; + pref[4] = OAKLEY_ELGAMAL_ENC; + pref[5] = OAKLEY_RSA_ENC; + } else { + DBG(DBG_PARSING | DBG_CRYPT, + DBG_log("Preferring digisig schemes, then standard pk"); + ); + pref[0] = OAKLEY_RSA_SIG; + pref[1] = OAKLEY_DSS_SIG; + pref[2] = OAKLEY_ELGAMAL_ENC; + pref[3] = OAKLEY_RSA_ENC; + pref[4] = OAKLEY_ELGAMAL_ENC_REV; + pref[5] = OAKLEY_RSA_ENC_REV; + } + } + + for(i=0; ((ita; + *trans = auth[pref[i]]->trans; + *attr_start = alloc_bytes(auth[pref[i]]->attr_len, "attribute"); + if (*attr_start) { + *attr_len = auth[pref[i]]->attr_len; + memcpy(*attr_start, auth[pref[i]]->attr_start, *attr_len); + } + DBG(DBG_PARSING, + DBG_log("Candidate selected: %s", + enum_show(&oakley_auth_names, pref[i])); + ); + } +} + + for(i=OAKLEY_PRESHARED_KEY; i<=OAKLEY_RSA_ENC_REV; i++) { + trans_list_free(&auth[i]); + } + return ret; +} +#endif + /* Parse the body of an ISAKMP SA Payload (i.e. Phase 1 / Main Mode). * Various shortcuts are taken. In particular, the policy, such as * it is, is hardwired. @@ -674,6 +1483,12 @@ struct isakmp_proposal proposal; unsigned no_trans_left; int last_transnum; + const struct connection *c = st->st_connection; + +#ifdef OPENSSL + bool selected; + trans_list tl = NULL; +#endif /* DOI */ if (sa->isasa_doi != ISAKMP_DOI_IPSEC) @@ -859,12 +1674,31 @@ case OAKLEY_ENCRYPTION_ALGORITHM | ISAKMP_ATTR_AF_TV: switch (val) { -#if 0 /* we don't feel DES is safe */ +#ifdef DES case OAKLEY_DES_CBC: + if ((c->block_cypher == ALL_BLOCK_CYPHER) || + (c->block_cypher == DES_BLOCK_CYPHER)) { + ta.encrypt = val; + ta.encrypter = &oakley_encrypter[val]; + } else { + ugh = builddiag("%s is not accepted" + , enum_show(&oakley_enc_names, val)); + } + break; #endif case OAKLEY_3DES_CBC: +#ifdef DES + if ((c->block_cypher == ALL_BLOCK_CYPHER) || + (c->block_cypher == DES3_BLOCK_CYPHER)) { +#endif ta.encrypt = val; ta.encrypter = &oakley_encrypter[val]; +#ifdef DES + } else { + ugh = builddiag("%s is not accepted" + , enum_show(&oakley_enc_names, val)); + } +#endif break; default: ugh = builddiag("%s is not supported" @@ -923,9 +1757,54 @@ ta.auth = val; } break; + +#ifdef OPENSSL + case OAKLEY_DSS_SIG: + if ((st->st_connection->key == NULL) || + (((EVP_PKEY *)(st->st_connection->key))->type != EVP_PKEY_DSA)) + ugh = builddiag( + "OAKLEY_DSS_SIG requested, but no DSA key available to sign with. Still unsupported."); + ta.auth = val; + break; +/* + * case OAKLEY_RSA_SIG: + * see after #endif OPENSSL + */ + case OAKLEY_RSA_ENC: + if (!have_rsa_keypair(st)) + ugh = builddiag( + "OAKLEY_RSA_ENC requested, but no cert available to encrypt with"); + ta.auth = val; + break; + case OAKLEY_ELGAMAL_ENC: + if (!have_elgamal_keypair(st)) + ugh = builddiag( + "OAKLEY_ELGAMAL_ENC requested, but no cert available to encrypt with"); + ta.auth = val; + break; + case OAKLEY_RSA_ENC_REV: + if (!have_rsa_keypair(st)) + ugh = builddiag( + "OAKLEY_RSA_ENC_REV requested, but no cert available to encrypt with"); + ta.auth = val; + break; + case OAKLEY_ELGAMAL_ENC_REV: + if (!have_elgamal_keypair(st)) + ugh = builddiag( + "OAKLEY_ELGAMAL_ENC_REV requested, but no cert available to encrypt with"); + ta.auth = val; + break; + case OAKLEY_RSA_SIG: + if (!use_openssl(st->st_connection)) + { +#endif /* OPENSSL, !use_openssl */ /* Accept if policy specifies RSASIG or is default */ +#ifndef OPENSSL if ((iap & POLICY_RSASIG) == LEMPTY) +#else + if ((iap & POLICY_OPENSSL) == LEMPTY) +#endif { ugh = "policy does not allow OAKLEY_RSA_SIG authentication"; } @@ -941,6 +1820,15 @@ */ ta.auth = val; } +#ifdef OPENSSL + } else { /* use_openssl */ + if ((st->st_connection->key == NULL) || + (((EVP_PKEY *)(st->st_connection->key))->type != EVP_PKEY_RSA)) + ugh = builddiag( + "OAKLEY_RSA_SIG requested, but no key available to sign with"); + ta.auth = val; + } +#endif break; default: @@ -1055,6 +1943,7 @@ * Lets finish early and leave. */ +#ifndef OPENSSL DBG(DBG_PARSING | DBG_CRYPT , DBG_log("Oakley Transform %u accepted", trans.isat_transnum)); @@ -1108,6 +1997,14 @@ /* copy over the results */ st->st_oakley = ta; return NOTHING_WRONG; +#else + /* + * We store the ta result into the list of candidates + * Afterwards, site policy dictates which of the + * candidates we should select + */ + trans_list_append(&tl, &ta, &trans, attr_start, attr_len); +#endif } /* on to next transform */ @@ -1128,9 +2025,77 @@ , enum_show(&payload_names, proposal.isap_np)); return BAD_PROPOSAL_SYNTAX; } - } + } /* for */ + +#ifndef OPENSSL loglog(RC_LOG_SERIOUS, "no acceptable Oakley Transform"); return NO_PROPOSAL_CHOSEN; +#else + /* We should have a list of hopefuls in the list tl */ + { /* open scope */ + u_char *attr_start; + size_t attr_len; + struct isakmp_transform trans; + + selected = select_trans_candidate(tl, &st->st_oakley, &trans, + &attr_start, &attr_len, st->st_connection->cert_options); + trans_list_free(&tl); + if (! selected) { + log("no acceptable Oakley Transform"); + return NO_PROPOSAL_CHOSEN; + } else { + DBG(DBG_PARSING | DBG_CRYPT, + DBG_log("Oakley Transform %u accepted", trans.isat_transnum) + ); + + if (r_sa_pbs != NULL) + { + struct isakmp_proposal r_proposal = proposal; + pb_stream r_proposal_pbs; + struct isakmp_transform r_trans = trans; + pb_stream r_trans_pbs; + + /* Situation */ + if (!out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL)) + passert(FALSE); + + /* Proposal */ +#ifdef EMIT_ISAKMP_SPI + r_proposal.isap_spisize = COOKIE_SIZE; +#else + r_proposal.isap_spisize = 0; +#endif + r_proposal.isap_notrans = 1; + if (!out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs)) + passert(FALSE); + + /* SPI */ +#ifdef EMIT_ISAKMP_SPI + if (!out_raw(my_cookie, COOKIE_SIZE, &r_proposal_pbs, "SPI")) + passert(FALSE); + r_proposal.isap_spisize = COOKIE_SIZE; +#else + /* none (0) */ +#endif + + /* Transform */ + r_trans.isat_np = ISAKMP_NEXT_NONE; + if (!out_struct(&r_trans, &isakmp_isakmp_transform_desc, + &r_proposal_pbs, &r_trans_pbs)) + passert(FALSE); + + if (!out_raw(attr_start, attr_len, &r_trans_pbs, "attributes")) + passert(FALSE); + if (attr_start) pfree(attr_start); + + close_output_pbs(&r_trans_pbs); + close_output_pbs(&r_proposal_pbs); + close_output_pbs(r_sa_pbs); + } /* if (r_sa_pbs != NULL) */ + return NOTHING_WRONG; + } /* if (! selected) */ + } /* end this scope */ +#endif /* OPENSSL */ } /* Parse the body of an IPsec SA Payload (i.e. Phase 2 / Quick Mode). @@ -1802,7 +2767,7 @@ switch (esp_attrs.transid) { -#if 0 /* we don't feel single DES is safe */ +#ifdef DES case ESP_DES: #endif case ESP_3DES: diff -BbruN freeswan-1.91.orig/pluto/spdb.h freeswan-1.91/pluto/spdb.h --- freeswan-1.91.orig/pluto/spdb.h Fri Sep 15 05:09:28 2000 +++ freeswan-1.91/pluto/spdb.h Mon Jul 16 23:26:30 2001 @@ -24,11 +24,32 @@ u_int16_t val; }; +#ifdef OPENSSL +typedef bool offer_fn(struct state *st); +/* Addition for OpenSSL: we don't want to offer cipher suites */ +/* which we aren't capable of generating, so I added a function */ +/* parameter 'offer', which takes the state as a parameter, and */ +/* returns either TRUE or FALSE, depending on whether the cipher */ +/* suite is supportable. For instance, there's no point in */ +/* offering to sign things with a DSA signature key, if all you've */ +/* got is an RSA one. */ +/* NB: If the function pointer is set to NULL, it means offer the */ +/* cipher suite under all conditions. The downside to this is that */ +/* another parameter must be added to all the IPsec cipher transforms */ +/* which is always NULL. I suppose we could embed policy information */ +/* within that parameter, e.g. If a pair of endpoints must have */ +/* a particular cipher between them. Trouble is, that information is */ +/* present within ipsec.conf, to some extent -- nd */ +#endif + /* transform */ struct db_trans { u_int8_t transid; /* Transform-Id */ struct db_attr *attrs; /* array */ int attr_cnt; /* number of elements */ +#ifdef OPENSSL + offer_fn *offer; +#endif }; /* proposal */ @@ -56,9 +77,12 @@ }; /* The oakley sadb is subscripted by a bitset with members - * from POLICY_PSK and POLICY_RSASIG. + * from POLICY_PSK and POLICY_RSASIG/OPENSSL. */ extern struct db_sa oakley_sadb[1 << 2]; +#ifdef OPENSSL +extern struct db_sa oakley_sadb2[1 << 2]; +#endif /* The ipsec sadb is subscripted by a bitset with members * from POLICY_ENCRYPT, POLICY_AUTHENTICATE, POLICY_COMPRESS diff -BbruN freeswan-1.91.orig/pluto/state.c freeswan-1.91/pluto/state.c --- freeswan-1.91.orig/pluto/state.c Mon Jun 4 23:14:28 2001 +++ freeswan-1.91/pluto/state.c Mon Jul 16 23:26:30 2001 @@ -359,6 +359,16 @@ pfreeany(st->st_esp.our_keymat); pfreeany(st->st_esp.peer_keymat); +#ifdef OPENSSL + /* Clean out the stuff for revised PK encryption mode */ + pfreeany(st->st_ne_i.ptr); + memset(&st->st_ks_i, 0, sizeof(st->st_ks_i)); + memset(st->st_ne_i_iv, 0, MAX_DIGEST_LEN); + pfreeany(st->st_ne_r.ptr); + memset(&st->st_ks_r, 0, sizeof(st->st_ks_r)); + memset(st->st_ne_r_iv, 0, MAX_DIGEST_LEN); +#endif + pfree(st); } diff -BbruN freeswan-1.91.orig/pluto/state.h freeswan-1.91/pluto/state.h --- freeswan-1.91.orig/pluto/state.h Thu Mar 1 22:19:46 2001 +++ freeswan-1.91/pluto/state.h Mon Jul 16 23:26:30 2001 @@ -145,6 +145,15 @@ u_int8_t st_rcookie[COOKIE_SIZE];/* Responder Cookie */ chunk_t st_nr; /* Nr nonce */ +#ifdef OPENSSL + /* key material for revised public key information */ + u_int8_t st_ne_i_iv[MAX_DIGEST_LEN]; + chunk_t st_ne_i; /* key for initiator payloads */ + keysched st_ks_i; + u_int8_t st_ne_r_iv[MAX_DIGEST_LEN]; + chunk_t st_ne_r; /* key for responder payloads */ + keysched st_ks_r; +#endif /* my stuff */ diff -BbruN freeswan-1.91.orig/pluto/version.c freeswan-1.91/pluto/version.c --- freeswan-1.91.orig/pluto/version.c Wed May 30 09:02:20 2001 +++ freeswan-1.91/pluto/version.c Sat Aug 18 12:09:19 2001 @@ -1,2 +1 @@ -/* silly pointless RCSID $Id: version.c,v 1.19 2001/05/30 13:02:20 henry Exp $ */ -static const char freeswan_version[] = "1.91"; +static const char freeswan_version[] = "FreeSWAN-1.91-pkix6b"; diff -BbruN freeswan-1.91.orig/pluto/whack.c freeswan-1.91/pluto/whack.c --- freeswan-1.91.orig/pluto/whack.c Mon May 14 16:37:48 2001 +++ freeswan-1.91/pluto/whack.c Wed Jul 18 14:51:42 2001 @@ -1,4 +1,6 @@ /* command interface to Pluto + * + * Modified by Luc Lanthier based on work from: * Copyright (C) 1997 Angelos D. Keromytis. * Copyright (C) 1998, 1999 D. Hugh Redelmeier. * @@ -82,6 +84,10 @@ " [--compress]" " [--tunnel]" " [--pfs]" +#ifdef OPENSSL + " [--openssl]" +#endif + " \\\n " " [--ikelifetime ]" " [--ipseclifetime ]" @@ -90,6 +96,14 @@ " [--reykeyfuzz ]" " \\\n " " [--keyingtries ]" +#ifdef OPENSSL + " \\\n " + " [--certfile ]" + " [--certopts <[!]opt1,[!]opt2,...,[!]optN>]" + " [--peerfile ]" + " [--keyfile ]" + " [--certpath ]" +#endif "\n\n" "routing: whack" " (--route | --unroute)" @@ -142,6 +156,11 @@ "shutdown: whack" " --shutdown" "\n\n" +#ifdef DES + "DES type: whack" + " [--force_encrypt_cypher ]" + "\n\n" +#endif "FreeS/WAN %s\n", freeswan_version); } @@ -203,6 +222,14 @@ OPT_KEYID, OPT_PUBKEYRSA, +#ifdef OPENSSL + OPT_CERTFILE, + OPT_CERTOPTS, + OPT_PEERFILE, + OPT_KEYFILE, + OPT_CERTPATH, +#endif + OPT_ROUTE, OPT_UNROUTE, @@ -234,7 +261,11 @@ # define CD_POLICY_FIRST CD_PSK CD_PSK, /* same order as POLICY_* */ +#ifndef OPENSSL CD_RSASIG, /* same order as POLICY_* */ +#else + CD_OPENSSL, /* same order as POLICY_* */ +#endif CD_ENCRYPT, /* same order as POLICY_* */ CD_AUTHENTICATE, /* same order as POLICY_* */ CD_COMPRESS, /* same order as POLICY_* */ @@ -247,6 +278,10 @@ CD_CONNIPV4, CD_CONNIPV6, +#ifdef DES + CD_FORCE_ENCRYPT_CYPHER, /* to force DES or 3DES only */ +#endif + CD_IKELIFETIME, CD_IPSECLIFETIME, CD_RKMARGIN, @@ -319,7 +354,12 @@ { "updown", required_argument, NULL, CD_UPDOWN + OO }, { "psk", no_argument, NULL, CD_PSK + OO }, +#ifndef OPENSSL { "rsasig", no_argument, NULL, CD_RSASIG + OO }, +#else + { "rsasig", no_argument, NULL, CD_OPENSSL + OO }, + { "openssl", no_argument, NULL, CD_OPENSSL + OO }, +#endif { "encrypt", no_argument, NULL, CD_ENCRYPT + OO }, { "authenticate", no_argument, NULL, CD_AUTHENTICATE + OO }, @@ -339,6 +379,18 @@ { "rekeywindow", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG }, /* OBSOLETE */ { "rekeyfuzz", required_argument, NULL, CD_RKFUZZ + OO + NUMERIC_ARG }, { "keyingtries", required_argument, NULL, CD_KTRIES + OO + NUMERIC_ARG }, +#ifdef DES +/* DES Support */ + { "force_encrypt_cypher", required_argument, NULL, CD_FORCE_ENCRYPT_CYPHER + OO }, +#endif + +#ifdef OPENSSL + { "certfile", required_argument, NULL, OPT_CERTFILE + OO }, + { "certopts", required_argument, NULL, OPT_CERTOPTS + OO }, + { "peerfile", required_argument, NULL, OPT_PEERFILE + OO }, + { "keyfile", required_argument, NULL, OPT_KEYFILE + OO }, + { "certpath", required_argument, NULL, OPT_CERTPATH + OO }, +#endif #ifdef DEBUG { "debug-none", no_argument, NULL, DBGOPT_NONE + OO }, @@ -443,7 +495,11 @@ /* client is 0.0.0.0/32: Opportunism connection */ if (!isanyaddr(&this->host_addr)) diag("normal client network must not be 0.0.0.0/32 or 0::0/128"); +#ifndef OPENSSL if ((policy & (POLICY_PSK | POLICY_RSASIG)) != POLICY_RSASIG) +#else + if ((policy & (POLICY_PSK | POLICY_OPENSSL)) != POLICY_OPENSSL) +#endif diag("only RSASIG is supported for opportunism"); if ((policy & POLICY_PFS) == 0) diag("PFS required for opportunism"); @@ -492,6 +548,9 @@ msg.sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT; msg.sa_rekey_fuzz = SA_REPLACEMENT_FUZZ_DEFAULT; msg.sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT; +#ifdef DES + msg.block_cypher = FORCE_ENCRYPT_CYPHER_DEFAULT; +#endif msg.addr_family = AF_INET; msg.tunnel_addr_family = AF_INET; @@ -672,6 +731,37 @@ msg.whack_async = TRUE; continue; +#ifdef OPENSSL + case OPT_CERTFILE: + if (strlen(optarg) >= FILE_NAME_LIMIT) + diagq("certificate file name too long", optarg); + strcpy(msg.whack_certfile, optarg); + continue; + + case OPT_CERTOPTS: + if (strlen(optarg) >= CERT_OPTIONS_LIMIT) + diagq("certificate file name too long", optarg); + strcpy(msg.whack_certopts, optarg); + continue; + + case OPT_PEERFILE: + if (strlen(optarg) >= FILE_NAME_LIMIT) + diagq("peer certificate file name too long", optarg); + strcpy(msg.whack_peerfile, optarg); + continue; + + case OPT_KEYFILE: + if (strlen(optarg) >= FILE_NAME_LIMIT) + diagq("key file name too long", optarg); + strcpy(msg.whack_keyfile, optarg); + continue; + + case OPT_CERTPATH: + if (strlen(optarg) >= PATH_NAME_LIMIT) + diagq("certificate path name too long", optarg); + strcpy(msg.whack_certpath, optarg); + continue; +#endif /* Connection Description options */ @@ -750,7 +840,11 @@ continue; case CD_PSK: /* --psk */ +#ifndef OPENSSL case CD_RSASIG: /* --rsasig */ +#else + case CD_OPENSSL: /* --rsasig */ +#endif case CD_ENCRYPT: /* --encrypt */ case CD_AUTHENTICATE: /* --authenticate */ case CD_COMPRESS: /* --compress */ @@ -780,6 +874,22 @@ case CD_KTRIES: /* --keyingtries */ msg.sa_keying_tries = opt_whole; continue; + +#ifdef DES + /* DES support */ + case CD_FORCE_ENCRYPT_CYPHER: /* --force_encrypt_cypher */ + if (strcmp("des", optarg) == 0) { + msg.block_cypher = DES_BLOCK_CYPHER; + } + if (strcmp("3des", optarg) == 0) { + msg.block_cypher = DES3_BLOCK_CYPHER; + } + /* else */ + if ((strcmp("3des", optarg) != 0) && (strcmp("des", optarg) != 0)) { + diag("--force_encrypt_cypher must have a parameter of either 'des' or '3des'"); + } + continue; +#endif case OPT_KEYID: /* --keyid */ msg.whack_key = TRUE; diff -BbruN freeswan-1.91.orig/pluto/whack.h freeswan-1.91/pluto/whack.h --- freeswan-1.91.orig/pluto/whack.h Sun Jan 28 16:03:05 2001 +++ freeswan-1.91/pluto/whack.h Mon Jul 16 23:26:30 2001 @@ -16,6 +16,10 @@ #include +#ifdef OPENSSL +#include "openssl_defs.h" +#endif + /* * Since the message remains on one host, native representation is used. * Think of this as horizontal microcode: all selected operations are @@ -83,6 +87,14 @@ enum pubkey_alg pubkey_alg; chunk_t keyval; /* chunk */ +#ifdef OPENSSL + char whack_certfile[FILE_NAME_LIMIT]; + char whack_certopts[CERT_OPTIONS_LIMIT]; + char whack_peerfile[FILE_NAME_LIMIT]; + char whack_keyfile[FILE_NAME_LIMIT]; + char whack_certpath[PATH_NAME_LIMIT]; +#endif + /* for WHACK_ROUTE: */ bool whack_route; @@ -110,6 +122,12 @@ /* for WHACK_SHUTDOWN */ bool whack_shutdown; + +#ifdef DES + /* for des type to use */ + lset_t block_cypher; +#endif + /* space for strings (hope there is enough room): * Note that pointers don't travel on wire. diff -BbruN freeswan-1.91.orig/pluto/x_sobj.c freeswan-1.91/pluto/x_sobj.c --- freeswan-1.91.orig/pluto/x_sobj.c Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/x_sobj.c Mon Jul 23 16:57:55 2001 @@ -0,0 +1,47 @@ +#ifdef OPENSSL +#include "x_sobj.h" + +IMPLEMENT_STACK_OF(X509_OBJECT) + +X509_OBJECT * +X509_OBJECT_new( const int type, void *p ) +{ + X509_OBJECT *ret = OPENSSL_malloc(sizeof(X509_OBJECT)); + + if (ret == NULL) return ret; + switch(type) { + case X509_LU_X509: + ret->type = type; + ret->data.x509 = (X509 *)p; + break; + case X509_LU_CRL: + ret->type = type; + ret->data.crl = (X509_CRL *)p; + break; + default: /* Unknown type */ + OPENSSL_free((char *)ret); + ret = NULL; + break; + } + return ret; +} + +void +X509_OBJECT_free(X509_OBJECT *x) +{ + if (!x) return; + X509_OBJECT_free_contents(x); + OPENSSL_free((char *)x); +} + + +#if 0 +/* + * static NAME_ATTRIBUTE NAME_ATTRIBUTES[] = { + * { OBJ, TEXT, TEXTID }, + * { OBJ, TEXT, TEXTID }, + * }; + */ +#endif + +#endif /* OPENSSL */ diff -BbruN freeswan-1.91.orig/pluto/x_sobj.h freeswan-1.91/pluto/x_sobj.h --- freeswan-1.91.orig/pluto/x_sobj.h Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/x_sobj.h Mon Jul 23 16:58:24 2001 @@ -0,0 +1,76 @@ +#ifndef X_SOBJ_H +#define X_SOBJ_H + +#include +#include + +/* OpenSSL 0.9.{4,5} use compiler macros much like sk_##type##_new + * OpenSSL 0.9.6 doesn't. Here's how to compensate: + */ +#if OPENSSL_VERSION_NUMBER >= 0x00906000L +#define sk_XMAP_new(st) SKM_sk_new(XMAP, (st)) +#define sk_XMAP_new_null() SKM_sk_new_null(XMAP) +#define sk_XMAP_free(st) SKM_sk_free(XMAP, (st)) +#define sk_XMAP_num(st) SKM_sk_num(XMAP, (st)) +#define sk_XMAP_value(st, i) SKM_sk_value(XMAP, (st), (i)) +#define sk_XMAP_set(st, i, val) SKM_sk_set(XMAP, (st), (i), (val)) +#define sk_XMAP_zero(st) SKM_sk_zero(XMAP, (st)) +#define sk_XMAP_push(st, val) SKM_sk_push(XMAP, (st), (val)) +#define sk_XMAP_unshift(st, val) SKM_sk_unshift(XMAP, (st), (val)) +#define sk_XMAP_find(st, val) SKM_sk_find(XMAP, (st), (val)) +#define sk_XMAP_delete(st, i) SKM_sk_delete(XMAP, (st), (i)) +#define sk_XMAP_delete_ptr(st, ptr) SKM_sk_delete_ptr(XMAP, (st), (ptr)) +#define sk_XMAP_insert(st, val, i) SKM_sk_insert(XMAP, (st), (val), (i)) +#define sk_XMAP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(XMAP, (st), (cmp)) +#define sk_XMAP_dup(st) SKM_sk_dup(XMAP, st) +#define sk_XMAP_pop_free(st, free_func) SKM_sk_pop_free(XMAP, (st), (free_func)) +#define sk_XMAP_shift(st) SKM_sk_shift(XMAP, (st)) +#define sk_XMAP_pop(st) SKM_sk_pop(XMAP, (st)) +#define sk_XMAP_sort(st) SKM_sk_sort(XMAP, (st)) + +#else + +#define OPENSSL_malloc(num) Malloc(num) +#define OPENSSL_free(addr) Free(addr) +#define OPENSSL_realloc(addr,num) Realloc(addr,num) +#define OPENSSL_remalloc(addr,num) Remalloc(addr,num) +#define OPENSSL_freeFunc FreeFunc +#define OPENSSL_malloc_locked(num) Malloc_locked(num) +#define OPENSSL_free_locked(addr) Free_locked(addr) +#endif + + +DECLARE_STACK_OF(X509_OBJECT) + +X509_OBJECT *X509_OBJECT_new( const int type, void *ptr ); +void X509_OBJECT_free(X509_OBJECT *x); + +#if 0 +/* There are the items to be able to process while converting a DN from + * text to ID_DER_ASN1_DN + * From RFC2459: + * + * commonName + * surname + * countryName + * localityName + * stateOrProvinceName + * organizationName + * organizationalUnitName + * title + * name + * givenName + * initials + * generationQualifier + * dnQualifier + */ + +/* typedef struct _name_attribute_st { + * OBJID + * TEXT + * TEXTID + * } NAME_ATTRIBUTE + */ +#endif + +#endif diff -BbruN freeswan-1.91.orig/pluto/xmap.c freeswan-1.91/pluto/xmap.c --- freeswan-1.91.orig/pluto/xmap.c Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/xmap.c Mon Jul 16 23:26:30 2001 @@ -0,0 +1,401 @@ +#ifdef OPENSSL +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "x_sobj.h" +#include "xmap_file.h" +#include "xmap_dir.h" +#include "xmap_db.h" +#include "xmap_ldap.h" +#include "xmap.h" + +#include /* needed by constants.h */ +#include "constants.h" +#include "defs.h" +#include "log.h" + +static XMAP_METHOD_LIST *xmth = NULL; + +XMAP *XMAP_new(const char *spec); +STACK_OF(X509_OBJECT) * +XMAP_lookup( XMAP *xm, const int type, const char *index, void *p ); +void XMAP_free(XMAP *xm); +void XMAP_dump(XMAP *xm); + +int +XMAP_register(XMAP_METHOD *meth) +{ + XMAP_METHOD_LIST *p; + int found; + + for(p=xmth,found=0; ((!found) && (p)); p=p->next) + if (strcasecmp(meth->prefix, p->meth->prefix) == 0) found=1; + + if (found) { + return 0; + } else { + p = malloc(sizeof(XMAP_METHOD_LIST)); + if (p) { + p->next = xmth; + p->meth = meth; + xmth = p; + } else + return 0; + } + return 1; +} + +void +XMAP_METHOD_LIST_free( void ) +{ + XMAP_METHOD_LIST *p, *q; + + for(p=xmth; p;) { + q = p->next; + free(p); + q = p; + } +} + +int +XMAP_unregister(const char *prefix) +{ + XMAP_METHOD_LIST *p, *q; + int found; + + for(p = xmth, found = 0; ((!found) && (p)); ) + if (strcasecmp(p->meth->prefix, prefix) == 0) + found = 1; + else + p=p->next; + + if (!found) + return 0; + else { + if ( p == xmth ) { + xmth = xmth->next; + free(p); + } else { + for(q = xmth; q->next != p; q = q->next); + q->next = p->next; + free(p); + } + } + return 1; +} + +XMAP * +XMAP_new(const char *spec) +{ + XMAP *ret; + char *s; + + if ((ret = malloc(sizeof(XMAP))) == NULL) goto end; + if ((ret->spec = strdup(spec)) == NULL) goto end; + ret->methp = NULL; + + if ((s = strchr(spec, DICT_SEPARATOR)) == NULL) { + log("No type prefix"); + } else { + int l = (int)(s - spec) + 1; + XMAP_METHOD_LIST *p; + int found; + + for(p=xmth, found = 0; ((!found) && (p));) { + if (strncasecmp(p->meth->prefix, spec, l-1) == 0) + found = 1; + else + p = p->next; + } + + if (found) { + ret->pmap = p->meth->new(&s[1]); + if (! ret->pmap) goto end; + ret->methp = p; + } else { + log("Unknown map type spec: %s", spec); + goto end; + } + } + return ret; + end: + if (ret->spec) free(ret->spec); + if (ret) free(ret); + return NULL; +} + +static int +check_methp(XMAP *xm) +{ + XMAP_METHOD_LIST *p; + + for(p = xmth; p; p = p->next) + if (xm->methp == p) { + return 1; + } + + return 0; +} + +STACK_OF(X509_OBJECT) * +XMAP_lookup( XMAP *xm, const int type, const char *index, void *p ) +{ + if ((!xm) || (!check_methp(xm)) || (! xm->methp->meth->lookup) ) + { + return NULL; + } + return xm->methp->meth->lookup(xm->pmap, type, index, p); +} + +void +XMAP_free(XMAP *xm) +{ + if (!xm) return; + if (!xm->pmap) return; + if (!check_methp(xm)) return; + if (xm->methp->meth->free) xm->methp->meth->free(xm->pmap); + if (xm->spec) free(xm->spec); + free(xm); +} + +void +XMAP_dump(XMAP *xm) +{ + if (! xm->pmap) return; + if (!check_methp(xm)) return; + if (! xm->methp->meth->dump) return; + xm->methp->meth->dump(xm->pmap); +} + +int +X509_subjAltName_check_dns(X509 *x, const char *dns) +{ + int i, loc, ret; + X509_EXTENSION *ext; + u_char *p; + STACK_OF(GENERAL_NAME) *nsk = NULL; + GENERAL_NAME *gn; + + ret = 0; + if ((loc = X509_get_ext_by_NID(x, NID_subject_alt_name, -1)) >= 0) { + if ((ext = X509_get_ext(x, loc)) != NULL) { + p = ext->value->data; + d2i_GENERAL_NAMES(&nsk, &p, ext->value->length); + if (nsk) { + for(i=0; i < sk_GENERAL_NAME_num(nsk); i++) { + gn = sk_GENERAL_NAME_value(nsk, i); + + if (gn->type == GEN_DNS) { + if (strncasecmp(dns, gn->d.ia5->data, gn->d.ia5->length) == 0) { + ret = 1; + break; + } + } + } + sk_GENERAL_NAME_free(nsk); + nsk = NULL; + } + } + } + return ret; +} + +int +X509_subjAltName_check_ip(X509 *x, const struct in_addr ip) +{ + int i, loc, ret; + X509_EXTENSION *ext; + u_char *p; + STACK_OF(GENERAL_NAME) *nsk = NULL; + GENERAL_NAME *gn; + + ret = 0; + if ((loc = X509_get_ext_by_NID(x, NID_subject_alt_name, -1)) >= 0) { + if ((ext = X509_get_ext(x, loc)) != NULL) { + p = ext->value->data; + d2i_GENERAL_NAMES(&nsk, &p, ext->value->length); + if (nsk) { + for(i=0; i < sk_GENERAL_NAME_num(nsk); i++) { + gn = sk_GENERAL_NAME_value(nsk, i); + + if (gn->type == GEN_IPADD) { + if (memcmp(&ip.s_addr, gn->d.ip->data, gn->d.ip->length) == 0) { + ret = 1; + break; + } + } + } + sk_GENERAL_NAME_free(nsk); + nsk = NULL; + } + } + } + return ret; +} + + +/* some cloning procedures. needed to unshare connection + * for road warrior support. + */ + +STACK_OF(XMAP) +*clone_sk_XMAP ( STACK_OF(XMAP) *sk_xm ) +{ + /* declare new stack */ + STACK_OF(XMAP) *temp_sk_xm; + int i; + + /* clone contents of stack. Memory pointers stay the same + * so further cloning for each sub-structure is needed. + * + * typedef struct stack_st + * { + * int num; + * char **data; + * int sorted; + * int num_alloc; + * int (*comp)(); + * } STACK; + */ + + temp_sk_xm = sk_XMAP_new_null(); + for (i=0; ispec = clone_str(xm->spec, "cloning XMAP spec"); + temp_xm->pmap = clone_XMAP_pmap(xm->pmap, xm->spec); + + /* let's try without cloning the XMAP_METHOD_LIST, so that + * check_methp will work. + * temp_xm->methp = clone_XMAP_METHOD_LIST(xm->methp); + */ + temp_xm->methp = xm->methp; + + return temp_xm; +} + +XMAP_METHOD_LIST +*clone_XMAP_METHOD_LIST ( XMAP_METHOD_LIST *xm_l ) +{ + XMAP_METHOD_LIST *temp_xm_l; + + /* + * typedef struct _xmap_method_list_st { + * XMAP_METHOD *meth; + * struct _xmap_method_list_st *next; + * } XMAP_METHOD_LIST; + * + * Recursive cloning... + */ + + temp_xm_l = malloc(sizeof(XMAP_METHOD_LIST)); + if (xm_l->next) { + temp_xm_l->next = clone_XMAP_METHOD_LIST(xm_l->next); + } else { + temp_xm_l->next = NULL; + } + + temp_xm_l->meth = clone_XMAP_METHOD(xm_l->meth); + return temp_xm_l; +} + + +XMAP_METHOD +*clone_XMAP_METHOD ( XMAP_METHOD *xm_m ) +{ + XMAP_METHOD *temp_xm_m; + + /* + * typedef struct _xmap_method_st { + * char *prefix; + * STACK_OF(X509_OBJECT) *(*lookup)( void *this, + * const int type, const char *index, void *p ); + * void (*dump)(void *pmap); + * void (*free)(void *pmap); + * void *(*new) (const char *spec); + * } XMAP_METHOD; + */ + + + temp_xm_m = malloc(sizeof(XMAP_METHOD)); + + if (xm_m->prefix) { + temp_xm_m->prefix = clone_str(xm_m->prefix, + "cloning XMAP_METHOD prefix"); + } + + /* don't clone the following */ + temp_xm_m->lookup = xm_m->lookup; + temp_xm_m->dump = xm_m->dump; + temp_xm_m->free = xm_m->free; + temp_xm_m->new = xm_m->new; + + return temp_xm_m; +} + +void +*clone_XMAP_pmap ( void *pmap, char *spec ) +{ + void *t_pmap; + char *s; + int l, found; + XMAP_METHOD_LIST *p; + + s = strchr(spec, DICT_SEPARATOR); + l = (int)(s - spec) + 1; + + for(p=xmth, found = 0; ((!found) && (p));) { + if (strncasecmp(p->meth->prefix, spec, l-1) == 0) { + found = 1; + } else { + p = p->next; + } + } + + if (found) { + t_pmap = p->meth->new(&s[1]); + } + + return t_pmap; +} + + +IMPLEMENT_STACK_OF(XMAP) +#endif /* OPENSSL */ diff -BbruN freeswan-1.91.orig/pluto/xmap.h freeswan-1.91/pluto/xmap.h --- freeswan-1.91.orig/pluto/xmap.h Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/xmap.h Mon Jul 16 23:26:30 2001 @@ -0,0 +1,62 @@ +#ifndef XMAP_H +#define XMAP_H + +#include +#include +#include + +#include +#include +#include + +#include "x_sobj.h" + +typedef struct _xmap_method_st { + const char *prefix; + STACK_OF(X509_OBJECT) *(*lookup)( void *this, const int type, const char *index, void *p ); + void (*dump)(void *pmap); + void (*free)(void *pmap); + void *(*new) (const char *spec); +} XMAP_METHOD; + +typedef struct _xmap_method_list_st { + XMAP_METHOD *meth; + struct _xmap_method_list_st *next; +} XMAP_METHOD_LIST; + +typedef struct _xmap_st { + char *spec; + void *pmap; + XMAP_METHOD_LIST *methp; +} XMAP; + +DECLARE_STACK_OF(XMAP) + +#ifndef DICT_SEPARATOR +#define DICT_SEPARATOR ':' +#endif + +#define XMAP_UNKNOWN_TYPE 0 +#define XMAP_FILE_TYPE 1 +#define XMAP_DIR_TYPE 2 +#define XMAP_DB_TYPE 3 + +int XMAP_register(XMAP_METHOD *meth); +void XMAP_METHOD_LIST_free( void ); +int XMAP_unregister(const char *prefix); + +int X509_subjAltName_check_dns(X509 *x, const char *dns); +int X509_subjAltName_check_ip(X509 *x, const struct in_addr in); + +XMAP *XMAP_new(const char *spec); +STACK_OF(X509_OBJECT) *XMAP_lookup( XMAP *xm, const int type, const char *index, void *p ); +void XMAP_free(XMAP *xm); +void XMAP_dump(XMAP *xm); + +extern STACK_OF(XMAP) *clone_sk_XMAP ( STACK_OF(XMAP) *sk_xm ); +extern XMAP *clone_XMAP ( XMAP *xm ); +extern void *clone_XMAP_pmap ( void *pmap, char *spec ); +extern XMAP_METHOD_LIST *clone_XMAP_METHOD_LIST ( XMAP_METHOD_LIST *xm_l ); +extern XMAP_METHOD *clone_XMAP_METHOD ( XMAP_METHOD *xm_m ); + +#endif /* XMAP_H */ diff -BbruN freeswan-1.91.orig/pluto/xmap_db.c freeswan-1.91/pluto/xmap_db.c --- freeswan-1.91.orig/pluto/xmap_db.c Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/xmap_db.c Mon Jul 16 23:26:30 2001 @@ -0,0 +1,574 @@ +#ifdef OPENSSL +#if defined(HAVE_DB) || (HAVE_DB185) +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef HAVE_DB185 +#include +#else +#include +#endif + +#include +#include +#include + +#include "xmap_db.h" + +#include /* needed by constants.h */ +#include "constants.h" +#include "defs.h" +#include "log.h" + +static void XMAP_DB_dump(void *this); +static void XMAP_DB_free(void *this); +static void *XMAP_DB_new(const char *dbname); +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup( void *this, const int type, const char *index, void *p ); +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_cert_by_subject( XMAP_DB *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_cert_by_issuer( XMAP_DB *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_crl_by_issuer( XMAP_DB *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_cert_by_uid( XMAP_DB *xm, const char *uid ); +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_cert_by_dns( XMAP_DB *xm, const char *dns ); +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_cert_by_ip( XMAP_DB *xm, const struct in_addr ip); +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_ca_certs( XMAP_DB *xm ); + +#define TAGLEN 4 + +static unsigned char tag_cert[] = { 0x00, 0x00, 0x00, 0x00 }; +static unsigned char tag_subj[] = { 0x00, 0x00, 0x00, 0x01 }; +static unsigned char tag_csub[] = { 0x00, 0x00, 0x00, 0x02 }; +static unsigned char tag_uid[] = { 0x00, 0x00, 0x00, 0x03 }; +static unsigned char tag_crl[] = { 0x00, 0x00, 0x00, 0x04 }; +static unsigned char tag_ca[] = { 0x00, 0x00, 0x00, 0x05 }; +static unsigned char tag_dns[] = { 0x00, 0x00, 0x00, 0x06 }; +static unsigned char tag_ip[] = { 0x00, 0x00, 0x00, 0x07 }; + +#define DBZ(x) memset(&(x), 0, sizeof((x))) + +static XMAP_METHOD xmap_db_methods = { + "db", + XMAP_DB_lookup, + XMAP_DB_dump, + XMAP_DB_free, + XMAP_DB_new +}; + +void * +XMAP_DB_new(const char *dbname) +{ + XMAP_DB *ret; + + if ((ret = alloc_thing(XMAP_DB, "xmap_db")) == NULL) goto end; + if ((ret->dbname = clone_bytes(dbname, strlen(dbname)+1, "dbname")) == NULL) + goto end; + if ((ret->db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL)) == NULL) + goto end; + + ret->meth = &xmap_db_methods; + + return (void *)ret; + end: + if (ret->db) ret->db->close(ret->db); + if (ret->dbname) pfree(ret->dbname); + if (ret) pfree(ret); + return NULL; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup( void *this, const int type, const char *index, void *p ) +{ + XMAP_DB *xm = (XMAP_DB *)this; + + switch(type) { + case X509_LU_X509: + if (strcasecmp(index, "subject") == 0) + return XMAP_DB_lookup_cert_by_subject( xm, (X509_NAME *)p); + if (strcasecmp(index, "issuer") == 0) + return XMAP_DB_lookup_cert_by_issuer( xm, (X509_NAME *)p); + else if (strcasecmp(index, "uid") == 0) + return XMAP_DB_lookup_cert_by_uid( xm, (char *)p); + else if (strcasecmp(index, "dns") == 0) + return XMAP_DB_lookup_cert_by_dns( xm, (char *)p); + else if (strcasecmp(index, "ip") == 0) + return XMAP_DB_lookup_cert_by_ip( xm, *((struct in_addr *)p)); + else if (strcasecmp(index, "ca") == 0) + return XMAP_DB_lookup_ca_certs( xm ); + else + return NULL; + break; + case X509_LU_CRL: + if (strcasecmp(index, "issuer") == 0) + return XMAP_DB_lookup_crl_by_issuer( xm, (X509_NAME *)p); + else + return NULL; + break; + default: + return NULL; + } +} + +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_cert_by_subject(XMAP_DB *xm, X509_NAME *name) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + DBT k, v; + unsigned char *d, *dum; + unsigned int i, dlen; + + DBZ(k); + DBZ(v); + if (!xm->db) goto end; + dlen = i2d_X509_NAME(name, NULL); + if ((d = alloc_bytes(dlen + TAGLEN, "ASN.1 name")) == NULL) goto end; + dum = &d[TAGLEN]; + memcpy(d, tag_subj, TAGLEN); + i2d_X509_NAME(name, &dum); + k.data = d; + k.size = dlen + TAGLEN; + if (xm->db->get(xm->db, &k, &v, 0) == 0) { + u_int32_t c1, c2; + + memcpy((unsigned char *)&c1, v.data, sizeof(c1)); + c2 = ntohl(c1); + pfree(d); d = NULL; + dlen = SHA_DIGEST_LENGTH + TAGLEN; + if ((d = alloc_bytes(dlen, "SHA-1 tag")) == NULL) goto end; + memcpy(d, tag_cert, TAGLEN); + for(i=0; idb->get(xm->db, &k, &v2, 0) == 0) { + X509 *x; + dum = (unsigned char *)v2.data; + if ((x = d2i_X509(NULL, &dum, v2.size)) != NULL) { + X509_OBJECT *xo = X509_OBJECT_new( X509_LU_X509, x); + if (x) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); + } + } + } + pfree(d); d = NULL; + } + end: + if (d) pfree(d); + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_cert_by_issuer(XMAP_DB *xm, X509_NAME *name) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + DBT k, v; + unsigned char *d, *dum; + unsigned int i, dlen; + + DBZ(k); + DBZ(v); + if (!xm->db) goto end; + dlen = i2d_X509_NAME(name, NULL); + if ((d = alloc_bytes(dlen + TAGLEN, "ASN.1 name")) == NULL) goto end; + dum = &d[TAGLEN]; + memcpy(d, tag_subj, TAGLEN); + i2d_X509_NAME(name, &dum); + k.data = d; + k.size = dlen + TAGLEN; + if (xm->db->get(xm->db, &k, &v, 0) == 0) { + u_int32_t c1, c2; + + memcpy((unsigned char *)&c1, v.data, sizeof(c1)); + c2 = ntohl(c1); + pfree(d); d = NULL; + dlen = SHA_DIGEST_LENGTH + TAGLEN; + if ((d = alloc_bytes(dlen, "SHA-1 tag")) == NULL) goto end; + memcpy(d, tag_cert, TAGLEN); + for(i=0; idb->get(xm->db, &k, &v2, 0) == 0) { + X509 *x; + dum = (unsigned char *)v2.data; + if ((x = d2i_X509(NULL, &dum, v2.size)) != NULL) { + X509_OBJECT *xo = X509_OBJECT_new( X509_LU_X509, x); + if (x) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); + } + } + } + pfree(d); d = NULL; + } + end: + if (d) pfree(d); + return sk; +} + +static int +isCA( X509 *x ) +{ + X509_EXTENSION *ext; + BASIC_CONSTRAINTS *p = NULL; + int loc; + + loc = X509_get_ext_by_NID(x, NID_basic_constraints, -1); + if (loc >= 0) { + ext = X509_get_ext(x, loc); + if (ext) { + p = X509V3_EXT_d2i(ext); + if (! p->ca) { + BASIC_CONSTRAINTS_free(p); + return 0; + } else { + BASIC_CONSTRAINTS_free(p); + return 1; /* This is a CA certificate */ + } + } else + return 0; + } else + return 0; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_crl_by_issuer(XMAP_DB *xm, X509_NAME *name) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + DBT k, v; + unsigned char *d, *dum; + unsigned int i, dlen; + + DBZ(k); + DBZ(v); + if (!xm->db) goto end; + dlen = i2d_X509_NAME(name, NULL); + if ((d = alloc_bytes(dlen + TAGLEN, "ASN.1 name")) == NULL) goto end; + dum = &d[TAGLEN]; + memcpy(d, tag_csub, TAGLEN); + i2d_X509_NAME(name, &dum); + k.data = d; + k.size = dlen + TAGLEN; + if (xm->db->get(xm->db, &k, &v, 0) == 0) { + u_int32_t c1, c2; + + memcpy((unsigned char *)&c1, v.data, sizeof(c1)); + c2 = ntohl(c1); + pfree(d); d = NULL; + dlen = SHA_DIGEST_LENGTH + TAGLEN; + if ((d = alloc_bytes(dlen, "SHA-1 tag")) == NULL) goto end; + memcpy(d, tag_crl, TAGLEN); + for(i=0; idb->get(xm->db, &k, &v2, 0) == 0) { + X509_CRL *c; + dum = (unsigned char *)v2.data; + if ((c = d2i_X509_CRL(NULL, &dum, v2.size)) != NULL) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_CRL, c); + + if (xo) + sk_X509_OBJECT_push(sk, xo); + else + X509_CRL_free(c); + } + } + } + pfree(d); d = NULL; + } + end: + if (d) pfree(d); + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_ca_certs( XMAP_DB *xm ) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + DBT k, v; + unsigned char *d, *dum; + unsigned int i, dlen; + + DBZ(k); + DBZ(v); + if (!xm->db) goto end; + if ((d = alloc_bytes(TAGLEN, "CA tag")) == NULL) goto end; + memcpy(d, tag_ca, TAGLEN); + k.data = d; + k.size = TAGLEN; + if (xm->db->get(xm->db, &k, &v, 0) == 0) { + u_int32_t c1, c2; + + memcpy((unsigned char *)&c1, v.data, sizeof(c1)); + c2 = ntohl(c1); + pfree(d); d = NULL; + dlen = SHA_DIGEST_LENGTH + TAGLEN; + if ((d = alloc_bytes(dlen, "SHA-1 tag")) == NULL) goto end; + memcpy(d, tag_cert, TAGLEN); + for(i=0; idb->get(xm->db, &k, &v2, 0) == 0) { + X509 *x; + dum = (unsigned char *)v2.data; + if (((x = d2i_X509(NULL, &dum, v2.size)) != NULL) && (isCA(x))) { + X509_OBJECT *xo = X509_OBJECT_new( X509_LU_X509, x); + + if (xo) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); + } + } + } + pfree(d); d = NULL; + } + end: + if (d) pfree(d); + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_cert_by_uid(XMAP_DB *xm, const char *uid) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + DBT k, v; + unsigned char *d, *dum; + unsigned int i, ulen, dlen; + + DBZ(k); + DBZ(v); + if (!xm->db) goto end; + ulen = strlen(uid); + if ((d = alloc_bytes(ulen + TAGLEN, "uid tag")) == NULL) goto end; + memcpy(d, tag_uid, TAGLEN); + strncpy(&d[TAGLEN], uid, ulen); + k.data = d; + k.size = ulen + TAGLEN; + if (xm->db->get(xm->db, &k, &v, 0) == 0) { + u_int32_t c1, c2; + + memcpy((unsigned char *)&c1, v.data, sizeof(c1)); + c2 = ntohl(c1); + pfree(d); d = NULL; + dlen = SHA_DIGEST_LENGTH + TAGLEN; + if ((d = alloc_bytes(dlen, "SHA-1 tag")) == NULL) goto end; + memcpy(d, tag_cert, TAGLEN); + for(i=0; idb->get(xm->db, &k, &v2, 0) == 0) { + X509 *x; + dum = (unsigned char *)v2.data; + if ((x = d2i_X509(NULL, &dum, v2.size)) != NULL) { + X509_OBJECT *xo = X509_OBJECT_new( X509_LU_X509, x); + + if (xo) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); + } + } + } + pfree(d); d = NULL; + } + end: + if (d) pfree(d); + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_cert_by_dns(XMAP_DB *xm, const char *dns) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + DBT k, v; + unsigned char *d, *dum; + unsigned int i, ulen, dlen; + + DBZ(k); + DBZ(v); + if (!xm->db) goto end; + ulen = strlen(dns); + if ((d = alloc_bytes(ulen + TAGLEN, "dns tag")) == NULL) goto end; + memcpy(d, tag_dns, TAGLEN); + strncpy(&d[TAGLEN], dns, ulen); + k.data = d; + k.size = ulen + TAGLEN; + if (xm->db->get(xm->db, &k, &v, 0) == 0) { + u_int32_t c1, c2; + + memcpy((unsigned char *)&c1, v.data, sizeof(c1)); + c2 = ntohl(c1); + pfree(d); d = NULL; + dlen = SHA_DIGEST_LENGTH + TAGLEN; + if ((d = alloc_bytes(dlen, "SHA-1 tag")) == NULL) goto end; + memcpy(d, tag_cert, TAGLEN); + for(i=0; idb->get(xm->db, &k, &v2, 0) == 0) { + X509 *x; + dum = (unsigned char *)v2.data; + if ((x = d2i_X509(NULL, &dum, v2.size)) != NULL) { + if (X509_subjAltName_check_dns(x, dns)) { + X509_OBJECT *xo = X509_OBJECT_new( X509_LU_X509, x); + + if (xo) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); + } else + X509_free(x); + } + } + } + pfree(d); d = NULL; + } + end: + if (d) free(d); + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DB_lookup_cert_by_ip(XMAP_DB *xm, const struct in_addr ip) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + DBT k, v; + unsigned char *d, *dum; + unsigned int i, ulen, dlen; + + DBZ(k); + DBZ(v); + if (!xm->db) goto end; + ulen = sizeof(ip.s_addr); + if ((d = alloc_bytes(ulen + TAGLEN, "ip tag")) == NULL) goto end; + memcpy(d, tag_ip, TAGLEN); + memcpy(&d[TAGLEN], &ip.s_addr, ulen); + k.data = d; + k.size = ulen + TAGLEN; + if (xm->db->get(xm->db, &k, &v, 0) == 0) { + u_int32_t c1, c2; + + memcpy((unsigned char *)&c1, v.data, sizeof(c1)); + c2 = ntohl(c1); + pfree(d); d = NULL; + dlen = SHA_DIGEST_LENGTH + TAGLEN; + if ((d = alloc_bytes(dlen, "SHA-1 tag")) == NULL) goto end; + memcpy(d, tag_cert, TAGLEN); + for(i=0; idb->get(xm->db, &k, &v2, 0) == 0) { + X509 *x; + dum = (unsigned char *)v2.data; + + DBG(DBG_PARSING | DBG_RAW, + DBG_log("** v2 length: %d", v2.size); + ); + DBG(DBG_RAW, + DBG_dump("** v2: ", v2.data, v2.size); + ); + + if ((x = d2i_X509(NULL, &dum, v2.size)) != NULL) { + if (X509_subjAltName_check_ip(x, ip)) { + X509_OBJECT *xo = X509_OBJECT_new( X509_LU_X509, x); + + if (xo) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); + } + } else + X509_free(x); + } + } + pfree(d); d = NULL; + } + end: + if (d) pfree(d); + return sk; +} + +static void +XMAP_DB_dump(void *this) +{ + XMAP_DB *xm = (XMAP_DB *)this; + DBG(DBG_PARSING, + DBG_log("XMAP_DB: %s", xm->dbname); + ); +} + +static void +XMAP_DB_free(void *this) +{ + XMAP_DB *xm = (XMAP_DB *)this; + + if (!xm) return; + if (xm->dbname) pfree(xm->dbname); + if (xm->db) xm->db->close(xm->db); + pfree(xm); +} + +XMAP_METHOD * +XMAP_METHOD_db( void ) +{ + return (&xmap_db_methods); +} +#endif /* HAVE_DB */ +#endif /* OPENSSL */ diff -BbruN freeswan-1.91.orig/pluto/xmap_db.h freeswan-1.91/pluto/xmap_db.h --- freeswan-1.91.orig/pluto/xmap_db.h Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/xmap_db.h Mon Jul 16 23:26:30 2001 @@ -0,0 +1,27 @@ +#ifndef XMAP_DB_H +#define XMAP_DB_H + +#if defined(HAVE_DB) || defined(HAVE_DB185) + +#include +#include + +#ifdef HAVE_DB185 +#include +#else +#include +#endif + +#include "x_sobj.h" +#include "xmap.h" + +typedef struct xmap_db_st { + char *dbname; + DB *db; + XMAP_METHOD *meth; +} XMAP_DB; + +XMAP_METHOD *XMAP_METHOD_db( void ); + +#endif /* HAVE_DB */ +#endif /* XMAP_DB_H */ diff -BbruN freeswan-1.91.orig/pluto/xmap_dir.c freeswan-1.91/pluto/xmap_dir.c --- freeswan-1.91.orig/pluto/xmap_dir.c Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/xmap_dir.c Mon Jul 16 23:26:30 2001 @@ -0,0 +1,545 @@ +#ifdef OPENSSL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "xmap_dir.h" +#include "xmap.h" + +#include /* needed by constants.h */ +#include "constants.h" +#include "defs.h" +#include "log.h" + +static void XMAP_DIR_dump(void *this); +static void XMAP_DIR_free(void *this); +static void *XMAP_DIR_new(const char *dir); +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup( void *this, const int type, const char *index, void *p ); +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_cert_by_subject( XMAP_DIR *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_cert_by_issuer( XMAP_DIR *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_crl_by_issuer( XMAP_DIR *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_cert_by_uid( XMAP_DIR *xm, const char *uid ); +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_cert_by_dns( XMAP_DIR *xm, const char *dns ); +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_cert_by_ip( XMAP_DIR *xm, const struct in_addr ip ); +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_ca_certs( XMAP_DIR *xm ); + +static XMAP_METHOD xmap_dir_methods = { + "dir", + XMAP_DIR_lookup, + XMAP_DIR_dump, + XMAP_DIR_free, + XMAP_DIR_new +}; + +static void * +XMAP_DIR_new(const char *dir) +{ + XMAP_DIR *ret; + + if ((ret = alloc_thing(XMAP_DIR, "xmap_dir")) == NULL) goto end; + if ((ret->dir = clone_bytes(dir, strlen(dir)+1, "directory name")) == NULL) + goto end; + ret->meth = &xmap_dir_methods; + + return (void *)ret; + end: + if (ret->dir) pfree(ret->dir); + if (ret) pfree(ret); + return NULL; +} + +static int +isCA( X509 *x ) +{ + X509_EXTENSION *ext; + BASIC_CONSTRAINTS *p = NULL; + int loc; + + loc = X509_get_ext_by_NID(x, NID_basic_constraints, -1); + if (loc >= 0) { + ext = X509_get_ext(x, loc); + if (ext) { + p = X509V3_EXT_d2i(ext); + if (! p->ca) { + BASIC_CONSTRAINTS_free(p); + return 0; + } else { + BASIC_CONSTRAINTS_free(p); + return 1; /* This is a CA certificate */ + } + } else + return 0; + } else + return 0; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup( void *this, const int type, const char *index, void *p ) +{ + XMAP_DIR *xm = (XMAP_DIR *)this; + + switch(type) { + case X509_LU_X509: + if (strcasecmp(index, "subject") == 0) + return XMAP_DIR_lookup_cert_by_subject( xm, (X509_NAME *)p); + if (strcasecmp(index, "issuer") == 0) + return XMAP_DIR_lookup_cert_by_issuer( xm, (X509_NAME *)p); + else if (strcasecmp(index, "uid") == 0) + return XMAP_DIR_lookup_cert_by_uid( xm, (char *)p); + else if (strcasecmp(index, "dns") == 0) + return XMAP_DIR_lookup_cert_by_dns( xm, (char *)p); + else if (strcasecmp(index, "ip") == 0) + return XMAP_DIR_lookup_cert_by_ip( xm, *(struct in_addr *)p); + else if (strcasecmp(index, "ca") == 0) + return XMAP_DIR_lookup_ca_certs( xm ); + else + return NULL; + break; + case X509_LU_CRL: + if (strcasecmp(index, "issuer") == 0) + return XMAP_DIR_lookup_crl_by_issuer( xm, (X509_NAME *)p); + else + return NULL; + break; + default: + return NULL; + } +} + +static char hashval[PATH_MAX+1] = ""; +static char dirname[PATH_MAX+1] = ""; + +static int +hash_select(const struct dirent *de) +{ + int l = strlen(hashval); + + if (strncmp(de->d_name, hashval, l) == 0) { + return 1; + } else { + return 0; + } +} + +static int +select_files(const struct dirent *de) +{ + struct stat st; + char path[PATH_MAX+1]; + + snprintf(path, sizeof(path), "%s/%s", dirname, de->d_name); + if (lstat(path, &st) == 0) { + if (S_ISREG(st.st_mode)) + return 1; + else + return 0; + } else { + log("error in stat: %s", strerror(errno)); + return 0; + } +} + +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_cert_by_subject( XMAP_DIR *xm, X509_NAME *name ) +{ + char path[PATH_MAX+1]; + int n; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + struct dirent **flist; + + if (!sk) return sk; + snprintf(hashval, sizeof(hashval)-1, "%08lx.cert", X509_NAME_hash(name)); + n = scandir(xm->dir, &flist, hash_select, alphasort); + if (n < 0) + log("error on scandir: %s", strerror(errno)); + else { + int i; + + for(i=0; idir, flist[i]->d_name); + + if ((b = BIO_new_file(path, "r")) != NULL) { + X509 *x; + + /* Try a PEM load first, then try DER if it fails */ + if ((x = PEM_read_bio_X509(b, NULL, NULL, NULL)) == NULL) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + x = d2i_X509_bio(b, NULL); /* Try DER loading */ + } + + if (x) { + if (X509_NAME_cmp(X509_get_subject_name(x), name) == 0) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + + if (x) { + sk_X509_OBJECT_push(sk, xo); + } else + X509_free(x); + } else + X509_free(x); + } + + BIO_free(b); + } else { + ERR_print_errors_fp(stderr); + } + } + if (n > 0) free(flist); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_cert_by_issuer( XMAP_DIR *xm, X509_NAME *name ) +{ + char path[PATH_MAX+1]; + int n; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + struct dirent **flist; + + if (!sk) return sk; + snprintf(hashval, sizeof(hashval)-1, "%08lx.cert", X509_NAME_hash(name)); + n = scandir(xm->dir, &flist, hash_select, alphasort); + if (n < 0) + log("error on scandir: %s", strerror(errno)); + else { + int i; + + for(i=0; idir, flist[i]->d_name); + + if ((b = BIO_new_file(path, "r")) != NULL) { + X509 *x; + + /* Try a PEM load first, then try DER if it fails */ + if ((x = PEM_read_bio_X509(b, NULL, NULL, NULL)) == NULL) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + x = d2i_X509_bio(b, NULL); /* Try DER loading */ + } + + if (x) { + if (X509_NAME_cmp(X509_get_issuer_name(x), name) == 0) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + + if (x) { + sk_X509_OBJECT_push(sk, xo); + } else + X509_free(x); + } else + X509_free(x); + } + + BIO_free(b); + } else { + ERR_print_errors_fp(stderr); + } + } + if (n > 0) free(flist); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_ca_certs( XMAP_DIR *xm ) +{ + char path[PATH_MAX+1]; + int n; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + struct dirent **flist; + + if (!sk) return sk; + strncpy(dirname, xm->dir, sizeof(dirname)-1); + n = scandir(xm->dir, &flist, select_files, alphasort); + if (n < 0) + log("error in scandir: %s", strerror(errno)); + else { + int i; + + for(i=0; idir, flist[i]->d_name); + + if ((b = BIO_new_file(path, "r")) != NULL) { + X509 *x; + + /* Try a PEM load first, then try DER if it fails */ + if ((x = PEM_read_bio_X509(b, NULL, NULL, NULL)) == NULL) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + x = d2i_X509_bio(b, NULL); /* Try DER loading */ + } + + if (x) { + if (isCA(x)) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + + if (xo) { + sk_X509_OBJECT_push(sk, xo); + } else + X509_free(x); + } else + X509_free(x); + } + + BIO_free(b); + } else { + ERR_print_errors_fp(stderr); + } + } + if (n > 0) free(flist); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_crl_by_issuer( XMAP_DIR *xm, X509_NAME *name ) +{ + char path[PATH_MAX+1]; + int n; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + struct dirent **flist; + + if (!sk) return sk; + snprintf(hashval, sizeof(hashval)-1, "%08lx.crl", X509_NAME_hash(name)); + n = scandir(xm->dir, &flist, hash_select, alphasort); + if (n < 0) + log("error in scandir: %s", strerror(errno)); + else { + int i; + + for(i=0; idir, flist[i]->d_name); + + if ((b = BIO_new_file(path, "r")) != NULL) { + X509_CRL *c; + + /* Try a PEM load first, then try DER if it fails */ + if ((c = PEM_read_bio_X509_CRL(b, NULL, NULL, NULL)) == NULL) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + c = d2i_X509_CRL_bio(b, NULL); /* Try DER loading */ + } + + if (c) { + if (X509_NAME_cmp(X509_CRL_get_issuer(c), name) == 0) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_CRL, c); + if (xo) + sk_X509_OBJECT_push(sk, xo); + else + X509_CRL_free(c); + } else + X509_CRL_free(c); + } + + BIO_free(b); + } else { + ERR_print_errors_fp(stderr); + } + } + if (n > 0) free(flist); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_cert_by_uid( XMAP_DIR *xm, const char *uid ) +{ + char path[PATH_MAX+1]; + int n; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + struct dirent **flist; + + if (!sk) return sk; + snprintf(hashval, sizeof(hashval)-1, "uid-%s", uid); + n = scandir(xm->dir, &flist, hash_select, alphasort); + if (n < 0) + log("error in scandir: %s", strerror(errno)); + else { + int i; + + for(i=0; idir, flist[i]->d_name); + + if ((b = BIO_new_file(path, "r")) != NULL) { + X509 *x; + + /* Try a PEM load first, then try DER if it fails */ + if ((x = PEM_read_bio_X509(b, NULL, NULL, NULL)) == NULL) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + x = d2i_X509_bio(b, NULL); /* Try DER loading */ + } + + if (x) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); + } + + BIO_free(b); + } else { + ERR_print_errors_fp(stderr); + } + } + if (n > 0) free(flist); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_cert_by_dns( XMAP_DIR *xm, const char *dns ) +{ + char path[PATH_MAX+1]; + int n; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + struct dirent **flist; + + if (!sk) return sk; + snprintf(hashval, sizeof(hashval)-1, "dns-%s", dns); + n = scandir(xm->dir, &flist, hash_select, alphasort); + if (n < 0) + log("error in scandir: %s", strerror(errno)); + else { + int i; + + for(i=0; idir, flist[i]->d_name); + + if ((b = BIO_new_file(path, "r")) != NULL) { + X509 *x; + + /* Try a PEM load first, then try DER if it fails */ + if ((x = PEM_read_bio_X509(b, NULL, NULL, NULL)) == NULL) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + x = d2i_X509_bio(b, NULL); /* Try DER loading */ + } + + if (x) { + if (X509_subjAltName_check_dns(x, dns)) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); + } + } else { + X509_free(x); + } + + BIO_free(b); + } else { + ERR_print_errors_fp(stderr); + } + } + if (n > 0) free(flist); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_DIR_lookup_cert_by_ip( XMAP_DIR *xm, const struct in_addr ip ) +{ + char path[PATH_MAX+1]; + int n; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + struct dirent **flist; + + if (!sk) return sk; + + snprintf(hashval, sizeof(hashval)-1, "ip-%s", inet_ntoa(ip)); + n = scandir(xm->dir, &flist, hash_select, alphasort); + if (n < 0) + log("error in scandir: %s", strerror(errno)); + else { + int i; + + for(i=0; idir, flist[i]->d_name); + + if ((b = BIO_new_file(path, "r")) != NULL) { + X509 *x; + + /* Try a PEM load first, then try DER if it fails */ + if ((x = PEM_read_bio_X509(b, NULL, NULL, NULL)) == NULL) { + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + x = d2i_X509_bio(b, NULL); /* Try DER loading */ + } + + if (x) { + if (X509_subjAltName_check_ip(x, ip)) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); + } + } else { + X509_free(x); + } + + BIO_free(b); + } else { + ERR_print_errors_fp(stderr); + } + } + if (n > 0) free(flist); + } + return sk; +} + +static void +XMAP_DIR_dump(void *this) +{ + XMAP_DIR *xm = (XMAP_DIR *)this; + DBG_log("XMAP_DIR: %s", xm->dir); +} + +static void +XMAP_DIR_free(void *this) +{ + XMAP_DIR *xm = (XMAP_DIR *)this; + + if (!xm) return; + if (xm->dir) pfree(xm->dir); + free(xm); +} + +XMAP_METHOD * +XMAP_METHOD_dir( void ) +{ + return (&xmap_dir_methods); +} +#endif /* OPENSSL */ diff -BbruN freeswan-1.91.orig/pluto/xmap_dir.h freeswan-1.91/pluto/xmap_dir.h --- freeswan-1.91.orig/pluto/xmap_dir.h Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/xmap_dir.h Mon Jul 16 23:26:30 2001 @@ -0,0 +1,17 @@ +#ifndef XMAP_DIR_H +#define XMAP_DIR_H + +#include +#include + +#include "x_sobj.h" +#include "xmap.h" + +typedef struct xmap_dir_st { + char *dir; + XMAP_METHOD *meth; +} XMAP_DIR; + +XMAP_METHOD *XMAP_METHOD_dir( void ); + +#endif /* XMAP_DIR_H */ diff -BbruN freeswan-1.91.orig/pluto/xmap_file.c freeswan-1.91/pluto/xmap_file.c --- freeswan-1.91.orig/pluto/xmap_file.c Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/xmap_file.c Mon Jul 16 23:26:30 2001 @@ -0,0 +1,359 @@ +#ifdef OPENSSL +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "xmap.h" +#include "xmap_file.h" + +#include /* needed by constants.h */ +#include "constants.h" +#include "defs.h" +#include "log.h" + +static void XMAP_FILE_dump(void *this); +static void XMAP_FILE_free(void *this); +static void *XMAP_FILE_new(const char *file); +static int isCA( X509 *x ); +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup( void *this, const int type, const char *index, void *p ); +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_cert_by_subject( XMAP_FILE *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_cert_by_issuer( XMAP_FILE *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_crl_by_issuer( XMAP_FILE *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_cert_by_uid( XMAP_FILE *xm, const char *uid ); +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_cert_by_dns( XMAP_FILE *xm, const char *dns ); +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_cert_by_ip( XMAP_FILE *xm, const struct in_addr ip ); +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_ca_certs( XMAP_FILE *xm ); + +static XMAP_METHOD xmap_file_methods = { + "file", + XMAP_FILE_lookup, + XMAP_FILE_dump, + XMAP_FILE_free, + XMAP_FILE_new +}; + +/* Pattern is (ignoring lower/upper case -- + * uid: + */ +#define UID_REGEX \ +"^[[:space:]]*[Uu][Ii][Dd]:[[:space:]]*([[:alnum:]]+)[[:space:]]$" + +static int +isCA( X509 *x ) +{ + X509_EXTENSION *ext; + BASIC_CONSTRAINTS *p = NULL; + int loc; + + loc = X509_get_ext_by_NID(x, NID_basic_constraints, -1); + if (loc >= 0) { + ext = X509_get_ext(x, loc); + if (ext) { + p = X509V3_EXT_d2i(ext); + if (! p->ca) { + BASIC_CONSTRAINTS_free(p); + return 0; + } else { + BASIC_CONSTRAINTS_free(p); + return 1; /* This is a CA certificate */ + } + } else + return 0; + } else + return 0; +} + +XMAP_METHOD * +XMAP_METHOD_file( void ) +{ + return (&xmap_file_methods); +} + +static void * +XMAP_FILE_new(const char *file) +{ + XMAP_FILE *ret; + int re_code; + char errbuf[257]; + + if ((ret = alloc_thing(XMAP_FILE, "xmap_file")) == NULL) goto end; + if ((ret->file = clone_bytes(file, strlen(file)+1, "file name")) == NULL) + goto end; + if ((ret->bio = BIO_new_file(ret->file, "r")) == NULL) goto end; + + if ((re_code = regcomp(&ret->uidreg, UID_REGEX, REG_EXTENDED)) != 0) { + regerror(re_code, &ret->uidreg, errbuf, sizeof(errbuf-1)); + log("Regex Error: %s", errbuf); + goto end; + } + + ret->meth = &xmap_file_methods; + return (void *)ret; + end: + if (ret->bio) BIO_free(ret->bio); + if (ret->file) pfree(ret->file); + if (ret) pfree(ret); + return NULL; +} + +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup( void *this, const int type, const char *index, void *p ) +{ + XMAP_FILE *xm = (XMAP_FILE *)this; + + switch(type) { + case X509_LU_X509: + if (strcasecmp(index, "issuer") == 0) + { + return XMAP_FILE_lookup_cert_by_issuer( xm, (X509_NAME *)p); + } + if (strcasecmp(index, "subject") == 0) + { + return XMAP_FILE_lookup_cert_by_subject( xm, (X509_NAME *)p); + } + else if (strcasecmp(index, "uid") == 0) + { + return XMAP_FILE_lookup_cert_by_uid( xm, (char *)p); + } + else if (strcasecmp(index, "dns") == 0) + { + return XMAP_FILE_lookup_cert_by_dns( xm, (char *)p); + } + else if (strcasecmp(index, "ip") == 0) + { + return XMAP_FILE_lookup_cert_by_ip( xm, *((struct in_addr *)p)); + } + else if (strcasecmp(index, "ca") == 0) + { + return XMAP_FILE_lookup_ca_certs( xm ); + } + else + { + return NULL; + } + break; + case X509_LU_CRL: + if (strcasecmp(index, "issuer") == 0) + return XMAP_FILE_lookup_crl_by_issuer( xm, (X509_NAME *)p); + else + return NULL; + break; + default: + return NULL; + } +} + +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_cert_by_subject( XMAP_FILE *xm, X509_NAME *name ) +{ + X509 *x; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + + if (sk == NULL) return sk; + BIO_ctrl(xm->bio, BIO_CTRL_RESET, 0, NULL); + while ((x = PEM_read_bio_X509(xm->bio, NULL, NULL, NULL)) != NULL) { + if (X509_NAME_cmp(X509_get_subject_name(x), name) == 0) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) { + sk_X509_OBJECT_push(sk, xo); + } else + X509_free(x); + } else + X509_free(x); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_cert_by_issuer( XMAP_FILE *xm, X509_NAME *name ) +{ + X509 *x; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + + if (sk == NULL) return sk; + BIO_ctrl(xm->bio, BIO_CTRL_RESET, 0, NULL); + while ((x = PEM_read_bio_X509(xm->bio, NULL, NULL, NULL)) != NULL) { + if (X509_NAME_cmp(X509_get_issuer_name(x), name) == 0) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) { + sk_X509_OBJECT_push(sk, xo); + } else + X509_free(x); + } else + X509_free(x); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_ca_certs( XMAP_FILE *xm ) +{ + X509 *x; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + + if (sk == NULL) return sk; + BIO_ctrl(xm->bio, BIO_CTRL_RESET, 0, NULL); + while ((x = PEM_read_bio_X509(xm->bio, NULL, NULL, NULL)) != NULL) { + if (isCA(x)) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) { + sk_X509_OBJECT_push(sk, xo); + } else + X509_free(x); + } else + X509_free(x); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_crl_by_issuer( XMAP_FILE *xm, X509_NAME *name ) +{ + X509_CRL *c; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + + if (sk == NULL) return sk; + BIO_ctrl(xm->bio, BIO_CTRL_RESET, 0, NULL); + while ((c = PEM_read_bio_X509_CRL(xm->bio, NULL, NULL, NULL)) != NULL) { + if (X509_NAME_cmp(X509_CRL_get_issuer(c), name) == 0) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_CRL, c); + if (xo) { + sk_X509_OBJECT_push(sk, xo); + } else + X509_CRL_free(c); + } else + X509_CRL_free(c); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_cert_by_uid( XMAP_FILE *xm, const char *uid ) +{ + char line[BUFSIZ+1], user[BUFSIZ+1]; + regmatch_t pmatch[2]; + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + X509 *x; + + if (sk == NULL) return sk; + BIO_ctrl(xm->bio, BIO_CTRL_RESET, 0, NULL); + while (BIO_gets(xm->bio, line, sizeof(line)-1)) { + if (!regexec(&xm->uidreg, line, 2, pmatch, 0)) + if ((pmatch[1].rm_so != -1) && (pmatch[1].rm_eo != -1)) { + memset(user, 0, sizeof(user)); + strncpy(user, &line[pmatch[1].rm_so], + pmatch[1].rm_eo - pmatch[1].rm_so); + if (strcmp(uid, user) == 0) { + /* Found a match for the user id */ + if ((x = PEM_read_bio_X509(xm->bio, NULL, NULL, NULL)) != NULL) { + X509_OBJECT *xo = X509_OBJECT_new( X509_LU_X509, x); + if (xo) { + sk_X509_OBJECT_push(sk, xo); + } else + X509_free(x); + } + } + } + } + + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_cert_by_dns( XMAP_FILE *xm, const char *dns ) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + X509 *x; + int zap; + X509_OBJECT *xo; + + if (sk == NULL) return sk; + BIO_ctrl(xm->bio, BIO_CTRL_RESET, 0, NULL); + while ((x = PEM_read_bio_X509(xm->bio, NULL, NULL, NULL)) != NULL) { + zap = X509_subjAltName_check_dns(x, dns) ? 0 : 1; + + if (zap) + X509_free(x); + else { + xo = X509_OBJECT_new( X509_LU_X509, x); + if (xo) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); + } + } + + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_FILE_lookup_cert_by_ip( XMAP_FILE *xm, struct in_addr ip ) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + X509 *x; + int zap; + X509_OBJECT *xo; + + if (sk == NULL) { + DBG(DBG_PARSING, + DBG_log("sk is NULL, returning NULL."); + ); + return sk; + } + BIO_ctrl(xm->bio, BIO_CTRL_RESET, 0, NULL); + while ((x = PEM_read_bio_X509(xm->bio, NULL, NULL, NULL)) != NULL) { + zap = X509_subjAltName_check_ip(x, ip) ? 0 : 1; + + if (zap) + X509_free(x); + else { + xo = X509_OBJECT_new( X509_LU_X509, x); + if (xo) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); + } + } + + return sk; +} + +static void +XMAP_FILE_dump(void *this) +{ + XMAP_FILE *xm = (XMAP_FILE *)this; + DBG(DBG_CONTROL | DBG_PARSING, + DBG_log("XMAP_FILE: %s\n", xm->file); + ); +} + +static void +XMAP_FILE_free(void *this) +{ + XMAP_FILE *xm = (XMAP_FILE *)this; + + if (!xm) return; + regfree(&xm->uidreg); + if (xm->bio) BIO_free(xm->bio); + if (xm->file) pfree(xm->file); + pfree(xm); +} +#endif /* OPENSSL */ diff -BbruN freeswan-1.91.orig/pluto/xmap_file.h freeswan-1.91/pluto/xmap_file.h --- freeswan-1.91.orig/pluto/xmap_file.h Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/xmap_file.h Mon Jul 16 23:26:30 2001 @@ -0,0 +1,28 @@ +#ifndef XMAP_FILE_H +#define XMAP_FILE_H + +#include + +#include +#include +#include +#include + +#include "x_sobj.h" +#include "xmap.h" + +typedef struct xmap_file_st { + char *file; + BIO *bio; + regex_t uidreg; + regex_t ipreg; + XMAP_METHOD *meth; +} XMAP_FILE; + +XMAP_METHOD *XMAP_METHOD_file( void ); +#endif /* XMAP_FILE_H */ + + + + + diff -BbruN freeswan-1.91.orig/pluto/xmap_ldap.c freeswan-1.91/pluto/xmap_ldap.c --- freeswan-1.91.orig/pluto/xmap_ldap.c Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/xmap_ldap.c Mon Jul 16 23:26:30 2001 @@ -0,0 +1,1369 @@ +#ifdef OPENSSL +#ifdef HAVE_LDAP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "x_sobj.h" +#include "xmap.h" +#include "xmap_ldap.h" + +#include + +#include /* needed by constants.h */ +#include "constants.h" +#include "defs.h" +#include "log.h" +#include "whack.h" + +static void XMAP_LDAP_dump(void *this); +static void XMAP_LDAP_free(void *this); +static void *XMAP_LDAP_new(const char *ldap); +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup( void *this, const int type, const char *index, void *p ); +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_cert_by_subject( XMAP_LDAP *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_cert_by_issuer( XMAP_LDAP *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_crl_by_issuer( XMAP_LDAP *xm, X509_NAME *name ); +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_cert_by_uid( XMAP_LDAP *xm, const char *uid ); +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_cert_by_dns( XMAP_LDAP *xm, const char *dns ); +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_cert_by_ip( XMAP_LDAP *xm, const struct in_addr ip ); +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_ca_certs( XMAP_LDAP *xm ); +static char **make_attrs( const char *a ); +static void attrs_free( char **attrs ); + +char *find_filter( const char *index, const int type, flist *fl ); +char **find_attrs( const char *index, const int type, alist *al ); + +static XMAP_METHOD xmap_ldap_methods = { + "ldap", + XMAP_LDAP_lookup, + XMAP_LDAP_dump, + XMAP_LDAP_free, + XMAP_LDAP_new +}; + +#define HOST_REGEX "^([[:alnum:]]+)_host_name[[:space:]]*=[[:space:]]*([[:punct:][:alnum:]]+)" +#define PORT_REGEX "^([[:alnum:]]+)_port[[:space:]]*=[[:space:]]*([[:digit:]]+)" +#define BASE_REGEX "^([[:alnum:]]+)_base[[:space:]]*=[[:space:]]*([^[:space:]].*)" +#define TIMEOUT_REGEX "^([[:alnum:]]+)_timeout[[:space:]]*=[[:space:]]*([[:digit:]]+)" +#define BINDDN_REGEX "^([[:alnum:]]+)_bind_dn[[:space:]]*=[[:space:]]*([^[:space:]].*)" +#define BINDPW_REGEX "^([[:alnum:]]+)_password[[:space:]]*=[[:space:]]*([^[:space:]].*)" +#define FILTER_REGEX "^([[:alnum:]]+)_filter(:(([\\*[:alnum:]]+)(:([[:alnum:]]+))?))?[[:space:]]*=[[:space:]]*([^[:space:]].*)" +#define ATTRS_REGEX "^([[:alnum:]]+)_attributes(:(([\\*[:alnum:]]+)(:([[:alnum:]]+))?))?[[:space:]]*=[[:space:]]*([^[:space:]].*)" + +static void +insert_filter( const char *index, const int type, const char *filter, flist *fl ) +{ + int i; + char *f, *in; + + for(i=0; ((i < MAXFLIST) && (fl[i].index)) ;i++) + if ((strcasecmp(index, fl[i].index) == 0) && (fl[i].type == type)) break; + + if (i == MAXFLIST) return; /* No more room */ + if (fl[i].index) { + /* A replacement operation */ + if ((f = clone_bytes(filter, strlen(filter)+1, "filter")) == NULL) return; + pfree(fl[i].filter); + fl[i].filter = f; + } else { + if ((in = clone_bytes(index, strlen(index)+1, "index string")) == NULL) + return; + if ((f = clone_bytes(filter, strlen(filter)+1, "filter string")) == NULL) + { pfree(in); return; } + fl[i].index = in; + fl[i].type = type; + fl[i].filter = f; + + DBG(DBG_PARSING, + DBG_log("Insert filter: %d (%s,%d,%s)", i+1, in, type, f); + ); + } +} + +static void +insert_attrs( const char *index, const int type, const char *attr, alist *al ) +{ + int i, j; + char **af, *in; + + for(i=0; ((i < MAXFLIST) && (al[i].index)) ;i++) { + if ((strcasecmp(index, al[i].index) == 0) && (al[i].type == type)) { + break; + } + } + + if (i == MAXFLIST) return; /* No more room */ + if (al[i].index) { + /* A replacement operation */ + if ((af = make_attrs(attr)) == NULL) return; + attrs_free(al[i].attrs); + al[i].attrs = af; + } else { + if ((in = clone_bytes(index, strlen(index)+1, "index string")) == NULL) + return; + if ((af = make_attrs(attr)) == NULL) { pfree(in); return; } + al[i].index = in; + al[i].type = type; + al[i].attrs = af; + DBG(DBG_PARSING, + DBG_log("Insert attribute: %d (%s,%d)", i+1, in, type); + ); + for(j=0; af[j]; j++) + DBG(DBG_PARSING, + DBG_log("Attribute %d: %s", j+1, af[j]); + ); + } +} + +char * +find_filter( const char *index, const int type, flist *fl ) +{ + int i, OKind; + unsigned char OK, indOK, typeOK; + + OK = 0x00; + for(i=0, OKind=0; ((i < MAXFLIST) && (fl[i].index)); i++) { + typeOK = (fl[i].type == X509_LU_FAIL) ? 0x01 : + ((fl[i].type == type) ? 0x04 : 0); + indOK = (strcasecmp(fl[i].index, "*") == 0) ? 0x02 : + ((strcasecmp(fl[i].index, index) == 0) ? 0x08 : 0); + if ((typeOK | indOK) > OK) { OKind = i; OK = typeOK | indOK; } + } + + return fl[OKind].filter; +} + +char ** +find_attrs( const char *index, const int type, alist *al ) +{ + int i, OKind; + unsigned char OK, indOK, typeOK; + + OK = 0x00; + for(i=0, OKind=0; ((i < MAXFLIST) && (al[i].index)); i++) { + typeOK = (al[i].type == X509_LU_FAIL) ? 0x01 : + ((al[i].type == type) ? 0x04 : 0); + indOK = (strcasecmp(al[i].index, "*") == 0) ? 0x02 : + ((strcasecmp(al[i].index, index) == 0) ? 0x08 : 0); + if ((typeOK | indOK) > OK) { OKind = i; OK = typeOK | indOK; } + } + + return al[OKind].attrs; +} + +static void +extract_re_sub( const char *buf, regmatch_t *rm, char **lv) +{ + if (!buf || !lv || !rm) return; + if (*lv) return; + if ((rm->rm_so == -1) || (rm->rm_eo == -1)) return; + if ((*lv = alloc_bytes(rm->rm_eo - rm->rm_so + 1, "subexpression")) == NULL) + return; + strncpy(*lv, &buf[rm->rm_so], rm->rm_eo - rm->rm_so); + (*lv)[rm->rm_eo - rm->rm_so] = '\0'; +} + +static char ** +make_attrs( const char *a ) +{ + char *s = clone_bytes(a, strlen(a)+1, "attribute list"); + char *at; + int i = 0, j; + char **ret = NULL; + const char *delim = ", "; + + if (!s) return NULL; + at = strtok(s, delim); + while (at != NULL) { + i++; + at = strtok(NULL, delim); + } + ret = alloc_bytes((i+1) * sizeof(char *), "attribute array"); + if (!ret) { pfree(s); return NULL; } + for(j=0; j<=i; j++) ret[j] = NULL; + pfree(s); + + if ((s = clone_bytes(a, strlen(a)+1, "attribute list")) == NULL) return NULL; + at = strtok(s, delim); + i = 0; + while (at != NULL) { + if ((ret[i++] = clone_bytes(at, strlen(at)+1, "attribute")) == NULL) { + for(i=0; ret[i]; i++) pfree(ret[i]); + pfree(ret); + pfree(s); + return NULL; + } + at = strtok(NULL, delim); + } + + pfree(s); + return ret; +} + +static void +attrs_free( char **attrs ) +{ + int i=0; + + for(i=0; attrs[i]; i++) pfree(attrs[i]); + pfree(attrs); +} + +static jmp_buf env; +static void +ldap_timeout(int unused_sig __attribute__((unused))) +{ + longjmp(env, 1); +} + +static int +open_bind( XMAP_LDAP *xm ) +{ + void (*saved_alarm)(int); + + if ((saved_alarm = signal(SIGALRM, ldap_timeout)) == SIG_ERR) { + log("signal: %s", strerror(errno)); + return 0; + } + + alarm(xm->ldap_timeout); + if (setjmp(env) == 0) { + if ((xm->ld = ldap_open(xm->ldap_host, xm->ldap_port)) == NULL) { + alarm(0); /* turn it off */ + DBG(DBG_PARSING, + DBG_log("Open to %s:%d failed", xm->ldap_host, xm->ldap_port); + ); + loglog(RC_LOG_SERIOUS, "ldap_open: %s", strerror(errno)); + return 0; + } + } else { + DBG(DBG_PARSING, + DBG_log("Open to %s:%d failed", xm->ldap_host, xm->ldap_port); + ); + loglog(RC_LOG_SERIOUS, "ldap_open: Connection timed out."); + return 0; + } + alarm(0); + + if ((ldap_bind_s(xm->ld, xm->ldap_bindDN, xm->ldap_bindPW, + LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS) return 0; + + return 1; +} + +void * +XMAP_LDAP_new(const char *ldapspec) +{ + char *ls = NULL, *s, *ldapvar = NULL, *ldapfile; + FILE *fp; + XMAP_LDAP *ret = NULL; + int i, re_code; + char re_err[256]; + regmatch_t re_match[10]; + + regex_t host_re; + regex_t port_re; + regex_t timeout_re; + regex_t base_re; + regex_t binddn_re; + regex_t bindpw_re; + regex_t filter_re; + regex_t attrs_re; + + /* Default values */ + char *ldap_host = clone_bytes("localhost", strlen("localhost")+1, + "ldap_host"); + int ldap_port = LDAP_PORT; + int ldap_timeout = 10; /* seconds */ + char *ldap_bindDN = clone_bytes("", 1, "bindDN"); + char *ldap_bindPW = clone_bytes("", 1, "bindPW"); + char *ldap_base = NULL; + flist ldap_filter[MAXFLIST]; + alist ldap_attrs[MAXFLIST]; + + memset(ldap_filter, 0, sizeof(ldap_filter)); + insert_filter("*", X509_LU_FAIL, "(cn=%s)", ldap_filter); + + memset(ldap_attrs, 0, sizeof(ldap_attrs)); + insert_attrs("*", X509_LU_FAIL, "usercertificate, usercertificate;binary, cacertificate, cacertificate;binary", ldap_attrs); + + if ((re_code = regcomp(&host_re, HOST_REGEX, REG_EXTENDED)) != 0) { + regerror(re_code, &host_re, re_err, sizeof(re_err)); + log("Regex error: %s", re_err); + goto end; + } + + if ((re_code = regcomp(&port_re, PORT_REGEX, REG_EXTENDED)) != 0) { + regerror(re_code, &port_re, re_err, sizeof(re_err)); + log("Regex error: %s", re_err); + goto end; + } + + if ((re_code = regcomp(&base_re, BASE_REGEX, REG_EXTENDED)) != 0) { + regerror(re_code, &base_re, re_err, sizeof(re_err)); + log("Regex error: %s", re_err); + goto end; + } + + if ((re_code = regcomp(&timeout_re, TIMEOUT_REGEX, REG_EXTENDED)) != 0) { + regerror(re_code, &timeout_re, re_err, sizeof(re_err)); + log("Regex error: %s", re_err); + goto end; + } + + if ((re_code = regcomp(&binddn_re, BINDDN_REGEX, REG_EXTENDED)) != 0) { + regerror(re_code, &binddn_re, re_err, sizeof(re_err)); + log("Regex error: %s", re_err); + goto end; + } + + if ((re_code = regcomp(&bindpw_re, BINDPW_REGEX, REG_EXTENDED)) != 0) { + regerror(re_code, &bindpw_re, re_err, sizeof(re_err)); + log("Regex error: %s", re_err); + goto end; + } + + if ((re_code = regcomp(&filter_re, FILTER_REGEX, REG_EXTENDED)) != 0) { + regerror(re_code, &filter_re, re_err, sizeof(re_err)); + log("Regex error: %s", re_err); + goto end; + } + + if ((re_code = regcomp(&attrs_re, ATTRS_REGEX, REG_EXTENDED)) != 0) { + regerror(re_code, &attrs_re, re_err, sizeof(re_err)); + log("Regex error: %s", re_err); + goto end; + } + + if ((!ldap_host) || (!ldap_bindDN) || (!ldap_bindPW) || + (!ldap_filter) || (!ldap_attrs)) goto end; + + if (!ldapspec) goto end; + ls = clone_bytes(ldapspec, strlen(ldapspec)+1, "ldap spec"); + if (!ls) goto end; + s = strchr(ls, ':'); + ldapfile = ls; + if (s) { + ldapvar = clone_bytes(&s[1], strlen(&s[1])+1, "ldap name"); + *s = '\0'; + } else { + ldapvar = NULL; + } + + fp = fopen( ldapfile, "r" ); + if (!fp) { + perror("fopen"); + goto end; + } + + while (!feof(fp)) { + char buf[BUFSIZ], *ptr; + + if (fgets(buf, sizeof(buf), fp)) { + int l; + + for(ptr = buf; ((*ptr) && (isspace(*ptr))); ptr++); + if (! *ptr) continue; /* Blank Line */ + if (*ptr == '#') continue; /* Comment */ + l = strlen(buf)-1; + while ((l > 0) && (isspace(buf[l]))) { buf[l] = '\0'; l--; } + + /* Check for host name spec */ + if ((re_code = regexec(&host_re, buf, 10, re_match, 0)) == 0) { + char *lv = NULL; + + extract_re_sub(buf, &re_match[1], &lv); + if (!ldapvar) extract_re_sub(buf, &re_match[1], &ldapvar); + if (strcmp(ldapvar, lv) == 0) { + if (ldap_host) { pfree(ldap_host); ldap_host = NULL; } + extract_re_sub(buf, &re_match[2], &ldap_host); + } + pfree(lv); + } + + /* Check for port spec */ + if ((re_code = regexec(&port_re, buf, 10, re_match, 0)) == 0) { + char *lv = NULL; + + extract_re_sub(buf, &re_match[1], &lv); + if (!ldapvar) extract_re_sub(buf, &re_match[1], &ldapvar); + if (strcmp(ldapvar, lv) == 0) { + char *ps = NULL; + + extract_re_sub(buf, &re_match[2], &ps); + ldap_port = atoi(ps); + pfree(ps); + } + pfree(lv); + } + + /* Check for base spec */ + if ((re_code = regexec(&base_re, buf, 10, re_match, 0)) == 0) { + char *lv = NULL; + + extract_re_sub(buf, &re_match[1], &lv); + if (!ldapvar) extract_re_sub(buf, &re_match[1], &ldapvar); + if (strcmp(ldapvar, lv) == 0) { + if (ldap_base) { free(ldap_base); ldap_base = NULL; } + extract_re_sub(buf, &re_match[2], &ldap_base); + } + pfree(lv); + } + + /* Check for timeout spec */ + if ((re_code = regexec(&timeout_re, buf, 10, re_match, 0)) == 0) { + char *lv = NULL; + + extract_re_sub(buf, &re_match[1], &lv); + if (!ldapvar) extract_re_sub(buf, &re_match[1], &ldapvar); + if (strcmp(ldapvar, lv) == 0) { + char *to = NULL; + + extract_re_sub(buf, &re_match[2], &to); + ldap_timeout = atoi(to); + free(to); + } + pfree(lv); + } + + /* Check for bind DN spec */ + if ((re_code = regexec(&binddn_re, buf, 10, re_match, 0)) == 0) { + char *lv = NULL; + + extract_re_sub(buf, &re_match[1], &lv); + if (!ldapvar) extract_re_sub(buf, &re_match[1], &ldapvar); + if (strcmp(ldapvar, lv) == 0) { + if (ldap_bindDN) { free(ldap_bindDN); ldap_bindDN = NULL; } + extract_re_sub(buf, &re_match[2], &ldap_bindDN); + } + pfree(lv); + } + + /* Check for bind PW spec */ + if ((re_code = regexec(&bindpw_re, buf, 10, re_match, 0)) == 0) { + char *lv = NULL; + + extract_re_sub(buf, &re_match[1], &lv); + if (!ldapvar) extract_re_sub(buf, &re_match[1], &ldapvar); + if (strcmp(ldapvar, lv) == 0) { + if (ldap_bindPW) { free(ldap_bindPW); ldap_bindPW = NULL; } + extract_re_sub(buf, &re_match[2], &ldap_bindPW); + } + pfree(lv); + } + + /* Check for filter spec */ + if ((re_code = regexec(&filter_re, buf, 10, re_match, 0)) == 0) { + char *lv = NULL; + + extract_re_sub(buf, &re_match[1], &lv); + if (!ldapvar) extract_re_sub(buf, &re_match[1], &ldapvar); + if (strcmp(ldapvar, lv) == 0) { + char *filt = NULL, *sf = NULL, *ssf = NULL; + int ssftype = X509_LU_FAIL; /* Use this as a catchall */ + + if (re_match[2].rm_so != -1) { + extract_re_sub(buf, &re_match[4], &sf); + if (re_match[5].rm_so != -1) { + extract_re_sub(buf, &re_match[6], &ssf); + if (strcasecmp(ssf, "cert") == 0) + ssftype = X509_LU_X509; + else if (strcasecmp(ssf, "crl") == 0) + ssftype = X509_LU_CRL; + else + ssftype = X509_LU_RETRY; /* Use as an "invalid" value */ + pfree(ssf); + } + } + extract_re_sub(buf, &re_match[7], &filt); + if (ssftype != X509_LU_RETRY) + insert_filter((sf == NULL) ? "*" : sf, ssftype, filt, ldap_filter); + else + if (filt) pfree(filt); + if (sf) pfree(sf); + } + pfree(lv); + } + + /* Check for attributes spec */ + if ((re_code = regexec(&attrs_re, buf, 10, re_match, 0)) == 0) { + char *lv = NULL; + + extract_re_sub(buf, &re_match[1], &lv); + if (!ldapvar) extract_re_sub(buf, &re_match[1], &ldapvar); + if (strcmp(ldapvar, lv) == 0) { + char *attr = NULL; + char *sf = NULL, *ssf = NULL; + int ssftype = X509_LU_FAIL; /* Use this as a catchall */ + + if (re_match[2].rm_so != -1) { + extract_re_sub(buf, &re_match[4], &sf); + if (re_match[5].rm_so != -1) { + extract_re_sub(buf, &re_match[6], &ssf); + if (strcasecmp(ssf, "cert") == 0) + ssftype = X509_LU_X509; + else if (strcasecmp(ssf, "crl") == 0) + ssftype = X509_LU_CRL; + else if (strcasecmp(ssf, "*") == 0) + ssftype = X509_LU_FAIL; + else + ssftype = X509_LU_RETRY; /* Use as an "invalid" value */ + pfree(ssf); + } + } + extract_re_sub(buf, &re_match[7], &attr); + if (ssftype != X509_LU_RETRY) + insert_attrs((sf == NULL) ? "*" : sf, ssftype, attr, ldap_attrs); + else + if (attr) pfree(attr); + if (sf) pfree(sf); + } + pfree(lv); + } + + } + } + + if (!ldap_base) goto end; /* No search base - and we can't default to one */ + + if ((ret = alloc_thing(XMAP_LDAP, "xmap_ldap")) == NULL) goto end; + + ret->ldapsource = ldapvar; + ret->ldap_host = ldap_host; + ret->ldap_port = ldap_port; + ret->ldap_base = ldap_base; + ret->ldap_timeout = ldap_timeout; + ret->ldap_bindDN = ldap_bindDN; + ret->ldap_bindPW = ldap_bindPW; + memcpy(ret->ldap_filter, ldap_filter, MAXFLIST * sizeof(flist)); + memcpy(ret->ldap_attrs, ldap_attrs, MAXFLIST * sizeof(alist)); + + fclose(fp); fp = NULL; + + if (!open_bind(ret)) goto end; + + if (ls) pfree(ls); + return (void *)ret; + + end: + if (ldap_host) pfree(ldap_host); + if (ldap_base) pfree(ldap_base); + if (ldap_bindDN) pfree(ldap_bindDN); + if (ldap_bindPW) pfree(ldap_bindPW); + for(i=0; ldap_filter[i].index; i++) + { pfree(ldap_filter[i].index); pfree(ldap_filter[i].filter); } + for(i=0; ldap_attrs[i].index; i++) + { pfree(ldap_attrs[i].index); attrs_free(ldap_attrs[i].attrs); } + if (ldapvar) pfree(ldapvar); + if (ls) pfree(ls); + if (fp) fclose(fp); + return NULL; +} + +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup( void *this, const int type, const char *index, void *p ) +{ + XMAP_LDAP *xm = (XMAP_LDAP *)this; + + if (type == X509_LU_X509) { + if (strcasecmp(index, "subject") == 0) + return XMAP_LDAP_lookup_cert_by_subject(xm, (X509_NAME *)p); + if (strcasecmp(index, "issuer") == 0) + return XMAP_LDAP_lookup_cert_by_issuer(xm, (X509_NAME *)p); + else if (strcasecmp(index, "uid") == 0) + return XMAP_LDAP_lookup_cert_by_uid(xm, (char *)p); + else if (strcasecmp(index, "dns") == 0) + return XMAP_LDAP_lookup_cert_by_dns(xm, (char *)p); + else if (strcasecmp(index, "ip") == 0) + return XMAP_LDAP_lookup_cert_by_ip(xm, *((struct in_addr *)p)); + else if (strcasecmp(index, "ca") == 0) + return XMAP_LDAP_lookup_ca_certs( xm ); + else + return NULL; + } else if (type == X509_LU_CRL) { + if (strcasecmp(index, "issuer") == 0) + return XMAP_LDAP_lookup_crl_by_issuer(xm, (X509_NAME *)p); + else + return NULL; + } else { + log("Unknown search type"); + return NULL; + } +} + +static int +ASN1_UTCTIME_cmp(ASN1_UTCTIME *a, ASN1_UTCTIME *b) +{ + char buff1[14],buff2[14],*p; + int i,j; + + /* Degenerate cases */ + if (!a && !b) return 0; + if (a && !b) return 1; + if (!a && b) return -1; + + memset(buff1, 0, sizeof(buff1)); + memset(buff2, 0, sizeof(buff2)); + + p=buff1; + i=a->length; + if ((i < 11) || (i > 17)) return(0); + memcpy(p,a->data,12); + + p=buff2; + j=b->length; + if ((j < 11) || (j > 17)) return(0); + memcpy(p,b->data,12); + + /* Correct for Y2K */ + i=(buff1[0]-'0')*10+(buff1[1]-'0'); + if (i < 50) i+=100; /* cf. RFC 2459 */ + j=(buff2[0]-'0')*10+(buff2[1]-'0'); + if (j < 50) j+=100; + + if (i < j) return (-1); + if (i > j) return (1); + + i=strcmp(buff1,buff2); + + if (i == 0) + return 0; + else if (i < 0) + return(-1); + else + return(1); +} + +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_cert_by_subject( XMAP_LDAP *xm, X509_NAME *name ) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + char *str, *s1, *ff, **af; + int i, j, tlen, rc; + LDAPMessage *res = NULL, *ent = NULL; + struct timeval tv; + struct berval **bv; + + if (!sk) return NULL; + if (!xm->ld) + if (!open_bind(xm)) return NULL; + +/* + * Searching by 'common name' alone is wrong. Will let the code + * from the original author remain until a better solution is found. + * + * // First find the 'common name' attribute from the subject + * for(i=0; iobject); + * + * if (nid == NID_commonName) { + * if (!(str = alloc_bytes(ASN1_STRING_length(ne->value)+1, "common name"))) + * return sk; + * memset(str, 0, ASN1_STRING_length(ne->value)+1); + * memcpy(str, ASN1_STRING_data(ne->value), + * ASN1_STRING_length(ne->value)); + * break; + * } + * } + */ + +/* Use the whole DN */ + str = X509_NAME_oneline(name, NULL, 0); + + ff = find_filter("subject", X509_LU_X509, xm->ldap_filter); + af = find_attrs("subject", X509_LU_X509, xm->ldap_attrs); + tlen = strlen(ff) + strlen(str); + if ((s1 = alloc_bytes(tlen, "filter pattern")) != NULL) { + snprintf(s1, tlen, ff, str); + tv.tv_sec = xm->ldap_timeout; tv.tv_usec = 0; + rc = ldap_search_st(xm->ld, xm->ldap_base, LDAP_SCOPE_SUBTREE, + s1, af, 0, + &tv, &res); + if (rc == LDAP_SUCCESS) { + for(ent = ldap_first_entry(xm->ld, res); ent ; + ent = ldap_next_entry(xm->ld, ent)) { + for(i = 0; af[i]; i++) { + bv = ldap_get_values_len(xm->ld, ent, af[i]); + if (bv) { + for(j=0; bv[j]; j++) { + unsigned char *p; + X509 *x; + + + p = bv[j]->bv_val; + x = d2i_X509(NULL, &p, bv[j]->bv_len); + if (x) { + + if (X509_NAME_cmp(X509_get_subject_name(x), name) == 0) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) { + int i, found = 0; + + for(i=0; (!found) && (idata.x509) == 0) + found = 1; + } + if (!found) + sk_X509_OBJECT_push(sk, xo); + else { + X509_free(x); /* duplicate of existing item */ + } + } else { + X509_free(x); /* cannot allocate X509_OBJECT */ + } + } else { + X509_free(x); /* subject name doesn't match */ + } + } + } + ldap_value_free_len(bv); + } + } + } + } else { + log("ldap_search_st error: %s", ldap_err2string(rc)); + ldap_unbind(xm->ld); + xm->ld = NULL; + } + pfree(s1); + } + pfree(str); + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_cert_by_issuer( XMAP_LDAP *xm, X509_NAME *name ) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + char *str, *s1, *ff, **af; + int i, j, tlen, rc; + LDAPMessage *res = NULL, *ent = NULL; + struct timeval tv; + struct berval **bv; + + if (!sk) return NULL; + if (!xm->ld) + if (!open_bind(xm)) return NULL; + + str = X509_NAME_oneline(name, NULL, 0); + + ff = find_filter("issuer", X509_LU_X509, xm->ldap_filter); + af = find_attrs("issuer", X509_LU_X509, xm->ldap_attrs); + tlen = strlen(ff) + strlen(str); + if ((s1 = alloc_bytes(tlen, "filter pattern")) != NULL) { + snprintf(s1, tlen, ff, str); + tv.tv_sec = xm->ldap_timeout; tv.tv_usec = 0; + rc = ldap_search_st(xm->ld, xm->ldap_base, LDAP_SCOPE_SUBTREE, + s1, af, 0, + &tv, &res); + if (rc == LDAP_SUCCESS) { + for(ent = ldap_first_entry(xm->ld, res); ent ; + ent = ldap_next_entry(xm->ld, ent)) { + for(i = 0; af[i]; i++) { + bv = ldap_get_values_len(xm->ld, ent, af[i]); + if (bv) { + for(j=0; bv[j]; j++) { + unsigned char *p; + X509 *x; + + + p = bv[j]->bv_val; + x = d2i_X509(NULL, &p, bv[j]->bv_len); + if (x) { + + if (X509_NAME_cmp(X509_get_issuer_name(x), name) == 0) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) { + int i, found = 0; + + for(i=0; (!found) && (idata.x509) == 0) + found = 1; + } + if (!found) + sk_X509_OBJECT_push(sk, xo); + else { + X509_free(x); /* duplicate of existing item */ + } + } else { + X509_free(x); /* cannot allocate X509_OBJECT */ + } + } else { + X509_free(x); /* subject name doesn't match */ + } + } + } + ldap_value_free_len(bv); + } + } + } + } else { + log("ldap_search_st error: %s", ldap_err2string(rc)); + ldap_unbind(xm->ld); + xm->ld = NULL; + } + pfree(s1); + } + pfree(str); + return sk; +} + +static int +isCA( X509 *x ) +{ + X509_EXTENSION *ext; + BASIC_CONSTRAINTS *p = NULL; + int loc; + + loc = X509_get_ext_by_NID(x, NID_basic_constraints, -1); + if (loc >= 0) { + ext = X509_get_ext(x, loc); + if (ext) { + p = X509V3_EXT_d2i(ext); + if (! p->ca) { + BASIC_CONSTRAINTS_free(p); + return 0; + } else { + BASIC_CONSTRAINTS_free(p); + return 1; /* This is a CA certificate */ + } + } else + return 0; + } else + return 0; +} + +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_ca_certs( XMAP_LDAP *xm ) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + char *ff, **af; + int i, j, rc; + LDAPMessage *res = NULL, *ent = NULL; + struct timeval tv; + struct berval **bv; + + if (!sk) return NULL; + if (!xm->ld) + if (!open_bind(xm)) return NULL; + + ff = find_filter("ca", X509_LU_X509, xm->ldap_filter); + af = find_attrs("ca", X509_LU_X509, xm->ldap_attrs); + tv.tv_sec = xm->ldap_timeout; tv.tv_usec = 0; + rc = ldap_search_st(xm->ld, xm->ldap_base, LDAP_SCOPE_SUBTREE, + ff, af, 0, &tv, &res); + if (rc == LDAP_SUCCESS) { + for(ent = ldap_first_entry(xm->ld, res); ent ; + ent = ldap_next_entry(xm->ld, ent)) { + for(i = 0; af[i]; i++) { + bv = ldap_get_values_len(xm->ld, ent, af[i]); + if (bv) { + for(j=0; bv[j]; j++) { + unsigned char *p; + X509 *x; + + p = bv[j]->bv_val; + x = d2i_X509(NULL, &p, bv[j]->bv_len); + if ((x) && (isCA(x))) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) { + int i, found = 0; + + for(i=0; (!found) && (idata.x509) == 0) + found = 1; + } + if (!found) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); /* duplicate of existing item */ + } else + X509_free(x); /* cannot allocate X509_OBJECT */ + } else + X509_free(x); /* subject name doesn't match */ + } + ldap_value_free_len(bv); + } + } + } + } else { + log("ldap_search_st error: %s", ldap_err2string(rc)); + ldap_unbind(xm->ld); + xm->ld = NULL; + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_crl_by_issuer( XMAP_LDAP *xm, X509_NAME *name ) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + STACK_OF(X509_NAME_ENTRY) *ns = name->entries; + char *str, *s1, *ff, **af; + int i, j, tlen, rc; + LDAPMessage *res = NULL, *ent = NULL; + struct timeval tv; + struct berval **bv; + + if (!sk) return NULL; + if (!xm->ld) + if (!open_bind(xm)) return NULL; + + /* First find the 'common name' attribute from the subject */ + for(i=0; iobject); + + if (nid == NID_commonName) { + if (!(str = alloc_bytes(ASN1_STRING_length(ne->value)+1, + "common name"))) + return sk; + memset(str, 0, ASN1_STRING_length(ne->value)+1); + memcpy(str, ASN1_STRING_data(ne->value), + ASN1_STRING_length(ne->value)); + break; + } + } + ff = find_filter("issuer", X509_LU_CRL, xm->ldap_filter); + af = find_attrs("issuer", X509_LU_CRL, xm->ldap_attrs); + tlen = strlen(ff) + strlen(str); + if ((s1 = alloc_bytes(tlen, "filter pattern")) != NULL) { + snprintf(s1, tlen, ff, str); + tv.tv_sec = xm->ldap_timeout; tv.tv_usec = 0; + DBG(DBG_PARSING, + DBG_log("LDAP search: \"%s\"", s1); + ); + for(i=0; af[i]; i++) { + DBG(DBG_PARSING, + DBG_log("Attr %d: %s", i+1, af[i]); + ); + } + rc = ldap_search_st(xm->ld, xm->ldap_base, LDAP_SCOPE_SUBTREE, + s1, af, 0, + &tv, &res); + if (rc == LDAP_SUCCESS) { + for(ent = ldap_first_entry(xm->ld, res); ent ; + ent = ldap_next_entry(xm->ld, ent)) { + for(i = 0; af[i]; i++) { + bv = ldap_get_values_len(xm->ld, ent, af[i]); + if (bv) { + for(j=0; bv[j]; j++) { + unsigned char *p; + X509_CRL *x; + + p = bv[j]->bv_val; + x = d2i_X509_CRL(NULL, &p, bv[j]->bv_len); + if (x) { + if (X509_NAME_cmp(X509_CRL_get_issuer(x), name) == 0) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_CRL, x); + + if (xo) { + int i, found = 0; + + for(i=0; (!found) && (idata.crl, x) == 0) && + (ASN1_UTCTIME_cmp(X509_CRL_get_lastUpdate(o->data.crl), + X509_CRL_get_lastUpdate(x)) == 0) && + (ASN1_UTCTIME_cmp(X509_CRL_get_nextUpdate(o->data.crl), + X509_CRL_get_nextUpdate(x)) == 0)) + found = 1; + } + if (!found) + sk_X509_OBJECT_push(sk, xo); + else + X509_CRL_free(x); /* duplicate of existing item */ + } else + X509_CRL_free(x); /* cannot allocate X509_OBJECT */ + } else + X509_CRL_free(x); /* subject name doesn't match */ + } + } + ldap_value_free_len(bv); + } + } + } + } else { + log("ldap_search_st error: %s", ldap_err2string(rc)); + ldap_unbind(xm->ld); + xm->ld = NULL; + } + pfree(s1); + } + pfree(str); + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_cert_by_uid( XMAP_LDAP *xm, const char *uid ) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + char *s1, *ff, **af; + int i, j, tlen, rc; + LDAPMessage *res = NULL, *ent = NULL; + struct timeval tv; + struct berval **bv; + + if (!sk) return NULL; + if (!xm->ld) + if (!open_bind(xm)) return NULL; + + ff = find_filter("uid", X509_LU_X509, xm->ldap_filter); + af = find_attrs("uid", X509_LU_X509, xm->ldap_attrs); + tlen = strlen(ff) + strlen(uid); + if ((s1 = alloc_bytes(tlen, "filter pattern")) != NULL) { + snprintf(s1, tlen, ff, uid); + tv.tv_sec = xm->ldap_timeout; tv.tv_usec = 0; + rc = ldap_search_st(xm->ld, xm->ldap_base, LDAP_SCOPE_SUBTREE, + s1, af, 0, + &tv, &res); + if (rc == LDAP_SUCCESS) { + for(ent = ldap_first_entry(xm->ld, res); ent ; + ent = ldap_next_entry(xm->ld, ent)) { + for(i = 0; af[i]; i++) { + bv = ldap_get_values_len(xm->ld, ent, af[i]); + if (bv) { + for(j=0; bv[j]; j++) { + unsigned char *p; + X509 *x; + + p = bv[j]->bv_val; + x = d2i_X509(NULL, &p, bv[j]->bv_len); + if (x) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) { + int i, found = 0; + + for(i=0; (!found) && (idata.x509) == 0) + found = 1; + } + if (!found) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); /* duplicate of existing item */ + } else + X509_free(x); /* cannot allocate X509_OBJECT */ + } + } + ldap_value_free_len(bv); + } + } + } + } else { + log("ldap_search_st error: %s", ldap_err2string(rc)); + ldap_unbind(xm->ld); + xm->ld = NULL; + } + pfree(s1); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_cert_by_dns( XMAP_LDAP *xm, const char *dns ) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + char *s1, *ff, **af; + int i, j, tlen, rc; + LDAPMessage *res = NULL, *ent = NULL; + struct timeval tv; + struct berval **bv; + + if (!sk) return NULL; + if (!xm->ld) + if (!open_bind(xm)) return NULL; + + ff = find_filter("dns", X509_LU_X509, xm->ldap_filter); + af = find_attrs("dns", X509_LU_X509, xm->ldap_attrs); + tlen = strlen(ff) + strlen(dns); + if ((s1 = alloc_bytes(tlen, "filter patten")) != NULL) { + snprintf(s1, tlen, ff, dns); + tv.tv_sec = xm->ldap_timeout; tv.tv_usec = 0; + rc = ldap_search_st(xm->ld, xm->ldap_base, LDAP_SCOPE_SUBTREE, + s1, af, 0, + &tv, &res); + if (rc == LDAP_SUCCESS) { + for(ent = ldap_first_entry(xm->ld, res); ent ; + ent = ldap_next_entry(xm->ld, ent)) { + for(i = 0; af[i]; i++) { + bv = ldap_get_values_len(xm->ld, ent, af[i]); + if (bv) { + for(j=0; bv[j]; j++) { + unsigned char *p; + X509 *x; + + p = bv[j]->bv_val; + x = d2i_X509(NULL, &p, bv[j]->bv_len); + if (x) { + if (X509_subjAltName_check_dns(x, dns)) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) { + int i, found = 0; + + for(i=0; (!found) && (idata.x509) == 0) + found = 1; + } + if (!found) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); /* duplicate of existing item */ + } else + X509_free(x); /* cannot allocate X509_OBJECT */ + } else + X509_free(x); /* subjAltName mismatch */ + } + } + ldap_value_free_len(bv); + } + } + } + } else { + log("ldap_search_st error: %s", ldap_err2string(rc)); + ldap_unbind(xm->ld); + xm->ld = NULL; + } + pfree(s1); + } + return sk; +} + +static STACK_OF(X509_OBJECT) * +XMAP_LDAP_lookup_cert_by_ip( XMAP_LDAP *xm, const struct in_addr ip ) +{ + STACK_OF(X509_OBJECT) *sk = sk_X509_OBJECT_new_null(); + char *s1, *ff, **af, *ipt; + int i, j, tlen, rc; + LDAPMessage *res = NULL, *ent = NULL; + struct timeval tv; + struct berval **bv; + + if (!sk) return NULL; + if (!xm->ld) + if (!open_bind(xm)) return NULL; + + if ((ipt = inet_ntoa(ip)) == NULL) return NULL; + ff = find_filter("ip", X509_LU_X509, xm->ldap_filter); + af = find_attrs("ip", X509_LU_X509, xm->ldap_attrs); + + tlen = strlen(ff) + strlen(ipt); + if ((s1 = alloc_bytes(tlen, "filter pattern")) != NULL) { + snprintf(s1, tlen, ff, ipt); + tv.tv_sec = xm->ldap_timeout; tv.tv_usec = 0; + + DBG(DBG_PARSING, + DBG_log("xm->ldap_base: %s -- s1: %s -- *af: %s", xm->ldap_base, s1, *af); + ); + + rc = ldap_search_st(xm->ld, xm->ldap_base, LDAP_SCOPE_SUBTREE, + s1, af, 0, + &tv, &res); + if (rc == LDAP_SUCCESS) { + for(ent = ldap_first_entry(xm->ld, res); ent ; + ent = ldap_next_entry(xm->ld, ent)) { + for(i = 0; af[i]; i++) { + DBG(DBG_PARSING, + DBG_log("af[%d]: [%s]", i, af[i]); + ); + + bv = ldap_get_values_len(xm->ld, ent, af[i]); + if (bv) { + for(j=0; bv[j]; j++) { + unsigned char *p; + X509 *x; + + DBG(DBG_PARSING, + DBG_log("** We got LDAP. Trying to process. j=%d.", j); + ); + + DBG(DBG_PARSING | DBG_RAW, + DBG_log("** length of X509 cert: %d", (int )bv[j]->bv_len); + ); + DBG(DBG_RAW, + DBG_dump("** p: ", bv[j]->bv_val, bv[j]->bv_len); + ); + + p = bv[j]->bv_val; + x = d2i_X509(NULL, &p, bv[j]->bv_len); + if (x) { + if (X509_subjAltName_check_ip(x, ip)) { + X509_OBJECT *xo = X509_OBJECT_new(X509_LU_X509, x); + if (xo) { + int i, found = 0; + + for(i=0; (!found) && (idata.x509) == 0) + found = 1; + } /* end for */ + if (!found) + sk_X509_OBJECT_push(sk, xo); + else + X509_free(x); /* duplicate of existing item */ + } /* end if (xo) */ + else + X509_free(x); /* cannot allocate X509_OBJECT */ + } /* end if (X509_subjAltName_check_ip(x, ip)) */ + else + X509_free(x); /* SubjectAltName mismatch */ + } /* end if (x) */ + else + { + } + } + ldap_value_free_len(bv); + } + } + } + } else { + DBG(DBG_PARSING, + DBG_log("ldap_search_st error: %s", ldap_err2string(rc)); + ); + ldap_unbind(xm->ld); + xm->ld = NULL; + } + pfree(s1); + } + return sk; +} + +static void +sanitize(const char *buf, char *buf2, int buf2len) +{ + int l = strlen(buf), i, nl, p; + char *b; + + for(i=0, nl=l; ildapsource); + DBG_log("Host = %s:%d (Timeout = %d seconds)", + xm->ldap_host, xm->ldap_port, xm->ldap_timeout); + DBG_log("Search base = %s", xm->ldap_base); + DBG_log("Bind = (\"%s\", \"%s\")", xm->ldap_bindDN, xm->ldap_bindPW); + ); + for(i=0; ((i < MAXFLIST) && (xm->ldap_filter[i].index)); i++) { + snprintf(buf, sizeof(buf)-1, "Filter[%d] (%s,", + i+1, xm->ldap_filter[i].index); + switch(xm->ldap_filter[i].type) { + case X509_LU_X509: strncat(buf, "Cert", sizeof(buf)-1); break; + case X509_LU_CRL: strncat(buf, "CRL", sizeof(buf)-1); break; + default: strncat(buf, "*", sizeof(buf)-1); break; + } + strncat(buf, ") ", sizeof(buf)-1); + strncat(buf, xm->ldap_filter[i].filter, sizeof(buf)-1); + sanitize(buf, buf, sizeof(buf)-1); + DBG(DBG_PARSING, + DBG_log(buf); + ); + } + for(i=0; ((i < MAXFLIST) && (xm->ldap_attrs[i].index)); i++) { + snprintf(buf, sizeof(buf), "Attributes[%d] (%s,", + i+1, xm->ldap_attrs[i].index); + switch(xm->ldap_attrs[i].type) { + case X509_LU_X509: strncat(buf, "Cert", sizeof(buf)-1); break; + case X509_LU_CRL: strncat(buf, "CRL", sizeof(buf)-1); break; + default: strncat(buf, "*", sizeof(buf)-1); break; + } + strncat(buf, ") ", sizeof(buf)-1); + for(j=0; xm->ldap_attrs[i].attrs[j]; j++) { + strncat(buf, ",", sizeof(buf)-1); + strncat(buf, xm->ldap_attrs[i].attrs[j], sizeof(buf)-1); + } + sanitize(buf, buf, sizeof(buf)-1); + DBG(DBG_PARSING, + DBG_log(buf); + ); + } +} + +static void +XMAP_LDAP_free(void *this) +{ + XMAP_LDAP *xm = (XMAP_LDAP *)this; + int i; + + if (!xm) return; + if (xm->ld) ldap_unbind(xm->ld); + if (xm->ldapsource) pfree(xm->ldapsource); + if (xm->ldap_host) pfree(xm->ldap_host); + if (xm->ldap_base) pfree(xm->ldap_base); + if (xm->ldap_bindDN) pfree(xm->ldap_bindDN); + if (xm->ldap_bindPW) pfree(xm->ldap_bindPW); + + for(i=0; ((i < MAXFLIST) && (xm->ldap_filter[i].index)); i++) { + pfree(xm->ldap_filter[i].index); + pfree(xm->ldap_filter[i].filter); + } + + for(i=0; ((i < MAXFLIST) && (xm->ldap_attrs[i].index)); i++) { + pfree(xm->ldap_attrs[i].index); + attrs_free(xm->ldap_attrs[i].attrs); + } + + pfree(xm); +} + +XMAP_METHOD * +XMAP_METHOD_ldap( void ) +{ + return (&xmap_ldap_methods); +} + +#endif /* HAVE_LDAP */ +#endif /* OPENSSL */ diff -BbruN freeswan-1.91.orig/pluto/xmap_ldap.h freeswan-1.91/pluto/xmap_ldap.h --- freeswan-1.91.orig/pluto/xmap_ldap.h Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/pluto/xmap_ldap.h Mon Jul 16 23:26:30 2001 @@ -0,0 +1,49 @@ +#ifndef XMAP_LDAP_H +#define XMAP_LDAP_H + +#ifdef HAVE_LDAP + +#include +#include + +#include +#include + +#include "x_sobj.h" +#include "xmap.h" + +typedef struct _flist_st { + char *index; + int type; + char *filter; +} flist; + +#define MAXFLIST 10 + +typedef struct _alist_st { + char *index; + int type; + char **attrs; +} alist; + +typedef struct xmap_ldap_st { + char *ldapsource; + char *ldap_host; + int ldap_port; + char *ldap_base; + int ldap_timeout; + char *ldap_bindDN; + char *ldap_bindPW; + flist ldap_filter[MAXFLIST]; + alist ldap_attrs[MAXFLIST]; + + LDAP *ld; + + XMAP_METHOD *meth; +} XMAP_LDAP; + +XMAP_METHOD *XMAP_METHOD_ldap( void ); + +#endif /* HAVE_LDAP */ + +#endif /* XMAP_LDAP_H */ diff -BbruN freeswan-1.91.orig/utils/Makefile freeswan-1.91/utils/Makefile --- freeswan-1.91.orig/utils/Makefile Thu Jun 14 09:20:14 2001 +++ freeswan-1.91/utils/Makefile Fri Aug 3 11:22:38 2001 @@ -11,22 +11,30 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: Makefile,v 1.85 2001/06/14 13:20:14 henry Exp $ +# RCSID $Id: Makefile,v 1.74 2001/02/06 18:11:41 henry Exp $ # pathnames, subject to overrides from main Makefile PUBDIR=/usr/local/sbin PRIVDIR=/usr/local/lib/ipsec REALPRIVDIR=/usr/local/lib/ipsec +FINALPRIVDIR=/usr/local/lib/ipsec RCDIR=/etc/rc.d/init.d REALRCDIR=/etc/rc.d/init.d CONFDIR=/etc -MANTREE=/usr/local/man +MANTREE=/usr/man FMANDIR=$(MANTREE)/man5 CMANDIR=$(MANTREE)/man8 PUBS=ipsec -BINS=ranbits rsasigkey + +ifeq "$(USEOPENSSL)" "1" +SCRIPTS=barf manual auto look showdefaults showhostkey rehashcertdir rsakeygen updown.firewall +BINS=ranbits rsasigkey fswcert +else SCRIPTS=barf manual auto look showdefaults showhostkey +BINS=ranbits rsasigkey +endif + INTERNALS=_include _confread _keycensor _secretcensor _updown \ _realsetup _startklips _plutorun _plutoload PRIVS=$(PUBS) $(SCRIPTS) $(INTERNALS) $(BINS) @@ -35,7 +43,7 @@ LOCALS= PLAIN_MANS=ipsec.8 IPSEC_CMANS=auto.8 barf.8 manual.8 ranbits.8 rsasigkey.8 setup.8 \ - showdefaults.8 showhostkey.8 + showdefaults.8 showhostkey.8 rehashcertdir.8 fswcert.8 MANS=$(PLAIN_MANS) $(IPSEC_CMANS) CFLAGS=-I../lib LIB=../lib/libfreeswan.a @@ -49,6 +57,10 @@ all: $(PUBS) $(PRIVS) $(GENDFILES) $(LOCALS) +fswcert: fswcert-0.4/fswcert.c + cd fswcert-0.4; $(MAKE) + cp fswcert-0.4/fswcert . + ranbits: ranbits.o $(CC) $(CFLAGS) ranbits.o $(LIB) -o $@ @@ -93,43 +105,53 @@ ./randomize conf.proto | egrep -v RCSI >$@ install: $(PUBS) $(PRIVS) $(MANS) $(GENDFILES) - mkdir -p $(PUBDIR) $(PRIVDIR) $(FMANDIR) $(CMANDIR) $(CONFDIR) - $(INSTALL) $(PUBS) $(PUBDIR) - $(INSTALL) $(PRIVS) $(PRIVDIR) - $(INSTALL) $(PUB) ipsec.conf.5 $(FMANDIR) - $(INSTALL) $(PUB) $(PLAIN_MANS) $(CMANDIR) + mkdir -p $(PREFIX)/$(PUBDIR) $(PREFIX)/$(PRIVDIR) + mkdir -p $(PREFIX)/$(FMANDIR) $(PREFIX)/$(CMANDIR) + mkdir -p $(PREFIX)/$(CONFDIR) + $(INSTALL) $(PUBS) $(PREFIX)/$(PUBDIR) + $(INSTALL) $(PRIVS) $(PREFIX)/$(PRIVDIR) + $(INSTALL) $(PUB) ipsec.conf.5 $(PREFIX)/$(FMANDIR) + $(INSTALL) $(PUB) $(PLAIN_MANS) $(PREFIX)/$(CMANDIR) for f in $(IPSEC_CMANS) ; \ do \ - $(INSTALL) $(PUB) $$f $(CMANDIR)/ipsec_$$f || exit 1 ; \ - ./manlink $(CMANDIR) ipsec_$$f ; \ + $(INSTALL) $(PUB) $$f $(PREFIX)/$(CMANDIR)/ipsec_$$f || exit 1 ; \ + ./manlink $(PREFIX)/$(CMANDIR) ipsec_$$f ; \ done - test -f $(CONFDIR)/ipsec.secrets || \ - $(INSTALL) $(PRIV) secrets.eg $(CONFDIR)/ipsec.secrets - test -f $(CONFDIR)/ipsec.conf || \ - $(INSTALL) $(PUB) conf.eg $(CONFDIR)/ipsec.conf + test -d $(PREFIX)/$(CONFDIR) || $(INSTALL) -d $(PREFIX)/$(CONFDIR) + test -f $(PREFIX)/$(CONFDIR)/ipsec.secrets || \ + $(INSTALL) $(PRIV) secrets.eg $(PREFIX)/$(CONFDIR)/ipsec.secrets + test -f $(PREFIX)/$(CONFDIR)/ipsec.conf || \ + $(INSTALL) $(PUB) conf.eg $(PREFIX)/$(CONFDIR)/ipsec.conf # main copy must go in RCDIR, PRIVDIR may not be mounted at boot time - mkdir -p $(RCDIR) - $(INSTALL) setup $(RCDIR)/ipsec - rm -f $(PRIVDIR)/setup - ln -s $(REALRCDIR)/ipsec $(PRIVDIR)/setup - PATH=/sbin:/usr/sbin:$$PATH ; export PATH ; \ - if test " $(DESTDIR)" != " " ; \ - then : do nothing ; \ - elif which chkconfig >/dev/null 2>&1 ; \ + test -d $(PREFIX)/$(RCDIR) || mkdir -p $(PREFIX)/$(RCDIR) + $(INSTALL) setup $(PREFIX)/$(RCDIR)/ipsec + rm -f $(PREFIX)/$(PRIVDIR)/setup + ln -sf $(PREFIX)/$(REALRCDIR)/ipsec $(PREFIX)/$(PRIVDIR)/setup + # Only turn on the service if doing default install + if [ $(PREFIX) = '/' ] ; then \ + if which chkconfig >/dev/null 2>&1 ; \ then chkconfig --add ipsec ; \ else $(MAKE) setup4 ; \ + fi ; \ fi + setup4: $(RCDIR)/ipsec - # fallback rc install -- on in run states 2345, off in 016, with - # priorities matching those in setup's chkconfig line - -cd $(RCDIR)/../rc0.d ; ln -s ../init.d/ipsec K68ipsec - -cd $(RCDIR)/../rc1.d ; ln -s ../init.d/ipsec K68ipsec - -cd $(RCDIR)/../rc2.d ; ln -s ../init.d/ipsec S47ipsec - -cd $(RCDIR)/../rc3.d ; ln -s ../init.d/ipsec S47ipsec - -cd $(RCDIR)/../rc4.d ; ln -s ../init.d/ipsec S47ipsec - -cd $(RCDIR)/../rc5.d ; ln -s ../init.d/ipsec S47ipsec - -cd $(RCDIR)/../rc6.d ; ln -s ../init.d/ipsec K68ipsec + # fallback rc install -- on in run states 2345, off in 016 + -test -d $(RCDIR) && test -d $(RCDIR)/../rc0.d && \ + ( cd $(RCDIR)/../rc0.d ; ln -sf ../init.d/ipsec K68ipsec ) ||: + -test -d $(RCDIR) && test -d $(RCDIR)/../rc1.d && \ + ( cd $(RCDIR)/../rc1.d ; ln -sf ../init.d/ipsec K68ipsec ) ||: + -test -d $(RCDIR) && test -d $(RCDIR)/../rc2.d && \ + ( cd $(RCDIR)/../rc2.d ; ln -sf ../init.d/ipsec S47ipsec ) ||: + -test -d $(RCDIR) && test -d $(RCDIR)/../rc3.d && \ + ( cd $(RCDIR)/../rc3.d ; ln -sf ../init.d/ipsec S47ipsec ) ||: + -test -d $(RCDIR) && test -d $(RCDIR)/../rc4.d && \ + ( cd $(RCDIR)/../rc4.d ; ln -sf ../init.d/ipsec S47ipsec ) ||: + -test -d $(RCDIR) && test -d $(RCDIR)/../rc5.d && \ + ( cd $(RCDIR)/../rc5.d ; ln -sf ../init.d/ipsec S47ipsec ) ||: + -test -d $(RCDIR) && test -d $(RCDIR)/../rc6.d && \ + ( cd $(RCDIR)/../rc6.d ; ln -sf ../init.d/ipsec K68ipsec ) ||: clean: rm -f *.o $(BINS) $(GENDFILES) $(GENDSCRIPTS) $(LOCALS) diff -BbruN freeswan-1.91.orig/utils/_confread freeswan-1.91/utils/_confread --- freeswan-1.91.orig/utils/_confread Wed Jun 13 16:09:19 2001 +++ freeswan-1.91/utils/_confread Mon Jul 16 23:26:30 2001 @@ -1,6 +1,6 @@ #!/bin/sh # configuration-file reader utility -# Copyright (C) 1999, 2000, 2001 Henry Spencer. +# Copyright (C) 1999, 2000 Henry Spencer. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -12,7 +12,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: _confread,v 1.41 2001/06/13 20:09:19 henry Exp $ +# RCSID $Id: _confread,v 1.39 2001/06/01 15:49:13 henry Exp $ # # Extract configuration info from /etc/ipsec.conf, repackage as assignments # to shell variables or tab-delimited fields. Success or failure is reported @@ -47,7 +47,6 @@ fieldfmt=yes prefix= search= -export=0 me="ipsec _confread" for dummy @@ -120,10 +119,11 @@ fail("invalid section name " bq na[i] eq) } - good = "also type auto authby" + good = "also type auto authby force_encrypt_cypher" left = " left leftsubnet leftnexthop leftfirewall leftupdown" akey = " keyexchange auth pfs keylife rekeymargin rekeyfuzz compress" obs = " lifetime rekeystart rekeytries" + cert = " certfile keyfile peerfile certopts certpath" akey = akey " keyingtries ikelifetime" obs mkey = " spibase spi esp espenckey espauthkey espreplay_window" left = left " leftespenckey leftespauthkey leftahkey" @@ -131,7 +131,7 @@ mkey = mkey " ah ahkey ahreplay_window" right = left gsub(/left/, "right", right) - n = split(good left right akey mkey, g) + n = split(good left right akey mkey cert, g) for (i = 1; i <= n; i++) goodnames["conn:" g[i]] = 1 @@ -231,7 +231,7 @@ # referencing is transitive: xyz->from->to if (from in refsto) { listnum = split(refsto[from], reflist, ";") - for (i = 1; i <= listnum; i++) + for (i=1; i <= listnum; i++) chainref(reflist[i], to) } addref(from, to) @@ -337,7 +337,7 @@ searchfound(sectionname) } else { # rather a kludge, but must check this somewhere - if (search == "auto" && rest !~ /^(add|route|start|ignore)$/) + if (search == "auto" && rest !~ /^(add|route|start|ignore|background)$/) fail("illegal auto value " bq rest eq) } next diff -BbruN freeswan-1.91.orig/utils/auto freeswan-1.91/utils/auto --- freeswan-1.91.orig/utils/auto Fri Jun 1 11:49:13 2001 +++ freeswan-1.91/utils/auto Mon Jul 16 23:26:30 2001 @@ -12,7 +12,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: auto,v 1.61 2001/06/01 15:49:13 henry Exp $ +# RCSID $Id: auto,v 1.59 2001/05/04 05:31:50 henry Exp $ me='ipsec auto' usage="Usage: @@ -323,8 +323,10 @@ s["rightupdown"] = s["rightupdown"] " ipfwadm" default("authby", "secret") + authbyfound = "0" authtype = "--psk" if (s["authby"] == "rsasig") { + authbyfound = "1" authtype = "--rsasig" need("leftrsasigkey") need("rightrsasigkey") @@ -332,8 +334,45 @@ fail("ID \"" id("left") "\" cannot have RSA key") if (id("right") == "%any") fail("ID \"" id("right") "\" cannot have RSA key") - } else if (s["authby"] != "secret") + } + + + if (s["authby"] == "cert") { + authbyfound = "1" + default("certfile", "") + default("certopts", "send") + default("keyfile", "") + default("certpath", "") + authtype = "--openssl" + need("certfile") + need("certopts") + need("keyfile") + need("certpath") + } + + if (s["authby"] != "secret") { + if (s["authby"] != "psk") { + if (authbyfound != "1") { fail("unknown authby value \"" s["authby"] "\"") + } + } + } + + default("force_encrypt_cypher", "") + if ("force_encrypt_cypher" in s) { + if (s["force_encrypt_cypher"] == "des") { + force_encrypt_cypher = "des" + } + if (s["force_encrypt_cypher"] == "DES") { + force_encrypt_cypher = "des" + } + if (s["force_encrypt_cypher"] == "3des") { + force_encrypt_cypher = "3des" + } + if (s["force_encrypt_cypher"] == "3DES") { + force_encrypt_cypher = "3des" + } + } settings = "--encrypt" if (s["type"] != "transport") @@ -368,6 +407,17 @@ if ("rekeyfuzz" in s) fuzz = "--rekeyfuzz " s["rekeyfuzz"] + if (authtype == "--openssl") { + if ("certfile" in s) + certfile = "--certfile " s["certfile"] + if ("certopts" in s) + certopts = "--certopts " s["certopts"] + if ("keyfile" in s) + keyfile = "--keyfile " s["keyfile"] + if ("certpath" in s) + certpath = "--certpath " s["certpath"] + } + print "ipsec whack --name", name, settings, "\\" print "\t--host", s["left"], lc, "--nexthop", s["leftnexthop"], lud, lid, "\\" @@ -375,8 +425,23 @@ "--nexthop", s["rightnexthop"], rud, rid, "\\" print "\t--ipseclifetime", s["keylife"], "--rekeywindow", s["rekeymargin"], "\\" + if (authtype == "--openssl") { + if (certfile != "--certfile ") + print certfile, "\\" + if (certopts != "--certopts ") + print certopts, "\\" + if (keyfile != "--keyfile ") + print keyfile, "\\" + if (certpath != "--certpath ") + print certpath, "\\" + } + + if (force_encrypt_cypher != "") { + print "\t--force_encrypt_cypher", s["force_encrypt_cypher"], "\\" + } + print "\t--keyingtries", s["keyingtries"], fuzz - if (authtype != "--psk") { + if (authtype == "--rsasig") { whackkey("left") whackkey("right") } diff -BbruN freeswan-1.91.orig/utils/barf freeswan-1.91/utils/barf --- freeswan-1.91.orig/utils/barf Fri Jun 15 12:18:22 2001 +++ freeswan-1.91/utils/barf Mon Jul 16 23:26:30 2001 @@ -12,7 +12,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: barf,v 1.50 2001/06/15 16:18:22 henry Exp $ +# RCSID $Id: barf,v 1.47 2001/06/01 15:49:13 henry Exp $ KERNSRC=${KERNSRC-/usr/src/linux} LOGS=${LOGS-/var/log} @@ -75,10 +75,6 @@ hostname ; date set -x _________________________ -ipsec --version -_________________________ -cat /proc/version -_________________________ cat /proc/net/ipsec_eroute _________________________ cat /proc/net/ipsec_spi @@ -91,14 +87,14 @@ _________________________ cat /proc/net/pf_key _________________________ -( cd /proc/net ; egrep '^' pf_key_* ) -_________________________ ( cd /proc/sys/net/ipsec ; egrep '^' * ) _________________________ ipsec auto --status _________________________ ifconfig -a _________________________ +ipsec --version +_________________________ ipsec --directory _________________________ hostname --fqdn @@ -128,6 +124,8 @@ _________________________ uname -a _________________________ +cat /proc/version +_________________________ if test -r /etc/redhat-release then cat /etc/redhat-release @@ -137,15 +135,15 @@ _________________________ ipchains -L -v -n _________________________ -ipfwadm -F -l -n -e +ipfwadm -F -l -n _________________________ -ipfwadm -I -l -n -e +ipfwadm -I -l -n _________________________ -ipfwadm -O -l -n -e +ipfwadm -O -l -n _________________________ ipchains -M -L -v -n _________________________ -ipfwadm -M -l -n -e +ipfwadm -M -l -n _________________________ cat /proc/modules _________________________ diff -BbruN freeswan-1.91.orig/utils/fswcert-0.4/Makefile freeswan-1.91/utils/fswcert-0.4/Makefile --- freeswan-1.91.orig/utils/fswcert-0.4/Makefile Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/utils/fswcert-0.4/Makefile Fri Aug 17 15:21:17 2001 @@ -0,0 +1,26 @@ +################################################### +# Adjust SSLDIR before make ... +SSLDIR=/usr/ssl + +# Adjust IPSECDIR before make install ... +IPSECDIR=/usr/lib/ipsec +################################################### + +VERSION = 0.4-pkix2 + +CFLAGS = -g -Wall -O2 -DVERSION=\"$(VERSION)\" -I$(SSLDIR)/include -I$(OPENSSLROOT)/include +LDFLAGS = -g -L$(SSLDIR)/lib -L$(OPENSSLROOT)/lib +LDLIBS = -lcrypto + +DISTFILES=Makefile README fswcert.c + +all : fswcert + +fswcert : fswcert.o + $(CC) $(LDFLAGS) -o fswcert fswcert.o $(LDLIBS) + +fswcert.o: fswcert.c + $(CC) $(CFLAGS) -c fswcert.c + +clean : + rm -f fswcert fswcert.o diff -BbruN freeswan-1.91.orig/utils/fswcert-0.4/README freeswan-1.91/utils/fswcert-0.4/README --- freeswan-1.91.orig/utils/fswcert-0.4/README Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/utils/fswcert-0.4/README Mon Jul 30 11:08:59 2001 @@ -0,0 +1,75 @@ +fswcert Utility +=============== + + +This utility allows output of the certificate's ID or ID_DER_ASN1_DN used +by FreeSWAN/PKIX to authenticate hosts using certificates. + +Dependencies: + fswcert requires the openssl package. + +Bugs: + Due to openssl, the fswcert binary is HUGE. + + +These are the options supported: +-------------------------------- + +-c --certificate print certificate data + + Prints the certificate data needed for FreeS/WAN's + ipsec.conf. Input can be from an X.509 file in PEM + or DER format, or from a PKCS12 (*.p12) file. + +-k --key print private RSA key data + + Prints the private key data needed for FreeS/WAN's + ipsec.secrets. Input can be from an RSA private key + file, or from a PKCS12 (*.p12) file. + +-l --left left-side parameters for ipsec.conf + + Prefix certificate data with `left' + +-r --right right-side parameters for ipsec.conf + + Prefix certificate data with `left' + +--type=[x509|rsa|pkcs7|pkcs12] select input file type + + Select input file type. Defaults to x509. + +--format=[PEM|DER] select input file format + + Select input file format. Defaults to PEM. + +-C --directory=dir change into dir first + + Change into dir at startup. (Files are then + read relative to this directory). + +-q --quiet single line error messages to stdout + + This is a hack to better integrate with _confread. + Don't use manually. + +-d --der-output [-a(scii)/-b(inary)] + outputs DN in DER binary format + + This is also a hack. Useful to give the CA the DN in DER + so that it can insert the 'subject' search field in its + LDAP tables. + +-v --version returns version of fswcert + +Either --key or --certificate is required. It makes no sense to +specify both --left and --right; the last option wins. + + +To use with FreeSWAN/PKIX (examples): + PKCS12 (left side, ascii output): + ipsec fswcert --type pkcs12 -c /etc/ipsec/baka.p12 -d a -l + PKCS7 (right side, ascii output): + Yipsec fswcert --type pkcs7 -c /etc/ipsec/baka.pk7 -d a -r + X.509 (left side, ascii output): + ipsec fswcert -c /etc/ipsec/baka.pem -d a -l diff -BbruN freeswan-1.91.orig/utils/fswcert-0.4/fswcert.c freeswan-1.91/utils/fswcert-0.4/fswcert.c --- freeswan-1.91.orig/utils/fswcert-0.4/fswcert.c Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/utils/fswcert-0.4/fswcert.c Fri Aug 17 15:13:58 2001 @@ -0,0 +1,782 @@ +/* Certificate and Private Key Format Conversions for FreeS/WAN + * + * Copyright (C) 2000 Andreas Gruenbacher, + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include +#include +#include +#include + +#define _GNU_SOURCE +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct option long_options[] = { + {"certificate", 0, 0, 'c'}, + {"key", 0, 0, 'k'}, + {"left", 0, 0, 'l'}, + {"right", 0, 0, 'r'}, + {"type", 1, 0, 1 }, + {"format", 1, 0, 'f'}, + {"quiet", 0, 0, 'q'}, + {"der-output", 0, 0, 'd'}, + {"directory", 1, 0, 'C'}, + {"version", 0, 0, 'v'}, + {"help", 0, 0, 'h'}, + {NULL, 0, 0, 0 } +}; + +int prompt_for_passwords = 0; +const char *peer_prefix = NULL; +int opt_quiet = 0; +int der_output = 0; +int der_binary = 0; +const char *input_file = NULL; + +#define DUMP_CERTIFICATE 1 +#define DUMP_KEY 2 + +void safe_PKCS12_SAFEBAG_free(void *a) { + return PKCS12_SAFEBAG_free((PKCS12_SAFEBAG *)a); +} +void safe_PKCS7_free(void *a) { + return PKCS7_free((PKCS7 *)a); +} + +static STACK_OF(X509) *extract_STACK_OF_X509_from_PKCS7 (PKCS7 *p7); +int dump_x509_certificate(X509 *x509); +int dump_pkcs7_certificates(PKCS7 *p7); + + +int opt_what = 0; + +BIO *bio_err = NULL; + +enum input_file_type { + IN_PKCS12 = 1, + IN_X509 = 2, + IN_RSA = 3, + IN_PKCS7 = 4, + IN_PKCS8 = 5 +}; +enum input_format { FORMAT_ASN1 = 1, FORMAT_PEM = 3 }; + +void print_errors(int ssl, const char *fmt, ...) +{ + if (fmt) { + va_list args; + + va_start(args, fmt); + if (input_file) + fprintf(stderr, "%s: ", input_file); + fprintf(stderr, "Error "); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + } + if (ssl && !opt_quiet) + +ERR_print_errors(bio_err); +} + +const char *read_password(void) +{ + static char password[1024]; + struct termio saved, no_echo; + + printf("Password: "); + + (void) ioctl(0, TCGETA, &saved); + no_echo = saved; + no_echo.c_lflag &= ~ECHO; + (void) ioctl(0, TCSETA, &no_echo); + fgets(password, sizeof(password), stdin); + (void) ioctl(0, TCSETA, &saved); + puts(""); + + if (strchr(password, '\n')) + *strchr(password, '\n') = '\0'; + return password; +} + +void BN_print_0(BIGNUM *num) +{ + int bits = BN_num_bits(num); + + if ((bits-1) % 8 < 3) + putchar('0'); + BN_print_fp(stdout, num); +} + +#define print(what, num) do { \ + printf("\t%s: 0x", what); \ + BN_print_0(num); \ + putchar('\n'); \ + } while(0) + +int dump_rsa_private_key(RSA *rsa) +{ + if (rsa->d == NULL) { + print_errors(0, "no private exponent"); + return 1; + } + if (opt_what & DUMP_KEY) { + print("Modulus", rsa->n); + print("PublicExponent", rsa->e); + print("PrivateExponent", rsa->d); + print("Prime1", rsa->p); + print("Prime2", rsa->q); + print("Exponent1", rsa->dmp1); + print("Exponent2", rsa->dmq1); + print("Coefficient", rsa->iqmp); + } + return 0; +} + +#undef print + +int dump_pkcs7_certificates(PKCS7 *p7) +{ + STACK_OF(X509) *x509_stack = extract_STACK_OF_X509_from_PKCS7(p7); + int error = 0; + int i; + + if (sk_X509_num(x509_stack) == 0) { + print_errors(0, "no certificates in PKCS7 chain"); + PKCS7_free(p7); + return 1; + } + else + { + for (i = 0; i < sk_X509_num(x509_stack); i++) + { + printf("\t#Cert #%d in PKCS7 chain:\n", i+1); + error = dump_x509_certificate(sk_X509_value(x509_stack,i)); + if (error) { + return error; + } + } + } + return 0; +} + +static STACK_OF(X509) * +extract_STACK_OF_X509_from_PKCS7 (PKCS7 *p7) +{ + STACK_OF(X509) *certs=NULL; + int i=OBJ_obj2nid(p7->type); + + switch (i) + { + case NID_pkcs7_signed: + certs=p7->d.sign->cert; + break; + case NID_pkcs7_signedAndEnveloped: + certs=p7->d.signed_and_enveloped->cert; + break; + default: + break; + } + + return certs; +} + + +int dump_x509_certificate(X509 *x509) +{ + BUF_MEM *subject; + EVP_PKEY *pkey; + RSA *rsa; + int i, error = 0; + char derbuf[256]; + + if (!x509->cert_info || !x509->cert_info->subject || + !x509->cert_info->subject->bytes) { + fprintf(stderr, "Certificate contains no subject\n"); + return 1; + } + subject = &x509->cert_info->subject->bytes[0]; + + if (opt_what & DUMP_CERTIFICATE) { + if (!der_output) { + printf("\t%sid=@~", peer_prefix); + for (i = 0; i < subject->length; i++) + printf("%02X", (unsigned char)subject->data[i]); + printf("\n"); + } else if (der_output) { + int derlen; + unsigned char *derbytes, *derout; + + derlen=i2d_X509_NAME(x509->cert_info->subject, NULL); + derbytes=malloc(derlen); + derout=(unsigned char *)derbytes; + + derlen=i2d_X509_NAME(X509_get_subject_name(x509), &derout); + derout=(unsigned char *)derbytes; + + if (der_binary) { + for (i = 0; i < derlen; i++) + printf("%c", derout[i]); + } else { + X509_NAME_oneline(x509->cert_info->subject, + derbuf, 256); + printf("\t%sid=@%s\n", peer_prefix, derbuf); + printf("\t#%sid=@~", peer_prefix); + for (i = 0; i < derlen; i++) + printf("%02X", (unsigned char)derout[i]); + printf("\n"); + +#if 0 +{ /* DEBUGGING ON */ + X509_NAME *xn = X509_NAME_new(); + char dnout[256]; + if (xn == NULL) { + printf("\t#Unable to malloc X509_NAME *xn"); + } + + printf("\t#derlen = %d\n", derlen); + printf("\t#certlen = %d\n", certlen); + + /* X509_NAME * d2i_X509_NAME(X509_NAME **a,unsigned char **pp,long length); + */ + xn = d2i_X509_NAME(&xn, &(derout), (long)derlen); + + if (xn != NULL) { + X509_NAME_oneline(xn,dnout,256); + printf("\t#DNtest == %s\n", dnout); + } else { + printf("\t#Invalid DER string\n"); + } +} /* DEBUGGING OFF */ +#endif + + } + + free(derbytes); + } + } + + pkey = X509_get_pubkey(x509); + if (pkey == NULL) { + print_errors(1, "getting public key"); + return 1; + } + if (pkey->type != EVP_PKEY_RSA) { + print_errors(0, "not an RSA public key"); + error = 1; + goto cleanup; + } + rsa = pkey->pkey.rsa; + +#if 0 + if (opt_what & DUMP_CERTIFICATE) { + int bytes = BN_num_bytes(rsa->e); + printf("\t%srsasigkey=0x%02X", peer_prefix, bytes); + BN_print_0(rsa->e); + BN_print_0(rsa->n); + putchar('\n'); + } +#endif + +cleanup: + EVP_PKEY_free(pkey); + return 0; +} + +int read_pkcs12_safebag(PKCS12_SAFEBAG *bag, const char *password) +{ + PKCS8_PRIV_KEY_INFO *p8; + EVP_PKEY *pkey; + X509 *x509; + RSA *rsa; + int error = 0; + + switch (M_PKCS12_bag_type(bag)) { + case NID_keyBag: + p8 = bag->value.keybag; + pkey = EVP_PKCS82PKEY(p8); + if (!pkey) { + print_errors(1, "grabbing private key"); + return 1; + } + rsa = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + if (!rsa) { + print_errors(1, "getting RSA key"); + return 1; + } + error = dump_rsa_private_key(rsa); + RSA_free(rsa); + break; + + case NID_pkcs8ShroudedKeyBag: + p8 = M_PKCS12_decrypt_skey(bag, password, -1); + if (!p8) { + print_errors(1, "decrypting private key"); + return 1; + } + pkey = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (!pkey) { + print_errors(1, "grabbing private key"); + return 1; + } + rsa = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + if (!rsa) { + print_errors(1, "getting RSA private key"); + return 1; + } + error = dump_rsa_private_key(rsa); + RSA_free(rsa); + break; + + case NID_certBag: + if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate){ + print_errors(0, "not an X.509 certificate"); + return 1; + } + /* only dump the key's certificate */ + if (!PKCS12_get_attr(bag, NID_localKeyID)) + return 0; + x509 = M_PKCS12_certbag2x509(bag); + if (!x509) { + print_errors(1, "grabbing certificate"); + return 1; + } + if (dump_x509_certificate(x509)) + return 1; + X509_free(x509); + break; + + default: + /* other bag entry */ + } + return error; +} + +int read_pkcs12_file(BIO *bio_in) +{ + const char *password = "\0"; + PKCS12 *p12; + STACK /* _OF(PKCS7) */ *asafes = NULL; + PKCS7 *p7; + int i; + + p12 = d2i_PKCS12_bio (bio_in, NULL); + if (!p12) { + print_errors(1, "reading PKCS12 file"); + return 1; + } + if (!PKCS12_verify_mac(p12, password, 0)) { + if (prompt_for_passwords) + password = read_password(); + if (!prompt_for_passwords || + !PKCS12_verify_mac(p12, password, -1)) { + print_errors(1, "verifying MAC: wrong password?"); + return 1; + } + } + + /* Unpack PKCS12 file */ + asafes = M_PKCS12_unpack_authsafes (p12); + if (!asafes) { + print_errors(1, "unpacking PKCS12 file"); + return 1; + } + for (i = 0; i < sk_num(asafes); i++) { + int bagnid, j; + STACK /* _OK(PKCS12) */ *bags; + + p7 = (PKCS7 *) sk_value(asafes, i); + bagnid = OBJ_obj2nid(p7->type); + if (bagnid == NID_pkcs7_data) + bags = M_PKCS12_unpack_p7data(p7); + else if (bagnid == NID_pkcs7_encrypted) + bags = M_PKCS12_unpack_p7encdata(p7, password, -1); + else + continue; + if (!bags) { + print_errors(1, "unpacking PKCS12 file"); + return 1; + } + for (j = 0; j < sk_num(bags); j++) { + PKCS12_SAFEBAG *bag = + (PKCS12_SAFEBAG *)sk_value(bags, j); + if (read_pkcs12_safebag(bag, password)) + return 1; + } + sk_pop_free(bags, safe_PKCS12_SAFEBAG_free); + } + sk_pop_free(asafes, safe_PKCS7_free); + return 0; +} + +int read_pkcs7_file(BIO *bio_in, enum input_format input_format) +{ + PKCS7 *p7 = NULL; + int error; + + if (input_format == FORMAT_PEM) +#if OPENSSL_VERSION_NUMBER > 0x00903000L + p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL); +#else + p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL); +#endif + else if (input_format == FORMAT_ASN1) + p7 = d2i_PKCS7_bio(bio_in, NULL); + if (!p7) { + print_errors(1, "reading PKCS7 certificate"); + return 1; + } + error = dump_pkcs7_certificates(p7); + PKCS7_free(p7); + + return 0; +} + +int read_x509_file(BIO *bio_in, enum input_format input_format) +{ + X509 *x509 = NULL; + int error; + + if (input_format == FORMAT_PEM) +#if OPENSSL_VERSION_NUMBER > 0x00903000L + x509 = PEM_read_bio_X509(bio_in, NULL, NULL, NULL); +#else + x509 = PEM_read_bio_X509(bio_in, NULL, NULL); +#endif + else if (input_format == FORMAT_ASN1) + x509 = d2i_X509_bio(bio_in, NULL); + if (!x509) { + print_errors(1, "reading X509 certificate"); + return 1; + } + error = dump_x509_certificate(x509); + X509_free(x509); + + return error; +} + +int read_rsa_file(BIO *bio_in, enum input_format input_format) +{ + RSA *rsa = NULL; + int error; + + if (input_format == FORMAT_PEM) +#if OPENSSL_VERSION_NUMBER > 0x00903000L + rsa = PEM_read_bio_RSAPrivateKey(bio_in, NULL, NULL, NULL); +#else + rsa = PEM_read_bio_RSAPrivateKey(bio_in, NULL, NULL); +#endif + else if (input_format == FORMAT_ASN1) + rsa = d2i_RSAPrivateKey_bio(bio_in, NULL); + if (!rsa) { + print_errors(1, "reading RSA private key"); + return 1; + } + error = dump_rsa_private_key(rsa); + RSA_free(rsa); + return error; +} + + +static EVP_PKEY * +extract_pkey_using_p8inf(PKCS8_PRIV_KEY_INFO *p8inf) +{ + EVP_PKEY *pkey = NULL; + + if (!(pkey = EVP_PKCS82PKEY(p8inf))) { + print_errors(1, "Error converting PKCS8 data"); + return NULL; + } + + if (p8inf->broken) { + switch (p8inf->broken) { + case PKCS8_NO_OCTET: + print_errors(1, "Warning: broken key encoding: " + "No Octet String in PrivateKey"); + break; + + case PKCS8_EMBEDDED_PARAM: + print_errors(1, "Warning: broken key encoding: " + "DSA parameters included in PrivateKey"); + break; + + case PKCS8_NS_DB: + print_errors(1, "Warning: broken key encoding: " + "DSA public key include in PrivateKey"); + break; + + default: + print_errors(1, "Warning: broken key encoding: " + "Unknown broken type"); + break; + } + } + return pkey; +} + + +int dump_PKCS8_certificate(X509_SIG *p8) +{ + EVP_PKEY *pkey; + PKCS8_PRIV_KEY_INFO *p8inf; + int error; + const char *password = "\0"; + RSA *rsa; + + /* We handle the password, and decrypt p8 */ + p8inf = M_PKCS8_decrypt(p8, password, strlen(password)); + if (!p8inf) + { + /* try encrypted */ + password = read_password(); + p8inf = M_PKCS8_decrypt(p8, password, strlen(password)); + } + + if (!p8inf) + { + print_errors(1, "Unable to extract key information from PKCS8 file"); + return 1; + } + + pkey = extract_pkey_using_p8inf(p8inf); + if (!pkey) { + print_errors(1, "grabbing private key"); + return 1; + } + rsa = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + if (!rsa) { + print_errors(1, "getting RSA key"); + return 1; + } + error = dump_rsa_private_key(rsa); + RSA_free(rsa); + + /* we clean up */ + PKCS8_PRIV_KEY_INFO_free(p8inf); + + return error; +} + +int read_pkcs8_file(BIO *bio_in, enum input_format input_format) +{ + X509_SIG *p8; + int error; + + if (input_format == FORMAT_PEM) + { +#if OPENSSL_VERSION_NUMBER > 0x00903000L + p8 = PEM_read_bio_PKCS8(bio_in, NULL, NULL, NULL); +#else + p8 = PEM_read_bio_PKCS8(bio_in, NULL, NULL); +#endif + } else { + p8 = d2i_PKCS8_bio(bio_in, NULL); + } + + if (!p8) { + print_errors(1, "reading PKCS8 key certificate"); + return 1; + } + + error = dump_PKCS8_certificate(p8); + X509_SIG_free(p8); + + return error; +} + + +int main(int argc, char *argv[]) +{ + enum input_file_type input_file_type = 0; + enum input_format input_format = 0; + int error = 0, opt; + + prompt_for_passwords = isatty(0) && isatty(1); + + while ((opt = getopt_long(argc, argv, "cklrqd:C:hv", + long_options, NULL)) != -1) { + switch(opt) { + case 1: /* input file type */ + if (!strcmp(optarg, "pkcs12")) + input_file_type = IN_PKCS12; + else if (!strcmp(optarg, "pkcs7")) + input_file_type = IN_PKCS7; + else if (!strcmp(optarg, "pkcs8")) + input_file_type = IN_PKCS8; + else if (!strcmp(optarg, "x509")) + input_file_type = IN_X509; + else if (!strcmp(optarg, "rsa")) + input_file_type = IN_RSA; + else + goto synopsis; + break; + + case 'f': /* input format */ + if ((!strcmp(optarg, "PEM")) || + (!strcmp(optarg, "pem"))) + input_format = FORMAT_PEM; + else if ((!strcmp(optarg, "DER")) || + (!strcmp(optarg, "der"))) + input_format = FORMAT_ASN1; + else + goto synopsis; + break; + + case 'c': /* certificate */ + opt_what |= DUMP_CERTIFICATE; + if (!input_file_type) + input_file_type = IN_X509; + break; + + case 'k': /* key */ + opt_what |= DUMP_KEY; + if (!input_file_type) + input_file_type = IN_RSA; + break; + + case 'l': /* left */ + if (!opt_what) + opt_what = DUMP_CERTIFICATE; + peer_prefix = "left"; + break; + + case 'r': /* right */ + if (!opt_what) + opt_what = DUMP_CERTIFICATE; + peer_prefix = "right"; + break; + + case 'C': /* change directory */ + if (chdir(optarg) && errno) { + perror(optarg); + error = 1; + } + break; + + case 'v': /* print version and exit */ + printf("%s " VERSION "\n", argv[0]); + return 0; + + case 'q': /* quiet */ + opt_quiet = 1; + break; + + case 'd': /* output in DER */ + der_output = 1; + if (!strcmp(optarg, "a")) { + /* ascii */ + der_binary = 0; + } else if (!strcmp(optarg, "b")) { + der_binary = 1; + } else { + goto synopsis; + } + break; + + default: + goto synopsis; + } + } + if (peer_prefix == NULL) + peer_prefix = ""; + + if (optind+1 != argc || !opt_what) + goto synopsis; + + if (!input_file_type) + input_file_type = IN_X509; + if (!input_format) + input_format = FORMAT_PEM; + + if (opt_quiet) + dup2(1,2); /* stderr is stdout (awk hack) */ + + ERR_load_crypto_strings(); + SSLeay_add_all_algorithms(); + bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); + + while (optind < argc) { + BIO *bio_in; + + input_file = argv[optind]; + bio_in = BIO_new_file(input_file, "rb"); + if (!bio_in) { + perror(input_file); + error = 1; + } else { + if (input_file_type == IN_PKCS7) + { + if (opt_what & DUMP_CERTIFICATE) + error |= read_pkcs7_file(bio_in, input_format); + else if (opt_what & DUMP_KEY) + print_errors(1, + "There is no such thing as a PKCS7 private key."); + } + else if (input_file_type == IN_PKCS8) + { + if (opt_what & DUMP_KEY) + error |= read_pkcs8_file(bio_in, input_format); + else + print_errors(1, + "There is no such thing as a PKCS8 public key."); + } + else if (input_file_type == IN_PKCS12) + error |= read_pkcs12_file(bio_in); + else if (input_file_type == IN_X509) + error |= read_x509_file(bio_in, input_format); + else if (input_file_type == IN_RSA) + error |= read_rsa_file(bio_in, input_format); + BIO_free(bio_in); + } + optind++; + } + + BIO_free(bio_err); + + return error; + +synopsis: + fprintf(stderr, "SYNOPSIS: %s --cert|--key [--left|--right] " + "options file\n", argv[0]); + if (!opt_quiet) { + fprintf(stderr, + "\t-c --cert\tprint certificate data\n" + "\t-k --key\tprint private RSA key data\n" + "\t-l --left\tleft-side parameters for ipsec.conf\n" + "\t-r --right\tright-side parameters for ipsec.conf\n" + "\t --type=[x509|rsa|pkcs7|pkcs8|pkcs12]\tselect input file type\n" + "\t --format=[PEM|DER]\tselect input file format\n" + "\t-C --directory=dir\tchange into dir first\n" + "\t-d [ab]\tprints out the DER\n" + + "\t-h --help\tprint this help\n" + "\t-q --quiet\tsingle line error messages to stdout\n" + "\t-v --version\tprints fswcert version\n"); + } + return error; +} + diff -BbruN freeswan-1.91.orig/utils/fswcert.8 freeswan-1.91/utils/fswcert.8 --- freeswan-1.91.orig/utils/fswcert.8 Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/utils/fswcert.8 Fri Aug 3 11:18:43 2001 @@ -0,0 +1,76 @@ +.TH "FSWCERT" 8 +.SH NAME +fswcert \- FreeSWAN certificate data manipulation utility +.SH SYNOPSIS +.B ipsec fswcert +command [ argument ...] +.br +ipsec fswcert \-\-help +.br +ipsec fswcert \-\-version +.br +ipsec fswcert [\-c|\-l] certificate [\-\-left|\-\-right] + [\-d a|b] [\-\-type x509|pkcs7|pkcs8|pkcs12|rsa] + [\-C directory] [\-q|\-\-quiet] [\-f|\-\-format PEM|DER] +.SH DESCRIPTION +fswcert allows and simplifies the extraction of certificate +data for use with pluto. It permits extraction of ID data +from X509, PKCS7 or PKCS12 certificates to be used for +identification by pluto. +.SH OPTIONS +.TP +.B \-\-help +lists the available commands. +.TP +.B \-\-version +supplies the version number of the fswcert utility. +.TP +.B \-c filename +Use this X509, PKCS7 or PKCS12 file containing a public +certificate to display the ID data. This data can be used +for authentication in ipsec.conf. Default certificate +used is PEM X509. +.TP +.B \-k filename +Use this X509, PKCS8 or PKCS12 file containing a private +certificate, and display it's RSA private key data +structure. This data could be used to generate an RSA +entry in /etc/ipsec.secrets. Default certificate format +used is PEM X509. +.TP +.B \l|\-\-left +Prepends 'left' in front of id information to ease insertion +of data into ipsec.conf files. Used in conjuction with +'\-c' option. +.TP +.B \-r|\-\-right +Prepends 'right' to id information, as done with \-l|\-\-left, +.TP +.B \-d [a|b] +Display DER_ASN1_DN from a public certificate. Use 'a' +for ascii output. Use 'b' for direct binary extract. +CAUTION: '\-d b' may currupt your terminal. +Used in conjuction with '\-c' option. +.TP +.B \-\-type [x509|pkcs7|pkcs8|pkcs12|rsa] +Specify the type of certificate to work with. +.TP +.B \-C directory +Specify working directory. Usually, it's the directory where +you'll find the certificate. +.TP +.B \-q|\-\-quiet +Do not return warnings or errors. +.TP +.B \-f|\-\-format +Specify the encoding format of the certificate. The format is +either 'DER' or 'PEM'. +.SH EXAMPLES +.TP +fswcert \-c baka.pem \-l \-d a \-C /etc/ipsec/t \-q \-\-format=pem +Display a certificate's subject info for use as 'leftid' +in 'ipsec.conf'. Be quiet about errors. Use '/etc/ipsec/t' +as working directory. The certificate is stored in 'PEM' +format. +.SH BUGS +No bugs known. diff -BbruN freeswan-1.91.orig/utils/ipsec.8 freeswan-1.91/utils/ipsec.8 --- freeswan-1.91.orig/utils/ipsec.8 Fri Jun 1 11:48:36 2001 +++ freeswan-1.91/utils/ipsec.8 Fri Aug 3 11:25:45 2001 @@ -67,6 +67,9 @@ ipsec.conf(5), ipsec.secrets(5), ipsec_auto(8), ipsec_barf(8), +ipsec_dir2hash(8), +ipsec_fswcert(8), +ipsec_rehashcertdir(8), ipsec_setup(8), ipsec_showdefaults(8), ipsec_showhostkey(8) @@ -78,9 +81,9 @@ .I may also be of use. .SH HISTORY -Written for Linux FreeS/WAN +Orifginally written for Linux FreeS/WAN -by Henry Spencer. +by Henry Spencer. Modified for FreeSWAN/PKIX by Luc Lanthier. .SH BUGS The provision of centralized services, while convenient, diff -BbruN freeswan-1.91.orig/utils/ipsec.conf.5 freeswan-1.91/utils/ipsec.conf.5 --- freeswan-1.91.orig/utils/ipsec.conf.5 Thu Jun 14 15:48:27 2001 +++ freeswan-1.91/utils/ipsec.conf.5 Mon Jul 16 23:26:30 2001 @@ -1,5 +1,5 @@ -.TH IPSEC.CONF 5 "14 June 2001" -.\" RCSID $Id: ipsec.conf.5,v 1.70 2001/06/14 19:48:27 henry Exp $ +.TH IPSEC.CONF 5 "29 May 2001" +.\" RCSID $Id: ipsec.conf.5,v 1.68 2001/05/31 21:57:33 henry Exp $ .SH NAME ipsec.conf \- IPsec configuration and connections .SH DESCRIPTION @@ -850,8 +850,7 @@ If the special value .B %search is used, all connections with -.BR auto=add , -.BR auto=route , +.B auto=add or .B auto=start are loaded. @@ -867,11 +866,6 @@ If the special value .B %search is used, all connections with -.B auto=route -or -.B auto=start -are routed, -and all connections with .B auto=start are started. .TP @@ -887,11 +881,9 @@ .BR no . .TP .B plutobackgroundload -obsolete parameter, ignored, nominally specifying whether -loading and starting of connections should be spun off as a background -process to avoid startup delays. -This is now always done. -Values were +should loading and starting of connections be spun off as a background +process to avoid startup delays? +Values are .B yes or .BR no diff -BbruN freeswan-1.91.orig/utils/rehashcertdir freeswan-1.91/utils/rehashcertdir --- freeswan-1.91.orig/utils/rehashcertdir Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/utils/rehashcertdir Mon Jul 16 23:26:30 2001 @@ -0,0 +1,38 @@ +#!/bin/sh +if [ "$1" = "" ]; +then + echo "Error: No directory to process." + echo "Usage: $0 " + echo + exit 1 +fi + +if [ ! -d $1 ]; +then + echo "Error: "$1" is not a directory." + echo "Usage: $0 " + echo + exit 2 +fi + +cd $1 +for ii in *.pem; do + if [ "`basename $ii`" = "crl.pem" ]; + then + ln -fs $ii `openssl crl -noout -hash -in crl.pem`.crl.0 + else + ln -fs $ii `openssl x509 -noout -hash -in $ii`.cert.0 + perl -e "open(IN, \"openssl x509 -in $ii -noout -text \|\"); \ + @IN = ; \ + foreach (@IN) { \ + if (/IP Address:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})/) { \ + system(\"ln -sf $ii `dirname $ii`/ip-\$1.cert.0\"); \ + } \ + if (/DNS:([^, ]*).*$/) { \ + system(\"ln -sf $ii `dirname $ii`/dns-\$1.cert.0\"); \ + } \ + };" + fi +done + + diff -BbruN freeswan-1.91.orig/utils/rehashcertdir.8 freeswan-1.91/utils/rehashcertdir.8 --- freeswan-1.91.orig/utils/rehashcertdir.8 Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/utils/rehashcertdir.8 Fri Aug 3 11:02:25 2001 @@ -0,0 +1,28 @@ +.TH "REHASHCERTDIR" 8 +.SH NAME +ipsec rehashcertdir \- parses certificate hashes in a directory for use with FreeSWAN-PKIX. +.SH SYNOPSIS +.B ipsec rehashcertdir + +.SH DESCRIPTION +rehashcertdir parses all X509 certificates in a directory +for use with the PKIX 'certopts' options from ipsec.conf. +It creates symbolic links of all the certificates in the +given directory. The links' filenames will contain searcheable +data. This way, a Certificate Authorithy is not absolutely +necessary. + +You need to use rehashcertdir to create the compatible db +for use with dir2hash and the db 'certopts'. +.SH HISTORY +Written for Linux/FreeSWAN-PKIX by Luc Lanthier based on the +original work by Neil Dunbar in his pluto-openssl patch for +FreeSWAN 1.1. +.SH "SEE ALSO" +dir2hash(8) +.SH BUGS +None known. +.SH TODO +Allow parsing PKCS7 and PKCS12 data in both DER and PEM formats. +Merge the rehashcert dir shell script and the dir2hash application +into a single application. Maybe make it part of 'fswcert'? diff -BbruN freeswan-1.91.orig/utils/rsakeygen freeswan-1.91/utils/rsakeygen --- freeswan-1.91.orig/utils/rsakeygen Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/utils/rsakeygen Mon Jul 16 23:26:30 2001 @@ -0,0 +1,32 @@ +#!/bin/sh +# use command line specified directory for rsakeys and publickey files, +# otherwise use the current directory +KEYDIR=/usr/local/lib/ipsec +if [ $# -eq 1 ] +then + KEYDIR=$1 +fi + +# define variables +KEYFILE=$KEYDIR/rsakeys +PUBKEY=$KEYDIR/publickey +IPSEC_SECRETS=/etc/ipsec.secrets + + +# generate rsa keys +touch $KEYFILE +chmod 600 $KEYFILE +ipsec rsasigkey --random /dev/urandom 1024 > $KEYFILE +chmod 400 $KEYFILE + +# extract public key to write to publickey file +awk 'NR==3 {print $0}' $KEYFILE | cut -d= -f2 > $PUBKEY + +# write the rest part including private key to the ipsec.secrets file +touch ${IPSEC_SECRETS} +chmod 600 ${IPSEC_SECRETS} +echo ": rsa {" > ${IPSEC_SECRETS} +cat $KEYFILE >> ${IPSEC_SECRETS} +echo " }" >> ${IPSEC_SECRETS} +chmod 400 ${IPSEC_SECRETS} +exit 0 diff -BbruN freeswan-1.91.orig/utils/rsasigkey.c freeswan-1.91/utils/rsasigkey.c --- freeswan-1.91.orig/utils/rsasigkey.c Mon May 14 19:09:30 2001 +++ freeswan-1.91/utils/rsasigkey.c Mon Jul 16 23:26:30 2001 @@ -353,7 +353,8 @@ /* ctime provides \n */ printf("\t# for signatures only, UNSAFE FOR ENCRYPTION\n"); bundp = bundle(E, n, &bs); - printf("\t#pubkey=%s\n", conv(bundp, bs, 's')); /* RFC2537ish format */ + printf("\t#pubkey=%s\n", conv(bundp, bs, 'x')); /* RFC2537ish format */ + printf("\t#newpubkey=%s\n", conv(bundp, bs, 's')); /* RFC2537ish format */ printf("\t#IN KEY 0x4200 4 1 %s\n", conv(bundp, bs, 's')+2); /* RFC2537 */ printf("\t# (0x4200 = auth-only host-level, 4 = IPSec, 1 = RSA)\n"); diff -BbruN freeswan-1.91.orig/utils/setup freeswan-1.91/utils/setup --- freeswan-1.91.orig/utils/setup Wed Jun 13 16:10:07 2001 +++ freeswan-1.91/utils/setup Mon Jul 16 23:26:30 2001 @@ -1,6 +1,6 @@ #!/bin/sh # IPsec startup and shutdown script -# Copyright (C) 1998, 1999, 2001 Henry Spencer. +# Copyright (C) 1998, 1999 Henry Spencer. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -12,7 +12,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: setup,v 1.109 2001/06/13 20:10:07 henry Exp $ +# RCSID $Id: setup,v 1.105 2001/06/01 15:49:14 henry Exp $ # # ipsec init.d script for starting and stopping # the IPsec security subsystem (KLIPS and Pluto). @@ -30,10 +30,6 @@ # description: IPsec provides encrypted and authenticated communications; \ # KLIPS is the kernel half of it, Pluto is the user-level management daemon. -me='ipsec setup' # for messages - - - if test " $IPSEC_DIR" = " " # if we were not called by the ipsec command then # we must establish a suitable PATH ourselves @@ -41,6 +37,19 @@ export PATH fi +me='ipsec setup' # for messages + +# make sure output of (e.g.) ifconfig is in English +unset LANG LANGUAGE LC_ALL LC_MESSAGES + +# verify permissions +if test " `id -u`" != " 0" +then + echo "permission denied (must be superuser)" | + logger -s -p daemon.error -t ipsec_setup + exit 1 +fi + # Check that the ipsec command is available. found= for dir in `echo $PATH | tr ':' ' '` @@ -60,39 +69,587 @@ # Pick up IPsec configuration (until we have done this, successfully, we # do not know where errors should go, hence the explicit "daemon.error"s.) -# Note the "--export", which exports the variables created. -eval `ipsec _confread --varprefix IPSEC --export --type config setup` +eval `ipsec _confread --varprefix IPSEC --type config setup` if test " $IPSEC_confreadstatus" != " " then echo "$IPSEC_confreadstatus -- \`$1' aborted" | logger -s -p daemon.error -t ipsec_setup exit 1 fi -IPSECsyslog=${IPSECsyslog-daemon.error} -export IPSECsyslog -# misc setup +# Misc. paths (some of this should perhaps be overrideable from ipsec.conf). +plutopid=/var/run/pluto.pid +subsyslock=/var/lock/subsys/ipsec +info=/var/run/ipsec.info +sysflags=/proc/sys/net/ipsec +modules=/proc/modules +# full rp_filter path is $rpfilter1/interface/$rpfilter2 +rpfilter1=/proc/sys/net/ipv4/conf +rpfilter2=rp_filter +ipforward=/proc/sys/net/ipv4/ip_forward +ipsecversion=/proc/net/ipsec_version + +# Misc. configuration (should perhaps be overrideable). umask 022 +# some shell functions, to clarify the actual code + +# start KLIPS +startklips() { + # load module if necessary + if test ! -f $ipsecversion + then + if test -r $modules # kernel does have modules + then + unset MODPATH MODULECONF # no user overrides! + depmod -a >/dev/null 2>&1 && modprobe ipsec + fi + if test ! -f $ipsecversion + then + echo "Fatal error, kernel appears to lack KLIPS." + exit 1 + fi + fi + + # figure out debugging flags + case "$IPSECklipsdebug" in + '') IPSECklipsdebug=none ;; + esac + echo "KLIPS debug \`$IPSECklipsdebug'" | logonly + case "$IPSECklipsdebug" in + none) ipsec klipsdebug --none ;; + all) ipsec klipsdebug --all ;; + *) ipsec klipsdebug --none + for d in $IPSECklipsdebug + do + ipsec klipsdebug --set $d + done + ;; + esac + + # figure out misc. kernel config + if test -d $sysflags + then + sysflag "$IPSECfragicmp" "fragicmp" no icmp + echo 1 >$sysflags/inbound_policy_check # no debate + sysflag no "no_eroute_pass" no no_eroute_pass # obsolete parm + sysflag no "opportunistic" no opportunistic # obsolete parm + sysflag "$IPSEChidetos" "hidetos" yes tos + else + echo "Cannot adjust kernel flags, no $sysflags directory!" + fi + + # clear tables out in case dregs have been left over + ipsec eroute --clear + ipsec spi --clear + + # figure out interfaces + for i in $IPSECinterfaces + do + case "$i" in + ipsec*=?*) klipsinterface "$i" ;; + %defaultroute) defaultinterface ;; + *) echo "$me: interface \`$i' not understood, ignored" >&2 + ;; + esac + done + + # set up default eroute if necessary + if test " $IPSECpacketdefault" = " " + then + case "$IPSECno_eroute_pass" in + ''|no) IPSECpacketdefault=drop ;; + yes) IPSECpacketdefault=pass ;; + *) echo "$me: unknown (not yes/no) no_eroute_pass value \`$IPSECno_eroute_pass'" >&2 + IPSECpacketdefault=drop + ;; + esac + fi + case "$IPSECpacketdefault" in + pass|reject) + ipsec eroute --label "packetdefault" --replace --eraf inet \ + --src 0/0 --dst 0/0 --said "%$IPSECpacketdefault" + ;; + drop) ;; + *) echo "$me: unknown packetdefault value \`$IPSECpacketdefault'" >&2 ;; + esac +} + +# set up a system flag based on a variable +# sysflag value shortname default flagname +sysflag() { + case "$1" in + '') v="$3" ;; + *) v="$1" ;; + esac + if test ! -f $sysflags/$4 + then + if test " $v" != " $3" + then + echo "$me: cannot implement $2=$v because" >&2 + echo " $sysflags/$4 does not exist" >&2 + return 1 + else + return 0 # can't set it, but it's default anyway + fi + fi + case "$v" in + yes) echo 1 >$sysflags/$4 ;; + no) echo 0 >$sysflags/$4 ;; + *) echo "Unknown (not yes/no) $2 value \`$1'" ;; + esac +} + +# interfaces=%defaultroute: put ipsec0 on top of default route's interface +defaultinterface() { + phys=`netstat -nr | + awk '$1 == "0.0.0.0" && $3 == "0.0.0.0" { print $NF }'` + if test " $phys" = " " + then + echo "$me: no default route, %defaultroute cannot cope!!!" >&2 + return # really should exit, hard to arrange + fi + if test `echo " $phys" | wc -l` -gt 1 + then + echo "$me: multiple default routes, %defaultroute cannot cope!!!" >&2 + return # really should exit, hard to arrange + fi + next=`netstat -nr | + awk '$1 == "0.0.0.0" && $3 == "0.0.0.0" { print $2 }'` + klipsinterface "ipsec0=$phys" $next +} + +# set up a Klips interface +klipsinterface() { + # pull apart the interface spec + virt=`expr $1 : '\([^=]*\)=.*'` + phys=`expr $1 : '[^=]*=\(.*\)'` + + # figure out ifconfig for interface + addr= + eval `ifconfig $phys | + awk '$1 == "inet" && $2 ~ /^addr:/ && $4 ~ /^Mask:/ { + gsub(/:/, " ", $0) + print "addr=" $3 + if ($4 == "Bcast") + print "type=broadcast" + else if ($4 == "P-t-P") + print "type=pointopoint" + else + print "type=" + print "otheraddr=" $5 + print "mask=" $7 + }'` + if test " $addr" = " " + then + echo "$me: unable to determine address of \`$phys'" >&2 + exit 1 + fi + if test " $type" = " " + then + echo "$me: \`$phys' is of an unknown type, can't use it" >&2 + return + fi + if test " $IPSECoverridemtu" != " " + then + mtu="mtu $IPSECoverridemtu" + else + mtu= + fi + echo "KLIPS $virt on $phys $addr/$mask $type $otheraddr $mtu" | logonly + + # attach the interface and bring it up + ipsec tncfg --attach --virtual $virt --physical $phys + ifconfig $virt inet $addr $type $otheraddr netmask $mask $mtu + + # if %defaultroute, note the facts + if test " $2" != " " + then + ( + echo "defaultroutephys=$phys" + echo "defaultroutevirt=$virt" + echo "defaultrouteaddr=$addr" + if test " $2" != " 0.0.0.0" + then + echo "defaultroutenexthop=$2" + fi + ) >>$info + else + echo '#dr: no default route' >>$info + fi + + # check for advanced-router trouble + checkif $virt + checkif $phys +} + +# check an interface for problems +checkif() { + rpf=$rpfilter1/$1/$rpfilter2 + if test -f $rpf + then + r="`cat $rpf`" + if test " $r" != " 0" + then + echo "WARNING: $1 has route filtering turned on, KLIPS may not work" + echo " ($rpf = \`$r', should be 0)" + fi + fi +} + +# set up manually-keyed connections +manualconns() { + if test " $IPSECmanualstart" != " " + then + for tu in $IPSECmanualstart + do + ipsec manual --up $tu + done + fi +} + +# internal setup for Pluto start +# sets up vars, so must do its own logging to avoid subprocess +plutopre() { + # searches, if needed + if test " $IPSECplutoload" = " %search" + then + eval `ipsec _confread --varprefix PLUTO --search auto add start background` + if test " $PLUTO_confreadstatus" != " " + then + echo "plutoload: $PLUTO_confreadstatus" | logit + echo "unable to determine what conns to add" | logit + IPSECplutoload= + else + IPSECplutoload="$PLUTO_confreadnames" + fi + fi + if test " $IPSECplutostart" = " %search" + then + eval `ipsec _confread --varprefix PLUTO --search auto start` + if test " $PLUTO_confreadstatus" != " " + then + echo "plutostart: $PLUTO_confreadstatus" | logit + echo "unable to determine what conns to start" | logit + IPSECplutostart= + else + IPSECplutostart="$PLUTO_confreadnames" + fi + fi + + # ensure plutoload > plutoroute > plutostart + for s in $IPSECplutostart + do + found= + for lo in $IPSECplutoroute + do + if test " $lo" = " $s" + then + found=yes + fi + done + if test ! "$found" + then + IPSECplutoroute="$IPSECplutoroute $s" + fi + done + for s in $IPSECplutoroute + do + found= + for lo in $IPSECplutoload + do + if test " $lo" = " $s" + then + found=yes + fi + done + if test ! "$found" + then + IPSECplutoload="$IPSECplutoload $s" + fi + done + + # execute any preliminaries + if test " $IPSECprepluto" != " " + then + $IPSECprepluto 2>&1 | logit + fi +} + +# start Pluto daemon +plutodaemon() { + # double-check one little detail + if test ! -e /dev/urandom + then + echo "Cannot start Pluto, system lacks /dev/urandom !!!" + exit 1 + fi + + # figure out options + pd= + for d in $IPSECplutodebug + do + pd="$pd --debug-$d" + done + case "$IPSECuniqueids" in + yes) pd="$pd --uniqueids" ;; + no|'') ;; + *) echo "Unknown uniqueids value (not yes/no) \`$IPSECuniqueids'" ;; + esac + + # do it + if test " $IPSECdumpdir" = " " + then + ulimit -c 0 # preclude core dumps + elif test ! -d "$IPSECdumpdir" + then + echo "Dumpdir \`$IPSECdumpdir' does not exist, ignored." + ulimit -c 0 # preclude core dumps + else + cd $IPSECdumpdir # put them where desired + ulimit -c unlimited # and permit them + fi + echo "Pluto debug \`$IPSECplutodebug'" | logonly + ipsec pluto $pd +} + +# Pluto subsystem startup and cleanup, after daemon is running +plutopost() { + # database load + if test " $IPSECplutoload" != " " + then + echo "$IPSECplutoload" | tr ' ' '\n' | column -x -c 100 | + tr -s '\t ' ' ' | + while read bunch + do + for tu in $bunch + do + ipsec auto --add $tu + done + done + fi + + # enable listening + ipsec auto --ready + + # execute any cleanup + if test " $IPSECpostpluto" != " " + then + $IPSECpostpluto + fi + + # quickly establish routing + if test " $IPSECplutoroute" != " " + then + echo "$IPSECplutoroute" | + tr ' ' '\n' | column -x -c 100 | + tr -s '\t ' ' ' | + while read bunch + do + for tu in $bunch + do + ipsec auto --route $tu + done + done + fi +} + +# Pluto negotiation start (if any) +plutogo() { + # tunnel initiation, which may take a while + if test " $IPSECplutostart" != " " + then + async= + p= + if test " $IPSECplutowait" = " no" + then + async="--asynchronous" + p=" (asynchronously)" + fi + for tu in $IPSECplutostart + do + #echo "Initiating Pluto tunnel \`$tu'$p:" + ipsec auto --up $async $tu + done + fi +} + +# logging control +logit() { + IPSECsyslog=${IPSECsyslog-daemon.error} + logger -s -p $IPSECsyslog -t ipsec_setup 2>&1 +} +logonly() { + IPSECsyslog=${IPSECsyslog-daemon.error} + logger -p $IPSECsyslog -t ipsec_setup +} + + + +# the mainline code + +# backward compatibility, defaults. +if test " $IPSECdump" = " yes" -a " $IPSECdumpdir" = " " +then + IPSECdumpdir=/var/tmp +fi + # do it case "$1" in - start|--start|stop|--stop) - if test " `id -u`" != " 0" + start|--start) + # Start things rolling. + # First, does it seem to be going already? + if test -f $info then - echo "permission denied (must be superuser)" | - logger -s -p $IPSECsyslog -t ipsec_setup 2>&1 + echo "FreeS/WAN IPsec apparently already running, start aborted!" | logit + exit 1 + fi + # announcement + # (Warning, changes to this log message may affect barf.) + version="`ipsec --version | awk 'NR == 1 { print $3 }'`" + echo "Starting FreeS/WAN IPsec $version..." | logit + rm -f $info + if test ! -r /dev/random + then + echo "...unable to start FreeS/WAN IPsec, no /dev/random!" | + logit + exit 1 + fi + if test ! -r /dev/urandom + then + echo "...unable to start FreeS/WAN IPsec, no /dev/urandom!" | + logit + exit 1 + fi + >$info + if test ! -r $info + then + echo "...unable to create $info, aborting start!" | logit exit 1 fi - tmp=/var/run/ipsec_setup.st + startklips 2>&1 | logit + if test ! -f $ipsecversion # hard to test startklips exit status + then + echo "No KLIPS, cannot continue IPsec startup!" + rm -f $info + exit 1 + fi + if test -d `dirname $subsyslock` + then + touch $subsyslock + fi + manualconns 2>&1 | logit + if test " $IPSECpluto" = " no" + then + pluto=no + elif test " $IPSECplutobackgroundload" = " yes" + then + pluto=back + else + pluto=fore + fi + case $pluto in + fore|back) + plutopre + plutodaemon 2>&1 | logit + sleep 1 # give it a moment to get going + ;; + esac + case $pluto in + fore) plutopost 2>&1 | logit ;; + back) ( plutopost ; plutogo ) 2>&1 | logonly & ;; + esac + fw=`cat $ipforward` + if test " $IPSECforwardcontrol" = " yes" -a " $fw" = " 0" + then + echo "Enabling IP forwarding:" | logonly + echo "ipforwardingwas=$fw" >>$info + echo 1 >$ipforward + fi + case $pluto in + fore) plutogo 2>&1 | logit ;; + esac + echo "...FreeS/WAN IPsec started" | logonly + + echo "Starting background tunnels..." | logit + $0 --startbacktunnels + ;; + + stop|--stop) + # Shut things down. + if test -r $info + then + echo "Stopping FreeS/WAN IPsec..." | logit + status=0 + . $info + else + echo "Stop ordered, but IPsec does not appear to be running!" | + logit + echo "Doing cleanup anyway..." | logit + status=1 + fi + if test " $IPSECforwardcontrol" = " yes" -a " $ipforwardingwas" = " 0" + then + echo "Disabling IP forwarding:" | logonly + echo 0 >$ipforward + fi + if test ! -f $plutopid + then + : nothing + elif test ! -s $plutopid + then + echo "Removing empty $plutopid -- pluto still running?" | logit + rm -f $plutopid + elif kill -0 `cat $plutopid` 2>/dev/null + then + ( + # kill pluto in 30 secs no matter what. ( - ipsec _realsetup $1 - echo "$?" >$tmp - ) 2>&1 | logger -s -p $IPSECsyslog -t ipsec_setup 2>&1 - st=`cat $tmp` - rm -f $tmp - exit $st + sleep 30 + echo "30 second timeout expired. Killing Pluto." | logit + kill -9 $plutopid &> /dev/null + ) &> /dev/null & + killpid=$! + ipsec whack --shutdown | awk '$1 != "002"' | logit + sleep 1 # general paranoia + # kill the killpid if we still need to. + if kill -0 $killpid &> /dev/null ; then + kill -9 $killpid &> /dev/null + fi + ) 2> /dev/null + if test -s $plutopid + then + echo "Pluto did not go away! Killing it:" | logit + kill `cat $plutopid` 2>&1 | logit + sleep 5 + fi + rm -f $plutopid # harmless if already gone + else + echo "Removing orphaned $plutopid:" | logit + rm -f $plutopid + fi + for i in `ifconfig | awk '/^ipsec/ { print $1 }'` + do + ifconfig $i down 2>&1 | logit + ipsec tncfg --detach --virtual $i 2>&1 | logit + done + ipsec klipsdebug --none 2>&1 | logit + ipsec eroute --clear 2>&1 | logit + ipsec spi --clear 2>&1 | logit + i=`lsmod 2>&1 | awk '$1 == "ipsec" { print $1 }'` + if test " $i" = " ipsec" + then + rmmod ipsec 2>&1 | logit + fi + if test -d `dirname $subsyslock` + then + rm -f $subsyslock + fi + rm -f $info + echo "...FreeS/WAN IPsec stopped" | logonly + exit $status ;; restart|--restart) @@ -101,8 +658,94 @@ ;; status|--status) - ipsec _realsetup $1 - exit + if test -f $info + then + hasinfo=yes + fi + + if test -f $subsyslock + then + haslock=yes + fi + + if test -s $plutopid + then + if ps -p `cat $plutopid` >/dev/null + then + haspluto=yes + plutokind=normal + elif ps -C pluto >/dev/null + then + haspluto=yes + plutokind=illicit + fi + elif ps -C pluto >/dev/null + then + haspluto=yes + plutokind=orphaned + fi + + if test -r /proc/net/ipsec_eroute -a \ + " `wc -l /dev/null + ) & ;; *) diff -BbruN freeswan-1.91.orig/utils/setup.8 freeswan-1.91/utils/setup.8 --- freeswan-1.91.orig/utils/setup.8 Thu Jun 14 15:45:13 2001 +++ freeswan-1.91/utils/setup.8 Mon Jul 16 23:26:30 2001 @@ -1,5 +1,5 @@ -.TH IPSEC_SETUP 8 "7 June 2001" -.\" RCSID $Id: setup.8,v 1.31 2001/06/14 19:45:13 henry Exp $ +.TH IPSEC_SETUP 8 "31 May 2001" +.\" RCSID $Id: setup.8,v 1.29 2001/05/31 21:57:33 henry Exp $ .SH NAME ipsec setup \- control IPsec subsystem .SH SYNOPSIS @@ -54,11 +54,9 @@ .B status report the status of the subsystem; normally just reports -.B "IPsec running" -and -.BR "pluto pid \fInnn\fP" , +.B started or -.BR "IPsec stopped" , +.B stopped and exits with status 0, but will go into more detail (and exit with status 1) if something strange is found. @@ -97,12 +95,12 @@ .B start and .B stop -goes both to standard +invoke goes both to standard output and to -.IR syslogd (8), +.IR syslogd (8) via .IR logger (1). -Selected additional information is logged only to +The script itself logs selected information to .IR syslogd (8). .SH HISTORY Written for the FreeS/WAN project @@ -111,4 +109,8 @@ .SH BUGS Old versions of .IR logger (1) -inject spurious extra newlines onto standard output. +injected spurious extra newlines onto standard output. +.PP +Startup failure is not consistently reported in the exit status. +.PP +The normal status report probably should include Pluto's process ID. diff -BbruN freeswan-1.91.orig/utils/showhostkey freeswan-1.91/utils/showhostkey --- freeswan-1.91.orig/utils/showhostkey Mon Jun 11 22:50:03 2001 +++ freeswan-1.91/utils/showhostkey Mon Jul 16 23:26:30 2001 @@ -1,6 +1,6 @@ #! /bin/sh -# show key for this host, in DNS (or other) format -# Copyright (C) 2000, 2001 Henry Spencer. +# show key for this host, in DNS format +# Copyright (C) 2000 Henry Spencer. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -12,15 +12,14 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: showhostkey,v 1.9 2001/06/12 02:50:03 henry Exp $ +# RCSID $Id: showhostkey,v 1.8 2001/06/01 15:49:14 henry Exp $ me="ipsec showhostkey" -usage="Usage: $me [--file secrets] [--left] [--right] [--txt gateway] [--id id]" +usage="Usage: $me [--file secrets] [--left] [--right] [--txt gateway]" file=/etc/ipsec.secrets fmt="dns" gw= -id= for dummy do case "$1" in @@ -28,7 +27,6 @@ --left) fmt="left" ;; --right) fmt="right" ;; --txt) fmt="txt" ; gw="$2" ; shift ;; - --id) id="$2" ; shift ;; --version) echo "$me $IPSEC_VERSION" ; exit 0 ;; --help) echo "$usage" ; exit 0 ;; --) shift ; break ;; @@ -65,19 +63,10 @@ file = "'"$file"'" fmt = "'"$fmt"'" gw = "'"$gw"'" - id = "'"$id"'" comment = "" - s = "[ \t]+" - os = "[ \t]*" - x = "[^ \t]+" - suffix = ":" s "RSA" s "{$" - if (id == "") - pat = "^" suffix - else - pat = "^(" x s ")*" id "(" s x ")*" os suffix status = 0 } - $0 ~ pat { + /^:[ \t]+RSA[ \t]+{$/ { inkey = 1 seenkey = 1 } diff -BbruN freeswan-1.91.orig/utils/showhostkey.8 freeswan-1.91/utils/showhostkey.8 --- freeswan-1.91.orig/utils/showhostkey.8 Mon Jun 11 22:50:03 2001 +++ freeswan-1.91/utils/showhostkey.8 Mon Jul 16 23:26:30 2001 @@ -1,5 +1,5 @@ -.TH IPSEC_SHOWHOSTKEY 8 "11 June 2001" -.\" RCSID $Id: showhostkey.8,v 1.7 2001/06/12 02:50:03 henry Exp $ +.TH IPSEC_SHOWHOSTKEY 8 "22 May 2001" +.\" RCSID $Id: showhostkey.8,v 1.6 2001/05/31 21:59:17 henry Exp $ .SH NAME ipsec showhostkey \- show host's authentication key .SH SYNOPSIS @@ -15,9 +15,6 @@ ] [ .B \-\-file secretfile -] [ -.B \-\-id -identity ] .SH DESCRIPTION .I Showhostkey @@ -62,10 +59,6 @@ IN TXT "X-IPsec-Server(10)=10.11.12.13 AQOF8tZ2...+buFuFn/" .fi .PP -No name is supplied in the TXT record -because there are too many possibilities, -depending on how it will be used. -.PP The .B \-\-left and @@ -87,14 +80,6 @@ leftrsasigkey=0x0103cc2a86fcf440...cf1011abb82d1 .fi .PP -Normally, the default key for this host is the one extracted. -The -.B \-\-id -option overrides this, -causing extraction of the key labeled with the specified -.IR identity , -if any. -.PP The .B \-\-file option overrides the default for where the key information should be @@ -132,10 +117,6 @@ currently it is hardwired to .BR 10 . .PP -The -.B \-\-id -option assumes that the -.I identity -appears on the same line as the -.B ":\ RSA\ {" -that begins the key proper. +Assumes there is only one RSA key in +.IR ipsec.secrets , +which is common but not necessarily universal. diff -BbruN freeswan-1.91.orig/utils/updown.firewall freeswan-1.91/utils/updown.firewall --- freeswan-1.91.orig/utils/updown.firewall Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/utils/updown.firewall Mon Jul 16 23:26:30 2001 @@ -0,0 +1,166 @@ +#! /bin/sh +# sample updown script for ipchains +# Copyright (C) 2000 D. Hugh Redelmeier, Henry Spencer +# sample updown script for iptables +# Copyright (C) 2000 Luc Lanthier +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See . +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# RCSID $Id: updown.firewall,v 1.1.2.9 2001/03/27 18:44:16 lanthierl Exp $ +# +# Modifications: Add ipchains rules specific to Netwinder OfficeServer to +# let FreeS/WAN work with the firewall. Dacheng Tang + +KERNVER=`uname -r | cut -d. -f 1,2` + +# check interface version +case "$PLUTO_VERSION" in +1.0) echo "$0: Pluto interface version 1.0 is obsolete." >&2 + ;; +1.1) ;; +*) echo "$0: unknown interface version \`$PLUTO_VERSION'" >&2 + exit 2 + ;; +esac + +# check parameter(s) +case "$*" in +'') ;; +*) echo "$0: parameters unexpected" >&2 + exit 2 + ;; +esac + +# utility functions for route manipulation +# Meddling with this stuff should never be necessary and is most unwise. +uproute() { + route add -net $PLUTO_PEER_CLIENT_NET netmask $PLUTO_PEER_CLIENT_MASK \ + dev $PLUTO_INTERFACE gw $PLUTO_NEXT_HOP + st=$? + if test $st -ne 0 + then + # route has already given its own cryptic message + echo "$0: \`route $1 $parms' failed" >&2 + fi + return $st +} + +downroute() { + route del -net $PLUTO_PEER_CLIENT_NET netmask $PLUTO_PEER_CLIENT_MASK \ + dev $PLUTO_INTERFACE gw $PLUTO_NEXT_HOP + st=$? + if test $st -ne 0 + then + # route has already given its own cryptic message + echo "$0: \`route $1 $parms' failed" >&2 + fi + return $st + +} + +# the big choice +case "$PLUTO_VERB" in +prepare-host|prepare-client) + # delete possibly-existing route (preliminary to adding a route) + oops="`route del -net $PLUTO_PEER_CLIENT_NET \ + netmask $PLUTO_PEER_CLIENT_MASK 2>&1`" + status="$?" + if test " $oops" = " " -a " $status" != " 0" + then + oops="silent error in route command, exit status $status" + fi + case "$oops" in + 'SIOCDELRT: No such process') + # This is what route (currently -- not documented!) gives + # for "could not find such a route". + status=0 + ;; + esac + exit $status + ;; +route-host|route-client) + # connection to this host or client being routed + uproute + ;; +unroute-host|unroute-client) + # connection to this host or client being unrouted + downroute + ;; +up-host) + # connection to this host coming up + ;; +down-host) + # connection to this host going down + ;; +up-client) + if [ "$KERNVER" = "2.2" ]; + then + # add an input rule to let KLIPS decapsulated packets pass ipsec0 + ipchains -A input -i $PLUTO_INTERFACE -j ACCEPT -p all \ + -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK + # connection to client subnet, through forwarding firewall, coming up + ipchains -I forward -j ACCEPT -b \ + -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \ + -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK + elif [ "$KERNVER" = "2.4" ]; + then + # add an input rule to let KLIPS decapsulated packets pass ipsec0 + iptables -A INPUT -i $PLUTO_INTERFACE -j ACCEPT \ + -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK + # connection to client subnet, through forwarding firewall, coming up + iptables -I FORWARD -j ACCEPT \ + -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \ + -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK + iptables -I FORWARD -j ACCEPT \ + -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK \ + -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK + if ( iptables -t nat -L -n &> /dev/null ) ; then + iptables -t nat -I POSTROUTING -j ACCEPT \ + -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \ + -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK + fi + fi + ;; +down-client) + if [ "$KERNVER" = "2.2" ]; + then + # delete the input rule for the KLIPS decapsulated packets + ipchains -D input -i $PLUTO_INTERFACE -j ACCEPT -p all \ + -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK + # connection to client subnet, through forwarding firewall, going down + ipchains -D forward -j ACCEPT -b \ + -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \ + -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK + elif [ "$KERNVER" = "2.4" ]; + then + # delete the input rule for the KLIPS decapsulated packets + iptables -D INPUT -i $PLUTO_INTERFACE -j ACCEPT \ + -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK + # connection to client subnet, through forwarding firewall, going down + iptables -D FORWARD -j ACCEPT \ + -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \ + -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK + iptables -D FORWARD -j ACCEPT \ + -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK \ + -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK + if ( iptables -t nat -L -n &> /dev/null ) ; then + iptables -t nat -D POSTROUTING -j ACCEPT \ + -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \ + -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK + fi + fi + # force a zero error code even the ipchains command(s) failed + echo "ok" + ;; +*) echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2 + exit 1 + ;; +esac diff -BbruN freeswan-1.91.orig/version.c freeswan-1.91/version.c --- freeswan-1.91.orig/version.c Wed May 30 09:02:20 2001 +++ freeswan-1.91/version.c Sat Aug 18 12:09:01 2001 @@ -1,2 +1 @@ -/* silly pointless RCSID $Id: version.c,v 1.19 2001/05/30 13:02:20 henry Exp $ */ -static const char freeswan_version[] = "1.91"; +static const char freeswan_version[] = "FreeSWAN-1.91-pkix6b";