11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures'); 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciif (!common.hasCrypto) 61cb0ef41Sopenharmony_ci common.skip('missing crypto'); 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci// This test ensures that when a TLS connection is established, the server 91cb0ef41Sopenharmony_ci// selects the most recently added SecureContext that matches the servername. 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ciconst assert = require('assert'); 121cb0ef41Sopenharmony_ciconst tls = require('tls'); 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_cifunction loadPEM(n) { 151cb0ef41Sopenharmony_ci return fixtures.readKey(`${n}.pem`); 161cb0ef41Sopenharmony_ci} 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciconst serverOptions = { 191cb0ef41Sopenharmony_ci key: loadPEM('agent2-key'), 201cb0ef41Sopenharmony_ci cert: loadPEM('agent2-cert'), 211cb0ef41Sopenharmony_ci requestCert: true, 221cb0ef41Sopenharmony_ci rejectUnauthorized: false, 231cb0ef41Sopenharmony_ci}; 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ciconst badSecureContext = { 261cb0ef41Sopenharmony_ci key: loadPEM('agent1-key'), 271cb0ef41Sopenharmony_ci cert: loadPEM('agent1-cert'), 281cb0ef41Sopenharmony_ci ca: [ loadPEM('ca2-cert') ] 291cb0ef41Sopenharmony_ci}; 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ciconst goodSecureContext = { 321cb0ef41Sopenharmony_ci key: loadPEM('agent1-key'), 331cb0ef41Sopenharmony_ci cert: loadPEM('agent1-cert'), 341cb0ef41Sopenharmony_ci ca: [ loadPEM('ca1-cert') ] 351cb0ef41Sopenharmony_ci}; 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ciconst server = tls.createServer(serverOptions, (c) => { 381cb0ef41Sopenharmony_ci // The 'a' and 'b' subdomains are used to distinguish between client 391cb0ef41Sopenharmony_ci // connections. 401cb0ef41Sopenharmony_ci // Connection to subdomain 'a' is made when the 'bad' secure context is 411cb0ef41Sopenharmony_ci // the only one in use. 421cb0ef41Sopenharmony_ci if ('a.example.com' === c.servername) { 431cb0ef41Sopenharmony_ci assert.strictEqual(c.authorized, false); 441cb0ef41Sopenharmony_ci } 451cb0ef41Sopenharmony_ci // Connection to subdomain 'b' is made after the 'good' context has been 461cb0ef41Sopenharmony_ci // added. 471cb0ef41Sopenharmony_ci if ('b.example.com' === c.servername) { 481cb0ef41Sopenharmony_ci assert.strictEqual(c.authorized, true); 491cb0ef41Sopenharmony_ci } 501cb0ef41Sopenharmony_ci}); 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci// 1. Add the 'bad' secure context. A connection using this context will not be 531cb0ef41Sopenharmony_ci// authorized. 541cb0ef41Sopenharmony_ciserver.addContext('*.example.com', badSecureContext); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ciserver.listen(0, () => { 571cb0ef41Sopenharmony_ci const options = { 581cb0ef41Sopenharmony_ci port: server.address().port, 591cb0ef41Sopenharmony_ci key: loadPEM('agent1-key'), 601cb0ef41Sopenharmony_ci cert: loadPEM('agent1-cert'), 611cb0ef41Sopenharmony_ci ca: [loadPEM('ca1-cert')], 621cb0ef41Sopenharmony_ci servername: 'a.example.com', 631cb0ef41Sopenharmony_ci rejectUnauthorized: false, 641cb0ef41Sopenharmony_ci }; 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci // 2. Make a connection using servername 'a.example.com'. Since a 'bad' 671cb0ef41Sopenharmony_ci // secure context is used, this connection should not be authorized. 681cb0ef41Sopenharmony_ci const client = tls.connect(options, () => { 691cb0ef41Sopenharmony_ci client.end(); 701cb0ef41Sopenharmony_ci }); 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci client.on('close', common.mustCall(() => { 731cb0ef41Sopenharmony_ci // 3. Add a 'good' secure context. 741cb0ef41Sopenharmony_ci server.addContext('*.example.com', goodSecureContext); 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci options.servername = 'b.example.com'; 771cb0ef41Sopenharmony_ci // 4. Make a connection using servername 'b.example.com'. This connection 781cb0ef41Sopenharmony_ci // should be authorized because the 'good' secure context is the most 791cb0ef41Sopenharmony_ci // recently added matching context. 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci const other = tls.connect(options, () => { 821cb0ef41Sopenharmony_ci other.end(); 831cb0ef41Sopenharmony_ci }); 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci other.on('close', common.mustCall(() => { 861cb0ef41Sopenharmony_ci // 5. Make another connection using servername 'b.example.com' to ensure 871cb0ef41Sopenharmony_ci // that the array of secure contexts is not reversed in place with each 881cb0ef41Sopenharmony_ci // SNICallback call, as someone might be tempted to refactor this piece of 891cb0ef41Sopenharmony_ci // code by using Array.prototype.reverse() method. 901cb0ef41Sopenharmony_ci const onemore = tls.connect(options, () => { 911cb0ef41Sopenharmony_ci onemore.end(); 921cb0ef41Sopenharmony_ci }); 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci onemore.on('close', common.mustCall(() => { 951cb0ef41Sopenharmony_ci server.close(); 961cb0ef41Sopenharmony_ci })); 971cb0ef41Sopenharmony_ci })); 981cb0ef41Sopenharmony_ci })); 991cb0ef41Sopenharmony_ci}); 100