aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/installer/updatesigntool
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/installer/updatesigntool
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/installer/updatesigntool')
-rw-r--r--Src/external_dependencies/openmpt-trunk/installer/updatesigntool/updatesigntool.cpp206
1 files changed, 206 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/installer/updatesigntool/updatesigntool.cpp b/Src/external_dependencies/openmpt-trunk/installer/updatesigntool/updatesigntool.cpp
new file mode 100644
index 00000000..038e94d2
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/installer/updatesigntool/updatesigntool.cpp
@@ -0,0 +1,206 @@
+
+#include "openmpt/all/BuildSettings.hpp"
+
+#include "mpt/base/span.hpp"
+#include "mpt/crypto/hash.hpp"
+#include "mpt/crypto/jwk.hpp"
+#include "mpt/environment/environment.hpp"
+#include "mpt/exception_text/exception_text.hpp"
+#include "mpt/io/base.hpp"
+#include "mpt/io/io.hpp"
+#include "mpt/io/io_stdstream.hpp"
+#include "mpt/out_of_memory/out_of_memory.hpp"
+#include "mpt/string/types.hpp"
+#include "mpt/string_transcode/transcode.hpp"
+#include "mpt/uuid/uuid.hpp"
+#include "mpt/uuid_namespace/uuid_namespace.hpp"
+
+#include "../common/mptBaseMacros.h"
+#include "../common/mptBaseTypes.h"
+#include "../common/mptBaseUtils.h"
+#include "../common/mptStringFormat.h"
+#include "../common/mptPathString.h"
+#include "../common/mptFileIO.h"
+#include "../common/Logging.h"
+#include "../common/misc_util.h"
+
+#include <exception>
+#include <iostream>
+#include <locale>
+#include <optional>
+#include <stdexcept>
+#include <vector>
+
+
+#if defined(MPT_BUILD_MSVC)
+#if MPT_COMPILER_MSVC || MPT_COMPILER_CLANG
+
+#pragma comment(lib, "bcrypt.lib")
+#pragma comment(lib, "ncrypt.lib")
+#pragma comment(lib, "rpcrt4.lib")
+#pragma comment(lib, "shlwapi.lib")
+#pragma comment(lib, "winmm.lib")
+
+#endif // MPT_COMPILER_MSVC || MPT_COMPILER_CLANG
+#endif // MPT_BUILD_MSVC
+
+
+OPENMPT_NAMESPACE_BEGIN
+
+
+using namespace mpt::uuid_literals;
+
+
+#if defined(MPT_ASSERT_HANDLER_NEEDED) && defined(MPT_BUILD_UPDATESIGNTOOL)
+MPT_NOINLINE void AssertHandler(const mpt::source_location &loc, const char *expr, const char *msg)
+{
+ if(msg)
+ {
+ mpt::log::GlobalLogger().SendLogMessage(loc, LogError, "ASSERT",
+ MPT_USTRING("ASSERTION FAILED: ") + mpt::transcode<mpt::ustring>(mpt::common_encoding::ascii, msg) + MPT_USTRING(" (") + mpt::transcode<mpt::ustring>(mpt::common_encoding::ascii, expr) + MPT_USTRING(")")
+ );
+ } else
+ {
+ mpt::log::GlobalLogger().SendLogMessage(loc, LogError, "ASSERT",
+ MPT_USTRING("ASSERTION FAILED: ") + mpt::transcode<mpt::ustring>(mpt::common_encoding::ascii, expr)
+ );
+ }
+}
+#endif
+
+
+namespace updatesigntool {
+
+
+static mpt::ustring get_keyname(mpt::ustring keyname)
+{
+ if(keyname == MPT_USTRING("auto"))
+ {
+ constexpr mpt::UUID ns = "9a88e12a-a132-4215-8bd0-3a002da65373"_uuid;
+ mpt::ustring computername = mpt::getenv(MPT_USTRING("COMPUTERNAME")).value_or(MPT_USTRING(""));
+ mpt::ustring username = mpt::getenv(MPT_USTRING("USERNAME")).value_or(MPT_USTRING(""));
+ mpt::ustring name = MPT_UFORMAT("host={} user={}")(computername, username);
+ mpt::UUID uuid = mpt::UUIDRFC4122NamespaceV5(ns, name);
+ keyname = MPT_UFORMAT("OpenMPT Update Signing Key {}")(uuid);
+ }
+ return keyname;
+}
+
+static void main(const std::vector<mpt::ustring> &args)
+{
+ try
+ {
+ if(args.size() < 2)
+ {
+ throw std::invalid_argument("Usage: updatesigntool [dumpkey|sign] ...");
+ }
+ if(args[1] == MPT_USTRING(""))
+ {
+ throw std::invalid_argument("Usage: updatesigntool [dumpkey|sign] ...");
+ } else if(args[1] == MPT_USTRING("dumpkey"))
+ {
+ if(args.size() != 4)
+ {
+ throw std::invalid_argument("Usage: updatesigntool dumpkey KEYNAME FILENAME");
+ }
+ mpt::ustring keyname = get_keyname(args[2]);
+ mpt::ustring filename = args[3];
+ mpt::crypto::keystore keystore(mpt::crypto::keystore::domain::user);
+ mpt::crypto::asymmetric::rsassa_pss<>::managed_private_key key(keystore, keyname);
+ mpt::SafeOutputFile sfo(mpt::PathString::FromUnicode(filename));
+ mpt::ofstream & fo = sfo.stream();
+ mpt::IO::WriteText(fo, mpt::transcode<std::string>(mpt::common_encoding::utf8, key.get_public_key_data().as_jwk()));
+ fo.flush();
+ } else if(args[1] == MPT_USTRING("sign"))
+ {
+ if(args.size() != 6)
+ {
+ throw std::invalid_argument("Usage: updatesigntool sign [raw|jws_compact|jws] KEYNAME INPUTFILENAME OUTPUTFILENAME");
+ }
+ mpt::ustring mode = args[2];
+ mpt::ustring keyname = get_keyname(args[3]);
+ mpt::ustring inputfilename = args[4];
+ mpt::ustring outputfilename = args[5];
+ mpt::crypto::keystore keystore(mpt::crypto::keystore::domain::user);
+ mpt::crypto::asymmetric::rsassa_pss<>::managed_private_key key(keystore, keyname);
+ std::vector<std::byte> data;
+ {
+ mpt::ifstream fi(mpt::PathString::FromUnicode(inputfilename), std::ios::binary);
+ fi.imbue(std::locale::classic());
+ fi.exceptions(std::ios::badbit);
+ while(!mpt::IO::IsEof(fi))
+ {
+ std::array<std::byte, mpt::IO::BUFFERSIZE_TINY> buf;
+ mpt::append(data, mpt::IO::ReadRaw(fi, mpt::as_span(buf)));
+ }
+ }
+ if(mode == MPT_USTRING(""))
+ {
+ throw std::invalid_argument("Usage: updatesigntool sign [raw|jws_compact|jws] KEYNAME INPUTFILENAME OUTPUTFILENAME");
+ } else if(mode == MPT_USTRING("raw"))
+ {
+ std::vector<std::byte> signature = key.sign(mpt::as_span(data));
+ mpt::SafeOutputFile sfo(mpt::PathString::FromUnicode(outputfilename));
+ mpt::ofstream & fo = sfo.stream();
+ mpt::IO::WriteRaw(fo, mpt::as_span(signature));
+ fo.flush();
+ } else if(mode == MPT_USTRING("jws_compact"))
+ {
+ mpt::ustring signature = key.jws_compact_sign(mpt::as_span(data));
+ mpt::SafeOutputFile sfo(mpt::PathString::FromUnicode(outputfilename));
+ mpt::ofstream & fo = sfo.stream();
+ mpt::IO::WriteText(fo, mpt::transcode<std::string>(mpt::common_encoding::utf8, signature));
+ fo.flush();
+ } else if(mode == MPT_USTRING("jws"))
+ {
+ mpt::ustring signature = key.jws_sign(mpt::as_span(data));
+ mpt::SafeOutputFile sfo(mpt::PathString::FromUnicode(outputfilename));
+ mpt::ofstream & fo = sfo.stream();
+ mpt::IO::WriteText(fo, mpt::transcode<std::string>(mpt::common_encoding::utf8, signature));
+ fo.flush();
+ } else
+ {
+ throw std::invalid_argument("Usage: updatesigntool sign [raw|jws_compact|jws] KEYNAME INPUTFILENAME OUTPUTFILENAME");
+ }
+ } else
+ {
+ throw std::invalid_argument("Usage: updatesigntool [dumpkey|sign] ...");
+ }
+ } catch(const std::exception &e)
+ {
+ std::cerr << mpt::get_exception_text<std::string>(e) << std::endl;
+ throw;
+ }
+}
+
+} // namespace updatesigntool
+
+
+OPENMPT_NAMESPACE_END
+
+
+#if defined(WIN32) && defined(UNICODE)
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ std::locale::global(std::locale(""));
+ std::vector<mpt::ustring> args;
+ for(int arg = 0; arg < argc; ++arg)
+ {
+ #if defined(WIN32) && defined(UNICODE)
+ args.push_back(mpt::transcode<mpt::ustring>(argv[arg]));
+ #else
+ args.push_back(mpt::transcode<mpt::ustring>(mpt::logical_encoding::locale, argv[arg]));
+ #endif
+ }
+ try
+ {
+ OPENMPT_NAMESPACE::updatesigntool::main(args);
+ } catch(...)
+ {
+ return 1;
+ }
+ return 0;
+}