summaryrefslogtreecommitdiffstats
path: root/src/network/ssl/qsslkey.cpp
diff options
context:
space:
mode:
authorCorentin Chary <corentin.chary@gmail.com>2011-08-31 19:35:35 +0200
committerQt by Nokia <qt-info@nokia.com>2011-08-31 21:06:53 +0200
commita4878db8df3fbaf9d222ec1206813b16dcdd90c7 (patch)
tree83271767995af278a8fe57ad0ac2e9a316deb9a4 /src/network/ssl/qsslkey.cpp
parenta3e8f1ab0cc38c0d2e631d3e7f9e6379982204b7 (diff)
qssl: add support for QSsl::Opaque key
This allow to use directly EVP_PKEY * with QSslKey (for example comming from a PKCS#11 dongle). Change-Id: Icb1ba5081506a831ec3d8cfffe13ce70939608ea Merge-request: 48 Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com> Reviewed-on: http://codereview.qt.nokia.com/4010 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Diffstat (limited to 'src/network/ssl/qsslkey.cpp')
-rw-r--r--src/network/ssl/qsslkey.cpp46
1 files changed, 41 insertions, 5 deletions
diff --git a/src/network/ssl/qsslkey.cpp b/src/network/ssl/qsslkey.cpp
index 29cfd0a77d..580b71bca9 100644
--- a/src/network/ssl/qsslkey.cpp
+++ b/src/network/ssl/qsslkey.cpp
@@ -89,6 +89,11 @@ void QSslKeyPrivate::clear(bool deep)
q_DSA_free(dsa);
dsa = 0;
}
+ if (opaque) {
+ if (deep)
+ q_EVP_PKEY_free(opaque);
+ opaque = 0;
+ }
}
/*!
@@ -265,6 +270,23 @@ QSslKey::QSslKey(QIODevice *device, QSsl::KeyAlgorithm algorithm, QSsl::Encoding
}
/*!
+ Constructs a QSslKey from a valid native key \a handle.
+ \a type specifies whether the key is public or private.
+
+ QSslKey will take ownership for this key and you must not
+ free the key using the native library. The algorithm used
+ when creating a key from a handle will always be QSsl::Opaque.
+*/
+QSslKey::QSslKey(Qt::HANDLE handle, QSsl::KeyType type)
+ : d(new QSslKeyPrivate)
+{
+ d->opaque = reinterpret_cast<EVP_PKEY *>(handle);
+ d->algorithm = QSsl::Opaque;
+ d->type = type;
+ d->isNull = !d->opaque;
+}
+
+/*!
Constructs an identical copy of \a other.
*/
QSslKey::QSslKey(const QSslKey &other) : d(other.d)
@@ -315,8 +337,9 @@ void QSslKey::clear()
*/
int QSslKey::length() const
{
- if (d->isNull)
+ if (d->isNull || d->algorithm == QSsl::Opaque)
return -1;
+
return (d->algorithm == QSsl::Rsa)
? q_BN_num_bits(d->rsa->n) : q_BN_num_bits(d->dsa->p);
}
@@ -345,8 +368,9 @@ QSsl::KeyAlgorithm QSslKey::algorithm() const
// ### autotest failure for non-empty passPhrase and private key
QByteArray QSslKey::toDer(const QByteArray &passPhrase) const
{
- if (d->isNull)
+ if (d->isNull || d->algorithm == QSsl::Opaque)
return QByteArray();
+
return d->derFromPem(toPem(passPhrase));
}
@@ -357,7 +381,7 @@ QByteArray QSslKey::toDer(const QByteArray &passPhrase) const
*/
QByteArray QSslKey::toPem(const QByteArray &passPhrase) const
{
- if (!QSslSocket::supportsSsl() || d->isNull)
+ if (!QSslSocket::supportsSsl() || d->isNull || d->algorithm == QSsl::Opaque)
return QByteArray();
BIO *bio = q_BIO_new(q_BIO_s_mem());
@@ -417,7 +441,16 @@ QByteArray QSslKey::toPem(const QByteArray &passPhrase) const
*/
Qt::HANDLE QSslKey::handle() const
{
- return (d->algorithm == QSsl::Rsa) ? Qt::HANDLE(d->rsa) : Qt::HANDLE(d->dsa);
+ switch (d->algorithm) {
+ case QSsl::Opaque:
+ return Qt::HANDLE(d->opaque);
+ case QSsl::Rsa:
+ return Qt::HANDLE(d->rsa);
+ case QSsl::Dsa:
+ return Qt::HANDLE(d->dsa);
+ default:
+ return Qt::HANDLE(NULL);
+ }
}
/*!
@@ -435,6 +468,8 @@ bool QSslKey::operator==(const QSslKey &other) const
return false;
if (length() != other.length())
return false;
+ if (algorithm() == QSsl::Opaque)
+ return handle() == other.handle();
return toDer() == other.toDer();
}
@@ -450,7 +485,8 @@ QDebug operator<<(QDebug debug, const QSslKey &key)
{
debug << "QSslKey("
<< (key.type() == QSsl::PublicKey ? "PublicKey" : "PrivateKey")
- << ", " << (key.algorithm() == QSsl::Rsa ? "RSA" : "DSA")
+ << ", " << (key.algorithm() == QSsl::Opaque ? "OPAQUE" :
+ (key.algorithm() == QSsl::Rsa ? "RSA" : "DSA"))
<< ", " << key.length()
<< ')';
return debug;