diff --git a/doc/api/errors.md b/doc/api/errors.md
index cc7c668267fd6b..c8fdd30c9445a9 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -3132,6 +3132,13 @@ Failed to set PSK identity hint. Hint may be too long.
An attempt was made to renegotiate TLS on a socket instance with renegotiation
disabled.
+
+
+### `ERR_TLS_RENEGOTIATION_UNSUPPORTED`
+
+An attempt was made to renegotiate TLS, but the TLS implementation does not
+support caller-initiated renegotiation.
+
### `ERR_TLS_REQUIRED_SERVER_NAME`
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index 1d31e2b43dc2bd..a93bb57e6cf0ad 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -1843,6 +1843,8 @@ E('ERR_TLS_PROTOCOL_VERSION_CONFLICT',
'TLS protocol version %j conflicts with secureProtocol %j', TypeError);
E('ERR_TLS_RENEGOTIATION_DISABLED',
'TLS session renegotiation disabled for this socket', Error);
+E('ERR_TLS_RENEGOTIATION_UNSUPPORTED',
+ 'TLS session renegotiation is unsupported by this TLS implementation', Error);
// This should probably be a `TypeError`.
E('ERR_TLS_REQUIRED_SERVER_NAME',
diff --git a/lib/internal/tls/wrap.js b/lib/internal/tls/wrap.js
index d89e501432968a..05ce6955ed9217 100644
--- a/lib/internal/tls/wrap.js
+++ b/lib/internal/tls/wrap.js
@@ -72,6 +72,7 @@ const {
ERR_TLS_INVALID_CONTEXT,
ERR_TLS_INVALID_STATE,
ERR_TLS_RENEGOTIATION_DISABLED,
+ ERR_TLS_RENEGOTIATION_UNSUPPORTED,
ERR_TLS_REQUIRED_SERVER_NAME,
ERR_TLS_SESSION_ATTACK,
ERR_TLS_SNI_FROM_SERVER,
@@ -1014,8 +1015,13 @@ TLSSocket.prototype.renegotiate = function(options, callback) {
try {
this._handle.renegotiate();
} catch (err) {
+ const isBoringSSLRenegotiationUnsupported =
+ process.features.openssl_is_boringssl &&
+ err?.code === 'ERR_SSL_FUNCTION_SHOULD_NOT_HAVE_BEEN_CALLED';
+ const error = isBoringSSLRenegotiationUnsupported ?
+ new ERR_TLS_RENEGOTIATION_UNSUPPORTED() : err;
if (callback) {
- process.nextTick(callback, err);
+ process.nextTick(callback, error);
}
return false;
}
diff --git a/test/addons/openssl-get-ssl-ctx/binding.cc b/test/addons/openssl-get-ssl-ctx/binding.cc
index 3945ec870fb8b9..47468ffbcd789d 100644
--- a/test/addons/openssl-get-ssl-ctx/binding.cc
+++ b/test/addons/openssl-get-ssl-ctx/binding.cc
@@ -18,12 +18,12 @@ void GetSSLCtx(const v8::FunctionCallbackInfo& args) {
return;
}
- // Verify the pointer is a valid SSL_CTX by calling an OpenSSL function.
- const SSL_METHOD* method = SSL_CTX_get_ssl_method(ctx);
- if (method == nullptr) {
+ // Verify the pointer is a valid SSL_CTX by calling a function available
+ // across OpenSSL-compatible TLS backends and checking context-owned state.
+ STACK_OF(SSL_CIPHER)* ciphers = SSL_CTX_get_ciphers(ctx);
+ if (ciphers == nullptr) {
isolate->ThrowException(v8::Exception::Error(
- v8::String::NewFromUtf8(isolate,
- "SSL_CTX_get_ssl_method returned nullptr")
+ v8::String::NewFromUtf8(isolate, "SSL_CTX_get_ciphers returned nullptr")
.ToLocalChecked()));
return;
}
diff --git a/test/common/boringssl.js b/test/common/boringssl.js
new file mode 100644
index 00000000000000..e6e91387c304c7
--- /dev/null
+++ b/test/common/boringssl.js
@@ -0,0 +1,346 @@
+/* eslint-disable node-core/crypto-check */
+
+'use strict';
+const common = require('../common');
+const assert = require('assert');
+const fixtures = require('../common/fixtures');
+const tls = require('tls');
+
+// This module is for BoringSSL-specific branches in tests whose original
+// OpenSSL coverage cannot run unchanged. Each helper should assert the
+// observable BoringSSL behavior that explains why the OpenSSL-specific
+// assertions are bypassed.
+
+/**
+ * BoringSSL exposes many removed or disabled TLS cipher suites as "no match"
+ * at secure-context creation time. This is used for suites such as
+ * finite-field DHE and anonymous ECDH that OpenSSL builds may still negotiate
+ * in tests.
+ * @param {Function} fn
+ */
+function assertNoCipherMatch(fn) {
+ assert.throws(fn, {
+ code: 'ERR_SSL_NO_CIPHER_MATCH',
+ library: 'SSL routines',
+ function: 'OPENSSL_internal',
+ reason: 'NO_CIPHER_MATCH',
+ });
+}
+
+/**
+ * BoringSSL does not parse OpenSSL cipher-string commands such as `@SECLEVEL`.
+ * Those are OpenSSL policy directives, not cipher names.
+ * @param {Function} fn
+ */
+function assertInvalidCommand(fn) {
+ assert.throws(fn, {
+ code: 'ERR_SSL_INVALID_COMMAND',
+ library: 'SSL routines',
+ function: 'OPENSSL_internal',
+ reason: 'INVALID_COMMAND',
+ });
+}
+
+/**
+ * Node's DHE tests exercise OpenSSL's finite-field DHE cipher support and DH
+ * parameter-size policy. BoringSSL does not offer these DHE cipher suites on
+ * this surface, so creating a server context with a DHE-only cipher list fails
+ * before a handshake can test DH parameter behavior.
+ */
+function assertFiniteFieldDheUnsupported() {
+ assertNoCipherMatch(() => {
+ tls.createServer({
+ key: fixtures.readKey('agent2-key.pem'),
+ cert: fixtures.readKey('agent2-cert.pem'),
+ ciphers: 'DHE-RSA-AES128-GCM-SHA256',
+ });
+ });
+}
+
+/**
+ * OpenSSL security levels reject small keys by policy and can be adjusted with
+ * `@SECLEVEL` in the cipher string. BoringSSL does not implement those security
+ * levels: the small-key server context is accepted, while the OpenSSL-specific
+ * `@SECLEVEL` command is rejected as invalid cipher-string syntax.
+ */
+function assertOpenSSLSecurityLevelsUnsupported() {
+ const options = {
+ key: fixtures.readKey('agent11-key.pem'),
+ cert: fixtures.readKey('agent11-cert.pem'),
+ ciphers: 'DEFAULT',
+ };
+
+ tls.createServer(options).close();
+
+ options.ciphers = 'DEFAULT:@SECLEVEL=0';
+ assertInvalidCommand(() => tls.createServer(options));
+}
+
+/**
+ * Node's multi-key tests rely on OpenSSL accepting an array of private keys and
+ * matching them with an array of certificates. BoringSSL rejects this mixed
+ * EC/RSA identity configuration while configuring the certificate chain, before
+ * a client can negotiate either identity.
+ */
+function assertMultiKeyUnsupported() {
+ assert.throws(() => {
+ tls.createServer({
+ key: [
+ fixtures.readKey('ec10-key.pem'),
+ fixtures.readKey('agent1-key.pem'),
+ ],
+ cert: [
+ fixtures.readKey('agent1-cert.pem'),
+ fixtures.readKey('ec10-cert.pem'),
+ ],
+ });
+ }, {
+ code: 'ERR_OSSL_X509_KEY_TYPE_MISMATCH',
+ library: 'X.509 certificate routines',
+ function: 'OPENSSL_internal',
+ reason: 'KEY_TYPE_MISMATCH',
+ });
+}
+
+/**
+ * BoringSSL does not support caller-initiated renegotiation. Even on a TLS 1.2
+ * connection, TLSSocket#renegotiate() returns false and the callback receives
+ * Node's BoringSSL-specific unsupported-renegotiation error instead of
+ * entering the native binding or exercising Node's renegotiation-limit logic.
+ */
+function testRenegotiationUnsupported() {
+ const server = tls.createServer({
+ key: fixtures.readKey('rsa_private.pem'),
+ cert: fixtures.readKey('rsa_cert.crt'),
+ maxVersion: 'TLSv1.2',
+ }, (socket) => socket.resume());
+
+ server.listen(0, common.mustCall(() => {
+ const client = tls.connect({
+ port: server.address().port,
+ rejectUnauthorized: false,
+ maxVersion: 'TLSv1.2',
+ }, common.mustCall(() => {
+ const ok = client.renegotiate({}, common.mustCall((err) => {
+ assert.throws(() => { throw err; }, {
+ code: 'ERR_TLS_RENEGOTIATION_UNSUPPORTED',
+ message: 'TLS session renegotiation is unsupported by this TLS ' +
+ 'implementation',
+ });
+ client.destroy();
+ server.close();
+ }));
+ assert.strictEqual(ok, false);
+ }));
+ client.on('error', common.mustNotCall());
+ }));
+}
+
+/**
+ * OpenSSL exposes the negotiated ephemeral key type, name, and size for TLS
+ * clients. With BoringSSL the same ECDHE TLS 1.2 handshake succeeds, but
+ * getEphemeralKeyInfo() returns null on the server side and an object whose
+ * fields are undefined on the client side.
+ */
+function testEphemeralKeyInfoUnsupported() {
+ const server = tls.createServer({
+ key: fixtures.readKey('agent2-key.pem'),
+ cert: fixtures.readKey('agent2-cert.pem'),
+ ciphers: 'ECDHE-RSA-AES256-GCM-SHA384',
+ ecdhCurve: 'prime256v1',
+ maxVersion: 'TLSv1.2',
+ }, common.mustCall((socket) => {
+ assert.strictEqual(socket.getEphemeralKeyInfo(), null);
+ socket.end();
+ }));
+
+ server.listen(0, common.mustCall(() => {
+ const client = tls.connect({
+ port: server.address().port,
+ rejectUnauthorized: false,
+ maxVersion: 'TLSv1.2',
+ }, common.mustCall(() => {
+ assert.deepStrictEqual(client.getEphemeralKeyInfo(), {
+ type: undefined,
+ name: undefined,
+ size: undefined,
+ });
+ server.close();
+ }));
+ }));
+}
+
+/**
+ * The protocol matrix tests cover OpenSSL behavior for legacy TLS protocols.
+ * For BoringSSL we only need to exhibit that a TLSv1-only client cannot connect
+ * to a server whose minimum protocol is TLS 1.2; the client receives the
+ * protocol-version alert instead of the OpenSSL version-specific matrix.
+ */
+function testLegacyProtocolUnsupported() {
+ const server = tls.createServer({
+ key: fixtures.readKey('agent2-key.pem'),
+ cert: fixtures.readKey('agent2-cert.pem'),
+ minVersion: 'TLSv1.2',
+ }, common.mustNotCall());
+
+ server.on('tlsClientError', common.mustCall());
+ server.listen(0, common.mustCall(() => {
+ const client = tls.connect({
+ port: server.address().port,
+ rejectUnauthorized: false,
+ secureProtocol: 'TLSv1_method',
+ }, common.mustNotCall());
+ client.on('error', common.mustCall((err) => {
+ assert.strictEqual(err.code, 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION');
+ server.close();
+ }));
+ }));
+}
+
+/**
+ * BoringSSL can load a multi-PFX option well enough to serve the ECDSA
+ * identity, but it does not provide the same OpenSSL multi-identity selection
+ * behavior. After the ECDSA handshake succeeds, an RSA-only client fails with
+ * no shared cipher instead of selecting the RSA identity from the same PFX list.
+ */
+function testMultiPfxSelectionDifference() {
+ const server = tls.createServer({
+ pfx: [
+ {
+ buf: fixtures.readKey('agent1.pfx'),
+ passphrase: 'sample',
+ },
+ fixtures.readKey('ec.pfx'),
+ ],
+ }, common.mustCallAtLeast((socket) => socket.end(), 1));
+
+ server.listen(0, common.mustCall(() => {
+ const ecdsa = tls.connect(server.address().port, {
+ ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384',
+ maxVersion: 'TLSv1.2',
+ rejectUnauthorized: false,
+ }, common.mustCall(() => {
+ assert.strictEqual(ecdsa.getCipher().name,
+ 'ECDHE-ECDSA-AES256-GCM-SHA384');
+ ecdsa.end();
+
+ server.once('tlsClientError', common.mustCall((err) => {
+ assert.strictEqual(err.code, 'ERR_SSL_NO_SHARED_CIPHER');
+ }));
+ const rsa = tls.connect(server.address().port, {
+ ciphers: 'ECDHE-RSA-AES256-GCM-SHA384',
+ maxVersion: 'TLSv1.2',
+ rejectUnauthorized: false,
+ }, common.mustNotCall());
+ rsa.on('error', common.mustCall((err) => {
+ assert.strictEqual(err.code, 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE');
+ server.close();
+ }));
+ }));
+ }));
+}
+
+/**
+ * PSK works for TLS 1.2 in BoringSSL, but Node's PSK tests also cover the
+ * default TLS 1.3 path. In that path BoringSSL does not complete a certificate-
+ * less PSK-only handshake through Node's current server setup: the server
+ * reports NO_CERTIFICATE_SET and the client receives an internal-error alert.
+ */
+function testPskTls13Unsupported() {
+ const key = Buffer.from('d731ef57be09e5204f0b205b60627028', 'hex');
+ let gotClientError = false;
+ let gotServerError = false;
+ function maybeClose(server) {
+ if (gotClientError && gotServerError)
+ server.close();
+ }
+
+ const server = tls.createServer({
+ ciphers: 'PSK+HIGH',
+ pskCallback() { return key; },
+ }, common.mustNotCall());
+
+ server.once('tlsClientError', common.mustCall((err) => {
+ assert.strictEqual(err.code, 'ERR_SSL_NO_CERTIFICATE_SET');
+ gotServerError = true;
+ maybeClose(server);
+ }));
+
+ server.listen(0, common.mustCall(() => {
+ const client = tls.connect({
+ port: server.address().port,
+ ciphers: 'PSK+HIGH',
+ checkServerIdentity() {},
+ pskCallback() {
+ return { psk: key, identity: 'TestUser' };
+ },
+ }, common.mustNotCall());
+ client.on('error', common.mustCall((err) => {
+ assert.strictEqual(err.code, 'ERR_SSL_TLSV1_ALERT_INTERNAL_ERROR');
+ gotClientError = true;
+ maybeClose(server);
+ }));
+ }));
+}
+
+/**
+ * The OpenSSL ticket tests assume that once a TLS 1.3 session is reused, the
+ * client will not necessarily receive a replacement session event before close.
+ * BoringSSL emits new session tickets on both the initial and resumed TLS 1.3
+ * connections, so the resumed connection still emits at least one 'session'
+ * event while isSessionReused() is true.
+ */
+function testTls13SessionTicketSemanticsDiffer() {
+ const server = tls.createServer({
+ key: fixtures.readKey('agent1-key.pem'),
+ cert: fixtures.readKey('agent1-cert.pem'),
+ }, (socket) => socket.end());
+
+ let session;
+ let secondSessionEvents = 0;
+
+ server.listen(0, common.mustCall(() => {
+ const first = tls.connect({
+ port: server.address().port,
+ rejectUnauthorized: false,
+ }, common.mustCall(() => {
+ assert.strictEqual(first.isSessionReused(), false);
+ }));
+ first.on('session', common.mustCallAtLeast((sess) => {
+ session = sess;
+ }, 1));
+ first.on('close', common.mustCall(() => {
+ assert(Buffer.isBuffer(session));
+
+ const second = tls.connect({
+ port: server.address().port,
+ rejectUnauthorized: false,
+ session,
+ }, common.mustCall(() => {
+ assert.strictEqual(second.isSessionReused(), true);
+ }));
+ second.on('session', common.mustCallAtLeast(() => {
+ secondSessionEvents++;
+ }, 1));
+ second.on('close', common.mustCall(() => {
+ assert(secondSessionEvents > 0);
+ server.close();
+ }));
+ second.resume();
+ }));
+ first.resume();
+ }));
+}
+
+module.exports = {
+ assertFiniteFieldDheUnsupported,
+ assertMultiKeyUnsupported,
+ assertNoCipherMatch,
+ assertOpenSSLSecurityLevelsUnsupported,
+ testEphemeralKeyInfoUnsupported,
+ testLegacyProtocolUnsupported,
+ testMultiPfxSelectionDifference,
+ testPskTls13Unsupported,
+ testRenegotiationUnsupported,
+ testTls13SessionTicketSemanticsDiffer,
+};
diff --git a/test/parallel/test-crypto-dh-stateless.js b/test/parallel/test-crypto-dh-stateless.js
index 9e13c62595ef26..0ade828eb2342b 100644
--- a/test/parallel/test-crypto-dh-stateless.js
+++ b/test/parallel/test-crypto-dh-stateless.js
@@ -6,6 +6,7 @@ if (!common.hasCrypto)
const assert = require('assert');
const crypto = require('crypto');
const { hasOpenSSL } = require('../common/crypto');
+const isBoringSSL = process.features.openssl_is_boringssl;
// Error code for a key-type mismatch during (EC)DH. The underlying OpenSSL
// error code varies by version, and in OpenSSL 4.0 by platform: some builds
@@ -212,8 +213,28 @@ function testDHError(options, expected) {
}));
}
-const alicePrivateKey = crypto.createPrivateKey({
- key: '-----BEGIN PRIVATE KEY-----\n' +
+{
+ const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
+ namedCurve: 'P-256',
+ });
+
+ assert.throws(() => crypto.diffieHellman({ privateKey }), {
+ name: 'TypeError',
+ code: 'ERR_INVALID_ARG_TYPE',
+ });
+
+ assert.throws(() => crypto.diffieHellman({ publicKey }), {
+ name: 'TypeError',
+ code: 'ERR_INVALID_ARG_TYPE',
+ });
+}
+
+if (isBoringSSL) {
+ common.printSkipMessage('Skipping finite-field DH KeyObject import and ' +
+ 'generation tests unsupported by BoringSSL');
+} else {
+ const alicePrivateKey = crypto.createPrivateKey({
+ key: '-----BEGIN PRIVATE KEY-----\n' +
'MIIBoQIBADCB1QYJKoZIhvcNAQMBMIHHAoHBAP//////////yQ/aoiFowjTExmKL\n' +
'gNwc0SkCTgiKZ8x0Agu+pjsTmyJRSgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVt\n' +
'bVHCReSFtXZiXn7G9ExC6aY37WsL/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR\n' +
@@ -224,10 +245,10 @@ const alicePrivateKey = crypto.createPrivateKey({
'iIt9FmvFaaOVe2DupqSr6xzbf/zyON+WF5B5HNVOWXswgpgdUsCyygs98hKy/Xje\n' +
'TGzJUoWInW39t0YgMXenJrkS0m6wol8Rhxx81AGgELNV7EHZqg==\n' +
'-----END PRIVATE KEY-----',
- format: 'pem'
-});
-const alicePublicKey = crypto.createPublicKey({
- key: '-----BEGIN PUBLIC KEY-----\n' +
+ format: 'pem'
+ });
+ const alicePublicKey = crypto.createPublicKey({
+ key: '-----BEGIN PUBLIC KEY-----\n' +
'MIIBnzCB1QYJKoZIhvcNAQMBMIHHAoHBAP//////////yQ/aoiFowjTExmKLgNwc\n' +
'0SkCTgiKZ8x0Agu+pjsTmyJRSgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHC\n' +
'ReSFtXZiXn7G9ExC6aY37WsL/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7ORb\n' +
@@ -238,11 +259,11 @@ const alicePublicKey = crypto.createPublicKey({
'rDEz8mjIlnvbWpKB9+uYmbjfVoc3leFvUBqfG2In2m23Md1swsPxr3n7g68H66JX\n' +
'iBJKZLQMqNdbY14G9rdKmhhTJrQjC+i7Q/wI8JPhOFzHIGA=\n' +
'-----END PUBLIC KEY-----',
- format: 'pem'
-});
+ format: 'pem'
+ });
-const bobPrivateKey = crypto.createPrivateKey({
- key: '-----BEGIN PRIVATE KEY-----\n' +
+ const bobPrivateKey = crypto.createPrivateKey({
+ key: '-----BEGIN PRIVATE KEY-----\n' +
'MIIBoQIBADCB1QYJKoZIhvcNAQMBMIHHAoHBAP//////////yQ/aoiFowjTExmKL\n' +
'gNwc0SkCTgiKZ8x0Agu+pjsTmyJRSgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVt\n' +
'bVHCReSFtXZiXn7G9ExC6aY37WsL/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR\n' +
@@ -253,11 +274,11 @@ const bobPrivateKey = crypto.createPrivateKey({
'GagGtIy3dV5f4FA0B/2C97jQ1pO16ah8gSLQRKsNpTCw2rqsZusE0rK6RaYAef7H\n' +
'y/0tmLIsHxLIn+WK9CANqMbCWoP4I178BQaqhiOBkNyNZ0ndqA==\n' +
'-----END PRIVATE KEY-----',
- format: 'pem'
-});
+ format: 'pem'
+ });
-const bobPublicKey = crypto.createPublicKey({
- key: '-----BEGIN PUBLIC KEY-----\n' +
+ const bobPublicKey = crypto.createPublicKey({
+ key: '-----BEGIN PUBLIC KEY-----\n' +
'MIIBoDCB1QYJKoZIhvcNAQMBMIHHAoHBAP//////////yQ/aoiFowjTExmKLgNwc\n' +
'0SkCTgiKZ8x0Agu+pjsTmyJRSgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHC\n' +
'ReSFtXZiXn7G9ExC6aY37WsL/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7ORb\n' +
@@ -268,83 +289,83 @@ const bobPublicKey = crypto.createPublicKey({
'QFKfjzNaJRNMFFd4f2Dn8MSB4yu1xpA1T2i0JSk24vS2H55jx24xhUYtfhT2LJgK\n' +
'JvnaODey/xtY4Kql10ZKf43Lw6gdQC3G8opC9OxVxt9oNR7Z\n' +
'-----END PUBLIC KEY-----',
- format: 'pem'
-});
+ format: 'pem'
+ });
-assert.throws(() => crypto.diffieHellman({ privateKey: alicePrivateKey }), {
- name: 'TypeError',
- code: 'ERR_INVALID_ARG_TYPE',
-});
+ assert.throws(() => crypto.diffieHellman({ privateKey: alicePrivateKey }), {
+ name: 'TypeError',
+ code: 'ERR_INVALID_ARG_TYPE',
+ });
-assert.throws(() => crypto.diffieHellman({ publicKey: alicePublicKey }), {
- name: 'TypeError',
- code: 'ERR_INVALID_ARG_TYPE',
-});
+ assert.throws(() => crypto.diffieHellman({ publicKey: alicePublicKey }), {
+ name: 'TypeError',
+ code: 'ERR_INVALID_ARG_TYPE',
+ });
-const privateKey = Buffer.from(
- '487CD880159D835FD0A8DBA9848898317283DB07E822741B344AD397BA84CDDD3920A51588' +
+ const privateKey = Buffer.from(
+ '487CD880159D835FD0A8DBA9848898317283DB07E822741B344AD397BA84CDDD3920A51588' +
'B891B03B3EBEF3C9F767D921FAC1294D4B5E09CABB6D1DE3EB4527989754FEB64D007EBBDA' +
'2E6C8CE7A17EF41DE3C2DFE7CEAAF963199F55D5DBD9A415E77552FE69B7A41D87888B7D16' +
'6BC569A3957B60EEA6A4ABEB1CDB7FFCF238DF961790791CD54E597B3082981D52C0B2CA0B' +
'3DF212B2FD78DE4C6CC95285889D6DFDB746203177A726B912D26EB0A25F11871C7CD401A0' +
'10B355EC41D9AA', 'hex');
-const publicKey = Buffer.from(
- '8b6ea8abccff18d4819b7ce280db7b480edc02b5016d3c4835af622d85a9e9bc6bbc22b00d' +
+ const publicKey = Buffer.from(
+ '8b6ea8abccff18d4819b7ce280db7b480edc02b5016d3c4835af622d85a9e9bc6bbc22b00d' +
'0c0848ddfafd0530f275007bc691c8cb74a189fecbabd63f0e4e94ef932eb51e94c5456800' +
'c4ce8628987d335466f4b16e1a04df21682d266eb3edf50b21802be3af58443c49da40529f' +
'8f335a25134c1457787f60e7f0c481e32bb5c690354f68b4252936e2f4b61f9e63c76e3185' +
'462d7e14f62c980a26f9da3837b2ff1b58e0aaa5d7464a7f8dcbc3a81d402dc6f28a42f4ec' +
'55c6df68351ed9', 'hex');
-const group = crypto.getDiffieHellman('modp5');
-const dh = crypto.createDiffieHellman(group.getPrime(), group.getGenerator());
-dh.setPrivateKey(privateKey);
+ const group = crypto.getDiffieHellman('modp5');
+ const dh = crypto.createDiffieHellman(group.getPrime(), group.getGenerator());
+ dh.setPrivateKey(privateKey);
-// Test simple Diffie-Hellman, no curves involved.
-test({ publicKey: alicePublicKey, privateKey: alicePrivateKey },
- { publicKey: bobPublicKey, privateKey: bobPrivateKey },
- dh.computeSecret(publicKey));
+ // Test simple Diffie-Hellman, no curves involved.
+ test({ publicKey: alicePublicKey, privateKey: alicePrivateKey },
+ { publicKey: bobPublicKey, privateKey: bobPrivateKey },
+ dh.computeSecret(publicKey));
-test(crypto.generateKeyPairSync('dh', { group: 'modp5' }),
- crypto.generateKeyPairSync('dh', { group: 'modp5' }));
+ test(crypto.generateKeyPairSync('dh', { group: 'modp5' }),
+ crypto.generateKeyPairSync('dh', { group: 'modp5' }));
-test(crypto.generateKeyPairSync('dh', { group: 'modp5' }),
- crypto.generateKeyPairSync('dh', { prime: group.getPrime() }));
+ test(crypto.generateKeyPairSync('dh', { group: 'modp5' }),
+ crypto.generateKeyPairSync('dh', { prime: group.getPrime() }));
-// DH parameter mismatch tests
-{
- const list = [
+ // DH parameter mismatch tests
+ {
+ const list = [
// Same generator, but different primes.
- [{ group: 'modp5' }, { group: 'modp18' }]];
+ [{ group: 'modp5' }, { group: 'modp18' }]];
- // TODO(danbev): Take a closer look if there should be a check in OpenSSL3
- // when the dh parameters differ.
- if (!hasOpenSSL(3)) {
+ // TODO(danbev): Take a closer look if there should be a check in OpenSSL3
+ // when the dh parameters differ.
+ if (!hasOpenSSL(3)) {
// Same primes, but different generator.
- list.push([{ group: 'modp5' }, { prime: group.getPrime(), generator: 5 }]);
- // Same generator, but different primes.
- list.push([{ primeLength: 1024 }, { primeLength: 1024 }]);
- }
+ list.push([{ group: 'modp5' }, { prime: group.getPrime(), generator: 5 }]);
+ // Same generator, but different primes.
+ list.push([{ primeLength: 1024 }, { primeLength: 1024 }]);
+ }
- for (const [params1, params2] of list) {
- const options = {
- privateKey: crypto.generateKeyPairSync('dh', params1).privateKey,
- publicKey: crypto.generateKeyPairSync('dh', params2).publicKey,
- };
- testDHError(options, {
- name: 'Error',
- code: hasOpenSSL(3) ?
- 'ERR_OSSL_MISMATCHING_DOMAIN_PARAMETERS' :
- 'ERR_OSSL_EVP_DIFFERENT_PARAMETERS'
- });
+ for (const [params1, params2] of list) {
+ const options = {
+ privateKey: crypto.generateKeyPairSync('dh', params1).privateKey,
+ publicKey: crypto.generateKeyPairSync('dh', params2).publicKey,
+ };
+ testDHError(options, {
+ name: 'Error',
+ code: hasOpenSSL(3) ?
+ 'ERR_OSSL_MISMATCHING_DOMAIN_PARAMETERS' :
+ 'ERR_OSSL_EVP_DIFFERENT_PARAMETERS'
+ });
+ }
}
-}
-// This key combination will result in an unusually short secret, and should
-// not cause an assertion failure.
-{
- const shortPrivateKey = crypto.createPrivateKey({
- key: '-----BEGIN PRIVATE KEY-----\n' +
+ // This key combination will result in an unusually short secret, and should
+ // not cause an assertion failure.
+ {
+ const shortPrivateKey = crypto.createPrivateKey({
+ key: '-----BEGIN PRIVATE KEY-----\n' +
'MIIBoQIBADCB1QYJKoZIhvcNAQMBMIHHAoHBAP//////////yQ/aoiFowjTExmKL\n' +
'gNwc0SkCTgiKZ8x0Agu+pjsTmyJRSgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVt\n' +
'bVHCReSFtXZiXn7G9ExC6aY37WsL/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR\n' +
@@ -355,9 +376,9 @@ test(crypto.generateKeyPairSync('dh', { group: 'modp5' }),
'RQD0QogW7ejSwMG8hCYibfrvMm0b5PHlwimISyEKh7VtDQ1frYN/Wr9ZbiV+FePJ\n' +
'2j6RUKYNj1Pv+B4zdMgiLLjILAs8WUfbHciU21KSJh1izVQaUQ==\n' +
'-----END PRIVATE KEY-----'
- });
- const shortPublicKey = crypto.createPublicKey({
- key: '-----BEGIN PUBLIC KEY-----\n' +
+ });
+ const shortPublicKey = crypto.createPublicKey({
+ key: '-----BEGIN PUBLIC KEY-----\n' +
'MIIBoDCB1QYJKoZIhvcNAQMBMIHHAoHBAP//////////yQ/aoiFowjTExmKLgNwc\n' +
'0SkCTgiKZ8x0Agu+pjsTmyJRSgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHC\n' +
'ReSFtXZiXn7G9ExC6aY37WsL/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7ORb\n' +
@@ -368,19 +389,20 @@ test(crypto.generateKeyPairSync('dh', { group: 'modp5' }),
'taGX4mP3247golVx2DS4viDYs7UtaMdx03dWaP6y5StNUZQlgCIUzL7MYpC16V5y\n' +
'KkFrE+Kp/Z77gEjivaG6YuxVj4GPLxJYbNFVTel42oSVeKuq\n' +
'-----END PUBLIC KEY-----',
- format: 'pem'
- });
+ format: 'pem'
+ });
- testDH({ publicKey: shortPublicKey, privateKey: shortPrivateKey },
- Buffer.from(
- '0099d0fa242af5db9ea7330e23937a27db041f79c581500fc7f9976' +
+ testDH({ publicKey: shortPublicKey, privateKey: shortPrivateKey },
+ Buffer.from(
+ '0099d0fa242af5db9ea7330e23937a27db041f79c581500fc7f9976' +
'554d59d5b9ced934778d72e19a1fefc81e9d981013198748c0b5c6c' +
'762985eec687dc5bec5c9367b05837daee9d0bcc29024ed7f3abba1' +
'2794b65a745117fb0d87bc5b1b2b68c296c3f686cc29e450e4e1239' +
- '21f56a5733fe58aabf71f14582954059c2185d342b9b0fa10c2598a' +
- '5426c2baee7f9a686fc1e16cd4757c852bf7225a2732250548efe28' +
- 'debc26f1acdec51efe23d20786a6f8a14d360803bbc71972e87fd3',
- 'hex'));
+ '21f56a5733fe58aabf71f14582954059c2185d342b9b0fa10c2598a' +
+ '5426c2baee7f9a686fc1e16cd4757c852bf7225a2732250548efe28' +
+ 'debc26f1acdec51efe23d20786a6f8a14d360803bbc71972e87fd3',
+ 'hex'));
+ }
}
// Test ECDH.
@@ -401,20 +423,25 @@ test(crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' }),
});
}
-test(crypto.generateKeyPairSync('x448'),
- crypto.generateKeyPairSync('x448'));
+if (isBoringSSL) {
+ common.printSkipMessage('Skipping x448 diffieHellman test cases ' +
+ 'unsupported by BoringSSL');
+} else {
+ test(crypto.generateKeyPairSync('x448'),
+ crypto.generateKeyPairSync('x448'));
+
+ {
+ const options = {
+ privateKey: crypto.generateKeyPairSync('x448').privateKey,
+ publicKey: crypto.generateKeyPairSync('x25519').publicKey,
+ };
+ testDHError(options, { code: keyTypeMismatchCode });
+ }
+}
test(crypto.generateKeyPairSync('x25519'),
crypto.generateKeyPairSync('x25519'));
-{
- const options = {
- privateKey: crypto.generateKeyPairSync('x448').privateKey,
- publicKey: crypto.generateKeyPairSync('x25519').publicKey,
- };
- testDHError(options, { code: keyTypeMismatchCode });
-}
-
// Test all key encoding formats
for (const { privateKey: alicePriv, publicKey: bobPub } of [
crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' }),
@@ -514,7 +541,7 @@ for (const { privateKey: alicePriv, publicKey: bobPub } of [
{
const ec256 = crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' });
const ec384 = crypto.generateKeyPairSync('ec', { namedCurve: 'P-384' });
- const x448 = crypto.generateKeyPairSync('x448');
+ const x448 = isBoringSSL ? null : crypto.generateKeyPairSync('x448');
const x25519 = crypto.generateKeyPairSync('x25519');
const ed25519 = crypto.generateKeyPairSync('ed25519');
@@ -564,18 +591,21 @@ for (const { privateKey: alicePriv, publicKey: bobPub } of [
/^ERR_OSSL_EVP_(OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE|INTERNAL_ERROR)$/ :
'ERR_OSSL_EVP_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE' });
- // Incompatible key types (x448 + x25519)
- testDHError({
- privateKey: privKey(x448.privateKey),
- publicKey: pubKey(x25519.publicKey),
- }, { code: keyTypeMismatchCode });
+ if (!isBoringSSL) {
+ // Incompatible key types (x448 + x25519)
+ testDHError({
+ privateKey: privKey(x448.privateKey),
+ publicKey: pubKey(x25519.publicKey),
+ }, { code: keyTypeMismatchCode });
+ }
// Zero x25519 public key
testDHError({
privateKey: privKey(x25519.privateKey),
publicKey: pubKey(zeroX25519PublicKey),
- }, hasOpenSSL(3) ?
- { code: 'ERR_OSSL_FAILED_DURING_DERIVATION' } :
- { message: /Deriving bits failed/ });
+ }, isBoringSSL ? { code: 'ERR_OSSL_EVP_INVALID_PEER_KEY' } :
+ hasOpenSSL(3) ?
+ { code: 'ERR_OSSL_FAILED_DURING_DERIVATION' } :
+ { message: /Deriving bits failed/ });
}
}
diff --git a/test/parallel/test-crypto-keygen.js b/test/parallel/test-crypto-keygen.js
index 7911520af34481..751029e1921edb 100644
--- a/test/parallel/test-crypto-keygen.js
+++ b/test/parallel/test-crypto-keygen.js
@@ -15,6 +15,7 @@ const {
const { inspect } = require('util');
const { hasOpenSSL3 } = require('../common/crypto');
+const isBoringSSL = process.features.openssl_is_boringssl;
// Test invalid parameter encoding.
{
@@ -361,13 +362,24 @@ const { hasOpenSSL3 } = require('../common/crypto');
// Test invalid exponents. (caught by OpenSSL)
for (const publicExponent of [1, 1 + 0x10001]) {
- generateKeyPair('rsa', {
- modulusLength: 4096,
- publicExponent
- }, common.mustCall((err) => {
- assert.strictEqual(err.name, 'Error');
- assert.match(err.message, hasOpenSSL3 ? /exponent/ : /bad e value/);
- }));
+ if (isBoringSSL) {
+ assert.throws(() => generateKeyPair('rsa', {
+ modulusLength: 4096,
+ publicExponent
+ }, common.mustNotCall()), {
+ name: 'RangeError',
+ code: 'ERR_OUT_OF_RANGE',
+ message: 'publicExponent is invalid',
+ });
+ } else {
+ generateKeyPair('rsa', {
+ modulusLength: 4096,
+ publicExponent
+ }, common.mustCall((err) => {
+ assert.strictEqual(err.name, 'Error');
+ assert.match(err.message, hasOpenSSL3 ? /exponent/ : /bad e value/);
+ }));
+ }
}
}
@@ -494,16 +506,21 @@ const { hasOpenSSL3 } = require('../common/crypto');
});
}));
- generateKeyPair('ec', {
- namedCurve: 'secp256k1',
- }, common.mustSucceed((publicKey, privateKey) => {
- assert.deepStrictEqual(publicKey.asymmetricKeyDetails, {
- namedCurve: 'secp256k1'
- });
- assert.deepStrictEqual(privateKey.asymmetricKeyDetails, {
- namedCurve: 'secp256k1'
- });
- }));
+ if (isBoringSSL) {
+ common.printSkipMessage('Skipping secp256k1 keygen test case ' +
+ 'unsupported by BoringSSL');
+ } else {
+ generateKeyPair('ec', {
+ namedCurve: 'secp256k1',
+ }, common.mustSucceed((publicKey, privateKey) => {
+ assert.deepStrictEqual(publicKey.asymmetricKeyDetails, {
+ namedCurve: 'secp256k1'
+ });
+ assert.deepStrictEqual(privateKey.asymmetricKeyDetails, {
+ namedCurve: 'secp256k1'
+ });
+ }));
+ }
}
{
diff --git a/test/parallel/test-crypto.js b/test/parallel/test-crypto.js
index fbb065dd442876..46f4571b33dfe8 100644
--- a/test/parallel/test-crypto.js
+++ b/test/parallel/test-crypto.js
@@ -62,7 +62,7 @@ assert.throws(() => {
// Throws general Error, so there is no opensslErrorStack property.
return err instanceof Error &&
err.name === 'Error' &&
- /^Error: mac verify failure$/.test(err) &&
+ /^Error: (mac verify failure|INCORRECT_PASSWORD)$/.test(err) &&
!('opensslErrorStack' in err);
});
@@ -72,7 +72,7 @@ assert.throws(() => {
// Throws general Error, so there is no opensslErrorStack property.
return err instanceof Error &&
err.name === 'Error' &&
- /^Error: mac verify failure$/.test(err) &&
+ /^Error: (mac verify failure|INCORRECT_PASSWORD)$/.test(err) &&
!('opensslErrorStack' in err);
});
@@ -82,7 +82,7 @@ assert.throws(() => {
// Throws general Error, so there is no opensslErrorStack property.
return err instanceof Error &&
err.name === 'Error' &&
- /^Error: not enough data$/.test(err) &&
+ /^Error: (not enough data|BAD_PKCS12_DATA)$/.test(err) &&
!('opensslErrorStack' in err);
});
@@ -211,49 +211,72 @@ assert.throws(() => {
].join('\n');
crypto.createSign('SHA256').update('test').sign(priv);
}, (err) => {
- if (!hasOpenSSL3)
- assert.ok(!('opensslErrorStack' in err));
- assert.throws(() => { throw err; }, hasOpenSSL3 ? {
- name: 'Error',
- message: 'error:02000070:rsa routines::digest too big for rsa key',
- library: 'rsa routines',
- } : {
- name: 'Error',
- message: /routines:RSA_sign:digest too big for rsa key$/,
- library: /rsa routines/i,
- function: 'RSA_sign',
- reason: /digest[\s_]too[\s_]big[\s_]for[\s_]rsa[\s_]key/i,
- code: 'ERR_OSSL_RSA_DIGEST_TOO_BIG_FOR_RSA_KEY'
- });
+ if (process.features.openssl_is_boringssl) {
+ // BoringSSL rejects the tiny RSA key while decoding it, before signing.
+ assert.throws(() => { throw err; }, {
+ name: 'Error',
+ message: 'error:06000066:public key routines:OPENSSL_internal:' +
+ 'DECODE_ERROR',
+ library: 'public key routines',
+ function: 'OPENSSL_internal',
+ reason: 'DECODE_ERROR',
+ code: 'ERR_OSSL_EVP_DECODE_ERROR'
+ });
+ assert(Array.isArray(err.opensslErrorStack));
+ assert(err.opensslErrorStack.length > 0);
+ } else {
+ if (!hasOpenSSL3)
+ assert.ok(!('opensslErrorStack' in err));
+ assert.throws(() => { throw err; }, hasOpenSSL3 ? {
+ name: 'Error',
+ message: 'error:02000070:rsa routines::digest too big for rsa key',
+ library: 'rsa routines',
+ } : {
+ name: 'Error',
+ message: /routines:RSA_sign:digest too big for rsa key$/,
+ library: /rsa routines/i,
+ function: 'RSA_sign',
+ reason: /digest[\s_]too[\s_]big[\s_]for[\s_]rsa[\s_]key/i,
+ code: 'ERR_OSSL_RSA_DIGEST_TOO_BIG_FOR_RSA_KEY'
+ });
+ }
return true;
});
if (!hasOpenSSL3) {
- assert.throws(() => {
- // The correct header inside `rsa_private_pkcs8_bad.pem` should have been
- // -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----
- // instead of
- // -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY-----
- const sha1_privateKey = fixtures.readKey('rsa_private_pkcs8_bad.pem',
- 'ascii');
- // This would inject errors onto OpenSSL's error stack
- crypto.createSign('sha1').sign(sha1_privateKey);
- }, (err) => {
- // Do the standard checks, but then do some custom checks afterwards.
- assert.throws(() => { throw err; }, {
- message: 'error:0D0680A8:asn1 encoding routines:asn1_check_tlen:' +
- 'wrong tag',
- library: 'asn1 encoding routines',
- function: 'asn1_check_tlen',
- reason: 'wrong tag',
- code: 'ERR_OSSL_ASN1_WRONG_TAG',
+ // The correct header inside `rsa_private_pkcs8_bad.pem` should have been
+ // -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----
+ // instead of
+ // -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY-----
+ const sha1_privateKey = fixtures.readKey('rsa_private_pkcs8_bad.pem',
+ 'ascii');
+
+ if (process.features.openssl_is_boringssl) {
+ // BoringSSL accepts the PKCS#8 payload despite the legacy PEM label.
+ const signature = crypto.createSign('sha1').sign(sha1_privateKey);
+ assert(Buffer.isBuffer(signature));
+ assert.strictEqual(signature.length, 256);
+ } else {
+ assert.throws(() => {
+ // This would inject errors onto OpenSSL's error stack
+ crypto.createSign('sha1').sign(sha1_privateKey);
+ }, (err) => {
+ // Do the standard checks, but then do some custom checks afterwards.
+ assert.throws(() => { throw err; }, {
+ message: 'error:0D0680A8:asn1 encoding routines:asn1_check_tlen:' +
+ 'wrong tag',
+ library: 'asn1 encoding routines',
+ function: 'asn1_check_tlen',
+ reason: 'wrong tag',
+ code: 'ERR_OSSL_ASN1_WRONG_TAG',
+ });
+ // Throws crypto error, so there is an opensslErrorStack property.
+ // The openSSL stack should have content.
+ assert(Array.isArray(err.opensslErrorStack));
+ assert(err.opensslErrorStack.length > 0);
+ return true;
});
- // Throws crypto error, so there is an opensslErrorStack property.
- // The openSSL stack should have content.
- assert(Array.isArray(err.opensslErrorStack));
- assert(err.opensslErrorStack.length > 0);
- return true;
- });
+ }
}
// Make sure memory isn't released before being returned
diff --git a/test/parallel/test-https-agent-session-reuse.js b/test/parallel/test-https-agent-session-reuse.js
index 485f4b1ca308c9..c5b7b78b8e0272 100644
--- a/test/parallel/test-https-agent-session-reuse.js
+++ b/test/parallel/test-https-agent-session-reuse.js
@@ -5,6 +5,11 @@ const assert = require('assert');
if (!common.hasCrypto)
common.skip('missing crypto');
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testTls13SessionTicketSemanticsDiffer();
+ return;
+}
+
const https = require('https');
const crypto = require('crypto');
const fixtures = require('../common/fixtures');
diff --git a/test/parallel/test-https-client-renegotiation-limit.js b/test/parallel/test-https-client-renegotiation-limit.js
index 6614090e737614..729176b7c1aa21 100644
--- a/test/parallel/test-https-client-renegotiation-limit.js
+++ b/test/parallel/test-https-client-renegotiation-limit.js
@@ -25,6 +25,11 @@ if (!common.hasCrypto) {
common.skip('missing crypto');
}
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testRenegotiationUnsupported();
+ return;
+}
+
const assert = require('assert');
const tls = require('tls');
const https = require('https');
diff --git a/test/parallel/test-https-foafssl.js b/test/parallel/test-https-foafssl.js
index ffa44f218b935d..a191bdcf32b73e 100644
--- a/test/parallel/test-https-foafssl.js
+++ b/test/parallel/test-https-foafssl.js
@@ -56,8 +56,8 @@ const server = https.createServer(options, common.mustCall(function(req, res) {
cert = req.connection.getPeerCertificate();
assert.strictEqual(cert.subjectaltname, webIdUrl);
- assert.strictEqual(cert.exponent, exponent);
- assert.strictEqual(cert.modulus, modulus);
+ assert.strictEqual(cert.exponent.toLowerCase(), exponent.toLowerCase());
+ assert.strictEqual(cert.modulus.toLowerCase(), modulus.toLowerCase());
res.writeHead(200, { 'content-type': 'text/plain' });
res.end(body, () => { console.log('stream finished'); });
console.log('sent response');
diff --git a/test/parallel/test-https-options-boolean-check.js b/test/parallel/test-https-options-boolean-check.js
index 9740704e169f1e..fa02a165b80f10 100644
--- a/test/parallel/test-https-options-boolean-check.js
+++ b/test/parallel/test-https-options-boolean-check.js
@@ -40,9 +40,23 @@ const keyDataView = toDataView(keyBuff);
const certDataView = toDataView(certBuff);
const caArrDataView = toDataView(caCert);
+function filterBoringSSLKeyCertArrayCases(options, setName) {
+ if (!process.features.openssl_is_boringssl)
+ return options;
+
+ // The array-valued cases exercise multi-identity key/cert handling.
+ // BoringSSL may reject those cases with backend key/cert mismatch errors
+ // before the boolean/type validation this test is targeting. Keep the scalar
+ // cases so https.createServer() option type validation is still covered.
+ common.printSkipMessage(
+ `BoringSSL: skipping ${setName} key/cert array cases`);
+ return options.filter(([key, cert]) => !Array.isArray(key) &&
+ !Array.isArray(cert));
+}
+
// Checks to ensure https.createServer doesn't throw an error
// Format ['key', 'cert']
-[
+const validOptions = [
[keyBuff, certBuff],
[false, certBuff],
[keyBuff, false],
@@ -62,13 +76,16 @@ const caArrDataView = toDataView(caCert);
[false, [certStr, certStr2]],
[[{ pem: keyBuff }], false],
[[{ pem: keyBuff }, { pem: keyBuff }], false],
-].forEach(([key, cert]) => {
- https.createServer({ key, cert });
-});
+];
+
+filterBoringSSLKeyCertArrayCases(validOptions, 'valid')
+ .forEach(([key, cert]) => {
+ https.createServer({ key, cert });
+ });
// Checks to ensure https.createServer predictably throws an error
// Format ['key', 'cert', 'expected message']
-[
+const invalidKeyOptions = [
[true, certBuff],
[true, certStr],
[true, certArrBuff],
@@ -81,7 +98,10 @@ const caArrDataView = toDataView(caCert);
[[true, keyStr2], [certStr, certStr2], 0],
[[true, false], [certBuff, certBuff2], 0],
[true, [certBuff, certBuff2]],
-].forEach(([key, cert, index]) => {
+];
+
+for (const [key, cert, index] of
+ filterBoringSSLKeyCertArrayCases(invalidKeyOptions, 'invalid key')) {
const val = index === undefined ? key : key[index];
assert.throws(() => {
https.createServer({ key, cert });
@@ -92,9 +112,9 @@ const caArrDataView = toDataView(caCert);
'instance of Buffer, TypedArray, or DataView.' +
common.invalidArgTypeHelper(val)
});
-});
+}
-[
+const invalidCertOptions = [
[keyBuff, true],
[keyStr, true],
[keyArrBuff, true],
@@ -107,7 +127,10 @@ const caArrDataView = toDataView(caCert);
[[keyStr, keyStr2], [certStr, true], 1],
[[keyStr, keyStr2], [true, false], 0],
[[keyStr, keyStr2], true],
-].forEach(([key, cert, index]) => {
+];
+
+for (const [key, cert, index] of
+ filterBoringSSLKeyCertArrayCases(invalidCertOptions, 'invalid cert')) {
const val = index === undefined ? cert : cert[index];
assert.throws(() => {
https.createServer({ key, cert });
@@ -118,7 +141,7 @@ const caArrDataView = toDataView(caCert);
'instance of Buffer, TypedArray, or DataView.' +
common.invalidArgTypeHelper(val)
});
-});
+}
// Checks to ensure https.createServer works with the CA parameter
// Format ['key', 'cert', 'ca']
diff --git a/test/parallel/test-tls-alert.js b/test/parallel/test-tls-alert.js
index 23c92e7293458f..64b7080e39ba25 100644
--- a/test/parallel/test-tls-alert.js
+++ b/test/parallel/test-tls-alert.js
@@ -48,6 +48,33 @@ const server = tls.Server({
key: loadPEM('agent2-key'),
cert: loadPEM('agent2-cert')
}, null).listen(0, common.mustCall(() => {
+ if (process.features.openssl_is_boringssl) {
+ let gotClientError = false;
+ let gotServerError = false;
+ function maybeClose() {
+ if (gotClientError && gotServerError)
+ server.close();
+ }
+
+ server.once('tlsClientError', common.mustCall((err) => {
+ assert.strictEqual(err.code, 'ERR_SSL_UNSUPPORTED_PROTOCOL');
+ gotServerError = true;
+ maybeClose();
+ }));
+
+ const client = tls.connect({
+ port: server.address().port,
+ rejectUnauthorized: false,
+ secureProtocol: 'TLSv1_1_method',
+ }, common.mustNotCall());
+ client.once('error', common.mustCall((err) => {
+ assert.strictEqual(err.code, 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION');
+ gotClientError = true;
+ maybeClose();
+ }));
+ return;
+ }
+
const args = ['s_client', '-quiet', '-tls1_1',
'-cipher', (hasOpenSSL(3, 1) ? 'DEFAULT:@SECLEVEL=0' : 'DEFAULT'),
'-connect', `127.0.0.1:${server.address().port}`];
diff --git a/test/parallel/test-tls-client-auth.js b/test/parallel/test-tls-client-auth.js
index 67aed40914c9fe..517054c6e290dc 100644
--- a/test/parallel/test-tls-client-auth.js
+++ b/test/parallel/test-tls-client-auth.js
@@ -111,7 +111,10 @@ if (tls.DEFAULT_MAX_VERSION === 'TLSv1.3') connect({
// and sends a fatal Alert to the client that the client discovers there has
// been a fatal error.
pair.client.conn.once('error', common.mustCall((err) => {
- assert.strictEqual(err.code, 'ERR_SSL_TLSV13_ALERT_CERTIFICATE_REQUIRED');
+ const expectedErr = process.features.openssl_is_boringssl ?
+ 'ERR_SSL_TLSV1_ALERT_CERTIFICATE_REQUIRED' :
+ 'ERR_SSL_TLSV13_ALERT_CERTIFICATE_REQUIRED';
+ assert.strictEqual(err.code, expectedErr);
cleanup();
}));
}));
diff --git a/test/parallel/test-tls-client-getephemeralkeyinfo.js b/test/parallel/test-tls-client-getephemeralkeyinfo.js
index 19728e3733d868..2107d024012c4d 100644
--- a/test/parallel/test-tls-client-getephemeralkeyinfo.js
+++ b/test/parallel/test-tls-client-getephemeralkeyinfo.js
@@ -2,6 +2,12 @@
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
+
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testEphemeralKeyInfoUnsupported();
+ return;
+}
+
const fixtures = require('../common/fixtures');
const { hasOpenSSL } = require('../common/crypto');
diff --git a/test/parallel/test-tls-client-mindhsize.js b/test/parallel/test-tls-client-mindhsize.js
index cd7b16ea566fe8..fa494c583a2f3b 100644
--- a/test/parallel/test-tls-client-mindhsize.js
+++ b/test/parallel/test-tls-client-mindhsize.js
@@ -85,21 +85,25 @@ function testDHE3072() {
test(3072, false, null);
}
-if (hasOpenSSL(4, 0)) {
- // OpenSSL 4.0 implements RFC 7919 FFDHE negotiation for TLS 1.2 and
- // ignores the server-supplied dhparam in favor of FFDHE-2048. The 3072
- // success case is therefore replaced by a 2048 success case.
- testDHE2048(true, () => test(2048, false, null, 2048));
-} else if (secLevel > 1) {
- // Minimum size for OpenSSL security level 2 and above is 2048 by default
- testDHE2048(true, testDHE3072);
+if (!process.features.openssl_is_boringssl) {
+ if (hasOpenSSL(4, 0)) {
+ // OpenSSL 4.0 implements RFC 7919 FFDHE negotiation for TLS 1.2 and
+ // ignores the server-supplied dhparam in favor of FFDHE-2048. The 3072
+ // success case is therefore replaced by a 2048 success case.
+ testDHE2048(true, () => test(2048, false, null, 2048));
+ } else if (secLevel > 1) {
+ // Minimum size for OpenSSL security level 2 and above is 2048 by default
+ testDHE2048(true, testDHE3072);
+ } else {
+ testDHE1024();
+ }
+
+ assert.throws(() => test(512, true, common.mustNotCall()),
+ /DH parameter is less than 1024 bits/);
} else {
- testDHE1024();
+ require('../common/boringssl').assertFiniteFieldDheUnsupported();
}
-assert.throws(() => test(512, true, common.mustNotCall()),
- /DH parameter is less than 1024 bits/);
-
for (const minDHSize of [0, -1, -Infinity, NaN]) {
assert.throws(() => {
tls.connect({ minDHSize });
@@ -118,7 +122,9 @@ for (const minDHSize of [true, false, null, undefined, {}, [], '', '1']) {
});
}
-process.on('exit', function() {
- assert.strictEqual(nsuccess, 1);
- assert.strictEqual(nerror, 1);
-});
+if (!process.features.openssl_is_boringssl) {
+ process.on('exit', function() {
+ assert.strictEqual(nsuccess, 1);
+ assert.strictEqual(nerror, 1);
+ });
+}
diff --git a/test/parallel/test-tls-client-reject.js b/test/parallel/test-tls-client-reject.js
index 68922e3690eac0..cff0aabc89a774 100644
--- a/test/parallel/test-tls-client-reject.js
+++ b/test/parallel/test-tls-client-reject.js
@@ -30,7 +30,8 @@ const fixtures = require('../common/fixtures');
const options = {
key: fixtures.readKey('rsa_private.pem'),
- cert: fixtures.readKey('rsa_cert.crt')
+ cert: fixtures.readKey('rsa_cert.crt'),
+ ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}),
};
const server = tls.createServer(options, function(socket) {
@@ -46,7 +47,8 @@ function unauthorized() {
const socket = tls.connect({
port: server.address().port,
servername: 'localhost',
- rejectUnauthorized: false
+ rejectUnauthorized: false,
+ ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}),
}, common.mustCall(function() {
let _data;
assert(!socket.authorized);
@@ -67,7 +69,8 @@ function unauthorized() {
function rejectUnauthorized() {
console.log('reject unauthorized');
const socket = tls.connect(server.address().port, {
- servername: 'localhost'
+ servername: 'localhost',
+ ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}),
}, common.mustNotCall());
socket.on('data', common.mustNotCall());
socket.on('error', common.mustCall(function(err) {
@@ -80,7 +83,8 @@ function rejectUnauthorizedUndefined() {
console.log('reject unauthorized undefined');
const socket = tls.connect(server.address().port, {
servername: 'localhost',
- rejectUnauthorized: undefined
+ rejectUnauthorized: undefined,
+ ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}),
}, common.mustNotCall());
socket.on('data', common.mustNotCall());
socket.on('error', common.mustCall(function(err) {
@@ -93,7 +97,8 @@ function authorized() {
console.log('connect authorized');
const socket = tls.connect(server.address().port, {
ca: [fixtures.readKey('rsa_cert.crt')],
- servername: 'localhost'
+ servername: 'localhost',
+ ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}),
}, common.mustCall(function() {
console.log('... authorized');
assert(socket.authorized);
diff --git a/test/parallel/test-tls-client-renegotiation-13.js b/test/parallel/test-tls-client-renegotiation-13.js
index 5afa8389ed37ca..80c4753d065ec1 100644
--- a/test/parallel/test-tls-client-renegotiation-13.js
+++ b/test/parallel/test-tls-client-renegotiation-13.js
@@ -32,14 +32,22 @@ connect({
assert.strictEqual(client.getProtocol(), 'TLSv1.3');
const ok = client.renegotiate({}, common.mustCall((err) => {
- assert.throws(() => { throw err; }, {
- message: hasOpenSSL3 ?
- 'error:0A00010A:SSL routines::wrong ssl version' :
- 'error:1420410A:SSL routines:SSL_renegotiate:wrong ssl version',
- code: 'ERR_SSL_WRONG_SSL_VERSION',
- library: 'SSL routines',
- reason: 'wrong ssl version',
- });
+ if (process.features.openssl_is_boringssl) {
+ assert.throws(() => { throw err; }, {
+ message: 'TLS session renegotiation is unsupported by this TLS ' +
+ 'implementation',
+ code: 'ERR_TLS_RENEGOTIATION_UNSUPPORTED',
+ });
+ } else {
+ assert.throws(() => { throw err; }, {
+ message: hasOpenSSL3 ?
+ 'error:0A00010A:SSL routines::wrong ssl version' :
+ 'error:1420410A:SSL routines:SSL_renegotiate:wrong ssl version',
+ code: 'ERR_SSL_WRONG_SSL_VERSION',
+ library: 'SSL routines',
+ reason: 'wrong ssl version',
+ });
+ }
cleanup();
}));
diff --git a/test/parallel/test-tls-client-renegotiation-limit.js b/test/parallel/test-tls-client-renegotiation-limit.js
index 86111d6da0b402..9b7f62865b336d 100644
--- a/test/parallel/test-tls-client-renegotiation-limit.js
+++ b/test/parallel/test-tls-client-renegotiation-limit.js
@@ -31,6 +31,11 @@ if (!opensslCli) {
common.skip('node compiled without OpenSSL CLI.');
}
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testRenegotiationUnsupported();
+ return;
+}
+
const assert = require('assert');
const tls = require('tls');
const fixtures = require('../common/fixtures');
diff --git a/test/parallel/test-tls-dhe.js b/test/parallel/test-tls-dhe.js
index 03750bc206adbe..b788d153293899 100644
--- a/test/parallel/test-tls-dhe.js
+++ b/test/parallel/test-tls-dhe.js
@@ -26,6 +26,11 @@ if (!common.hasCrypto) {
common.skip('missing crypto');
}
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').assertFiniteFieldDheUnsupported();
+ return;
+}
+
const {
opensslCli,
hasOpenSSL,
diff --git a/test/parallel/test-tls-disable-renegotiation.js b/test/parallel/test-tls-disable-renegotiation.js
index f91868c6345d71..84a6ead4a5441c 100644
--- a/test/parallel/test-tls-disable-renegotiation.js
+++ b/test/parallel/test-tls-disable-renegotiation.js
@@ -8,6 +8,11 @@ const fixtures = require('../common/fixtures');
if (!common.hasCrypto)
common.skip('missing crypto');
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testRenegotiationUnsupported();
+ return;
+}
+
const tls = require('tls');
// Renegotiation as a protocol feature was dropped after TLS1.2.
diff --git a/test/parallel/test-tls-ecdh-multiple.js b/test/parallel/test-tls-ecdh-multiple.js
index ee52f288610956..ed60044197d7da 100644
--- a/test/parallel/test-tls-ecdh-multiple.js
+++ b/test/parallel/test-tls-ecdh-multiple.js
@@ -26,7 +26,7 @@ function loadPEM(n) {
// OpenSSL 4.0 disables support for deprecated elliptic curves from RFC 8422
// (including secp256k1) by default.
-const ecdhCurve = hasOpenSSL(4, 0) ?
+const ecdhCurve = process.features.openssl_is_boringssl || hasOpenSSL(4, 0) ?
'prime256v1:secp521r1' :
'secp256k1:prime256v1:secp521r1';
@@ -67,7 +67,7 @@ const server = tls.createServer(options, (conn) => {
}
// Deprecated RFC 8422 curves are disabled by default in OpenSSL 4.0.
- if (hasOpenSSL(4, 0)) {
+ if (process.features.openssl_is_boringssl || hasOpenSSL(4, 0)) {
unsupportedCurves.push('secp256k1');
}
diff --git a/test/parallel/test-tls-empty-sni-context.js b/test/parallel/test-tls-empty-sni-context.js
index e4136ff71e1d52..6ecdfbeecbe3c9 100644
--- a/test/parallel/test-tls-empty-sni-context.js
+++ b/test/parallel/test-tls-empty-sni-context.js
@@ -16,7 +16,7 @@ const options = {
const server = tls.createServer(options, (c) => {
assert.fail('Should not be called');
}).on('tlsClientError', common.mustCall((err, c) => {
- assert.match(err.message, /no suitable signature algorithm/i);
+ assert.match(err.message, /no suitable signature algorithm|NO_CERTIFICATE_SET/i);
server.close();
})).listen(0, common.mustCall(() => {
const c = tls.connect({
@@ -26,9 +26,10 @@ const server = tls.createServer(options, (c) => {
}, common.mustNotCall());
c.on('error', common.mustCall((err) => {
- const expectedErr = hasOpenSSL(4, 0) ?
- 'ERR_SSL_TLS_ALERT_HANDSHAKE_FAILURE' : hasOpenSSL(3, 2) ?
- 'ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE' : 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE';
+ const expectedErr = process.features.openssl_is_boringssl ?
+ 'ERR_SSL_TLSV1_ALERT_INTERNAL_ERROR' : hasOpenSSL(4, 0) ?
+ 'ERR_SSL_TLS_ALERT_HANDSHAKE_FAILURE' : hasOpenSSL(3, 2) ?
+ 'ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE' : 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE';
assert.strictEqual(err.code, expectedErr);
}));
}));
diff --git a/test/parallel/test-tls-finished.js b/test/parallel/test-tls-finished.js
index 8b52934b049d95..b23b4567d27ec6 100644
--- a/test/parallel/test-tls-finished.js
+++ b/test/parallel/test-tls-finished.js
@@ -20,7 +20,8 @@ const msg = {};
const pem = (n) => fixtures.readKey(`${n}.pem`);
const server = tls.createServer({
key: pem('agent1-key'),
- cert: pem('agent1-cert')
+ cert: pem('agent1-cert'),
+ ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}),
}, common.mustCall((alice) => {
msg.server = {
alice: alice.getFinished(),
@@ -32,7 +33,8 @@ const server = tls.createServer({
server.listen(0, common.mustCall(() => {
const bob = tls.connect({
port: server.address().port,
- rejectUnauthorized: false
+ rejectUnauthorized: false,
+ ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}),
}, common.mustCall(() => {
msg.client = {
alice: bob.getPeerFinished(),
diff --git a/test/parallel/test-tls-getcipher.js b/test/parallel/test-tls-getcipher.js
index 4d5042d6e6beab..2d4de5639afb70 100644
--- a/test/parallel/test-tls-getcipher.js
+++ b/test/parallel/test-tls-getcipher.js
@@ -36,27 +36,42 @@ const options = {
honorCipherOrder: true
};
+const isBoringSSL = process.features.openssl_is_boringssl;
let clients = 0;
+const expectedClients = isBoringSSL ? 1 : 2;
const server = tls.createServer(options, common.mustCall(() => {
if (--clients === 0)
server.close();
-}, 2));
+}, expectedClients));
server.listen(0, '127.0.0.1', common.mustCall(function() {
- clients++;
- tls.connect({
- host: '127.0.0.1',
- port: this.address().port,
- ciphers: 'AES256-SHA256',
- rejectUnauthorized: false,
- maxVersion: 'TLSv1.2',
- }, common.mustCall(function() {
- const cipher = this.getCipher();
- assert.strictEqual(cipher.name, 'AES256-SHA256');
- assert.strictEqual(cipher.standardName, 'TLS_RSA_WITH_AES_256_CBC_SHA256');
- assert.strictEqual(cipher.version, 'TLSv1.2');
- this.end();
- }));
+ if (isBoringSSL) {
+ // BoringSSL does not provide this static RSA TLS 1.2 cipher suite on
+ // Node's supported cipher surface, so keep the OpenSSL getCipher()
+ // assertion below limited to backends that can create the context.
+ common.printSkipMessage('BoringSSL does not provide AES256-SHA256');
+ assert.throws(() => tls.createSecureContext({ ciphers: 'AES256-SHA256' }), {
+ code: 'ERR_SSL_NO_CIPHER_MATCH',
+ library: 'SSL routines',
+ function: 'OPENSSL_internal',
+ reason: 'NO_CIPHER_MATCH',
+ });
+ } else {
+ clients++;
+ tls.connect({
+ host: '127.0.0.1',
+ port: this.address().port,
+ ciphers: 'AES256-SHA256',
+ rejectUnauthorized: false,
+ maxVersion: 'TLSv1.2',
+ }, common.mustCall(function() {
+ const cipher = this.getCipher();
+ assert.strictEqual(cipher.name, 'AES256-SHA256');
+ assert.strictEqual(cipher.standardName, 'TLS_RSA_WITH_AES_256_CBC_SHA256');
+ assert.strictEqual(cipher.version, 'TLSv1.2');
+ this.end();
+ }));
+ }
clients++;
tls.connect({
@@ -70,7 +85,9 @@ server.listen(0, '127.0.0.1', common.mustCall(function() {
assert.strictEqual(cipher.name, 'ECDHE-RSA-AES256-GCM-SHA384');
assert.strictEqual(cipher.standardName,
'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384');
- assert.strictEqual(cipher.version, 'TLSv1.2');
+ assert.strictEqual(cipher.version, isBoringSSL ?
+ 'TLSv1/SSLv3' :
+ 'TLSv1.2');
this.end();
}));
}));
@@ -90,9 +107,14 @@ tls.createServer({
rejectUnauthorized: false
}, common.mustCall(() => {
const cipher = client.getCipher();
- assert.strictEqual(cipher.name, 'TLS_AES_256_GCM_SHA384');
+ const expectedCipher = isBoringSSL ?
+ 'TLS_AES_128_GCM_SHA256' :
+ 'TLS_AES_256_GCM_SHA384';
+ assert.strictEqual(cipher.name, expectedCipher);
assert.strictEqual(cipher.standardName, cipher.name);
- assert.strictEqual(cipher.version, 'TLSv1.3');
+ assert.strictEqual(cipher.version, isBoringSSL ?
+ 'TLSv1/SSLv3' :
+ 'TLSv1.3');
client.end();
}));
}));
diff --git a/test/parallel/test-tls-getprotocol.js b/test/parallel/test-tls-getprotocol.js
index 5fe46c43c376cf..2945ff99b5a290 100644
--- a/test/parallel/test-tls-getprotocol.js
+++ b/test/parallel/test-tls-getprotocol.js
@@ -12,7 +12,7 @@ const assert = require('assert');
const tls = require('tls');
const fixtures = require('../common/fixtures');
-const clientConfigs = [
+let clientConfigs = [
{
secureProtocol: 'TLSv1_method',
version: 'TLSv1',
@@ -27,6 +27,14 @@ const clientConfigs = [
},
];
+if (process.features.openssl_is_boringssl) {
+ // Remove the TLSv1 and TLSv1.1 cases. BoringSSL does not negotiate those
+ // legacy protocols in this configuration; keep TLSv1.2 to cover getProtocol()
+ // on a successful BoringSSL TLS handshake.
+ common.printSkipMessage('BoringSSL: skipping TLSv1/TLSv1.1 getProtocol cases');
+ clientConfigs = clientConfigs.filter(({ version }) => version === 'TLSv1.2');
+}
+
const serverConfig = {
secureProtocol: 'TLS_method',
key: fixtures.readKey('agent2-key.pem'),
diff --git a/test/parallel/test-tls-handshake-error.js b/test/parallel/test-tls-handshake-error.js
index 5547964780cd60..94a21a14975b5d 100644
--- a/test/parallel/test-tls-handshake-error.js
+++ b/test/parallel/test-tls-handshake-error.js
@@ -20,7 +20,7 @@ const server = tls.createServer({
port: this.address().port,
ciphers: 'no-such-cipher'
}, common.mustNotCall());
- }, /no cipher match/i);
+ }, /no[_ ]cipher[_ ]match/i);
server.close();
}));
diff --git a/test/parallel/test-tls-honorcipherorder.js b/test/parallel/test-tls-honorcipherorder.js
index 5f123cd739a4c0..d86a59aa4cdc6d 100644
--- a/test/parallel/test-tls-honorcipherorder.js
+++ b/test/parallel/test-tls-honorcipherorder.js
@@ -16,14 +16,40 @@ const util = require('util');
// default method is updated in the future
const SSL_Method = 'TLSv1_2_method';
const localhost = '127.0.0.1';
+const config = process.features.openssl_is_boringssl ? {
+ serverCiphers:
+ 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256',
+ clientPreferenceCiphers:
+ 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384',
+ clientPreferredCipher: 'ECDHE-RSA-AES128-GCM-SHA256',
+ serverPreferredCipher: 'ECDHE-RSA-AES256-GCM-SHA384',
+ singleCipher: 'ECDHE-RSA-AES128-GCM-SHA256',
+ defaultCipher: 'ECDHE-RSA-AES256-GCM-SHA384',
+ limitedDefaultCipher: 'ECDHE-RSA-AES128-GCM-SHA256',
+ extraCases: [],
+} : {
+ serverCiphers: 'AES256-SHA256:AES128-GCM-SHA256:AES128-SHA256:' +
+ 'ECDHE-RSA-AES128-GCM-SHA256',
+ clientPreferenceCiphers: 'AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256',
+ clientPreferredCipher: 'AES128-GCM-SHA256',
+ serverPreferredCipher: 'AES256-SHA256',
+ singleCipher: 'AES128-SHA256',
+ defaultCipher: 'AES256-SHA256',
+ limitedDefaultCipher: 'ECDHE-RSA-AES128-GCM-SHA256',
+ extraCases: [
+ // Server has the preference of cipher suites. AES128-GCM-SHA256 is given
+ // higher priority over AES128-SHA256 among client cipher suites.
+ [true, 'AES128-SHA256:AES128-GCM-SHA256', 'AES128-GCM-SHA256'],
+ [undefined, 'AES128-SHA256:AES128-GCM-SHA256', 'AES128-GCM-SHA256'],
+ ],
+};
function test(honorCipherOrder, clientCipher, expectedCipher, defaultCiphers) {
const soptions = {
secureProtocol: SSL_Method,
key: fixtures.readKey('agent2-key.pem'),
cert: fixtures.readKey('agent2-cert.pem'),
- ciphers: 'AES256-SHA256:AES128-GCM-SHA256:AES128-SHA256:' +
- 'ECDHE-RSA-AES128-GCM-SHA256',
+ ciphers: config.serverCiphers,
honorCipherOrder: honorCipherOrder,
};
@@ -57,34 +83,27 @@ function test(honorCipherOrder, clientCipher, expectedCipher, defaultCiphers) {
}
// Client explicitly has the preference of cipher suites, not the default.
-test(false, 'AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256',
- 'AES128-GCM-SHA256');
+test(false, config.clientPreferenceCiphers, config.clientPreferredCipher);
-// Server has the preference of cipher suites, and AES256-SHA256 is
-// the server's top choice.
-test(true, 'AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256',
- 'AES256-SHA256');
-test(undefined, 'AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256',
- 'AES256-SHA256');
-
-// Server has the preference of cipher suites. AES128-GCM-SHA256 is given
-// higher priority over AES128-SHA256 among client cipher suites.
-test(true, 'AES128-SHA256:AES128-GCM-SHA256', 'AES128-GCM-SHA256');
-test(undefined, 'AES128-SHA256:AES128-GCM-SHA256', 'AES128-GCM-SHA256');
+// Server has the preference of cipher suites.
+test(true, config.clientPreferenceCiphers, config.serverPreferredCipher);
+test(undefined, config.clientPreferenceCiphers, config.serverPreferredCipher);
+for (const args of config.extraCases) {
+ test(...args);
+}
// As client has only one cipher, server has no choice, irrespective
// of honorCipherOrder.
-test(true, 'AES128-SHA256', 'AES128-SHA256');
-test(undefined, 'AES128-SHA256', 'AES128-SHA256');
+test(true, config.singleCipher, config.singleCipher);
+test(undefined, config.singleCipher, config.singleCipher);
-// Client did not explicitly set ciphers and client offers
-// tls.DEFAULT_CIPHERS. All ciphers of the server are included in the
-// default list so the negotiated cipher is selected according to the
-// server's top preference of AES256-SHA256.
-test(true, tls.DEFAULT_CIPHERS, 'AES256-SHA256');
-test(true, null, 'AES256-SHA256');
-test(undefined, null, 'AES256-SHA256');
+// Client did not explicitly set ciphers and client offers tls.DEFAULT_CIPHERS.
+// All ciphers of the server are included in the default list so the negotiated
+// cipher is selected according to server preference.
+test(true, tls.DEFAULT_CIPHERS, config.defaultCipher);
+test(true, null, config.defaultCipher);
+test(undefined, null, config.defaultCipher);
// Ensure that `tls.DEFAULT_CIPHERS` is used when its a limited cipher set.
-test(true, null, 'ECDHE-RSA-AES128-GCM-SHA256', 'ECDHE-RSA-AES128-GCM-SHA256');
+test(true, null, config.limitedDefaultCipher, config.limitedDefaultCipher);
diff --git a/test/parallel/test-tls-junk-server.js b/test/parallel/test-tls-junk-server.js
index 42f089f8f90ed2..b6ff3cd2a467f2 100644
--- a/test/parallel/test-tls-junk-server.js
+++ b/test/parallel/test-tls-junk-server.js
@@ -24,7 +24,7 @@ server.listen(0, common.mustCall(function() {
// Different OpenSSL versions report different errors for junk data on a
// TLS connection, depending on which record validation check fires first.
const expectedErrorMessage =
- /wrong version number|packet length too long|bad record type/;
+ /wrong[ _]version[ _]number|packet length too long|bad record type/i;
req.once('error', common.mustCall(function(err) {
assert.match(err.message, expectedErrorMessage);
server.close();
diff --git a/test/parallel/test-tls-key-mismatch.js b/test/parallel/test-tls-key-mismatch.js
index df8848a03de4a9..797c7c171dc5ff 100644
--- a/test/parallel/test-tls-key-mismatch.js
+++ b/test/parallel/test-tls-key-mismatch.js
@@ -31,9 +31,11 @@ const { hasOpenSSL3 } = require('../common/crypto');
const assert = require('assert');
const tls = require('tls');
-const errorMessageRegex = hasOpenSSL3 ?
- /^Error: error:05800074:x509 certificate routines::key values mismatch$/ :
- /^Error: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch$/;
+const errorMessageRegex = process.features.openssl_is_boringssl ?
+ /^Error: error:0b000074:X\.509 certificate routines:OPENSSL_internal:KEY_VALUES_MISMATCH$/ :
+ hasOpenSSL3 ?
+ /^Error: error:05800074:x509 certificate routines::key values mismatch$/ :
+ /^Error: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch$/;
const options = {
key: fixtures.readKey('agent1-key.pem'),
diff --git a/test/parallel/test-tls-max-send-fragment.js b/test/parallel/test-tls-max-send-fragment.js
index 009021045624bb..2e319fcdaeafea 100644
--- a/test/parallel/test-tls-max-send-fragment.js
+++ b/test/parallel/test-tls-max-send-fragment.js
@@ -60,9 +60,15 @@ const server = tls.createServer({
assert.throws(() => c.setMaxSendFragment(Symbol()), { name: 'TypeError' });
- // Lower and upper limits.
- assert(!c.setMaxSendFragment(511));
- assert(!c.setMaxSendFragment(16385));
+ // OpenSSL enforces Node's documented fragment size range. BoringSSL accepts
+ // both out-of-range values and reports success, so assert that difference
+ // explicitly instead of using a truthiness shortcut.
+ const acceptsOutOfRangeFragmentSize =
+ process.features.openssl_is_boringssl;
+ assert.strictEqual(c.setMaxSendFragment(511),
+ acceptsOutOfRangeFragmentSize);
+ assert.strictEqual(c.setMaxSendFragment(16385),
+ acceptsOutOfRangeFragmentSize);
// Correct fragment size.
assert(c.setMaxSendFragment(maxChunk));
diff --git a/test/parallel/test-tls-min-max-version.js b/test/parallel/test-tls-min-max-version.js
index 4903d92f5c5700..abddbbeb0eba1b 100644
--- a/test/parallel/test-tls-min-max-version.js
+++ b/test/parallel/test-tls-min-max-version.js
@@ -4,6 +4,12 @@ const common = require('../common');
if (!common.hasCrypto) {
common.skip('missing crypto');
}
+
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testLegacyProtocolUnsupported();
+ return;
+}
+
const {
hasOpenSSL,
hasOpenSSL3,
diff --git a/test/parallel/test-tls-multi-key.js b/test/parallel/test-tls-multi-key.js
index 89f9931e5bdd77..0a9c6f108bf675 100644
--- a/test/parallel/test-tls-multi-key.js
+++ b/test/parallel/test-tls-multi-key.js
@@ -27,6 +27,11 @@ const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').assertMultiKeyUnsupported();
+ return;
+}
+
const fixtures = require('../common/fixtures');
const assert = require('assert');
const tls = require('tls');
diff --git a/test/parallel/test-tls-multi-pfx.js b/test/parallel/test-tls-multi-pfx.js
index 526b77b1484cd3..fec697cd3b7093 100644
--- a/test/parallel/test-tls-multi-pfx.js
+++ b/test/parallel/test-tls-multi-pfx.js
@@ -3,6 +3,11 @@ const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testMultiPfxSelectionDifference();
+ return;
+}
+
const assert = require('assert');
const tls = require('tls');
const fixtures = require('../common/fixtures');
diff --git a/test/parallel/test-tls-no-cert-required.js b/test/parallel/test-tls-no-cert-required.js
index b3dcfa516ab502..499ab2dfd14ed2 100644
--- a/test/parallel/test-tls-no-cert-required.js
+++ b/test/parallel/test-tls-no-cert-required.js
@@ -28,10 +28,15 @@ const assert = require('assert');
const tls = require('tls');
// Omitting the cert or pfx option to tls.createServer() should not throw.
-// AECDH-NULL-SHA is a no-authentication/no-encryption cipher and hence
-// doesn't need a certificate.
-tls.createServer({ ciphers: 'AECDH-NULL-SHA' })
- .listen(0, common.mustCall(close));
+if (process.features.openssl_is_boringssl) {
+ // AECDH-NULL-SHA is a no-authentication/no-encryption cipher and hence
+ // does not need a certificate. BoringSSL does not provide that anonymous
+ // cipher suite, so only this cipher-specific no-cert case is skipped.
+ common.printSkipMessage('BoringSSL: skipping anonymous AECDH-NULL-SHA case');
+} else {
+ tls.createServer({ ciphers: 'AECDH-NULL-SHA' })
+ .listen(0, common.mustCall(close));
+}
tls.createServer(assert.fail)
.listen(0, common.mustCall(close));
diff --git a/test/parallel/test-tls-options-boolean-check.js b/test/parallel/test-tls-options-boolean-check.js
index 900a39f0c1cd42..f7dd7bb102f361 100644
--- a/test/parallel/test-tls-options-boolean-check.js
+++ b/test/parallel/test-tls-options-boolean-check.js
@@ -40,9 +40,23 @@ const keyDataView = toDataView(keyBuff);
const certDataView = toDataView(certBuff);
const caArrDataView = toDataView(caCert);
+function filterBoringSSLKeyCertArrayCases(options, setName) {
+ if (!process.features.openssl_is_boringssl)
+ return options;
+
+ // The array-valued cases exercise multi-identity key/cert handling.
+ // BoringSSL may reject those cases with backend key/cert mismatch errors
+ // before the boolean/type validation this test is targeting. Keep the scalar
+ // cases so tls.createServer() option type validation is still covered.
+ common.printSkipMessage(
+ `BoringSSL: skipping ${setName} key/cert array cases`);
+ return options.filter(([key, cert]) => !Array.isArray(key) &&
+ !Array.isArray(cert));
+}
+
// Checks to ensure tls.createServer doesn't throw an error
// Format ['key', 'cert']
-[
+const validOptions = [
[keyBuff, certBuff],
[false, certBuff],
[keyBuff, false],
@@ -62,13 +76,16 @@ const caArrDataView = toDataView(caCert);
[false, [certStr, certStr2]],
[[{ pem: keyBuff }], false],
[[{ pem: keyBuff }, { pem: keyBuff }], false],
-].forEach(([key, cert]) => {
- tls.createServer({ key, cert });
-});
+];
+
+filterBoringSSLKeyCertArrayCases(validOptions, 'valid')
+ .forEach(([key, cert]) => {
+ tls.createServer({ key, cert });
+ });
// Checks to ensure tls.createServer predictably throws an error
// Format ['key', 'cert', 'expected message']
-[
+const invalidKeyOptions = [
[true, certBuff],
[true, certStr],
[true, certArrBuff],
@@ -80,7 +97,10 @@ const caArrDataView = toDataView(caCert);
[[true, keyStr2], [certStr, certStr2], 0],
[[true, false], [certBuff, certBuff2], 0],
[true, [certBuff, certBuff2]],
-].forEach(([key, cert, index]) => {
+];
+
+for (const [key, cert, index] of
+ filterBoringSSLKeyCertArrayCases(invalidKeyOptions, 'invalid key')) {
const val = index === undefined ? key : key[index];
assert.throws(() => {
tls.createServer({ key, cert });
@@ -91,9 +111,9 @@ const caArrDataView = toDataView(caCert);
'instance of Buffer, TypedArray, or DataView.' +
common.invalidArgTypeHelper(val)
});
-});
+}
-[
+const invalidCertOptions = [
[keyBuff, true],
[keyStr, true],
[keyArrBuff, true],
@@ -106,7 +126,10 @@ const caArrDataView = toDataView(caCert);
[[keyStr, keyStr2], [certStr, true], 1],
[[keyStr, keyStr2], [true, false], 0],
[[keyStr, keyStr2], true],
-].forEach(([key, cert, index]) => {
+];
+
+for (const [key, cert, index] of
+ filterBoringSSLKeyCertArrayCases(invalidCertOptions, 'invalid cert')) {
const val = index === undefined ? cert : cert[index];
assert.throws(() => {
tls.createServer({ key, cert });
@@ -117,7 +140,7 @@ const caArrDataView = toDataView(caCert);
'instance of Buffer, TypedArray, or DataView.' +
common.invalidArgTypeHelper(val)
});
-});
+}
// Checks to ensure tls.createServer works with the CA parameter
// Format ['key', 'cert', 'ca']
diff --git a/test/parallel/test-tls-passphrase.js b/test/parallel/test-tls-passphrase.js
index 8d802400f6ee3b..4372da249bb509 100644
--- a/test/parallel/test-tls-passphrase.js
+++ b/test/parallel/test-tls-passphrase.js
@@ -223,7 +223,7 @@ server.listen(0, common.mustCall(function() {
}, onSecureConnect());
})).unref();
-const errMessageDecrypt = /bad decrypt/;
+const errMessageDecrypt = /bad[ _]decrypt/i;
// Missing passphrase
assert.throws(function() {
diff --git a/test/parallel/test-tls-psk-alpn-callback-exception-handling.js b/test/parallel/test-tls-psk-alpn-callback-exception-handling.js
index 881215672ecd0d..cdeb9f3b31f8fe 100644
--- a/test/parallel/test-tls-psk-alpn-callback-exception-handling.js
+++ b/test/parallel/test-tls-psk-alpn-callback-exception-handling.js
@@ -14,6 +14,11 @@ const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testPskTls13Unsupported();
+ return;
+}
+
const assert = require('assert');
const { describe, it } = require('node:test');
const tls = require('tls');
diff --git a/test/parallel/test-tls-psk-circuit.js b/test/parallel/test-tls-psk-circuit.js
index bdf9c86c26a7b6..c9c93d53350165 100644
--- a/test/parallel/test-tls-psk-circuit.js
+++ b/test/parallel/test-tls-psk-circuit.js
@@ -5,6 +5,11 @@ if (!common.hasCrypto) {
common.skip('missing crypto');
}
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testPskTls13Unsupported();
+ return;
+}
+
const { hasOpenSSL } = require('../common/crypto');
const assert = require('assert');
const tls = require('tls');
diff --git a/test/parallel/test-tls-psk-server.js b/test/parallel/test-tls-psk-server.js
index af038493469880..692550fc1c198b 100644
--- a/test/parallel/test-tls-psk-server.js
+++ b/test/parallel/test-tls-psk-server.js
@@ -5,6 +5,11 @@ if (!common.hasCrypto) {
common.skip('missing crypto');
}
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testPskTls13Unsupported();
+ return;
+}
+
const { opensslCli } = require('../common/crypto');
if (!opensslCli) {
diff --git a/test/parallel/test-tls-reduced-SECLEVEL-in-cipher.js b/test/parallel/test-tls-reduced-SECLEVEL-in-cipher.js
index 9f4458e0a7d671..cca22067a0fe19 100644
--- a/test/parallel/test-tls-reduced-SECLEVEL-in-cipher.js
+++ b/test/parallel/test-tls-reduced-SECLEVEL-in-cipher.js
@@ -4,6 +4,11 @@ const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').assertOpenSSLSecurityLevelsUnsupported();
+ return;
+}
+
const assert = require('assert');
const tls = require('tls');
const fixtures = require('../common/fixtures');
diff --git a/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js b/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js
index 2fb43b9cbbf87a..9c30989af0afb3 100644
--- a/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js
+++ b/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js
@@ -22,7 +22,7 @@ const server = tls.createServer({})
'Instance of Error should be passed to error handler');
assert.match(
e.message,
- /SSL routines:[^:]*:wrong version number/,
+ /SSL routines:[^:]*:wrong[ _]version[ _]number/i,
);
server.close();
diff --git a/test/parallel/test-tls-server-verify.js b/test/parallel/test-tls-server-verify.js
index 94f372d37a3b1f..439e321310305a 100644
--- a/test/parallel/test-tls-server-verify.js
+++ b/test/parallel/test-tls-server-verify.js
@@ -47,7 +47,7 @@ const { SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION } =
const tls = require('tls');
const fixtures = require('../common/fixtures');
-const testCases =
+let testCases =
[{ title: 'Do not request certs. Everyone is unauthorized.',
requestCert: false,
rejectUnauthorized: false,
@@ -125,6 +125,15 @@ const testCases =
] },
];
+if (process.features.openssl_is_boringssl) {
+ // Remove the delayed client-certificate verification case. It depends on TLS
+ // renegotiation to request a client certificate after the initial handshake,
+ // but BoringSSL does not support caller-initiated renegotiation.
+ common.printSkipMessage(
+ 'BoringSSL: skipping renegotiated client certificate verification case');
+ testCases = testCases.filter((tcase) => !tcase.renegotiate);
+}
+
function filenamePEM(n) {
return fixtures.path('keys', `${n}.pem`);
}
diff --git a/test/parallel/test-tls-session-cache.js b/test/parallel/test-tls-session-cache.js
index aaf9c2c03c83e9..ae560e567980c9 100644
--- a/test/parallel/test-tls-session-cache.js
+++ b/test/parallel/test-tls-session-cache.js
@@ -37,6 +37,7 @@ const fixtures = require('../common/fixtures');
const assert = require('assert');
const tls = require('tls');
const { spawn } = require('child_process');
+const isBoringSSL = process.features.openssl_is_boringssl;
doTest({ tickets: false }, function() {
doTest({ tickets: true }, function() {
@@ -56,7 +57,9 @@ function doTest(testOptions, callback) {
requestCert: true,
rejectUnauthorized: false,
secureProtocol: 'TLS_method',
- ciphers: 'RSA@SECLEVEL=0'
+ // BoringSSL supports the RSA cipher selector, but not OpenSSL's
+ // cipher-string policy command syntax.
+ ciphers: isBoringSSL ? 'RSA' : 'RSA@SECLEVEL=0'
};
let requestCount = 0;
let resumeCount = 0;
@@ -105,7 +108,7 @@ function doTest(testOptions, callback) {
server.listen(0, common.mustCall(function() {
const args = [
's_client',
- '-tls1',
+ isBoringSSL ? '-tls1_2' : '-tls1',
'-cipher', (hasOpenSSL(3, 1) ? 'DEFAULT:@SECLEVEL=0' : 'DEFAULT'),
'-connect', `localhost:${this.address().port}`,
'-servername', 'ohgod',
diff --git a/test/parallel/test-tls-set-ciphers-error.js b/test/parallel/test-tls-set-ciphers-error.js
index 3cfc8c391bf7d5..b79bd512ffe1db 100644
--- a/test/parallel/test-tls-set-ciphers-error.js
+++ b/test/parallel/test-tls-set-ciphers-error.js
@@ -21,8 +21,12 @@ const { hasOpenSSL } = require('../common/crypto');
assert.throws(() => tls.createServer(options, common.mustNotCall()),
/no[_ ]cipher[_ ]match/i);
options.ciphers = 'TLS_not_a_cipher';
- assert.throws(() => tls.createServer(options, common.mustNotCall()),
- /no[_ ]cipher[_ ]match/i);
+ if (process.features.openssl_is_boringssl) {
+ tls.createServer(options).close();
+ } else {
+ assert.throws(() => tls.createServer(options, common.mustNotCall()),
+ /no[_ ]cipher[_ ]match/i);
+ }
}
// Cipher name matching is case-sensitive prior to OpenSSL 4.0, and
diff --git a/test/parallel/test-tls-set-default-ca-certificates-recovery.js b/test/parallel/test-tls-set-default-ca-certificates-recovery.js
index e3eb0e84149ae8..ea6f98d5686e03 100644
--- a/test/parallel/test-tls-set-default-ca-certificates-recovery.js
+++ b/test/parallel/test-tls-set-default-ca-certificates-recovery.js
@@ -27,7 +27,9 @@ function testRecovery(expectedCerts) {
{
const invalidCert = '-----BEGIN CERTIFICATE-----\nvalid cert content\n-----END CERTIFICATE-----';
assert.throws(() => tls.setDefaultCACertificates([fixtureCert, invalidCert]), {
- code: 'ERR_OSSL_PEM_ASN1_LIB',
+ code: process.features.openssl_is_boringssl ?
+ 'ERR_OSSL_PEM_ASN.1_ENCODING_ROUTINES' :
+ 'ERR_OSSL_PEM_ASN1_LIB',
});
assertEqualCerts(tls.getCACertificates('default'), expectedCerts);
}
diff --git a/test/parallel/test-tls-set-sigalgs.js b/test/parallel/test-tls-set-sigalgs.js
index 1bce814f3e8604..e1bf8b93f8a342 100644
--- a/test/parallel/test-tls-set-sigalgs.js
+++ b/test/parallel/test-tls-set-sigalgs.js
@@ -39,9 +39,14 @@ function test(csigalgs, ssigalgs, shared_sigalgs, cerr, serr) {
assert.ifError(pair.client.err);
assert(pair.server.conn);
assert(pair.client.conn);
+ // BoringSSL's OpenSSL-compatible SSL_get_shared_sigalgs() API always
+ // returns zero, so a successful handshake still reports an empty list.
+ const expectedSharedSigalgs = process.features.openssl_is_boringssl ?
+ [] :
+ shared_sigalgs;
assert.deepStrictEqual(
pair.server.conn.getSharedSigalgs(),
- shared_sigalgs
+ expectedSharedSigalgs
);
} else {
if (serr) {
@@ -69,10 +74,13 @@ test('RSA-PSS+SHA256:RSA-PSS+SHA512:ECDSA+SHA256',
const handshakeErr = hasOpenSSL(4, 0) ?
'ERR_SSL_TLS_ALERT_HANDSHAKE_FAILURE' : hasOpenSSL(3, 2) ?
'ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE' : 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE';
+const noSharedSigalgsErr = process.features.openssl_is_boringssl ?
+ 'ERR_SSL_NO_COMMON_SIGNATURE_ALGORITHMS' :
+ 'ERR_SSL_NO_SHARED_SIGNATURE_ALGORITHMS';
test('RSA-PSS+SHA384', 'ECDSA+SHA256',
undefined, handshakeErr,
- 'ERR_SSL_NO_SHARED_SIGNATURE_ALGORITHMS');
+ noSharedSigalgsErr);
test('RSA-PSS+SHA384:ECDSA+SHA256', 'ECDSA+SHA384:RSA-PSS+SHA256',
undefined, handshakeErr,
- 'ERR_SSL_NO_SHARED_SIGNATURE_ALGORITHMS');
+ noSharedSigalgsErr);
diff --git a/test/parallel/test-tls-socket-failed-handshake-emits-error.js b/test/parallel/test-tls-socket-failed-handshake-emits-error.js
index c88f0c3a1855f2..c64d4ad4aabe8d 100644
--- a/test/parallel/test-tls-socket-failed-handshake-emits-error.js
+++ b/test/parallel/test-tls-socket-failed-handshake-emits-error.js
@@ -22,7 +22,7 @@ const server = net.createServer(common.mustCall((c) => {
'Instance of Error should be passed to error handler');
assert.match(
e.message,
- /SSL routines:[^:]*:wrong version number/,
+ /SSL routines:[^:]*:wrong[ _]version[ _]number/i,
);
}));
diff --git a/test/parallel/test-tls-ticket-cluster.js b/test/parallel/test-tls-ticket-cluster.js
index 2ed4abb93c8d47..f183b53f24c0b9 100644
--- a/test/parallel/test-tls-ticket-cluster.js
+++ b/test/parallel/test-tls-ticket-cluster.js
@@ -24,6 +24,11 @@ const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testTls13SessionTicketSemanticsDiffer();
+ return;
+}
+
const assert = require('assert');
const tls = require('tls');
const cluster = require('cluster');
diff --git a/test/parallel/test-tls-ticket.js b/test/parallel/test-tls-ticket.js
index 0a77e52fb275cd..8316f5e8da8d8f 100644
--- a/test/parallel/test-tls-ticket.js
+++ b/test/parallel/test-tls-ticket.js
@@ -30,6 +30,12 @@ const net = require('net');
const crypto = require('crypto');
const fixtures = require('../common/fixtures');
+if (process.features.openssl_is_boringssl &&
+ tls.DEFAULT_MAX_VERSION !== 'TLSv1.2') {
+ require('../common/boringssl').testTls13SessionTicketSemanticsDiffer();
+ return;
+}
+
const keys = crypto.randomBytes(48);
const serverLog = [];
const ticketLog = [];
diff --git a/test/parallel/test-x509-escaping.js b/test/parallel/test-x509-escaping.js
index a5937a09cb1535..ab91e334555669 100644
--- a/test/parallel/test-x509-escaping.js
+++ b/test/parallel/test-x509-escaping.js
@@ -438,7 +438,9 @@ const { hasOpenSSL3 } = require('../common/crypto');
const cert = fixtures.readKey('incorrect_san_correct_subject-cert.pem');
// The hostname is the CN, but not a SAN entry.
- const servername = process.features.openssl_is_boringssl ? undefined : 'good.example.com';
+ const servername = 'good.example.com';
+ const cnFallback = process.features.openssl_is_boringssl ? undefined :
+ servername;
const certX509 = new X509Certificate(cert);
assert.strictEqual(certX509.subject, `CN=${servername}`);
assert.strictEqual(certX509.subjectAltName, 'DNS:evil.example.com');
@@ -448,7 +450,7 @@ const { hasOpenSSL3 } = require('../common/crypto');
assert.strictEqual(certX509.checkHost(servername, { subject: 'default' }),
undefined);
assert.strictEqual(certX509.checkHost(servername, { subject: 'always' }),
- servername);
+ cnFallback);
assert.strictEqual(certX509.checkHost(servername, { subject: 'never' }),
undefined);
@@ -483,11 +485,13 @@ const { hasOpenSSL3 } = require('../common/crypto');
assert.strictEqual(certX509.subjectAltName, 'IP Address:1.2.3.4');
// The newer X509Certificate API allows customizing this behavior:
- assert.strictEqual(certX509.checkHost(servername), servername);
+ const cnFallback = process.features.openssl_is_boringssl ? undefined :
+ servername;
+ assert.strictEqual(certX509.checkHost(servername), cnFallback);
assert.strictEqual(certX509.checkHost(servername, { subject: 'default' }),
- servername);
+ cnFallback);
assert.strictEqual(certX509.checkHost(servername, { subject: 'always' }),
- servername);
+ cnFallback);
assert.strictEqual(certX509.checkHost(servername, { subject: 'never' }),
undefined);
diff --git a/test/sequential/test-tls-connect.js b/test/sequential/test-tls-connect.js
index 189b9afa6352bb..ca8a1d8128554e 100644
--- a/test/sequential/test-tls-connect.js
+++ b/test/sequential/test-tls-connect.js
@@ -57,5 +57,5 @@ const tls = require('tls');
port: common.PORT,
ciphers: 'rick-128-roll',
}, common.mustNotCall());
- }, /no cipher match/i);
+ }, /no[_ ]cipher[_ ]match/i);
}
diff --git a/test/sequential/test-tls-psk-client.js b/test/sequential/test-tls-psk-client.js
index 65e628a6f4e0eb..2eb6228f79f265 100644
--- a/test/sequential/test-tls-psk-client.js
+++ b/test/sequential/test-tls-psk-client.js
@@ -5,6 +5,11 @@ if (!common.hasCrypto) {
common.skip('missing crypto');
}
+if (process.features.openssl_is_boringssl) {
+ require('../common/boringssl').testPskTls13Unsupported();
+ return;
+}
+
const { opensslCli } = require('../common/crypto');
if (!opensslCli) {