diff options
author | Jeremy Lainé <jeremy.laine@m4x.org> | 2015-01-30 15:58:32 +0100 |
---|---|---|
committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2015-02-07 06:51:05 +0000 |
commit | 06524c11dcaeea2f8c8d19fc8999df673696eb5b (patch) | |
tree | b07d21d3340ec96fcf02b341cb64d9255f734cf8 /tests | |
parent | cbec1ed1a15d1f4a3367bfefb694ba9a837bc501 (diff) |
ssl: add test for server-side QSslSocket::PeerVerifyMode
This adds tests to check the behavior of a QSslSocket-based server when
presented with various client certificates.
Change-Id: I431157e46cfb00880ae8b7a33015cce50e56b6bb
Reviewed-by: Daniel Molkentin <daniel@molkentin.de>
Diffstat (limited to 'tests')
7 files changed, 285 insertions, 1 deletions
diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.crt b/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.crt new file mode 100644 index 0000000000..cf5893e98d --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMzCCAhugAwIBAgIJAJBdFtmKuuELMA0GCSqGSIb3DQEBCwUAMC8xGjAYBgNV +BAoMEUJvZ3VzIENvcnBvcmF0aW9uMREwDwYDVQQDDAhCb2d1cyBDQTAgFw0xNTAx +MzAxNzM0NDdaGA8yMTE1MDEwNjE3MzQ0N1owLzEaMBgGA1UECgwRQm9ndXMgQ29y +cG9yYXRpb24xETAPBgNVBAMMCEJvZ3VzIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAnXt/X69lmfvWampP88f20yNs1VZroG9VjdR4GaJM6pbWu5Wn +SYBfS81osnHC7dTW2FvKZUGnz7KX+ImkbE2qUvj6yTeFu6ILj3o+8ws7A4iOTkiH +84CHb6T/HxWO5fW6mS5v+tvPDp3rQ7JpPVYvoh7dSv8X1+JCdDmkepRveN6Pzo47 +9VFVC0oscc5I4Y0wPwnaXZ4X26vmRfbhqtoKL57lz1lJ0R6bvLC9mf4DGFPx7WXQ +eOtlKX2dtuKj+Cl3vyHff6gHNMKM0bq3KfsT+vDO6eIs/ayqVRdd0XBIMj+bZYd9 +7QI/+3XTNR3TwTisrjo71XZtHdA1DkcMaSGoJwIDAQABo1AwTjAdBgNVHQ4EFgQU +xVZK4BIjBgmluCLIespCbne4BIUwHwYDVR0jBBgwFoAUxVZK4BIjBgmluCLIespC +bne4BIUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAgZn6odHr2y1G +1OStblBdsXNxmsW7WzhLUYFUhSzBw9KS/O7uG2HAFLwJNM4sQHeuc0JjxqXG5n7s +mGbmWpUYt8+KJDRnUssmKwwg2u6Rqp+0I9leCk9KTtYpXX7d9wprSsgwjQKhTEeQ +fNImbNR6Br7GDO7Om2MnOALvZmp0KJgUFIH0J630LJTrsrTvwfX7wKhYb1wgud5N +SXdGjBuJxKK3Y0VBMsbqwI0y+wHIYE+qLzlFWNRHmKaYeGtg0T8CVK6XWUrLcjcr +rQINqW3rb1OlWF7YZ5dg7vXoZrza6YSQLWha6/FQMCaKtJHxIE1NBw0ZXK6txnkI +f4HXoPvSGg== +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.key b/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.key new file mode 100644 index 0000000000..1c2db7932e --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-ca.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAnXt/X69lmfvWampP88f20yNs1VZroG9VjdR4GaJM6pbWu5Wn +SYBfS81osnHC7dTW2FvKZUGnz7KX+ImkbE2qUvj6yTeFu6ILj3o+8ws7A4iOTkiH +84CHb6T/HxWO5fW6mS5v+tvPDp3rQ7JpPVYvoh7dSv8X1+JCdDmkepRveN6Pzo47 +9VFVC0oscc5I4Y0wPwnaXZ4X26vmRfbhqtoKL57lz1lJ0R6bvLC9mf4DGFPx7WXQ +eOtlKX2dtuKj+Cl3vyHff6gHNMKM0bq3KfsT+vDO6eIs/ayqVRdd0XBIMj+bZYd9 +7QI/+3XTNR3TwTisrjo71XZtHdA1DkcMaSGoJwIDAQABAoIBAGKkKmJq4L8UyXca +ZD4UcHxL4i221e9GDVarURbtXDRMivAwivo1GHvIi93J+Ak0meYniJzoBQ7JlPsu +a/kSpK8YGS3UQ0YF+CvErI1b6XkLHefW8qEJTswVk1+LB1jvFBRCzA1bhVRogiaD +J/wtceSgZIhHRE4LAQj/2hCVzUTtV6Zr0GIJGjB7hdF9MHGlTwkPrkjvERlK/PTc +dVjyNbinYGJNA2i701u/atplH2eSBUresMhHu3AZUUXZKfFQ2m07FDBNAtsoYNnO +d17EXDaoQRDVWSP83GN4b/hpmngvHl1fuFBZ1ms375FNPQo/K33QBaUsLsqiIS/v +k3LBkeECgYEAyqv5dkgte9c2mxT5zUQySr1fDms4nwZTth8477jRnOZND1M9VoIv +1EjBfxq3y7gJVd34VWYeCxNBYwK8C45SDXtlU9X2hLeKWU6yfdegyxv950P5AahT +J80YtYSez+mTLPOC42GeTg7l01NXlTHmPpraIkdNniHc8bqyAEK9w+kCgYEAxuuO +Ln84GkAm1gr6gyFkOMVwVEfszKjRGIqp4BnSwM9bFgWvhyj4jpr+bpe4gQKQQE5q +E/GoxYOtdZ3yYupd2Ki0irGhhm3u0ywgmbomurOw46AInONWcHTU6kZY/dd8wfvW +8YcmFq/LNupwFOEw18mKaQXygMnUYci+uOSw0Y8CgYEAkcX0XjE4FdUL/6usqQme +KsfesR5J0YfZeism5rXGftXfI2C5w5lMEaJrGqL7A9pRTKOlVLdocIrfAvoaiy1I +s03H6e8Bqx/gsK+8DmujybNOgqMPXTPW68/HL/g9ykm0hCZ6RFYYaQiqIb/WRQdp +FiqHLxSeLVkp8+xWz30xxNECgYAA7P23Z64qKRxFKL3ruE8QGJMiQUdv2GVIuPR7 +b4NUlGJ3IsWjWmR1vXDrsNcR+qITOoox15ESgj9facHEBhUzue1FK/h1eLOA1ha8 +wGoHumhbVtZTbJdtZI3NHVCytbsF6Bci/p8FwgGvGr40yquAhZaYUIfFY6sSXW3N +zHqqLwKBgQCUGrePDhjjUZZNQya0TQZ95HL8OQB2e9bx8RwypYdC3pAZ6uDfl+Ne +IZoA8EoDHVbsxDXmLTGil/kyvmYBnzvkVz/yMyFm/7I0zXEOr8bTgqE5wJ8BMGSp +yil5jDoN28KL6D+HsDsWUEOvvHieDYP3cxfpZWiQuWIZ6gfDDVjIwQ== +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-client.crt b/tests/auto/network/ssl/qsslsocket/certs/bogus-client.crt new file mode 100644 index 0000000000..c9d43ce662 --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-client.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIBADANBgkqhkiG9w0BAQsFADAvMRowGAYDVQQKDBFCb2d1 +cyBDb3Jwb3JhdGlvbjERMA8GA1UEAwwIQm9ndXMgQ0EwIBcNMTUwMTMwMTczNTI0 +WhgPMjExNTAxMDYxNzM1MjRaMDMxGjAYBgNVBAoMEUJvZ3VzIENvcnBvcmF0aW9u +MRUwEwYDVQQDDAxCb2d1cyBDbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDa28y3b2qcrFTjr3GIgjx78qlbRZomBt/A//ZW5qx00+QXT30bu8F0 +jCfHaBTDSnabP86856C/kL1d6oRtc7jmaxNoj39uRh3NcV3VmFEiLI9XmJ0gOIBN +vMQ0voi4gvRBzjFMnVOFML8FePV4OUX1QUZK4eAvZCsDhaJv1cCEERsfcttv7X31 +CT3+a3geZsb0cMDqicq/uaX2IONhqoNYwGlmgF+bWICIxJmEnaK3e/LnKKpvvfTt +n2M0Fx0W4150HSZxQ9Iz6fQQ8oLNn3qNL5i9377XKpck2uxC39yt5WXK2d5m8xBF +5+qwMMqlEW4LoE/dTU9mJ1lZLwV7m7QJAgMBAAGjIDAeMAkGA1UdEwQCMAAwEQYJ +YIZIAYb4QgEBBAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IBAQBBeGwXbU/WRLkfxDoI +Js2nPqzpfEXAcrJhurHKlm/wMIHnHHhTM69O7yTl/VUdKIXPzC1bGkAiSBQo+51B +SJkyWo3vt47g8rqAnUs4oM+bPD2t1YkJVeGLu+Nfw5SHlc+HdojdAcpKtnCbqtrd +vnV4QyB70nxKXC3jmWVBu/jeim0RzUacO+lF9vRPqwnlDINopx8ZpEjaXxABtaQA +cVUosFGEPRjOYAbw9j4fK7J7EXh/124j81OfawkfaMMDt2EedmSdlhPy+Io7VaBo +ho+39cX/oO3Ek+C9v+4aGF7rgp3VyKOGtC5rIy+YiwjcI09pRVPuqEqXC6C4nQcS +SjjF +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-client.key b/tests/auto/network/ssl/qsslsocket/certs/bogus-client.key new file mode 100644 index 0000000000..f676af73d4 --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-client.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA2tvMt29qnKxU469xiII8e/KpW0WaJgbfwP/2VuasdNPkF099 +G7vBdIwnx2gUw0p2mz/OvOegv5C9XeqEbXO45msTaI9/bkYdzXFd1ZhRIiyPV5id +IDiATbzENL6IuIL0Qc4xTJ1ThTC/BXj1eDlF9UFGSuHgL2QrA4Wib9XAhBEbH3Lb +b+199Qk9/mt4HmbG9HDA6onKv7ml9iDjYaqDWMBpZoBfm1iAiMSZhJ2it3vy5yiq +b7307Z9jNBcdFuNedB0mcUPSM+n0EPKCzZ96jS+Yvd++1yqXJNrsQt/creVlytne +ZvMQRefqsDDKpRFuC6BP3U1PZidZWS8Fe5u0CQIDAQABAoIBAQDOzZlA0CgWiYTh +bLvEOQQ8Pw0msLs7KY2vCm7UqL3W2w4RtMvMM/tWTMWd2EyeSLOQeZe5ysmLmpJF +tz+RSSMzn4REbiwEoH6yzWfUWEx6FU8Rf6UheCJM0o04Jb59U0jJEbRl59eu6GPo +IOcaxkvDtv1b7tnvDiDTACiAsqNqZhs54QlqwpadSYe4QgK9KH0WxqBzLpXr8eEq +ZV1uuuNpaf+mitVaJhXHyVt7Od1yPfohbTYaXjko3xt3BcStt4tzRZkGQk2kjMWd +d53wqcFlc+zxSW9/ogLr+TCDttTEa1oV+JLpXLkV5J0/saf/LYw96r6f98XhLrd1 +5otsbQ+dAoGBAP0nCzd6otnuUsLX+dz0ed61zDzyTVBXLxuOOvDpuPItVUKPI8yZ +mwveIm97/4u50HGSWUgLR5v+ABfMVG/DqkEP50dDbIhQ2uBhkR5xVgSlZSiZ7S03 +1AErADaeViphKjfAuHraGgC6SRv8HBZadbYW+ZQRVTF6IRJmstiLNJIDAoGBAN1S +AYtYhH0tJSQxyL+sdeuPGhY5RDdlSeLRAStpoGjmaOC4Rc8uDsts2xuInkCcTW2y +nogoR5YxFvcly3vGL5kOzLuscLbueqkz/rbTlZPruqL7fMyPI7Y3YgGER5XNwPpE ++DlW1fu2aE42WUU49mkUNaT2WBtOLnbZKShAWKoDAoGAOGZfeF/JMnaHV8OYdmK9 +WCH2u8lb8j9KToBUn2HjA4mYCjkrx6SdR3qY/2+H0pB2YScy3vssXBOt3591XGUi +ZFZvt4/M+V3SNdVm6HplqKlUrUQF9GIQyKXU6VZDajO1nTBBqZU339ug+Cwl8dD7 +krLxrcxix6AnCBt7UwVIlBMCgYEAydQADogxgknKJiC0Vn86pg9BFeUxXWckIxDA +hUt0+lSsbcn993qkCUUC5zAGSRuAzLnoMnixF7k6nTW9Q+mu/GBvufH+dAQ0ndsJ +vMZlEJkXAYxf+dfLFF+bI5DzCxywkEqXJwsWZs6ofjK35BWXOKoyZXY1UOlSHBXb +n5ZWhOsCgYBRLqEjUehkZfqjZj8VClyPQ/6bAgtfjMRqpgsLgvqG9gBraDs4DXJr +K8Ac3+vCP8rqVwIUC0iu/5MFX75WJ7Go7wbAg7m91P9tmzSiLEm5H1toXJpla6nv +oLZW+jN9O1BaVow8f2qIEJMjHnDbuZnMPQlMGUD+g2tNgczfxT3MOA== +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-server.crt b/tests/auto/network/ssl/qsslsocket/certs/bogus-server.crt new file mode 100644 index 0000000000..7e59f6128d --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-server.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQsFADAvMRowGAYDVQQKDBFCb2d1 +cyBDb3Jwb3JhdGlvbjERMA8GA1UEAwwIQm9ndXMgQ0EwIBcNMTUwMTMxMTc0MjI3 +WhgPMjExNTAxMDcxNzQyMjdaMDMxGjAYBgNVBAoMEUJvZ3VzIENvcnBvcmF0aW9u +MRUwEwYDVQQDDAxCb2d1cyBTZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCv899JQxy/mpaQzscopmoKOkgbmwGwty1KiTpT09MU1+gtMHCfhmVp +nAiNIlQlDa+5mjhvyy1fSf+mgdjnvT5pdUAro633gfCv318EViwYsvA7/0ZumFqU +UyPWw4/2of/ZfJv2ewzMLoYEDKiLcXxInBsMlt5Lr7IBS8SNitDU+TAM7HLEIkMz +c0JpxY09H707tO8G3e93yfB5l8H+JdeEdPe+7PDfnsZZuMmaImiNYRByPTTuGvrN +I9I+OxcE4ZOMMNb3mzAoEFnyfHiCO2ehHl58y0a49ayAKJdP/FV3n2LtL/Zc5Ilq +b3VJgaShevrfIiItURjOAjDA9B95hYuZAgMBAAGjIDAeMAkGA1UdEwQCMAAwEQYJ +YIZIAYb4QgEBBAQDAgZAMA0GCSqGSIb3DQEBCwUAA4IBAQBhTqwD3HxamZGopq0K +r8KUdtliiPwo4GBFp0zg6VdSxo01WfpwFGOaeKNmV0JadtJ1DhcsdIUv2OvrxiWQ +1n0IGHULeazQnst1q1t/Vlup3IggKTGCLi8yd3acY8tr2wj9lGjWhsR+BcrCUTEB +BCpIsQiFA8+PTf/8SHuzMokDBP+j02fWCqwR749H4NDQgqrFsgzxLDA69XgvkNM3 ++HOsOR/QxeYIp54mqPnsNVhzV0JbpQpF4j9R5kMI/bsPmWH6W0GbSSyA07o8iVw7 +eqPbwHnIlHXzafvaGmF0QituAzU0nPgMc9OMxuoqacBSmSvmSdMmh///vr7O2KHO +7s+g +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qsslsocket/certs/bogus-server.key b/tests/auto/network/ssl/qsslsocket/certs/bogus-server.key new file mode 100644 index 0000000000..bda8dae678 --- /dev/null +++ b/tests/auto/network/ssl/qsslsocket/certs/bogus-server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAr/PfSUMcv5qWkM7HKKZqCjpIG5sBsLctSok6U9PTFNfoLTBw +n4ZlaZwIjSJUJQ2vuZo4b8stX0n/poHY570+aXVAK6Ot94Hwr99fBFYsGLLwO/9G +bphalFMj1sOP9qH/2Xyb9nsMzC6GBAyoi3F8SJwbDJbeS6+yAUvEjYrQ1PkwDOxy +xCJDM3NCacWNPR+9O7TvBt3vd8nweZfB/iXXhHT3vuzw357GWbjJmiJojWEQcj00 +7hr6zSPSPjsXBOGTjDDW95swKBBZ8nx4gjtnoR5efMtGuPWsgCiXT/xVd59i7S/2 +XOSJam91SYGkoXr63yIiLVEYzgIwwPQfeYWLmQIDAQABAoIBAHVRJJLjpZp3h2a8 +CHypIND69TM60hCywgcNoo9cEES4hL0ErEMhSCL3f5giyHoAOyeElZasoO8FFuk9 +cJNrUd7c59FxDECYKhQJ2n+4uSQqwxUt6xc4jESTfrTmpemrMD0h4ZehifHmH0M5 +8XMwUs7TDxIA0e0jE4vbqg05/m3RMHoeJ4W5K4dMxkJbjmyjjCr8aT8WP/KSTABS +YQPql0rs6WL5Q2s1I/i3I4qIS4CKk8Ym7O5/Wk1fxbCh2ABL2PhW8PZDzvsFYo2T +cwX0cc0EILBc3tOG11Iua6mK8y9Zz1BpUT02ZvGaPf9R6vI0Shk1yWbZ0NYLx0MH +Zu8HIYECgYEA5awzjNcnDYQY9f6C/0TNj54Z8I7UFmGJX7XhPVVMceNieUiLvrsH +Zmf4Q51PLM1iz0S2qGA/c7lngHDXwFe++MANIK7KNwL2LtPF/83mYgBUxBKJaNHD +4B/6CCitjSwAfMNBnE70zg0F9chqy+9p+fTEwUFW6Y4y9U5jO4kw5HECgYEAxB8+ +YYMUGeIt9TnMKrC2YK/o8jo+5ZEOpEIPwleeAIUMujVVonu3TX2nKos2MgaZg/F0 +OpvDlcQZqb4Em73ctf3ZgBYEs9tt2qdB5qGlg4Hs2wyfgKUPQGLX2RseUQCYsOWT +cPPKvYDTZ6yhW6gGBd5ufl5tnG93CsIpcNV1DakCgYEAwByZhi6V4Q1k36eDpcjE +dWRW6ExghVQS17dIb8hAyGbeAPs4wVKqbvN6y/vytVQbWapta0wO51rng51gKuh6 +upHSqUrrpLZafHLyBPYSxljmjpe+zqnfwUKeH2L/QL3UroeZAwlcZlqoaJ27D1j0 ++XrPdaOU8onagCyQfsVT21ECgYAafW3blezdIiO6/7eH/J5lqNz5+swMDe/AV/vw +8AyzXUU+0X1jmPpFSTePE4aaczHBFJfyYp+kVvxwZO4Say6olkUOe+resEDCS90m +3aaRgLcRTz8sDR9mPvOQq40Iu9/j5N5pX0R/HCtx0WtqCePmXwjloLOFcbjOhzM5 +vls1IQKBgEF8DEk8T4ycjwBXC3U7Duj9jPL815417BAHdGstLP1yNcI05ubN2T56 +ITbf625YS7OdtYfrf1/jBnUVXsJspsQqkOUB97M224CVWI+vJiv8jPX+KCnR7/Zh +A/7OrtZ6FCzLyBeu/2p1NHAttqSUqu9t6wCeeBcelnAUcrjfLmlw +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index fe5a70996b..c3b7cb1250 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -65,7 +65,9 @@ Q_DECLARE_METATYPE(QSslSocket::SslMode) typedef QList<QSslError::SslError> SslErrorList; Q_DECLARE_METATYPE(SslErrorList) Q_DECLARE_METATYPE(QSslError) +Q_DECLARE_METATYPE(QSslKey) Q_DECLARE_METATYPE(QSsl::SslProtocol) +Q_DECLARE_METATYPE(QSslSocket::PeerVerifyMode); typedef QSharedPointer<QSslSocket> QSslSocketPtr; // Non-OpenSSL backends are not able to report a specific error code @@ -221,6 +223,8 @@ private slots: void qtbug18498_peek2(); void dhServer(); void ecdhServer(); + void verifyClientCertificate_data(); + void verifyClientCertificate(); void setEmptyDefaultConfiguration(); // this test should be last #ifndef QT_NO_OPENSSL @@ -1059,12 +1063,17 @@ public: const QString &certFile = SRCDIR "certs/fluke.cert", const QString &interFile = QString()) : socket(0), + ignoreSslErrors(true), + peerVerifyMode(QSslSocket::AutoVerifyPeer), protocol(QSsl::TlsV1_0), m_keyFile(keyFile), m_certFile(certFile), m_interFile(interFile) { } QSslSocket *socket; + QString addCaCertificates; + bool ignoreSslErrors; + QSslSocket::PeerVerifyMode peerVerifyMode; QSsl::SslProtocol protocol; QString m_keyFile; QString m_certFile; @@ -1075,8 +1084,10 @@ protected: void incomingConnection(qintptr socketDescriptor) { socket = new QSslSocket(this); + socket->setPeerVerifyMode(peerVerifyMode); socket->setProtocol(protocol); - connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot())); + if (ignoreSslErrors) + connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot())); QFile file(m_keyFile); QVERIFY(file.open(QIODevice::ReadOnly)); @@ -1084,6 +1095,14 @@ protected: QVERIFY(!key.isNull()); socket->setPrivateKey(key); + // Add CA certificates to verify client certificate + if (!addCaCertificates.isEmpty()) { + QList<QSslCertificate> caCert = QSslCertificate::fromPath(addCaCertificates); + QVERIFY(!caCert.isEmpty()); + QVERIFY(!caCert.first().isNull()); + socket->addCaCertificates(caCert); + } + // If we have a cert issued directly from the CA if (m_interFile.isEmpty()) { QList<QSslCertificate> localCert = QSslCertificate::fromPath(m_certFile); @@ -2782,6 +2801,132 @@ void tst_QSslSocket::ecdhServer() QVERIFY(client->state() == QAbstractSocket::ConnectedState); } +void tst_QSslSocket::verifyClientCertificate_data() +{ + QTest::addColumn<QSslSocket::PeerVerifyMode>("peerVerifyMode"); + QTest::addColumn<QList<QSslCertificate> >("clientCerts"); + QTest::addColumn<QSslKey>("clientKey"); + QTest::addColumn<bool>("works"); + + // no certificate + QList<QSslCertificate> noCerts; + QSslKey noKey; + + QTest::newRow("NoCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << noCerts << noKey << true; + QTest::newRow("NoCert:QueryPeer") << QSslSocket::QueryPeer << noCerts << noKey << true; + QTest::newRow("NoCert:VerifyNone") << QSslSocket::VerifyNone << noCerts << noKey << true; + QTest::newRow("NoCert:VerifyPeer") << QSslSocket::VerifyPeer << noCerts << noKey << false; + + // self-signed certificate + QList<QSslCertificate> flukeCerts = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert"); + QCOMPARE(flukeCerts.size(), 1); + + QFile flukeFile(SRCDIR "certs/fluke.key"); + QVERIFY(flukeFile.open(QIODevice::ReadOnly)); + QSslKey flukeKey(flukeFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); + QVERIFY(!flukeKey.isNull()); + + QTest::newRow("SelfSignedCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << flukeCerts << flukeKey << true; + QTest::newRow("SelfSignedCert:QueryPeer") << QSslSocket::QueryPeer << flukeCerts << flukeKey << true; + QTest::newRow("SelfSignedCert:VerifyNone") << QSslSocket::VerifyNone << flukeCerts << flukeKey << true; + QTest::newRow("SelfSignedCert:VerifyPeer") << QSslSocket::VerifyPeer << flukeCerts << flukeKey << false; + + // valid certificate, but wrong usage (server certificate) + QList<QSslCertificate> serverCerts = QSslCertificate::fromPath(SRCDIR "certs/bogus-server.crt"); + QCOMPARE(serverCerts.size(), 1); + + QFile serverFile(SRCDIR "certs/bogus-server.key"); + QVERIFY(serverFile.open(QIODevice::ReadOnly)); + QSslKey serverKey(serverFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); + QVERIFY(!serverKey.isNull()); + + QTest::newRow("ValidServerCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << serverCerts << serverKey << true; + QTest::newRow("ValidServerCert:QueryPeer") << QSslSocket::QueryPeer << serverCerts << serverKey << true; + QTest::newRow("ValidServerCert:VerifyNone") << QSslSocket::VerifyNone << serverCerts << serverKey << true; + QTest::newRow("ValidServerCert:VerifyPeer") << QSslSocket::VerifyPeer << serverCerts << serverKey << false; + + // valid certificate, correct usage (client certificate) + QList<QSslCertificate> validCerts = QSslCertificate::fromPath(SRCDIR "certs/bogus-client.crt"); + QCOMPARE(validCerts.size(), 1); + + QFile validFile(SRCDIR "certs/bogus-client.key"); + QVERIFY(validFile.open(QIODevice::ReadOnly)); + QSslKey validKey(validFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); + QVERIFY(!validKey.isNull()); + + QTest::newRow("ValidClientCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << validCerts << validKey << true; + QTest::newRow("ValidClientCert:QueryPeer") << QSslSocket::QueryPeer << validCerts << validKey << true; + QTest::newRow("ValidClientCert:VerifyNone") << QSslSocket::VerifyNone << validCerts << validKey << true; + QTest::newRow("ValidClientCert:VerifyPeer") << QSslSocket::VerifyPeer << validCerts << validKey << true; + + // valid certificate, correct usage (client certificate), with chain + validCerts += QSslCertificate::fromPath(SRCDIR "certs/bogus-ca.crt"); + QCOMPARE(validCerts.size(), 2); + + QTest::newRow("ValidClientCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << validCerts << validKey << true; + QTest::newRow("ValidClientCert:QueryPeer") << QSslSocket::QueryPeer << validCerts << validKey << true; + QTest::newRow("ValidClientCert:VerifyNone") << QSslSocket::VerifyNone << validCerts << validKey << true; + QTest::newRow("ValidClientCert:VerifyPeer") << QSslSocket::VerifyPeer << validCerts << validKey << true; +} + +void tst_QSslSocket::verifyClientCertificate() +{ + if (!QSslSocket::supportsSsl()) { + qWarning("SSL not supported, skipping test"); + return; + } + + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + QFETCH(QSslSocket::PeerVerifyMode, peerVerifyMode); + SslServer server; + server.addCaCertificates = QLatin1String(SRCDIR "certs/bogus-ca.crt"); + server.ignoreSslErrors = false; + server.peerVerifyMode = peerVerifyMode; + QVERIFY(server.listen()); + + QEventLoop loop; + QTimer::singleShot(5000, &loop, SLOT(quit())); + + QFETCH(QList<QSslCertificate>, clientCerts); + QFETCH(QSslKey, clientKey); + QSslSocketPtr client(new QSslSocket); + client->setLocalCertificateChain(clientCerts); + client->setPrivateKey(clientKey); + socket = client.data(); + + connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot())); + connect(socket, SIGNAL(disconnected()), &loop, SLOT(quit())); + connect(socket, SIGNAL(encrypted()), &loop, SLOT(quit())); + + client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort()); + + loop.exec(); + + QFETCH(bool, works); + QAbstractSocket::SocketState expectedState = (works) ? QAbstractSocket::ConnectedState : QAbstractSocket::UnconnectedState; + + // check server socket + QVERIFY(server.socket); + + QCOMPARE(int(server.socket->state()), int(expectedState)); + QCOMPARE(server.socket->isEncrypted(), works); + + if (peerVerifyMode == QSslSocket::VerifyNone || clientCerts.isEmpty()) { + QVERIFY(server.socket->peerCertificate().isNull()); + QVERIFY(server.socket->peerCertificateChain().isEmpty()); + } else { + QCOMPARE(server.socket->peerCertificate(), clientCerts.first()); + QCOMPARE(server.socket->peerCertificateChain(), clientCerts); + } + + // check client socket + QCOMPARE(int(client->state()), int(expectedState)); + QCOMPARE(client->isEncrypted(), works); +} + void tst_QSslSocket::setEmptyDefaultConfiguration() // this test should be last, as it has some side effects { // used to produce a crash in QSslConfigurationPrivate::deepCopyDefaultConfiguration, QTBUG-13265 |