From c4f79962c9ce2f55dc7721bd8d4085fdf88d8cd2 Mon Sep 17 00:00:00 2001 From: Sudhi Herle Date: Sun, 12 Nov 2023 12:21:31 -0800 Subject: [PATCH] Updated dependencies; use SafeFile from go-utils. Teach tests.sh to use a user supplied binary & tmpdir --- crypt.go | 8 +-- go.mod | 10 ++-- go.sum | 17 +++---- sign/encrypt.go | 3 +- sign/keys.go | 2 +- sign/safefile.go | 124 ----------------------------------------------- sign/sign.go | 5 +- sigtool.go | 2 +- tests.sh | 58 +++++++++++++--------- 9 files changed, 59 insertions(+), 170 deletions(-) delete mode 100644 sign/safefile.go diff --git a/crypt.go b/crypt.go index d6122f3..ad9cd79 100644 --- a/crypt.go +++ b/crypt.go @@ -35,8 +35,8 @@ func encrypt(args []string) { var outfile string var keyfile string - var szstr string = "128k" - var envpw string + var szstr string = "128k" + var envpw string var nopw, force bool var blksize uint64 @@ -140,7 +140,7 @@ func encrypt(args []string) { mode = ist.Mode() } - sf, err := sign.NewSafeFile(outfile, force, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode) + sf, err := utils.NewSafeFile(outfile, force, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode) if err != nil { Die("%s", err) } @@ -302,7 +302,7 @@ func decrypt(args []string) { mode = ist.Mode() } - sf, err := sign.NewSafeFile(outfile, force, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode) + sf, err := utils.NewSafeFile(outfile, force, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode) if err != nil { Die("%s", err) } diff --git a/go.mod b/go.mod index baa9046..2720e13 100644 --- a/go.mod +++ b/go.mod @@ -1,17 +1,17 @@ module github.com/opencoff/sigtool -go 1.20 +go 1.21 require ( github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a github.com/gogo/protobuf v1.3.2 - github.com/opencoff/go-utils v0.4.1 + github.com/opencoff/go-utils v0.7.2 github.com/opencoff/pflag v1.0.6-sh1 - golang.org/x/crypto v0.7.0 + golang.org/x/crypto v0.15.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.6.0 // indirect + golang.org/x/sys v0.14.0 // indirect + golang.org/x/term v0.14.0 // indirect ) diff --git a/go.sum b/go.sum index 349aa00..e2a681c 100644 --- a/go.sum +++ b/go.sum @@ -4,18 +4,17 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/opencoff/go-utils v0.4.1 h1:Ke4Q1Tl2GKMI+dwleuPNHH713ngRiNMOFIkymncHqXg= -github.com/opencoff/go-utils v0.4.1/go.mod h1:c+7QUAiCCHcNH6OGvsZ0fviG7cgse8Y3ucg+xy7sGXM= +github.com/opencoff/go-utils v0.7.2 h1:FK250pZ9UH+zdp1DlGyRARq7nULHEIkTVbpITTwwVXk= +github.com/opencoff/go-utils v0.7.2/go.mod h1:8hMC3uc+N0wUMxpmW2yzM6FuhlCCxRST1Wj+cYntqFA= github.com/opencoff/pflag v1.0.6-sh1 h1:6RO8GgnpH928yu6earGDD01FnFT//bDJ1hCovcVVqY4= github.com/opencoff/pflag v1.0.6-sh1/go.mod h1:2bXtpAD/5h/2LarkbsRwiUxqnvB1nZBzn9Xjad1P41A= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -28,10 +27,10 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/sign/encrypt.go b/sign/encrypt.go index 86229f0..6db7e1c 100644 --- a/sign/encrypt.go +++ b/sign/encrypt.go @@ -753,7 +753,8 @@ func (d *Decryptor) verifySender(key []byte, senderPk *PublicKey) error { } // Wrap data encryption key 'k' with the sender's PK and our ephemeral curve SK -// basically, we do a scalarmult: Ephemeral encryption/decryption SK x receiver PK +// +// basically, we do a scalarmult: Ephemeral encryption/decryption SK x receiver PK func (e *Encryptor) wrapKey(pk *PublicKey) (*pb.WrappedKey, error) { rxPK := pk.ToCurve25519PK() sekrit, err := curve25519.X25519(e.encSK, rxPK) diff --git a/sign/keys.go b/sign/keys.go index 3516911..4a32d45 100644 --- a/sign/keys.go +++ b/sign/keys.go @@ -503,7 +503,7 @@ func (pk *PublicKey) UnmarshalBinary(yml []byte) error { // 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 := NewSafeFile(fn, ovwrite, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(mode)) + sf, err := utils.NewSafeFile(fn, ovwrite, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(mode)) if err != nil { return err } diff --git a/sign/safefile.go b/sign/safefile.go deleted file mode 100644 index 8a28af8..0000000 --- a/sign/safefile.go +++ /dev/null @@ -1,124 +0,0 @@ -// safefile.go - safe file creation and unwinding on error -// -// (c) 2021 Sudhi Herle -// -// 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 ( - "fmt" - "io" - "os" -) - -// SafeFile is an io.WriteCloser which uses a temporary file that -// will be atomically renamed when there are no errors and -// caller invokes Close(). Callers are advised to call -// Abort() in the appropriate error handling (defer) context -// so that the temporary file is properly deleted. -type SafeFile struct { - *os.File - - // error for writes recorded once - err error - name string // actual filename - - closed bool // set if the file is closed properly -} - -var _ io.WriteCloser = &SafeFile{} - -// NewSafeFile creates a new temporary file that would either be -// aborted or safely renamed to the correct name. -// 'nm' is the name of the final file; if 'ovwrite' is true, -// then the file is overwritten if it exists. -func NewSafeFile(nm string, ovwrite bool, flag int, perm os.FileMode) (*SafeFile, error) { - if _, err := os.Stat(nm); err == nil && !ovwrite { - return nil, fmt.Errorf("safefile: won't overwrite existing %s", nm) - } - - // forcibly unlink the old file - so previous artifacts don't exist - os.Remove(nm) - - tmp := fmt.Sprintf("%s.tmp.%d.%x", nm, os.Getpid(), randu32()) - fd, err := os.OpenFile(tmp, flag, perm) - if err != nil { - return nil, err - } - - sf := &SafeFile{ - File: fd, - name: nm, - } - return sf, nil -} - -// Attempt to write everything in 'b' and don't proceed if there was -// a previous error or the file was already closed. -func (sf *SafeFile) Write(b []byte) (int, error) { - if sf.err != nil { - return 0, sf.err - } - - if sf.closed { - return 0, fmt.Errorf("safefile: %s is closed", sf.Name()) - } - - var z, nw int - n := len(b) - for n > 0 { - if nw, sf.err = sf.File.Write(b); sf.err != nil { - return z, sf.err - } - z += nw - n -= nw - b = b[nw:] - } - return z, nil -} - -// Abort the file write and remove any temporary artifacts -func (sf *SafeFile) Abort() { - // if we've successfully closed, nothing to do! - if sf.closed { - return - } - - sf.closed = true - sf.File.Close() - os.Remove(sf.Name()) -} - -// Close flushes all file data & metadata to disk, closes the file and atomically renames -// the temp file to the actual file - ONLY if there were no intervening errors. -func (sf *SafeFile) Close() error { - if sf.err != nil { - sf.Abort() - return sf.err - } - - // mark this file as closed! - sf.closed = true - - if sf.err = sf.Sync(); sf.err != nil { - return sf.err - } - - if sf.err = sf.File.Close(); sf.err != nil { - return sf.err - } - - if sf.err = os.Rename(sf.Name(), sf.name); sf.err != nil { - return sf.err - } - - return nil -} diff --git a/sign/sign.go b/sign/sign.go index b8714a0..bce9d85 100644 --- a/sign/sign.go +++ b/sign/sign.go @@ -38,8 +38,9 @@ type Signature struct { // Sign a prehashed Message; return the signature as opaque bytes // Signature is an YAML file: -// Comment: source file path -// Signature: Ed25519 signature +// +// Comment: source file path +// Signature: Ed25519 signature func (sk *PrivateKey) SignMessage(ck []byte, comment string) (*Signature, error) { h := sha512.New() h.Write([]byte("sigtool signed message")) diff --git a/sigtool.go b/sigtool.go index ef7b7f5..69a249c 100644 --- a/sigtool.go +++ b/sigtool.go @@ -213,7 +213,7 @@ Options: var fd io.WriteCloser = os.Stdout if outf != "-" { - sf, err := sign.NewSafeFile(outf, force, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) + 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) } diff --git a/tests.sh b/tests.sh index 42b9464..c1fa38b 100755 --- a/tests.sh +++ b/tests.sh @@ -1,32 +1,44 @@ #! /usr/bin/env bash - - # simple round-trip tests to verify the tool +# Usage: +# $0 [bin=/path/to/sigtool] [tmpdir=/path/to/workdir] -# Use cmdline flag to get go-root - -GoRoot=$HOME/go - -if [ -n "$1" ]; then - GoRoot=$1 -fi - -arch=`./build --go-root=$GoRoot --print-arch` -bin=./bin/$arch/sigtool Z=`basename $0` - -# workdir -tmpdir=/tmp/sigtool$$ - die() { echo "$Z: $@" 1>&2 echo "$Z: Test output in $tmpdir .." 1>&2 exit 1 } +# cmd line args processing +for a in $*; do + key=${a%=*} + val=${a#*=} + case $key in + bin) + bin=$val + ;; + + tmpdir) + tmpdir=$val + ;; + + *) + echo "Ignoring $key .." + ;; + esac +done + +if [ -z "$bin" ]; then + arch=`./build --print-arch` + bin=./bin/$arch/sigtool + + [ -x $bin ] || ./build || die "can't find & build sigtool" +fi + +[ -z "$tmpdir" ] && tmpdir=/tmp/sigtool$$ mkdir -p $tmpdir || die "can't mkdir $tmpdir" -[ -x $bin ] || ./build || die "Can't build sigtool for $arch" # env name for reading the password passenv=FOO @@ -38,9 +50,9 @@ FOO=bar #trap "rm -rf $tmpdir" EXIT bn=$tmpdir/foo +sig=$tmpdir/$Z.sig pk=$bn.pub sk=$bn.key -sig=$tmpdir/$Z.sig bn2=$tmpdir/bar pk2=$bn2.pub sk2=$bn2.key @@ -76,15 +88,15 @@ rm -f $sig $encout $decout # generate keys -$bin g -E FOO $bn || die "can't gen keypair $pk, $sk" -$bin g -E FOO $bn && die "overwrote prev keypair" +$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 --overwrite $bn || die "can't force gen keypair $pk, $sk" $bin g -E FOO $bn2 || die "can't force gen keypair $pk2, $sk2" # sign and verify -$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 $pk2 $sig $0 && die "bad verification with wrong $pk2" +$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 $pk2 $sig $0 2>/dev/null && die "bad verification with wrong $pk2" # encrypt/decrypt $bin e -E FOO -o $encout $pk2 $0 || die "can't encrypt to $pk2"