the original qca-1.0 sources with the TQt layer added. This resolves bug report 817.pull/1/head
commit
c663e43e71
@ -0,0 +1,12 @@
|
|||||||
|
Installing QCA
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Installation should be straightforward:
|
||||||
|
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
NOTE: You may also need to run '/sbin/ldconfig' or a similar tool to
|
||||||
|
get the new library files recognized by the system. If you are
|
||||||
|
using Linux, just run it for good measure.
|
@ -0,0 +1,29 @@
|
|||||||
|
Qt Cryptographic Architecture
|
||||||
|
-----------------------------
|
||||||
|
Version: API v1.0, Plugin v1
|
||||||
|
Author: Justin Karneges <justin@affinix.com>
|
||||||
|
Date: September 10th 2003
|
||||||
|
|
||||||
|
This library provides an easy API for the following features:
|
||||||
|
|
||||||
|
SSL/TLS
|
||||||
|
X509
|
||||||
|
SASL
|
||||||
|
RSA
|
||||||
|
Hashing (SHA1, MD5)
|
||||||
|
Ciphers (BlowFish, 3DES, AES)
|
||||||
|
|
||||||
|
Functionality is supplied via plugins. This is useful for avoiding
|
||||||
|
dependence on a particular crypto library and makes upgrading easier,
|
||||||
|
as there is no need to recompile your application when adding or
|
||||||
|
upgrading a crypto plugin. Also, by pushing crypto functionality into
|
||||||
|
plugins, your application is free of legal issues, such as export
|
||||||
|
regulation.
|
||||||
|
|
||||||
|
And of course, you get a very simple crypto API for Qt, where you can
|
||||||
|
do things like:
|
||||||
|
|
||||||
|
TQString hash = QCA::SHA1::hashToString(blockOfData);
|
||||||
|
|
||||||
|
Have fun!
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
* plugins: thread safety ?
|
||||||
|
|
||||||
|
* dsa
|
||||||
|
* diffie-hellman
|
||||||
|
* entropy
|
||||||
|
|
@ -0,0 +1,492 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
show_usage() {
|
||||||
|
cat <<EOT
|
||||||
|
Usage: ./configure [OPTION]...
|
||||||
|
|
||||||
|
This script creates necessary configuration files to build/install.
|
||||||
|
|
||||||
|
Main options:
|
||||||
|
--prefix=[path] Base path for build/install. Default: /usr/local
|
||||||
|
--qtdir=[path] Directory where Qt is installed.
|
||||||
|
--help This help text.
|
||||||
|
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--prefix=*)
|
||||||
|
PREFIX=`expr "${1}" : "--prefix=\(.*\)"`
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
--qtdir=*)
|
||||||
|
QTDIR=`expr "${1}" : "--qtdir=\(.*\)"`
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
--debug)
|
||||||
|
QC_DEBUG="Y"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--help) show_usage; exit ;;
|
||||||
|
*) show_usage; exit ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
PREFIX=${PREFIX:-/usr/local}
|
||||||
|
|
||||||
|
echo "Configuring TQt Cryptographic Architecture (QCA) ..."
|
||||||
|
|
||||||
|
if [ "$QC_DEBUG" = "Y" ]; then
|
||||||
|
echo
|
||||||
|
echo PREFIX=$PREFIX
|
||||||
|
echo QTDIR=$QTDIR
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "Verifying TQt 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/tqt /usr/share/tqt /usr/share/tqt3 /usr/local/lib/tqt /usr/local/share/tqt /usr/lib/tqt3 /usr/local/lib/tqt3 /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
|
||||||
|
|
||||||
|
EOT
|
||||||
|
cat >$1/modules_new.cpp <<EOT
|
||||||
|
|
||||||
|
EOT
|
||||||
|
cat >$1/conf.cpp <<EOT
|
||||||
|
#include<stdio.h>
|
||||||
|
#include<stdlib.h>
|
||||||
|
#include<tqstring.h>
|
||||||
|
#include<tqdict.h>
|
||||||
|
#include<tqptrlist.h>
|
||||||
|
#include<tqfileinfo.h>
|
||||||
|
#include<tqfile.h>
|
||||||
|
#include<tqdir.h>
|
||||||
|
#include<tqstringlist.h>
|
||||||
|
|
||||||
|
class Conf;
|
||||||
|
|
||||||
|
class ConfObj
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConfObj(Conf *c);
|
||||||
|
virtual ~ConfObj();
|
||||||
|
|
||||||
|
virtual TQString name() const=0;
|
||||||
|
virtual TQString shortname() const=0;
|
||||||
|
virtual bool exec()=0;
|
||||||
|
|
||||||
|
Conf *conf;
|
||||||
|
bool required;
|
||||||
|
bool disabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef TQPtrList<ConfObj> ConfObjList;
|
||||||
|
typedef TQPtrListIterator<ConfObj> ConfObjListIt;
|
||||||
|
|
||||||
|
class Conf
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Conf() : vars(17)
|
||||||
|
{
|
||||||
|
list.setAutoDelete(true);
|
||||||
|
vars.setAutoDelete(true);
|
||||||
|
|
||||||
|
vars.insert("QMAKE_INCDIR_X11", new TQString(X11_INC));
|
||||||
|
vars.insert("QMAKE_LIBDIR_X11", new TQString(X11_LIBDIR));
|
||||||
|
vars.insert("QMAKE_LIBS_X11", new TQString(X11_LIB));
|
||||||
|
vars.insert("QMAKE_CC", new TQString(CC));
|
||||||
|
}
|
||||||
|
|
||||||
|
~Conf()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void added(ConfObj *o)
|
||||||
|
{
|
||||||
|
list.append(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
TQString getenv(const TQString &var)
|
||||||
|
{
|
||||||
|
char *p = ::getenv(var.latin1());
|
||||||
|
if(!p)
|
||||||
|
return TQString::null;
|
||||||
|
return TQString(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) {
|
||||||
|
TQString v = TQString("QC_ENABLE_") + o->shortname();
|
||||||
|
if(getenv(v) != "Y")
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// and the opposite?
|
||||||
|
else {
|
||||||
|
TQString v = TQString("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 TQString & qvar(const TQString &s)
|
||||||
|
{
|
||||||
|
TQString *p = vars.find(s);
|
||||||
|
if(p)
|
||||||
|
return *p;
|
||||||
|
else
|
||||||
|
return blank;
|
||||||
|
}
|
||||||
|
|
||||||
|
TQString expandIncludes(const TQString &inc)
|
||||||
|
{
|
||||||
|
return TQString("-I") + inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
TQString expandLibs(const TQString &lib)
|
||||||
|
{
|
||||||
|
return TQString("-L") + lib;
|
||||||
|
}
|
||||||
|
|
||||||
|
int doCommand(const TQString &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 TQString &filedata, const TQString &flags, int *retcode=0)
|
||||||
|
{
|
||||||
|
TQDir dir(".");
|
||||||
|
TQString fname = "atest.c";
|
||||||
|
TQString out = "atest";
|
||||||
|
TQFile f(fname);
|
||||||
|
TQCString cs = filedata.latin1();
|
||||||
|
if(!f.open(IO_WriteOnly | IO_Truncate))
|
||||||
|
return false;
|
||||||
|
f.writeBlock(cs.data(), cs.length());
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
TQString str = qvar("QMAKE_CC") + ' ' + fname + " -o " + out + ' ' + flags;
|
||||||
|
int r = doCommand(str);
|
||||||
|
if(r == 0 && retcode)
|
||||||
|
*retcode = doCommand(TQString("./") + out);
|
||||||
|
dir.remove(fname);
|
||||||
|
dir.remove(out);
|
||||||
|
if(r != 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkHeader(const TQString &path, const TQString &h)
|
||||||
|
{
|
||||||
|
TQFileInfo fi(path + '/' + h);
|
||||||
|
if(fi.exists())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool findHeader(const TQString &h, const TQStringList &ext, TQString *inc)
|
||||||
|
{
|
||||||
|
if(checkHeader("/usr/include", h)) {
|
||||||
|
*inc = "";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
TQStringList dirs;
|
||||||
|
dirs += "/usr/local/include";
|
||||||
|
dirs += ext;
|
||||||
|
for(TQStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
|
||||||
|
if(checkHeader(*it, h)) {
|
||||||
|
*inc = *it;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkLibrary(const TQString &path, const TQString &name)
|
||||||
|
{
|
||||||
|
TQString str =
|
||||||
|
"int main()\n"
|
||||||
|
"{\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
TQString extra;
|
||||||
|
if(!path.isEmpty())
|
||||||
|
extra += TQString("-L") + path + ' ';
|
||||||
|
extra += TQString("-l") + name;
|
||||||
|
if(!doCompileAndLink(str, extra))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool findLibrary(const TQString &name, TQString *lib)
|
||||||
|
{
|
||||||
|
if(checkLibrary("", name)) {
|
||||||
|
*lib = "";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(checkLibrary("/usr/local/lib", name)) {
|
||||||
|
*lib = "/usr/local/lib";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addDefine(const TQString &str)
|
||||||
|
{
|
||||||
|
if(DEFINES.isEmpty())
|
||||||
|
DEFINES = str;
|
||||||
|
else
|
||||||
|
DEFINES += TQString(" ") + str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addLib(const TQString &str)
|
||||||
|
{
|
||||||
|
if(LIBS.isEmpty())
|
||||||
|
LIBS = str;
|
||||||
|
else
|
||||||
|
LIBS += TQString(" ") + str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addIncludePath(const TQString &str)
|
||||||
|
{
|
||||||
|
if(INCLUDEPATH.isEmpty())
|
||||||
|
INCLUDEPATH = str;
|
||||||
|
else
|
||||||
|
INCLUDEPATH += TQString(" ") + str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addExtra(const TQString &str)
|
||||||
|
{
|
||||||
|
extra += str + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
TQString DEFINES;
|
||||||
|
TQString INCLUDEPATH;
|
||||||
|
TQString LIBS;
|
||||||
|
TQString extra;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConfObjList list;
|
||||||
|
TQDict<TQString> vars;
|
||||||
|
TQString 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()) {
|
||||||
|
TQFile f("conf.pri");
|
||||||
|
if(!f.open(IO_WriteOnly | IO_Truncate)) {
|
||||||
|
printf("Error writing %s\n", f.name().latin1());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TQString str;
|
||||||
|
str += "# qconf\n";
|
||||||
|
str += "QT_PATH_PLUGINS = " + TQString(tqInstallPathPlugins()) + '\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 += TQString("target.path = ") + p + '\n';
|
||||||
|
str += "INSTALLS += target\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
TQCString 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
|
||||||
|
INCLUDEPATH += '/usr/include/tqt'
|
||||||
|
|
||||||
|
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 PREFIX
|
||||||
|
export QTDIR
|
||||||
|
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 "TQt 3.x Multithreaded (MT) build environment set up."
|
||||||
|
if [ ! -f "$QTDIR/lib/libtqt-mt.so.3" ]; then
|
||||||
|
echo
|
||||||
|
echo "One possible reason is that you don't have"
|
||||||
|
echo "libtqt-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.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
|
@ -0,0 +1,65 @@
|
|||||||
|
#include<tqdom.h>
|
||||||
|
#include<tqfile.h>
|
||||||
|
#include"base64.h"
|
||||||
|
#include"qca.h"
|
||||||
|
|
||||||
|
TQCA::Cert readCertXml(const TQDomElement &e)
|
||||||
|
{
|
||||||
|
TQCA::Cert cert;
|
||||||
|
// there should be one child data tag
|
||||||
|
TQDomElement data = e.elementsByTagName("data").item(0).toElement();
|
||||||
|
if(!data.isNull())
|
||||||
|
cert.fromDER(Base64::stringToArray(data.text()));
|
||||||
|
return cert;
|
||||||
|
}
|
||||||
|
|
||||||
|
void showCertInfo(const TQCA::Cert &cert)
|
||||||
|
{
|
||||||
|
printf(" CN: %s\n", cert.subject()["CN"].latin1());
|
||||||
|
printf(" Valid from: %s, until %s\n",
|
||||||
|
cert.notBefore().toString().latin1(),
|
||||||
|
cert.notAfter().toString().latin1());
|
||||||
|
printf(" PEM:\n%s\n", cert.toPEM().latin1());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
if(!TQCA::isSupported(TQCA::CAP_X509)) {
|
||||||
|
printf("X509 not supported!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open the Psi rootcerts file
|
||||||
|
TQFile f("/usr/local/share/psi/certs/rootcert.xml");
|
||||||
|
if(!f.open(IO_ReadOnly)) {
|
||||||
|
printf("unable to open %s\n", f.name().latin1());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TQDomDocument doc;
|
||||||
|
doc.setContent(&f);
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
TQDomElement base = doc.documentElement();
|
||||||
|
if(base.tagName() != "store") {
|
||||||
|
printf("wrong format of %s\n", f.name().latin1());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TQDomNodeList cl = base.elementsByTagName("certificate");
|
||||||
|
if(cl.count() == 0) {
|
||||||
|
printf("no certs found in %s\n", f.name().latin1());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int n = 0; n < (int)cl.count(); ++n) {
|
||||||
|
printf("-- Cert %d --\n", n);
|
||||||
|
TQCA::Cert cert = readCertXml(cl.item(n).toElement());
|
||||||
|
if(cert.isNull()) {
|
||||||
|
printf("error reading cert\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
showCertInfo(cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += thread console
|
||||||
|
TARGET = certtest
|
||||||
|
|
||||||
|
INCLUDEPATH += ../common
|
||||||
|
HEADERS += ../common/base64.h
|
||||||
|
SOURCES += ../common/base64.cpp certtest.cpp
|
||||||
|
include(../examples.pri)
|
@ -0,0 +1,89 @@
|
|||||||
|
#include"qca.h"
|
||||||
|
#include<stdio.h>
|
||||||
|
|
||||||
|
static TQCString arrayToCString(const TQByteArray &);
|
||||||
|
static TQByteArray cstringToArray(const TQCString &);
|
||||||
|
static void doDynTest(TQCA::Cipher *c, const TQString &name, const TQCString &cs);
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
TQCA::init();
|
||||||
|
TQCString cs = (argc >= 2) ? argv[1] : "hello";
|
||||||
|
|
||||||
|
// AES128 test
|
||||||
|
if(!TQCA::isSupported(TQCA::CAP_AES128))
|
||||||
|
printf("AES128 not supported!\n");
|
||||||
|
else {
|
||||||
|
// encrypt
|
||||||
|
TQByteArray key = TQCA::AES128::generateKey();
|
||||||
|
TQByteArray iv = TQCA::AES128::generateIV();
|
||||||
|
printf("aes128:key:%s\n", TQCA::arrayToHex(key).latin1());
|
||||||
|
printf("aes128:iv:%s\n", TQCA::arrayToHex(iv).latin1());
|
||||||
|
TQCA::AES128 c(TQCA::Encrypt, TQCA::CBC, key, iv);
|
||||||
|
c.update(cstringToArray(cs));
|
||||||
|
TQByteArray f = c.final();
|
||||||
|
TQString result = TQCA::arrayToHex(f);
|
||||||
|
printf(">aes128(\"%s\") = [%s]\n", cs.data(), result.latin1());
|
||||||
|
|
||||||
|
// decrypt
|
||||||
|
TQCA::AES128 d(TQCA::Decrypt, TQCA::CBC, key, iv);
|
||||||
|
d.update(f);
|
||||||
|
TQCString dec = arrayToCString(d.final());
|
||||||
|
printf("<aes128(\"%s\") = [%s]\n", result.latin1(), dec.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlowFish, TripleDES, and AES256 tested dynamically
|
||||||
|
if(!TQCA::isSupported(TQCA::CAP_BlowFish))
|
||||||
|
printf("BlowFish not supported!\n");
|
||||||
|
else
|
||||||
|
doDynTest(new TQCA::BlowFish, "bfish", cs);
|
||||||
|
|
||||||
|
if(!TQCA::isSupported(TQCA::CAP_TripleDES))
|
||||||
|
printf("TripleDES not supported!\n");
|
||||||
|
else
|
||||||
|
doDynTest(new TQCA::TripleDES, "3des", cs);
|
||||||
|
|
||||||
|
if(!TQCA::isSupported(TQCA::CAP_AES256))
|
||||||
|
printf("AES256 not supported!\n");
|
||||||
|
else
|
||||||
|
doDynTest(new TQCA::AES256, "aes256", cs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TQCString arrayToCString(const TQByteArray &a)
|
||||||
|
{
|
||||||
|
TQCString cs;
|
||||||
|
cs.resize(a.size()+1);
|
||||||
|
memcpy(cs.data(), a.data(), a.size());
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
TQByteArray cstringToArray(const TQCString &cs)
|
||||||
|
{
|
||||||
|
TQByteArray a(cs.length());
|
||||||
|
memcpy(a.data(), cs.data(), a.size());
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doDynTest(TQCA::Cipher *c, const TQString &name, const TQCString &cs)
|
||||||
|
{
|
||||||
|
// encrypt
|
||||||
|
TQByteArray key = c->dyn_generateKey();
|
||||||
|
TQByteArray iv = c->dyn_generateIV();
|
||||||
|
printf("%s:key:%s\n", name.latin1(), TQCA::arrayToHex(key).latin1());
|
||||||
|
printf("%s:iv:%s\n", name.latin1(), TQCA::arrayToHex(iv).latin1());
|
||||||
|
c->reset(TQCA::Encrypt, TQCA::CBC, key, iv);
|
||||||
|
c->update(cstringToArray(cs));
|
||||||
|
TQByteArray f = c->final();
|
||||||
|
TQString result = TQCA::arrayToHex(f);
|
||||||
|
printf(">%s(\"%s\") = [%s]\n", name.latin1(), cs.data(), result.latin1());
|
||||||
|
|
||||||
|
// decrypt
|
||||||
|
c->reset(TQCA::Decrypt, TQCA::CBC, key, iv);
|
||||||
|
c->update(f);
|
||||||
|
TQCString dec = arrayToCString(c->final());
|
||||||
|
printf("<%s(\"%s\") = [%s]\n", name.latin1(), result.latin1(), dec.data());
|
||||||
|
delete c;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += thread console
|
||||||
|
TARGET = ciphertest
|
||||||
|
|
||||||
|
SOURCES += ciphertest.cpp
|
||||||
|
include(../examples.pri)
|
@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
* base64.cpp - Base64 converting functions
|
||||||
|
* 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"base64.h"
|
||||||
|
|
||||||
|
//! \class Base64 base64.h
|
||||||
|
//! \brief Base64 conversion functions.
|
||||||
|
//!
|
||||||
|
//! Converts Base64 data between arrays and strings.
|
||||||
|
//!
|
||||||
|
//! \code
|
||||||
|
//! #include "base64.h"
|
||||||
|
//!
|
||||||
|
//! ...
|
||||||
|
//!
|
||||||
|
//! // encode a block of data into base64
|
||||||
|
//! TQByteArray block(1024);
|
||||||
|
//! TQByteArray enc = Base64::encode(block);
|
||||||
|
//!
|
||||||
|
//! \endcode
|
||||||
|
|
||||||
|
//!
|
||||||
|
//! Encodes array \a s and returns the result.
|
||||||
|
TQByteArray Base64::encode(const TQByteArray &s)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int len = s.size();
|
||||||
|
char tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||||
|
int a, b, c;
|
||||||
|
|
||||||
|
TQByteArray p((len+2)/3*4);
|
||||||
|
int at = 0;
|
||||||
|
for( i = 0; i < len; i += 3 ) {
|
||||||
|
a = ((unsigned char)s[i] & 3) << 4;
|
||||||
|
if(i + 1 < len) {
|
||||||
|
a += (unsigned char)s[i + 1] >> 4;
|
||||||
|
b = ((unsigned char)s[i + 1] & 0xF) << 2;
|
||||||
|
if(i + 2 < len) {
|
||||||
|
b += (unsigned char)s[i + 2] >> 6;
|
||||||
|
c = (unsigned char)s[i + 2] & 0x3F;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
c = 64;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
b = c = 64;
|
||||||
|
|
||||||
|
p[at++] = tbl[(unsigned char)s[i] >> 2];
|
||||||
|
p[at++] = tbl[a];
|
||||||
|
p[at++] = tbl[b];
|
||||||
|
p[at++] = tbl[c];
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
//!
|
||||||
|
//! Decodes array \a s and returns the result.
|
||||||
|
TQByteArray Base64::decode(const TQByteArray &s)
|
||||||
|
{
|
||||||
|
// return value
|
||||||
|
TQByteArray p;
|
||||||
|
|
||||||
|
// -1 specifies invalid
|
||||||
|
// 64 specifies eof
|
||||||
|
// everything else specifies data
|
||||||
|
|
||||||
|
char tbl[] = {
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
|
||||||
|
52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,
|
||||||
|
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
|
||||||
|
15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
|
||||||
|
-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
|
||||||
|
41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// this should be a multiple of 4
|
||||||
|
int len = s.size();
|
||||||
|
|
||||||
|
if(len % 4)
|
||||||
|
return p;
|
||||||
|
|
||||||
|
p.resize(len / 4 * 3);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int at = 0;
|
||||||
|
|
||||||
|
int a, b, c, d;
|
||||||
|
c = d = 0;
|
||||||
|
|
||||||
|
for( i = 0; i < len; i += 4 ) {
|
||||||
|
a = tbl[(int)s[i]];
|
||||||
|
b = tbl[(int)s[i + 1]];
|
||||||
|
c = tbl[(int)s[i + 2]];
|
||||||
|
d = tbl[(int)s[i + 3]];
|
||||||
|
if((a == 64 || b == 64) || (a < 0 || b < 0 || c < 0 || d < 0)) {
|
||||||
|
p.resize(0);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
p[at++] = ((a & 0x3F) << 2) | ((b >> 4) & 0x03);
|
||||||
|
p[at++] = ((b & 0x0F) << 4) | ((c >> 2) & 0x0F);
|
||||||
|
p[at++] = ((c & 0x03) << 6) | ((d >> 0) & 0x3F);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c & 64)
|
||||||
|
p.resize(at - 2);
|
||||||
|
else if(d & 64)
|
||||||
|
p.resize(at - 1);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
//!
|
||||||
|
//! Encodes array \a a and returns the result as a string.
|
||||||
|
TQString Base64::arrayToString(const TQByteArray &a)
|
||||||
|
{
|
||||||
|
TQByteArray b = encode(a);
|
||||||
|
TQCString c;
|
||||||
|
c.resize(b.size()+1);
|
||||||
|
memcpy(c.data(), b.data(), b.size());
|
||||||
|
return TQString::fromLatin1(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
//!
|
||||||
|
//! Decodes string \a s and returns the result as an array.
|
||||||
|
TQByteArray Base64::stringToArray(const TQString &s)
|
||||||
|
{
|
||||||
|
if(s.isEmpty())
|
||||||
|
return TQByteArray();
|
||||||
|
const char *c = s.latin1();
|
||||||
|
int len = strlen(c);
|
||||||
|
TQByteArray b(len);
|
||||||
|
memcpy(b.data(), c, len);
|
||||||
|
TQByteArray a = decode(b);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
//!
|
||||||
|
//! Encodes string \a s and returns the result as a string.
|
||||||
|
TQString Base64::encodeString(const TQString &s)
|
||||||
|
{
|
||||||
|
TQCString c = s.utf8();
|
||||||
|
int len = c.length();
|
||||||
|
TQByteArray b(len);
|
||||||
|
memcpy(b.data(), c.data(), len);
|
||||||
|
return arrayToString(b);
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* base64.h - Base64 converting functions
|
||||||
|
* 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 CS_BASE64_H
|
||||||
|
#define CS_BASE64_H
|
||||||
|
|
||||||
|
#include<qstring.h>
|
||||||
|
|
||||||
|
class Base64
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static TQByteArray encode(const TQByteArray &);
|
||||||
|
static TQByteArray decode(const TQByteArray &);
|
||||||
|
static TQString arrayToString(const TQByteArray &);
|
||||||
|
static TQByteArray stringToArray(const TQString &);
|
||||||
|
static TQString encodeString(const TQString &);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,7 @@
|
|||||||
|
# change/remove these entries, depending on the installation prefix
|
||||||
|
INCLUDEPATH += /usr/local/include
|
||||||
|
LIBS += -L/usr/local/lib
|
||||||
|
|
||||||
|
# link
|
||||||
|
LIBS += -lqca
|
||||||
|
|
@ -0,0 +1,11 @@
|
|||||||
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
|
SUBDIRS += \
|
||||||
|
hashtest \
|
||||||
|
ciphertest \
|
||||||
|
rsatest \
|
||||||
|
certtest \
|
||||||
|
ssltest \
|
||||||
|
sslservtest \
|
||||||
|
sasltest
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
#include"qca.h"
|
||||||
|
#include<stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
TQCA::init();
|
||||||
|
TQCString cs = (argc >= 2) ? argv[1] : "hello";
|
||||||
|
|
||||||
|
if(!TQCA::isSupported(TQCA::CAP_SHA1))
|
||||||
|
printf("SHA1 not supported!\n");
|
||||||
|
else {
|
||||||
|
TQString result = TQCA::SHA1::hashToString(cs);
|
||||||
|
printf("sha1(\"%s\") = [%s]\n", cs.data(), result.latin1());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!TQCA::isSupported(TQCA::CAP_MD5))
|
||||||
|
printf("MD5 not supported!\n");
|
||||||
|
else {
|
||||||
|
TQString result = TQCA::MD5::hashToString(cs);
|
||||||
|
printf("md5(\"%s\") = [%s]\n", cs.data(), result.latin1());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += thread console
|
||||||
|
TARGET = hashtest
|
||||||
|
|
||||||
|
SOURCES += hashtest.cpp
|
||||||
|
include(../examples.pri)
|
@ -0,0 +1,86 @@
|
|||||||
|
#include<tqfile.h>
|
||||||
|
#include<tqfileinfo.h>
|
||||||
|
#include"qca.h"
|
||||||
|
#include<stdio.h>
|
||||||
|
|
||||||
|
//#define USE_FILE
|
||||||
|
|
||||||
|
TQCA::RSAKey readKeyFile(const TQString &name)
|
||||||
|
{
|
||||||
|
TQCA::RSAKey k;
|
||||||
|
TQFile f(name);
|
||||||
|
if(!f.open(IO_ReadOnly)) {
|
||||||
|
printf("Unable to open %s\n", name.latin1());
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
TQByteArray der = f.readAll();
|
||||||
|
f.close();
|
||||||
|
printf("Read %s [%d bytes]\n", name.latin1(), der.size());
|
||||||
|
|
||||||
|
if(!k.fromDER(der)) {
|
||||||
|
printf("%s: Error importing DER format.\n", name.latin1());
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
char *yes = "yes";
|
||||||
|
char *no = "no";
|
||||||
|
printf("Successfully imported %s (enc=%s, dec=%s)\n",
|
||||||
|
name.latin1(),
|
||||||
|
k.havePublic() ? yes : no,
|
||||||
|
k.havePrivate() ? yes : no);
|
||||||
|
|
||||||
|
printf("Converting to DER: %d bytes\n", k.toDER().size());
|
||||||
|
printf("Converting to PEM:\n%s\n", k.toPEM().latin1());
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
TQCA::init();
|
||||||
|
TQCString cs = (argc >= 2) ? argv[1] : "hello";
|
||||||
|
|
||||||
|
if(!TQCA::isSupported(TQCA::CAP_RSA))
|
||||||
|
printf("RSA not supported!\n");
|
||||||
|
else {
|
||||||
|
#ifdef USE_FILE
|
||||||
|
TQCA::RSAKey pubkey = readKeyFile("keypublic.der");
|
||||||
|
if(pubkey.isNull())
|
||||||
|
return 1;
|
||||||
|
TQCA::RSAKey seckey = readKeyFile("keyprivate.der");
|
||||||
|
if(seckey.isNull())
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
TQCA::RSAKey seckey = TQCA::RSA::generateKey(1024);
|
||||||
|
if(seckey.isNull())
|
||||||
|
return 1;
|
||||||
|
TQCA::RSAKey pubkey = seckey;
|
||||||
|
#endif
|
||||||
|
// encrypt some data
|
||||||
|
TQByteArray a(cs.length());
|
||||||
|
memcpy(a.data(), cs.data(), a.size());
|
||||||
|
|
||||||
|
TQCA::RSA op;
|
||||||
|
op.setKey(pubkey);
|
||||||
|
TQByteArray result;
|
||||||
|
if(!op.encrypt(a, &result)) {
|
||||||
|
printf("Error encrypting.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TQString rstr = TQCA::arrayToHex(result);
|
||||||
|
printf(">rsa(\"%s\") = [%s]\n", cs.data(), rstr.latin1());
|
||||||
|
|
||||||
|
// now decrypt it
|
||||||
|
op.setKey(seckey);
|
||||||
|
TQByteArray dec;
|
||||||
|
if(!op.decrypt(result, &dec)) {
|
||||||
|
printf("Error decrypting.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TQCString dstr;
|
||||||
|
dstr.resize(dec.size()+1);
|
||||||
|
memcpy(dstr.data(), dec.data(), dec.size());
|
||||||
|
printf("<rsa(\"%s\") = [%s]\n", rstr.latin1(), dstr.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += thread console
|
||||||
|
TARGET = rsatest
|
||||||
|
|
||||||
|
SOURCES += rsatest.cpp
|
||||||
|
include(../examples.pri)
|
@ -0,0 +1,615 @@
|
|||||||
|
#include<tqapplication.h>
|
||||||
|
#include<tqtimer.h>
|
||||||
|
#include<tqsocket.h>
|
||||||
|
#include<tqserversocket.h>
|
||||||
|
#include<stdio.h>
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
#include<unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include"base64.h"
|
||||||
|
#include"qca.h"
|
||||||
|
|
||||||
|
#define PROTO_NAME "foo"
|
||||||
|
#define PROTO_PORT 8001
|
||||||
|
|
||||||
|
static TQString prompt(const TQString &s)
|
||||||
|
{
|
||||||
|
printf("* %s ", s.latin1());
|
||||||
|
fflush(stdout);
|
||||||
|
char line[256];
|
||||||
|
fgets(line, 255, stdin);
|
||||||
|
TQString result = line;
|
||||||
|
if(result[result.length()-1] == '\n')
|
||||||
|
result.truncate(result.length()-1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClientTest : public TQObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ClientTest()
|
||||||
|
{
|
||||||
|
sock = new TQSocket;
|
||||||
|
connect(sock, SIGNAL(connected()), SLOT(sock_connected()));
|
||||||
|
connect(sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed()));
|
||||||
|
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
|
||||||
|
connect(sock, SIGNAL(error(int)), SLOT(sock_error(int)));
|
||||||
|
|
||||||
|
sasl = new QCA::SASL;
|
||||||
|
connect(sasl, SIGNAL(clientFirstStep(const TQString &, const TQByteArray *)), SLOT(sasl_clientFirstStep(const TQString &, const TQByteArray *)));
|
||||||
|
connect(sasl, SIGNAL(nextStep(const TQByteArray &)), SLOT(sasl_nextStep(const TQByteArray &)));
|
||||||
|
connect(sasl, SIGNAL(needParams(bool, bool, bool, bool)), SLOT(sasl_needParams(bool, bool, bool, bool)));
|
||||||
|
connect(sasl, SIGNAL(authenticated()), SLOT(sasl_authenticated()));
|
||||||
|
connect(sasl, SIGNAL(readyRead()), SLOT(sasl_readyRead()));
|
||||||
|
connect(sasl, SIGNAL(readyReadOutgoing(int)), SLOT(sasl_readyReadOutgoing(int)));
|
||||||
|
connect(sasl, SIGNAL(error(int)), SLOT(sasl_error(int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
~ClientTest()
|
||||||
|
{
|
||||||
|
delete sock;
|
||||||
|
delete sasl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start(const TQString &_host, int port, const TQString &user="", const TQString &pass="")
|
||||||
|
{
|
||||||
|
mode = 0;
|
||||||
|
host = _host;
|
||||||
|
sock->connectToHost(host, port);
|
||||||
|
sasl->setMinimumSSF(0);
|
||||||
|
sasl->setMaximumSSF(256);
|
||||||
|
|
||||||
|
if(!user.isEmpty()) {
|
||||||
|
sasl->setUsername(user);
|
||||||
|
sasl->setAuthzid(user);
|
||||||
|
}
|
||||||
|
if(!pass.isEmpty())
|
||||||
|
sasl->setPassword(pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void quit();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void sock_connected()
|
||||||
|
{
|
||||||
|
printf("Connected to server. Awaiting mechanism list...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_connectionClosed()
|
||||||
|
{
|
||||||
|
printf("Connection closed by peer.\n");
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_error(int x)
|
||||||
|
{
|
||||||
|
TQString s;
|
||||||
|
if(x == TQSocket::ErrConnectionRefused)
|
||||||
|
s = "connection refused or timed out";
|
||||||
|
else if(x == TQSocket::ErrHostNotFound)
|
||||||
|
s = "host not found";
|
||||||
|
else if(x == TQSocket::ErrSocketRead)
|
||||||
|
s = "read error";
|
||||||
|
|
||||||
|
printf("Socket error: %s\n", s.latin1());
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_readyRead()
|
||||||
|
{
|
||||||
|
if(mode == 2) {
|
||||||
|
int avail = sock->bytesAvailable();
|
||||||
|
TQByteArray a(avail);
|
||||||
|
int n = sock->readBlock(a.data(), a.size());
|
||||||
|
a.resize(n);
|
||||||
|
printf("Read %d bytes\n", a.size());
|
||||||
|
sasl->writeIncoming(a);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(sock->canReadLine()) {
|
||||||
|
TQString line = sock->readLine();
|
||||||
|
line.truncate(line.length()-1); // chop the newline
|
||||||
|
handleLine(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_clientFirstStep(const TQString &mech, const TQByteArray *clientInit)
|
||||||
|
{
|
||||||
|
printf("Choosing mech: %s\n", mech.latin1());
|
||||||
|
TQString line = mech;
|
||||||
|
if(clientInit) {
|
||||||
|
TQCString cs(clientInit->data(), clientInit->size()+1);
|
||||||
|
line += ' ';
|
||||||
|
line += cs;
|
||||||
|
}
|
||||||
|
sendLine(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_nextStep(const TQByteArray &stepData)
|
||||||
|
{
|
||||||
|
TQCString cs(stepData.data(), stepData.size()+1);
|
||||||
|
TQString line = "C";
|
||||||
|
if(!stepData.isEmpty()) {
|
||||||
|
line += ',';
|
||||||
|
line += cs;
|
||||||
|
}
|
||||||
|
sendLine(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_needParams(bool user, bool authzid, bool pass, bool realm)
|
||||||
|
{
|
||||||
|
TQString username;
|
||||||
|
if(user || authzid)
|
||||||
|
username = prompt("Username:");
|
||||||
|
if(user) {
|
||||||
|
sasl->setUsername(username);
|
||||||
|
}
|
||||||
|
if(authzid) {
|
||||||
|
sasl->setAuthzid(username);
|
||||||
|
}
|
||||||
|
if(pass) {
|
||||||
|
sasl->setPassword(prompt("Password (not hidden!) :"));
|
||||||
|
}
|
||||||
|
if(realm) {
|
||||||
|
sasl->setRealm(prompt("Realm:"));
|
||||||
|
}
|
||||||
|
sasl->continueAfterParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_authenticated()
|
||||||
|
{
|
||||||
|
printf("SASL success!\n");
|
||||||
|
printf("SSF: %d\n", sasl->ssf());
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_readyRead()
|
||||||
|
{
|
||||||
|
TQByteArray a = sasl->read();
|
||||||
|
int oldsize = inbuf.size();
|
||||||
|
inbuf.resize(oldsize + a.size());
|
||||||
|
memcpy(inbuf.data() + oldsize, a.data(), a.size());
|
||||||
|
processInbuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_readyReadOutgoing(int)
|
||||||
|
{
|
||||||
|
TQByteArray a = sasl->readOutgoing();
|
||||||
|
sock->writeBlock(a.data(), a.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_error(int)
|
||||||
|
{
|
||||||
|
printf("SASL error!\n");
|
||||||
|
quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TQSocket *sock;
|
||||||
|
QCA::SASL *sasl;
|
||||||
|
int mode;
|
||||||
|
TQString host;
|
||||||
|
TQByteArray inbuf;
|
||||||
|
|
||||||
|
void processInbuf()
|
||||||
|
{
|
||||||
|
TQStringList list;
|
||||||
|
for(int n = 0; n < (int)inbuf.size(); ++n) {
|
||||||
|
if(inbuf[n] == '\n') {
|
||||||
|
TQCString cs(inbuf.data(), n+1);
|
||||||
|
char *p = inbuf.data();
|
||||||
|
++n;
|
||||||
|
int x = inbuf.size() - n;
|
||||||
|
memmove(p, p + n, x);
|
||||||
|
inbuf.resize(x);
|
||||||
|
list += TQString::fromUtf8(cs);
|
||||||
|
// start over, basically
|
||||||
|
n = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it)
|
||||||
|
handleLine(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleLine(const TQString &line)
|
||||||
|
{
|
||||||
|
printf("Reading: [%s]\n", line.latin1());
|
||||||
|
if(mode == 0) {
|
||||||
|
// first line is the method list
|
||||||
|
TQStringList mechlist = TQStringList::split(' ', line);
|
||||||
|
++mode;
|
||||||
|
|
||||||
|
// kick off the client
|
||||||
|
sasl->setAllowAnonymous(false);
|
||||||
|
if(!sasl->startClient(PROTO_NAME, host, mechlist)) {
|
||||||
|
printf("Error starting client!\n");
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(mode == 1) {
|
||||||
|
TQString type, rest;
|
||||||
|
int n = line.find(',');
|
||||||
|
if(n != -1) {
|
||||||
|
type = line.mid(0, n);
|
||||||
|
rest = line.mid(n+1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
type = line;
|
||||||
|
rest = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type == "C") {
|
||||||
|
TQCString cs = rest.latin1();
|
||||||
|
TQByteArray buf(cs.length());
|
||||||
|
memcpy(buf.data(), cs.data(), buf.size());
|
||||||
|
sasl->putStep(buf);
|
||||||
|
}
|
||||||
|
else if(type == "E") {
|
||||||
|
printf("Authentication failed.\n");
|
||||||
|
quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(type == "A") {
|
||||||
|
printf("Authentication success.\n");
|
||||||
|
++mode;
|
||||||
|
sock_readyRead(); // any extra data?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Bad format from peer, closing.\n");
|
||||||
|
quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendLine(const TQString &line)
|
||||||
|
{
|
||||||
|
printf("Writing: {%s}\n", line.latin1());
|
||||||
|
TQString s = line + '\n';
|
||||||
|
TQCString cs = s.latin1();
|
||||||
|
if(mode == 2) {
|
||||||
|
TQByteArray a(cs.length());
|
||||||
|
memcpy(a.data(), cs.data(), a.size());
|
||||||
|
sasl->write(a);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sock->writeBlock(cs.data(), cs.length());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ServerTest : public QServerSocket
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ServerTest(const TQString &_str, int _port) : QServerSocket(_port), port(_port)
|
||||||
|
{
|
||||||
|
sock = 0;
|
||||||
|
sasl = 0;
|
||||||
|
realm = TQString::null;
|
||||||
|
str = _str;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ServerTest()
|
||||||
|
{
|
||||||
|
delete sock;
|
||||||
|
delete sasl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start()
|
||||||
|
{
|
||||||
|
if(!ok()) {
|
||||||
|
printf("Error binding to port %d!\n", port);
|
||||||
|
TTQTimer::singleShot(0, this, SIGNAL(quit()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char myhostname[256];
|
||||||
|
int r = gethostname(myhostname, sizeof(myhostname)-1);
|
||||||
|
if(r == -1) {
|
||||||
|
printf("Error getting hostname!\n");
|
||||||
|
TTQTimer::singleShot(0, this, SIGNAL(quit()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
host = myhostname;
|
||||||
|
printf("Listening on %s:%d ...\n", host.latin1(), port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void newConnection(int s)
|
||||||
|
{
|
||||||
|
// Note: only 1 connection supported at a time in this example!
|
||||||
|
if(sock) {
|
||||||
|
TQSocket tmp;
|
||||||
|
tmp.setSocket(s);
|
||||||
|
printf("Connection ignored, already have one active.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Connection received! Starting SASL handshake...\n");
|
||||||
|
|
||||||
|
sock = new TQSocket;
|
||||||
|
connect(sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed()));
|
||||||
|
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
|
||||||
|
connect(sock, SIGNAL(error(int)), SLOT(sock_error(int)));
|
||||||
|
connect(sock, SIGNAL(bytesWritten(int)), SLOT(sock_bytesWritten(int)));
|
||||||
|
|
||||||
|
sasl = new QCA::SASL;
|
||||||
|
connect(sasl, SIGNAL(authCheck(const TQString &, const TQString &)), SLOT(sasl_authCheck(const TQString &, const TQString &)));
|
||||||
|
connect(sasl, SIGNAL(nextStep(const TQByteArray &)), SLOT(sasl_nextStep(const TQByteArray &)));
|
||||||
|
connect(sasl, SIGNAL(authenticated()), SLOT(sasl_authenticated()));
|
||||||
|
connect(sasl, SIGNAL(readyRead()), SLOT(sasl_readyRead()));
|
||||||
|
connect(sasl, SIGNAL(readyReadOutgoing(int)), SLOT(sasl_readyReadOutgoing(int)));
|
||||||
|
connect(sasl, SIGNAL(error(int)), SLOT(sasl_error(int)));
|
||||||
|
|
||||||
|
sock->setSocket(s);
|
||||||
|
mode = 0;
|
||||||
|
inbuf.resize(0);
|
||||||
|
|
||||||
|
sasl->setMinimumSSF(0);
|
||||||
|
sasl->setMaximumSSF(256);
|
||||||
|
|
||||||
|
TQStringList mechlist;
|
||||||
|
if(!sasl->startServer(PROTO_NAME, host, realm, &mechlist)) {
|
||||||
|
printf("Error starting server!\n");
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
TQString str;
|
||||||
|
bool first = true;
|
||||||
|
for(TQStringList::ConstIterator it = mechlist.begin(); it != mechlist.end(); ++it) {
|
||||||
|
if(!first)
|
||||||
|
str += ' ';
|
||||||
|
str += *it;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
sendLine(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void quit();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void sock_connectionClosed()
|
||||||
|
{
|
||||||
|
printf("Connection closed by peer.\n");
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_error(int x)
|
||||||
|
{
|
||||||
|
TQString s;
|
||||||
|
if(x == TQSocket::ErrConnectionRefused)
|
||||||
|
s = "connection refused or timed out";
|
||||||
|
else if(x == TQSocket::ErrHostNotFound)
|
||||||
|
s = "host not found";
|
||||||
|
else if(x == TQSocket::ErrSocketRead)
|
||||||
|
s = "read error";
|
||||||
|
|
||||||
|
printf("Socket error: %s\n", s.latin1());
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_readyRead()
|
||||||
|
{
|
||||||
|
if(sock->canReadLine()) {
|
||||||
|
TQString line = sock->readLine();
|
||||||
|
line.truncate(line.length()-1); // chop the newline
|
||||||
|
handleLine(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_bytesWritten(int x)
|
||||||
|
{
|
||||||
|
if(mode == 2) {
|
||||||
|
toWrite -= x;
|
||||||
|
if(toWrite <= 0) {
|
||||||
|
printf("Sent, closing.\n");
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_nextStep(const TQByteArray &stepData)
|
||||||
|
{
|
||||||
|
TQCString cs(stepData.data(), stepData.size()+1);
|
||||||
|
TQString line = "C";
|
||||||
|
if(!stepData.isEmpty()) {
|
||||||
|
line += ',';
|
||||||
|
line += cs;
|
||||||
|
}
|
||||||
|
sendLine(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_authCheck(const TQString &user, const TQString &authzid)
|
||||||
|
{
|
||||||
|
printf("AuthCheck: User: [%s], Authzid: [%s]\n", user.latin1(), authzid.latin1());
|
||||||
|
sasl->continueAfterAuthCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_authenticated()
|
||||||
|
{
|
||||||
|
sendLine("A");
|
||||||
|
printf("Authentication success.\n");
|
||||||
|
++mode;
|
||||||
|
printf("SSF: %d\n", sasl->ssf());
|
||||||
|
sendLine(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_readyRead()
|
||||||
|
{
|
||||||
|
TQByteArray a = sasl->read();
|
||||||
|
int oldsize = inbuf.size();
|
||||||
|
inbuf.resize(oldsize + a.size());
|
||||||
|
memcpy(inbuf.data() + oldsize, a.data(), a.size());
|
||||||
|
processInbuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_readyReadOutgoing(int)
|
||||||
|
{
|
||||||
|
TQByteArray a = sasl->readOutgoing();
|
||||||
|
toWrite = a.size();
|
||||||
|
sock->writeBlock(a.data(), a.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void sasl_error(int x)
|
||||||
|
{
|
||||||
|
if(x == QCA::SASL::ErrAuth) {
|
||||||
|
sendLine("E");
|
||||||
|
printf("Authentication failed.\n");
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("SASL security layer error!\n");
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TQSocket *sock;
|
||||||
|
QCA::SASL *sasl;
|
||||||
|
TQString host, realm;
|
||||||
|
int port;
|
||||||
|
int mode;
|
||||||
|
TQString str;
|
||||||
|
TQByteArray inbuf;
|
||||||
|
int toWrite;
|
||||||
|
|
||||||
|
void processInbuf()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleLine(const TQString &line)
|
||||||
|
{
|
||||||
|
printf("Reading: [%s]\n", line.latin1());
|
||||||
|
if(mode == 0) {
|
||||||
|
int n = line.find(' ');
|
||||||
|
if(n != -1) {
|
||||||
|
TQString mech = line.mid(0, n);
|
||||||
|
TQCString cs = line.mid(n+1).latin1();
|
||||||
|
TQByteArray clientInit(cs.length());
|
||||||
|
memcpy(clientInit.data(), cs.data(), clientInit.size());
|
||||||
|
sasl->putServerFirstStep(mech, clientInit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sasl->putServerFirstStep(line);
|
||||||
|
++mode;
|
||||||
|
}
|
||||||
|
else if(mode == 1) {
|
||||||
|
TQString type, rest;
|
||||||
|
int n = line.find(',');
|
||||||
|
if(n != -1) {
|
||||||
|
type = line.mid(0, n);
|
||||||
|
rest = line.mid(n+1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
type = line;
|
||||||
|
rest = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type == "C") {
|
||||||
|
TQCString cs = rest.latin1();
|
||||||
|
TQByteArray buf(cs.length());
|
||||||
|
memcpy(buf.data(), cs.data(), buf.size());
|
||||||
|
sasl->putStep(buf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Bad format from peer, closing.\n");
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendLine(const TQString &line)
|
||||||
|
{
|
||||||
|
printf("Writing: {%s}\n", line.latin1());
|
||||||
|
TQString s = line + '\n';
|
||||||
|
TQCString cs = s.latin1();
|
||||||
|
if(mode == 2) {
|
||||||
|
TQByteArray a(cs.length());
|
||||||
|
memcpy(a.data(), cs.data(), a.size());
|
||||||
|
sasl->write(a);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sock->writeBlock(cs.data(), cs.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
sock->deleteLater();
|
||||||
|
sock = 0;
|
||||||
|
delete sasl;
|
||||||
|
sasl = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#include"sasltest.moc"
|
||||||
|
|
||||||
|
void usage()
|
||||||
|
{
|
||||||
|
printf("usage: sasltest client [host] [user] [pass]\n");
|
||||||
|
printf(" sasltest server [string]\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
TQApplication app(argc, argv, false);
|
||||||
|
|
||||||
|
TQString host, user, pass;
|
||||||
|
TQString str = "Hello, World";
|
||||||
|
bool server;
|
||||||
|
if(argc < 2) {
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
TQString arg = argv[1];
|
||||||
|
if(arg == "client") {
|
||||||
|
if(argc < 3) {
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
host = argv[2];
|
||||||
|
if(argc >= 4)
|
||||||
|
user = argv[3];
|
||||||
|
if(argc >= 5)
|
||||||
|
pass = argv[4];
|
||||||
|
server = false;
|
||||||
|
}
|
||||||
|
else if(arg == "server") {
|
||||||
|
if(argc >= 3)
|
||||||
|
str = argv[2];
|
||||||
|
server = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!QCA::isSupported(QCA::CAP_SASL)) {
|
||||||
|
printf("SASL not supported!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(server) {
|
||||||
|
ServerTest *s = new ServerTest(str, PROTO_PORT);
|
||||||
|
TQObject::connect(s, SIGNAL(quit()), &app, SLOT(quit()));
|
||||||
|
s->start();
|
||||||
|
app.exec();
|
||||||
|
delete s;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ClientTest *c = new ClientTest;
|
||||||
|
TQObject::connect(c, SIGNAL(quit()), &app, SLOT(quit()));
|
||||||
|
c->start(host, PROTO_PORT, user, pass);
|
||||||
|
app.exec();
|
||||||
|
delete c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += thread console
|
||||||
|
TARGET = sasltest
|
||||||
|
|
||||||
|
INCLUDEPATH += ../common
|
||||||
|
HEADERS += ../common/base64.h
|
||||||
|
SOURCES += ../common/base64.cpp sasltest.cpp
|
||||||
|
include(../examples.pri)
|
@ -0,0 +1,294 @@
|
|||||||
|
#include<tqapplication.h>
|
||||||
|
#include<tqfile.h>
|
||||||
|
#include<tqsocket.h>
|
||||||
|
#include<tqserversocket.h>
|
||||||
|
#include<tqvaluelist.h>
|
||||||
|
#include<tqtimer.h>
|
||||||
|
#include"qca.h"
|
||||||
|
|
||||||
|
char pemdata_cert[] =
|
||||||
|
"-----BEGIN CERTIFICATE-----\n"
|
||||||
|
"MIIDbjCCAtegAwIBAgIBADANBgkqhkiG9w0BAQQFADCBhzELMAkGA1UEBhMCVVMx\n"
|
||||||
|
"EzARBgNVBAgTCkNhbGlmb3JuaWExDzANBgNVBAcTBklydmluZTEYMBYGA1UEChMP\n"
|
||||||
|
"RXhhbXBsZSBDb21wYW55MRQwEgYDVQQDEwtleGFtcGxlLmNvbTEiMCAGCSqGSIb3\n"
|
||||||
|
"DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbTAeFw0wMzA3MjQwNzMwMDBaFw0wMzA4\n"
|
||||||
|
"MjMwNzMwMDBaMIGHMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEP\n"
|
||||||
|
"MA0GA1UEBxMGSXJ2aW5lMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNV\n"
|
||||||
|
"BAMTC2V4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUu\n"
|
||||||
|
"Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCobzCF268K2sRp473gvBTT\n"
|
||||||
|
"4AgSL1kjeF8N57vxS1P8zWrWMXNs4LuH0NRZmKTajeboy0br8xw+smIy3AbaKAwW\n"
|
||||||
|
"WZToesxebu3m9VeA8dqWyOaUMjoxAcgVYesgVaMpjRe7fcWdJnX1wJoVVPuIcO8m\n"
|
||||||
|
"a+AAPByfTORbzpSTmXAQAwIDAQABo4HnMIHkMB0GA1UdDgQWBBTvFierzLmmYMq0\n"
|
||||||
|
"cB/+5rK1bNR56zCBtAYDVR0jBIGsMIGpgBTvFierzLmmYMq0cB/+5rK1bNR566GB\n"
|
||||||
|
"jaSBijCBhzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDzANBgNV\n"
|
||||||
|
"BAcTBklydmluZTEYMBYGA1UEChMPRXhhbXBsZSBDb21wYW55MRQwEgYDVQQDEwtl\n"
|
||||||
|
"eGFtcGxlLmNvbTEiMCAGCSqGSIb3DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbYIB\n"
|
||||||
|
"ADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAGqGhXf7xNOnYNtFO7gz\n"
|
||||||
|
"K6RdZGHFI5q1DAEz4hhNBC9uElh32XGX4wN7giz3zLC8v9icL/W4ff/K5NDfv3Gf\n"
|
||||||
|
"gQe/+Wo9Be3H3ul6uwPPFnx4+PIOF2a5TW99H9smyxWdNjnFtcUte4al3RszcMWG\n"
|
||||||
|
"x3iqsWosGtj6F+ridmKoqKLu\n"
|
||||||
|
"-----END CERTIFICATE-----\n";
|
||||||
|
|
||||||
|
char pemdata_privkey[] =
|
||||||
|
"-----BEGIN RSA PRIVATE KEY-----\n"
|
||||||
|
"MIICXAIBAAKBgQCobzCF268K2sRp473gvBTT4AgSL1kjeF8N57vxS1P8zWrWMXNs\n"
|
||||||
|
"4LuH0NRZmKTajeboy0br8xw+smIy3AbaKAwWWZToesxebu3m9VeA8dqWyOaUMjox\n"
|
||||||
|
"AcgVYesgVaMpjRe7fcWdJnX1wJoVVPuIcO8ma+AAPByfTORbzpSTmXAQAwIDAQAB\n"
|
||||||
|
"AoGAP83u+aYghuIcaWhmM03MLf69z/WztKYSi/fu0BcS977w67bL3MC9CVPoPRB/\n"
|
||||||
|
"0nLSt/jZIuRzHKUCYfXLerSU7v0oXDTy6GPzWMh/oXIrpF0tYNbwWF7LSq2O2gGZ\n"
|
||||||
|
"XtA9MSmUNNJaKzQQeXjqdVFOY8A0Pho+k2KByBiCi+ChkcECQQDRUuyX0+PKJtA2\n"
|
||||||
|
"M36BOTFpy61BAv+JRlXUnHuevOfQWl6NR6YGygqCyH1sWtP1sa9S4wWys3DFH+5A\n"
|
||||||
|
"DkuAqk7zAkEAzf4eUH2hp5CIMsXH+WpIzKj09oY1it2CAKjVq4rUELf8iXvmGoFl\n"
|
||||||
|
"000spua4MjHNUYm7LR0QaKesKrMyGZUesQJAL8aLdYPJI+SD9Tr/jqLtIkZ4frQe\n"
|
||||||
|
"eshw4pvsoyheiHF3zyshO791crAr4EVCx3sMlxB1xnmqLXPCPyCEHxO//QJBAIBY\n"
|
||||||
|
"IYkjDZJ6ofGIe1UyXJNvfdkPu9J+ut4wU5jjEcgs6mK62J6RGuFxhy2iOQfFMdjo\n"
|
||||||
|
"yL+OCUg7mDCun7uCxrECQAtSvnLOFMjO5qExRjFtwi+b1rcSekd3Osk/izyRFSzg\n"
|
||||||
|
"Or+AL56/EKfiogNnFipgaXIbb/xj785Cob6v96XoW1I=\n"
|
||||||
|
"-----END RSA PRIVATE KEY-----\n";
|
||||||
|
|
||||||
|
class LayerTracker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Item
|
||||||
|
{
|
||||||
|
int plain;
|
||||||
|
int encoded;
|
||||||
|
};
|
||||||
|
|
||||||
|
LayerTracker()
|
||||||
|
{
|
||||||
|
p = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
p = 0;
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addPlain(int plain)
|
||||||
|
{
|
||||||
|
p += plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
void specifyEncoded(int encoded, int plain)
|
||||||
|
{
|
||||||
|
// can't specify more bytes than we have
|
||||||
|
if(plain > p)
|
||||||
|
plain = p;
|
||||||
|
p -= plain;
|
||||||
|
Item i;
|
||||||
|
i.plain = plain;
|
||||||
|
i.encoded = encoded;
|
||||||
|
list += i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int finished(int encoded)
|
||||||
|
{
|
||||||
|
int plain = 0;
|
||||||
|
for(TQValueList<Item>::Iterator it = list.begin(); it != list.end();) {
|
||||||
|
Item &i = *it;
|
||||||
|
|
||||||
|
// not enough?
|
||||||
|
if(encoded < i.encoded) {
|
||||||
|
i.encoded -= encoded;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
encoded -= i.encoded;
|
||||||
|
plain += i.plain;
|
||||||
|
it = list.remove(it);
|
||||||
|
}
|
||||||
|
return plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
int p;
|
||||||
|
TQValueList<Item> list;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SecureServerTest : public QServerSocket
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum { Idle, Handshaking, Active, Closing };
|
||||||
|
|
||||||
|
SecureServerTest(int _port) : QServerSocket(_port), port(_port)
|
||||||
|
{
|
||||||
|
sock = new TQSocket;
|
||||||
|
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
|
||||||
|
connect(sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed()));
|
||||||
|
connect(sock, SIGNAL(error(int)), SLOT(sock_error(int)));
|
||||||
|
connect(sock, SIGNAL(bytesWritten(int)), SLOT(sock_bytesWritten(int)));
|
||||||
|
|
||||||
|
ssl = new QCA::TLS;
|
||||||
|
connect(ssl, SIGNAL(handshaken()), SLOT(ssl_handshaken()));
|
||||||
|
connect(ssl, SIGNAL(readyRead()), SLOT(ssl_readyRead()));
|
||||||
|
connect(ssl, SIGNAL(readyReadOutgoing(int)), SLOT(ssl_readyReadOutgoing(int)));
|
||||||
|
connect(ssl, SIGNAL(closed()), SLOT(ssl_closed()));
|
||||||
|
connect(ssl, SIGNAL(error(int)), SLOT(ssl_error(int)));
|
||||||
|
|
||||||
|
cert.fromPEM(pemdata_cert);
|
||||||
|
privkey.fromPEM(pemdata_privkey);
|
||||||
|
|
||||||
|
mode = Idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
~SecureServerTest()
|
||||||
|
{
|
||||||
|
delete ssl;
|
||||||
|
delete sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start()
|
||||||
|
{
|
||||||
|
if(cert.isNull() || privkey.isNull()) {
|
||||||
|
printf("Error loading cert and/or private key!\n");
|
||||||
|
TTQTimer::singleShot(0, this, SIGNAL(quit()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!ok()) {
|
||||||
|
printf("Error binding to port %d!\n", port);
|
||||||
|
TTQTimer::singleShot(0, this, SIGNAL(quit()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("Listening on port %d ...\n", port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void newConnection(int s)
|
||||||
|
{
|
||||||
|
// Note: only 1 connection supported at a time in this example!
|
||||||
|
if(sock->isOpen()) {
|
||||||
|
TQSocket tmp;
|
||||||
|
tmp.setSocket(s);
|
||||||
|
printf("throwing away extra connection\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mode = Handshaking;
|
||||||
|
sock->setSocket(s);
|
||||||
|
printf("Connection received! Starting TLS handshake...\n");
|
||||||
|
ssl->setCertificate(cert, privkey);
|
||||||
|
ssl->startServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void quit();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void sock_readyRead()
|
||||||
|
{
|
||||||
|
TQByteArray buf(sock->bytesAvailable());
|
||||||
|
int num = sock->readBlock(buf.data(), buf.size());
|
||||||
|
if(num < (int)buf.size())
|
||||||
|
buf.resize(num);
|
||||||
|
ssl->writeIncoming(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_connectionClosed()
|
||||||
|
{
|
||||||
|
printf("Connection closed.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_bytesWritten(int x)
|
||||||
|
{
|
||||||
|
if(mode == Active && sent) {
|
||||||
|
int bytes = layer.finished(x);
|
||||||
|
bytesLeft -= bytes;
|
||||||
|
|
||||||
|
if(bytesLeft == 0) {
|
||||||
|
mode = Closing;
|
||||||
|
printf("SSL shutdown\n");
|
||||||
|
ssl->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_error(int)
|
||||||
|
{
|
||||||
|
printf("Socket error.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_handshaken()
|
||||||
|
{
|
||||||
|
printf("Successful SSL handshake. Waiting for newline.\n");
|
||||||
|
layer.reset();
|
||||||
|
bytesLeft = 0;
|
||||||
|
sent = false;
|
||||||
|
mode = Active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_readyRead()
|
||||||
|
{
|
||||||
|
TQByteArray a = ssl->read();
|
||||||
|
TQString str =
|
||||||
|
"<html>\n"
|
||||||
|
"<head><title>Test</title></head>\n"
|
||||||
|
"<body>this is only a test</body>\n"
|
||||||
|
"</html>\n";
|
||||||
|
TQCString cs = str.latin1();
|
||||||
|
TQByteArray b(cs.length());
|
||||||
|
memcpy(b.data(), cs.data(), b.size());
|
||||||
|
|
||||||
|
printf("Sending test response...\n");
|
||||||
|
sent = true;
|
||||||
|
layer.addPlain(b.size());
|
||||||
|
ssl->write(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_readyReadOutgoing(int plainBytes)
|
||||||
|
{
|
||||||
|
TQByteArray a = ssl->readOutgoing();
|
||||||
|
layer.specifyEncoded(a.size(), plainBytes);
|
||||||
|
sock->writeBlock(a.data(), a.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_closed()
|
||||||
|
{
|
||||||
|
printf("Closing.\n");
|
||||||
|
sock->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_error(int x)
|
||||||
|
{
|
||||||
|
if(x == QCA::TLS::ErrHandshake) {
|
||||||
|
printf("SSL Handshake Error! Closing.\n");
|
||||||
|
sock->close();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("SSL Error! Closing.\n");
|
||||||
|
sock->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int port;
|
||||||
|
TQSocket *sock;
|
||||||
|
QCA::TLS *ssl;
|
||||||
|
QCA::Cert cert;
|
||||||
|
QCA::RSAKey privkey;
|
||||||
|
|
||||||
|
bool sent;
|
||||||
|
int mode;
|
||||||
|
int bytesLeft;
|
||||||
|
LayerTracker layer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include"sslservtest.moc"
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
TQApplication app(argc, argv, false);
|
||||||
|
int port = argc > 1 ? TQString(argv[1]).toInt() : 8000;
|
||||||
|
|
||||||
|
if(!QCA::isSupported(QCA::CAP_TLS)) {
|
||||||
|
printf("TLS not supported!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SecureServerTest *s = new SecureServerTest(port);
|
||||||
|
TQObject::connect(s, SIGNAL(quit()), &app, SLOT(quit()));
|
||||||
|
s->start();
|
||||||
|
app.exec();
|
||||||
|
delete s;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += thread console
|
||||||
|
TARGET = sslservtest
|
||||||
|
|
||||||
|
SOURCES += sslservtest.cpp
|
||||||
|
include(../examples.pri)
|
@ -0,0 +1,276 @@
|
|||||||
|
#include<tqapplication.h>
|
||||||
|
#include<tqdom.h>
|
||||||
|
#include<tqfile.h>
|
||||||
|
#include<tqsocket.h>
|
||||||
|
#include<tqptrlist.h>
|
||||||
|
#include"base64.h"
|
||||||
|
#include"qca.h"
|
||||||
|
|
||||||
|
TQCA::Cert readCertXml(const TQDomElement &e)
|
||||||
|
{
|
||||||
|
TQCA::Cert cert;
|
||||||
|
// there should be one child data tag
|
||||||
|
TQDomElement data = e.elementsByTagName("data").item(0).toElement();
|
||||||
|
if(!data.isNull())
|
||||||
|
cert.fromDER(Base64::stringToArray(data.text()));
|
||||||
|
return cert;
|
||||||
|
}
|
||||||
|
|
||||||
|
void showCertInfo(const TQCA::Cert &cert)
|
||||||
|
{
|
||||||
|
printf("-- Cert --\n");
|
||||||
|
printf(" CN: %s\n", cert.subject()["CN"].latin1());
|
||||||
|
printf(" Valid from: %s, until %s\n",
|
||||||
|
cert.notBefore().toString().latin1(),
|
||||||
|
cert.notAfter().toString().latin1());
|
||||||
|
printf(" PEM:\n%s\n", cert.toPEM().latin1());
|
||||||
|
}
|
||||||
|
|
||||||
|
TQPtrList<TQCA::Cert> getRootCerts(const TQString &store)
|
||||||
|
{
|
||||||
|
TQPtrList<TQCA::Cert> list;
|
||||||
|
|
||||||
|
// open the Psi rootcerts file
|
||||||
|
TQFile f(store);
|
||||||
|
if(!f.open(IO_ReadOnly)) {
|
||||||
|
printf("unable to open %s\n", f.name().latin1());
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
TQDomDocument doc;
|
||||||
|
doc.setContent(&f);
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
TQDomElement base = doc.documentElement();
|
||||||
|
if(base.tagName() != "store") {
|
||||||
|
printf("wrong format of %s\n", f.name().latin1());
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
TQDomNodeList cl = base.elementsByTagName("certificate");
|
||||||
|
if(cl.count() == 0) {
|
||||||
|
printf("no certs found in %s\n", f.name().latin1());
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num = 0;
|
||||||
|
for(int n = 0; n < (int)cl.count(); ++n) {
|
||||||
|
TQCA::Cert *cert = new TQCA::Cert(readCertXml(cl.item(n).toElement()));
|
||||||
|
if(cert->isNull()) {
|
||||||
|
printf("error reading cert\n");
|
||||||
|
delete cert;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
++num;
|
||||||
|
list.append(cert);
|
||||||
|
}
|
||||||
|
printf("imported %d root certs\n", num);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
TQString resultToString(int result)
|
||||||
|
{
|
||||||
|
TQString s;
|
||||||
|
switch(result) {
|
||||||
|
case TQCA::TLS::NoCert:
|
||||||
|
s = TQObject::tr("No certificate presented.");
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::Valid:
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::HostMismatch:
|
||||||
|
s = TQObject::tr("Hostname mismatch.");
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::Rejected:
|
||||||
|
s = TQObject::tr("Root CA rejects the specified purpose.");
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::Untrusted:
|
||||||
|
s = TQObject::tr("Not trusted for the specified purpose.");
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::SignatureFailed:
|
||||||
|
s = TQObject::tr("Invalid signature.");
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::InvalidCA:
|
||||||
|
s = TQObject::tr("Invalid CA certificate.");
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::InvalidPurpose:
|
||||||
|
s = TQObject::tr("Invalid certificate purpose.");
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::SelfSigned:
|
||||||
|
s = TQObject::tr("Certificate is self-signed.");
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::Revoked:
|
||||||
|
s = TQObject::tr("Certificate has been revoked.");
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::PathLengthExceeded:
|
||||||
|
s = TQObject::tr("Maximum cert chain length exceeded.");
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::Expired:
|
||||||
|
s = TQObject::tr("Certificate has expired.");
|
||||||
|
break;
|
||||||
|
case TQCA::TLS::Unknown:
|
||||||
|
default:
|
||||||
|
s = TQObject::tr("General validation error.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SecureTest : public TQObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SecureTest()
|
||||||
|
{
|
||||||
|
sock = new TQSocket;
|
||||||
|
connect(sock, SIGNAL(connected()), SLOT(sock_connected()));
|
||||||
|
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
|
||||||
|
connect(sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed()));
|
||||||
|
connect(sock, SIGNAL(error(int)), SLOT(sock_error(int)));
|
||||||
|
|
||||||
|
ssl = new TQCA::TLS;
|
||||||
|
connect(ssl, SIGNAL(handshaken()), SLOT(ssl_handshaken()));
|
||||||
|
connect(ssl, SIGNAL(readyRead()), SLOT(ssl_readyRead()));
|
||||||
|
connect(ssl, SIGNAL(readyReadOutgoing(int)), SLOT(ssl_readyReadOutgoing(int)));
|
||||||
|
connect(ssl, SIGNAL(closed()), SLOT(ssl_closed()));
|
||||||
|
connect(ssl, SIGNAL(error(int)), SLOT(ssl_error(int)));
|
||||||
|
|
||||||
|
rootCerts.setAutoDelete(true);
|
||||||
|
rootCerts = getRootCerts("/usr/local/share/psi/certs/rootcert.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
~SecureTest()
|
||||||
|
{
|
||||||
|
delete ssl;
|
||||||
|
delete sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start(const TQString &_host)
|
||||||
|
{
|
||||||
|
int n = _host.find(':');
|
||||||
|
int port;
|
||||||
|
if(n != -1) {
|
||||||
|
host = _host.mid(0, n);
|
||||||
|
port = _host.mid(n+1).toInt();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
host = _host;
|
||||||
|
port = 443;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Trying %s:%d...\n", host.latin1(), port);
|
||||||
|
sock->connectToHost(host, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void quit();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void sock_connected()
|
||||||
|
{
|
||||||
|
printf("Connected, starting TLS handshake...\n");
|
||||||
|
ssl->setCertificateStore(rootCerts);
|
||||||
|
ssl->startClient(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_readyRead()
|
||||||
|
{
|
||||||
|
TQByteArray buf(sock->bytesAvailable());
|
||||||
|
int num = sock->readBlock(buf.data(), buf.size());
|
||||||
|
if(num < (int)buf.size())
|
||||||
|
buf.resize(num);
|
||||||
|
ssl->writeIncoming(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_connectionClosed()
|
||||||
|
{
|
||||||
|
printf("\nConnection closed.\n");
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sock_error(int)
|
||||||
|
{
|
||||||
|
printf("\nSocket error.\n");
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_handshaken()
|
||||||
|
{
|
||||||
|
cert = ssl->peerCertificate();
|
||||||
|
int vr = ssl->certificateValidityResult();
|
||||||
|
|
||||||
|
printf("Successful SSL handshake.\n");
|
||||||
|
if(!cert.isNull())
|
||||||
|
showCertInfo(cert);
|
||||||
|
if(vr == TQCA::TLS::Valid)
|
||||||
|
printf("Valid certificate.\n");
|
||||||
|
else
|
||||||
|
printf("Invalid certificate: %s\n", resultToString(vr).latin1());
|
||||||
|
|
||||||
|
printf("Let's try a GET request now.\n");
|
||||||
|
TQString req = "GET / HTTP/1.0\nHost: " + host + "\n\n";
|
||||||
|
TQCString cs = req.latin1();
|
||||||
|
TQByteArray buf(cs.length());
|
||||||
|
memcpy(buf.data(), cs.data(), buf.size());
|
||||||
|
ssl->write(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_readyRead()
|
||||||
|
{
|
||||||
|
TQByteArray a = ssl->read();
|
||||||
|
TQCString cs;
|
||||||
|
cs.resize(a.size()+1);
|
||||||
|
memcpy(cs.data(), a.data(), a.size());
|
||||||
|
printf("%s", cs.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_readyReadOutgoing(int)
|
||||||
|
{
|
||||||
|
TQByteArray a = ssl->readOutgoing();
|
||||||
|
sock->writeBlock(a.data(), a.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_closed()
|
||||||
|
{
|
||||||
|
printf("SSL session closed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_error(int x)
|
||||||
|
{
|
||||||
|
if(x == TQCA::TLS::ErrHandshake) {
|
||||||
|
printf("SSL Handshake Error!\n");
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("SSL Error!\n");
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TQString host;
|
||||||
|
TQSocket *sock;
|
||||||
|
TQCA::TLS *ssl;
|
||||||
|
TQCA::Cert cert;
|
||||||
|
TQPtrList<TQCA::Cert> rootCerts;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include"ssltest.moc"
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
TQApplication app(argc, argv, false);
|
||||||
|
TQString host = argc > 1 ? argv[1] : "andbit.net";
|
||||||
|
|
||||||
|
if(!TQCA::isSupported(TQCA::CAP_TLS)) {
|
||||||
|
printf("TLS not supported!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SecureTest *s = new SecureTest;
|
||||||
|
TQObject::connect(s, SIGNAL(quit()), &app, SLOT(quit()));
|
||||||
|
s->start(host);
|
||||||
|
app.exec();
|
||||||
|
delete s;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += thread console
|
||||||
|
TARGET = ssltest
|
||||||
|
|
||||||
|
INCLUDEPATH += ../common
|
||||||
|
HEADERS += ../common/base64.h
|
||||||
|
SOURCES += ../common/base64.cpp ssltest.cpp
|
||||||
|
include(../examples.pri)
|
@ -0,0 +1,33 @@
|
|||||||
|
# qca qmake profile
|
||||||
|
|
||||||
|
TEMPLATE = lib
|
||||||
|
CONFIG += qt thread release
|
||||||
|
TARGET = qca
|
||||||
|
|
||||||
|
MOC_DIR = .moc
|
||||||
|
OBJECTS_DIR = .obj
|
||||||
|
UI_DIR = .ui
|
||||||
|
|
||||||
|
VER_MAJ = 1
|
||||||
|
VER_MIN = 0
|
||||||
|
|
||||||
|
# make DLL
|
||||||
|
win32:{
|
||||||
|
CONFIG += dll
|
||||||
|
DEFINES += QCA_MAKEDLL
|
||||||
|
}
|
||||||
|
|
||||||
|
QCA_CPP = src
|
||||||
|
INCLUDEPATH += $$QCA_CPP
|
||||||
|
INCLUDEPATH += /usr/include/tqt
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$QCA_CPP/qca.h \
|
||||||
|
$$QCA_CPP/qcaprovider.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$QCA_CPP/qca.cpp
|
||||||
|
|
||||||
|
include(conf.pri)
|
||||||
|
include(extra.pri)
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
<qconf>
|
||||||
|
<name>Qt Cryptographic Architecture (QCA)</name>
|
||||||
|
<profile>qca.pro</profile>
|
||||||
|
<nobindir/>
|
||||||
|
</qconf>
|
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
cat >extra.pri <<EOT
|
||||||
|
target.path=$PREFIX/lib
|
||||||
|
INSTALLS += target
|
||||||
|
|
||||||
|
incfiles.path=$PREFIX/include
|
||||||
|
incfiles.files=src/qca.h
|
||||||
|
INSTALLS += incfiles
|
||||||
|
|
||||||
|
INSTALL_ROOT = $PREFIX
|
||||||
|
|
||||||
|
EOT
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,466 @@
|
|||||||
|
/*
|
||||||
|
* 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 TQCA_H
|
||||||
|
#define TQCA_H
|
||||||
|
|
||||||
|
#include<tqstring.h>
|
||||||
|
#include<tqcstring.h>
|
||||||
|
#include<tqdatetime.h>
|
||||||
|
#include<tqmap.h>
|
||||||
|
#include<tqptrlist.h>
|
||||||
|
#include<tqobject.h>
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
# ifndef TQCA_STATIC
|
||||||
|
# ifdef TQCA_MAKEDLL
|
||||||
|
# define TQCA_EXPORT __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define TQCA_EXPORT __declspec(dllimport)
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifndef TQCA_EXPORT
|
||||||
|
#define TQCA_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
# ifdef TQCA_PLUGIN_DLL
|
||||||
|
# define TQCA_PLUGIN_EXPORT extern "C" __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define TQCA_PLUGIN_EXPORT extern "C" __declspec(dllimport)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifndef TQCA_PLUGIN_EXPORT
|
||||||
|
#define TQCA_PLUGIN_EXPORT extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class TQHostAddress;
|
||||||
|
class TQStringList;
|
||||||
|
|
||||||
|
class TQCAProvider;
|
||||||
|
class TQCA_HashContext;
|
||||||
|
class TQCA_CipherContext;
|
||||||
|
class TQCA_CertContext;
|
||||||
|
|
||||||
|
namespace TQCA
|
||||||
|
{
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
TQCA_EXPORT void init();
|
||||||
|
TQCA_EXPORT bool isSupported(int capabilities);
|
||||||
|
TQCA_EXPORT void insertProvider(TQCAProvider *);
|
||||||
|
TQCA_EXPORT void unloadAllPlugins();
|
||||||
|
|
||||||
|
TQCA_EXPORT TQString arrayToHex(const TQByteArray &);
|
||||||
|
TQCA_EXPORT TQByteArray hexToArray(const TQString &);
|
||||||
|
|
||||||
|
class TQCA_EXPORT Hash
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Hash(const Hash &);
|
||||||
|
Hash & operator=(const Hash &);
|
||||||
|
~Hash();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
void update(const TQByteArray &a);
|
||||||
|
TQByteArray final();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Hash(TQCA_HashContext *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Private;
|
||||||
|
Private *d;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class TQCA_EXPORT HashStatic
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HashStatic<T>() {}
|
||||||
|
|
||||||
|
static TQByteArray hash(const TQByteArray &a)
|
||||||
|
{
|
||||||
|
T obj;
|
||||||
|
obj.update(a);
|
||||||
|
return obj.final();
|
||||||
|
}
|
||||||
|
|
||||||
|
static TQByteArray hash(const TQCString &cs)
|
||||||
|
{
|
||||||
|
TQByteArray a(cs.length());
|
||||||
|
memcpy(a.data(), cs.data(), a.size());
|
||||||
|
return hash(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TQString hashToString(const TQByteArray &a)
|
||||||
|
{
|
||||||
|
return arrayToHex(hash(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
static TQString hashToString(const TQCString &cs)
|
||||||
|
{
|
||||||
|
return arrayToHex(hash(cs));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_EXPORT Cipher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Cipher(const Cipher &);
|
||||||
|
Cipher & operator=(const Cipher &);
|
||||||
|
~Cipher();
|
||||||
|
|
||||||
|
TQByteArray dyn_generateKey(int size=-1) const;
|
||||||
|
TQByteArray dyn_generateIV() const;
|
||||||
|
void reset(int dir, int mode, const TQByteArray &key, const TQByteArray &iv, bool pad=true);
|
||||||
|
bool update(const TQByteArray &a);
|
||||||
|
TQByteArray final(bool *ok=0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Cipher(TQCA_CipherContext *, int dir, int mode, const TQByteArray &key, const TQByteArray &iv, bool pad);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Private;
|
||||||
|
Private *d;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class TQCA_EXPORT CipherStatic
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CipherStatic<T>() {}
|
||||||
|
|
||||||
|
static TQByteArray generateKey(int size=-1)
|
||||||
|
{
|
||||||
|
T obj;
|
||||||
|
return obj.dyn_generateKey(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TQByteArray generateIV()
|
||||||
|
{
|
||||||
|
T obj;
|
||||||
|
return obj.dyn_generateIV();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_EXPORT SHA1 : public Hash, public HashStatic<SHA1>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHA1();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_EXPORT SHA256 : public Hash, public HashStatic<SHA256>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHA256();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_EXPORT MD5 : public Hash, public HashStatic<MD5>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MD5();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_EXPORT BlowFish : public Cipher, public CipherStatic<BlowFish>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BlowFish(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true);
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_EXPORT TripleDES : public Cipher, public CipherStatic<TripleDES>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TripleDES(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true);
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_EXPORT AES128 : public Cipher, public CipherStatic<AES128>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AES128(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true);
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_EXPORT AES256 : public Cipher, public CipherStatic<AES256>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AES256(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true);
|
||||||
|
};
|
||||||
|
|
||||||
|
class RSA;
|
||||||
|
class TQCA_EXPORT RSAKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RSAKey();
|
||||||
|
RSAKey(const RSAKey &from);
|
||||||
|
RSAKey & operator=(const RSAKey &from);
|
||||||
|
~RSAKey();
|
||||||
|
|
||||||
|
bool isNull() const;
|
||||||
|
bool havePublic() const;
|
||||||
|
bool havePrivate() const;
|
||||||
|
|
||||||
|
TQByteArray toDER(bool publicOnly=false) const;
|
||||||
|
bool fromDER(const TQByteArray &a);
|
||||||
|
|
||||||
|
TQString toPEM(bool publicOnly=false) const;
|
||||||
|
bool fromPEM(const TQString &);
|
||||||
|
|
||||||
|
// 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 TQByteArray &a, TQByteArray *out, bool oaep) const;
|
||||||
|
bool decrypt(const TQByteArray &a, TQByteArray *out, bool oaep) const;
|
||||||
|
bool generate(unsigned int bits);
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_EXPORT RSA
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RSA();
|
||||||
|
~RSA();
|
||||||
|
|
||||||
|
RSAKey key() const;
|
||||||
|
void setKey(const RSAKey &);
|
||||||
|
|
||||||
|
bool encrypt(const TQByteArray &a, TQByteArray *out, bool oaep=false) const;
|
||||||
|
bool decrypt(const TQByteArray &a, TQByteArray *out, bool oaep=false) const;
|
||||||
|
|
||||||
|
static RSAKey generateKey(unsigned int bits);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RSAKey v_key;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef TQMap<TQString, TQString> CertProperties;
|
||||||
|
class TQCA_EXPORT Cert
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Cert();
|
||||||
|
Cert(const Cert &);
|
||||||
|
Cert & operator=(const Cert &);
|
||||||
|
~Cert();
|
||||||
|
|
||||||
|
bool isNull() const;
|
||||||
|
|
||||||
|
TQString commonName() const;
|
||||||
|
TQString serialNumber() const;
|
||||||
|
TQString subjectString() const;
|
||||||
|
TQString issuerString() const;
|
||||||
|
CertProperties subject() const;
|
||||||
|
CertProperties issuer() const;
|
||||||
|
TQDateTime notBefore() const;
|
||||||
|
TQDateTime notAfter() const;
|
||||||
|
|
||||||
|
TQByteArray toDER() const;
|
||||||
|
bool fromDER(const TQByteArray &a);
|
||||||
|
|
||||||
|
TQString toPEM() const;
|
||||||
|
bool fromPEM(const TQString &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Private;
|
||||||
|
Private *d;
|
||||||
|
|
||||||
|
friend class TLS;
|
||||||
|
void fromContext(TQCA_CertContext *);
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_EXPORT TLS : public TQObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum Validity {
|
||||||
|
NoCert,
|
||||||
|
Valid,
|
||||||
|
HostMismatch,
|
||||||
|
Rejected,
|
||||||
|
Untrusted,
|
||||||
|
SignatureFailed,
|
||||||
|
InvalidCA,
|
||||||
|
InvalidPurpose,
|
||||||
|
SelfSigned,
|
||||||
|
Revoked,
|
||||||
|
PathLengthExceeded,
|
||||||
|
Expired,
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
enum Error { ErrHandshake, ErrCrypt };
|
||||||
|
|
||||||
|
TLS(TQObject *parent=0);
|
||||||
|
~TLS();
|
||||||
|
|
||||||
|
void setCertificate(const Cert &cert, const RSAKey &key);
|
||||||
|
void setCertificateStore(const TQPtrList<Cert> &store); // note: store must persist
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
bool startClient(const TQString &host="");
|
||||||
|
bool startServer();
|
||||||
|
void close();
|
||||||
|
bool isHandshaken() const;
|
||||||
|
|
||||||
|
// plain (application side)
|
||||||
|
void write(const TQByteArray &a);
|
||||||
|
TQByteArray read();
|
||||||
|
|
||||||
|
// encoded (socket side)
|
||||||
|
void writeIncoming(const TQByteArray &a);
|
||||||
|
TQByteArray readOutgoing();
|
||||||
|
TQByteArray 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 TQCA_EXPORT SASL : public TQObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum Error { ErrAuth, ErrCrypt };
|
||||||
|
enum ErrorCond {
|
||||||
|
NoMech,
|
||||||
|
BadProto,
|
||||||
|
BadServ,
|
||||||
|
BadAuth,
|
||||||
|
NoAuthzid,
|
||||||
|
TooWeak,
|
||||||
|
NeedEncrypt,
|
||||||
|
Expired,
|
||||||
|
Disabled,
|
||||||
|
NoUser,
|
||||||
|
RemoteUnavail
|
||||||
|
};
|
||||||
|
SASL(TQObject *parent=0);
|
||||||
|
~SASL();
|
||||||
|
|
||||||
|
static void setAppName(const TQString &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 TQString &authid);
|
||||||
|
void setExternalSSF(int);
|
||||||
|
|
||||||
|
void setLocalAddr(const TQHostAddress &addr, TQ_UINT16 port);
|
||||||
|
void setRemoteAddr(const TQHostAddress &addr, TQ_UINT16 port);
|
||||||
|
|
||||||
|
// initialize
|
||||||
|
bool startClient(const TQString &service, const TQString &host, const TQStringList &mechlist, bool allowClientSendFirst=true);
|
||||||
|
bool startServer(const TQString &service, const TQString &host, const TQString &realm, TQStringList *mechlist);
|
||||||
|
|
||||||
|
// authentication
|
||||||
|
void putStep(const TQByteArray &stepData);
|
||||||
|
void putServerFirstStep(const TQString &mech);
|
||||||
|
void putServerFirstStep(const TQString &mech, const TQByteArray &clientInit);
|
||||||
|
void setUsername(const TQString &user);
|
||||||
|
void setAuthzid(const TQString &auth);
|
||||||
|
void setPassword(const TQString &pass);
|
||||||
|
void setRealm(const TQString &realm);
|
||||||
|
void continueAfterParams();
|
||||||
|
void continueAfterAuthCheck();
|
||||||
|
|
||||||
|
// security layer
|
||||||
|
int ssf() const;
|
||||||
|
void write(const TQByteArray &a);
|
||||||
|
TQByteArray read();
|
||||||
|
void writeIncoming(const TQByteArray &a);
|
||||||
|
TQByteArray readOutgoing();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// for authentication
|
||||||
|
void clientFirstStep(const TQString &mech, const TQByteArray *clientInit);
|
||||||
|
void nextStep(const TQByteArray &stepData);
|
||||||
|
void needParams(bool user, bool authzid, bool pass, bool realm);
|
||||||
|
void authCheck(const TQString &user, const TQString &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
|
@ -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 TQCAPROVIDER_H
|
||||||
|
#define TQCAPROVIDER_H
|
||||||
|
|
||||||
|
#include<tqglobal.h>
|
||||||
|
#include<tqstring.h>
|
||||||
|
#include<tqdatetime.h>
|
||||||
|
#include<tqobject.h>
|
||||||
|
#include<tqhostaddress.h>
|
||||||
|
#include"qca.h"
|
||||||
|
|
||||||
|
#define TQCA_PLUGIN_VERSION 1
|
||||||
|
|
||||||
|
class TQCAProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TQCAProvider() {}
|
||||||
|
virtual ~TQCAProvider() {}
|
||||||
|
|
||||||
|
virtual void init()=0;
|
||||||
|
virtual int qcaVersion() const=0;
|
||||||
|
virtual int capabilities() const=0;
|
||||||
|
virtual void *context(int cap)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_HashContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~TQCA_HashContext() {}
|
||||||
|
|
||||||
|
virtual TQCA_HashContext *clone()=0;
|
||||||
|
virtual void reset()=0;
|
||||||
|
virtual void update(const char *in, unsigned int len)=0;
|
||||||
|
virtual void final(TQByteArray *out)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_CipherContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~TQCA_CipherContext() {}
|
||||||
|
|
||||||
|
virtual TQCA_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(TQByteArray *out)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_RSAKeyContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~TQCA_RSAKeyContext() {}
|
||||||
|
|
||||||
|
virtual TQCA_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(TQByteArray *out, bool publicOnly)=0;
|
||||||
|
virtual bool toPEM(TQByteArray *out, bool publicOnly)=0;
|
||||||
|
|
||||||
|
virtual bool encrypt(const TQByteArray &in, TQByteArray *out, bool oaep)=0;
|
||||||
|
virtual bool decrypt(const TQByteArray &in, TQByteArray *out, bool oaep)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TQCA_CertProperty
|
||||||
|
{
|
||||||
|
TQString var;
|
||||||
|
TQString val;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_CertContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~TQCA_CertContext() {}
|
||||||
|
|
||||||
|
virtual TQCA_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(TQByteArray *out)=0;
|
||||||
|
virtual bool toPEM(TQByteArray *out)=0;
|
||||||
|
|
||||||
|
virtual TQString serialNumber() const=0;
|
||||||
|
virtual TQString subjectString() const=0;
|
||||||
|
virtual TQString issuerString() const=0;
|
||||||
|
virtual TQValueList<TQCA_CertProperty> subject() const=0;
|
||||||
|
virtual TQValueList<TQCA_CertProperty> issuer() const=0;
|
||||||
|
virtual TQDateTime notBefore() const=0;
|
||||||
|
virtual TQDateTime notAfter() const=0;
|
||||||
|
virtual bool matchesAddress(const TQString &realHost) const=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_TLSContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Result { Success, Error, Continue };
|
||||||
|
virtual ~TQCA_TLSContext() {}
|
||||||
|
|
||||||
|
virtual void reset()=0;
|
||||||
|
virtual bool startClient(const TQPtrList<TQCA_CertContext> &store, const TQCA_CertContext &cert, const TQCA_RSAKeyContext &key)=0;
|
||||||
|
virtual bool startServer(const TQPtrList<TQCA_CertContext> &store, const TQCA_CertContext &cert, const TQCA_RSAKeyContext &key)=0;
|
||||||
|
|
||||||
|
virtual int handshake(const TQByteArray &in, TQByteArray *out)=0;
|
||||||
|
virtual int shutdown(const TQByteArray &in, TQByteArray *out)=0;
|
||||||
|
virtual bool encode(const TQByteArray &plain, TQByteArray *to_net, int *encoded)=0;
|
||||||
|
virtual bool decode(const TQByteArray &from_net, TQByteArray *plain, TQByteArray *to_net)=0;
|
||||||
|
virtual bool eof() const=0;
|
||||||
|
virtual TQByteArray unprocessed()=0;
|
||||||
|
|
||||||
|
virtual TQCA_CertContext *peerCertificate() const=0;
|
||||||
|
virtual int validityResult() const=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TQCA_SASLHostPort
|
||||||
|
{
|
||||||
|
TQHostAddress addr;
|
||||||
|
Q_UINT16 port;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TQCA_SASLNeedParams
|
||||||
|
{
|
||||||
|
bool user, authzid, pass, realm;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQCA_SASLContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Result { Success, Error, NeedParams, AuthCheck, Continue };
|
||||||
|
virtual ~TQCA_SASLContext() {}
|
||||||
|
|
||||||
|
// common
|
||||||
|
virtual void reset()=0;
|
||||||
|
virtual void setCoreProps(const TQString &service, const TQString &host, TQCA_SASLHostPort *local, TQCA_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 TQString &_ext_authid, int _ext_ssf)=0;
|
||||||
|
virtual int security() const=0;
|
||||||
|
virtual int errorCond() const=0;
|
||||||
|
|
||||||
|
// init / first step
|
||||||
|
virtual bool clientStart(const TQStringList &mechlist)=0;
|
||||||
|
virtual int clientFirstStep(bool allowClientSendFirst)=0;
|
||||||
|
virtual bool serverStart(const TQString &realm, TQStringList *mechlist, const TQString &name)=0;
|
||||||
|
virtual int serverFirstStep(const TQString &mech, const TQByteArray *in)=0;
|
||||||
|
|
||||||
|
// get / set params
|
||||||
|
virtual TQCA_SASLNeedParams clientParamsNeeded() const=0;
|
||||||
|
virtual void setClientParams(const TQString *user, const TQString *authzid, const TQString *pass, const TQString *realm)=0;
|
||||||
|
virtual TQString username() const=0;
|
||||||
|
virtual TQString authzid() const=0;
|
||||||
|
|
||||||
|
// continue steps
|
||||||
|
virtual int nextStep(const TQByteArray &in)=0;
|
||||||
|
virtual int tryAgain()=0;
|
||||||
|
|
||||||
|
// results
|
||||||
|
virtual TQString mech() const=0;
|
||||||
|
virtual const TQByteArray *clientInit() const=0;
|
||||||
|
virtual TQByteArray result() const=0;
|
||||||
|
|
||||||
|
// security layer
|
||||||
|
virtual bool encode(const TQByteArray &in, TQByteArray *out)=0;
|
||||||
|
virtual bool decode(const TQByteArray &in, TQByteArray *out)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in new issue