| 1 | /**************************************************************************** |
| 2 | ** |
| 3 | ** Copyright (C) 2015 Mikkel Krautz <mikkel@krautz.dk> |
| 4 | ** Contact: https://www.qt.io/licensing/ |
| 5 | ** |
| 6 | ** This file is part of the test suite of the Qt Toolkit. |
| 7 | ** |
| 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| 9 | ** Commercial License Usage |
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in |
| 11 | ** accordance with the commercial license agreement provided with the |
| 12 | ** Software or, alternatively, in accordance with the terms contained in |
| 13 | ** a written agreement between you and The Qt Company. For licensing terms |
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
| 15 | ** information use the contact form at https://www.qt.io/contact-us. |
| 16 | ** |
| 17 | ** GNU General Public License Usage |
| 18 | ** Alternatively, this file may be used under the terms of the GNU |
| 19 | ** General Public License version 3 as published by the Free Software |
| 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| 21 | ** included in the packaging of this file. Please review the following |
| 22 | ** information to ensure the GNU General Public License requirements will |
| 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| 24 | ** |
| 25 | ** $QT_END_LICENSE$ |
| 26 | ** |
| 27 | ****************************************************************************/ |
| 28 | |
| 29 | #include <QtTest/QtTest> |
| 30 | #include <QSslDiffieHellmanParameters> |
| 31 | #include <QSslSocket> |
| 32 | #include <QByteArray> |
| 33 | |
| 34 | // Default DH parameters, exported by qssldiffiehellmanparameters.cpp. |
| 35 | QT_BEGIN_NAMESPACE |
| 36 | extern Q_AUTOTEST_EXPORT const char *qssl_dhparams_default_base64; |
| 37 | QT_END_NAMESPACE |
| 38 | |
| 39 | QT_USE_NAMESPACE |
| 40 | |
| 41 | class tst_QSslDiffieHellmanParameters : public QObject |
| 42 | { |
| 43 | Q_OBJECT |
| 44 | |
| 45 | #ifndef QT_NO_SSL |
| 46 | private Q_SLOTS: |
| 47 | void constructionEmpty(); |
| 48 | void constructionDefault(); |
| 49 | void constructionDER(); |
| 50 | void constructionPEM(); |
| 51 | void unsafe512Bits(); |
| 52 | void unsafeNonPrime(); |
| 53 | void defaultIsValid(); |
| 54 | #endif |
| 55 | }; |
| 56 | |
| 57 | #ifndef QT_NO_SSL |
| 58 | |
| 59 | void tst_QSslDiffieHellmanParameters::constructionEmpty() |
| 60 | { |
| 61 | QSslDiffieHellmanParameters dh; |
| 62 | |
| 63 | QCOMPARE(dh.isEmpty(), true); |
| 64 | QCOMPARE(dh.isValid(), true); |
| 65 | QCOMPARE(dh.error(), QSslDiffieHellmanParameters::NoError); |
| 66 | } |
| 67 | |
| 68 | void tst_QSslDiffieHellmanParameters::constructionDefault() |
| 69 | { |
| 70 | QSslDiffieHellmanParameters dh = QSslDiffieHellmanParameters::defaultParameters(); |
| 71 | |
| 72 | #ifndef QT_NO_OPENSSL |
| 73 | QCOMPARE(dh.isValid(), true); |
| 74 | QCOMPARE(dh.error(), QSslDiffieHellmanParameters::NoError); |
| 75 | #endif |
| 76 | } |
| 77 | |
| 78 | void tst_QSslDiffieHellmanParameters::constructionDER() |
| 79 | { |
| 80 | // Uniquely generated with 'openssl dhparam -outform DER -out out.der -check -2 4096' |
| 81 | const auto dh = QSslDiffieHellmanParameters::fromEncoded(encoded: QByteArray::fromBase64(QByteArrayLiteral( |
| 82 | "MIICCAKCAgEAsbQYx57ZlyEyWF8jD5WYEswGR2aTVFsHqP3026SdyTwcjY+YlMOae0EagK" |
| 83 | "jDA0UlPcih1kguQOvOVgyc5gI3YbBb4pCNEdy048xITlsdqG7qC3+2VvFR3vfixEbQQll9" |
| 84 | "2cGIIneD/36p7KJcDnBNUwwWj/VJKhTwelTfKTj2T39si9xGMkqZiQuCaXRk6vSKZ4ZDPk" |
| 85 | "jiq5Ti1kHVFbL9SMWRa8zplPtDMrVfhSyw10njgD4qKd1UoUPdmhEPhRZlHaZ/cAHNSHMj" |
| 86 | "uhDakeMpN+XP2/sl5IpPZ3/vVOk9PhBDFO1NYzKx/b7RQgZCUmXoglKYpfBiz8OheoI0hK" |
| 87 | "V0fU/OCtHjRrP4hE9vIHA2aE+gaQZiYCciGcR9BjHQ7Y8K9qHyTX8UIz2G4ZKzQZK9G+pA" |
| 88 | "K0xD+1H3qZ/MaUhzNDQOwwihnTjjXzTjfIGqYDdbouAhw+tX51CsGonI0cL3s3QMa3CwGH" |
| 89 | "mw+AH2b/Z68dTSy0sC3CYn9cNbrctqyeHwQrsx9FfpOz+Z6sk2WsPgqgSp/pDVVgm5oSfO" |
| 90 | "2mN7WAWgUlf9TQuj1HIRCTI+PbBq2vYvn+YResMRo+8ng1QptKAAgQoVVGNRYxZ9iAZlvO" |
| 91 | "52DcHKlsqDuafQ1XVGmzVIrKtBi2gfLtPqY4v6g6v26l8gbzK67PpWstllHiPb4VMCAQI=" |
| 92 | )), format: QSsl::Der); |
| 93 | |
| 94 | #ifndef QT_NO_OPENSSL |
| 95 | QCOMPARE(dh.isValid(), true); |
| 96 | QCOMPARE(dh.error(), QSslDiffieHellmanParameters::NoError); |
| 97 | #endif |
| 98 | } |
| 99 | |
| 100 | void tst_QSslDiffieHellmanParameters::constructionPEM() |
| 101 | { |
| 102 | // Uniquely generated with 'openssl dhparam -outform PEM -out out.pem -check -2 4096' |
| 103 | const auto dh = QSslDiffieHellmanParameters::fromEncoded(QByteArrayLiteral( |
| 104 | "-----BEGIN DH PARAMETERS-----\n" |
| 105 | "MIICCAKCAgEA9QTdqhQkbGuhWzBsW5X475AjjrITpg1BHX5+mp1sstUd84Lshq1T\n" |
| 106 | "+S2QQQtdl25EPoUblpyyLAf8krFSH4YwR7jjLWklA8paDOwRYod0zLmVZ1Wx6og3\n" |
| 107 | "PRc8P+SCs+6gKTXfv//bJJhiJXnM73lDFsGHbSqN+msf20ei/zy5Rwey2t8dPjLC\n" |
| 108 | "Q+qkb/avlovi2t2rsUWcxMT1875TQ4HuApayqw3R3lTQe9u05b9rTrinmT7AE4mm\n" |
| 109 | "xGqO9FZJdXYE2sOKwwJkpM48KFyV90uJANmqJnQrkgdukaGTHwxZxgAyO6ur/RWC\n" |
| 110 | "kzf9STFT6IY4Qy05q+oZVJfh8xPHszKmmC8nWaLfiHMYBnL5fv+1kh/aU11Kz9TG\n" |
| 111 | "iDXwQ+tzhKAutQPUwe3IGQUYQMZPwZI4vegdU88/7YPXuWt7b/0Il5+2ma5FbtG2\n" |
| 112 | "u02PMi+J3JZsYi/tEUv1tJBVHGH0kDpgcyOm8rvkCtNbNkETzfwUPoEgA0oPMhVt\n" |
| 113 | "sFGub1av+jLRyFNGNBJcqXAO+Tq2zXG00DxbGY+aooJ50qU/Lh5gfnCEMDXlMM9P\n" |
| 114 | "T8JVpWaaNLCC+0Z5txsfYp+FO8mOttIPIF6F8FtmTnm/jhNntvqKvsU+NHylIYzr\n" |
| 115 | "o42EpiWwS7ktPPUS2GtG+IUdy8rvdO1xJ5kNxs7ZlygY4W1htOhbUusCAQI=\n" |
| 116 | "-----END DH PARAMETERS-----\n" |
| 117 | ), format: QSsl::Pem); |
| 118 | |
| 119 | #ifndef QT_NO_OPENSSL |
| 120 | QCOMPARE(dh.isValid(), true); |
| 121 | QCOMPARE(dh.error(), QSslDiffieHellmanParameters::NoError); |
| 122 | #endif |
| 123 | } |
| 124 | |
| 125 | void tst_QSslDiffieHellmanParameters::unsafe512Bits() |
| 126 | { |
| 127 | // Uniquely generated with 'openssl dhparam -outform PEM -out out.pem -check -2 512' |
| 128 | const auto dh = QSslDiffieHellmanParameters::fromEncoded(QByteArrayLiteral( |
| 129 | "-----BEGIN DH PARAMETERS-----\n" |
| 130 | "MEYCQQCf8goDn56akiliAtEL1ZG7VH+9wfLxsv8/B1emTUG+rMKB1yaVAU7HaAiM\n" |
| 131 | "Gtmo2bAWUqBczUTOTzqmWTm28P6bAgEC\n" |
| 132 | "-----END DH PARAMETERS-----\n" |
| 133 | ), format: QSsl::Pem); |
| 134 | |
| 135 | #ifndef QT_NO_OPENSSL |
| 136 | QCOMPARE(dh.isValid(), false); |
| 137 | QCOMPARE(dh.error(), QSslDiffieHellmanParameters::UnsafeParametersError); |
| 138 | #endif |
| 139 | } |
| 140 | |
| 141 | void tst_QSslDiffieHellmanParameters::unsafeNonPrime() |
| 142 | { |
| 143 | // Uniquely generated with 'openssl dhparam -outform DER -out out.der -check -2 1024' |
| 144 | // and then modified by hand to make P not be a prime number. |
| 145 | const auto dh = QSslDiffieHellmanParameters::fromEncoded(encoded: QByteArray::fromBase64(QByteArrayLiteral( |
| 146 | "MIGHAoGBALLcOLg+ow8TMnbCUeNjwys6wUTIH9mn4ZSeIbD6qvCsJgg4cUxXwJQmPY" |
| 147 | "Xl15AsKXgkXWh0n+/N6tjH0sSRJnzDvN2H3KxFLKkvxmBYrDOJMdCuMgZD50aOsVyd" |
| 148 | "vholAW9zilkoYkB6sqwxY1Z2dbpTWajCsUAWZQ0AIP4Y5nesAgEC" |
| 149 | )), format: QSsl::Der); |
| 150 | |
| 151 | #ifndef QT_NO_OPENSSL |
| 152 | QCOMPARE(dh.isValid(), false); |
| 153 | QCOMPARE(dh.error(), QSslDiffieHellmanParameters::UnsafeParametersError); |
| 154 | #endif |
| 155 | } |
| 156 | |
| 157 | void tst_QSslDiffieHellmanParameters::defaultIsValid() |
| 158 | { |
| 159 | // The QSslDiffieHellmanParameters::defaultParameters() method takes a shortcut, |
| 160 | // by not verifying the passed-in parameters. Instead, it simply assigns the default |
| 161 | // DH parameters to the derData field of QSslDiffieHellmanParametersPrivate. |
| 162 | // |
| 163 | // This test ensures that our default parameters pass the internal verification tests |
| 164 | // by constructing, using fromEncoded(), a QSslDiffieHellmanParameters instance that |
| 165 | // we expect to be equivalent to the one returned by defaultParameters(). By using |
| 166 | // fromEncoded() we go through the internal verification mechanisms. Finally, to ensure |
| 167 | // the two instances are equivalent, we compare them. |
| 168 | |
| 169 | const auto dh = QSslDiffieHellmanParameters::fromEncoded( |
| 170 | encoded: QByteArray::fromBase64(base64: QByteArray(qssl_dhparams_default_base64)), |
| 171 | format: QSsl::Der |
| 172 | ); |
| 173 | |
| 174 | const auto defaultdh = QSslDiffieHellmanParameters::defaultParameters(); |
| 175 | |
| 176 | #ifndef QT_NO_OPENSSL |
| 177 | QCOMPARE(dh.isEmpty(), false); |
| 178 | QCOMPARE(dh.isValid(), true); |
| 179 | QCOMPARE(dh.error(), QSslDiffieHellmanParameters::NoError); |
| 180 | QCOMPARE(dh, defaultdh); |
| 181 | #endif |
| 182 | } |
| 183 | |
| 184 | #endif // QT_NO_SSL |
| 185 | |
| 186 | QTEST_MAIN(tst_QSslDiffieHellmanParameters) |
| 187 | #include "tst_qssldiffiehellmanparameters.moc" |
| 188 | |