From 234200b01cf731176f4a7f8249aef12e21ef9bc2 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Thu, 8 Aug 2024 14:03:29 +0200 Subject: [PATCH] chore: group args of ExportCertificateAndKey for readability --- src/binding.cc | 48 ++++++++++++++++++++++++------------------------ src/certs.cc | 23 ++++++++--------------- src/certs.h | 19 +++++++++++-------- 3 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/binding.cc b/src/binding.cc index a602721..ec621f8 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -5,6 +5,17 @@ namespace { using namespace Napi; using namespace WinExportCertificateAndKey; +Array BufferListToArray(Env env, const std::vector>& vec) { + Array ret = Array::New(env); + if (vec.size() > static_cast(-1)) { + throw std::runtime_error("result length exceeds uint32 max"); + } + for (uint32_t i = 0; i < vec.size(); i++) { + ret[i] = Buffer::Copy(env, vec[i].data(), vec[i].size()); + } + return ret; +} + // Convert UTF-8 to a Windows UTF-16 wstring. std::wstring MultiByteToWideChar(Value value) { static_assert(sizeof(std::wstring::value_type) == sizeof(std::u16string::value_type), @@ -18,16 +29,8 @@ Value ExportAllCertificatesSync(const CallbackInfo& args) { DWORD store_type = args[1].ToNumber().Uint32Value(); try { - std::vector> certs = - ExportAllCertificates(sys_store_name, store_type); - if (certs.size() > static_cast(-1)) { - throw std::runtime_error("result length exceeds uint32 max"); - } - Array result = Array::New(args.Env()); - for (uint32_t i = 0; i < certs.size(); i++) { - result[i] = Buffer::Copy(args.Env(), certs[i].data(), certs[i].size()); - } - return result; + return BufferListToArray( + args.Env(), ExportAllCertificates(sys_store_name, store_type)); } catch (const std::exception& e) { throw Error::New(args.Env(), e.what()); } @@ -36,28 +39,25 @@ Value ExportAllCertificatesSync(const CallbackInfo& args) { // Export a given certificate from a system certificate store, // identified either by its thumbprint or its subject line. Value ExportCertificateAndKeySync(const CallbackInfo& args) { - std::wstring password_buf = MultiByteToWideChar(args[0].ToString()); - std::wstring sys_store_name = MultiByteToWideChar(args[1].ToString()); - DWORD store_type = args[2].ToNumber().Uint32Value(); - bool use_thumbprint; - std::vector thumbprint; - std::wstring subject; - bool require_private_key = args[4].ToBoolean(); + ExportCertificateAndKeyArgs exp_args; + exp_args.password_buf = MultiByteToWideChar(args[0].ToString()); + exp_args.sys_store_name = MultiByteToWideChar(args[1].ToString()); + exp_args.store_type = args[2].ToNumber().Uint32Value(); + exp_args.require_private_key = args[4].ToBoolean(); Object search_spec = args[3].ToObject(); if (search_spec.HasOwnProperty("thumbprint")) { - use_thumbprint = true; - Buffer thumbprint_buf = search_spec.Get("thumbprint").As>(); - thumbprint = {thumbprint_buf.Data(), thumbprint_buf.Data() + thumbprint_buf.Length()}; + exp_args.use_thumbprint = true; + Buffer thumbprint = search_spec.Get("thumbprint").As>(); + exp_args.thumbprint = {thumbprint.Data(), thumbprint.Data() + thumbprint.Length()}; } else if (search_spec.HasOwnProperty("subject")) { - use_thumbprint = false; - subject = MultiByteToWideChar(search_spec.Get("subject").ToString()); + exp_args.use_thumbprint = false; + exp_args.subject = MultiByteToWideChar(search_spec.Get("subject").ToString()); } else { throw Error::New(args.Env(), "Need to specify either `thumbprint` or `subject`"); } try { - auto result = ExportCertificateAndKey( - store_type, sys_store_name, use_thumbprint, thumbprint, subject, password_buf, require_private_key); + auto result = ExportCertificateAndKey(exp_args); return Buffer::Copy(args.Env(), result.data(), result.size()); } catch (const std::exception& e) { throw Error::New(args.Env(), e.what()); diff --git a/src/certs.cc b/src/certs.cc index 88cf529..d071b45 100644 --- a/src/certs.cc +++ b/src/certs.cc @@ -132,22 +132,15 @@ std::vector> ExportAllCertificates( return result; } -std::vector ExportCertificateAndKey( - DWORD store_type, - const std::wstring& sys_store_name, - bool use_thumbprint, - const std::vector& thumbprint, - const std::wstring& subject, - const std::wstring& password_buf, - bool require_private_key) { - LPCWSTR password = password_buf.data(); - CertStoreHandle sys_cs = CertOpenStore(sys_store_name, store_type); +std::vector ExportCertificateAndKey(const ExportCertificateAndKeyArgs& args) { + LPCWSTR password = args.password_buf.data(); + CertStoreHandle sys_cs = CertOpenStore(args.sys_store_name, args.store_type); PCCERT_CONTEXT cert = nullptr; - if (use_thumbprint) { + if (args.use_thumbprint) { CRYPT_HASH_BLOB thumbprint_blob = { - static_cast(thumbprint.size()), - const_cast(thumbprint.data()) + static_cast(args.thumbprint.size()), + const_cast(args.thumbprint.data()) }; cert = CertFindCertificateInStore( sys_cs.get(), @@ -162,7 +155,7 @@ std::vector ExportCertificateAndKey( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, - subject.data(), + args.subject.data(), nullptr); } @@ -173,7 +166,7 @@ std::vector ExportCertificateAndKey( Cleanup cleanup_cert([&]() { CertFreeCertificateContext(cert); }); DWORD export_flags = EXPORT_PRIVATE_KEYS; - if (require_private_key) { + if (args.require_private_key) { export_flags |= REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY; } return CertToBuffer(cert, password, export_flags); diff --git a/src/certs.h b/src/certs.h index 3dc5f77..b4f4e9c 100644 --- a/src/certs.h +++ b/src/certs.h @@ -4,14 +4,17 @@ #include namespace WinExportCertificateAndKey { -std::vector ExportCertificateAndKey( - DWORD store_type, - const std::wstring& sys_store_name, - bool use_thumbprint, - const std::vector& thumbprint, - const std::wstring& subject, - const std::wstring& password_buf, - bool require_private_key); +struct ExportCertificateAndKeyArgs { + DWORD store_type; + std::wstring sys_store_name; + bool use_thumbprint; + std::vector thumbprint; + std::wstring subject; + std::wstring password_buf; + bool require_private_key; +}; + +std::vector ExportCertificateAndKey(const ExportCertificateAndKeyArgs& args); std::vector> ExportAllCertificates( const std::wstring& sys_store_name, DWORD store_type);