diff options
Diffstat (limited to 'tests/auto/network/ssl')
26 files changed, 1230 insertions, 142 deletions
diff --git a/tests/auto/network/ssl/qocsp/certs/alice.crt b/tests/auto/network/ssl/qocsp/certs/alice.crt new file mode 100644 index 0000000000..02df86a517 --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/alice.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBjjELMAkGA1UEBhMCTk8x +DTALBgNVBAgMBE9zbG8xEjAQBgNVBAcMCU9zbG8gQ2l0eTETMBEGA1UECgwKVGhl +IFF0IENBMTENMAsGA1UECwwEUVRDTjERMA8GA1UEAwwIY2ExcXQuaW8xJTAjBgkq +hkiG9w0BCQEWFnRpbXVyLnBvY2hlcHRzb3ZAcXQuaW8wHhcNMTgxMTIyMTEwNjE4 +WhcNMjgxMTE5MTEwNjE4WjCBkjELMAkGA1UEBhMCTk8xDTALBgNVBAgMBE9zbG8x +EjAQBgNVBAcMCU9zbG8gQ2l0eTEdMBsGA1UECgwUVGhlIEZhbW91cyBBbGljZSBM +dGQxDTALBgNVBAsMBEdPQUExEjAQBgNVBAMMCWFsaWNlLm9yZzEeMBwGCSqGSIb3 +DQEJARYPYWxpY2VAYWxpY2Uub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAtuGDR9oIEkK57xlxq/xc3u7B1ni4pdoyhf9r+pkgmu591qp2kl3Xcq3W +Ve5Z553orAUCAExPlKfFV+CYYAedSgsDYlKk8DN+f/n+hkG6Wl2qyFzHgl+mvPwa +eDqdVMIcDHGhSljALi9AqsN4lbrUhSxiyuPhAwl82WB0EIucmBs1NxSSZgFPRBLG +Uzy9WvtQFq1qtn795PVIUsNg68qZQ9BvRduOQAr3bg3anoYqytthWnzLWKri2QR4 +Z4Y0mvcbT/PZwhtcFZzDXG3Hvc7k3AroAbWoSghMEgok9TW9grKYkW2d5cpQTP+l +ptkB6yZ06MY9/uCdYzhm8eu2RgVndwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCG +SAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4E +FgQUQz2PuE4VuqHtZYTvVLr4+0IuHTUwHwYDVR0jBBgwFoAUeBcnAkU7sTqm7i2Q +vTxwgr0nQ0QwDQYJKoZIhvcNAQELBQADggEBABGGmo1vUAXKQm9kowvUtjDpEIIY +TpT+KqiUBOgJg5fGn6a63vBn5GMA6eT948ywi9ZU2M9dIXJCM+bdqjXeOtt4bBPZ +xz6DcBPW9CoTR4CV1muNa95WIXzAHatq3XYG041ddMf41WG7QIdQsojBYEG0IYlv +PQx+B+m2cu7A04aI2tCS8aUh7Xc9wRilJ+h/FlYFFQzgyEKsd7CFgkyxG/sLyFNH +skYYk/DLlmaWa+YScHYB5kAk8StoETeMI2LLs7rgJmchi8eAxjLroYDUhQclUjqz +vlNM+4GvcF5RluyuEXFOZVdmQahkXcyu0Q3yxvsBbnDglmbb2YHPl/blB7w= +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qocsp/certs/alice.key b/tests/auto/network/ssl/qocsp/certs/alice.key new file mode 100644 index 0000000000..6f2666ebde --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/alice.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC24YNH2ggSQrnv +GXGr/Fze7sHWeLil2jKF/2v6mSCa7n3WqnaSXddyrdZV7lnnneisBQIATE+Up8VX +4JhgB51KCwNiUqTwM35/+f6GQbpaXarIXMeCX6a8/Bp4Op1UwhwMcaFKWMAuL0Cq +w3iVutSFLGLK4+EDCXzZYHQQi5yYGzU3FJJmAU9EEsZTPL1a+1AWrWq2fv3k9UhS +w2DryplD0G9F245ACvduDdqehirK22FafMtYquLZBHhnhjSa9xtP89nCG1wVnMNc +bce9zuTcCugBtahKCEwSCiT1Nb2CspiRbZ3lylBM/6Wm2QHrJnToxj3+4J1jOGbx +67ZGBWd3AgMBAAECggEADbzU+sHDF3QRuYdExbGYXFq9DtpUrIi+gNhWCSYVj+3Y +YBa//3CzLXcngZ78++wdvUZHBzS0SatspJRHffc0doprP6iLoUuM9hoWZ4lqcT1W +BeUKS53ZzZp2do+Yn/RQ3RJwFkCidxWvmuRCG6VEL5jM9wa1MWA2E7IuJcwHAFny +WIByosje5Qrd7eXDuVoqr1hjJ2UxIjIJ8Zgg3EE9wVUyJE3PU1HLz2AefonYRwbL +XlzNgnj0c9Ti9ejfyon+jTnpslLKtPal2kxyGoKPAngadAhCzqSaCWggACm7R8Ge +pZ0Y0pV7QReEgjfFd4D3qOqLRQZVJOMDb3vJu2/rsQKBgQDfKjfSpUweBM9li7GS +xXbDpC3Y8zQ2VY+2SvgYoYiYU/Y6YenxhKM1XDbWZxhxS8GVfCUAESFDOTZcMvdi +QEbG1uEmuCn1ksvrC2y54rtd8WDppcS0vJxCrU4nZG0v9IjVKp67B8EpBpAQeNb1 +tR6ByT2fLJu5+WU2S7OxqX7uLwKBgQDRyfKvrCQgdJOQlJlHOv1y1hN8WY51A8P/ +JbDXoun3PCPd+JczvFXCUh3ZLXqUEAX2qDOBD1pBM62EN6/A9ukO4mcMd8uYIet6 +nR4nVqXUjWuzXe6eo913lTDQrIOGWpViTc8fnvFlwBPfwzxbZNx38HZbw0L0nT7d +8TE/JxLROQKBgQC4Kzo4b8vadjPGZLueGbICkQp5IXR0ZrYcRdBrW1vEAn6Q/d84 +PzMFxV1IIXrNfSx8NiC+5mQh+yQ+gJ0iC1OdoxXag1+1V3lMN3h6C4B/bcWB7Rjh +40m9yRJXdgyZ59/Is8ydIzAosE7SGTelPNy5VR+yrfiySPxbC6x3MR8cZwKBgQCq +PVTg1bIjXDZ7NvsDYI1XaP07BXmi30FnhXByLFPsOzNn51jbtNNq8zQhjtRP3ojY +VjolWw4EpykBiCbpUfRiDbtN1NC0TaJHR8S2a4v6ZiCl123R8mu/pKOOUtAQcOWU +dkvD/zkpNqtqA4axK7H06n9Bi7yDwC7J7/Xkp5KPkQKBgFDprXrXg4zvIsxbXYZ3 +2bCaxyhBXNKcGwtWbbLfJcOwHJPns/abGkYIJ0NbMZX1LwTDfQWmC+8YKKvIlbKG +S2uk5H4qzupR4XN6YJ7SCHlGv2z0vxVjV7aWc1TME2iZQoBuO1urxPZwHd/euruo +kluWh1KV5XnWjBSYjZpiXxWl +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qocsp/certs/ca1.crt b/tests/auto/network/ssl/qocsp/certs/ca1.crt new file mode 100644 index 0000000000..b5ae194fab --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/ca1.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID9DCCAtygAwIBAgIJAMQbE3657KDYMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD +VQQGEwJOTzENMAsGA1UECAwET3NsbzESMBAGA1UEBwwJT3NsbyBDaXR5MRMwEQYD +VQQKDApUaGUgUXQgQ0ExMQ0wCwYDVQQLDARRVENOMREwDwYDVQQDDAhjYTFxdC5p +bzElMCMGCSqGSIb3DQEJARYWdGltdXIucG9jaGVwdHNvdkBxdC5pbzAeFw0xODEx +MjIxMDIxMTNaFw0yODExMTkxMDIxMTNaMIGOMQswCQYDVQQGEwJOTzENMAsGA1UE +CAwET3NsbzESMBAGA1UEBwwJT3NsbyBDaXR5MRMwEQYDVQQKDApUaGUgUXQgQ0Ex +MQ0wCwYDVQQLDARRVENOMREwDwYDVQQDDAhjYTFxdC5pbzElMCMGCSqGSIb3DQEJ +ARYWdGltdXIucG9jaGVwdHNvdkBxdC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAOCs3AV7sDKHJUJcm7a0OqnShIvoB1qv6UcOmlBmUzGl5GzX90Jz +7jYJoOPjxjNyRxMOsOReB1ZcSuIAjkdAEfFMaVe6j7qKTJ5ycTVY/fVoxyxsSNuI +xOJ6RCEjLHcxONEbkN/xI8LMdVko3m4P10r5GxwrgyPvpa87Yq5+XJ1BPWJyKbD7 +Tqpn3dvZUj0/POsMUTT7Q7VXOfDlZj58XWAC6ECTqJauhGFMhiwgqOn2Qo1W0QjV +DkGqRTdgIAM6Rv2cSRxgnflwW5QZ8kWUV81h/yx4cck/D9TcVxjr3Pvy6aJ/U41u +d4XJQgwCj4LJi4msw1S0CvZWmz+2BKxcbRsCAwEAAaNTMFEwHQYDVR0OBBYEFHgX +JwJFO7E6pu4tkL08cIK9J0NEMB8GA1UdIwQYMBaAFHgXJwJFO7E6pu4tkL08cIK9 +J0NEMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADp1kqDRcyVG +BdMge+Il10IjbpzzSjAoZiqiw69V99LiHW9ePbxG4AmliE6Za60GE5PCXOLjJh/5 +efgnIbybbyIOIT9iK4TXWLw2XW+rMY51c0RAxp2h/sc+5CZ0F0I811F5VUHXg2qR +U7C2zbzqAimN8TBm6FRe7NFQfqLCrsuFJjSc3obrqKQcpvRwxMk6NpkdoemzqLmY +lrBrTaeVbZ4ix3srVPvXRm9TdiC+JuuFmvulMfe+/wwnhb+dwT3JUC+EIq/Uf5Wb +g8lvB4ntitL8NLQ2hFGqYuoFNIGs6tRN71ohk+/ONqe9wJhcI9QAruPOvsg+8J0H +uGooX7PUNHg= +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qocsp/certs/ca1.key b/tests/auto/network/ssl/qocsp/certs/ca1.key new file mode 100644 index 0000000000..4ee080f706 --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/ca1.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgrNwFe7AyhyVC +XJu2tDqp0oSL6Adar+lHDppQZlMxpeRs1/dCc+42CaDj48YzckcTDrDkXgdWXEri +AI5HQBHxTGlXuo+6ikyecnE1WP31aMcsbEjbiMTiekQhIyx3MTjRG5Df8SPCzHVZ +KN5uD9dK+RscK4Mj76WvO2KuflydQT1icimw+06qZ93b2VI9PzzrDFE0+0O1Vznw +5WY+fF1gAuhAk6iWroRhTIYsIKjp9kKNVtEI1Q5BqkU3YCADOkb9nEkcYJ35cFuU +GfJFlFfNYf8seHHJPw/U3FcY69z78umif1ONbneFyUIMAo+CyYuJrMNUtAr2Vps/ +tgSsXG0bAgMBAAECggEBAL1RCwjXw42gEUZM8KzQS0pD6IpXVrMU3ZWReXhb8Kg6 +KDOK+3+UXlpMXLUKfj1lgvxM+cNEdBxSIoszerARDc1s3KseufOui4dL2ZbhSQVc +Z9BH4lCSe4x3CCeAEvzQjhatirMY51BCpnMdm+fUE07KfwyKobNLQSpZ+Pod4f5i +oQbOiZYfRfU2quaWIsVb/a5IiUD0gG0KS9O5wX6VigVeFRpOPHT4YCQ1qds4HqQq +PKQtkLq0mo6beXCfXWrJ5Nc0QOIFlgSAHkeRR7zLK8MlaerwZ5YdeJIWuPM9l9H+ +34FVkHle1rPN6dJf7EPwWxn1PceFe3QYn1GHoiMmXfkCgYEA/U6iQypbLEKLmLbt +XTvhV1FVDQM42BX+ATNQ8Wro0ybdyzM+d4271uAUGTF1Zvxndv22p+JOmldWveAR +0iVK4mvrs25ACg27Bz3LiUaQB2OyYrj9M7TLgQ47gYEhwgnsSniFyrMcptNyIfW5 +GoB1N00EKiCvHyWo5LK6kRZt5QcCgYEA4xBOC/Otc9lTp24iSVA8Y7XJ+nlypFtc +pehf262jH11wEkWskmc9aP/kpxt9fUrDxf3YIOqITR4mMNn184P1WywHAQF7Adfd +3r5YBMVaanuaMsSuAZOJGyvuk2BE6328IKdE+3emndzXuQdDf0X2TUznwdKe9AzZ +qadCBLfUpk0CgYAgDKbzIJTQkMrg06RMu5rTVXMRZmr2zDGLLVb8dK5oqO4/G4i3 +z7MIiOmCFoPoN99PauKFc1jGpm5PL96RXC6RX14/IZ/wpbQYQnVSNR9cD/0uCIHg +3OsytP5KcHA5ANBoy78B2o+xe+dg7JozBDXQfWodem0t37Hy3bpFSTU2WQKBgETY +qcFn9hydNYcblpvCDz1wXjhq4H7DENlhFseF42LcMuHnbEbLtMwEYrDkXe1CYQ/E +QubgFcnELXI8dB2M0jT9qXX9m+1YJXanIgr4R8zngz6HcfcaY8TwUhsvYlZAvmzs +KrdQdR2CW4pHkIijjuWrPs3+7aEz0D9nblX94yU1AoGATVCfQOwmEMFHg33luMMt +0lTOHsar6g1O5vz0ZPZ1NjJF9Qe3+T7B4n4gq9pLwfi7Ohoa4CDmt0nKmy56dBha +5LM8mzw+PaH9a3pP93caS6k/X68TLOp7fwvnzP6HTjtis2sdYzVma6ghEF0zRdQr +6nWMI6Kx2kFaNdzKSHzxP5A= +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qocsp/certs/infbob.key b/tests/auto/network/ssl/qocsp/certs/infbob.key new file mode 100644 index 0000000000..7878339151 --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/infbob.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDkF2BuPlkQa3Ox +JxnbQ+gy1mAxaGGzfnmGocraxVSKSssX3zSkeIrWB1kW3diOtIZ1jovYftHGsqoB +F5k6fN9dr37mFIZnilF6Bq0seYjNUl6I0d7Cf3NJSf7TG5+P+dAyNLN8aXILctY8 +krlSe4ysb++9xgawt2DYL3I0LBd+W27hd2BlfcmB4g2X3zOasjZM8F5HSBxF5e7f +fVaUmCC8S4jdXUQEbUNFk6HufDwDhP1gMtoGKHusWOdI5O6cQAfUUmRLSfi/jWoe +KLPafbj7KIcA8+YojOvub2guNpO42h9fc83/gCkkBJhwXNdIQjRUnz6Lu05kDTG9 +X28gbX9TAgMBAAECggEBAN9xCxVUXJmaOb6ciFblIi3TFm6wS62zw0chbgB8eQH0 +nRoonYBVWeSrVBnzf7bkoCe/Wb3fFo+o7KOfQ4spUwOK7SxlhPkfZgu9SJ4d/Obu +vw8XUTqF8iEkrM6P6/L2DX9xYzcIcSFIARlbvtJPmBJAocHtoRYyvltpt13mp6kt +/LVYR4qFAWRpPR6rnjlXEjfrE9taHWgIJEjwMj+IcTjnGiS1rX1T/JNhjRxsRJwU +qxqhYmeenNymyUJxS2B806EcG3UAJu63dK61VXN1dtPhS3FqjeR//GRlmy14n7RW +ZQAuT9dPB/WzUZVzEcOgTwe/+XsPTSfz7gpaoffgMJECgYEA/43xZRi48Dfp3tdq +qwwLf6Ya9pB2zb3XE8MUQhxsrygzL5ngZhmr2m0LgGCf5fXa983G6wzA6sOdpvve +jFAlBZYbWaYnvog9QIFcTj0S6PahGTBaR7PSNzK0UzoHYexYVCkyzQl1O2hktazd +Cankh/6IlAFkKbUSDqAwc07jNCkCgYEA5H0tNXpcDN6JTgKNe8YHM0GjZB+qGEoL +7YZbFlANjO9pOPY6JMQ3+DbOoruIH97CIyVYokuH0qRAfjm5LNiVYECFVFZRnGFb +BNPOPAnPJPISDF66zjW0KLMYCykJAHQ4SpHUPcJ6JnfBr76s/xSbNI9qnhpy3QYI +ATkqOrP25xsCgYEAy3pjmJGEv5BloM942VSv2yWRFn2UeuELXWrYuIMVbqndh6tH +50PNeA+XNtK4vktx3Bl2pzTybnrvDkRBwQsXT0lj4Y/Q2X509uWJb6plYiTtxLah +S7I8UUMIHbR4qFmdQvXCw0sikvjeJ2HKZaVml3ntmZs5+5N3GzolGcrYUXECgYEA +pPsBnsCoIJ66s7pCIKIfZtI5QT1f20P0EuDVemn5Ls9bwcaAuzV3WGFymKwiISj+ +MtRviFhTTTROYRYa8Be+3A4ad4gQS4M8bmLlYhKPIJUtlQL9jZHXcR/H9578ofhJ +AQcFIkb/XjFQiC58yX4+hxgbGufsEk2dkAyPwm1ZlQsCgYBTjnraJbYSz1v3MQKx +fHm9eHki/ODR3lWiCYYnnW3AwRa7AXS4ZiSw78wzkUX2XTJbE6JlEUH4M9DMzr4y +QBwKmx+3u+Im4WcZ889jo6XrF0X9mXRmY25+gr2ypTbKZjT8FCYcXIgiOxITLXZh +Bmn7KZcsdaPxSFn05ASEanLNqA== +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qocsp/certs/infbobchain.crt b/tests/auto/network/ssl/qocsp/certs/infbobchain.crt new file mode 100644 index 0000000000..7ed13c2856 --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/infbobchain.crt @@ -0,0 +1,49 @@ +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjjELMAkGA1UEBhMCTk8x +DTALBgNVBAgMBE9zbG8xEjAQBgNVBAcMCU9zbG8gQ2l0eTETMBEGA1UECgwKVGhl +IFF0IENBMTENMAsGA1UECwwEUVRDTjERMA8GA1UEAwwIY2ExcXQuaW8xJTAjBgkq +hkiG9w0BCQEWFnRpbXVyLnBvY2hlcHRzb3ZAcXQuaW8wHhcNMTgxMTIyMTAyOTM3 +WhcNMjgxMTE5MTAyOTM3WjCBmDELMAkGA1UEBhMCTk8xDTALBgNVBAgMBE9zbG8x +EjAQBgNVBAcMCU9zbG8gQ2l0eTEkMCIGA1UECgwbVGhlIEluZmFtb3VzIFNuZWFr +eSBCb2IgTHRkMQwwCgYDVQQLDANCREExEzARBgNVBAMMCmluZmJvYi5jb20xHTAb +BgkqhkiG9w0BCQEWDmJvYkBpbmZib2IuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA5Bdgbj5ZEGtzsScZ20PoMtZgMWhhs355hqHK2sVUikrLF980 +pHiK1gdZFt3YjrSGdY6L2H7RxrKqAReZOnzfXa9+5hSGZ4pRegatLHmIzVJeiNHe +wn9zSUn+0xufj/nQMjSzfGlyC3LWPJK5UnuMrG/vvcYGsLdg2C9yNCwXfltu4Xdg +ZX3JgeINl98zmrI2TPBeR0gcReXu331WlJggvEuI3V1EBG1DRZOh7nw8A4T9YDLa +Bih7rFjnSOTunEAH1FJkS0n4v41qHiiz2n24+yiHAPPmKIzr7m9oLjaTuNofX3PN +/4ApJASYcFzXSEI0VJ8+i7tOZA0xvV9vIG1/UwIDAQABo3sweTAJBgNVHRMEAjAA +MCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd +BgNVHQ4EFgQUloqk6Iihkkcxp85jAzeUPGVmapkwHwYDVR0jBBgwFoAUeBcnAkU7 +sTqm7i2QvTxwgr0nQ0QwDQYJKoZIhvcNAQELBQADggEBAGCdYFNskTzMilRtmw+v +oJQM3mc6LdYYuADCuh8O/GKaqUnE7V2XnMBYWMN93eeN9VXmK2yAZaQU1J6ruP1S +pLMzJ8hbQej+sm+XAHVxAtr34KmEC50gIn1cB/sRKxHMombbNl7EK44puFU7q58P +zBz5lTXXTfA954D/ijEMMSDvIZ25me6vrGPMj1LX/wC6CWadSr9IxAO9HQVQQqwv +AbbqrCvMSMv633/f1EYU8Q6jhUCTlnin4pXtriOnqi+6MZICaYRCUgV224Rs3OUS +jmrbOeoaZUpmOVmuoYXWeexe229G2KGiEIgnSBEk5OLFHCeZ8++WJ5/SLHt8MBLc +O0w= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID9DCCAtygAwIBAgIJAMQbE3657KDYMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD +VQQGEwJOTzENMAsGA1UECAwET3NsbzESMBAGA1UEBwwJT3NsbyBDaXR5MRMwEQYD +VQQKDApUaGUgUXQgQ0ExMQ0wCwYDVQQLDARRVENOMREwDwYDVQQDDAhjYTFxdC5p +bzElMCMGCSqGSIb3DQEJARYWdGltdXIucG9jaGVwdHNvdkBxdC5pbzAeFw0xODEx +MjIxMDIxMTNaFw0yODExMTkxMDIxMTNaMIGOMQswCQYDVQQGEwJOTzENMAsGA1UE +CAwET3NsbzESMBAGA1UEBwwJT3NsbyBDaXR5MRMwEQYDVQQKDApUaGUgUXQgQ0Ex +MQ0wCwYDVQQLDARRVENOMREwDwYDVQQDDAhjYTFxdC5pbzElMCMGCSqGSIb3DQEJ +ARYWdGltdXIucG9jaGVwdHNvdkBxdC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAOCs3AV7sDKHJUJcm7a0OqnShIvoB1qv6UcOmlBmUzGl5GzX90Jz +7jYJoOPjxjNyRxMOsOReB1ZcSuIAjkdAEfFMaVe6j7qKTJ5ycTVY/fVoxyxsSNuI +xOJ6RCEjLHcxONEbkN/xI8LMdVko3m4P10r5GxwrgyPvpa87Yq5+XJ1BPWJyKbD7 +Tqpn3dvZUj0/POsMUTT7Q7VXOfDlZj58XWAC6ECTqJauhGFMhiwgqOn2Qo1W0QjV +DkGqRTdgIAM6Rv2cSRxgnflwW5QZ8kWUV81h/yx4cck/D9TcVxjr3Pvy6aJ/U41u +d4XJQgwCj4LJi4msw1S0CvZWmz+2BKxcbRsCAwEAAaNTMFEwHQYDVR0OBBYEFHgX +JwJFO7E6pu4tkL08cIK9J0NEMB8GA1UdIwQYMBaAFHgXJwJFO7E6pu4tkL08cIK9 +J0NEMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADp1kqDRcyVG +BdMge+Il10IjbpzzSjAoZiqiw69V99LiHW9ePbxG4AmliE6Za60GE5PCXOLjJh/5 +efgnIbybbyIOIT9iK4TXWLw2XW+rMY51c0RAxp2h/sc+5CZ0F0I811F5VUHXg2qR +U7C2zbzqAimN8TBm6FRe7NFQfqLCrsuFJjSc3obrqKQcpvRwxMk6NpkdoemzqLmY +lrBrTaeVbZ4ix3srVPvXRm9TdiC+JuuFmvulMfe+/wwnhb+dwT3JUC+EIq/Uf5Wb +g8lvB4ntitL8NLQ2hFGqYuoFNIGs6tRN71ohk+/ONqe9wJhcI9QAruPOvsg+8J0H +uGooX7PUNHg= +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qocsp/certs/ss1-private.key b/tests/auto/network/ssl/qocsp/certs/ss1-private.key new file mode 100644 index 0000000000..1c42daaf9f --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/ss1-private.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC4bXcfIjweShLx +6jBTKu/i5sXmlwTH9Z4PTzQ1VteKyEIDlnW5ocVWqRgBrvz3NlTFkDKkQXshkXyE +JyVZFbAPCfGsroZVISpFhUmJbPMBNn3SyGEU+sxWIpOZOKmG5tel6B4Bt5TWsRHL +mtU8Pv/APsz+i9JhgE25ksGhx16MqvdRv/xNGleF8qe+hDOeiNF3/lNv2hYb/MvD +1F73FBoDVnqty/VXXOJFb7elLE4ArXsTN/hip42Lbl1guYvnqnTZFhCHwMzRu4qc +3FTlemumfJpacpRnqVw2TURA5SdpTp9NYIxygEGNY201meNEjAEyg8GeFkAgu99R +LPQT+rTNAgMBAAECggEAPQEIfCXo2OQLrDWY0onLW7SWFZYyoKngJJRAYrxdA60G +GQW13zdhfS7ln/jv+B3ioI74EVkPj6T+GQCR3AvOdssFQ+dey93yi5hxIKIHJ4mM +ySI66qOi34MEa5RQjyzgfCJxeoPtGa7sgfqvOgRkuISNbk11w4abLx0aK5c08TY0 +JdeoWWhATaFZXl782Aw2FwGPTwOIf7GB09BJS3qUqlMT9fowLmWO10jOKkNtvcnT +2mAqT5cdZG1ffT5+f0JETPCbBPhhyE7VyYEVQfqTkRnEoz3hcZvjx91jD527+CSL +Qhg7zZu2oakyJQvpHETZ6cgrs7uDEiol7ARANezwyQKBgQDmapxV/qIOd5WFDVXw +lGt+dsELBBdMhvzr4A9eZdIZiXu48rdFG0XoECo5BKpXa1+ISr2od0U0YODrJrws +OHxHhlxGjJFs8kFteUPHyEZv6/rvkbA+xc0Uw04NnDRHBLK8VvX7MBWfvTqLN4bK +sZsMblscRBtEpFpN1fiJgnNASwKBgQDM56lBugtueBV9M4C/JF2is96d14ue3Y4i +SgMnHY18D3ru+KDuxPYoIs5Yos2vDWK2k8754WZ+WNXokjRoYPiFbeBPpI9NudJs +BUJz/sLJHjs3a4HrQs3hCuufczNxq9wQnALQHCMEqeBUTYCu/1+zYgwAu3Z/R8rJ +jKgexl+gRwKBgGrLCNCWpze7VzKGvsk1kSjZE5nueHoAqqMMgzMGUD2DyjMrU6QV +Au6O53Lr5aOE4Y9CzOqS9SFUsYprtpVsTLW94XDVX+W11ntN1At5mKPxJKn6xUwi +022HI9sNBfHQjKLcTz/vxmX2B3dU8gVqEenOEC5mppjG8A/ZV0ssigxHAoGAfGsG +OSSwoElGMxm8yVNZj9vMBufEnZhGH8f1FiE5seTsboKFpbXvCfvoc6WXYv2rvNUP +TmdxBrMGYAu2ytJm1Q4cr/9qDHYSsQiYizpcKCa1KjebUbDktgsde1pGGHWUUHmK +s7cCBGjqEAZnZtslzxRv2Vn639pF5hAEXXtywS0CgYAUIjhp43qgtbQdZMX7xbVR +lT26aq7NguCtt7njpgkhqc0HThb3I8ImrhNSDcS0/T9dPU70vt0ceruyRXmwX5hA +l28i5GzF5ufaRQdcsSR9u+P67nD5sTZBesbejXFySis5EC/97A4XZvkSfY4DQSZ+ +u8JJPZUlb2kGAHRpmxvpDA== +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qocsp/certs/ss1.crt b/tests/auto/network/ssl/qocsp/certs/ss1.crt new file mode 100644 index 0000000000..43ca8316c2 --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/ss1.crt @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEKzCCAxOgAwIBAgIJAOO/b5uLSmT8MA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD +VQQGEwJOTzENMAsGA1UECAwET3NsbzENMAsGA1UEBwwET3NsbzESMBAGA1UECgwJ +VGhlIFF0IENBMScwJQYDVQQLDB5SJkQgKGZha2UgY2VydGlmaWNhdGVzIGlzc3Vl +cikxGTAXBgNVBAMMEFRpbXVyIFBvY2hlcHRzb3YxJTAjBgkqhkiG9w0BCQEWFnRp +bXVyLnBvY2hlcHRzb3ZAcXQuaW8wIBcNMTgxMTE3MDUxNDA1WhgPMjExODEwMjQw +NTE0MDVaMIGqMQswCQYDVQQGEwJOTzENMAsGA1UECAwET3NsbzENMAsGA1UEBwwE +T3NsbzESMBAGA1UECgwJVGhlIFF0IENBMScwJQYDVQQLDB5SJkQgKGZha2UgY2Vy +dGlmaWNhdGVzIGlzc3VlcikxGTAXBgNVBAMMEFRpbXVyIFBvY2hlcHRzb3YxJTAj +BgkqhkiG9w0BCQEWFnRpbXVyLnBvY2hlcHRzb3ZAcXQuaW8wggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC4bXcfIjweShLx6jBTKu/i5sXmlwTH9Z4PTzQ1 +VteKyEIDlnW5ocVWqRgBrvz3NlTFkDKkQXshkXyEJyVZFbAPCfGsroZVISpFhUmJ +bPMBNn3SyGEU+sxWIpOZOKmG5tel6B4Bt5TWsRHLmtU8Pv/APsz+i9JhgE25ksGh +x16MqvdRv/xNGleF8qe+hDOeiNF3/lNv2hYb/MvD1F73FBoDVnqty/VXXOJFb7el +LE4ArXsTN/hip42Lbl1guYvnqnTZFhCHwMzRu4qc3FTlemumfJpacpRnqVw2TURA +5SdpTp9NYIxygEGNY201meNEjAEyg8GeFkAgu99RLPQT+rTNAgMBAAGjUDBOMB0G +A1UdDgQWBBSyHPlJr6BrpwMY7Sxg2R3CpQR7UzAfBgNVHSMEGDAWgBSyHPlJr6Br +pwMY7Sxg2R3CpQR7UzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBD +o86xp1WwvX6mYzF94ifZlkq1aDN6/njj2B9fvJCtygfqq6b9BrQJ0hNeqRh8OaIh +v2YmjbdUaoYguHmUxL+SeS67Sp8QBoSwdU5x0i8ygrigBrbb3myNqN6hGvpGy9E0 +B8PnVDt9DaOCunaMyGNPMLNPVGYULmberGtxV9wilcH4Q6WZrk9IhuyfqeBZtBYM +IcjV3OKdUv/ggu2IZSN7njKcgr+uyPt0Ymo9GozJSTdnN/E4hsRgzcgzCMf2fxzj +nGcsDRQ4L1R8p1zDlduxmmk42zGCGz3duFX7dijAxJWirS8Zsea4aooLgDQYT/zI +8hKd3KC3knLhPcxFKiUg +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qocsp/qocsp.pro b/tests/auto/network/ssl/qocsp/qocsp.pro new file mode 100644 index 0000000000..f4e846f39b --- /dev/null +++ b/tests/auto/network/ssl/qocsp/qocsp.pro @@ -0,0 +1,15 @@ +CONFIG += testcase + +SOURCES += tst_qocsp.cpp +QT = core network network-private testlib + +TARGET = tst_qocsp + +win32 { + CONFIG(debug, debug|release) { + DESTDIR = debug + } else { + DESTDIR = release + } +} + diff --git a/tests/auto/network/ssl/qocsp/tst_qocsp.cpp b/tests/auto/network/ssl/qocsp/tst_qocsp.cpp new file mode 100644 index 0000000000..9716c04bbb --- /dev/null +++ b/tests/auto/network/ssl/qocsp/tst_qocsp.cpp @@ -0,0 +1,823 @@ +/**************************************************************************** + ** + ** Copyright (C) 2018 The Qt Company Ltd. + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of the test suite of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ + ** Commercial License Usage + ** Licensees holding valid commercial Qt licenses may use this file in + ** accordance with the commercial license agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and The Qt Company. For licensing terms + ** and conditions see https://www.qt.io/terms-conditions. For further + ** information use the contact form at https://www.qt.io/contact-us. + ** + ** GNU General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU + ** General Public License version 3 as published by the Free Software + ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT + ** included in the packaging of this file. Please review the following + ** information to ensure the GNU General Public License requirements will + ** be met: https://www.gnu.org/licenses/gpl-3.0.html. + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QtNetwork/private/qtnetworkglobal_p.h> + +#include <QtNetwork/private/qsslsocket_openssl_symbols_p.h> +#include <QtNetwork/private/qsslsocket_openssl_p.h> + +#include <QtNetwork/qsslcertificate.h> +#include <QtNetwork/qtcpserver.h> +#include <QtNetwork/qsslerror.h> +#include <QtNetwork/qsslkey.h> +#include <QtNetwork/qssl.h> + +#include <QtCore/qsharedpointer.h> +#include <QtCore/qbytearray.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qstring.h> +#include <QtCore/qfile.h> +#include <QtCore/qlist.h> +#include <QtCore/qdir.h> + +#include <openssl/ocsp.h> + +#include <algorithm> +#include <utility> + +// NOTE: the word 'subject' in the code below means the subject of a status request, +// so in general it's our peer's certificate we are asking about. + +using SslError = QT_PREPEND_NAMESPACE(QSslError); +using VectorOfErrors = QT_PREPEND_NAMESPACE(QVector<SslError>); +using Latin1String = QT_PREPEND_NAMESPACE(QLatin1String); + +Q_DECLARE_METATYPE(SslError) +Q_DECLARE_METATYPE(VectorOfErrors) +Q_DECLARE_METATYPE(Latin1String) + +QT_BEGIN_NAMESPACE + +namespace { + +using OcspResponse = QSharedPointer<OCSP_RESPONSE>; +using BasicResponse = QSharedPointer<OCSP_BASICRESP>; +using SingleResponse = QSharedPointer<OCSP_SINGLERESP>; +using CertId = QSharedPointer<OCSP_CERTID>; +using EvpKey = QSharedPointer<EVP_PKEY>; +using Asn1Time = QSharedPointer<ASN1_TIME>; +using CertificateChain = QList<QSslCertificate>; + +using NativeX509Ptr = X509 *; + +class X509Stack { +public: + explicit X509Stack(const QList<QSslCertificate> &chain); + + ~X509Stack(); + + int size() const; + X509 *operator[](int index) const; + operator STACK_OF(X509) *() const; + +private: + OPENSSL_STACK *stack = nullptr; + + Q_DISABLE_COPY(X509Stack) +}; + +X509Stack::X509Stack(const QList<QSslCertificate> &chain) +{ + if (!chain.size()) + return; + + stack = q_OPENSSL_sk_new_null(); + if (!stack) + return; + + for (const QSslCertificate &cert : chain) { + X509 *nativeCert = NativeX509Ptr(cert.handle()); + if (!nativeCert) + continue; + q_OPENSSL_sk_push(stack, nativeCert); + q_X509_up_ref(nativeCert); + } +} + +X509Stack::~X509Stack() +{ + if (stack) + q_OPENSSL_sk_pop_free(stack, reinterpret_cast<void(*)(void*)>(q_X509_free)); +} + +int X509Stack::size() const +{ + if (stack) + return q_OPENSSL_sk_num(stack); + return 0; +} + +X509 *X509Stack::operator[](int index) const +{ + return NativeX509Ptr(q_OPENSSL_sk_value(stack, index)); +} + +X509Stack::operator STACK_OF(X509) *() const +{ + return reinterpret_cast<STACK_OF(X509)*>(stack); +} + +struct OcspTimeStamp +{ + OcspTimeStamp() = default; + OcspTimeStamp(long secondsBeforeNow, long secondsAfterNow); + + static Asn1Time timeToAsn1Time(long adjustment); + + Asn1Time thisUpdate; + Asn1Time nextUpdate; +}; + +OcspTimeStamp::OcspTimeStamp(long secondsBeforeNow, long secondsAfterNow) +{ + Asn1Time start = timeToAsn1Time(secondsBeforeNow); + Asn1Time end = timeToAsn1Time(secondsAfterNow); + if (start.data() && end.data()) { + thisUpdate.swap(start); + nextUpdate.swap(end); + } +} + +Asn1Time OcspTimeStamp::timeToAsn1Time(long adjustment) +{ + if (ASN1_TIME *adjusted = q_X509_gmtime_adj(nullptr, adjustment)) + return Asn1Time(adjusted, q_ASN1_TIME_free); + return Asn1Time{}; +} + +struct OcspResponder +{ + OcspResponder(const OcspTimeStamp &stamp, const CertificateChain &subjs, + const CertificateChain &respChain, const QSslKey &respPKey); + + QByteArray buildResponse(int responseStatus, int certificateStatus) const; + static EvpKey privateKeyToEVP_PKEY(const QSslKey &privateKey); + static CertId certificateToCertId(X509 *subject, X509 *issuer); + static QByteArray responseToDer(OCSP_RESPONSE *response); + + OcspTimeStamp timeStamp; + // Plural, we can send a 'wrong' BasicResponse containing more than + // 1 SingleResponse. + X509Stack subjects; + X509Stack responderChain; + QSslKey responderKey; +}; + +OcspResponder::OcspResponder(const OcspTimeStamp &stamp, const CertificateChain &subjs, + const CertificateChain &respChain, const QSslKey &respPKey) + : timeStamp(stamp), + subjects(subjs), + responderChain(respChain), + responderKey(respPKey) +{ +} + +QByteArray OcspResponder::buildResponse(int responseStatus, int certificateStatus) const +{ + if (responseStatus != OCSP_RESPONSE_STATUS_SUCCESSFUL) { + OCSP_RESPONSE *response = q_OCSP_response_create(responseStatus, nullptr); + if (!response) + return {}; + const OcspResponse rGuard(response, q_OCSP_RESPONSE_free); + return responseToDer(response); + } + + Q_ASSERT(subjects.size() && responderChain.size() && responderKey.handle()); + + const EvpKey nativeKey = privateKeyToEVP_PKEY(responderKey); + if (!nativeKey.data()) + return {}; + + OCSP_BASICRESP *basicResponse = q_OCSP_BASICRESP_new(); + if (!basicResponse) + return {}; + const BasicResponse brGuard(basicResponse, q_OCSP_BASICRESP_free); + + for (int i = 0, e = subjects.size(); i < e; ++i) { + X509 *subject = subjects[i]; + Q_ASSERT(subject); + CertId certId = certificateToCertId(subject, responderChain[0]); + if (!certId.data()) + return {}; + + // NOTE: we do not own this 'singleResponse': + ASN1_TIME *revisionTime = certificateStatus == V_OCSP_CERTSTATUS_REVOKED ? + timeStamp.thisUpdate.data() : nullptr; + + if (!q_OCSP_basic_add1_status(basicResponse, certId.data(), certificateStatus, 0, revisionTime, + timeStamp.thisUpdate.data(), timeStamp.nextUpdate.data())) { + return {}; + } + } + + if (q_OCSP_basic_sign(basicResponse, responderChain[0], nativeKey.data(), q_EVP_sha1(), + responderChain, 0) != 1) { + return {}; + } + + OCSP_RESPONSE *ocspResponse = q_OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, basicResponse); + if (!ocspResponse) + return {}; + const OcspResponse rGuard(ocspResponse, q_OCSP_RESPONSE_free); + return responseToDer(ocspResponse); +} + +EvpKey OcspResponder::privateKeyToEVP_PKEY(const QSslKey &privateKey) +{ + const EvpKey nullKey; + if (privateKey.isNull() || privateKey.algorithm() != QSsl::Rsa) { + // We use only RSA keys in this auto-test, since we test OCSP only, + // not handshake/TLS in general. + return nullKey; + } + + EVP_PKEY *nativeKey = q_EVP_PKEY_new(); + if (!nativeKey) + return nullKey; + + const EvpKey keyGuard(nativeKey, q_EVP_PKEY_free); + if (!q_EVP_PKEY_set1_RSA(nativeKey, reinterpret_cast<RSA *>(privateKey.handle()))) + return nullKey; + + return keyGuard; +} + +CertId OcspResponder::certificateToCertId(X509 *subject, X509 *issuer) +{ + const CertId nullId; + if (!subject || !issuer) + return nullId; + + const EVP_MD *digest = q_EVP_sha1(); + if (!digest) + return nullId; + + OCSP_CERTID *certId = q_OCSP_cert_to_id(digest, subject, issuer); + if (!certId) + return nullId; + + return CertId(certId, q_OCSP_CERTID_free); +} + +QByteArray OcspResponder::responseToDer(OCSP_RESPONSE *response) +{ + if (!response) + return {}; + + const int derSize = q_i2d_OCSP_RESPONSE(response, nullptr); + if (derSize <= 0) + return {}; + + QByteArray derData(derSize, Qt::Uninitialized); + unsigned char *pData = reinterpret_cast<unsigned char *>(derData.data()); + const int serializedSize = q_i2d_OCSP_RESPONSE(response, &pData); + if (serializedSize != derSize) + return {}; + + return derData; +} + +// The QTcpServer capable of sending OCSP status responses. +class OcspServer : public QTcpServer +{ + Q_OBJECT + +public: + OcspServer(const CertificateChain &serverChain, const QSslKey &privateKey); + + void configureResponse(const QByteArray &responseDer); + QString hostName() const; + QString peerVerifyName() const; + +Q_SIGNALS: + void internalServerError(); + +private: + void incomingConnection(qintptr descriptor) override; + +public: + QSslConfiguration serverConfig; + QSslSocket serverSocket; +}; + +OcspServer::OcspServer(const CertificateChain &serverChain, const QSslKey &privateKey) +{ + Q_ASSERT(serverChain.size()); + Q_ASSERT(!privateKey.isNull()); + + serverConfig = QSslConfiguration::defaultConfiguration(); + serverConfig.setLocalCertificateChain(serverChain); + serverConfig.setPrivateKey(privateKey); +} + +void OcspServer::configureResponse(const QByteArray &responseDer) +{ + serverConfig.setBackendConfigurationOption("Qt-OCSP-response", responseDer); +} + +QString OcspServer::hostName() const +{ + // It's 'name' and not 'address' to be consistent with QSslSocket's naming style, + // where it's connectToHostEncrypted(hostName, ...) + const QHostAddress &addr = serverAddress(); + if (addr == QHostAddress::Any || addr == QHostAddress::AnyIPv4) + return QStringLiteral("127.0.0.1"); + if (addr == QHostAddress::AnyIPv6) + return QStringLiteral("::1"); + return addr.toString(); +} + +QString OcspServer::peerVerifyName() const +{ + const CertificateChain &localChain = serverConfig.localCertificateChain(); + if (localChain.isEmpty()) + return {}; + const auto cert = localChain.first(); + if (cert.isNull()) + return {}; + + const QStringList &names = cert.subjectInfo(QSslCertificate::CommonName); + return names.isEmpty() ? QString{} : names.first(); +} + +void OcspServer::incomingConnection(qintptr socketDescriptor) +{ + close(); + + if (!serverSocket.setSocketDescriptor(socketDescriptor)) { + emit internalServerError(); + return; + } + + serverSocket.setSslConfiguration(serverConfig); + // Since we test a client, not a server, we don't care about any + // possible errors on the server (QAbstractSocket or QSslSocket-related). + // Thus, we don't connect to any error signal. + serverSocket.startServerEncryption(); +} + +} // unnamed namespace + +class tst_QOcsp : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + +private slots: + void connectSelfSigned(); + void badStatus_data(); + void badStatus(); + void multipleSingleResponses(); + void malformedResponse(); + void expiredResponse_data(); + void expiredResponse(); + void noNextUpdate(); + void wrongCertificateInResponse_data(); + void wrongCertificateInResponse(); + void untrustedResponder(); + + // OCSPTODO: more tests in future ... + +private: + void setupOcspClient(QSslSocket &clientSocket, const CertificateChain &trustedCAs, + const QString &peerName); + bool containsOcspErrors(const QList<QSslError> &errorsFound) const; + static bool containsError(const QList<QSslError> &errors, QSslError::SslError code); + static QByteArray goodResponse(const CertificateChain &subject, const CertificateChain &responder, + const QSslKey &privateKey, long beforeNow = -1000, long afterNow = 1000); + static bool loadPrivateKey(const QString &keyName, QSslKey &key); + static CertificateChain issuerToChain(const CertificateChain &chain); + static CertificateChain subjectToChain(const CertificateChain &chain); + + static QString certDirPath; + + void (QSslSocket::*socketErrorSignal)(QAbstractSocket::SocketError) = &QAbstractSocket::error; + void (QSslSocket::*tlsErrorsSignal)(const QList<QSslError> &) = &QSslSocket::sslErrors; + void (QTestEventLoop::*exitLoopSlot)() = &QTestEventLoop::exitLoop; + + const int handshakeTimeoutMS = 500; + QTestEventLoop loop; + + std::vector<QSslError::SslError> ocspErrorCodes = {QSslError::OcspNoResponseFound, + QSslError::OcspMalformedRequest, + QSslError::OcspMalformedResponse, + QSslError::OcspInternalError, + QSslError::OcspTryLater, + QSslError::OcspSigRequred, + QSslError::OcspUnauthorized, + QSslError::OcspResponseCannotBeTrusted, + QSslError::OcspResponseCertIdUnknown, + QSslError::OcspResponseExpired, + QSslError::OcspStatusUnknown}; +}; + +#define QCOMPARE_SINGLE_ERROR(sslSocket, expectedError) \ + const auto &tlsErrors = sslSocket.sslErrors(); \ + QCOMPARE(tlsErrors.size(), 1); \ + QCOMPARE(tlsErrors[0].error(), expectedError) + +#define QVERIFY_HANDSHAKE_WITHOUT_ERRORS(sslSocket) \ + QVERIFY(sslSocket.isEncrypted()); \ + QCOMPARE(sslSocket.state(), QAbstractSocket::ConnectedState); \ + QVERIFY(sslSocket.sslErrors().isEmpty()) + +#define QDECLARE_CHAIN(object, chainFileName) \ + CertificateChain object = QSslCertificate::fromPath(certDirPath + QLatin1String(chainFileName)); \ + QVERIFY(object.size()) + +#define QDECLARE_PRIVATE_KEY(key, keyFileName) \ + QSslKey key; \ + QVERIFY(loadPrivateKey(QLatin1String(keyFileName), key)) + +QString tst_QOcsp::certDirPath; + +void tst_QOcsp::initTestCase() +{ + QVERIFY(QSslSocket::supportsSsl()); + + certDirPath = QFileInfo(QFINDTESTDATA("certs")).absolutePath(); + QVERIFY(certDirPath.size() > 0); + certDirPath += QDir::separator() + QStringLiteral("certs") + QDir::separator(); +} + +void tst_QOcsp::connectSelfSigned() +{ + // This test may look a bit confusing, since we have essentially 1 + // self-signed certificate, which we trust for the purpose of this test, + // but we also request its (the certificate's) status and then we sign + // the status response using the same certificate and the corresponding + // private key. Anyway, we test the very basic things here: we send + // an OCSP status request, we verify the response (if server has sent it), + // and detect errors (if any). + QDECLARE_CHAIN(subjectChain, "ss1.crt"); + QDECLARE_CHAIN(responderChain, "ss1.crt"); + QDECLARE_PRIVATE_KEY(privateKey, "ss1-private.key"); + { + // This server ignores our status request: + const QSslError::SslError expectedError = QSslError::OcspNoResponseFound; + + OcspServer server(subjectChain, privateKey); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + QSslConfiguration clientConfig = QSslConfiguration::defaultConfiguration(); + auto roots = clientConfig.caCertificates(); + setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY(!clientSocket.isEncrypted()); + QCOMPARE_SINGLE_ERROR(clientSocket, expectedError); + } + { + // Now the server will send a valid 'status: good' response. + OcspServer server(subjectChain, privateKey); + const QByteArray response(goodResponse(subjectChain, responderChain, privateKey)); + QVERIFY(response.size()); + server.configureResponse(response); + QVERIFY(server.listen()); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY_HANDSHAKE_WITHOUT_ERRORS(clientSocket); + } +} + +void tst_QOcsp::badStatus_data() +{ + QTest::addColumn<int>("responseStatus"); + QTest::addColumn<int>("certificateStatus"); + QTest::addColumn<QSslError>("expectedError"); + + QTest::addRow("malformed-request") << OCSP_RESPONSE_STATUS_MALFORMEDREQUEST << 1 << QSslError(QSslError::OcspMalformedRequest); + QTest::addRow("internal-error") << OCSP_RESPONSE_STATUS_INTERNALERROR << 2 << QSslError(QSslError::OcspInternalError); + QTest::addRow("try-later") << OCSP_RESPONSE_STATUS_TRYLATER << 3 << QSslError(QSslError::OcspTryLater); + QTest::addRow("signed-request-require") << OCSP_RESPONSE_STATUS_SIGREQUIRED << 2 << QSslError(QSslError::OcspSigRequred); + QTest::addRow("unauthorized-request") << OCSP_RESPONSE_STATUS_UNAUTHORIZED << 1 <<QSslError(QSslError::OcspUnauthorized); + + QTest::addRow("certificate-revoked") << OCSP_RESPONSE_STATUS_SUCCESSFUL << V_OCSP_CERTSTATUS_REVOKED + << QSslError(QSslError::CertificateRevoked); + QTest::addRow("status-unknown") << OCSP_RESPONSE_STATUS_SUCCESSFUL << V_OCSP_CERTSTATUS_UNKNOWN + << QSslError(QSslError::OcspStatusUnknown); +} + +void tst_QOcsp::badStatus() +{ + // This test works with two types of 'bad' responses: + // 1. 'Error messages' (the response's status is anything but SUCCESSFUL, + // no information about the certificate itself, no signature); + // 2. 'REVOKED' or 'UNKNOWN' status for a certificate in question. + QFETCH(const int, responseStatus); + QFETCH(const int, certificateStatus); + QFETCH(const QSslError, expectedError); + + QDECLARE_CHAIN(subjectChain, "infbobchain.crt"); + QCOMPARE(subjectChain.size(), 2); + QDECLARE_CHAIN(responderChain, "ca1.crt"); + QDECLARE_PRIVATE_KEY(subjPrivateKey, "infbob.key"); + QDECLARE_PRIVATE_KEY(respPrivateKey, "ca1.key"); + + OcspServer server(subjectChain, subjPrivateKey); + const OcspTimeStamp stamp(-1000, 1000); + OcspResponder builder(stamp, subjectToChain(subjectChain), responderChain, respPrivateKey); + const QByteArray response(builder.buildResponse(responseStatus, certificateStatus)); + QVERIFY(response.size()); + server.configureResponse(response); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY(!clientSocket.isEncrypted()); + QCOMPARE_SINGLE_ERROR(clientSocket, expectedError.error()); +} + +void tst_QOcsp::multipleSingleResponses() +{ + // We handle a response with more than one SingleResponse as malformed: + const QSslError::SslError expectedError = QSslError::OcspMalformedResponse; + + // Here we use subjectChain only to generate a response, the server + // is configured with the responder chain (it's the same cert after all). + QDECLARE_CHAIN(subjectChain, "ss1.crt"); + QDECLARE_CHAIN(responderChain, "ss1.crt"); + QDECLARE_PRIVATE_KEY(privateKey, "ss1-private.key"); + + // Let's have more than 1 certificate in a chain: + subjectChain.append(subjectChain[0]); + + OcspServer server(responderChain, privateKey); + // Generate a BasicOCSPResponse containing 2 SingleResponses: + const QByteArray response(goodResponse(subjectChain, responderChain, privateKey)); + QVERIFY(response.size()); + server.configureResponse(response); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, issuerToChain(responderChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY(!clientSocket.isEncrypted()); + QCOMPARE_SINGLE_ERROR(clientSocket, expectedError); +} + +void tst_QOcsp::malformedResponse() +{ + QDECLARE_CHAIN(serverChain, "ss1.crt"); + QDECLARE_PRIVATE_KEY(privateKey, "ss1-private.key"); + + OcspServer server(serverChain, privateKey); + // Let's send some arbitrary bytes instead of DER and see what happens next: + server.configureResponse("Sure, you can trust me, this cert was not revoked (I don't say it was issued at all)!"); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, issuerToChain(serverChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY(!clientSocket.isEncrypted()); + QCOMPARE(clientSocket.error(), QAbstractSocket::SslHandshakeFailedError); +} + +void tst_QOcsp::expiredResponse_data() +{ + QTest::addColumn<long>("beforeNow"); + QTest::addColumn<long>("afterNow"); + + QTest::addRow("expired") << -2000L << -1000L; + QTest::addRow("not-valid-yet") << 5000L << 10000L; + QTest::addRow("next-before-this") << -1000L << -2000L; +} + +void tst_QOcsp::expiredResponse() +{ + // We report different kinds of problems with [thisUpdate, nextUpdate] + // as 'expired' (to keep it simple): + const QSslError::SslError expectedError = QSslError::OcspResponseExpired; + + QFETCH(const long, beforeNow); + QFETCH(const long, afterNow); + + QDECLARE_CHAIN(subjectChain, "ss1.crt"); + QDECLARE_CHAIN(responderChain, "ss1.crt"); + QDECLARE_PRIVATE_KEY(privateKey, "ss1-private.key"); + + OcspServer server(subjectChain, privateKey); + const QByteArray response(goodResponse(subjectChain, responderChain, privateKey, beforeNow, afterNow)); + QVERIFY(response.size()); + server.configureResponse(response); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY(!clientSocket.isEncrypted()); + QCOMPARE_SINGLE_ERROR(clientSocket, expectedError); +} + +void tst_QOcsp::noNextUpdate() +{ + // RFC2560, 2.4: + // "If nextUpdate is not set, the responder is indicating that newer + // revocation information is available all the time." + // + // This test is just to verify that we correctly handle such responses. + QDECLARE_CHAIN(subjectChain, "ss1.crt"); + QDECLARE_CHAIN(responderChain, "ss1.crt"); + QDECLARE_PRIVATE_KEY(privateKey, "ss1-private.key"); + + OcspServer server(subjectChain, privateKey); + OcspTimeStamp openRange(-1000, 0); + openRange.nextUpdate.clear(); + const OcspResponder responder(openRange, subjectChain, responderChain, privateKey); + const QByteArray response(responder.buildResponse(OCSP_RESPONSE_STATUS_SUCCESSFUL, + V_OCSP_CERTSTATUS_GOOD)); + QVERIFY(response.size()); + server.configureResponse(response); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY_HANDSHAKE_WITHOUT_ERRORS(clientSocket); +} + +void tst_QOcsp::wrongCertificateInResponse_data() +{ + QTest::addColumn<QLatin1String>("respChainName"); + QTest::addColumn<QLatin1String>("respKeyName"); + QTest::addColumn<QLatin1String>("wrongChainName"); + + QTest::addRow("same-CA-wrong-subject") << QLatin1String("ca1.crt") << QLatin1String("ca1.key") + << QLatin1String("alice.crt"); + QTest::addRow("wrong-CA-same-subject") << QLatin1String("ss1.crt") << QLatin1String("ss1-private.key") + << QLatin1String("alice.crt"); + QTest::addRow("wrong-CA-wrong-subject") << QLatin1String("ss1.crt") << QLatin1String("ss1-private.key") + << QLatin1String("ss1.crt"); +} + +void tst_QOcsp::wrongCertificateInResponse() +{ + QFETCH(const QLatin1String, respChainName); + QFETCH(const QLatin1String, respKeyName); + QFETCH(const QLatin1String, wrongChainName); + // In this test, the server will send a valid response (correctly signed + // by a trusted key/cert) but for a wrong certificate (not the one the + // server presented to the client in the server's 'Certificate' message). + const QSslError::SslError expectedError = QSslError::OcspResponseCertIdUnknown; + + QDECLARE_CHAIN(subjectChain, "infbobchain.crt"); + QDECLARE_PRIVATE_KEY(subjectKey, "infbob.key"); + QDECLARE_CHAIN(responderChain, respChainName); + QDECLARE_PRIVATE_KEY(responderKey, respKeyName); + + QDECLARE_CHAIN(wrongChain, wrongChainName); + + OcspServer server(subjectToChain(subjectChain), subjectKey); + const QByteArray wrongResponse(goodResponse(wrongChain, responderChain, responderKey)); + QVERIFY(wrongResponse.size()); + server.configureResponse(wrongResponse); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY(!clientSocket.isEncrypted()); + QVERIFY(containsError(clientSocket.sslErrors(), expectedError)); +} + +void tst_QOcsp::untrustedResponder() +{ + const QSslError::SslError expectedError = QSslError::OcspResponseCannotBeTrusted; + + QDECLARE_CHAIN(subjectChain, "infbobchain.crt"); + QDECLARE_PRIVATE_KEY(subjectKey, "infbob.key"); + QDECLARE_CHAIN(responderChain, "ca1.crt"); + QDECLARE_PRIVATE_KEY(responderKey, "ca1.key"); + + OcspServer server(subjectChain, subjectKey); + const QByteArray response(goodResponse(subjectToChain(subjectChain), responderChain, responderKey)); + QVERIFY(response.size()); + server.configureResponse(response); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, {}, server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY(!clientSocket.isEncrypted()); + QVERIFY(containsError(clientSocket.sslErrors(), expectedError)); +} + +void tst_QOcsp::setupOcspClient(QSslSocket &clientSocket, const CertificateChain &caCerts, const QString &name) +{ + QSslConfiguration clientConfig = QSslConfiguration::defaultConfiguration(); + clientConfig.setOcspStaplingEnabled(true); + + if (caCerts.size()) { + auto roots = clientConfig.caCertificates(); + roots.append(caCerts); + clientConfig.setCaCertificates(roots); + } + + clientSocket.setSslConfiguration(clientConfig); + clientSocket.setPeerVerifyName(name); + + connect(&clientSocket, socketErrorSignal, &loop, exitLoopSlot); + connect(&clientSocket, tlsErrorsSignal, &loop, exitLoopSlot); + connect(&clientSocket, &QSslSocket::encrypted, &loop, exitLoopSlot); +} + +bool tst_QOcsp::containsOcspErrors(const QList<QSslError> &errorsFound) const +{ + for (auto code : ocspErrorCodes) { + if (containsError(errorsFound, code)) + return true; + } + return false; +} + +bool tst_QOcsp::containsError(const QList<QSslError> &errors, QSslError::SslError code) +{ + const auto it = std::find_if(errors.begin(), errors.end(), + [&code](const QSslError &other){return other.error() == code;}); + return it != errors.end(); +} + +QByteArray tst_QOcsp::goodResponse(const CertificateChain &subject, const CertificateChain &responder, + const QSslKey &privateKey, long beforeNow, long afterNow) +{ + const OcspResponder builder(OcspTimeStamp(beforeNow, afterNow), subject, responder, privateKey); + return builder.buildResponse(OCSP_RESPONSE_STATUS_SUCCESSFUL, V_OCSP_CERTSTATUS_GOOD); +} + +bool tst_QOcsp::loadPrivateKey(const QString &keyFileName, QSslKey &key) +{ + QFile keyFile(certDirPath + keyFileName); + if (!keyFile.open(QIODevice::ReadOnly)) + return false; + key = QSslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); + return !key.isNull(); +} + +CertificateChain tst_QOcsp::issuerToChain(const CertificateChain &chain) +{ + // Here we presume that, if the chain isn't a single self-signed certificate, its second + // entry is the issuer. + const int length = chain.size(); + Q_ASSERT(length > 0); + return CertificateChain() << chain[length > 1 ? 1 : 0]; +} + +CertificateChain tst_QOcsp::subjectToChain(const CertificateChain &chain) +{ + Q_ASSERT(chain.size()); + return CertificateChain() << chain[0]; +} + +QT_END_NAMESPACE + +QTEST_MAIN(tst_QOcsp) + +#include "tst_qocsp.moc" diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.der b/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.der Binary files differnew file mode 100644 index 0000000000..687009e087 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.der diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.pem new file mode 100644 index 0000000000..233e0dfb37 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.pem @@ -0,0 +1,9 @@ +-----BEGIN PRIVATE KEY----- +MIIBIQIBADCBlQYJKoZIhvcNAQMBMIGHAoGBAIlk2YX0TJzfQ18ZzZroQoE5Nyjt +bWxWRxBriG/c+JWhBwttVDb6lzLN+GVJxXVPfc6JJmDORVRxdxAlMqu++2Vqpsnl +/H8xIXsxjuTcTjq8sXagGRa0LfeggkUD64tEhO4iZ8Q2TIdb3OHkAF0Sn+06b/0e +iIz323Kywq0CsspTAgECBIGDAoGAQCo39UHP4s2ZVH4nOmWgNlb4JsHPX4EzqDBr +ig46hvMLAFrILYnsCbqqD/+GNAUl1PV/nfEQoAk/HvtACqLFLG5/3jK2w6dVHGEo +JnVOGz9vZpWUx+SCslHJRFaeE+6AAbbvrTr0lci29Ta4IesHlamRsj+ZaUrVX6k/ +/9OTGAo= +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.der b/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.der Binary files differnew file mode 100644 index 0000000000..e193f25f07 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.der diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.pem new file mode 100644 index 0000000000..32299b2b6c --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.pem @@ -0,0 +1,14 @@ +-----BEGIN PRIVATE KEY----- +MIICJgIBADCCARcGCSqGSIb3DQEDATCCAQgCggEBAJsiReJxBjkC7Hy99AJATusq +YsNQHhjoeTLPeHhsBuLtJK18Krk736V09efX6qeAEmvgMQbvbHqtrOaY3q6dut6C +UTGVW+oVg3d/Y8qakkanvEnIlliaTIyWIz0JMjO2prC6AuU/QEzZcQVUS6bxyn3D +iYFxCE6+7cJJpEH9HVbcrl+J6Ch6ax5rQGUyxpSMkmItLJx92upRxOnaxJMHR+ZF +OSdDPfrkINpEzahnhteLszddyLasnE0or6ZnXYLvKsT1Uu6QwDc4EO1FJHScoeep +zsK/VRcXzMpj/1Rl+F9E/AikCqHRrnvISt25wrK0Mwy854P2T7dJlBNewc6vE6MC +AQIEggEEAoIBAGIctO30MoZ9DiuKbOBpqM9rl2bNH/I46GGcfEiSsO/zOw2V9WFC +MxkjF0I1ilDfPY+Ag3bLB2n89DPcfXliYH9MFolehPTc1fWplhX3+ImdC6y95uXO +FV5xtcEQCbPktnUtkUdcAT5831p9lu1QJo+DzMPrQa7axMLj8heBAi4VqAi+8Q31 +dpGKuhCUlgs+pLENx1o0QY2kui6Z5uR0YhmA547lwBWA4XEv5OV9ExmxytiatvOv +PZKT1ID76LrL9bnnZvOEGczWLQvJ9VaaZSpoP+2QisRANWW4w57d+PIR1WR/FTSH +F6xocElUoTzuiSPzRz60aw/KkisImBBKERQ= +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.der b/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.der Binary files differnew file mode 100644 index 0000000000..42ddbaaae2 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.der diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem new file mode 100644 index 0000000000..d2c3170b16 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGcAgEAMFMGCSqGSIb3DQEDATBGAkEAvXx0QxJvIGA2ig8Je55R2rmeO4Ta2Esj +ANLuyVIFRbtuLFsdhU+amUc8bs9RUQmkUNzS92jkpAfqtCv+mQ06EwIBAgRCAkBJ +rDM0BTevOPIHpJzMtSQhw3e7Dr38HUfTn8zF3uYi1RCxjkTUukmzRLPTf0aqPgpd +8dSldjG/11aZORl8/mXO +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.der b/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.der Binary files differnew file mode 100644 index 0000000000..2805a67633 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.der diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.pem new file mode 100644 index 0000000000..da4e327ac9 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBHzCBlQYJKoZIhvcNAQMBMIGHAoGBAIlk2YX0TJzfQ18ZzZroQoE5NyjtbWxW +RxBriG/c+JWhBwttVDb6lzLN+GVJxXVPfc6JJmDORVRxdxAlMqu++2Vqpsnl/H8x +IXsxjuTcTjq8sXagGRa0LfeggkUD64tEhO4iZ8Q2TIdb3OHkAF0Sn+06b/0eiIz3 +23Kywq0CsspTAgECA4GEAAKBgA8pxU1sMDvRWKpvJKNs3jNhZPQWFf4Tszu/cMcb +1qAQ/q0DRb41VvsUoMaCfef/plZleV4MG26owb574AJeC86wX5MbRDTPS4CzAn+I +an92AZl3vlYRQ2sSo3ktkyhw6LV1iewi08Ky7J4rqvG0Oo335QGEZlK1OgwBsyh0 +FKLe +-----END PUBLIC KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.der b/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.der Binary files differnew file mode 100644 index 0000000000..9e749d8a41 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.der diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.pem new file mode 100644 index 0000000000..f751157c87 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.pem @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICJDCCARcGCSqGSIb3DQEDATCCAQgCggEBAJsiReJxBjkC7Hy99AJATusqYsNQ +HhjoeTLPeHhsBuLtJK18Krk736V09efX6qeAEmvgMQbvbHqtrOaY3q6dut6CUTGV +W+oVg3d/Y8qakkanvEnIlliaTIyWIz0JMjO2prC6AuU/QEzZcQVUS6bxyn3DiYFx +CE6+7cJJpEH9HVbcrl+J6Ch6ax5rQGUyxpSMkmItLJx92upRxOnaxJMHR+ZFOSdD +PfrkINpEzahnhteLszddyLasnE0or6ZnXYLvKsT1Uu6QwDc4EO1FJHScoeepzsK/ +VRcXzMpj/1Rl+F9E/AikCqHRrnvISt25wrK0Mwy854P2T7dJlBNewc6vE6MCAQID +ggEFAAKCAQAUeWRuqjl7F84USogxJOM1M4y8yKtBYY2KLs5iIVhzV4UZ+9+cMNZA +otLXJ/e8BH0diR0yk7tjxD6hjjqd+nyafIkJGPElDMnTbRPHg5zZYMmI5L/efdSm +OPbM7QsodrYH5aoF4c7hjMb/cttYVG2Yupsy4tfORuDbwL70upqOo6rkVq55eOGS +6pseEume/SD+7e3xIPJTkrMMzBFHG6H7bVHikT4O7yWV1iVzElj919yi+4Zy6TK8 +0hG6l31D5bsJpOduhHYZtN1yQpw+sGT6Yiepkjgt+1YkGFiiRs5vDl4DHeYHyAhL +oH9uKcm3q4lhaOeT5ml765g87qQD6+vr +-----END PUBLIC KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.der b/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.der Binary files differnew file mode 100644 index 0000000000..8a75babb6d --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.der diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.pem new file mode 100644 index 0000000000..1f4e5c9a47 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGaMFMGCSqGSIb3DQEDATBGAkEAvXx0QxJvIGA2ig8Je55R2rmeO4Ta2EsjANLu +yVIFRbtuLFsdhU+amUc8bs9RUQmkUNzS92jkpAfqtCv+mQ06EwIBAgNDAAJARGBh +9FmRRZZAxBtXZmS8wIgDwWvjB63GQ+E1pDLtZPztvPQ2eqUjTgSuGKV5cDankAV1 +Pkj/IA0Xl+SuFhLLew== +-----END PUBLIC KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/genkeys.sh b/tests/auto/network/ssl/qsslkey/keys/genkeys.sh index 6210b42ab4..0106953bff 100755 --- a/tests/auto/network/ssl/qsslkey/keys/genkeys.sh +++ b/tests/auto/network/ssl/qsslkey/keys/genkeys.sh @@ -88,6 +88,27 @@ do openssl ec -in ec-pri-$size-$curve.pem -pubout -out ec-pub-$size-$curve.der -outform DER done +#--- DH ---------------------------------------------------------------------------- +for size in 512 1024 2048 +do + echo -e "\ngenerating DH parameters to PEM file ..." + openssl dhparam -out dhpar-$size.pem $size + + echo -e "\ngenerating DH private key to PEM file ..." + openssl genpkey -paramfile dhpar-$size.pem -out dh-pri-$size.pem + + /bin/rm dhpar-$size.pem + + echo -e "\ngenerating DH private key to DER file ..." + openssl pkey -in dh-pri-$size.pem -out dh-pri-$size.der -outform DER + + echo -e "\ngenerating DH public key to PEM file ..." + openssl pkey -in dh-pri-$size.pem -pubout -out dh-pub-$size.pem + + echo -e "\ngenerating DH public key to DER file ..." + openssl pkey -in dh-pri-$size.pem -pubout -out dh-pub-$size.der -outform DER +done + #--- PKCS#8 ------------------------------------------------------------------------ # Note: We'll just grab some of the keys generated earlier and convert those # https://www.openssl.org/docs/manmaster/man1/pkcs8.html#PKCS-5-v1.5-and-PKCS-12-algorithms diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp index ddfe52c5e4..70001f7375 100644 --- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp @@ -63,7 +63,7 @@ class tst_QSslKey : public QObject QList<KeyInfo> keyInfoList; - void createPlainTestRows(bool filter = false, QSsl::EncodingFormat format = QSsl::EncodingFormat::Pem); + void createPlainTestRows(bool pemOnly = false); public slots: void initTestCase(); @@ -111,13 +111,14 @@ void tst_QSslKey::initTestCase() QDir dir(testDataDir + "keys"); const QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable); - QRegExp rx(QLatin1String("^(rsa|dsa|ec)-(pub|pri)-(\\d+)-?[\\w-]*\\.(pem|der)$")); + QRegExp rx(QLatin1String("^(rsa|dsa|dh|ec)-(pub|pri)-(\\d+)-?[\\w-]*\\.(pem|der)$")); for (const QFileInfo &fileInfo : fileInfoList) { if (rx.indexIn(fileInfo.fileName()) >= 0) { keyInfoList << KeyInfo( fileInfo, rx.cap(1) == QLatin1String("rsa") ? QSsl::Rsa : - (rx.cap(1) == QLatin1String("dsa") ? QSsl::Dsa : QSsl::Ec), + rx.cap(1) == QLatin1String("dsa") ? QSsl::Dsa : + rx.cap(1) == QLatin1String("dh") ? QSsl::Dh : QSsl::Ec, rx.cap(2) == QLatin1String("pub") ? QSsl::PublicKey : QSsl::PrivateKey, rx.cap(3).toInt(), rx.cap(4) == QLatin1String("pem") ? QSsl::Pem : QSsl::Der); @@ -154,7 +155,7 @@ Q_DECLARE_METATYPE(QSsl::KeyAlgorithm) Q_DECLARE_METATYPE(QSsl::KeyType) Q_DECLARE_METATYPE(QSsl::EncodingFormat) -void tst_QSslKey::createPlainTestRows(bool filter, QSsl::EncodingFormat format) +void tst_QSslKey::createPlainTestRows(bool pemOnly) { QTest::addColumn<QString>("absFilePath"); QTest::addColumn<QSsl::KeyAlgorithm>("algorithm"); @@ -162,7 +163,7 @@ void tst_QSslKey::createPlainTestRows(bool filter, QSsl::EncodingFormat format) QTest::addColumn<int>("length"); QTest::addColumn<QSsl::EncodingFormat>("format"); foreach (KeyInfo keyInfo, keyInfoList) { - if (filter && keyInfo.format != format) + if (pemOnly && keyInfo.format != QSsl::EncodingFormat::Pem) continue; #ifdef Q_OS_WINRT if (keyInfo.fileInfo.fileName().contains("RC2-64")) diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index bca142e245..0523f2591f 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -245,6 +245,9 @@ private slots: void signatureAlgorithm(); #endif + void deprecatedProtocols_data(); + void deprecatedProtocols(); + void setEmptyDefaultConfiguration(); // this test should be last protected slots: @@ -952,24 +955,6 @@ void tst_QSslSocket::protocol() QCOMPARE(socket->protocol(), QSsl::SecureProtocols); QFETCH_GLOBAL(bool, setProxy); { - // qt-test-server allows SSLv3. - socket->setProtocol(QSsl::SslV3); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->abort(); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->connectToHost(QtNetworkSettings::serverName(), 443); - QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString())); - socket->startClientEncryption(); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->abort(); - } - { // qt-test-server allows TLSV1. socket->setProtocol(QSsl::TlsV1_0); QCOMPARE(socket->protocol(), QSsl::TlsV1_0); @@ -1045,26 +1030,6 @@ void tst_QSslSocket::protocol() socket->abort(); } #endif // TLS1_3_VERSION -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - { - // qt-test-server allows SSLV2. - socket->setProtocol(QSsl::SslV2); - QCOMPARE(socket->protocol(), QSsl::SslV2); - socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - QCOMPARE(socket->protocol(), QSsl::SslV2); - socket->abort(); - QCOMPARE(socket->protocol(), QSsl::SslV2); - socket->connectToHost(QtNetworkSettings::serverName(), 443); - if (setProxy && !socket->waitForConnected()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - socket->startClientEncryption(); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - socket->abort(); - } -#endif { // qt-test-server allows SSLV3, so it allows AnyProtocol. socket->setProtocol(QSsl::AnyProtocol); @@ -1084,7 +1049,7 @@ void tst_QSslSocket::protocol() socket->abort(); } { - // qt-test-server allows SSLV3, so it allows NoSslV2 + // qt-test-server allows TlsV1, so it allows TlsV1SslV3 socket->setProtocol(QSsl::TlsV1SslV3); QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); @@ -1207,120 +1172,38 @@ void tst_QSslSocket::protocolServerSide_data() QTest::addColumn<QSsl::SslProtocol>("clientProtocol"); QTest::addColumn<bool>("works"); -#if QT_CONFIG(opensslv11) -#if !defined(OPENSSL_NO_SSL2) - // OpenSSL 1.1 has removed SSL2 support. But there is no OPENSSL_NO_SSL2 macro ... -#define OPENSSL_NO_SSL2 -#endif // OPENSSL_NO_SSL2 -#endif // opensslv11 - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("ssl2-ssl2") << QSsl::SslV2 << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2 -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-ssl3") << QSsl::SslV3 << QSsl::SslV3 << true; -#endif QTest::newRow("tls1.0-tls1.0") << QSsl::TlsV1_0 << QSsl::TlsV1_0 << true; QTest::newRow("tls1ssl3-tls1ssl3") << QSsl::TlsV1SslV3 << QSsl::TlsV1SslV3 << true; QTest::newRow("any-any") << QSsl::AnyProtocol << QSsl::AnyProtocol << true; QTest::newRow("secure-secure") << QSsl::SecureProtocols << QSsl::SecureProtocols << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("ssl2-ssl3") << QSsl::SslV2 << QSsl::SslV3 << false; - QTest::newRow("ssl2-tls1.0") << QSsl::SslV2 << QSsl::TlsV1_0 << false; - QTest::newRow("ssl2-tls1ssl3") << QSsl::SslV2 << QSsl::TlsV1SslV3 << false; - QTest::newRow("ssl2-secure") << QSsl::SslV2 << QSsl::SecureProtocols << false; - QTest::newRow("ssl2-any") << QSsl::SslV2 << QSsl::AnyProtocol << false; // no idea why it does not work, but we don't care about SSL 2 -#endif - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) && !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-ssl2") << QSsl::SslV3 << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-tls1.0") << QSsl::SslV3 << QSsl::TlsV1_0 << false; - QTest::newRow("ssl3-tls1ssl3") << QSsl::SslV3 << QSsl::TlsV1SslV3 << true; - QTest::newRow("ssl3-secure") << QSsl::SslV3 << QSsl::SecureProtocols << false; -#endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) && !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << false; // we won't set a SNI header here because we connect to a - // numerical IP, so OpenSSL will send a SSL 2 handshake -#elif !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << true; -#endif - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.0-ssl2") << QSsl::TlsV1_0 << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.0-ssl3") << QSsl::TlsV1_0 << QSsl::SslV3 << false; -#endif QTest::newRow("tls1-tls1ssl3") << QSsl::TlsV1_0 << QSsl::TlsV1SslV3 << true; QTest::newRow("tls1.0-secure") << QSsl::TlsV1_0 << QSsl::SecureProtocols << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.0-any") << QSsl::TlsV1_0 << QSsl::AnyProtocol << false; // we won't set a SNI header here because we connect to a - // numerical IP, so OpenSSL will send a SSL 2 handshake -#else QTest::newRow("tls1.0-any") << QSsl::TlsV1_0 << QSsl::AnyProtocol << true; -#endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1ssl3-ssl2") << QSsl::TlsV1SslV3 << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1ssl3-ssl3") << QSsl::TlsV1SslV3 << QSsl::SslV3 << true; -#endif QTest::newRow("tls1ssl3-tls1.0") << QSsl::TlsV1SslV3 << QSsl::TlsV1_0 << true; QTest::newRow("tls1ssl3-secure") << QSsl::TlsV1SslV3 << QSsl::SecureProtocols << true; QTest::newRow("tls1ssl3-any") << QSsl::TlsV1SslV3 << QSsl::AnyProtocol << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("secure-ssl2") << QSsl::SecureProtocols << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("secure-ssl3") << QSsl::SecureProtocols << QSsl::SslV3 << false; -#endif QTest::newRow("secure-tls1.0") << QSsl::SecureProtocols << QSsl::TlsV1_0 << true; QTest::newRow("secure-tls1ssl3") << QSsl::SecureProtocols << QSsl::TlsV1SslV3 << true; QTest::newRow("secure-any") << QSsl::SecureProtocols << QSsl::AnyProtocol << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("any-ssl2") << QSsl::AnyProtocol << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2 -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("any-ssl3") << QSsl::AnyProtocol << QSsl::SslV3 << true; -#endif - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.0orlater-ssl2") << QSsl::TlsV1_0OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.0orlater-ssl3") << QSsl::TlsV1_0OrLater << QSsl::SslV3 << false; -#endif QTest::newRow("tls1.0orlater-tls1.0") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_0 << true; QTest::newRow("tls1.0orlater-tls1.1") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_1 << true; QTest::newRow("tls1.0orlater-tls1.2") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_2 << true; #ifdef TLS1_3_VERSION QTest::newRow("tls1.0orlater-tls1.3") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_3 << true; #endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.1orlater-ssl2") << QSsl::TlsV1_1OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.1orlater-ssl3") << QSsl::TlsV1_1OrLater << QSsl::SslV3 << false; -#endif QTest::newRow("tls1.1orlater-tls1.0") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_0 << false; QTest::newRow("tls1.1orlater-tls1.1") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_1 << true; QTest::newRow("tls1.1orlater-tls1.2") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_2 << true; + #ifdef TLS1_3_VERSION QTest::newRow("tls1.1orlater-tls1.3") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_3 << true; #endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.2orlater-ssl2") << QSsl::TlsV1_2OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.2orlater-ssl3") << QSsl::TlsV1_2OrLater << QSsl::SslV3 << false; -#endif + QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_0 << false; QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_1 << false; QTest::newRow("tls1.2orlater-tls1.2") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_2 << true; @@ -1328,12 +1211,6 @@ void tst_QSslSocket::protocolServerSide_data() QTest::newRow("tls1.2orlater-tls1.3") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_3 << true; #endif #ifdef TLS1_3_VERSION -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.3orlater-ssl2") << QSsl::TlsV1_3OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.3orlater-ssl3") << QSsl::TlsV1_3OrLater << QSsl::SslV3 << false; -#endif QTest::newRow("tls1.3orlater-tls1.0") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_0 << false; QTest::newRow("tls1.3orlater-tls1.1") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_1 << false; QTest::newRow("tls1.3orlater-tls1.2") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_2 << false; @@ -1389,10 +1266,10 @@ void tst_QSslSocket::protocolServerSide() if (server.socket) QVERIFY(server.socket->error() == QAbstractSocket::UnknownSocketError); - QCOMPARE(int(client.state()), int(expectedState)); + QCOMPARE(client.state(), expectedState); } else if (server.socket->error() != QAbstractSocket::UnknownSocketError) { QVERIFY(client.error() == QAbstractSocket::UnknownSocketError); - QCOMPARE(int(server.socket->state()), int(expectedState)); + QCOMPARE(server.socket->state(), expectedState); } QCOMPARE(client.isEncrypted(), works); @@ -3316,10 +3193,10 @@ void tst_QSslSocket::verifyClientCertificate_data() validCerts += QSslCertificate::fromPath(testDataDir + "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; + QTest::newRow("ValidChainedClientCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << validCerts << validKey << true; + QTest::newRow("ValidChainedClientCert:QueryPeer") << QSslSocket::QueryPeer << validCerts << validKey << true; + QTest::newRow("ValidChainedClientCert:VerifyNone") << QSslSocket::VerifyNone << validCerts << validKey << true; + QTest::newRow("ValidChainedClientCert:VerifyPeer") << QSslSocket::VerifyPeer << validCerts << validKey << true; } void tst_QSslSocket::verifyClientCertificate() @@ -3375,7 +3252,7 @@ void tst_QSslSocket::verifyClientCertificate() // check server socket QVERIFY(server.socket); - QCOMPARE(int(server.socket->state()), int(expectedState)); + QCOMPARE(server.socket->state(), expectedState); QCOMPARE(server.socket->isEncrypted(), works); if (peerVerifyMode == QSslSocket::VerifyNone || clientCerts.isEmpty()) { @@ -3387,7 +3264,7 @@ void tst_QSslSocket::verifyClientCertificate() } // check client socket - QCOMPARE(int(client.state()), int(expectedState)); + QCOMPARE(client.state(), expectedState); QCOMPARE(client.isEncrypted(), works); } @@ -4174,6 +4051,63 @@ void tst_QSslSocket::forwardReadChannelFinished() #endif // QT_NO_OPENSSL +void tst_QSslSocket::deprecatedProtocols_data() +{ + QTest::addColumn<QSsl::SslProtocol>("protocol"); + QTest::addColumn<bool>("succeeds"); + QTest::newRow("SecureProtocols") << QSsl::SecureProtocols << true; + QTest::newRow("SslV2") << QSsl::SslV2 << false; + QTest::newRow("SslV3") << QSsl::SslV3 << false; +} + +void tst_QSslSocket::deprecatedProtocols() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + QSKIP("This test does not work under a proxy"); + + QFETCH(QSsl::SslProtocol, protocol); + QFETCH(bool, succeeds); + + QSslSocket socket; + socket.setProtocol(protocol); + + QSignalSpy connectedSpy(&socket, &QSslSocket::connected); + QVERIFY(connectedSpy.isValid()); + + QSignalSpy encryptedSpy(&socket, &QSslSocket::encrypted); + QVERIFY(encryptedSpy.isValid()); + + QSignalSpy errorSpy(&socket, QOverload<QAbstractSocket::SocketError>::of(&QSslSocket::error)); + QVERIFY(errorSpy.isValid()); + + connect(&socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), + &socket, QOverload<>::of(&QSslSocket::ignoreSslErrors)); + + SslServer server; + QVERIFY(server.listen()); + + socket.connectToHost(server.serverAddress(), server.serverPort()); + + // Can't use waitForConnected / waitForEncrypted as they wait forever, + // so do this asynchronously via QTRY_ macros (QTBUG-72179) + QTRY_COMPARE(connectedSpy.size(), 1); + QCOMPARE(encryptedSpy.size(), 0); + QCOMPARE(errorSpy.size(), 0); + + socket.startClientEncryption(); + + if (succeeds) { + QTRY_COMPARE(encryptedSpy.size(), 1); + QCOMPARE(errorSpy.size(), 0); + } else { + // The various backends differ in the errors fired here (QTBUG-72196), + // so just check that we did get an error (and we're not encrypted) + QTRY_VERIFY(errorSpy.size() > 0); + QCOMPARE(encryptedSpy.size(), 0); + } +} + #endif // QT_NO_SSL QTEST_MAIN(tst_QSslSocket) diff --git a/tests/auto/network/ssl/ssl.pro b/tests/auto/network/ssl/ssl.pro index e89443ef4e..169e9bce83 100644 --- a/tests/auto/network/ssl/ssl.pro +++ b/tests/auto/network/ssl/ssl.pro @@ -21,6 +21,8 @@ qtConfig(ssl) { qdtlscookie \ qdtls } + + qtConfig(ocsp): SUBDIRS += qocsp } } |