summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2014-08-30 16:39:29 +0200
committerJeremy Lainé <jeremy.laine@m4x.org>2014-08-30 17:36:23 +0200
commit5c3a499c9ffbf2d4872dd6a6916b3a3a9a7d9cdd (patch)
tree9ea3da5c7856f1ae48b192e3f4999a8e775bc7b3 /src/network
parent2fd0afc1f87edf28295caeaeb8a830d888a3e81b (diff)
ssl: disable (broken) i/o on DER encoded keys
QSslKey currently has methods which supposedly allow decoding and encoding private keys as DER protected by a passphrase. This is broken by design as explained in QTBUG-41038, as storing the encrypted DER data alone makes no sense: such a file lacks the necessary information about the encryption algorithm and initialization vector. This change: - explicitly stops using the passphrase when decoding DER in the constructor. The behavior is unchanged, it is not possible to read the encrypted DER alone. - refuses to honor the passphrase to DER encode a private key. The toDer method now outputs an empty QByteArray instead of garbage. Task-number: QTBUG-41038 Change-Id: I4281050cf1104f12d154db201a173633bfe22bd9 Reviewed-by: Richard J. Moore <rich@kde.org>
Diffstat (limited to 'src/network')
-rw-r--r--src/network/ssl/qsslcertificate_qt.cpp2
-rw-r--r--src/network/ssl/qsslkey_openssl.cpp5
-rw-r--r--src/network/ssl/qsslkey_p.cpp35
-rw-r--r--src/network/ssl/qsslkey_p.h3
-rw-r--r--src/network/ssl/qsslkey_qt.cpp15
5 files changed, 31 insertions, 29 deletions
diff --git a/src/network/ssl/qsslcertificate_qt.cpp b/src/network/ssl/qsslcertificate_qt.cpp
index 26c9c5e64e..391ee6f7f9 100644
--- a/src/network/ssl/qsslcertificate_qt.cpp
+++ b/src/network/ssl/qsslcertificate_qt.cpp
@@ -143,7 +143,7 @@ QSslKey QSslCertificate::publicKey() const
key.d->type = QSsl::PublicKey;
if (d->publicKeyAlgorithm != QSsl::Opaque) {
key.d->algorithm = d->publicKeyAlgorithm;
- key.d->decodeDer(d->publicKeyDerData, QByteArray());
+ key.d->decodeDer(d->publicKeyDerData);
}
return key;
}
diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp
index 14559d6618..7e78ac0fee 100644
--- a/src/network/ssl/qsslkey_openssl.cpp
+++ b/src/network/ssl/qsslkey_openssl.cpp
@@ -109,10 +109,9 @@ bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey)
return false;
}
-void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhrase,
- bool deepClear)
+void QSslKeyPrivate::decodeDer(const QByteArray &der, bool deepClear)
{
- decodePem(pemFromDer(der), passPhrase, deepClear);
+ decodePem(pemFromDer(der), QByteArray(), deepClear);
}
void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhrase,
diff --git a/src/network/ssl/qsslkey_p.cpp b/src/network/ssl/qsslkey_p.cpp
index 40e9231177..2b0dab9933 100644
--- a/src/network/ssl/qsslkey_p.cpp
+++ b/src/network/ssl/qsslkey_p.cpp
@@ -175,8 +175,10 @@ QByteArray QSslKeyPrivate::derFromPem(const QByteArray &pem) const
/*!
Constructs a QSslKey by decoding the string in the byte array
\a encoded using a specified \a algorithm and \a encoding format.
- If the encoded key is encrypted, \a passPhrase is used to decrypt
- it. \a type specifies whether the key is public or private.
+ \a type specifies whether the key is public or private.
+
+ If the key is encoded as PEM and encrypted, \a passPhrase is used
+ to decrypt it.
After construction, use isNull() to check if \a encoded contained
a valid key.
@@ -188,7 +190,7 @@ QSslKey::QSslKey(const QByteArray &encoded, QSsl::KeyAlgorithm algorithm,
d->type = type;
d->algorithm = algorithm;
if (encoding == QSsl::Der)
- d->decodeDer(encoded, passPhrase);
+ d->decodeDer(encoded);
else
d->decodePem(encoded, passPhrase);
}
@@ -196,8 +198,10 @@ QSslKey::QSslKey(const QByteArray &encoded, QSsl::KeyAlgorithm algorithm,
/*!
Constructs a QSslKey by reading and decoding data from a
\a device using a specified \a algorithm and \a encoding format.
- If the encoded key is encrypted, \a passPhrase is used to decrypt
- it. \a type specifies whether the key is public or private.
+ \a type specifies whether the key is public or private.
+
+ If the key is encoded as PEM and encrypted, \a passPhrase is used
+ to decrypt it.
After construction, use isNull() to check if \a device provided
a valid key.
@@ -211,9 +215,10 @@ QSslKey::QSslKey(QIODevice *device, QSsl::KeyAlgorithm algorithm, QSsl::Encoding
encoded = device->readAll();
d->type = type;
d->algorithm = algorithm;
- d->decodePem((encoding == QSsl::Der) ?
- d->pemFromDer(encoded) : encoded,
- passPhrase);
+ if (encoding == QSsl::Der)
+ d->decodeDer(encoded);
+ else
+ d->decodePem(encoded, passPhrase);
}
/*!
@@ -317,23 +322,23 @@ QSsl::KeyAlgorithm QSslKey::algorithm() const
}
/*!
- Returns the key in DER encoding. The result is encrypted with
- \a passPhrase if the key is a private key and \a passPhrase is
- non-empty.
+ Returns the key in DER encoding.
+
+ The \a passPhrase argument should be omitted as DER cannot be
+ encrypted. It will be removed in a future version of Qt.
*/
-// ### autotest failure for non-empty passPhrase and private key
QByteArray QSslKey::toDer(const QByteArray &passPhrase) const
{
if (d->isNull || d->algorithm == QSsl::Opaque)
return QByteArray();
-#ifndef QT_NO_OPENSSL
- return d->derFromPem(toPem(passPhrase));
-#else
// Encrypted DER is nonsense, see QTBUG-41038.
if (d->type == QSsl::PrivateKey && !passPhrase.isEmpty())
return QByteArray();
+#ifndef QT_NO_OPENSSL
+ return d->derFromPem(toPem(passPhrase));
+#else
return d->derData;
#endif
}
diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h
index 64a157ba09..9c1476038a 100644
--- a/src/network/ssl/qsslkey_p.h
+++ b/src/network/ssl/qsslkey_p.h
@@ -86,8 +86,7 @@ public:
#ifndef QT_NO_OPENSSL
bool fromEVP_PKEY(EVP_PKEY *pkey);
#endif
- void decodeDer(const QByteArray &der, const QByteArray &passPhrase,
- bool deepClear = true);
+ void decodeDer(const QByteArray &der, bool deepClear = true);
void decodePem(const QByteArray &pem, const QByteArray &passPhrase,
bool deepClear = true);
QByteArray pemHeader() const;
diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp
index 1e60476601..feeb7d6f87 100644
--- a/src/network/ssl/qsslkey_qt.cpp
+++ b/src/network/ssl/qsslkey_qt.cpp
@@ -86,19 +86,13 @@ void QSslKeyPrivate::clear(bool deep)
keyLength = -1;
}
-void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhrase,
- bool deepClear)
+void QSslKeyPrivate::decodeDer(const QByteArray &der, bool deepClear)
{
clear(deepClear);
if (der.isEmpty())
return;
- if (type == QSsl::PrivateKey && !passPhrase.isEmpty()) {
- Q_UNIMPLEMENTED();
- return;
- }
-
QAsn1Element elem;
if (!elem.read(der) || elem.type() != QAsn1Element::SequenceType)
return;
@@ -161,7 +155,12 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhra
void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhrase,
bool deepClear)
{
- decodeDer(derFromPem(pem), passPhrase, deepClear);
+ if (type == QSsl::PrivateKey && !passPhrase.isEmpty()) {
+ Q_UNIMPLEMENTED();
+ return;
+ }
+
+ decodeDer(derFromPem(pem), deepClear);
}
int QSslKeyPrivate::length() const