From 419369d922cec628f7d710d5de4cd71135f24813 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Fri, 6 Nov 2020 17:52:26 +0000 Subject: [PATCH 01/25] internal/build: implement signify's signing func --- internal/build/signify.go | 77 ++++++++++++++++++++++++++++++++++ internal/build/signify_test.go | 20 +++++++++ 2 files changed, 97 insertions(+) create mode 100644 internal/build/signify.go create mode 100644 internal/build/signify_test.go diff --git a/internal/build/signify.go b/internal/build/signify.go new file mode 100644 index 000000000000..a6ab1c32930c --- /dev/null +++ b/internal/build/signify.go @@ -0,0 +1,77 @@ +// Copyright 2020 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// signFile reads the contents of an input file and signs it (in armored format) +// with the key provided, placing the signature into the output file. + +package build + +import ( + "encoding/base64" + "errors" + "fmt" + "io/ioutil" + "os" + + "crypto/ed25519" +) + +var ( + errInvalidKeyHeader = errors.New("Incorrect key header") + errInvalidKeyLength = errors.New("invalid, key length != 42") +) + +func readSKey(key []byte) (ed25519.PrivateKey, error) { + if len(key) != 104 { + return nil, errInvalidKeyLength + } + + if string(key[:2]) != "Ed" { + return nil, errInvalidKeyHeader + } + + return ed25519.PrivateKey(key[40:]), nil + +} + +// SignifySignFile creates a signature of the input file. +func SignifySignFile(input string, output string, key string) error { + in, err := os.Open(input) + if err != nil { + return err + } + defer in.Close() + + out, err := os.Create(output) + if err != nil { + return err + } + defer out.Close() + + keydata, err := base64.StdEncoding.DecodeString(key) + skey, err := readSKey(keydata) + if err != nil { + return nil + } + + filedata, err := ioutil.ReadAll(in) + if err != nil { + return err + } + + out.WriteString(fmt.Sprintf("untrusted comment: verify with geth.pub\n%s\n", base64.StdEncoding.EncodeToString(ed25519.Sign(skey, filedata)))) + return nil +} diff --git a/internal/build/signify_test.go b/internal/build/signify_test.go new file mode 100644 index 000000000000..0ab23f21ba12 --- /dev/null +++ b/internal/build/signify_test.go @@ -0,0 +1,20 @@ +// Copyright 2020 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// signFile reads the contents of an input file and signs it (in armored format) +// with the key provided, placing the signature into the output file. + +package build From 20331e9b3a1189622f0d20841d6d4e82f0705c7e Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Sun, 8 Nov 2020 19:17:13 +0100 Subject: [PATCH 02/25] Add signify to the ci utility --- build/ci.go | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/build/ci.go b/build/ci.go index 0cffb903aadb..b40d0a8c7321 100644 --- a/build/ci.go +++ b/build/ci.go @@ -396,11 +396,12 @@ func downloadLinter(cachedir string) string { // Release Packaging func doArchive(cmdline []string) { var ( - arch = flag.String("arch", runtime.GOARCH, "Architecture cross packaging") - atype = flag.String("type", "zip", "Type of archive to write (zip|tar)") - signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. LINUX_SIGNING_KEY)`) - upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) - ext string + arch = flag.String("arch", runtime.GOARCH, "Architecture cross packaging") + atype = flag.String("type", "zip", "Type of archive to write (zip|tar)") + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. LINUX_SIGNING_KEY)`) + signify = flag.String("signify", "", `Environment variable holding the signify key (e.g. LINUX_SIGNIFY_KEY)`) + upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) + ext string ) flag.CommandLine.Parse(cmdline) switch *atype { @@ -427,7 +428,7 @@ func doArchive(cmdline []string) { log.Fatal(err) } for _, archive := range []string{geth, alltools} { - if err := archiveUpload(archive, *upload, *signer); err != nil { + if err := archiveUpload(archive, *upload, *signer, *signify); err != nil { log.Fatal(err) } } @@ -447,7 +448,7 @@ func archiveBasename(arch string, archiveVersion string) string { return platform + "-" + archiveVersion } -func archiveUpload(archive string, blobstore string, signer string) error { +func archiveUpload(archive string, blobstore string, signer string, signify string) error { // If signing was requested, generate the signature files if signer != "" { key := getenvBase64(signer) @@ -455,6 +456,12 @@ func archiveUpload(archive string, blobstore string, signer string) error { return err } } + if signify != "" { + key := getenvBase64(string(signify)) + if err := build.SignifySignFile(archive, archive+".sig", key); err != nil { + return err + } + } // If uploading to Azure was requested, push the archive possibly with its signature if blobstore != "" { auth := build.AzureBlobstoreConfig{ @@ -806,6 +813,7 @@ func doWindowsInstaller(cmdline []string) { var ( arch = flag.String("arch", runtime.GOARCH, "Architecture for cross build packaging") signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. WINDOWS_SIGNING_KEY)`) + signify = flag.String("signify key", "", `Environment variable holding the signify signing key (e.g. WINDOWS_SIGNIFY_KEY)`) upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) workdir = flag.String("workdir", "", `Output directory for packages (uses temp dir if unset)`) ) @@ -867,7 +875,7 @@ func doWindowsInstaller(cmdline []string) { filepath.Join(*workdir, "geth.nsi"), ) // Sign and publish installer. - if err := archiveUpload(installer, *upload, *signer); err != nil { + if err := archiveUpload(installer, *upload, *signer, *signify); err != nil { log.Fatal(err) } } @@ -876,10 +884,11 @@ func doWindowsInstaller(cmdline []string) { func doAndroidArchive(cmdline []string) { var ( - local = flag.Bool("local", false, `Flag whether we're only doing a local build (skip Maven artifacts)`) - signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. ANDROID_SIGNING_KEY)`) - deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "https://oss.sonatype.org")`) - upload = flag.String("upload", "", `Destination to upload the archive (usually "gethstore/builds")`) + local = flag.Bool("local", false, `Flag whether we're only doing a local build (skip Maven artifacts)`) + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. ANDROID_SIGNING_KEY)`) + signify = flag.String("signify", "", `Environment variable holding the signify signing key (e.g. ANDROID_SIGNIFY_KEY)`) + deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "https://oss.sonatype.org")`) + upload = flag.String("upload", "", `Destination to upload the archive (usually "gethstore/builds")`) ) flag.CommandLine.Parse(cmdline) env := build.Env() @@ -908,7 +917,7 @@ func doAndroidArchive(cmdline []string) { archive := "geth-" + archiveBasename("android", params.ArchiveVersion(env.Commit)) + ".aar" os.Rename("geth.aar", archive) - if err := archiveUpload(archive, *upload, *signer); err != nil { + if err := archiveUpload(archive, *upload, *signer, *signify); err != nil { log.Fatal(err) } // Sign and upload all the artifacts to Maven Central @@ -1001,10 +1010,11 @@ func newMavenMetadata(env build.Environment) mavenMetadata { func doXCodeFramework(cmdline []string) { var ( - local = flag.Bool("local", false, `Flag whether we're only doing a local build (skip Maven artifacts)`) - signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. IOS_SIGNING_KEY)`) - deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "trunk")`) - upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) + local = flag.Bool("local", false, `Flag whether we're only doing a local build (skip Maven artifacts)`) + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. IOS_SIGNING_KEY)`) + signify = flag.String("signify", "", `Environment variable holding the signify signing key (e.g. IOS_SIGNIFY_KEY)`) + deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "trunk")`) + upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) ) flag.CommandLine.Parse(cmdline) env := build.Env() @@ -1032,7 +1042,7 @@ func doXCodeFramework(cmdline []string) { maybeSkipArchive(env) // Sign and upload the framework to Azure - if err := archiveUpload(archive+".tar.gz", *upload, *signer); err != nil { + if err := archiveUpload(archive+".tar.gz", *upload, *signer, *signify); err != nil { log.Fatal(err) } // Prepare and upload a PodSpec to CocoaPods From ea463a261622759bc918d1a550596829ca895df1 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Sun, 8 Nov 2020 19:17:34 +0100 Subject: [PATCH 03/25] fix output file format --- internal/build/signify.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/build/signify.go b/internal/build/signify.go index a6ab1c32930c..ab75bef21330 100644 --- a/internal/build/signify.go +++ b/internal/build/signify.go @@ -72,6 +72,11 @@ func SignifySignFile(input string, output string, key string) error { return err } - out.WriteString(fmt.Sprintf("untrusted comment: verify with geth.pub\n%s\n", base64.StdEncoding.EncodeToString(ed25519.Sign(skey, filedata)))) + sigdata := []byte("Ed") + copy(sigdata, keydata[:2]) + sigdata = append(sigdata, keydata[32:40]...) + sigdata = append(sigdata, ed25519.Sign(skey, filedata)...) + + out.WriteString(fmt.Sprintf("untrusted comment: verify with geth.pub\n%s\n", base64.StdEncoding.EncodeToString(sigdata))) return nil } From 0028e1d31193e2ac0b9c8f1034ef00612ff76eb9 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Sun, 8 Nov 2020 19:18:21 +0100 Subject: [PATCH 04/25] Add unit test for signify --- internal/build/signify_test.go | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/internal/build/signify_test.go b/internal/build/signify_test.go index 0ab23f21ba12..7844289ae401 100644 --- a/internal/build/signify_test.go +++ b/internal/build/signify_test.go @@ -18,3 +18,39 @@ // with the key provided, placing the signature into the output file. package build + +import ( + "fmt" + "io/ioutil" + "math/rand" + "os" + "testing" + "time" +) + +func TestSignify(t *testing.T) { + tmpFile, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpFile.Name()) + defer tmpFile.Close() + + rand.Seed(time.Now().UnixNano()) + + data := make([]byte, 1024) + rand.Read(data) + tmpFile.Write(data) + + if err = tmpFile.Close(); err != nil { + t.Fatal(err) + } + + err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), "RWRCSwAAAABVN5lr2JViGBN8DhX3/Qb/0g0wBdsNAR/APRW2qy9Fjsfr12sK2cd3URUFis1jgzQzaoayK8x4syT4G3Gvlt9RwGIwUYIQW/0mTeI+ECHu1lv5U4Wa2YHEPIesVPyRm5M=") + if err != nil { + t.Fatal(err) + } + if err = os.Remove(fmt.Sprintf("%s.sig", tmpFile.Name())); err != nil { + t.Fatal(err) + } +} From d8758375b602a779a54c94c5c6d94a79cf1cf734 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Mon, 16 Nov 2020 11:18:21 +0100 Subject: [PATCH 05/25] holiman's + travis' feedback --- build/ci.go | 7 ++++++- internal/build/signify.go | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/build/ci.go b/build/ci.go index b40d0a8c7321..ba06d7be5ed0 100644 --- a/build/ci.go +++ b/build/ci.go @@ -458,7 +458,7 @@ func archiveUpload(archive string, blobstore string, signer string, signify stri } if signify != "" { key := getenvBase64(string(signify)) - if err := build.SignifySignFile(archive, archive+".sig", key); err != nil { + if err := build.SignifySignFile(archive, archive+".sig", string(key)); err != nil { return err } } @@ -477,6 +477,11 @@ func archiveUpload(archive string, blobstore string, signer string, signify stri return err } } + if signify != "" { + if err := build.AzureBlobstoreUpload(archive+".sig", filepath.Base(archive+".sig"), auth); err != nil { + return err + } + } } return nil } diff --git a/internal/build/signify.go b/internal/build/signify.go index ab75bef21330..f206feb4b7c9 100644 --- a/internal/build/signify.go +++ b/internal/build/signify.go @@ -62,9 +62,12 @@ func SignifySignFile(input string, output string, key string) error { defer out.Close() keydata, err := base64.StdEncoding.DecodeString(key) + if err != nil { + return err + } skey, err := readSKey(keydata) if err != nil { - return nil + return err } filedata, err := ioutil.ReadAll(in) From 9fb07a829ee2c159bc5585c1218a036f592fd09e Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Tue, 17 Nov 2020 12:17:59 +0100 Subject: [PATCH 06/25] internal/build: verify signify's output --- .travis.yml | 15 ++++++++++++++ internal/build/signify_test.go | 36 +++++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index fd31e3d506b4..b1ca4c737125 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,6 +44,7 @@ jobs: - fakeroot - python-bzrlib - python-paramiko + - signify-openbsd script: - echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts - go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder " @@ -64,12 +65,15 @@ jobs: apt: packages: - gcc-multilib + - signify-openbsd script: # Build for the primary platforms that Trusty can manage - go run build/ci.go install -dlgo - go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go archive -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go install -dlgo -arch 386 - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds # Switch over GCC to cross compilation (breaks 386, hence why do it here only) - sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross @@ -77,12 +81,16 @@ jobs: - GOARM=5 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds - GOARM=6 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds - GOARM=7 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabihf-gcc - GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go install -dlgo -arch arm64 -cc aarch64-linux-gnu-gcc - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds # This builder does the Linux Azure MIPS xgo uploads - stage: build @@ -101,18 +109,22 @@ jobs: - go run build/ci.go xgo --alltools -- --targets=linux/mips --ldflags '-extldflags "-static"' -v - for bin in build/bin/*-linux-mips; do mv -f "${bin}" "${bin/-linux-mips/}"; done - go run build/ci.go archive -arch mips -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go archive -arch mips -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go xgo --alltools -- --targets=linux/mipsle --ldflags '-extldflags "-static"' -v - for bin in build/bin/*-linux-mipsle; do mv -f "${bin}" "${bin/-linux-mipsle/}"; done - go run build/ci.go archive -arch mipsle -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go archive -arch mipsle -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go xgo --alltools -- --targets=linux/mips64 --ldflags '-extldflags "-static"' -v - for bin in build/bin/*-linux-mips64; do mv -f "${bin}" "${bin/-linux-mips64/}"; done - go run build/ci.go archive -arch mips64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go archive -arch mips64 -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go xgo --alltools -- --targets=linux/mips64le --ldflags '-extldflags "-static"' -v - for bin in build/bin/*-linux-mips64le; do mv -f "${bin}" "${bin/-linux-mips64le/}"; done - go run build/ci.go archive -arch mips64le -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go archive -arch mips64le -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds # This builder does the Android Maven and Azure uploads - stage: build @@ -152,6 +164,7 @@ jobs: - mkdir -p $GOPATH/src/github.com/ethereum - ln -s `pwd` $GOPATH/src/github.com/ethereum/go-ethereum - go run build/ci.go aar -signer ANDROID_SIGNING_KEY -deploy https://oss.sonatype.org -upload gethstore/builds + - go run build/ci.go aar -signer ANDROID_SIGNIFY_KEY -deploy https://oss.sonatype.org -upload gethstore/builds # This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads - stage: build @@ -168,6 +181,7 @@ jobs: script: - go run build/ci.go install -dlgo - go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go archive -type tar -signer OSX_SIGNIFY_KEY -upload gethstore/builds # Build the iOS framework and upload it to CocoaPods and Azure - gem uninstall cocoapods -a -x @@ -183,6 +197,7 @@ jobs: # Workaround for https://github.com/golang/go/issues/23749 - export CGO_CFLAGS_ALLOW='-fmodules|-fblocks|-fobjc-arc' - go run build/ci.go xcode -signer IOS_SIGNING_KEY -deploy trunk -upload gethstore/builds + - go run build/ci.go xcode -signer IOS_SIGNIFY_KEY -deploy trunk -upload gethstore/builds # These builders run the tests - stage: build diff --git a/internal/build/signify_test.go b/internal/build/signify_test.go index 7844289ae401..3a66c537939e 100644 --- a/internal/build/signify_test.go +++ b/internal/build/signify_test.go @@ -24,10 +24,17 @@ import ( "io/ioutil" "math/rand" "os" + "os/exec" + "runtime" "testing" "time" ) +var ( + testSecKey = "RWRCSwAAAABVN5lr2JViGBN8DhX3/Qb/0g0wBdsNAR/APRW2qy9Fjsfr12sK2cd3URUFis1jgzQzaoayK8x4syT4G3Gvlt9RwGIwUYIQW/0mTeI+ECHu1lv5U4Wa2YHEPIesVPyRm5M=" + testPubKey = "RWTAPRW2qy9FjsBiMFGCEFv9Jk3iPhAh7tZb+VOFmtmBxDyHrFT8kZuT" +) + func TestSignify(t *testing.T) { tmpFile, err := ioutil.TempFile("", "") if err != nil { @@ -46,11 +53,34 @@ func TestSignify(t *testing.T) { t.Fatal(err) } - err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), "RWRCSwAAAABVN5lr2JViGBN8DhX3/Qb/0g0wBdsNAR/APRW2qy9Fjsfr12sK2cd3URUFis1jgzQzaoayK8x4syT4G3Gvlt9RwGIwUYIQW/0mTeI+ECHu1lv5U4Wa2YHEPIesVPyRm5M=") + err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), testSecKey) if err != nil { t.Fatal(err) } - if err = os.Remove(fmt.Sprintf("%s.sig", tmpFile.Name())); err != nil { - t.Fatal(err) + defer os.Remove(fmt.Sprintf("%s.sig", tmpFile.Name())) + + // if signify-openbsd is present, check the signature. + // signify-openbsd will be present in CI. + if runtime.GOOS == "linux" { + cmd := exec.Command("which", "signify-openbsd") + if err = cmd.Run(); err == nil { + // Write the public key into the file to pass it as + // an argument to signify-openbsd + pubKeyFile, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(pubKeyFile.Name()) + defer pubKeyFile.Close() + pubKeyFile.WriteString("untrusted comment: signify public key\n") + pubKeyFile.WriteString(testPubKey) + pubKeyFile.WriteString("\n") + + cmd := exec.Command("signify-openbsd", "-V", "-p", pubKeyFile.Name(), "-x", fmt.Sprintf("%s.sig", tmpFile.Name()), "-m", tmpFile.Name()) + if output, err := cmd.CombinedOutput(); err != nil { + fmt.Println(string(output)) + t.Fatalf("could not verify the file: %v", err) + } + } } } From c4fee159014686ec430ec37a0bdc098b072b57a1 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Tue, 17 Nov 2020 12:59:56 +0100 Subject: [PATCH 07/25] crypto: move signify to common dir --- {internal/build => crypto}/signify.go | 4 ++-- {internal/build => crypto}/signify_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename {internal/build => crypto}/signify.go (97%) rename {internal/build => crypto}/signify_test.go (99%) diff --git a/internal/build/signify.go b/crypto/signify.go similarity index 97% rename from internal/build/signify.go rename to crypto/signify.go index f206feb4b7c9..7205f956babd 100644 --- a/internal/build/signify.go +++ b/crypto/signify.go @@ -17,7 +17,7 @@ // signFile reads the contents of an input file and signs it (in armored format) // with the key provided, placing the signature into the output file. -package build +package crypto import ( "encoding/base64" @@ -26,7 +26,7 @@ import ( "io/ioutil" "os" - "crypto/ed25519" + "golang.org/x/crypto/ed25519" ) var ( diff --git a/internal/build/signify_test.go b/crypto/signify_test.go similarity index 99% rename from internal/build/signify_test.go rename to crypto/signify_test.go index 3a66c537939e..c8b28770ce61 100644 --- a/internal/build/signify_test.go +++ b/crypto/signify_test.go @@ -17,7 +17,7 @@ // signFile reads the contents of an input file and signs it (in armored format) // with the key provided, placing the signature into the output file. -package build +package crypto import ( "fmt" From 5eb3540e97901383b186421410f71009bf9257bc Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Tue, 17 Nov 2020 14:37:06 +0100 Subject: [PATCH 08/25] use go-minisign to verify binaries --- crypto/signify_test.go | 21 +++++++++++++++++++++ go.mod | 1 + go.sum | 3 +++ 3 files changed, 25 insertions(+) mode change 100755 => 100644 go.mod mode change 100755 => 100644 go.sum diff --git a/crypto/signify_test.go b/crypto/signify_test.go index c8b28770ce61..3a78ff075043 100644 --- a/crypto/signify_test.go +++ b/crypto/signify_test.go @@ -28,6 +28,8 @@ import ( "runtime" "testing" "time" + + "github.com/jedisct1/go-minisign" ) var ( @@ -83,4 +85,23 @@ func TestSignify(t *testing.T) { } } } + + // Verify the signature using a golang library + sig, err := minisign.NewSignatureFromFile(tmpFile.Name() + ".sig") + if err != nil { + t.Fatal(err) + } + + pKey, err := minisign.NewPublicKey(testPubKey) + if err != nil { + t.Fatal(err) + } + + valid, err := pKey.VerifyFromFile(tmpFile.Name(), sig) + if err != nil { + t.Fatal(err) + } + if !valid { + t.Fatal("invalid signature") + } } diff --git a/go.mod b/go.mod old mode 100755 new mode 100644 index ae1cf64aaf9c..9a35f6447ff4 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/huin/goupnp v1.0.0 github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883 github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 + github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21 github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 github.com/kr/pretty v0.1.0 // indirect diff --git a/go.sum b/go.sum old mode 100755 new mode 100644 index 10bec96411e9..dedae7bc7a20 --- a/go.sum +++ b/go.sum @@ -123,6 +123,8 @@ github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883 h1:FSeK4fZCo github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 h1:6OvNmYgJyexcZ3pYbTI9jWx5tHo1Dee/tWbLMfPe2TA= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e h1:UvSe12bq+Uj2hWd8aOlwPmoZ+CITRFrdit+sDGfAg8U= +github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21 h1:F/iKcka0K2LgnKy/fgSBf235AETtm1n1TvBzqu40LE0= @@ -214,6 +216,7 @@ github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8 github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/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 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= From 80d45d0b7e64e5b1f20afa47547b45662e8c0746 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Wed, 18 Nov 2020 00:11:54 +0000 Subject: [PATCH 09/25] more holiman feedback --- build/ci.go | 3 ++- crypto/signify.go | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/build/ci.go b/build/ci.go index ba06d7be5ed0..2c8f4ef5e9f1 100644 --- a/build/ci.go +++ b/build/ci.go @@ -58,6 +58,7 @@ import ( "time" "github.com/cespare/cp" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/internal/build" "github.com/ethereum/go-ethereum/params" ) @@ -458,7 +459,7 @@ func archiveUpload(archive string, blobstore string, signer string, signify stri } if signify != "" { key := getenvBase64(string(signify)) - if err := build.SignifySignFile(archive, archive+".sig", string(key)); err != nil { + if err := crypto.SignifySignFile(archive, archive+".sig", string(key)); err != nil { return err } } diff --git a/crypto/signify.go b/crypto/signify.go index 7205f956babd..f94a2f787d24 100644 --- a/crypto/signify.go +++ b/crypto/signify.go @@ -31,7 +31,7 @@ import ( var ( errInvalidKeyHeader = errors.New("Incorrect key header") - errInvalidKeyLength = errors.New("invalid, key length != 42") + errInvalidKeyLength = errors.New("invalid, key length != 104") ) func readSKey(key []byte) (ed25519.PrivateKey, error) { @@ -75,9 +75,12 @@ func SignifySignFile(input string, output string, key string) error { return err } - sigdata := []byte("Ed") - copy(sigdata, keydata[:2]) - sigdata = append(sigdata, keydata[32:40]...) + header := keydata[:2] + keyNum := keydata[32:40] + + var sigdata []byte + sigdata = append(sigdata, header...) + sigdata = append(sigdata, keyNum...) sigdata = append(sigdata, ed25519.Sign(skey, filedata)...) out.WriteString(fmt.Sprintf("untrusted comment: verify with geth.pub\n%s\n", base64.StdEncoding.EncodeToString(sigdata))) From 3e1f47c8efa2e49da5b10c842d16f0bafea1c267 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Wed, 18 Nov 2020 13:08:08 +0100 Subject: [PATCH 10/25] crypto, ci: support minisign output --- build/ci.go | 2 +- crypto/signify.go | 14 ++++++++++++-- crypto/signify_test.go | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/build/ci.go b/build/ci.go index 2c8f4ef5e9f1..460ecff44c19 100644 --- a/build/ci.go +++ b/build/ci.go @@ -459,7 +459,7 @@ func archiveUpload(archive string, blobstore string, signer string, signify stri } if signify != "" { key := getenvBase64(string(signify)) - if err := crypto.SignifySignFile(archive, archive+".sig", string(key)); err != nil { + if err := crypto.SignifySignFile(archive, archive+".sig", string(key), fmt.Sprintf("%d", time.Now().UTC().Unix())); err != nil { return err } } diff --git a/crypto/signify.go b/crypto/signify.go index f94a2f787d24..c6e2dc96eff7 100644 --- a/crypto/signify.go +++ b/crypto/signify.go @@ -48,7 +48,7 @@ func readSKey(key []byte) (ed25519.PrivateKey, error) { } // SignifySignFile creates a signature of the input file. -func SignifySignFile(input string, output string, key string) error { +func SignifySignFile(input string, output string, key string, trustedComment string) error { in, err := os.Open(input) if err != nil { return err @@ -75,14 +75,24 @@ func SignifySignFile(input string, output string, key string) error { return err } + rawSig := ed25519.Sign(skey, filedata) header := keydata[:2] keyNum := keydata[32:40] var sigdata []byte sigdata = append(sigdata, header...) sigdata = append(sigdata, keyNum...) - sigdata = append(sigdata, ed25519.Sign(skey, filedata)...) + sigdata = append(sigdata, rawSig...) out.WriteString(fmt.Sprintf("untrusted comment: verify with geth.pub\n%s\n", base64.StdEncoding.EncodeToString(sigdata))) + + // Add the trusted comment if available (minisign only) + if trustedComment != "" { + var sigAndComment []byte + sigAndComment = append(sigAndComment, rawSig...) + sigAndComment = append(sigAndComment, []byte(trustedComment)...) + out.WriteString(fmt.Sprintf("trusted comment: %s\n%s\n", trustedComment, base64.StdEncoding.EncodeToString(ed25519.Sign(skey, sigAndComment)))) + } + return nil } diff --git a/crypto/signify_test.go b/crypto/signify_test.go index 3a78ff075043..d2ae450d361d 100644 --- a/crypto/signify_test.go +++ b/crypto/signify_test.go @@ -55,7 +55,7 @@ func TestSignify(t *testing.T) { t.Fatal(err) } - err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), testSecKey) + err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), testSecKey, "croissants") if err != nil { t.Fatal(err) } From f035c156a4830933373fd30835feaae81679f9e3 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Wed, 18 Nov 2020 15:42:44 +0100 Subject: [PATCH 11/25] only accept one-line trusted comments --- crypto/signify.go | 8 ++++++++ crypto/signify_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/crypto/signify.go b/crypto/signify.go index c6e2dc96eff7..f15851ed33cf 100644 --- a/crypto/signify.go +++ b/crypto/signify.go @@ -25,6 +25,7 @@ import ( "fmt" "io/ioutil" "os" + "strings" "golang.org/x/crypto/ed25519" ) @@ -88,6 +89,13 @@ func SignifySignFile(input string, output string, key string, trustedComment str // Add the trusted comment if available (minisign only) if trustedComment != "" { + // Check that the trusted comment fits in one line + firstCRIndex := strings.IndexByte(trustedComment, 13) + firstLFIndex := strings.IndexByte(trustedComment, 10) + if (firstCRIndex >= 0 && firstCRIndex < len(trustedComment)-1) || (firstLFIndex >= 0 && firstLFIndex < len(trustedComment)-1) { + return errors.New("trusted comment must fit on a single line") + } + var sigAndComment []byte sigAndComment = append(sigAndComment, rawSig...) sigAndComment = append(sigAndComment, []byte(trustedComment)...) diff --git a/crypto/signify_test.go b/crypto/signify_test.go index d2ae450d361d..d1f3eb8bad77 100644 --- a/crypto/signify_test.go +++ b/crypto/signify_test.go @@ -105,3 +105,30 @@ func TestSignify(t *testing.T) { t.Fatal("invalid signature") } } + +func TestSignifyTrustedCommentTooManyLines(t *testing.T) { + tmpFile, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpFile.Name()) + defer tmpFile.Close() + + rand.Seed(time.Now().UnixNano()) + + data := make([]byte, 1024) + rand.Read(data) + tmpFile.Write(data) + + if err = tmpFile.Close(); err != nil { + t.Fatal(err) + } + + err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), testSecKey, "crois\nsants") + fmt.Println(err) + if err == nil || err.Error() == "" { + t.Fatalf("should have errored on a multi-line trusted comment, got %v", err) + } + defer os.Remove(fmt.Sprintf("%s.sig", tmpFile.Name())) + +} From 80c928c0640254f76205c642e0a87eeaaf65d7cb Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Wed, 18 Nov 2020 16:07:53 +0100 Subject: [PATCH 12/25] configurable untrusted comments --- build/ci.go | 2 +- crypto/signify.go | 19 ++++++++++++++----- crypto/signify_test.go | 4 ++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/build/ci.go b/build/ci.go index 460ecff44c19..34ba7205f952 100644 --- a/build/ci.go +++ b/build/ci.go @@ -459,7 +459,7 @@ func archiveUpload(archive string, blobstore string, signer string, signify stri } if signify != "" { key := getenvBase64(string(signify)) - if err := crypto.SignifySignFile(archive, archive+".sig", string(key), fmt.Sprintf("%d", time.Now().UTC().Unix())); err != nil { + if err := crypto.SignifySignFile(archive, archive+".sig", string(key), "verify with geth.pub", fmt.Sprintf("%d", time.Now().UTC().Unix())); err != nil { return err } } diff --git a/crypto/signify.go b/crypto/signify.go index f15851ed33cf..37c231d011a7 100644 --- a/crypto/signify.go +++ b/crypto/signify.go @@ -48,8 +48,14 @@ func readSKey(key []byte) (ed25519.PrivateKey, error) { } +func isCommentOnlyOneLine(comment string) bool { + firstCRIndex := strings.IndexByte(comment, 13) + firstLFIndex := strings.IndexByte(comment, 10) + return (firstCRIndex >= 0 && firstCRIndex < len(comment)-1) || (firstLFIndex >= 0 && firstLFIndex < len(comment)-1) +} + // SignifySignFile creates a signature of the input file. -func SignifySignFile(input string, output string, key string, trustedComment string) error { +func SignifySignFile(input string, output string, key string, unTrustedComment string, trustedComment string) error { in, err := os.Open(input) if err != nil { return err @@ -85,14 +91,17 @@ func SignifySignFile(input string, output string, key string, trustedComment str sigdata = append(sigdata, keyNum...) sigdata = append(sigdata, rawSig...) - out.WriteString(fmt.Sprintf("untrusted comment: verify with geth.pub\n%s\n", base64.StdEncoding.EncodeToString(sigdata))) + // Check that the trusted comment fits in one line + if isCommentOnlyOneLine(unTrustedComment) { + return errors.New("untrusted comment must fit on a single line") + } + + out.WriteString(fmt.Sprintf("untrusted comment: %s\n%s\n", unTrustedComment, base64.StdEncoding.EncodeToString(sigdata))) // Add the trusted comment if available (minisign only) if trustedComment != "" { // Check that the trusted comment fits in one line - firstCRIndex := strings.IndexByte(trustedComment, 13) - firstLFIndex := strings.IndexByte(trustedComment, 10) - if (firstCRIndex >= 0 && firstCRIndex < len(trustedComment)-1) || (firstLFIndex >= 0 && firstLFIndex < len(trustedComment)-1) { + if isCommentOnlyOneLine(trustedComment) { return errors.New("trusted comment must fit on a single line") } diff --git a/crypto/signify_test.go b/crypto/signify_test.go index d1f3eb8bad77..32f647597770 100644 --- a/crypto/signify_test.go +++ b/crypto/signify_test.go @@ -55,7 +55,7 @@ func TestSignify(t *testing.T) { t.Fatal(err) } - err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), testSecKey, "croissants") + err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), testSecKey, "clé", "croissants") if err != nil { t.Fatal(err) } @@ -124,7 +124,7 @@ func TestSignifyTrustedCommentTooManyLines(t *testing.T) { t.Fatal(err) } - err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), testSecKey, "crois\nsants") + err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), testSecKey, "", "crois\nsants") fmt.Println(err) if err == nil || err.Error() == "" { t.Fatalf("should have errored on a multi-line trusted comment, got %v", err) From 951d75c924355a76adcb6efd4af745d8b2a815b6 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Wed, 18 Nov 2020 16:11:38 +0100 Subject: [PATCH 13/25] code cleanup in tests --- crypto/signify_test.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/crypto/signify_test.go b/crypto/signify_test.go index 32f647597770..620545f84f7b 100644 --- a/crypto/signify_test.go +++ b/crypto/signify_test.go @@ -20,7 +20,6 @@ package crypto import ( - "fmt" "io/ioutil" "math/rand" "os" @@ -55,11 +54,11 @@ func TestSignify(t *testing.T) { t.Fatal(err) } - err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), testSecKey, "clé", "croissants") + err = SignifySignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "clé", "croissants") if err != nil { t.Fatal(err) } - defer os.Remove(fmt.Sprintf("%s.sig", tmpFile.Name())) + defer os.Remove(tmpFile.Name() + ".sig") // if signify-openbsd is present, check the signature. // signify-openbsd will be present in CI. @@ -78,10 +77,9 @@ func TestSignify(t *testing.T) { pubKeyFile.WriteString(testPubKey) pubKeyFile.WriteString("\n") - cmd := exec.Command("signify-openbsd", "-V", "-p", pubKeyFile.Name(), "-x", fmt.Sprintf("%s.sig", tmpFile.Name()), "-m", tmpFile.Name()) + cmd := exec.Command("signify-openbsd", "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name()) if output, err := cmd.CombinedOutput(); err != nil { - fmt.Println(string(output)) - t.Fatalf("could not verify the file: %v", err) + t.Fatalf("could not verify the file: %v, output: \n%s", err, output) } } } @@ -124,11 +122,10 @@ func TestSignifyTrustedCommentTooManyLines(t *testing.T) { t.Fatal(err) } - err = SignifySignFile(tmpFile.Name(), fmt.Sprintf("%s.sig", tmpFile.Name()), testSecKey, "", "crois\nsants") - fmt.Println(err) + err = SignifySignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "", "crois\nsants") if err == nil || err.Error() == "" { t.Fatalf("should have errored on a multi-line trusted comment, got %v", err) } - defer os.Remove(fmt.Sprintf("%s.sig", tmpFile.Name())) + defer os.Remove(tmpFile.Name() + ".sig") } From 68f8638d803d9768827f0fe67c50487559899dfb Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Fri, 20 Nov 2020 13:12:00 +0100 Subject: [PATCH 14/25] revert to use ed25519 from the stdlib --- crypto/signify.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/signify.go b/crypto/signify.go index 37c231d011a7..812bdca8a10a 100644 --- a/crypto/signify.go +++ b/crypto/signify.go @@ -27,7 +27,7 @@ import ( "os" "strings" - "golang.org/x/crypto/ed25519" + "crypto/ed25519" ) var ( From 6726a72edcdfde957e5d09b07215892cfeddef7c Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Mon, 23 Nov 2020 11:18:10 +0100 Subject: [PATCH 15/25] bug: fix for empty untrusted comments --- crypto/signify.go | 3 +++ crypto/signify_test.go | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/crypto/signify.go b/crypto/signify.go index 812bdca8a10a..864ba148daa2 100644 --- a/crypto/signify.go +++ b/crypto/signify.go @@ -96,6 +96,9 @@ func SignifySignFile(input string, output string, key string, unTrustedComment s return errors.New("untrusted comment must fit on a single line") } + if unTrustedComment == "" { + unTrustedComment = "verify with " + input + ".pub" + } out.WriteString(fmt.Sprintf("untrusted comment: %s\n%s\n", unTrustedComment, base64.StdEncoding.EncodeToString(sigdata))) // Add the trusted comment if available (minisign only) diff --git a/crypto/signify_test.go b/crypto/signify_test.go index 620545f84f7b..dfab1bb7dafd 100644 --- a/crypto/signify_test.go +++ b/crypto/signify_test.go @@ -128,4 +128,27 @@ func TestSignifyTrustedCommentTooManyLines(t *testing.T) { } defer os.Remove(tmpFile.Name() + ".sig") + // if signify-openbsd is present, check the signature. + // signify-openbsd will be present in CI. + if runtime.GOOS == "linux" { + cmd := exec.Command("which", "signify-openbsd") + if err = cmd.Run(); err == nil { + // Write the public key into the file to pass it as + // an argument to signify-openbsd + pubKeyFile, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(pubKeyFile.Name()) + defer pubKeyFile.Close() + pubKeyFile.WriteString("untrusted comment: signify public key\n") + pubKeyFile.WriteString(testPubKey) + pubKeyFile.WriteString("\n") + + cmd := exec.Command("signify-openbsd", "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name()) + if output, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("could not verify the file: %v, output: \n%s", err, output) + } + } + } } From 76886da2effcaa6f265260936bb3a33491150578 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Mon, 23 Nov 2020 11:40:08 +0100 Subject: [PATCH 16/25] write timestamp as comment if trusted comment isn't present --- crypto/signify.go | 25 +++++++++++---------- crypto/signify_test.go | 49 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/crypto/signify.go b/crypto/signify.go index 864ba148daa2..e226b240abe0 100644 --- a/crypto/signify.go +++ b/crypto/signify.go @@ -26,6 +26,7 @@ import ( "io/ioutil" "os" "strings" + "time" "crypto/ed25519" ) @@ -101,18 +102,20 @@ func SignifySignFile(input string, output string, key string, unTrustedComment s } out.WriteString(fmt.Sprintf("untrusted comment: %s\n%s\n", unTrustedComment, base64.StdEncoding.EncodeToString(sigdata))) - // Add the trusted comment if available (minisign only) - if trustedComment != "" { - // Check that the trusted comment fits in one line - if isCommentOnlyOneLine(trustedComment) { - return errors.New("trusted comment must fit on a single line") - } - - var sigAndComment []byte - sigAndComment = append(sigAndComment, rawSig...) - sigAndComment = append(sigAndComment, []byte(trustedComment)...) - out.WriteString(fmt.Sprintf("trusted comment: %s\n%s\n", trustedComment, base64.StdEncoding.EncodeToString(ed25519.Sign(skey, sigAndComment)))) + // Add the trusted comment if unavailable + if trustedComment == "" { + trustedComment = fmt.Sprintf("timestamp:%d", time.Now().Unix()) } + // Check that the trusted comment fits in one line + if commentHasManyLines(trustedComment) { + return errors.New("trusted comment must fit on a single line") + } + + var sigAndComment []byte + sigAndComment = append(sigAndComment, rawSig...) + sigAndComment = append(sigAndComment, []byte(trustedComment)...) + out.WriteString(fmt.Sprintf("trusted comment: %s\n%s\n", trustedComment, base64.StdEncoding.EncodeToString(ed25519.Sign(skey, sigAndComment)))) + return nil } diff --git a/crypto/signify_test.go b/crypto/signify_test.go index dfab1bb7dafd..27435d6af251 100644 --- a/crypto/signify_test.go +++ b/crypto/signify_test.go @@ -152,3 +152,52 @@ func TestSignifyTrustedCommentTooManyLines(t *testing.T) { } } } + +func TestSignifyTrustedCommentEmpty(t *testing.T) { + tmpFile, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpFile.Name()) + defer tmpFile.Close() + + rand.Seed(time.Now().UnixNano()) + + data := make([]byte, 1024) + rand.Read(data) + tmpFile.Write(data) + + if err = tmpFile.Close(); err != nil { + t.Fatal(err) + } + + err = SignifySignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpFile.Name() + ".sig") + + // if signify-openbsd is present, check the signature. + // signify-openbsd will be present in CI. + if runtime.GOOS == "linux" { + cmd := exec.Command("which", "signify-openbsd") + if err = cmd.Run(); err == nil { + // Write the public key into the file to pass it as + // an argument to signify-openbsd + pubKeyFile, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(pubKeyFile.Name()) + defer pubKeyFile.Close() + pubKeyFile.WriteString("untrusted comment: signify public key\n") + pubKeyFile.WriteString(testPubKey) + pubKeyFile.WriteString("\n") + + cmd := exec.Command("signify-openbsd", "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name()) + if output, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("could not verify the file: %v, output: \n%s", err, output) + } + } + } +} From 3fe9eb6066e3eaec8635beb46b2eb811f4d7f492 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Mon, 23 Nov 2020 11:49:35 +0100 Subject: [PATCH 17/25] rename line checker to commentHasManyLines --- crypto/signify.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/signify.go b/crypto/signify.go index e226b240abe0..784a4d47b40c 100644 --- a/crypto/signify.go +++ b/crypto/signify.go @@ -49,7 +49,7 @@ func readSKey(key []byte) (ed25519.PrivateKey, error) { } -func isCommentOnlyOneLine(comment string) bool { +func commentHasManyLines(comment string) bool { firstCRIndex := strings.IndexByte(comment, 13) firstLFIndex := strings.IndexByte(comment, 10) return (firstCRIndex >= 0 && firstCRIndex < len(comment)-1) || (firstLFIndex >= 0 && firstLFIndex < len(comment)-1) @@ -93,7 +93,7 @@ func SignifySignFile(input string, output string, key string, unTrustedComment s sigdata = append(sigdata, rawSig...) // Check that the trusted comment fits in one line - if isCommentOnlyOneLine(unTrustedComment) { + if commentHasManyLines(unTrustedComment) { return errors.New("untrusted comment must fit on a single line") } From dfac93ae2e2f7ff5c2cdbccd62cb1bca32376145 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Mon, 23 Nov 2020 12:43:03 +0100 Subject: [PATCH 18/25] crypto: added signify fuzzer (#6) * crypto: added signify fuzzer * stuff * crypto: updated signify fuzzer to fuzz comments * crypto: repro signify crashes * rebased fuzzer on build-signify branch * hide fuzzer behind gofuzz build flag --- crypto/signify_fuzz.go | 152 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 crypto/signify_fuzz.go diff --git a/crypto/signify_fuzz.go b/crypto/signify_fuzz.go new file mode 100644 index 000000000000..be7f8a6dddba --- /dev/null +++ b/crypto/signify_fuzz.go @@ -0,0 +1,152 @@ +// Copyright 2020 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build gofuzz + +package crypto + +import ( + "bufio" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "runtime" + + fuzz "github.com/google/gofuzz" + "github.com/jedisct1/go-minisign" +) + +func Fuzz(data []byte) int { + if len(data) < 32 { + return -1 + } + tmpFile, err := ioutil.TempFile("", "") + if err != nil { + panic(err) + } + defer os.Remove(tmpFile.Name()) + defer tmpFile.Close() + + testSecKey, testPubKey := createKeyPair() + // Create message + tmpFile.Write(data) + if err = tmpFile.Close(); err != nil { + panic(err) + } + // Fuzz comments + var untrustedComment string + var trustedComment string + f := fuzz.NewFromGoFuzz(data) + f.Fuzz(&untrustedComment) + f.Fuzz(&trustedComment) + fmt.Printf("untrusted: %v\n", untrustedComment) + fmt.Printf("trusted: %v\n", trustedComment) + + err = SignifySignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, untrustedComment, trustedComment) + if err != nil { + panic(err) + } + defer os.Remove(tmpFile.Name() + ".sig") + + signify := "signify" + path := os.Getenv("SIGNIFY") + if path != "" { + signify = path + } + + // if signify-openbsd is present, check the signature. + // signify-openbsd will be present in CI. + if runtime.GOOS == "linux" { + cmd := exec.Command("which", signify) + if err = cmd.Run(); err == nil { + // Write the public key into the file to pass it as + // an argument to signify-openbsd + pubKeyFile, err := ioutil.TempFile("", "") + if err != nil { + panic(err) + } + defer os.Remove(pubKeyFile.Name()) + defer pubKeyFile.Close() + pubKeyFile.WriteString("untrusted comment: signify public key\n") + pubKeyFile.WriteString(testPubKey) + pubKeyFile.WriteString("\n") + + cmd := exec.Command(signify, "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name()) + if output, err := cmd.CombinedOutput(); err != nil { + panic(fmt.Sprintf("could not verify the file: %v, output: \n%s", err, output)) + } + } else { + panic(err) + } + } + + // Verify the signature using a golang library + sig, err := minisign.NewSignatureFromFile(tmpFile.Name() + ".sig") + if err != nil { + panic(err) + } + + pKey, err := minisign.NewPublicKey(testPubKey) + if err != nil { + panic(err) + } + + valid, err := pKey.VerifyFromFile(tmpFile.Name(), sig) + if err != nil { + panic(err) + } + if !valid { + panic("invalid signature") + } + return 1 +} + +func getKey(fileS string) (string, error) { + file, err := os.Open(fileS) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + // Discard the first line + scanner.Scan() + scanner.Scan() + return scanner.Text(), scanner.Err() +} + +func createKeyPair() (string, string) { + // Create key and put it in correct format + tmpKey, err := ioutil.TempFile("", "") + defer os.Remove(tmpKey.Name()) + defer os.Remove(tmpKey.Name() + ".pub") + defer os.Remove(tmpKey.Name() + ".sec") + cmd := exec.Command("signify", "-G", "-n", "-p", tmpKey.Name()+".pub", "-s", tmpKey.Name()+".sec") + if output, err := cmd.CombinedOutput(); err != nil { + panic(fmt.Sprintf("could not verify the file: %v, output: \n%s", err, output)) + } + secKey, err := getKey(tmpKey.Name() + ".sec") + if err != nil { + panic(err) + } + pubKey, err := getKey(tmpKey.Name() + ".pub") + if err != nil { + panic(err) + } + return secKey, pubKey +} From b2cf7c63614bb25a9339db2c7562dfa413aece41 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Mon, 23 Nov 2020 13:44:58 +0100 Subject: [PATCH 19/25] extract key data inside a single function --- crypto/signify.go | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/crypto/signify.go b/crypto/signify.go index 784a4d47b40c..a99870dcb822 100644 --- a/crypto/signify.go +++ b/crypto/signify.go @@ -36,17 +36,21 @@ var ( errInvalidKeyLength = errors.New("invalid, key length != 104") ) -func readSKey(key []byte) (ed25519.PrivateKey, error) { - if len(key) != 104 { - return nil, errInvalidKeyLength +func parsePrivateKey(key string) (ed25519.PrivateKey, []byte, []byte, error) { + keydata, err := base64.StdEncoding.DecodeString(key) + if err != nil { + return nil, nil, nil, err } - if string(key[:2]) != "Ed" { - return nil, errInvalidKeyHeader + if len(keydata) != 104 { + return nil, nil, nil, errInvalidKeyLength } - return ed25519.PrivateKey(key[40:]), nil + if string(keydata[:2]) != "Ed" { + return nil, nil, nil, errInvalidKeyHeader + } + return ed25519.PrivateKey(keydata[40:]), keydata[:2], keydata[32:40], nil } func commentHasManyLines(comment string) bool { @@ -69,11 +73,7 @@ func SignifySignFile(input string, output string, key string, unTrustedComment s } defer out.Close() - keydata, err := base64.StdEncoding.DecodeString(key) - if err != nil { - return err - } - skey, err := readSKey(keydata) + skey, header, keyNum, err := parsePrivateKey(key) if err != nil { return err } @@ -84,8 +84,6 @@ func SignifySignFile(input string, output string, key string, unTrustedComment s } rawSig := ed25519.Sign(skey, filedata) - header := keydata[:2] - keyNum := keydata[32:40] var sigdata []byte sigdata = append(sigdata, header...) From 76db596b14b8bb8d3e0f0626d0d41d228b23aef4 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Mon, 23 Nov 2020 14:06:44 +0100 Subject: [PATCH 20/25] don't treat \r as a newline --- crypto/signify.go | 3 +-- crypto/signify_test.go | 49 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/crypto/signify.go b/crypto/signify.go index a99870dcb822..f61884f4de9b 100644 --- a/crypto/signify.go +++ b/crypto/signify.go @@ -54,9 +54,8 @@ func parsePrivateKey(key string) (ed25519.PrivateKey, []byte, []byte, error) { } func commentHasManyLines(comment string) bool { - firstCRIndex := strings.IndexByte(comment, 13) firstLFIndex := strings.IndexByte(comment, 10) - return (firstCRIndex >= 0 && firstCRIndex < len(comment)-1) || (firstLFIndex >= 0 && firstLFIndex < len(comment)-1) + return (firstLFIndex >= 0 && firstLFIndex < len(comment)-1) } // SignifySignFile creates a signature of the input file. diff --git a/crypto/signify_test.go b/crypto/signify_test.go index 27435d6af251..0499d4044049 100644 --- a/crypto/signify_test.go +++ b/crypto/signify_test.go @@ -153,6 +153,55 @@ func TestSignifyTrustedCommentTooManyLines(t *testing.T) { } } +func TestSignifyTrustedCommentTooManyLinesLF(t *testing.T) { + tmpFile, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpFile.Name()) + defer tmpFile.Close() + + rand.Seed(time.Now().UnixNano()) + + data := make([]byte, 1024) + rand.Read(data) + tmpFile.Write(data) + + if err = tmpFile.Close(); err != nil { + t.Fatal(err) + } + + err = SignifySignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "crois\rsants", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpFile.Name() + ".sig") + + // if signify-openbsd is present, check the signature. + // signify-openbsd will be present in CI. + if runtime.GOOS == "linux" { + cmd := exec.Command("which", "signify-openbsd") + if err = cmd.Run(); err == nil { + // Write the public key into the file to pass it as + // an argument to signify-openbsd + pubKeyFile, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(pubKeyFile.Name()) + defer pubKeyFile.Close() + pubKeyFile.WriteString("untrusted comment: signify public key\n") + pubKeyFile.WriteString(testPubKey) + pubKeyFile.WriteString("\n") + + cmd := exec.Command("signify-openbsd", "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name()) + if output, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("could not verify the file: %v, output: \n%s", err, output) + } + } + } +} + func TestSignifyTrustedCommentEmpty(t *testing.T) { tmpFile, err := ioutil.TempFile("", "") if err != nil { From f92a4504c12430e7291b7213e97036534389578c Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Tue, 24 Nov 2020 12:39:45 +0100 Subject: [PATCH 21/25] travis: fix signing command line --- .travis.yml | 61 +++++++++++++++++++++-------------------------------- build/ci.go | 2 +- 2 files changed, 25 insertions(+), 38 deletions(-) diff --git a/.travis.yml b/.travis.yml index b1ca4c737125..f63503be020d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -69,62 +69,52 @@ jobs: script: # Build for the primary platforms that Trusty can manage - go run build/ci.go install -dlgo - - go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - go run build/ci.go archive -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds + - go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go install -dlgo -arch 386 - - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds + - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds # Switch over GCC to cross compilation (breaks 386, hence why do it here only) - sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross - sudo ln -s /usr/include/asm-generic /usr/include/asm - GOARM=5 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - - GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds + - GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds - GOARM=6 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - - GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds + - GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds - GOARM=7 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabihf-gcc - - GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds + - GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go install -dlgo -arch arm64 -cc aarch64-linux-gnu-gcc - - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds - - # This builder does the Linux Azure MIPS xgo uploads - - stage: build - if: type = push - os: linux - dist: xenial - services: - - docker - go: 1.15.x - env: - - azure-linux-mips + - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds + + # This builder does the Linux Azure MIPS xgo uploads + - stage: build + if: type = push + os: linux + dist: xenial + services: + - docker + go: 1.15.x + env: + - azure-linux-mips - GO111MODULE=on git: submodules: false # avoid cloning ethereum/tests script: - go run build/ci.go xgo --alltools -- --targets=linux/mips --ldflags '-extldflags "-static"' -v - for bin in build/bin/*-linux-mips; do mv -f "${bin}" "${bin/-linux-mips/}"; done - - go run build/ci.go archive -arch mips -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - go run build/ci.go archive -arch mips -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds + - go run build/ci.go archive -arch mips -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go xgo --alltools -- --targets=linux/mipsle --ldflags '-extldflags "-static"' -v - for bin in build/bin/*-linux-mipsle; do mv -f "${bin}" "${bin/-linux-mipsle/}"; done - - go run build/ci.go archive -arch mipsle -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - go run build/ci.go archive -arch mipsle -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds + - go run build/ci.go archive -arch mipsle -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go xgo --alltools -- --targets=linux/mips64 --ldflags '-extldflags "-static"' -v - for bin in build/bin/*-linux-mips64; do mv -f "${bin}" "${bin/-linux-mips64/}"; done - - go run build/ci.go archive -arch mips64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - go run build/ci.go archive -arch mips64 -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds + - go run build/ci.go archive -arch mips64 -type tar -signer LINUX_SIGNING_KEY signify LINUX_SIGNIFY_KEY -upload gethstore/builds - go run build/ci.go xgo --alltools -- --targets=linux/mips64le --ldflags '-extldflags "-static"' -v - for bin in build/bin/*-linux-mips64le; do mv -f "${bin}" "${bin/-linux-mips64le/}"; done - - go run build/ci.go archive -arch mips64le -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds - - go run build/ci.go archive -arch mips64le -type tar -signer LINUX_SIGNIFY_KEY -upload gethstore/builds + - go run build/ci.go archive -arch mips64le -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds # This builder does the Android Maven and Azure uploads - stage: build @@ -163,8 +153,7 @@ jobs: - mkdir -p $GOPATH/src/github.com/ethereum - ln -s `pwd` $GOPATH/src/github.com/ethereum/go-ethereum - - go run build/ci.go aar -signer ANDROID_SIGNING_KEY -deploy https://oss.sonatype.org -upload gethstore/builds - - go run build/ci.go aar -signer ANDROID_SIGNIFY_KEY -deploy https://oss.sonatype.org -upload gethstore/builds + - go run build/ci.go aar -signer ANDROID_SIGNING_KEY -signify ANDROID_SIGNIFY_KEY -deploy https://oss.sonatype.org -upload gethstore/builds # This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads - stage: build @@ -180,8 +169,7 @@ jobs: submodules: false # avoid cloning ethereum/tests script: - go run build/ci.go install -dlgo - - go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -upload gethstore/builds - - go run build/ci.go archive -type tar -signer OSX_SIGNIFY_KEY -upload gethstore/builds + - go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -signify OSX_SIGNIFY_KEY -upload gethstore/builds # Build the iOS framework and upload it to CocoaPods and Azure - gem uninstall cocoapods -a -x @@ -196,8 +184,7 @@ jobs: # Workaround for https://github.com/golang/go/issues/23749 - export CGO_CFLAGS_ALLOW='-fmodules|-fblocks|-fobjc-arc' - - go run build/ci.go xcode -signer IOS_SIGNING_KEY -deploy trunk -upload gethstore/builds - - go run build/ci.go xcode -signer IOS_SIGNIFY_KEY -deploy trunk -upload gethstore/builds + - go run build/ci.go xcode -signer IOS_SIGNING_KEY -signify IOS_SIGNIFY_KEY -deploy trunk -upload gethstore/builds # These builders run the tests - stage: build diff --git a/build/ci.go b/build/ci.go index 34ba7205f952..1b2cde7844a1 100644 --- a/build/ci.go +++ b/build/ci.go @@ -26,7 +26,7 @@ Available commands are: install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables test [ -coverage ] [ packages... ] -- runs the tests lint -- runs certain pre-selected linters - archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -upload dest ] -- archives build artifacts + archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts importkeys -- imports signing keys from env debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package nsis -- creates a Windows NSIS installer From 6fa7fc6943ea9500dfabce71ad0f54f64804ce1b Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Tue, 24 Nov 2020 14:44:16 +0100 Subject: [PATCH 22/25] do not use an external binary in tests --- .travis.yml | 2 - crypto/signify_fuzz.go | 44 +++++++++---------- crypto/signify_test.go | 98 ------------------------------------------ 3 files changed, 20 insertions(+), 124 deletions(-) diff --git a/.travis.yml b/.travis.yml index f63503be020d..c9f0cf3969d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,7 +44,6 @@ jobs: - fakeroot - python-bzrlib - python-paramiko - - signify-openbsd script: - echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts - go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder " @@ -65,7 +64,6 @@ jobs: apt: packages: - gcc-multilib - - signify-openbsd script: # Build for the primary platforms that Trusty can manage - go run build/ci.go install -dlgo diff --git a/crypto/signify_fuzz.go b/crypto/signify_fuzz.go index be7f8a6dddba..42df7b41cc0c 100644 --- a/crypto/signify_fuzz.go +++ b/crypto/signify_fuzz.go @@ -69,30 +69,26 @@ func Fuzz(data []byte) int { signify = path } - // if signify-openbsd is present, check the signature. - // signify-openbsd will be present in CI. - if runtime.GOOS == "linux" { - cmd := exec.Command("which", signify) - if err = cmd.Run(); err == nil { - // Write the public key into the file to pass it as - // an argument to signify-openbsd - pubKeyFile, err := ioutil.TempFile("", "") - if err != nil { - panic(err) - } - defer os.Remove(pubKeyFile.Name()) - defer pubKeyFile.Close() - pubKeyFile.WriteString("untrusted comment: signify public key\n") - pubKeyFile.WriteString(testPubKey) - pubKeyFile.WriteString("\n") - - cmd := exec.Command(signify, "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name()) - if output, err := cmd.CombinedOutput(); err != nil { - panic(fmt.Sprintf("could not verify the file: %v, output: \n%s", err, output)) - } - } else { - panic(err) - } + _, err := exec.LookPath(signify) + if err != nil { + panic(err) + } + + // Write the public key into the file to pass it as + // an argument to signify-openbsd + pubKeyFile, err := ioutil.TempFile("", "") + if err != nil { + panic(err) + } + defer os.Remove(pubKeyFile.Name()) + defer pubKeyFile.Close() + pubKeyFile.WriteString("untrusted comment: signify public key\n") + pubKeyFile.WriteString(testPubKey) + pubKeyFile.WriteString("\n") + + cmd := exec.Command(signify, "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name()) + if output, err := cmd.CombinedOutput(); err != nil { + panic(fmt.Sprintf("could not verify the file: %v, output: \n%s", err, output)) } // Verify the signature using a golang library diff --git a/crypto/signify_test.go b/crypto/signify_test.go index 0499d4044049..a22d81e9c971 100644 --- a/crypto/signify_test.go +++ b/crypto/signify_test.go @@ -23,8 +23,6 @@ import ( "io/ioutil" "math/rand" "os" - "os/exec" - "runtime" "testing" "time" @@ -60,30 +58,6 @@ func TestSignify(t *testing.T) { } defer os.Remove(tmpFile.Name() + ".sig") - // if signify-openbsd is present, check the signature. - // signify-openbsd will be present in CI. - if runtime.GOOS == "linux" { - cmd := exec.Command("which", "signify-openbsd") - if err = cmd.Run(); err == nil { - // Write the public key into the file to pass it as - // an argument to signify-openbsd - pubKeyFile, err := ioutil.TempFile("", "") - if err != nil { - t.Fatal(err) - } - defer os.Remove(pubKeyFile.Name()) - defer pubKeyFile.Close() - pubKeyFile.WriteString("untrusted comment: signify public key\n") - pubKeyFile.WriteString(testPubKey) - pubKeyFile.WriteString("\n") - - cmd := exec.Command("signify-openbsd", "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name()) - if output, err := cmd.CombinedOutput(); err != nil { - t.Fatalf("could not verify the file: %v, output: \n%s", err, output) - } - } - } - // Verify the signature using a golang library sig, err := minisign.NewSignatureFromFile(tmpFile.Name() + ".sig") if err != nil { @@ -127,30 +101,6 @@ func TestSignifyTrustedCommentTooManyLines(t *testing.T) { t.Fatalf("should have errored on a multi-line trusted comment, got %v", err) } defer os.Remove(tmpFile.Name() + ".sig") - - // if signify-openbsd is present, check the signature. - // signify-openbsd will be present in CI. - if runtime.GOOS == "linux" { - cmd := exec.Command("which", "signify-openbsd") - if err = cmd.Run(); err == nil { - // Write the public key into the file to pass it as - // an argument to signify-openbsd - pubKeyFile, err := ioutil.TempFile("", "") - if err != nil { - t.Fatal(err) - } - defer os.Remove(pubKeyFile.Name()) - defer pubKeyFile.Close() - pubKeyFile.WriteString("untrusted comment: signify public key\n") - pubKeyFile.WriteString(testPubKey) - pubKeyFile.WriteString("\n") - - cmd := exec.Command("signify-openbsd", "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name()) - if output, err := cmd.CombinedOutput(); err != nil { - t.Fatalf("could not verify the file: %v, output: \n%s", err, output) - } - } - } } func TestSignifyTrustedCommentTooManyLinesLF(t *testing.T) { @@ -176,30 +126,6 @@ func TestSignifyTrustedCommentTooManyLinesLF(t *testing.T) { t.Fatal(err) } defer os.Remove(tmpFile.Name() + ".sig") - - // if signify-openbsd is present, check the signature. - // signify-openbsd will be present in CI. - if runtime.GOOS == "linux" { - cmd := exec.Command("which", "signify-openbsd") - if err = cmd.Run(); err == nil { - // Write the public key into the file to pass it as - // an argument to signify-openbsd - pubKeyFile, err := ioutil.TempFile("", "") - if err != nil { - t.Fatal(err) - } - defer os.Remove(pubKeyFile.Name()) - defer pubKeyFile.Close() - pubKeyFile.WriteString("untrusted comment: signify public key\n") - pubKeyFile.WriteString(testPubKey) - pubKeyFile.WriteString("\n") - - cmd := exec.Command("signify-openbsd", "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name()) - if output, err := cmd.CombinedOutput(); err != nil { - t.Fatalf("could not verify the file: %v, output: \n%s", err, output) - } - } - } } func TestSignifyTrustedCommentEmpty(t *testing.T) { @@ -225,28 +151,4 @@ func TestSignifyTrustedCommentEmpty(t *testing.T) { t.Fatal(err) } defer os.Remove(tmpFile.Name() + ".sig") - - // if signify-openbsd is present, check the signature. - // signify-openbsd will be present in CI. - if runtime.GOOS == "linux" { - cmd := exec.Command("which", "signify-openbsd") - if err = cmd.Run(); err == nil { - // Write the public key into the file to pass it as - // an argument to signify-openbsd - pubKeyFile, err := ioutil.TempFile("", "") - if err != nil { - t.Fatal(err) - } - defer os.Remove(pubKeyFile.Name()) - defer pubKeyFile.Close() - pubKeyFile.WriteString("untrusted comment: signify public key\n") - pubKeyFile.WriteString(testPubKey) - pubKeyFile.WriteString("\n") - - cmd := exec.Command("signify-openbsd", "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name()) - if output, err := cmd.CombinedOutput(); err != nil { - t.Fatalf("could not verify the file: %v, output: \n%s", err, output) - } - } - } } From 40b8b5f72885c9848ee7cee991426761639c2577 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Tue, 24 Nov 2020 15:07:45 +0100 Subject: [PATCH 23/25] crypto: move signify to crypto/signify --- crypto/{ => signify}/signify.go | 2 +- crypto/{ => signify}/signify_fuzz.go | 2 +- crypto/{ => signify}/signify_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename crypto/{ => signify}/signify.go (99%) rename crypto/{ => signify}/signify_fuzz.go (99%) rename crypto/{ => signify}/signify_test.go (99%) diff --git a/crypto/signify.go b/crypto/signify/signify.go similarity index 99% rename from crypto/signify.go rename to crypto/signify/signify.go index f61884f4de9b..e86c4f09b0bd 100644 --- a/crypto/signify.go +++ b/crypto/signify/signify.go @@ -17,7 +17,7 @@ // signFile reads the contents of an input file and signs it (in armored format) // with the key provided, placing the signature into the output file. -package crypto +package signify import ( "encoding/base64" diff --git a/crypto/signify_fuzz.go b/crypto/signify/signify_fuzz.go similarity index 99% rename from crypto/signify_fuzz.go rename to crypto/signify/signify_fuzz.go index 42df7b41cc0c..d1bcf356a4db 100644 --- a/crypto/signify_fuzz.go +++ b/crypto/signify/signify_fuzz.go @@ -16,7 +16,7 @@ // +build gofuzz -package crypto +package signify import ( "bufio" diff --git a/crypto/signify_test.go b/crypto/signify/signify_test.go similarity index 99% rename from crypto/signify_test.go rename to crypto/signify/signify_test.go index a22d81e9c971..af77eaf227e9 100644 --- a/crypto/signify_test.go +++ b/crypto/signify/signify_test.go @@ -17,7 +17,7 @@ // signFile reads the contents of an input file and signs it (in armored format) // with the key provided, placing the signature into the output file. -package crypto +package signify import ( "io/ioutil" From 698af718aa7508ac7c58af412333a77b3f2582ef Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Fri, 27 Nov 2020 10:54:57 +0100 Subject: [PATCH 24/25] travis: fix formatting issue --- .travis.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index c9f0cf3969d5..d37458792a42 100644 --- a/.travis.yml +++ b/.travis.yml @@ -84,16 +84,16 @@ jobs: - go run build/ci.go install -dlgo -arch arm64 -cc aarch64-linux-gnu-gcc - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds - # This builder does the Linux Azure MIPS xgo uploads - - stage: build - if: type = push - os: linux - dist: xenial - services: - - docker - go: 1.15.x - env: - - azure-linux-mips + # This builder does the Linux Azure MIPS xgo uploads + - stage: build + if: type = push + os: linux + dist: xenial + services: + - docker + go: 1.15.x + env: + - azure-linux-mips - GO111MODULE=on git: submodules: false # avoid cloning ethereum/tests From b22cdb2bec2ad539a41376dccd24dd108a91cc94 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Fri, 27 Nov 2020 11:07:52 +0100 Subject: [PATCH 25/25] ci: fix linter build after package move --- build/ci.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/ci.go b/build/ci.go index 1b2cde7844a1..951b21f9108a 100644 --- a/build/ci.go +++ b/build/ci.go @@ -58,7 +58,7 @@ import ( "time" "github.com/cespare/cp" - "github.com/ethereum/go-ethereum/crypto" + signifyPkg "github.com/ethereum/go-ethereum/crypto/signify" "github.com/ethereum/go-ethereum/internal/build" "github.com/ethereum/go-ethereum/params" ) @@ -459,7 +459,7 @@ func archiveUpload(archive string, blobstore string, signer string, signify stri } if signify != "" { key := getenvBase64(string(signify)) - if err := crypto.SignifySignFile(archive, archive+".sig", string(key), "verify with geth.pub", fmt.Sprintf("%d", time.Now().UTC().Unix())); err != nil { + if err := signifyPkg.SignifySignFile(archive, archive+".sig", string(key), "verify with geth.pub", fmt.Sprintf("%d", time.Now().UTC().Unix())); err != nil { return err } }