mirror of
https://github.com/jedisct1/minisign.git
synced 2025-04-05 03:47:45 +03:00
Compare commits
188 commits
Author | SHA1 | Date | |
---|---|---|---|
|
108ea640ba | ||
|
c7d965e43a | ||
|
428c18e08a | ||
|
32038530b7 | ||
|
e9631e8c67 | ||
|
74365c0f51 | ||
|
d5a2f02bc0 | ||
|
4dd6fbf632 | ||
|
41306e3e42 | ||
|
090cc4752c | ||
|
b5cf334b42 | ||
|
c684406e21 | ||
|
29a07eade0 | ||
|
90d46db240 | ||
|
101e90a668 | ||
|
c165362385 | ||
|
1c44ef601e | ||
|
3c889ce7f3 | ||
|
b85e15d45a | ||
|
9896d072d4 | ||
|
b393ff47b1 | ||
|
c084f9ca38 | ||
|
c1c452560f | ||
|
e0e86b4e4f | ||
|
12333fd7d1 | ||
|
952225f9b7 | ||
|
e43b9ff13b | ||
|
e640be4b8f | ||
|
a1c07cc277 | ||
|
285b53d52c | ||
|
28612a431a | ||
|
cbc79b3ece | ||
|
55320cc84c | ||
|
868785690f | ||
|
45478e1dd6 | ||
|
996ea4fee3 | ||
|
573988d235 | ||
|
5f96819f44 | ||
|
ef2db96ae0 | ||
|
7d1116c5cc | ||
|
8aef018182 | ||
|
709fed6b73 | ||
|
05a0cd435d | ||
|
444ef2dca9 | ||
|
ee46615226 | ||
|
12fd90b6fe | ||
|
ef445ab928 | ||
|
3f1df52db4 | ||
|
506ac9ce3e | ||
|
27bff8a1f5 | ||
|
80defb2a99 | ||
|
6040047c27 | ||
|
16624abf2e | ||
|
6ccd801dbc | ||
|
41938e99f5 | ||
|
a536c178ab | ||
|
94e18a72d8 | ||
|
d870938ae5 | ||
|
d2afa89fe7 | ||
|
c33051dec3 | ||
|
cb2fc2ce7c | ||
|
0fccaf94e2 | ||
|
a26f2c8e5d | ||
|
a2c8848418 | ||
|
4b2df2ee07 | ||
|
b81f3d4065 | ||
|
e74428c464 | ||
|
aa99a5c417 | ||
|
614fd57665 | ||
|
503f722ac3 | ||
|
40dd5acf36 | ||
|
da6c6e7f77 | ||
|
a02e9e608b | ||
|
a832bbc270 | ||
|
dfb7dda9dc | ||
|
b653798d66 | ||
|
52ccad8685 | ||
|
f6965a0858 | ||
|
1e050e7d0a | ||
|
c9ba80b656 | ||
|
1cbcac9644 | ||
|
f3e97d838f | ||
|
b9349929fb | ||
|
7edc350137 | ||
|
d5b74ae86e | ||
|
121cf06e9b | ||
|
1a7cc6c860 | ||
|
246d542e37 | ||
|
bb81665e20 | ||
|
82913c2b64 | ||
|
9b3a4f28fd | ||
|
3bd2ae56da | ||
|
6a3fb509dc | ||
|
c4aad021da | ||
|
4d1f41e5be | ||
|
d357a3a5a4 | ||
|
95e4e900a7 | ||
|
a705d72380 | ||
|
dfb9963ce7 | ||
|
0c45001d33 | ||
|
9727843b70 | ||
|
5cff07069b | ||
|
ddc54a9248 | ||
|
9f6bdd5856 | ||
|
7c3e56a1da | ||
|
841a552290 | ||
|
7cc9b23ed9 | ||
|
21a6f41c06 | ||
|
056fa3541b | ||
|
76161c653e | ||
|
c295ceb267 | ||
|
507c6f6781 | ||
|
246237e3ea | ||
|
5af09266d8 | ||
|
2a20f7d920 | ||
|
25508229e4 | ||
|
da3962b837 | ||
|
a88527ae5f | ||
|
8bd7ec0197 | ||
|
c78fe77559 | ||
|
a27bd363b3 | ||
|
03ba8a6355 | ||
|
e71c9a7a47 | ||
|
15dddd7c45 | ||
|
971d70bd2e | ||
|
41806352d2 | ||
|
b718d329de | ||
|
33bdfce764 | ||
|
b3890abbb6 | ||
|
0137cd75af | ||
|
ff212957a7 | ||
|
d45184dbbe | ||
|
d6c5c8c17b | ||
|
9eac49b161 | ||
|
e5f7f65b8a | ||
|
237772bb40 | ||
|
7fdb9fdb0e | ||
|
391d51d3a2 | ||
|
0c265d0dc6 | ||
|
75879f460f | ||
|
e2a39c4e76 | ||
|
978a8b4086 | ||
|
139c99a73a | ||
|
f384177a3a | ||
|
5e81e5a3c6 | ||
|
c4cca6ef89 | ||
|
66b19a6da3 | ||
|
1d4855a83a | ||
|
4727fff205 | ||
|
4dfcb00afd | ||
|
eb48c20f8d | ||
|
6e313cb9d8 | ||
|
3db5a6ad2c | ||
|
ab55b98c34 | ||
|
81c9d95930 | ||
|
4dcfeb8e7c | ||
|
48bdcdc932 | ||
|
ba6bc8eb98 | ||
|
e3ee3d5a6c | ||
|
86d883c1dc | ||
|
626e8785b2 | ||
|
32fe65cf08 | ||
|
9dddf952df | ||
|
2c97046c15 | ||
|
9ad3d02b6e | ||
|
cea57b2fe7 | ||
|
e12bf0a774 | ||
|
203f385c09 | ||
|
910159752d | ||
|
1139d9497c | ||
|
e8a6730eae | ||
|
86e2210682 | ||
|
d654ad4647 | ||
|
180c40bf03 | ||
|
f97cc049ac | ||
|
fa455e73d6 | ||
|
546d7ee631 | ||
|
2ca0bea22f | ||
|
be2cc10844 | ||
|
eb13b0adb7 | ||
|
74f7017d7e | ||
|
90ff4a5f94 | ||
|
7f41769d67 | ||
|
e748f644dd | ||
|
a205a35a1b | ||
|
d55d86e219 | ||
|
230ea4367d | ||
|
8b01faa74a |
24 changed files with 1796 additions and 447 deletions
165
.clang-format
Normal file
165
.clang-format
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveMacros: true
|
||||||
|
AlignConsecutiveAssignments: true
|
||||||
|
AlignConsecutiveBitFields: true
|
||||||
|
AlignConsecutiveDeclarations: true
|
||||||
|
AlignEscapedNewlines: true
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: false
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: false
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||||
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
|
AttributeMacros:
|
||||||
|
- __capability
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeConceptDeclarations: true
|
||||||
|
BreakBeforeBraces: WebKit
|
||||||
|
BreakBeforeInheritanceComma: true
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 100
|
||||||
|
CommentPragmas: "^ IWYU pragma:"
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
DeriveLineEnding: true
|
||||||
|
DerivePointerAlignment: true
|
||||||
|
DisableFormat: false
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
ExperimentalAutoDetectBinPacking: true
|
||||||
|
FixNamespaceComments: false
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
StatementAttributeLikeMacros:
|
||||||
|
- Q_EMIT
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: ".*"
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
IncludeIsMainRegex: "(Test)?$"
|
||||||
|
IncludeIsMainSourceRegex: ""
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: AfterHash
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
|
IndentRequires: false
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
InsertTrailingCommas: None
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ""
|
||||||
|
MacroBlockEnd: ""
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: Inner
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 4
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
|
ObjCSpaceAfterProperty: true
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PointerAlignment: Left
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: true
|
||||||
|
SortJavaStaticImport: Before
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: true
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: true
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
Standard: Latest
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 4
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- STRINGIZE
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
|
- NS_SWIFT_NAME
|
||||||
|
- CF_SWIFT_NAME
|
||||||
|
---
|
||||||
|
|
7
.dockerignore
Normal file
7
.dockerignore
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
**
|
||||||
|
|
||||||
|
!LICENSE
|
||||||
|
!README.md
|
||||||
|
!/share
|
||||||
|
!/src
|
||||||
|
!/CMakeLists.txt
|
32
.github/workflows/codeql-analysis.yml
vendored
Normal file
32
.github/workflows/codeql-analysis.yml
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
name: "CodeQL scan"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 16 * * 2'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
CodeQL-Build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 2
|
||||||
|
|
||||||
|
- run: git checkout HEAD^2
|
||||||
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
|
|
||||||
|
- run: sudo apt-get install -qy libsodium-dev
|
||||||
|
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v1
|
||||||
|
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v1
|
17
.github/workflows/issues.yml
vendored
Normal file
17
.github/workflows/issues.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: Close inactive issues
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "30 1 * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
close-issues:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v9
|
||||||
|
with:
|
||||||
|
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
|
||||||
|
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,4 +1,3 @@
|
||||||
*.cmake
|
|
||||||
*.dSYM
|
*.dSYM
|
||||||
*.exp
|
*.exp
|
||||||
*.gcda
|
*.gcda
|
||||||
|
@ -24,4 +23,5 @@ CMakeFiles
|
||||||
Makefile
|
Makefile
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
minisign
|
minisign
|
||||||
|
.zig-cache
|
||||||
|
zig-out
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
project(minisign C)
|
project(minisign C)
|
||||||
|
|
||||||
|
@ -7,24 +7,88 @@ set(CPACK_PACKAGE_VENDOR "Frank Denis")
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
|
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
|
||||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR "6")
|
set(CPACK_PACKAGE_VERSION_MINOR "12")
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH "0")
|
set(CPACK_PACKAGE_VERSION_PATCH "0")
|
||||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
set(
|
||||||
set(CPACK_SOURCE_IGNORE_FILES "/build/;minisign.key;minisign.pub;a.out;/.git/;~$;${CPACK_SOURCE_IGNORE_FILES}")
|
CPACK_SOURCE_PACKAGE_FILE_NAME
|
||||||
|
"${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}"
|
||||||
|
)
|
||||||
|
set(
|
||||||
|
CPACK_SOURCE_IGNORE_FILES
|
||||||
|
"/build/;minisign.key;minisign.pub;a.out;/.git/;~$;${CPACK_SOURCE_IGNORE_FILES}"
|
||||||
|
)
|
||||||
set(CPACK_PACKAGE_EXECUTABLES "minisign" "minisign")
|
set(CPACK_PACKAGE_EXECUTABLES "minisign" "minisign")
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
set(
|
||||||
|
CMAKE_BUILD_TYPE
|
||||||
|
MinSizeRel
|
||||||
|
CACHE
|
||||||
|
STRING
|
||||||
|
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
|
||||||
|
FORCE)
|
||||||
endif(NOT CMAKE_BUILD_TYPE)
|
endif(NOT CMAKE_BUILD_TYPE)
|
||||||
|
|
||||||
include(CPack)
|
include(CPack)
|
||||||
include(CheckLibraryExists)
|
|
||||||
|
|
||||||
find_library(LIB_SODIUM NAMES sodium REQUIRED)
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_ALL_SOURCE -D_GNU_SOURCE")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64")
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||||
|
if(BUILD_STATIC_EXECUTABLES)
|
||||||
|
set(STATIC_LIBSODIUM on)
|
||||||
|
if (NOT APPLE)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS -static)
|
||||||
|
endif (NOT APPLE)
|
||||||
|
endif(BUILD_STATIC_EXECUTABLES)
|
||||||
|
|
||||||
add_executable(minisign
|
add_executable(minisign
|
||||||
src/minisign.c src/base64.c src/helpers.c src/get_line.c)
|
src/base64.c
|
||||||
|
src/get_line.c
|
||||||
|
src/helpers.c
|
||||||
|
src/minisign.c)
|
||||||
|
|
||||||
target_link_libraries(minisign ${LIB_SODIUM})
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(LIBSODIUM libsodium)
|
||||||
|
|
||||||
|
if(STATIC_LIBSODIUM)
|
||||||
|
if(BUILD_STATIC_EXECUTABLES)
|
||||||
|
set_target_properties(minisign PROPERTIES LINK_SEARCH_START_STATIC 1)
|
||||||
|
set_target_properties(minisign PROPERTIES LINK_SEARCH_END_STATIC 1)
|
||||||
|
endif()
|
||||||
|
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_path(SODIUM_INCLUDE_DIR sodium.h HINTS ${LIBSODIUM_INCLUDE_DIRS} /usr/local/include /opt/local/include /opt/include)
|
||||||
|
find_library(SODIUM_LIBRARY NAMES sodium HINTS ${LIBSODIUM_LIBRARY_DIRS} /usr/local/lib /opt/local/lib /opt/lib)
|
||||||
|
|
||||||
|
if(STATIC_LIBSODIUM)
|
||||||
|
set(LIBSODIUM_CFLAGS_OTHER ${LIBSODIUM_STATIC_CFLAGS_OTHER})
|
||||||
|
set(LIBSODIUM_LDFLAGS_OTHER ${LIBSODIUM_STATIC_LDFLAGS_OTHER})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(minisign PUBLIC ${SODIUM_INCLUDE_DIR})
|
||||||
|
target_compile_options(minisign PUBLIC ${LIBSODIUM_CFLAGS} ${LIBSODIUM_CFLAGS_OTHER})
|
||||||
|
target_link_libraries(minisign ${SODIUM_LIBRARY} ${LIBSODIUM_LDFLAGS_OTHER})
|
||||||
|
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
if(THREADS_HAVE_PTHREAD_ARG)
|
||||||
|
target_compile_options(minisign PUBLIC "-pthread")
|
||||||
|
endif(THREADS_HAVE_PTHREAD_ARG)
|
||||||
|
if(CMAKE_THREAD_LIBS_INIT)
|
||||||
|
target_link_libraries(minisign "${CMAKE_THREAD_LIBS_INIT}")
|
||||||
|
endif(CMAKE_THREAD_LIBS_INIT)
|
||||||
|
|
||||||
|
if (NOT MSVC AND CMAKE_STRIP)
|
||||||
|
add_custom_command(TARGET minisign POST_BUILD
|
||||||
|
COMMAND ${CMAKE_STRIP} ${STRIP_FLAGS} $<TARGET_FILE:minisign>)
|
||||||
|
endif(NOT MSVC AND CMAKE_STRIP)
|
||||||
|
|
||||||
install(TARGETS minisign DESTINATION bin)
|
install(TARGETS minisign DESTINATION bin)
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
install(FILES "share/man/man1/minisign.1"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
|
||||||
|
COMPONENT doc)
|
||||||
|
|
15
Dockerfile
Normal file
15
Dockerfile
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
FROM alpine:latest as build
|
||||||
|
|
||||||
|
WORKDIR /usr/src/minisign
|
||||||
|
|
||||||
|
RUN apk add --no-cache build-base cmake curl pkgconfig
|
||||||
|
RUN apk add --no-cache upx ||:
|
||||||
|
RUN curl https://download.libsodium.org/libsodium/releases/LATEST.tar.gz | tar xzvf - && cd libsodium-stable && env CFLAGS="-Os" CPPFLAGS="-DED25519_NONDETERMINISTIC=1" ./configure --disable-dependency-tracking && make -j$(nproc) check && make install && cd .. && rm -fr libsodium-stable
|
||||||
|
|
||||||
|
COPY ./ ./
|
||||||
|
RUN mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_STATIC_EXECUTABLES=1 .. && make -j$(nproc)
|
||||||
|
RUN upx --lzma build/minisign ||:
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
COPY --from=build /usr/src/minisign/build/minisign /usr/local/bin/
|
||||||
|
ENTRYPOINT ["/usr/local/bin/minisign"]
|
4
LICENSE
4
LICENSE
|
@ -1,5 +1,7 @@
|
||||||
|
ISC LICENSE.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015
|
* Copyright (c) 2015-2025
|
||||||
* Frank Denis <j at pureftpd dot org>
|
* Frank Denis <j at pureftpd dot org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
|
113
README.md
113
README.md
|
@ -1,6 +1,6 @@
|
||||||
|

