initial commit

This commit is contained in:
mikhail "synzr" 2025-12-25 01:37:49 +05:00
commit 9d20827c46
2469 changed files with 470994 additions and 0 deletions

32
third-party/JsonQt/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,32 @@
PROJECT(JsonQt)
# Stop cmake 2.6 from whining
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
IF(COMMAND cmake_policy)
CMAKE_POLICY(SET CMP0003 NEW)
ENDIF(COMMAND cmake_policy)
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR})
# If building for release, don't include QDebug stuff
IF("x${CMAKE_BUILD_TYPE}" STREQUAL "x")
SET(CMAKE_BUILD_TYPE "Release")
ENDIF()
IF("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
ADD_DEFINITIONS("-DQT_NO_DEBUG_OUTPUT")
ELSE()
IF(${CMAKE_COMPILER_IS_GNUCXX})
ADD_DEFINITIONS("-Wall -Werror")
ENDIF()
ENDIF()
# Docs
CONFIGURE_FILE(Doxyfile.cmake Doxyfile)
ADD_CUSTOM_TARGET(doc doxygen)
# Subdirs
ADD_SUBDIRECTORY(lib)
IF("${BUILD_TESTS}" STREQUAL "")
OPTION(BUILD_TESTS "Build tests" ON)
ENDIF()
IF(BUILD_TESTS)
ADD_SUBDIRECTORY(tests)
ENDIF()

11
third-party/JsonQt/COMPATIBILITY vendored Normal file
View file

@ -0,0 +1,11 @@
The 0.1.0 API is aimed to be the 1.0.0 API.
From 1.0.0, JsonQt will follow the normal standards for API and ABI
compatability between versions:
- Anything built against a specific version should work with any later version
with the same major version; for example, something built against 1.0.0
should work with 1.1.0.
- New features that don't break backwards compatability will result in a bump of
the minor version; this should mean that anything built against version
a.b.c will work with any a.b.* version.

13
third-party/JsonQt/COPYING.HEADER vendored Normal file
View file

@ -0,0 +1,13 @@
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

299
third-party/JsonQt/Doxyfile.cmake vendored Normal file
View file

@ -0,0 +1,299 @@
# Doxyfile 1.5.5
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = JsonQt
PROJECT_NUMBER =
OUTPUT_DIRECTORY = doc
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
TYPEDEF_HIDES_STRUCT = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ${CMAKE_SOURCE_DIR}/lib/ \
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.d \
*.java \
*.ii \
*.ixx \
*.ipp \
*.i++ \
*.inl \
*.h \
*.hh \
*.hxx \
*.hpp \
*.h++ \
*.idl \
*.odl \
*.cs \
*.php \
*.php3 \
*.inc \
*.m \
*.mm \
*.dox \
*.py \
*.f90 \
*.f \
*.vhd \
*.vhdl \
*.C \
*.CC \
*.C++ \
*.II \
*.I++ \
*.H \
*.HH \
*.H++ \
*.CS \
*.PHP \
*.PHP3 \
*.M \
*.MM \
*.PY \
*.F90 \
*.F \
*.VHD \
*.VHDL
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = *_p.h \
*_p.cpp \
${CMAKE_SOURCE_DIR}/src/plugins
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
HTML_DYNAMIC_SECTIONS = YES
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = YES
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = YES
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO

View file

@ -0,0 +1,13 @@
#!/bin/sh
NOTICE_HEADER="/* LICENSE NOTICE"
TMPFILE=$(mktemp)
for file in $(find -name *.cpp -o -name *.h); do
if ! grep -q "$NOTICE_HEADER" "$file"; then
echo "$NOTICE_HEADER" > $TMPFILE
cat COPYING.HEADER >> $TMPFILE
echo "*/" >> $TMPFILE
cat "$file" >> $TMPFILE
cat $TMPFILE > "$file"
fi
done
rm $TMPFILE

21
third-party/JsonQt/jsonqt.pri vendored Normal file
View file

@ -0,0 +1,21 @@
HEADERS += \
$$PWD/lib/JsonQtExport.h \
$$PWD/lib/JsonRpc.h \
$$PWD/lib/JsonRpcAdaptor.h \
$$PWD/lib/JsonRpcAdaptorPrivate.h \
$$PWD/lib/JsonToProperties.h \
$$PWD/lib/JsonToVariant.h \
$$PWD/lib/ParseException.h \
$$PWD/lib/VariantToJson.h
SOURCES += \
$$PWD/lib/JsonRpc.cpp \
$$PWD/lib/JsonRpcAdaptor.cpp \
$$PWD/lib/JsonRpcAdaptorPrivate.cpp \
$$PWD/lib/JsonToProperties.cpp \
$$PWD/lib/JsonToVariant.cpp \
$$PWD/lib/ParseException.cpp \
$$PWD/lib/VariantToJson.cpp
INCLUDEPATH += $$PWD/lib
DEPENDPATH += $$PWD/lib

76
third-party/JsonQt/lib/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,76 @@
SET(
CLASSES
ParseException
JsonRpc
JsonRpcAdaptor
JsonRpcAdaptorPrivate
JsonToProperties
JsonToVariant
VariantToJson
)
SET(HEADERS JsonQtExport.h)
SET(VERSION 0.1.0)
##### Probably don't want to edit below this line #####
# Find Qt4
FIND_PACKAGE( Qt4 REQUIRED )
SET( QT_DONT_USE_QTGUI TRUE )
# Include the cmake file needed to use qt4
INCLUDE( ${QT_USE_FILE} )
# Include the binary directory for moc files.
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
FOREACH(class ${CLASSES})
QT4_WRAP_CPP(MOC_SOURCE ${class}.h)
SET(SOURCES ${SOURCES} ${class}.cpp ${MOC_SOURCE})
SET(HEADERS ${HEADERS} ${class}.h)
ENDFOREACH()
SET(SOURCES ${SOURCES} ${MOC_SOURCE})
IF("${STATIC_JSONQT}" STREQUAL "")
OPTION(STATIC_JSONQT "Build static libraries of JsonQt instead of shared" OFF)
ENDIF()
IF(STATIC_JSONQT)
SET(BUILD STATIC)
ELSE()
SET(BUILD SHARED)
ENDIF()
MESSAGE(STATUS "Building ${BUILD} JsonQt")
ADD_LIBRARY(
JsonQt
${BUILD}
${SOURCES}
)
SET_TARGET_PROPERTIES(
JsonQt
PROPERTIES
VERSION "${VERSION}"
SOVERSION "0"
)
TARGET_LINK_LIBRARIES(
JsonQt
${QT_LIBRARIES}
)
INSTALL(
TARGETS
JsonQt
DESTINATION
lib${LIB_SUFFIX}
)
INSTALL(
FILES
${HEADERS}
DESTINATION
include/JsonQt
)

24
third-party/JsonQt/lib/JsonQtExport.h vendored Normal file
View file

@ -0,0 +1,24 @@
/* LICENSE NOTICE
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _JSONQT_EXPORT_H
#define _JSONQT_EXPORT_H
#include <QtGlobal>
#define JSONQT_EXPORT Q_DECL_EXPORT
#endif

167
third-party/JsonQt/lib/JsonRpc.cpp vendored Normal file
View file

@ -0,0 +1,167 @@
#include "JsonRpc.h"
#include "JsonToVariant.h"
#include "VariantToJson.h"
#include <QDebug>
namespace JsonQt
{
JsonRpc::JsonRpc(QObject* parent) : QObject(parent) {}
void JsonRpc::sendRequest(const QVariant& id, const QString& method, const QVariant& parameters)
{
Q_ASSERT(parameters.type() == QVariant::List || parameters.type() == QVariant::Map || parameters.isNull());
QVariantMap request;
request["jsonrpc"] = "2.0";
request["method"] = method;
request["id"] = id;
if(!parameters.isNull())
{
request["params"] = parameters;
}
emit sendJson(VariantToJson::parse(request));
}
void JsonRpc::sendNotification(const QString& method, const QVariant& parameters)
{
Q_ASSERT(parameters.type() == QVariant::List || parameters.type() == QVariant::Map || parameters.isNull());
QVariantMap request;
request["jsonrpc"] = "2.0";
request["method"] = method;
// no ID for notifications.
if(!parameters.isNull())
{
request["params"] = parameters;
}
emit sendJson(VariantToJson::parse(request));
}
void JsonRpc::sendResponse(const QVariant& id, const QVariant& result)
{
QVariantMap response;
response["jsonrpc"] = "2.0";
response["id"] = id;
response["result"] = result;
emit sendJson(VariantToJson::parse(response));
}
void JsonRpc::sendError(const QVariant& id, int errorCode, const QString& message, const QVariant& data)
{
QVariantMap error;
error["code"] = errorCode;
error["message"] = message;
error["data"] = data;
QVariantMap response;
response["jsonrpc"] = "2.0";
response["id"] = id;
response["error"] = error;
emit sendJson(VariantToJson::parse(response));
}
void JsonRpc::processJson(const QString& json)
{
QList<QVariantMap> objects;
try
{
objects = JsonToVariant::multiParse(json);
}
catch(ParseException)
{
sendError(QVariant(), InvalidJson, "Parse error.");
return;
}
Q_FOREACH(const QVariantMap& object, objects)
{
if(object.value("jsonrpc").toString() != "2.0")
{
sendError(object.value("id"), InvalidJsonRpc, "JSON-RPC version not specified or not supported.", object);
continue;
}
// Notification or request
if(object.contains("method"))
{
if(object.value("method").type() != QVariant::String)
{
sendError(object.value("id"), InvalidJsonRpc, "'method' member of request must be a string.", object);
continue;
}
QString method = object.value("method").toString();
QVariant parameters = object.value("params");
if(parameters.isNull()) parameters = QVariantList();
if(parameters.type() != QVariant::List && parameters.type() != QVariant::Map)
{
sendError(object.value("id"), InvalidJsonRpc, "'parameters' member of request must be omitted, a list, or an object.", object);
continue;
}
// Request or notification
if(object.contains("id"))
{
emit requestReceived(object.value("id"), method, parameters);
}
else
{
emit notificationReceived(method, parameters);
}
continue;
}
// Request successful
if(object.contains("result"))
{
if(!object.contains("id"))
{
sendError(QVariant(), InvalidJsonRpc, "ID not specified in response.", object);
continue;
}
emit responseReceived(object.value("id"), object.value("result"));
continue;
}
// Request failed
if(object.contains("error"))
{
if(!object.contains("id"))
{
sendError(QVariant(), InvalidJsonRpc, "ID not specified in response.", object);
continue;
}
if(object.value("error").type() != QVariant::Map)
{
sendError(object.value("id"), InvalidJsonRpc, "'error' member is not an Error object.", object);
continue;
}
QVariantMap error = object.value("error").toMap();
if(error.value("code").type() != QVariant::Int)
{
sendError(object.value("id"), InvalidJsonRpc, "'code' member of error object is not an integer.", object);
continue;
}
if(error.value("message").type() != QVariant::String)
{
sendError(object.value("id"), InvalidJsonRpc, "'message' member of error object is not a string.", object);
continue;
}
emit errorReceived(object.value("id"), error.value("code").toInt(), error.value("message").toString(), error.value("data"));
continue;
}
// Not a notification, request, or response
sendError(object.value("id"), InvalidJsonRpc, "JSON object doesn't appear to be a JSON-RPC request, notification, or response.", object);
}
}
};

105
third-party/JsonQt/lib/JsonRpc.h vendored Normal file
View file

@ -0,0 +1,105 @@
#ifndef _JSONQT_JSON_RPC_H
#define _JSONQT_JSON_RPC_H
#include "JsonQtExport.h"
#include <QObject>
#include <QVariant>
namespace JsonQt
{
/** Class implementing JSON-RPC.
*
* This implements the JSON-RPC 2.0 proposal, as of 2008-11-15, located
* at http://groups.google.com/group/json-rpc/web/json-rpc-1-2-proposal.
*
* While 1.1 is more popular for web services, 2.0 is a much simpler
* protocol, and is not restricted to HTTP requests.
*
* Note that 'parameter' QVariant objects must be either null QVariants,
* contain a QVariantList, or a QVariantMap. If a QVariantList is used,
* it must be a list of all the parameters the method takes, in the
* correct order. If a QVariantMap is used, the keys must be strings
* exactly matching the parameter names of the method (case-sensitive).
*
* There are two IO members:
* - processJson - slot - parse the JSON string given, and act upon it
* - sendJson - signal - an action that an instance of JsonRpc has been
* told to do requires that the specified JSON be sent to the other
* peer.
*
* All other members are interfaces to JSON-RPC.
*
* 'id' parameters SHOULD NOT be NULL, for reasons defined in the
* specification. Also, it SHOULD be a scalar.
*
* @author Fred Emmott <mail@fredemmott.co.uk>
*/
class JSONQT_EXPORT JsonRpc : public QObject
{
Q_OBJECT
public:
Q_ENUMS(ErrorCode);
/** List of standard JSON-RPC error codes.
* All error codes between ServerErrorLow and
* ServerErrorHigh are reserved for
* implementation-defined server errors.
*
* All codes between -32768 and -32000 are reserved
* either for the definitions below, or for future use.
*
* Other values may be used.
*
* InvalidJson and InvalidJsonRpc should only
* be used internally by this class.
*
*/
enum ErrorCode
{
InvalidJson = -32700,
InvalidJsonRpc = -32600,
MethodNotFound = -32601,
BadParameters = -32602,
InternalError = -32603,
ServerErrorLow = -32099,
ServerErrorHigh = -32000
};
/// Construct a JsonRpc object.
JsonRpc(QObject* parent = NULL);
/// Send a request, expecting a response.
void sendRequest(const QVariant& id, const QString& method, const QVariant& parameters = QVariant());
/// Send a request, not expecting a response.
void sendNotification(const QString& method, const QVariant& parameters = QVariant());
/// Respond to a request with success.
void sendResponse(const QVariant& id, const QVariant& result = QVariant());
/// Respond to a request with an error.
void sendError(const QVariant& id, int errorCode, const QString& message, const QVariant& data = QVariant());
public slots:
/** Process a received JSON string, and emit the
* appropriate signals.
*/
void processJson(const QString& json);
signals:
/** Emitted when JsonRpc needs to send some JSON to the
* other peer.
*/
void sendJson(const QString& json);
/** A notification has been received from the other peer.
* No reponse is neccessary.
*/
void notificationReceived(const QString& method, const QVariant& parameters);
/** A request has been received from the other peer.
* A response (with the same id) is required.
*/
void requestReceived(const QVariant& id, const QString& method, const QVariant& parameters);
/// A successful response has been received from the other peer.
void responseReceived(const QVariant& id, const QVariant& result);
/// An error has been recevied from the other peer.
void errorReceived(const QVariant& id, int errorCode, const QString& message, const QVariant& data);
};
};
#endif

View file

@ -0,0 +1,19 @@
#include "JsonRpcAdaptor.h"
#include "JsonRpcAdaptorPrivate.h"
namespace JsonQt
{
JsonRpcAdaptor::JsonRpcAdaptor(QObject* adapt, QObject* parent)
:
QObject(parent),
d(new JsonRpcAdaptorPrivate(adapt, this))
{
connect(d, SIGNAL(sendJson(const QString&)), this, SIGNAL(sendJson(const QString&)));
}
void JsonRpcAdaptor::processJson(const QString& json)
{
d->processJson(json);
}
};

69
third-party/JsonQt/lib/JsonRpcAdaptor.h vendored Normal file
View file

@ -0,0 +1,69 @@
#ifndef _JSONQT_JSON_RPC_ADAPTOR_H
#define _JSONQT_JSON_RPC_ADAPTOR_H
#include "JsonQtExport.h"
#include <QObject>
namespace JsonQt
{
class JsonRpcAdaptorPrivate;
/** Class exporting a QObject's public slots via JSON-RPC.
*
* This implements the JSON-RPC 2.0 proposal, as of 2008-11-15, located
* at http://groups.google.com/group/json-rpc/web/json-rpc-1-2-proposal.
*
* It also implements the introspection functionality of JSON-RPC 1.1.
*
* There are several Q_CLASSINFO declarations that this adaptor will pay
* attention to:
*
* - JsonQt-RPC-id: *REQUIRED*. This is the only required parameter; it
* specifies a unique identifier for this service, in the format
* described by RFC 3986.
*
* - JsonQt-RPC-name: the name of the service provided by the QObject.
* If this is not specified, the class name will be used.
*
* - JsonQt-RPC-version: the version of the service provided by the QObject.
* If this is omitted, it will be omitted from the introspection data.
*
* - JsonQt-RPC-summary: A short description of this service. If this
* is omitted, it will be omitted from the introspection data.
*
* - JsonQt-RPC-help: An URL pointing to human-readable documentation
* about the service. If this is omitted, it will be omitted from the
* introspection data.
*
* The following types are supported for parameters and return values:
* - void return
* - bool
* - int
* - QString
* - QVariantList (which can contain any types supported by JsonQt)
* - QVariantMap (which can contain any types supported by JsonQt)
*
* @author Fred Emmott <mail@fredemmott.co.uk>
*/
class JSONQT_EXPORT JsonRpcAdaptor : public QObject
{
Q_OBJECT
public:
/** Construct a JsonRpcAdaptor.
* This will expose @param adapt via JSON.
*/
JsonRpcAdaptor(QObject* adapt, QObject* parent = NULL);
public slots:
/// Handle received JSON.
void processJson(const QString& json);
signals:
/** When this is emitted, the JSON provided should be
* sent to the peer.
*/
void sendJson(const QString& json);
private:
JsonRpcAdaptorPrivate* d;
};
};
#endif

View file

@ -0,0 +1,351 @@
#include "JsonRpcAdaptorPrivate.h"
#include "VariantToJson.h"
#include <QDebug>
#include <QGenericArgument>
#include <QMetaClassInfo>
#include <QMetaObject>
namespace JsonQt
{
JsonRpcAdaptorPrivate::JsonRpcAdaptorPrivate(QObject* adapt, QObject* parent) : QObject(parent)
{
m_adapted = adapt;
connect(
&m_jsonRpc,
SIGNAL(sendJson(const QString&)),
this,
SIGNAL(sendJson(const QString&))
);
connect(
&m_jsonRpc,
SIGNAL(requestReceived(const QVariant&, const QString&, const QVariant&)),
this,
SLOT(requestReceived(const QVariant&, const QString&, const QVariant&))
);
populateServiceDescription();
}
void JsonRpcAdaptorPrivate::populateServiceDescription()
{
m_serviceDescription.clear();
const QMetaObject* metaObject = m_adapted->metaObject();
QString id = getClassInfo("JsonQt-RPC-id");
Q_ASSERT(!id.isEmpty());
m_serviceDescription["id"] = id;
m_serviceDescription["sdversion"] = "1.0";
QString name = getClassInfo("JsonQt-RPC-name");
if(name.isEmpty()) name = metaObject->className();
m_serviceDescription["name"] = name;
QString version = getClassInfo("JsonQt-RPC-version");
if(!version.isNull()) m_serviceDescription["version"] = version;
QString summary = getClassInfo("JsonQt-RPC-summary");
if(!summary.isNull()) m_serviceDescription["summary"] = summary;
QString help = getClassInfo("JsonQt-RPC-help");
if(!help.isNull()) m_serviceDescription["help"] = help;
QMap<QString, QString> typeMap;
typeMap[""] = "nil"; // void
typeMap["bool"] = "bit";
typeMap["int"] = "num";
typeMap["QString"] = "str";
// typeMap["QVariant"] = "any"; // not supported
typeMap["QVariantList"] = "arr";
typeMap["QVariantMap"] = "obj";
QVariantList procs;
for(int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i)
{
QMetaMethod method = metaObject->method(i);
// Check we should export it
if(method.access() != QMetaMethod::Public || method.methodType() != QMetaMethod::Slot) continue;
QVariantMap proc;
QString signature = method.signature();
// Name
QString methodName = signature.left(signature.indexOf('('));
proc["name"] = methodName;
// Return type
if(!typeMap.contains(method.typeName()))
{
qDebug() << "Public slot" << signature << "has unknown return type" << method.typeName();
continue;
}
proc["return"] = typeMap.value(method.typeName());
// Parameters
QVariantList parameters;
bool badParameter = false;
for(int i = 0; i < method.parameterNames().count(); ++i)
{
QVariantMap parameter;
QString parameterName(method.parameterNames().at(i));
parameter["name"] = parameterName;
QString parameterType = method.parameterTypes().at(i);
if(!typeMap.contains(method.parameterTypes().at(i)))
{
qDebug() << "Public slot" << signature << "has parameter" << parameterName << "with unknown type" << parameterType;
badParameter = true;
continue;
}
parameter["type"] = typeMap.value(parameterType);
parameters.append(parameter);
m_parameterIndices[methodName].insert(parameterName, i);
}
if(badParameter) continue;
m_methods.insert(methodName, method);
proc["params"] = parameters;
// Done
procs.append(proc);
}
m_serviceDescription["procs"] = procs;
}
QString JsonRpcAdaptorPrivate::getClassInfo(const char* name)
{
const QMetaObject* metaObject = m_adapted->metaObject();
int index = metaObject->indexOfClassInfo(name);
if(index == -1) return QString();
return metaObject->classInfo(index).value();
}
void JsonRpcAdaptorPrivate::requestReceived(const QVariant& id, const QString& method, const QVariant& parameters)
{
if(method == "system.describe")
{
m_jsonRpc.sendResponse(id, m_serviceDescription);
return;
}
ReturnData result = invokeMethod(method, parameters);
if(result.succeeded)
{
m_jsonRpc.sendResponse(id, result.data);
}
else
{
m_jsonRpc.sendError(id, result.code, result.message, result.data);
}
}
JsonRpcAdaptorPrivate::ReturnData JsonRpcAdaptorPrivate::invokeMethod(const QString& methodName, const QVariant& parameters)
{
ReturnData ret;
ret.succeeded = false;
if(!m_methods.contains(methodName))
{
ret.code = JsonRpc::MethodNotFound;
ret.message = QString("The method %1 does not exist.").arg(methodName);
return ret;
}
QMetaMethod metaMethod(m_methods.value(methodName));
int parameterCount;
QVariantList parameterList;
switch(parameters.type())
{
case QVariant::List:
parameterList = parameters.toList();
parameterCount = parameterList.count();
break;
case QVariant::Map:
parameterCount = parameters.toMap().count();
for(int i = 0; i < parameterCount; ++i)
{
parameterList.append(QVariant());
}
break;
default:
parameterCount = 0;
}
Q_ASSERT(parameterCount <= 9);
ret.code = JsonRpc::BadParameters;
if(parameterCount != metaMethod.parameterNames().count())
{
ret.message = "Parameter count mismatch.";
return ret;
}
if(parameters.type() == QVariant::Map)
{
QMap<QString, int> parameterIndices = m_parameterIndices.value(methodName);
QVariantMap parameterMap = parameters.toMap();
for(QVariantMap::ConstIterator it = parameterMap.constBegin(); it != parameterMap.constEnd(); ++it)
{
if(!parameterIndices.contains(it.key()))
{
ret.message = QString("'%1' is not a parameter of method '%2'.").arg(it.key()).arg(methodName);
return ret;
}
int index = parameterIndices.value(it.key());
Q_ASSERT(index < parameterCount);
parameterList[index] = it.value();
}
}
QMap<QString, QVariant::Type> typeMap;
typeMap[""] = QVariant::Invalid;
typeMap["bool"] = QVariant::Bool;
typeMap["int"] = QVariant::Int;
typeMap["QString"] = QVariant::String;
typeMap["QVariantList"] = QVariant::List;
typeMap["QVariantMap"] = QVariant::Map;
///@todo more types
QVariant::Type returnType = typeMap.value(metaMethod.typeName());
// QMetaObject::invokeMethod takes 9 generic arguments
QGenericArgument arguments[9];
for(int i = 0; i < parameterCount; ++i)
{
const QVariant& value = parameterList.value(i);
if(typeMap.value(metaMethod.parameterTypes().at(i)) != value.type())
{
ret.message = QString("Value for parameter %1 was not of the correct type.").arg(QString(metaMethod.parameterNames().at(i)));
return ret;
}
void* data = 0;
switch(value.type())
{
case QVariant::Bool:
data = new bool(value.toBool());
arguments[i] = Q_ARG(bool, *static_cast<bool*>(data));
break;
case QVariant::Int:
data = new int(value.toInt());
arguments[i] = Q_ARG(int, *static_cast<int*>(data));
break;
case QVariant::String:
data = new QString(value.toString());
arguments[i] = Q_ARG(QString, *static_cast<QString*>(data));
break;
case QVariant::List:
data = new QVariantList(value.toList());
arguments[i] = Q_ARG(QVariantList, *static_cast<QVariantList*>(data));
break;
case QVariant::Map:
data = new QVariantMap(value.toMap());
arguments[i] = Q_ARG(QVariantMap, *static_cast<QVariantMap*>(data));
break;
default:
break;
}
}
QGenericReturnArgument returnValue;
switch(returnType)
{
case QVariant::Bool:
returnValue = Q_RETURN_ARG(bool, *(new bool));
break;
case QVariant::Int:
returnValue = Q_RETURN_ARG(int, *(new int));
break;
case QVariant::String:
returnValue = Q_RETURN_ARG(QString, *(new QString));
break;
case QVariant::List:
returnValue = Q_RETURN_ARG(QVariantList, *(new QVariantList));
break;
case QVariant::Map:
returnValue = Q_RETURN_ARG(QVariantMap, *(new QVariantMap));
break;
default:
break;
}
bool success = m_adapted->metaObject()->invokeMethod(
m_adapted,
methodName.toLatin1().constData(),
Qt::DirectConnection,
returnValue,
arguments[0],
arguments[1],
arguments[2],
arguments[3],
arguments[4],
arguments[5],
arguments[6],
arguments[7],
arguments[8],
arguments[9]
);
// clean up memory allocation
for(int i = 0; i < parameterCount; ++i)
{
QVariant::Type parameterType = parameterList.value(i).type();
switch(parameterType)
{
case QVariant::Bool:
delete static_cast<bool*>(arguments[i].data());
break;
case QVariant::Int:
delete static_cast<int*>(arguments[i].data());
break;
case QVariant::String:
delete static_cast<QString*>(arguments[i].data());
break;
case QVariant::List:
delete static_cast<QVariantList*>(arguments[i].data());
break;
case QVariant::Map:
delete static_cast<QVariantMap*>(arguments[i].data());
break;
default:
break;
}
}
if(success == false)
{
ret.code = JsonRpc::InternalError;
ret.message = "Could not execute method.";
return ret;
}
ret.succeeded = true;
switch(returnType)
{
case QVariant::Bool:
ret.data = *static_cast<bool*>(returnValue.data());
break;
case QVariant::Int:
ret.data = *static_cast<int*>(returnValue.data());
break;
case QVariant::String:
ret.data = *static_cast<QString*>(returnValue.data());
break;
case QVariant::List:
ret.data = *static_cast<QVariantList*>(returnValue.data());
break;
case QVariant::Map:
ret.data = *static_cast<QVariantMap*>(returnValue.data());
break;
default:
break;
}
return ret;
}
void JsonRpcAdaptorPrivate::processJson(const QString& json)
{
m_jsonRpc.processJson(json);
}
}

View file

@ -0,0 +1,44 @@
#ifndef _JSONQT_JSON_RPC_ADAPTOR_PRIVATE_H
#define _JSONQT_JSON_RPC_ADAPTOR_PRIVATE_H
#include "JsonRpc.h"
#include <QMetaMethod>
#include <QObject>
#include <QStringList>
namespace JsonQt
{
class JsonRpcAdaptorPrivate : public QObject
{
Q_OBJECT
public:
JsonRpcAdaptorPrivate(QObject* adapt, QObject* parent);
signals:
void sendJson(const QString& json);
public slots:
void processJson(const QString& json);
private slots:
void requestReceived(const QVariant& id, const QString& method, const QVariant& parameters);
private:
struct ReturnData
{
bool succeeded;
int code;
QString message;
QVariant data;
};
void populateServiceDescription();
QString getClassInfo(const char* name);
ReturnData invokeMethod(const QString& method, const QVariant& parameters);
QMap<QString, QMetaMethod> m_methods;
QMap<QString, QMap<QString, int> > m_parameterIndices;
QVariantMap m_serviceDescription;
JsonRpc m_jsonRpc;
QObject* m_adapted;
};
}
#endif

View file

@ -0,0 +1,53 @@
/* LICENSE NOTICE
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "JsonToProperties.h"
#include "JsonToVariant.h"
#include <QDebug>
#include <QMetaObject>
#include <QMetaProperty>
namespace JsonQt
{
JsonToProperties::JsonToProperties()
{
}
void JsonToProperties::parse(const QString& json, QObject* object)
throw(ParseException)
{
QVariantMap dataMap = JsonToVariant::parse(json).toMap();
const QMetaObject* meta = object->metaObject();
for(
int i = 0;
i < meta->propertyCount();
++i
)
{
QMetaProperty property = meta->property(i);
if(dataMap.contains(property.name()))
{
QVariant data = dataMap[property.name()];
if(data.canConvert(property.type()))
property.write(object, data);
else
qDebug() << QObject::tr("Found property %1 with incompatible data type.").arg(property.name());
}
}
}
};

View file

@ -0,0 +1,52 @@
/* LICENSE NOTICE
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _JSONQT_JSON_TO_PROPERTIES_H
#define _JSONQT_JSON_TO_PROPERTIES_H
#include "ParseException.h"
#include "JsonQtExport.h"
#include <QObject>
#include <QString>
namespace JsonQt
{
/** Class for setting the properties of a QObject from a JSON string.
* Note that this only pays attention to basic types in the top level
* object in the JSON.
*
* @author Fred Emmott <mail@fredemmott.co.uk>
*/
class JSONQT_EXPORT JsonToProperties
{
public:
/** Main parsing function.
*
* @param json is a string containing JSON text.
* @param object is an object with properties to be
* filled from JSON.
* @throws ParseException if the string provided is not
* valid JSON (or at least this parser thinks it
* isn't ;) )
*/
static void parse(const QString& json, QObject* object)
throw(ParseException);
private:
JsonToProperties();
};
}
#endif

606
third-party/JsonQt/lib/JsonToVariant.cpp vendored Normal file
View file

@ -0,0 +1,606 @@
/* LICENSE NOTICE
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "JsonToVariant.h"
#include <QDebug>
#define FAIL(x) throw ParseException(*m_sym, x, remaining())
namespace JsonQt
{
JsonToVariant::JsonToVariant(){}
QVariant JsonToVariant::parse(const QString& json) throw(ParseException)
{
JsonToVariant parser;
// Store the start and end of the string
parser.m_next = json.constBegin();
parser.m_sym = parser.m_next;
parser.m_end = json.constEnd();
// Parse any JSON value.
return parser.parseValue();
}
QList<QVariantMap> JsonToVariant::multiParse(const QString& raw) throw(ParseException)
{
QList<QVariantMap> objects;
QString json(raw.trimmed());
JsonToVariant parser;
// Store the start and end of the string
parser.m_next = json.constBegin();
parser.m_sym = parser.m_next;
parser.m_end = json.constEnd();
// A JSON Object is the top-level item in the parse tree
do
{
objects.append(parser.parseObject());
}
while(parser.m_next != parser.m_end && parser.m_sym != parser.m_end);
return objects;
}
QVariantMap JsonToVariant::parseObject()
{
/*
* object
* {}
* { members }
*/
QVariantMap data;
consume('{');
if(peekNext() != '}')
data = parseMembers();
consume('}');
return data;
}
QVariantMap JsonToVariant::parseMembers()
{
/*
* members
* pair
* pair , members
*/
QVariantMap data;
QPair<QString, QVariant> pair;
// loop instead of recursing
do
{
// Grab a pair
pair = parsePair();
// Store it in our data
data[pair.first] = pair.second;
}
while(tryConsume(',')); // Loop if we've got a list separator
return data;
}
QPair<QString, QVariant> JsonToVariant::parsePair()
{
/*
* pair
* string : value
*/
QString key = parseString();
consume(':');
QVariant value = parseValue();
return qMakePair(key, value);
}
QVariantList JsonToVariant::parseArray()
{
/*
* array
* []
* [ elements ]
*/
QVariantList data;
consume('[');
if(peekNext() != ']')
data = parseElements();
consume(']');
return data;
}
QVariantList JsonToVariant::parseElements()
{
/*
* elements
* value
* value , elements
*/
QVariantList data;
// loop instead of recursing
do
{
// Grab a value
data += parseValue();
}
while(tryConsume(',')); // repeat if we've got a list separator
return data;
}
QVariant JsonToVariant::parseValue()
{
/*
* value
* string
* number
* object
* array
* bool
* null
*/
tryConsume(':');
// Lookahead to work out the type of value
switch(peekNext().toAscii())
{
case '"':
return parseString();
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
return parseNumber();
case '{':
return parseObject();
case '[':
return parseArray();
case 't': // true
case 'f': // false
return parseBool();
case 'n': // null
return parseNull();
default:
FAIL(QObject::tr("string, number, object, array, bool, or null"));
}
}
QString JsonToVariant::parseString()
{
/*
* string
* ""
* " chars "
*/
QString data;
// Starting quotation marks
consume('"');
// If it's a non-empty string, grab the contents
if(*m_next != '"')
data = parseChars();
// Ending quotation marks
consume('"');
return data;
}
QString JsonToVariant::parseChars()
{
/*
* chars
* char
* char chars
*/
QString data;
// chars contains at least one char
data = parseChar();
while(peekNext() != '"')
data.append( parseChar() );
return data;
}
QChar JsonToVariant::parseChar()
{
/*
* char
* any character except for ", \, or control characters
* \"
* \\
* \/
* \b
* \f
* \n
* \r
* \t
* \u four-hex-digits
*/
// Grab the next character, without skipping whitespace
consume(false);
// We're not allowed unescaped quotation marks
if(*m_sym == '"')
FAIL(QObject::tr("Any unicode character except for \" or JSON escape sequences"));
// But some escape sequences are allowed
if(*m_sym == '\\')
{
QString digits;
switch(consume().toAscii())
{
case '"':
return '"';
case '\\':
return '\\';
case '/':
return '/';
case 'b':
return '\b';
case 'f':
return '\f';
case 'n':
return '\n';
case 'r':
return '\r';
case 't':
return '\t';
case 'u':
// Unicode 4-digit hex
for(int i = 0; i < 4; ++i)
{
digits += parseHexDigit();
}
return QChar(digits.toInt(0, 16));
default:
FAIL("[\"\\/bfnrtu]");
}
}
return *m_sym;
}
QVariant JsonToVariant::parseNumber()
{
/*
* number
* int
* int frac
* int exp
* int frac exp
*/
// Every JSON number starts with an int
QString data = parseInt();
// Lookahead for fractions and exponents
// Do we have a fraction?
if(*m_next == '.') data += parseFrac();
// Do we have an exponent?
if(*m_next == 'e' || *m_next == 'E') data += parseExp();
// Try several return types...
bool ok;
QVariant ret;
ret = data.toInt(&ok); if(ok) return ret;
ret = data.toLongLong(&ok); if(ok) return ret;
ret = data.toDouble(&ok); if(ok) return ret;
// If this point is reached, don't know how to convert the string
// to an integer.
Q_ASSERT(false);
return QVariant();
}
QString JsonToVariant::parseInt()
{
/*
* int
* digit
* digit1-9 digits
* - digit
* - digit1-9 digits
*/
QString data;
// Match any negation mark
if(tryConsume('-'))
data = "-";
// Grab the first digit...
QChar firstDigit = parseDigit();
data += firstDigit;
// ...if it's not zero...
if(firstDigit != '0')
{
// ... try and add more digits.
try { data += parseDigits(); }
catch(ParseException)
{
// Catch, as more digits are entirely optional
// Roll back.
m_next = m_sym--;
}
}
return data;
}
QString JsonToVariant::parseFrac()
{
/*
* frac
* . digits
*/
consume('.');
return QString(".%1").arg(parseDigits());
}
QString JsonToVariant::parseExp()
{
/*
* exp
* e digits
*/
QString data;
data = parseE();
data += parseDigits();
return data;
}
QString JsonToVariant::parseDigits()
{
/*
* digits
* digit
* digit digits
*/
QString data;
// Digits has at least one digit...
data += parseDigit();
// ... try and get some more
// Loop instead of recurse
Q_FOREVER
{
try { data += parseDigit(); }
catch(ParseException)
{
m_next = m_sym--; // roll back
break;
}
}
return data;
}
QString JsonToVariant::parseE()
{
/*
* e
* e
* e+
* e-
* E
* E+
* E-
*/
// Try and grab an 'e' or 'E'
if(consume(false).toLower() == 'e')
{
// digits in follow[e]
if(m_next->isDigit())
return "e";
// Hopefully the next is a + or -
// grab another chracter...
consume(false);
// If it's not + or -, fail
if(*m_sym != '+' && *m_sym != '-')
FAIL("+ | -");
// Otherwise, return e[+-]
return QString("e%1").arg(*m_sym);
}
else
FAIL("e | E");
}
QChar JsonToVariant::parseDigit()
{
/*
* digit
* [0-9]
*/
if(!consume(false).isDigit())
FAIL("[0-9]");
return *m_sym;
}
QChar JsonToVariant::parseHexDigit()
{
/*
* hexdigit
* [0-9a-fA-F]
*/
QChar character = consume().toLower();
if(character.isDigit() || (character >= 'a' && character <= 'f'))
return character;
FAIL("[0-9a-fA-F]");
}
bool JsonToVariant::parseBool()
{
/*
* bool
* true
* false
*/
switch(peekNext().toAscii())
{
case 't':
consume(QString("true"));
return true;
case 'f':
consume(QString("false"));
return false;
default:
consume(false);
FAIL("true | false");
}
}
QVariant JsonToVariant::parseNull()
{
/*
* null
* null
*/
consume(QString("null"));
return QVariant();
}
QString JsonToVariant::remaining()
{
QString data;
QString::ConstIterator it = m_sym;
while(it != m_end) data += *it++;
return data;
}
QChar JsonToVariant::consume(bool skipWhitespace) throw(ParseException)
{
// Read a character...
do
{
if(m_next == m_end)
{
throw ParseException("EOF", "symbol", remaining());
}
m_sym = m_next++;
}
//...and loop while we get whitespace, if it's being skipped
while(skipWhitespace && m_sym->isSpace());
// Just for convenience...
return *m_sym;
}
void JsonToVariant::consume(QChar wanted) throw(ParseException)
{
// Grab a char(ignoring whitespace), and if it's not what's
// expected, throw
if(consume() != wanted)
{
FAIL(wanted);
}
}
void JsonToVariant::consume(char wanted) throw(ParseException)
{
// Convenience function for the above
consume(QChar(wanted));
}
void JsonToVariant::consume(QString wanted) throw(ParseException)
{
// Keep track of where we start...
QString::ConstIterator it = m_sym;
// Grab wanted.length() characters, and compare them to the
// character in the appropriate position in the parameter
for(int i = 0; i < wanted.length(); ++i)
if(consume(false) != wanted[i])
{
// If it doesn't match, roll back, and throw a
// parse exception
m_sym = it;
m_next = ++it;
FAIL(wanted);
}
}
bool JsonToVariant::tryConsume(QChar wanted) throw()
{
// Grab the next character
try
{
consume();
}
catch(ParseException)
{
// End-Of-String, rollback and return false
m_next = m_sym--;
return false;
}
// Check if it's what we want
if(*m_sym != wanted)
{
// nope, something else, rollback and return false
m_next = m_sym--;
return false;
}
return true;
}
QChar JsonToVariant::peekNext(bool skipWhitespace) throw(ParseException)
{
QString::ConstIterator it = m_sym;
do
{
++it;
if(it == m_end)
{
FAIL("symbol");
}
}
while(skipWhitespace && it->isSpace());
return *it;
}
}

160
third-party/JsonQt/lib/JsonToVariant.h vendored Normal file
View file

@ -0,0 +1,160 @@
/* LICENSE NOTICE
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _JSONQT_JSON_TO_VARIANT_H
#define _JSONQT_JSON_TO_VARIANT_H
#include "ParseException.h"
#include "JsonQtExport.h"
#include <QList>
#include <QPair>
#include <QString>
#include <QVariant>
/** Qt-based JSON handling.
* This is based on a recursive descent parser with 1-character lookahed,
* and follows the structure of the grammar presented on json.org as closely
* as possible, to avoid mistakes, and hopefully to make the code more readable.
*
* @author Fred Emmott <mail@fredemmott.co.uk>
*/
namespace JsonQt
{
/** Class for converting JSON strings to QVariant-based structures.
*
* @author Fred Emmott <mail@fredemmott.co.uk>
*/
class JSONQT_EXPORT JsonToVariant
{
public:
/** Main parsing function.
*
* @param json is a string containing JSON text.
* @returns A QVariant-representation of the JSON
* structure.
* @throws ParseException if the string provided is not
* valid JSON (or at least this parser thinks it
* isn't ;) )
*/
static QVariant parse(const QString& json) throw (ParseException);
/** Parse multiple objects in one string.
* This is useful when working on streams where
* one-chunk-per-json-object is not guaranteed.
*/
static QList<QVariantMap> multiParse(const QString& json) throw(ParseException);
private:
JsonToVariant();
// Parsers for types given on JSON.org
QVariantMap parseObject();
QVariantMap parseMembers();
QPair<QString, QVariant> parsePair();
QVariantList parseArray();
QVariantList parseElements();
QVariant parseValue();
QString parseString();
QString parseChars();
QChar parseChar();
QVariant parseNumber();
QString parseInt();
QString parseFrac();
QString parseExp();
QString parseDigits();
QString parseE();
// Parsers for types implied on JSON.org
QChar parseDigit();
QChar parseHexDigit();
bool parseBool();
QVariant parseNull();
// Internal functions
/// The unparsed part of the input string.
inline QString remaining();
/** Consume the next character.
* Advances m_sym to the next character, and returns it.
* Optionally skips over whitespace.
*
* @param skipWhitespace controls if whitespace is
* ignored.
* @returns *m_sym
* @throws ParseException if the end of the string is
* reached.
*/
QChar consume(bool skipWhitespace = true)
throw(ParseException);
/** Consume the next character, and check for equality
* with the specified character.
*
* @param wanted is the character to compare to.
* @throws ParseException if the end of the string is
* reached, or the characaters are not equal.
*/
void consume(QChar wanted) throw(ParseException);
/// Convenience function for consume(QChar).
void consume(char wanted) throw(ParseException);
/** Attempt to consume the specified string.
* This attempts to consume length(wanted) characters,
* including whitespace, and checks that they are equal
* to the characters in the same position in the
* specified string.
*
* @param wanted is the string to attempt to consume.
* @throws ParseException if the end of the string is
* reached, or the string comparisson fails.
*/
void consume(QString wanted) throw(ParseException);
/** Try to consume a single character, without throw.
* This will try to read a single character, and
* compares to the specified character.
*
* @param wanted is the character to compare to.
* @returns true if the character specified was
* successfully consumed.
* @returns false if the end of the string was reached,
* or the characters were not equal.
*/
bool tryConsume(QChar wanted) throw();
/** Return the next symbol.
* Optionally skips whitespace.
*
* @param skipWhitespace sets the whitespace handling.
* @returns the next symbol.
* @throws ParseException if the end of the string is
* reached.
*/
QChar peekNext(bool skipWhitespace = true)
throw(ParseException);
// Variables
/// Iterator pointing at the current symbol.
QString::ConstIterator m_sym;
/// Iterator pointing at the next symbol.
QString::ConstIterator m_next;
/// Iterator pointing at the end of the string.
QString::ConstIterator m_end;
};
}
#endif

View file

@ -0,0 +1,47 @@
/* LICENSE NOTICE
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ParseException.h"
// For QObject::tr
#include <QObject>
#include "psilogger.h"
namespace JsonQt
{
ParseException::ParseException(const QString& got, const QString& expected, const QString& remaining) throw()
:
m_got(got),
m_expected(expected),
m_remaining(remaining)
{
PsiLogger::instance()->log(QString("JsonQt::ParseException(): got = %1; expected = %2; remaining = %3")
.arg(got)
.arg(expected)
.arg(remaining));
}
ParseException::~ParseException() throw(){}
const char* ParseException::what() const throw()
{
return qPrintable(QObject::tr("A parsing error occurred:\n\tGot: '%1'\n\tExpected: '%2'\n\tAt: '%3'").arg(m_got).arg(m_expected).arg(m_remaining));
}
QString ParseException::got() { return m_got; }
QString ParseException::expected() { return m_expected; }
QString ParseException::remaining() { return m_remaining; }
}

63
third-party/JsonQt/lib/ParseException.h vendored Normal file
View file

@ -0,0 +1,63 @@
/* LICENSE NOTICE
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _JSONQT_PARSE_EXCEPTION_H
#define _JSONQT_PARSE_EXCEPTION_H
#include "JsonQtExport.h"
#include <exception>
#include <QChar>
#include <QString>
namespace JsonQt
{
/** Parsing exception class.
* Raised whenever JsonQt can't pass something it's been given, for
* whatever reason.
*/
class JSONQT_EXPORT ParseException : public std::exception
{
public:
/** Create a ParseException.
* @param got is what was found in the string.
* @param expected is what the parser was expecting.
* @param remaining is what was left of the input.
*/
ParseException(
const QString& got,
const QString& expected,
const QString& remaining
) throw();
~ParseException() throw();
/// A single string providing information on the
/// exception.
virtual const char* what() const throw();
/// What the parser found.
QString got();
/// What the parser was expecting.
QString expected();
/// The remaining unparsed input.
QString remaining();
private:
QString m_got;
QString m_expected;
QString m_remaining;
};
};
#endif

View file

@ -0,0 +1,64 @@
#include "VariantToJson.h"
namespace JsonQt
{
QString VariantToJson::parse(const QVariantMap& data)
{
QStringList members;
for(QVariantMap::ConstIterator it = data.begin(); it != data.end(); ++it)
{
members.append(QString("\"%1\": %2").arg(it.key()).arg(parseElement(it.value())));
}
return "{" + members.join(", ") + "}";
}
QString VariantToJson::parseElement(const QVariant& value)
{
switch(value.type())
{
case QVariant::Bool:
return value.toBool() ? "true" : "false";
case QVariant::Map:
return parse(value.toMap());
case QVariant::Int:
return QString::number(value.toInt());
case QVariant::LongLong:
return QString::number(value.toLongLong());
case QVariant::Double:
return QString::number(value.toDouble());
case QVariant::UInt:
return QString::number(value.toUInt());
case QVariant::ULongLong:
return QString::number(value.toULongLong());
case QVariant::List:
return parseList(value.toList());
case QVariant::String:
return QString("\"%1\"").arg(value.toString().replace("\\", "\\\\").replace("\"", "\\\""));
case QVariant::StringList:
return parseStringList(value.toStringList());
case QVariant::Invalid:
return "null";
default:
return QString();
}
}
QString VariantToJson::parseList(const QVariantList& list)
{
QStringList parts;
Q_FOREACH(QVariant variant, list)
{
parts.append(parseElement(variant));
}
return "[" + parts.join(", ") + "]";
}
QString VariantToJson::parseStringList(const QStringList& stringList)
{
QVariantList variantList;
Q_FOREACH(const QString& string, stringList)
{
variantList.append(string);
}
return parseList(variantList);
}
}

40
third-party/JsonQt/lib/VariantToJson.h vendored Normal file
View file

@ -0,0 +1,40 @@
#ifndef _JSONQT_VARIANT_TO_JSON_H
#define _JSONQT_VARIANT_TO_JSON_H
#include "JsonQtExport.h"
#include <QString>
#include <QStringList>
#include <QVariant>
namespace JsonQt
{
/** Class for converting QVariants into JSON structures.
*
* The following variant types are supported:
* - QVariant::Bool
* - QVariant::String
* - QVariant::Double
* - QVariant::Int
* - QVariant::LongLong
* - QVariant::UInt
* - QVariant::ULongLong
* - QVariant::Invalid
* - QVariant::List // JSON array
* - QVariant::Map // JSON object
*
* @author Fred Emmott <mail@fredemmott.co.uk>
*/
class JSONQT_EXPORT VariantToJson
{
public:
/// Parse a QVariant into JSON.
static QString parse(const QVariantMap& data);
private:
static QString parseElement(const QVariant& element);
static QString parseList(const QVariantList& list);
static QString parseStringList(const QStringList& list);
};
}
#endif

44
third-party/JsonQt/tests/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,44 @@
SET(
TESTS
JsonRpc
JsonRpcAdaptor
JsonToProperties
JsonToVariant
VariantToJson
)
##### Probably don't want to edit below this line #####
# Find Qt4
FIND_PACKAGE( Qt4 REQUIRED )
# Pick modules
SET( QT_DONT_USE_QTGUI TRUE )
SET( QT_USE_QTTEST TRUE )
# Use it
INCLUDE( ${QT_USE_FILE} )
# Include the library include directories, and the current build directory (moc)
INCLUDE_DIRECTORIES(
../lib
${CMAKE_CURRENT_BINARY_DIR}
)
# Build the tests
INCLUDE(AddFileDependencies)
FOREACH(test ${TESTS})
MESSAGE(STATUS "Building ${test}")
QT4_WRAP_CPP(MOC_SOURCE ${test}.cpp)
ADD_EXECUTABLE(
${test}
${test}.cpp
)
ADD_FILE_DEPENDENCIES(${test}.cpp ${MOC_SOURCE})
TARGET_LINK_LIBRARIES(
${test}
${QT_LIBRARIES}
JsonQt
)
ENDFOREACH()

300
third-party/JsonQt/tests/JsonRpc.cpp vendored Normal file
View file

@ -0,0 +1,300 @@
#include "JsonRpc.h"
#include "JsonToVariant.h"
#include <QtTest/QtTest>
#include <QSignalSpy>
/// Check that JSON a gets error code b
#define ERROR_TEST(a, b) \
JsonQt::JsonRpc t; \
QSignalSpy jsonSpy(&t, SIGNAL(sendJson(const QString&))); \
t.processJson(a); \
\
QCOMPARE(jsonSpy.count(), 1); \
\
QString json(jsonSpy.first().first().toString()); \
QVariantMap response = JsonQt::JsonToVariant::parse(json).toMap(); \
\
QVERIFY(response.contains("error")); \
QCOMPARE(response.value("error").type(), QVariant::Map); \
\
QVariantMap error = response.value("error").toMap(); \
QVERIFY(error.contains("code")); \
QVERIFY(error.contains("message")); \
\
QCOMPARE(error.value("code").type(), QVariant::Int); \
QCOMPARE(error.value("code").toInt(), static_cast<int>(b));
/// Get a QVariantMap from spy
#define GET_DATA() \
QCOMPARE(spy.count(), 1); \
QCOMPARE(spy.first().first().type(), QVariant::String); \
QVariantMap data(JsonQt::JsonToVariant::parse(spy.first().first().toString()).toMap());
/// Setup client and server JsonRpc instances
#define SETUP_CLIENT_SERVER() \
JsonQt::JsonRpc client; \
JsonQt::JsonRpc server; \
\
connect( \
&client, SIGNAL(sendJson(const QString&)), \
&server, SLOT(processJson(const QString&)) \
);
Q_DECLARE_METATYPE(QVariant);
class JsonRpc : public QObject
{
Q_OBJECT
private slots:
void initTestCase()
{
qRegisterMetaType<QVariant>("QVariant");
}
void testInvalidJson()
{
ERROR_TEST("{", JsonQt::JsonRpc::InvalidJson);
}
void testEmptyJsonObject()
{
ERROR_TEST("{}", JsonQt::JsonRpc::InvalidJsonRpc);
}
void testSimpleNotificationReceived()
{
JsonQt::JsonRpc t;
QSignalSpy spy(&t, SIGNAL(notificationReceived(const QString&, const QVariant&)));
t.processJson(
"{"
"\"jsonrpc\": \"2.0\","
"\"method\": \"ping\""
"}"
);
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.first().first().toString(), QString("ping"));
}
void testSimpleRequestReceived()
{
JsonQt::JsonRpc t;
QSignalSpy requestSpy(&t, SIGNAL(requestReceived(const QVariant&, const QString&, const QVariant&)));
t.processJson(
"{"
"\"jsonrpc\": \"2.0\","
"\"method\": \"ping\","
"\"id\": 9001"
"}"
);
QCOMPARE(requestSpy.count(), 1);
// method
QCOMPARE(requestSpy.first().value(1).toString(), QString("ping"));
// id
QVariant id = requestSpy.first().value(0).value<QVariant>();
QCOMPARE(id.type(), QVariant::Int);
QCOMPARE(id.toInt(), 9001);
}
void testErrorReceived()
{
JsonQt::JsonRpc t;
QSignalSpy spy(&t, SIGNAL(errorReceived(const QVariant&, int, const QString&, const QVariant&)));
t.processJson(
"{"
"\"jsonrpc\": \"2.0\","
"\"error\":"
"{"
"\"code\": 1234,"
"\"message\": \"foo\","
"\"data\": \"bar\""
"},"
"\"id\": 9001"
"}"
);
QCOMPARE(spy.count(), 1);
// id
QVariant id = spy.first().first().value<QVariant>();
QCOMPARE(id.type(), QVariant::Int);
QCOMPARE(id.toInt(), 9001);
// code
QCOMPARE(spy.first().value(1).type(), QVariant::Int);
QCOMPARE(spy.first().value(1).toInt(), 1234);
// message
QCOMPARE(spy.first().value(2).type(), QVariant::String);
QCOMPARE(spy.first().value(2).toString(), QString("foo"));
// data
QVariant data = spy.first().value(3).value<QVariant>();
QCOMPARE(data.type(), QVariant::String);
QCOMPARE(data.toString(), QString("bar"));
}
void testJsonRpcVersion()
{
QString testString =
"{"
"\"jsonrpc\": \"9001\","
"\"method\": \"ping\""
"}";
ERROR_TEST(testString, JsonQt::JsonRpc::InvalidJsonRpc);
}
void testComplexNotificationReceived()
{
JsonQt::JsonRpc t;
QSignalSpy spy(&t, SIGNAL(notificationReceived(const QString&, const QVariant&)));
t.processJson(
"{"
"\"jsonrpc\": \"2.0\","
"\"method\": \"ping\","
"\"params\":"
"{"
"\"foo\": \"bar\","
"\"123\": 456"
"}"
"}"
);
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.first().first().toString(), QString("ping"));
QVariantMap parameters = spy.first().value(1).value<QVariant>().toMap();
QVERIFY(parameters.contains("foo"));
QCOMPARE(parameters.value("foo").type(), QVariant::String);
QCOMPARE(parameters.value("foo").toString(), QString("bar"));
QVERIFY(parameters.contains("123"));
QCOMPARE(parameters.value("123").type(), QVariant::Int);
QCOMPARE(parameters.value("123").toInt(), 456);
}
void testSendingSimpleNotification()
{
JsonQt::JsonRpc t;
QSignalSpy spy(&t, SIGNAL(sendJson(const QString&)));
t.sendNotification("foo");
GET_DATA();
QCOMPARE(data.value("method").toString(), QString("foo"));
QVERIFY(!data.contains("id"));
QVERIFY(!data.contains("params"));
}
void testSendingSimpleRequest()
{
JsonQt::JsonRpc t;
QSignalSpy spy(&t, SIGNAL(sendJson(const QString&)));
t.sendRequest(QVariant(123), "foo");
GET_DATA();
QCOMPARE(data.value("method").toString(), QString("foo"));
QCOMPARE(data.value("id").toInt(), 123);
QVERIFY(!data.contains("params"));
}
void testSendingResponse()
{
JsonQt::JsonRpc t;
QSignalSpy spy(&t, SIGNAL(sendJson(const QString&)));
t.sendResponse(QVariant(123), "foo");
GET_DATA();
QCOMPARE(data.value("result").toString(), QString("foo"));
QCOMPARE(data.value("id").toInt(), 123);
}
void testSendingError()
{
JsonQt::JsonRpc t;
QSignalSpy spy(&t, SIGNAL(sendJson(const QString&)));
t.sendError(QVariant(123), 456, "foo", QVariant(789));
GET_DATA();
QCOMPARE(data.value("id").toInt(), 123);
QCOMPARE(data.value("error").type(), QVariant::Map);
QVariantMap error = data.value("error").toMap();
QCOMPARE(error.value("code").toInt(), 456);
QCOMPARE(error.value("message").toString(), QString("foo"));
QCOMPARE(error.value("data").toInt(), 789);
}
void testSendingComplexNotification()
{
JsonQt::JsonRpc t;
QSignalSpy spy(&t, SIGNAL(sendJson(const QString&)));
QVariantMap params;
params["bar"] = "baz";
t.sendNotification("foo", params);
GET_DATA();
QCOMPARE(data.value("method").toString(), QString("foo"));
QVERIFY(!data.contains("id"));
QCOMPARE(data.value("params").toMap(), params);
}
void testNotificationBothEnds()
{
SETUP_CLIENT_SERVER();
QSignalSpy spy(&server, SIGNAL(notificationReceived(const QString&, const QVariant&)));
QVariantMap params;
params["bar"] = "baz";
client.sendNotification("foo", params);
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.first().value(0).toString(), QString("foo"));
QCOMPARE(spy.first().value(1).value<QVariant>().toMap(), params);
}
void testRequestBothEnds()
{
SETUP_CLIENT_SERVER();
QSignalSpy spy(&server, SIGNAL(requestReceived(const QVariant&, const QString&, const QVariant&)));
QVariantMap params;
params["bar"] = "baz";
client.sendRequest(123, "foo", params);
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.first().value(0).value<QVariant>(), QVariant::fromValue<QVariant>(123));
QCOMPARE(spy.first().value(1).toString(), QString("foo"));
QCOMPARE(spy.first().value(2).value<QVariant>().toMap(), params);
}
void testResponseBothEnds()
{
SETUP_CLIENT_SERVER();
QSignalSpy spy(&server, SIGNAL(responseReceived(const QVariant&, const QVariant&)));
client.sendResponse(123, "foo");
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.first().value(0).value<QVariant>(), QVariant::fromValue<QVariant>(123));
QCOMPARE(spy.first().value(1).value<QVariant>().toString(), QString("foo"));
}
void testErrorBothEnds()
{
SETUP_CLIENT_SERVER();
QSignalSpy spy(&server, SIGNAL(errorReceived(const QVariant&, int, const QString&, const QVariant&)));
client.sendError(123, 456, "789", "foo");
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.first().value(0).value<QVariant>(), QVariant::fromValue<QVariant>(123));
QCOMPARE(spy.first().value(1).toInt(), 456);
QCOMPARE(spy.first().value(2).toString(), QString("789"));
QCOMPARE(spy.first().value(3).value<QVariant>().toString(), QString("foo"));
}
void testJsonErrorBothEnds()
{
SETUP_CLIENT_SERVER();
QSignalSpy spy(&server, SIGNAL(errorReceived(const QVariant&, int, const QString&, const QVariant&)));
client.processJson("{");
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.first().value(1).toInt(), static_cast<int>(JsonQt::JsonRpc::InvalidJson));
}
};
QTEST_MAIN(JsonRpc);
#include "moc_JsonRpc.cxx"

View file

@ -0,0 +1,258 @@
#include "JsonRpcAdaptor.h"
#include "JsonRpc.h"
#include <QtTest/QtTest>
Q_DECLARE_METATYPE(QVariant);
class TestObject : public QObject
{
Q_OBJECT;
Q_CLASSINFO("JsonQt-RPC-name", "TestName");
Q_CLASSINFO("JsonQt-RPC-id", "urn:data:test");
Q_CLASSINFO("JsonQt-RPC-version", "9000.001");
Q_CLASSINFO("JsonQt-RPC-summary", "Ponies");
public:
TestObject(QObject* parent) : QObject(parent) {}
public slots:
void functionOne(const QString& foo)
{
emit functionOneCalled(foo);
}
QString functionTwo()
{
emit functionTwoCalled();
return "Mary had a little lamb.";
}
void functionThree(int one, bool two, QVariantList three, QVariantMap four)
{
emit functionThreeCalled(one, two, three, four);
}
void functionFour(const QString& foo, const QString& bar)
{
emit functionFourCalled(foo, bar);
}
signals:
void functionOneCalled(const QString& foo);
void functionTwoCalled();
void functionThreeCalled(int, bool, QVariantList, QVariantMap);
void functionFourCalled(QString, QString);
};
class JsonRpcAdaptor : public QObject
{
Q_OBJECT
private slots:
void initTestCase()
{
qRegisterMetaType<QVariant>("QVariant");
m_testObject = new TestObject(this);
m_adaptor = new JsonQt::JsonRpcAdaptor(m_testObject, this);
m_rpc = new JsonQt::JsonRpc(this);
connect(
m_rpc, SIGNAL(sendJson(const QString&)),
m_adaptor, SLOT(processJson(const QString&))
);
connect(
m_adaptor, SIGNAL(sendJson(const QString&)),
m_rpc, SLOT(processJson(const QString&))
);
}
void testFunctionOne()
{
QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionOneCalled(const QString&)));
QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&)));
QVariantMap parameters;
parameters["foo"] = "bar";
m_rpc->sendRequest(42, "functionOne", parameters);
QCOMPARE(testObjectSpy.count(), 1);
QCOMPARE(testObjectSpy.first().first().toString(), QString("bar"));
QCOMPARE(rpcSpy.count(), 1);
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant(42));
QCOMPARE(rpcSpy.first().value(1).value<QVariant>(), QVariant());
}
void testFunctionFour()
{
QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionFourCalled(QString, QString)));
QVariantMap parameters;
parameters["foo"] = "bar";
parameters["bar"] = "baz";
m_rpc->sendRequest(123, "functionFour", parameters);
QCOMPARE(testObjectSpy.count(), 1);
QCOMPARE(testObjectSpy.first().value(0).toString(), QString("bar"));
QCOMPARE(testObjectSpy.first().value(1).toString(), QString("baz"));
}
void testFunctionTwo()
{
QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionTwoCalled()));
QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&)));
m_rpc->sendRequest(1337, "functionTwo");
QCOMPARE(testObjectSpy.count(), 1);
QCOMPARE(rpcSpy.count(), 1);
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant(1337));
QCOMPARE(rpcSpy.first().value(1).value<QVariant>().toString(), QString("Mary had a little lamb."));
}
void testFunctionThree()
{
QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionThreeCalled(int, bool, QVariantList, QVariantMap)));
QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&)));
QVariantList listParameter;
QVariantMap nestedMap;
nestedMap["foo"] = "bar";
listParameter.append(nestedMap);
listParameter.append("baz");
QVariantList parameters;
parameters.append(123);
parameters.append(true);
parameters.append(listParameter);
parameters.append(nestedMap);
m_rpc->sendRequest(42, "functionThree", parameters);
QCOMPARE(testObjectSpy.count(), 1);
QVariantList result = testObjectSpy.first();
QCOMPARE(result.value(0), QVariant(123));
QCOMPARE(result.value(1), QVariant(true));
QCOMPARE(result.value(2), QVariant(listParameter));
QCOMPARE(result.value(3), QVariant(nestedMap));
QCOMPARE(rpcSpy.count(), 1);
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant(42));
QCOMPARE(rpcSpy.first().value(1).value<QVariant>(), QVariant());
}
void testInvalidFunction()
{
QSignalSpy rpcSpy(m_rpc, SIGNAL(errorReceived(QVariant, int, QString, QVariant)));
m_rpc->sendRequest("123", "DOES NOT EXIST");
QCOMPARE(rpcSpy.count(), 1);
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant("123"));
QCOMPARE(rpcSpy.first().value(1), QVariant(JsonQt::JsonRpc::MethodNotFound));
}
void testBadArgumentCount()
{
QSignalSpy rpcSpy(m_rpc, SIGNAL(errorReceived(QVariant, int, QString, QVariant)));
m_rpc->sendRequest("123", "functionOne");
QCOMPARE(rpcSpy.count(), 1);
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant("123"));
QCOMPARE(rpcSpy.first().value(1), QVariant(JsonQt::JsonRpc::BadParameters));
}
void testWrongArgumentTypes()
{
QSignalSpy rpcSpy(m_rpc, SIGNAL(errorReceived(QVariant, int, QString, QVariant)));
QVariantMap parameters;
parameters["foo"] = 123;
m_rpc->sendRequest("123", "functionOne", parameters);
QCOMPARE(rpcSpy.count(), 1);
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant("123"));
QCOMPARE(rpcSpy.first().value(1), QVariant(JsonQt::JsonRpc::BadParameters));
}
void testIntropection()
{
QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&)));
m_rpc->sendRequest(QVariant(), "system.describe");
QCOMPARE(rpcSpy.count(), 1);
QVariantMap introspectionData = rpcSpy.first().value(1).value<QVariant>().toMap();
QVERIFY(!introspectionData.isEmpty());
// Service data
QCOMPARE(introspectionData.value("sdversion").toString(), QString("1.0")); // Service Description version
QCOMPARE(introspectionData.value("name").toString(), QString("TestName"));
QCOMPARE(introspectionData.value("id").toString(), QString("urn:data:test"));
QCOMPARE(introspectionData.value("version").toString(), QString("9000.001"));
QCOMPARE(introspectionData.value("summary").toString(), QString("Ponies"));
QVERIFY(!introspectionData.contains("help"));
QVERIFY(introspectionData.contains("procs"));
// Method data
QVariantList methods = introspectionData.value("procs").toList();
QCOMPARE(methods.count(), 4);
QVariantMap functionOne = methods.takeFirst().toMap();
QVariantMap functionTwo = methods.takeFirst().toMap();
QVariantMap functionThree = methods.takeFirst().toMap();
QVariantMap functionFour = methods.takeFirst().toMap();
QVariantList params;
QVariantMap param;
// functionOne
QCOMPARE(functionOne.value("name").toString(), QString("functionOne"));
QCOMPARE(functionOne.value("return").toString(), QString("nil"));
params = functionOne.value("params").toList();
QCOMPARE(params.count(), 1);
param = params.first().toMap();
QCOMPARE(param.value("name").toString(), QString("foo"));
QCOMPARE(param.value("type").toString(), QString("str"));
// functionTwo
QCOMPARE(functionTwo.value("name").toString(), QString("functionTwo"));
QCOMPARE(functionTwo.value("return").toString(), QString("str"));
params = functionTwo.value("params").toList();
QCOMPARE(params.count(), 0);
// functionThree
QCOMPARE(functionThree.value("name").toString(), QString("functionThree"));
QCOMPARE(functionThree.value("return").toString(), QString("nil"));
params = functionThree.value("params").toList();
QCOMPARE(params.count(), 4);
param = params.takeFirst().toMap();
QCOMPARE(param.value("name").toString(), QString("one"));
QCOMPARE(param.value("type").toString(), QString("num"));
param = params.takeFirst().toMap();
QCOMPARE(param.value("name").toString(), QString("two"));
QCOMPARE(param.value("type").toString(), QString("bit"));
param = params.takeFirst().toMap();
QCOMPARE(param.value("name").toString(), QString("three"));
QCOMPARE(param.value("type").toString(), QString("arr"));
param = params.takeFirst().toMap();
QCOMPARE(param.value("name").toString(), QString("four"));
QCOMPARE(param.value("type").toString(), QString("obj"));
// functionFour
QCOMPARE(functionFour.value("name").toString(), QString("functionFour"));
QCOMPARE(functionFour.value("return").toString(), QString("nil"));
params = functionFour.value("params").toList();
QCOMPARE(params.count(), 2);
param = params.takeFirst().toMap();
QCOMPARE(param.value("name").toString(), QString("foo"));
QCOMPARE(param.value("type").toString(), QString("str"));
param = params.takeFirst().toMap();
QCOMPARE(param.value("name").toString(), QString("bar"));
QCOMPARE(param.value("type").toString(), QString("str"));
}
private:
JsonQt::JsonRpc* m_rpc;
JsonQt::JsonRpcAdaptor* m_adaptor;
TestObject* m_testObject;
};
QTEST_MAIN(JsonRpcAdaptor);
#include "moc_JsonRpcAdaptor.cxx"

View file

@ -0,0 +1,46 @@
/* LICENSE NOTICE
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "JsonToProperties.h"
#include <QtTest/QtTest>
// This test assumes that JsonToVariant works correctly.
class JsonToProperties : public QObject
{
Q_OBJECT;
private slots:
void initTestCase()
{
JsonQt::JsonToProperties::parse(
"{"
"\"objectName\": \"My JSON Properties Test Object\","
"\"END\" : [\"OF\", \"TEST\"]"
"}",
this
);
}
void testObjectName()
{
QCOMPARE(
this->objectName(),
QString("My JSON Properties Test Object")
);
}
};
QTEST_MAIN(JsonToProperties);
#include "moc_JsonToProperties.cxx"

View file

@ -0,0 +1,166 @@
/* LICENSE NOTICE
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "JsonToVariant.h"
#include <QtTest/QtTest>
class JsonToVariant : public QObject
{
Q_OBJECT;
private slots:
void initTestCase()
{
// Variable use of whitespace intentional
QVariant data = JsonQt::JsonToVariant::parse(
"{"
"\"MyString\": \"foo\","
"\"MyInt\" :123 ,"
"\"MyBigNum\" : 42e10 , "
"\"MyLongNum\" : 8589934592,"
"\"MyFraction\" : 2.718,"
"\"MyArray\" : [1, \"2\", {\"3\": 4}],"
"\"MyObject\" : {\"a\" : 1, \"b\" : 2 },"
"\"MyEmptyObject\" : { },"
"\"MyBool\": true,"
"\"END\" : [\"OF\", \"TEST\"]"
"}"
);
QCOMPARE(data.type(), QVariant::Map);
m_parsed = data.toMap();
}
void testStringWithEscapedForwardSlash()
{
QVariant data = JsonQt::JsonToVariant::parse("\"\\/\"");
QCOMPARE(data.type(), QVariant::String);
QCOMPARE(data.toString(), QString("/"));
}
void testMulti()
{
QList<QVariantMap> parsed = JsonQt::JsonToVariant::multiParse(
"{"
"\"foo\": \"bar\""
"}"
"{"
"\"x\": \"y\""
"}"
);
QCOMPARE(parsed.count(), 2);
QCOMPARE(parsed.at(0).value("foo"), QVariant("bar"));
QCOMPARE(parsed.at(1).value("x"), QVariant("y"));
}
void testEmpty()
{
bool thrown = false;
try
{
JsonQt::JsonToVariant::parse("");
}
catch(JsonQt::ParseException e)
{
thrown = true;
}
QVERIFY(thrown);
}
void testString()
{
QVariant data = m_parsed["MyString"];
QCOMPARE(data.type(), QVariant::String);
QCOMPARE(data.toString(), QString("foo"));
QCOMPARE(data, JsonQt::JsonToVariant::parse("\"foo\""));
}
void testInt()
{
QVariant data = m_parsed["MyInt"];
QCOMPARE(data.type(), QVariant::Int);
QCOMPARE(data.toInt(), 123);
QCOMPARE(data, JsonQt::JsonToVariant::parse("123"));
}
void testBigNum()
{
QVariant data = m_parsed["MyBigNum"];
QCOMPARE(data.type(), QVariant::Double);
QCOMPARE(data.toDouble(), 42e10);
QCOMPARE(data, JsonQt::JsonToVariant::parse("42e10"));
}
void testLongNum()
{
QVariant data = m_parsed["MyLongNum"];
QCOMPARE(data.type(), QVariant::LongLong);
QCOMPARE(data.value<qint64>(), Q_INT64_C(8589934592));
QCOMPARE(data, JsonQt::JsonToVariant::parse("8589934592"));
}
void testFraction()
{
QVariant data = m_parsed["MyFraction"];
QCOMPARE(data.type(), QVariant::Double);
QCOMPARE(data.toDouble(), double(2.718));
QCOMPARE(data, JsonQt::JsonToVariant::parse("2.718"));
}
void testArray()
{
QVariant root = m_parsed["MyArray"];
QCOMPARE(root.type(), QVariant::List);
QVariantList rootData = root.toList();
QCOMPARE(rootData[0].type(), QVariant::Int);
QCOMPARE(rootData[0].toInt(), 1);
QCOMPARE(rootData[1].type(), QVariant::String);
QCOMPARE(rootData[1].toString(), QString("2"));
QCOMPARE(rootData[2].type(), QVariant::Map);
QVariantMap childData = rootData[2].toMap();
QCOMPARE(childData["3"].type(), QVariant::Int);
QCOMPARE(childData["3"].toInt(), 4);
QCOMPARE(root, JsonQt::JsonToVariant::parse("[1, \"2\", {\"3\": 4}]"));
}
void testObject()
{
QVariant root = m_parsed["MyObject"];
QCOMPARE(root.type(), QVariant::Map);
QVariantMap rootData = root.toMap();
QCOMPARE(rootData["a"].toInt(), 1);
QCOMPARE(rootData["b"].toInt(), 2);
QCOMPARE(root, JsonQt::JsonToVariant::parse("{\"a\" : 1, \"b\" : 2 }"));
}
void testEmptyObject()
{
QVariant root = m_parsed["MyEmptyObject"];
QCOMPARE(root.type(), QVariant::Map);
QCOMPARE(root.value<QVariantMap>().size(), 0);
QCOMPARE(root, JsonQt::JsonToVariant::parse("{}"));
}
private:
QVariantMap m_parsed;
};
QTEST_MAIN(JsonToVariant);
#include "moc_JsonToVariant.cxx"

View file

@ -0,0 +1,46 @@
#include "VariantToJson.h"
#include "JsonToVariant.h"
#include <QtTest/QtTest>
class VariantToJson : public QObject
{
Q_OBJECT
private slots:
void testFlat()
{
QVariantMap map;
map["string_foo"] = "foo";
map["bool_true"] = true;
map["int_42"] = 42;
map["double_pi"] = 3.14159;
QString json(JsonQt::VariantToJson::parse(map));
QCOMPARE(map, JsonQt::JsonToVariant::parse(json).toMap());
}
void testComplex()
{
QVariantMap map;
map["string_foo"] = "foo";
map["bool_true"] = true;
map["int_42"] = 42;
map["double_pi"] = 3.14159;
map["recurse"] = map;
QVariantList list;
list.append("zero");
list.append("one");
map["list"] = list;
QStringList list2;
for(int i = 0; i < 25; i++)
list2.append(QString("element").append(QString::number(i)));
map["list2"] = list2;
QString json(JsonQt::VariantToJson::parse(map));
QCOMPARE(map, JsonQt::JsonToVariant::parse(json).toMap());
}
};
QTEST_MAIN(VariantToJson);
#include "moc_VariantToJson.cxx"

8
third-party/qca/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
/libqca_psi.a
/object_script.*
/qca_psi.lib
/vc70.pdb
/.moc
/.obj
/libqca_psi.a
/Makefile

1
third-party/qca/qca-cyrus-sasl.pri vendored Normal file
View file

@ -0,0 +1 @@
SOURCES += $$PWD/qca-cyrus-sasl/qca-cyrus-sasl.cpp

View file

@ -0,0 +1,948 @@
/*
* qca-sasl.cpp - SASL plugin for QCA
* Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com>
* Copyright (C) 2006 Michail Pishchagin <mblsha@gmail.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#include <QtCrypto>
#include <qcaprovider.h>
#include <QDebug>
#include <QtPlugin>
extern "C"
{
#include <sasl/sasl.h>
}
#include <QStringList>
#include <QList>
#include <QFile>
#define SASL_BUFSIZE 8192
#define SASL_APP "qca"
using namespace QCA;
namespace saslQCAPlugin {
class saslProvider : public Provider
{
public:
saslProvider();
void init();
~saslProvider();
int qcaVersion() const;
QString name() const;
QString credit() const;
QStringList features() const;
Context *createContext(const QString &type);
bool client_init;
bool server_init;
QString appname;
};
//----------------------------------------------------------------------------
// SASLParams
//----------------------------------------------------------------------------
class SASLParams
{
public:
class SParams
{
public:
bool user, authzid, pass, realm;
};
SASLParams()
{
reset();
}
void reset()
{
resetNeed();
resetHave();
foreach(char *result, results)
delete result;
results.clear();
}
void resetNeed()
{
need.user = false;
need.authzid = false;
need.pass = false;
need.realm = false;
}
void resetHave()
{
have.user = false;
have.authzid = false;
have.pass = false;
have.realm = false;
}
void setUsername(const QString &s)
{
have.user = true;
user = s;
}
void setAuthzid(const QString &s)
{
have.authzid = true;
authzid = s;
}
void setPassword(const SecureArray &s)
{
have.pass = true;
pass = QString::fromUtf8(s.toByteArray());
}
void setRealm(const QString &s)
{
have.realm = true;
realm = s;
}
void applyInteract(sasl_interact_t *needp)
{
for(int n = 0; needp[n].id != SASL_CB_LIST_END; ++n) {
if(needp[n].id == SASL_CB_AUTHNAME)
need.user = true; // yes, I know these
if(needp[n].id == SASL_CB_USER)
need.authzid = true; // look backwards
if(needp[n].id == SASL_CB_PASS)
need.pass = true;
if(needp[n].id == SASL_CB_GETREALM)
need.realm = true;
}
}
void extractHave(sasl_interact_t *needp)
{
for(int n = 0; needp[n].id != SASL_CB_LIST_END; ++n) {
if(needp[n].id == SASL_CB_AUTHNAME && have.user)
setValue(&needp[n], user);
if(needp[n].id == SASL_CB_USER && have.authzid)
setValue(&needp[n], authzid);
if(needp[n].id == SASL_CB_PASS && have.pass)
setValue(&needp[n], pass);
if(needp[n].id == SASL_CB_GETREALM && have.realm)
setValue(&needp[n], realm);
}
}
bool missingAny() const
{
if((need.user && !have.user) /*|| (need.authzid && !have.authzid)*/ || (need.pass && !have.pass) /*|| (need.realm && !have.realm)*/)
return true;
return false;
}
SParams missing() const
{
SParams np = need;
if(have.user)
np.user = false;
if(have.authzid)
np.authzid = false;
if(have.pass)
np.pass = false;
if(have.realm)
np.realm = false;
return np;
}
void setValue(sasl_interact_t *i, const QString &s)
{
if(i->result)
return;
QByteArray cs = s.toUtf8();
int len = cs.length();
char *p = new char[len+1];
memcpy(p, cs.data(), len);
p[len] = 0;
i->result = p;
i->len = len;
// record this
results.append(p);
}
QList<char *> results;
SParams need;
SParams have;
QString user, authzid, pass, realm;
};
static QByteArray makeByteArray(const void *in, unsigned int len)
{
QByteArray buf(len, 0);
memcpy(buf.data(), in, len);
return buf;
}
static QString addrString(const SASLContext::HostPort &hp)
{
return (hp.addr + ';' + QString::number(hp.port));
}
//----------------------------------------------------------------------------
// saslContext
//----------------------------------------------------------------------------
class saslContext : public SASLContext
{
saslProvider *g;
// core props
QString service, host;
QString localAddr, remoteAddr;
// security props
int secflags;
int ssf_min, ssf_max;
QString ext_authid;
int ext_ssf;
sasl_conn_t *con;
sasl_interact_t *need;
int maxoutbuf;
sasl_callback_t *callbacks;
// state
bool servermode;
int step;
bool in_sendFirst;
QByteArray in_buf;
QString in_mech;
bool in_useClientInit;
QByteArray in_clientInit;
QString out_mech;
// bool out_useClientInit;
// QByteArray out_clientInit;
QByteArray out_buf;
SASLParams params;
QString sc_username, sc_authzid;
bool ca_flag, ca_done, ca_skip;
int last_r;
int result_ssf;
Result result_result;
bool result_haveClientInit;
QStringList result_mechlist;
SASL::AuthCondition result_authCondition;
QByteArray result_to_net;
QByteArray result_plain;
int result_encoded;
private:
void resetState()
{
if(con) {
sasl_dispose(&con);
con = 0;
}
need = 0;
if(callbacks) {
delete callbacks;
callbacks = 0;
}
localAddr = "";
remoteAddr = "";
maxoutbuf = 128;
sc_username = "";
sc_authzid = "";
result_authCondition = SASL::AuthFail;
result_haveClientInit = false;
result_mechlist.clear();
result_plain.clear();
result_plain.clear();
result_plain.clear();
result_ssf = 0;
}
void resetParams()
{
params.reset();
secflags = 0;
ssf_min = 0;
ssf_max = 0;
ext_authid = "";
ext_ssf = 0;
}
bool setsecprops()
{
sasl_security_properties_t secprops;
secprops.min_ssf = ssf_min;
secprops.max_ssf = ssf_max;
secprops.maxbufsize = SASL_BUFSIZE;
secprops.property_names = NULL;
secprops.property_values = NULL;
secprops.security_flags = secflags;
int r = sasl_setprop(con, SASL_SEC_PROPS, &secprops);
if(r != SASL_OK)
return false;
if(!ext_authid.isEmpty()) {
const char *authid = ext_authid.toLatin1().data();
sasl_ssf_t ssf = ext_ssf;
r = sasl_setprop(con, SASL_SSF_EXTERNAL, &ssf);
if(r != SASL_OK)
return false;
r = sasl_setprop(con, SASL_AUTH_EXTERNAL, &authid);
if(r != SASL_OK)
return false;
}
return true;
}
void setAuthCondition(int r)
{
//qDebug() << "authcondition: " << r;
SASL::AuthCondition x;
switch(r) {
// common
case SASL_NOMECH: x = SASL::NoMechanism; break;
case SASL_BADPROT: x = SASL::BadProtocol; break;
// client
case SASL_BADSERV: x = SASL::BadServer; break;
// server
case SASL_BADAUTH: x = SASL::BadAuth; break;
case SASL_NOAUTHZ: x = SASL::NoAuthzid; break;
case SASL_TOOWEAK: x = SASL::TooWeak; break;
case SASL_ENCRYPT: x = SASL::NeedEncrypt; break;
case SASL_EXPIRED: x = SASL::Expired; break;
case SASL_DISABLED: x = SASL::Disabled; break;
case SASL_NOUSER: x = SASL::NoUser; break;
case SASL_UNAVAIL: x = SASL::RemoteUnavailable; break;
default: x = SASL::AuthFail; break;
}
result_authCondition = x;
}
void getssfparams()
{
const void *maybe_sff;
if( SASL_OK == sasl_getprop( con, SASL_SSF, &maybe_sff ) )
result_ssf = *(const int*)maybe_sff;
const void *maybe_maxoutbuf;
if (SASL_OK == sasl_getprop( con, SASL_MAXOUTBUF, &maybe_maxoutbuf ) )
maxoutbuf = *(const int*)maybe_maxoutbuf;
}
static int scb_checkauth(sasl_conn_t *, void *context, const char *requested_user, unsigned, const char *auth_identity, unsigned, const char *, unsigned, struct propctx *)
{
saslContext *that = (saslContext *)context;
that->sc_username = auth_identity; // yeah yeah, it looks
that->sc_authzid = requested_user; // backwards, but it is right
that->ca_flag = true;
return SASL_OK;
}
void clientTryAgain()
{
result_haveClientInit = false;
if(step == 0) {
const char *clientout, *m;
unsigned int clientoutlen;
need = 0;
QString list = result_mechlist.join(" ");
int r;
while(1) {
if(need)
params.extractHave(need);
if(in_sendFirst)
r = sasl_client_start(con, list.toLatin1().data(), &need, &clientout, &clientoutlen, &m);
else
r = sasl_client_start(con, list.toLatin1().data(), &need, NULL, NULL, &m);
if(r != SASL_INTERACT)
break;
params.applyInteract(need);
if(params.missingAny()) {
out_mech = m;
result_result = Params;
return;
}
}
if(r != SASL_OK && r != SASL_CONTINUE) {
setAuthCondition(r);
result_result = Error;
return;
}
out_mech = m;
if(in_sendFirst && clientout) {
out_buf = makeByteArray(clientout, clientoutlen);
result_haveClientInit = true;
}
++step;
if(r == SASL_OK) {
getssfparams();
result_result = Success;
return;
}
result_result = Continue;
return;
}
else {
const char *clientout;
unsigned int clientoutlen;
int r;
while(1) {
if(need)
params.extractHave(need);
//printf("sasl_client_step(con, {%s}, %d, &need, &clientout, &clientoutlen);\n", in_buf.data(), in_buf.size());
r = sasl_client_step(con, in_buf.data(), in_buf.size(), &need, &clientout, &clientoutlen);
//printf("returned: %d\n", r);
if(r != SASL_INTERACT)
break;
params.applyInteract(need);
if(params.missingAny()) {
result_result = Params;
return;
}
}
if(r != SASL_OK && r != SASL_CONTINUE) {
setAuthCondition(r);
result_result = Error;
return;
}
out_buf = makeByteArray(clientout, clientoutlen);
if(r == SASL_OK) {
getssfparams();
result_result = Success;
return;
}
result_result = Continue;
return;
}
}
void serverTryAgain()
{
if(step == 0) {
if(!ca_skip) {
const char *clientin = 0;
unsigned int clientinlen = 0;
if(in_useClientInit) {
clientin = in_clientInit.data();
clientinlen = in_clientInit.size();
}
const char *serverout;
unsigned int serveroutlen;
ca_flag = false;
int r = sasl_server_start(con, in_mech.toLatin1().data(), clientin, clientinlen, &serverout, &serveroutlen);
if(r != SASL_OK && r != SASL_CONTINUE) {
setAuthCondition(r);
result_result = Error;
return;
}
out_buf = makeByteArray(serverout, serveroutlen);
last_r = r;
if(ca_flag && !ca_done) {
ca_done = true;
ca_skip = true;
result_result = AuthCheck;
return;
}
}
ca_skip = false;
++step;
if(last_r == SASL_OK) {
getssfparams();
result_result = Success;
return;
}
result_result = Continue;
return;
}
else {
if(!ca_skip) {
const char *serverout;
unsigned int serveroutlen;
int r = sasl_server_step(con, in_buf.data(), in_buf.size(), &serverout, &serveroutlen);
if(r != SASL_OK && r != SASL_CONTINUE) {
setAuthCondition(r);
result_result = Error;
return;
}
if(r == SASL_OK)
out_buf.resize(0);
else
out_buf = makeByteArray(serverout, serveroutlen);
last_r = r;
if(ca_flag && !ca_done) {
ca_done = true;
ca_skip = true;
result_result = AuthCheck;
return;
}
}
ca_skip = false;
if(last_r == SASL_OK) {
getssfparams();
result_result = Success;
return;
}
result_result = Continue;
return;
}
}
bool sasl_endecode(const QByteArray &in, QByteArray *out, bool enc)
{
// no security
if(result_ssf == 0) {
*out = in;
return true;
}
int at = 0;
out->resize(0);
while(1) {
int size = in.size() - at;
if(size == 0)
break;
if(size > maxoutbuf)
size = maxoutbuf;
const char *outbuf;
unsigned len;
int r;
if(enc)
r = sasl_encode(con, in.data() + at, size, &outbuf, &len);
else
r = sasl_decode(con, in.data() + at, size, &outbuf, &len);
if(r != SASL_OK)
return false;
int oldsize = out->size();
out->resize(oldsize + len);
memcpy(out->data() + oldsize, outbuf, len);
at += size;
}
return true;
}
void doResultsReady()
{
QMetaObject::invokeMethod(this, "resultsReady", Qt::QueuedConnection);
}
public:
saslContext(saslProvider *_g)
: SASLContext(_g)
{
result_result = Success;
g = _g;
con = 0;
callbacks = 0;
reset();
}
~saslContext()
{
reset();
}
virtual Provider::Context *clone() const
{
return 0;
}
virtual Result result() const
{
return result_result;
}
virtual void reset()
{
resetState();
resetParams();
}
virtual void setup(const QString &_service, const QString &_host, const HostPort *local, const HostPort *remote, const QString &ext_id, int _ext_ssf)
{
service = _service;
host = _host;
localAddr = local ? addrString(*local) : "";
remoteAddr = remote ? addrString(*remote) : "";
ext_authid = ext_id;
ext_ssf = _ext_ssf;
}
virtual int ssf() const
{
return result_ssf;
}
virtual void startClient(const QStringList &mechlist, bool allowClientSendFirst)
{
resetState();
in_sendFirst = allowClientSendFirst;
if(!g->client_init) {
sasl_client_init(NULL);
g->client_init = true;
}
callbacks = new sasl_callback_t[5];
callbacks[0].id = SASL_CB_GETREALM;
callbacks[0].proc = 0;
callbacks[0].context = 0;
callbacks[1].id = SASL_CB_USER;
callbacks[1].proc = 0;
callbacks[1].context = 0;
callbacks[2].id = SASL_CB_AUTHNAME;
callbacks[2].proc = 0;
callbacks[2].context = 0;
callbacks[3].id = SASL_CB_PASS;
callbacks[3].proc = 0;
callbacks[3].context = 0;
callbacks[4].id = SASL_CB_LIST_END;
callbacks[4].proc = 0;
callbacks[4].context = 0;
result_result = Error;
int r = sasl_client_new(service.toLatin1().data(), host.toLatin1().data(), localAddr.isEmpty() ? 0 : localAddr.toLatin1().data(), remoteAddr.isEmpty() ? 0 : remoteAddr.toLatin1().data(), callbacks, 0, &con);
if(r != SASL_OK) {
setAuthCondition(r);
doResultsReady();
return;
}
if(!setsecprops())
{
doResultsReady();
return;
}
result_mechlist = mechlist;
servermode = false;
step = 0;
result_result = Success;
clientTryAgain();
doResultsReady();
return;
}
// TODO: make use of disableServerSendLast
virtual void startServer(const QString &realm, bool disableServerSendLast)
{
Q_UNUSED(disableServerSendLast);
resetState();
g->appname = SASL_APP;
if(!g->server_init) {
sasl_server_init(NULL, QFile::encodeName(g->appname));
g->server_init = true;
}
callbacks = new sasl_callback_t[2];
callbacks[0].id = SASL_CB_PROXY_POLICY;
callbacks[0].proc = (int(*)())scb_checkauth;
callbacks[0].context = this;
callbacks[1].id = SASL_CB_LIST_END;
callbacks[1].proc = 0;
callbacks[1].context = 0;
result_result = Error;
int r = sasl_server_new(service.toLatin1().data(), host.toLatin1().data(), !realm.isEmpty() ? realm.toLatin1().data() : 0, localAddr.isEmpty() ? 0 : localAddr.toLatin1().data(), remoteAddr.isEmpty() ? 0 : remoteAddr.toLatin1().data(), callbacks, 0, &con);
if(r != SASL_OK) {
setAuthCondition(r);
doResultsReady();
return;
}
if(!setsecprops())
{
doResultsReady();
return;
}
const char *ml;
r = sasl_listmech(con, 0, 0, " ", 0, &ml, 0, 0);
if(r != SASL_OK)
return;
result_mechlist = QString::fromUtf8(ml).split(' ');
servermode = true;
step = 0;
ca_done = false;
ca_skip = false;
result_result = Success;
doResultsReady();
return;
}
virtual void serverFirstStep(const QString &mech, const QByteArray *clientInit)
{
in_mech = mech;
if(clientInit) {
in_useClientInit = true;
in_clientInit = *clientInit;
}
else
in_useClientInit = false;
serverTryAgain();
doResultsReady();
}
virtual SASL::Params clientParams() const
{
SASLParams::SParams sparams = params.missing();
return SASL::Params(sparams.user, sparams.authzid, sparams.pass, sparams.realm);
}
virtual void setClientParams(const QString *user, const QString *authzid, const SecureArray *pass, const QString *realm)
{
if(user)
params.setUsername(*user);
if(authzid)
params.setAuthzid(*authzid);
if(pass)
params.setPassword(*pass);
if(realm)
params.setRealm(*realm);
}
virtual QString username() const
{
return sc_username;
}
virtual QString authzid() const
{
return sc_authzid;
}
virtual void nextStep(const QByteArray &from_net)
{
in_buf = from_net;
tryAgain();
}
virtual void tryAgain()
{
if(servermode)
serverTryAgain();
else
clientTryAgain();
doResultsReady();
}
virtual QString mech() const
{
if (servermode)
return in_mech;
else
return out_mech;
}
virtual QStringList mechlist() const
{
return result_mechlist;
}
virtual QStringList realmlist() const
{
// TODO
return QStringList();
}
virtual void setConstraints(SASL::AuthFlags f, int minSSF, int maxSSF)
{
int sf = 0;
if( !(f & SASL::AllowPlain) )
sf |= SASL_SEC_NOPLAINTEXT;
// if( !(f & SASL::AllowActiveVulnerable) ) // TODO
// sf |= SASL_SEC_NOACTIVE;
// if( !(f & SASL::AllowDictVulnerable) ) // TODO
// sf |= SASL_SEC_NODICTIONARY;
if( !(f & SASL::AllowAnonymous) )
sf |= SASL_SEC_NOANONYMOUS;
if( f & SASL::RequireForwardSecrecy )
sf |= SASL_SEC_FORWARD_SECRECY;
if( f & SASL::RequirePassCredentials )
sf |= SASL_SEC_PASS_CREDENTIALS;
if( f & SASL::RequireMutualAuth )
sf |= SASL_SEC_MUTUAL_AUTH;
secflags = sf;
ssf_min = minSSF;
ssf_max = maxSSF;
}
virtual bool waitForResultsReady(int msecs)
{
// TODO: for now, all operations block anyway
Q_UNUSED(msecs);
return true;
}
virtual void update(const QByteArray &from_net, const QByteArray &from_app)
{
bool ok = true;
if(!from_app.isEmpty())
ok = sasl_endecode(from_app, &result_to_net, true);
if(ok && !from_net.isEmpty())
ok = sasl_endecode(from_net, &result_plain, false);
result_result = ok ? Success : Error;
result_encoded = from_app.size();
//printf("update (from_net=%d, to_net=%d, from_app=%d, to_app=%d)\n", from_net.size(), result_to_net.size(), from_app.size(), result_plain.size());
doResultsReady();
}
virtual bool haveClientInit() const
{
return result_haveClientInit;
}
virtual QByteArray stepData() const
{
return out_buf;
}
virtual QByteArray to_net()
{
QByteArray a = result_to_net;
result_to_net.clear();
return a;
}
virtual int encoded() const
{
return result_encoded;
}
virtual QByteArray to_app()
{
QByteArray a = result_plain;
result_plain.clear();
return a;
}
virtual SASL::AuthCondition authCondition() const
{
return result_authCondition;
}
};
//----------------------------------------------------------------------------
// saslProvider
//----------------------------------------------------------------------------
saslProvider::saslProvider()
{
client_init = false;
server_init = false;
}
void saslProvider::init()
{
}
saslProvider::~saslProvider()
{
if(client_init || server_init)
sasl_done();
}
int saslProvider::qcaVersion() const
{
return QCA_VERSION;
}
QString saslProvider::name() const
{
return "qca-cyrus-sasl";
}
QString saslProvider::credit() const
{
return QString(); // TODO
}
QStringList saslProvider::features() const
{
QStringList list;
list += "sasl";
return list;
}
Provider::Context *saslProvider::createContext(const QString &type)
{
if ( type == "sasl" )
return new saslContext( this );
return 0;
}
} // namespace saslQCAPlugin
using namespace saslQCAPlugin;
//----------------------------------------------------------------------------
// saslPlugin
//----------------------------------------------------------------------------
class saslPlugin : public QObject, public QCAPlugin
{
Q_OBJECT
Q_INTERFACES(QCAPlugin)
public:
virtual Provider *createProvider() { return new saslProvider; }
};
#include "qca-cyrus-sasl.moc"
Q_EXPORT_PLUGIN2(qca_cyrus_sasl, saslPlugin)

12
third-party/qca/qca-gnupg.pri vendored Normal file
View file

@ -0,0 +1,12 @@
# DEFINES += GPG_DEBUG
windows:LIBS += -ladvapi32
GPG_BASE = $$PWD/qca-gnupg
GPGPROC_BASE = $$GPG_BASE/gpgproc
include($$GPGPROC_BASE/gpgproc.pri)
INCLUDEPATH += $$GPGPROC_BASE
INCLUDEPATH += $$GPG_BASE
HEADERS += \
$$GPG_BASE/gpgop.h
SOURCES += \
$$GPG_BASE/gpgop.cpp \
$$GPG_BASE/qca-gnupg.cpp

1641
third-party/qca/qca-gnupg/gpgop.cpp vendored Normal file

File diff suppressed because it is too large Load diff

208
third-party/qca/qca-gnupg/gpgop.h vendored Normal file
View file

@ -0,0 +1,208 @@
/*
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#ifndef GPGOP_H
#define GPGOP_H
#include <QtCrypto>
#include "qpipe.h"
namespace gpgQCAPlugin {
class GpgOp : public QObject
{
Q_OBJECT
public:
enum Type
{
Check, // --version
SecretKeyringFile, // --list-secret-keys
PublicKeyringFile, // --list-public-keys
SecretKeys, // --fixed-list-mode --with-colons --list-secret-keys
PublicKeys, // --fixed-list-mode --with-colons --list-public-keys
Encrypt, // --encrypt
Decrypt, // --decrypt
Sign, // --sign
SignAndEncrypt, // --sign --encrypt
SignClearsign, // --clearsign
SignDetached, // --detach-sign
Verify, // --verify
VerifyDetached, // --verify
Import, // --import
Export, // --export
DeleteKey // --delete-key
};
enum VerifyResult
{
VerifyGood, // good sig
VerifyBad, // bad sig
VerifyNoKey // we don't have signer's public key
};
enum Error
{
ErrorProcess, // startup, process, or ipc error
ErrorPassphrase, // passphrase was either wrong or not provided
ErrorFormat, // input format was bad
ErrorSignerExpired, // signing key is expired
ErrorEncryptExpired, // encrypting key is expired
ErrorEncryptUntrusted, // encrypting key is untrusted
ErrorEncryptInvalid, // encrypting key is invalid in some way
ErrorDecryptNoKey, // missing decrypt key
ErrorUnknown // other error
};
class Event
{
public:
enum Type
{
None,
ReadyRead,
BytesWritten,
Finished,
NeedPassphrase,
NeedCard,
ReadyReadDiagnosticText
};
Type type;
int written; // BytesWritten
QString keyId; // NeedPassphrase
Event() : type(None), written(0) {}
};
class KeyItem
{
public:
enum Type
{
RSA,
DSA,
ElGamal,
Unknown
};
enum Caps
{
Encrypt = 0x01,
Sign = 0x02,
Certify = 0x04,
Auth = 0x08
};
QString id;
Type type;
int bits;
QDateTime creationDate;
QDateTime expirationDate;
int caps; // flags OR'd together
QString fingerprint;
KeyItem() : type(Unknown), bits(0), caps(0) {}
};
class Key
{
public:
QList<KeyItem> keyItems; // first item is primary
QStringList userIds;
bool isTrusted;
Key() : isTrusted(false) {}
};
typedef QList<Key> KeyList;
explicit GpgOp(const QString &bin, QObject *parent = 0);
~GpgOp();
void reset();
bool isActive() const;
Type op() const;
void setAsciiFormat(bool b);
void setDisableAgent(bool b);
void setAlwaysTrust(bool b);
void setKeyrings(const QString &pubfile, const QString &secfile); // for keylists and import
void doCheck();
void doSecretKeyringFile();
void doPublicKeyringFile();
void doSecretKeys();
void doPublicKeys();
void doEncrypt(const QStringList &recip_ids);
void doDecrypt();
void doSign(const QString &signer_id);
void doSignAndEncrypt(const QString &signer_id, const QStringList &recip_ids);
void doSignClearsign(const QString &signer_id);
void doSignDetached(const QString &signer_id);
void doVerify();
void doVerifyDetached(const QByteArray &sig);
void doImport(const QByteArray &in);
void doExport(const QString &key_id);
void doDeleteKey(const QString &key_fingerprint);
#ifdef QPIPE_SECURE
void submitPassphrase(const QCA::SecureArray &a);
#else
void submitPassphrase(const QByteArray &a);
#endif
void cardOkay();
// for encrypt, decrypt, sign, verify, export
QByteArray read();
void write(const QByteArray &in);
void endWrite();
QString readDiagnosticText();
// for synchronous operation
Event waitForEvent(int msecs = -1);
// results
bool success() const;
Error errorCode() const;
KeyList keys() const; // Keys
QString keyringFile() const; // KeyringFile
QString encryptedToId() const; // Decrypt (for ErrorDecryptNoKey)
bool wasSigned() const; // Decrypt
QString signerId() const; // Verify
QDateTime timestamp() const; // Verify
VerifyResult verifyResult() const; // Verify
Q_SIGNALS:
void readyRead();
void bytesWritten(int bytes);
void finished();
void needPassphrase(const QString &keyId);
void needCard();
void readyReadDiagnosticText();
private:
class Private;
friend class Private;
Private *d;
};
}
#endif

View file

@ -0,0 +1,8 @@
GPGProc launches a single instance of GPG and provides a friendly API to
work with all six possible pipe channels. Theoretically, it should be
possible to build any GPG front end with it, even though qca-gnupg uses it
for only a handful of operations. If you are writing a Qt-based GPG front
end, please use this class.
GPGProc works on both Windows and Unix platforms.

View file

@ -0,0 +1,830 @@
/*
* Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#include "gpgproc.h"
#include "sprocess.h"
#ifdef Q_OS_MAC
#define QT_PIPE_HACK
#endif
#define QPROC_SIGNAL_RELAY
using namespace QCA;
namespace gpgQCAPlugin {
void releaseAndDeleteLater(QObject *owner, QObject *obj)
{
obj->disconnect(owner);
obj->setParent(0);
obj->deleteLater();
}
//----------------------------------------------------------------------------
// SafeTimer
//----------------------------------------------------------------------------
SafeTimer::SafeTimer(QObject *parent) :
QObject(parent)
{
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), SIGNAL(timeout()));
}
SafeTimer::~SafeTimer()
{
releaseAndDeleteLater(this, timer);
}
int SafeTimer::interval() const
{
return timer->interval();
}
bool SafeTimer::isActive() const
{
return timer->isActive();
}
bool SafeTimer::isSingleShot() const
{
return timer->isSingleShot();
}
void SafeTimer::setInterval(int msec)
{
timer->setInterval(msec);
}
void SafeTimer::setSingleShot(bool singleShot)
{
timer->setSingleShot(singleShot);
}
int SafeTimer::timerId() const
{
return timer->timerId();
}
void SafeTimer::start(int msec)
{
timer->start(msec);
}
void SafeTimer::start()
{
timer->start();
}
void SafeTimer::stop()
{
timer->stop();
}
//----------------------------------------------------------------------------
// QProcessSignalRelay
//----------------------------------------------------------------------------
class QProcessSignalRelay : public QObject
{
Q_OBJECT
public:
QProcessSignalRelay(QProcess *proc, QObject *parent = 0)
:QObject(parent)
{
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
connect(proc, SIGNAL(started()), SLOT(proc_started()), Qt::QueuedConnection);
connect(proc, SIGNAL(readyReadStandardOutput()), SLOT(proc_readyReadStandardOutput()), Qt::QueuedConnection);
connect(proc, SIGNAL(readyReadStandardError()), SLOT(proc_readyReadStandardError()), Qt::QueuedConnection);
connect(proc, SIGNAL(bytesWritten(qint64)), SLOT(proc_bytesWritten(qint64)), Qt::QueuedConnection);
connect(proc, SIGNAL(finished(int)), SLOT(proc_finished(int)), Qt::QueuedConnection);
connect(proc, SIGNAL(error(QProcess::ProcessError)), SLOT(proc_error(QProcess::ProcessError)), Qt::QueuedConnection);
}
signals:
void started();
void readyReadStandardOutput();
void readyReadStandardError();
void bytesWritten(qint64);
void finished(int);
void error(QProcess::ProcessError);
public slots:
void proc_started()
{
emit started();
}
void proc_readyReadStandardOutput()
{
emit readyReadStandardOutput();
}
void proc_readyReadStandardError()
{
emit readyReadStandardError();
}
void proc_bytesWritten(qint64 x)
{
emit bytesWritten(x);
}
void proc_finished(int x)
{
emit finished(x);
}
void proc_error(QProcess::ProcessError x)
{
emit error(x);
}
};
//----------------------------------------------------------------------------
// GPGProc
//----------------------------------------------------------------------------
enum ResetMode
{
ResetSession = 0,
ResetSessionAndData = 1,
ResetAll = 2
};
class GPGProc::Private : public QObject
{
Q_OBJECT
public:
GPGProc *q;
QString bin;
QStringList args;
GPGProc::Mode mode;
SProcess *proc;
#ifdef QPROC_SIGNAL_RELAY
QProcessSignalRelay *proc_relay;
#endif
QPipe pipeAux, pipeCommand, pipeStatus;
QByteArray statusBuf;
QStringList statusLines;
GPGProc::Error error;
int exitCode;
SafeTimer startTrigger, doneTrigger;
QByteArray pre_stdin, pre_aux;
#ifdef QPIPE_SECURE
SecureArray pre_command;
#else
QByteArray pre_command;
#endif
bool pre_stdin_close, pre_aux_close, pre_command_close;
bool need_status, fin_process, fin_process_success, fin_status;
QByteArray leftover_stdout;
QByteArray leftover_stderr;
Private(GPGProc *_q) : QObject(_q), q(_q), pipeAux(this), pipeCommand(this), pipeStatus(this), startTrigger(this), doneTrigger(this)
{
qRegisterMetaType<gpgQCAPlugin::GPGProc::Error>("gpgQCAPlugin::GPGProc::Error");
proc = 0;
#ifdef QPROC_SIGNAL_RELAY
proc_relay = 0;
#endif
startTrigger.setSingleShot(true);
doneTrigger.setSingleShot(true);
connect(&pipeAux.writeEnd(), SIGNAL(bytesWritten(int)), SLOT(aux_written(int)));
connect(&pipeAux.writeEnd(), SIGNAL(error(QCA::QPipeEnd::Error)), SLOT(aux_error(QCA::QPipeEnd::Error)));
connect(&pipeCommand.writeEnd(), SIGNAL(bytesWritten(int)), SLOT(command_written(int)));
connect(&pipeCommand.writeEnd(), SIGNAL(error(QCA::QPipeEnd::Error)), SLOT(command_error(QCA::QPipeEnd::Error)));
connect(&pipeStatus.readEnd(), SIGNAL(readyRead()), SLOT(status_read()));
connect(&pipeStatus.readEnd(), SIGNAL(error(QCA::QPipeEnd::Error)), SLOT(status_error(QCA::QPipeEnd::Error)));
connect(&startTrigger, SIGNAL(timeout()), SLOT(doStart()));
connect(&doneTrigger, SIGNAL(timeout()), SLOT(doTryDone()));
reset(ResetSessionAndData);
}
~Private()
{
reset(ResetSession);
}
void closePipes()
{
#ifdef QT_PIPE_HACK
pipeAux.readEnd().reset();
pipeCommand.readEnd().reset();
pipeStatus.writeEnd().reset();
#endif
pipeAux.reset();
pipeCommand.reset();
pipeStatus.reset();
}
void reset(ResetMode mode)
{
#ifndef QT_PIPE_HACK
closePipes();
#endif
if(proc)
{
proc->disconnect(this);
if(proc->state() != QProcess::NotRunning)
proc->terminate();
proc->setParent(0);
#ifdef QPROC_SIGNAL_RELAY
releaseAndDeleteLater(this, proc_relay);
proc_relay = 0;
delete proc; // should be safe to do thanks to relay
#else
proc->deleteLater();
#endif
proc = 0;
}
#ifdef QT_PIPE_HACK
closePipes();
#endif
startTrigger.stop();
doneTrigger.stop();
pre_stdin.clear();
pre_aux.clear();
pre_command.clear();
pre_stdin_close = false;
pre_aux_close = false;
pre_command_close = false;
need_status = false;
fin_process = false;
fin_status = false;
if(mode >= ResetSessionAndData)
{
statusBuf.clear();
statusLines.clear();
leftover_stdout.clear();
leftover_stderr.clear();
error = GPGProc::FailedToStart;
exitCode = -1;
}
}
bool setupPipes(bool makeAux)
{
if(makeAux && !pipeAux.create())
{
closePipes();
emit q->debug("Error creating pipeAux");
return false;
}
#ifdef QPIPE_SECURE
if(!pipeCommand.create(true)) // secure
#else
if(!pipeCommand.create())
#endif
{
closePipes();
emit q->debug("Error creating pipeCommand");
return false;
}
if(!pipeStatus.create())
{
closePipes();
emit q->debug("Error creating pipeStatus");
return false;
}
return true;
}
void setupArguments()
{
QStringList fullargs;
fullargs += "--no-tty";
if(mode == ExtendedMode)
{
fullargs += "--enable-special-filenames";
fullargs += "--status-fd";
fullargs += QString::number(pipeStatus.writeEnd().idAsInt());
fullargs += "--command-fd";
fullargs += QString::number(pipeCommand.readEnd().idAsInt());
}
for(int n = 0; n < args.count(); ++n)
{
QString a = args[n];
if(mode == ExtendedMode && a == "-&?")
fullargs += QString("-&") + QString::number(pipeAux.readEnd().idAsInt());
else
fullargs += a;
}
QString fullcmd = fullargs.join(" ");
emit q->debug(QString("Running: [") + bin + ' ' + fullcmd + ']');
args = fullargs;
}
public slots:
void doStart()
{
#ifdef Q_OS_WIN
// Note: for unix, inheritability is set in SProcess
if(pipeAux.readEnd().isValid())
pipeAux.readEnd().setInheritable(true);
if(pipeCommand.readEnd().isValid())
pipeCommand.readEnd().setInheritable(true);
if(pipeStatus.writeEnd().isValid())
pipeStatus.writeEnd().setInheritable(true);
#endif
setupArguments();
proc->start(bin, args);
// FIXME: From reading the source to Qt on both windows
// and unix platforms, we know that fork/CreateProcess
// are called in start. However this is not guaranteed
// from an API perspective. We should probably call
// QProcess::waitForStarted() to synchronously ensure
// fork/CreateProcess are called before closing these
// pipes.
pipeAux.readEnd().close();
pipeCommand.readEnd().close();
pipeStatus.writeEnd().close();
}
void aux_written(int x)
{
emit q->bytesWrittenAux(x);
}
void aux_error(QCA::QPipeEnd::Error)
{
emit q->debug("Aux: Pipe error");
reset(ResetSession);
emit q->error(GPGProc::ErrorWrite);
}
void command_written(int x)
{
emit q->bytesWrittenCommand(x);
}
void command_error(QCA::QPipeEnd::Error)
{
emit q->debug("Command: Pipe error");
reset(ResetSession);
emit q->error(GPGProc::ErrorWrite);
}
void status_read()
{
if(readAndProcessStatusData())
emit q->readyReadStatusLines();
}
void status_error(QCA::QPipeEnd::Error e)
{
if(e == QPipeEnd::ErrorEOF)
emit q->debug("Status: Closed (EOF)");
else
emit q->debug("Status: Closed (gone)");
fin_status = true;
doTryDone();
}
void proc_started()
{
emit q->debug("Process started");
// Note: we don't close these here anymore. instead we
// do it just after calling proc->start().
// close these, we don't need them
/*pipeAux.readEnd().close();
pipeCommand.readEnd().close();
pipeStatus.writeEnd().close();*/
// do the pre* stuff
if(!pre_stdin.isEmpty())
{
proc->write(pre_stdin);
pre_stdin.clear();
}
if(!pre_aux.isEmpty())
{
pipeAux.writeEnd().write(pre_aux);
pre_aux.clear();
}
if(!pre_command.isEmpty())
{
#ifdef QPIPE_SECURE
pipeCommand.writeEnd().writeSecure(pre_command);
#else
pipeCommand.writeEnd().write(pre_command);
#endif
pre_command.clear();
}
if(pre_stdin_close)
proc->closeWriteChannel();
if(pre_aux_close)
pipeAux.writeEnd().close();
if(pre_command_close)
pipeCommand.writeEnd().close();
}
void proc_readyReadStandardOutput()
{
emit q->readyReadStdout();
}
void proc_readyReadStandardError()
{
emit q->readyReadStderr();
}
void proc_bytesWritten(qint64 lx)
{
int x = (int)lx;
emit q->bytesWrittenStdin(x);
}
void proc_finished(int x)
{
emit q->debug(QString("Process finished: %1").arg(x));
exitCode = x;
fin_process = true;
fin_process_success = true;
if(need_status && !fin_status)
{
pipeStatus.readEnd().finalize();
fin_status = true;
if(readAndProcessStatusData())
{
doneTrigger.start();
emit q->readyReadStatusLines();
return;
}
}
doTryDone();
}
void proc_error(QProcess::ProcessError x)
{
QMap<int, QString> errmap;
errmap[QProcess::FailedToStart] = "FailedToStart";
errmap[QProcess::Crashed] = "Crashed";
errmap[QProcess::Timedout] = "Timedout";
errmap[QProcess::WriteError] = "WriteError";
errmap[QProcess::ReadError] = "ReadError";
errmap[QProcess::UnknownError] = "UnknownError";
emit q->debug(QString("Process error: %1").arg(errmap[x]));
if(x == QProcess::FailedToStart)
error = GPGProc::FailedToStart;
else if(x == QProcess::WriteError)
error = GPGProc::ErrorWrite;
else
error = GPGProc::UnexpectedExit;
fin_process = true;
fin_process_success = false;
#ifdef QT_PIPE_HACK
// If the process fails to start, then the ends of the pipes
// intended for the child process are still open. Some Mac
// users experience a lockup if we close our ends of the pipes
// when the child's ends are still open. If we ensure the
// child's ends are closed, we prevent this lockup. I have no
// idea why the problem even happens or why this fix should
// work.
pipeAux.readEnd().reset();
pipeCommand.readEnd().reset();
pipeStatus.writeEnd().reset();
#endif
if(need_status && !fin_status)
{
pipeStatus.readEnd().finalize();
fin_status = true;
if(readAndProcessStatusData())
{
doneTrigger.start();
emit q->readyReadStatusLines();
return;
}
}
doTryDone();
}
void doTryDone()
{
if(!fin_process)
return;
if(need_status && !fin_status)
return;
emit q->debug("Done");
// get leftover data
proc->setReadChannel(QProcess::StandardOutput);
leftover_stdout = proc->readAll();
proc->setReadChannel(QProcess::StandardError);
leftover_stderr = proc->readAll();
reset(ResetSession);
if(fin_process_success)
emit q->finished(exitCode);
else
emit q->error(error);
}
private:
bool readAndProcessStatusData()
{
QByteArray buf = pipeStatus.readEnd().read();
if(buf.isEmpty())
return false;
return processStatusData(buf);
}
// return true if there are newly parsed lines available
bool processStatusData(const QByteArray &buf)
{
statusBuf.append(buf);
// extract all lines
QStringList list;
while(1)
{
int n = statusBuf.indexOf('\n');
if(n == -1)
break;
// extract the string from statusbuf
++n;
char *p = (char *)statusBuf.data();
QByteArray cs(p, n);
int newsize = statusBuf.size() - n;
memmove(p, p + n, newsize);
statusBuf.resize(newsize);
// convert to string without newline
QString str = QString::fromUtf8(cs);
str.truncate(str.length() - 1);
// ensure it has a proper header
if(str.left(9) != "[GNUPG:] ")
continue;
// take it off
str = str.mid(9);
// add to the list
list += str;
}
if(list.isEmpty())
return false;
statusLines += list;
return true;
}
};
GPGProc::GPGProc(QObject *parent)
:QObject(parent)
{
d = new Private(this);
}
GPGProc::~GPGProc()
{
delete d;
}
void GPGProc::reset()
{
d->reset(ResetAll);
}
bool GPGProc::isActive() const
{
return (d->proc ? true : false);
}
void GPGProc::start(const QString &bin, const QStringList &args, Mode mode)
{
if(isActive())
d->reset(ResetSessionAndData);
if(mode == ExtendedMode)
{
if(!d->setupPipes(args.contains("-&?")))
{
d->error = FailedToStart;
// emit later
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(gpgQCAPlugin::GPGProc::Error, d->error));
return;
}
d->need_status = true;
emit debug("Pipe setup complete");
}
d->proc = new SProcess(d);
#ifdef Q_OS_UNIX
QList<int> plist;
if(d->pipeAux.readEnd().isValid())
plist += d->pipeAux.readEnd().id();
if(d->pipeCommand.readEnd().isValid())
plist += d->pipeCommand.readEnd().id();
if(d->pipeStatus.writeEnd().isValid())
plist += d->pipeStatus.writeEnd().id();
d->proc->setInheritPipeList(plist);
#endif
// enable the pipes we want
if(d->pipeAux.writeEnd().isValid())
d->pipeAux.writeEnd().enable();
if(d->pipeCommand.writeEnd().isValid())
d->pipeCommand.writeEnd().enable();
if(d->pipeStatus.readEnd().isValid())
d->pipeStatus.readEnd().enable();
#ifdef QPROC_SIGNAL_RELAY
d->proc_relay = new QProcessSignalRelay(d->proc, d);
connect(d->proc_relay, SIGNAL(started()), d, SLOT(proc_started()));
connect(d->proc_relay, SIGNAL(readyReadStandardOutput()), d, SLOT(proc_readyReadStandardOutput()));
connect(d->proc_relay, SIGNAL(readyReadStandardError()), d, SLOT(proc_readyReadStandardError()));
connect(d->proc_relay, SIGNAL(bytesWritten(qint64)), d, SLOT(proc_bytesWritten(qint64)));
connect(d->proc_relay, SIGNAL(finished(int)), d, SLOT(proc_finished(int)));
connect(d->proc_relay, SIGNAL(error(QProcess::ProcessError)), d, SLOT(proc_error(QProcess::ProcessError)));
#else
connect(d->proc, SIGNAL(started()), d, SLOT(proc_started()));
connect(d->proc, SIGNAL(readyReadStandardOutput()), d, SLOT(proc_readyReadStandardOutput()));
connect(d->proc, SIGNAL(readyReadStandardError()), d, SLOT(proc_readyReadStandardError()));
connect(d->proc, SIGNAL(bytesWritten(qint64)), d, SLOT(proc_bytesWritten(qint64)));
connect(d->proc, SIGNAL(finished(int)), d, SLOT(proc_finished(int)));
connect(d->proc, SIGNAL(error(QProcess::ProcessError)), d, SLOT(proc_error(QProcess::ProcessError)));
#endif
d->bin = bin;
d->args = args;
d->mode = mode;
d->startTrigger.start();
}
QByteArray GPGProc::readStdout()
{
if(d->proc)
{
d->proc->setReadChannel(QProcess::StandardOutput);
return d->proc->readAll();
}
else
{
QByteArray a = d->leftover_stdout;
d->leftover_stdout.clear();
return a;
}
}
QByteArray GPGProc::readStderr()
{
if(d->proc)
{
d->proc->setReadChannel(QProcess::StandardError);
return d->proc->readAll();
}
else
{
QByteArray a = d->leftover_stderr;
d->leftover_stderr.clear();
return a;
}
}
QStringList GPGProc::readStatusLines()
{
QStringList out = d->statusLines;
d->statusLines.clear();
return out;
}
void GPGProc::writeStdin(const QByteArray &a)
{
if(!d->proc || a.isEmpty())
return;
if(d->proc->state() == QProcess::Running)
d->proc->write(a);
else
d->pre_stdin += a;
}
void GPGProc::writeAux(const QByteArray &a)
{
if(!d->proc || a.isEmpty())
return;
if(d->proc->state() == QProcess::Running)
d->pipeAux.writeEnd().write(a);
else
d->pre_aux += a;
}
#ifdef QPIPE_SECURE
void GPGProc::writeCommand(const SecureArray &a)
#else
void GPGProc::writeCommand(const QByteArray &a)
#endif
{
if(!d->proc || a.isEmpty())
return;
if(d->proc->state() == QProcess::Running)
#ifdef QPIPE_SECURE
d->pipeCommand.writeEnd().writeSecure(a);
#else
d->pipeCommand.writeEnd().write(a);
#endif
else
d->pre_command += a;
}
void GPGProc::closeStdin()
{
if(!d->proc)
return;
if(d->proc->state() == QProcess::Running)
d->proc->closeWriteChannel();
else
d->pre_stdin_close = true;
}
void GPGProc::closeAux()
{
if(!d->proc)
return;
if(d->proc->state() == QProcess::Running)
d->pipeAux.writeEnd().close();
else
d->pre_aux_close = true;
}
void GPGProc::closeCommand()
{
if(!d->proc)
return;
if(d->proc->state() == QProcess::Running)
d->pipeCommand.writeEnd().close();
else
d->pre_command_close = true;
}
}
#include "gpgproc.moc"

View file

@ -0,0 +1,114 @@
/*
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#ifndef GPGPROC_H
#define GPGPROC_H
#include "qpipe.h"
class QTimer;
namespace gpgQCAPlugin {
// FIXME: Even though deleting an object during a metacall event is supposed
// to be legal with Qt, it is unfortunately buggy (at least before Qt 4.4).
// This function performs the following steps:
// obj->disconnect(owner); // to prevent future signals to owner
// obj->setParent(0); // to prevent delete if parent is deleted
// obj->deleteLater(); // now we can forget about the object
void releaseAndDeleteLater(QObject *owner, QObject *obj);
class SafeTimer : public QObject
{
Q_OBJECT
public:
SafeTimer(QObject *parent = 0);
~SafeTimer();
int interval() const;
bool isActive() const;
bool isSingleShot() const;
void setInterval(int msec);
void setSingleShot(bool singleShot);
int timerId() const;
public slots:
void start(int msec);
void start();
void stop();
signals:
void timeout();
private:
QTimer *timer;
};
// GPGProc - executes gpg and provides access to all 6 channels. NormalMode
// enables stdout, stderr, and stdin. ExtendedMode has those 3 plus status
// aux, and command. The aux channel is connected to the '-&?' argument.
// The debug() signal, as well as stderr, can be used for diagnostic text.
class GPGProc : public QObject
{
Q_OBJECT
public:
enum Error { FailedToStart, UnexpectedExit, ErrorWrite };
enum Mode { NormalMode, ExtendedMode };
GPGProc(QObject *parent = 0);
~GPGProc();
void reset();
bool isActive() const;
void start(const QString &bin, const QStringList &args, Mode m = ExtendedMode);
QByteArray readStdout();
QByteArray readStderr();
QStringList readStatusLines();
void writeStdin(const QByteArray &a);
void writeAux(const QByteArray &a);
#ifdef QPIPE_SECURE
void writeCommand(const QCA::SecureArray &a);
#else
void writeCommand(const QByteArray &a);
#endif
void closeStdin();
void closeAux();
void closeCommand();
Q_SIGNALS:
void error(gpgQCAPlugin::GPGProc::Error error);
void finished(int exitCode);
void readyReadStdout();
void readyReadStderr();
void readyReadStatusLines();
void bytesWrittenStdin(int bytes);
void bytesWrittenAux(int bytes);
void bytesWrittenCommand(int bytes);
void debug(const QString &str); // not signal-safe
private:
class Private;
friend class Private;
Private *d;
};
}
#endif

View file

@ -0,0 +1,8 @@
HEADERS += \
$$PWD/sprocess.h \
$$PWD/gpgproc.h
SOURCES += \
$$PWD/sprocess.cpp \
$$PWD/gpgproc.cpp

View file

@ -0,0 +1,55 @@
/*
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#include "sprocess.h"
#ifdef Q_OS_UNIX
# include <unistd.h>
# include <fcntl.h>
#endif
namespace gpgQCAPlugin {
//----------------------------------------------------------------------------
// SProcess
//----------------------------------------------------------------------------
SProcess::SProcess(QObject *parent)
:QProcess(parent)
{
}
SProcess::~SProcess()
{
}
#ifdef Q_OS_UNIX
void SProcess::setInheritPipeList(const QList<int> &list)
{
pipeList = list;
}
void SProcess::setupChildProcess()
{
// set the pipes to be inheritable
for(int n = 0; n < pipeList.count(); ++n)
::fcntl(pipeList[n], F_SETFD, (::fcntl(pipeList[n], F_GETFD) & ~FD_CLOEXEC));
}
#endif
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#ifndef SPROCESS_H
#define SPROCESS_H
#include <QProcess>
#include <QTimer>
namespace gpgQCAPlugin {
class SProcess : public QProcess
{
Q_OBJECT
public:
SProcess(QObject *parent = 0);
~SProcess();
#ifdef Q_OS_UNIX
void setInheritPipeList(const QList<int> &);
protected:
virtual void setupChildProcess();
private:
QList<int> pipeList;
#endif
};
}
#endif

1790
third-party/qca/qca-gnupg/qca-gnupg.cpp vendored Normal file

File diff suppressed because it is too large Load diff

5
third-party/qca/qca-ossl.pri vendored Normal file
View file

@ -0,0 +1,5 @@
SOURCES += $$PWD/qca-ossl/qca-ossl.cpp
windows {
LIBS += -lgdi32 -lwsock32 -llibeay32 -lssleay32
}

7033
third-party/qca/qca-ossl/qca-ossl.cpp vendored Normal file

File diff suppressed because it is too large Load diff

4
third-party/qca/qca.pri vendored Normal file
View file

@ -0,0 +1,4 @@
INCLUDEPATH += $$PWD/qca/include/QtCrypto
LIBS += -L$$PWD -lqca_psi
windows:LIBS += -lcrypt32
mac:LIBS += -framework Security

90
third-party/qca/qca.pro vendored Normal file
View file

@ -0,0 +1,90 @@
TEMPLATE = lib
QT -= gui
CONFIG += staticlib
DEFINES += QCA_STATIC
TARGET = qca_psi
QCA_BASE = qca
QCA_INCBASE = $$QCA_BASE/include
QCA_SRCBASE = $$QCA_BASE/src
MOC_DIR = .moc
OBJECTS_DIR = .obj
QCA_INC = $$QCA_INCBASE/QtCrypto
QCA_CPP = $$QCA_SRCBASE
INCLUDEPATH += $$QCA_INC $$QCA_CPP
windows {
# Explicitly remove d_and_r, so the lib gets built in the right place
CONFIG -= debug_and_release
CONFIG += release
# Set explicit targets, to ensure a correct name for MSVC
}
# botantools
include($$QCA_SRCBASE/botantools/botantools.pri)
PRIVATE_HEADERS += \
$$QCA_CPP/qca_plugin.h \
$$QCA_CPP/qca_safeobj.h \
$$QCA_CPP/qca_systemstore.h
PUBLIC_HEADERS += \
$$QCA_INC/qca_export.h \
$$QCA_INC/qca_support.h \
$$QCA_INC/qca_tools.h \
$$QCA_INC/qca_core.h \
$$QCA_INC/qca_textfilter.h \
$$QCA_INC/qca_basic.h \
$$QCA_INC/qca_publickey.h \
$$QCA_INC/qca_cert.h \
$$QCA_INC/qca_keystore.h \
$$QCA_INC/qca_securelayer.h \
$$QCA_INC/qca_securemessage.h \
$$QCA_INC/qcaprovider.h \
$$QCA_INC/qpipe.h
HEADERS += $$PRIVATE_HEADERS $$PUBLIC_HEADERS
# do support first
SOURCES += \
$$QCA_CPP/support/syncthread.cpp \
$$QCA_CPP/support/logger.cpp \
$$QCA_CPP/support/synchronizer.cpp \
$$QCA_CPP/support/dirwatch.cpp
SOURCES += \
$$QCA_CPP/qca_tools.cpp \
$$QCA_CPP/qca_core.cpp \
$$QCA_CPP/qca_textfilter.cpp \
$$QCA_CPP/qca_plugin.cpp \
$$QCA_CPP/qca_basic.cpp \
$$QCA_CPP/qca_publickey.cpp \
$$QCA_CPP/qca_cert.cpp \
$$QCA_CPP/qca_keystore.cpp \
$$QCA_CPP/qca_securelayer.cpp \
$$QCA_CPP/qca_safeobj.cpp \
$$QCA_CPP/qca_securemessage.cpp \
$$QCA_CPP/qca_default.cpp \
$$QCA_CPP/support/qpipe.cpp \
$$QCA_CPP/support/console.cpp
unix:!mac: {
SOURCES += $$QCA_CPP/qca_systemstore_flatfile.cpp
}
windows: {
SOURCES += $$QCA_CPP/qca_systemstore_win.cpp
}
mac: {
SOURCES += $$QCA_CPP/qca_systemstore_mac.cpp
}
include(../../conf.pri)
qc_universal {
CONFIG += x86 x86_64
QMAKE_MAC_SDK=/Developer/SDKs/MacOSX10.5.sdk
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.5
}

5
third-party/qca/qca/certs/README vendored Normal file
View file

@ -0,0 +1,5 @@
rootcerts.pem is created by qca/tools/mozcerts
File: mozilla/security/nss/lib/ckfw/builtins/certdata.txt
Date: August 19th, 2007

2822
third-party/qca/qca/certs/rootcerts.pem vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
#include "qca.h"

View file

@ -0,0 +1,47 @@
/*
* qca.h - Qt Cryptographic Architecture
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
* Copyright (C) 2004-2006 Brad Hards <bradh@frogmouth.net>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**
\file qca.h
Summary header file for %QCA.
\note You should not use this header directly from an
application. You should just use <tt> \#include \<QtCrypto>
</tt> instead.
*/
#ifndef QCA_H
#define QCA_H
#include "qca_core.h"
#include "qca_textfilter.h"
#include "qca_basic.h"
#include "qca_publickey.h"
#include "qca_cert.h"
#include "qca_keystore.h"
#include "qca_securelayer.h"
#include "qca_securemessage.h"
#include "qcaprovider.h"
#include "qpipe.h"
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,52 @@
/*
* qca_export.h - Qt Cryptographic Architecture
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**
\file qca_export.h
Preprocessor magic to allow export of library symbols.
This is strictly internal.
\note You should not include this header directly from an
application. You should just use <tt> \#include \<QtCrypto>
</tt> instead.
*/
#ifndef QCA_EXPORT_H
#define QCA_EXPORT_H
#include <QtGlobal>
#ifdef Q_OS_WIN
# ifndef QCA_STATIC
# ifdef QCA_MAKEDLL
# define QCA_EXPORT Q_DECL_EXPORT
# else
# define QCA_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
#ifndef QCA_EXPORT
# define QCA_EXPORT
#endif
#endif

View file

@ -0,0 +1,798 @@
/*
* qca_keystore.h - Qt Cryptographic Architecture
* Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com>
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**
\file qca_keystore.h
Header file for classes that provide and manage keys
\note You should not use this header directly from an
application. You should just use <tt> \#include \<QtCrypto>
</tt> instead.
*/
#ifndef QCA_KEYSTORE_H
#define QCA_KEYSTORE_H
#include "qca_core.h"
#include "qca_cert.h"
namespace QCA {
class KeyStoreTracker;
class KeyStoreManagerPrivate;
class KeyStorePrivate;
/**
\class KeyStoreEntry qca_keystore.h QtCrypto
Single entry in a KeyStore
This is a container for any kind of object in a KeyStore
(such as PGP keys, or X.509 certificates / private keys).
KeyStoreEntry objects are obtained through KeyStore or loaded from a
serialized string format. The latter method requires a KeyStoreEntry
obtained through KeyStore to be serialized for future loading. For
example:
\code
QString str = someKeyStoreEntry.toString();
[ app saves str to disk ]
[ app quits ]
...
[ app launches ]
[ app reads str from disk ]
KeyStoreEntry entry(str);
printf("Entry name: [%s]\n", qPrintable(entry.name()));
\endcode
KeyStoreEntry objects may or may not be available. An entry is
unavailable if it has a private content that is not present. The
private content might exist on external hardware. To determine if an
entry is available, call isAvailable(). To ensure an entry is available
before performing a private key operation, call ensureAvailable. For
example:
\code
if(entry.ensureAvailable())
{
entry.keyBundle().privateKey().signMessage(...);
...
}
\endcode
ensureAvailable() blocks and may cause hardware access, but
if it completes successfully then you may use the entry's private
content. It also means, in the case of a Smart Card token, that
it is probably inserted.
To watch this entry asynchronously, you would do:
\code
KeyStoreEntryWatcher *watcher = new KeyStoreEntryWatcher(entry);
connect(watcher, SIGNAL(available()), SLOT(entry_available()));
...
void entry_available()
{
// entry now available
watcher->entry().keyBundle().privateKey().signMessage(...);
}
\endcode
Unlike private content, public content is always usable even if the
entry is not available. Serialized entry data contains all of the
metadata necessary to reconstruct the public content.
Now, even though an entry may be available, it does not
mean you have access to use it for operations. For
example, even though a KeyBundle entry offered by a Smart Card
may be available, as soon as you try to use the PrivateKey object
for a signing operation, a PIN might be asked for. You can call
ensureAccess() if you want to synchronously provide the PIN
early on:
\code
if(entry.ensureAccess())
{
// do private key stuff
...
}
\endcode
Note that you don't have to call ensureAvailable() before
ensureAccess(). Calling the latter is enough to imply
both.
After an application is configured to use a particular key,
it is expected that its usual running procedure will be:
1) Construct KeyStoreEntry from the serialized data.
2) If the content object is not available, wait for it
(with either ensureAvailable() or KeyStoreEntryWatcher).
3) Pass the content object(s) to a high level operation like TLS.
In this case, any PIN prompting and private key operations
would be caused/handled from the TLS object. Omit step 2 and
the private key operations might cause token prompting.
\ingroup UserAPI
*/
class QCA_EXPORT KeyStoreEntry : public Algorithm
{
public:
/**
The type of entry in the KeyStore
*/
enum Type
{
TypeKeyBundle,
TypeCertificate,
TypeCRL,
TypePGPSecretKey,
TypePGPPublicKey
};
/**
Create an empty KeyStoreEntry
*/
KeyStoreEntry();
/**
Create a passive KeyStoreEntry based on a serialized
string
\param serialized the string containing the keystore entry information
\sa fromString
*/
KeyStoreEntry(const QString &serialized);
/**
Standard copy constructor
\param from the source entry
*/
KeyStoreEntry(const KeyStoreEntry &from);
~KeyStoreEntry();
/**
Standard assignment operator
\param from the source entry
*/
KeyStoreEntry & operator=(const KeyStoreEntry &from);
/**
Test if this key is empty (null)
*/
bool isNull() const;
/**
Test if the key is available for use.
A key is considered available if the key's private
content is present.
\sa ensureAvailable
\sa isAccessible
*/
bool isAvailable() const;
/**
Test if the key is currently accessible.
This means that the private key part can be used
at this time. For a smartcard, this means that all
required operations (e.g. login / PIN entry) are
completed.
If isAccessible() is true, then the key
is necessarily available (i.e. isAvailable() is
also true).
\sa ensureAccessible
\sa isAvailable
*/
bool isAccessible() const;
/**
Determine the type of key stored in this object
*/
Type type() const;
/**
The name associated with the key stored in this object
*/
QString name() const;
/**
The ID associated with the key stored in this object.
*/
QString id() const;
/**
The name of the KeyStore for this key object
*/
QString storeName() const;
/**
The id of the KeyStore for this key object
\sa KeyStore::id()
*/
QString storeId() const;
/**
Serialize into a string for use as a passive entry
*/
QString toString() const;
/**
Load a passive entry by using a serialized string
as input
\param serialized the string containing the keystore entry information
\return the newly created KeyStoreEntry
*/
static KeyStoreEntry fromString(const QString &serialized);
/**
If a KeyBundle is stored in this object, return that
bundle.
*/
KeyBundle keyBundle() const;
/**
If a Certificate is stored in this object, return that
certificate.
*/
Certificate certificate() const;
/**
If a CRL is stored in this object, return the value
of the CRL
*/
CRL crl() const;
/**
If the key stored in this object is a private
PGP key, return the contents of that key.
*/
PGPKey pgpSecretKey() const;
/**
If the key stored in this object is either an
public or private PGP key, extract the public key
part of that PGP key.
*/
PGPKey pgpPublicKey() const;
/**
Returns true if the entry is available, otherwise false.
Available means that any private content for this entry is
present and ready for use. In the case of a smart card, this
will ensure the card is inserted, and may invoke a token
prompt.
Calling this function on an already available entry may cause
the entry to be refreshed.
\sa isAvailable
\sa ensureAccess
\note This function is blocking.
\note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler.
*/
bool ensureAvailable();
/**
Like ensureAvailable, but will also ensure
that the PIN is provided if needed.
\sa isAccessible
\sa ensureAvailable
\note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler.
*/
bool ensureAccess();
private:
class Private;
Private *d;
friend class KeyStoreTracker;
};
/**
\class KeyStoreEntryWatcher qca_keystore.h QtCrypto
Class to monitor the availability of a KeyStoreEntry
Some KeyStore types have the concept of an entry that can be
available only part of the time (for example, a smart card that
can be removed). This class allows you to identify when a
KeyStoreEntry becomes available / unavailable.
\note You can also monitor availability of a whole KeyStore,
using KeyStoreManager::keyStoreAvailable() signal, and
the KeyStore::unavailable() signal.
\sa KeyStore for more discussion on availability of
keys and related objects.
\ingroup UserAPI
*/
class QCA_EXPORT KeyStoreEntryWatcher : public QObject
{
Q_OBJECT
public:
/**
Standard constructor.
This creates an object that monitors the specified KeyStore entry,
emitting available() and unavailable() as the entry becomes available
and unavailable respectively.
\param e the KeyStoreEntry to monitor
\param parent the parent object for this object
*/
explicit KeyStoreEntryWatcher(const KeyStoreEntry &e, QObject *parent = 0);
~KeyStoreEntryWatcher();
/**
The KeyStoreEntry that is being monitored
*/
KeyStoreEntry entry() const;
Q_SIGNALS:
/**
This signal is emitted when the entry that is being monitored
becomes available.
*/
void available();
/**
This signal is emitted when the entry that is being monitored
becomes unavailble.
*/
void unavailable();
private:
Q_DISABLE_COPY(KeyStoreEntryWatcher)
class Private;
friend class Private;
Private *d;
};
/**
\class KeyStore qca_keystore.h QtCrypto
General purpose key storage object
Examples of use of this are:
- systemstore: System TrustedCertificates
- accepted self-signed: Application TrustedCertificates
- apple keychain: User Identities
- smartcard: SmartCard Identities
- gnupg: PGPKeyring Identities,PGPPublicKeys
\note
- there can be multiple KeyStore objects referring to the same id
- when a KeyStore is constructed, it refers to a given id (deviceId)
and internal contextId. if the context goes away, the KeyStore
becomes invalid (isValid() == false), and unavailable() is emitted.
even if the device later reappears, the KeyStore remains invalid.
a new KeyStore will have to be created to use the device again.
\ingroup UserAPI
*/
class QCA_EXPORT KeyStore : public QObject, public Algorithm
{
Q_OBJECT
public:
/**
The type of keystore
*/
enum Type
{
System, ///< objects such as root certificates
User, ///< objects such as Apple Keychain, KDE Wallet
Application, ///< for caching accepted self-signed certificates
SmartCard, ///< for smartcards
PGPKeyring ///< for a PGP keyring
};
/**
Obtain a specific KeyStore
\param id the identification for the key store
\param keyStoreManager the parent manager for this keystore
*/
KeyStore(const QString &id, KeyStoreManager *keyStoreManager);
~KeyStore();
/**
Check if this KeyStore is valid
\return true if the KeyStore is valid
*/
bool isValid() const;
/**
The KeyStore Type
*/
Type type() const;
/**
The name associated with the KeyStore
*/
QString name() const;
/**
The ID associated with the KeyStore
*/
QString id() const;
/**
Test if the KeyStore is writeable or not
\return true if the KeyStore is read-only
*/
bool isReadOnly() const;
/**
Turns on asynchronous mode for this KeyStore instance.
Normally, entryList() and writeEntry() are blocking
calls. However, if startAsynchronousMode() is called,
then these functions will return immediately. entryList()
will return with the latest known entries, or an empty
list if none are known yet (in this mode, updated() will
be emitted once the initial entries are known, even if the
store has not actually been altered). writeEntry() will
always return an empty string, and the entryWritten()
signal indicates the result of a write.
*/
void startAsynchronousMode();
/**
A list of the KeyStoreEntry objects in this store
\note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler
(this is not a concern if asynchronous mode is enabled).
\sa startAsynchronousMode
*/
QList<KeyStoreEntry> entryList() const;
/**
test if the KeyStore holds trusted certificates (and CRLs)
*/
bool holdsTrustedCertificates() const;
/**
test if the KeyStore holds identities (eg KeyBundle or PGPSecretKey)
*/
bool holdsIdentities() const;
/**
test if the KeyStore holds PGPPublicKey objects
*/
bool holdsPGPPublicKeys() const;
/**
Add a entry to the KeyStore
Returns the entryId of the written entry or an empty
string on failure.
\param kb the KeyBundle to add to the KeyStore
\note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler
(this is not a concern if asynchronous mode is enabled).
\sa startAsynchronousMode
*/
QString writeEntry(const KeyBundle &kb);
/**
\overload
\param cert the Certificate to add to the KeyStore
*/
QString writeEntry(const Certificate &cert);
/**
\overload
\param crl the CRL to add to the KeyStore
*/
QString writeEntry(const CRL &crl);
/**
\overload
\param key the PGPKey to add to the KeyStore
\return a ref to the key in the keyring
*/
QString writeEntry(const PGPKey &key);
/**
Delete the a specified KeyStoreEntry from this KeyStore
\param id the ID for the entry to be deleted
\note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler
(this is not a concern if asynchronous mode is enabled).
\sa startAsynchronousMode
*/
bool removeEntry(const QString &id);
Q_SIGNALS:
/**
Emitted when the KeyStore is changed
This occurs if entries are added, removed, or changed in this
KeyStore, including changes in entry availability.
*/
void updated();
/**
Emitted when the KeyStore becomes unavailable
*/
void unavailable();
/**
Emitted when an entry has been written, in asynchronous
mode.
\param entryId is the newly written entry id on success,
or an empty string if the write failed.
*/
void entryWritten(const QString &entryId);
/**
Emitted when an entry has been removed, in asynchronous
mode.
\param success indicates if the removal succeeded (true) or not (false).
*/
void entryRemoved(bool success);
private:
Q_DISABLE_COPY(KeyStore)
friend class KeyStorePrivate;
KeyStorePrivate *d;
friend class KeyStoreManagerPrivate;
};
/**
\class KeyStoreInfo qca_keystore.h QtCrypto
Key store information, outside of a KeyStore object
This class is used in conjunction with the Event class,
and related classes such as PasswordAsker and TokenAsker,
to describe the key store source of the Event.
Each KeyStoreInfo represents a single KeyStore, and describes
the type of store (e.g. smartcard or PGP keyring - see
KeyStore::Type), and a couple of names. The id() of a KeyStore
is used to reference it, and is typically of the form
"qca-mystorename". The name() of a KeyStore is used to describe
it (i.e. this is the "pretty" name to show the user), and is
typically of the form "My Store Name".
\ingroup UserAPI
*/
class QCA_EXPORT KeyStoreInfo
{
public:
/**
Constructor.
\note This form of constructor for KeyStoreInfo
produces an object that does not describe any
KeyStore, and isNull() will return true.
*/
KeyStoreInfo();
/**
Standard constructor.
This builds a KeyStoreInfo object that descibes a
KeyStore.
\param type the type of KeyStore
\param id the identification of the KeyStore
\param name the descriptive name of the KeyStore
*/
KeyStoreInfo(KeyStore::Type type, const QString &id, const QString &name);
/**
Copy constructor.
\param from the KeyStoreInfo to copy from
*/
KeyStoreInfo(const KeyStoreInfo &from);
~KeyStoreInfo();
/**
Assignment operator.
\param from the KeyStoreInfo to copy from
*/
KeyStoreInfo & operator=(const KeyStoreInfo &from);
/**
Test if this object is valid
\return true if the object is not valid
*/
bool isNull() const;
/**
The Type of KeyStore that this KeyStoreInfo object
describes.
*/
KeyStore::Type type() const;
/**
The unique identification of the KeyStore that
this KeyStoreInfo object describes.
*/
QString id() const;
/**
The descriptive name of the KeyStore that this
KeyStoreInfo object describes.
*/
QString name() const;
private:
class Private;
QSharedDataPointer<Private> d;
};
/**
\class KeyStoreManager qca_keystore.h QtCrypto
Access keystores, and monitor keystores for changes.
Before you can access a KeyStore, you must create a
KeyStoreManager. You then need to start()
the KeyStoreManager, and either wait for the busyFinished()
signal, or block using waitForBusyFinished().
If you know the KeyStoreEntry that you need, you can
use KeyStore passively, as described in the KeyStoreEntry
documentation.
\ingroup UserAPI
*/
class QCA_EXPORT KeyStoreManager : public QObject
{
Q_OBJECT
public:
/**
Create a new KeyStoreManager
\param parent the parent for this object
*/
KeyStoreManager(QObject *parent = 0);
~KeyStoreManager();
/**
Initialize all key store providers
*/
static void start();
/**
Initialize a specific key store provider
\param provider the name of the provider to start
*/
static void start(const QString &provider);
/**
Indicates if the manager is busy looking for key stores
*/
bool isBusy() const;
/**
Blocks until the manager is done looking for key stores
*/
void waitForBusyFinished();
/**
A list of all the key stores
*/
QStringList keyStores() const;
/**
The diagnostic result of key store operations, such as
warnings and errors
*/
static QString diagnosticText();
/**
Clears the diagnostic result log
*/
static void clearDiagnosticText();
/**
If you are not using the eventloop, call this to update
the object state to the present
*/
void sync();
Q_SIGNALS:
/**
emitted when the manager has started looking for key stores
*/
void busyStarted();
/**
emitted when the manager has finished looking for key stores
*/
void busyFinished();
/**
emitted when a new key store becomes available
\param id the name of the key store that has become available
*/
void keyStoreAvailable(const QString &id);
private:
Q_DISABLE_COPY(KeyStoreManager)
friend class KeyStoreManagerPrivate;
KeyStoreManagerPrivate *d;
friend class Global;
friend class KeyStorePrivate;
static void scan();
static void shutdown();
};
}
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,955 @@
/*
* qca_securemessage.h - Qt Cryptographic Architecture
* Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com>
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**
\file qca_securemessage.h
Header file for secure message (PGP, CMS) classes
\note You should not use this header directly from an
application. You should just use <tt> \#include \<QtCrypto>
</tt> instead.
*/
#ifndef QCA_SECUREMESSAGE_H
#define QCA_SECUREMESSAGE_H
#include <QObject>
#include "qca_core.h"
#include "qca_publickey.h"
#include "qca_cert.h"
class QDateTime;
namespace QCA {
class SecureMessageSystem;
/**
\class SecureMessageKey qca_securemessage.h QtCrypto
Key for SecureMessage system
\ingroup UserAPI
*/
class QCA_EXPORT SecureMessageKey
{
public:
/**
The key type
*/
enum Type
{
None, ///< no key
PGP, ///< Pretty Good Privacy key
X509 ///< X.509 CMS key
};
/**
Construct an empty key
*/
SecureMessageKey();
/**
Standard copy constructor
\param from the source key
*/
SecureMessageKey(const SecureMessageKey &from);
~SecureMessageKey();
/**
Standard assignment operator
\param from the source key
*/
SecureMessageKey & operator=(const SecureMessageKey &from);
/**
Returns true for null object
*/
bool isNull() const;
/**
The key type
*/
Type type() const;
/**
Public key part of a PGP key
*/
PGPKey pgpPublicKey() const;
/**
Private key part of a PGP key
*/
PGPKey pgpSecretKey() const;
/**
Set the public key part of a PGP key
\param pub the PGP public key
*/
void setPGPPublicKey(const PGPKey &pub);
/**
Set the private key part of a PGP key
\param sec the PGP secretkey
*/
void setPGPSecretKey(const PGPKey &sec);
/**
The X.509 certificate chain (public part) for this key
*/
CertificateChain x509CertificateChain() const;
/**
The X.509 private key part of this key
*/
PrivateKey x509PrivateKey() const;
/**
Set the public key part of this X.509 key.
\param c the Certificate chain containing the public keys
*/
void setX509CertificateChain(const CertificateChain &c);
/**
Set the private key part of this X.509 key.
\param k the private key
*/
void setX509PrivateKey(const PrivateKey &k);
/**
Set the public and private part of this X.509 key with KeyBundle.
\param kb the public and private key bundle
*/
void setX509KeyBundle(const KeyBundle &kb);
/**
Test if this key contains a private key part
*/
bool havePrivate() const;
/**
The name associated with this key
For a PGP key, this is the primary user ID
For an X.509 key, this is the Common Name
*/
QString name() const;
private:
class Private;
QSharedDataPointer<Private> d;
};
/**
A list of message keys
*/
typedef QList<SecureMessageKey> SecureMessageKeyList;
/**
\class SecureMessageSignature qca_securemessage.h QtCrypto
SecureMessage signature
\ingroup UserAPI
*/
class QCA_EXPORT SecureMessageSignature
{
public:
/**
The result of identity verification
*/
enum IdentityResult
{
Valid, ///< indentity is verified, matches signature
InvalidSignature, ///< valid key provided, but signature failed
InvalidKey, ///< invalid key provided
NoKey ///< identity unknown
};
/**
Create an empty signature check object.
User applications don't normally need to create signature checks. You normally
get the object back as a result of a SecureMessage operation.
*/
SecureMessageSignature();
/**
Create a signature check object
User applications don't normally need to create signature checks. You normally
get the object back as a result of a SecureMessage operation.
\param r the result of the check
\param v the Validity of the key validation check
\param key the key associated with the signature
\param ts the timestamp associated with the signature
*/
SecureMessageSignature(IdentityResult r, Validity v, const SecureMessageKey &key, const QDateTime &ts);
/**
Standard copy constructor
\param from the source signature object
*/
SecureMessageSignature(const SecureMessageSignature &from);
~SecureMessageSignature();
/**
Standard assignment operator
\param from the source signature object
*/
SecureMessageSignature & operator=(const SecureMessageSignature &from);
/**
get the results of the identity check on this signature
*/
IdentityResult identityResult() const;
/**
get the results of the key validation check on this signature
*/
Validity keyValidity() const;
/**
get the key associated with this signature
*/
SecureMessageKey key() const;
/**
get the timestamp associated with this signature
*/
QDateTime timestamp() const;
private:
class Private;
QSharedDataPointer<Private> d;
};
/**
A list of signatures
*/
typedef QList<SecureMessageSignature> SecureMessageSignatureList;
/**
\class SecureMessage qca_securemessage.h QtCrypto
Class representing a secure message
SecureMessage presents a unified interface for working with both
OpenPGP and CMS (S/MIME) messages. Prepare the object by calling
setFormat(), setRecipient(), and setSigner() as necessary, and then
begin the operation by calling an appropriate 'start' function, such
as startSign().
Here is an example of how to perform a Clearsign operation using PGP:
\code
// first make the SecureMessageKey
PGPKey myPGPKey = getSecretKeyFromSomewhere();
SecureMessageKey key;
key.setPGPSecretKey(myPGPKey);
// our data to sign
QByteArray plain = "Hello, world";
// let's do it
OpenPGP pgp;
SecureMessage msg(&pgp);
msg.setSigner(key);
msg.startSign(SecureMessage::Clearsign);
msg.update(plain);
msg.end();
msg.waitForFinished(-1);
if(msg.success())
{
QByteArray result = msg.read();
// result now contains the clearsign text data
}
else
{
// error
...
}
\endcode
Performing a CMS sign operation is similar. Simply set up the
SecureMessageKey with a Certificate instead of a PGPKey, and operate on a
CMS object instead of an OpenPGP object.
\sa SecureMessageKey
\sa SecureMessageSignature
\sa OpenPGP
\sa CMS
\ingroup UserAPI
*/
class QCA_EXPORT SecureMessage : public QObject, public Algorithm
{
Q_OBJECT
public:
/**
The type of secure message
*/
enum Type
{
OpenPGP, ///< a Pretty Good Privacy message
CMS ///< a Cryptographic Message Syntax message
};
/**
The type of message signature
*/
enum SignMode
{
Message, ///< the message includes the signature
Clearsign, ///< the message is clear signed
Detached ///< the signature is detached
};
/**
Formats for secure messages
*/
enum Format
{
Binary, ///< DER/binary
Ascii ///< PEM/ascii-armored
};
/**
Errors for secure messages
*/
enum Error
{
ErrorPassphrase, ///< passphrase was either wrong or not provided
ErrorFormat, ///< input format was bad
ErrorSignerExpired, ///< signing key is expired
ErrorSignerInvalid, ///< signing key is invalid in some way
ErrorEncryptExpired, ///< encrypting key is expired
ErrorEncryptUntrusted, ///< encrypting key is untrusted
ErrorEncryptInvalid, ///< encrypting key is invalid in some way
ErrorNeedCard, ///< pgp card is missing
ErrorCertKeyMismatch, ///< certificate and private key don't match
ErrorUnknown ///< other error
};
/**
Create a new secure message
This constructor uses an existing
SecureMessageSystem object (for example, an OpenPGP
or CMS object) to generate a specific kind of
secure message.
\param system a pre-existing and configured SecureMessageSystem
object
*/
SecureMessage(SecureMessageSystem *system);
~SecureMessage();
/**
The Type of secure message
*/
Type type() const;
/**
Test if the message type supports multiple
(parallel) signatures.
\return true if the secure message support multiple
parallel signatures
\note PGP cannot do this - it is primarily a CMS
feature
*/
bool canSignMultiple() const;
/**
True if the SecureMessageSystem can clearsign
messages.
\note CMS cannot clearsign - this is normally only
available for PGP
*/
bool canClearsign() const;
/**
True if the SecureMessageSystem can both sign and
encrypt (in the same operation).
\note CMS cannot do an integrated sign/encrypt -
this is normally only available for PGP. You can do
separate signing and encrypting operations on the
same message with CMS though.
*/
bool canSignAndEncrypt() const;
/**
Reset the object state to that of original construction.
Now a new operation can be performed immediately.
*/
void reset();
/**
Returns true if bundling of the signer certificate chain is
enabled
*/
bool bundleSignerEnabled() const;
/**
Returns true if inclusion of S/MIME attributes is enabled
*/
bool smimeAttributesEnabled() const;
/**
Return the format type set for this message
*/
Format format() const;
/**
Return the recipient(s) set for this message with setRecipient() or
setRecipients()
*/
SecureMessageKeyList recipientKeys() const;
/**
Return the signer(s) set for this message with setSigner() or
setSigners()
*/
SecureMessageKeyList signerKeys() const;
/**
For CMS only, this will bundle the signer certificate chain
into the message. This allows a message to be verified
on its own, without the need to have obtained the signer's
certificate in advance. Email clients using S/MIME often
bundle the signer, greatly simplifying key management.
This behavior is enabled by default.
\param b whether to bundle (if true) or not (false)
*/
void setBundleSignerEnabled(bool b);
/**
For CMS only, this will put extra attributes into the
message related to S/MIME, such as the preferred
type of algorithm to use in replies. The attributes
used are decided by the provider.
This behavior is enabled by default.
\param b whether to embed extra attribues (if true) or not (false)
*/
void setSMIMEAttributesEnabled(bool b);
/**
Set the Format used for messages
The default is Binary.
\param f whether to use Binary or Ascii
*/
void setFormat(Format f);
/**
Set the recipient for an encrypted message
\param key the recipient's key
\sa setRecipients
*/
void setRecipient(const SecureMessageKey &key);
/**
Set the list of recipients for an encrypted message.
For a list with one item, this has the same effect as setRecipient.
\param keys the recipients' key
\sa setRecipient
*/
void setRecipients(const SecureMessageKeyList &keys);
/**
Set the signer for a signed message.
This is used for both creating signed messages as well as for
verifying CMS messages that have no signer bundled.
\param key the key associated with the signer
\sa setSigners
*/
void setSigner(const SecureMessageKey &key);
/**
Set the list of signers for a signed message.
This is used for both creating signed messages as well as for
verifying CMS messages that have no signer bundled.
For a list with one item, this has the same effect as setSigner.
\param keys the key associated with the signer
\sa setSigner
*/
void setSigners(const SecureMessageKeyList &keys);
/**
Start an encryption operation
You will normally use this with some code along
these lines:
\code
encryptingObj.startEncrypt();
encryptingObj.update(message);
// perhaps some more update()s
encryptingObj.end();
\endcode
Each update() may (or may not) result in some
encrypted data, as indicated by the readyRead()
signal being emitted. Alternatively, you can wait
until the whole message is available (using either
waitForFinished(), or use the finished()
signal. The encrypted message can then be read
using the read() method.
*/
void startEncrypt();
/**
Start an decryption operation
You will normally use this with some code along
these lines:
\code
decryptingObj.startEncrypt();
decryptingObj.update(message);
// perhaps some more update()s
decryptingObj.end();
\endcode
Each update() may (or may not) result in some
decrypted data, as indicated by the readyRead()
signal being emitted. Alternatively, you can wait
until the whole message is available (using either
waitForFinished(), or the finished()
signal). The decrypted message can then be read
using the read() method.
\note If decrypted result is also signed (not for
CMS), then the signature will be verified during
this operation.
*/
void startDecrypt();
/**
Start a signing operation
You will normally use this with some code along
these lines:
\code
signingObj.startSign(QCA::SecureMessage::Detached)
signingObj.update(message);
// perhaps some more update()s
signingObj.end();
\endcode
For Detached signatures, you won't get any results
until the whole process is done - you either
waitForFinished(), or use the finished() signal, to
figure out when you can get the signature (using
the signature() method, not using read()). For
other formats, you can use the readyRead() signal
to determine when there may be part of a signed
message to read().
\param m the mode that will be used to generate the
signature
*/
void startSign(SignMode m = Message);
/**
Start a verification operation
\param detachedSig the detached signature to
verify. Do not pass a signature for other signature
types.
*/
void startVerify(const QByteArray &detachedSig = QByteArray());
/**
Start a combined signing and encrypting
operation. You use this in the same way as
startEncrypt().
\note This may not be possible (e.g. CMS
cannot do this) - see canSignAndEncrypt() for a
suitable test.
*/
void startSignAndEncrypt();
/**
Process a message (or the next part of a message)
in the current operation. You need to have already
set up the message (startEncrypt(), startDecrypt(),
startSign(), startSignAndEncrypt() and
startVerify()) before calling this method.
\param in the data to process
*/
void update(const QByteArray &in);
/**
Read the available data.
\note For detached signatures, you don't get
anything back using this method. Use signature() to
get the detached signature().
*/
QByteArray read();
/**
The number of bytes available to be read.
*/
int bytesAvailable() const;
/**
Complete an operation.
You need to call this method after you have
processed the message (which you pass in as the
argument to update().
\note the results of the operation are not
available as soon as this method returns. You need
to wait for the finished() signal, or use
waitForFinished().
*/
void end();
/**
Block until the operation (encryption, decryption,
signing or verifying) completes.
\param msecs the number of milliseconds to wait for
the operation to complete. Pass -1 to wait
indefinitely.
\note You should not use this in GUI
applications where the blocking behaviour looks
like a hung application. Instead, connect the
finished() signal to a slot that handles the
results.
\note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler.
*/
bool waitForFinished(int msecs = 30000);
/**
Indicates whether or not the operation was successful
or failed. If this function returns false, then
the reason for failure can be obtained with errorCode().
\sa errorCode
\sa diagnosticText
*/
bool success() const;
/**
Returns the failure code.
\sa success
\sa diagnosticText
*/
Error errorCode() const;
/**
The signature for the message. This is only used
for Detached signatures. For other message types,
you get the message and signature together using
read().
*/
QByteArray signature() const;
/**
The name of the hash used for the signature process
*/
QString hashName() const;
/**
Test if the message was signed.
This is true for OpenPGP if the decrypted message
was also signed.
\return true if the message was signed.
*/
bool wasSigned() const;
/**
Verify that the message signature is correct.
\return true if the signature is valid for the
message, otherwise return false
*/
bool verifySuccess() const;
/**
Information on the signer for the message
*/
SecureMessageSignature signer() const;
/**
Information on the signers for the message.
This is only meaningful if the message type supports
multiple signatures (see canSignMultiple() for a
suitable test).
*/
SecureMessageSignatureList signers() const;
/**
Returns a log of technical information about the operation,
which may be useful for presenting to the user in an
advanced error dialog.
*/
QString diagnosticText() const;
Q_SIGNALS:
/**
This signal is emitted when there is some data to
read. Typically you connect this signal to a slot
that does a read() of the available data.
\note This signal does not mean that the processing
of a message is necessarily complete - see
finished().
*/
void readyRead();
/**
This signal is emitted when data has been accepted
by the message processor.
\param bytes the number of bytes written
*/
void bytesWritten(int bytes);
/**
This signal is emitted when the message is fully
processed.
*/
void finished();
private:
Q_DISABLE_COPY(SecureMessage)
class Private;
friend class Private;
Private *d;
};
/**
\class SecureMessageSystem qca_securemessage.h QtCrypto
Abstract superclass for secure messaging systems
\sa SecureMessage
\sa SecureMessageKey
\ingroup UserAPI
*/
class QCA_EXPORT SecureMessageSystem : public QObject, public Algorithm
{
Q_OBJECT
public:
~SecureMessageSystem();
protected:
/**
Protected constructor for SecureMessageSystem
classes. You are meant to be using a subclass (such
as OpenPGP or CMS) - you only need to worry about
this class if you are creating a whole new
SecureMessageSystem type.
\param parent the parent object for this object
\param type the name of the Type of
SecureMessageSystem to create
\param provider the provider to use, if a specific
provider is required.
*/
SecureMessageSystem(QObject *parent, const QString &type, const QString &provider);
private:
Q_DISABLE_COPY(SecureMessageSystem)
};
/**
\class OpenPGP qca_securemessage.h QtCrypto
Pretty Good Privacy messaging system
\sa SecureMessage
\sa SecureMessageKey
\ingroup UserAPI
*/
class QCA_EXPORT OpenPGP : public SecureMessageSystem
{
Q_OBJECT
public:
/**
Standard constructor
\param parent the parent object for this object
\param provider the provider to use, if a specific
provider is required
*/
explicit OpenPGP(QObject *parent = 0, const QString &provider = QString());
~OpenPGP();
private:
Q_DISABLE_COPY(OpenPGP)
class Private;
Private *d;
};
/**
\class CMS qca_securemessage.h QtCrypto
Cryptographic Message Syntax messaging system
Cryptographic Message Syntax (%CMS) "is used to digitally
sign, digest, authenticate, or encrypt arbitrary message
content. The %CMS describes an encapsulation syntax for
data protection. It supports digital signatures and
encryption. The syntax allows multiple encapsulations; one
encapsulation envelope can be nested inside another.
Likewise, one party can digitally sign some previously
encapsulated data. It also allows arbitrary attributes,
such as signing time, to be signed along with the message
content, and provides for other attributes such as
countersignatures to be associated with a signature." (from
<a href="http://www.ietf.org/rfc/rfc3852.txt">RFC3852</a>
"Cryptographic Message Syntax")
\sa SecureMessage
\sa SecureMessageKey
\ingroup UserAPI
*/
class QCA_EXPORT CMS : public SecureMessageSystem
{
Q_OBJECT
public:
/**
Standard constructor
\param parent the parent object for this object
\param provider the provider to use, if a specific
provider is required
*/
explicit CMS(QObject *parent = 0, const QString &provider = QString());
~CMS();
/**
Return the trusted certificates set for this object
*/
CertificateCollection trustedCertificates() const;
/**
Return the untrusted certificates set for this object
*/
CertificateCollection untrustedCertificates() const;
/**
Return the private keys set for this object
*/
SecureMessageKeyList privateKeys() const;
/**
Set the trusted certificates to use for the
messages built using this CMS object.
\param trusted the collection of trusted
certificates to use
*/
void setTrustedCertificates(const CertificateCollection &trusted);
/**
Set the untrusted certificates to use for the
messages built using this CMS object.
This function is useful when verifying messages that don't
contain the certificates (or intermediate signers) within
the CMS blob. In order to verify such messages, you'll
have to pass the possible signer certs with this function.
\param untrusted the collection of untrusted
certificates to use
*/
void setUntrustedCertificates(const CertificateCollection &untrusted);
/**
Set the private keys to use for the messages built
using this CMS object.
Keys are required for decrypting and signing (not
for encrypting or verifying).
\param keys the collection of keys to use
*/
void setPrivateKeys(const SecureMessageKeyList &keys);
private:
Q_DISABLE_COPY(CMS)
class Private;
Private *d;
};
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,327 @@
/*
* qca_textfilter.h - Qt Cryptographic Architecture
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**
\file qca_textfilter.h
Header file for text encoding/decoding classes
\note You should not use this header directly from an
application. You should just use <tt> \#include \<QtCrypto>
</tt> instead.
*/
#ifndef QCA_TEXTFILTER_H
#define QCA_TEXTFILTER_H
#include "qca_core.h"
namespace QCA {
/**
\class TextFilter qca_textfilter.h QtCrypto
Superclass for text based filtering algorithms
This differs from Filter in that it has the concept
of an algorithm that works in two directions, and
supports operations on QString arguments.
\ingroup UserAPI
*/
class QCA_EXPORT TextFilter : public Filter
{
public:
/**
Standard constructor
\param dir the Direction that this TextFilter
should use.
*/
TextFilter(Direction dir);
/**
Reset the TextFilter
\param dir the Direction that this TextFilter
should use.
*/
void setup(Direction dir);
/**
The direction the TextFilter is set up to use
*/
Direction direction() const;
/**
Process an array in the "forward" direction,
returning an array
This method runs in the forward direction, so
for something like a Base64 encoding, it takes
the "native" array, and returns that array
encoded in base64.
\param a the array to encode
*/
MemoryRegion encode(const MemoryRegion &a);
/**
Process an array in the "reverse" direction,
returning an array
This method runs in the reverse direction, so
for something like a Base64 encoding, it takes
a Base64 encoded array, and returns the "native"
representation.
\param a the array to decode
*/
MemoryRegion decode(const MemoryRegion &a);
/**
Process an array in the "forward" direction,
returning a QString
This is equivalent to encode(), except
that it returns a QString, rather than a
byte array.
\param a the array to encode
*/
QString arrayToString(const MemoryRegion &a);
/**
Process an string in the "reverse" direction,
returning a byte array
This is equivalent to decode(), except
that it takes a QString, rather than a
byte array.
\param s the array to decode
*/
MemoryRegion stringToArray(const QString &s);
/**
Process a string in the "forward" direction,
returning a string
This is equivalent to encode(), except
that it takes and returns a QString, rather than
byte arrays.
\param s the string to encode
*/
QString encodeString(const QString &s);
/**
Process a string in the "reverse" direction,
returning a string
This is equivalent to decode(), except
that it takes and returns a QString, rather than
byte arrays.
\param s the string to decode
*/
QString decodeString(const QString &s);
protected:
/**
Internal state variable for the Direction
that the filter operates in
*/
Direction _dir;
};
/**
\class Hex qca_textfilter.h QtCrypto
Hexadecimal encoding / decoding
\ingroup UserAPI
*/
class QCA_EXPORT Hex : public TextFilter
{
public:
/**
Standard constructor
\param dir the Direction that should be used.
\note The direction can be changed using
the setup() call.
*/
Hex(Direction dir = Encode);
/**
Reset the internal state.
This is useful to reuse an existing Hex object
*/
virtual void clear();
/**
Process more data, returning the corresponding
encoded or decoded (depending on the Direction
set in the constructor or setup() call) representation.
If you find yourself with code that only calls
this method once, you might be better off using
encode() or decode(). Similarly, if the data is
really a string, you might be better off using
arrayToString(), encodeString(), stringToArray()
or decodeString().
\param a the array containing data to process
*/
virtual MemoryRegion update(const MemoryRegion &a);
/**
Complete the algorithm
\return any remaining output. Because of the way
hexadecimal encoding works, this will return a
zero length array - any output will have been returned
from the update() call.
*/
virtual MemoryRegion final();
/**
Test if an update() or final() call succeeded.
\return true if the previous call succeeded
*/
virtual bool ok() const;
private:
Q_DISABLE_COPY(Hex)
uchar val;
bool partial;
bool _ok;
};
/**
\class Base64 qca_textfilter.h QtCrypto
%Base64 encoding / decoding
\ingroup UserAPI
*/
class QCA_EXPORT Base64 : public TextFilter
{
public:
/**
Standard constructor
\param dir the Direction that should be used.
\note The direction can be changed using
the setup() call.
*/
Base64(Direction dir = Encode);
/**
Returns true if line breaks are enabled
*/
bool lineBreaksEnabled() const;
/**
Returns the line break column
*/
int lineBreaksColumn() const;
/**
Sets line break mode. If enabled, linebreaks will be
added to encoded output or accepted in encoded input.
If disabled, linebreaks in encoded input will cause
a failure to decode. The default is disabled.
\param b whether to enable line breaks (true) or disable line breaks (false)
*/
void setLineBreaksEnabled(bool b);
/**
Sets the column that linebreaks should be inserted at
when encoding.
\param column the column number that line breaks should be inserted at.
*/
void setLineBreaksColumn(int column);
/**
Reset the internal state. This is useful to
reuse an existing Base64 object
*/
virtual void clear();
/**
Process more data, returning the corresponding
encoded or decoded (depending on the Direction
set in the constructor or setup() call) representation.
If you find yourself with code that only calls
this method once, you might be better off using
encode() or decode(). Similarly, if the data is
really a string, you might be better off using
arrayToString(), encodeString(), stringToArray()
or decodeString().
\param a the array containing data to process
*/
virtual MemoryRegion update(const MemoryRegion &a);
/**
Complete the algorithm
\return any remaining output. Because of the way
Base64 encoding works, you will get either an
empty array, or an array containing one or two
"=" (equals, 0x3D) characters.
*/
virtual MemoryRegion final();
/**
Test if an update() or final() call succeeded.
\return true if the previous call succeeded
*/
virtual bool ok() const;
private:
Q_DISABLE_COPY(Base64)
QByteArray partial;
bool _ok;
int col;
bool _lb_enabled;
int _lb_column;
class Private;
Private *d;
};
}
#endif

View file

@ -0,0 +1,853 @@
/*
* qca_tools.h - Qt Cryptographic Architecture
* Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com>
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**
\file qca_tools.h
Header file for "tool" classes used in %QCA
These classes differ from those in qca_support.h, in that they have
some cryptographic relationship, and require secure memory.
\note You should not use this header directly from an
application. You should just use <tt> \#include \<QtCrypto>
</tt> instead.
*/
#ifndef QCA_TOOLS_H
#define QCA_TOOLS_H
#include <QSharedData>
#include <QSharedDataPointer>
#include <QMetaType>
#include "qca_export.h"
class QString;
class QByteArray;
class QTextStream;
/**
Allocate a block of memory from the secure memory pool.
This is intended to be used when working with C libraries.
\param bytes the number of bytes to allocate
*/
QCA_EXPORT void *qca_secure_alloc(int bytes);
/**
Free (de-allocate) a block of memory that has been previously
allocated from the secure memory pool.
This is intended to be used when working with C libraries.
\param p pointer to the block of memory to be free'd
*/
QCA_EXPORT void qca_secure_free(void *p);
/**
Resize (re-allocate) a block of memory that has been previously
allocated from the secure memory pool.
\param p pointer to the block of memory to be resized.
\param bytes the new size that is required.
*/
QCA_EXPORT void *qca_secure_realloc(void *p, int bytes);
namespace QCA {
/**
\class MemoryRegion qca_tools.h QtCrypto
Array of bytes that may be optionally secured
This class is mostly unusable on its own. Either use it as a SecureArray
subclass or call toByteArray() to convert to QByteArray.
Note that this class is implicitly shared (that is, copy on write).
\ingroup UserAPI
*/
class QCA_EXPORT MemoryRegion
{
public:
MemoryRegion();
/**
Constructs a new Memory Region from a null terminated
character array
\param str pointer to the array of data to copy
*/
MemoryRegion(const char *str);
/**
Constructs a new MemoryRegion from the data in a
byte array
\param from the QByteArray to copy from
*/
MemoryRegion(const QByteArray &from);
/**
Standard copy constructor
\param from the MemoryRegion to copy from
*/
MemoryRegion(const MemoryRegion &from);
~MemoryRegion();
/**
Standard assignment operator
\param from the MemoryRegion to copy from
*/
MemoryRegion & operator=(const MemoryRegion &from);
/**
Standard assignment operator
\param from the QByteArray to copy from
*/
MemoryRegion & operator=(const QByteArray &from);
/**
Test if the MemoryRegion is null (i.e. was created
as a null array, and hasn't been resized).
This is probably not what you are trying to do. If
you are trying to determine whether there are any
bytes in the array, use isEmpty() instead.
*/
bool isNull() const;
/**
Test if the MemoryRegion is using secure memory, or not.
In this context, memory is secure if it will not be paged
out to disk.
\return true if the memory region is secure
*/
bool isSecure() const;
/**
Convert this memory region to a byte array.
\note For secure data, this will make it insecure
\sa data() and constData() for other ways to convert
to an "accessible" format.
*/
QByteArray toByteArray() const;
/**
Returns true if the size of the memory region is zero.
*/
bool isEmpty() const;
/**
Returns the number of bytes in the memory region.
*/
int size() const;
/**
Convert the contents of the memory region to
a C-compatible character array. This consists
of size() bytes, followed by a null terminator.
\sa toByteArray for an alternative approach.
\sa constData, which is equivalent to this method, but avoids
the possibility that the compiler picks the wrong version.
*/
const char *data() const;
/**
Convert the contents of the memory region to
a C-compatible character array. This consists
of size() bytes, followed by a null terminator.
\sa toByteArray for an alternative approach.
\sa data which is equivalent to this method
*/
const char *constData() const;
/**
Obtain the value of the memory location at the specified
position.
\param index the offset into the memory region.
\note The contents of a memory region are between
0 and size()-1. The content at position size() is
always a null terminator.
*/
const char & at(int index) const;
protected:
/**
Create a memory region, optionally using secure
storage.
\param secure if this is true, the memory region
will use secure storage.
\note This will create a memory region without
any content (i.e. both isNull() and isEmpty() will
return true.
*/
MemoryRegion(bool secure);
/**
Create a memory region, optionally using secure
storage.
\param size the number of bytes in the memory
region.
\param secure if this is true, the memory region
will use secure storage.
*/
MemoryRegion(int size, bool secure);
/**
Create a memory region, optionally using secure
storage.
This constructor variant allows you to
initialize the memory region from an existing
array.
\param from the byte array to copy from.
\param secure if this is true, the memory region
will use secure storage.
*/
MemoryRegion(const QByteArray &from, bool secure);
/**
Convert the contents of the memory region to
a C-compatible character array. This consists
of size() bytes, followed by a null terminator.
*/
char *data();
/**
Obtain the value of the memory location at the specified
position.
\param index the offset into the memory region.
\note The contents of a memory region are between
0 and size()-1. The content at position size() is
always a null terminator.
*/
char & at(int index);
/**
Resize the memory region to the specified size.
\param size the new size of the region.
*/
bool resize(int size);
/**
Modify the memory region to match a specified
byte array. This resizes the memory region
as required to match the byte array size.
\param from the byte array to copy from.
\param secure if this is true, the memory region
will use secure storage.
*/
void set(const QByteArray &from, bool secure);
/**
Convert the memory region to use the specified
memory type.
This may involve copying data from secure to
insecure storage, or from insecure to secure
storage.
\param secure if true, use secure memory; otherwise
use insecure memory.
*/
void setSecure(bool secure);
private:
bool _secure;
class Private;
QSharedDataPointer<Private> d;
};
/**
\class SecureArray qca_tools.h QtCrypto
Secure array of bytes
The %SecureArray provides an array of memory from a pool that is,
at least partly, secure. In this sense, secure means that the contents
of the memory should not be made available to other applications. By
comparison, a QByteArray or QString may be held in pages that might be
swapped to disk or free'd without being cleared first.
Note that this class is implicitly shared (that is, copy on write).
\ingroup UserAPI
*/
class QCA_EXPORT SecureArray : public MemoryRegion
{
public:
/**
Construct a secure byte array, zero length
*/
SecureArray();
/**
Construct a secure byte array of the specified length
\param size the number of bytes in the array
\param ch the value every byte should be set to
*/
explicit SecureArray(int size, char ch = 0);
/**
Construct a secure byte array from a string
Note that this copies, rather than references the source array.
\param str the source of the data (as a null terminated string).
*/
SecureArray(const char *str);
/**
Construct a secure byte array from a QByteArray
Note that this copies, rather than references the source array.
\param a the source of the data.
\sa operator=()
*/
SecureArray(const QByteArray &a);
/**
Construct a secure byte array from a MemoryRegion
Note that this copies, rather than references the source array
\param a the source of the data.
\sa operator=()
*/
SecureArray(const MemoryRegion &a);
/**
Construct a (shallow) copy of another secure byte array
\param from the source of the data and length.
*/
SecureArray(const SecureArray &from);
~SecureArray();
/**
Creates a reference, rather than a deep copy.
\param from the array to reference
*/
SecureArray & operator=(const SecureArray &from);
/**
Creates a copy, rather than references
\param a the array to copy from
*/
SecureArray & operator=(const QByteArray &a);
/**
Clears the contents of the array and makes it empty
*/
void clear();
/**
Returns a reference to the byte at the index position
\param index the zero-based offset to obtain
*/
char & operator[](int index);
/**
Returns a reference to the byte at the index position
\param index the zero-based offset to obtain
*/
const char & operator[](int index) const;
/**
Pointer to the data in the secure array
You can use this for memcpy and similar functions. If you are trying
to obtain data at a particular offset, you might be better off using
at() or operator[]
*/
char *data();
/**
Pointer to the data in the secure array
You can use this for memcpy and similar functions. If you are trying
to obtain data at a particular offset, you might be better off using
at() or operator[]
*/
const char *data() const;
/**
Pointer to the data in the secure array
You can use this for memcpy and similar functions. If you are trying
to obtain data at a particular offset, you might be better off using
at() or operator[]
*/
const char *constData() const;
/**
Returns a reference to the byte at the index position
\param index the zero-based offset to obtain
*/
char & at(int index);
/**
Returns a reference to the byte at the index position
\param index the zero-based offset to obtain
*/
const char & at(int index) const;
/**
Returns the number of bytes in the array
*/
int size() const;
/**
Test if the array contains any bytes.
This is equivalent to testing (size() != 0). Note that if
the array is allocated, isEmpty() is false (even if no data
has been added)
\return true if the array has zero length, otherwise false
*/
bool isEmpty() const;
/**
Change the length of this array
If the new length is less than the old length, the extra information
is (safely) discarded. If the new length is equal to or greater than
the old length, the existing data is copied into the array.
\param size the new length
*/
bool resize(int size);
/**
Fill the data array with a specified character
\param fillChar the character to use as the fill
\param fillToPosition the number of characters to fill
to. If not specified (or -1), fills array to
current length.
\note This function does not extend the array - if
you ask for fill beyond the current length, only
the current length will be used.
\note The number of characters is 1 based, so if
you ask for fill('x', 10), it will fill from
*/
void fill(char fillChar, int fillToPosition = -1);
/**
Copy the contents of the secure array out to a
standard QByteArray. Note that this performs a deep copy
of the data.
*/
QByteArray toByteArray() const;
/**
Append a secure byte array to the end of this array
\param a the array to append to this array
*/
SecureArray & append(const SecureArray &a);
/**
Equality operator. Returns true if both arrays have the same
data (and the same length, of course).
\param other the MemoryRegion to compare to
*/
bool operator==(const MemoryRegion &other) const;
/**
Inequality operator. Returns true if both arrays have different
length, or the same length but different data.
\param other the MemoryRegion to compare to
*/
inline bool operator!=(const MemoryRegion &other) const
{
return !(*this == other);
}
/**
Append a secure byte array to the end of this array
\param a the array to append to this array
*/
SecureArray & operator+=(const SecureArray &a);
protected:
/**
Assign the contents of a provided byte array to this
object.
\param from the byte array to copy
*/
void set(const SecureArray &from);
/**
Assign the contents of a provided byte array to this
object.
\param from the byte array to copy
*/
void set(const QByteArray &from);
};
/**
Returns an array that is the result of concatenating a and b
\param a the string to put at the start of the result
\param b the string to put at the end of the result
*/
QCA_EXPORT const SecureArray operator+(const SecureArray &a, const SecureArray &b);
/**
\class BigInteger qca_tools.h QtCrypto
Arbitrary precision integer
BigInteger provides arbitrary precision integers.
\code
if ( BigInteger("3499543804349") ==
BigInteger("38493290803248") + BigInteger( 343 ) )
{
// do something
}
\endcode
\ingroup UserAPI
*/
class QCA_EXPORT BigInteger
{
public:
/**
Constructor. Creates a new BigInteger, initialised to zero.
*/
BigInteger();
/**
\overload
\param n an alternative integer initialisation value.
*/
BigInteger(int n);
/**
\overload
\param c an alternative initialisation value, encoded as a character array
\code
BigInteger b ( "9890343" );
\endcode
*/
BigInteger(const char *c);
/**
\overload
\param s an alternative initialisation value, encoded as a string
*/
BigInteger(const QString &s);
/**
\overload
\param a an alternative initialisation value, encoded as SecureArray
*/
BigInteger(const QCA::SecureArray &a);
/**
\overload
\param from an alternative initialisation value, encoded as a %BigInteger
*/
BigInteger(const BigInteger &from);
~BigInteger();
/**
Assignment operator
\param from the BigInteger to copy from
\code
BigInteger a; // a is zero
BigInteger b( 500 );
a = b; // a is now 500
\endcode
*/
BigInteger & operator=(const BigInteger &from);
/**
\overload
\param s the QString containing an integer representation
\sa bool fromString(const QString &s)
\note it is the application's responsibility to make sure
that the QString represents a valid integer (ie it only
contains numbers and an optional minus sign at the start)
*/
BigInteger & operator=(const QString &s);
/**
Increment in place operator
\param b the amount to increment by
\code
BigInteger a; // a is zero
BigInteger b( 500 );
a += b; // a is now 500
a += b; // a is now 1000
\endcode
*/
BigInteger & operator+=(const BigInteger &b);
/**
Decrement in place operator
\param b the amount to decrement by
\code
BigInteger a; // a is zero
BigInteger b( 500 );
a -= b; // a is now -500
a -= b; // a is now -1000
\endcode
*/
BigInteger & operator-=(const BigInteger &b);
/**
Multiply in place operator
\param b the amount to multiply by
*/
BigInteger & operator*=(const BigInteger &b);
/**
Divide in place operator
\param b the amount to divide by
*/
BigInteger & operator/=(const BigInteger &b);
/**
Modulo in place operator
\param b the amount to divide by
*/
BigInteger & operator%=(const BigInteger &b);
/**
Output %BigInteger as a byte array, useful for storage or
transmission. The format is a binary integer in sign-extended
network-byte-order.
\sa void fromArray(const SecureArray &a);
*/
QCA::SecureArray toArray() const;
/**
Assign from an array. The input is expected to be a binary integer
in sign-extended network-byte-order.
\param a a SecureArray that represents an integer
\sa BigInteger(const SecureArray &a);
\sa SecureArray toArray() const;
*/
void fromArray(const QCA::SecureArray &a);
/**
Convert %BigInteger to a QString
\code
QString aString;
BigInteger aBiggishInteger( 5878990 );
aString = aBiggishInteger.toString(); // aString is now "5878990"
\endcode
*/
QString toString() const;
/**
Assign from a QString
\param s a QString that represents an integer
\note it is the application's responsibility to make sure
that the QString represents a valid integer (ie it only
contains numbers and an optional minus sign at the start)
\sa BigInteger(const QString &s)
\sa BigInteger & operator=(const QString &s)
*/
bool fromString(const QString &s);
/**
Compare this value with another %BigInteger
Normally it is more readable to use one of the operator overloads,
so you don't need to use this method directly.
\param n the BigInteger to compare with
\return zero if the values are the same, negative if the argument
is less than the value of this BigInteger, and positive if the
argument value is greater than this BigInteger
\code
BigInteger a( "400" );
BigInteger b( "-400" );
BigInteger c( " 200 " );
int result;
result = a.compare( b ); // return positive 400 > -400
result = a.compare( c ); // return positive, 400 > 200
result = b.compare( c ); // return negative, -400 < 200
\endcode
*/
int compare(const BigInteger &n) const;
/**
Equality operator. Returns true if the two BigInteger values
are the same, including having the same sign.
\param other the BigInteger to compare to
*/
inline bool operator==(const BigInteger &other) const
{
return (compare(other) == 0);
}
/**
Inequality operator. Returns true if the two BigInteger values
are different in magnitude, sign or both.
\param other the BigInteger to compare to
*/
inline bool operator!=(const BigInteger &other) const
{
return !(*this == other);
}
/**
Less than or equal operator. Returns true if the BigInteger value
on the left hand side is equal to or less than the BigInteger
value on the right hand side.
\param other the BigInteger to compare to
*/
inline bool operator<=(const BigInteger &other) const
{
return (compare(other) <= 0);
}
/**
Greater than or equal operator. Returns true if the BigInteger
value on the left hand side is equal to or greater than the
BigInteger value on the right hand side.
\param other the BigInteger to compare to
*/
inline bool operator>=(const BigInteger &other) const
{
return (compare(other) >= 0);
}
/**
Less than operator. Returns true if the BigInteger value
on the left hand side is less than the BigInteger value
on the right hand side.
\param other the BigInteger to compare to
*/
inline bool operator<(const BigInteger &other) const
{
return (compare(other) < 0);
}
/**
Greater than operator. Returns true if the BigInteger value
on the left hand side is greater than the BigInteger value
on the right hand side.
\param other the BigInteger to compare to
*/
inline bool operator>(const BigInteger &other) const
{
return (compare(other) > 0);
}
private:
class Private;
QSharedDataPointer<Private> d;
};
/**
Stream operator
\param stream the stream to write to
\param b the integer to write to the stream
\relates BigInteger
*/
QCA_EXPORT QTextStream &operator<<(QTextStream &stream, const BigInteger &b);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,534 @@
/*
* Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**
\file qpipe.h
Header file for the QPipe FIFO class
\note You should not use this header directly from an
application. You should just use <tt> \#include \<QtCrypto>
</tt> instead.
*/
#ifndef QPIPE_H
#define QPIPE_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifndef QPIPE_NO_SECURE
# define QPIPE_SECURE
#endif
#ifdef QPIPE_SECURE
# include <QtCrypto>
#else
# define QCA_EXPORT
#endif
// defs adapted qprocess_p.h
#ifdef Q_OS_WIN
#include <windows.h>
typedef HANDLE Q_PIPE_ID;
#define INVALID_Q_PIPE_ID INVALID_HANDLE_VALUE
#else
typedef int Q_PIPE_ID;
#define INVALID_Q_PIPE_ID -1
#endif
#endif
// Note: for Windows console, I/O must be in UTF-8. Reads are guaranteed to
// to completely decode (no partial characters). Likewise, writes must
// not contain partial characters.
namespace QCA {
/**
\class QPipeDevice qpipe.h QtCrypto
Unbuffered direct pipe.
This class is not usually required except for very low level operations.
You should use QPipe and QPipeEnd for most applications.
\ingroup UserAPI
*/
class QCA_EXPORT QPipeDevice : public QObject
{
Q_OBJECT
public:
/**
The type of device
*/
enum Type
{
Read, ///< The pipe end can be read from
Write ///< The pipe end can be written to
};
/**
Standard constructor
\param parent the parent object to this object
*/
QPipeDevice(QObject *parent = 0);
~QPipeDevice();
/**
The Type of the pipe device (that is, read or write)
*/
Type type() const;
/**
Test whether this object corresponds to a valid pipe
*/
bool isValid() const;
/**
The low level identification for this pipe.
On Windows, this is a HANDLE. On Unix, this is a file descriptor (i.e. integer).
Code using this method should be carefully tested for portability.
\sa idAsInt
*/
Q_PIPE_ID id() const;
/**
The low level identification for this pipe, returned as an integer.
Code using this method should be carefully tested for portability.
\sa id().
*/
int idAsInt() const;
/**
Take over an existing pipe id, closing the old pipe if any.
\param id the identification of the pipe end to take over.
\param t the type of pipe end (read or write).
*/
void take(Q_PIPE_ID id, Type t);
/**
Enable the pipe for reading or writing (depending on Type)
*/
void enable();
/**
Close the pipe end.
*/
void close();
/**
Release the pipe end, but do not close it.
*/
void release();
/**
Set the pipe end to be inheritable
\note On Windows, this operation changes the pipe end id value.
\param enabled whether the pipe is inheritable (true) or not (false)
*/
bool setInheritable(bool enabled);
/**
Obtain the number of bytes available to be read.
*/
int bytesAvailable() const;
/**
Read from the pipe end
\param data where to put the data that has been read
\param maxsize the maximum number of bytes to be read.
\return the actual number of bytes read, 0 on end-of-file, or -1 on error.
*/
int read(char *data, int maxsize);
/**
Write to the pipe end.
\param data the source of the data to be written
\param size the number of bytes in the data to be written
\note the data source must remain valid
\return the number of bytes written, or -1 on error.
*/
int write(const char *data, int size);
/**
The result of a write operation
\param written if not null, this will be set to the number of
bytes written in the last operation.
\return 0 on success (all data written), or -1 on error
*/
int writeResult(int *written) const;
Q_SIGNALS:
/**
Emitted when the pipe end can be read from or written to (depending on its Type).
*/
void notify();
private:
Q_DISABLE_COPY(QPipeDevice)
class Private;
friend class Private;
Private *d;
};
/**
\class QPipeEnd qpipe.h QtCrypto
A buffered higher-level pipe end
This is either the read end or write end of a QPipe.
\ingroup UserAPI
*/
class QCA_EXPORT QPipeEnd : public QObject
{
Q_OBJECT
public:
/**
The type of error
*/
enum Error
{
ErrorEOF, ///< End of file error
ErrorBroken ///< Broken pipe error
};
/**
Standard constructor
\param parent the parent object for this object
*/
QPipeEnd(QObject *parent = 0);
~QPipeEnd();
/**
Reset the pipe end to an inactive state
*/
void reset();
/**
The type of pipe end (either read or write)
*/
QPipeDevice::Type type() const;
/**
Determine whether the pipe end is valid.
\note This does not mean the pipe is ready to be used - you
may need to call enable() first
*/
bool isValid() const;
/**
Pipe identification
*/
Q_PIPE_ID id() const;
/**
Pipe identification
*/
int idAsInt() const;
/**
Take over an existing pipe handle
\param id the pipe handle
\param t the type of the pipe (read or write)
*/
void take(Q_PIPE_ID id, QPipeDevice::Type t);
#ifdef QPIPE_SECURE
/**
Sets whether the pipe uses secure memory for read/write
Enabling this may reduce performance, and it should only be used if
sensitive data is being transmitted (such as a passphrase).
\param secure whether the pipe uses secure memory (true) or not (false).
*/
void setSecurityEnabled(bool secure);
#endif
/**
Enable the endpoint for the pipe
When an endpoint is created, it is not
able to be used until it is enabled.
*/
void enable();
/**
Close the end of the pipe
\sa closed()
*/
void close();
/**
Let go of the active pipe handle, but don't close it
Use this before destructing QPipeEnd, if you don't want the pipe
to automatically close.
*/
void release();
/**
Sets whether the pipe should be inheritable to child processes
Returns true if inheritability was successfully changed, otherwise
false.
\param enabled whether the pipe is inheritable (true) or not (false).
*/
bool setInheritable(bool enabled);
/**
Clear the contents of the pipe, and invalidate the pipe
*/
void finalize();
/**
Clear the contents of the pipe, and release the pipe
*/
void finalizeAndRelease();
/**
Determine how many bytes are available to be read.
This only makes sense at the read end of the pipe
\sa readyRead() for a signal that can be used to determine
when there are bytes available to read.
*/
int bytesAvailable() const;
/**
Returns the number of bytes pending to write
This only makes sense at the write end of the pipe
\sa bytesWritten() for a signal that can be used to determine
when bytes have been written
*/
int bytesToWrite() const;
/**
Read bytes from the pipe.
You can only call this on the read end of the pipe
If the pipe is using secure memory, you should use readSecure()
\param bytes the number of bytes to read (-1 for all
content).
*/
QByteArray read(int bytes = -1);
/**
Write bytes to the pipe.
You can only call this on the write end of the pipe.
If the pipe is using secure memory, you should use writeSecure().
\param a the array to write to the pipe
*/
void write(const QByteArray &a);
#ifdef QPIPE_SECURE
/**
Read bytes from the pipe.
You can only call this on the read end of the pipe
If the pipe is using insecure memory, you should use read()
\param bytes the number of bytes to read (-1 for all
content).
*/
SecureArray readSecure(int bytes = -1);
/**
Write bytes to the pipe.
You can only call this on the write end of the pipe.
If the pipe is using insecure memory, you should use write().
\param a the array to write to the pipe
*/
void writeSecure(const SecureArray &a);
#endif
/**
Returns any unsent bytes queued for writing
If the pipe is using secure memory, you should use
takeBytesToWriteSecure().
*/
QByteArray takeBytesToWrite();
#ifdef QPIPE_SECURE
/**
Returns any unsent bytes queued for writing
If the pipe is using insecure memory, you should use
takeBytesToWrite().
*/
SecureArray takeBytesToWriteSecure();
#endif
Q_SIGNALS:
/**
Emitted when there are bytes available to be read
from the read end of the pipe.
\sa bytesAvailable()
*/
void readyRead();
/**
Emitted when bytes have been written to the
write end of the pipe.
\param bytes the number of bytes written
*/
void bytesWritten(int bytes);
/**
Emitted when this end of the pipe is closed as a result of calling
close()
If this is the write end of the pipe and there is data still
pending to write, this signal will be emitted once all of the data
has been written.
To be notified if the other end of the pipe has been closed, see
error().
*/
void closed();
/**
Emitted when the pipe encounters an error trying to read or write,
or if the other end of the pipe has been closed
\param e the reason for error
*/
void error(QCA::QPipeEnd::Error e);
private:
Q_DISABLE_COPY(QPipeEnd)
class Private;
friend class Private;
Private *d;
};
/**
\class QPipe qpipe.h QtCrypto
A FIFO buffer (named pipe) abstraction
This class creates a full buffer, consisting of two ends
(QPipeEnd). You can obtain each end (after calling create()) using
readEnd() and writeEnd(), however you must call enable() on each end
before using the pipe.
By default, the pipe ends are not inheritable by child processes. On
Windows, the pipe is created with inheritability disabled. On Unix, the
FD_CLOEXEC flag is set on each end's file descriptor.
\ingroup UserAPI
*/
class QCA_EXPORT QPipe
{
public:
/**
Standard constructor
\note You must call create() before using the pipe ends.
\param parent the parent object for this object
*/
QPipe(QObject *parent = 0);
~QPipe();
/**
Reset the pipe.
At this point, the readEnd() and writeEnd() calls
will no longer be valid.
*/
void reset();
#ifdef QPIPE_SECURE
/**
Create the pipe
\param secure whether to use secure memory (true) or not (false)
*/
bool create(bool secure = false);
#else
/**
Create the pipe
*/
bool create();
#endif
/**
The read end of the pipe.
*/
QPipeEnd & readEnd() { return i; }
/**
The write end of the pipe.
*/
QPipeEnd & writeEnd() { return o; }
private:
Q_DISABLE_COPY(QPipe)
QPipeEnd i, o;
};
}
#endif

View file

@ -0,0 +1,84 @@
Botantools 1.6.2
----------------
Botan is written by Jack Lloyd and available at http://botan.randombit.net/
Description (from the website) :
Botan is a library, written in C++. It's main purpose it to provide an easy
to use, high level interface to various cryptographic primitives, such as
block ciphers, hash functions, and public key algorithms. In addition, the
intent is that Botan is as general purpose as possible, and for this reason,
it supports many standards and de-facto standards.
"Botantools" is a subset of Botan, tailored for use with QCA. It includes
only the memory allocation, memory locking, and big integer capabilities. To
use it, just include botantools.pri in your qmake profile, and botantools.h in
your code.
The 'botan' subfolder consists of files just from Botan. Inside are source
files (originally from Botan's 'src' folder) as well as some modules (from
'modules'). The further 'botan' subfolder contains headers (from 'include'
and modules).
Some files had to be modified, and botantools.diff contains the differences.
Also, license headers and namespace declarations were added to all source
files, but I don't count these as real modifications, and they are not
included in the diff. The addlicenseheaders.sh script can be used to apply
the license headers. To apply the namespace declarations, build wrapns.c and
use the addnamespace.sh script.
Files used:
'*' indicates modification
doc/license.txt
include/allocate.h
* include/bigint.h
include/bit_ops.h
* include/charset.h
include/defalloc.h
include/exceptn.h
* include/libstate.h
include/mem_ops.h
include/mem_pool.h
* include/modules.h
include/mp_asm.h
include/mp_asmi.h
include/mp_core.h
include/mp_types.h
include/mutex.h
* include/numthry.h
* include/parsing.h
include/secmem.h
include/stl_util.h
* include/types.h
* include/util.h
modules/alloc_mmap/mmap_mem.h
modules/alloc_mmap/mmap_mem.cpp
modules/ml_unix/mlock.cpp
modules/ml_win32/mlock.cpp
modules/mux_qt/mux_qt.h
* modules/mux_qt/mux_qt.cpp
src/big_base.cpp
* src/big_code.cpp
* src/big_io.cpp
src/big_ops2.cpp
src/big_ops3.cpp
src/bit_ops.cpp
* src/charset.cpp
src/defalloc.cpp
src/divide.cpp
src/exceptn.cpp
* src/libstate.cpp
* src/mem_pool.cpp
* src/modules.cpp
* src/mp_asm.cpp
src/mp_comba.cpp
src/mp_misc.cpp
src/mp_mul.cpp
src/mp_mulop.cpp
src/mp_shift.cpp
src/mutex.cpp
* src/parsing.cpp
* src/util.cpp

View file

@ -0,0 +1,12 @@
#!/bin/sh
for f in `find botan -name \*.cpp -o -name \*.h` ; do
echo "/*" > file.tmp
cat botan/license.txt >> file.tmp
echo "*/" >> file.tmp
echo "// LICENSEHEADER_END" >> file.tmp
cat $f >> file.tmp
cp file.tmp $f
rm file.tmp
done

View file

@ -0,0 +1,6 @@
#!/bin/sh
for f in `find botan -name \*.cpp -o -name \*.h` ; do
./wrapns $f QCA
done

View file

@ -0,0 +1,173 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Memory Mapping Allocator Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
} // WRAPNS_LINE
#include <botan/mmap_mem.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <cstring>
namespace QCA { // WRAPNS_LINE
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 500
#endif
#ifndef _XOPEN_SOURCE_EXTENDED
#define _XOPEN_SOURCE_EXTENDED 1
#endif
} // WRAPNS_LINE
#include <sys/types.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <sys/mman.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <sys/stat.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <unistd.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <stdlib.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <fcntl.h>
namespace QCA { // WRAPNS_LINE
#ifndef MAP_FAILED
#define MAP_FAILED -1
#endif
namespace Botan {
namespace {
/*************************************************
* MemoryMapping_Allocator Exception *
*************************************************/
class MemoryMapping_Failed : public Exception
{
public:
MemoryMapping_Failed(const std::string& msg) :
Exception("MemoryMapping_Allocator: " + msg) {}
};
}
/*************************************************
* Memory Map a File into Memory *
*************************************************/
void* MemoryMapping_Allocator::alloc_block(u32bit n)
{
class TemporaryFile
{
public:
int get_fd() const { return fd; }
const std::string path() const { return filepath; }
TemporaryFile(const std::string& base)
{
const std::string path = base + "XXXXXX";
filepath = new char[path.length() + 1];
std::strcpy(filepath, path.c_str());
mode_t old_umask = umask(077);
fd = mkstemp(filepath);
umask(old_umask);
}
~TemporaryFile()
{
delete[] filepath;
if(fd != -1 && close(fd) == -1)
throw MemoryMapping_Failed("Could not close file");
}
private:
int fd;
char* filepath;
};
TemporaryFile file("/tmp/botan_");
if(file.get_fd() == -1)
throw MemoryMapping_Failed("Could not create file");
if(unlink(file.path().c_str()))
throw MemoryMapping_Failed("Could not unlink file " + file.path());
lseek(file.get_fd(), n-1, SEEK_SET);
if(write(file.get_fd(), "\0", 1) != 1)
throw MemoryMapping_Failed("Could not write to file");
void* ptr = mmap(0, n, PROT_READ | PROT_WRITE, MAP_SHARED,
file.get_fd(), 0);
if(ptr == (void*)MAP_FAILED)
throw MemoryMapping_Failed("Could not map file");
return ptr;
}
/*************************************************
* Remove a Memory Mapping *
*************************************************/
void MemoryMapping_Allocator::dealloc_block(void* ptr, u32bit n)
{
if(ptr == 0) return;
#ifdef MLOCK_NOT_VOID_PTR
# define MLOCK_TYPE_CAST (char *)
#else
# define MLOCK_TYPE_CAST
#endif
const u32bit OVERWRITE_PASSES = 12;
const byte PATTERNS[] = { 0x00, 0xFF, 0xAA, 0x55, 0x73, 0x8C, 0x5F, 0xA0,
0x6E, 0x91, 0x30, 0xCF, 0xD3, 0x2C, 0xAC, 0x53 };
for(u32bit j = 0; j != OVERWRITE_PASSES; j++)
{
std::memset(ptr, PATTERNS[j % sizeof(PATTERNS)], n);
if(msync(MLOCK_TYPE_CAST ptr, n, MS_SYNC))
throw MemoryMapping_Failed("Sync operation failed");
}
std::memset(ptr, 0, n);
if(msync(MLOCK_TYPE_CAST ptr, n, MS_SYNC))
throw MemoryMapping_Failed("Sync operation failed");
if(munmap(MLOCK_TYPE_CAST ptr, n))
throw MemoryMapping_Failed("Could not unmap file");
}
}
} // WRAPNS_LINE

View file

@ -0,0 +1,58 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Memory Mapping Allocator Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_EXT_MMAP_ALLOCATOR_H__
#define BOTAN_EXT_MMAP_ALLOCATOR_H__
} // WRAPNS_LINE
#include <botan/mem_pool.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Memory Mapping Allocator *
*************************************************/
class MemoryMapping_Allocator : public Pooling_Allocator
{
public:
MemoryMapping_Allocator() : Pooling_Allocator(64*1024, false) {}
std::string type() const { return "mmap"; }
private:
void* alloc_block(u32bit);
void dealloc_block(void*, u32bit);
};
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,416 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* BigInt Base Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
} // WRAPNS_LINE
#include <botan/bigint.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/mp_core.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/bit_ops.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/parsing.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/util.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Construct a BigInt from a regular number *
*************************************************/
BigInt::BigInt(u64bit n)
{
set_sign(Positive);
if(n == 0)
return;
const u32bit limbs_needed = sizeof(u64bit) / sizeof(word);
reg.create(4*limbs_needed);
for(u32bit j = 0; j != limbs_needed; ++j)
reg[j] = (word)((n >> (j*MP_WORD_BITS)) & MP_WORD_MASK);
}
/*************************************************
* Construct a BigInt of the specified size *
*************************************************/
BigInt::BigInt(Sign s, u32bit size)
{
reg.create(round_up(size, 8));
signedness = s;
}
/*************************************************
* Construct a BigInt from a "raw" BigInt *
*************************************************/
BigInt::BigInt(const BigInt& b)
{
const u32bit b_words = b.sig_words();
if(b_words)
{
reg.create(round_up(b_words, 8));
reg.copy(b.data(), b_words);
set_sign(b.sign());
}
else
{
reg.create(2);
set_sign(Positive);
}
}
/*************************************************
* Construct a BigInt from a string *
*************************************************/
BigInt::BigInt(const std::string& str)
{
Base base = Decimal;
u32bit markers = 0;
bool negative = false;
if(str.length() > 0 && str[0] == '-') { markers += 1; negative = true; }
if(str.length() > markers + 2 && str[markers ] == '0' &&
str[markers + 1] == 'x')
{ markers += 2; base = Hexadecimal; }
else if(str.length() > markers + 1 && str[markers] == '0')
{ markers += 1; base = Octal; }
*this = decode((const byte*)str.data() + markers,
str.length() - markers, base);
if(negative) set_sign(Negative);
else set_sign(Positive);
}
/*************************************************
* Construct a BigInt from an encoded BigInt *
*************************************************/
BigInt::BigInt(const byte input[], u32bit length, Base base)
{
set_sign(Positive);
*this = decode(input, length, base);
}
/*************************************************
* Swap this BigInt with another *
*************************************************/
void BigInt::swap(BigInt& other)
{
std::swap(reg, other.reg);
std::swap(signedness, other.signedness);
}
/*************************************************
* Grow the internal storage *
*************************************************/
void BigInt::grow_reg(u32bit n) const
{
reg.grow_to(round_up(size() + n, 8));
}
/*************************************************
* Grow the internal storage *
*************************************************/
void BigInt::grow_to(u32bit n) const
{
if(n > size())
reg.grow_to(round_up(n, 8));
}
/*************************************************
* Comparison Function *
*************************************************/
s32bit BigInt::cmp(const BigInt& n, bool check_signs) const
{
if(check_signs)
{
if(n.is_positive() && this->is_negative()) return -1;
if(n.is_negative() && this->is_positive()) return 1;
if(n.is_negative() && this->is_negative())
return (-bigint_cmp(data(), sig_words(), n.data(), n.sig_words()));
}
return bigint_cmp(data(), sig_words(), n.data(), n.sig_words());
}
/*************************************************
* Convert this number to a u32bit, if possible *
*************************************************/
u32bit BigInt::to_u32bit() const
{
if(is_negative())
throw Encoding_Error("BigInt::to_u32bit: Number is negative");
if(bits() >= 32)
throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert");
u32bit out = 0;
for(u32bit j = 0; j != 4; ++j)
out = (out << 8) | byte_at(3-j);
return out;
}
/*************************************************
* Return byte n of this number *
*************************************************/
byte BigInt::byte_at(u32bit n) const
{
const u32bit WORD_BYTES = sizeof(word);
u32bit word_num = n / WORD_BYTES, byte_num = n % WORD_BYTES;
if(word_num >= size())
return 0;
else
return get_byte(WORD_BYTES - byte_num - 1, reg[word_num]);
}
/*************************************************
* Return bit n of this number *
*************************************************/
bool BigInt::get_bit(u32bit n) const
{
return ((word_at(n / MP_WORD_BITS) >> (n % MP_WORD_BITS)) & 1);
}
/*************************************************
* Return bits {offset...offset+length} *
*************************************************/
u32bit BigInt::get_substring(u32bit offset, u32bit length) const
{
if(length > 32)
throw Invalid_Argument("BigInt::get_substring: Substring size too big");
u64bit piece = 0;
for(u32bit j = 0; j != 8; ++j)
piece = (piece << 8) | byte_at((offset / 8) + (7-j));
u64bit mask = (1 << length) - 1;
u32bit shift = (offset % 8);
return static_cast<u32bit>((piece >> shift) & mask);
}
/*************************************************
* Set bit number n *
*************************************************/
void BigInt::set_bit(u32bit n)
{
const u32bit which = n / MP_WORD_BITS;
const word mask = (word)1 << (n % MP_WORD_BITS);
if(which >= size()) grow_to(which + 1);
reg[which] |= mask;
}
/*************************************************
* Clear bit number n *
*************************************************/
void BigInt::clear_bit(u32bit n)
{
const u32bit which = n / MP_WORD_BITS;
const word mask = (word)1 << (n % MP_WORD_BITS);
if(which < size())
reg[which] &= ~mask;
}
/*************************************************
* Clear all but the lowest n bits *
*************************************************/
void BigInt::mask_bits(u32bit n)
{
if(n == 0) { clear(); return; }
if(n >= bits()) return;
const u32bit top_word = n / MP_WORD_BITS;
const word mask = ((word)1 << (n % MP_WORD_BITS)) - 1;
if(top_word < size())
for(u32bit j = top_word + 1; j != size(); ++j)
reg[j] = 0;
reg[top_word] &= mask;
}
/*************************************************
* Count the significant words *
*************************************************/
u32bit BigInt::sig_words() const
{
const word* x = data();
u32bit top_set = size();
while(top_set >= 4)
{
word sum = x[top_set-1] | x[top_set-2] | x[top_set-3] | x[top_set-4];
if(sum) break;
else top_set -= 4;
}
while(top_set && (x[top_set-1] == 0))
top_set--;
return top_set;
}
/*************************************************
* Count how many bytes are being used *
*************************************************/
u32bit BigInt::bytes() const
{
return (bits() + 7) / 8;
}
/*************************************************
* Count how many bits are being used *
*************************************************/
u32bit BigInt::bits() const
{
if(sig_words() == 0)
return 0;
u32bit full_words = sig_words() - 1, top_bits = MP_WORD_BITS;
word top_word = word_at(full_words), mask = MP_WORD_TOP_BIT;
while(top_bits && ((top_word & mask) == 0))
{ mask >>= 1; top_bits--; }
return (full_words * MP_WORD_BITS + top_bits);
}
/*************************************************
* Calcluate the size in a certain base *
*************************************************/
u32bit BigInt::encoded_size(Base base) const
{
static const double LOG_2_BASE_10 = 0.30102999566;
if(base == Binary)
return bytes();
else if(base == Hexadecimal)
return 2*bytes();
else if(base == Octal)
return ((bits() + 2) / 3);
else if(base == Decimal)
return (u32bit)((bits() * LOG_2_BASE_10) + 1);
else
throw Invalid_Argument("Unknown base for BigInt encoding");
}
/*************************************************
* Return true if this number is zero *
*************************************************/
bool BigInt::is_zero() const
{
for(u32bit j = 0; j != size(); ++j)
if(reg[j]) return false;
return true;
}
/*************************************************
* Set the sign *
*************************************************/
void BigInt::set_sign(Sign s)
{
if(is_zero())
signedness = Positive;
else
signedness = s;
}
/*************************************************
* Reverse the value of the sign flag *
*************************************************/
void BigInt::flip_sign()
{
set_sign(reverse_sign());
}
/*************************************************
* Return the opposite value of the current sign *
*************************************************/
BigInt::Sign BigInt::reverse_sign() const
{
if(sign() == Positive)
return Negative;
return Positive;
}
/*************************************************
* Return the negation of this number *
*************************************************/
BigInt BigInt::operator-() const
{
BigInt x = (*this);
x.flip_sign();
return x;
}
/*************************************************
* Return the absolute value of this number *
*************************************************/
BigInt BigInt::abs() const
{
BigInt x = (*this);
x.set_sign(Positive);
return x;
}
/*************************************************
* Encode this number into bytes *
*************************************************/
void BigInt::binary_encode(byte output[]) const
{
const u32bit sig_bytes = bytes();
for(u32bit j = 0; j != sig_bytes; ++j)
output[sig_bytes-j-1] = byte_at(j);
}
/*************************************************
* Set this number to the value in buf *
*************************************************/
void BigInt::binary_decode(const byte buf[], u32bit length)
{
const u32bit WORD_BYTES = sizeof(word);
reg.create(round_up((length / WORD_BYTES) + 1, 8));
for(u32bit j = 0; j != length / WORD_BYTES; ++j)
{
u32bit top = length - WORD_BYTES*j;
for(u32bit k = WORD_BYTES; k > 0; --k)
reg[j] = (reg[j] << 8) | buf[top - k];
}
for(u32bit j = 0; j != length % WORD_BYTES; ++j)
reg[length / WORD_BYTES] = (reg[length / WORD_BYTES] << 8) | buf[j];
}
}
} // WRAPNS_LINE

View file

@ -0,0 +1,195 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* BigInt Encoding/Decoding Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
} // WRAPNS_LINE
#include <botan/bigint.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/numthry.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/charset.h>
namespace QCA { // WRAPNS_LINE
#ifndef BOTAN_MINIMAL_BIGINT
} // WRAPNS_LINE
#include <botan/hex.h>
namespace QCA { // WRAPNS_LINE
#endif
namespace Botan {
/*************************************************
* Encode a BigInt *
*************************************************/
void BigInt::encode(byte output[], const BigInt& n, Base base)
{
if(base == Binary)
n.binary_encode(output);
#ifndef BOTAN_MINIMAL_BIGINT
else if(base == Hexadecimal)
{
SecureVector<byte> binary(n.encoded_size(Binary));
n.binary_encode(binary);
for(u32bit j = 0; j != binary.size(); ++j)
Hex_Encoder::encode(binary[j], output + 2*j);
}
#endif
else if(base == Octal)
{
BigInt copy = n;
const u32bit output_size = n.encoded_size(Octal);
for(u32bit j = 0; j != output_size; ++j)
{
output[output_size - 1 - j] = Charset::digit2char(copy % 8);
copy /= 8;
}
}
else if(base == Decimal)
{
BigInt copy = n;
BigInt remainder;
copy.set_sign(Positive);
const u32bit output_size = n.encoded_size(Decimal);
for(u32bit j = 0; j != output_size; ++j)
{
divide(copy, 10, copy, remainder);
output[output_size - 1 - j] =
Charset::digit2char(remainder.word_at(0));
if(copy.is_zero())
{
if(j < output_size - 1)
{
int extra = output_size - 1 - j;
memmove(output, output + extra, output_size - extra);
memset(output + output_size - extra, 0, extra);
}
break;
}
}
}
else
throw Invalid_Argument("Unknown BigInt encoding method");
}
/*************************************************
* Encode a BigInt *
*************************************************/
SecureVector<byte> BigInt::encode(const BigInt& n, Base base)
{
SecureVector<byte> output(n.encoded_size(base));
encode(output, n, base);
if(base != Binary)
for(u32bit j = 0; j != output.size(); ++j)
if(output[j] == 0)
output[j] = '0';
return output;
}
/*************************************************
* Encode a BigInt, with leading 0s if needed *
*************************************************/
SecureVector<byte> BigInt::encode_1363(const BigInt& n, u32bit bytes)
{
const u32bit n_bytes = n.bytes();
if(n_bytes > bytes)
throw Encoding_Error("encode_1363: n is too large to encode properly");
const u32bit leading_0s = bytes - n_bytes;
SecureVector<byte> output(bytes);
encode(output + leading_0s, n, Binary);
return output;
}
/*************************************************
* Decode a BigInt *
*************************************************/
BigInt BigInt::decode(const MemoryRegion<byte>& buf, Base base)
{
return BigInt::decode(buf, buf.size(), base);
}
/*************************************************
* Decode a BigInt *
*************************************************/
BigInt BigInt::decode(const byte buf[], u32bit length, Base base)
{
BigInt r;
if(base == Binary)
r.binary_decode(buf, length);
#ifndef BOTAN_MINIMAL_BIGINT
else if(base == Hexadecimal)
{
SecureVector<byte> hex;
for(u32bit j = 0; j != length; ++j)
if(Hex_Decoder::is_valid(buf[j]))
hex.append(buf[j]);
u32bit offset = (hex.size() % 2);
SecureVector<byte> binary(hex.size() / 2 + offset);
if(offset)
{
byte temp[2] = { '0', hex[0] };
binary[0] = Hex_Decoder::decode(temp);
}
for(u32bit j = offset; j != binary.size(); ++j)
binary[j] = Hex_Decoder::decode(hex+2*j-offset);
r.binary_decode(binary, binary.size());
}
#endif
else if(base == Decimal || base == Octal)
{
const u32bit RADIX = ((base == Decimal) ? 10 : 8);
for(u32bit j = 0; j != length; ++j)
{
byte x = Charset::char2digit(buf[j]);
if(x >= RADIX)
{
if(RADIX == 10)
throw Invalid_Argument("BigInt: Invalid decimal string");
else
throw Invalid_Argument("BigInt: Invalid octal string");
}
r *= RADIX;
r += x;
}
}
else
throw Invalid_Argument("Unknown BigInt decoding method");
return r;
}
}
} // WRAPNS_LINE

View file

@ -0,0 +1,88 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* BigInt Input/Output Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
} // WRAPNS_LINE
#include <botan/bigint.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <iostream>
namespace QCA { // WRAPNS_LINE
namespace Botan {
#ifndef BOTAN_MINIMAL_BIGINT
/*************************************************
* Write the BigInt into a stream *
*************************************************/
std::ostream& operator<<(std::ostream& stream, const BigInt& n)
{
BigInt::Base base = BigInt::Decimal;
if(stream.flags() & std::ios::hex)
base = BigInt::Hexadecimal;
else if(stream.flags() & std::ios::oct)
base = BigInt::Octal;
if(n == 0)
stream.write("0", 1);
else
{
if(n < 0)
stream.write("-", 1);
SecureVector<byte> buffer = BigInt::encode(n, base);
u32bit skip = 0;
while(buffer[skip] == '0' && skip < buffer.size())
++skip;
stream.write((const char*)buffer.begin() + skip, buffer.size() - skip);
}
if(!stream.good())
throw Stream_IO_Error("BigInt output operator has failed");
return stream;
}
/*************************************************
* Read the BigInt from a stream *
*************************************************/
std::istream& operator>>(std::istream& stream, BigInt& n)
{
std::string str;
std::getline(stream, str);
if(stream.bad() || (stream.fail() && !stream.eof()))
throw Stream_IO_Error("BigInt input operator has failed");
n = BigInt(str);
return stream;
}
#endif
}
} // WRAPNS_LINE

View file

@ -0,0 +1,272 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* BigInt Assignment Operators Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
} // WRAPNS_LINE
#include <botan/bigint.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/numthry.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/mp_core.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/bit_ops.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/util.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <algorithm>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Addition Operator *
*************************************************/
BigInt& BigInt::operator+=(const BigInt& y)
{
const u32bit x_sw = sig_words(), y_sw = y.sig_words();
#ifdef BOTAN_TYPES_QT
const u32bit reg_size = qMax(x_sw, y_sw) + 1;
#else
const u32bit reg_size = std::max(x_sw, y_sw) + 1;
#endif
grow_to(reg_size);
if((sign() == y.sign()))
bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
else
{
s32bit relative_size = bigint_cmp(data(), x_sw, y.data(), y_sw);
if(relative_size < 0)
{
SecureVector<word> z(reg_size - 1);
bigint_sub3(z, y.data(), reg_size - 1, data(), x_sw);
copy_mem(reg.begin(), z.begin(), z.size());
set_sign(y.sign());
}
else if(relative_size == 0)
{
reg.clear();
set_sign(Positive);
}
else if(relative_size > 0)
bigint_sub2(get_reg(), x_sw, y.data(), y_sw);
}
return (*this);
}
/*************************************************
* Subtraction Operator *
*************************************************/
BigInt& BigInt::operator-=(const BigInt& y)
{
const u32bit x_sw = sig_words(), y_sw = y.sig_words();
s32bit relative_size = bigint_cmp(data(), x_sw, y.data(), y_sw);
#ifdef BOTAN_TYPES_QT
const u32bit reg_size = qMax(x_sw, y_sw) + 1;
#else
const u32bit reg_size = std::max(x_sw, y_sw) + 1;
#endif
grow_to(reg_size);
if(relative_size < 0)
{
if(sign() == y.sign())
{
SecureVector<word> z(reg_size - 1);
bigint_sub3(z, y.data(), reg_size - 1, data(), x_sw);
copy_mem(reg.begin(), z.begin(), z.size());
}
else
bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
set_sign(y.reverse_sign());
}
else if(relative_size == 0)
{
if(sign() == y.sign())
{
reg.clear();
set_sign(Positive);
}
else
bigint_shl1(get_reg(), x_sw, 0, 1);
}
else if(relative_size > 0)
{
if(sign() == y.sign())
bigint_sub2(get_reg(), x_sw, y.data(), y_sw);
else
bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
}
return (*this);
}
/*************************************************
* Multiplication Operator *
*************************************************/
BigInt& BigInt::operator*=(const BigInt& y)
{
const u32bit x_sw = sig_words(), y_sw = y.sig_words();
set_sign((sign() == y.sign()) ? Positive : Negative);
if(x_sw == 0 || y_sw == 0)
{
reg.clear();
set_sign(Positive);
}
else if(x_sw == 1 && y_sw)
{
grow_to(y_sw + 2);
bigint_linmul3(get_reg(), y.data(), y_sw, word_at(0));
}
else if(y_sw == 1 && x_sw)
{
grow_to(x_sw + 2);
bigint_linmul2(get_reg(), x_sw, y.word_at(0));
}
else
{
grow_to(size() + y.size());
SecureVector<word> z(data(), x_sw);
SecureVector<word> workspace(size());
bigint_mul(get_reg(), size(), workspace,
z, z.size(), x_sw,
y.data(), y.size(), y_sw);
}
return (*this);
}
/*************************************************
* Division Operator *
*************************************************/
BigInt& BigInt::operator/=(const BigInt& y)
{
if(y.sig_words() == 1 && power_of_2(y.word_at(0)))
(*this) >>= (y.bits() - 1);
else
(*this) = (*this) / y;
return (*this);
}
/*************************************************
* Modulo Operator *
*************************************************/
BigInt& BigInt::operator%=(const BigInt& mod)
{
return (*this = (*this) % mod);
}
/*************************************************
* Modulo Operator *
*************************************************/
word BigInt::operator%=(word mod)
{
if(mod == 0)
throw BigInt::DivideByZero();
if(power_of_2(mod))
{
word result = (word_at(0) & (mod - 1));
clear();
grow_to(2);
reg[0] = result;
return result;
}
word remainder = 0;
for(u32bit j = sig_words(); j > 0; --j)
remainder = bigint_modop(remainder, word_at(j-1), mod);
clear();
grow_to(2);
if(remainder && sign() == BigInt::Negative)
reg[0] = mod - remainder;
else
reg[0] = remainder;
set_sign(BigInt::Positive);
return word_at(0);
}
/*************************************************
* Left Shift Operator *
*************************************************/
BigInt& BigInt::operator<<=(u32bit shift)
{
if(shift)
{
const u32bit shift_words = shift / MP_WORD_BITS,
shift_bits = shift % MP_WORD_BITS,
words = sig_words();
grow_to(words + shift_words + (shift_bits ? 1 : 0));
bigint_shl1(get_reg(), words, shift_words, shift_bits);
}
return (*this);
}
/*************************************************
* Right Shift Operator *
*************************************************/
BigInt& BigInt::operator>>=(u32bit shift)
{
if(shift)
{
const u32bit shift_words = shift / MP_WORD_BITS,
shift_bits = shift % MP_WORD_BITS;
bigint_shr1(get_reg(), sig_words(), shift_words, shift_bits);
if(is_zero())
set_sign(Positive);
}
return (*this);
}
}
} // WRAPNS_LINE

View file

@ -0,0 +1,234 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* BigInt Binary Operators Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
} // WRAPNS_LINE
#include <botan/bigint.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/numthry.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/mp_core.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/bit_ops.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <algorithm>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Addition Operator *
*************************************************/
BigInt operator+(const BigInt& x, const BigInt& y)
{
const u32bit x_sw = x.sig_words(), y_sw = y.sig_words();
#ifdef BOTAN_TYPES_QT
BigInt z(x.sign(), qMax(x_sw, y_sw) + 1);
#else
BigInt z(x.sign(), std::max(x_sw, y_sw) + 1);
#endif
if((x.sign() == y.sign()))
bigint_add3(z.get_reg(), x.data(), x_sw, y.data(), y_sw);
else
{
s32bit relative_size = bigint_cmp(x.data(), x_sw, y.data(), y_sw);
if(relative_size < 0)
{
bigint_sub3(z.get_reg(), y.data(), y_sw, x.data(), x_sw);
z.set_sign(y.sign());
}
else if(relative_size == 0)
z.set_sign(BigInt::Positive);
else if(relative_size > 0)
bigint_sub3(z.get_reg(), x.data(), x_sw, y.data(), y_sw);
}
return z;
}
/*************************************************
* Subtraction Operator *
*************************************************/
BigInt operator-(const BigInt& x, const BigInt& y)
{
const u32bit x_sw = x.sig_words(), y_sw = y.sig_words();
s32bit relative_size = bigint_cmp(x.data(), x_sw, y.data(), y_sw);
#ifdef BOTAN_TYPES_QT
BigInt z(BigInt::Positive, qMax(x_sw, y_sw) + 1);
#else
BigInt z(BigInt::Positive, std::max(x_sw, y_sw) + 1);
#endif
if(relative_size < 0)
{
if(x.sign() == y.sign())
bigint_sub3(z.get_reg(), y.data(), y_sw, x.data(), x_sw);
else
bigint_add3(z.get_reg(), x.data(), x_sw, y.data(), y_sw);
z.set_sign(y.reverse_sign());
}
else if(relative_size == 0)
{
if(x.sign() != y.sign())
bigint_shl2(z.get_reg(), x.data(), x_sw, 0, 1);
}
else if(relative_size > 0)
{
if(x.sign() == y.sign())
bigint_sub3(z.get_reg(), x.data(), x_sw, y.data(), y_sw);
else
bigint_add3(z.get_reg(), x.data(), x_sw, y.data(), y_sw);
z.set_sign(x.sign());
}
return z;
}
/*************************************************
* Multiplication Operator *
*************************************************/
BigInt operator*(const BigInt& x, const BigInt& y)
{
const u32bit x_sw = x.sig_words(), y_sw = y.sig_words();
BigInt z(BigInt::Positive, x.size() + y.size());
if(x_sw == 1 && y_sw)
bigint_linmul3(z.get_reg(), y.data(), y_sw, x.word_at(0));
else if(y_sw == 1 && x_sw)
bigint_linmul3(z.get_reg(), x.data(), x_sw, y.word_at(0));
else if(x_sw && y_sw)
{
SecureVector<word> workspace(z.size());
bigint_mul(z.get_reg(), z.size(), workspace,
x.data(), x.size(), x_sw,
y.data(), y.size(), y_sw);
}
if(x_sw && y_sw && x.sign() != y.sign())
z.flip_sign();
return z;
}
/*************************************************
* Division Operator *
*************************************************/
BigInt operator/(const BigInt& x, const BigInt& y)
{
BigInt q, r;
divide(x, y, q, r);
return q;
}
/*************************************************
* Modulo Operator *
*************************************************/
BigInt operator%(const BigInt& n, const BigInt& mod)
{
if(mod.is_zero())
throw BigInt::DivideByZero();
if(mod.is_negative())
throw Invalid_Argument("BigInt::operator%: modulus must be > 0");
if(n.is_positive() && mod.is_positive() && n < mod)
return n;
BigInt q, r;
divide(n, mod, q, r);
return r;
}
/*************************************************
* Modulo Operator *
*************************************************/
word operator%(const BigInt& n, word mod)
{
if(mod == 0)
throw BigInt::DivideByZero();
if(power_of_2(mod))
return (n.word_at(0) & (mod - 1));
word remainder = 0;
for(u32bit j = n.sig_words(); j > 0; --j)
remainder = bigint_modop(remainder, n.word_at(j-1), mod);
if(remainder && n.sign() == BigInt::Negative)
return mod - remainder;
return remainder;
}
/*************************************************
* Left Shift Operator *
*************************************************/
BigInt operator<<(const BigInt& x, u32bit shift)
{
if(shift == 0)
return x;
const u32bit shift_words = shift / MP_WORD_BITS,
shift_bits = shift % MP_WORD_BITS;
const u32bit x_sw = x.sig_words();
BigInt y(x.sign(), x_sw + shift_words + (shift_bits ? 1 : 0));
bigint_shl2(y.get_reg(), x.data(), x_sw, shift_words, shift_bits);
return y;
}
/*************************************************
* Right Shift Operator *
*************************************************/
BigInt operator>>(const BigInt& x, u32bit shift)
{
if(shift == 0)
return x;
if(x.bits() <= shift)
return 0;
const u32bit shift_words = shift / MP_WORD_BITS,
shift_bits = shift % MP_WORD_BITS,
x_sw = x.sig_words();
BigInt y(x.sign(), x_sw - shift_words);
bigint_shr2(y.get_reg(), x.data(), x_sw, shift_words, shift_bits);
return y;
}
}
} // WRAPNS_LINE

View file

@ -0,0 +1,128 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Bit/Word Operations Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
} // WRAPNS_LINE
#include <botan/bit_ops.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* XOR arrays together *
*************************************************/
void xor_buf(byte data[], const byte mask[], u32bit length)
{
while(length >= 8)
{
data[0] ^= mask[0]; data[1] ^= mask[1];
data[2] ^= mask[2]; data[3] ^= mask[3];
data[4] ^= mask[4]; data[5] ^= mask[5];
data[6] ^= mask[6]; data[7] ^= mask[7];
data += 8; mask += 8; length -= 8;
}
for(u32bit j = 0; j != length; ++j)
data[j] ^= mask[j];
}
void xor_buf(byte out[], const byte in[], const byte mask[], u32bit length)
{
while(length >= 8)
{
out[0] = in[0] ^ mask[0]; out[1] = in[1] ^ mask[1];
out[2] = in[2] ^ mask[2]; out[3] = in[3] ^ mask[3];
out[4] = in[4] ^ mask[4]; out[5] = in[5] ^ mask[5];
out[6] = in[6] ^ mask[6]; out[7] = in[7] ^ mask[7];
in += 8; out += 8; mask += 8; length -= 8;
}
for(u32bit j = 0; j != length; ++j)
out[j] = in[j] ^ mask[j];
}
/*************************************************
* Return true iff arg is 2**n for some n > 0 *
*************************************************/
bool power_of_2(u64bit arg)
{
if(arg == 0 || arg == 1)
return false;
if((arg & (arg-1)) == 0)
return true;
return false;
}
/*************************************************
* Return the index of the highest set bit *
*************************************************/
u32bit high_bit(u64bit n)
{
for(u32bit count = 64; count > 0; --count)
if((n >> (count - 1)) & 0x01)
return count;
return 0;
}
/*************************************************
* Return the index of the lowest set bit *
*************************************************/
u32bit low_bit(u64bit n)
{
for(u32bit count = 0; count != 64; ++count)
if((n >> count) & 0x01)
return (count + 1);
return 0;
}
/*************************************************
* Return the number of significant bytes in n *
*************************************************/
u32bit significant_bytes(u64bit n)
{
for(u32bit j = 0; j != 8; ++j)
if(get_byte(j, n))
return 8-j;
return 0;
}
/*************************************************
* Return the Hamming weight of n *
*************************************************/
u32bit hamming_weight(u64bit n)
{
u32bit weight = 0;
for(u32bit j = 0; j != 64; ++j)
if((n >> j) & 0x01)
++weight;
return weight;
}
}
} // WRAPNS_LINE

View file

@ -0,0 +1,71 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Allocator Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_ALLOCATOR_H__
#define BOTAN_ALLOCATOR_H__
} // WRAPNS_LINE
#include <botan/types.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <string>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Allocator *
*************************************************/
class Allocator
{
public:
static Allocator* get(bool);
virtual void* allocate(u32bit) = 0;
virtual void deallocate(void*, u32bit) = 0;
virtual std::string type() const = 0;
virtual void init() {}
virtual void destroy() {}
virtual ~Allocator() {}
};
/*************************************************
* Get an allocator *
*************************************************/
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,208 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* BigInt Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_BIGINT_H__
#define BOTAN_BIGINT_H__
#ifdef BOTAN_MINIMAL_BIGINT
} // WRAPNS_LINE
# include <botan/secmem.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
# include <botan/exceptn.h>
namespace QCA { // WRAPNS_LINE
#else
} // WRAPNS_LINE
# include <botan/base.h>
namespace QCA { // WRAPNS_LINE
#endif
} // WRAPNS_LINE
#include <botan/mp_types.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <iosfwd>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* BigInt *
*************************************************/
class BigInt
{
public:
enum Base { Octal = 8, Decimal = 10, Hexadecimal = 16, Binary = 256 };
enum Sign { Negative = 0, Positive = 1 };
enum NumberType { Random, Power2 };
struct DivideByZero : public Exception
{ DivideByZero() : Exception("BigInt divide by zero") {} };
BigInt& operator+=(const BigInt&);
BigInt& operator-=(const BigInt&);
BigInt& operator*=(const BigInt&);
BigInt& operator/=(const BigInt&);
BigInt& operator%=(const BigInt&);
word operator%=(word);
BigInt& operator<<=(u32bit);
BigInt& operator>>=(u32bit);
BigInt& operator++() { return (*this += 1); }
BigInt& operator--() { return (*this -= 1); }
BigInt operator++(int) { BigInt x = (*this); ++(*this); return x; }
BigInt operator--(int) { BigInt x = (*this); --(*this); return x; }
BigInt operator-() const;
bool operator !() const { return (!is_nonzero()); }
s32bit cmp(const BigInt&, bool = true) const;
bool is_even() const { return (get_bit(0) == 0); }
bool is_odd() const { return (get_bit(0) == 1); }
bool is_nonzero() const { return (!is_zero()); }
bool is_zero() const;
void set_bit(u32bit);
void clear_bit(u32bit);
void mask_bits(u32bit);
bool get_bit(u32bit) const;
u32bit get_substring(u32bit, u32bit) const;
byte byte_at(u32bit) const;
word word_at(u32bit n) const
{ return ((n < size()) ? reg[n] : 0); }
u32bit to_u32bit() const;
bool is_negative() const { return (sign() == Negative); }
bool is_positive() const { return (sign() == Positive); }
Sign sign() const { return (signedness); }
Sign reverse_sign() const;
void flip_sign();
void set_sign(Sign);
BigInt abs() const;
u32bit size() const { return reg.size(); }
u32bit sig_words() const;
u32bit bytes() const;
u32bit bits() const;
const word* data() const { return reg.begin(); }
SecureVector<word>& get_reg() { return reg; }
void grow_reg(u32bit) const;
word& operator[](u32bit index) { return reg[index]; }
word operator[](u32bit index) const { return reg[index]; }
void clear() { reg.clear(); }
#ifndef BOTAN_MINIMAL_BIGINT
void randomize(u32bit = 0);
#endif
void binary_encode(byte[]) const;
void binary_decode(const byte[], u32bit);
u32bit encoded_size(Base = Binary) const;
static SecureVector<byte> encode(const BigInt&, Base = Binary);
static void encode(byte[], const BigInt&, Base = Binary);
static BigInt decode(const byte[], u32bit, Base = Binary);
static BigInt decode(const MemoryRegion<byte>&, Base = Binary);
static SecureVector<byte> encode_1363(const BigInt&, u32bit);
void swap(BigInt&);
BigInt() { signedness = Positive; }
BigInt(u64bit);
BigInt(const BigInt&);
BigInt(const std::string&);
BigInt(const byte[], u32bit, Base = Binary);
BigInt(Sign, u32bit);
#ifndef BOTAN_MINIMAL_BIGINT
BigInt(NumberType, u32bit);
#endif
private:
void grow_to(u32bit) const;
SecureVector<word> reg;
Sign signedness;
};
/*************************************************
* Arithmetic Operators *
*************************************************/
BigInt operator+(const BigInt&, const BigInt&);
BigInt operator-(const BigInt&, const BigInt&);
BigInt operator*(const BigInt&, const BigInt&);
BigInt operator/(const BigInt&, const BigInt&);
BigInt operator%(const BigInt&, const BigInt&);
word operator%(const BigInt&, word);
BigInt operator<<(const BigInt&, u32bit);
BigInt operator>>(const BigInt&, u32bit);
/*************************************************
* Comparison Operators *
*************************************************/
inline bool operator==(const BigInt& a, const BigInt& b)
{ return (a.cmp(b) == 0); }
inline bool operator!=(const BigInt& a, const BigInt& b)
{ return (a.cmp(b) != 0); }
inline bool operator<=(const BigInt& a, const BigInt& b)
{ return (a.cmp(b) <= 0); }
inline bool operator>=(const BigInt& a, const BigInt& b)
{ return (a.cmp(b) >= 0); }
inline bool operator<(const BigInt& a, const BigInt& b)
{ return (a.cmp(b) < 0); }
inline bool operator>(const BigInt& a, const BigInt& b)
{ return (a.cmp(b) > 0); }
/*************************************************
* I/O Operators *
*************************************************/
#ifndef BOTAN_MINIMAL_BIGINT
std::ostream& operator<<(std::ostream&, const BigInt&);
std::istream& operator>>(std::istream&, BigInt&);
#endif
}
#ifndef BOTAN_MINIMAL_BIGINT
} // WRAPNS_LINE
namespace std {
inline void swap(Botan::BigInt& a, Botan::BigInt& b) { a.swap(b); }
}
namespace QCA { // WRAPNS_LINE
#endif
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,94 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Bit/Word Operations Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_BIT_OPS_H__
#define BOTAN_BIT_OPS_H__
} // WRAPNS_LINE
#include <botan/types.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Rotation Functions *
*************************************************/
template<typename T> inline T rotate_left(T input, u32bit rot)
{ return (T)((input << rot) | (input >> (8*sizeof(T)-rot))); }
template<typename T> inline T rotate_right(T input, u32bit rot)
{ return (T)((input >> rot) | (input << (8*sizeof(T)-rot))); }
/*************************************************
* Byte Extraction Function *
*************************************************/
template<typename T> inline byte get_byte(u32bit byte_num, T input)
{ return (byte)(input >> ((sizeof(T)-1-(byte_num&(sizeof(T)-1))) << 3)); }
/*************************************************
* Byte to Word Conversions *
*************************************************/
inline u16bit make_u16bit(byte input0, byte input1)
{ return (u16bit)(((u16bit)input0 << 8) | input1); }
inline u32bit make_u32bit(byte input0, byte input1, byte input2, byte input3)
{ return (u32bit)(((u32bit)input0 << 24) | ((u32bit)input1 << 16) |
((u32bit)input2 << 8) | input3); }
inline u64bit make_u64bit(byte input0, byte input1, byte input2, byte input3,
byte input4, byte input5, byte input6, byte input7)
{
return (u64bit)(((u64bit)input0 << 56) | ((u64bit)input1 << 48) |
((u64bit)input2 << 40) | ((u64bit)input3 << 32) |
((u64bit)input4 << 24) | ((u64bit)input5 << 16) |
((u64bit)input6 << 8) | input7);
}
/*************************************************
* XOR Functions *
*************************************************/
void xor_buf(byte[], const byte[], u32bit);
void xor_buf(byte[], const byte[], const byte[], u32bit);
/*************************************************
* Misc Utility Functions *
*************************************************/
bool power_of_2(u64bit);
u32bit high_bit(u64bit);
u32bit low_bit(u64bit);
u32bit significant_bytes(u64bit);
u32bit hamming_weight(u64bit);
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,85 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Character Set Handling Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_CHARSET_H__
#define BOTAN_CHARSET_H__
} // WRAPNS_LINE
#include <botan/types.h>
namespace QCA { // WRAPNS_LINE
#ifndef BOTAN_TOOLS_ONLY
} // WRAPNS_LINE
#include <botan/enums.h>
namespace QCA { // WRAPNS_LINE
#endif
} // WRAPNS_LINE
#include <string>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Character Set Transcoder Interface *
*************************************************/
#ifndef BOTAN_TOOLS_ONLY
class Charset_Transcoder
{
public:
virtual std::string transcode(const std::string&,
Character_Set, Character_Set) const = 0;
virtual ~Charset_Transcoder() {}
};
#endif
namespace Charset {
/*************************************************
* Character Set Handling *
*************************************************/
#ifndef BOTAN_TOOLS_ONLY
std::string transcode(const std::string&, Character_Set, Character_Set);
#endif
bool is_digit(char);
bool is_space(char);
bool caseless_cmp(char, char);
byte char2digit(char);
char digit2char(byte);
}
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,71 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Basic Allocators Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_BASIC_ALLOC_H__
#define BOTAN_BASIC_ALLOC_H__
} // WRAPNS_LINE
#include <botan/mem_pool.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Malloc Allocator *
*************************************************/
class Malloc_Allocator : public Pooling_Allocator
{
public:
Malloc_Allocator() : Pooling_Allocator(64*1024, false) {}
std::string type() const { return "malloc"; }
private:
void* alloc_block(u32bit);
void dealloc_block(void*, u32bit);
};
/*************************************************
* Locking Allocator *
*************************************************/
class Locking_Allocator : public Pooling_Allocator
{
public:
Locking_Allocator() : Pooling_Allocator(64*1024, true) {}
std::string type() const { return "locking"; }
private:
void* alloc_block(u32bit);
void dealloc_block(void*, u32bit);
};
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,246 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Exceptions Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_EXCEPTION_H__
#define BOTAN_EXCEPTION_H__
} // WRAPNS_LINE
#include <botan/types.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <exception>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <string>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Exception Base Class *
*************************************************/
class Exception : public std::exception
{
public:
const char* what() const throw() { return msg.c_str(); }
Exception(const std::string& m = "Unknown error") { set_msg(m); }
virtual ~Exception() throw() {}
protected:
void set_msg(const std::string& m) { msg = "Botan: " + m; }
private:
std::string msg;
};
/*************************************************
* Invalid_Argument Exception *
*************************************************/
struct Invalid_Argument : public Exception
{
Invalid_Argument(const std::string& err = "") : Exception(err) {}
};
/*************************************************
* Invalid_Key_Length Exception *
*************************************************/
struct Invalid_Key_Length : public Invalid_Argument
{
Invalid_Key_Length(const std::string&, u32bit);
};
/*************************************************
* Invalid_Block_Size Exception *
*************************************************/
struct Invalid_Block_Size : public Invalid_Argument
{
Invalid_Block_Size(const std::string&, const std::string&);
};
/*************************************************
* Invalid_IV_Length Exception *
*************************************************/
struct Invalid_IV_Length : public Invalid_Argument
{
Invalid_IV_Length(const std::string&, u32bit);
};
/*************************************************
* Invalid_Message_Number Exception *
*************************************************/
struct Invalid_Message_Number : public Invalid_Argument
{
Invalid_Message_Number(const std::string&, u32bit);
};
/*************************************************
* Invalid_State Exception *
*************************************************/
struct Invalid_State : public Exception
{
Invalid_State(const std::string& err) : Exception(err) {}
};
/*************************************************
* PRNG_Unseeded Exception *
*************************************************/
struct PRNG_Unseeded : public Invalid_State
{
PRNG_Unseeded(const std::string& algo) :
Invalid_State("PRNG not seeded: " + algo) {}
};
/*************************************************
* Policy_Violation Exception *
*************************************************/
struct Policy_Violation : public Invalid_State
{
Policy_Violation(const std::string& err) :
Invalid_State("Policy violation: " + err) {}
};
/*************************************************
* Lookup_Error Exception *
*************************************************/
struct Lookup_Error : public Exception
{
Lookup_Error(const std::string& err) : Exception(err) {}
};
/*************************************************
* Algorithm_Not_Found Exception *
*************************************************/
struct Algorithm_Not_Found : public Exception
{
Algorithm_Not_Found(const std::string&);
};
/*************************************************
* Format_Error Exception *
*************************************************/
struct Format_Error : public Exception
{
Format_Error(const std::string& err = "") : Exception(err) {}
};
/*************************************************
* Invalid_Algorithm_Name Exception *
*************************************************/
struct Invalid_Algorithm_Name : public Format_Error
{
Invalid_Algorithm_Name(const std::string&);
};
/*************************************************
* Encoding_Error Exception *
*************************************************/
struct Encoding_Error : public Format_Error
{
Encoding_Error(const std::string& name) :
Format_Error("Encoding error: " + name) {}
};
/*************************************************
* Decoding_Error Exception *
*************************************************/
struct Decoding_Error : public Format_Error
{
Decoding_Error(const std::string& name) :
Format_Error("Decoding error: " + name) {}
};
/*************************************************
* Invalid_OID Exception *
*************************************************/
struct Invalid_OID : public Decoding_Error
{
Invalid_OID(const std::string& oid) :
Decoding_Error("Invalid ASN.1 OID: " + oid) {}
};
/*************************************************
* Stream_IO_Error Exception *
*************************************************/
struct Stream_IO_Error : public Exception
{
Stream_IO_Error(const std::string& err) :
Exception("I/O error: " + err) {}
};
/*************************************************
* Configuration Error Exception *
*************************************************/
struct Config_Error : public Format_Error
{
Config_Error(const std::string& err) :
Format_Error("Config error: " + err) {}
Config_Error(const std::string&, u32bit);
};
/*************************************************
* Integrity Failure Exception *
*************************************************/
struct Integrity_Failure : public Exception
{
Integrity_Failure(const std::string& err) :
Exception("Integrity failure: " + err) {}
};
/*************************************************
* Internal_Error Exception *
*************************************************/
struct Internal_Error : public Exception
{
Internal_Error(const std::string& err) :
Exception("Internal error: " + err) {}
};
/*************************************************
* Self Test Failure Exception *
*************************************************/
struct Self_Test_Failure : public Internal_Error
{
Self_Test_Failure(const std::string& err) :
Internal_Error("Self test failed: " + err) {}
};
/*************************************************
* Memory Allocation Exception *
*************************************************/
struct Memory_Exhaustion : public Exception
{
Memory_Exhaustion() :
Exception("Ran out of memory, allocation failed") {}
};
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,181 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Library Internal/Global State Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_LIB_STATE_H__
#define BOTAN_LIB_STATE_H__
#ifdef BOTAN_TOOLS_ONLY
} // WRAPNS_LINE
#include <botan/allocate.h>
namespace QCA { // WRAPNS_LINE
#else
} // WRAPNS_LINE
#include <botan/base.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/enums.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/ui.h>
namespace QCA { // WRAPNS_LINE
#endif
} // WRAPNS_LINE
#include <string>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <vector>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <map>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Global State Container Base *
*************************************************/
class Library_State
{
public:
#ifndef BOTAN_TOOLS_ONLY
class Engine_Iterator
{
public:
class Engine* next();
Engine_Iterator(const Library_State& l) : lib(l) { n = 0; }
private:
const Library_State& lib;
u32bit n;
};
friend class Engine_Iterator;
class UI
{
public:
virtual void pulse(Pulse_Type) {}
virtual ~UI() {}
};
#endif
int prealloc_size;
Allocator* get_allocator(const std::string& = "") const;
void add_allocator(Allocator*);
#ifdef BOTAN_TOOLS_ONLY
void set_default_allocator(const std::string&);
#else
void set_default_allocator(const std::string&) const;
#endif
#ifndef BOTAN_TOOLS_ONLY
bool rng_is_seeded() const { return rng->is_seeded(); }
void randomize(byte[], u32bit);
void set_prng(RandomNumberGenerator*);
void add_entropy_source(EntropySource*, bool = true);
void add_entropy(const byte[], u32bit);
void add_entropy(EntropySource&, bool);
u32bit seed_prng(bool, u32bit);
#endif
void load(class Modules&);
#ifndef BOTAN_TOOLS_ONLY
void set_timer(class Timer*);
u64bit system_clock() const;
class Config& config() const;
void add_engine(class Engine*);
#endif
class Mutex* get_mutex() const;
class Mutex* get_named_mutex(const std::string&);
#ifndef BOTAN_TOOLS_ONLY
void set_x509_state(class X509_GlobalState*);
class X509_GlobalState& x509_state();
void pulse(Pulse_Type) const;
void set_ui(UI*);
void set_transcoder(class Charset_Transcoder*);
std::string transcode(const std::string,
Character_Set, Character_Set) const;
#endif
Library_State(class Mutex_Factory*);
~Library_State();
private:
Library_State(const Library_State&) {}
Library_State& operator=(const Library_State&) { return (*this); }
#ifndef BOTAN_TOOLS_ONLY
class Engine* get_engine_n(u32bit) const;
#endif
class Mutex_Factory* mutex_factory;
#ifndef BOTAN_TOOLS_ONLY
class Timer* timer;
class Config* config_obj;
class X509_GlobalState* x509_state_obj;
#endif
std::map<std::string, class Mutex*> locks;
std::map<std::string, Allocator*> alloc_factory;
mutable Allocator* cached_default_allocator;
#ifdef BOTAN_TOOLS_ONLY
std::string default_allocator_type;
#endif
#ifndef BOTAN_TOOLS_ONLY
UI* ui;
class Charset_Transcoder* transcoder;
RandomNumberGenerator* rng;
#endif
std::vector<Allocator*> allocators;
#ifndef BOTAN_TOOLS_ONLY
std::vector<EntropySource*> entropy_sources;
std::vector<class Engine*> engines;
#endif
};
/*************************************************
* Global State *
*************************************************/
Library_State& global_state();
void set_global_state(Library_State*);
Library_State* swap_global_state(Library_State*);
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,66 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Memory Operations Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_MEMORY_OPS_H__
#define BOTAN_MEMORY_OPS_H__
} // WRAPNS_LINE
#include <botan/types.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <cstring>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <string.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Memory Manipulation Functions *
*************************************************/
template<typename T> inline void copy_mem(T* out, const T* in, u32bit n)
{ memmove(out, in, sizeof(T)*n); }
template<typename T> inline void clear_mem(T* ptr, u32bit n)
{ memset(ptr, 0, sizeof(T)*n); }
template<typename T> inline void set_mem(T* ptr, u32bit n, byte val)
{ memset(ptr, val, sizeof(T)*n); }
template<typename T> inline bool same_mem(const T* p1, const T* p2, u32bit n)
{ return (memcmp(p1, p2, sizeof(T)*n) == 0); }
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,113 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Pooling Allocator Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_POOLING_ALLOCATOR_H__
#define BOTAN_POOLING_ALLOCATOR_H__
} // WRAPNS_LINE
#include <botan/allocate.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/exceptn.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/mutex.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <utility>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <vector>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Pooling Allocator *
*************************************************/
class Pooling_Allocator : public Allocator
{
public:
void* allocate(u32bit);
void deallocate(void*, u32bit);
void destroy();
Pooling_Allocator(u32bit, bool);
~Pooling_Allocator();
private:
void get_more_core(u32bit);
byte* allocate_blocks(u32bit);
virtual void* alloc_block(u32bit) = 0;
virtual void dealloc_block(void*, u32bit) = 0;
class Memory_Block
{
public:
Memory_Block(void*);
static u32bit bitmap_size() { return BITMAP_SIZE; }
static u32bit block_size() { return BLOCK_SIZE; }
bool contains(void*, u32bit) const throw();
byte* alloc(u32bit) throw();
void free(void*, u32bit) throw();
bool operator<(const Memory_Block& other) const
{
if(buffer < other.buffer && other.buffer < buffer_end)
return false;
return (buffer < other.buffer);
}
private:
typedef u64bit bitmap_type;
static const u32bit BITMAP_SIZE;
static const u32bit BLOCK_SIZE;
bitmap_type bitmap;
byte* buffer, *buffer_end;
};
const u32bit PREF_SIZE;
std::vector<Memory_Block> blocks;
std::vector<Memory_Block>::iterator last_used;
std::vector<std::pair<void*, u32bit> > allocated;
Mutex* mutex;
};
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,58 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Memory Mapping Allocator Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_EXT_MMAP_ALLOCATOR_H__
#define BOTAN_EXT_MMAP_ALLOCATOR_H__
} // WRAPNS_LINE
#include <botan/mem_pool.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Memory Mapping Allocator *
*************************************************/
class MemoryMapping_Allocator : public Pooling_Allocator
{
public:
MemoryMapping_Allocator() : Pooling_Allocator(64*1024, false) {}
std::string type() const { return "mmap"; }
private:
void* alloc_block(u32bit);
void dealloc_block(void*, u32bit);
};
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,109 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Module Factory Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_MODULE_FACTORIES_H__
#define BOTAN_MODULE_FACTORIES_H__
#ifndef BOTAN_TOOLS_ONLY
} // WRAPNS_LINE
#include <botan/init.h>
namespace QCA { // WRAPNS_LINE
#endif
} // WRAPNS_LINE
#include <string>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <vector>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Module Builder Interface *
*************************************************/
class Modules
{
public:
virtual class Mutex_Factory* mutex_factory() const = 0;
#ifndef BOTAN_TOOLS_ONLY
virtual class Timer* timer() const = 0;
virtual class Charset_Transcoder* transcoder() const = 0;
#endif
virtual std::string default_allocator() const = 0;
virtual std::vector<class Allocator*> allocators() const = 0;
#ifndef BOTAN_TOOLS_ONLY
virtual std::vector<class EntropySource*> entropy_sources() const = 0;
virtual std::vector<class Engine*> engines() const = 0;
#endif
virtual ~Modules() {}
};
/*************************************************
* Built In Modules *
*************************************************/
class Builtin_Modules : public Modules
{
public:
class Mutex_Factory* mutex_factory() const;
#ifndef BOTAN_TOOLS_ONLY
class Timer* timer() const;
class Charset_Transcoder* transcoder() const;
#endif
std::string default_allocator() const;
std::vector<class Allocator*> allocators() const;
#ifndef BOTAN_TOOLS_ONLY
std::vector<class EntropySource*> entropy_sources() const;
std::vector<class Engine*> engines() const;
#endif
#ifdef BOTAN_TOOLS_ONLY
Builtin_Modules();
#else
Builtin_Modules(const InitializerOptions&);
#endif
private:
#ifdef BOTAN_TOOLS_ONLY
const bool should_lock;
#else
const bool should_lock, use_engines;
#endif
};
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,81 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Lowest Level MPI Algorithms Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_MP_ASM_H__
#define BOTAN_MP_ASM_H__
} // WRAPNS_LINE
#include <botan/mp_types.h>
namespace QCA { // WRAPNS_LINE
#if (BOTAN_MP_WORD_BITS == 8)
typedef Botan::u16bit dword;
#elif (BOTAN_MP_WORD_BITS == 16)
typedef Botan::u32bit dword;
#elif (BOTAN_MP_WORD_BITS == 32)
typedef Botan::u64bit dword;
#elif (BOTAN_MP_WORD_BITS == 64)
#error BOTAN_MP_WORD_BITS can be 64 only with assembly support
#else
#error BOTAN_MP_WORD_BITS must be 8, 16, 32, or 64
#endif
namespace Botan {
extern "C" {
/*************************************************
* Word Multiply/Add *
*************************************************/
inline word word_madd2(word a, word b, word c, word* carry)
{
dword z = (dword)a * b + c;
*carry = (word)(z >> BOTAN_MP_WORD_BITS);
return (word)z;
}
/*************************************************
* Word Multiply/Add *
*************************************************/
inline word word_madd3(word a, word b, word c, word d, word* carry)
{
dword z = (dword)a * b + c + d;
*carry = (word)(z >> BOTAN_MP_WORD_BITS);
return (word)z;
}
}
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,215 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Lowest Level MPI Algorithms Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_MP_ASM_INTERNAL_H__
#define BOTAN_MP_ASM_INTERNAL_H__
} // WRAPNS_LINE
#include <botan/mp_asm.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
extern "C" {
/*************************************************
* Word Addition *
*************************************************/
inline word word_add(word x, word y, word* carry)
{
word z = x + y;
word c1 = (z < x);
z += *carry;
*carry = c1 | (z < *carry);
return z;
}
/*************************************************
* Eight Word Block Addition, Two Argument *
*************************************************/
inline word word8_add2(word x[8], const word y[8], word carry)
{
x[0] = word_add(x[0], y[0], &carry);
x[1] = word_add(x[1], y[1], &carry);
x[2] = word_add(x[2], y[2], &carry);
x[3] = word_add(x[3], y[3], &carry);
x[4] = word_add(x[4], y[4], &carry);
x[5] = word_add(x[5], y[5], &carry);
x[6] = word_add(x[6], y[6], &carry);
x[7] = word_add(x[7], y[7], &carry);
return carry;
}
/*************************************************
* Eight Word Block Addition, Three Argument *
*************************************************/
inline word word8_add3(word z[8], const word x[8],
const word y[8], word carry)
{
z[0] = word_add(x[0], y[0], &carry);
z[1] = word_add(x[1], y[1], &carry);
z[2] = word_add(x[2], y[2], &carry);
z[3] = word_add(x[3], y[3], &carry);
z[4] = word_add(x[4], y[4], &carry);
z[5] = word_add(x[5], y[5], &carry);
z[6] = word_add(x[6], y[6], &carry);
z[7] = word_add(x[7], y[7], &carry);
return carry;
}
/*************************************************
* Word Subtraction *
*************************************************/
inline word word_sub(word x, word y, word* carry)
{
word t0 = x - y;
word c1 = (t0 > x);
word z = t0 - *carry;
*carry = c1 | (z > t0);
return z;
}
/*************************************************
* Eight Word Block Subtraction, Two Argument *
*************************************************/
inline word word8_sub2(word x[4], const word y[4], word carry)
{
x[0] = word_sub(x[0], y[0], &carry);
x[1] = word_sub(x[1], y[1], &carry);
x[2] = word_sub(x[2], y[2], &carry);
x[3] = word_sub(x[3], y[3], &carry);
x[4] = word_sub(x[4], y[4], &carry);
x[5] = word_sub(x[5], y[5], &carry);
x[6] = word_sub(x[6], y[6], &carry);
x[7] = word_sub(x[7], y[7], &carry);
return carry;
}
/*************************************************
* Eight Word Block Subtraction, Three Argument *
*************************************************/
inline word word8_sub3(word z[8], const word x[8],
const word y[8], word carry)
{
z[0] = word_sub(x[0], y[0], &carry);
z[1] = word_sub(x[1], y[1], &carry);
z[2] = word_sub(x[2], y[2], &carry);
z[3] = word_sub(x[3], y[3], &carry);
z[4] = word_sub(x[4], y[4], &carry);
z[5] = word_sub(x[5], y[5], &carry);
z[6] = word_sub(x[6], y[6], &carry);
z[7] = word_sub(x[7], y[7], &carry);
return carry;
}
/*************************************************
* Eight Word Block Linear Multiplication *
*************************************************/
inline word word8_linmul2(word x[4], word y, word carry)
{
x[0] = word_madd2(x[0], y, carry, &carry);
x[1] = word_madd2(x[1], y, carry, &carry);
x[2] = word_madd2(x[2], y, carry, &carry);
x[3] = word_madd2(x[3], y, carry, &carry);
x[4] = word_madd2(x[4], y, carry, &carry);
x[5] = word_madd2(x[5], y, carry, &carry);
x[6] = word_madd2(x[6], y, carry, &carry);
x[7] = word_madd2(x[7], y, carry, &carry);
return carry;
}
/*************************************************
* Eight Word Block Linear Multiplication *
*************************************************/
inline word word8_linmul3(word z[8], const word x[8], word y, word carry)
{
z[0] = word_madd2(x[0], y, carry, &carry);
z[1] = word_madd2(x[1], y, carry, &carry);
z[2] = word_madd2(x[2], y, carry, &carry);
z[3] = word_madd2(x[3], y, carry, &carry);
z[4] = word_madd2(x[4], y, carry, &carry);
z[5] = word_madd2(x[5], y, carry, &carry);
z[6] = word_madd2(x[6], y, carry, &carry);
z[7] = word_madd2(x[7], y, carry, &carry);
return carry;
}
/*************************************************
* Eight Word Block Multiply/Add *
*************************************************/
inline word word8_madd3(word z[8], const word x[8], word y, word carry)
{
z[0] = word_madd3(x[0], y, z[0], carry, &carry);
z[1] = word_madd3(x[1], y, z[1], carry, &carry);
z[2] = word_madd3(x[2], y, z[2], carry, &carry);
z[3] = word_madd3(x[3], y, z[3], carry, &carry);
z[4] = word_madd3(x[4], y, z[4], carry, &carry);
z[5] = word_madd3(x[5], y, z[5], carry, &carry);
z[6] = word_madd3(x[6], y, z[6], carry, &carry);
z[7] = word_madd3(x[7], y, z[7], carry, &carry);
return carry;
}
/*************************************************
* Multiply-Add Accumulator *
*************************************************/
inline void word3_muladd(word* w2, word* w1, word* w0, word a, word b)
{
*w0 = word_madd2(a, b, *w0, &b);
*w1 += b;
*w2 += (*w1 < b) ? 1 : 0;
}
/*************************************************
* Multiply-Add Accumulator *
*************************************************/
inline void word3_muladd_2(word* w2, word* w1, word* w0, word a, word b)
{
a = word_madd2(a, b, 0, &b);
word top = (b >> (BOTAN_MP_WORD_BITS-1));
b <<= 1;
b |= (a >> (BOTAN_MP_WORD_BITS-1));
a <<= 1;
word carry = 0;
*w0 = word_add(*w0, a, &carry);
*w1 = word_add(*w1, b, &carry);
*w2 = word_add(*w2, top, &carry);
}
}
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,118 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* MPI Algorithms Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_MP_CORE_H__
#define BOTAN_MP_CORE_H__
} // WRAPNS_LINE
#include <botan/mp_types.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* The size of the word type, in bits *
*************************************************/
const u32bit MP_WORD_BITS = BOTAN_MP_WORD_BITS;
extern "C" {
/*************************************************
* Addition/Subtraction Operations *
*************************************************/
void bigint_add2(word[], u32bit, const word[], u32bit);
void bigint_add3(word[], const word[], u32bit, const word[], u32bit);
word bigint_add2_nc(word[], u32bit, const word[], u32bit);
word bigint_add3_nc(word[], const word[], u32bit, const word[], u32bit);
void bigint_sub2(word[], u32bit, const word[], u32bit);
void bigint_sub3(word[], const word[], u32bit, const word[], u32bit);
/*************************************************
* Shift Operations *
*************************************************/
void bigint_shl1(word[], u32bit, u32bit, u32bit);
void bigint_shl2(word[], const word[], u32bit, u32bit, u32bit);
void bigint_shr1(word[], u32bit, u32bit, u32bit);
void bigint_shr2(word[], const word[], u32bit, u32bit, u32bit);
/*************************************************
* Multiplication and Squaring Operations *
*************************************************/
word bigint_mul_add_words(word[], const word[], u32bit, word);
void bigint_linmul2(word[], u32bit, word);
void bigint_linmul3(word[], const word[], u32bit, word);
void bigint_linmul_add(word[], u32bit, const word[], u32bit, word);
/*************************************************
* Montgomery Reduction *
*************************************************/
void bigint_monty_redc(word[], u32bit, const word[], u32bit, word);
/*************************************************
* Misc Utility Operations *
*************************************************/
u32bit bigint_divcore(word, word, word, word, word, word);
s32bit bigint_cmp(const word[], u32bit, const word[], u32bit);
word bigint_divop(word, word, word);
word bigint_modop(word, word, word);
void bigint_wordmul(word, word, word*, word*);
/*************************************************
* Comba Multiplication / Squaring *
*************************************************/
void bigint_comba_mul4(word[8], const word[4], const word[4]);
void bigint_comba_mul6(word[12], const word[6], const word[6]);
void bigint_comba_mul8(word[16], const word[8], const word[8]);
void bigint_comba_sqr4(word[8], const word[4]);
void bigint_comba_sqr6(word[12], const word[6]);
void bigint_comba_sqr8(word[16], const word[8]);
}
/*************************************************
* High Level Multiplication/Squaring Interfaces *
*************************************************/
void bigint_mul(word[], u32bit, word[],
const word[], u32bit, u32bit,
const word[], u32bit, u32bit);
void bigint_sqr(word[], u32bit, word[],
const word[], u32bit, u32bit);
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,61 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Low Level MPI Types Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_MPI_TYPES_H__
#define BOTAN_MPI_TYPES_H__
} // WRAPNS_LINE
#include <botan/types.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
#if (BOTAN_MP_WORD_BITS == 8)
typedef byte word;
#elif (BOTAN_MP_WORD_BITS == 16)
typedef u16bit word;
#elif (BOTAN_MP_WORD_BITS == 32)
typedef u32bit word;
#elif (BOTAN_MP_WORD_BITS == 64)
typedef u64bit word;
#else
#error BOTAN_MP_WORD_BITS must be 8, 16, 32, or 64
#endif
const word MP_WORD_MASK = ~((word)0);
const word MP_WORD_TOP_BIT = (word)1 << (8*sizeof(word) - 1);
const word MP_WORD_MAX = MP_WORD_MASK;
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,101 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Mutex Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_MUTEX_H__
#define BOTAN_MUTEX_H__
} // WRAPNS_LINE
#include <botan/exceptn.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Mutex Base Class *
*************************************************/
class Mutex
{
public:
virtual void lock() = 0;
virtual void unlock() = 0;
virtual ~Mutex() {}
};
/*************************************************
* Mutex Factory *
*************************************************/
class Mutex_Factory
{
public:
virtual Mutex* make() = 0;
virtual ~Mutex_Factory() {}
};
/*************************************************
* Default Mutex Factory *
*************************************************/
class Default_Mutex_Factory : public Mutex_Factory
{
public:
Mutex* make();
};
/*************************************************
* Mutex Holding Class *
*************************************************/
class Mutex_Holder
{
public:
Mutex_Holder(Mutex*);
~Mutex_Holder();
private:
Mutex* mux;
};
/*************************************************
* Named Mutex Holder *
*************************************************/
#ifndef BOTAN_NO_LIBSTATE
class Named_Mutex_Holder
{
public:
Named_Mutex_Holder(const std::string&);
~Named_Mutex_Holder();
private:
const std::string mutex_name;
};
#endif
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,54 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Qt Mutex Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_EXT_MUTEX_QT_H__
#define BOTAN_EXT_MUTEX_QT_H__
} // WRAPNS_LINE
#include <botan/mutex.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Qt Mutex *
*************************************************/
class Qt_Mutex_Factory : public Mutex_Factory
{
public:
Mutex* make();
};
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,131 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Number Theory Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_NUMBTHRY_H__
#define BOTAN_NUMBTHRY_H__
} // WRAPNS_LINE
#include <botan/bigint.h>
namespace QCA { // WRAPNS_LINE
#ifndef BOTAN_MINIMAL_BIGINT
} // WRAPNS_LINE
#include <botan/reducer.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/pow_mod.h>
namespace QCA { // WRAPNS_LINE
#endif
namespace Botan {
#ifndef BOTAN_MINIMAL_BIGINT
/*************************************************
* Fused Arithmetic Operations *
*************************************************/
BigInt mul_add(const BigInt&, const BigInt&, const BigInt&);
BigInt sub_mul(const BigInt&, const BigInt&, const BigInt&);
/*************************************************
* Number Theory Functions *
*************************************************/
inline BigInt abs(const BigInt& n) { return n.abs(); }
#endif
void divide(const BigInt&, const BigInt&, BigInt&, BigInt&);
#ifndef BOTAN_MINIMAL_BIGINT
BigInt gcd(const BigInt&, const BigInt&);
BigInt lcm(const BigInt&, const BigInt&);
BigInt square(const BigInt&);
BigInt inverse_mod(const BigInt&, const BigInt&);
s32bit jacobi(const BigInt&, const BigInt&);
BigInt power_mod(const BigInt&, const BigInt&, const BigInt&);
/*************************************************
* Utility Functions *
*************************************************/
u32bit low_zero_bits(const BigInt&);
/*************************************************
* Primality Testing *
*************************************************/
bool check_prime(const BigInt&);
bool is_prime(const BigInt&);
bool verify_prime(const BigInt&);
s32bit simple_primality_tests(const BigInt&);
bool passes_mr_tests(const BigInt&, u32bit = 1);
bool run_primality_tests(const BigInt&, u32bit = 1);
/*************************************************
* Random Number Generation *
*************************************************/
BigInt random_integer(u32bit);
BigInt random_integer(const BigInt&, const BigInt&);
BigInt random_prime(u32bit, const BigInt& = 1, u32bit = 1, u32bit = 2);
BigInt random_safe_prime(u32bit);
SecureVector<byte> generate_dsa_primes(BigInt&, BigInt&, u32bit);
bool generate_dsa_primes(BigInt&, BigInt&, const byte[], u32bit, u32bit,
u32bit = 0);
/*************************************************
* Prime Numbers *
*************************************************/
const u32bit PRIME_TABLE_SIZE = 6541;
const u32bit PRIME_PRODUCTS_TABLE_SIZE = 256;
extern const u16bit PRIMES[];
extern const u64bit PRIME_PRODUCTS[];
/*************************************************
* Miller-Rabin Primality Tester *
*************************************************/
class MillerRabin_Test
{
public:
bool passes_test(const BigInt&);
MillerRabin_Test(const BigInt&);
private:
BigInt n, r, n_minus_1;
u32bit s;
Fixed_Exponent_Power_Mod pow_mod;
Modular_Reducer reducer;
};
#endif
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,70 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Parser Functions Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_PARSER_H__
#define BOTAN_PARSER_H__
} // WRAPNS_LINE
#include <botan/types.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <string>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <vector>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* String Parsing Functions *
*************************************************/
#ifndef BOTAN_TOOLS_ONLY
std::vector<std::string> parse_algorithm_name(const std::string&);
std::vector<std::string> split_on(const std::string&, char);
std::vector<u32bit> parse_asn1_oid(const std::string&);
bool x500_name_cmp(const std::string&, const std::string&);
u32bit parse_expr(const std::string&);
#endif
/*************************************************
* String/Integer Conversions *
*************************************************/
std::string to_string(u64bit, u32bit = 0);
#ifndef BOTAN_TOOLS_ONLY
u32bit to_u32bit(const std::string&);
#endif
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,245 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Secure Memory Buffers Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__
#define BOTAN_SECURE_MEMORY_BUFFERS_H__
} // WRAPNS_LINE
#include <botan/allocate.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/mem_ops.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Variable Length Memory Buffer *
*************************************************/
template<typename T>
class MemoryRegion
{
public:
u32bit size() const { return used; }
u32bit is_empty() const { return (used == 0); }
u32bit has_items() const { return (used != 0); }
operator T* () { return buf; }
operator const T* () const { return buf; }
T* begin() { return buf; }
const T* begin() const { return buf; }
T* end() { return (buf + size()); }
const T* end() const { return (buf + size()); }
bool operator==(const MemoryRegion<T>& other) const
{
return (size() == other.size() &&
same_mem(buf, other.buf, size()));
}
bool operator<(const MemoryRegion<T>&) const;
bool operator!=(const MemoryRegion<T>& in) const
{ return (!(*this == in)); }
MemoryRegion<T>& operator=(const MemoryRegion<T>& in)
{ if(this != &in) set(in); return (*this); }
void copy(const T in[], u32bit n)
{ copy(0, in, n); }
void copy(u32bit off, const T in[], u32bit n)
{ copy_mem(buf + off, in, (n > size() - off) ? (size() - off) : n); }
void set(const T in[], u32bit n) { create(n); copy(in, n); }
void set(const MemoryRegion<T>& in) { set(in.begin(), in.size()); }
void append(const T data[], u32bit n)
{ grow_to(size()+n); copy(size() - n, data, n); }
void append(T x) { append(&x, 1); }
void append(const MemoryRegion<T>& x) { append(x.begin(), x.size()); }
void clear() { clear_mem(buf, allocated); }
void destroy() { create(0); }
void create(u32bit);
void grow_to(u32bit) const;
void swap(MemoryRegion<T>&);
~MemoryRegion() { deallocate(buf, allocated); }
protected:
MemoryRegion() { buf = 0; alloc = 0; used = allocated = 0; }
MemoryRegion(const MemoryRegion<T>& copy)
{
buf = 0;
used = allocated = 0;
alloc = copy.alloc;
set(copy.buf, copy.used);
}
void init(bool locking, u32bit size = 0)
{ alloc = Allocator::get(locking); create(size); }
private:
T* allocate(u32bit n) const { return (T*)alloc->allocate(sizeof(T)*n); }
void deallocate(T* p, u32bit n) const
{ alloc->deallocate(p, sizeof(T)*n); }
mutable T* buf;
mutable u32bit used;
mutable u32bit allocated;
mutable Allocator* alloc;
};
/*************************************************
* Create a new buffer *
*************************************************/
template<typename T>
void MemoryRegion<T>::create(u32bit n)
{
if(n <= allocated) { clear(); used = n; return; }
deallocate(buf, allocated);
buf = allocate(n);
allocated = used = n;
}
/*************************************************
* Increase the size of the buffer *
*************************************************/
template<typename T>
void MemoryRegion<T>::grow_to(u32bit n) const
{
if(n > used && n <= allocated)
{
clear_mem(buf + used, n - used);
used = n;
return;
}
else if(n > allocated)
{
T* new_buf = allocate(n);
copy_mem(new_buf, buf, used);
deallocate(buf, allocated);
buf = new_buf;
allocated = used = n;
}
}
/*************************************************
* Compare this buffer with another one *
*************************************************/
template<typename T>
bool MemoryRegion<T>::operator<(const MemoryRegion<T>& in) const
{
if(size() < in.size()) return true;
if(size() > in.size()) return false;
for(u32bit j = 0; j != size(); j++)
{
if(buf[j] < in[j]) return true;
if(buf[j] > in[j]) return false;
}
return false;
}
/*************************************************
* Swap this buffer with another one *
*************************************************/
template<typename T>
void MemoryRegion<T>::swap(MemoryRegion<T>& x)
{
std::swap(buf, x.buf);
std::swap(used, x.used);
std::swap(allocated, x.allocated);
std::swap(alloc, x.alloc);
}
/*************************************************
* Unlocked Variable Length Buffer *
*************************************************/
template<typename T>
class MemoryVector : public MemoryRegion<T>
{
public:
MemoryVector<T>& operator=(const MemoryRegion<T>& in)
{ if(this != &in) set(in); return (*this); }
MemoryVector(u32bit n = 0) { MemoryRegion<T>::init(false, n); }
MemoryVector(const T in[], u32bit n)
{ MemoryRegion<T>::init(false); set(in, n); }
MemoryVector(const MemoryRegion<T>& in)
{ MemoryRegion<T>::init(false); set(in); }
MemoryVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
{ MemoryRegion<T>::init(false); set(in1); append(in2); }
};
/*************************************************
* Locked Variable Length Buffer *
*************************************************/
template<typename T>
class SecureVector : public MemoryRegion<T>
{
public:
SecureVector<T>& operator=(const MemoryRegion<T>& in)
{ if(this != &in) set(in); return (*this); }
SecureVector(u32bit n = 0) { MemoryRegion<T>::init(true, n); }
SecureVector(const T in[], u32bit n)
{ MemoryRegion<T>::init(true); this->set(in, n); }
SecureVector(const MemoryRegion<T>& in)
{ MemoryRegion<T>::init(true); set(in); }
SecureVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
{ MemoryRegion<T>::init(true); set(in1); append(in2); }
};
/*************************************************
* Locked Fixed Length Buffer *
*************************************************/
template<typename T, u32bit L>
class SecureBuffer : public MemoryRegion<T>
{
public:
SecureBuffer<T,L>& operator=(const SecureBuffer<T,L>& in)
{ if(this != &in) set(in); return (*this); }
SecureBuffer() { MemoryRegion<T>::init(true, L); }
SecureBuffer(const T in[], u32bit n)
{ MemoryRegion<T>::init(true, L); copy(in, n); }
private:
SecureBuffer<T, L>& operator=(const MemoryRegion<T>& in)
{ if(this != &in) set(in); return (*this); }
};
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,114 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* STL Utility Functions Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_STL_UTIL_H__
#define BOTAN_STL_UTIL_H__
} // WRAPNS_LINE
#include <map>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Copy-on-Predicate Algorithm *
*************************************************/
template<typename InputIterator, typename OutputIterator, typename Predicate>
OutputIterator copy_if(InputIterator current, InputIterator end,
OutputIterator dest, Predicate copy_p)
{
while(current != end)
{
if(copy_p(*current))
*dest++ = *current;
++current;
}
return dest;
}
/*************************************************
* Searching through a std::map *
*************************************************/
template<typename K, typename V>
inline V search_map(const std::map<K, V>& mapping,
const K& key,
const V& null_result = V())
{
typename std::map<K, V>::const_iterator i = mapping.find(key);
if(i == mapping.end())
return null_result;
return i->second;
}
template<typename K, typename V, typename R>
inline R search_map(const std::map<K, V>& mapping, const K& key,
const R& null_result, const R& found_result)
{
typename std::map<K, V>::const_iterator i = mapping.find(key);
if(i == mapping.end())
return null_result;
return found_result;
}
/*************************************************
* Function adaptor for delete operation *
*************************************************/
template<class T>
class del_fun : public std::unary_function<T, void>
{
public:
void operator()(T* ptr) { delete ptr; }
};
/*************************************************
* Delete the second half of a pair of objects *
*************************************************/
template<typename Pair>
void delete2nd(Pair& pair)
{
delete pair.second;
}
/*************************************************
* Insert a key/value pair into a multimap *
*************************************************/
template<typename K, typename V>
void multimap_insert(std::multimap<K, V>& multimap,
const K& key, const V& value)
{
multimap.insert(std::make_pair(key, value));
}
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,86 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Low Level Types Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_TYPES_H__
#define BOTAN_TYPES_H__
#ifdef BOTAN_TYPES_QT
} // WRAPNS_LINE
#include <QtGlobal>
namespace QCA { // WRAPNS_LINE
#else
} // WRAPNS_LINE
#include <botan/build.h>
namespace QCA { // WRAPNS_LINE
#endif
namespace Botan {
#ifdef BOTAN_TYPES_QT
typedef quint8 byte;
typedef quint16 u16bit;
typedef quint32 u32bit;
typedef qint32 s32bit;
typedef quint64 u64bit;
#else
typedef unsigned char byte;
typedef unsigned short u16bit;
typedef unsigned int u32bit;
typedef signed int s32bit;
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 u64bit;
#elif defined(__KCC)
typedef unsigned __long_long u64bit;
#elif defined(__GNUG__)
__extension__ typedef unsigned long long u64bit;
#else
typedef unsigned long long u64bit;
#endif
#endif // BOTAN_TYPES_QT
}
namespace Botan_types {
typedef Botan::byte byte;
typedef Botan::u32bit u32bit;
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,76 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Utility Functions Header File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#ifndef BOTAN_UTIL_H__
#define BOTAN_UTIL_H__
} // WRAPNS_LINE
#include <botan/types.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Timer Access Functions *
*************************************************/
#ifndef BOTAN_TOOLS_ONLY
u64bit system_time();
u64bit system_clock();
#endif
/*************************************************
* Memory Locking Functions *
*************************************************/
void lock_mem(void*, u32bit);
void unlock_mem(void*, u32bit);
/*************************************************
* Misc Utility Functions *
*************************************************/
u32bit round_up(u32bit, u32bit);
u32bit round_down(u32bit, u32bit);
#ifndef BOTAN_TOOLS_ONLY
u64bit combine_timers(u32bit, u32bit, u32bit);
#endif
/*************************************************
* Work Factor Estimates *
*************************************************/
#ifndef BOTAN_TOOLS_ONLY
u32bit entropy_estimate(const byte[], u32bit);
u32bit dl_work_factor(u32bit);
#endif
}
#endif
} // WRAPNS_LINE

View file

@ -0,0 +1,224 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Character Set Handling Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
} // WRAPNS_LINE
#include <botan/charset.h>
namespace QCA { // WRAPNS_LINE
#ifdef BOTAN_TOOLS_ONLY
} // WRAPNS_LINE
#include <botan/exceptn.h>
namespace QCA { // WRAPNS_LINE
#else
} // WRAPNS_LINE
#include <botan/hex.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/base64.h>
namespace QCA { // WRAPNS_LINE
#endif
} // WRAPNS_LINE
#include <botan/libstate.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <cctype>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <ctype.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
namespace Charset {
/*************************************************
* Perform character set transcoding *
*************************************************/
#ifndef BOTAN_TOOLS_ONLY
std::string transcode(const std::string& str,
Character_Set to, Character_Set from)
{
return global_state().transcode(str, to, from);
}
#endif
/*************************************************
* Check if a character represents a digit *
*************************************************/
bool is_digit(char c)
{
if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' ||
c == '5' || c == '6' || c == '7' || c == '8' || c == '9')
return true;
return false;
}
/*************************************************
* Check if a character represents whitespace *
*************************************************/
bool is_space(char c)
{
if(c == ' ' || c == '\t' || c == '\n' || c == '\r')
return true;
return false;
}
/*************************************************
* Convert a character to a digit *
*************************************************/
byte char2digit(char c)
{
switch(c)
{
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
}
throw Invalid_Argument("char2digit: Input is not a digit character");
}
/*************************************************
* Convert a digit to a character *
*************************************************/
char digit2char(byte b)
{
switch(b)
{
case 0: return '0';
case 1: return '1';
case 2: return '2';
case 3: return '3';
case 4: return '4';
case 5: return '5';
case 6: return '6';
case 7: return '7';
case 8: return '8';
case 9: return '9';
}
throw Invalid_Argument("digit2char: Input is not a digit");
}
/*************************************************
* Case-insensitive character comparison *
*************************************************/
bool caseless_cmp(char a, char b)
{
return (tolower((unsigned char)a) == tolower((unsigned char)b));
}
}
#ifndef BOTAN_TOOLS_ONLY
/*************************************************
* Hex Encoder Lookup Tables *
*************************************************/
const byte Hex_Encoder::BIN_TO_HEX_UPPER[16] = {
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43,
0x44, 0x45, 0x46 };
const byte Hex_Encoder::BIN_TO_HEX_LOWER[16] = {
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63,
0x64, 0x65, 0x66 };
/*************************************************
* Base64 Encoder Lookup Table *
*************************************************/
const byte Base64_Encoder::BIN_TO_BASE64[64] = {
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,
0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F };
/*************************************************
* Hex Decoder Lookup Table *
*************************************************/
const byte Hex_Decoder::HEX_TO_BIN[256] = {
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
/*************************************************
* Base64 Decoder Lookup Table *
*************************************************/
const byte Base64_Decoder::BASE64_TO_BIN[256] = {
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, 0x80, 0x3F, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
#endif
}
} // WRAPNS_LINE

View file

@ -0,0 +1,142 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Basic Allocators Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
} // WRAPNS_LINE
#include <botan/defalloc.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/libstate.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/util.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <cstdlib>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <cstring>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <stdlib.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <string.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
namespace {
/*************************************************
* Perform Memory Allocation *
*************************************************/
void* do_malloc(u32bit n, bool do_lock)
{
void* ptr = malloc(n);
if(!ptr)
return 0;
if(do_lock)
lock_mem(ptr, n);
memset(ptr, 0, n);
return ptr;
}
/*************************************************
* Perform Memory Deallocation *
*************************************************/
void do_free(void* ptr, u32bit n, bool do_lock)
{
if(!ptr)
return;
memset(ptr, 0, n);
if(do_lock)
unlock_mem(ptr, n);
free(ptr);
}
}
/*************************************************
* Malloc_Allocator's Allocation *
*************************************************/
void* Malloc_Allocator::alloc_block(u32bit n)
{
return do_malloc(n, false);
}
/*************************************************
* Malloc_Allocator's Deallocation *
*************************************************/
void Malloc_Allocator::dealloc_block(void* ptr, u32bit n)
{
do_free(ptr, n, false);
}
/*************************************************
* Locking_Allocator's Allocation *
*************************************************/
void* Locking_Allocator::alloc_block(u32bit n)
{
return do_malloc(n, true);
}
/*************************************************
* Locking_Allocator's Deallocation *
*************************************************/
void Locking_Allocator::dealloc_block(void* ptr, u32bit n)
{
do_free(ptr, n, true);
}
/*************************************************
* Get an allocator *
*************************************************/
Allocator* Allocator::get(bool locking)
{
std::string type = "";
if(!locking)
type = "malloc";
Allocator* alloc = global_state().get_allocator(type);
if(alloc)
return alloc;
throw Exception("Couldn't find an allocator to use in get_allocator");
}
}
} // WRAPNS_LINE

View file

@ -0,0 +1,136 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Division Algorithm Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
} // WRAPNS_LINE
#include <botan/numthry.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/mp_core.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
namespace {
/*************************************************
* Handle signed operands, if necessary *
*************************************************/
void sign_fixup(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r)
{
if(x.sign() == BigInt::Negative)
{
q.flip_sign();
if(r.is_nonzero()) { --q; r = y.abs() - r; }
}
if(y.sign() == BigInt::Negative)
q.flip_sign();
}
}
/*************************************************
* Solve x = q * y + r *
*************************************************/
void divide(const BigInt& x, const BigInt& y_arg, BigInt& q, BigInt& r)
{
if(y_arg.is_zero())
throw BigInt::DivideByZero();
BigInt y = y_arg;
const u32bit y_words = y.sig_words();
r = x;
r.set_sign(BigInt::Positive);
y.set_sign(BigInt::Positive);
s32bit compare = r.cmp(y);
if(compare < 0)
q = 0;
else if(compare == 0)
{
q = 1;
r = 0;
}
else
{
u32bit shifts = 0;
word y_top = y[y.sig_words()-1];
while(y_top < MP_WORD_TOP_BIT) { y_top <<= 1; ++shifts; }
y <<= shifts;
r <<= shifts;
const u32bit n = r.sig_words() - 1, t = y_words - 1;
q.get_reg().create(n - t + 1);
if(n <= t)
{
while(r > y) { r -= y; q++; }
r >>= shifts;
sign_fixup(x, y_arg, q, r);
return;
}
BigInt temp = y << (MP_WORD_BITS * (n-t));
while(r >= temp) { r -= temp; ++q[n-t]; }
for(u32bit j = n; j != t; --j)
{
const word x_j0 = r.word_at(j);
const word x_j1 = r.word_at(j-1);
const word y_t = y.word_at(t);
if(x_j0 == y_t)
q[j-t-1] = MP_WORD_MAX;
else
q[j-t-1] = bigint_divop(x_j0, x_j1, y_t);
while(bigint_divcore(q[j-t-1], y_t, y.word_at(t-1),
x_j0, x_j1, r.word_at(j-2)))
--q[j-t-1];
r -= (q[j-t-1] * y) << (MP_WORD_BITS * (j-t-1));
if(r.is_negative())
{
r += y << (MP_WORD_BITS * (j-t-1));
--q[j-t-1];
}
}
r >>= shifts;
}
sign_fixup(x, y_arg, q, r);
}
}
} // WRAPNS_LINE

View file

@ -0,0 +1,102 @@
/*
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions, and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// LICENSEHEADER_END
namespace QCA { // WRAPNS_LINE
/*************************************************
* Exceptions Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
} // WRAPNS_LINE
#include <botan/exceptn.h>
namespace QCA { // WRAPNS_LINE
} // WRAPNS_LINE
#include <botan/parsing.h>
namespace QCA { // WRAPNS_LINE
namespace Botan {
/*************************************************
* Constructor for Invalid_Key_Length *
*************************************************/
Invalid_Key_Length::Invalid_Key_Length(const std::string& name, u32bit length)
{
set_msg(name + " cannot accept a key of length " + to_string(length));
}
/*************************************************
* Constructor for Invalid_Block_Size *
*************************************************/
Invalid_Block_Size::Invalid_Block_Size(const std::string& mode,
const std::string& pad)
{
set_msg("Padding method " + pad + " cannot be used with " + mode);
}
/*************************************************
* Constructor for Invalid_IV_Length *
*************************************************/
Invalid_IV_Length::Invalid_IV_Length(const std::string& mode, u32bit bad_len)
{
set_msg("IV length " + to_string(bad_len) + " is invalid for " + mode);
}
/*************************************************
* Constructor for Invalid_Message_Number *
*************************************************/
Invalid_Message_Number::Invalid_Message_Number(const std::string& where,
u32bit message_no)
{
set_msg("Pipe::" + where + ": Invalid message number " +
to_string(message_no));
}
/*************************************************
* Constructor for Algorithm_Not_Found *
*************************************************/
Algorithm_Not_Found::Algorithm_Not_Found(const std::string& name)
{
set_msg("Could not find any algorithm named \"" + name + "\"");
}
/*************************************************
* Constructor for Invalid_Algorithm_Name *
*************************************************/
Invalid_Algorithm_Name::Invalid_Algorithm_Name(const std::string& name)
{
set_msg("Invalid algorithm name: " + name);
}
/*************************************************
* Constructor for Config_Error *
*************************************************/
Config_Error::Config_Error(const std::string& err, u32bit line)
{
set_msg("Config error at line " + to_string(line) + ": " + err);
}
}
} // WRAPNS_LINE

Some files were not shown because too many files have changed in this diff Show more