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 Mon Jul 2 21:54:12 2001 @@ -0,0 +1,47 @@ +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: I don't think freeswan-pkix will compile against OpenSSL 0.9.6. There +has been many major changes in the OpenSSL project. + +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 +luc.lanthier@rebel.com 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 Mon Jul 2 20:27:12 2001 @@ -13,21 +13,41 @@ # # 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 + +# 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 +58,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 +68,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) \ @@ -89,13 +111,29 @@ ln -s `pwd`/libdes/asm/*.pl $(KERNELKLIPS)/libdes/asm ln -s `pwd`/libdes/asm/perlasm $(KERNELKLIPS)/libdes/asm 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 +160,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 +249,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 +261,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 +272,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 +320,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 +331,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 +368,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 Tue Jul 3 03:15:54 2001 @@ -0,0 +1,4 @@ +This program is released under the GPL with the additional exemption +that compiling, linking and/or using OpenSSL is allowed. + +-- 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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.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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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 Jun 4 11:34:31 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-ca.quickstart freeswan-1.91/doc/pkix/ldap-ca.quickstart --- freeswan-1.91.orig/doc/pkix/ldap-ca.quickstart Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/doc/pkix/ldap-ca.quickstart Mon Jun 4 11:34:31 2001 @@ -0,0 +1,340 @@ + +Quick commands and files based on how I set up my own LDAP CA. +-- Luc Lanthier, 20001004 +-- revised: 20010301 + +A more complete explanation can be found in the README.xmap file written +by the original freeswan-pkix patch author, Neil Dunbar. + +Building and LDAP server is nothing simple. Easiest is installing the base +package or compiling it yourself. But after that, it's editing, creating, or +modifying many configuration files or scripts. + +Here's a list of some of the config files or scripts you will encounter +in this document: + LDIF.sh + LDIF + slapd.oc-x509.conf + slapd.at-x509.conf + slapd.conf + regen-ldap_ca.sh + ldap.cnf + ipsec.conf + /etc/ipsec/* + /etc/rc.d/rc.local + + +Your best bet is to following the LDAP documentation and use this document as +a source of information, with examples. + + + +1A- Building openldap software: +----------------------------------------------------------------- +# The following containing version numbers is just an example. +# If you compile from source, you can expect the config files to +# be found in /usr/local/etc/openldap +cd /usr/src +tar xfvz openldap-stable-20000704.tgz +cd openldap-1.2.11 +./configure --enable-shared --with-gnu-ld --enable-ldapd +make depend +make +cd tests +make +cd .. +make install + +1B- Installing openldap software from RPMs: +----------------------------------------------------------------- +Make sure the following are installed. Version numbers are merely a +suggestion. + openldap-1.2.9-6_nw1.armv4l.rpm + openldap-devel-1.2.9-6_nw1.armv4l.rpm +The config files should be found under "/etc/openldap". + + + +2: Creating LDIF files: +----------------------------------------------------------------- +A LDIF file contains the information to add to the LDAP directory +database in a simplified manner. + +Use your favorite editor and create an LDIF file that contains: + dn: dc=, 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/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 Mon Jun 18 16:35:38 2001 @@ -0,0 +1,268 @@ +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 + +# will simplify finding global conf files. +ln -s /etc etc + +# 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 /etc/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 +openssl ca -gencrl -out crl.pem; # distribute/make available to all hosts. + + +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 +openssl ca -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 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 Jun 4 11:34:31 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 2 20:30:27 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 2 20:31:23 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 2 20:31:39 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 2 20:37:04 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 2 20:42:15 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 2 20:48:51 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 3 01:24:29 2001 @@ -69,6 +69,9 @@ { 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((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: @@ -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 2 20:58:42 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 Mon Jul 2 21:03:21 2001 @@ -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((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)) { @@ -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 Tue Jul 3 04:03:17 2001 @@ -1,2 +1,2 @@ /* 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-pkix1"; 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 2 21:05: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 Mon Jul 2 21:06:39 2001 @@ -1,2 +1,2 @@ /* 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-pkix1"; 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 2 21:51:03 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 2 21:53:03 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/pluto/Makefile freeswan-1.91/pluto/Makefile --- freeswan-1.91.orig/pluto/Makefile Sat Jun 16 15:36:40 2001 +++ freeswan-1.91/pluto/Makefile Tue Jul 3 01:52:08 2001 @@ -12,7 +12,7 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # -# RCSID $Id: Makefile,v 1.79 2001/06/16 19:36:40 dhr Exp $ +# RCSID $Id: Makefile,v 1.76 2001/03/13 09:22:01 dhr Exp $ SHELL = /bin/sh @@ -31,17 +31,32 @@ FREESWANLIB=$(FREESWANLIBDIR)/libfreeswan.a LIBDESLITE=$(FREESWANLIBDIR)/libdes.a +ifeq "$(USEOPENSSL)" "1" +OPENSSLDEFS=-DOPENSSL + +OPENSSLOBJS=openssl.o xmap.o xmap_file.o xmap_dir.o xmap_db.o xmap_ldap.o \ + x_sobj.o + +LDAPLIBS=-L$(LDAPROOT)/lib -lldap -llber -Wl,-rpath $(LDAPROOT)/lib +LDAPDEFS=-DHAVE_LDAP + +DBROOT=/usr +DBINCS=-I$(DBROOT)/include +DBLIBS=-L$(DBROOT)/lib -ldb +DBDEFS=-DHAVE_DB -DHAVE_DB185 +endif # USEOPENSSL = 1 + KLIPSD=../klips/net/ipsec INSTALL=install # -O on Linux makes gcc coredump when compiling sha1.c # -Wundef is nice but RHL5.2 compiler doesn't support it -CFLAGS = -g -Wall -W -Wmissing-prototypes -Wpointer-arith -Wbad-function-cast \ - -Wcast-qual -Wmissing-declarations -Wwrite-strings -Wstrict-prototypes +CFLAGS = -g -Wall -Wmissing-prototypes -Wpointer-arith -Wbad-function-cast \ + -Wcast-qual -Wmissing-declarations -Wwrite-strings # where to find klips headers and FreeS/WAN headers -HDRDIRS = -I$(KLIPSD) $(FREESWANINCLS) +HDRDIRS = -I$(KLIPSD) $(FREESWANINCLS) $(OPENSSLINCLS) $(LDAPINCS) $(DBINCS) # On non-LINUX systems, these one of these may be needed (see endian.h) # BYTE_ORDER = -DBIG_ENDIAN=4321 -DLITTLE_ENDIAN=1234 -DBYTE_ORDER=BIG_ENDIAN @@ -76,22 +91,31 @@ CPPFLAGS = $(HDRDIRS) $(BYTE_ORDER) \ -DPLUTO -DKLIPS -DDODGE_DH_MISSING_ZERO_BUG \ - -DDEBUG -DGCC_LINT + -DDEBUG -DGCC_LINT $(OPENSSLDEFS) $(LDAPDEFS) $(DBDEFS) ALLFLAGS = $(CPPFLAGS) $(CFLAGS) # libefence is a free memory allocation debugger # Solaris 2 needs -lsocket -lnsl -LIBSPLUTO = -lgmp -lresolv # -lefence +LIBSPLUTO = -lgmp -lresolv $(OPENSSLLIBS) $(LDAPLIBS) $(DBLIBS) # -lefence LDFLAGS = # Solaris needs -lsocket -lnsl LIBSWHACK = +LIBSD2H = $(OPENSSLLIBS) $(DBLIBS) + BINNAMEPLUTO = pluto BINNAMEWHACK = whack +# Comment this out if you don't have Berkeley DB available, which, +# if you're running Linux is a bit strange... +#ifeq ($(USEOPENSSL),1) +ifeq "$(USEOPENSSL)" "1" +BINNAMED2H = dir2hash +endif + RM = /bin/rm RMFLAGS = -f @@ -105,7 +129,7 @@ DISTGCRYPT = \ gcryptfix.c gcryptfix.h \ - dsa.c dsa.h \ + g10_dsa.c g10_dsa.h \ elgamal.c elgamal.h \ primegen.c \ smallprime.c @@ -142,23 +166,30 @@ # start of support for DSS/DSA. Not currently used. # OBJSGCRYPT = gcryptfix.o dsa.o elgamal.o primegen.o smallprime.o -OBJSGCRYPT = +OBJSGCRYPT = gcryptfix.o g10_dsa.o elgamal.o primegen.o smallprime.o OBJSPLUTO = connections.o constants.o cookie.o crypto.o defs.o log.o \ state.o main.o server.o timer.o id.o ipsec_doi.o kernel.o \ kernel_comm.o demux.o packet.o preshared.o dnskey.o rnd.o spdb.o \ - sha1.o md5.o $(OBJSGCRYPT) $(LIBDESLITE) $(FREESWANLIB) + sha1.o md5.o $(OBJSGCRYPT) $(LIBDESLITE) $(FREESWANLIB) \ + $(OPENSSLOBJS) $(LIBGMP) OBJSWHACK = whack.o $(FREESWANLIB) -all: $(BINNAMEPLUTO) $(BINNAMEWHACK) +#ifeq ($(USEOPENSSL),1) +ifeq "$(USEOPENSSL)" "1" +OBJSD2H = dir2hash.o +endif + +all: $(BINNAMEPLUTO) $(BINNAMEWHACK) $(BINNAMED2H) install: all - $(INSTALL) $(BINNAMEPLUTO) $(BINNAMEWHACK) $(BINDIR) - $(INSTALL) pluto.8 $(PMANDIR)/ipsec_pluto.8 - ../utils/manlink $(PMANDIR) ipsec_pluto.8 - $(INSTALL) ipsec.secrets.5 $(FMANDIR) - ../utils/manlink $(FMANDIR) ipsec.secrets.5 + $(INSTALL) $(BINNAMEPLUTO) $(BINNAMEWHACK) $(BINNAMED2H) \ + $(PREFIX)/$(BINDIR) + $(INSTALL) pluto.8 $(PREFIX)/$(PMANDIR)/ipsec_pluto.8 + ../utils/manlink $(PREFIX)/$(PMANDIR) ipsec_pluto.8 + $(INSTALL) ipsec.secrets.5 $(PREFIX)/$(FMANDIR) + ../utils/manlink $(PREFIX)/$(FMANDIR) ipsec.secrets.5 $(BINNAMEPLUTO): $(OBJSPLUTO) $(CC) -o $(BINNAMEPLUTO) $(LDFLAGS) $(OBJSPLUTO) $(LIBSPLUTO) @@ -166,6 +197,9 @@ $(BINNAMEWHACK): $(OBJSWHACK) $(CC) -o $(BINNAMEWHACK) $(OBJSWHACK) $(LIBSWHACK) +$(BINNAMED2H): $(OBJSD2H) + $(CC) -o $(BINNAMED2H) $(OBJSD2H) $(LIBSD2H) + distlist: @echo $(DIST) @@ -185,8 +219,10 @@ realclean: clean clean: - $(RM) $(RMFLAGS) $(OBJSPLUTO) *.core core *~ a.out ktrace.out - $(RM) $(RMFLAGS) $(BINNAMEPLUTO) $(OBJSWHACK) $(BINNAMEWHACK) + $(RM) $(RMFLAGS) $(OBJSPLUTO) $(OBJSD2H) \ + *.core core *~ a.out ktrace.out + $(RM) $(RMFLAGS) $(BINNAMEPLUTO) $(OBJSWHACK) $(BINNAMEWHACK) \ + $(BINNAMED2H) .c.o: $(CC) $(COPTS) $(ALLFLAGS) -c $< @@ -221,9 +258,6 @@ defs.o: defs.c demux.o: demux.c dnskey.o: dnskey.c -dsa.o: dsa.c -elgamal.o: elgamal.c -gcryptfix.o: gcryptfix.c id.o: id.c ipsec_doi.o: ipsec_doi.c kernel.o: kernel.c @@ -233,11 +267,9 @@ md5.o: md5.c packet.o: packet.c preshared.o: preshared.c -primegen.o: primegen.c rnd.o: rnd.c server.o: server.c sha1.o: sha1.c -smallprime.o: smallprime.c spdb.o: spdb.c state.o: state.c timer.o: timer.c @@ -302,23 +334,6 @@ dnskey.o: dnskey.h dnskey.o: packet.h dnskey.o: timer.h -dsa.o: constants.h -dsa.o: defs.h -dsa.o: log.h -dsa.o: rnd.h -dsa.o: gcryptfix.h -dsa.o: dsa.h -elgamal.o: constants.h -elgamal.o: defs.h -elgamal.o: log.h -elgamal.o: rnd.h -elgamal.o: gcryptfix.h -elgamal.o: elgamal.h -gcryptfix.o: constants.h -gcryptfix.o: defs.h -gcryptfix.o: log.h -gcryptfix.o: rnd.h -gcryptfix.o: gcryptfix.h id.o: constants.h id.o: defs.h id.o: id.h @@ -351,7 +366,6 @@ kernel.o: id.h kernel.o: connections.h kernel.o: state.h -kernel.o: timer.h kernel.o: kernel.h kernel.o: log.h kernel.o: server.h @@ -410,11 +424,6 @@ preshared.o: dnskey.h preshared.o: log.h preshared.o: whack.h -primegen.o: constants.h -primegen.o: defs.h -primegen.o: log.h -primegen.o: rnd.h -primegen.o: gcryptfix.h rnd.o: sha1.h rnd.o: constants.h rnd.o: defs.h @@ -436,9 +445,6 @@ server.o: whack.h sha1.o: sha1.h sha1.o: endian.h -smallprime.o: constants.h -smallprime.o: defs.h -smallprime.o: gcryptfix.h spdb.o: constants.h spdb.o: defs.h spdb.o: id.h @@ -474,7 +480,6 @@ timer.o: packet.h timer.o: demux.h timer.o: ipsec_doi.h -timer.o: kernel.h timer.o: server.h timer.o: log.h timer.o: rnd.h diff -BbruN freeswan-1.91.orig/pluto/connections.c freeswan-1.91/pluto/connections.c --- freeswan-1.91.orig/pluto/connections.c Fri Jun 15 17:30:44 2001 +++ freeswan-1.91/pluto/connections.c Tue Jul 3 01:56:45 2001 @@ -43,6 +43,10 @@ #include "dnskey.h" /* needs preshared.h */ #include "whack.h" +#ifdef OPENSSL +#include "openssl.h" +#include "xmap.h" +#endif static void flush_pending_by_connection(struct connection *c); /* forward */ static struct connection *connections = NULL; @@ -280,6 +284,20 @@ } release_connection(c); /* won't delete c */ +#ifdef OPENSSL + if (c->cert != 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 +558,61 @@ 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); + } +/* ******** HOW to use EVP_PKEY ************* + * #define RSAPrivateKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPrivateKey, + * (char *(*)())d2i_RSAPrivateKey,(char *)rsa) + * /usr/include/openssl/evp.h:621:RSA * EVP_PKEY_get1_RSA(EVP_PKEY *pkey); + * + * DEFS: + * /usr/include/openssl/evp.h:637:EVP_PKEY * d2i_PrivateKey(int type, + * EVP_PKEY **a, unsigned char **pp, + * /usr/include/openssl/evp.h:641:int i2d_PrivateKey(EVP_PKEY *a, + * unsigned char **pp); + * X509 dup macro: + * #define X509_dup(x509) (X509 *)ASN1_dup((int (*)())i2d_X509, \ + * (char *(*)())d2i_X509,(char *)x509) + * NEW MACRO: + * #define EVP_PKEY_dup(pkey) \ + * (EVP_PKEY *)ASN1_dup((int (*)())i2d_PrivateKey, \ + * (char *(*)())d2i_AutoPrivateKey,(char *)pkey) + */ + + 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 +682,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 +702,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 +728,15 @@ c->sa_rekey_fuzz = wm->sa_rekey_fuzz; c->sa_keying_tries = wm->sa_keying_tries; + c->block_cypher = wm->block_cypher; + +#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; @@ -673,6 +755,43 @@ c->that = t; } +#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_options can tell us if we have to deal with + * X509 certs from now on. See function "use_openssl" + */ + if (c->cert_options != 0) { + load_cert_and_key(wm->whack_certfile, wm->whack_keyfile, + (X509 **)&(c->cert), (EVP_PKEY **)&(c->key), c->name); + + if ((c->cert == NULL) || (c->key == NULL)) { + success = FALSE; + } + +#if 0 /* to be removed? */ + /* ID_DER_ASN1_DN cannot be done with path=db or path=dir */ + if (! check_idtype_and_path(c, wm->whack_certpath)) { + success = FALSE; + } +#endif + + if (! make_lookups((STACK_OF(XMAP) **)(&(c->lu)), + wm->whack_certpath) ) { + success = FALSE; + } + strncpy(c->path, wm->whack_certpath, PATH_NAME_LIMIT); + } +#endif + /* set internal fields */ c->ac_next = connections; connections = c; @@ -697,7 +816,8 @@ 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]; @@ -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); + } } } @@ -1057,6 +1186,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 +1565,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 +1582,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 +1614,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 +1666,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. 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 Tue Jul 3 01:56:59 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,20 @@ 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; +#endif + lset_t block_cypher; lset_t policy; time_t sa_ike_life_seconds; time_t sa_ipsec_life_seconds; 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 Tue Jul 3 02:02:30 2001 @@ -311,13 +312,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 +796,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 +910,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 Tue Jul 3 02:02:31 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 */ @@ -625,6 +657,12 @@ #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 */ extern enum_names enc_mode_names; 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 Tue Jul 3 02:04:35 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 Tue Jul 3 02:05:03 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 Tue Jul 3 02:05:03 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 3 02:09:48 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,294 @@ } 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((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((des_cblock *)key->ptr + 0, ks->des3_ks.ks[0]); + (void)des_set_key((des_cblock *)key->ptr + 1, ks->des3_ks.ks[1]); + (void)des_set_key((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) { + 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; +#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) { + 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; +#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 Tue Jul 3 03:17:07 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.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 Tue Jul 3 02:10:21 2001 @@ -0,0 +1,1071 @@ +/* + * Convert an XMAP hash directory to a Berkeley DB hash file + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + +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"); + } +} + +int +main( int argc, char *argv[] ) +{ + int c; + DB *db; + CERT *clist = NULL, *crlist = NULL; + XNAME *xlist = NULL, *nlist = NULL, *xcrlist = NULL, *calist = NULL; + XNAME *dnlist = NULL, *iplist = NULL; + + while(1) { + int option_index = 0; + static struct option long_options[] = { + { "output", 1, 0, 0 }, + { 0, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "o:", + long_options, &option_index); + if (c == -1) break; + + switch(c) { + case 0: + if (strcasecmp(long_options[option_index].name, "output") == 0) + hashout = optarg; + break; + case 'o': + hashout = optarg; + break; + case '?': + break; + default: + printf("?? getopt returned character code 0%o ??\n", c); + } + } + + 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; +} + + 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 Tue Jul 3 02:11:16 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 Tue Jul 3 02:11:16 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 Tue Jul 3 02:11:54 2001 @@ -21,11 +21,16 @@ #include #include +#ifdef OPENSSL +#include /* needed by DER handling */ +#endif + #include #include "constants.h" #include "defs.h" #include "id.h" +#include "log.h" #include "connections.h" /* needs id.h */ #include "packet.h" @@ -38,9 +43,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 +65,70 @@ { 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 + { 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 +177,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 +216,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 +239,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 +256,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 +292,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 +337,49 @@ 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 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 Tue Jul 3 02:12:07 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 3 02:16:57 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 +820,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 +891,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 +1094,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 +1302,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 +1567,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 +1667,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; } @@ -1358,6 +1688,15 @@ pb_stream *const id_pbs = &id_pld->pbs; struct isakmp_id *const id = &id_pld->payload.id; struct id peer; + const u_int max_len = 512; + +#ifdef OPENSSL + 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 @@ -1411,8 +1751,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 +1761,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 +1842,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 +1852,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 +1903,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 +2292,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 +2381,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 +2402,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); +#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)); + ); - /* 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) */ + if ((st->st_oakley.auth == OAKLEY_RSA_ENC_REV) || + (st->st_oakley.auth == OAKLEY_ELGAMAL_ENC_REV)) { + struct isakmp_hdr r_hdr = md->hdr; - st->st_state = STATE_MAIN_I2; + /* 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; - return STF_REPLY; -} + if (!build_and_ship_nonce_pk(st, &st->st_ni, &md->rbody, + ISAKMP_NEXT_KE, "PubKey_r")) + 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 + 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 */ + 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;KE;Nr ****************/ + /**************** build output packet HDR*;HASH_I ****************/ - /* HDR out done */ + /* 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; + /* HASH_I out */ + { + u_char hash_val[MAX_DIGEST_LEN]; + size_t hash_len = main_mode_hash(st, hash_val, TRUE, TRUE); - /* Nr out */ - if (!build_and_ship_nonce(&st->st_nr, &md->rbody, ISAKMP_NEXT_NONE, "Nr")) + 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 +3470,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 +3521,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 +3917,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 +4059,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 +4068,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 +4369,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 Tue Jul 3 02:19:23 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 Tue Jul 3 03:19:43 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? */ @@ -2145,6 +2144,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 +2242,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 +2249,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 Tue Jul 3 02:54:17 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 Tue Jul 3 02:54:40 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 Tue Jul 3 02:54:40 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 Tue Jul 3 02:54:53 2001 @@ -0,0 +1,2285 @@ +#ifdef OPENSSL +#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 ); + +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; i 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); + 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 { + 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 (sk_X509_num(p7_stack) > 1) { + loglog(RC_LOG_SERIOUS, "Too many certificates in PKCS7 chain"); + PKCS7_free(p7); + BIO_free(b); + return; + } else { + { + X509 *tempcert = sk_X509_value(p7_stack,0); + /* *x needs to be allocated memory. a read_bio would normally + * handle that, but in this case, it's just being copied the + * pointer from p7_stack. Let's duplicate it instead of + * a simple assignment, keeping it clean. + */ + *x = X509_dup(tempcert); + PKCS7_free(p7); + } + } + } + } else { + /* 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); + if ((*x = d2i_X509_bio(b, NULL)) == NULL) { + log_err(); + BIO_free(b); + return; + } + } + } + DBG(DBG_PARSING, + DBG_log("Read certificate from %s", cert); + ); + BIO_free(b); + + + if ((b = BIO_new_file(key, "r")) == NULL) { + log_err(); + X509_free(*x); + *x = NULL; + return; + } + + /* 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); + if ((p8 = d2i_PKCS8_bio(b, NULL)) != NULL) pub_PKCS8_found = TRUE; + } else { + pub_PKCS8_found = TRUE; + } + + if (pub_PKCS8_found) { + loglog(RC_LOG_SERIOUS, + "Cannot load private key: Private Key file for \"%s\" found" + " but is encrypted in PKCS#8 format", conn_name); + + /* clear out pub cert first */ + X509_free(*x); + *x = NULL; + + /* next clean out priv key */ + X509_SIG_free(p8); + BIO_free(b); + return; + } + + BIO_free(b); + if ((b = BIO_new_file(key, "r")) == NULL) { + log_err(); + X509_free(*x); + *x = NULL; + return; + } + +/* 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 *r; + + /* Try DER reading of RSA Key */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + r = d2i_RSAPrivateKey_bio(b, NULL); + if (r) { + if ((*k = EVP_PKEY_new()) != NULL) { + (*k)->type = EVP_PKEY_RSA; + (*k)->pkey.rsa = r; + strncpy(keystr, "DER RSA private key", sizeof(keystr)-1); + } else + RSA_free(r); + } + } + + if (!*k) { + DSA *d; + + /* Try DER reading of DSA/El Gamal Key */ + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + d = d2i_DSAPrivateKey_bio(b, NULL); + if (d) { + if ((*k = EVP_PKEY_new()) != NULL) { + (*k)->type = EVP_PKEY_DSA; + (*k)->pkey.dsa = d; + strncpy(keystr, "DER DSA private key", sizeof(keystr)-1); + } else + DSA_free(d); + } + } + + if (!*k) { + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + + BIO_ctrl(b, BIO_CTRL_RESET, 0, NULL); + /* try PKCS8 (unencrypted) keyform */ + + 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); + } else + strncpy(keystr, "PEM PKCS-8 private key", sizeof(keystr)-1); + if (!p8inf) { + log("Error in loading PKCS-8 private key"); + log_err(); + X509_free(*x); + *x = NULL; + BIO_free(b); + return; + } else + strncpy(keystr, "DER PKCS-8 private key", sizeof(keystr)-1); + if ((*k = EVP_PKCS82PKEY(p8inf)) == NULL) { + log("Error in converting PKCS-8 private key"); + log_err(); + X509_free(*x); + *x = NULL; + BIO_free(b); + return; + } + } + DBG(DBG_PARSING, + DBG_log("Read %s from %s", keystr, key); + ); + BIO_free(b); +} + +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; + } + } else { +#ifndef DONT_BE_FASCIST + 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 *)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); + 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 *)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); + 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); + temp_mp_int->_mp_alloc = temp_bignum->max; + 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); + temp_mp_int->_mp_alloc = temp_bignum->max; + 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; +} + + +#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 Tue Jul 3 02:54:53 2001 @@ -0,0 +1,142 @@ +#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_and_key( const char *cert, const char *key, + X509 **x, EVP_PKEY **k, char *conn_name ); +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 ); + +#if 0 /* an interesting struct for certs */ +struct x509cert { + chunk_t certificate; + chunk_t tbsCertificate; + u_int version; + chunk_t serialNumber; + /* signature */ + chunk_t sigAlg; + chunk_t issuer; + /* validity */ + chunk_t notBefore; + chunk_t notAfter; + chunk_t subject; + /* subjectPublicKeyInfo */ + enum pubkey_alg subjectPublicKeyAlgorithm; + /* subjectPublicKey */ + chunk_t modulus; + chunk_t publicExponent; + chunk_t issuerUniqueID; + chunk_t subjectUniqueID; + /* v3 extensions */ + /* extension */ + /* extension */ + /* extnID */ + /* critical */ + /* extnValue */ + /* generalNames */ + chunk_t dnsName; + chunk_t ipAddress; + chunk_t rfc822Name; + /* signatureAlgorithm */ + chunk_t algorithm; + chunk_t signature; +}; +#endif + +/* to lookup CRLs */ +extern X509_CRL *lookup_crl(STACK_OF(XMAP) *lu, X509_NAME *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 Tue Jul 3 02:54:53 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/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 Tue Jul 3 02:56:34 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,12 @@ /* arrays of attributes for transforms, preshared key */ +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 }, + }; static struct db_attr otpsk1024des3md5[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, @@ -53,6 +64,12 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, }; +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 }, + }; static struct db_attr otpsk1536des3md5[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, @@ -60,6 +77,12 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, }; +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 }, + }; static struct db_attr otpsk1024des3sha[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, @@ -67,6 +90,12 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, }; +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 }, + }; static struct db_attr otpsk1536des3sha[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, @@ -76,6 +105,12 @@ /* arrays of attributes for transforms, RSA signatures */ +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 }, + }; static struct db_attr otrsasig1024des3md5[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, @@ -83,6 +118,12 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, }; +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 }, + }; static struct db_attr otrsasig1536des3md5[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_MD5 }, @@ -90,6 +131,12 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, }; +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 }, + }; static struct db_attr otrsasig1024des3sha[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, @@ -97,6 +144,12 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024 }, }; +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 }, + }; static struct db_attr otrsasig1536des3sha[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_SHA }, @@ -104,11 +157,305 @@ { OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536 }, }; +#ifdef OPENSSL /* OPENSSL */ +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 }, + }; + +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 }, + }; +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 +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 }, + }; static struct db_attr otpsk1024des3tiger[] = { { OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC }, { OAKLEY_HASH_ALGORITHM, OAKLEY_TIGER }, @@ -127,6 +475,14 @@ { KEY_IKE, AD(otpsk1024des3md5) }, { KEY_IKE, AD(otpsk1536des3md5) }, { KEY_IKE, AD(otpsk1536des3sha) }, +/* 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) }, }; static struct db_trans oakley_trans_rsasig[] = { @@ -134,8 +490,139 @@ { KEY_IKE, AD(otrsasig1024des3md5) }, { KEY_IKE, AD(otrsasig1536des3md5) }, { KEY_IKE, AD(otrsasig1536des3sha) }, +/* DES */ + { KEY_IKE, AD(otrsasig1024dessha) }, + { KEY_IKE, AD(otrsasig1024desmd5) }, + { KEY_IKE, AD(otrsasig1536desmd5) }, + { KEY_IKE, AD(otrsasig1536dessha) }, }; +#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 }, +/* 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 }, + }; + +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 }, +/* 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 }, + }; + +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 }, +/* 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 /* #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 +638,18 @@ { KEY_IKE, AD(otpsk1536des3md5) }, { KEY_IKE, AD(otrsasig1536des3sha) }, { KEY_IKE, AD(otpsk1536des3sha) }, +/* 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) }, }; /* array of proposals to be conjoined (can only be one for Oakley) */ @@ -164,6 +663,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 +682,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 +698,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 +731,22 @@ /* 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) }, + { ESP_DES, AD(espmd5_attr) }, + { ESP_DES, AD(espsha1_attr) }, +#else + { ESP_3DES, AD(espmd5_attr), NULL }, + { ESP_3DES, AD(espsha1_attr), NULL }, + { ESP_DES, AD(espmd5_attr), NULL }, + { ESP_DES, AD(espsha1_attr), NULL }, +#endif }; static struct db_trans esp_trans[] = { { ESP_3DES, AD_NULL }, + { ESP_DES, AD_NULL }, }; #ifdef SUPPORT_ESP_NULL @@ -219,8 +757,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 +977,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 +1088,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 +1208,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 +1411,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 +1602,25 @@ case OAKLEY_ENCRYPTION_ALGORITHM | ISAKMP_ATTR_AF_TV: switch (val) { -#if 0 /* we don't feel DES is safe */ case OAKLEY_DES_CBC: -#endif + 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 supported", + enum_show(&oakley_enc_names, val)); + } + break; case OAKLEY_3DES_CBC: + if ((c->block_cypher == ALL_BLOCK_CYPHER) || + (c->block_cypher == DES3_BLOCK_CYPHER)) { ta.encrypt = val; ta.encrypter = &oakley_encrypter[val]; + } else { + ugh = builddiag("%s is not supported", + enum_show(&oakley_enc_names, val)); + } break; default: ugh = builddiag("%s is not supported" @@ -923,9 +1679,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 +1742,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 +1865,7 @@ * Lets finish early and leave. */ +#ifndef OPENSSL DBG(DBG_PARSING | DBG_CRYPT , DBG_log("Oakley Transform %u accepted", trans.isat_transnum)); @@ -1108,6 +1920,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 +1948,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,9 +2690,7 @@ switch (esp_attrs.transid) { -#if 0 /* we don't feel single DES is safe */ case ESP_DES: -#endif case ESP_3DES: break; 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 Tue Jul 3 02:56:35 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 Tue Jul 3 02:58:33 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 Tue Jul 3 02:58:39 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 Tue Jul 3 04:02:32 2001 @@ -1,2 +1,2 @@ /* 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-pkix1"; 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 Tue Jul 3 03:00:13 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,9 @@ "shutdown: whack" " --shutdown" "\n\n" + "DES type: whack" + " [--force_encrypt_cypher ]" + "\n\n" "FreeS/WAN %s\n", freeswan_version); } @@ -203,6 +220,14 @@ OPT_KEYID, OPT_PUBKEYRSA, +#ifdef OPENSSL + OPT_CERTFILE, + OPT_CERTOPTS, + OPT_PEERFILE, + OPT_KEYFILE, + OPT_CERTPATH, +#endif + OPT_ROUTE, OPT_UNROUTE, @@ -234,7 +259,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 +277,8 @@ CD_CONNIPV4, CD_CONNIPV6, + CD_FORCE_ENCRYPT_CYPHER, /* to force DES or 3DES only */ + CD_IKELIFETIME, CD_IPSECLIFETIME, CD_RKMARGIN, @@ -319,7 +351,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 +376,16 @@ { "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 }, +/* DES Support */ + { "force_encrypt_cypher", required_argument, NULL, CD_FORCE_ENCRYPT_CYPHER + OO }, + +#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 +490,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 +544,7 @@ msg.sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT; msg.sa_rekey_fuzz = SA_REPLACEMENT_FUZZ_DEFAULT; msg.sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT; + msg.block_cypher = FORCE_ENCRYPT_CYPHER_DEFAULT; msg.addr_family = AF_INET; msg.tunnel_addr_family = AF_INET; @@ -672,6 +725,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 +834,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 */ @@ -781,6 +869,20 @@ msg.sa_keying_tries = opt_whole; continue; + /* 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; + case OPT_KEYID: /* --keyid */ msg.whack_key = TRUE; msg.keyid = optarg; /* decoded by Pluto */ 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 Tue Jul 3 03:00:14 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,10 @@ /* for WHACK_SHUTDOWN */ bool whack_shutdown; + + /* for des type to use */ + lset_t block_cypher; + /* 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 Tue Jul 3 03:00:39 2001 @@ -0,0 +1,36 @@ +#ifdef OPENSSL +#include "x_sobj.h" + +IMPLEMENT_STACK_OF(X509_OBJECT) + +X509_OBJECT * +X509_OBJECT_new( const int type, void *p ) +{ + X509_OBJECT *ret = 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 */ + Free((char *)ret); + ret = NULL; + break; + } + return ret; +} + +void +X509_OBJECT_free(X509_OBJECT *x) +{ + if (!x) return; + X509_OBJECT_free_contents(x); + Free((char *)x); +} +#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 Tue Jul 3 03:00:39 2001 @@ -0,0 +1,12 @@ +#ifndef X_SOBJ_H +#define X_SOBJ_H + +#include +#include + +DECLARE_STACK_OF(X509_OBJECT) + +X509_OBJECT *X509_OBJECT_new( const int type, void *ptr ); +void X509_OBJECT_free(X509_OBJECT *x); + +#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 Tue Jul 3 03:00:39 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 Tue Jul 3 03:00:39 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 { + 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 Tue Jul 3 03:00:39 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 Tue Jul 3 03:00:39 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 Tue Jul 3 03:00:39 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 Tue Jul 3 03:00:39 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 Tue Jul 3 03:00:39 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 Tue Jul 3 03:00:39 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 Tue Jul 3 03:00:39 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 Tue Jul 3 03:00:39 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 Mon Jul 2 21:49:48 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) @@ -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,46 @@ ./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 -s $(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) && cd $(RCDIR)/../rc0.d ; ln -s ../init.d/ipsec K68ipsec + -test -d $(RCDIR) && cd $(RCDIR)/../rc1.d ; ln -s ../init.d/ipsec K68ipsec + -test -d $(RCDIR) && cd $(RCDIR)/../rc2.d ; ln -s ../init.d/ipsec S47ipsec + -test -d $(RCDIR) && cd $(RCDIR)/../rc3.d ; ln -s ../init.d/ipsec S47ipsec + -test -d $(RCDIR) && cd $(RCDIR)/../rc4.d ; ln -s ../init.d/ipsec S47ipsec + -test -d $(RCDIR) && cd $(RCDIR)/../rc5.d ; ln -s ../init.d/ipsec S47ipsec + -test -d $(RCDIR) && cd $(RCDIR)/../rc6.d ; ln -s ../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 2 21:38:15 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 +232,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 +338,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 Jun 4 10:44:49 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 Jun 4 10:45:44 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 Wed May 16 10:57:20 2001 @@ -0,0 +1,26 @@ +################################################### +# Adjust SSLDIR before make ... +SSLDIR=/usr/ssl + +# Adjust IPSECDIR before make install ... +IPSECDIR=/usr/lib/ipsec +################################################### + +VERSION = 0.4 + +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 _confread.patch + +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 Wed May 16 10:57:20 2001 @@ -0,0 +1,94 @@ +fswcert Utility +=============== + + +This replaces the grabkey and grabsubject utilities from the +FreeS/WAN X.509 patch, and supports the new configuration +options leftcert=... and rightcert=... + +Dependencies: + fswcert requires the openssl 0.9.5a 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|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 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 X.509 PEM-encoded certificates with FreeS/WAN directly, do this: +----------------------------------------------------------------------- + +- Adjust the IPSECDIR and SSLDIR in Makefile + +- Build fswcert with `make' + +- Install fswcert with `make install' + +- Patch FreeS/WAN's _confread with the patch provided + +- Put all the certificates you want to use with FreeS/WAN + in the /etc/ipsec.d/ directory + + +Then you can use these new options in ipsec.conf and includes: +-------------------------------------------------------------- + +leftcert=filename.pem + Reads the identity and public key from filename.pem + (Replaces both leftid=@~... and leftrsasigkex=0x...) + +rightcert=filename.pem + Reads the identity and public key from filename.pem + (Replaces both rightid=@~... and rightrsasigkex=0x...) + diff -BbruN freeswan-1.91.orig/utils/fswcert-0.4/_confread.patch freeswan-1.91/utils/fswcert-0.4/_confread.patch --- freeswan-1.91.orig/utils/fswcert-0.4/_confread.patch Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/utils/fswcert-0.4/_confread.patch Wed May 16 10:57:20 2001 @@ -0,0 +1,51 @@ +--- freeswan-1.5/utils/_confread Wed May 31 14:10:40 2000 ++++ freeswan-1.5-x509/utils/_confread Tue Sep 19 16:29:42 2000 +@@ -42,6 +42,7 @@ + # fi + + config=/etc/ipsec.conf ++fswcert="$IPSECDIR/fswcert --directory /etc/ipsec.d" + include=yes + type=conn + fieldfmt=yes +@@ -71,7 +72,7 @@ + else + cat $config + fi | +-awk 'BEGIN { ++awk -v "fswcert=$fswcert" 'BEGIN { + type = "'"$type"'" + names = "'"$*"'" + prefix = "'"$prefix"'" +@@ -122,6 +123,7 @@ + mkey = " spibase spi esp espenckey espauthkey espreplay_window" + left = left " leftespenckey leftespauthkey leftahkey" + left = left " leftespspi leftahspi leftid leftrsasigkey" ++ left = left " leftcert" + mkey = mkey " ah ahkey ahreplay_window" + right = left + gsub(/left/, "right", right) +@@ -313,6 +315,23 @@ + value = substr($0, equal+1) + if (value ~ /^"/) + value = substr(value, 2, length(value)-2) ++} ++name ~ /^(left|right)cert$/ { ++ side = name ++ gsub(/cert$/, "", side) ++ pipe = fswcert " --quiet --cert " value ++ pipe | getline ID ++ pipe | getline RSASIGKEY ++ if (close(pipe) != 0) ++ fail(ID); ++ gsub(/^.*id=/, "", ID) ++ gsub(/^.*rsasigkey=/, "", RSASIGKEY) ++ seen[side "cert"] = 1 ++ seen[side "id"] = 1 ++ seen[side "rsasigkey"] = 1 ++ output(o_parm, side "id", ID) ++ output(o_parm, side "rsasigkey", RSASIGKEY) ++ next + } + indefault { + if (name in default) 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 Wed May 16 11:20:34 2001 @@ -0,0 +1,550 @@ +/* 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, 2 }, + {"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 +int opt_what = 0; + +BIO *bio_err = NULL; + +enum input_file_type { IN_PKCS12 = 1, IN_X509 = 2, IN_RSA = 3 }; +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_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#%s DN: %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, PKCS12_SAFEBAG_free); + } + sk_pop_free(asafes, PKCS7_free); + return 0; +} + +int read_x509_file(BIO *bio_in, enum input_format input_format) +{ + X509 *x509 = NULL; + int error; + + if (input_format == FORMAT_PEM) + x509 = PEM_read_bio_X509(bio_in, NULL, NULL, NULL); + 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) + rsa = PEM_read_bio_RSAPrivateKey(bio_in, NULL, NULL, NULL); + 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; +} + +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, "x509")) + input_file_type = IN_X509; + else if (!strcmp(optarg, "rsa")) + input_file_type = IN_RSA; + else + goto synopsis; + break; + + case 2: /* input format */ + if (!strcmp(optarg, "PEM")) + input_format = FORMAT_PEM; + else if (!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_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|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-q --quiet\tsingle line error messages to stdout\n"); + } + return error; +} + 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 Jun 4 10:47:28 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 Wed May 16 10:57:20 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/rsakeygen freeswan-1.91/utils/rsakeygen --- freeswan-1.91.orig/utils/rsakeygen Wed Dec 31 19:00:00 1969 +++ freeswan-1.91/utils/rsakeygen Wed May 16 13:09:59 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} +awk 'NR>3 {print $0}' $KEYFILE >> ${IPSEC_SECRETS} +echo " }" >> ${IPSEC_SECRETS} +chmod 400 ${IPSEC_SECRETS} +exit 0 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 Jun 4 11:29:01 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 Jun 4 10:37:06 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 Jun 4 11:29:24 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 Jun 4 11:29:24 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 Wed May 16 10:57:20 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 Tue Jul 3 04:02:51 2001 @@ -1,2 +1,2 @@ /* 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-pkix1";