Compare commits

...

188 commits
0.6 ... master

Author SHA1 Message Date
Frank Denis
108ea640ba Require Zig 0.14 2025-03-11 19:06:46 +01:00
Frank Denis
c7d965e43a Update .gitignore 2025-03-11 19:04:58 +01:00
Frank Denis
428c18e08a Zig 0.14 compat 2025-03-11 19:04:40 +01:00
Frank Denis
32038530b7 Add a note about signify compatibility
Fixes #159
2025-03-11 18:43:41 +01:00
Chad Dougherty
e9631e8c67
Add a note in the man page about signify compatibility (#159)
based nearly verbatim on @jedisct1's explanation in the discussion of #59
2025-03-11 18:40:49 +01:00
Frank Denis
74365c0f51 Normalize Markdown files 2025-03-11 18:31:43 +01:00
Frank Denis
d5a2f02bc0 Look at possible include/lib paths for linuxbrew
Fixes #156
2025-01-29 23:05:34 +01:00
Frank Denis
4dd6fbf632 Use a list for possible include paths to be consistent with libraries 2025-01-29 23:02:34 +01:00
Frank Denis
41306e3e42 No need to set headerpad_max_install_names when linking statically 2025-01-29 18:28:41 +01:00
Frank Denis
090cc4752c Set headerpad_max_install_names only when linking libsodium 2025-01-29 18:27:40 +01:00
Rui Chen
b5cf334b42
build: fix mach-o relocation (#155)
Signed-off-by: Rui Chen <rui@chenrui.dev>
2025-01-29 18:27:25 +01:00
Frank Denis
c684406e21 Don't include nonexistent library paths
Introduced in 101e90a668 to make
Minisign build with Zig 0.13.

Fixes #153
2025-01-18 14:46:57 +01:00
Frank Denis
29a07eade0 Add compatibility with 32-bit targets (webassembly) 2025-01-16 13:36:56 +01:00
Frank Denis
90d46db240 Add the ability to override the libsodium install dirs 2025-01-16 12:55:52 +01:00
Frank Denis
101e90a668 Allow compilation with Zig 0.13 as well as 0.14
Fixes #150
2025-01-16 00:54:22 +01:00
Frank Denis
c165362385 Move libzodium files to a dedicated directory 2025-01-15 23:42:24 +01:00
Frank Denis
1c44ef601e Regen man page 2025-01-15 23:42:04 +01:00
Frank Denis
3c889ce7f3 Add a section title 2025-01-15 23:27:20 +01:00
Frank Denis
b85e15d45a Add build.zig.zon 2025-01-15 22:46:54 +01:00
Frank Denis
9896d072d4 Bump 2025-01-15 22:46:54 +01:00
Frank Denis
b393ff47b1 Let people compile with ReleaseFast if they want to 2025-01-15 22:46:54 +01:00
Frank Denis
c084f9ca38 without_libsodium -> without-libsodium 2025-01-15 22:46:54 +01:00
Frank Denis
c1c452560f Nits 2025-01-15 22:46:51 +01:00
Frank Denis
e0e86b4e4f Add -Dstatic 2025-01-15 22:46:51 +01:00
Frank Denis
12333fd7d1 Minisign is 10 years old 2025-01-15 22:46:51 +01:00
Frank Denis
952225f9b7 Import zodium.h 2025-01-15 22:46:51 +01:00
Frank Denis
e43b9ff13b Make libsodium optional 2025-01-15 22:11:52 +01:00
Frank Denis
e640be4b8f Indent 2025-01-15 22:07:37 +01:00
Frank Denis
a1c07cc277 Leverage root_module.linkSystemLibrary() 2025-01-15 21:03:56 +01:00
Frank Denis
285b53d52c Mention where the compiled binary is 2025-01-15 21:03:49 +01:00
Frank Denis
28612a431a Add issues.yml 2024-12-31 14:58:15 +01:00
Frank Denis
cbc79b3ece defineCMacro -> root_module.addCMacro 2024-12-20 12:21:03 +01:00
Frank Denis
55320cc84c 2024 2024-12-11 18:46:14 +01:00
Frank Denis
868785690f Add a Docker usage example
Fixes #132
2024-12-11 18:45:20 +01:00
Frank Denis
45478e1dd6 Udpate for Zig 0.13 2024-05-09 21:46:20 +02:00
Ryan Castellucci
996ea4fee3
exclude other unneeded code for VERIFY_ONLY (#139) 2024-04-02 08:11:27 +02:00
Frank Denis
573988d235 Update for zig-master 2024-01-04 12:24:31 +01:00
Isaac Yonemoto
5f96819f44
Add Elixir to minisign implementations (#138) 2023-12-18 18:50:08 +01:00
Frank Denis
ef2db96ae0 Breaking: wero-pad key identifiers
Fixes #137
2023-12-17 22:04:43 +01:00
Frank Denis
7d1116c5cc Zig 0.12 compat 2023-11-20 19:13:22 +01:00
Frank Denis
8aef018182 Update for Zig 0.11 2023-08-12 11:21:37 +02:00
Frank Denis
709fed6b73 Build script 2023-01-17 11:48:15 +01:00
Frank Denis
05a0cd435d Remove Travis 2023-01-17 11:40:20 +01:00
Frank Denis
444ef2dca9 Remove unused var 2023-01-16 22:42:27 +01:00
Frank Denis
ee46615226 Zeroize seckey_struct early 2023-01-16 21:24:08 +01:00
Frank Denis
12fd90b6fe Update man page 2023-01-16 21:18:39 +01:00
Frank Denis
ef445ab928 2023 2023-01-16 21:16:52 +01:00
Frank Denis
3f1df52db4 Warn about -C -W implications before it's too late 2023-01-16 21:16:38 +01:00
Frank Denis
506ac9ce3e Simplify usage without key encryption 2023-01-16 21:12:16 +01:00
Frank Denis
27bff8a1f5 Use CMAKE_BUILD_TYPE=MinSizeRel 2023-01-16 20:50:57 +01:00
Frank Denis
80defb2a99 Bump 2023-01-16 20:46:34 +01:00
Frank Denis
6040047c27 seckey_chk() actually computes chk 2023-01-16 20:46:34 +01:00
Frank Denis
16624abf2e Add the ability to change the password of a secret key
Fixes #110
2023-01-16 20:39:56 +01:00
Frank Denis
6ccd801dbc Allow seckey_load() to optionally return a copy of the key comment 2023-01-16 20:04:16 +01:00
Frank Denis
41938e99f5 Move key encryption/decryption code to dedicated functions 2023-01-16 19:45:00 +01:00
Frank Denis
a536c178ab Format 2023-01-16 19:40:34 +01:00
Frank Denis
94e18a72d8 Move variables to a local context 2023-01-16 19:38:39 +01:00
Frank Denis
d870938ae5 Reorder commands for clarity 2023-01-16 19:21:19 +01:00
Frank Denis
d2afa89fe7 Update usage 2023-01-16 19:15:53 +01:00
Frank Denis
c33051dec3 Update usage 2023-01-16 19:03:20 +01:00
Frank Denis
cb2fc2ce7c Add a flag to allow secret keys to be unencrypted
https://github.com/ziglang/zig/issues/4945
2023-01-16 18:50:36 +01:00
Frank Denis
0fccaf94e2 Require cmake 2.8.12 2023-01-16 18:43:18 +01:00
Frank Denis
a26f2c8e5d Update build.zig for zig 0.10 2023-01-11 01:27:48 +01:00
Frank Denis
a2c8848418 Add cosign public key
Fixes #121
2022-06-10 14:17:52 +02:00
Frank Denis
4b2df2ee07 Bail out if fgets() output is not \n terminated when it should
Fixes #116
2022-02-20 10:50:37 +01:00
Frank Denis
b81f3d4065 Add paths for Homebrew on Apple Silicon 2021-11-30 09:22:24 +01:00
Frank Denis
e74428c464 Update man page
Fixes #106
2021-10-25 00:53:09 +02:00
Frank Denis
aa99a5c417 Document -f option 2021-10-09 17:47:16 +02:00
Frank Denis
614fd57665 Define _GNU_SOURCE 2021-10-09 15:54:09 +02:00
Frank Denis
503f722ac3 Suggest release-safe 2021-10-09 15:34:41 +02:00
Frank Denis
40dd5acf36 Bump CMakeList version 2021-10-09 15:04:03 +02:00
Frank Denis
da6c6e7f77 Remove final stop 2021-10-09 14:00:23 +02:00
Frank Denis
a02e9e608b Bump version 2021-10-08 22:15:00 +02:00
Frank Denis
a832bbc270 Autoformat 2021-10-08 22:08:02 +02:00
Frank Denis
dfb7dda9dc Add -H / -l options 2021-10-08 19:31:50 +02:00
Frank Denis
b653798d66 Remove workaround for really ancient libsodium versions 2021-10-08 15:06:06 +02:00
Frank Denis
52ccad8685 Add build.zig file 2021-10-08 15:04:21 +02:00
Frank Denis
f6965a0858 Fix compilation with VERIFY_ONLY 2021-10-08 14:40:58 +02:00
Frank Denis
1e050e7d0a Always prehash, add this to the default trusted comment 2021-10-08 14:39:33 +02:00
Frank Denis
c9ba80b656 Add minizign 2021-04-15 17:42:03 +02:00
Frank Denis
1cbcac9644 Error out if the same option is specified multiple times
Fixes #87
2021-04-04 19:24:12 +02:00
Frank Denis
f3e97d838f up 2021-03-04 18:44:27 +01:00
Frank Denis
b9349929fb Add the Go rewrite of minisign 2021-03-04 18:41:59 +01:00
Frank Denis
7edc350137 Add py-minisign 2021-02-27 01:32:24 +01:00
Frank Denis
d5b74ae86e up 2021-02-27 01:32:22 +01:00
Abu Sakib
121cf06e9b
Fix example of how to verify with pubkey (#89) 2020-11-07 22:37:19 +01:00
Frank Denis
1a7cc6c860
Merge pull request #80 from soatok/patch-1
Add link to PHP implementation
2020-08-08 08:25:21 +02:00
Soatok Dreamseeker
246d542e37
Add link to PHP implementation 2020-08-07 19:54:10 -04:00
Frank Denis
bb81665e20 Remove duplicate va_end() on error path 2020-07-17 16:08:50 +02:00
Frank Denis
82913c2b64 Add CodeQL scan 2020-06-11 10:27:28 +02:00
Frank Denis
9b3a4f28fd constify 2020-06-06 22:28:52 +02:00
Frank Denis
3bd2ae56da Bump 2020-06-06 22:24:07 +02:00
Frank Denis
6a3fb509dc Dockerfile: use more recent tools & build a smaller executable 2020-06-06 22:02:42 +02:00
Frank Denis
c4aad021da Merge branch 'master' of github.com:jedisct1/minisign
* 'master' of github.com:jedisct1/minisign:
  Added docker support (#55)
2020-06-06 21:27:03 +02:00
Bruno Wego
4d1f41e5be
Added docker support (#55)
* chore(repo): added docker support

* docs(readme): added docker instruction

* refactor(docker): build from current branch

* fix(docker): remove unnecessary packages

Co-authored-by: Frank Denis <124872+jedisct1@users.noreply.github.com>
2020-06-06 21:26:51 +02:00
Frank Denis
d357a3a5a4 y++ 2020-06-06 21:12:46 +02:00
akoshibe
95e4e900a7
README: move '..' to end when passing configs to cmake (#76) 2020-06-04 10:12:29 +02:00
Frank Denis
a705d72380 Add line breaks between synopsis commands; regen man page
Fixes #74
2020-05-06 10:22:34 +02:00
Frank Denis
dfb9963ce7 Seems to be a more common way to test for CMAKE_STRIP 2019-12-31 15:06:33 +01:00
peter-tank
0c45001d33 should fix: default empty strip command defined by openwrt toolchain #66 (#68)
FYI CMake documents: https://cmake.org/cmake/help/v3.0/command/if.html

Signed-off-by: peter-tank <30540412+peter-tank@users.noreply.github.com>
2019-12-31 15:05:40 +01:00
Rory Bradford
9727843b70 Add Ubuntu PPA package (#64) 2019-10-06 13:57:31 +02:00
Frank Denis
5cff07069b Progressively reduce the parameters on low memory 2019-08-28 14:17:41 +02:00
Maciej Soltysiak
ddc54a9248 Fallback to lower KDF settings in low memory situation 2019-08-28 14:16:51 +02:00
Frank Denis
9f6bdd5856 Improve error message 2019-08-19 11:50:11 +02:00
Frank Denis
7c3e56a1da Merge branch 'master' of github.com:jedisct1/minisign
* 'master' of github.com:jedisct1/minisign:
  Move up
2019-07-26 10:25:13 +02:00
Frank Denis
841a552290 Remove Minisign-py 2019-07-26 10:25:02 +02:00
Frank Denis
7cc9b23ed9 Merge branch 'master' of github.com:jedisct1/minisign
* 'master' of github.com:jedisct1/minisign:
  Better diagnostic message when the trusted section is missing
  Reword the part on fault injections
  Add links to webassembly versions
2019-07-23 21:24:33 +02:00
Frank Denis
21a6f41c06 Move up 2019-07-23 21:24:12 +02:00
Frank Denis
056fa3541b Better diagnostic message when the trusted section is missing
Fixes #59
2019-07-23 07:47:50 +02:00
Frank Denis
76161c653e Reword the part on fault injections
Fault injection is rarely part of the threat model for the typical
minisign use case, and minisign already includes mitigations.

What's more important is the fact that non-deterministic signatures
are allowed if necessary, and are fully compatible with
implementations using deterministic signatures.
2019-07-09 16:36:26 +02:00
Frank Denis
c295ceb267 Add links to webassembly versions 2019-07-09 16:31:06 +02:00
Frank Denis
507c6f6781 cmake... 2019-06-01 15:53:44 +02:00
Frank Denis
246237e3ea Update Travis 2019-06-01 15:49:52 +02:00
Frank Denis
5af09266d8 Document options for static builds 2019-06-01 15:49:42 +02:00
Frank Denis
2a20f7d920 ... 2019-06-01 15:19:51 +02:00
Frank Denis
25508229e4 Remove LINK_SEARCH_END_STATIC 2019-06-01 14:05:11 +02:00
Frank Denis
da3962b837 LIBSODIUM_STATIC is already defined, so use STATIC_LIBSODIUM 2019-06-01 13:59:15 +02:00
Frank Denis
a88527ae5f Keep fighting with cmake 2019-06-01 13:42:28 +02:00
Frank Denis
8bd7ec0197 Try setting LINK_SEARCH_END_STATIC 2019-06-01 13:00:04 +02:00
Frank Denis
c78fe77559 Document that debatable -R command-line switch 2019-06-01 12:43:20 +02:00
Frank Denis
a27bd363b3 I hate cmake 2019-06-01 12:38:18 +02:00
Frank Denis
03ba8a6355 Sodium -> sodium 2019-06-01 11:50:41 +02:00
Frank Denis
e71c9a7a47 Set -static except on macOS 2019-06-01 11:30:23 +02:00
Frank Denis
15dddd7c45 Use Findsodium.cmake, add the ability to statically link the library 2019-06-01 11:21:52 +02:00
Frank Denis
971d70bd2e
Merge pull request #52 from brunowego/patch-1
Link correction for go-minisign
2019-05-31 18:25:45 +02:00
Bruno Wego
41806352d2
chore(README): link correction for go-minisign 2019-05-31 12:26:06 -03:00
Frank Denis
b718d329de Print a meaningful error message instead of abort()ing on OOM 2019-05-29 10:57:50 +02:00
Frank Denis
33bdfce764 Add an option to recreate a public key file from a secret key file
Fixes #51
2019-05-26 15:58:17 +02:00
Frank Denis
b3890abbb6 cmake-format 2019-05-11 12:16:13 +02:00
Frank Denis
0137cd75af Add the Javascript implementation 2019-05-09 00:34:20 +02:00
Frank Denis
ff212957a7 Add rust-minisign 2019-04-28 23:37:12 +02:00
Frank Denis
d45184dbbe rsign2 2019-04-28 12:35:51 +02:00
Frank Denis
d6c5c8c17b More libraries and implementations 2019-04-20 20:33:39 +02:00
Frank Denis
9eac49b161 Don't unconditionally print errno when fgets() fails (if can be an EOF)
Fixes #46
2018-10-21 13:33:29 +02:00
Frank Denis
e5f7f65b8a
Merge pull request #38 from leper/dir_sep
Use the DIR_SEP macro to remove an ifdef.
2018-02-04 08:58:40 +01:00
Georg Kilzer
237772bb40 Use the DIR_SEP macro to remove an ifdef. 2018-02-04 05:58:58 +01:00
Frank Denis
7fdb9fdb0e Remove unused variable 2018-02-02 23:34:28 +01:00
Frank Denis
391d51d3a2 Update man page, bump version 2018-02-02 23:33:36 +01:00
Frank Denis
0c265d0dc6 Add the ability to sign multiple files at once 2018-02-02 23:33:33 +01:00
Frank Denis
75879f460f 2018 2017-12-31 19:18:28 +01:00
Frank Denis
e2a39c4e76
Merge pull request #36 from alaviss/haiku
Add Haiku support
2017-12-17 12:01:07 +01:00
Leorize
978a8b4086
Add Haiku support 2017-12-17 17:50:52 +07:00
Frank Denis
139c99a73a Reorder for consistency with the rest of the code 2017-12-14 16:12:52 +01:00
Frank Denis
f384177a3a
Merge pull request #35 from ulidtko/fix-broken-mkdir
fix "new.key: Is a directory" and a memleak when generating a keypair
2017-12-14 16:11:00 +01:00
Maxim Ivanov
5e81e5a3c6 fix "new.key: Is a directory" and a memleak when generating a keypair
Test: minisign -G -p new.pub -s new.key
Expected: new.pub and new.key appears in CWD
Actual: error "new.key: Is a directory" and no keys
2017-12-14 14:37:18 +02:00
Frank Denis
c4cca6ef89 Fix format string 2017-12-01 15:56:21 +01:00
Frank Denis
66b19a6da3 Add a note on ED25519_NONDETERMINISTIC 2017-10-18 09:30:46 +02:00
Frank Denis
1d4855a83a Travis: build with non-deterministic signatures 2017-10-18 09:02:57 +02:00
Frank Denis
4727fff205 Mention rsign 2017-09-11 22:33:40 +02:00
Frank Denis
4dfcb00afd Minimal libsodium builds will not be enough with libsodium >= 1.0.13 2017-07-11 21:57:56 +02:00
Frank Denis
eb48c20f8d Gb -> GB 2017-07-07 22:16:42 +02:00
Frank Denis
6e313cb9d8 2017 2017-07-07 22:14:43 +02:00
Frank Denis
3db5a6ad2c sys/fcntl.h -> fcntl.h 2017-04-30 19:06:16 +02:00
Frank Denis
ab55b98c34 Factorize 2017-03-11 11:11:12 +01:00
Frank Denis
81c9d95930 Verify the signature after signing if a public key is available
The overhead is negligible and it validates that the public key
is correct.
2017-03-11 10:29:31 +01:00
Frank Denis
4dcfeb8e7c Turn a redundant check into an assertion 2016-12-04 18:21:00 +01:00
Frank Denis
48bdcdc932 Add minisign-misc 2016-08-05 16:57:01 +02:00
Frank Denis
ba6bc8eb98 No need to manually move the secret key to ~/.minisign any more 2016-08-01 01:17:25 +02:00
Frank Denis
e3ee3d5a6c Travis: don't forget to configure libsodium 2016-08-01 01:13:16 +02:00
Frank Denis
86d883c1dc Add the license title 2016-08-01 01:05:38 +02:00
Frank Denis
626e8785b2 Add a Travis script 2016-08-01 00:53:48 +02:00
Frank Denis
32fe65cf08 Version bump 2016-08-01 00:47:33 +02:00
Frank Denis
9dddf952df Install the man page 2016-08-01 00:47:23 +02:00
Frank Denis
2c97046c15 Final stop 2016-08-01 00:46:54 +02:00
Frank Denis
9ad3d02b6e Take the signature off the man page
Is it not very readable as a man page
2016-08-01 00:45:35 +02:00
Frank Denis
cea57b2fe7 Update the man page 2016-08-01 00:40:58 +02:00
Frank Denis
e12bf0a774 Improve the "key already exists" error message 2016-08-01 00:28:03 +02:00
Frank Denis
203f385c09 Make Windows users happy with backslashes as dir separators 2016-08-01 00:26:17 +02:00
Frank Denis
910159752d Missing ; for Windows 2016-08-01 00:19:58 +02:00
Frank Denis
1139d9497c Try to create the base directory of the secret key 2016-08-01 00:11:05 +02:00
Frank Denis
e8a6730eae Overwrite a previous key pair now requires the -f flag 2016-07-31 23:31:46 +02:00
Frank Denis
86e2210682 More things to remove in VERIFY_ONLY mode 2016-07-31 14:49:57 +02:00
Frank Denis
d654ad4647 Don't compile some more code in VERIFY_ONLY mode 2016-07-31 14:48:14 +02:00
Frank Denis
180c40bf03 Fix git merge conflict, duh 2016-06-13 06:56:41 +02:00
Frank Denis
f97cc049ac Merge branch 'master' of https://github.com/jedisct1/minisign
* 'master' of https://github.com/jedisct1/minisign:
  Remove superfluous semicolumns
2016-06-12 21:58:06 +02:00
Frank Denis
fa455e73d6 Load the secret key from ~/.minisign/minisign.key by default
Or `${MINISIGN_CONFIG_DIR}/minisign.key` if `MINISIGN_CONFIG_DIR` is
defined.
2016-06-12 21:55:53 +02:00
Frank Denis
546d7ee631 Remove superfluous semicolumns 2016-06-12 19:32:02 +02:00
Frank Denis
2ca0bea22f Define preprocess macros to enable extensions and support for large files 2016-01-23 16:17:07 +01:00
Satish Bysany
be2cc10844 Use unsigned type for array indexing
This fixes compilation warning about '-Wchar-subscripts'.
2016-01-23 16:09:39 +01:00
Frank Denis
eb13b0adb7 2016 2016-01-01 21:00:31 +01:00
Frank Denis
74f7017d7e Despam 2016-01-01 10:39:56 +01:00
Frank Denis
90ff4a5f94 Merge pull request #16 from cedwardsmedia/manpage
Added manual page
2016-01-01 02:00:04 +01:00
Corey Edwards
7f41769d67 Added manual page
I thought it would be nice to have a man page for this wonderful piece of software, especially with it being available in various package managers like Homebrew.

This man page is basically a reformatting (and slight reorganizing to fit the typical man page structure) of the official docs.

src/manpage.md is the Markdown source which can generate the actual man page (share/man/man1/minisign.1) using ronn <http://rtomayko.github.com/ronn/>

Update: Corrected a few typos that I didn't catch before original submission.
2015-12-31 18:18:28 -06:00
Frank Denis
e748f644dd Support signing of empty files 2015-12-30 09:38:30 +01:00
Frank Denis
a205a35a1b Explain what failed when a base64 conversion failed 2015-12-29 19:29:02 +01:00
Frank Denis
d55d86e219 Merge pull request #11 from bitbeans/master
Added chocolatey to README
2015-12-29 17:16:32 +01:00
Christian Hermann
230ea4367d Added chocolatey to README
- See https://chocolatey.org/packages/minisign/0.6.0
2015-12-29 17:12:49 +01:00
Frank Denis
8b01faa74a Explicitly initialize mask 2015-11-12 17:59:54 +01:00
24 changed files with 1796 additions and 447 deletions

165
.clang-format Normal file
View 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
View file

@ -0,0 +1,7 @@
**
!LICENSE
!README.md
!/share
!/src
!/CMakeLists.txt

32
.github/workflows/codeql-analysis.yml vendored Normal file
View 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
View 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
View file

@ -1,4 +1,3 @@
*.cmake
*.dSYM
*.exp
*.gcda
@ -24,4 +23,5 @@ CMakeFiles
Makefile
cmake_install.cmake
minisign
.zig-cache
zig-out

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.10)
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_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
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_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_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")
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)
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
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)
include(GNUInstallDirs)
install(FILES "share/man/man1/minisign.1"
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
COMPONENT doc)

15
Dockerfile Normal file
View 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"]

View file

@ -1,5 +1,7 @@
ISC LICENSE.
/*
* Copyright (c) 2015
* Copyright (c) 2015-2025
* Frank Denis <j at pureftpd dot org>
*
* Permission to use, copy, modify, and/or distribute this software for any

113
README.md
View file

@ -1,6 +1,6 @@
![CodeQL scan](https://github.com/jedisct1/minisign/workflows/CodeQL%20scan/badge.svg)
Minisign
========
# Minisign
Minisign is a dead simple tool to sign files and verify signatures.
@ -12,12 +12,39 @@ public key:
RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3
Compilation / installation
--------------------------
## Compilation / installation
## Building with Zig
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:
@ -27,6 +54,16 @@ Compilation:
$ make
# 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:
$ brew install minisign
@ -34,3 +71,67 @@ Minisign is also available in Homebrew:
Minisign is also available in Scoop on Windows:
$ 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
View 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
View 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
View 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
View file

@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExjZWrlc6c58W7ZzmQnx6mugty99C
OQTDtJeciX9LF9hEbs1J1fzZHRdRhV4OTqcq0jTW9PXnrSSZlk1fbkE/5w==
-----END PUBLIC KEY-----

168
share/man/man1/minisign.1 Normal file
View 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)

View file

@ -5,44 +5,70 @@
#include "base64.h"
unsigned char *
b64_to_bin(unsigned char * const bin, const char *b64,
size_t bin_maxlen, size_t b64_len, size_t * const bin_len_p)
b64_to_bin(unsigned char *const bin, const char *b64, size_t bin_maxlen, size_t b64_len,
size_t *const bin_len_p)
{
#define REV64_EOT 128U
#define REV64_NONE 64U
#define REV64_PAD '='
#define REV64_NONE 64U
#define REV64_PAD '='
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, 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,
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
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE, REV64_NONE,
REV64_NONE, REV64_NONE, REV64_NONE, 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, 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;
unsigned char *bin_w = bin;
unsigned char mask;
unsigned char t0, t1, t2, t3;
uint32_t t;
unsigned char mask = 0U;
unsigned char t0 = 0, t1 = 0, t2 = 0, t3 = 0;
uint32_t t = 0;
size_t i;
if (b64_len % 4U != 0U || (i = b64_len / 4U) <= 0U || bin_maxlen < i * 3U -
(b64_u[b64_len - 1U] == REV64_PAD) - (b64_u[b64_len - 2U] == REV64_PAD)) {
if (b64_len % 4U != 0U || (i = b64_len / 4U) <= 0U ||
bin_maxlen <
i * 3U - (b64_u[b64_len - 1U] == REV64_PAD) - (b64_u[b64_len - 2U] == REV64_PAD)) {
return NULL;
}
while (i-- > 0U) {
t0 = rev64chars[*b64++];
t1 = rev64chars[*b64++];
t2 = rev64chars[*b64++];
t3 = rev64chars[*b64++];
t = t3 | ((uint32_t) t2 << 6) | ((uint32_t) t1 << 12) |
((uint32_t) t0 << 18);
t0 = rev64chars[*b64_u++];
t1 = rev64chars[*b64_u++];
t2 = rev64chars[*b64_u++];
t3 = rev64chars[*b64_u++];
t = t3 | ((uint32_t) t2 << 6) | ((uint32_t) t1 << 12) | ((uint32_t) t0 << 18);
mask = t0 | t1 | t2 | t3;
if ((mask & (REV64_NONE | REV64_EOT)) != 0U) {
if ((mask & REV64_NONE) != 0U || i > 0U) {
@ -69,8 +95,8 @@ b64_to_bin(unsigned char * const bin, const char *b64,
return bin;
}
char *bin_to_b64(char * const b64, const unsigned char *bin,
size_t b64_maxlen, size_t bin_len)
char *
bin_to_b64(char *const b64, const unsigned char *bin, size_t b64_maxlen, size_t bin_len)
{
#define B64_PAD '='

View file

@ -4,12 +4,10 @@
#include <stddef.h>
unsigned char *b64_to_bin(unsigned char * const bin, const char *b64,
size_t bin_maxlen, size_t b64_len,
size_t * const bin_len_p);
unsigned char *b64_to_bin(unsigned char *const bin, const char *b64, size_t bin_maxlen,
size_t b64_len, size_t *const bin_len_p);
char *bin_to_b64(char * const b64, const unsigned char *bin,
size_t b64_maxlen, size_t bin_len);
char *bin_to_b64(char *const b64, const unsigned char *bin, size_t b64_maxlen, size_t bin_len);
#define B64_MAX_LEN_FROM_BIN_LEN(X) (((X) + 2) / 3 * 4 + 1)
#define BIN_MAX_LEN_FROM_B64_LEN(X) ((X) / 4 * 3)

View file

@ -1,6 +1,6 @@
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
# include <sys/types.h>
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
# include <sys/types.h>
#endif
#include <assert.h>
@ -9,20 +9,20 @@
#include <stdio.h>
#include <string.h>
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
# include <fcntl.h>
# include <poll.h>
# include <termios.h>
# include <unistd.h>
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
# include <fcntl.h>
# include <poll.h>
# include <termios.h>
# include <unistd.h>
#elif defined(_WIN32)
# include <windows.h>
# include <windows.h>
#endif
#include "get_line.h"
#include "helpers.h"
#ifndef TCSAFLUSH
# define TCSAFLUSH 0
# define TCSAFLUSH 0
#endif
#ifndef VERIFY_ONLY
@ -33,7 +33,7 @@ disable_echo(void)
fflush(stdout);
fflush(stderr);
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
{
struct termios p;
@ -43,15 +43,15 @@ disable_echo(void)
p.c_lflag &= ~ECHO;
tcsetattr(0, TCSAFLUSH, &p);
}
# elif defined(_WIN32)
# elif defined(_WIN32)
{
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode = 0;
DWORD mode = 0;
GetConsoleMode(handle, &mode);
SetConsoleMode(handle, mode & ~ENABLE_ECHO_INPUT);
}
# endif
# endif
}
static void
@ -60,7 +60,7 @@ enable_echo(void)
fflush(stdout);
fflush(stderr);
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
{
struct termios p;
@ -70,15 +70,15 @@ enable_echo(void)
p.c_lflag |= ECHO;
tcsetattr(0, TCSAFLUSH, &p);
}
# elif defined(_WIN32)
# elif defined(_WIN32)
{
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode = 0;
DWORD mode = 0;
GetConsoleMode(handle, &mode);
SetConsoleMode(handle, mode | ENABLE_ECHO_INPUT);
}
# endif
# endif
}
int
@ -95,7 +95,7 @@ get_line(char *line, size_t max_len, const char *prompt)
}
trim(line);
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) {
fprintf(stderr, "(empty)\n");
} else {

View file

@ -1,17 +1,24 @@
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
# include <sys/types.h>
# include <sys/fcntl.h>
# include <sys/stat.h>
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
# include <fcntl.h>
# include <sys/stat.h>
# include <sys/types.h>
#elif defined(_WIN32)
# include <direct.h>
#endif
#include <errno.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sodium.h>
#ifdef LIBZODIUM
# include "libzodium/sodium.h"
#else
# include <sodium.h>
#endif
#include "base64.h"
#include "helpers.h"
@ -19,10 +26,9 @@
uint64_t
le64_load(const unsigned char *p)
{
return ((uint64_t)(p[0])) | ((uint64_t)(p[1]) << 8) |
((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
return ((uint64_t) (p[0])) | ((uint64_t) (p[1]) << 8) | ((uint64_t) (p[2]) << 16) |
((uint64_t) (p[3]) << 24) | ((uint64_t) (p[4]) << 32) | ((uint64_t) (p[5]) << 40) |
((uint64_t) (p[6]) << 48) | ((uint64_t) (p[7]) << 56);
}
void
@ -63,6 +69,17 @@ xmalloc(size_t size)
return pnt;
}
char *
xstrdup(const char *str)
{
char *clone;
if ((clone = strdup(str)) == NULL) {
exit_err("strdup()");
}
return clone;
}
void *
xsodium_malloc(size_t size)
{
@ -102,7 +119,6 @@ xfprintf(FILE *fp, const char *format, ...)
va_end(va);
if (fwrite(out, (size_t) len, 1U, fp) != 1U) {
sodium_free(out);
va_end(va);
exit_err("fwrite()");
}
sodium_free(out);
@ -113,8 +129,8 @@ xfprintf(FILE *fp, const char *format, ...)
int
xfput_b64(FILE *fp, const unsigned char *bin, size_t bin_len)
{
const size_t b64_maxlen = (bin_len + 2) * 4 / 3 + 1;
char *b64;
const size_t b64_maxlen = (bin_len + 2) * 4 / 3 + 1;
char *b64;
b64 = xsodium_malloc(b64_maxlen);
if (bin_to_b64(b64, bin, b64_maxlen, bin_len) == NULL) {
@ -139,16 +155,21 @@ xfclose(FILE *fp)
return 0;
}
void
int
trim(char *str)
{
size_t i = strlen(str);
int t = 0;
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;
}
}
return t;
}
const char *
@ -156,25 +177,19 @@ file_basename(const char *file)
{
char *ptr;
if ((ptr = strrchr(file, '/')) != NULL) {
if ((ptr = strrchr(file, DIR_SEP)) != NULL) {
return ptr + 1;
}
#ifdef _WIN32
if ((ptr = strrchr(file, '\\')) != NULL) {
return ptr + 1;
}
#endif
return file;
}
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;
if ((fd = open(file, O_CREAT | O_TRUNC | O_WRONLY,
(mode_t) 0600)) == -1) {
if ((fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, (mode_t) 0600)) == -1) {
return NULL;
}
return fdopen(fd, "w");
@ -182,3 +197,60 @@ fopen_create_useronly(const char *file)
return fopen(file, "w");
#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;
}

View file

@ -2,11 +2,16 @@
#ifndef HELPERS_H
#define HELPERS_H 1
#include <stdio.h>
#include <stdint.h>
#include <stdio.h>
#if !defined(__GNUC__) && !defined(__attribute__)
# define __attribute__(X)
# define __attribute__(X)
#endif
#ifdef _WIN32
# define DIR_SEP '\\'
#else
# define DIR_SEP '/'
#endif
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 * 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);
@ -29,10 +36,14 @@ int xfprintf(FILE *fp, const char *format, ...) __attribute__((format(printf, 2,
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

120
src/libzodium/libzodium.zig Normal file
View 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
View 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
View 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: &lt;file&gt;.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 &lt;pubkey&gt;
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)

File diff suppressed because it is too large Load diff

View file

@ -2,22 +2,25 @@
#ifndef MINISIGN_H
#define MINISIGN_H 1
#define COMMENTMAXBYTES 1024
#define KEYNUMBYTES 8
#define PASSWORDMAXBYTES 1024
#define TRUSTEDCOMMENTMAXBYTES 8192
#define SIGALG "Ed"
#define SIGALG_HASHED "ED"
#define KDFALG "Sc"
#define CHKALG "B2"
#define COMMENT_PREFIX "untrusted comment: "
#define DEFAULT_COMMENT "signature from minisign secret key"
#define SECRETKEY_DEFAULT_COMMENT "minisign encrypted secret key"
#define TRUSTED_COMMENT_PREFIX "trusted comment: "
#define SIG_DEFAULT_PKFILE "minisign.pub";
#define SIG_DEFAULT_SKFILE "minisign.key";
#define SIG_SUFFIX ".minisig"
#define VERSION_STRING "minisign 0.6"
#define COMMENTMAXBYTES 1024
#define KEYNUMBYTES 8
#define PASSWORDMAXBYTES 1024
#define TRUSTEDCOMMENTMAXBYTES 8192
#define SIGALG "Ed"
#define SIGALG_HASHED "ED"
#define KDFALG "Sc"
#define KDFNONE "\0\0"
#define CHKALG "B2"
#define COMMENT_PREFIX "untrusted comment: "
#define DEFAULT_COMMENT "signature from minisign secret key"
#define SECRETKEY_DEFAULT_COMMENT "minisign encrypted secret key"
#define TRUSTED_COMMENT_PREFIX "trusted comment: "
#define SIG_DEFAULT_CONFIG_DIR ".minisign"
#define SIG_DEFAULT_CONFIG_DIR_ENV_VAR "MINISIGN_CONFIG_DIR"
#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_ {
unsigned char keynum[KEYNUMBYTES];
@ -37,12 +40,12 @@ typedef struct SeckeyStruct_ {
unsigned char kdf_salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
unsigned char kdf_opslimit_le[8];
unsigned char kdf_memlimit_le[8];
KeynumSK keynum_sk;
KeynumSK keynum_sk;
} SeckeyStruct;
typedef struct PubkeyStruct_ {
unsigned char sig_alg[2];
KeynumPK keynum_pk;
KeynumPK keynum_pk;
} PubkeyStruct;
typedef struct SigStruct_ {
@ -55,7 +58,9 @@ typedef enum Action_ {
ACTION_NONE,
ACTION_GENERATE,
ACTION_SIGN,
ACTION_VERIFY
ACTION_VERIFY,
ACTION_RECREATE_PK,
ACTION_UPDATE_PASSWORD
} Action;
#endif