Compare commits

..

17 commits

Author SHA1 Message Date
aa96303d43
chore(deps): update module golang.org/x/crypto to v0.36.0 (#5)
Reviewed-on: #5
Co-authored-by: renovate[bot] <renovate@rgst.io>
Co-committed-by: renovate[bot] <renovate@rgst.io>
2025-03-06 17:33:08 +00:00
8d3686eb14
chore: add mise fix yaml.v3 2025-02-27 21:07:47 -08:00
6b2e5526b2
Update module gopkg.in/yaml.v2 to v3 (#4)
Reviewed-on: #4
Co-authored-by: renovate[bot] <renovate@rgst.io>
Co-committed-by: renovate[bot] <renovate@rgst.io>
2025-02-28 05:05:32 +00:00
d128cfa7ce
Update module github.com/opencoff/go-fio to v0.5.14 (#2)
Reviewed-on: #2
Co-authored-by: renovate[bot] <renovate@rgst.io>
Co-committed-by: renovate[bot] <renovate@rgst.io>
2025-02-28 04:37:29 +00:00
3f6b9cd2af
Update module gopkg.in/yaml.v2 to v3 (#3)
Reviewed-on: #3
Co-authored-by: renovate[bot] <renovate@rgst.io>
Co-committed-by: renovate[bot] <renovate@rgst.io>
2025-02-28 04:37:18 +00:00
6a16789886 Configure Renovate (#1)
Co-authored-by: renovate[bot] <renovate@rgst.io>
Co-committed-by: renovate[bot] <renovate@rgst.io>
2025-02-28 04:03:09 +00:00
1823aaa5e0
add back from bytes 2025-02-25 11:28:39 -08:00
810aa02bdd
update import path and deps 2025-02-25 11:08:20 -08:00
Sudhi Herle
1786734c0a Updated dependencies; updated ABI compat 2024-12-18 19:13:24 -08:00
Sudhi Herle
d47a4596ef Remove build timestamp 2024-08-30 09:37:59 -07:00
Sudhi Herle
fc94d7cd7d Updated build script to make reproducible builds
* fixed mk-rel.sh; put all release artifiacts in releases/ dir
* updated vt-proto dependencies
2024-08-29 09:42:16 -07:00
Sudhi Herle
2e6d92c753 Updated build script to parse VCS version# correctly 2024-04-09 14:33:38 -07:00
Sudhi Herle
5c6152b4ed Updated to latest safefile lib - fixed up caller sites. 2024-03-10 12:48:16 -07:00
Sudhi Herle
e3053142f5 Teach sigtool verify to use public key as a command line string (in lieu of a file).
- Reorganized the code a bit and split each of sigtool's
  commands into a separate file.
- Added extra tests to validate verify's new capabilities
- Updated README
2024-01-13 10:34:24 -08:00
Sudhi Herle
d49f732c71 Updated go-mmap; added release script 2024-01-12 13:37:20 -08:00
Sudhi Herle
15053202a1 Updated sigtool to use portable mmap lib 2024-01-07 11:55:21 -08:00
Sudhi Herle
c5400a6b18 Updated x/crypto (security fix) 2023-12-19 10:34:46 -08:00
23 changed files with 808 additions and 637 deletions

2
.gitignore vendored
View file

@ -31,4 +31,4 @@ sigtool
*.pub *.pub
*.key *.key
*.sig *.sig
releases/*

2
.mise.toml Normal file
View file

@ -0,0 +1,2 @@
[tools]
golang = "1.24"

View file

@ -40,7 +40,7 @@ You need two things:
Next, build sigtool: Next, build sigtool:
git clone https://github.com/opencoff/sigtool git clone https://git.rgst.io/homelab/sigtool/v3
cd sigtool cd sigtool
make make
@ -101,6 +101,10 @@ e.g., to verify the signature of *archive.tar.gz* against
sigtool verify /tmp/testkey.pub archive.sig archive.tar.gz sigtool verify /tmp/testkey.pub archive.sig archive.tar.gz
You can also pass a public key as a string (instead of a file):
sigtool verify iF84Dymq/bAEnUMK6DRIHWAQDRD8FwDDDfsgFfzdjWM= archive.sig archive.tar.gz
Note that signing and verifying can also work with OpenSSH ed25519 Note that signing and verifying can also work with OpenSSH ed25519
keys. keys.

109
build
View file

@ -13,12 +13,13 @@
# #
# License: GPLv2 # License: GPLv2
# #
Progs=".:sigtool" Progs="src:sigtool"
# Relative path to protobuf sources # Relative path to protobuf sources
# e.g. src/foo/a.proto # e.g. src/foo/a.proto
Protobufs="internal/pb/hdr.proto" Protobufs="internal/pb/hdr.proto"
#set -x
# -- DO NOT CHANGE ANYTHING AFTER THIS -- # -- DO NOT CHANGE ANYTHING AFTER THIS --
@ -28,8 +29,10 @@ PWD=`pwd`
Static=0 Static=0
Dryrun=0 Dryrun=0
Prodver="" Prodver=""
Repover=""
Verbose=0 Verbose=0
Go=`which go` Go=`which go`
Bindir=$PWD/bin
die() { die() {
echo "$Z: $@" 1>&2 echo "$Z: $@" 1>&2
@ -47,18 +50,56 @@ case $BASH_VERSION in
;; ;;
esac esac
getvcs_version() {
local rev=
local prodv=
local git=`which git`
local hg=`which hg`
if [ -n "$git" ]; then
local xrev=$(git describe --always --dirty --long --abbrev=12) || exit 1
rev="git:$xrev"
prodv=$(git tag --list | sort -V | tail -1)
elif [ -n "$hg" ]; then
local xrev=$(hg id --id) || exit 1
local brev=${xrev%+}
if [ "$brev" != "$xrev" ]; then
rev="hg:${brev}-dirty"
else
rev="hg:${brev}"
fi
prodv=$(hg log -r "branch(stable) and tag()" -T "{tags}\n" | sort -V | tail -1)
else
warn "no git or hg found; can't get VCS info"
rev="UNKNOWN-VER"
fi
[ -n "$Prodver" ] && prodv=$Prodver
echo "$rev $prodv"
return 0
}
read -r Repover Prodver <<< $(getvcs_version)
usage() { usage() {
declare -a progv=($Progs)
declare n=${#progv[@]}
declare pstr=
for ((i=0; i < n; i++)); do
local ent=${progv[$i]}
local dir=${ent%%:*}
local tool=${ent##*:}
pstr=$(printf "$pstr\n\t%s $Prodver $Repover (from ./%s)" $tool $dir)
done
cat <<EOF cat <<EOF
$0 - A Go production build tool that adds git-repository information, $0 - A Go production build tool that adds git-repository information,
product version, build-timestamp etc. It supports cross-compilation, product version, build-timestamp etc. It supports cross-compilation,
static linking and generating protobuf output. static linking and generating protobuf output.
If needed, it uses the gogo-slick protobuf compiler [github.com/gogo/protobuf].
Build output is in bin/\$OS-\$CPU for a given OS, CPU combination. Build output is in bin/\$OS-\$CPU for a given OS, CPU combination.
Usage: $0 Usage: $0
@ -67,13 +108,14 @@ Usage: $0
Where OS-ARCH denotes one of the valid OS, ARCH combinations supported by 'go'. Where OS-ARCH denotes one of the valid OS, ARCH combinations supported by 'go'.
And, PROGS is one or more go programs. And, PROGS is one or more go programs.
With no arguments, $0 builds: $Progs (source in ./src/) With no arguments, $0 builds: $pstr
The repository's latest tag is used as the default version of the software being The repository's latest tag is used as the default version of the software being
built. built. The current repository version is $Repover.
Options: Options:
-h, --help Show this help message and quit -h, --help Show this help message and quit
-b D, --bindir=D Put the binaries in the directory 'D' [$Bindir]
-s, --static Build a statically linked binary [False] -s, --static Build a statically linked binary [False]
-V N, --version=N Use 'N' as the product version string [$Prodver] -V N, --version=N Use 'N' as the product version string [$Prodver]
-a X, --arch=X Cross compile for OS-CPU 'X' [$hostos-$hostcpu] -a X, --arch=X Cross compile for OS-CPU 'X' [$hostos-$hostcpu]
@ -156,6 +198,14 @@ do
ac_prev=Arch ac_prev=Arch
;; ;;
-b|--bindir)
ac_prev=Bindir
;;
--bindir=*)
Bindir=$ac_optarg
;;
--version=*) --version=*)
Prodver=$ac_optarg Prodver=$ac_optarg
;; ;;
@ -280,6 +330,7 @@ buildproto() {
return 0 return 0
} }
# the rest has to execute in the context of main shell (not funcs) # the rest has to execute in the context of main shell (not funcs)
hostos=$($Go env GOHOSTOS) || exit 1 hostos=$($Go env GOHOSTOS) || exit 1
@ -336,36 +387,13 @@ fi
# This is where build outputs go # This is where build outputs go
Bindir=$PWD/bin/$cross Outdir=$Bindir/$cross
Hostbindir=$PWD/bin/$hostos-$hostcpu Hostbindir=$Bindir/$hostos-$hostcpu
export PATH=$Hostbindir:$PATH export PATH=$Hostbindir:$PATH
[ -d $Bindir ] || mkdir -p $Bindir [ -d $Outdir ] || mkdir -p $Outdir
[ -d $Hostbindir ] || mkdir -p $Hostbindir [ -d $Hostbindir ] || mkdir -p $Hostbindir
# Get git/hg version info for the build
if [ -d "./.hg" ]; then
xrev=$(hg id --id) || exit 1
brev=${xrev%+}
if [ "$brev" != "$xrev" ]; then
rev="hg:${brev}-dirty"
else
rev="hg:${brev}"
fi
if [ -z "$Prodver" ]; then
Prodver=$(hg log -r "branch(stable) and tag()" -T "{tags}\n" | tail -1)
fi
elif [ -d "./.git" ]; then
xrev=$(git describe --always --dirty --long --abbrev=12) || exit 1
rev="git:$xrev"
if [ -z "$Prodver" ]; then
Prodver=$(git tag --list | tail -1)
fi
else
rev="UNKNOWN-VER"
echo "$0: Can't find version info" 1>&2
fi
# Do Protobufs if needed # Do Protobufs if needed
if [ -n "$Protobufs" ]; then if [ -n "$Protobufs" ]; then
@ -374,10 +402,10 @@ if [ -n "$Protobufs" ]; then
set -e set -e
fi fi
repover="main.RepoVersion=$rev" # Get git/hg version info for the build
repover="main.RepoVersion=$Repover"
prodver="main.ProductVersion=$Prodver" prodver="main.ProductVersion=$Prodver"
date="main.Buildtime=`date -u '+%Y-%m-%dT%H:%M.%SZ'`" ldflags="-ldflags \"-X $repover -X $prodver $ldflags -buildid=\""
ldflags="-ldflags \"-X $repover -X $prodver -X $date $ldflags\""
vflag="" vflag=""
[ $Verbose -gt 0 ] && vflag="-v" [ $Verbose -gt 0 ] && vflag="-v"
@ -406,7 +434,9 @@ case $Tool in
all="$@" all="$@"
fi fi
echo "Building $Prodver ($rev), $cross $msg .." [ -z "$all" ] && die "No programs specified. Try '$Z --help'"
echo "Building $Prodver ($Repover), $cross $msg .."
for p in $all; do for p in $all; do
if echo $p | grep -q ':' ; then if echo $p | grep -q ':' ; then
@ -416,8 +446,15 @@ case $Tool in
out=$p out=$p
dir=$p dir=$p
fi fi
# Add .exe suffix to out if needed
if [ "$GOOS" = "windows" ]; then
base=${out%%.exe}
out="${base}.exe"
fi
echo " $dir: $out .. " echo " $dir: $out .. "
$e eval $Go build $vflag -o $Bindir/$out $isuffix "$ldflags" ./$dir || exit 1 $e eval $Go build $vflag -trimpath -o $Outdir/$out $isuffix "$ldflags" ./$dir || exit 1
done done
;; ;;
esac esac

27
go.mod
View file

@ -1,18 +1,25 @@
module github.com/opencoff/sigtool module git.rgst.io/homelab/sigtool/v3
go 1.21 go 1.24.0
require ( require (
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a
github.com/opencoff/go-utils v0.7.2 github.com/opencoff/go-fio v0.5.14
github.com/opencoff/pflag v1.0.6-sh1 github.com/opencoff/go-mmap v0.1.5
golang.org/x/crypto v0.15.0 github.com/opencoff/go-utils v1.0.2
google.golang.org/protobuf v1.31.0 github.com/opencoff/pflag v1.0.7
gopkg.in/yaml.v2 v2.4.0 github.com/planetscale/vtprotobuf v0.6.0
golang.org/x/crypto v0.36.0
google.golang.org/protobuf v1.36.5
gopkg.in/yaml.v3 v3.0.1
) )
require ( require (
golang.org/x/sys v0.14.0 // indirect github.com/pkg/xattr v0.4.10 // indirect
golang.org/x/term v0.14.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect golang.org/x/sys v0.31.0 // indirect
golang.org/x/term v0.30.0 // indirect
) )
//replace github.com/opencoff/go-mmap => ../go-mmap
//replace github.com/opencoff/go-utils => ../go-utils

50
go.sum
View file

@ -1,25 +1,39 @@
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a h1:saTgr5tMLFnmy/yg3qDTft4rE5DY2uJ/cCxCe3q0XTU= github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a h1:saTgr5tMLFnmy/yg3qDTft4rE5DY2uJ/cCxCe3q0XTU=
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a/go.mod h1:Bw9BbhOJVNR+t0jCqx2GC6zv0TGBsShs56Y3gfSCvl0= github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a/go.mod h1:Bw9BbhOJVNR+t0jCqx2GC6zv0TGBsShs56Y3gfSCvl0=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/opencoff/go-utils v0.7.2 h1:FK250pZ9UH+zdp1DlGyRARq7nULHEIkTVbpITTwwVXk= github.com/opencoff/go-fio v0.5.14 h1:PGi4XLLO4RSuc3m5exY0G2vweov6w3UThhScehBfM8c=
github.com/opencoff/go-utils v0.7.2/go.mod h1:8hMC3uc+N0wUMxpmW2yzM6FuhlCCxRST1Wj+cYntqFA= github.com/opencoff/go-fio v0.5.14/go.mod h1:hoSySYpavRnfQUsxzUgadk31kYiNQhMDvA2MObsXKf8=
github.com/opencoff/pflag v1.0.6-sh1 h1:6RO8GgnpH928yu6earGDD01FnFT//bDJ1hCovcVVqY4= github.com/opencoff/go-mmap v0.1.5 h1:RKPtevC4mOW5bi9skBPPo4nFTIH4lVWAL20Tff+FjLg=
github.com/opencoff/pflag v1.0.6-sh1/go.mod h1:2bXtpAD/5h/2LarkbsRwiUxqnvB1nZBzn9Xjad1P41A= github.com/opencoff/go-mmap v0.1.5/go.mod h1:y/6Jk/tDUc00k3oSQpiJX++20Nw7xFSlc5kLkhGnRXw=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= github.com/opencoff/go-utils v1.0.2 h1:BANRL8ZxgHpuo8gQBAzT3M9Im3aNFhaWW28jhc86LNs=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= github.com/opencoff/go-utils v1.0.2/go.mod h1:eZkEVQVzNfuE8uGepyhscMsqcXq7liGbBHYYwgYaoy8=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= github.com/opencoff/pflag v1.0.7 h1:o5cQIuX75bDcdJ6AXl68gzpA72a3CJ2MPStaMnEuwi4=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= github.com/opencoff/pflag v1.0.7/go.mod h1:2bXtpAD/5h/2LarkbsRwiUxqnvB1nZBzn9Xjad1P41A=
golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= github.com/pkg/xattr v0.4.10 h1:Qe0mtiNFHQZ296vRgUjRCoPHPqH7VdTOrZx3g0T+pGA=
golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= github.com/pkg/xattr v0.4.10/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU=
github.com/planetscale/vtprotobuf v0.6.0 h1:nBeETjudeJ5ZgBHUz1fVHvbqUKnYOXNhsIEabROxmNA=
github.com/planetscale/vtprotobuf v0.6.0/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.28.1 // protoc-gen-go v1.32.0
// protoc v3.21.12 // protoc v3.21.12
// source: internal/pb/hdr.proto // source: internal/pb/hdr.proto

View file

@ -1,14 +1,14 @@
// Code generated by protoc-gen-go-vtproto. DO NOT EDIT. // Code generated by protoc-gen-go-vtproto. DO NOT EDIT.
// protoc-gen-go-vtproto version: v0.5.0 // protoc-gen-go-vtproto version: v0.6.0
// source: internal/pb/hdr.proto // source: internal/pb/hdr.proto
package pb package pb
import ( import (
fmt "fmt" fmt "fmt"
protohelpers "github.com/planetscale/vtprotobuf/protohelpers"
protoimpl "google.golang.org/protobuf/runtime/protoimpl" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
io "io" io "io"
bits "math/bits"
) )
const ( const (
@ -55,7 +55,7 @@ func (m *Header) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
return 0, err return 0, err
} }
i -= size i -= size
i = encodeVarint(dAtA, i, uint64(size)) i = protohelpers.EncodeVarint(dAtA, i, uint64(size))
i-- i--
dAtA[i] = 0x2a dAtA[i] = 0x2a
} }
@ -63,26 +63,26 @@ func (m *Header) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if len(m.Sender) > 0 { if len(m.Sender) > 0 {
i -= len(m.Sender) i -= len(m.Sender)
copy(dAtA[i:], m.Sender) copy(dAtA[i:], m.Sender)
i = encodeVarint(dAtA, i, uint64(len(m.Sender))) i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Sender)))
i-- i--
dAtA[i] = 0x22 dAtA[i] = 0x22
} }
if len(m.Pk) > 0 { if len(m.Pk) > 0 {
i -= len(m.Pk) i -= len(m.Pk)
copy(dAtA[i:], m.Pk) copy(dAtA[i:], m.Pk)
i = encodeVarint(dAtA, i, uint64(len(m.Pk))) i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Pk)))
i-- i--
dAtA[i] = 0x1a dAtA[i] = 0x1a
} }
if len(m.Salt) > 0 { if len(m.Salt) > 0 {
i -= len(m.Salt) i -= len(m.Salt)
copy(dAtA[i:], m.Salt) copy(dAtA[i:], m.Salt)
i = encodeVarint(dAtA, i, uint64(len(m.Salt))) i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Salt)))
i-- i--
dAtA[i] = 0x12 dAtA[i] = 0x12
} }
if m.ChunkSize != 0 { if m.ChunkSize != 0 {
i = encodeVarint(dAtA, i, uint64(m.ChunkSize)) i = protohelpers.EncodeVarint(dAtA, i, uint64(m.ChunkSize))
i-- i--
dAtA[i] = 0x8 dAtA[i] = 0x8
} }
@ -122,31 +122,20 @@ func (m *WrappedKey) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if len(m.Nonce) > 0 { if len(m.Nonce) > 0 {
i -= len(m.Nonce) i -= len(m.Nonce)
copy(dAtA[i:], m.Nonce) copy(dAtA[i:], m.Nonce)
i = encodeVarint(dAtA, i, uint64(len(m.Nonce))) i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Nonce)))
i-- i--
dAtA[i] = 0x12 dAtA[i] = 0x12
} }
if len(m.DKey) > 0 { if len(m.DKey) > 0 {
i -= len(m.DKey) i -= len(m.DKey)
copy(dAtA[i:], m.DKey) copy(dAtA[i:], m.DKey)
i = encodeVarint(dAtA, i, uint64(len(m.DKey))) i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.DKey)))
i-- i--
dAtA[i] = 0xa dAtA[i] = 0xa
} }
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func encodeVarint(dAtA []byte, offset int, v uint64) int {
offset -= sov(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *Header) SizeVT() (n int) { func (m *Header) SizeVT() (n int) {
if m == nil { if m == nil {
return 0 return 0
@ -154,24 +143,24 @@ func (m *Header) SizeVT() (n int) {
var l int var l int
_ = l _ = l
if m.ChunkSize != 0 { if m.ChunkSize != 0 {
n += 1 + sov(uint64(m.ChunkSize)) n += 1 + protohelpers.SizeOfVarint(uint64(m.ChunkSize))
} }
l = len(m.Salt) l = len(m.Salt)
if l > 0 { if l > 0 {
n += 1 + l + sov(uint64(l)) n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
} }
l = len(m.Pk) l = len(m.Pk)
if l > 0 { if l > 0 {
n += 1 + l + sov(uint64(l)) n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
} }
l = len(m.Sender) l = len(m.Sender)
if l > 0 { if l > 0 {
n += 1 + l + sov(uint64(l)) n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
} }
if len(m.Keys) > 0 { if len(m.Keys) > 0 {
for _, e := range m.Keys { for _, e := range m.Keys {
l = e.SizeVT() l = e.SizeVT()
n += 1 + l + sov(uint64(l)) n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
} }
} }
n += len(m.unknownFields) n += len(m.unknownFields)
@ -186,22 +175,16 @@ func (m *WrappedKey) SizeVT() (n int) {
_ = l _ = l
l = len(m.DKey) l = len(m.DKey)
if l > 0 { if l > 0 {
n += 1 + l + sov(uint64(l)) n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
} }
l = len(m.Nonce) l = len(m.Nonce)
if l > 0 { if l > 0 {
n += 1 + l + sov(uint64(l)) n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
} }
n += len(m.unknownFields) n += len(m.unknownFields)
return n return n
} }
func sov(x uint64) (n int) {
return (bits.Len64(x|1) + 6) / 7
}
func soz(x uint64) (n int) {
return sov(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Header) UnmarshalVT(dAtA []byte) error { func (m *Header) UnmarshalVT(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
@ -210,7 +193,7 @@ func (m *Header) UnmarshalVT(dAtA []byte) error {
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflow return protohelpers.ErrIntOverflow
} }
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -238,7 +221,7 @@ func (m *Header) UnmarshalVT(dAtA []byte) error {
m.ChunkSize = 0 m.ChunkSize = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflow return protohelpers.ErrIntOverflow
} }
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -257,7 +240,7 @@ func (m *Header) UnmarshalVT(dAtA []byte) error {
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflow return protohelpers.ErrIntOverflow
} }
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -270,11 +253,11 @@ func (m *Header) UnmarshalVT(dAtA []byte) error {
} }
} }
if byteLen < 0 { if byteLen < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
postIndex := iNdEx + byteLen postIndex := iNdEx + byteLen
if postIndex < 0 { if postIndex < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -291,7 +274,7 @@ func (m *Header) UnmarshalVT(dAtA []byte) error {
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflow return protohelpers.ErrIntOverflow
} }
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -304,11 +287,11 @@ func (m *Header) UnmarshalVT(dAtA []byte) error {
} }
} }
if byteLen < 0 { if byteLen < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
postIndex := iNdEx + byteLen postIndex := iNdEx + byteLen
if postIndex < 0 { if postIndex < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -325,7 +308,7 @@ func (m *Header) UnmarshalVT(dAtA []byte) error {
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflow return protohelpers.ErrIntOverflow
} }
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -338,11 +321,11 @@ func (m *Header) UnmarshalVT(dAtA []byte) error {
} }
} }
if byteLen < 0 { if byteLen < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
postIndex := iNdEx + byteLen postIndex := iNdEx + byteLen
if postIndex < 0 { if postIndex < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -359,7 +342,7 @@ func (m *Header) UnmarshalVT(dAtA []byte) error {
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflow return protohelpers.ErrIntOverflow
} }
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -372,11 +355,11 @@ func (m *Header) UnmarshalVT(dAtA []byte) error {
} }
} }
if msglen < 0 { if msglen < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
postIndex := iNdEx + msglen postIndex := iNdEx + msglen
if postIndex < 0 { if postIndex < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -388,12 +371,12 @@ func (m *Header) UnmarshalVT(dAtA []byte) error {
iNdEx = postIndex iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:]) skippy, err := protohelpers.Skip(dAtA[iNdEx:])
if err != nil { if err != nil {
return err return err
} }
if (skippy < 0) || (iNdEx+skippy) < 0 { if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
if (iNdEx + skippy) > l { if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -416,7 +399,7 @@ func (m *WrappedKey) UnmarshalVT(dAtA []byte) error {
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflow return protohelpers.ErrIntOverflow
} }
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -444,7 +427,7 @@ func (m *WrappedKey) UnmarshalVT(dAtA []byte) error {
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflow return protohelpers.ErrIntOverflow
} }
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -457,11 +440,11 @@ func (m *WrappedKey) UnmarshalVT(dAtA []byte) error {
} }
} }
if byteLen < 0 { if byteLen < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
postIndex := iNdEx + byteLen postIndex := iNdEx + byteLen
if postIndex < 0 { if postIndex < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -478,7 +461,7 @@ func (m *WrappedKey) UnmarshalVT(dAtA []byte) error {
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflow return protohelpers.ErrIntOverflow
} }
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -491,11 +474,11 @@ func (m *WrappedKey) UnmarshalVT(dAtA []byte) error {
} }
} }
if byteLen < 0 { if byteLen < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
postIndex := iNdEx + byteLen postIndex := iNdEx + byteLen
if postIndex < 0 { if postIndex < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -507,12 +490,12 @@ func (m *WrappedKey) UnmarshalVT(dAtA []byte) error {
iNdEx = postIndex iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:]) skippy, err := protohelpers.Skip(dAtA[iNdEx:])
if err != nil { if err != nil {
return err return err
} }
if (skippy < 0) || (iNdEx+skippy) < 0 { if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength return protohelpers.ErrInvalidLength
} }
if (iNdEx + skippy) > l { if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
@ -527,88 +510,3 @@ func (m *WrappedKey) UnmarshalVT(dAtA []byte) error {
} }
return nil return nil
} }
func skip(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLength
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroup
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLength
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflow = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group")
)

54
mk-rel.sh Executable file
View file

@ -0,0 +1,54 @@
#! /usr/bin/env bash
Z=`basename $0`
die() {
echo "$Z: $@" 1>&2
exit 1
}
warn() {
echo "$Z: $@" 1>&2
}
case $BASH_VERSION in
4.*|5.*) ;;
*) die "I need bash 4.x to run!"
;;
esac
Rel=$PWD/releases
Bindir=$Rel/bin
mkdir -p $Bindir || die "can't make $Bindir"
pkgit() {
local os=$1
local cpu=$2
local rev=$3
local arch="$os-$cpu"
local tgz="$Rel/sigtool-${rev}_${arch}.tar.gz"
local bindir=$Bindir/$arch
local bin=sigtool
if [ "$os" = "windows" ]; then
bin=${bin}.exe
fi
./build -V $rev -b $Bindir -s -a $arch || die "can't build $arch"
(cd $bindir && tar cf - $bin) | gzip -9 > $tgz || die "can't tar $tgz"
}
xrev=$(git describe --always --dirty --abbrev=12) || exit 1
if echo $xrev | grep -q dirty; then
die "won't build releases; repo dirty!"
true
fi
os="linux windows openbsd darwin"
arch="amd64 arm64"
for xx in $os; do
for yy in $arch; do
pkgit $xx $yy $xrev
done
done

3
renovate.json Normal file
View file

@ -0,0 +1,3 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
}

View file

@ -1,10 +1,10 @@
[![GoDoc](https://godoc.org/github.com/opencoff/sigtool/sign?status.svg)](https://godoc.org/github.com/opencoff/sigtool/sign) [![GoDoc](https://godoc.org/git.rgst.io/homelab/sigtool/v3/sign?status.svg)](https://godoc.org/git.rgst.io/homelab/sigtool/v3/sign)
# sigtool/sign - Ed25519 signature calculation and verification # sigtool/sign - Ed25519 signature calculation and verification
This is a small library that makes it easier to create and serialize Ed25519 keys, and sign, This is a small library that makes it easier to create and serialize Ed25519 keys, and sign,
verify files using those keys. The library uses mmap(2) to read and process very large files. verify files using those keys. The library uses mmap(2) to read and process very large files.
The companion program [sigtool](https://github.com/opencoff/sigtool) uses this library. The companion program [sigtool](https://git.rgst.io/homelab/sigtool/v3) uses this library.
## License ## License
GPL v2.0 GPL v2.0

View file

@ -70,13 +70,14 @@ import (
"crypto/subtle" "crypto/subtle"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/hkdf"
"hash" "hash"
"io" "io"
"os" "os"
"github.com/opencoff/sigtool/internal/pb" "golang.org/x/crypto/curve25519"
"golang.org/x/crypto/hkdf"
"git.rgst.io/homelab/sigtool/v3/internal/pb"
) )
// Encryption chunk size = 4MB // Encryption chunk size = 4MB

67
sign/iomisc.go Normal file
View file

@ -0,0 +1,67 @@
// iomisc.go -- misc i/o functions
//
// (c) 2016 Sudhi Herle <sudhi@herle.net>
//
// Licensing Terms: GPLv2
//
// If you need a commercial license for this work, please contact
// the author.
//
// This software does not come with any express or implied
// warranty; it is provided "as is". No claim is made to its
// suitability for any purpose.
package sign
import (
"encoding/binary"
"fmt"
"github.com/opencoff/go-fio"
"github.com/opencoff/go-mmap"
"hash"
"os"
)
// Simple function to reliably write data to a file.
// Does MORE than ioutil.WriteFile() - in that it doesn't trash the
// existing file with an incomplete write.
func writeFile(fn string, b []byte, ovwrite bool, mode uint32) error {
var opts uint32
if ovwrite {
opts |= fio.OPT_OVERWRITE
}
sf, err := fio.NewSafeFile(fn, opts, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(mode))
if err != nil {
return err
}
defer sf.Abort()
if _, err = sf.Write(b); err != nil {
return err
}
return sf.Close()
}
// Generate file checksum out of hash function h
func fileCksum(fn string, h hash.Hash) ([]byte, error) {
fd, err := os.Open(fn)
if err != nil {
return nil, fmt.Errorf("can't open %s: %s", fn, err)
}
defer fd.Close()
sz, err := mmap.Reader(fd, func(b []byte) error {
h.Write(b)
return nil
})
if err != nil {
return nil, err
}
var b [8]byte
binary.BigEndian.PutUint64(b[:], uint64(sz))
h.Write(b[:])
return h.Sum(nil)[:], nil
}

View file

@ -25,18 +25,14 @@ import (
"crypto/sha256" "crypto/sha256"
"crypto/sha512" "crypto/sha512"
"encoding/base64" "encoding/base64"
"encoding/binary"
"fmt" "fmt"
"hash"
"io/ioutil" "io/ioutil"
"math/big" "math/big"
"os"
Ed "crypto/ed25519" Ed "crypto/ed25519"
"golang.org/x/crypto/scrypt"
"gopkg.in/yaml.v2"
"github.com/opencoff/go-utils" "golang.org/x/crypto/scrypt"
"gopkg.in/yaml.v3"
) )
// Private Ed25519 key // Private Ed25519 key
@ -184,14 +180,14 @@ func makePrivateKeyFromBytes(sk *PrivateKey, buf []byte) error {
return nil return nil
} }
/*
// Make a private key from 64-bytes of extended Ed25519 key // Make a private key from 64-bytes of extended Ed25519 key
func PrivateKeyFromBytes(buf []byte) (*PrivateKey, error) { func PrivateKeyFromBytes(buf []byte) (*PrivateKey, error) {
var sk PrivateKey var sk PrivateKey
if err := makePrivateKeyFromBytes(&sk, buf); err != nil {
return makePrivateKeyFromBytes(&sk, buf) return nil, err
}
return &sk, nil
} }
*/
// Given a secret key, return the corresponding Public Key // Given a secret key, return the corresponding Public Key
func (sk *PrivateKey) PublicKey() *PublicKey { func (sk *PrivateKey) PublicKey() *PublicKey {
@ -374,6 +370,29 @@ func MakePublicKey(yml []byte) (*PublicKey, error) {
return &pk, nil return &pk, nil
} }
// Make a public key from a string
func MakePublicKeyFromString(s string) (*PublicKey, error) {
// first try to decode it as a openssh key
if pk2, err := parseEncPubKey([]byte(s), "command-line-pk"); err == nil {
return pk2, nil
}
// Now try to decode as an sigtool key
b64 := base64.StdEncoding.DecodeString
pkb, err := b64(s)
if err != nil {
return nil, err
}
var pk PublicKey
err = makePublicKeyFromBytes(&pk, pkb)
if err != nil {
return nil, err
}
return &pk, nil
}
func makePublicKeyFromBytes(pk *PublicKey, b []byte) error { func makePublicKeyFromBytes(pk *PublicKey, b []byte) error {
if len(b) != 32 { if len(b) != 32 {
return fmt.Errorf("public key is malformed (len %d!)", len(b)) return fmt.Errorf("public key is malformed (len %d!)", len(b))
@ -386,14 +405,14 @@ func makePublicKeyFromBytes(pk *PublicKey, b []byte) error {
return nil return nil
} }
/*
// Make a public key from a byte string // Make a public key from a byte string
func PublicKeyFromBytes(b []byte) (*PublicKey, error) { func PublicKeyFromBytes(b []byte) (*PublicKey, error) {
var pk PublicKey var pk PublicKey
if err := makePublicKeyFromBytes(&pk, b); err != nil {
makePublicKeyFromBytes(&pk, b) return nil, err
}
return &pk, nil
} }
*/
// Serialize a PublicKey into file 'fn' with a human readable 'comment'. // Serialize a PublicKey into file 'fn' with a human readable 'comment'.
// If 'ovwrite' is true, overwrite the file if it exists. // If 'ovwrite' is true, overwrite the file if it exists.
@ -499,41 +518,6 @@ func (pk *PublicKey) UnmarshalBinary(yml []byte) error {
// -- Internal Utility Functions -- // -- Internal Utility Functions --
// Simple function to reliably write data to a file.
// Does MORE than ioutil.WriteFile() - in that it doesn't trash the
// existing file with an incomplete write.
func writeFile(fn string, b []byte, ovwrite bool, mode uint32) error {
sf, err := utils.NewSafeFile(fn, ovwrite, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(mode))
if err != nil {
return err
}
defer sf.Abort() // always cleanup on error
sf.Write(b)
return sf.Close()
}
// Generate file checksum out of hash function h
func fileCksum(fn string, h hash.Hash) ([]byte, error) {
fd, err := os.Open(fn)
if err != nil {
return nil, fmt.Errorf("can't open %s: %s", fn, err)
}
defer fd.Close()
sz, err := utils.MmapReader(fd, 0, 0, h)
if err != nil {
return nil, err
}
var b [8]byte
binary.BigEndian.PutUint64(b[:], uint64(sz))
h.Write(b[:])
return h.Sum(nil)[:], nil
}
func clamp(k []byte) []byte { func clamp(k []byte) []byte {
k[0] &= 248 k[0] &= 248
k[31] &= 127 k[31] &= 127

View file

@ -27,7 +27,8 @@ import (
"io/ioutil" "io/ioutil"
Ed "crypto/ed25519" Ed "crypto/ed25519"
"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
) )
// An Ed25519 Signature // An Ed25519 Signature

View file

@ -1,360 +0,0 @@
// sigtool.go -- Tool to generate, manage Ed25519 keys and
// signatures.
//
// (c) 2016 Sudhi Herle <sudhi@herle.net>
//
// Licensing Terms: GPLv2
//
// If you need a commercial license for this work, please contact
// the author.
//
// This software does not come with any express or implied
// warranty; it is provided "as is". No claim is made to its
// suitability for any purpose.
package main
import (
"fmt"
"io"
"os"
"path"
"strings"
"github.com/opencoff/go-utils"
flag "github.com/opencoff/pflag"
"github.com/opencoff/sigtool/sign"
)
var Z string = path.Base(os.Args[0])
func main() {
var ver, help, debug bool
mf := flag.NewFlagSet(Z, flag.ExitOnError)
mf.SetInterspersed(false)
mf.BoolVarP(&ver, "version", "v", false, "Show version info and exit")
mf.BoolVarP(&help, "help", "h", false, "Show help info exit")
mf.BoolVarP(&debug, "debug", "", false, "Enable debug mode")
mf.Parse(os.Args[1:])
if ver {
fmt.Printf("%s - %s [%s; %s]\n", Z, ProductVersion, RepoVersion, Buildtime)
os.Exit(0)
}
if help {
usage(0)
}
args := mf.Args()
if len(args) < 1 {
Die("Insufficient arguments. Try '%s -h'", Z)
}
cmds := map[string]func(args []string){
"generate": gen,
"sign": signify,
"verify": verify,
"encrypt": encrypt,
"decrypt": decrypt,
"help": func(_ []string) {
usage(0)
},
}
words := make([]string, 0, len(cmds))
for k := range cmds {
words = append(words, k)
}
ab := utils.Abbrev(words)
canon, ok := ab[strings.ToLower(args[0])]
if !ok {
Die("Unknown command %s", args[0])
}
cmd := cmds[canon]
if cmd == nil {
Die("can't map command %s", canon)
}
if debug {
sign.Debug(1)
}
cmd(args[1:])
// always call Exit so that at-exit handlers are called.
Exit(0)
}
// Run the generate command
func gen(args []string) {
var nopw, help, force bool
var comment string
var envpw string
fs := flag.NewFlagSet("generate", flag.ExitOnError)
fs.BoolVarP(&help, "help", "h", false, "Show this help and exit")
fs.BoolVarP(&nopw, "no-password", "", false, "Don't ask for a password for the private key")
fs.StringVarP(&comment, "comment", "c", "", "Use `C` as the text comment for the keys")
fs.StringVarP(&envpw, "env-password", "E", "", "Use passphrase from environment variable `E`")
fs.BoolVarP(&force, "overwrite", "", false, "Overwrite the output file if it exists")
fs.Parse(args)
if help {
fs.SetOutput(os.Stdout)
fmt.Printf(`%s generate|gen|g [options] file-prefix
Generate a new Ed25519 public+private key pair and write public key to
FILE-PREFIX.pub and private key to FILE-PREFIX.key.
Options:
`, Z)
fs.PrintDefaults()
os.Exit(0)
}
args = fs.Args()
if len(args) < 1 {
Die("Insufficient arguments to 'generate'. Try '%s generate -h' ..", Z)
}
bn := args[0]
pkn := fmt.Sprintf("%s.pub", path.Clean(bn))
skn := fmt.Sprintf("%s.key", path.Clean(bn))
if !force {
if exists(pkn) || exists(skn) {
Die("Public/Private key files (%s, %s) exist. won't overwrite!", skn, pkn)
}
}
var err error
var pw []byte
if !nopw {
var pws string
if len(envpw) > 0 {
pws = os.Getenv(envpw)
} else {
pws, err = utils.Askpass("Enter passphrase for private key", true)
if err != nil {
Die("%s", err)
}
}
pw = []byte(pws)
}
sk, err := sign.NewPrivateKey()
if err != nil {
Die("%s", err)
}
if err = sk.Serialize(skn, comment, force, pw); err != nil {
Die("%s", err)
}
pk := sk.PublicKey()
if err = pk.Serialize(pkn, comment, force); err != nil {
Die("%s", err)
}
}
// Run the 'sign' command.
func signify(args []string) {
var nopw, help, force bool
var output string
var envpw string
fs := flag.NewFlagSet("sign", flag.ExitOnError)
fs.BoolVarP(&help, "help", "h", false, "Show this help and exit")
fs.BoolVarP(&nopw, "no-password", "", false, "Don't ask for a password for the private key")
fs.StringVarP(&envpw, "env-password", "E", "", "Use passphrase from environment variable `E`")
fs.StringVarP(&output, "output", "o", "", "Write signature to file `F`")
fs.BoolVarP(&force, "overwrite", "", false, "Overwrite previous signature file if it exists")
fs.Parse(args)
if help {
fs.SetOutput(os.Stdout)
fmt.Printf(`%s sign|s [options] privkey file
Sign FILE with a Ed25519 private key PRIVKEY and write signature to FILE.sig
Options:
`, Z)
fs.PrintDefaults()
os.Exit(0)
}
args = fs.Args()
if len(args) < 2 {
Die("Insufficient arguments to 'sign'. Try '%s sign -h' ..", Z)
}
kn := args[0]
fn := args[1]
outf := fmt.Sprintf("%s.sig", fn)
var err error
if len(output) > 0 {
outf = output
}
var fd io.WriteCloser = os.Stdout
if outf != "-" {
sf, err := utils.NewSafeFile(outf, force, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
Die("can't create sig file: %s", err)
}
// we unlink and remove temp on any error
AtExit(sf.Abort)
defer sf.Abort()
fd = sf
}
sk, err := sign.ReadPrivateKey(kn, func() ([]byte, error) {
if nopw {
return nil, nil
}
var pws string
if len(envpw) > 0 {
pws = os.Getenv(envpw)
} else {
pws, err = utils.Askpass("Enter passphrase for private key", false)
if err != nil {
Die("%s", err)
}
}
return []byte(pws), nil
})
if err != nil {
Die("%s", err)
}
sig, err := sk.SignFile(fn)
if err != nil {
Die("%s", err)
}
sigbytes, err := sig.MarshalBinary(fmt.Sprintf("input=%s", fn))
fd.Write(sigbytes)
fd.Close()
}
// Verify signature on a given file
func verify(args []string) {
var help, quiet bool
fs := flag.NewFlagSet("verify", flag.ExitOnError)
fs.BoolVarP(&help, "help", "h", false, "Show this help and exit")
fs.BoolVarP(&quiet, "quiet", "q", false, "Don't show any output; exit with status code only")
fs.Parse(args)
if help {
fs.SetOutput(os.Stdout)
fmt.Printf(`%s verify|v [options] pubkey sig file
Verify an Ed25519 signature in SIG of FILE using a public key PUBKEY.
Options:
`, Z)
fs.PrintDefaults()
os.Exit(0)
}
args = fs.Args()
if len(args) < 3 {
Die("Insufficient arguments to 'verify'. Try '%s verify -h' ..", Z)
}
pn := args[0]
sn := args[1]
fn := args[2]
sig, err := sign.ReadSignature(sn)
if err != nil {
Die("Can't read signature '%s': %s", sn, err)
}
pk, err := sign.ReadPublicKey(pn)
if err != nil {
Die("%s", err)
}
if !sig.IsPKMatch(pk) {
Die("Wrong public key '%s' for verifying '%s'", pn, sn)
}
ok, err := pk.VerifyFile(fn, sig)
if err != nil {
Die("%s", err)
}
exit := 0
if !ok {
exit = 1
}
if !quiet {
if ok {
fmt.Printf("%s: Signature %s verified\n", fn, sn)
} else {
fmt.Printf("%s: Signature %s verification failure\n", fn, sn)
}
}
os.Exit(exit)
}
func usage(c int) {
x := fmt.Sprintf(`%s is a tool to generate, sign and verify files with Ed25519 signatures.
Usage: %s [global-options] command [options] arg [args..]
Global options:
-h, --help Show help and exit
-v, --version Show version info and exit
--debug Enable debug (DANGEROUS)
Commands:
generate, g Generate a new Ed25519 keypair
sign, s Sign a file with a private key
verify, v Verify a signature against a file and a public key
encrypt, e Encrypt an input file to one or more recipients
decrypt, d Decrypt a file with a private key
`, Z, Z)
os.Stdout.Write([]byte(x))
os.Exit(c)
}
// Return true if $bn.key or $bn.pub exist; false otherwise
func exists(nm string) bool {
if _, err := os.Stat(nm); err == nil {
return true
}
return false
}
// This will be filled in by "build"
var RepoVersion string = "UNDEFINED"
var Buildtime string = "UNDEFINED"
var ProductVersion string = "UNDEFINED"
// vim: ft=go:sw=8:ts=8:noexpandtab:tw=98:

View file

@ -20,9 +20,10 @@ import (
"os" "os"
"strings" "strings"
"git.rgst.io/homelab/sigtool/v3/sign"
"github.com/opencoff/go-fio"
"github.com/opencoff/go-utils" "github.com/opencoff/go-utils"
flag "github.com/opencoff/pflag" flag "github.com/opencoff/pflag"
"github.com/opencoff/sigtool/sign"
) )
// sigtool encrypt [-i|--identity my.key] to.pub [to.pub] [ssh.pub] inputfile|- [-o output] // sigtool encrypt [-i|--identity my.key] to.pub [to.pub] [ssh.pub] inputfile|- [-o output]
@ -140,7 +141,11 @@ func encrypt(args []string) {
mode = ist.Mode() mode = ist.Mode()
} }
sf, err := utils.NewSafeFile(outfile, force, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode) var opts uint32
if force {
opts |= fio.OPT_OVERWRITE
}
sf, err := fio.NewSafeFile(outfile, opts, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode)
if err != nil { if err != nil {
Die("%s", err) Die("%s", err)
} }
@ -302,7 +307,11 @@ func decrypt(args []string) {
mode = ist.Mode() mode = ist.Mode()
} }
sf, err := utils.NewSafeFile(outfile, force, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode) var opts uint32
if force {
opts |= fio.OPT_OVERWRITE
}
sf, err := fio.NewSafeFile(outfile, opts, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode)
if err != nil { if err != nil {
Die("%s", err) Die("%s", err)
} }

View file

100
src/gen.go Normal file
View file

@ -0,0 +1,100 @@
// gen.go -- generate keys
//
// (c) 2016 Sudhi Herle <sudhi@herle.net>
//
// Licensing Terms: GPLv2
//
// If you need a commercial license for this work, please contact
// the author.
//
// This software does not come with any express or implied
// warranty; it is provided "as is". No claim is made to its
// suitability for any purpose.
package main
import (
"fmt"
"os"
"path"
"git.rgst.io/homelab/sigtool/v3/sign"
"github.com/opencoff/go-utils"
flag "github.com/opencoff/pflag"
)
// Run the generate command
func gen(args []string) {
var nopw, help, force bool
var comment string
var envpw string
fs := flag.NewFlagSet("generate", flag.ExitOnError)
fs.BoolVarP(&help, "help", "h", false, "Show this help and exit")
fs.BoolVarP(&nopw, "no-password", "", false, "Don't ask for a password for the private key")
fs.StringVarP(&comment, "comment", "c", "", "Use `C` as the text comment for the keys")
fs.StringVarP(&envpw, "env-password", "E", "", "Use passphrase from environment variable `E`")
fs.BoolVarP(&force, "overwrite", "", false, "Overwrite the output file if it exists")
fs.Parse(args)
if help {
fs.SetOutput(os.Stdout)
fmt.Printf(`%s generate|gen|g [options] file-prefix
Generate a new Ed25519 public+private key pair and write public key to
FILE-PREFIX.pub and private key to FILE-PREFIX.key.
Options:
`, Z)
fs.PrintDefaults()
os.Exit(0)
}
args = fs.Args()
if len(args) < 1 {
Die("Insufficient arguments to 'generate'. Try '%s generate -h' ..", Z)
}
bn := args[0]
pkn := fmt.Sprintf("%s.pub", path.Clean(bn))
skn := fmt.Sprintf("%s.key", path.Clean(bn))
if !force {
if exists(pkn) || exists(skn) {
Die("Public/Private key files (%s, %s) exist. won't overwrite!", skn, pkn)
}
}
var err error
var pw []byte
if !nopw {
var pws string
if len(envpw) > 0 {
pws = os.Getenv(envpw)
} else {
pws, err = utils.Askpass("Enter passphrase for private key", true)
if err != nil {
Die("%s", err)
}
}
pw = []byte(pws)
}
sk, err := sign.NewPrivateKey()
if err != nil {
Die("%s", err)
}
if err = sk.Serialize(skn, comment, force, pw); err != nil {
Die("%s", err)
}
pk := sk.PublicKey()
if err = pk.Serialize(pkn, comment, force); err != nil {
Die("%s", err)
}
}

116
src/sign.go Normal file
View file

@ -0,0 +1,116 @@
// sign.go -- 'sign' command implementation
//
// (c) 2016 Sudhi Herle <sudhi@herle.net>
//
// Licensing Terms: GPLv2
//
// If you need a commercial license for this work, please contact
// the author.
//
// This software does not come with any express or implied
// warranty; it is provided "as is". No claim is made to its
// suitability for any purpose.
package main
import (
"fmt"
"io"
"os"
"git.rgst.io/homelab/sigtool/v3/sign"
"github.com/opencoff/go-fio"
"github.com/opencoff/go-utils"
flag "github.com/opencoff/pflag"
)
// Run the 'sign' command.
func signify(args []string) {
var nopw, help, force bool
var output string
var envpw string
fs := flag.NewFlagSet("sign", flag.ExitOnError)
fs.BoolVarP(&help, "help", "h", false, "Show this help and exit")
fs.BoolVarP(&nopw, "no-password", "", false, "Don't ask for a password for the private key")
fs.StringVarP(&envpw, "env-password", "E", "", "Use passphrase from environment variable `E`")
fs.StringVarP(&output, "output", "o", "", "Write signature to file `F`")
fs.BoolVarP(&force, "overwrite", "", false, "Overwrite previous signature file if it exists")
fs.Parse(args)
if help {
fs.SetOutput(os.Stdout)
fmt.Printf(`%s sign|s [options] privkey file
Sign FILE with a Ed25519 private key PRIVKEY and write signature to FILE.sig
Options:
`, Z)
fs.PrintDefaults()
os.Exit(0)
}
args = fs.Args()
if len(args) < 2 {
Die("Insufficient arguments to 'sign'. Try '%s sign -h' ..", Z)
}
kn := args[0]
fn := args[1]
outf := fmt.Sprintf("%s.sig", fn)
var err error
if len(output) > 0 {
outf = output
}
var fd io.WriteCloser = os.Stdout
if outf != "-" {
var opts uint32
if force {
opts |= fio.OPT_OVERWRITE
}
sf, err := fio.NewSafeFile(outf, opts, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
Die("can't create sig file: %s", err)
}
// we unlink and remove temp on any error
AtExit(sf.Abort)
defer sf.Abort()
fd = sf
}
sk, err := sign.ReadPrivateKey(kn, func() ([]byte, error) {
if nopw {
return nil, nil
}
var pws string
if len(envpw) > 0 {
pws = os.Getenv(envpw)
} else {
pws, err = utils.Askpass("Enter passphrase for private key", false)
if err != nil {
Die("%s", err)
}
}
return []byte(pws), nil
})
if err != nil {
Die("%s", err)
}
sig, err := sk.SignFile(fn)
if err != nil {
Die("%s", err)
}
sigbytes, err := sig.MarshalBinary(fmt.Sprintf("input=%s", fn))
fd.Write(sigbytes)
fd.Close()
}

129
src/sigtool.go Normal file
View file

@ -0,0 +1,129 @@
// sigtool.go -- Tool to generate, manage Ed25519 keys and
// signatures.
//
// (c) 2016 Sudhi Herle <sudhi@herle.net>
//
// Licensing Terms: GPLv2
//
// If you need a commercial license for this work, please contact
// the author.
//
// This software does not come with any express or implied
// warranty; it is provided "as is". No claim is made to its
// suitability for any purpose.
package main
import (
"fmt"
"os"
"path"
"strings"
"git.rgst.io/homelab/sigtool/v3/sign"
"github.com/opencoff/go-utils"
flag "github.com/opencoff/pflag"
)
var Z string = path.Base(os.Args[0])
func main() {
var ver, help, debug bool
mf := flag.NewFlagSet(Z, flag.ExitOnError)
mf.SetInterspersed(false)
mf.BoolVarP(&ver, "version", "v", false, "Show version info and exit")
mf.BoolVarP(&help, "help", "h", false, "Show help info exit")
mf.BoolVarP(&debug, "debug", "", false, "Enable debug mode")
mf.Parse(os.Args[1:])
if ver {
fmt.Printf("%s - %s [%s]\n", Z, ProductVersion, RepoVersion)
os.Exit(0)
}
if help {
usage(0)
}
args := mf.Args()
if len(args) < 1 {
Die("Insufficient arguments. Try '%s -h'", Z)
}
cmds := map[string]func(args []string){
"generate": gen,
"sign": signify,
"verify": verify,
"encrypt": encrypt,
"decrypt": decrypt,
"help": func(_ []string) {
usage(0)
},
}
words := make([]string, 0, len(cmds))
for k := range cmds {
words = append(words, k)
}
ab := utils.Abbrev(words)
canon, ok := ab[strings.ToLower(args[0])]
if !ok {
Die("Unknown command %s", args[0])
}
cmd := cmds[canon]
if cmd == nil {
Die("can't map command %s", canon)
}
if debug {
sign.Debug(1)
}
cmd(args[1:])
// always call Exit so that at-exit handlers are called.
Exit(0)
}
// Verify signature on a given file
func usage(c int) {
x := fmt.Sprintf(`%s is a tool to generate, sign and verify files with Ed25519 signatures.
Usage: %s [global-options] command [options] arg [args..]
Global options:
-h, --help Show help and exit
-v, --version Show version info and exit
--debug Enable debug (DANGEROUS)
Commands:
generate, g Generate a new Ed25519 keypair
sign, s Sign a file with a private key
verify, v Verify a signature against a file and a public key
encrypt, e Encrypt an input file to one or more recipients
decrypt, d Decrypt a file with a private key
`, Z, Z)
os.Stdout.Write([]byte(x))
os.Exit(c)
}
// Return true if $bn.key or $bn.pub exist; false otherwise
func exists(nm string) bool {
if _, err := os.Stat(nm); err == nil {
return true
}
return false
}
// This will be filled in by "build"
var RepoVersion string = "UNDEFINED"
var ProductVersion string = "UNDEFINED"
// vim: ft=go:sw=8:ts=8:noexpandtab:tw=98:

96
src/verify.go Normal file
View file

@ -0,0 +1,96 @@
// verify.go -- Verify signatures
//
// (c) 2016 Sudhi Herle <sudhi@herle.net>
//
// Licensing Terms: GPLv2
//
// If you need a commercial license for this work, please contact
// the author.
//
// This software does not come with any express or implied
// warranty; it is provided "as is". No claim is made to its
// suitability for any purpose.
package main
import (
"fmt"
"os"
"git.rgst.io/homelab/sigtool/v3/sign"
flag "github.com/opencoff/pflag"
)
func verify(args []string) {
var help, quiet bool
fs := flag.NewFlagSet("verify", flag.ExitOnError)
fs.BoolVarP(&help, "help", "h", false, "Show this help and exit")
fs.BoolVarP(&quiet, "quiet", "q", false, "Don't show any output; exit with status code only")
fs.Parse(args)
if help {
fs.SetOutput(os.Stdout)
fmt.Printf(`%s verify|v [options] pubkey sig file
Verify an Ed25519 signature in SIG of FILE using a public key PUBKEY.
The pubkey can be one of:
- a file: either OpenSSH ed25519 pubkey or a sigtool pubkey
- a string: the raw OpenSSH or sigtool pubkey
%s will first parse it as a string before trying to parse it as a file.
Options:
`, Z, Z)
fs.PrintDefaults()
os.Exit(0)
}
args = fs.Args()
if len(args) < 3 {
Die("Insufficient arguments to 'verify'. Try '%s verify -h' ..", Z)
}
pn := args[0]
sn := args[1]
fn := args[2]
// We first try to read the public key as a base64/openssh string
pk, err := sign.MakePublicKeyFromString(pn)
if err != nil {
pk, err = sign.ReadPublicKey(pn)
if err != nil {
Die("%s", err)
}
}
sig, err := sign.ReadSignature(sn)
if err != nil {
Die("Can't read signature '%s': %s", sn, err)
}
if !sig.IsPKMatch(pk) {
Die("Wrong public key '%s' for verifying '%s'", pn, sn)
}
ok, err := pk.VerifyFile(fn, sig)
if err != nil {
Die("%s", err)
}
exit := 0
if !ok {
exit = 1
}
if !quiet {
if ok {
fmt.Printf("%s: Signature %s verified\n", fn, sn)
} else {
fmt.Printf("%s: Signature %s verification failure\n", fn, sn)
}
}
os.Exit(exit)
}

View file

@ -77,26 +77,35 @@ spk2=$ssk2.pub
$keygen -q -C 'ssk1@foo' -t ed25519 -f $ssk1 -N "" $keygen -q -C 'ssk1@foo' -t ed25519 -f $ssk1 -N ""
$keygen -q -C 'ssk2@foo' -t ed25519 -f $ssk2 -N "" $keygen -q -C 'ssk2@foo' -t ed25519 -f $ssk2 -N ""
$bin s --no-password $ssk1 -o $sig $0 || die "can't sign with $ssk1" # extract the pk string
$bin v -q $spk1 $sig $0 || die "can't verify with $spk2" spk1_str=$(cat $spk1 | awk '{ print $2 }')
$bin e --no-password -o $encout $spk2 $0 || die "can't encrypt to $spk2 with $ssk1" $bin s --no-password $ssk1 -o $sig $0 || die "can't sign with $ssk1"
$bin d --no-password -o $decout $ssk2 $encout || die "can't decrypt with $ssk2" $bin v -q $spk1 $sig $0 || die "can't verify with $spk2"
$bin v -q $spk1_str $sig $0 || die "can't verify with $spk2_str"
$bin e --no-password -o $encout $spk2 $0 || die "can't encrypt to $spk2 with $ssk1"
$bin d --no-password -o $decout $ssk2 $encout || die "can't decrypt with $ssk2"
# cleanup state # cleanup state
rm -f $sig $encout $decout rm -f $sig $encout $decout
# generate keys # generate keys
$bin g -E FOO $bn || die "can't gen keypair $pk, $sk" $bin g -E FOO $bn || die "can't gen keypair $pk, $sk"
$bin g -E FOO $bn 2>/dev/null && die "overwrote prev keypair" $bin g -E FOO $bn 2>/dev/null && die "overwrote prev keypair"
$bin g -E FOO --overwrite $bn || die "can't force gen keypair $pk, $sk" $bin g -E FOO --overwrite $bn || die "can't force gen keypair $pk, $sk"
$bin g -E FOO $bn2 || die "can't force gen keypair $pk2, $sk2" $bin g -E FOO $bn2 || die "can't force gen keypair $pk2, $sk2"
# extract pk string
pk_str=$(cat $pk | grep 'pk:' | sed -e 's/^pk: //g')
pk2_str=$(cat $pk2 | grep 'pk:' | sed -e 's/^pk: //g')
# sign and verify # sign and verify
$bin s -E FOO $sk $0 -o $sig || die "can't sign $0" $bin s -E FOO $sk $0 -o $sig || die "can't sign $0"
$bin v -q $pk $sig $0 || die "can't verify signature of $0" $bin v -q $pk $sig $0 || die "can't verify signature of $0"
$bin v -q $pk2 $sig $0 2>/dev/null && die "bad verification with wrong $pk2" $bin v -q $pk_str $sig $0 || die "can't verify signature of $0"
$bin v -q $pk2 $sig $0 2>/dev/null && die "bad verification with wrong $pk2"
$bin v -q $pk2_str $sig $0 2>/dev/null && die "bad verification with wrong $pk2"
# encrypt/decrypt # encrypt/decrypt
$bin e -E FOO -o $encout $pk2 $0 || die "can't encrypt to $pk2" $bin e -E FOO -o $encout $pk2 $0 || die "can't encrypt to $pk2"
@ -106,7 +115,7 @@ cmp -s $decout $0 || die "decrypted file mismatch with $0"
# now with sender verification # now with sender verification
$bin e -E FOO --overwrite -o $encout -s $sk $pk2 $0 || die "can't sender-encrypt to $pk2" $bin e -E FOO --overwrite -o $encout -s $sk $pk2 $0 || die "can't sender-encrypt to $pk2"
$bin d -E FOO --overwrite -o $decout -v $pk $sk2 $encout || die "can't decrypt with $sk2" $bin d -E FOO --overwrite -o $decout -v $pk $sk2 $encout || die "can't decrypt with $sk2"
cmp -s $decout $0 || die "decrypted file mismatch with $0" cmp -s $decout $0 || die "decrypted file mismatch with $0"
# Only delete if everything worked # Only delete if everything worked
echo "$Z: All tests pass!" echo "$Z: All tests pass!"