|
||||||
|
|
||||||
Minisign
|
# Minisign
|
||||||
========
|
|
||||||
|
|
||||||
Minisign is a dead simple tool to sign files and verify signatures.
|
Minisign is a dead simple tool to sign files and verify signatures.
|
||||||
|
|
||||||
|
@ -12,12 +12,39 @@ public key:
|
||||||
|
|
||||||
RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3
|
RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3
|
||||||
|
|
||||||
Compilation / installation
|
## Compilation / installation
|
||||||
--------------------------
|
|
||||||
|
## Building with Zig
|
||||||
|
|
||||||
Dependencies:
|
Dependencies:
|
||||||
* [libsodium](http://doc.libsodium.org/)
|
|
||||||
* cmake
|
- [libsodium](https://libsodium.org/) (_optional_)
|
||||||
|
- [zig](https://ziglang.org)
|
||||||
|
|
||||||
|
Compilation with libsodium, dynamically linked (libsodium will need to be installed on the system for the command to run):
|
||||||
|
|
||||||
|
$ zig build -Doptimize=ReleaseSmall
|
||||||
|
|
||||||
|
Compilation with libsodium, statically linked (libsodium will only be needed for compilation):
|
||||||
|
|
||||||
|
$ zig build -Doptimize=ReleaseSmall -Dstatic
|
||||||
|
|
||||||
|
Compilation without libsodium, no dependencies required:
|
||||||
|
|
||||||
|
$ zig build -Doptimize=ReleaseSmall -Dwithout-libsodium
|
||||||
|
|
||||||
|
The resulting binary can be found in `zig-out/bin/minisign`.
|
||||||
|
|
||||||
|
In all these examples, `ReleaseFast` can be replaced with `ReleaseSmall` to favor speed over size.
|
||||||
|
|
||||||
|
## Building with cmake and gcc or clang:
|
||||||
|
|
||||||
|
Dependencies:
|
||||||
|
|
||||||
|
- [libsodium](https://libsodium.org/) (_required_)
|
||||||
|
- cmake
|
||||||
|
- pkg-config
|
||||||
|
- gcc or clang
|
||||||
|
|
||||||
Compilation:
|
Compilation:
|
||||||
|
|
||||||
|
@ -27,6 +54,16 @@ Compilation:
|
||||||
$ make
|
$ make
|
||||||
# make install
|
# make install
|
||||||
|
|
||||||
|
Alternative configuration for static binaries:
|
||||||
|
|
||||||
|
$ cmake -D STATIC_LIBSODIUM=1 ..
|
||||||
|
|
||||||
|
or:
|
||||||
|
|
||||||
|
$ cmake -D BUILD_STATIC_EXECUTABLES=1 ..
|
||||||
|
|
||||||
|
## Pre-built packages
|
||||||
|
|
||||||
Minisign is also available in Homebrew:
|
Minisign is also available in Homebrew:
|
||||||
|
|
||||||
$ brew install minisign
|
$ brew install minisign
|
||||||
|
@ -34,3 +71,67 @@ Minisign is also available in Homebrew:
|
||||||
Minisign is also available in Scoop on Windows:
|
Minisign is also available in Scoop on Windows:
|
||||||
|
|
||||||
$ scoop install minisign
|
$ scoop install minisign
|
||||||
|
|
||||||
|
Minisign is also available in chocolatey on Windows:
|
||||||
|
|
||||||
|
$ choco install minisign
|
||||||
|
|
||||||
|
Minisign is also available with docker:
|
||||||
|
|
||||||
|
$ docker run -i --rm jedisct1/minisign
|
||||||
|
|
||||||
|
For example, verifying a signature using the docker image can be done
|
||||||
|
with:
|
||||||
|
|
||||||
|
$ docker run -v .:/minisign -e HOME=/minisign -w /minisign \
|
||||||
|
-it --rm jedisct1/minisign \
|
||||||
|
-Vm file_to_verify -p minisign.pub
|
||||||
|
|
||||||
|
The image can be verified with the following cosign public key:
|
||||||
|
|
||||||
|
```text
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExjZWrlc6c58W7ZzmQnx6mugty99C
|
||||||
|
OQTDtJeciX9LF9hEbs1J1fzZHRdRhV4OTqcq0jTW9PXnrSSZlk1fbkE/5w==
|
||||||
|
-----END PUBLIC KEY-----
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional tools, libraries and implementations
|
||||||
|
|
||||||
|
- [minizign](https://github.com/jedisct1/zig-minisign) is a compact
|
||||||
|
implementation in Zig, that can also use ssh-encoded keys.
|
||||||
|
- [minisign-misc](https://github.com/JayBrown/minisign-misc) is a very
|
||||||
|
nice set of workflows and scripts for macOS to verify and sign files
|
||||||
|
with minisign.
|
||||||
|
- [go-minisign](https://github.com/jedisct1/go-minisign) is a small module
|
||||||
|
in Go to verify Minisign signatures.
|
||||||
|
- [rust-minisign](https://github.com/jedisct1/rust-minisign) is a Minisign
|
||||||
|
library written in pure Rust, that can be embedded in other applications.
|
||||||
|
- [rsign2](https://github.com/jedisct1/rsign2) is a reimplementation of
|
||||||
|
the command-line tool in Rust.
|
||||||
|
- [minisign (go)](https://github.com/aead/minisign) is a rewrite of Minisign
|
||||||
|
in the Go language. It reimplements the CLI but can also be used as a library.
|
||||||
|
- [minisign-verify](https://github.com/jedisct1/rust-minisign-verify) is
|
||||||
|
a small Rust crate to verify Minisign signatures.
|
||||||
|
- [minisign-net](https://github.com/bitbeans/minisign-net) is a .NET library
|
||||||
|
to handle and create Minisign signatures.
|
||||||
|
- [minisign](https://github.com/chm-diederichs/minisign) a Javascript
|
||||||
|
implementation.
|
||||||
|
- WebAssembly implementations of [rsign2](https://wapm.io/package/jedisct1/rsign2)
|
||||||
|
and [minisign-cli](https://wapm.io/package/jedisct1/minisign) are available on
|
||||||
|
WAPM.
|
||||||
|
- [minisign-php](https://github.com/soatok/minisign-php) is a PHP implementation.
|
||||||
|
- [py-minisign](https://github.com/x13a/py-minisign) is a Python
|
||||||
|
implementation.
|
||||||
|
- [minisign](https://hexdocs.pm/minisign/Minisign.html) is an Elixir implementation
|
||||||
|
(verification only)
|
||||||
|
|
||||||
|
## Signature determinism
|
||||||
|
|
||||||
|
This implementation uses deterministic signatures, unless libsodium
|
||||||
|
was compiled with the `ED25519_NONDETERMINISTIC` macro defined. This
|
||||||
|
adds random noise to the computation of EdDSA nonces.
|
||||||
|
|
||||||
|
Other implementations can choose to use non-deterministic signatures
|
||||||
|
by default. They will remain fully interoperable with implementations
|
||||||
|
using deterministic signatures.
|
||||||
|
|
4
build-dist-package.sh
Executable file
4
build-dist-package.sh
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
tar czpvf minisign-0.12.tar.gz $(git ls-files)
|
||||||
|
minisign -Sm minisign-0.12.tar.gz
|
80
build.zig
Normal file
80
build.zig
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) !void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const use_libzodium = b.option(bool, "without-libsodium", "Use the zig standard library instead of libsodium") orelse false;
|
||||||
|
const use_static_linking = b.option(bool, "static", "Statically link the binary") orelse false;
|
||||||
|
|
||||||
|
const minisign = b.addExecutable(.{
|
||||||
|
.name = "minisign",
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.strip = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (builtin.zig_version.major == 0 and builtin.zig_version.minor < 14) {
|
||||||
|
@compileError("Building requires Zig 0.14.0 or later");
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix Mach-O relocation
|
||||||
|
minisign.headerpad_max_install_names = true;
|
||||||
|
|
||||||
|
minisign.linkLibC();
|
||||||
|
if (use_libzodium) {
|
||||||
|
var libzodium = lib: {
|
||||||
|
const libzodium_mod = b.createModule(.{
|
||||||
|
.root_source_file = b.path("src/libzodium/libzodium.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
break :lib b.addStaticLibrary(.{
|
||||||
|
.name = "zodium",
|
||||||
|
.root_module = libzodium_mod,
|
||||||
|
.strip = true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
libzodium.linkLibC();
|
||||||
|
b.installArtifact(libzodium);
|
||||||
|
minisign.root_module.addCMacro("LIBZODIUM", "1");
|
||||||
|
minisign.linkLibrary(libzodium);
|
||||||
|
} else {
|
||||||
|
var override_pkgconfig = false;
|
||||||
|
if (std.posix.getenv("LIBSODIUM_INCLUDE_PATH")) |path| {
|
||||||
|
minisign.addSystemIncludePath(.{ .cwd_relative = path });
|
||||||
|
override_pkgconfig = true;
|
||||||
|
}
|
||||||
|
if (std.posix.getenv("LIBSODIUM_LIB_PATH")) |path| {
|
||||||
|
minisign.addLibraryPath(.{ .cwd_relative = path });
|
||||||
|
override_pkgconfig = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ([_][]const u8{ "/opt/homebrew/include", "/home/linuxbrew/.linuxbrew/include", "/usr/local/include" }) |path| {
|
||||||
|
std.fs.accessAbsolute(path, .{}) catch continue;
|
||||||
|
minisign.addSystemIncludePath(.{ .cwd_relative = path });
|
||||||
|
}
|
||||||
|
for ([_][]const u8{ "/opt/homebrew/lib", "/home/linuxbrew/.linuxbrew/lib", "/usr/local/lib" }) |path| {
|
||||||
|
std.fs.accessAbsolute(path, .{}) catch continue;
|
||||||
|
minisign.addLibraryPath(.{ .cwd_relative = path });
|
||||||
|
}
|
||||||
|
if (!use_static_linking) {
|
||||||
|
minisign.headerpad_max_install_names = true; // required to compile using Homebrew, see https://github.com/jedisct1/minisign/pull/155
|
||||||
|
}
|
||||||
|
minisign.root_module.linkSystemLibrary(
|
||||||
|
"sodium",
|
||||||
|
.{
|
||||||
|
.use_pkg_config = if (override_pkgconfig) .no else .yes,
|
||||||
|
.preferred_link_mode = if (use_static_linking) .static else .dynamic,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
minisign.addIncludePath(b.path("src"));
|
||||||
|
|
||||||
|
minisign.root_module.addCMacro("_GNU_SOURCE", "1");
|
||||||
|
const source_files = &.{ "src/base64.c", "src/get_line.c", "src/helpers.c", "src/minisign.c" };
|
||||||
|
minisign.addCSourceFiles(.{ .files = source_files });
|
||||||
|
|
||||||
|
b.installArtifact(minisign);
|
||||||
|
}
|
13
build.zig.zon
Normal file
13
build.zig.zon
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
.{
|
||||||
|
.name = .minisign,
|
||||||
|
.version = "0.12.0",
|
||||||
|
.fingerprint = 0x280456c1fd373c55,
|
||||||
|
.paths = .{
|
||||||
|
"LICEMSE",
|
||||||
|
"README.md",
|
||||||
|
"build.zig",
|
||||||
|
"build.zig.zon",
|
||||||
|
"src",
|
||||||
|
"share",
|
||||||
|
},
|
||||||
|
}
|
4
cosign.pub
Normal file
4
cosign.pub
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExjZWrlc6c58W7ZzmQnx6mugty99C
|
||||||
|
OQTDtJeciX9LF9hEbs1J1fzZHRdRhV4OTqcq0jTW9PXnrSSZlk1fbkE/5w==
|
||||||
|
-----END PUBLIC KEY-----
|
168
share/man/man1/minisign.1
Normal file
168
share/man/man1/minisign.1
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
.\" generated with Ronn/v0.7.3
|
||||||
|
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||||
|
.
|
||||||
|
.TH "MINISIGN" "1" "March 2025" "" ""
|
||||||
|
.
|
||||||
|
.SH "NAME"
|
||||||
|
\fBminisign\fR \- A dead simple tool to sign files and verify signatures\.
|
||||||
|
.
|
||||||
|
.SH "SYNOPSIS"
|
||||||
|
\fBminisign\fR \-G [\-p pubkey_file] [\-s seckey_file] [\-W]
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
\fBminisign\fR \-R [\-s seckey_file] [\-p pubkey_file]
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
\fBminisign\fR \-C [\-s seckey_file] [\-W]
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
\fBminisign\fR \-S [\-H] [\-x sig_file] [\-s seckey_file] [\-c untrusted_comment] [\-t trusted_comment] \-m file [file \.\.\.]
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
\fBminisign\fR \-V [\-x sig_file] [\-p pubkey_file | \-P pubkey] [\-o] [\-q] \-m file
|
||||||
|
.
|
||||||
|
.SH "DESCRIPTION"
|
||||||
|
\fBMinisign\fR is a dead simple tool to sign files and verify signatures\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
It is portable, lightweight, and uses the highly secure Ed25519 \fIhttp://ed25519\.cr\.yp\.to/\fR public\-key signature system\.
|
||||||
|
.
|
||||||
|
.SH "OPTIONS"
|
||||||
|
These options control the actions of \fBminisign\fR\.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-G\fR
|
||||||
|
Generate a new key pair
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-C\fR
|
||||||
|
Change/remove the password of a secret key
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-R\fR
|
||||||
|
Recreate a public key file from a secret key file
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-S\fR
|
||||||
|
Sign files
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-V\fR
|
||||||
|
Verify that a signature is valid for a given file
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-H\fR
|
||||||
|
Requires the input to be prehashed
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-l\fR
|
||||||
|
Sign using the legacy format
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-m <file>\fR
|
||||||
|
File to sign/verify
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-o\fR
|
||||||
|
Combined with \-V, output the file content after verification
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-p <pubkey_file>\fR
|
||||||
|
Public key file (default: \./minisign\.pub)
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-P <pubkey>\fR
|
||||||
|
Public key, as a base64 string
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-s <seckey_file>\fR
|
||||||
|
Secret key file (default: ~/\.minisign/minisign\.key)
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-W\fR
|
||||||
|
Do not encrypt/decrypt the secret key with a password
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-x <sig_file>\fR
|
||||||
|
Signature file (default: <file>\.minisig)
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-c <comment>\fR
|
||||||
|
Add a one\-line untrusted comment
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-t <comment>\fR
|
||||||
|
Add a one\-line trusted comment
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-q\fR
|
||||||
|
Quiet mode, suppress output
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-Q\fR
|
||||||
|
Pretty quiet mode, only print the trusted comment
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-f\fR
|
||||||
|
Force\. Combined with \-G, overwrite a previous key pair
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-v\fR
|
||||||
|
Display version number
|
||||||
|
.
|
||||||
|
.SH "EXAMPLES"
|
||||||
|
Creating a key pair
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
\fBminisign\fR \-G
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
The public key is printed and put into the \fBminisign\.pub\fR file\. The secret key is encrypted and saved as a file named \fB~/\.minisign/minisign\.key\fR\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
Signing files
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
$ \fBminisign\fR \-Sm myfile\.txt $ \fBminisign\fR \-Sm myfile\.txt myfile2\.txt *\.c
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
Or to include a comment in the signature, that will be verified and displayed when verifying the file:
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
$ \fBminisign\fR \-Sm myfile\.txt \-t \'This comment will be signed as well\'
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
The secret key is loaded from \fB${MINISIGN_CONFIG_DIR}/minisign\.key\fR, \fB~/\.minisign/minisign\.key\fR, or its path can be explicitly set with the \fB\-s <path>\fR command\-line switch\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
Verifying a file
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
$ \fBminisign\fR \-Vm myfile\.txt \-P <pubkey>
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
or
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
$ \fBminisign\fR \-Vm myfile\.txt \-p signature\.pub
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
This requires the signature \fBmyfile\.txt\.minisig\fR to be present in the same directory\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
The public key can either reside in a file (\fB\./minisign\.pub\fR by default) or be directly specified on the command line\.
|
||||||
|
.
|
||||||
|
.SH "NOTES"
|
||||||
|
Signature files include an untrusted comment line that can be freely modified even after the signature is created\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
They also include a second comment line that cannot be modified without the secret key\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
Trusted comments can be used to add instructions or application\-specific metadata such as the intended file name, timestamps, resource identifiers, or version numbers to prevent downgrade attacks\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
OpenBSD\'s \fBsignify(1)\fR is conceptually similar to Minisign\. Minisign creates signatures that can be verified by \fBsignify\fR; however, signatures created by \fBsignify\fR cannot be verified with Minisign because Minisign expects a trusted comment section to be present\. Trusted comments are crucial for describing what has been signed, in addition to merely confirming that a signature exists\.
|
||||||
|
.
|
||||||
|
.SH "AUTHOR"
|
||||||
|
Frank Denis (github [at] pureftpd [dot] org)
|
82
src/base64.c
82
src/base64.c
|
@ -5,44 +5,70 @@
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
|
|
||||||
unsigned char *
|
unsigned char *
|
||||||
b64_to_bin(unsigned char * const bin, const char *b64,
|
b64_to_bin(unsigned char *const bin, const char *b64, size_t bin_maxlen, size_t b64_len,
|
||||||
size_t bin_maxlen, size_t b64_len, size_t * const bin_len_p)
|
size_t *const bin_len_p)
|
||||||
{
|
{
|
||||||
#define REV64_EOT 128U
|
#define REV64_EOT 128U
|
||||||
#define REV64_NONE 64U
|
#define REV64_NONE 64U
|
||||||
#define REV64_PAD '='
|
#define REV64_PAD '='
|
||||||
|
|
||||||
static const unsigned char rev64chars[256] = {
|
static const unsigned char rev64chars[256] = {
|
||||||
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
REV64_NONE, REV64_NONE, REV64_NONE, 62U, REV64_NONE, REV64_NONE, REV64_NONE, 63U, 52U, 53U, 54U, 55U, 56U, 57U, 58U, 59U, 60U, 61U, REV64_NONE, REV64_NONE, REV64_NONE, REV64_EOT, REV64_NONE, REV64_NONE, REV64_NONE, 0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 16U, 17U, 18U, 19U, 20U, 21U, 22U, 23U, 24U, 25U, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, 26U, 27U, 28U, 29U, 30U, 31U, 32U, 33U, 34U, 35U, 36U, 37U, 38U, 39U, 40U, 41U, 42U,
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
43U, 44U, 45U, 46U, 47U, 48U, 49U, 50U, 51U, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
REV64_NONE, 62U, REV64_NONE, REV64_NONE, REV64_NONE, 63U, 52U,
|
||||||
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
53U, 54U, 55U, 56U, 57U, 58U, 59U,
|
||||||
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
60U, 61U, REV64_NONE, REV64_NONE, REV64_NONE, REV64_EOT, REV64_NONE,
|
||||||
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
REV64_NONE, REV64_NONE, 0U, 1U, 2U, 3U, 4U,
|
||||||
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE
|
5U, 6U, 7U, 8U, 9U, 10U, 11U,
|
||||||
|
12U, 13U, 14U, 15U, 16U, 17U, 18U,
|
||||||
|
19U, 20U, 21U, 22U, 23U, 24U, 25U,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, 26U,
|
||||||
|
27U, 28U, 29U, 30U, 31U, 32U, 33U,
|
||||||
|
34U, 35U, 36U, 37U, 38U, 39U, 40U,
|
||||||
|
41U, 42U, 43U, 44U, 45U, 46U, 47U,
|
||||||
|
48U, 49U, 50U, 51U, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
|
||||||
|
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE
|
||||||
};
|
};
|
||||||
const unsigned char *b64_u = (const unsigned char *) b64;
|
const unsigned char *b64_u = (const unsigned char *) b64;
|
||||||
unsigned char *bin_w = bin;
|
unsigned char *bin_w = bin;
|
||||||
unsigned char mask;
|
unsigned char mask = 0U;
|
||||||
unsigned char t0, t1, t2, t3;
|
unsigned char t0 = 0, t1 = 0, t2 = 0, t3 = 0;
|
||||||
uint32_t t;
|
uint32_t t = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (b64_len % 4U != 0U || (i = b64_len / 4U) <= 0U || bin_maxlen < i * 3U -
|
if (b64_len % 4U != 0U || (i = b64_len / 4U) <= 0U ||
|
||||||
(b64_u[b64_len - 1U] == REV64_PAD) - (b64_u[b64_len - 2U] == REV64_PAD)) {
|
bin_maxlen <
|
||||||
|
i * 3U - (b64_u[b64_len - 1U] == REV64_PAD) - (b64_u[b64_len - 2U] == REV64_PAD)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
while (i-- > 0U) {
|
while (i-- > 0U) {
|
||||||
t0 = rev64chars[*b64++];
|
t0 = rev64chars[*b64_u++];
|
||||||
t1 = rev64chars[*b64++];
|
t1 = rev64chars[*b64_u++];
|
||||||
t2 = rev64chars[*b64++];
|
t2 = rev64chars[*b64_u++];
|
||||||
t3 = rev64chars[*b64++];
|
t3 = rev64chars[*b64_u++];
|
||||||
t = t3 | ((uint32_t) t2 << 6) | ((uint32_t) t1 << 12) |
|
t = t3 | ((uint32_t) t2 << 6) | ((uint32_t) t1 << 12) | ((uint32_t) t0 << 18);
|
||||||
((uint32_t) t0 << 18);
|
|
||||||
mask = t0 | t1 | t2 | t3;
|
mask = t0 | t1 | t2 | t3;
|
||||||
if ((mask & (REV64_NONE | REV64_EOT)) != 0U) {
|
if ((mask & (REV64_NONE | REV64_EOT)) != 0U) {
|
||||||
if ((mask & REV64_NONE) != 0U || i > 0U) {
|
if ((mask & REV64_NONE) != 0U || i > 0U) {
|
||||||
|
@ -69,8 +95,8 @@ b64_to_bin(unsigned char * const bin, const char *b64,
|
||||||
return bin;
|
return bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *bin_to_b64(char * const b64, const unsigned char *bin,
|
char *
|
||||||
size_t b64_maxlen, size_t bin_len)
|
bin_to_b64(char *const b64, const unsigned char *bin, size_t b64_maxlen, size_t bin_len)
|
||||||
{
|
{
|
||||||
#define B64_PAD '='
|
#define B64_PAD '='
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,10 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
unsigned char *b64_to_bin(unsigned char * const bin, const char *b64,
|
unsigned char *b64_to_bin(unsigned char *const bin, const char *b64, size_t bin_maxlen,
|
||||||
size_t bin_maxlen, size_t b64_len,
|
size_t b64_len, size_t *const bin_len_p);
|
||||||
size_t * const bin_len_p);
|
|
||||||
|
|
||||||
char *bin_to_b64(char * const b64, const unsigned char *bin,
|
char *bin_to_b64(char *const b64, const unsigned char *bin, size_t b64_maxlen, size_t bin_len);
|
||||||
size_t b64_maxlen, size_t bin_len);
|
|
||||||
|
|
||||||
#define B64_MAX_LEN_FROM_BIN_LEN(X) (((X) + 2) / 3 * 4 + 1)
|
#define B64_MAX_LEN_FROM_BIN_LEN(X) (((X) + 2) / 3 * 4 + 1)
|
||||||
#define BIN_MAX_LEN_FROM_B64_LEN(X) ((X) / 4 * 3)
|
#define BIN_MAX_LEN_FROM_B64_LEN(X) ((X) / 4 * 3)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -9,20 +9,20 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <poll.h>
|
# include <poll.h>
|
||||||
# include <termios.h>
|
# include <termios.h>
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "get_line.h"
|
#include "get_line.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
#ifndef TCSAFLUSH
|
#ifndef TCSAFLUSH
|
||||||
# define TCSAFLUSH 0
|
# define TCSAFLUSH 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef VERIFY_ONLY
|
#ifndef VERIFY_ONLY
|
||||||
|
@ -33,7 +33,7 @@ disable_echo(void)
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
|
||||||
{
|
{
|
||||||
struct termios p;
|
struct termios p;
|
||||||
|
|
||||||
|
@ -43,15 +43,15 @@ disable_echo(void)
|
||||||
p.c_lflag &= ~ECHO;
|
p.c_lflag &= ~ECHO;
|
||||||
tcsetattr(0, TCSAFLUSH, &p);
|
tcsetattr(0, TCSAFLUSH, &p);
|
||||||
}
|
}
|
||||||
# elif defined(_WIN32)
|
# elif defined(_WIN32)
|
||||||
{
|
{
|
||||||
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
|
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
DWORD mode = 0;
|
DWORD mode = 0;
|
||||||
|
|
||||||
GetConsoleMode(handle, &mode);
|
GetConsoleMode(handle, &mode);
|
||||||
SetConsoleMode(handle, mode & ~ENABLE_ECHO_INPUT);
|
SetConsoleMode(handle, mode & ~ENABLE_ECHO_INPUT);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -60,7 +60,7 @@ enable_echo(void)
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
|
||||||
{
|
{
|
||||||
struct termios p;
|
struct termios p;
|
||||||
|
|
||||||
|
@ -70,15 +70,15 @@ enable_echo(void)
|
||||||
p.c_lflag |= ECHO;
|
p.c_lflag |= ECHO;
|
||||||
tcsetattr(0, TCSAFLUSH, &p);
|
tcsetattr(0, TCSAFLUSH, &p);
|
||||||
}
|
}
|
||||||
# elif defined(_WIN32)
|
# elif defined(_WIN32)
|
||||||
{
|
{
|
||||||
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
|
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
DWORD mode = 0;
|
DWORD mode = 0;
|
||||||
|
|
||||||
GetConsoleMode(handle, &mode);
|
GetConsoleMode(handle, &mode);
|
||||||
SetConsoleMode(handle, mode | ENABLE_ECHO_INPUT);
|
SetConsoleMode(handle, mode | ENABLE_ECHO_INPUT);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -95,7 +95,7 @@ get_line(char *line, size_t max_len, const char *prompt)
|
||||||
}
|
}
|
||||||
trim(line);
|
trim(line);
|
||||||
if (strlen(line) >= max_len) {
|
if (strlen(line) >= max_len) {
|
||||||
fprintf(stderr, "(truncated to %u characters)\n", (int) max_len);
|
fprintf(stderr, "(truncated to %u characters)\n", (unsigned int) max_len);
|
||||||
} else if (*line == 0) {
|
} else if (*line == 0) {
|
||||||
fprintf(stderr, "(empty)\n");
|
fprintf(stderr, "(empty)\n");
|
||||||
} else {
|
} else {
|
||||||
|
|
118
src/helpers.c
118
src/helpers.c
|
@ -1,17 +1,24 @@
|
||||||
|
|
||||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
|
||||||
# include <sys/types.h>
|
# include <fcntl.h>
|
||||||
# include <sys/fcntl.h>
|
# include <sys/stat.h>
|
||||||
# include <sys/stat.h>
|
# include <sys/types.h>
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
# include <direct.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <sodium.h>
|
#ifdef LIBZODIUM
|
||||||
|
# include "libzodium/sodium.h"
|
||||||
|
#else
|
||||||
|
# include <sodium.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
@ -19,10 +26,9 @@
|
||||||
uint64_t
|
uint64_t
|
||||||
le64_load(const unsigned char *p)
|
le64_load(const unsigned char *p)
|
||||||
{
|
{
|
||||||
return ((uint64_t)(p[0])) | ((uint64_t)(p[1]) << 8) |
|
return ((uint64_t) (p[0])) | ((uint64_t) (p[1]) << 8) | ((uint64_t) (p[2]) << 16) |
|
||||||
((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
|
((uint64_t) (p[3]) << 24) | ((uint64_t) (p[4]) << 32) | ((uint64_t) (p[5]) << 40) |
|
||||||
((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
|
((uint64_t) (p[6]) << 48) | ((uint64_t) (p[7]) << 56);
|
||||||
((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -63,6 +69,17 @@ xmalloc(size_t size)
|
||||||
return pnt;
|
return pnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
xstrdup(const char *str)
|
||||||
|
{
|
||||||
|
char *clone;
|
||||||
|
|
||||||
|
if ((clone = strdup(str)) == NULL) {
|
||||||
|
exit_err("strdup()");
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
xsodium_malloc(size_t size)
|
xsodium_malloc(size_t size)
|
||||||
{
|
{
|
||||||
|
@ -102,7 +119,6 @@ xfprintf(FILE *fp, const char *format, ...)
|
||||||
va_end(va);
|
va_end(va);
|
||||||
if (fwrite(out, (size_t) len, 1U, fp) != 1U) {
|
if (fwrite(out, (size_t) len, 1U, fp) != 1U) {
|
||||||
sodium_free(out);
|
sodium_free(out);
|
||||||
va_end(va);
|
|
||||||
exit_err("fwrite()");
|
exit_err("fwrite()");
|
||||||
}
|
}
|
||||||
sodium_free(out);
|
sodium_free(out);
|
||||||
|
@ -113,8 +129,8 @@ xfprintf(FILE *fp, const char *format, ...)
|
||||||
int
|
int
|
||||||
xfput_b64(FILE *fp, const unsigned char *bin, size_t bin_len)
|
xfput_b64(FILE *fp, const unsigned char *bin, size_t bin_len)
|
||||||
{
|
{
|
||||||
const size_t b64_maxlen = (bin_len + 2) * 4 / 3 + 1;
|
const size_t b64_maxlen = (bin_len + 2) * 4 / 3 + 1;
|
||||||
char *b64;
|
char *b64;
|
||||||
|
|
||||||
b64 = xsodium_malloc(b64_maxlen);
|
b64 = xsodium_malloc(b64_maxlen);
|
||||||
if (bin_to_b64(b64, bin, b64_maxlen, bin_len) == NULL) {
|
if (bin_to_b64(b64, bin, b64_maxlen, bin_len) == NULL) {
|
||||||
|
@ -139,16 +155,21 @@ xfclose(FILE *fp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
trim(char *str)
|
trim(char *str)
|
||||||
{
|
{
|
||||||
size_t i = strlen(str);
|
size_t i = strlen(str);
|
||||||
|
int t = 0;
|
||||||
|
|
||||||
while (i-- > (size_t) 0U) {
|
while (i-- > (size_t) 0U) {
|
||||||
if (str[i] == '\n' || str[i] == '\r') {
|
if (str[i] == '\n') {
|
||||||
|
str[i] = 0;
|
||||||
|
t = 1;
|
||||||
|
} else if (str[i] == '\r') {
|
||||||
str[i] = 0;
|
str[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
@ -156,25 +177,19 @@ file_basename(const char *file)
|
||||||
{
|
{
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
if ((ptr = strrchr(file, '/')) != NULL) {
|
if ((ptr = strrchr(file, DIR_SEP)) != NULL) {
|
||||||
return ptr + 1;
|
return ptr + 1;
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
|
||||||
if ((ptr = strrchr(file, '\\')) != NULL) {
|
|
||||||
return ptr + 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *
|
FILE *
|
||||||
fopen_create_useronly(const char *file)
|
fopen_create_useronly(const char *file)
|
||||||
{
|
{
|
||||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if ((fd = open(file, O_CREAT | O_TRUNC | O_WRONLY,
|
if ((fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, (mode_t) 0600)) == -1) {
|
||||||
(mode_t) 0600)) == -1) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return fdopen(fd, "w");
|
return fdopen(fd, "w");
|
||||||
|
@ -182,3 +197,60 @@ fopen_create_useronly(const char *file)
|
||||||
return fopen(file, "w");
|
return fopen(file, "w");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
basedir_create_useronly(const char *file)
|
||||||
|
{
|
||||||
|
const char *basename;
|
||||||
|
char *dir;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
dir = xstrdup(file);
|
||||||
|
basename = file_basename(dir);
|
||||||
|
if (basename == dir) {
|
||||||
|
free(dir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dir[basename - dir - 1] = 0;
|
||||||
|
|
||||||
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
|
||||||
|
if (*dir == 0 || mkdir(dir, 0700) == 0 || errno == EEXIST) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
if (*dir == 0 || _mkdir(dir) == 0 || errno == EEXIST) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
free(dir);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
get_home_dir(void)
|
||||||
|
{
|
||||||
|
char *dir;
|
||||||
|
#ifdef _WIN32
|
||||||
|
const char *hd;
|
||||||
|
const char *hp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((dir = getenv("HOME")) != NULL) {
|
||||||
|
return xstrdup(dir);
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
if ((dir = getenv("USERPROFILE")) != NULL) {
|
||||||
|
return xstrdup(dir);
|
||||||
|
}
|
||||||
|
if ((dir = getenv("USERPROFILE")) != NULL) {
|
||||||
|
return xstrdup(dir);
|
||||||
|
}
|
||||||
|
if ((hd = getenv("HOMEDRIVE")) != NULL && (hp = getenv("HOMEPATH")) != NULL) {
|
||||||
|
if (asprintf(&dir, "%s%s", hd, hp) < 0) {
|
||||||
|
exit_err("asprintf()");
|
||||||
|
}
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -2,11 +2,16 @@
|
||||||
#ifndef HELPERS_H
|
#ifndef HELPERS_H
|
||||||
#define HELPERS_H 1
|
#define HELPERS_H 1
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#if !defined(__GNUC__) && !defined(__attribute__)
|
#if !defined(__GNUC__) && !defined(__attribute__)
|
||||||
# define __attribute__(X)
|
# define __attribute__(X)
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define DIR_SEP '\\'
|
||||||
|
#else
|
||||||
|
# define DIR_SEP '/'
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint64_t le64_load(const unsigned char *p);
|
uint64_t le64_load(const unsigned char *p);
|
||||||
|
@ -17,9 +22,11 @@ void exit_err(const char *msg) __attribute__((noreturn));
|
||||||
|
|
||||||
void exit_msg(const char *msg) __attribute__((noreturn));
|
void exit_msg(const char *msg) __attribute__((noreturn));
|
||||||
|
|
||||||
void * xmalloc(size_t size);
|
void *xmalloc(size_t size);
|
||||||
|
|
||||||
void * xsodium_malloc(size_t size);
|
char *xstrdup(const char *str);
|
||||||
|
|
||||||
|
void *xsodium_malloc(size_t size);
|
||||||
|
|
||||||
void xor_buf(unsigned char *dst, const unsigned char *src, size_t len);
|
void xor_buf(unsigned char *dst, const unsigned char *src, size_t len);
|
||||||
|
|
||||||
|
@ -29,10 +36,14 @@ int xfprintf(FILE *fp, const char *format, ...) __attribute__((format(printf, 2,
|
||||||
|
|
||||||
int xfclose(FILE *fp);
|
int xfclose(FILE *fp);
|
||||||
|
|
||||||
void trim(char *str);
|
int trim(char *str);
|
||||||
|
|
||||||
const char * file_basename(const char *file);
|
const char *file_basename(const char *file);
|
||||||
|
|
||||||
FILE * fopen_create_useronly(const char *file);
|
FILE *fopen_create_useronly(const char *file);
|
||||||
|
|
||||||
|
int basedir_create_useronly(const char *file);
|
||||||
|
|
||||||
|
char *get_home_dir(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
120
src/libzodium/libzodium.zig
Normal file
120
src/libzodium/libzodium.zig
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const crypto = std.crypto;
|
||||||
|
const mem = std.mem;
|
||||||
|
const Ed25519 = crypto.sign.Ed25519;
|
||||||
|
|
||||||
|
export fn sodium_init() callconv(.C) c_int {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn sodium_memzero(pnt: [*c]u8, len: usize) callconv(.C) void {
|
||||||
|
crypto.utils.secureZero(u8, pnt[0..len]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn randombytes_buf(pnt: [*c]u8, len: usize) callconv(.C) void {
|
||||||
|
crypto.random.bytes(pnt[0..len]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn sodium_malloc(len: usize) callconv(.C) ?*anyopaque {
|
||||||
|
return std.c.malloc(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn sodium_free(pnt: ?*anyopaque) callconv(.C) void {
|
||||||
|
return std.c.free(pnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn crypto_pwhash_scryptsalsa208sha256(
|
||||||
|
out: [*c]u8,
|
||||||
|
outlen: c_ulonglong,
|
||||||
|
passwd: [*c]const u8,
|
||||||
|
passwdlen: c_ulonglong,
|
||||||
|
salt: [*c]const u8,
|
||||||
|
opslimit: c_ulonglong,
|
||||||
|
memlimit: usize,
|
||||||
|
) callconv(.C) c_int {
|
||||||
|
crypto.pwhash.scrypt.kdf(
|
||||||
|
std.heap.c_allocator,
|
||||||
|
out[0..@intCast(outlen)],
|
||||||
|
passwd[0..@intCast(passwdlen)],
|
||||||
|
salt[0..32],
|
||||||
|
crypto.pwhash.scrypt.Params.fromLimits(opslimit, memlimit),
|
||||||
|
) catch return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const crypto_generichash_state = crypto.hash.blake2.Blake2b512;
|
||||||
|
|
||||||
|
export fn crypto_generichash_init(
|
||||||
|
state: *crypto_generichash_state,
|
||||||
|
_: [*c]const u8,
|
||||||
|
_: usize,
|
||||||
|
outlen: usize,
|
||||||
|
) c_int {
|
||||||
|
state.* = crypto.hash.blake2.Blake2b512.init(.{ .expected_out_bits = outlen * 8 });
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn crypto_generichash_update(
|
||||||
|
state: *crypto_generichash_state,
|
||||||
|
in: [*c]const u8,
|
||||||
|
inlen: c_ulonglong,
|
||||||
|
) c_int {
|
||||||
|
state.*.update(in[0..@intCast(inlen)]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn crypto_generichash_final(
|
||||||
|
state: *crypto_generichash_state,
|
||||||
|
out: [*c]u8,
|
||||||
|
outlen: usize,
|
||||||
|
) c_int {
|
||||||
|
var h: [64]u8 = undefined;
|
||||||
|
state.*.final(&h);
|
||||||
|
@memcpy(out[0..outlen], h[0..outlen]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn crypto_sign_keypair(pk: [*c]u8, sk: [*c]u8) callconv(.C) c_int {
|
||||||
|
const kp = if (std.meta.hasFn(Ed25519.KeyPair, "generate")) Ed25519.KeyPair.generate() else (Ed25519.KeyPair.create(null) catch return -1);
|
||||||
|
pk[0..32].* = kp.public_key.toBytes();
|
||||||
|
sk[0..64].* = kp.secret_key.toBytes();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn crypto_sign_detached(
|
||||||
|
sig_bytes: [*c]u8,
|
||||||
|
_: [*c]c_ulonglong,
|
||||||
|
m: [*c]const u8,
|
||||||
|
mlen: c_ulonglong,
|
||||||
|
sk_bytes: [*c]const u8,
|
||||||
|
) callconv(.C) c_int {
|
||||||
|
const sk = Ed25519.SecretKey.fromBytes(sk_bytes[0..64].*) catch return -1;
|
||||||
|
const kp = Ed25519.KeyPair.fromSecretKey(sk) catch return -1;
|
||||||
|
var noise: [Ed25519.noise_length]u8 = undefined;
|
||||||
|
crypto.random.bytes(&noise);
|
||||||
|
const s = kp.sign(m[0..@intCast(mlen)], noise) catch return -1;
|
||||||
|
sig_bytes[0..64].* = s.toBytes();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn crypto_sign_verify_detached(
|
||||||
|
sig_bytes: [*c]const u8,
|
||||||
|
m: [*c]const u8,
|
||||||
|
mlen: c_ulonglong,
|
||||||
|
pk_bytes: [*c]const u8,
|
||||||
|
) callconv(.C) c_int {
|
||||||
|
const pk = Ed25519.PublicKey.fromBytes(pk_bytes[0..32].*) catch return -1;
|
||||||
|
const sig = Ed25519.Signature.fromBytes(sig_bytes[0..64].*);
|
||||||
|
sig.verify(m[0..@intCast(mlen)], pk) catch return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn sodium_bin2hex(
|
||||||
|
hex: [*c]u8,
|
||||||
|
hex_maxlen: usize,
|
||||||
|
bin: [*c]const u8,
|
||||||
|
bin_len: usize,
|
||||||
|
) callconv(.C) [*c]u8 {
|
||||||
|
_ = std.fmt.bufPrint(hex[0..hex_maxlen], "{s}", .{std.fmt.fmtSliceHexLower(bin[0..bin_len])}) catch return null;
|
||||||
|
return hex;
|
||||||
|
}
|
62
src/libzodium/sodium.h
Normal file
62
src/libzodium/sodium.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
int sodium_init(void) __attribute__((warn_unused_result));
|
||||||
|
;
|
||||||
|
|
||||||
|
void sodium_memzero(void* const pnt, const size_t len);
|
||||||
|
|
||||||
|
void randombytes_buf(void* const buf, const size_t size) __attribute__((nonnull));
|
||||||
|
|
||||||
|
void* sodium_malloc(const size_t size) __attribute__((malloc));
|
||||||
|
|
||||||
|
void sodium_free(void* ptr);
|
||||||
|
|
||||||
|
#define crypto_pwhash_scryptsalsa208sha256_SALTBYTES 32U
|
||||||
|
#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN 32768U
|
||||||
|
#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN 16777216U
|
||||||
|
#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE 33554432U
|
||||||
|
#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE 1073741824U
|
||||||
|
|
||||||
|
int crypto_pwhash_scryptsalsa208sha256(unsigned char* const out,
|
||||||
|
unsigned long long outlen,
|
||||||
|
const char* const passwd,
|
||||||
|
unsigned long long passwdlen,
|
||||||
|
const unsigned char* const salt,
|
||||||
|
unsigned long long opslimit,
|
||||||
|
size_t memlimit) __attribute__((warn_unused_result))
|
||||||
|
__attribute__((nonnull));
|
||||||
|
|
||||||
|
typedef struct crypto_generichash_state {
|
||||||
|
unsigned char opaque[512];
|
||||||
|
} crypto_generichash_state;
|
||||||
|
|
||||||
|
#define crypto_generichash_BYTES_MAX 64U
|
||||||
|
#define crypto_generichash_BYTES 32U
|
||||||
|
|
||||||
|
int crypto_generichash_init(crypto_generichash_state* state, const unsigned char* key,
|
||||||
|
const size_t keylen, const size_t outlen) __attribute__((nonnull(1)));
|
||||||
|
|
||||||
|
int crypto_generichash_update(crypto_generichash_state* state,
|
||||||
|
const unsigned char* in,
|
||||||
|
unsigned long long inlen) __attribute__((nonnull(1)));
|
||||||
|
|
||||||
|
int crypto_generichash_final(crypto_generichash_state* state, unsigned char* out,
|
||||||
|
const size_t outlen) __attribute__((nonnull));
|
||||||
|
|
||||||
|
#define crypto_sign_SECRETKEYBYTES 64
|
||||||
|
#define crypto_sign_PUBLICKEYBYTES 32
|
||||||
|
#define crypto_sign_BYTES 64
|
||||||
|
|
||||||
|
int crypto_sign_keypair(unsigned char* pk, unsigned char* sk) __attribute__((nonnull));
|
||||||
|
|
||||||
|
int crypto_sign_detached(unsigned char* sig, unsigned long long* siglen_p, const unsigned char* m,
|
||||||
|
unsigned long long mlen, const unsigned char* sk)
|
||||||
|
__attribute__((nonnull(1, 5)));
|
||||||
|
|
||||||
|
int crypto_sign_verify_detached(const unsigned char* sig,
|
||||||
|
const unsigned char* m,
|
||||||
|
unsigned long long mlen,
|
||||||
|
const unsigned char* pk) __attribute__((warn_unused_result))
|
||||||
|
__attribute__((nonnull(1, 4)));
|
113
src/manpage.md
Normal file
113
src/manpage.md
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
<!---
|
||||||
|
This man page can be generated using ronn - https://rtomayko.github.io/ronn/
|
||||||
|
-->
|
||||||
|
|
||||||
|
# minisign(1) -- A dead simple tool to sign files and verify signatures.
|
||||||
|
|
||||||
|
## SYNOPSIS
|
||||||
|
|
||||||
|
`minisign` -G [-p pubkey_file] [-s seckey_file] [-W]
|
||||||
|
|
||||||
|
`minisign` -R [-s seckey_file] [-p pubkey_file]
|
||||||
|
|
||||||
|
`minisign` -C [-s seckey_file] [-W]
|
||||||
|
|
||||||
|
`minisign` -S [-H] [-x sig_file] [-s seckey_file] [-c untrusted_comment] [-t trusted_comment] -m file [file ...]
|
||||||
|
|
||||||
|
`minisign` -V [-x sig_file] [-p pubkey_file | -P pubkey] [-o] [-q] -m file
|
||||||
|
|
||||||
|
## DESCRIPTION
|
||||||
|
|
||||||
|
**Minisign** is a dead simple tool to sign files and verify signatures.
|
||||||
|
|
||||||
|
It is portable, lightweight, and uses the highly secure [Ed25519](http://ed25519.cr.yp.to/) public-key signature system.
|
||||||
|
|
||||||
|
## OPTIONS
|
||||||
|
|
||||||
|
These options control the actions of `minisign`.
|
||||||
|
|
||||||
|
- `-G`:
|
||||||
|
Generate a new key pair
|
||||||
|
- `-C`:
|
||||||
|
Change/remove the password of a secret key
|
||||||
|
- `-R`:
|
||||||
|
Recreate a public key file from a secret key file
|
||||||
|
- `-S`:
|
||||||
|
Sign files
|
||||||
|
- `-V`:
|
||||||
|
Verify that a signature is valid for a given file
|
||||||
|
- `-H`:
|
||||||
|
Requires the input to be prehashed
|
||||||
|
- `-l`:
|
||||||
|
Sign using the legacy format
|
||||||
|
- `-m <file>`:
|
||||||
|
File to sign/verify
|
||||||
|
- `-o`:
|
||||||
|
Combined with -V, output the file content after verification
|
||||||
|
- `-p <pubkey_file>`:
|
||||||
|
Public key file (default: ./minisign.pub)
|
||||||
|
- `-P <pubkey>`:
|
||||||
|
Public key, as a base64 string
|
||||||
|
- `-s <seckey_file>`:
|
||||||
|
Secret key file (default: ~/.minisign/minisign.key)
|
||||||
|
- `-W`:
|
||||||
|
Do not encrypt/decrypt the secret key with a password
|
||||||
|
- `-x <sig_file>`:
|
||||||
|
Signature file (default: <file>.minisig)
|
||||||
|
- `-c <comment>`:
|
||||||
|
Add a one-line untrusted comment
|
||||||
|
- `-t <comment>`:
|
||||||
|
Add a one-line trusted comment
|
||||||
|
- `-q`:
|
||||||
|
Quiet mode, suppress output
|
||||||
|
- `-Q`:
|
||||||
|
Pretty quiet mode, only print the trusted comment
|
||||||
|
- `-f`:
|
||||||
|
Force. Combined with -G, overwrite a previous key pair
|
||||||
|
- `-v`:
|
||||||
|
Display version number
|
||||||
|
|
||||||
|
## EXAMPLES
|
||||||
|
|
||||||
|
Creating a key pair
|
||||||
|
|
||||||
|
`minisign` -G
|
||||||
|
|
||||||
|
The public key is printed and put into the `minisign.pub` file. The secret key is encrypted and saved as a file named `~/.minisign/minisign.key`.
|
||||||
|
|
||||||
|
Signing files
|
||||||
|
|
||||||
|
$ `minisign` -Sm myfile.txt
|
||||||
|
$ `minisign` -Sm myfile.txt myfile2.txt \*.c
|
||||||
|
|
||||||
|
Or to include a comment in the signature, that will be verified and displayed when verifying the file:
|
||||||
|
|
||||||
|
$ `minisign` -Sm myfile.txt -t 'This comment will be signed as well'
|
||||||
|
|
||||||
|
The secret key is loaded from `${MINISIGN_CONFIG_DIR}/minisign.key`, `~/.minisign/minisign.key`, or its path can be explicitly set with the `-s <path>` command-line switch.
|
||||||
|
|
||||||
|
Verifying a file
|
||||||
|
|
||||||
|
$ `minisign` -Vm myfile.txt -P <pubkey>
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
$ `minisign` -Vm myfile.txt -p signature.pub
|
||||||
|
|
||||||
|
This requires the signature `myfile.txt.minisig` to be present in the same directory.
|
||||||
|
|
||||||
|
The public key can either reside in a file (`./minisign.pub` by default) or be directly specified on the command line.
|
||||||
|
|
||||||
|
## NOTES
|
||||||
|
|
||||||
|
Signature files include an untrusted comment line that can be freely modified even after the signature is created.
|
||||||
|
|
||||||
|
They also include a second comment line that cannot be modified without the secret key.
|
||||||
|
|
||||||
|
Trusted comments can be used to add instructions or application-specific metadata such as the intended file name, timestamps, resource identifiers, or version numbers to prevent downgrade attacks.
|
||||||
|
|
||||||
|
OpenBSD's `signify(1)` is conceptually similar to Minisign. Minisign creates signatures that can be verified by `signify`; however, signatures created by `signify` cannot be verified with Minisign because Minisign expects a trusted comment section to be present. Trusted comments are crucial for describing what has been signed, in addition to merely confirming that a signature exists.
|
||||||
|
|
||||||
|
## AUTHOR
|
||||||
|
|
||||||
|
Frank Denis (github [at] pureftpd [dot] org)
|
928
src/minisign.c
928
src/minisign.c
File diff suppressed because it is too large
Load diff
|
@ -2,22 +2,25 @@
|
||||||
#ifndef MINISIGN_H
|
#ifndef MINISIGN_H
|
||||||
#define MINISIGN_H 1
|
#define MINISIGN_H 1
|
||||||
|
|
||||||
#define COMMENTMAXBYTES 1024
|
#define COMMENTMAXBYTES 1024
|
||||||
#define KEYNUMBYTES 8
|
#define KEYNUMBYTES 8
|
||||||
#define PASSWORDMAXBYTES 1024
|
#define PASSWORDMAXBYTES 1024
|
||||||
#define TRUSTEDCOMMENTMAXBYTES 8192
|
#define TRUSTEDCOMMENTMAXBYTES 8192
|
||||||
#define SIGALG "Ed"
|
#define SIGALG "Ed"
|
||||||
#define SIGALG_HASHED "ED"
|
#define SIGALG_HASHED "ED"
|
||||||
#define KDFALG "Sc"
|
#define KDFALG "Sc"
|
||||||
#define CHKALG "B2"
|
#define KDFNONE "\0\0"
|
||||||
#define COMMENT_PREFIX "untrusted comment: "
|
#define CHKALG "B2"
|
||||||
#define DEFAULT_COMMENT "signature from minisign secret key"
|
#define COMMENT_PREFIX "untrusted comment: "
|
||||||
#define SECRETKEY_DEFAULT_COMMENT "minisign encrypted secret key"
|
#define DEFAULT_COMMENT "signature from minisign secret key"
|
||||||
#define TRUSTED_COMMENT_PREFIX "trusted comment: "
|
#define SECRETKEY_DEFAULT_COMMENT "minisign encrypted secret key"
|
||||||
#define SIG_DEFAULT_PKFILE "minisign.pub";
|
#define TRUSTED_COMMENT_PREFIX "trusted comment: "
|
||||||
#define SIG_DEFAULT_SKFILE "minisign.key";
|
#define SIG_DEFAULT_CONFIG_DIR ".minisign"
|
||||||
#define SIG_SUFFIX ".minisig"
|
#define SIG_DEFAULT_CONFIG_DIR_ENV_VAR "MINISIGN_CONFIG_DIR"
|
||||||
#define VERSION_STRING "minisign 0.6"
|
#define SIG_DEFAULT_PKFILE "minisign.pub"
|
||||||
|
#define SIG_DEFAULT_SKFILE "minisign.key"
|
||||||
|
#define SIG_SUFFIX ".minisig"
|
||||||
|
#define VERSION_STRING "minisign 0.12"
|
||||||
|
|
||||||
typedef struct KeynumSK_ {
|
typedef struct KeynumSK_ {
|
||||||
unsigned char keynum[KEYNUMBYTES];
|
unsigned char keynum[KEYNUMBYTES];
|
||||||
|
@ -37,12 +40,12 @@ typedef struct SeckeyStruct_ {
|
||||||
unsigned char kdf_salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
|
unsigned char kdf_salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
|
||||||
unsigned char kdf_opslimit_le[8];
|
unsigned char kdf_opslimit_le[8];
|
||||||
unsigned char kdf_memlimit_le[8];
|
unsigned char kdf_memlimit_le[8];
|
||||||
KeynumSK keynum_sk;
|
KeynumSK keynum_sk;
|
||||||
} SeckeyStruct;
|
} SeckeyStruct;
|
||||||
|
|
||||||
typedef struct PubkeyStruct_ {
|
typedef struct PubkeyStruct_ {
|
||||||
unsigned char sig_alg[2];
|
unsigned char sig_alg[2];
|
||||||
KeynumPK keynum_pk;
|
KeynumPK keynum_pk;
|
||||||
} PubkeyStruct;
|
} PubkeyStruct;
|
||||||
|
|
||||||
typedef struct SigStruct_ {
|
typedef struct SigStruct_ {
|
||||||
|
@ -55,7 +58,9 @@ typedef enum Action_ {
|
||||||
ACTION_NONE,
|
ACTION_NONE,
|
||||||
ACTION_GENERATE,
|
ACTION_GENERATE,
|
||||||
ACTION_SIGN,
|
ACTION_SIGN,
|
||||||
ACTION_VERIFY
|
ACTION_VERIFY,
|
||||||
|
ACTION_RECREATE_PK,
|
||||||
|
ACTION_UPDATE_PASSWORD
|
||||||
} Action;
|
} Action;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue