From 80416fb0b08069ee1179437045ef128a7a817a5f Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Wed, 11 Oct 2023 22:07:47 +0200 Subject: [PATCH] Split basic functions Extract all functions that only depend on Openssl and QtCore --- lib/CMakeLists.txt | 1 + lib/func.cpp | 250 ---------------------------------- lib/func.h | 43 +----- lib/func_base.cpp | 276 ++++++++++++++++++++++++++++++++++++++ lib/func_base.h | 67 +++++++++ lib/test_asn1int.cpp | 25 ++++ lib/test_biobytearray.cpp | 66 +++++++++ 7 files changed, 438 insertions(+), 290 deletions(-) create mode 100644 lib/func_base.cpp create mode 100644 lib/func_base.h create mode 100644 lib/test_asn1int.cpp create mode 100644 lib/test_biobytearray.cpp diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index cba3f8a2..bc2a0a66 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -37,6 +37,7 @@ dhgen.cpp dhgen.h XcaProgress.cpp XcaProgress.h XcaWarningCore.cpp XcaWarningCore.h PwDialogCore.cpp PwDialogCore.h digest.h digest.cpp pki_export.cpp +func_base.cpp func_base.h ) list(TRANSFORM xca_sources PREPEND ${PROJECT_SOURCE_DIR}/lib/) diff --git a/lib/func.cpp b/lib/func.cpp index dc3bb4f8..e40c198d 100644 --- a/lib/func.cpp +++ b/lib/func.cpp @@ -45,8 +45,6 @@ #define getch() getchar() #endif -bool is_gui_app = false; - int console_write(FILE *fp, const QByteArray &ba) { if (ba.size() == 0) @@ -96,19 +94,6 @@ Passwd readPass() return pw; } -const QStringList getLibExtensions() -{ - return QStringList { -#if defined(Q_OS_WIN32) - QString("*.dll"), QString("*.DLL"), -#elif defined(Q_OS_MACOS) - QString("*.dylib"), QString("*.so"), -#else - QString("*.so"), -#endif - }; -} - #if defined(Q_OS_WIN32) static QString registryInstallDir() { @@ -305,21 +290,6 @@ void migrateOldPaths() old_dir.rmdir(old); } -// Qt's open and save dialogs result in some undesirable quirks. -// This function makes sure that a filename has the user-selected extension. -QString getFullFilename(const QString & filename, const QString & selectedFilter) -{ - QString rv = filename.trimmed(), ext; - auto match = QRegularExpression(".* \\( ?\\*(.[a-z]{1,3}) ?\\)") - .match(selectedFilter); - - ext = match.captured(1); - if (ext.isEmpty() || rv.endsWith(ext)) - return rv; - - return rv + ext; -} - QString hostId() { static QString id; @@ -391,171 +361,6 @@ QString hostId() return id; } -QString compressFilename(const QString &filename, int maxlen) -{ - QString fn = filename; - if (fn.length() >= maxlen) { - fn.replace("\\", "/"); - int len, lastslash = fn.lastIndexOf('/'); - QString base = filename.mid(lastslash); - len = maxlen - base.length() - 3; - if (len < 0) { - fn = "..." + base.right(maxlen -3); - } else { - fn = fn.left(len); - lastslash = fn.lastIndexOf('/'); - fn = filename.left(lastslash + 1) + "..." + base; - } - } - return nativeSeparator(fn); -} - -QString asn1ToQString(const ASN1_STRING *str, bool quote) -{ - unsigned char *out = NULL; - int len; - QString utf8; - - len = ASN1_STRING_to_UTF8(&out, str); - if (len != -1) { - utf8 = QString::fromUtf8((const char*)out, len); - OPENSSL_free(out); - } - if (quote) - utf8.replace('\n', "\\n\\"); - return utf8; -} - -/* returns an encoded ASN1 string from QString for a special nid*/ -ASN1_STRING *QStringToAsn1(const QString s, int nid) -{ - QByteArray ba = s.toUtf8(); - const unsigned char *utf8 = (const unsigned char *)ba.constData(); - unsigned long global_mask = ASN1_STRING_get_default_mask(); - unsigned long mask = DIRSTRING_TYPE & global_mask; - ASN1_STRING *out = NULL; - ASN1_STRING_TABLE *tbl; - - tbl = ASN1_STRING_TABLE_get(nid); - if (tbl) { - mask = tbl->mask; - if (!(tbl->flags & STABLE_NO_MASK)) - mask &= global_mask; - } - ASN1_mbstring_copy(&out, utf8, -1, MBSTRING_UTF8, mask); - openssl_error_msg(QString("'%1' (%2)").arg(s).arg(OBJ_nid2ln(nid))); - return out; -} - -const char *OBJ_ln2sn(const char *ln) -{ - return OBJ_nid2sn(OBJ_ln2nid(ln)); -} - -const char *OBJ_sn2ln(const char *sn) -{ - return OBJ_nid2ln(OBJ_sn2nid(sn)); -} - -const char *OBJ_obj2sn(ASN1_OBJECT *a) -{ - OBJ_obj2nid(a); - openssl_error(); - return OBJ_nid2sn(OBJ_obj2nid(a)); -} - -QString OBJ_obj2QString(const ASN1_OBJECT *a, int no_name) -{ - char buf[512]; - int len; - - len = OBJ_obj2txt(buf, sizeof buf, a, no_name); - openssl_error(); - return QString::fromLatin1(buf, len); -} - -QByteArray i2d_bytearray(int(*i2d)(const void*, unsigned char **), - const void *data) -{ - QByteArray ba; - - ba.resize(i2d(data, NULL)); - unsigned char *p = (unsigned char*)ba.data(); - i2d(data, &p); - openssl_error(); - return ba; -} - -void *d2i_bytearray(void *(*d2i)(void *, unsigned char **, long), - QByteArray &ba) -{ - unsigned char *p, *p1; - void *ret; - p = p1 = (unsigned char *)ba.constData(); - ret = d2i(NULL, &p1, ba.size()); - ba = ba.mid(p1-p); - openssl_error(); - return ret; -} - -void _openssl_error(const QString &txt, const char *file, int line) -{ - QString error; - - while (int i = ERR_get_error() ) { - error += QString(ERR_error_string(i, NULL)) + "\n"; - fputs(CCHAR(QString("OpenSSL error (%1:%2) : %3\n"). - arg(file).arg(line).arg(ERR_error_string(i, NULL))), - stderr); - } - if (!error.isEmpty()) { - if (!txt.isEmpty()) - error = txt + "\n" + error + "\n" + - QString("(%1:%2)").arg(file).arg(line); - throw errorEx(error); - } -} - -#undef PRINT_IGNORED_ANYWAY -bool _ign_openssl_error(const QString &txt, const char *file, int line) -{ - // ignore openssl errors - QString errtxt; -#if PRINT_IGNORED_ANYWAY - if (!txt.isEmpty() && ERR_peek_error()) - qDebug() << txt; -#else - (void)txt; - (void)file; - (void)line; -#endif - while (int i = ERR_get_error() ) { - errtxt = ERR_error_string(i, NULL); -#if PRINT_IGNORED_ANYWAY - qDebug() << QString("IGNORED (%1:%2) : %3\n") - .arg(file).arg(line).arg(errtxt); -#endif - } - return !errtxt.isEmpty(); -} - -QString formatHash(const QByteArray &data, QString sep, int width) -{ - return QString(data.toHex()).toUpper() - .replace(QRegularExpression(QString("(.{%1})(?=.)").arg(width)), - QString("\\1") + sep); -} - -QByteArray Digest(const QByteArray &data, const EVP_MD *type) -{ - unsigned int n; - unsigned char m[EVP_MAX_MD_SIZE]; - - EVP_Digest(data.constData(), data.size(), m, &n, type, NULL); - openssl_error(); - return QByteArray((char*)m, (int)n); -} - QString fingerprint(const QByteArray &data, const EVP_MD *type) { return formatHash(Digest(data, type), @@ -566,58 +371,3 @@ void update_workingdir(const QString &file) { Settings["workingdir"] = QFileInfo(file).absolutePath(); } - -QMap dn_translations; - -void dn_translations_setup() -{ -QMap D; -D[NID_countryName] = QObject::tr("Country code"); -D[NID_stateOrProvinceName] = QObject::tr("State or Province"); -D[NID_localityName] = QObject::tr("Locality"); -D[NID_organizationName] = QObject::tr("Organisation"); -D[NID_organizationalUnitName] = QObject::tr("Organisational unit"); -D[NID_commonName] = QObject::tr("Common name"); -D[NID_pkcs9_emailAddress] = QObject::tr("E-Mail address"); -D[NID_serialNumber] = QObject::tr("Serial number"); -D[NID_givenName] = QObject::tr("Given name"); -D[NID_surname] = QObject::tr("Surname"); -D[NID_title] = QObject::tr("Title"); -D[NID_initials] = QObject::tr("Initials"); -D[NID_description] = QObject::tr("Description"); -D[NID_role] = QObject::tr("Role"); -D[NID_pseudonym] = QObject::tr("Pseudonym"); -D[NID_generationQualifier] = QObject::tr("Generation Qualifier"); -D[NID_x500UniqueIdentifier] = QObject::tr("x500 Unique Identifier"); -D[NID_name] = QObject::tr("Name"); -D[NID_dnQualifier] = QObject::tr("DN Qualifier"); -D[NID_pkcs9_unstructuredName] = QObject::tr("Unstructured name"); -D[NID_pkcs9_challengePassword] = QObject::tr("Challenge password"); - -D[NID_basic_constraints] = QObject::tr("Basic Constraints"); -D[NID_subject_alt_name] = QObject::tr("Subject alternative name"); -D[NID_issuer_alt_name] = QObject::tr("issuer alternative name"); -D[NID_subject_key_identifier] = QObject::tr("Subject key identifier"); -D[NID_authority_key_identifier] = QObject::tr("Authority key identifier"); -D[NID_key_usage] = QObject::tr("Key usage"); -D[NID_ext_key_usage] = QObject::tr("Extended key usage"); -D[NID_crl_distribution_points] = QObject::tr("CRL distribution points"); -D[NID_info_access] = QObject::tr("Authority information access"); -D[NID_netscape_cert_type] = QObject::tr("Certificate type"); -D[NID_netscape_base_url] = QObject::tr("Base URL"); -D[NID_netscape_revocation_url] = QObject::tr("Revocation URL"); -D[NID_netscape_ca_revocation_url] = QObject::tr("CA Revocation URL"); -D[NID_netscape_renewal_url] = QObject::tr("Certificate renewal URL"); -D[NID_netscape_ca_policy_url] = QObject::tr("CA policy URL"); -D[NID_netscape_ssl_server_name] = QObject::tr("SSL server name"); -D[NID_netscape_comment] = QObject::tr("Comment"); - -dn_translations = D; -} - -QString appendXcaComment(QString current, QString msg) -{ - if (!current.endsWith("\n") && !current.isEmpty()) - current += "\n"; - return current + QString("(%1)\n").arg(msg); -} diff --git a/lib/func.h b/lib/func.h index 995e2868..a32436c2 100644 --- a/lib/func.h +++ b/lib/func.h @@ -11,11 +11,8 @@ #include #include -#include -#include -#include - #include "base.h" +#include "func_base.h" #include "Passwd.h" #define IS_GUI_APP (is_gui_app) @@ -32,49 +29,15 @@ int console_write(FILE *fp, const QByteArray &ba); Passwd readPass(); int portable_app(); const QString getHomeDir(); +QString relativePath(QString path); const QString getLibDir(); const QString getDocDir(); const QString getUserSettingsDir(); const QString getI18nDir(); -QString relativePath(QString path); -QString getFullFilename(const QString &filename, const QString &selectedFilter); -const QStringList getLibExtensions(); +void migrateOldPaths(); QString hostId(); - -QString formatHash(const QByteArray &data, QString sep = ":", int width = 2); -QString compressFilename(const QString &filename, int maxlen = 50); - -QString asn1ToQString(const ASN1_STRING *str, bool quote = false); -ASN1_STRING *QStringToAsn1(QString s, int nid); - -QByteArray Digest(const QByteArray &data, const EVP_MD *type); QString fingerprint(const QByteArray &data, const EVP_MD *type); void update_workingdir(const QString &file); -const char *OBJ_ln2sn(const char *ln); -const char *OBJ_sn2ln(const char *sn); -const char *OBJ_obj2sn(ASN1_OBJECT *a); -QString OBJ_obj2QString(const ASN1_OBJECT *a, int no_name = 0); - -extern QMap dn_translations; -void dn_translations_setup(); -#define openssl_error_msg(x) _openssl_error(QString(x), C_FILE, __LINE__) -#define openssl_error() openssl_error_msg("") -#define ign_openssl_error() _ign_openssl_error(QString(), C_FILE, __LINE__) -void _openssl_error(const QString &txt, const char *file, int line); -bool _ign_openssl_error(const QString &txt, const char *file, int line); - -QByteArray i2d_bytearray(int(*i2d)(const void*, unsigned char**), const void*); -void *d2i_bytearray(void *(*d2i)(void*, unsigned char**, long), - QByteArray &ba); - -#define I2D_VOID(a) ((int (*)(const void *, unsigned char **))(a)) -#define D2I_VOID(a) ((void *(*)(void *, unsigned char **, long))(a)) - -QString appendXcaComment(QString current, QString msg); - -/* from version.cpp */ -const char *version_str(bool html); - #endif diff --git a/lib/func_base.cpp b/lib/func_base.cpp new file mode 100644 index 00000000..71ee7571 --- /dev/null +++ b/lib/func_base.cpp @@ -0,0 +1,276 @@ +/* vi: set sw=4 ts=4: + * + * Copyright (C) 2001 - 2014 Christian Hohnstaedt. + * + * All rights reserved. + */ + +#include "func_base.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#if 0 +#include +#include +#endif +#include +#include +#include + +#include "exception.h" + +bool is_gui_app = false; + +const QStringList getLibExtensions() +{ + return QStringList { +#if defined(Q_OS_WIN32) + QString("*.dll"), QString("*.DLL"), +#elif defined(Q_OS_MACOS) + QString("*.dylib"), QString("*.so"), +#else + QString("*.so"), +#endif + }; +} + +// Qt's open and save dialogs result in some undesirable quirks. +// This function makes sure that a filename has the user-selected extension. +QString getFullFilename(const QString & filename, const QString & selectedFilter) +{ + QString rv = filename.trimmed(), ext; + auto match = QRegularExpression(".* \\( ?\\*(.[a-z]{1,3}) ?\\)") + .match(selectedFilter); + + ext = match.captured(1); + if (ext.isEmpty() || rv.endsWith(ext)) + return rv; + + return rv + ext; +} + +QString compressFilename(const QString &filename, int maxlen) +{ + QString fn = filename; + if (fn.length() >= maxlen) { + fn.replace("\\", "/"); + int len, lastslash = fn.lastIndexOf('/'); + QString base = filename.mid(lastslash); + len = maxlen - base.length() - 3; + if (len < 0) { + fn = "..." + base.right(maxlen -3); + } else { + fn = fn.left(len); + lastslash = fn.lastIndexOf('/'); + fn = filename.left(lastslash + 1) + "..." + base; + } + } + return nativeSeparator(fn); +} + +QString asn1ToQString(const ASN1_STRING *str, bool quote) +{ + unsigned char *out = NULL; + int len; + QString utf8; + + len = ASN1_STRING_to_UTF8(&out, str); + if (len != -1) { + utf8 = QString::fromUtf8((const char*)out, len); + OPENSSL_free(out); + } + if (quote) + utf8.replace('\n', "\\n\\"); + return utf8; +} + +/* returns an encoded ASN1 string from QString for a special nid*/ +ASN1_STRING *QStringToAsn1(const QString s, int nid) +{ + QByteArray ba = s.toUtf8(); + const unsigned char *utf8 = (const unsigned char *)ba.constData(); + unsigned long global_mask = ASN1_STRING_get_default_mask(); + unsigned long mask = DIRSTRING_TYPE & global_mask; + ASN1_STRING *out = NULL; + ASN1_STRING_TABLE *tbl; + + tbl = ASN1_STRING_TABLE_get(nid); + if (tbl) { + mask = tbl->mask; + if (!(tbl->flags & STABLE_NO_MASK)) + mask &= global_mask; + } + ASN1_mbstring_copy(&out, utf8, -1, MBSTRING_UTF8, mask); + openssl_error_msg(QString("'%1' (%2)").arg(s).arg(OBJ_nid2ln(nid))); + return out; +} + +const char *OBJ_ln2sn(const char *ln) +{ + return OBJ_nid2sn(OBJ_ln2nid(ln)); +} + +const char *OBJ_sn2ln(const char *sn) +{ + return OBJ_nid2ln(OBJ_sn2nid(sn)); +} + +const char *OBJ_obj2sn(ASN1_OBJECT *a) +{ + OBJ_obj2nid(a); + openssl_error(); + return OBJ_nid2sn(OBJ_obj2nid(a)); +} + +QString OBJ_obj2QString(const ASN1_OBJECT *a, int no_name) +{ + char buf[512]; + int len; + + len = OBJ_obj2txt(buf, sizeof buf, a, no_name); + openssl_error(); + return QString::fromLatin1(buf, len); +} + +QByteArray i2d_bytearray(int(*i2d)(const void*, unsigned char **), + const void *data) +{ + QByteArray ba; + + ba.resize(i2d(data, NULL)); + unsigned char *p = (unsigned char*)ba.data(); + i2d(data, &p); + openssl_error(); + return ba; +} + +void *d2i_bytearray(void *(*d2i)(void *, unsigned char **, long), + QByteArray &ba) +{ + unsigned char *p, *p1; + void *ret; + p = p1 = (unsigned char *)ba.constData(); + ret = d2i(NULL, &p1, ba.size()); + ba = ba.mid(p1-p); + openssl_error(); + return ret; +} + +void _openssl_error(const QString &txt, const char *file, int line) +{ + QString error; + + while (int i = ERR_get_error() ) { + error += QString(ERR_error_string(i, NULL)) + "\n"; + fputs(CCHAR(QString("OpenSSL error (%1:%2) : %3\n"). + arg(file).arg(line).arg(ERR_error_string(i, NULL))), + stderr); + } + if (!error.isEmpty()) { + if (!txt.isEmpty()) + error = txt + "\n" + error + "\n" + + QString("(%1:%2)").arg(file).arg(line); + throw errorEx(error); + } +} + +#undef PRINT_IGNORED_ANYWAY +bool _ign_openssl_error(const QString &txt, const char *file, int line) +{ + // ignore openssl errors + QString errtxt; +#if PRINT_IGNORED_ANYWAY + if (!txt.isEmpty() && ERR_peek_error()) + qDebug() << txt; +#else + (void)txt; + (void)file; + (void)line; +#endif + while (int i = ERR_get_error() ) { + errtxt = ERR_error_string(i, NULL); +#if PRINT_IGNORED_ANYWAY + qDebug() << QString("IGNORED (%1:%2) : %3\n") + .arg(file).arg(line).arg(errtxt); +#endif + } + return !errtxt.isEmpty(); +} + +QString formatHash(const QByteArray &data, QString sep, int width) +{ + return QString(data.toHex()).toUpper() + .replace(QRegularExpression(QString("(.{%1})(?=.)").arg(width)), + QString("\\1") + sep); +} + +QByteArray Digest(const QByteArray &data, const EVP_MD *type) +{ + unsigned int n; + unsigned char m[EVP_MAX_MD_SIZE]; + + EVP_Digest(data.constData(), data.size(), m, &n, type, NULL); + openssl_error(); + return QByteArray((char*)m, (int)n); +} + +QMap dn_translations; + +void dn_translations_setup() +{ +QMap D; +D[NID_countryName] = QObject::tr("Country code"); +D[NID_stateOrProvinceName] = QObject::tr("State or Province"); +D[NID_localityName] = QObject::tr("Locality"); +D[NID_organizationName] = QObject::tr("Organisation"); +D[NID_organizationalUnitName] = QObject::tr("Organisational unit"); +D[NID_commonName] = QObject::tr("Common name"); +D[NID_pkcs9_emailAddress] = QObject::tr("E-Mail address"); +D[NID_serialNumber] = QObject::tr("Serial number"); +D[NID_givenName] = QObject::tr("Given name"); +D[NID_surname] = QObject::tr("Surname"); +D[NID_title] = QObject::tr("Title"); +D[NID_initials] = QObject::tr("Initials"); +D[NID_description] = QObject::tr("Description"); +D[NID_role] = QObject::tr("Role"); +D[NID_pseudonym] = QObject::tr("Pseudonym"); +D[NID_generationQualifier] = QObject::tr("Generation Qualifier"); +D[NID_x500UniqueIdentifier] = QObject::tr("x500 Unique Identifier"); +D[NID_name] = QObject::tr("Name"); +D[NID_dnQualifier] = QObject::tr("DN Qualifier"); +D[NID_pkcs9_unstructuredName] = QObject::tr("Unstructured name"); +D[NID_pkcs9_challengePassword] = QObject::tr("Challenge password"); + +D[NID_basic_constraints] = QObject::tr("Basic Constraints"); +D[NID_subject_alt_name] = QObject::tr("Subject alternative name"); +D[NID_issuer_alt_name] = QObject::tr("issuer alternative name"); +D[NID_subject_key_identifier] = QObject::tr("Subject key identifier"); +D[NID_authority_key_identifier] = QObject::tr("Authority key identifier"); +D[NID_key_usage] = QObject::tr("Key usage"); +D[NID_ext_key_usage] = QObject::tr("Extended key usage"); +D[NID_crl_distribution_points] = QObject::tr("CRL distribution points"); +D[NID_info_access] = QObject::tr("Authority information access"); +D[NID_netscape_cert_type] = QObject::tr("Certificate type"); +D[NID_netscape_base_url] = QObject::tr("Base URL"); +D[NID_netscape_revocation_url] = QObject::tr("Revocation URL"); +D[NID_netscape_ca_revocation_url] = QObject::tr("CA Revocation URL"); +D[NID_netscape_renewal_url] = QObject::tr("Certificate renewal URL"); +D[NID_netscape_ca_policy_url] = QObject::tr("CA policy URL"); +D[NID_netscape_ssl_server_name] = QObject::tr("SSL server name"); +D[NID_netscape_comment] = QObject::tr("Comment"); + +dn_translations = D; +} + +QString appendXcaComment(QString current, QString msg) +{ + if (!current.endsWith("\n") && !current.isEmpty()) + current += "\n"; + return current + QString("(%1)\n").arg(msg); +} diff --git a/lib/func_base.h b/lib/func_base.h new file mode 100644 index 00000000..d4fa9ac0 --- /dev/null +++ b/lib/func_base.h @@ -0,0 +1,67 @@ +/* vi: set sw=4 ts=4: + * + * Copyright (C) 2001 - 2012 Christian Hohnstaedt. + * + * All rights reserved. + */ + +#ifndef __FUNC_BASE_H +#define __FUNC_BASE_H + +#include +#include + +#include +#include +#include + +#include "base.h" +#include "Passwd.h" + +#define IS_GUI_APP (is_gui_app) + +class Validity; +class QPixmap; +extern bool is_gui_app; + +typedef struct asn1_object_st ASN1_OBJECT; +typedef struct asn1_string_st ASN1_STRING; +typedef struct evp_md_st EVP_MD; + +QString getFullFilename(const QString &filename, const QString &selectedFilter); +const QStringList getLibExtensions(); + +QString formatHash(const QByteArray &data, QString sep = ":", int width = 2); +QString compressFilename(const QString &filename, int maxlen = 50); + +QString asn1ToQString(const ASN1_STRING *str, bool quote = false); +ASN1_STRING *QStringToAsn1(QString s, int nid); + +QByteArray Digest(const QByteArray &data, const EVP_MD *type); + +const char *OBJ_ln2sn(const char *ln); +const char *OBJ_sn2ln(const char *sn); +const char *OBJ_obj2sn(ASN1_OBJECT *a); +QString OBJ_obj2QString(const ASN1_OBJECT *a, int no_name = 0); + +extern QMap dn_translations; +void dn_translations_setup(); +#define openssl_error_msg(x) _openssl_error(QString(x), C_FILE, __LINE__) +#define openssl_error() openssl_error_msg("") +#define ign_openssl_error() _ign_openssl_error(QString(), C_FILE, __LINE__) +void _openssl_error(const QString &txt, const char *file, int line); +bool _ign_openssl_error(const QString &txt, const char *file, int line); + +QByteArray i2d_bytearray(int(*i2d)(const void*, unsigned char**), const void*); +void *d2i_bytearray(void *(*d2i)(void*, unsigned char**, long), + QByteArray &ba); + +#define I2D_VOID(a) ((int (*)(const void *, unsigned char **))(a)) +#define D2I_VOID(a) ((void *(*)(void *, unsigned char **, long))(a)) + +QString appendXcaComment(QString current, QString msg); + +/* from version.cpp */ +const char *version_str(bool html); + +#endif diff --git a/lib/test_asn1int.cpp b/lib/test_asn1int.cpp new file mode 100644 index 00000000..d16ea11e --- /dev/null +++ b/lib/test_asn1int.cpp @@ -0,0 +1,25 @@ +/* vi: set sw=4 ts=4: + * + * Copyright (C) 2023 Christian Hohnstaedt. + * + * All rights reserved. + */ + +#include + +class test_asn1int: public QObject +{ + Q_OBJECT +private slots: + void toUpper(); +}; + +void test_asn1int::toUpper() +{ + QString str = "Hello"; + QCOMPARE(str.toUpper(), QString("HELLO")); +} + + +QTEST_MAIN(test_asn1int) +#include "test_asn1int.moc" diff --git a/lib/test_biobytearray.cpp b/lib/test_biobytearray.cpp new file mode 100644 index 00000000..2418a69b --- /dev/null +++ b/lib/test_biobytearray.cpp @@ -0,0 +1,66 @@ +/* vi: set sw=4 ts=4: + * + * Copyright (C) 2023 Christian Hohnstaedt. + * + * All rights reserved. + */ + +#include + +#include "BioByteArray.h" +#include + +class test_biobytearray: public QObject +{ + Q_OBJECT + + private slots: + void set(); + void add(); + void bio_ro(); + void bio_wr(); +}; + +void test_biobytearray::set() +{ + BioByteArray ba("Hello"); + QCOMPARE(ba.qstring(), QString("Hello")); + QCOMPARE(ba.byteArray(), QByteArray("Hello")); + + ba = "Wärme"; + QCOMPARE(ba.qstring(), QString("Wärme")); + QCOMPARE(ba.byteArray(), QByteArray("Wärme")); +} + +void test_biobytearray::add() +{ + BioByteArray ba("Wärme"); + + ba += "Bad"; + QCOMPARE(ba.qstring(), QString("WärmeBad")); + QCOMPARE(ba.byteArray(), QByteArray("WärmeBad")); +} + +void test_biobytearray::bio_ro() +{ + char buf[256]; + BioByteArray ba("Wärmetauscher"); + int l = BIO_read(ba.ro(), buf, sizeof buf); + QCOMPARE(l, 14); + QCOMPARE(l, ba.size()); + QCOMPARE(QByteArray(buf, l), ba.byteArray()); +} + +void test_biobytearray::bio_wr() +{ + BioByteArray ba("Suppe"); + ba += "n"; + BIO_puts(ba, "grün"); + BIO_write(ba, "einlage", 7); + + QCOMPARE(ba.byteArray(), QByteArray("Suppengrüneinlage")); + QCOMPARE(ba.size(), sizeof "Suppengrüneinlage" -1); +} + +QTEST_MAIN(test_biobytearray) +#include "test_biobytearray.moc"