mirror of
https://github.com/Neo-Desktop/WindowsXPKg
synced 2024-11-16 19:00:59 +02:00
update build scripts, add unit tests, pidgen2 needs polishing, confid is wip
This commit is contained in:
parent
015fd00d3f
commit
c7eb049c0b
116
.github/workflows/dos-djgpp.yml
vendored
116
.github/workflows/dos-djgpp.yml
vendored
@ -23,21 +23,35 @@ name: C/C++ CI (DOS DJGPP)
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**' ] # If only these files are edited, skip
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**' ] # If only these files are edited, skip
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
CC: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-gcc
|
||||
CXX: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-g++
|
||||
CMAKE_FIND_ROOT_PATH: ${{ github.workspace }}/djgpp
|
||||
WATT_ROOT: ${{ github.workspace }}/djgpp/watt32
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CC: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-gcc
|
||||
CXX: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-g++
|
||||
CMAKE_FIND_ROOT_PATH: ${{ github.workspace }}/djgpp
|
||||
GCC_EXEC_PREFIX: ${{ github.workspace }}/lib/gcc/
|
||||
DJDIR: ${{ github.workspace }}/djgpp/i586-pc-msdosdjgpp
|
||||
PATH: ${{ github.workspace }}/djgpp/i586-pc-msdosdjgpp/bin/:${{ github.workspace }}/djgpp/bin/:${PATH}
|
||||
|
||||
steps:
|
||||
- name: Checkout Source Tree
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4.1.1
|
||||
|
||||
- name: Set up CPM cache
|
||||
id: cache-cpm
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.cpm-cache
|
||||
key: ${{ runner.os }}-cpm-${{ hashFiles('**/') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cpm-
|
||||
|
||||
- name: Setup build environment
|
||||
run: |
|
||||
@ -46,24 +60,17 @@ jobs:
|
||||
|
||||
- name: Download and Setup DJGPP Toolchain
|
||||
run: |
|
||||
pushd ${{ github.workspace }}
|
||||
wget https://github.com/andrewwutw/build-djgpp/releases/download/v3.4/djgpp-linux64-gcc1220.tar.bz2
|
||||
tar xjf djgpp-linux64-gcc1220.tar.bz2
|
||||
cd ${{ github.workspace }}/djgpp
|
||||
git clone https://github.com/UMSKT/Watt-32.git watt32
|
||||
cd watt32/util
|
||||
make clean && make linux
|
||||
cd ../src
|
||||
source ${{ github.workspace }}/djgpp/setenv
|
||||
./configur.sh djgpp
|
||||
make -f djgpp.mak
|
||||
ln -s ${WATT_ROOT}/lib/libwatt.a ${CMAKE_FIND_ROOT_PATH}/lib
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
source ${{ github.workspace }}/djgpp/setenv
|
||||
cmake -DDJGPP_WATT32=${WATT_ROOT}/lib/libwatt.a -DCMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH} -DCMAKE_BUILD_TYPE=Release build/
|
||||
cmake --build build/
|
||||
- name: Build UMSKT for MSDOS via DJGPP
|
||||
uses: threeal/cmake-action@v1.3.0
|
||||
with:
|
||||
options: UMSKT_DJGPP_COMPILE=On CMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH} CMAKE_BUILD_TYPE=Release
|
||||
build-dir: build
|
||||
c-compiler: ${CC}
|
||||
cxx-compiler: ${CXX}
|
||||
build-args: -j 2
|
||||
|
||||
- name: Move executable to upload directory
|
||||
run: |
|
||||
@ -71,7 +78,68 @@ jobs:
|
||||
mv build/umskt.exe build/actions_upload/
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v3.1.2
|
||||
uses: actions/upload-artifact@v4.3.1
|
||||
with:
|
||||
name: UMSKT-DOS
|
||||
path: build/actions_upload
|
||||
|
||||
build-dos-win32-combined:
|
||||
needs: build
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
# https://github.com/actions/runner-images/issues/6067#issuecomment-1213069040
|
||||
- name: Install Windows XP Support for Visual Studio
|
||||
run: |
|
||||
Set-Location "C:\Program Files (x86)\Microsoft Visual Studio\Installer\"
|
||||
$InstallPath = "C:\Program Files\Microsoft Visual Studio\2022\Enterprise"
|
||||
$componentsToAdd = @(
|
||||
"Microsoft.VisualStudio.Component.WinXP"
|
||||
)
|
||||
[string]$workloadArgs = $componentsToAdd | ForEach-Object {" --add " + $_}
|
||||
$Arguments = ('/c', "vs_installer.exe", 'modify', '--installPath', "`"$InstallPath`"",$workloadArgs, '--quiet', '--norestart', '--nocache')
|
||||
$process = Start-Process -FilePath cmd.exe -ArgumentList $Arguments -Wait -PassThru -WindowStyle Hidden
|
||||
if ($process.ExitCode -eq 0)
|
||||
{
|
||||
Write-Host "components have been successfully added"
|
||||
Get-ChildItem C:\ProgramData\Microsoft\VisualStudio\Packages\Microsoft.Windows.XPSupport.*
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "components were not installed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Setup MSBuild
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Checkout Source Tree
|
||||
uses: actions/checkout@v4.1.1
|
||||
|
||||
- name: Set up CPM cache
|
||||
id: cache-cpm
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.cpm-cache
|
||||
key: ${{ runner.os }}-cpm-${{ hashFiles('**/') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cpm-
|
||||
|
||||
- name: Download Built DOS Artifact
|
||||
uses: actions/download-artifact@v4.1.2
|
||||
with:
|
||||
name: UMSKT-DOS
|
||||
|
||||
- name: Configure and build UMSKT for DOS+Win32
|
||||
uses: threeal/cmake-action@v1.3.0
|
||||
with:
|
||||
options: UMSKT_MSVC_WINXP=On CMAKE_BUILD_TYPE=Release CPM_SOURCE_CACHE=${{ github.workspace }}/.cpm-cache UMSKT_MSVC_MSDOS_STUB=${{ github.workspace }}/umskt.exe
|
||||
generator: "Visual Studio 17 2022"
|
||||
args: -A "Win32" -T "v141_xp"
|
||||
run-build: true
|
||||
build-args: "--config Release -j 2"
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4.3.1
|
||||
with:
|
||||
name: UMSKT-DOS+Win32
|
||||
path: build/Release
|
74
.github/workflows/freebsd.yml
vendored
74
.github/workflows/freebsd.yml
vendored
@ -18,45 +18,57 @@
|
||||
# @FileCreated by techguy16 on 07/23/2023
|
||||
# @Maintainer techguy16
|
||||
|
||||
name: C/C++ CI (FreeBSD)
|
||||
name: C/C++ CI (FreeBSD)
|
||||
|
||||
on:
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**' ] # If only these files are edited, skip
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip
|
||||
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**' ] # If only these files are edited, skip
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: build-x86_64
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: build-x86_64
|
||||
|
||||
- name: Build & Test in FreeBSD
|
||||
id: test
|
||||
uses: vmactions/freebsd-vm@v1
|
||||
with:
|
||||
usesh: true
|
||||
prepare: |
|
||||
pkg install -y cmake git bash
|
||||
steps:
|
||||
- name: Checkout Source Tree
|
||||
uses: actions/checkout@v4.1.1
|
||||
|
||||
run: |
|
||||
mkdir build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release build/
|
||||
cmake --build build/
|
||||
- name: Set up CPM cache
|
||||
id: cache-cpm
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.cpm-cache
|
||||
key: ${{ runner.os }}-cpm-${{ hashFiles('**/') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cpm-
|
||||
|
||||
- name: Move files to correct directory
|
||||
run: |
|
||||
mkdir -p build/actions_upload
|
||||
mv build/umskt build/actions_upload/umskt
|
||||
- name: Build & Test in FreeBSD
|
||||
id: test
|
||||
uses: vmactions/freebsd-vm@v1.0.6
|
||||
with:
|
||||
usesh: true
|
||||
prepare: |
|
||||
pkg install -y cmake git bash
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v3.1.2
|
||||
with:
|
||||
name: UMSKT-FreeBSD
|
||||
path: build/actions_upload
|
||||
run: |
|
||||
mkdir build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCPM_SOURCE_CACHE= ${{ github.workspace }}/.cpm-cache -DBUILD_TESTING=On -B build/
|
||||
cmake --build build/ -j 2
|
||||
cd build
|
||||
ctest
|
||||
|
||||
- name: Move files to correct directory
|
||||
run: |
|
||||
mkdir -p build/actions_upload
|
||||
mv build/umskt build/actions_upload/umskt
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4.3.1
|
||||
with:
|
||||
name: UMSKT-FreeBSD
|
||||
path: build/actions_upload
|
||||
|
74
.github/workflows/linux.yml
vendored
74
.github/workflows/linux.yml
vendored
@ -23,7 +23,10 @@ name: C/C++ CI (Linux)
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**' ] # If only these files are edited, skip
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**' ] # If only these files are edited, skip
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
@ -35,36 +38,53 @@ jobs:
|
||||
- x86
|
||||
- x86_64
|
||||
- aarch64
|
||||
- armhf
|
||||
- armv7
|
||||
- ppc64le
|
||||
- riscv64
|
||||
- s390x
|
||||
|
||||
steps:
|
||||
- name: Checkout Source Tree
|
||||
uses: actions/checkout@v3
|
||||
- name: Checkout Source Tree
|
||||
uses: actions/checkout@v4.1.1
|
||||
|
||||
- name: Setup latest Alpine Linux for ${{ matrix.arch }}
|
||||
uses: jirutka/setup-alpine@v1
|
||||
with:
|
||||
packages: >
|
||||
bash
|
||||
build-base
|
||||
cmake
|
||||
git
|
||||
musl-dev
|
||||
arch: ${{ matrix.arch }}
|
||||
shell-name: alpine-target.sh
|
||||
- name: Set up CPM cache
|
||||
id: cache-cpm
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.cpm-cache
|
||||
key: ${{ runner.os }}-cpm-${{ hashFiles('**/') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cpm-
|
||||
|
||||
- name: Configure and build UMSKT
|
||||
uses: threeal/cmake-action@v1.3.0
|
||||
with:
|
||||
options: MUSL_STATIC=ON CMAKE_BUILD_TYPE=Release
|
||||
run-build: true
|
||||
shell: alpine-target.sh {0}
|
||||
- name: Setup latest Alpine Linux for ${{ matrix.arch }}
|
||||
uses: jirutka/setup-alpine@v1
|
||||
with:
|
||||
packages: >
|
||||
bash
|
||||
build-base
|
||||
cmake
|
||||
git
|
||||
musl-dev
|
||||
arch: ${{ matrix.arch }}
|
||||
shell-name: alpine-target.sh
|
||||
|
||||
- name: Move files to correct directory
|
||||
run: |
|
||||
- name: Configure and build UMSKT
|
||||
uses: threeal/cmake-action@v1.3.0
|
||||
with:
|
||||
options: UMSKT_MUSL_STATIC=ON CMAKE_BUILD_TYPE=Release CPM_SOURCE_CACHE=${{ github.workspace }}/.cpm-cache BUILD_TESTING=On
|
||||
run-build: true
|
||||
build-args: -j 2
|
||||
run-test: true
|
||||
shell: alpine-target.sh {0}
|
||||
|
||||
- name: Move files to correct directory
|
||||
run: |
|
||||
mkdir -p build/actions_upload
|
||||
mv build/umskt build/actions_upload/umskt
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v3.1.2
|
||||
with:
|
||||
name: UMSKT-linux-${{ matrix.arch }}-static
|
||||
path: build/actions_upload
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4.3.1
|
||||
with:
|
||||
name: UMSKT-linux-${{ matrix.arch }}-static
|
||||
path: build/actions_upload
|
||||
|
31
.github/workflows/macos.yml
vendored
31
.github/workflows/macos.yml
vendored
@ -23,7 +23,10 @@ name: C/C++ CI (macOS)
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**' ] # If only these files are edited, skip
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**' ] # If only these files are edited, skip
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
@ -32,17 +35,29 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
arch:
|
||||
- { name: arm64;x86_64, displayName: all-x86_64_arm64}
|
||||
- { name: arm64;x86_64, displayName: all-x86_64_arm64 }
|
||||
- { name: x86_64, displayName: x86_64 }
|
||||
- { name: arm64, displayName: arm64 }
|
||||
steps:
|
||||
- name: Checkout Source Tree
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4.1.1
|
||||
|
||||
- name: Configure and build UMSKT ${{ matrix.arch.displayName }}
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=${{ matrix.arch.name }} build/
|
||||
cmake --build build/
|
||||
- name: Set up CPM cache
|
||||
id: cache-cpm
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.cpm-cache
|
||||
key: ${{ runner.os }}-cpm-${{ hashFiles('**/') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cpm-
|
||||
|
||||
- name: Configure and build UMSKT for ${{ matrix.arch.displayName }}
|
||||
uses: threeal/cmake-action@v1.3.0
|
||||
with:
|
||||
options: MUSL_STATIC=ON CMAKE_BUILD_TYPE=Release CPM_SOURCE_CACHE=${{ github.workspace }}/.cpm-cache CMAKE_OSX_ARCHITECTURES=${{ matrix.arch.name }} BUILD_TESTING=On
|
||||
run-build: true
|
||||
build-args: -j 2
|
||||
run-test: true
|
||||
|
||||
- name: Move files to correct directory
|
||||
run: |
|
||||
@ -50,7 +65,7 @@ jobs:
|
||||
mv build/umskt build/actions_upload/umskt
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v3.1.2
|
||||
uses: actions/upload-artifact@v4.3.1
|
||||
with:
|
||||
name: UMSKT-macOS-${{ matrix.arch.displayName }}
|
||||
path: build/actions_upload
|
||||
|
33
.github/workflows/windows.yml
vendored
33
.github/workflows/windows.yml
vendored
@ -24,11 +24,17 @@ on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [ { name: Win32, displayName: x86 }, { name: x64, displayName: x64 } ]
|
||||
steps:
|
||||
# https://github.com/actions/runner-images/issues/6067#issuecomment-1213069040
|
||||
- name: Install Windows XP Support for Visual Studio
|
||||
@ -52,30 +58,33 @@ jobs:
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Set up CPM cache
|
||||
id: cache-cpm
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.cpm-cache
|
||||
key: ${{ runner.os }}-cpm-${{ hashFiles('**/') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cpm-
|
||||
|
||||
- name: Checkout Source Tree
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4.1.1
|
||||
|
||||
- name: Setup MSBuild
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
needs: prepare
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [ { name: Win32, displayName: x86 }, { name: x64, displayName: x64} ]
|
||||
steps:
|
||||
- name: Configure and build UMSKT for ${{ matrix.values.displayName }}
|
||||
uses: threeal/cmake-action@v1.3.0
|
||||
with:
|
||||
options: CMAKE_BUILD_TYPE=Release
|
||||
options: CMAKE_BUILD_TYPE=Release CPM_SOURCE_CACHE=${{ github.workspace }}/.cpm-cache BUILD_TESTING=On
|
||||
generator: "Visual Studio 17 2022"
|
||||
args: -A "${{ matrix.arch.name }}" -T "v141_xp"
|
||||
run-build: true
|
||||
build-args: "--config Release"
|
||||
build-args: --config Release -j 2
|
||||
run-test: true
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v3.1.2
|
||||
uses: actions/upload-artifact@v4.3.1
|
||||
with:
|
||||
name: UMSKT-${{ matrix.values.displayName }}
|
||||
path: build/Release
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,6 +3,7 @@ build*/
|
||||
*.exe
|
||||
*.wasm
|
||||
umskt
|
||||
.cpm-cache
|
||||
|
||||
### NotepadPP template
|
||||
# Notepad++ backups #
|
||||
|
191
CMakeLists.txt
191
CMakeLists.txt
@ -19,48 +19,55 @@
|
||||
# @Maintainer Neo
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
||||
PROJECT(UMSKT)
|
||||
SET(PROJECT_NAME UMSKT)
|
||||
PROJECT(${PROJECT_NAME})
|
||||
|
||||
SET(CMAKE_CXX_STANDARD 17)
|
||||
SET(CMAKE_OSX_SYSROOT "macosx" CACHE PATH "macOS SDK path")
|
||||
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
OPTION(BUILD_SHARED_LIBS "Build all libraries as shared" OFF)
|
||||
OPTION(MUSL_STATIC "Enable fully static builds in a muslc environment (i.e. Alpine Linux)" OFF)
|
||||
OPTION(DJGPP_WATT32 "Enable compilation and linking with DJGPP/WATT32" OFF)
|
||||
OPTION(MSVC_MSDOS_STUB "Specify a custom MS-DOS stub for a 32-bit MSVC compilation" OFF)
|
||||
OPTION(BUILD_TESTING "Build testing binaries for CTest" OFF)
|
||||
OPTION(BUILD_SHARED_LIBS "Build all dependant libraries as shared" OFF)
|
||||
|
||||
SET(UMSKT_LINK_LIBS ${UMSKT_LINK_LIBS})
|
||||
SET(UMSKT_LINK_DIRS ${UMSKT_LINK_DIRS})
|
||||
OPTION(UMSKT_BUILD_SHARED_LIB "Build libumskt.so/.dll/.dylib" ON)
|
||||
OPTION(UMSKT_BUILD_STATIC_LIB "Build libumskt_static.a/.lib" ON)
|
||||
OPTION(UMSKT_MUSL_STATIC "Enable fully static builds in a muslc environment (i.e. Alpine Linux)" OFF)
|
||||
OPTION(UMSKT_DJGPP_COMPILE "Enable compilation and linking with DJGPP" OFF)
|
||||
OPTION(UMSKT_MSVC_MSDOS_STUB "Specify a custom MS-DOS stub for a 32-bit MSVC compilation" OFF)
|
||||
OPTION(UMSKT_MSVC_WINXP "Specify compile-time flag overrides for Windows XP" OFF)
|
||||
|
||||
IF (NOT MSVC)
|
||||
SET(CMAKE_CXX_FLAGS "-Os -fdata-sections -ffunction-sections -flto=auto -Wl,--gc-sections")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "-g")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG_INIT "-Wall -Wextra")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG_INIT "-Wall -Wextra -pedantic")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-Wall -Wextra")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-Wall -Wextra -pedantic")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE_INIT "-s")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -Wl,--gc-sections")
|
||||
ENDIF ()
|
||||
|
||||
IF (DJGPP_WATT32)
|
||||
IF (UMSKT_DJGPP_COMPILE)
|
||||
SET(CMAKE_SYSTEM_NAME MSDOS)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
SET(UMSKT_LINK_LIBS ${UMSKT_LINK_LIBS} ${DJGPP_WATT32})
|
||||
SET(UMSKT_LINK_DIRS ${UMSKT_LINK_DIRS} ${WATT_ROOT}/lib)
|
||||
SET(UMSKT_BUILD_SHARED_LIB OFF)
|
||||
SET(UMSKT_BUILD_STATIC_LIB OFF)
|
||||
SET(CMAKE_POSITION_INDEPENDENT_CODE OFF)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes -march=i386 -mtune=i386")
|
||||
MESSAGE(STATUS "[UMSKT] DJGPP Build requested - Shared libraries forced OFF")
|
||||
ENDIF ()
|
||||
|
||||
IF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
SET(BUILD_SHARED_LIBS ON)
|
||||
MESSAGE(STATUS "[UMSKT] macOS has no static library - Shared library forced on")
|
||||
MESSAGE(STATUS "[UMSKT] macOS Build requested - Shared libraries forced ON")
|
||||
ENDIF ()
|
||||
|
||||
# if we're compiling with MSVC, respect the DEBUG compile option
|
||||
IF (MSVC)
|
||||
SET(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
SET(CMAKE_CXX_FLAGS "/O1 /GL /LTCG /Gy /OPT:REF /OPT:ICF /EHsc")
|
||||
SET(CMAKE_CXX_FLAGS "/Os /LTCG /Gy /OPT:REF /OPT:ICF /EHsc")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "/MT")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "/MTd /Z7")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "/INCREMENTAL:NO /NODEFAULTLIB:MSVCRT /LTCG")
|
||||
@ -68,16 +75,18 @@ IF (MSVC)
|
||||
SET(CMAKE_ENABLE_EXPORTS ON)
|
||||
SET(UMSKT_EXE_WINDOWS_EXTRA src/windows/umskt.rc)
|
||||
SET(UMSKT_EXE_WINDOWS_DLL src/windows/dllmain.cpp)
|
||||
IF (UMSKT_MSVC_WINXP)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /U_WIN32_WINNT /DWINVER=0x0501 /D_WIN32_WINNT=0x0501")
|
||||
ENDIF ()
|
||||
ENDIF ()
|
||||
|
||||
IF (MUSL_STATIC)
|
||||
MESSAGE(STATUS "[UMSKT] Performing a fully static build using muslc")
|
||||
MESSAGE(STATUS "[UMSKT] musl libc Build requested - Shared librares forced OFF")
|
||||
SET(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc -static-libstdc++")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -static-libgcc -static-libstdc++")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||
ENDIF ()
|
||||
|
||||
# initialize cpm.CMake
|
||||
@ -88,6 +97,7 @@ FILE(
|
||||
EXPECTED_HASH SHA256=cc155ce02e7945e7b8967ddfaff0b050e958a723ef7aad3766d368940cb15494
|
||||
)
|
||||
INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake)
|
||||
CPMUsePackageLock(${CMAKE_SOURCE_DIR}/package-lock.cmake)
|
||||
|
||||
# fetch cpm.CMake dependencies
|
||||
# Include JSON development library
|
||||
@ -113,23 +123,23 @@ CPMAddPackage(
|
||||
VERSION 2.0.1
|
||||
)
|
||||
|
||||
# Include stdint128
|
||||
CPMAddPackage(
|
||||
NAME stdint128
|
||||
GITHUB_REPOSITORY UMSKT/stdint128-cmake
|
||||
GIT_TAG v1.0.0
|
||||
VERSION 1.0.0
|
||||
)
|
||||
|
||||
# Include Crypto++ development library
|
||||
CPMAddPackage(
|
||||
NAME cryptopp-cmake
|
||||
GITHUB_REPOSITORY abdes/cryptopp-cmake
|
||||
GITHUB_REPOSITORY UMSKT/cryptopp-cmake
|
||||
GIT_TAG CRYPTOPP_8_9_0
|
||||
VERSION 8.9.0
|
||||
OPTIONS "CRYPTOPP_BUILD_TESTING OFF"
|
||||
)
|
||||
|
||||
#include googletest unit testing library
|
||||
#CPMAddPackage(
|
||||
# NAME googletest
|
||||
# GITHUB_REPOSITORY google/googletest
|
||||
# VERSION 1.13.0
|
||||
# OPTIONS "INSTALL_GTEST OFF" "gtest_force_shared_crt"
|
||||
#)
|
||||
|
||||
### Resource compilation
|
||||
CMRC_ADD_RESOURCE_LIBRARY(umskt-rc ALIAS umskt::rc NAMESPACE umskt keys.json)
|
||||
|
||||
@ -137,8 +147,8 @@ SET(LIBUMSKT_PIDGEN2 src/libumskt/pidgen2/PIDGEN2.cpp)
|
||||
SET(LIBUMSKT_PIDGEN3 src/libumskt/pidgen3/PIDGEN3.cpp src/libumskt/pidgen3/BINK1998.cpp src/libumskt/pidgen3/BINK2002.cpp)
|
||||
SET(LIBUMSKT_CONFID src/libumskt/confid/confid.cpp src/libumskt/confid/polynomial.cpp src/libumskt/confid/residue.cpp src/libumskt/confid/divisor.cpp)
|
||||
SET(LIBUMSKT_SRC src/libumskt/libumskt.cpp src/libumskt/init.cpp src/libumskt/pidgen.cpp ${LIBUMSKT_PIDGEN2} ${LIBUMSKT_PIDGEN3} ${LIBUMSKT_CONFID})
|
||||
SET(UMSKT_CLI_SRC src/main.cpp src/help.cpp src/cli.cpp src/generate.cpp)
|
||||
SET(UMSKT_LINK_LIBS ${UMSKT_LINK_LIBS} fmt cryptopp)
|
||||
SET(UMSKT_CLI_SRC src/main.cpp src/cli/help.cpp src/cli/cli.cpp src/cli/confirmationid.cpp src/cli/options.cpp src/cli/pidgen.cpp)
|
||||
SET(UMSKT_LINK_LIBS ${UMSKT_LINK_LIBS} fmt cryptopp stdint128)
|
||||
|
||||
IF (NOT MSVC)
|
||||
SET(UMSKT_LINK_LIBS ${UMSKT_LINK_LIBS} umskt::rc)
|
||||
@ -150,7 +160,7 @@ ENDIF()
|
||||
#### Separate Build Path for emscripten
|
||||
IF (EMSCRIPTEN)
|
||||
ADD_EXECUTABLE(umskt ${UMSKT_CLI_SRC} ${LIBUMSKT_SRC})
|
||||
TARGET_INCLUDE_DIRECTORIES(umskt PUBLIC ${CMAKE_BINARY_DIR})
|
||||
TARGET_INCLUDE_DIRECTORIES(umskt PUBLIC ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR})
|
||||
TARGET_LINK_DIRECTORIES(umskt PUBLIC ${UMSKT_LINK_DIRS})
|
||||
TARGET_LINK_LIBRARIES(umskt PUBLIC ${UMSKT_LINK_LIBS})
|
||||
SET(CMAKE_EXECUTABLE_SUFFIX ".html")
|
||||
@ -159,47 +169,96 @@ IF (EMSCRIPTEN)
|
||||
SET_TARGET_PROPERTIES(umskt PROPERTIES LINK_FLAGS "-sWASM=1 -sEXPORT_ALL=1 -sEXPORTED_RUNTIME_METHODS=ccall,cwrap --no-entry")
|
||||
ELSE ()
|
||||
## umskt.so/.dll creation
|
||||
ADD_LIBRARY(libumskt SHARED ${LIBUMSKT_SRC} ${UMSKT_EXE_WINDOWS_EXTRA} ${UMSKT_EXE_WINDOWS_DLL})
|
||||
TARGET_INCLUDE_DIRECTORIES(libumskt PUBLIC ${CMAKE_BINARY_DIR})
|
||||
TARGET_LINK_DIRECTORIES(libumskt PUBLIC ${UMSKT_LINK_DIRS})
|
||||
TARGET_LINK_LIBRARIES(libumskt PUBLIC ${UMSKT_LINK_LIBS})
|
||||
IF (MSVC)
|
||||
SET_TARGET_PROPERTIES(libumskt PROPERTIES OUTPUT_NAME libumskt)
|
||||
ELSE ()
|
||||
SET_TARGET_PROPERTIES(libumskt PROPERTIES OUTPUT_NAME umskt)
|
||||
ENDIF ()
|
||||
IF (UMSKT_BUILD_SHARED_LIB)
|
||||
ADD_LIBRARY(libumskt SHARED ${LIBUMSKT_SRC} ${UMSKT_EXE_WINDOWS_EXTRA} ${UMSKT_EXE_WINDOWS_DLL})
|
||||
TARGET_INCLUDE_DIRECTORIES(libumskt PUBLIC ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR})
|
||||
TARGET_LINK_DIRECTORIES(libumskt PUBLIC ${UMSKT_LINK_DIRS})
|
||||
TARGET_LINK_LIBRARIES(libumskt PUBLIC ${UMSKT_LINK_LIBS})
|
||||
IF (MSVC)
|
||||
SET_TARGET_PROPERTIES(libumskt PROPERTIES OUTPUT_NAME libumskt)
|
||||
ELSE ()
|
||||
SET_TARGET_PROPERTIES(libumskt PROPERTIES OUTPUT_NAME umskt)
|
||||
ENDIF ()
|
||||
ENDIF()
|
||||
|
||||
## umskt_static.a/.lib creation
|
||||
ADD_LIBRARY(libumskt_static ${LIBUMSKT_SRC} ${UMSKT_EXE_WINDOWS_EXTRA} ${UMSKT_EXE_WINDOWS_DLL})
|
||||
TARGET_INCLUDE_DIRECTORIES(libumskt_static PUBLIC ${CMAKE_BINARY_DIR})
|
||||
TARGET_LINK_DIRECTORIES(libumskt_static PUBLIC ${UMSKT_LINK_DIRS})
|
||||
TARGET_LINK_LIBRARIES(libumskt_static PUBLIC ${UMSKT_LINK_LIBS})
|
||||
IF (MSVC)
|
||||
SET_TARGET_PROPERTIES(libumskt_static PROPERTIES OUTPUT_NAME libumskt_static)
|
||||
ELSE ()
|
||||
SET_TARGET_PROPERTIES(libumskt_static PROPERTIES OUTPUT_NAME umskt_static)
|
||||
ENDIF ()
|
||||
IF (UMSKT_BUILD_STATIC_LIB)
|
||||
ADD_LIBRARY(libumskt_static ${LIBUMSKT_SRC} ${UMSKT_EXE_WINDOWS_EXTRA} ${UMSKT_EXE_WINDOWS_DLL})
|
||||
TARGET_INCLUDE_DIRECTORIES(libumskt_static PUBLIC ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR})
|
||||
TARGET_LINK_DIRECTORIES(libumskt_static PUBLIC ${UMSKT_LINK_DIRS})
|
||||
TARGET_LINK_LIBRARIES(libumskt_static PUBLIC ${UMSKT_LINK_LIBS})
|
||||
IF (MSVC)
|
||||
SET_TARGET_PROPERTIES(libumskt_static PROPERTIES OUTPUT_NAME libumskt_static)
|
||||
ELSE ()
|
||||
SET_TARGET_PROPERTIES(libumskt_static PROPERTIES OUTPUT_NAME umskt_static)
|
||||
ENDIF ()
|
||||
ENDIF()
|
||||
|
||||
### UMSKT executable compilation
|
||||
IF (NOT BUILD_SHARED_LIBS)
|
||||
## Link against the static lib
|
||||
ADD_EXECUTABLE(umskt ${UMSKT_CLI_SRC} ${UMSKT_EXE_WINDOWS_EXTRA})
|
||||
TARGET_LINK_LIBRARIES(umskt PUBLIC libumskt_static ${UMSKT_LINK_LIBS} nlohmann_json::nlohmann_json)
|
||||
ELSE ()
|
||||
## Link against the dynamic lib
|
||||
ADD_EXECUTABLE(umskt ${UMSKT_CLI_SRC} ${UMSKT_EXE_WINDOWS_EXTRA})
|
||||
TARGET_LINK_LIBRARIES(umskt PUBLIC libumskt ${UMSKT_LINK_LIBS} nlohmann_json::nlohmann_json)
|
||||
ENDIF()
|
||||
TARGET_INCLUDE_DIRECTORIES(umskt PUBLIC ${CMAKE_BINARY_DIR})
|
||||
TARGET_LINK_DIRECTORIES(umskt PUBLIC ${UMSKT_LINK_DIRS})
|
||||
IF (MSVC)
|
||||
SET_PROPERTY(TARGET umskt APPEND PROPERTY COMPILE_FLAGS /DUMSKT_CLI_WINRC_EMBED_JSON)
|
||||
IF (MSVC_MSDOS_STUB)
|
||||
SET_PROPERTY(TARGET umskt APPEND PROPERTY LINK_FLAGS /STUB:${MSVC_MSDOS_STUB})
|
||||
IF (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||
### only build CLI if we're building UMSKT explicitly
|
||||
IF (UMSKT_BUILD_STATIC_LIB)
|
||||
## Link against the static lib
|
||||
ADD_EXECUTABLE(umskt ${UMSKT_CLI_SRC} ${UMSKT_EXE_WINDOWS_EXTRA})
|
||||
TARGET_LINK_LIBRARIES(umskt PUBLIC libumskt_static ${UMSKT_LINK_LIBS} nlohmann_json::nlohmann_json)
|
||||
ELSEIF (UMSKT_BUILD_SHARED_LIB)
|
||||
## Link against the dynamic lib
|
||||
ADD_EXECUTABLE(umskt ${UMSKT_CLI_SRC} ${UMSKT_EXE_WINDOWS_EXTRA})
|
||||
TARGET_LINK_LIBRARIES(umskt PUBLIC libumskt ${UMSKT_LINK_LIBS} nlohmann_json::nlohmann_json)
|
||||
ELSE()
|
||||
## Don't link against our output, do a full libumskt+cli compile
|
||||
ADD_EXECUTABLE(umskt ${LIBUMSKT_SRC} ${UMSKT_CLI_SRC} ${UMSKT_EXE_WINDOWS_EXTRA})
|
||||
TARGET_LINK_LIBRARIES(umskt PUBLIC ${UMSKT_LINK_LIBS} nlohmann_json::nlohmann_json)
|
||||
ENDIF()
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(umskt PUBLIC ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR})
|
||||
TARGET_LINK_DIRECTORIES(umskt PUBLIC ${UMSKT_LINK_DIRS})
|
||||
IF (MSVC)
|
||||
SET_PROPERTY(TARGET umskt APPEND PROPERTY COMPILE_FLAGS /DUMSKT_CLI_WINRC_EMBED_JSON)
|
||||
IF (MSVC_MSDOS_STUB)
|
||||
SET_PROPERTY(TARGET umskt APPEND PROPERTY LINK_FLAGS /STUB:${MSVC_MSDOS_STUB})
|
||||
ENDIF()
|
||||
ENDIF ()
|
||||
|
||||
IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
INSTALL(TARGETS umskt DESTINATION bin)
|
||||
ENDIF ()
|
||||
ENDIF ()
|
||||
|
||||
IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
INSTALL(TARGETS umskt DESTINATION bin)
|
||||
ENDIF ()
|
||||
### Strip the built binary
|
||||
IF (${CMAKE_BUILD_TYPE} MATCHES "Release" AND NOT MSVC)
|
||||
ADD_CUSTOM_COMMAND(TARGET umskt POST_BUILD
|
||||
COMMAND strip $<TARGET_FILE:umskt>
|
||||
COMMENT "Stripping symbols for release"
|
||||
)
|
||||
ENDIF()
|
||||
ENDIF ()
|
||||
|
||||
|
||||
#### Build Path for Unit Tests
|
||||
IF ((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR UMSKT_BUILD_TESTING) AND BUILD_TESTING)
|
||||
INCLUDE(CTest)
|
||||
ENABLE_TESTING()
|
||||
|
||||
#include googletest unit testing library
|
||||
CPMAddPackage(
|
||||
NAME googletest
|
||||
GITHUB_REPOSITORY google/googletest
|
||||
VERSION 1.14.0
|
||||
OPTIONS "INSTALL_GTEST OFF" "gtest_force_shared_crt"
|
||||
)
|
||||
|
||||
MACRO(ADD_GTEST TEST)
|
||||
ADD_EXECUTABLE(${TEST} ${ARGN})
|
||||
TARGET_LINK_LIBRARIES(${TEST} gtest gmock gtest_main libumskt_static)
|
||||
TARGET_COMPILE_FEATURES(${TEST} PRIVATE cxx_std_17)
|
||||
SET_TARGET_PROPERTIES(${TEST} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests)
|
||||
ADD_TEST(${TEST} tests/${TEST})
|
||||
ENDMACRO()
|
||||
|
||||
ADD_GTEST(TEST_PIDGEN2 src/libumskt/pidgen2/PIDGEN2_unittest.cpp)
|
||||
ADD_GTEST(TEST_PIDGEN3_BINK1998 src/libumskt/pidgen3/BINK1998_unittest.cpp)
|
||||
ADD_GTEST(TEST_PIDGEN3_BINK2002 src/libumskt/pidgen3/BINK2002_unittest.cpp)
|
||||
ADD_GTEST(TEST_CONFIRMATIONID src/libumskt/confid/confid_unittest.cpp)
|
||||
|
||||
ENDIF ()
|
||||
|
14
Dockerfile
14
Dockerfile
@ -27,9 +27,7 @@ RUN apk add --no-cache \
|
||||
build-base \
|
||||
cmake \
|
||||
git \
|
||||
musl-dev \
|
||||
openssl-dev \
|
||||
openssl-libs-static
|
||||
musl-dev
|
||||
|
||||
|
||||
# Stage 2: Build
|
||||
@ -40,15 +38,15 @@ COPY . /src
|
||||
|
||||
# Build UMSKT from the local directory
|
||||
RUN mkdir /src/build \
|
||||
&& cmake -B /src/build -DMUSL_STATIC=ON \
|
||||
&& cmake -B /src/build -DCPM_SOURCE_CACHE=/src/.cpm-cache -DCMAKE_BUILD_TYPE=Release -DUMSKT_MUSL_STATIC=ON \
|
||||
&& cmake --build /src/build -j 10
|
||||
|
||||
# Stage 3: Output
|
||||
FROM scratch as output
|
||||
|
||||
COPY --from=builder /src/build/umskt /umskt
|
||||
COPY --from=builder /src/build/libumskt.a /umskt
|
||||
COPY --from=builder /src/build/libumskt.so /umskt
|
||||
COPY --from=builder /src/build/umskt /
|
||||
COPY --from=builder /src/build/libumskt_static.a /
|
||||
COPY --from=builder /src/build/libumskt.so /
|
||||
|
||||
# invoke via
|
||||
# docker build -o type=tar,dest=umskt.tar .
|
||||
# docker build -o type=tar,dest=build-musl/umskt.tar .
|
||||
|
@ -19,67 +19,55 @@
|
||||
# @Maintainer Neo
|
||||
|
||||
# Stage 1: Install Prerequisites
|
||||
#FROM ubuntu:latest as prerequisites
|
||||
FROM ubuntu:latest as prerequisites
|
||||
|
||||
# Stage 1: Install build dependencies
|
||||
#RUN apt-get update && apt-get -y install \
|
||||
# build-essential \
|
||||
# cmake \
|
||||
# wget \
|
||||
# 7zip \
|
||||
# git \
|
||||
# flex \
|
||||
# libfl-dev \
|
||||
# nasm \
|
||||
# libslang2-dev \
|
||||
# pkg-config \
|
||||
# libslang2-modules \
|
||||
# gcc-multilib \
|
||||
# && rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update && apt-get -y install \
|
||||
build-essential \
|
||||
cmake \
|
||||
wget \
|
||||
7zip \
|
||||
git \
|
||||
flex \
|
||||
libfl-dev \
|
||||
nasm \
|
||||
libslang2-dev \
|
||||
pkg-config \
|
||||
libslang2-modules \
|
||||
gcc-multilib \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
FROM djgpp-prerequisites:latest as djgpp-watt32
|
||||
FROM prerequisites as djgpp
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
WORKDIR /
|
||||
|
||||
ENV CC=/djgpp/bin/i586-pc-msdosdjgpp-gcc CXX=/djgpp/bin/i586-pc-msdosdjgpp-g++ CMAKE_FIND_ROOT_PATH=/djgpp WATT_ROOT=/djgpp/watt32
|
||||
ENV CC=/djgpp/bin/i586-pc-msdosdjgpp-gcc CXX=/djgpp/bin/i586-pc-msdosdjgpp-g++ CMAKE_FIND_ROOT_PATH=/djgpp
|
||||
|
||||
# Stage 2: compile WATT32 for D
|
||||
# Stage 2: setup djgpp
|
||||
RUN wget https://github.com/andrewwutw/build-djgpp/releases/download/v3.4/djgpp-linux64-gcc1220.tar.bz2 \
|
||||
&& tar xjf djgpp-linux64-gcc1220.tar.bz2 \
|
||||
&& rm -rf djgpp-linux64-gcc1220.tar.bz2 \
|
||||
&& cd djgpp \
|
||||
&& git clone https://github.com/UMSKT/Watt-32.git watt32 \
|
||||
&& cd watt32/util \
|
||||
&& make clean && make linux \
|
||||
&& cd ../src \
|
||||
&& source /djgpp/setenv \
|
||||
&& ./configur.sh djgpp \
|
||||
&& make -f djgpp.mak \
|
||||
&& ln -s ${WATT_ROOT}/lib/libwatt.a ${CMAKE_FIND_ROOT_PATH}/lib
|
||||
&& rm -rf djgpp-linux64-gcc1220.tar.bz2
|
||||
|
||||
# Stage 3: compile UMSKT
|
||||
FROM djgpp-watt32 as build
|
||||
FROM djgpp as build
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
WORKDIR /src
|
||||
COPY . /src
|
||||
|
||||
ENV PKG_CONFIG_PATH=/djgpp/lib/pkgconfig VERBOSE=1
|
||||
# Build UMSKT from the local directory
|
||||
RUN mkdir /src/build \
|
||||
&& cd /src/build \
|
||||
&& source /djgpp/setenv \
|
||||
&& cmake -DDJGPP_WATT32=${WATT_ROOT}/lib/libwatt.a .. \
|
||||
&& make
|
||||
&& cmake -DUMSKT_DJGPP_COMPILE=On -DCMAKE_BUILD_TYPE=Release -DCPM_SOURCE_CACHE=`pwd`/.cpm-cache -B build \
|
||||
&& cmake --build build -j 10 --verbose
|
||||
|
||||
CMD ["bash"]
|
||||
|
||||
# Stage 6: Output
|
||||
FROM scratch as output
|
||||
|
||||
COPY --from=build /src/build/umskt.exe /umskt.exe
|
||||
COPY --from=build /src/build/umskt.exe /
|
||||
|
||||
# invoke via
|
||||
# docker build -f Dockerfile.djgpp -o type=tar,dest=build-djgpp/umskt-dos.tar .
|
||||
|
@ -23,8 +23,8 @@
|
||||
# Stage 1: Install Visual Studio
|
||||
FROM mcr.microsoft.com/dotnet/framework/runtime:4.8.1 as visualstudio
|
||||
# Download and install Build Tools for Visual Studio 2022 for native desktop workload.
|
||||
#ADD https://aka.ms/vs/17/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe
|
||||
ADD vs_buildtools.exe C:\TEMP\vs_buildtools.exe
|
||||
ADD https://aka.ms/vs/17/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe
|
||||
#ADD vs_buildtools.exe C:\TEMP\vs_buildtools.exe
|
||||
RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
|
||||
--add Microsoft.VisualStudio.Workload.VCTools `
|
||||
--add Microsoft.VisualStudio.Workload.MSBuildTools `
|
||||
@ -40,26 +40,15 @@ RUN ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass", "[System.Net.Ser
|
||||
RUN ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass", "choco feature enable -n allowGlobalConfirmation"]
|
||||
RUN ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass", "choco install git --params \"'/GitAndUnixToolsOnPath /WindowsTerminal /NoShellIntegration /NoGuiHereIntegration /NoShellHereIntegration /NoCredentialManager /SChannel'\""]
|
||||
|
||||
#Install OpenSSL 32bit 3.1.1
|
||||
#ADD https://slproweb.com/download/Win32OpenSSL-3_1_1.msi C:\TEMP\Win32OpenSSL-3_1_1.msi
|
||||
ADD Win32OpenSSL-3_1_1.msi C:\TEMP\Win32OpenSSL-3_1_1.msi
|
||||
RUN msiexec /i C:\TEMP\Win32OpenSSL-3_1_1.msi /quiet /qn /norestart
|
||||
|
||||
#Install OpenSSL 64bit 3.1.1
|
||||
#ADD https://slproweb.com/download/Win64OpenSSL-3_1_1.msi C:\TEMP\Win64OpenSSL-3_1_1.msi
|
||||
ADD Win64OpenSSL-3_1_1.msi C:\TEMP\Win64OpenSSL-3_1_1.msi
|
||||
RUN msiexec /i C:\TEMP\Win64OpenSSL-3_1_1.msi /quiet /qn /norestart
|
||||
|
||||
# Stage 3: Build the 32-bit version of UMSKT
|
||||
FROM prereqisites as Build32
|
||||
WORKDIR C:\umskt\
|
||||
COPY . C:\umskt\
|
||||
|
||||
RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat && `
|
||||
mkdir C:\umskt\build && `
|
||||
cd C:\umskt\build && `
|
||||
cmake -DMSVC_MSDOS_STUB:string=..\umskt.exe .. -G "Visual Studio 17 2022" -A "Win32" -T v141_xp && `
|
||||
msbuild ALL_BUILD.vcxproj /P:Configuration=Release
|
||||
mkdir C:\umskt\build && cd C:\umskt && `
|
||||
cmake -B build -DCPM_SOURCE_CACHE=../.cpm-cache -DUMSKT_MSVC_WINXP=On -DCMAKE_BUILD_TYPE=Release -DMSVC_MSDOS_STUB=..\umskt.exe -G "Visual Studio 17 2022" -A "Win32" -T v141_xp && `
|
||||
cmake --build build --config Release -j 10
|
||||
|
||||
# Stage 4: Build the 64-bit version of UMSKT
|
||||
FROM prereqisites as Build64
|
||||
@ -67,12 +56,10 @@ FROM prereqisites as Build64
|
||||
WORKDIR C:\umskt\
|
||||
COPY . C:\umskt\
|
||||
|
||||
ENV OPENSSL_ROOT_DIR="C:\Program Files\OpenSSL-Win64"
|
||||
RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat && `
|
||||
mkdir C:\umskt\build && `
|
||||
cd C:\umskt\build && `
|
||||
cmake .. && `
|
||||
msbuild ALL_BUILD.vcxproj /P:Configuration=Release
|
||||
cd C:\umskt && `
|
||||
cmake -B build -DCPM_SOURCE_CACHE=../.cpm-cache -DCMAKE_BUILD_TYPE=Release && `
|
||||
cmake --build build --config Release -j 10
|
||||
|
||||
# Stage 5: Copy binaries to an output/runtime image
|
||||
FROM mcr.microsoft.com/dotnet/framework/runtime:4.8.1 as output
|
||||
|
15
keys.json
15
keys.json
@ -1235,21 +1235,6 @@
|
||||
"y": "11647588982042777999933885074728841323429055317640349743317690400085264609368266409172384083304384956740124856614996"
|
||||
}
|
||||
},
|
||||
"0B": {
|
||||
"a": "1",
|
||||
"b": "0",
|
||||
"g": {
|
||||
"x": "17272533675023793624680016937607161394427776688401278127884215858369066406365237833207419170117031265147050748737186",
|
||||
"y": "10897684556651576571671151674586120690608236542740270859915076272932083320838022698730208293779451126638581586588925"
|
||||
},
|
||||
"n": "44682719955829289",
|
||||
"p": "31123778862031392435299439090755153401162704597024288571183830527113563344679315725116915983118187065183839828632113",
|
||||
"priv": "30177475288172038",
|
||||
"pub": {
|
||||
"x": "10584120526089473026246191383792758367144927589909587205278073830223938861208553884400816982485323081066790399437204",
|
||||
"y": "19710761542152200618172612283139324015316083022563473705358032993141026289202915973780473937312193485361804450068338"
|
||||
}
|
||||
},
|
||||
"0C": {
|
||||
"a": "1",
|
||||
"b": "0",
|
||||
|
325
src/cli.cpp
325
src/cli.cpp
@ -1,325 +0,0 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2024 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Andrew on 01/06/2023
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "cli.h"
|
||||
|
||||
// define static storage
|
||||
CLI::Options CLI::options;
|
||||
json CLI::keys;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param argcIn
|
||||
* @param argvIn
|
||||
* @return exit status (where success is 0)
|
||||
*/
|
||||
BYTE CLI::Init(int argcIn, char **argvIn)
|
||||
{
|
||||
// set default options
|
||||
options.argc = argcIn;
|
||||
options.argv = argvIn;
|
||||
options.binkID = "2E";
|
||||
options.productCode = "WINXP";
|
||||
options.productFlavour = "VLK";
|
||||
options.numKeys = 1;
|
||||
options.pidgenversion = Options::PIDGEN_VERSION::PIDGEN_3;
|
||||
options.state = Options::APPLICATION_STATE::STATE_PIDGEN_GENERATE;
|
||||
|
||||
SetHelpText();
|
||||
|
||||
BOOL success = parseCommandLine();
|
||||
if (!success)
|
||||
{
|
||||
return options.error;
|
||||
}
|
||||
|
||||
// if we displayed help, without an error
|
||||
// return success
|
||||
if (options.help)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
success = processOptions();
|
||||
if (!success)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param filename
|
||||
* @return success
|
||||
*/
|
||||
BOOL CLI::loadJSON(const fs::path &filename)
|
||||
{
|
||||
if (filename.empty())
|
||||
{
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("Loading internal keys file\n");
|
||||
}
|
||||
|
||||
auto retval = loadEmbeddedJSON();
|
||||
|
||||
if (retval && options.verbose)
|
||||
{
|
||||
fmt::print("Loaded internal keys file successfully\n\n");
|
||||
}
|
||||
else if (!retval)
|
||||
{
|
||||
fmt::print("Error loading internal keys file...\n\n");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (!fs::exists(filename))
|
||||
{
|
||||
fmt::print("ERROR: File {} does not exist\n", filename.string());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("Loading keys file: {}\n", options.keysFilename);
|
||||
}
|
||||
|
||||
std::ifstream f(filename);
|
||||
try
|
||||
{
|
||||
keys = json::parse(f, nullptr, false, false);
|
||||
}
|
||||
catch (const json::exception &e)
|
||||
{
|
||||
fmt::print("ERROR: Exception thrown while parsing {}: {}\n", filename.string(), e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keys.is_discarded())
|
||||
{
|
||||
fmt::print("ERROR: Unable to parse keys from: {}\n", filename.string());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("Loaded keys from \"{}\" successfully\n", options.keysFilename);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pidgen3
|
||||
* @return success
|
||||
*/
|
||||
BOOL CLI::InitPIDGEN3(PIDGEN3 *p3)
|
||||
{
|
||||
auto bink = keys["BINK"][options.binkID];
|
||||
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("{:->80}\n", "");
|
||||
fmt::print("Loaded the following elliptic curve parameters: BINK[{}]\n", options.binkID);
|
||||
fmt::print("{:->80}\n", "");
|
||||
fmt::print("{:>6}: {}\n", "P", bink["p"]);
|
||||
fmt::print("{:>6}: {}\n", "a", bink["a"]);
|
||||
fmt::print("{:>6}: {}\n", "b", bink["b"]);
|
||||
fmt::print("{:>6}: [{},\n{:>9}{}]\n", "G[x,y]", bink["g"]["x"], "", bink["g"]["y"]);
|
||||
fmt::print("{:>6}: [{},\n{:>9}{}]\n", "K[x,y]", bink["pub"]["x"], "", bink["pub"]["y"]);
|
||||
fmt::print("{:>6}: {}\n", "n", bink["n"]);
|
||||
fmt::print("{:>6}: {}\n", "k", bink["priv"]);
|
||||
fmt::print("\n");
|
||||
}
|
||||
|
||||
p3->LoadEllipticCurve(options.binkID, bink["p"], bink["a"], bink["b"], bink["g"]["x"], bink["g"]["y"],
|
||||
bink["pub"]["x"], bink["pub"]["y"], bink["n"], bink["priv"]);
|
||||
|
||||
if (options.state != Options::APPLICATION_STATE::STATE_PIDGEN_GENERATE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (options.channelID.IsZero())
|
||||
{
|
||||
options.channelID.Randomize(UMSKT::rng, sizeof(DWORD32) * 8);
|
||||
}
|
||||
|
||||
options.channelID %= 999;
|
||||
p3->info.ChannelID = options.channelID;
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("> Channel ID: {:d}\n", options.channelID);
|
||||
}
|
||||
|
||||
if (options.serial.NotZero() && p3->checkFieldIsBink1998())
|
||||
{
|
||||
p3->info.Serial = options.serial;
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("> Serial {:d}\n", options.serial);
|
||||
}
|
||||
}
|
||||
else if (options.serial.NotZero() && !p3->checkFieldIsBink1998())
|
||||
{
|
||||
fmt::print("Warning: Discarding user-supplied serial for BINK2002\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param confid
|
||||
* @return success
|
||||
*/
|
||||
BOOL CLI::InitConfirmationID(ConfirmationID &confid)
|
||||
{
|
||||
if (!keys["products"][options.productCode].contains("meta") ||
|
||||
!keys["products"][options.productCode]["meta"].contains("activation"))
|
||||
{
|
||||
fmt::print("ERROR: product flavour \"{}\" does not have known activation values", options.productCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto meta = keys["products"][options.productCode]["meta"]["activation"];
|
||||
|
||||
if (!keys["activation"].contains(meta["flavour"]))
|
||||
{
|
||||
fmt::print("ERROR: \"{}\" is an unknown activation flavour", meta["flavour"]);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto flavour = keys["activation"][meta["flavour"]];
|
||||
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("{:->80}\n", "");
|
||||
fmt::print("Loaded the following hyperelliptic curve parameters: activation[{}]\n", meta["flavour"]);
|
||||
fmt::print("{:->80}\n", "");
|
||||
fmt::print("{:>7}: {}\n", "name", flavour["name"]);
|
||||
fmt::print("{:>7}: {}\n", "version", meta["version"]);
|
||||
fmt::print("{:>7}: {}\n", "Fp", flavour["p"]);
|
||||
fmt::print("{:>7}: [{}, {}, {},\n{:>10}{}, {}, {}]\n", "F[]", flavour["x"]["0"], flavour["x"]["1"],
|
||||
flavour["x"]["2"], "", flavour["x"]["3"], flavour["x"]["4"], flavour["x"]["5"]);
|
||||
fmt::print("{:>7}: {}\n", "INV", flavour["quotient"]);
|
||||
fmt::print("{:>7}: {}\n", "mqnr", flavour["non_residue"]);
|
||||
fmt::print("{:>7}: {}\n", "k", flavour["priv"]);
|
||||
fmt::print("{:>7}: {}\n", "IID", flavour["iid_key"]);
|
||||
fmt::print("\n");
|
||||
}
|
||||
|
||||
confid.LoadHyperellipticCurve(flavour["x"]["0"], flavour["x"]["1"], flavour["x"]["2"], flavour["x"]["3"],
|
||||
flavour["x"]["4"], flavour["x"]["5"], flavour["priv"], flavour["quotient"],
|
||||
flavour["non_residue"], flavour["iid_key"], meta["tags"].contains("xpbrand"),
|
||||
meta["tags"].contains("office"), meta["activation"]["version"]);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return success
|
||||
*/
|
||||
BOOL CLI::PIDGenerate()
|
||||
{
|
||||
BOOL retval = false;
|
||||
|
||||
if (options.pidgenversion == Options::PIDGEN_VERSION::PIDGEN_2)
|
||||
{
|
||||
auto p2 = PIDGEN2();
|
||||
retval = PIDGEN2Generate(p2);
|
||||
return retval;
|
||||
}
|
||||
else if (options.pidgenversion == Options::PIDGEN_VERSION::PIDGEN_3)
|
||||
{
|
||||
auto bink = keys["BINK"][options.binkID];
|
||||
|
||||
auto p3 = PIDGEN3::Factory(bink["p"]);
|
||||
InitPIDGEN3(p3);
|
||||
retval = PIDGEN3Generate(p3);
|
||||
|
||||
delete p3;
|
||||
return retval;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return isValid
|
||||
*/
|
||||
BOOL CLI::PIDValidate()
|
||||
{
|
||||
BOOL retval = false;
|
||||
|
||||
if (options.pidgenversion == Options::PIDGEN_VERSION::PIDGEN_2)
|
||||
{
|
||||
auto p2 = PIDGEN2();
|
||||
retval = PIDGEN2Validate(p2);
|
||||
return retval;
|
||||
}
|
||||
else if (options.pidgenversion == Options::PIDGEN_VERSION::PIDGEN_3)
|
||||
{
|
||||
auto bink = keys["BINK"][options.binkID];
|
||||
|
||||
auto p3 = PIDGEN3::Factory(bink["p"]);
|
||||
InitPIDGEN3(p3);
|
||||
retval = PIDGEN3Validate(p3);
|
||||
|
||||
delete p3;
|
||||
return retval;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process application state
|
||||
*
|
||||
* @return application status code
|
||||
*/
|
||||
int CLI::Run()
|
||||
{
|
||||
/**
|
||||
* TODO: we should be checking if the system's pseudorandom facilities work
|
||||
* before attempting generation, validation does not require entropy
|
||||
*/
|
||||
switch (options.state)
|
||||
{
|
||||
case Options::APPLICATION_STATE::STATE_PIDGEN_GENERATE:
|
||||
return PIDGenerate();
|
||||
|
||||
case Options::APPLICATION_STATE::STATE_PIDGEN_VALIDATE:
|
||||
return PIDValidate();
|
||||
|
||||
case Options::APPLICATION_STATE::STATE_CONFIRMATION_ID:
|
||||
return ConfirmationIDGenerate();
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
159
src/cli/cli.cpp
Normal file
159
src/cli/cli.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2024 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Andrew on 01/06/2023
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "cli.h"
|
||||
|
||||
// define static storage
|
||||
CLI::Options CLI::options;
|
||||
json CLI::keys;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param argcIn
|
||||
* @param argvIn
|
||||
* @return exit status (where success is 0)
|
||||
*/
|
||||
BYTE CLI::Init(int argcIn, char **argvIn)
|
||||
{
|
||||
// set default options
|
||||
options.argc = argcIn;
|
||||
options.argv = argvIn;
|
||||
options.binkID = "2E";
|
||||
options.productCode = "WINXP";
|
||||
options.productFlavour = "VLK";
|
||||
options.numKeys = 1;
|
||||
options.pidgenversion = Options::PIDGEN_VERSION::PIDGEN_3;
|
||||
options.state = Options::APPLICATION_STATE::STATE_PIDGEN_GENERATE;
|
||||
|
||||
SetHelpText();
|
||||
|
||||
BOOL success = parseCommandLine();
|
||||
if (!success)
|
||||
{
|
||||
return options.error;
|
||||
}
|
||||
|
||||
// if we displayed help, without an error
|
||||
// return success
|
||||
if (options.help)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
success = processOptions();
|
||||
if (!success)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param filename
|
||||
* @return success
|
||||
*/
|
||||
BOOL CLI::loadJSON(const fs::path &filename)
|
||||
{
|
||||
if (filename.empty())
|
||||
{
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("Loading internal keys file\n");
|
||||
}
|
||||
|
||||
auto retval = loadEmbeddedJSON();
|
||||
|
||||
if (retval && options.verbose)
|
||||
{
|
||||
fmt::print("Loaded internal keys file successfully\n\n");
|
||||
}
|
||||
else if (!retval)
|
||||
{
|
||||
fmt::print("Error loading internal keys file...\n\n");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (!fs::exists(filename))
|
||||
{
|
||||
fmt::print("ERROR: File {} does not exist\n", filename.string());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("Loading keys file: {}\n", options.keysFilename);
|
||||
}
|
||||
|
||||
std::ifstream f(filename);
|
||||
try
|
||||
{
|
||||
keys = json::parse(f, nullptr, false, false);
|
||||
}
|
||||
catch (const json::exception &e)
|
||||
{
|
||||
fmt::print("ERROR: Exception thrown while parsing {}: {}\n", filename.string(), e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keys.is_discarded())
|
||||
{
|
||||
fmt::print("ERROR: Unable to parse keys from: {}\n", filename.string());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("Loaded keys from \"{}\" successfully\n", options.keysFilename);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process application state
|
||||
*
|
||||
* @return application status code
|
||||
*/
|
||||
int CLI::Run()
|
||||
{
|
||||
/**
|
||||
* TODO: we should be checking if the system's pseudorandom facilities work
|
||||
* before attempting generation, validation does not require entropy
|
||||
*/
|
||||
switch (options.state)
|
||||
{
|
||||
case Options::APPLICATION_STATE::STATE_PIDGEN_GENERATE:
|
||||
return PIDGenerate();
|
||||
|
||||
case Options::APPLICATION_STATE::STATE_PIDGEN_VALIDATE:
|
||||
return PIDValidate();
|
||||
|
||||
case Options::APPLICATION_STATE::STATE_CONFIRMATION_ID:
|
||||
return ConfirmationIDGenerate();
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
@ -23,8 +23,7 @@
|
||||
#ifndef UMSKT_CLI_H
|
||||
#define UMSKT_CLI_H
|
||||
|
||||
#include "libumskt/libumskt.h"
|
||||
#include "typedefs.h"
|
||||
#include <libumskt/libumskt.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
@ -32,7 +31,6 @@
|
||||
|
||||
#include <fmt/color.h>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/ostream.h>
|
||||
#include <fmt/ranges.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
@ -40,7 +38,7 @@ using json = nlohmann::json;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
// fmt <-> json linkage
|
||||
template <> struct fmt::formatter<json> : ostream_formatter
|
||||
template <> struct fmt::formatter<json> : formatter<string_view>
|
||||
{
|
||||
auto format(const json &j, format_context &ctx) const
|
||||
{
|
||||
@ -50,18 +48,20 @@ template <> struct fmt::formatter<json> : ostream_formatter
|
||||
}
|
||||
else
|
||||
{
|
||||
return basic_ostream_formatter<char>::format(j, ctx);
|
||||
std::stringstream s;
|
||||
s << j;
|
||||
return formatter<string_view>::format(s.str(), ctx);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#include "../libumskt/confid/confid.h"
|
||||
#include "../libumskt/libumskt.h"
|
||||
#include "../libumskt/pidgen2/PIDGEN2.h"
|
||||
#include "../libumskt/pidgen3/BINK1998.h"
|
||||
#include "../libumskt/pidgen3/BINK2002.h"
|
||||
#include "../libumskt/pidgen3/PIDGEN3.h"
|
||||
#include "help.h"
|
||||
#include "libumskt/confid/confid.h"
|
||||
#include "libumskt/libumskt.h"
|
||||
#include "libumskt/pidgen2/PIDGEN2.h"
|
||||
#include "libumskt/pidgen3/BINK1998.h"
|
||||
#include "libumskt/pidgen3/BINK2002.h"
|
||||
#include "libumskt/pidgen3/PIDGEN3.h"
|
||||
|
||||
#ifndef UMSKTCLI_VERSION_STRING
|
||||
#define UMSKTCLI_VERSION_STRING "unknown version-dirty"
|
127
src/cli/confirmationid.cpp
Normal file
127
src/cli/confirmationid.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2024 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 02/18/2024
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "cli.h"
|
||||
|
||||
/**
|
||||
*
|
||||
* @param confid
|
||||
* @return success
|
||||
*/
|
||||
BOOL CLI::InitConfirmationID(ConfirmationID &confid)
|
||||
{
|
||||
if (!keys["products"][options.productCode].contains("meta") ||
|
||||
!keys["products"][options.productCode]["meta"].contains("activation"))
|
||||
{
|
||||
fmt::print("ERROR: product flavour \"{}\" does not have known activation values", options.productCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto meta = keys["products"][options.productCode]["meta"]["activation"];
|
||||
|
||||
if (!keys["activation"].contains(meta["flavour"]))
|
||||
{
|
||||
fmt::print("ERROR: \"{}\" is an unknown activation flavour", meta["flavour"]);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto flavour = keys["activation"][meta["flavour"]];
|
||||
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("{:->80}\n", "");
|
||||
fmt::print("Loaded the following hyperelliptic curve parameters: activation[{}]\n", meta["flavour"]);
|
||||
fmt::print("{:->80}\n", "");
|
||||
fmt::print("{:>7}: {}\n", "name", flavour["name"]);
|
||||
fmt::print("{:>7}: {}\n", "version", meta["version"]);
|
||||
fmt::print("{:>7}: {}\n", "Fp", flavour["p"]);
|
||||
fmt::print("{:>7}: [{}, {}, {},\n{:>10}{}, {}, {}]\n", "F[]", flavour["x"]["0"], flavour["x"]["1"],
|
||||
flavour["x"]["2"], "", flavour["x"]["3"], flavour["x"]["4"], flavour["x"]["5"]);
|
||||
fmt::print("{:>7}: {}\n", "INV", flavour["quotient"]);
|
||||
fmt::print("{:>7}: {}\n", "mqnr", flavour["non_residue"]);
|
||||
fmt::print("{:>7}: {}\n", "k", flavour["priv"]);
|
||||
fmt::print("{:>7}: {}\n", "IID", flavour["iid_key"]);
|
||||
fmt::print("\n");
|
||||
}
|
||||
|
||||
confid.LoadHyperellipticCurve(flavour["x"]["0"], flavour["x"]["1"], flavour["x"]["2"], flavour["x"]["3"],
|
||||
flavour["x"]["4"], flavour["x"]["5"], flavour["priv"], flavour["quotient"],
|
||||
flavour["non_residue"], flavour["iid_key"], meta["tags"].contains("xpbrand"),
|
||||
meta["tags"].contains("office"), meta["activation"]["version"]);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return success
|
||||
*/
|
||||
BOOL CLI::ConfirmationIDGenerate()
|
||||
{
|
||||
auto confid = ConfirmationID();
|
||||
std::string confirmation_id;
|
||||
|
||||
if (!InitConfirmationID(confid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD32 err = confid.Generate(options.installationID, confirmation_id, options.productID);
|
||||
|
||||
if (err == SUCCESS)
|
||||
{
|
||||
fmt::print("{}\n", confirmation_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (err)
|
||||
{
|
||||
case ERR_TOO_SHORT:
|
||||
fmt::print("ERROR: Installation ID is too short.\n");
|
||||
break;
|
||||
|
||||
case ERR_TOO_LARGE:
|
||||
fmt::print("ERROR: Installation ID is too long.\n");
|
||||
break;
|
||||
|
||||
case ERR_INVALID_CHARACTER:
|
||||
fmt::print("ERROR: Invalid character in installation ID.\n");
|
||||
break;
|
||||
|
||||
case ERR_INVALID_CHECK_DIGIT:
|
||||
fmt::print("ERROR: Installation ID checksum failed. Please check that it is typed correctly.\n");
|
||||
break;
|
||||
|
||||
case ERR_UNKNOWN_VERSION:
|
||||
fmt::print("ERROR: Unknown installation ID version.\n");
|
||||
break;
|
||||
|
||||
case ERR_UNLUCKY:
|
||||
fmt::print("ERROR: Unable to generate valid confirmation ID.\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
fmt::print("Unknown error occurred during Confirmation ID generation: {}\n", err);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -37,7 +37,7 @@ void CLI::SetHelpText()
|
||||
helpOptions[OPTION_DEBUG] = {"d", "debug", "enable debug output", false, "", &SetDebugOption};
|
||||
|
||||
helpOptions[OPTION_FILE] = {
|
||||
"F", "file", "(advanced) specify which keys JSON file to load", true, "[embedded file]", &SetFileOption};
|
||||
"", "file", "(advanced) specify which keys JSON file to load", true, "[embedded file]", &SetFileOption};
|
||||
|
||||
helpOptions[OPTION_LIST] = {"l", "list", "list supported products", false, "", &SetListOption};
|
||||
|
||||
@ -52,7 +52,7 @@ void CLI::SetHelpText()
|
||||
true, "1", &SetNumberOption};
|
||||
|
||||
helpOptions[OPTION_ACTIVATIONID] = {
|
||||
"i", "installationID", "(activation only) installation ID used to generate confirmation ID", true,
|
||||
"I", "installationID", "(activation only) installation ID used to generate confirmation ID", true,
|
||||
"", &SetActivationIDOption};
|
||||
|
||||
helpOptions[OPTION_ACTIVATIONPID] = {
|
||||
@ -64,14 +64,14 @@ void CLI::SetHelpText()
|
||||
helpOptions[OPTION_UPGRADE] = {"U", "upgrade", "(PIDGEN 3 only) generate an upgrade key",
|
||||
false, "", &SetUpgradeOption};
|
||||
|
||||
helpOptions[OPTION_BINK] = {"b", "binkID", "(advanced) override which BINK identifier to load",
|
||||
true, "", &SetBINKOption};
|
||||
helpOptions[OPTION_BINK] = {"", "bink", "(advanced) override which BINK identifier to load",
|
||||
true, "", &SetBINKOption};
|
||||
|
||||
helpOptions[OPTION_CHANNELID] = {"c", "channelid", "(advanced) override which product channel to use",
|
||||
true, "", &SetChannelIDOption};
|
||||
helpOptions[OPTION_CHANNELID] = {"", "channel", "(advanced) override which product channel to use",
|
||||
true, "", &SetChannelIDOption};
|
||||
|
||||
helpOptions[OPTION_SERIAL] = {
|
||||
"s", "serial", "(advanced, PIDGEN 2/3 [BINK 1998] only) specify a serial to generate",
|
||||
"", "serial", "(advanced, PIDGEN 2/3 [BINK 1998] only) specify a serial to generate",
|
||||
true, "", &SetSerialOption};
|
||||
|
||||
helpOptions[OPTION_AUTHDATA] = {
|
||||
@ -331,9 +331,9 @@ BOOL CLI::processOptions()
|
||||
}
|
||||
|
||||
// FE and FF are BINK 1998, but use a different, currently unhandled encoding scheme, we return an error here
|
||||
if (options.binkID == "FE" || options.binkID == "FF")
|
||||
if (options.binkID == "TS00" || options.binkID == "TS01")
|
||||
{
|
||||
fmt::print("ERROR: Terminal Services BINKs (FE and FF) are unsupported at this time\n");
|
||||
fmt::print("ERROR: Terminal Services BINKs (TS00 and TS01) are unsupported at this time\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -357,7 +357,7 @@ BOOL CLI::processListCommand()
|
||||
// the following code is absolutely unhinged
|
||||
// I'm so sorry
|
||||
|
||||
#if defined(__UNICODE__) || defined(__GNUC__)
|
||||
#if defined(UNICODE) || defined(__GNUC__)
|
||||
auto *leaf = "\u251C", *last = "\u2514", *line = "\u2500";
|
||||
#else
|
||||
auto *leaf = "\xC3", *last = "\xC0", *line = "\xC4";
|
||||
@ -522,6 +522,7 @@ BOOL CLI::SetFileOption(const std::string &file)
|
||||
fmt::print("Setting file option to: {}\n", file);
|
||||
}
|
||||
options.keysFilename = file;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
3
src/cli/options.cpp
Normal file
3
src/cli/options.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
//
|
||||
// Created by neo on 2/18/2024.
|
||||
//
|
@ -16,12 +16,72 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 01/05/2024
|
||||
* @FileCreated by Neo on 02/18/2024
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "cli.h"
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pidgen3
|
||||
* @return success
|
||||
*/
|
||||
BOOL CLI::InitPIDGEN3(PIDGEN3 *p3)
|
||||
{
|
||||
auto bink = keys["BINK"][options.binkID];
|
||||
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("{:->80}\n", "");
|
||||
fmt::print("Loaded the following elliptic curve parameters: BINK[{}]\n", options.binkID);
|
||||
fmt::print("{:->80}\n", "");
|
||||
fmt::print("{:>6}: {}\n", "P", bink["p"]);
|
||||
fmt::print("{:>6}: {}\n", "a", bink["a"]);
|
||||
fmt::print("{:>6}: {}\n", "b", bink["b"]);
|
||||
fmt::print("{:>6}: [{},\n{:>9}{}]\n", "G[x,y]", bink["g"]["x"], "", bink["g"]["y"]);
|
||||
fmt::print("{:>6}: [{},\n{:>9}{}]\n", "K[x,y]", bink["pub"]["x"], "", bink["pub"]["y"]);
|
||||
fmt::print("{:>6}: {}\n", "n", bink["n"]);
|
||||
fmt::print("{:>6}: {}\n", "k", bink["priv"]);
|
||||
fmt::print("\n");
|
||||
}
|
||||
|
||||
p3->LoadEllipticCurve(options.binkID, bink["p"], bink["a"], bink["b"], bink["g"]["x"], bink["g"]["y"],
|
||||
bink["pub"]["x"], bink["pub"]["y"], bink["n"], bink["priv"]);
|
||||
|
||||
if (options.state != Options::APPLICATION_STATE::STATE_PIDGEN_GENERATE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (options.channelID.IsZero())
|
||||
{
|
||||
options.channelID.Randomize(UMSKT::rng, sizeof(DWORD32) * 8);
|
||||
}
|
||||
|
||||
options.channelID %= 999;
|
||||
p3->info.ChannelID = options.channelID;
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("> Channel ID: {:d}\n", options.channelID);
|
||||
}
|
||||
|
||||
if (options.serial.NotZero() && p3->checkFieldIsBink1998())
|
||||
{
|
||||
p3->info.Serial = options.serial;
|
||||
if (options.verbose)
|
||||
{
|
||||
fmt::print("> Serial {:d}\n", options.serial);
|
||||
}
|
||||
}
|
||||
else if (options.serial.NotZero() && !p3->checkFieldIsBink1998())
|
||||
{
|
||||
fmt::print("Warning: Discarding user-supplied serial for BINK2002\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pidgen2
|
||||
@ -59,6 +119,23 @@ BOOL CLI::PIDGEN2Generate(PIDGEN2 &p2)
|
||||
*/
|
||||
BOOL CLI::PIDGEN2Validate(PIDGEN2 &p2)
|
||||
{
|
||||
std::string product_key;
|
||||
|
||||
if (!p2.ValidateKeyString(options.keyToCheck, product_key))
|
||||
{
|
||||
fmt::print("ERROR: Product key is in an incorrect format!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
fmt::print("{}\n", p2.StringifyKey(product_key));
|
||||
|
||||
if (!p2.Validate(product_key))
|
||||
{
|
||||
fmt::print("ERROR: Product key is invalid! Wrong BINK ID?\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
fmt::print("Key validated successfully!\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -165,7 +242,7 @@ BOOL CLI::PIDGEN3Validate(PIDGEN3 *p3)
|
||||
{
|
||||
std::string product_key;
|
||||
|
||||
if (!PIDGEN3::ValidateKeyString(options.keyToCheck, product_key))
|
||||
if (!p3->ValidateKeyString(options.keyToCheck, product_key))
|
||||
{
|
||||
fmt::print("ERROR: Product key is in an incorrect format!\n");
|
||||
return false;
|
||||
@ -187,54 +264,56 @@ BOOL CLI::PIDGEN3Validate(PIDGEN3 *p3)
|
||||
*
|
||||
* @return success
|
||||
*/
|
||||
BOOL CLI::ConfirmationIDGenerate()
|
||||
BOOL CLI::PIDGenerate()
|
||||
{
|
||||
auto confid = ConfirmationID();
|
||||
std::string confirmation_id;
|
||||
BOOL retval = false;
|
||||
|
||||
if (!InitConfirmationID(confid))
|
||||
if (options.pidgenversion == Options::PIDGEN_VERSION::PIDGEN_2)
|
||||
{
|
||||
return false;
|
||||
auto p2 = PIDGEN2();
|
||||
retval = PIDGEN2Generate(p2);
|
||||
return retval;
|
||||
}
|
||||
else if (options.pidgenversion == Options::PIDGEN_VERSION::PIDGEN_3)
|
||||
{
|
||||
auto bink = keys["BINK"][options.binkID];
|
||||
|
||||
auto p3 = PIDGEN3::Factory(bink["p"]);
|
||||
InitPIDGEN3(p3);
|
||||
retval = PIDGEN3Generate(p3);
|
||||
|
||||
delete p3;
|
||||
return retval;
|
||||
}
|
||||
|
||||
DWORD32 err = confid.Generate(options.installationID, confirmation_id, options.productID);
|
||||
|
||||
if (err == SUCCESS)
|
||||
{
|
||||
fmt::print("{}\n", confirmation_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (err)
|
||||
{
|
||||
case ERR_TOO_SHORT:
|
||||
fmt::print("ERROR: Installation ID is too short.\n");
|
||||
break;
|
||||
|
||||
case ERR_TOO_LARGE:
|
||||
fmt::print("ERROR: Installation ID is too long.\n");
|
||||
break;
|
||||
|
||||
case ERR_INVALID_CHARACTER:
|
||||
fmt::print("ERROR: Invalid character in installation ID.\n");
|
||||
break;
|
||||
|
||||
case ERR_INVALID_CHECK_DIGIT:
|
||||
fmt::print("ERROR: Installation ID checksum failed. Please check that it is typed correctly.\n");
|
||||
break;
|
||||
|
||||
case ERR_UNKNOWN_VERSION:
|
||||
fmt::print("ERROR: Unknown installation ID version.\n");
|
||||
break;
|
||||
|
||||
case ERR_UNLUCKY:
|
||||
fmt::print("ERROR: Unable to generate valid confirmation ID.\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
fmt::print("Unknown error occurred during Confirmation ID generation: {}\n", err);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return isValid
|
||||
*/
|
||||
BOOL CLI::PIDValidate()
|
||||
{
|
||||
BOOL retval = false;
|
||||
|
||||
if (options.pidgenversion == Options::PIDGEN_VERSION::PIDGEN_2)
|
||||
{
|
||||
auto p2 = PIDGEN2();
|
||||
retval = PIDGEN2Validate(p2);
|
||||
return retval;
|
||||
}
|
||||
else if (options.pidgenversion == Options::PIDGEN_VERSION::PIDGEN_3)
|
||||
{
|
||||
auto bink = keys["BINK"][options.binkID];
|
||||
|
||||
auto p3 = PIDGEN3::Factory(bink["p"]);
|
||||
InitPIDGEN3(p3);
|
||||
retval = PIDGEN3Validate(p3);
|
||||
|
||||
delete p3;
|
||||
return retval;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
@ -24,6 +24,8 @@
|
||||
* the history provided by diamondggg is that they are the originator of the code
|
||||
* and was created in tandem with an acquaintance who knows number theory.
|
||||
* The file dates suggest this code was written sometime in 2017/2018
|
||||
*
|
||||
* The algorithm was refactored by Neo in 2023
|
||||
* }
|
||||
*/
|
||||
|
||||
@ -102,14 +104,14 @@ BOOL ConfirmationID::LoadHyperellipticCurve(const std::string *f, const std::str
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
Integer(&f[i][0]).Encode((BYTE *)curve[i], sizeof(QWORD));
|
||||
EncodeN(IntegerS(f[i]), curve[i]);
|
||||
}
|
||||
|
||||
Integer(&priv[0]).Encode(privateKey.byte, sizeof(Q_OWORD));
|
||||
EncodeN(IntegerS(priv), privateKey);
|
||||
|
||||
Integer(&modulus[0]).Encode((BYTE *)&MOD, sizeof(QWORD));
|
||||
EncodeN(IntegerS(modulus), MOD);
|
||||
|
||||
Integer(&nonresidue[0]).Encode((BYTE *)NON_RESIDUE, sizeof(QWORD));
|
||||
EncodeN(IntegerS(nonresidue), NON_RESIDUE);
|
||||
|
||||
this->isOffice = isOffice;
|
||||
this->isXPBrand = isXPBrand;
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifndef UMSKT_CONFID_H
|
||||
#define UMSKT_CONFID_H
|
||||
|
||||
#include "../libumskt.h"
|
||||
#include <libumskt/libumskt.h>
|
||||
|
||||
// Confirmation ID generator constants
|
||||
enum CONFIRMATION_ID_STATUS
|
||||
@ -44,7 +44,7 @@ typedef struct
|
||||
Q_OWORD u, v;
|
||||
} TDivisor;
|
||||
|
||||
class EXPORT ConfirmationID
|
||||
class EXPORT ConfirmationID : public UMSKT
|
||||
{
|
||||
QWORD MOD = 0, NON_RESIDUE = 0;
|
||||
QWORD curve[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
|
||||
|
55
src/libumskt/confid/confid_unittest.cpp
Normal file
55
src/libumskt/confid/confid_unittest.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2024 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 02/20/2024
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "confid.h"
|
||||
#include <libumskt/libumskt_unittest.h>
|
||||
|
||||
/**
|
||||
* ConfirmationID must not be an abstract class.
|
||||
*/
|
||||
TEST(TestConfirmationID, InstantiateConfirmationID)
|
||||
{
|
||||
auto p3 = new ConfirmationID();
|
||||
ASSERT_NE(p3, nullptr);
|
||||
delete p3;
|
||||
}
|
||||
|
||||
class TestConfirmationID : public libumsktUnitTests
|
||||
{
|
||||
protected:
|
||||
ConfirmationID *cid;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
cid = new ConfirmationID();
|
||||
cid->LoadHyperellipticCurve()
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
if (cid != nullptr)
|
||||
{
|
||||
delete cid;
|
||||
cid = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
@ -20,7 +20,7 @@
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "libumskt.h"
|
||||
#include <libumskt/libumskt.h>
|
||||
|
||||
std::FILE *UMSKT::debug;
|
||||
std::FILE *UMSKT::verbose;
|
||||
@ -38,7 +38,7 @@ BOOL UMSKT::CONSTRUCT()
|
||||
{
|
||||
#ifdef __DJGPP__
|
||||
// this should be set up as early as possible
|
||||
auto now = uclock();
|
||||
uclock();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@ -20,12 +20,12 @@
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "libumskt.h"
|
||||
#include "confid/confid.h"
|
||||
#include "pidgen2/PIDGEN2.h"
|
||||
#include "pidgen3/BINK1998.h"
|
||||
#include "pidgen3/BINK2002.h"
|
||||
#include "pidgen3/PIDGEN3.h"
|
||||
#include <libumskt/confid/confid.h>
|
||||
#include <libumskt/libumskt.h>
|
||||
#include <libumskt/pidgen2/PIDGEN2.h>
|
||||
#include <libumskt/pidgen3/BINK1998.h>
|
||||
#include <libumskt/pidgen3/BINK2002.h>
|
||||
#include <libumskt/pidgen3/PIDGEN3.h>
|
||||
|
||||
std::map<UMSKT_TAG, UMSKT_Value> UMSKT::tags;
|
||||
CryptoPP::DefaultAutoSeededRNG UMSKT::rng;
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifndef UMSKT_LIBUMSKT_H
|
||||
#define UMSKT_LIBUMSKT_H
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include <typedefs.h>
|
||||
|
||||
#ifdef __DJGPP__
|
||||
#include <time.h>
|
||||
@ -43,7 +43,6 @@ using Integer = CryptoPP::Integer;
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ostream.h>
|
||||
|
||||
// fmt <-> CryptoPP linkage
|
||||
template <> class fmt::formatter<Integer>
|
||||
@ -229,6 +228,21 @@ class EXPORT UMSKT
|
||||
return EncodeN(in, (BYTE *)&buf, sizeof(T));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode Integer to Native type T where T is a concrete type
|
||||
*
|
||||
* @tparam T
|
||||
* @param in
|
||||
* @param buf
|
||||
* @return
|
||||
*/
|
||||
template <typename T = DWORD32> INLINE static T EncodeN(const Integer &in)
|
||||
{
|
||||
T buf;
|
||||
EncodeN(in, (BYTE *)&buf, sizeof(T));
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a random number into a Native concrete type
|
||||
*
|
||||
|
39
src/libumskt/libumskt_unittest.h
Normal file
39
src/libumskt/libumskt_unittest.h
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2024 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 02/19/2024
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
#ifndef UMSKT_LIBUMSKT_UNITTEST_H
|
||||
#define UMSKT_LIBUMSKT_UNITTEST_H
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <libumskt/libumskt.h>
|
||||
|
||||
class libumsktUnitTests : public testing::Test
|
||||
{
|
||||
public:
|
||||
libumsktUnitTests()
|
||||
{
|
||||
// UMSKT::setVerboseOutput(stderr);
|
||||
// UMSKT::setDebugOutput(stderr);
|
||||
}
|
||||
~libumsktUnitTests() override = default;
|
||||
};
|
||||
|
||||
#endif // UMSKT_LIBUMSKT_UNITTEST_H
|
@ -34,15 +34,36 @@
|
||||
class PIDGEN : public UMSKT
|
||||
{
|
||||
public:
|
||||
virtual ~PIDGEN() = default;
|
||||
static const Integer SEVEN;
|
||||
static const Integer TEN;
|
||||
static const Integer MaxChannelID;
|
||||
static const Integer MaxSerial;
|
||||
|
||||
virtual BOOL Generate(std::string &pKey) = 0;
|
||||
virtual BOOL Validate(const std::string &pKey) = 0;
|
||||
virtual std::string StringifyKey(const std::string &pKey) = 0;
|
||||
virtual std::string StringifyProductID() = 0;
|
||||
virtual BOOL Generate(std::string &pKey)
|
||||
{
|
||||
throw std::runtime_error("PIDGEN::Generate() pure virtual function call");
|
||||
}
|
||||
|
||||
virtual BOOL Validate(const std::string &pKey)
|
||||
{
|
||||
throw std::runtime_error("PIDGEN::Validate() pure virtual function call");
|
||||
}
|
||||
|
||||
virtual std::string StringifyKey(const std::string &pKey)
|
||||
{
|
||||
throw std::runtime_error("PIDGEN::StringifyKey() pure virtual function call");
|
||||
}
|
||||
|
||||
virtual std::string StringifyProductID()
|
||||
{
|
||||
throw std::runtime_error("PIDGEN::StringifyProductID() pure virtual function call");
|
||||
}
|
||||
|
||||
virtual BOOL ValidateKeyString(const std::string &in_key, std::string &out_key)
|
||||
{
|
||||
throw std::runtime_error("PIDGEN::ValidateKeyString() pure virtual function call");
|
||||
}
|
||||
|
||||
Integer GenerateMod7(const Integer &in);
|
||||
BOOL isValidMod7(const Integer &in);
|
||||
|
@ -36,38 +36,21 @@ BOOL PIDGEN2::Generate(std::string &pKey)
|
||||
Integer random;
|
||||
random.Randomize(rng, sizeof(DWORD32) * 8);
|
||||
|
||||
info.ChannelID = random % MaxChannelID;
|
||||
if (!isValidChannelID())
|
||||
{
|
||||
info.ChannelID++;
|
||||
if (info.ChannelID <= Integer::Zero())
|
||||
{
|
||||
info.ChannelID = Integer::One();
|
||||
}
|
||||
else if (info.ChannelID >= 999)
|
||||
{
|
||||
info.ChannelID = 998;
|
||||
}
|
||||
}
|
||||
|
||||
random.Randomize(rng, sizeof(DWORD32) * 8);
|
||||
info.Serial = random % MaxSerial;
|
||||
info.ChannelID = info.ChannelID % MaxChannelID;
|
||||
info.Serial = info.Serial % MaxSerial;
|
||||
|
||||
if (info.isOEM)
|
||||
{
|
||||
info.Day = (random % Integer(365)) + Integer::One();
|
||||
info.Year = IntegerS(validYears[random % validYears.size()]);
|
||||
info.Day = info.Day % Integer(366);
|
||||
// info.Year = info.Year;
|
||||
|
||||
info.OEMID = (info.ChannelID * TEN) + (info.Serial / (MaxSerial / TEN));
|
||||
info.Serial %= (MaxSerial / TEN);
|
||||
|
||||
info.OEMID = (info.OEMID * TEN) + GenerateMod7(info.OEMID);
|
||||
|
||||
DWORD32 day, year, serial, oemid;
|
||||
EncodeN(info.Day, day);
|
||||
EncodeN(info.Year, year);
|
||||
EncodeN(info.Serial, serial);
|
||||
EncodeN(info.OEMID, oemid);
|
||||
DWORD32 day = EncodeN(info.Day), year = EncodeN(info.Year), serial = EncodeN(info.Serial),
|
||||
oemid = EncodeN(info.OEMID);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -81,9 +64,7 @@ BOOL PIDGEN2::Generate(std::string &pKey)
|
||||
info.ChannelID = (info.ChannelID * TEN) + ((info.ChannelID % TEN) + 1);
|
||||
info.Serial = (info.Serial * TEN) + GenerateMod7(info.Serial);
|
||||
|
||||
DWORD32 channelid, serial;
|
||||
EncodeN(info.ChannelID, channelid);
|
||||
EncodeN(info.Serial, serial);
|
||||
DWORD32 channelid = EncodeN(info.ChannelID), serial = EncodeN(info.Serial);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -96,11 +77,7 @@ BOOL PIDGEN2::Generate(std::string &pKey)
|
||||
{
|
||||
info.Serial = (info.Serial * TEN) + GenerateMod7(info.Serial);
|
||||
|
||||
fmt::print("{}\n", info.Serial);
|
||||
|
||||
DWORD32 channelid, serial;
|
||||
EncodeN(info.ChannelID, channelid);
|
||||
EncodeN(info.Serial, serial);
|
||||
DWORD32 channelid = EncodeN(info.ChannelID), serial = EncodeN(info.Serial);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -142,7 +119,7 @@ BOOL PIDGEN2::Generate(std::string &pKey)
|
||||
BOOL PIDGEN2::Validate(const std::string &pKey)
|
||||
{
|
||||
std::string filtered;
|
||||
std::copy_if(pKey.begin(), pKey.end(), std::back_inserter(filtered), [](char c) { return std::isdigit(c); });
|
||||
ValidateKeyString(pKey, filtered);
|
||||
|
||||
bool bIsValidChannelID, bIsValidSerial, bIsValidOEMDay, bIsValidOEMYear, bIsValidOEMID;
|
||||
|
||||
@ -241,6 +218,19 @@ std::string PIDGEN2::StringifyProductID()
|
||||
return fmt::format("{}-{}", info.ChannelID, info.Serial);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param in_key
|
||||
* @param out_key
|
||||
* @return
|
||||
*/
|
||||
BOOL INLINE PIDGEN2::ValidateKeyString(const std::string &in_key, std::string &out_key)
|
||||
{
|
||||
std::copy_if(in_key.begin(), in_key.end(), std::back_inserter(out_key), [](char c) { return std::isdigit(c); });
|
||||
|
||||
return out_key.length() == KeySize::FPP || out_key.length() == KeySize::Office || out_key.length() == KeySize::OEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the Serial with check digit a valid serial?
|
||||
*
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifndef UMSKT_PIDGEN2_H
|
||||
#define UMSKT_PIDGEN2_H
|
||||
|
||||
#include "../pidgen.h"
|
||||
#include <libumskt/pidgen.h>
|
||||
|
||||
class EXPORT PIDGEN2 : public PIDGEN
|
||||
{
|
||||
@ -38,6 +38,8 @@ class EXPORT PIDGEN2 : public PIDGEN
|
||||
};
|
||||
|
||||
public:
|
||||
~PIDGEN2() override = default;
|
||||
|
||||
struct KeyInfo
|
||||
{
|
||||
BOOL isOEM, isOffice;
|
||||
@ -48,6 +50,7 @@ class EXPORT PIDGEN2 : public PIDGEN
|
||||
BOOL Validate(const std::string &pKey) override;
|
||||
std::string StringifyKey(const std::string &pKey) override;
|
||||
std::string StringifyProductID() override;
|
||||
BOOL ValidateKeyString(const std::string &in_key, std::string &out_key) override;
|
||||
|
||||
BOOL isValidSerial();
|
||||
BOOL isValidOEMID();
|
||||
|
115
src/libumskt/pidgen2/PIDGEN2_unittest.cpp
Normal file
115
src/libumskt/pidgen2/PIDGEN2_unittest.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2024 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 02/19/2024
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "PIDGEN2.h"
|
||||
#include <libumskt/libumskt_unittest.h>
|
||||
|
||||
/**
|
||||
* PIDGEN2 must not be an abstract class.
|
||||
*/
|
||||
TEST(PIDGEN2, InstantiatePIDGEN2)
|
||||
{
|
||||
auto p2 = new PIDGEN2();
|
||||
ASSERT_NE(p2, nullptr);
|
||||
delete p2;
|
||||
}
|
||||
|
||||
class TestPIDGEN2 : public libumsktUnitTests
|
||||
{
|
||||
protected:
|
||||
PIDGEN *p;
|
||||
PIDGEN2 *p2;
|
||||
|
||||
PIDGEN2::KeyInfo valid_ki = {false, false, 60, 99, 0, 95, 111111};
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
p2 = new PIDGEN2();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
if (p != nullptr)
|
||||
{
|
||||
delete p;
|
||||
p = nullptr;
|
||||
}
|
||||
if (p2 != nullptr)
|
||||
{
|
||||
delete p2;
|
||||
p2 = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TestPIDGEN2, TestStringifyKeyFPP)
|
||||
{
|
||||
std::string pKey = "0951111111";
|
||||
pKey = p2->StringifyKey(pKey);
|
||||
ASSERT_STRCASEEQ(&pKey[0], "095-1111111");
|
||||
}
|
||||
|
||||
TEST_F(TestPIDGEN2, TestStringifyKeyOffice)
|
||||
{
|
||||
std::string pKey = "09561111111";
|
||||
pKey = p2->StringifyKey(pKey);
|
||||
ASSERT_STREQ(&pKey[0], "0956-1111111");
|
||||
}
|
||||
|
||||
TEST_F(TestPIDGEN2, TestStringifyKeyOEM)
|
||||
{
|
||||
std::string pKey = "06099000951611111";
|
||||
pKey = p2->StringifyKey(pKey);
|
||||
ASSERT_STREQ(&pKey[0], "06099-OEM-0009516-11111");
|
||||
}
|
||||
|
||||
TEST_F(TestPIDGEN2, GenerateValidFPPKey)
|
||||
{
|
||||
p2->info = valid_ki;
|
||||
|
||||
std::string pKey;
|
||||
p2->Generate(pKey);
|
||||
pKey = p2->StringifyKey(pKey);
|
||||
ASSERT_STREQ(&pKey[0], "095-1111111");
|
||||
}
|
||||
|
||||
TEST_F(TestPIDGEN2, GenerateValidOfficeKey)
|
||||
{
|
||||
p2->info = valid_ki;
|
||||
p2->info.isOffice = true;
|
||||
|
||||
std::string pKey;
|
||||
p2->Generate(pKey);
|
||||
pKey = p2->StringifyKey(pKey);
|
||||
ASSERT_STREQ(&pKey[0], "0956-1111111");
|
||||
}
|
||||
|
||||
TEST_F(TestPIDGEN2, GenerateValidOEMKey)
|
||||
{
|
||||
p2->info = valid_ki;
|
||||
p2->info.isOEM = true;
|
||||
|
||||
std::string pKey;
|
||||
p2->Generate(pKey);
|
||||
pKey = p2->StringifyKey(pKey);
|
||||
ASSERT_STREQ(&pKey[0], "06099-OEM-0009516-11111");
|
||||
}
|
@ -99,6 +99,11 @@ BOOL BINK1998::Generate(std::string &pKey)
|
||||
// copy initial state from object
|
||||
auto ki = info;
|
||||
|
||||
if (!ki.Rand.IsZero())
|
||||
{
|
||||
c = ki.Rand;
|
||||
}
|
||||
|
||||
// Data segment of the RPK.
|
||||
Integer serialPack = (ki.ChannelID * MaxSerial) + ki.Serial;
|
||||
Integer pData = (serialPack << 1) | ki.isUpgrade;
|
||||
@ -110,8 +115,11 @@ BOOL BINK1998::Generate(std::string &pKey)
|
||||
{
|
||||
ECP::Point R;
|
||||
|
||||
// Generate a random number c consisting of 384 bits without any constraints.
|
||||
c.Randomize(UMSKT::rng, FieldBits);
|
||||
if (ki.Rand.IsZero())
|
||||
{
|
||||
// Generate a random number c consisting of 384 bits without any constraints.
|
||||
c.Randomize(UMSKT::rng, FieldBits);
|
||||
}
|
||||
|
||||
// Pick a random derivative of the base point on the elliptic curve.
|
||||
// R = cG;
|
||||
@ -201,7 +209,7 @@ BOOL BINK1998::Generate(std::string &pKey)
|
||||
fmt::print(verbose, "\n");
|
||||
}
|
||||
|
||||
} while (ki.Signature.BitCount() > 55);
|
||||
} while (ki.Signature.BitCount() > 55 && ki.Rand.IsZero());
|
||||
// ↑ ↑ ↑
|
||||
// The signature can't be longer than 55 bits, else it will
|
||||
// make the CD-key longer than 25 characters.
|
||||
@ -237,13 +245,13 @@ BOOL BINK1998::Validate(const std::string &pKey)
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
fmt::print(UMSKT::verbose, "Validation results:\n");
|
||||
fmt::print(UMSKT::verbose, "{:>10}: {}\n", "Upgrade", (bool)ki.isUpgrade);
|
||||
fmt::print(UMSKT::verbose, "{:>10}: {}\n", "Channel ID", ki.ChannelID);
|
||||
fmt::print(UMSKT::verbose, "{:>10}: {}\n", "Sequence", ki.Serial);
|
||||
fmt::print(UMSKT::verbose, "{:>10}: {:x}\n", "Hash", ki.Hash);
|
||||
fmt::print(UMSKT::verbose, "{:>10}: {:x}\n", "Signature", ki.Signature);
|
||||
fmt::print(UMSKT::verbose, "\n");
|
||||
fmt::print(verbose, "Validation results:\n");
|
||||
fmt::print(verbose, "{:>10}: {}\n", "Upgrade", (bool)ki.isUpgrade);
|
||||
fmt::print(verbose, "{:>10}: {}\n", "Channel ID", ki.ChannelID);
|
||||
fmt::print(verbose, "{:>10}: {}\n", "Sequence", ki.Serial);
|
||||
fmt::print(verbose, "{:>10}: {:x}\n", "Hash", ki.Hash);
|
||||
fmt::print(verbose, "{:>10}: {:x}\n", "Signature", ki.Signature);
|
||||
fmt::print(verbose, "\n");
|
||||
}
|
||||
|
||||
Integer serialPack = (ki.ChannelID * MaxSerial) + ki.Serial;
|
||||
@ -280,7 +288,7 @@ BOOL BINK1998::Validate(const std::string &pKey)
|
||||
|
||||
if (debug)
|
||||
{
|
||||
fmt::print("\nP[x,y]: [{:x},\n{:x}]\n\n", P.x, P.y);
|
||||
fmt::print(debug, "P[x,y]: [{:x},\n{:x}]\n\n", P.x, P.y);
|
||||
}
|
||||
|
||||
BYTE msgDigest[SHA1::DIGESTSIZE], msgBuffer[SHAMessageLength], *pMsgBuffer = msgBuffer;
|
||||
|
@ -39,6 +39,8 @@ class EXPORT BINK1998 : public PIDGEN3
|
||||
eCurve = p3->eCurve;
|
||||
}
|
||||
|
||||
~BINK1998() override = default;
|
||||
|
||||
static constexpr DWORD32 FieldBits = (48 * 8);
|
||||
static constexpr DWORD32 FieldBytes = (FieldBits / 8);
|
||||
static constexpr DWORD32 SHAMessageLength = (4 + 2 * FieldBytes);
|
||||
|
110
src/libumskt/pidgen3/BINK1998_unittest.cpp
Normal file
110
src/libumskt/pidgen3/BINK1998_unittest.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2024 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 02/19/2024
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "../libumskt_unittest.h"
|
||||
#include "BINK1998.h"
|
||||
|
||||
/**
|
||||
* BINK1998 must not be an abstract class.
|
||||
*/
|
||||
TEST(PIDGEN3_BINK1998, InstantiateBINK1998)
|
||||
{
|
||||
auto p3 = new BINK1998();
|
||||
ASSERT_NE(p3, nullptr);
|
||||
delete p3;
|
||||
}
|
||||
|
||||
class TestBINK1998 : public libumsktUnitTests
|
||||
{
|
||||
protected:
|
||||
PIDGEN *p;
|
||||
PIDGEN3 *p3;
|
||||
BINK1998 *bink1998;
|
||||
|
||||
BINK1998::KeyInfo valid_ki = {false, false, 640, 111111, 0};
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
bink1998 = new BINK1998();
|
||||
bink1998->LoadEllipticCurve("0x2E",
|
||||
"2260481414313563299067995668434431120981995280321627195247220485552475627515144045"
|
||||
"6421260165232069708317717961315241",
|
||||
"1", "0",
|
||||
"1091074492220651278115691316907175015302838688467620894706280834607253141127048943"
|
||||
"2930252839559606812441712224597826",
|
||||
"1917099366991720451749161800061981867915210969017264186834961288993048036527467509"
|
||||
"6509477191800826190959228181870174",
|
||||
"1439923035396364333971294001595406158106423983592682351741971676961393703934682226"
|
||||
"9422480779920783799484349086780408",
|
||||
"5484731395987446993229594927733430043632089703338918322171291299699820472711849119"
|
||||
"800714736923107362018017833200634",
|
||||
"61760995553426173", "37454031876727861");
|
||||
bink1998->info = valid_ki;
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
if (bink1998 != nullptr)
|
||||
{
|
||||
delete bink1998;
|
||||
bink1998 = nullptr;
|
||||
}
|
||||
if (p3 != nullptr)
|
||||
{
|
||||
delete p3;
|
||||
p3 = nullptr;
|
||||
}
|
||||
if (p != nullptr)
|
||||
{
|
||||
p = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TestBINK1998, ValidateValidKeyString)
|
||||
{
|
||||
std::string pKey;
|
||||
auto ValidateKeyString = bink1998->ValidateKeyString("7KWK7-9W7H4-T64D6-DB8V7-BW7MW", pKey);
|
||||
|
||||
ASSERT_TRUE(ValidateKeyString);
|
||||
ASSERT_STREQ(&pKey[0], "7KWK79W7H4T64D6DB8V7BW7MW");
|
||||
}
|
||||
|
||||
TEST_F(TestBINK1998, ValidateValidKey)
|
||||
{
|
||||
std::string pKey = "7KWK79W7H4T64D6DB8V7BW7MW";
|
||||
|
||||
auto Validate = bink1998->Validate(pKey);
|
||||
ASSERT_TRUE(Validate);
|
||||
}
|
||||
|
||||
TEST_F(TestBINK1998, GenerateValidKey)
|
||||
{
|
||||
bink1998->info.Rand = UMSKT::IntegerS("3427338792529164195109698841758932126727183763685994848291878088992924483488"
|
||||
"5768429236548372772607190036626858221847");
|
||||
|
||||
std::string pKey;
|
||||
bink1998->Generate(pKey);
|
||||
pKey = bink1998->StringifyKey(pKey);
|
||||
|
||||
ASSERT_STREQ(&pKey[0], "7KWK7-9W7H4-T64D6-DB8V7-BW7MW");
|
||||
}
|
@ -44,7 +44,7 @@ Integer BINK2002::Pack(const KeyInfo &ki)
|
||||
|
||||
if (debug)
|
||||
{
|
||||
fmt::print("pack: {:x}\n\n", raw);
|
||||
fmt::print(debug, "pack: {:x}\n\n", raw);
|
||||
}
|
||||
|
||||
return raw;
|
||||
@ -97,6 +97,11 @@ BOOL BINK2002::Generate(std::string &pKey)
|
||||
|
||||
Integer c, e, s, pRaw;
|
||||
|
||||
if (!ki.Rand.IsZero())
|
||||
{
|
||||
c = ki.Rand;
|
||||
}
|
||||
|
||||
// Data segment of the RPK.
|
||||
Integer pData = ki.ChannelID << 1 | ki.isUpgrade;
|
||||
|
||||
@ -106,8 +111,11 @@ BOOL BINK2002::Generate(std::string &pKey)
|
||||
{
|
||||
ECP::Point R;
|
||||
|
||||
// Generate a random number c consisting of 512 bits without any constraints.
|
||||
c.Randomize(UMSKT::rng, FieldBits);
|
||||
if (ki.Rand.IsZero())
|
||||
{
|
||||
// Generate a random number c consisting of 512 bits without any constraints.
|
||||
c.Randomize(UMSKT::rng, FieldBits);
|
||||
}
|
||||
|
||||
// R = cG
|
||||
R = eCurve.Multiply(c, genPoint);
|
||||
@ -135,19 +143,19 @@ BOOL BINK2002::Generate(std::string &pKey)
|
||||
|
||||
if (debug)
|
||||
{
|
||||
fmt::print("msgBuffer[1]: ");
|
||||
fmt::print(debug, "msgBuffer[1]: ");
|
||||
for (BYTE b : msgBuffer)
|
||||
{
|
||||
fmt::print("{:x}", b);
|
||||
fmt::print(debug, "{:x}", b);
|
||||
}
|
||||
fmt::print("\n\n");
|
||||
fmt::print(debug, "\n\n");
|
||||
|
||||
fmt::print("msgDigest[1]: ");
|
||||
fmt::print(debug, "msgDigest[1]: ");
|
||||
for (BYTE b : msgDigest)
|
||||
{
|
||||
fmt::print("{:x}", b);
|
||||
fmt::print(debug, "{:x}", b);
|
||||
}
|
||||
fmt::print("\n\n");
|
||||
fmt::print(debug, "\n\n");
|
||||
}
|
||||
|
||||
// Translate the byte sha1 into a 32-bit integer - this is our computed hash.
|
||||
@ -159,12 +167,12 @@ BOOL BINK2002::Generate(std::string &pKey)
|
||||
BYTE buf[8];
|
||||
sha1.CalculateTruncatedDigest(buf, sizeof(buf), msgBuffer, SHAMessageLength);
|
||||
|
||||
fmt::print("truncated buffer: ");
|
||||
fmt::print(verbose, "truncated buffer: ");
|
||||
for (BYTE b : buf)
|
||||
{
|
||||
fmt::print("{:x}", b);
|
||||
fmt::print(verbose, "{:x}", b);
|
||||
}
|
||||
fmt::print("\n\n");
|
||||
fmt::print(verbose, "\n\n");
|
||||
|
||||
DWORD h0 = ((DWORD)buf[0] | ((DWORD)buf[1] << 8) | ((DWORD)buf[2] << 16) | ((DWORD)buf[3] << 24));
|
||||
DWORD h1 =
|
||||
@ -173,11 +181,11 @@ BOOL BINK2002::Generate(std::string &pKey)
|
||||
|
||||
h1 |= (h0 >> 31) & 1;
|
||||
|
||||
fmt::print("h0,1: {:x} {:x}\n\n", h0, h1);
|
||||
fmt::print(verbose, "h0,1: {:x} {:x}\n\n", h0, h1);
|
||||
|
||||
ki.Serial = IntegerN(h1);
|
||||
|
||||
fmt::print("serial: {:d}\n\n", ki.Serial);
|
||||
fmt::print(verbose, "serial: {:d}\n\n", ki.Serial);
|
||||
}
|
||||
|
||||
// Assemble the second SHA message.
|
||||
@ -200,19 +208,19 @@ BOOL BINK2002::Generate(std::string &pKey)
|
||||
|
||||
if (debug)
|
||||
{
|
||||
fmt::print("msgBuffer[2]: ");
|
||||
fmt::print(debug, "msgBuffer[2]: ");
|
||||
for (BYTE b : msgBuffer)
|
||||
{
|
||||
fmt::print("{:x}", b);
|
||||
fmt::print(debug, "{:x}", b);
|
||||
}
|
||||
fmt::print("\n\n");
|
||||
fmt::print(debug, "\n\n");
|
||||
|
||||
fmt::print("msgDigest[2]: ");
|
||||
fmt::print(debug, "msgDigest[2]: ");
|
||||
for (BYTE b : msgDigest)
|
||||
{
|
||||
fmt::print("{:x}", b);
|
||||
fmt::print(debug, "{:x}", b);
|
||||
}
|
||||
fmt::print("\n\n");
|
||||
fmt::print(debug, "\n\n");
|
||||
}
|
||||
|
||||
// Translate the byte sha1 into a 64-bit integer - this is our computed intermediate signature.
|
||||
@ -298,7 +306,7 @@ BOOL BINK2002::Generate(std::string &pKey)
|
||||
fmt::print(verbose, "{:>10}: {:x}\n", "AuthInfo", ki.AuthInfo);
|
||||
fmt::print(verbose, "\n");
|
||||
}
|
||||
} while (ki.Signature.BitCount() > 62 || noSquare);
|
||||
} while ((ki.Signature.BitCount() > 62 || noSquare) && ki.Rand.IsZero());
|
||||
// ↑ ↑ ↑
|
||||
// The signature can't be longer than 62 bits, else it will
|
||||
// overlap with the AuthInfo segment next to it.
|
||||
@ -402,7 +410,7 @@ BOOL BINK2002::Validate(const std::string &pKey)
|
||||
|
||||
if (debug)
|
||||
{
|
||||
fmt::print("P[x,y]: [{:x},\n{:x}]\n\n", P.x, P.y);
|
||||
fmt::print(debug, "P[x,y]: [{:x},\n{:x}]\n\n", P.x, P.y);
|
||||
}
|
||||
|
||||
// Assemble the second SHA message.
|
||||
|
@ -39,6 +39,8 @@ class EXPORT BINK2002 : public PIDGEN3
|
||||
eCurve = p3->eCurve;
|
||||
}
|
||||
|
||||
~BINK2002() override = default;
|
||||
|
||||
static constexpr DWORD32 FieldBits = (64 * 8);
|
||||
static constexpr DWORD32 FieldBytes = (FieldBits / 8);
|
||||
static constexpr DWORD32 SHAMessageLength = (3 + 2 * FieldBytes);
|
||||
|
121
src/libumskt/pidgen3/BINK2002_unittest.cpp
Normal file
121
src/libumskt/pidgen3/BINK2002_unittest.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2024 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 02/19/2024
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "BINK2002.h"
|
||||
#include <libumskt/libumskt_unittest.h>
|
||||
|
||||
/**
|
||||
* BINK2002 must not be an abstract class.
|
||||
*/
|
||||
TEST(PIDGEN3_BINK2002, InstantiateBINK2002)
|
||||
{
|
||||
auto p3 = new BINK2002();
|
||||
ASSERT_NE(p3, nullptr);
|
||||
delete p3;
|
||||
}
|
||||
|
||||
class TestBINK2002 : public libumsktUnitTests
|
||||
{
|
||||
protected:
|
||||
PIDGEN *p;
|
||||
PIDGEN3 *p3;
|
||||
BINK2002 *bink2002;
|
||||
|
||||
BINK2002::KeyInfo valid_ki = {false, false, 640, 0, 701};
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
bink2002 = new BINK2002();
|
||||
bink2002->LoadEllipticCurve("0x54",
|
||||
"1250964251969733259611431105354461862074700938981465222536952118871017192617497641"
|
||||
"9995384745134703589248167610052719613586668754176591418831031596093374569",
|
||||
"1", "0",
|
||||
"8059057663701168311917532277618827622978515614146963913097592614451721430413021070"
|
||||
"395782723330339842826599481063797559797462512297834269467666807971588275",
|
||||
"1223930383017475319177970597922037862339473226753699711562597963240231208768364492"
|
||||
"7405756146495100825573682155171145924668759419114616275413724686284123408",
|
||||
"4895832170509729140211911021638266775170167022247175324972987673313207244495397975"
|
||||
"379010973250279668424167408883454560376269866102669741515127286188717976",
|
||||
"5846013328426281815512452704859777850382010968846722453046994319336479079120767834"
|
||||
"777937190955827245502389471872759584209649693396095099112777776298051208",
|
||||
"5622613991231344109", "1285511085175426271");
|
||||
bink2002->info = valid_ki;
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
if (bink2002 != nullptr)
|
||||
{
|
||||
delete bink2002;
|
||||
bink2002 = nullptr;
|
||||
}
|
||||
if (p3 != nullptr)
|
||||
{
|
||||
delete p3;
|
||||
p3 = nullptr;
|
||||
}
|
||||
if (p != nullptr)
|
||||
{
|
||||
p = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TestBINK2002, ValidateValidKeyString)
|
||||
{
|
||||
std::string pKey;
|
||||
auto ValidateKeyString = bink2002->ValidateKeyString("QX7C7-6668G-RHTTC-9XXD6-4QKVM", pKey);
|
||||
ASSERT_TRUE(ValidateKeyString);
|
||||
ASSERT_STREQ(&pKey[0], "QX7C76668GRHTTC9XXD64QKVM");
|
||||
}
|
||||
|
||||
TEST_F(TestBINK2002, ValidateInvalidKeyString)
|
||||
{
|
||||
std::string pKey;
|
||||
auto ValidateKeyString = bink2002->ValidateKeyString("QX7C7-6668G-RHTTC-9XXD6-4QKVM-7", pKey);
|
||||
ASSERT_FALSE(ValidateKeyString);
|
||||
}
|
||||
|
||||
TEST_F(TestBINK2002, ValidateValidKey)
|
||||
{
|
||||
std::string pKey = "QX7C76668GRHTTC9XXD64QKVM";
|
||||
auto Validate = bink2002->Validate(pKey);
|
||||
ASSERT_TRUE(Validate);
|
||||
}
|
||||
|
||||
TEST_F(TestBINK2002, ValidateInvalidKey)
|
||||
{
|
||||
std::string pKey = "QX7C76668GRHTTC9XXD64QKV7";
|
||||
auto Validate = bink2002->Validate(pKey);
|
||||
ASSERT_FALSE(Validate);
|
||||
}
|
||||
|
||||
TEST_F(TestBINK2002, GenerateValidKey)
|
||||
{
|
||||
bink2002->info.Rand = UMSKT::IntegerS("2715417548459431244234182116258933974639514924173191881913315754156057922856"
|
||||
"789413383072541627152533502894944768632184791880876163762899980230935");
|
||||
std::string pKey;
|
||||
bink2002->Generate(pKey);
|
||||
pKey = bink2002->StringifyKey(pKey);
|
||||
|
||||
ASSERT_STREQ(&pKey[0], "QX7C7-6668G-RHTTC-9XXD6-4QKVM");
|
||||
}
|
@ -290,10 +290,10 @@ std::string PIDGEN3::StringifyKey(const std::string &pKey)
|
||||
* @param currentChar
|
||||
* @return
|
||||
*/
|
||||
std::string PIDGEN3::ValidateStringKeyInputCharset(std::string &accumulator, char currentChar)
|
||||
std::string INLINE PIDGEN3::ValidateStringKeyInputCharset(std::string &accumulator, char currentChar)
|
||||
{
|
||||
char cchar = (char)::toupper(currentChar);
|
||||
if (std::find(pKeyCharset.begin(), pKeyCharset.begin(), cchar) != pKeyCharset.end())
|
||||
if (std::find(pKeyCharset.begin(), pKeyCharset.end(), cchar) != pKeyCharset.end())
|
||||
{
|
||||
accumulator.push_back(cchar);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifndef UMSKT_PIDGEN3_H
|
||||
#define UMSKT_PIDGEN3_H
|
||||
|
||||
#include "../pidgen.h"
|
||||
#include <libumskt/pidgen.h>
|
||||
|
||||
class BINK1998;
|
||||
class BINK2002;
|
||||
@ -51,14 +51,12 @@ class EXPORT PIDGEN3 : public PIDGEN
|
||||
eCurve = p3.eCurve;
|
||||
}
|
||||
|
||||
virtual ~PIDGEN3()
|
||||
{
|
||||
}
|
||||
~PIDGEN3() override = default;
|
||||
|
||||
struct KeyInfo
|
||||
{
|
||||
Integer Serial = 0, AuthInfo = 0, ChannelID = 0, Hash = 0, Signature = 0, Rand = 0;
|
||||
BOOL isUpgrade = false, isOEM = false;
|
||||
Integer ChannelID = 0, Serial = 0, AuthInfo = 0, Rand = 0, Hash = 0, Signature = 0;
|
||||
|
||||
void setSerial(DWORD32 SerialIn)
|
||||
{
|
||||
@ -88,15 +86,22 @@ class EXPORT PIDGEN3 : public PIDGEN
|
||||
BOOL Validate(const std::string &pKey) override;
|
||||
std::string StringifyKey(const std::string &pKey) override;
|
||||
std::string StringifyProductID() override;
|
||||
BOOL ValidateKeyString(const std::string &in_key, std::string &out_key) override;
|
||||
|
||||
virtual Integer Pack(const KeyInfo &ki) = 0;
|
||||
virtual KeyInfo Unpack(const Integer &raw) = 0;
|
||||
virtual Integer Pack(const KeyInfo &ki)
|
||||
{
|
||||
throw std::runtime_error("PIDGEN3::Pack() pure virtual function call");
|
||||
}
|
||||
|
||||
virtual KeyInfo Unpack(const Integer &raw)
|
||||
{
|
||||
throw std::runtime_error("PIDGEN3::Unpack() pure virtual function call");
|
||||
}
|
||||
|
||||
// PIDGEN3.cpp
|
||||
static PIDGEN3 *Factory(const std::string &field);
|
||||
static BOOL checkFieldStrIsBink1998(std::string keyin);
|
||||
static std::string ValidateStringKeyInputCharset(std::string &accumulator, char currentChar);
|
||||
static BOOL ValidateKeyString(const std::string &in_key, std::string &out_key);
|
||||
static std::string base24(Integer &seq);
|
||||
static Integer unbase24(const std::string &cdKey);
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "cli.h"
|
||||
#include <cli/cli.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -20,7 +20,7 @@
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "cli.h"
|
||||
#include <cli/cli.h>
|
||||
|
||||
#include <cmrc/cmrc.hpp>
|
||||
CMRC_DECLARE(umskt);
|
||||
|
@ -25,20 +25,23 @@
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
// squelch the insane amount of warnings from cstdbool
|
||||
#define _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <intrin.h>
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstdbool>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
#include <stdint128>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -88,15 +91,6 @@ using WORD = uint16_t;
|
||||
using DWORD = unsigned long;
|
||||
using DWORD32 = uint32_t;
|
||||
using QWORD = uint64_t;
|
||||
|
||||
#if defined(__SIZEOF_INT128__) || defined(__int128)
|
||||
using uint128_t = unsigned __int128;
|
||||
#elif defined(_MSC_VER) && defined(_M_ARM) // for Windows on ARM ??
|
||||
using uint128_t = __n128;
|
||||
#else // use the intel-supplied __m128 intrisic from <intrin.h>
|
||||
using uint128_t = __m128;
|
||||
#endif
|
||||
|
||||
using OWORD = uint128_t;
|
||||
|
||||
typedef union {
|
||||
|
@ -20,8 +20,8 @@
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "resource.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
BOOLEAN WINAPI DllMain(IN HINSTANCE hDllHandle, IN DWORD nReason, IN LPVOID Reserved)
|
||||
{
|
||||
|
@ -20,7 +20,7 @@
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "../cli.h"
|
||||
#include "cli/cli.h"
|
||||
#include "resource.h"
|
||||
|
||||
/**
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user