From 064490a1ba183e3e669af720c12693e20eff4f57 Mon Sep 17 00:00:00 2001 From: Giovanni Minotti Date: Tue, 27 Apr 2021 14:54:16 +0200 Subject: [PATCH 1/5] HTTPS tests from #1435 --- test/helpers/create-https-test-server.ts | 17 +++++++- test/https.ts | 55 +++++++++++++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/test/helpers/create-https-test-server.ts b/test/helpers/create-https-test-server.ts index 9461e3759..cc3d363c1 100644 --- a/test/helpers/create-https-test-server.ts +++ b/test/helpers/create-https-test-server.ts @@ -3,10 +3,19 @@ import net from 'net'; import express from 'express'; import pify from 'pify'; import pem from 'pem'; +import type {SecureContextOptions} from 'tls'; export type HttpsServerOptions = { commonName?: string; days?: number; + ciphers?: SecureContextOptions['ciphers']; + honorCipherOrder?: SecureContextOptions['honorCipherOrder']; + minVersion?: SecureContextOptions['minVersion']; + maxVersion?: SecureContextOptions['maxVersion']; + signatureAlgorithms?: SecureContextOptions['sigalgs']; + tlsSessionLifetime?: SecureContextOptions['sessionTimeout']; + dhparam?: SecureContextOptions['dhparam']; + ecdhCurve?: SecureContextOptions['ecdhCurve']; }; export interface ExtendedHttpsTestServer extends express.Express { @@ -49,7 +58,13 @@ const createHttpsTestServer = async (options: HttpsServerOptions = {}): Promise< cert: serverCert, ca: caCert, requestCert: true, - rejectUnauthorized: false // This should be checked by the test + rejectUnauthorized: false, // This should be checked by the test + ciphers: options.ciphers, + honorCipherOrder: options.honorCipherOrder, + minVersion: options.minVersion, + maxVersion: options.maxVersion, + dhparam: options.dhparam, + ecdhCurve: options.ecdhCurve }, server ); diff --git a/test/https.ts b/test/https.ts index 5a49437dd..86d78b633 100644 --- a/test/https.ts +++ b/test/https.ts @@ -1,5 +1,5 @@ import test from 'ava'; -import {DetailedPeerCertificate} from 'tls'; +import tls, {DetailedPeerCertificate} from 'tls'; import pEvent from 'p-event'; import pify from 'pify'; import pem from 'pem'; @@ -434,3 +434,56 @@ test('client certificate PFX', withHttpsServer(), async (t, server, got) => { t.is(response.peerCertificate.subject.CN, 'client'); t.is(response.peerCertificate.issuer.CN, 'authority'); }); + +const ciphers = tls.getCiphers().map(cipher => cipher.toUpperCase()); + +test('https request with `ciphers` option', withHttpsServer({ciphers: `${ciphers[0]!}:${ciphers[1]!}:${ciphers[2]!}`}), async (t, server, got) => { + server.get('/', (request, response) => { + response.json({ + cipher: (request.socket as any).getCipher().name + }); + }); + + const response: any = await got({ + httpsOptions: { + ciphers: ciphers[0] + } + }).json(); + + t.is(response.cipher, ciphers[0]); +}); + +test('https request with `honorCipherOrder` option', withHttpsServer({ciphers: `${ciphers[0]!}:${ciphers[1]!}`}), async (t, server, got) => { + server.get('/', (request, response) => { + response.json({ + cipher: (request.socket as any).getCipher().name + }); + }); + + const response: any = await got({ + httpsOptions: { + ciphers: `${ciphers[1]!}:${ciphers[0]!}`, + honorCipherOrder: true + } + }).json(); + + t.is(response.cipher, ciphers[0]); +}); + +test('https request with `minVersion` option', withHttpsServer({maxVersion: 'TLSv1.2'}), async (t, server, got) => { + server.get('/', (request, response) => { + response.json({ + version: (request.socket as any).getCipher().version + }); + }); + + const request = got({ + httpsOptions: { + minVersion: 'TLSv1.3' + } + }); + + await t.throwsAsync(request, { + code: 'EPROTO' + }); +}); From 3b7fceef67530d088e3a007a33924ff9f65058cd Mon Sep 17 00:00:00 2001 From: Giovanni Minotti Date: Tue, 27 Apr 2021 14:56:41 +0200 Subject: [PATCH 2/5] Removed unused tests parameters Removed unused tests parameters --- test/helpers/create-https-test-server.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/test/helpers/create-https-test-server.ts b/test/helpers/create-https-test-server.ts index cc3d363c1..93abb0fce 100644 --- a/test/helpers/create-https-test-server.ts +++ b/test/helpers/create-https-test-server.ts @@ -12,10 +12,6 @@ export type HttpsServerOptions = { honorCipherOrder?: SecureContextOptions['honorCipherOrder']; minVersion?: SecureContextOptions['minVersion']; maxVersion?: SecureContextOptions['maxVersion']; - signatureAlgorithms?: SecureContextOptions['sigalgs']; - tlsSessionLifetime?: SecureContextOptions['sessionTimeout']; - dhparam?: SecureContextOptions['dhparam']; - ecdhCurve?: SecureContextOptions['ecdhCurve']; }; export interface ExtendedHttpsTestServer extends express.Express { @@ -62,9 +58,7 @@ const createHttpsTestServer = async (options: HttpsServerOptions = {}): Promise< ciphers: options.ciphers, honorCipherOrder: options.honorCipherOrder, minVersion: options.minVersion, - maxVersion: options.maxVersion, - dhparam: options.dhparam, - ecdhCurve: options.ecdhCurve + maxVersion: options.maxVersion }, server ); From 4e7d3012053acc6c43375c53a7dbf88e63380525 Mon Sep 17 00:00:00 2001 From: Giovanni Minotti Date: Wed, 28 Apr 2021 13:28:03 +0200 Subject: [PATCH 3/5] Update test/https.ts Co-authored-by: Sindre Sorhus --- test/https.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/https.ts b/test/https.ts index 86d78b633..16d98f214 100644 --- a/test/https.ts +++ b/test/https.ts @@ -470,7 +470,7 @@ test('https request with `honorCipherOrder` option', withHttpsServer({ciphers: ` t.is(response.cipher, ciphers[0]); }); -test('https request with `minVersion` option', withHttpsServer({maxVersion: 'TLSv1.2'}), async (t, server, got) => { +test('https request with `minVersion` option', withHttpsServer({maxVersion: 'TLSv1.2'}), async (t, server, got) => { server.get('/', (request, response) => { response.json({ version: (request.socket as any).getCipher().version From e90dde5ef39b9006e0eac89f94728e4d5a1bb690 Mon Sep 17 00:00:00 2001 From: Giovanni Minotti Date: Wed, 28 Apr 2021 13:28:39 +0200 Subject: [PATCH 4/5] Update https.ts --- test/https.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/https.ts b/test/https.ts index 16d98f214..348a63092 100644 --- a/test/https.ts +++ b/test/https.ts @@ -453,7 +453,7 @@ test('https request with `ciphers` option', withHttpsServer({ciphers: `${ciphers t.is(response.cipher, ciphers[0]); }); -test('https request with `honorCipherOrder` option', withHttpsServer({ciphers: `${ciphers[0]!}:${ciphers[1]!}`}), async (t, server, got) => { +test('https request with `honorCipherOrder` option', withHttpsServer({ciphers: `${ciphers[0]!}:${ciphers[1]!}`}), async (t, server, got) => { server.get('/', (request, response) => { response.json({ cipher: (request.socket as any).getCipher().name From 31ec3208d7947c386c7d46f1ed6664609caa511b Mon Sep 17 00:00:00 2001 From: Giovanni Minotti Date: Wed, 5 May 2021 10:42:16 +0200 Subject: [PATCH 5/5] Fixed HTTPS tests types --- test/https.ts | 54 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/test/https.ts b/test/https.ts index 348a63092..3d328d7a6 100644 --- a/test/https.ts +++ b/test/https.ts @@ -216,12 +216,18 @@ test('client certificate', withHttpsServer(), async (t, server, got) => { const clientKey = clientResult.clientKey; const clientCert = clientResult.certificate; - const response: any = await got({ + const response = await got({ httpsOptions: { key: clientKey, certificate: clientCert } - }).json(); + }).json<{ + authorized: boolean; + peerCertificate: { + subject: {CN: string}; + issuer: {CN: string}; + }; + }>(); t.true(response.authorized); t.is(response.peerCertificate.subject.CN, 'client'); @@ -249,12 +255,14 @@ test('invalid client certificate (self-signed)', withHttpsServer(), async (t, se const clientKey = clientResult.clientKey; const clientCert = clientResult.certificate; - const response: any = await got({ + const response = await got({ httpsOptions: { key: clientKey, certificate: clientCert } - }).json(); + }).json<{ + authorized: boolean; + }>(); t.is(response.authorized, false); }); @@ -289,12 +297,18 @@ test('invalid client certificate (other CA)', withHttpsServer(), async (t, serve const clientKey = clientResult.clientKey; const clientCert = clientResult.certificate; - const response: any = await got({ + const response = await got({ httpsOptions: { key: clientKey, certificate: clientCert } - }).json(); + }).json<{ + authorized: boolean; + peerCertificate: { + subject: {CN: string}; + issuer: {CN: string}; + }; + }>(); t.false(response.authorized); t.is(response.peerCertificate.subject.CN, 'other-client'); @@ -337,13 +351,19 @@ test('key passphrase', withHttpsServer(), async (t, server, got) => { }); const clientCert = clientResult.certificate; - const response: any = await got({ + const response = await got({ httpsOptions: { key: clientKey, passphrase: 'randomPassword', certificate: clientCert } - }).json(); + }).json<{ + authorized: boolean; + peerCertificate: { + subject: {CN: string}; + issuer: {CN: string}; + }; + }>(); t.true(response.authorized); t.is(response.peerCertificate.subject.CN, 'client'); @@ -423,12 +443,18 @@ test('client certificate PFX', withHttpsServer(), async (t, server, got) => { const {pkcs12} = await createPkcs12(clientKey, clientCert, 'randomPassword'); - const response: any = await got({ + const response = await got({ httpsOptions: { pfx: pkcs12, passphrase: 'randomPassword' } - }).json(); + }).json<{ + authorized: boolean; + peerCertificate: { + subject: {CN: string}; + issuer: {CN: string}; + }; + }>(); t.true(response.authorized); t.is(response.peerCertificate.subject.CN, 'client'); @@ -444,11 +470,11 @@ test('https request with `ciphers` option', withHttpsServer({ciphers: `${ciphers }); }); - const response: any = await got({ + const response = await got({ httpsOptions: { ciphers: ciphers[0] } - }).json(); + }).json<{cipher: string}>(); t.is(response.cipher, ciphers[0]); }); @@ -460,12 +486,12 @@ test('https request with `honorCipherOrder` option', withHttpsServer({ciphers: ` }); }); - const response: any = await got({ + const response = await got({ httpsOptions: { ciphers: `${ciphers[1]!}:${ciphers[0]!}`, honorCipherOrder: true } - }).json(); + }).json<{cipher: string}>(); t.is(response.cipher, ciphers[0]); });