summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Schmertmann <Lars.Schmertmann@governikus.de>2016-07-13 08:42:33 +0200
committerAndré Klitzing <aklitzing@gmail.com>2018-11-23 22:58:05 +0000
commitde83447830b0941216f922a37b6cd36e703197d4 (patch)
treeb2c58b8fb086cc7a6b45252b56f2014732a9f9ba /src
parent14144079709201929c97b9a5f0db406c27275baf (diff)
Add support for Diffie-Hellman keys to QSslKey
This is necessary to provide details for the key too, when the server is using DHE-RSA-AESxxx-SHAxxx. Amends 7f77dc84fb434f33ffe96f6633792706b80fb0a3. Change-Id: I8ab15b6987c17c857f54bc368df3c6c1818f428c Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/network/ssl/qasn1element_p.h1
-rw-r--r--src/network/ssl/qssl.cpp3
-rw-r--r--src/network/ssl/qssl.h3
-rw-r--r--src/network/ssl/qsslkey_openssl.cpp46
-rw-r--r--src/network/ssl/qsslkey_p.cpp8
-rw-r--r--src/network/ssl/qsslkey_p.h1
-rw-r--r--src/network/ssl/qsslkey_qt.cpp32
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp8
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h5
-rw-r--r--src/network/ssl/qsslsocket_opensslpre11_symbols_p.h1
10 files changed, 100 insertions, 8 deletions
diff --git a/src/network/ssl/qasn1element_p.h b/src/network/ssl/qasn1element_p.h
index 2068254a95..59d1f58482 100644
--- a/src/network/ssl/qasn1element_p.h
+++ b/src/network/ssl/qasn1element_p.h
@@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE
#define RSA_ENCRYPTION_OID QByteArrayLiteral(RSADSI_OID "1.1.1")
#define DSA_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10040.4.1")
#define EC_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10045.2.1")
+#define DH_ENCRYPTION_OID QByteArrayLiteral(RSADSI_OID "1.3.1")
// These are mostly from the RFC for PKCS#5
// PKCS#5: https://tools.ietf.org/html/rfc8018#appendix-B
diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp
index 19d99bc489..ea2b73bad5 100644
--- a/src/network/ssl/qssl.cpp
+++ b/src/network/ssl/qssl.cpp
@@ -71,7 +71,8 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl");
\value Rsa The RSA algorithm.
\value Dsa The DSA algorithm.
- \value Ec The Elliptic Curve algorithm
+ \value Ec The Elliptic Curve algorithm.
+ \value Dh The Diffie-Hellman algorithm.
\value Opaque A key that should be treated as a 'black box' by QSslKey.
The opaque key facility allows applications to add support for facilities
diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h
index 60362cb410..5c25e4e105 100644
--- a/src/network/ssl/qssl.h
+++ b/src/network/ssl/qssl.h
@@ -62,7 +62,8 @@ namespace QSsl {
Opaque,
Rsa,
Dsa,
- Ec
+ Ec,
+ Dh,
};
enum AlternativeNameEntryType {
diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp
index 9a43e67772..99c1a39c73 100644
--- a/src/network/ssl/qsslkey_openssl.cpp
+++ b/src/network/ssl/qsslkey_openssl.cpp
@@ -69,6 +69,11 @@ void QSslKeyPrivate::clear(bool deep)
q_DSA_free(dsa);
dsa = nullptr;
}
+ if (algorithm == QSsl::Dh && dh) {
+ if (deep)
+ q_DH_free(dh);
+ dh = nullptr;
+ }
#ifndef OPENSSL_NO_EC
if (algorithm == QSsl::Ec && ec) {
if (deep)
@@ -105,6 +110,12 @@ bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey)
type = QSsl::PrivateKey;
dsa = q_EVP_PKEY_get1_DSA(pkey);
return true;
+ } else if (keyType == EVP_PKEY_DH) {
+ isNull = false;
+ algorithm = QSsl::Dh;
+ type = QSsl::PrivateKey;
+ dh = q_EVP_PKEY_get1_DH(pkey);
+ return true;
}
#ifndef OPENSSL_NO_EC
else if (keyType == EVP_PKEY_EC) {
@@ -160,6 +171,15 @@ void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhra
: q_PEM_read_bio_DSAPrivateKey(bio, &dsa, nullptr, phrase);
if (dsa && dsa == result)
isNull = false;
+ } else if (algorithm == QSsl::Dh) {
+ EVP_PKEY *result = (type == QSsl::PublicKey)
+ ? q_PEM_read_bio_PUBKEY(bio, nullptr, nullptr, phrase)
+ : q_PEM_read_bio_PrivateKey(bio, nullptr, nullptr, phrase);
+ if (result)
+ dh = q_EVP_PKEY_get1_DH(result);
+ if (dh)
+ isNull = false;
+ q_EVP_PKEY_free(result);
#ifndef OPENSSL_NO_EC
} else if (algorithm == QSsl::Ec) {
EC_KEY *result = (type == QSsl::PublicKey)
@@ -181,6 +201,7 @@ int QSslKeyPrivate::length() const
switch (algorithm) {
case QSsl::Rsa: return q_RSA_bits(rsa);
case QSsl::Dsa: return q_DSA_bits(dsa);
+ case QSsl::Dh: return q_DH_bits(dh);
#ifndef OPENSSL_NO_EC
case QSsl::Ec: return q_EC_GROUP_get_degree(q_EC_KEY_get0_group(ec));
#endif
@@ -215,7 +236,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const
fail = true;
} else {
if (!q_PEM_write_bio_RSAPrivateKey(
- bio, rsa, cipher, const_cast<uchar *>((const uchar *)passPhrase.data()),
+ bio, rsa, cipher, (uchar *)passPhrase.data(),
passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
@@ -226,20 +247,33 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const
fail = true;
} else {
if (!q_PEM_write_bio_DSAPrivateKey(
- bio, dsa, cipher, const_cast<uchar *>((const uchar *)passPhrase.data()),
+ bio, dsa, cipher, (uchar *)passPhrase.data(),
passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
}
+ } else if (algorithm == QSsl::Dh) {
+ EVP_PKEY *result = q_EVP_PKEY_new();
+ if (!result || !q_EVP_PKEY_set1_DH(result, dh)) {
+ fail = true;
+ } else if (type == QSsl::PublicKey) {
+ if (!q_PEM_write_bio_PUBKEY(bio, result))
+ fail = true;
+ } else if (!q_PEM_write_bio_PrivateKey(
+ bio, result, cipher, (uchar *)passPhrase.data(),
+ passPhrase.size(), nullptr, nullptr)) {
+ fail = true;
+ }
+ q_EVP_PKEY_free(result);
#ifndef OPENSSL_NO_EC
} else if (algorithm == QSsl::Ec) {
if (type == QSsl::PublicKey) {
if (!q_PEM_write_bio_EC_PUBKEY(bio, ec))
fail = true;
} else {
- if (!q_PEM_write_bio_ECPrivateKey(bio, ec, cipher,
- const_cast<uchar *>((const uchar *)passPhrase.data()),
- passPhrase.size(), nullptr, nullptr)) {
+ if (!q_PEM_write_bio_ECPrivateKey(
+ bio, ec, cipher, (uchar *)passPhrase.data(),
+ passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
}
@@ -267,6 +301,8 @@ Qt::HANDLE QSslKeyPrivate::handle() const
return Qt::HANDLE(rsa);
case QSsl::Dsa:
return Qt::HANDLE(dsa);
+ case QSsl::Dh:
+ return Qt::HANDLE(dh);
#ifndef OPENSSL_NO_EC
case QSsl::Ec:
return Qt::HANDLE(ec);
diff --git a/src/network/ssl/qsslkey_p.cpp b/src/network/ssl/qsslkey_p.cpp
index 28e3e2efd8..b29b38beab 100644
--- a/src/network/ssl/qsslkey_p.cpp
+++ b/src/network/ssl/qsslkey_p.cpp
@@ -116,6 +116,8 @@ QByteArray QSslKeyPrivate::pemHeader() const
return QByteArrayLiteral("-----BEGIN DSA PRIVATE KEY-----");
else if (algorithm == QSsl::Ec)
return QByteArrayLiteral("-----BEGIN EC PRIVATE KEY-----");
+ else if (algorithm == QSsl::Dh)
+ return QByteArrayLiteral("-----BEGIN PRIVATE KEY-----");
Q_UNREACHABLE();
return QByteArray();
@@ -141,6 +143,8 @@ QByteArray QSslKeyPrivate::pemFooter() const
return QByteArrayLiteral("-----END DSA PRIVATE KEY-----");
else if (algorithm == QSsl::Ec)
return QByteArrayLiteral("-----END EC PRIVATE KEY-----");
+ else if (algorithm == QSsl::Dh)
+ return QByteArrayLiteral("-----END PRIVATE KEY-----");
Q_UNREACHABLE();
return QByteArray();
@@ -535,7 +539,9 @@ QDebug operator<<(QDebug debug, const QSslKey &key)
debug << "QSslKey("
<< (key.type() == QSsl::PublicKey ? "PublicKey" : "PrivateKey")
<< ", " << (key.algorithm() == QSsl::Opaque ? "OPAQUE" :
- (key.algorithm() == QSsl::Rsa ? "RSA" : ((key.algorithm() == QSsl::Dsa) ? "DSA" : "EC")))
+ (key.algorithm() == QSsl::Rsa ? "RSA" :
+ (key.algorithm() == QSsl::Dsa ? "DSA" :
+ (key.algorithm() == QSsl::Dh ? "DH" : "EC"))))
<< ", " << key.length()
<< ')';
return debug;
diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h
index 7ae2cc740b..310553cab2 100644
--- a/src/network/ssl/qsslkey_p.h
+++ b/src/network/ssl/qsslkey_p.h
@@ -116,6 +116,7 @@ public:
EVP_PKEY *opaque;
RSA *rsa;
DSA *dsa;
+ DH *dh;
#ifndef OPENSSL_NO_EC
EC_KEY *ec;
#endif
diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp
index a13275f3bb..5ebd8ac3bd 100644
--- a/src/network/ssl/qsslkey_qt.cpp
+++ b/src/network/ssl/qsslkey_qt.cpp
@@ -165,6 +165,7 @@ static int extractPkcs8KeyLength(const QVector<QAsn1Element> &items, QSslKeyPriv
switch (algorithm){
case QSsl::Rsa: return "RSA";
case QSsl::Dsa: return "DSA";
+ case QSsl::Dh: return "DH";
case QSsl::Ec: return "EC";
case QSsl::Opaque: return "Opaque";
}
@@ -217,6 +218,21 @@ static int extractPkcs8KeyLength(const QVector<QAsn1Element> &items, QSslKeyPriv
if (dsaInfo.size() != 3 || dsaInfo[0].type() != QAsn1Element::IntegerType)
return -1;
keyLength = numberOfBits(dsaInfo[0].value());
+ } else if (value == DH_ENCRYPTION_OID) {
+ if (Q_UNLIKELY(that->algorithm != QSsl::Dh)) {
+ // As above for RSA.
+ qWarning() << "QSslKey: Found DH when asked to use" << getName(that->algorithm)
+ << "\nLoading will fail.";
+ return -1;
+ }
+ // DH's structure is documented here:
+ // https://www.cryptsoft.com/pkcs11doc/STANDARD/v201-95.pdf in section 11.9.
+ if (pkcs8Info[1].type() != QAsn1Element::SequenceType)
+ return -1;
+ const QVector<QAsn1Element> dhInfo = pkcs8Info[1].toVector();
+ if (dhInfo.size() < 2 || dhInfo.size() > 3 || dhInfo[0].type() != QAsn1Element::IntegerType)
+ return -1;
+ keyLength = numberOfBits(dhInfo[0].value());
} else {
// in case of unexpected formats:
qWarning() << "QSslKey: Unsupported PKCS#8 key algorithm:" << value
@@ -268,6 +284,16 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhra
if (params.isEmpty() || params[0].type() != QAsn1Element::IntegerType)
return;
keyLength = numberOfBits(params[0].value());
+ } else if (algorithm == QSsl::Dh) {
+ if (infoItems[0].toObjectId() != DH_ENCRYPTION_OID)
+ return;
+ if (infoItems[1].type() != QAsn1Element::SequenceType)
+ return;
+ // key params
+ const QVector<QAsn1Element> params = infoItems[1].toVector();
+ if (params.isEmpty() || params[0].type() != QAsn1Element::IntegerType)
+ return;
+ keyLength = numberOfBits(params[0].value());
} else if (algorithm == QSsl::Ec) {
if (infoItems[0].toObjectId() != EC_ENCRYPTION_OID)
return;
@@ -307,6 +333,12 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhra
if (items.size() != 6 || items[1].type() != QAsn1Element::IntegerType)
return;
keyLength = numberOfBits(items[1].value());
+ } else if (algorithm == QSsl::Dh) {
+ if (versionHex != "00")
+ return;
+ if (items.size() < 5 || items.size() > 6 || items[1].type() != QAsn1Element::IntegerType)
+ return;
+ keyLength = numberOfBits(items[1].value());
} else if (algorithm == QSsl::Ec) {
if (versionHex != "01")
return;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 781b3d6640..5ba2c40636 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -366,12 +366,14 @@ DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return)
+DEFINEFUNC2(int, EVP_PKEY_set1_DH, EVP_PKEY *a, a, DH *b, b, return -1, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC2(int, EVP_PKEY_set1_EC_KEY, EVP_PKEY *a, a, EC_KEY *b, b, return -1, return)
#endif
DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG)
DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return nullptr, return)
DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return nullptr, return)
+DEFINEFUNC(DH *, EVP_PKEY_get1_DH, EVP_PKEY *a, a, return nullptr, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC(EC_KEY *, EVP_PKEY_get1_EC_KEY, EVP_PKEY *a, a, return nullptr, return)
#endif
@@ -397,6 +399,7 @@ DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_p
DEFINEFUNC4(DH *, PEM_read_bio_DHparams, BIO *a, a, DH **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC7(int, PEM_write_bio_DSAPrivateKey, BIO *a, a, DSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
+DEFINEFUNC7(int, PEM_write_bio_PrivateKey, BIO *a, a, EVP_PKEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
#endif
@@ -409,6 +412,7 @@ DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_pass
#endif
DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return)
DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return)
+DEFINEFUNC2(int, PEM_write_bio_PUBKEY, BIO *a, a, EVP_PKEY *b, b, return 0, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC2(int, PEM_write_bio_EC_PUBKEY, BIO *a, a, EC_KEY *b, b, return 0, return)
#endif
@@ -1168,12 +1172,14 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EVP_PKEY_assign)
RESOLVEFUNC(EVP_PKEY_set1_RSA)
RESOLVEFUNC(EVP_PKEY_set1_DSA)
+ RESOLVEFUNC(EVP_PKEY_set1_DH)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EVP_PKEY_set1_EC_KEY)
#endif
RESOLVEFUNC(EVP_PKEY_free)
RESOLVEFUNC(EVP_PKEY_get1_DSA)
RESOLVEFUNC(EVP_PKEY_get1_RSA)
+ RESOLVEFUNC(EVP_PKEY_get1_DH)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EVP_PKEY_get1_EC_KEY)
#endif
@@ -1197,6 +1203,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(PEM_read_bio_DHparams)
RESOLVEFUNC(PEM_write_bio_DSAPrivateKey)
RESOLVEFUNC(PEM_write_bio_RSAPrivateKey)
+ RESOLVEFUNC(PEM_write_bio_PrivateKey)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(PEM_write_bio_ECPrivateKey)
#endif
@@ -1210,6 +1217,7 @@ bool q_resolveOpenSslSymbols()
#endif
RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY)
RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY)
+ RESOLVEFUNC(PEM_write_bio_PUBKEY)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(PEM_write_bio_EC_PUBKEY)
#endif
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index bfdfbf0efc..7e759d3825 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -278,12 +278,14 @@ const EVP_MD *q_EVP_sha1();
int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c);
Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b);
int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
+int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b);
#ifndef OPENSSL_NO_EC
int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b);
#endif
void q_EVP_PKEY_free(EVP_PKEY *a);
RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a);
DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a);
+DH *q_EVP_PKEY_get1_DH(EVP_PKEY *a);
#ifndef OPENSSL_NO_EC
EC_KEY *q_EVP_PKEY_get1_EC_KEY(EVP_PKEY *a);
#endif
@@ -314,6 +316,8 @@ int q_PEM_write_bio_DSAPrivateKey(BIO *a, DSA *b, const EVP_CIPHER *c, unsigned
int e, pem_password_cb *f, void *g);
int q_PEM_write_bio_RSAPrivateKey(BIO *a, RSA *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
+int q_PEM_write_bio_PrivateKey(BIO *a, EVP_PKEY *b, const EVP_CIPHER *c, unsigned char *d,
+ int e, pem_password_cb *f, void *g);
#ifndef OPENSSL_NO_EC
int q_PEM_write_bio_ECPrivateKey(BIO *a, EC_KEY *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
@@ -327,6 +331,7 @@ EC_KEY *q_PEM_read_bio_EC_PUBKEY(BIO *a, EC_KEY **b, pem_password_cb *c, void *d
#endif
int q_PEM_write_bio_DSA_PUBKEY(BIO *a, DSA *b);
int q_PEM_write_bio_RSA_PUBKEY(BIO *a, RSA *b);
+int q_PEM_write_bio_PUBKEY(BIO *a, EVP_PKEY *b);
#ifndef OPENSSL_NO_EC
int q_PEM_write_bio_EC_PUBKEY(BIO *a, EC_KEY *b);
#endif
diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
index b7bac5d2a2..daf46f485c 100644
--- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
@@ -218,6 +218,7 @@ DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
#define q_SSL_SESSION_get_ticket_lifetime_hint(s) ((s)->tlsext_tick_lifetime_hint)
#define q_RSA_bits(rsa) q_BN_num_bits((rsa)->n)
#define q_DSA_bits(dsa) q_BN_num_bits((dsa)->p)
+#define q_DH_bits(dsa) q_BN_num_bits((dh)->p)
#define q_X509_STORE_set_verify_cb(s,c) X509_STORE_set_verify_cb_func((s),(c))
char *q_CONF_get1_default_config_file();