11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ciconst common = require('../common');
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ciif (!common.hasCrypto)
51cb0ef41Sopenharmony_ci  common.skip('missing crypto');
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciif (!common.opensslCli)
81cb0ef41Sopenharmony_ci  common.skip('node compiled without OpenSSL CLI');
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ciconst assert = require('assert');
111cb0ef41Sopenharmony_ciconst net = require('net');
121cb0ef41Sopenharmony_ciconst tls = require('tls');
131cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_cilet clientClosed = false;
161cb0ef41Sopenharmony_cilet errorReceived = false;
171cb0ef41Sopenharmony_cifunction canCloseServer() {
181cb0ef41Sopenharmony_ci  return clientClosed && errorReceived;
191cb0ef41Sopenharmony_ci}
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_cifunction loadPEM(n) {
221cb0ef41Sopenharmony_ci  return fixtures.readKey(`${n}.pem`, 'utf-8');
231cb0ef41Sopenharmony_ci}
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ciconst opts = {
261cb0ef41Sopenharmony_ci  key: loadPEM('agent2-key'),
271cb0ef41Sopenharmony_ci  cert: loadPEM('agent2-cert')
281cb0ef41Sopenharmony_ci};
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ciconst max_iter = 20;
311cb0ef41Sopenharmony_cilet iter = 0;
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ciconst errorHandler = common.mustCall((err) => {
341cb0ef41Sopenharmony_ci  assert.strictEqual(err.code, 'ERR_SSL_WRONG_VERSION_NUMBER');
351cb0ef41Sopenharmony_ci  assert.strictEqual(err.library, 'SSL routines');
361cb0ef41Sopenharmony_ci  if (!common.hasOpenSSL3) assert.strictEqual(err.function, 'ssl3_get_record');
371cb0ef41Sopenharmony_ci  assert.strictEqual(err.reason, 'wrong version number');
381cb0ef41Sopenharmony_ci  errorReceived = true;
391cb0ef41Sopenharmony_ci  if (canCloseServer())
401cb0ef41Sopenharmony_ci    server.close();
411cb0ef41Sopenharmony_ci});
421cb0ef41Sopenharmony_ciconst server = tls.createServer(opts, common.mustCall(function(s) {
431cb0ef41Sopenharmony_ci  s.pipe(s);
441cb0ef41Sopenharmony_ci  s.on('error', errorHandler);
451cb0ef41Sopenharmony_ci}, 2));
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(function() {
481cb0ef41Sopenharmony_ci  sendClient();
491cb0ef41Sopenharmony_ci}));
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ciserver.on('tlsClientError', common.mustNotCall());
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ciserver.on('error', common.mustNotCall());
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_cifunction sendClient() {
561cb0ef41Sopenharmony_ci  const client = tls.connect(server.address().port, {
571cb0ef41Sopenharmony_ci    rejectUnauthorized: false
581cb0ef41Sopenharmony_ci  });
591cb0ef41Sopenharmony_ci  client.on('data', common.mustCall(function() {
601cb0ef41Sopenharmony_ci    if (iter++ === 2) sendBADTLSRecord();
611cb0ef41Sopenharmony_ci    if (iter < max_iter) {
621cb0ef41Sopenharmony_ci      client.write('a');
631cb0ef41Sopenharmony_ci      return;
641cb0ef41Sopenharmony_ci    }
651cb0ef41Sopenharmony_ci    client.end();
661cb0ef41Sopenharmony_ci  }, max_iter));
671cb0ef41Sopenharmony_ci  client.write('a', common.mustCall());
681cb0ef41Sopenharmony_ci  client.on('error', common.mustNotCall());
691cb0ef41Sopenharmony_ci  client.on('close', common.mustCall(function() {
701cb0ef41Sopenharmony_ci    clientClosed = true;
711cb0ef41Sopenharmony_ci    if (canCloseServer())
721cb0ef41Sopenharmony_ci      server.close();
731cb0ef41Sopenharmony_ci  }));
741cb0ef41Sopenharmony_ci}
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_cifunction sendBADTLSRecord() {
781cb0ef41Sopenharmony_ci  const BAD_RECORD = Buffer.from([0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
791cb0ef41Sopenharmony_ci  const socket = net.connect(server.address().port);
801cb0ef41Sopenharmony_ci  const client = tls.connect({
811cb0ef41Sopenharmony_ci    socket: socket,
821cb0ef41Sopenharmony_ci    rejectUnauthorized: false
831cb0ef41Sopenharmony_ci  }, common.mustCall(function() {
841cb0ef41Sopenharmony_ci    client.write('x');
851cb0ef41Sopenharmony_ci    client.on('data', (data) => {
861cb0ef41Sopenharmony_ci      socket.end(BAD_RECORD);
871cb0ef41Sopenharmony_ci    });
881cb0ef41Sopenharmony_ci  }));
891cb0ef41Sopenharmony_ci  client.on('error', common.mustCall((err) => {
901cb0ef41Sopenharmony_ci    assert.strictEqual(err.code, 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION');
911cb0ef41Sopenharmony_ci    assert.strictEqual(err.library, 'SSL routines');
921cb0ef41Sopenharmony_ci    if (!common.hasOpenSSL3)
931cb0ef41Sopenharmony_ci      assert.strictEqual(err.function, 'ssl3_read_bytes');
941cb0ef41Sopenharmony_ci    assert.strictEqual(err.reason, 'tlsv1 alert protocol version');
951cb0ef41Sopenharmony_ci  }));
961cb0ef41Sopenharmony_ci}
97