Index: /qca-tls/tags/psios2-0.10.1/COPYING
===================================================================
--- /qca-tls/tags/psios2-0.10.1/COPYING	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/COPYING	(revision 81)
@@ -0,0 +1,513 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
Index: /qca-tls/tags/psios2-0.10.1/README
===================================================================
--- /qca-tls/tags/psios2-0.10.1/README	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/README	(revision 81)
@@ -0,0 +1,16 @@
+QCA TLS Plugin v1.0
+-------------------
+Author: Justin Karneges <justin@affinix.com>
+Date:   September 15th, 2003
+
+This is a plugin to provide SSL/TLS capability to programs that
+utilize the Qt Cryptographic Architecture (QCA).
+
+Requirements:
+  OpenSSL Library (http://www.openssl.org/)
+
+Installation procedure:
+  ./configure
+  make
+  su -c "make install"
+
Index: /qca-tls/tags/psios2-0.10.1/configure
===================================================================
--- /qca-tls/tags/psios2-0.10.1/configure	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/configure	(revision 81)
@@ -0,0 +1,583 @@
+#!/bin/sh
+
+show_usage() {
+cat <<EOT
+Usage: ./configure [OPTION]...
+
+This script creates necessary configuration files to build/install.
+
+Main options:
+  --qtdir=[path]    Directory where Qt is installed.
+  --help            This help text.
+
+Dependency options:
+  --with-openssl-inc=[path]    Path to OpenSSL include files
+  --with-openssl-lib=[path]    Path to OpenSSL library files
+
+EOT
+}
+
+while [ $# -gt 0 ]; do
+	case "$1" in
+		--qtdir=*)
+			QTDIR=`expr "${1}" : "--qtdir=\(.*\)"`
+			shift
+			;;
+
+		--with-openssl-inc=*)
+			QC_WITH_OPENSSL_INC=`expr "${1}" : "--with-openssl-inc=\(.*\)"`
+			shift
+			;;
+
+		--with-openssl-lib=*)
+			QC_WITH_OPENSSL_LIB=`expr "${1}" : "--with-openssl-lib=\(.*\)"`
+			shift
+			;;
+
+		--debug)
+			QC_DEBUG="Y"
+			shift
+			;;
+		--help) show_usage; exit ;;
+		*) show_usage; exit ;;
+	esac
+done
+
+
+echo "Configuring qca-tls ..."
+
+if [ "$QC_DEBUG" = "Y" ]; then
+echo
+echo QTDIR=$QTDIR
+echo QC_WITH_OPENSSL_INC=$QC_WITH_OPENSSL_INC
+echo QC_WITH_OPENSSL_LIB=$QC_WITH_OPENSSL_LIB
+echo
+fi
+
+printf "Verifying Qt 3.x Multithreaded (MT) build environment ... "
+
+if [ -z "$QTDIR" ]; then
+	if [ "$QC_DEBUG" = "Y" ]; then
+		echo \$QTDIR not set... trying to find Qt manually
+	fi
+	for p in /usr/lib/qt /usr/share/qt /usr/share/qt3 /usr/local/lib/qt /usr/local/share/qt /usr/lib/qt3 /usr/local/lib/qt3 /usr/X11R6/share/qt /usr/qt/3 ; do
+		if [ -d "$p/mkspecs" ]; then
+			QTDIR=$p
+			break;
+		fi;
+	done
+	if [ -z "$QTDIR" ]; then
+		echo fail
+		echo
+		echo Unable to find Qt 'mkspecs'. Please set QTDIR
+		echo manually. Perhaps you need to install Qt 3
+		echo development utilities. You may download them either
+		echo from the vendor of your operating system or from
+		echo www.trolltech.com
+		echo
+		exit 1;
+	fi
+fi
+
+if [ ! -x "$QTDIR/bin/qmake" ]; then
+	if [ "$QC_DEBUG" = "Y" ]; then
+		echo Warning: qmake not in \$QTDIR/bin/qmake
+		echo trying to find it in \$PATH
+	fi
+	qm=`type -p qmake`
+	if [ -x "$qm" ]; then
+		if [ "$QC_DEBUG" = "Y" ]; then
+			echo qmake found in $qm
+		fi
+	else
+		echo fail
+		echo
+		echo Sorry, you seem to have a very unusual setup,
+		echo or I missdetected \$QTDIR=$QTDIR
+		echo
+		echo Please set \$QTDIR manually and make sure that
+		echo \$QTDIR/bin/qmake exists.
+		echo
+		exit 1;
+	fi
+else
+	qm=$QTDIR/bin/qmake
+fi
+
+gen_files() {
+cat >$1/modules.cpp <<EOT
+/*
+-----BEGIN QCMOD-----
+name: OpenSSL
+arg: with-openssl-inc=[path],Path to OpenSSL include files
+arg: with-openssl-lib=[path],Path to OpenSSL library files
+-----END QCMOD-----
+*/
+class qc_openssl : public ConfObj
+{
+public:
+	qc_openssl(Conf *c) : ConfObj(c) {}
+	QString name() const { return "OpenSSL"; }
+	QString shortname() const { return "openssl"; }
+	bool exec()
+	{
+		QString inc, lib;
+		QString s;
+		bool kb = false;
+		QString kbdir = "/usr/kerberos/include";
+
+		// Redhat 9?
+		if(QFileInfo(kbdir).exists())
+			kb = true;
+
+		s = conf->getenv("QC_WITH_OPENSSL_INC");
+		if(!s.isEmpty()) {
+			if(!conf->checkHeader(s, "openssl/ssl.h"))
+				return false;
+			inc = s;
+		}
+		else {
+			if(!conf->findHeader("openssl/ssl.h", QStringList(), &s))
+				return false;
+			inc = s;
+		}
+
+		s = conf->getenv("QC_WITH_OPENSSL_LIB");
+		if(!s.isEmpty()) {
+			if(!conf->checkLibrary(s, "ssl"))
+				return false;
+			lib = s;
+		}
+		else {
+			if(!conf->findLibrary("ssl", &s))
+				return false;
+			lib = s;
+		}
+
+		// is it at least openssl 0.9.7?
+		QString str =
+			"#include<openssl/opensslv.h>\n"
+			"int main()\n"
+			"{\n"
+			"  unsigned long x = OPENSSL_VERSION_NUMBER;\n"
+			"  if(x >= 0x00907000) return 0; else return 1;\n"
+			"}\n";
+		QString ext;
+		if(!inc.isEmpty())
+			ext += QString("-I") + inc + ' ';
+		if(kb)
+			ext += QString("-I") + kbdir + ' ';
+		if(!lib.isEmpty())
+			ext += QString("-L") + lib + " -lssl -lcrypto ";
+		int ret;
+		if(!conf->doCompileAndLink(str, ext, &ret))
+			return false;
+		if(ret == 0)
+			conf->addDefine("OSSL_097");
+
+		if(!inc.isEmpty())
+			conf->addIncludePath(inc);
+		if(kb)
+			conf->addIncludePath(kbdir);
+		if(!lib.isEmpty())
+			conf->addLib(QString("-L") + s);
+		conf->addLib("-lssl -lcrypto");
+
+		return true;
+	}
+};
+
+EOT
+cat >$1/modules_new.cpp <<EOT
+    o = new qc_openssl(conf);
+    o->required = true;
+    o->disabled = false;
+
+EOT
+cat >$1/conf.cpp <<EOT
+#include<stdio.h>
+#include<stdlib.h>
+#include<qstring.h>
+#include<qdict.h>
+#include<qptrlist.h>
+#include<qfileinfo.h>
+#include<qfile.h>
+#include<qdir.h>
+#include<qstringlist.h>
+
+class Conf;
+
+class ConfObj
+{
+public:
+	ConfObj(Conf *c);
+	virtual ~ConfObj();
+
+	virtual QString name() const=0;
+	virtual QString shortname() const=0;
+	virtual bool exec()=0;
+
+	Conf *conf;
+	bool required;
+	bool disabled;
+};
+
+typedef QPtrList<ConfObj> ConfObjList;
+typedef QPtrListIterator<ConfObj> ConfObjListIt;
+
+class Conf
+{
+public:
+	Conf() : vars(17)
+	{
+		list.setAutoDelete(true);
+		vars.setAutoDelete(true);
+
+		vars.insert("QMAKE_INCDIR_X11", new QString(X11_INC));
+		vars.insert("QMAKE_LIBDIR_X11", new QString(X11_LIBDIR));
+		vars.insert("QMAKE_LIBS_X11",   new QString(X11_LIB));
+		vars.insert("QMAKE_CC",         new QString(CC));
+	}
+
+	~Conf()
+	{
+	}
+
+	void added(ConfObj *o)
+	{
+		list.append(o);
+	}
+
+	QString getenv(const QString &var)
+	{
+		char *p = ::getenv(var.latin1());
+		if(!p)
+			return QString::null;
+		return QString(p);
+	}
+
+	bool exec()
+	{
+		ConfObjListIt it(list);
+		for(ConfObj *o; (o = it.current()); ++it) {
+			// if this was a disabled-by-default option, check if it was enabled
+			if(o->disabled) {
+				QString v = QString("QC_ENABLE_") + o->shortname();
+				if(getenv(v) != "Y")
+					continue;
+			}
+			// and the opposite?
+			else {
+				QString v = QString("QC_DISABLE_") + o->shortname();
+				if(getenv(v) == "Y")
+					continue;
+			}
+
+			printf("Checking for %s ...", o->name().latin1());
+			fflush(stdout);
+			bool ok = o->exec();
+			if(ok)
+				printf(" yes\n");
+			else
+				printf(" no\n");
+			if(!ok && o->required) {
+				printf("\nError: need %s!\n", o->name().latin1());
+				return false;
+			}
+		}
+		return true;
+	}
+
+	const QString & qvar(const QString &s)
+	{
+		QString *p = vars.find(s);
+		if(p)
+			return *p;
+		else
+			return blank;
+	}
+
+	QString expandIncludes(const QString &inc)
+	{
+		return QString("-I") + inc;
+	}
+
+	QString expandLibs(const QString &lib)
+	{
+		return QString("-L") + lib;
+	}
+
+	int doCommand(const QString &s)
+	{
+		//printf("[%s]\n", s.latin1());
+		int r = system((s + " 1>/dev/null 2>/dev/null").latin1());
+		//printf("returned: %d\n", r);
+		return r;
+	}
+
+	bool doCompileAndLink(const QString &filedata, const QString &flags, int *retcode=0)
+	{
+		QDir dir(".");
+		QString fname = "atest.c";
+		QString out = "atest";
+		QFile f(fname);
+		QCString cs = filedata.latin1();
+		if(!f.open(IO_WriteOnly | IO_Truncate))
+			return false;
+		f.writeBlock(cs.data(), cs.length());
+		f.close();
+
+		QString str = qvar("QMAKE_CC") + ' ' + fname + " -o " + out + ' ' + flags;
+		int r = doCommand(str);
+		if(r == 0 && retcode)
+			*retcode = doCommand(QString("./") + out);
+		dir.remove(fname);
+		dir.remove(out);
+		if(r != 0)
+			return false;
+		return true;
+	}
+
+	bool checkHeader(const QString &path, const QString &h)
+	{
+		QFileInfo fi(path + '/' + h);
+		if(fi.exists())
+			return true;
+		return false;
+	}
+
+	bool findHeader(const QString &h, const QStringList &ext, QString *inc)
+	{
+		if(checkHeader("/usr/include", h)) {
+			*inc = "";
+			return true;
+		}
+		QStringList dirs;
+		dirs += "/usr/local/include";
+		dirs += ext;
+		for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
+			if(checkHeader(*it, h)) {
+				*inc = *it;
+				return true;
+			}
+		}
+		return false;
+	}
+
+	bool checkLibrary(const QString &path, const QString &name)
+	{
+		QString str =
+			"int main()\n"
+			"{\n"
+			"    return 0;\n"
+			"}\n";
+
+		QString extra;
+		if(!path.isEmpty())
+			extra += QString("-L") + path + ' ';
+		extra += QString("-l") + name;
+		if(!doCompileAndLink(str, extra))
+			return false;
+		return true;
+	}
+
+	bool findLibrary(const QString &name, QString *lib)
+	{
+		if(checkLibrary("", name)) {
+			*lib = "";
+			return true;
+		}
+		if(checkLibrary("/usr/local/lib", name)) {
+			*lib = "/usr/local/lib";
+			return true;
+		}
+		return false;
+	}
+
+	void addDefine(const QString &str)
+	{
+		if(DEFINES.isEmpty())
+			DEFINES = str;
+		else
+			DEFINES += QString(" ") + str;
+	}
+
+	void addLib(const QString &str)
+	{
+		if(LIBS.isEmpty())
+			LIBS = str;
+		else
+			LIBS += QString(" ") + str;
+	}
+
+	void addIncludePath(const QString &str)
+	{
+		if(INCLUDEPATH.isEmpty())
+			INCLUDEPATH = str;
+		else
+			INCLUDEPATH += QString(" ") + str;
+	}
+
+	void addExtra(const QString &str)
+	{
+		extra += str + '\n';
+	}
+
+	QString DEFINES;
+	QString INCLUDEPATH;
+	QString LIBS;
+	QString extra;
+
+private:
+	ConfObjList list;
+	QDict<QString> vars;
+	QString blank;
+};
+
+ConfObj::ConfObj(Conf *c)
+{
+	conf = c;
+	conf->added(this);
+	required = false;
+	disabled = false;
+}
+
+ConfObj::~ConfObj()
+{
+}
+
+#include"modules.cpp"
+
+//----------------------------------------------------------------------------
+// main
+//----------------------------------------------------------------------------
+int main()
+{
+	Conf *conf = new Conf;
+	ConfObj *o;
+	o = 0;
+#include"modules_new.cpp"
+
+	printf("ok\n");
+	bool success = false;
+	if(conf->exec()) {
+		QFile f("conf.pri");
+		if(!f.open(IO_WriteOnly | IO_Truncate)) {
+			printf("Error writing %s\n", f.name().latin1());
+			return 1;
+		}
+
+		QString str;
+		str += "# qconf\n";
+		str += "QT_PATH_PLUGINS = " + QString(qInstallPathPlugins()) + '\n';
+		if(!conf->DEFINES.isEmpty())
+			str += "DEFINES += " + conf->DEFINES + '\n';
+		if(!conf->INCLUDEPATH.isEmpty())
+			str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n';
+		if(!conf->LIBS.isEmpty())
+			str += "LIBS += " + conf->LIBS + '\n';
+		if(!conf->extra.isEmpty())
+			str += conf->extra;
+		str += '\n';
+
+		char *p = getenv("BINDIR");
+		if(p) {
+			str += QString("target.path = ") + p + '\n';
+			str += "INSTALLS += target\n";
+		}
+
+		QCString cs = str.latin1();
+		f.writeBlock(cs.data(), cs.length());
+		f.close();
+		success = true;
+	}
+	delete conf;
+
+	if(success)
+		return 0;
+	else
+		return 1;
+}
+
+EOT
+cat >$1/conf.pro <<EOT
+TEMPLATE = app
+CONFIG += qt x11 thread console
+TARGET = conf
+
+DEFINES += X11_INC='"\$\$QMAKE_INCDIR_X11"'
+DEFINES += X11_LIBDIR='"\$\$QMAKE_LIBDIR_X11"'
+DEFINES += X11_LIB='"\$\$QMAKE_LIBS_X11"'
+DEFINES += CC='"\$\$QMAKE_CC"'
+
+SOURCES += conf.cpp
+
+EOT
+}
+
+export QTDIR
+export QC_WITH_OPENSSL_INC
+export QC_WITH_OPENSSL_LIB
+rm -rf .qconftemp
+(
+	mkdir .qconftemp
+	gen_files .qconftemp
+	cd .qconftemp
+	$qm conf.pro >/dev/null
+	QTDIR=$QTDIR make clean >/dev/null 2>&1
+	QTDIR=$QTDIR make >../conf.log 2>&1
+)
+
+if [ "$?" != "0" ]; then
+	rm -rf .qconftemp
+	echo fail
+	echo
+	echo "There was an error compiling 'conf'.  Be sure you have a proper"
+	echo "Qt 3.x Multithreaded (MT) build environment set up."
+	if [ ! -f "$QTDIR/lib/libqt-mt.so.3" ]; then
+		echo
+		echo "One possible reason is that you don't have"
+		echo "libqt-mt.so.3 installed in $QTDIR/lib/."
+	fi
+	echo
+	exit 1;
+fi
+
+.qconftemp/conf
+ret="$?"
+if [ "$ret" = "1" ]; then
+	rm -rf .qconftemp
+	echo
+	exit 1;
+else
+	if [ "$ret" != "0" ]; then
+		rm -rf .qconftemp
+		echo fail
+		echo
+		echo Unexpected error launching 'conf'
+		echo
+		exit 1;
+	fi
+fi
+rm -rf .qconftemp
+
+if [ -x "./qcextra" ]; then
+	./qcextra
+fi
+# run qmake
+$qm qca-tls.pro
+if [ "$?" != "0" ]; then
+	echo
+	exit 1;
+fi
+cat >Makefile.tmp <<EOT
+export QTDIR = $QTDIR
+EOT
+cat Makefile >> Makefile.tmp
+rm -f Makefile
+cp -f Makefile.tmp Makefile
+rm -f Makefile.tmp
+
+echo
+echo Good, your configure finished.  Now run \'make\'.
+echo
Index: /qca-tls/tags/psios2-0.10.1/mk.cmd
===================================================================
--- /qca-tls/tags/psios2-0.10.1/mk.cmd	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/mk.cmd	(revision 81)
@@ -0,0 +1,21 @@
+@echo off
+rem ----------------------------------------------
+rem a simple make launcher for both OS/2 and Win32
+rem ----------------------------------------------
+
+if .%OS%.==.Windows_NT. goto Win
+
+set MAKEFILE=Makefile.os2
+set MAKE=make
+goto Common
+
+:Win
+set MAKEFILE=Makefile.win
+set MAKE=nmake
+
+:Common
+if exist %MAKEFILE% goto :Make
+call qmake -o %MAKEFILE%
+
+:Make
+%MAKE% -f %MAKEFILE% %1 %2 %3 %4 %5 %6 %7 %8 %9
Index: /qca-tls/tags/psios2-0.10.1/mk.sh
===================================================================
--- /qca-tls/tags/psios2-0.10.1/mk.sh	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/mk.sh	(revision 81)
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+## @todo (r=dmik) someone needs to add code to test
+## for mac and to set MAKEFILE accordingly. Don't forget
+## to uncomment the mac:MAKEFILE line in psi.pro!
+
+MAKEFILE=Makefile.unix
+MAKE=make
+
+if !(test -f $MAKEFILE); then
+    qmake -o $MAKEFILE;
+fi
+
+$MAKE -f $MAKEFILE "$@"
Index: /qca-tls/tags/psios2-0.10.1/openssl.qcm
===================================================================
--- /qca-tls/tags/psios2-0.10.1/openssl.qcm	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/openssl.qcm	(revision 81)
@@ -0,0 +1,80 @@
+/*
+-----BEGIN QCMOD-----
+name: OpenSSL
+arg: with-openssl-inc=[path],Path to OpenSSL include files
+arg: with-openssl-lib=[path],Path to OpenSSL library files
+-----END QCMOD-----
+*/
+class qc_openssl : public ConfObj
+{
+public:
+	qc_openssl(Conf *c) : ConfObj(c) {}
+	QString name() const { return "OpenSSL"; }
+	QString shortname() const { return "openssl"; }
+	bool exec()
+	{
+		QString inc, lib;
+		QString s;
+		bool kb = false;
+		QString kbdir = "/usr/kerberos/include";
+
+		// Redhat 9?
+		if(QFileInfo(kbdir).exists())
+			kb = true;
+
+		s = conf->getenv("QC_WITH_OPENSSL_INC");
+		if(!s.isEmpty()) {
+			if(!conf->checkHeader(s, "openssl/ssl.h"))
+				return false;
+			inc = s;
+		}
+		else {
+			if(!conf->findHeader("openssl/ssl.h", QStringList(), &s))
+				return false;
+			inc = s;
+		}
+
+		s = conf->getenv("QC_WITH_OPENSSL_LIB");
+		if(!s.isEmpty()) {
+			if(!conf->checkLibrary(s, "ssl"))
+				return false;
+			lib = s;
+		}
+		else {
+			if(!conf->findLibrary("ssl", &s))
+				return false;
+			lib = s;
+		}
+
+		// is it at least openssl 0.9.7?
+		QString str =
+			"#include<openssl/opensslv.h>\n"
+			"int main()\n"
+			"{\n"
+			"  unsigned long x = OPENSSL_VERSION_NUMBER;\n"
+			"  if(x >= 0x00907000) return 0; else return 1;\n"
+			"}\n";
+		QString ext;
+		if(!inc.isEmpty())
+			ext += QString("-I") + inc + ' ';
+		if(kb)
+			ext += QString("-I") + kbdir + ' ';
+		if(!lib.isEmpty())
+			ext += QString("-L") + lib + " -lssl -lcrypto ";
+		int ret;
+		if(!conf->doCompileAndLink(str, ext, &ret))
+			return false;
+		if(ret == 0)
+			conf->addDefine("OSSL_097");
+
+		if(!inc.isEmpty())
+			conf->addIncludePath(inc);
+		if(kb)
+			conf->addIncludePath(kbdir);
+		if(!lib.isEmpty())
+			conf->addLib(QString("-L") + s);
+		conf->addLib("-lssl -lcrypto");
+
+		return true;
+	}
+};
Index: /qca-tls/tags/psios2-0.10.1/prepare
===================================================================
--- /qca-tls/tags/psios2-0.10.1/prepare	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/prepare	(revision 81)
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+cp ../../src/qca.h .
+cp ../../src/qcaprovider.h .
+
Index: /qca-tls/tags/psios2-0.10.1/qca-tls.cpp
===================================================================
--- /qca-tls/tags/psios2-0.10.1/qca-tls.cpp	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/qca-tls.cpp	(revision 81)
@@ -0,0 +1,1491 @@
+/*
+ * qca-tls.cpp - TLS plugin for QCA
+ * Copyright (C) 2003  Justin Karneges
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include"qca-tls.h"
+
+#include<qregexp.h>
+
+#include<openssl/sha.h>
+#include<openssl/md5.h>
+#include<openssl/evp.h>
+#include<openssl/bio.h>
+#include<openssl/pem.h>
+#include<openssl/rsa.h>
+#include<openssl/x509.h>
+#include<openssl/x509v3.h>
+#include<openssl/ssl.h>
+#include<openssl/err.h>
+#include<openssl/rand.h>
+
+#ifndef OSSL_097
+#define NO_AES
+#endif
+
+static QByteArray lib_randomArray(int size)
+{
+	if(RAND_status() == 0) {
+		srand(time(NULL));
+		char buf[128];
+		for(int n = 0; n < 128; ++n)
+			buf[n] = rand();
+		RAND_seed(buf, 128);
+	}
+	QByteArray a(size);
+	RAND_bytes((unsigned char *)a.data(), a.size());
+	return a;
+}
+
+static bool lib_generateKeyIV(const EVP_CIPHER *_type, const QByteArray &data, const QByteArray &salt, QByteArray *key, QByteArray *iv, int keysize=-1)
+{
+	QByteArray k, i;
+	unsigned char *kp = 0;
+	unsigned char *ip = 0;
+	EVP_CIPHER type = *_type;
+	if(keysize != -1)
+		type.key_len = keysize;
+	if(key) {
+		k.resize(type.key_len);
+		kp = (unsigned char *)k.data();
+	}
+	if(iv) {
+		i.resize(type.iv_len);
+		ip = (unsigned char *)i.data();
+	}
+	if(!EVP_BytesToKey(&type, EVP_sha1(), (unsigned char *)salt.data(), (unsigned char *)data.data(), data.size(), 1, kp, ip))
+		return false;
+	if(key)
+		*key = k;
+	if(iv)
+		*iv = i;
+	return true;
+}
+
+static void appendArray(QByteArray *a, const QByteArray &b)
+{
+	int oldsize = a->size();
+	a->resize(oldsize + b.size());
+	memcpy(a->data() + oldsize, b.data(), b.size());
+}
+
+static QByteArray bio2buf(BIO *b)
+{
+	QByteArray buf;
+	while(1) {
+		char block[1024];
+		int ret = BIO_read(b, block, 1024);
+		int oldsize = buf.size();
+		buf.resize(oldsize + ret);
+		memcpy(buf.data() + oldsize, block, ret);
+		if(ret != 1024)
+			break;
+	}
+	BIO_free(b);
+	return buf;
+}
+
+class SHA1Context : public QCA_HashContext
+{
+public:
+	SHA1Context()
+	{
+		reset();
+	}
+
+	QCA_HashContext *clone()
+	{
+		return new SHA1Context(*this);
+	}
+
+	void reset()
+	{
+		SHA1_Init(&c);
+	}
+
+	void update(const char *in, unsigned int len)
+	{
+		SHA1_Update(&c, in, len);
+	}
+
+	void final(QByteArray *out)
+	{
+		QByteArray buf(20);
+		SHA1_Final((unsigned char *)buf.data(), &c);
+		*out = buf;
+	}
+
+	SHA_CTX c;
+};
+
+class MD5Context : public QCA_HashContext
+{
+public:
+	MD5Context()
+	{
+		reset();
+	}
+
+	QCA_HashContext *clone()
+	{
+		return new MD5Context(*this);
+	}
+
+	void reset()
+	{
+		MD5_Init(&c);
+	}
+
+	void update(const char *in, unsigned int len)
+	{
+		MD5_Update(&c, in, len);
+	}
+
+	void final(QByteArray *out)
+	{
+		QByteArray buf(16);
+		MD5_Final((unsigned char *)buf.data(), &c);
+		*out = buf;
+	}
+
+	MD5_CTX c;
+};
+
+class EVPCipherContext : public QCA_CipherContext
+{
+public:
+	EVPCipherContext()
+	{
+		type = 0;
+	}
+
+	virtual ~EVPCipherContext()
+	{
+		if(type) {
+			EVP_CIPHER_CTX_cleanup(&c);
+			type = 0;
+		}
+	}
+
+	QCA_CipherContext *clone()
+	{
+		EVPCipherContext *cc = cloneSelf();
+		cc->r = r.copy();
+		return cc;
+	}
+
+	virtual EVPCipherContext *cloneSelf() const=0;
+	virtual const EVP_CIPHER *getType(int mode) const=0;
+
+	int keySize() { return getType(QCA::CBC)->key_len; }
+	int blockSize() { return getType(QCA::CBC)->block_size; }
+
+	bool generateKey(char *out, int keysize)
+	{
+		QByteArray a;
+		if(!lib_generateKeyIV(getType(QCA::CBC), lib_randomArray(128), lib_randomArray(2), &a, 0, keysize))
+			return false;
+		memcpy(out, a.data(), a.size());
+		return true;
+	}
+
+	bool generateIV(char *out)
+	{
+		QByteArray a;
+		if(!lib_generateKeyIV(getType(QCA::CBC), lib_randomArray(128), lib_randomArray(2), 0, &a))
+			return false;
+		memcpy(out, a.data(), a.size());
+		return true;
+	}
+
+	bool setup(int _dir, int mode, const char *key, int keysize, const char *iv, bool _pad)
+	{
+		dir = _dir;
+		pad = _pad;
+		type = getType(mode);
+		r.resize(0);
+		EVP_CIPHER_CTX_init(&c);
+
+		if(dir == QCA::Encrypt) {
+			if(!EVP_EncryptInit(&c, type, NULL, NULL))
+				return false;
+			if(keysize != type->key_len)
+				EVP_CIPHER_CTX_set_key_length(&c, keysize);
+			if(!EVP_EncryptInit(&c, NULL, (unsigned char *)key, (unsigned char *)iv))
+				return false;
+		}
+		else {
+			if(!EVP_DecryptInit(&c, type, NULL, NULL))
+				return false;
+			if(keysize != type->key_len)
+				EVP_CIPHER_CTX_set_key_length(&c, keysize);
+			if(!EVP_DecryptInit(&c, NULL, (unsigned char *)key, (unsigned char *)iv))
+				return false;
+		}
+		return true;
+	}
+
+	bool update(const char *in, unsigned int len)
+	{
+		QByteArray result(len + type->block_size);
+		int olen;
+		if(dir == QCA::Encrypt || !pad) {
+			if(!EVP_EncryptUpdate(&c, (unsigned char *)result.data(), &olen, (unsigned char *)in, len))
+				return false;
+		}
+		else {
+			if(!EVP_DecryptUpdate(&c, (unsigned char *)result.data(), &olen, (unsigned char *)in, len))
+				return false;
+		}
+		result.resize(olen);
+		appendArray(&r, result);
+		return true;
+	}
+
+	bool final(QByteArray *out)
+	{
+		if(pad) {
+			QByteArray result(type->block_size);
+			int olen;
+			if(dir == QCA::Encrypt) {
+				if(!EVP_EncryptFinal(&c, (unsigned char *)result.data(), &olen))
+					return false;
+			}
+			else {
+				if(!EVP_DecryptFinal(&c, (unsigned char *)result.data(), &olen))
+					return false;
+			}
+			result.resize(olen);
+			appendArray(&r, result);
+		}
+
+		*out = r.copy();
+		r.resize(0);
+		return true;
+	}
+
+	EVP_CIPHER_CTX c;
+	const EVP_CIPHER *type;
+	QByteArray r;
+	int dir;
+	bool pad;
+};
+
+class BlowFishContext : public EVPCipherContext
+{
+public:
+	EVPCipherContext *cloneSelf() const { return new BlowFishContext(*this); }
+	const EVP_CIPHER *getType(int mode) const
+	{
+		if(mode == QCA::CBC)
+			return EVP_bf_cbc();
+		else if(mode == QCA::CFB)
+			return EVP_bf_cfb();
+		else
+			return 0;
+	}
+};
+
+class TripleDESContext : public EVPCipherContext
+{
+public:
+	EVPCipherContext *cloneSelf() const { return new TripleDESContext(*this); }
+	const EVP_CIPHER *getType(int mode) const
+	{
+		if(mode == QCA::CBC)
+			return EVP_des_ede3_cbc();
+		else if(mode == QCA::CFB)
+			return EVP_des_ede3_cfb();
+		else
+			return 0;
+	}
+};
+
+#ifndef NO_AES
+class AES128Context : public EVPCipherContext
+{
+public:
+	EVPCipherContext *cloneSelf() const { return new AES128Context(*this); }
+	const EVP_CIPHER *getType(int mode) const
+	{
+		if(mode == QCA::CBC)
+			return EVP_aes_128_cbc();
+		else if(mode == QCA::CFB)
+			return EVP_aes_128_cfb();
+		else
+			return 0;
+	}
+};
+
+class AES256Context : public EVPCipherContext
+{
+public:
+	EVPCipherContext *cloneSelf() const { return new AES256Context(*this); }
+	const EVP_CIPHER *getType(int mode) const
+	{
+		if(mode == QCA::CBC)
+			return EVP_aes_256_cbc();
+		else if(mode == QCA::CFB)
+			return EVP_aes_256_cfb();
+		else
+			return 0;
+	}
+};
+#endif
+
+class RSAKeyContext : public QCA_RSAKeyContext
+{
+public:
+	RSAKeyContext()
+	{
+		pub = 0;
+		sec = 0;
+	}
+
+	~RSAKeyContext()
+	{
+		reset();
+	}
+
+	void reset()
+	{
+		if(pub) {
+			RSA_free(pub);
+			pub = 0;
+		}
+		if(sec) {
+			RSA_free(sec);
+			sec = 0;
+		}
+	}
+
+	void separate(RSA *r, RSA **_pub, RSA **_sec)
+	{
+		// public
+		unsigned char *buf, *p;
+		int len = i2d_RSAPublicKey(r, NULL);
+		if(len > 0) {
+			buf = (unsigned char *)malloc(len);
+			p = buf;
+			i2d_RSAPublicKey(r, &p);
+			p = buf;
+#ifdef OSSL_097
+			*_pub = d2i_RSAPublicKey(NULL, (const unsigned char **)&p, len);
+#else
+			*_pub = d2i_RSAPublicKey(NULL, (unsigned char **)&p, len);
+#endif
+			free(buf);
+		}
+
+		len = i2d_RSAPrivateKey(r, NULL);
+		if(len > 0) {
+			buf = (unsigned char *)malloc(len);
+			p = buf;
+			i2d_RSAPrivateKey(r, &p);
+			p = buf;
+#ifdef OSSL_097
+			*_sec = d2i_RSAPrivateKey(NULL, (const unsigned char **)&p, len);
+#else
+			*_sec = d2i_RSAPrivateKey(NULL, (unsigned char **)&p, len);
+#endif
+			free(buf);
+		}
+	}
+
+	bool isNull() const
+	{
+		if(!pub && !sec)
+			return true;
+		return false;
+	}
+
+	bool havePublic() const
+	{
+		return pub ? true : false;
+	}
+
+	bool havePrivate() const
+	{
+		return sec ? true : false;
+	}
+
+	bool createFromDER(const char *in, unsigned int len)
+	{
+		RSA *r;
+		void *p;
+
+		// private?
+		p = (void *)in;
+#ifdef OSSL_097
+		r = d2i_RSAPrivateKey(NULL, (const unsigned char **)&p, len);
+#else
+		r = d2i_RSAPrivateKey(NULL, (unsigned char **)&p, len);
+#endif
+		if(r) {
+			reset();
+
+			// private means both, I think, so separate them
+			separate(r, &pub, &sec);
+			return true;
+		}
+		else {
+			// public?
+			p = (void *)in;
+#ifdef OSSL_097
+			r = d2i_RSAPublicKey(NULL, (const unsigned char **)&p, len);
+#else
+			r = d2i_RSAPublicKey(NULL, (unsigned char **)&p, len);
+#endif
+			if(!r) {
+				// try this other public function, for whatever reason
+				p = (void *)in;
+#ifdef OSSL_097
+				r = d2i_RSA_PUBKEY(NULL, (const unsigned char **)&p, len);
+#else
+				r = d2i_RSA_PUBKEY(NULL, (unsigned char **)&p, len);
+#endif
+			}
+			if(r) {
+				if(pub) {
+					RSA_free(pub);
+				}
+				pub = r;
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	bool createFromPEM(const char *in, unsigned int len)
+	{
+		BIO *bi;
+
+		// private?
+		bi = BIO_new(BIO_s_mem());
+		BIO_write(bi, in, len);
+		RSA *r = PEM_read_bio_RSAPrivateKey(bi, NULL, NULL, NULL);
+		BIO_free(bi);
+		if(r) {
+			reset();
+			separate(r, &pub, &sec);
+			return true;
+		}
+		else {
+			// public?
+			bi = BIO_new(BIO_s_mem());
+			BIO_write(bi, in, len);
+			r = PEM_read_bio_RSAPublicKey(bi, NULL, NULL, NULL);
+			BIO_free(bi);
+			if(r) {
+				if(pub) {
+					RSA_free(pub);
+				}
+				pub = r;
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	bool createFromNative(void *in)
+	{
+		reset();
+		separate((RSA *)in, &pub, &sec);
+		return true;
+	}
+
+	bool generate(unsigned int bits)
+	{
+		RSA *r = RSA_generate_key(bits, RSA_F4, NULL, NULL);
+		if(!r)
+			return false;
+		separate(r, &pub, &sec);
+		RSA_free(r);
+		return true;
+	}
+
+	QCA_RSAKeyContext *clone() const
+	{
+		// deep copy
+		RSAKeyContext *c = new RSAKeyContext;
+		if(pub) {
+			++(pub->references);
+			c->pub = pub; //RSAPublicKey_dup(pub);
+		}
+		if(sec) {
+			++(sec->references);
+			c->sec = sec; //RSAPrivateKey_dup(sec);
+		}
+		return c;
+	}
+
+	bool toDER(QByteArray *out, bool publicOnly)
+	{
+		if(sec && !publicOnly) {
+			int len = i2d_RSAPrivateKey(sec, NULL);
+			QByteArray buf(len);
+			unsigned char *p;
+			p = (unsigned char *)buf.data();
+			i2d_RSAPrivateKey(sec, &p);
+			*out = buf;
+			return true;
+		}
+		else if(pub) {
+			int len = i2d_RSAPublicKey(pub, NULL);
+			QByteArray buf(len);
+			unsigned char *p;
+			p = (unsigned char *)buf.data();
+			i2d_RSAPublicKey(pub, &p);
+			*out = buf;
+			return true;
+		}
+		else
+			return false;
+	}
+
+	bool toPEM(QByteArray *out, bool publicOnly)
+	{
+		if(sec && !publicOnly) {
+			BIO *bo = BIO_new(BIO_s_mem());
+			PEM_write_bio_RSAPrivateKey(bo, sec, NULL, NULL, 0, NULL, NULL);
+			*out = bio2buf(bo);
+			return true;
+		}
+		else if(pub) {
+			BIO *bo = BIO_new(BIO_s_mem());
+			PEM_write_bio_RSAPublicKey(bo, pub);
+			*out = bio2buf(bo);
+			return true;
+		}
+		else
+			return false;
+
+	}
+
+	bool encrypt(const QByteArray &in, QByteArray *out, bool oaep)
+	{
+		if(!pub)
+			return false;
+
+		int size = RSA_size(pub);
+		int flen = in.size();
+		if(oaep) {
+			if(flen >= size - 41)
+				flen = size - 41;
+		}
+		else {
+			if(flen >= size - 11)
+				flen = size - 11;
+		}
+		QByteArray result(size);
+		unsigned char *from = (unsigned char *)in.data();
+		unsigned char *to = (unsigned char *)result.data();
+		int ret = RSA_public_encrypt(flen, from, to, pub, oaep ? RSA_PKCS1_OAEP_PADDING : RSA_PKCS1_PADDING);
+		if(ret == -1)
+			return false;
+		result.resize(ret);
+
+		*out = result;
+		return true;
+	}
+
+	bool decrypt(const QByteArray &in, QByteArray *out, bool oaep)
+	{
+		if(!sec)
+			return false;
+
+		int size = RSA_size(sec);
+		int flen = in.size();
+		QByteArray result(size);
+		unsigned char *from = (unsigned char *)in.data();
+		unsigned char *to = (unsigned char *)result.data();
+		int ret = RSA_private_decrypt(flen, from, to, sec, oaep ? RSA_PKCS1_OAEP_PADDING : RSA_PKCS1_PADDING);
+		if(ret == -1)
+			return false;
+		result.resize(ret);
+
+		*out = result;
+		return true;
+	}
+
+	RSA *pub, *sec;
+};
+
+static QValueList<QCA_CertProperty> nameToProperties(struct X509_name_st *name)
+{
+	QValueList<QCA_CertProperty> list;
+
+	for(int n = 0; n < X509_NAME_entry_count(name); ++n) {
+		X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, n);
+		QCA_CertProperty p;
+
+		ASN1_OBJECT *ao = X509_NAME_ENTRY_get_object(ne);
+		int nid = OBJ_obj2nid(ao);
+		if(nid == NID_undef)
+			continue;
+		p.var = OBJ_nid2sn(nid);
+
+		ASN1_STRING *as = X509_NAME_ENTRY_get_data(ne);
+		QCString c;
+		c.resize(as->length+1);
+		strncpy(c.data(), (char *)as->data, as->length);
+		p.val = QString::fromLatin1(c);
+		list += p;
+	}
+
+	return list;
+}
+
+// (taken from kdelibs) -- Justin
+//
+// This code is mostly taken from OpenSSL v0.9.5a
+// by Eric Young
+QDateTime ASN1_UTCTIME_QDateTime(ASN1_UTCTIME *tm, int *isGmt)
+{
+	QDateTime qdt;
+	char *v;
+	int gmt=0;
+	int i;
+	int y=0,M=0,d=0,h=0,m=0,s=0;
+	QDate qdate;
+	QTime qtime;
+
+	i = tm->length;
+	v = (char *)tm->data;
+
+	if (i < 10) goto auq_err;
+	if (v[i-1] == 'Z') gmt=1;
+	for (i=0; i<10; i++)
+		if ((v[i] > '9') || (v[i] < '0')) goto auq_err;
+	y = (v[0]-'0')*10+(v[1]-'0');
+	if (y < 50) y+=100;
+	M = (v[2]-'0')*10+(v[3]-'0');
+	if ((M > 12) || (M < 1)) goto auq_err;
+	d = (v[4]-'0')*10+(v[5]-'0');
+	h = (v[6]-'0')*10+(v[7]-'0');
+	m =  (v[8]-'0')*10+(v[9]-'0');
+	if (    (v[10] >= '0') && (v[10] <= '9') &&
+		(v[11] >= '0') && (v[11] <= '9'))
+		s = (v[10]-'0')*10+(v[11]-'0');
+
+	// localize the date and display it.
+	qdate.setYMD(y+1900, M, d);
+	qtime.setHMS(h,m,s);
+	qdt.setDate(qdate); qdt.setTime(qtime);
+auq_err:
+	if (isGmt) *isGmt = gmt;
+	return qdt;
+}
+
+// (adapted from kdelibs) -- Justin
+static bool cnMatchesAddress(const QString &_cn, const QString &peerHost)
+{
+	QString cn = _cn.stripWhiteSpace().lower();
+	QRegExp rx;
+
+	// Check for invalid characters
+	if(QRegExp("[^a-zA-Z0-9\\.\\*\\-]").search(cn) >= 0)
+		return false;
+
+	// Domains can legally end with '.'s.  We don't need them though.
+	while(cn.endsWith("."))
+		cn.truncate(cn.length()-1);
+
+	// Do not let empty CN's get by!!
+	if(cn.isEmpty())
+		return false;
+
+	// Check for IPv4 address
+	rx.setPattern("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}");
+	if(rx.exactMatch(peerHost))
+		return peerHost == cn;
+
+	// Check for IPv6 address here...
+	rx.setPattern("^\\[.*\\]$");
+	if(rx.exactMatch(peerHost))
+		return peerHost == cn;
+
+	if(cn.contains('*')) {
+		// First make sure that there are at least two valid parts
+		// after the wildcard (*).
+		QStringList parts = QStringList::split('.', cn, false);
+
+		while(parts.count() > 2)
+			parts.remove(parts.begin());
+
+		if(parts.count() != 2) {
+			return false;  // we don't allow *.root - that's bad
+		}
+
+		if(parts[0].contains('*') || parts[1].contains('*')) {
+			return false;
+		}
+
+		// RFC2818 says that *.example.com should match against
+		// foo.example.com but not bar.foo.example.com
+		// (ie. they must have the same number of parts)
+		if(QRegExp(cn, false, true).exactMatch(peerHost) &&
+			QStringList::split('.', cn, false).count() ==
+			QStringList::split('.', peerHost, false).count())
+			return true;
+
+		return false;
+	}
+
+	// We must have an exact match in this case (insensitive though)
+	// (note we already did .lower())
+	if(cn == peerHost)
+		return true;
+	return false;
+}
+
+class CertContext : public QCA_CertContext
+{
+public:
+	CertContext()
+	{
+		x = 0;
+	}
+
+	~CertContext()
+	{
+		reset();
+	}
+
+	QCA_CertContext *clone() const
+	{
+		CertContext *c = new CertContext(*this);
+		if(x) {
+			++(x->references);
+			c->x = x;
+		}
+		return c;
+	}
+
+	void reset()
+	{
+		if(x) {
+			X509_free(x);
+			x = 0;
+
+			serial = "";
+			v_subject = "";
+			v_issuer = "";
+			cp_subject.clear();
+			cp_issuer.clear();
+			na = QDateTime();
+			nb = QDateTime();
+		}
+	}
+
+	bool isNull() const
+	{
+		return (x ? false: true);
+	}
+
+	bool createFromDER(const char *in, unsigned int len)
+	{
+#ifdef OSSL_097
+		const unsigned char *p = (const unsigned char *)in;
+#else
+		unsigned char *p = (unsigned char *)in;
+#endif
+		X509 *t = d2i_X509(NULL, &p, len);
+		if(!t)
+			return false;
+		fromX509(t);
+		X509_free(t);
+		return true;
+	}
+
+	bool createFromPEM(const char *in, unsigned int len)
+	{
+		BIO *bi = BIO_new(BIO_s_mem());
+		BIO_write(bi, in, len);
+		X509 *t = PEM_read_bio_X509(bi, NULL, NULL, NULL);
+		BIO_free(bi);
+		if(!t)
+			return false;
+		fromX509(t);
+		X509_free(t);
+		return true;
+	}
+
+	bool toDER(QByteArray *out)
+	{
+		int len = i2d_X509(x, NULL);
+		QByteArray buf(len);
+		unsigned char *p = (unsigned char *)buf.data();
+		i2d_X509(x, &p);
+		*out = buf;
+		return true;
+	}
+
+	bool toPEM(QByteArray *out)
+	{
+		BIO *bo = BIO_new(BIO_s_mem());
+		PEM_write_bio_X509(bo, x);
+		*out = bio2buf(bo);
+		return true;
+	}
+
+	void fromX509(X509 *t)
+	{
+		reset();
+		++(t->references);
+		x = t;
+
+		// serial number
+		ASN1_INTEGER *ai = X509_get_serialNumber(x);
+		if(ai) {
+			char *rep = i2s_ASN1_INTEGER(NULL, ai);
+			serial = rep;
+			OPENSSL_free(rep);
+		}
+
+		// validity dates
+		nb = ASN1_UTCTIME_QDateTime(X509_get_notBefore(x), NULL);
+		na = ASN1_UTCTIME_QDateTime(X509_get_notAfter(x), NULL);
+
+		// extract the subject/issuer strings
+		struct X509_name_st *sn = X509_get_subject_name(x);
+		struct X509_name_st *in = X509_get_issuer_name(x);
+		char buf[1024];
+		X509_NAME_oneline(sn, buf, 1024);
+		v_subject = buf;
+		X509_NAME_oneline(in, buf, 1024);
+		v_issuer = buf;
+
+		// extract the subject/issuer contents
+		cp_subject = nameToProperties(sn);
+		cp_issuer  = nameToProperties(in);
+	}
+
+	QString serialNumber() const
+	{
+		return serial;
+	}
+
+	QString subjectString() const
+	{
+		return v_subject;
+	}
+
+	QString issuerString() const
+	{
+		return v_issuer;
+	}
+
+	QValueList<QCA_CertProperty> subject() const
+	{
+		return cp_subject;
+	}
+
+	QValueList<QCA_CertProperty> issuer() const
+	{
+		return cp_issuer;
+	}
+
+	QDateTime notBefore() const
+	{
+		return nb;
+	}
+
+	QDateTime notAfter() const
+	{
+		return na;
+	}
+
+	bool matchesAddress(const QString &realHost) const
+	{
+		QString peerHost = realHost.stripWhiteSpace();
+		while(peerHost.endsWith("."))
+			peerHost.truncate(peerHost.length()-1);
+		peerHost = peerHost.lower();
+
+		QString cn;
+		for(QValueList<QCA_CertProperty>::ConstIterator it = cp_subject.begin(); it != cp_subject.end(); ++it) {
+			if((*it).var == "CN") {
+				cn = (*it).val;
+				break;
+			}
+		}
+		if(cnMatchesAddress(cn, peerHost))
+			return true;
+		return false;
+	}
+
+	X509 *x;
+	QString serial, v_subject, v_issuer;
+	QValueList<QCA_CertProperty> cp_subject, cp_issuer;
+	QDateTime nb, na;
+};
+
+static bool ssl_init = false;
+class TLSContext : public QCA_TLSContext
+{
+public:
+	enum { Good, TryAgain, Bad };
+	enum { Idle, Connect, Accept, Handshake, Active, Closing };
+
+	bool serv;
+	int mode;
+	QByteArray sendQueue, recvQueue;
+
+	CertContext *cert;
+	RSAKeyContext *key;
+
+	SSL *ssl;
+	SSL_METHOD *method;
+	SSL_CTX *context;
+	BIO *rbio, *wbio;
+	CertContext cc;
+	int vr;
+	bool v_eof;
+
+	TLSContext()
+	{
+		if(!ssl_init) {
+			SSL_library_init();
+			SSL_load_error_strings();
+			ssl_init = true;
+		}
+
+		ssl = 0;
+		context = 0;
+		cert = 0;
+		key = 0;
+	}
+
+	~TLSContext()
+	{
+		reset();
+	}
+
+	void reset()
+	{
+		if(ssl) {
+			SSL_free(ssl);
+			ssl = 0;
+		}
+		if(context) {
+			SSL_CTX_free(context);
+			context = 0;
+		}
+		if(cert) {
+			delete cert;
+			cert = 0;
+		}
+		if(key) {
+			delete key;
+			key = 0;
+		}
+
+		sendQueue.resize(0);
+		recvQueue.resize(0);
+		mode = Idle;
+		cc.reset();
+		vr = QCA::TLS::Unknown;
+		v_eof = false;
+	}
+
+	bool eof() const
+	{
+		return v_eof;
+	}
+
+	bool startClient(const QPtrList<QCA_CertContext> &store, const QCA_CertContext &_cert, const QCA_RSAKeyContext &_key)
+	{
+		reset();
+		serv = false;
+		method = SSLv23_client_method();
+
+		if(!setup(store, _cert, _key))
+			return false;
+
+		mode = Connect;
+		return true;
+	}
+
+	bool startServer(const QPtrList<QCA_CertContext> &store, const QCA_CertContext &_cert, const QCA_RSAKeyContext &_key)
+	{
+		reset();
+		serv = true;
+		method = SSLv23_server_method();
+
+		if(!setup(store, _cert, _key))
+			return false;
+
+		mode = Accept;
+		return true;
+	}
+
+	bool setup(const QPtrList<QCA_CertContext> &list, const QCA_CertContext &_cc, const QCA_RSAKeyContext &kc)
+	{
+		context = SSL_CTX_new(method);
+		if(!context) {
+			reset();
+			return false;
+		}
+
+		// load the cert store
+		if(!list.isEmpty()) {
+			X509_STORE *store = SSL_CTX_get_cert_store(context);
+			QPtrListIterator<QCA_CertContext> it(list);
+			for(CertContext *i; (i = (CertContext *)it.current()); ++it)
+				X509_STORE_add_cert(store, i->x);
+		}
+
+		ssl = SSL_new(context);
+		if(!ssl) {
+			reset();
+			return false;
+		}
+		SSL_set_ssl_method(ssl, method); // can this return error?
+
+		// setup the memory bio
+		rbio = BIO_new(BIO_s_mem());
+		wbio = BIO_new(BIO_s_mem());
+
+		// this passes control of the bios to ssl.  we don't need to free them.
+		SSL_set_bio(ssl, rbio, wbio);
+
+		// setup the cert to send
+		if(!_cc.isNull() && !kc.isNull()) {
+			cert = static_cast<CertContext*>(_cc.clone());
+			key = static_cast<RSAKeyContext*>(kc.clone());
+			if(SSL_use_certificate(ssl, cert->x) != 1) {
+				reset();
+				return false;
+			}
+			if(SSL_use_RSAPrivateKey(ssl, key->sec) != 1) {
+				reset();
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	int handshake(const QByteArray &in, QByteArray *out)
+	{
+		if(!in.isEmpty())
+			BIO_write(rbio, in.data(), in.size());
+
+		if(mode == Connect) {
+			int ret = doConnect();
+			if(ret == Good) {
+				mode = Handshake;
+			}
+			else if(ret == Bad) {
+				reset();
+				return Error;
+			}
+		}
+
+		if(mode == Accept) {
+			int ret = doAccept();
+			if(ret == Good) {
+				getCert();
+				mode = Active;
+			}
+			else if(ret == Bad) {
+				reset();
+				return Error;
+			}
+		}
+
+		if(mode == Handshake) {
+			int ret = doHandshake();
+			if(ret == Good) {
+				getCert();
+				mode = Active;
+			}
+			else if(ret == Bad) {
+				reset();
+				return Error;
+			}
+		}
+
+		// process outgoing
+		*out = readOutgoing();
+
+		if(mode == Active)
+			return Success;
+		else
+			return Continue;
+	}
+
+	int shutdown(const QByteArray &in, QByteArray *out)
+	{
+		if(!in.isEmpty())
+			BIO_write(rbio, in.data(), in.size());
+
+		int ret = doShutdown();
+		if(ret == Bad) {
+			reset();
+			return Error;
+		}
+
+		*out = readOutgoing();
+
+		if(ret == Good) {
+			mode = Idle;
+			return Success;
+		}
+		else {
+			mode = Closing;
+			return Continue;
+		}
+	}
+
+	void getCert()
+	{
+		// verify the certificate
+		int code = QCA::TLS::Unknown;
+		X509 *x = SSL_get_peer_certificate(ssl);
+		if(x) {
+			cc.fromX509(x);
+			X509_free(x);
+			int ret = SSL_get_verify_result(ssl);
+			if(ret == X509_V_OK)
+				code = QCA::TLS::Valid;
+			else
+				code = resultToCV(ret);
+		}
+		else {
+			cc.reset();
+			code = QCA::TLS::NoCert;
+		}
+		vr = code;
+	}
+
+	bool encode(const QByteArray &plain, QByteArray *to_net, int *enc)
+	{
+		if(mode != Active)
+			return false;
+		appendArray(&sendQueue, plain);
+
+		int encoded = 0;
+		if(sendQueue.size() > 0) {
+			int ret = SSL_write(ssl, sendQueue.data(), sendQueue.size());
+
+			enum { Good, Continue, Done, Error };
+			int m;
+			if(ret <= 0) {
+				int x = SSL_get_error(ssl, ret);
+				if(x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE)
+					m = Continue;
+				else if(x == SSL_ERROR_ZERO_RETURN)
+					m = Done;
+				else
+					m = Error;
+			}
+			else {
+				m = Good;
+				encoded = ret;
+				int newsize = sendQueue.size() - encoded;
+				char *r = sendQueue.data();
+				memmove(r, r + encoded, newsize);
+				sendQueue.resize(newsize);
+			}
+
+			if(m == Done) {
+				sendQueue.resize(0);
+				v_eof = true;
+				return false;
+			}
+			if(m == Error) {
+				sendQueue.resize(0);
+				return false;
+			}
+		}
+
+		*to_net = readOutgoing();
+		*enc = encoded;
+		return true;
+	}
+
+	bool decode(const QByteArray &from_net, QByteArray *plain, QByteArray *to_net)
+	{
+		if(mode != Active)
+			return false;
+		if(!from_net.isEmpty())
+			BIO_write(rbio, from_net.data(), from_net.size());
+
+		QByteArray a;
+		while(!v_eof) {
+			a.resize(8192);
+			int ret = SSL_read(ssl, a.data(), a.size());
+			if(ret > 0) {
+				if(ret != (int)a.size())
+					a.resize(ret);
+				appendArray(&recvQueue, a);
+			}
+			else if(ret <= 0) {
+				int x = SSL_get_error(ssl, ret);
+				if(x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE)
+					break;
+				else if(x == SSL_ERROR_ZERO_RETURN)
+					v_eof = true;
+				else
+					return false;
+			}
+		}
+
+		*plain = recvQueue.copy();
+		recvQueue.resize(0);
+
+		// could be outgoing data also
+		*to_net = readOutgoing();
+		return true;
+	}
+
+	QByteArray unprocessed()
+	{
+		QByteArray a;
+		int size = BIO_pending(rbio);
+		if(size <= 0)
+			return a;
+		a.resize(size);
+
+		int r = BIO_read(rbio, a.data(), size);
+		if(r <= 0) {
+			a.resize(0);
+			return a;
+		}
+		if(r != size)
+			a.resize(r);
+		return a;
+	}
+
+	QByteArray readOutgoing()
+	{
+		QByteArray a;
+		int size = BIO_pending(wbio);
+		if(size <= 0)
+			return a;
+		a.resize(size);
+
+		int r = BIO_read(wbio, a.data(), size);
+		if(r <= 0) {
+			a.resize(0);
+			return a;
+		}
+		if(r != size)
+			a.resize(r);
+		return a;
+	}
+
+	int doConnect()
+	{
+		int ret = SSL_connect(ssl);
+		if(ret < 0) {
+			int x = SSL_get_error(ssl, ret);
+			if(x == SSL_ERROR_WANT_CONNECT || x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE)
+				return TryAgain;
+			else
+				return Bad;
+		}
+		else if(ret == 0)
+			return Bad;
+		return Good;
+	}
+
+	int doAccept()
+	{
+		int ret = SSL_accept(ssl);
+		if(ret < 0) {
+			int x = SSL_get_error(ssl, ret);
+			if(x == SSL_ERROR_WANT_CONNECT || x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE)
+				return TryAgain;
+			else
+				return Bad;
+		}
+		else if(ret == 0)
+			return Bad;
+		return Good;
+	}
+
+	int doHandshake()
+	{
+		int ret = SSL_do_handshake(ssl);
+		if(ret < 0) {
+			int x = SSL_get_error(ssl, ret);
+			if(x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE)
+				return TryAgain;
+			else
+				return Bad;
+		}
+		else if(ret == 0)
+			return Bad;
+		return Good;
+	}
+
+	int doShutdown()
+	{
+		int ret = SSL_shutdown(ssl);
+		if(ret >= 1)
+			return Good;
+		else {
+			if(ret == 0)
+				return TryAgain;
+			int x = SSL_get_error(ssl, ret);
+			if(x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE)
+				return TryAgain;
+			return Bad;
+		}
+	}
+
+	QCA_CertContext *peerCertificate() const
+	{
+		return cc.clone();
+	}
+
+	int validityResult() const
+	{
+		return vr;
+	}
+
+	int resultToCV(int ret) const
+	{
+		int rc;
+
+		switch(ret) {
+			case X509_V_ERR_CERT_REJECTED:
+				rc = QCA::TLS::Rejected;
+				break;
+			case X509_V_ERR_CERT_UNTRUSTED:
+				rc = QCA::TLS::Untrusted;
+				break;
+			case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+			case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+			case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+			case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+			case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+				rc = QCA::TLS::SignatureFailed;
+				break;
+			case X509_V_ERR_INVALID_CA:
+			case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+			case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+			case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+				rc = QCA::TLS::InvalidCA;
+				break;
+			case X509_V_ERR_INVALID_PURPOSE:
+				rc = QCA::TLS::InvalidPurpose;
+				break;
+			case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+			case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+				rc = QCA::TLS::SelfSigned;
+				break;
+			case X509_V_ERR_CERT_REVOKED:
+				rc = QCA::TLS::Revoked;
+				break;
+			case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+				rc = QCA::TLS::PathLengthExceeded;
+				break;
+			case X509_V_ERR_CERT_NOT_YET_VALID:
+			case X509_V_ERR_CERT_HAS_EXPIRED:
+			case X509_V_ERR_CRL_NOT_YET_VALID:
+			case X509_V_ERR_CRL_HAS_EXPIRED:
+			case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+			case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+			case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+			case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+				rc = QCA::TLS::Expired;
+				break;
+			case X509_V_ERR_APPLICATION_VERIFICATION:
+			case X509_V_ERR_OUT_OF_MEM:
+			case X509_V_ERR_UNABLE_TO_GET_CRL:
+			case X509_V_ERR_CERT_CHAIN_TOO_LONG:
+			default:
+				rc = QCA::TLS::Unknown;
+				break;
+		}
+		return rc;
+	}
+};
+
+class QCAOpenSSL : public QCAProvider
+{
+public:
+	QCAOpenSSL() {}
+	~QCAOpenSSL() {}
+
+	void init()
+	{
+	}
+
+	int qcaVersion() const
+	{
+		return QCA_PLUGIN_VERSION;
+	}
+
+	int capabilities() const
+	{
+		int caps =
+			QCA::CAP_SHA1 |
+			QCA::CAP_MD5 |
+			QCA::CAP_BlowFish |
+			QCA::CAP_TripleDES |
+#ifndef NO_AES
+			QCA::CAP_AES128 |
+			QCA::CAP_AES256 |
+#endif
+			QCA::CAP_RSA |
+			QCA::CAP_X509 |
+			QCA::CAP_TLS;
+		return caps;
+	}
+
+	void *context(int cap)
+	{
+		if(cap == QCA::CAP_SHA1)
+			return new SHA1Context;
+		else if(cap == QCA::CAP_MD5)
+			return new MD5Context;
+		else if(cap == QCA::CAP_BlowFish)
+			return new BlowFishContext;
+		else if(cap == QCA::CAP_TripleDES)
+			return new TripleDESContext;
+#ifndef NO_AES
+		else if(cap == QCA::CAP_AES128)
+			return new AES128Context;
+		else if(cap == QCA::CAP_AES256)
+			return new AES256Context;
+#endif
+		else if(cap == QCA::CAP_RSA)
+			return new RSAKeyContext;
+		else if(cap == QCA::CAP_X509)
+			return new CertContext;
+		else if(cap == QCA::CAP_TLS)
+			return new TLSContext;
+		return 0;
+	}
+};
+
+#ifdef QCA_PLUGIN
+QCAProvider *createProvider()
+#else
+QCAProvider *createProviderTLS()
+#endif
+{
+	return (new QCAOpenSSL);
+}
Index: /qca-tls/tags/psios2-0.10.1/qca-tls.h
===================================================================
--- /qca-tls/tags/psios2-0.10.1/qca-tls.h	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/qca-tls.h	(revision 81)
@@ -0,0 +1,32 @@
+/*
+ * qca-tls.h - TLS plugin for QCA
+ * Copyright (C) 2003  Justin Karneges
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCA_TLS_H
+#define QCA_TLS_H
+
+#include"qcaprovider.h"
+
+#ifdef QCA_PLUGIN
+QCA_PLUGIN_EXPORT QCAProvider *createProvider();
+#else
+QCAProvider *createProviderTLS();
+#endif
+
+#endif
Index: /qca-tls/tags/psios2-0.10.1/qca-tls.pro
===================================================================
--- /qca-tls/tags/psios2-0.10.1/qca-tls.pro	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/qca-tls.pro	(revision 81)
@@ -0,0 +1,48 @@
+# qca-tls qmake profile
+
+TEMPLATE = lib
+CONFIG  += qt thread release plugin
+TARGET   = qca-tls
+
+OS = unknown
+os2:OS = os2
+win32:OS = win
+unix:OS = nix
+mac:OS = mac
+
+DESTDIR  = qca-tls-$$OS
+
+debug: {
+	MOC_DIR        = .debug/.$$OS/.moc
+	OBJECTS_DIR    = .debug/.$$OS/.obj
+	UI_DIR         = .debug/.$$OS/.ui
+} else {
+	MOC_DIR        = .$$OS/.moc
+	OBJECTS_DIR    = .$$OS/.obj
+	UI_DIR         = .$$OS/.ui
+}
+
+!exists(qcaprovider.h) {
+  Q_PREFIX = ../../src
+  INCLUDEPATH += $$Q_PREFIX
+}
+HEADERS += ($$Q_PREFIX)qcaprovider.h
+
+HEADERS = qca-tls.h
+SOURCES = qca-tls.cpp
+
+DEFINES += QCA_PLUGIN
+win32:{
+	DEFINES += QCA_PLUGIN_DLL OSSL_097
+	INCLUDEPATH += c:\local\include
+	LIBS += c:\local\lib\libeay32.lib c:\local\lib\ssleay32.lib
+}
+os2:{
+	DEFINES += QCA_PLUGIN_DLL OSSL_097
+	INCLUDEPATH += ..\openssl-0.9.8b\outinc
+	LIBS += ..\openssl-0.9.8b\out\crypto ..\openssl-0.9.8b\out\ssl
+}
+
+include(conf.pri)
+include(extra.pri)
+
Index: /qca-tls/tags/psios2-0.10.1/qca-tls.qc
===================================================================
--- /qca-tls/tags/psios2-0.10.1/qca-tls.qc	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/qca-tls.qc	(revision 81)
@@ -0,0 +1,9 @@
+<qconf>
+ <name>qca-tls</name>
+ <profile>qca-tls.pro</profile>
+ <noprefix/>
+ <dep type='openssl'>
+  <required/>
+ </dep>
+ <moddir>.</moddir>
+</qconf>
Index: /qca-tls/tags/psios2-0.10.1/qca.h
===================================================================
--- /qca-tls/tags/psios2-0.10.1/qca.h	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/qca.h	(revision 81)
@@ -0,0 +1,534 @@
+/*
+ * qca.h - Qt Cryptographic Architecture
+ * Copyright (C) 2003  Justin Karneges
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCA_H
+#define QCA_H
+
+#include<qstring.h>
+#include<qcstring.h>
+#include<qdatetime.h>
+#include<qmap.h>
+#include<qptrlist.h>
+#include<qobject.h>
+
+#ifdef Q_OS_WIN32
+#  ifndef QCA_STATIC
+#    ifdef QCA_MAKEDLL
+#      define QCA_EXPORT __declspec(dllexport)
+#    else
+#      define QCA_EXPORT __declspec(dllimport)
+#    endif
+#  endif
+#endif
+#ifndef QCA_EXPORT
+#define QCA_EXPORT
+#endif
+
+#if defined(Q_OS_WIN32)
+#  ifdef QCA_PLUGIN_DLL
+#    define QCA_PLUGIN_EXPORT extern "C" __declspec(dllexport)
+#  else
+#    define QCA_PLUGIN_EXPORT extern "C" __declspec(dllimport)
+#  endif
+#elif defined(Q_OS_OS2)
+#  define QCA_PLUGIN_EXPORT extern "C" _System
+#endif
+#ifndef QCA_PLUGIN_EXPORT
+#define QCA_PLUGIN_EXPORT extern "C"
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+#define MSC_NET_HOTFIX
+#endif
+
+class QHostAddress;
+class QStringList;
+
+class QCAProvider;
+class QCA_HashContext;
+class QCA_CipherContext;
+class QCA_CertContext;
+
+namespace QCA
+{
+	enum {
+		CAP_SHA1      = 0x0001,
+		CAP_SHA256    = 0x0002,
+		CAP_MD5       = 0x0004,
+		CAP_BlowFish  = 0x0008,
+		CAP_TripleDES = 0x0010,
+		CAP_AES128    = 0x0020,
+		CAP_AES256    = 0x0040,
+		CAP_RSA       = 0x0080,
+		CAP_X509      = 0x0100,
+		CAP_TLS       = 0x0200,
+		CAP_SASL      = 0x0400
+	};
+
+	enum {
+		CBC = 0x0001,
+		CFB = 0x0002
+	};
+
+	enum {
+		Encrypt = 0x0001,
+		Decrypt = 0x0002
+	};
+
+	QCA_EXPORT void init();
+	QCA_EXPORT bool isSupported(int capabilities);
+	QCA_EXPORT void insertProvider(QCAProvider *);
+	QCA_EXPORT void unloadAllPlugins();
+
+	QCA_EXPORT QString arrayToHex(const QByteArray &);
+	QCA_EXPORT QByteArray hexToArray(const QString &);
+
+	class QCA_EXPORT Hash
+	{
+	public:
+		Hash(const Hash &);
+		Hash & operator=(const Hash &);
+		~Hash();
+
+		void clear();
+		void update(const QByteArray &a);
+		QByteArray final();
+
+	protected:
+		Hash(QCA_HashContext *);
+
+	private:
+		class Private;
+		Private *d;
+	};
+
+#if !defined(MSC_NET_HOTFIX)
+	template <class T>
+	class QCA_EXPORT HashStatic
+	{
+	public:
+		HashStatic<T>() {}
+
+		static QByteArray hash(const QByteArray &a)
+		{
+			T obj;
+			obj.update(a);
+			return obj.final();
+		}
+
+		static QByteArray hash(const QCString &cs)
+		{
+			QByteArray a(cs.length());
+			memcpy(a.data(), cs.data(), a.size());
+			return hash(a);
+		}
+
+		static QString hashToString(const QByteArray &a)
+		{
+			return arrayToHex(hash(a));
+		}
+
+		static QString hashToString(const QCString &cs)
+		{
+			return arrayToHex(hash(cs));
+		}
+	};
+#endif
+
+	class QCA_EXPORT Cipher
+	{
+	public:
+		Cipher(const Cipher &);
+		Cipher & operator=(const Cipher &);
+		~Cipher();
+
+		QByteArray dyn_generateKey(int size=-1) const;
+		QByteArray dyn_generateIV() const;
+		void reset(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad=true);
+		bool update(const QByteArray &a);
+		QByteArray final(bool *ok=0);
+
+	protected:
+		Cipher(QCA_CipherContext *, int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad);
+
+	private:
+		class Private;
+		Private *d;
+	};
+
+	template <class T>
+	class QCA_EXPORT CipherStatic
+	{
+	public:
+		CipherStatic<T>() {}
+
+		static QByteArray generateKey(int size=-1)
+		{
+			T obj;
+			return obj.dyn_generateKey(size);
+		}
+
+		static QByteArray generateIV()
+		{
+			T obj;
+			return obj.dyn_generateIV();
+		}
+	};
+
+	class QCA_EXPORT SHA1 : public Hash
+#if !defined(MSC_NET_HOTFIX)
+		, public HashStatic<SHA1>
+#endif
+	{
+	public:
+		SHA1();
+
+#if defined(MSC_NET_HOTFIX)
+		static QByteArray hash(const QByteArray &a)
+		{
+			SHA1 obj;
+			obj.update(a);
+			return obj.final();
+		}
+
+		static QByteArray hash(const QCString &cs)
+		{
+			QByteArray a(cs.length());
+			memcpy(a.data(), cs.data(), a.size());
+			return hash(a);
+		}
+
+		static QString hashToString(const QByteArray &a)
+		{
+			return arrayToHex(hash(a));
+		}
+
+		static QString hashToString(const QCString &cs)
+		{
+			return arrayToHex(hash(cs));
+		}
+#endif
+	};
+
+#if !defined(MSC_NET_HOTFIX)
+	class QCA_EXPORT SHA256 : public Hash, public HashStatic<SHA256>
+	{
+	public:
+		SHA256();
+	};
+#endif
+
+	class QCA_EXPORT MD5 : public Hash
+#if !defined(MSC_NET_HOTFIX)
+		, public HashStatic<MD5>
+#endif
+	{
+	public:
+		MD5();
+
+#if defined(MSC_NET_HOTFIX)
+		static QByteArray hash(const QByteArray &a)
+		{
+			MD5 obj;
+			obj.update(a);
+			return obj.final();
+		}
+
+		static QByteArray hash(const QCString &cs)
+		{
+			QByteArray a(cs.length());
+			memcpy(a.data(), cs.data(), a.size());
+			return hash(a);
+		}
+
+		static QString hashToString(const QByteArray &a)
+		{
+			return arrayToHex(hash(a));
+		}
+
+		static QString hashToString(const QCString &cs)
+		{
+			return arrayToHex(hash(cs));
+		}
+#endif
+	};
+
+	class QCA_EXPORT BlowFish : public Cipher, public CipherStatic<BlowFish>
+	{
+	public:
+		BlowFish(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
+	};
+
+	class QCA_EXPORT TripleDES : public Cipher, public CipherStatic<TripleDES>
+	{
+	public:
+		TripleDES(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
+	};
+
+	class QCA_EXPORT AES128 : public Cipher, public CipherStatic<AES128>
+	{
+	public:
+		AES128(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
+	};
+
+	class QCA_EXPORT AES256 : public Cipher, public CipherStatic<AES256>
+	{
+	public:
+		AES256(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
+	};
+
+	class RSA;
+	class QCA_EXPORT RSAKey
+	{
+	public:
+		RSAKey();
+		RSAKey(const RSAKey &from);
+		RSAKey & operator=(const RSAKey &from);
+		~RSAKey();
+
+		bool isNull() const;
+		bool havePublic() const;
+		bool havePrivate() const;
+
+		QByteArray toDER(bool publicOnly=false) const;
+		bool fromDER(const QByteArray &a);
+
+		QString toPEM(bool publicOnly=false) const;
+		bool fromPEM(const QString &);
+
+		// only call if you know what you are doing
+		bool fromNative(void *);
+
+	private:
+		class Private;
+		Private *d;
+
+		friend class RSA;
+		friend class TLS;
+		bool encrypt(const QByteArray &a, QByteArray *out, bool oaep) const;
+		bool decrypt(const QByteArray &a, QByteArray *out, bool oaep) const;
+		bool generate(unsigned int bits);
+	};
+
+	class QCA_EXPORT RSA
+	{
+	public:
+		RSA();
+		~RSA();
+
+		RSAKey key() const;
+		void setKey(const RSAKey &);
+
+		bool encrypt(const QByteArray &a, QByteArray *out, bool oaep=false) const;
+		bool decrypt(const QByteArray &a, QByteArray *out, bool oaep=false) const;
+
+		static RSAKey generateKey(unsigned int bits);
+
+	private:
+		RSAKey v_key;
+	};
+
+	typedef QMap<QString, QString> CertProperties;
+	class QCA_EXPORT Cert
+	{
+	public:
+		Cert();
+		Cert(const Cert &);
+		Cert & operator=(const Cert &);
+		~Cert();
+
+		bool isNull() const;
+
+		QString commonName() const;
+		QString serialNumber() const;
+		QString subjectString() const;
+		QString issuerString() const;
+		CertProperties subject() const;
+		CertProperties issuer() const;
+		QDateTime notBefore() const;
+		QDateTime notAfter() const;
+
+		QByteArray toDER() const;
+		bool fromDER(const QByteArray &a);
+
+		QString toPEM() const;
+		bool fromPEM(const QString &);
+
+	private:
+		class Private;
+		Private *d;
+
+		friend class TLS;
+		void fromContext(QCA_CertContext *);
+	};
+
+	class QCA_EXPORT TLS : public QObject
+	{
+		Q_OBJECT
+	public:
+		enum Validity {
+			NoCert,
+			Valid,
+			HostMismatch,
+			Rejected,
+			Untrusted,
+			SignatureFailed,
+			InvalidCA,
+			InvalidPurpose,
+			SelfSigned,
+			Revoked,
+			PathLengthExceeded,
+			Expired,
+			Unknown
+		};
+		enum Error { ErrHandshake, ErrCrypt };
+
+		TLS(QObject *parent=0);
+		~TLS();
+
+		void setCertificate(const Cert &cert, const RSAKey &key);
+		void setCertificateStore(const QPtrList<Cert> &store);  // note: store must persist
+
+		void reset();
+		bool startClient(const QString &host="");
+		bool startServer();
+		void close();
+		bool isHandshaken() const;
+
+		// plain (application side)
+		void write(const QByteArray &a);
+		QByteArray read();
+
+		// encoded (socket side)
+		void writeIncoming(const QByteArray &a);
+		QByteArray readOutgoing();
+		QByteArray readUnprocessed();
+
+		// cert related
+		const Cert & peerCertificate() const;
+		int certificateValidityResult() const;
+
+	signals:
+		void handshaken();
+		void readyRead();
+		void readyReadOutgoing(int plainBytes);
+		void closed();
+		void error(int);
+
+	private slots:
+		void update();
+
+	private:
+		class Private;
+		Private *d;
+	};
+
+	class QCA_EXPORT SASL : public QObject
+	{
+		Q_OBJECT
+	public:
+		enum Error { ErrAuth, ErrCrypt };
+		enum ErrorCond {
+			NoMech,
+			BadProto,
+			BadServ,
+			BadAuth,
+			NoAuthzid,
+			TooWeak,
+			NeedEncrypt,
+			Expired,
+			Disabled,
+			NoUser,
+			RemoteUnavail
+		};
+		SASL(QObject *parent=0);
+		~SASL();
+
+		static void setAppName(const QString &name);
+
+		void reset();
+		int errorCondition() const;
+
+		// options
+		void setAllowPlain(bool);
+		void setAllowAnonymous(bool);
+		void setAllowActiveVulnerable(bool);
+		void setAllowDictionaryVulnerable(bool);
+		void setRequireForwardSecrecy(bool);
+		void setRequirePassCredentials(bool);
+		void setRequireMutualAuth(bool);
+
+		void setMinimumSSF(int);
+		void setMaximumSSF(int);
+		void setExternalAuthID(const QString &authid);
+		void setExternalSSF(int);
+
+		void setLocalAddr(const QHostAddress &addr, Q_UINT16 port);
+		void setRemoteAddr(const QHostAddress &addr, Q_UINT16 port);
+
+		// initialize
+		bool startClient(const QString &service, const QString &host, const QStringList &mechlist, bool allowClientSendFirst=true);
+		bool startServer(const QString &service, const QString &host, const QString &realm, QStringList *mechlist);
+
+		// authentication
+		void putStep(const QByteArray &stepData);
+		void putServerFirstStep(const QString &mech);
+		void putServerFirstStep(const QString &mech, const QByteArray &clientInit);
+		void setUsername(const QString &user);
+		void setAuthzid(const QString &auth);
+		void setPassword(const QString &pass);
+		void setRealm(const QString &realm);
+		void continueAfterParams();
+		void continueAfterAuthCheck();
+
+		// security layer
+		int ssf() const;
+		void write(const QByteArray &a);
+		QByteArray read();
+		void writeIncoming(const QByteArray &a);
+		QByteArray readOutgoing();
+
+	signals:
+		// for authentication
+		void clientFirstStep(const QString &mech, const QByteArray *clientInit);
+		void nextStep(const QByteArray &stepData);
+		void needParams(bool user, bool authzid, bool pass, bool realm);
+		void authCheck(const QString &user, const QString &authzid);
+		void authenticated();
+
+		// for security layer
+		void readyRead();
+		void readyReadOutgoing(int plainBytes);
+
+		// error
+		void error(int);
+
+	private slots:
+		void tryAgain();
+
+	private:
+		class Private;
+		Private *d;
+
+		void handleServerFirstStep(int r);
+	};
+};
+
+#endif
Index: /qca-tls/tags/psios2-0.10.1/qcaprovider.h
===================================================================
--- /qca-tls/tags/psios2-0.10.1/qcaprovider.h	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/qcaprovider.h	(revision 81)
@@ -0,0 +1,191 @@
+/*
+ * qcaprovider.h - QCA Plugin API
+ * Copyright (C) 2003  Justin Karneges
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCAPROVIDER_H
+#define QCAPROVIDER_H
+
+#include<qglobal.h>
+#include<qstring.h>
+#include<qdatetime.h>
+#include<qobject.h>
+#include<qhostaddress.h>
+#include"qca.h"
+
+#define QCA_PLUGIN_VERSION 1
+
+class QCAProvider
+{
+public:
+	QCAProvider() {}
+	virtual ~QCAProvider() {}
+
+	virtual void init()=0;
+	virtual int qcaVersion() const=0;
+	virtual int capabilities() const=0;
+	virtual void *context(int cap)=0;
+};
+
+class QCA_HashContext
+{
+public:
+	virtual ~QCA_HashContext() {}
+
+	virtual QCA_HashContext *clone()=0;
+	virtual void reset()=0;
+	virtual void update(const char *in, unsigned int len)=0;
+	virtual void final(QByteArray *out)=0;
+};
+
+class QCA_CipherContext
+{
+public:
+	virtual ~QCA_CipherContext() {}
+
+	virtual QCA_CipherContext *clone()=0;
+	virtual int keySize()=0;
+	virtual int blockSize()=0;
+	virtual bool generateKey(char *out, int keysize=-1)=0;
+	virtual bool generateIV(char *out)=0;
+
+	virtual bool setup(int dir, int mode, const char *key, int keysize, const char *iv, bool pad)=0;
+	virtual bool update(const char *in, unsigned int len)=0;
+	virtual bool final(QByteArray *out)=0;
+};
+
+class QCA_RSAKeyContext
+{
+public:
+	virtual ~QCA_RSAKeyContext() {}
+
+	virtual QCA_RSAKeyContext *clone() const=0;
+	virtual bool isNull() const=0;
+	virtual bool havePublic() const=0;
+	virtual bool havePrivate() const=0;
+	virtual bool createFromDER(const char *in, unsigned int len)=0;
+	virtual bool createFromPEM(const char *in, unsigned int len)=0;
+	virtual bool createFromNative(void *in)=0;
+	virtual bool generate(unsigned int bits)=0;
+	virtual bool toDER(QByteArray *out, bool publicOnly)=0;
+	virtual bool toPEM(QByteArray *out, bool publicOnly)=0;
+
+	virtual bool encrypt(const QByteArray &in, QByteArray *out, bool oaep)=0;
+	virtual bool decrypt(const QByteArray &in, QByteArray *out, bool oaep)=0;
+};
+
+struct QCA_CertProperty
+{
+	QString var;
+	QString val;
+};
+
+class QCA_CertContext
+{
+public:
+	virtual ~QCA_CertContext() {}
+
+	virtual QCA_CertContext *clone() const=0;
+	virtual bool isNull() const=0;
+	virtual bool createFromDER(const char *in, unsigned int len)=0;
+	virtual bool createFromPEM(const char *in, unsigned int len)=0;
+	virtual bool toDER(QByteArray *out)=0;
+	virtual bool toPEM(QByteArray *out)=0;
+
+	virtual QString serialNumber() const=0;
+	virtual QString subjectString() const=0;
+	virtual QString issuerString() const=0;
+	virtual QValueList<QCA_CertProperty> subject() const=0;
+	virtual QValueList<QCA_CertProperty> issuer() const=0;
+	virtual QDateTime notBefore() const=0;
+	virtual QDateTime notAfter() const=0;
+	virtual bool matchesAddress(const QString &realHost) const=0;
+};
+
+class QCA_TLSContext
+{
+public:
+	enum Result { Success, Error, Continue };
+	virtual ~QCA_TLSContext() {}
+
+	virtual void reset()=0;
+	virtual bool startClient(const QPtrList<QCA_CertContext> &store, const QCA_CertContext &cert, const QCA_RSAKeyContext &key)=0;
+	virtual bool startServer(const QPtrList<QCA_CertContext> &store, const QCA_CertContext &cert, const QCA_RSAKeyContext &key)=0;
+
+	virtual int handshake(const QByteArray &in, QByteArray *out)=0;
+	virtual int shutdown(const QByteArray &in, QByteArray *out)=0;
+	virtual bool encode(const QByteArray &plain, QByteArray *to_net, int *encoded)=0;
+	virtual bool decode(const QByteArray &from_net, QByteArray *plain, QByteArray *to_net)=0;
+	virtual bool eof() const=0;
+	virtual QByteArray unprocessed()=0;
+
+	virtual QCA_CertContext *peerCertificate() const=0;
+	virtual int validityResult() const=0;
+};
+
+struct QCA_SASLHostPort
+{
+	QHostAddress addr;
+	Q_UINT16 port;
+};
+
+struct QCA_SASLNeedParams
+{
+	bool user, authzid, pass, realm;
+};
+
+class QCA_SASLContext
+{
+public:
+	enum Result { Success, Error, NeedParams, AuthCheck, Continue };
+	virtual ~QCA_SASLContext() {}
+
+	// common
+	virtual void reset()=0;
+	virtual void setCoreProps(const QString &service, const QString &host, QCA_SASLHostPort *local, QCA_SASLHostPort *remote)=0;
+	virtual void setSecurityProps(bool noPlain, bool noActive, bool noDict, bool noAnon, bool reqForward, bool reqCreds, bool reqMutual, int ssfMin, int ssfMax, const QString &_ext_authid, int _ext_ssf)=0;
+	virtual int security() const=0;
+	virtual int errorCond() const=0;
+
+	// init / first step
+	virtual bool clientStart(const QStringList &mechlist)=0;
+	virtual int clientFirstStep(bool allowClientSendFirst)=0;
+	virtual bool serverStart(const QString &realm, QStringList *mechlist, const QString &name)=0;
+	virtual int serverFirstStep(const QString &mech, const QByteArray *in)=0;
+
+	// get / set params
+	virtual QCA_SASLNeedParams clientParamsNeeded() const=0;
+	virtual void setClientParams(const QString *user, const QString *authzid, const QString *pass, const QString *realm)=0;
+	virtual QString username() const=0;
+	virtual QString authzid() const=0;
+
+	// continue steps
+	virtual int nextStep(const QByteArray &in)=0;
+	virtual int tryAgain()=0;
+
+	// results
+	virtual QString mech() const=0;
+	virtual const QByteArray *clientInit() const=0;
+	virtual QByteArray result() const=0;
+
+	// security layer
+	virtual bool encode(const QByteArray &in, QByteArray *out)=0;
+	virtual bool decode(const QByteArray &in, QByteArray *out)=0;
+};
+
+#endif
Index: /qca-tls/tags/psios2-0.10.1/qcextra
===================================================================
--- /qca-tls/tags/psios2-0.10.1/qcextra	(revision 81)
+++ /qca-tls/tags/psios2-0.10.1/qcextra	(revision 81)
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+cat >extra.pri <<EOT
+target.path=\$\$QT_PATH_PLUGINS/crypto
+INSTALLS += target
+
+INSTALL_ROOT = $PREFIX
+
+EOT
