Skip to content

Commit a0423e2

Browse files
authored
crypto: deduplicate X509 subject matching logic
Signed-off-by: Tobias Nießen <tniessen@tnie.de> PR-URL: #63644 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
1 parent 6af9026 commit a0423e2

1 file changed

Lines changed: 36 additions & 53 deletions

File tree

src/crypto/crypto_x509.cc

Lines changed: 36 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -477,81 +477,64 @@ void CheckPublicKey(const FunctionCallbackInfo<Value>& args) {
477477
cert->view().checkPublicKey(key->Data().GetAsymmetricKey()));
478478
}
479479

480-
void CheckHost(const FunctionCallbackInfo<Value>& args) {
480+
template <typename F>
481+
void CheckX509Subject(const FunctionCallbackInfo<Value>& args, F check) {
481482
Environment* env = Environment::GetCurrent(args);
482483
X509Certificate* cert;
483484
ASSIGN_OR_RETURN_UNWRAP(&cert, args.This());
484485

485-
CHECK(args[0]->IsString()); // name
486+
CHECK(args[0]->IsString()); // subject
486487
CHECK(args[1]->IsUint32()); // flags
487488

488-
Utf8Value name(env->isolate(), args[0]);
489+
Utf8Value subject(env->isolate(), args[0]);
489490
uint32_t flags = args[1].As<Uint32>()->Value();
490-
DataPointer peername;
491491

492-
switch (cert->view().checkHost(name.ToStringView(), flags, &peername)) {
493-
case X509View::CheckMatch::MATCH: { // Match!
492+
DataPointer matched_subject;
493+
X509View view = cert->view();
494+
auto result = check(view, subject.ToStringView(), flags, &matched_subject);
495+
switch (result) {
496+
case X509View::CheckMatch::MATCH: {
494497
Local<Value> ret = args[0];
495-
if (peername) {
498+
if (matched_subject) {
496499
ret = OneByteString(env->isolate(),
497-
static_cast<const char*>(peername.get()),
498-
peername.size());
500+
matched_subject.get<const char>(),
501+
matched_subject.size());
499502
}
500503
return args.GetReturnValue().Set(ret);
501504
}
502-
case X509View::CheckMatch::NO_MATCH: // No Match!
503-
return; // No return value is set
504-
case X509View::CheckMatch::INVALID_NAME: // Error!
505+
case X509View::CheckMatch::NO_MATCH:
506+
break; // No return value is set.
507+
case X509View::CheckMatch::INVALID_NAME:
505508
return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name");
506-
default: // Error!
509+
default:
507510
return THROW_ERR_CRYPTO_OPERATION_FAILED(env);
508511
}
509512
}
510513

511-
void CheckEmail(const FunctionCallbackInfo<Value>& args) {
512-
Environment* env = Environment::GetCurrent(args);
513-
X509Certificate* cert;
514-
ASSIGN_OR_RETURN_UNWRAP(&cert, args.This());
515-
516-
CHECK(args[0]->IsString()); // name
517-
CHECK(args[1]->IsUint32()); // flags
518-
519-
Utf8Value name(env->isolate(), args[0]);
520-
uint32_t flags = args[1].As<Uint32>()->Value();
514+
void CheckHost(const FunctionCallbackInfo<Value>& args) {
515+
CheckX509Subject(
516+
args,
517+
[](X509View& cert,
518+
std::string_view subject,
519+
uint32_t flags,
520+
DataPointer* match) { return cert.checkHost(subject, flags, match); });
521+
}
521522

522-
switch (cert->view().checkEmail(name.ToStringView(), flags)) {
523-
case X509View::CheckMatch::MATCH: // Match!
524-
return args.GetReturnValue().Set(args[0]);
525-
case X509View::CheckMatch::NO_MATCH: // No Match!
526-
return; // No return value is set
527-
case X509View::CheckMatch::INVALID_NAME: // Error!
528-
return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name");
529-
default: // Error!
530-
return THROW_ERR_CRYPTO_OPERATION_FAILED(env);
531-
}
523+
void CheckEmail(const FunctionCallbackInfo<Value>& args) {
524+
CheckX509Subject(
525+
args,
526+
[](X509View& cert,
527+
std::string_view subject,
528+
uint32_t flags,
529+
DataPointer*) { return cert.checkEmail(subject, flags); });
532530
}
533531

534532
void CheckIP(const FunctionCallbackInfo<Value>& args) {
535-
Environment* env = Environment::GetCurrent(args);
536-
X509Certificate* cert;
537-
ASSIGN_OR_RETURN_UNWRAP(&cert, args.This());
538-
539-
CHECK(args[0]->IsString()); // IP
540-
CHECK(args[1]->IsUint32()); // flags
541-
542-
Utf8Value name(env->isolate(), args[0]);
543-
uint32_t flags = args[1].As<Uint32>()->Value();
544-
545-
switch (cert->view().checkIp(name.ToStringView(), flags)) {
546-
case X509View::CheckMatch::MATCH: // Match!
547-
return args.GetReturnValue().Set(args[0]);
548-
case X509View::CheckMatch::NO_MATCH: // No Match!
549-
return; // No return value is set
550-
case X509View::CheckMatch::INVALID_NAME: // Error!
551-
return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP");
552-
default: // Error!
553-
return THROW_ERR_CRYPTO_OPERATION_FAILED(env);
554-
}
533+
CheckX509Subject(args,
534+
[](X509View& cert,
535+
std::string_view subject,
536+
uint32_t flags,
537+
DataPointer*) { return cert.checkIp(subject, flags); });
555538
}
556539

557540
void GetIssuerCert(const FunctionCallbackInfo<Value>& args) {

0 commit comments

Comments
 (0)