From a0423e2e29f1c1f7033974580a519e889d3c2d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Wed, 3 Jun 2026 00:12:49 +0200 Subject: [PATCH 1/2] crypto: deduplicate X509 subject matching logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tobias Nießen PR-URL: https://github.com/nodejs/node/pull/63644 Reviewed-By: Anna Henningsen Reviewed-By: Filip Skokan --- src/crypto/crypto_x509.cc | 89 ++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 53 deletions(-) diff --git a/src/crypto/crypto_x509.cc b/src/crypto/crypto_x509.cc index 991c4ca6bfb404..8082496a87714e 100644 --- a/src/crypto/crypto_x509.cc +++ b/src/crypto/crypto_x509.cc @@ -477,81 +477,64 @@ void CheckPublicKey(const FunctionCallbackInfo& args) { cert->view().checkPublicKey(key->Data().GetAsymmetricKey())); } -void CheckHost(const FunctionCallbackInfo& args) { +template +void CheckX509Subject(const FunctionCallbackInfo& args, F check) { Environment* env = Environment::GetCurrent(args); X509Certificate* cert; ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); - CHECK(args[0]->IsString()); // name + CHECK(args[0]->IsString()); // subject CHECK(args[1]->IsUint32()); // flags - Utf8Value name(env->isolate(), args[0]); + Utf8Value subject(env->isolate(), args[0]); uint32_t flags = args[1].As()->Value(); - DataPointer peername; - switch (cert->view().checkHost(name.ToStringView(), flags, &peername)) { - case X509View::CheckMatch::MATCH: { // Match! + DataPointer matched_subject; + X509View view = cert->view(); + auto result = check(view, subject.ToStringView(), flags, &matched_subject); + switch (result) { + case X509View::CheckMatch::MATCH: { Local ret = args[0]; - if (peername) { + if (matched_subject) { ret = OneByteString(env->isolate(), - static_cast(peername.get()), - peername.size()); + matched_subject.get(), + matched_subject.size()); } return args.GetReturnValue().Set(ret); } - case X509View::CheckMatch::NO_MATCH: // No Match! - return; // No return value is set - case X509View::CheckMatch::INVALID_NAME: // Error! + case X509View::CheckMatch::NO_MATCH: + break; // No return value is set. + case X509View::CheckMatch::INVALID_NAME: return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name"); - default: // Error! + default: return THROW_ERR_CRYPTO_OPERATION_FAILED(env); } } -void CheckEmail(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); - - CHECK(args[0]->IsString()); // name - CHECK(args[1]->IsUint32()); // flags - - Utf8Value name(env->isolate(), args[0]); - uint32_t flags = args[1].As()->Value(); +void CheckHost(const FunctionCallbackInfo& args) { + CheckX509Subject( + args, + [](X509View& cert, + std::string_view subject, + uint32_t flags, + DataPointer* match) { return cert.checkHost(subject, flags, match); }); +} - switch (cert->view().checkEmail(name.ToStringView(), flags)) { - case X509View::CheckMatch::MATCH: // Match! - return args.GetReturnValue().Set(args[0]); - case X509View::CheckMatch::NO_MATCH: // No Match! - return; // No return value is set - case X509View::CheckMatch::INVALID_NAME: // Error! - return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name"); - default: // Error! - return THROW_ERR_CRYPTO_OPERATION_FAILED(env); - } +void CheckEmail(const FunctionCallbackInfo& args) { + CheckX509Subject( + args, + [](X509View& cert, + std::string_view subject, + uint32_t flags, + DataPointer*) { return cert.checkEmail(subject, flags); }); } void CheckIP(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); - - CHECK(args[0]->IsString()); // IP - CHECK(args[1]->IsUint32()); // flags - - Utf8Value name(env->isolate(), args[0]); - uint32_t flags = args[1].As()->Value(); - - switch (cert->view().checkIp(name.ToStringView(), flags)) { - case X509View::CheckMatch::MATCH: // Match! - return args.GetReturnValue().Set(args[0]); - case X509View::CheckMatch::NO_MATCH: // No Match! - return; // No return value is set - case X509View::CheckMatch::INVALID_NAME: // Error! - return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP"); - default: // Error! - return THROW_ERR_CRYPTO_OPERATION_FAILED(env); - } + CheckX509Subject(args, + [](X509View& cert, + std::string_view subject, + uint32_t flags, + DataPointer*) { return cert.checkIp(subject, flags); }); } void GetIssuerCert(const FunctionCallbackInfo& args) { From 7b08df713d6905a5763818e5c631d8199b335ace Mon Sep 17 00:00:00 2001 From: Muhammad Zeeshan <61280174+zeeshan56656@users.noreply.github.com> Date: Wed, 3 Jun 2026 03:57:15 +0500 Subject: [PATCH 2/2] doc: clarify tty raw mode applies to input processing only Update the setRawMode documentation to specify that raw mode disables special processing of input characters only. Output processing, such as newline translation on Unix terminals, is not affected. Fixes: https://github.com/nodejs/node/issues/63059 Signed-off-by: zeeshan56656 PR-URL: https://github.com/nodejs/node/pull/63438 Reviewed-By: Anna Henningsen --- doc/api/tty.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/api/tty.md b/doc/api/tty.md index a7c4c3a48d8707..03f86cd66052fd 100644 --- a/doc/api/tty.md +++ b/doc/api/tty.md @@ -80,10 +80,11 @@ added: v0.7.7 Allows configuration of `tty.ReadStream` so that it operates as a raw device. When in raw mode, input is always available character-by-character, not -including modifiers. Additionally, all special processing of characters by the -terminal is disabled, including echoing input +including modifiers. Additionally, all special processing of input characters +by the terminal is disabled, including echoing input characters. Ctrl+C will no longer cause a `SIGINT` when -in this mode. +in this mode. This mode does not affect terminal output processing, such as +newline translation on Unix terminals. ## Class: `tty.WriteStream`