Skip to content

Commit f935b1d

Browse files
authored
crypto/signify, build: fix archive signing with signify (#21977)
This fixes some issues in crypto/signify and makes release signing work. The archive signing step in ci.go used getenvBase64, which decodes the key data. This is incorrect here because crypto/signify already base64-decodes the key.
1 parent 915643a commit f935b1d

File tree

4 files changed

+66
-82
lines changed

4 files changed

+66
-82
lines changed

.travis.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,22 @@ jobs:
6767
script:
6868
# Build for the primary platforms that Trusty can manage
6969
- go run build/ci.go install -dlgo
70-
- go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds
70+
- go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
7171
- go run build/ci.go install -dlgo -arch 386
72-
- go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds
72+
- go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
7373

7474
# Switch over GCC to cross compilation (breaks 386, hence why do it here only)
7575
- 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
7676
- sudo ln -s /usr/include/asm-generic /usr/include/asm
7777

7878
- GOARM=5 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc
79-
- GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds
79+
- GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
8080
- GOARM=6 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc
81-
- GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds
81+
- GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
8282
- GOARM=7 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabihf-gcc
83-
- GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds
83+
- GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
8484
- go run build/ci.go install -dlgo -arch arm64 -cc aarch64-linux-gnu-gcc
85-
- go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds
85+
- go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
8686

8787
# This builder does the Linux Azure MIPS xgo uploads
8888
- stage: build
@@ -100,19 +100,19 @@ jobs:
100100
script:
101101
- go run build/ci.go xgo --alltools -- --targets=linux/mips --ldflags '-extldflags "-static"' -v
102102
- for bin in build/bin/*-linux-mips; do mv -f "${bin}" "${bin/-linux-mips/}"; done
103-
- go run build/ci.go archive -arch mips -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds
103+
- go run build/ci.go archive -arch mips -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
104104

105105
- go run build/ci.go xgo --alltools -- --targets=linux/mipsle --ldflags '-extldflags "-static"' -v
106106
- for bin in build/bin/*-linux-mipsle; do mv -f "${bin}" "${bin/-linux-mipsle/}"; done
107-
- go run build/ci.go archive -arch mipsle -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds
107+
- go run build/ci.go archive -arch mipsle -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
108108

109109
- go run build/ci.go xgo --alltools -- --targets=linux/mips64 --ldflags '-extldflags "-static"' -v
110110
- for bin in build/bin/*-linux-mips64; do mv -f "${bin}" "${bin/-linux-mips64/}"; done
111-
- go run build/ci.go archive -arch mips64 -type tar -signer LINUX_SIGNING_KEY signify LINUX_SIGNIFY_KEY -upload gethstore/builds
111+
- go run build/ci.go archive -arch mips64 -type tar -signer LINUX_SIGNING_KEY signify SIGNIFY_KEY -upload gethstore/builds
112112

113113
- go run build/ci.go xgo --alltools -- --targets=linux/mips64le --ldflags '-extldflags "-static"' -v
114114
- for bin in build/bin/*-linux-mips64le; do mv -f "${bin}" "${bin/-linux-mips64le/}"; done
115-
- go run build/ci.go archive -arch mips64le -type tar -signer LINUX_SIGNING_KEY -signify LINUX_SIGNIFY_KEY -upload gethstore/builds
115+
- go run build/ci.go archive -arch mips64le -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
116116

117117
# This builder does the Android Maven and Azure uploads
118118
- stage: build
@@ -151,7 +151,7 @@ jobs:
151151

152152
- mkdir -p $GOPATH/src/github.com/ethereum
153153
- ln -s `pwd` $GOPATH/src/github.com/ethereum/go-ethereum
154-
- go run build/ci.go aar -signer ANDROID_SIGNING_KEY -signify ANDROID_SIGNIFY_KEY -deploy https://oss.sonatype.org -upload gethstore/builds
154+
- go run build/ci.go aar -signer ANDROID_SIGNING_KEY -signify SIGNIFY_KEY -deploy https://oss.sonatype.org -upload gethstore/builds
155155

156156
# This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads
157157
- stage: build
@@ -167,7 +167,7 @@ jobs:
167167
submodules: false # avoid cloning ethereum/tests
168168
script:
169169
- go run build/ci.go install -dlgo
170-
- go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -signify OSX_SIGNIFY_KEY -upload gethstore/builds
170+
- go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
171171

172172
# Build the iOS framework and upload it to CocoaPods and Azure
173173
- gem uninstall cocoapods -a -x
@@ -182,7 +182,7 @@ jobs:
182182

183183
# Workaround for https://github.com/golang/go/issues/23749
184184
- export CGO_CFLAGS_ALLOW='-fmodules|-fblocks|-fobjc-arc'
185-
- go run build/ci.go xcode -signer IOS_SIGNING_KEY -signify IOS_SIGNIFY_KEY -deploy trunk -upload gethstore/builds
185+
- go run build/ci.go xcode -signer IOS_SIGNING_KEY -signify SIGNIFY_KEY -deploy trunk -upload gethstore/builds
186186

187187
# These builders run the tests
188188
- stage: build

build/ci.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import (
5858
"time"
5959

6060
"github.com/cespare/cp"
61-
signifyPkg "github.com/ethereum/go-ethereum/crypto/signify"
61+
"github.com/ethereum/go-ethereum/crypto/signify"
6262
"github.com/ethereum/go-ethereum/internal/build"
6363
"github.com/ethereum/go-ethereum/params"
6464
)
@@ -449,17 +449,19 @@ func archiveBasename(arch string, archiveVersion string) string {
449449
return platform + "-" + archiveVersion
450450
}
451451

452-
func archiveUpload(archive string, blobstore string, signer string, signify string) error {
452+
func archiveUpload(archive string, blobstore string, signer string, signifyVar string) error {
453453
// If signing was requested, generate the signature files
454454
if signer != "" {
455455
key := getenvBase64(signer)
456456
if err := build.PGPSignFile(archive, archive+".asc", string(key)); err != nil {
457457
return err
458458
}
459459
}
460-
if signify != "" {
461-
key := getenvBase64(string(signify))
462-
if err := signifyPkg.SignifySignFile(archive, archive+".sig", string(key), "verify with geth.pub", fmt.Sprintf("%d", time.Now().UTC().Unix())); err != nil {
460+
if signifyVar != "" {
461+
key := os.Getenv(signifyVar)
462+
untrustedComment := "verify with geth-release.pub"
463+
trustedComment := fmt.Sprintf("%s (%s)", archive, time.Now().UTC().Format(time.RFC1123))
464+
if err := signify.SignFile(archive, archive+".sig", key, untrustedComment, trustedComment); err != nil {
463465
return err
464466
}
465467
}
@@ -478,7 +480,7 @@ func archiveUpload(archive string, blobstore string, signer string, signify stri
478480
return err
479481
}
480482
}
481-
if signify != "" {
483+
if signifyVar != "" {
482484
if err := build.AzureBlobstoreUpload(archive+".sig", filepath.Base(archive+".sig"), auth); err != nil {
483485
return err
484486
}

crypto/signify/signify.go

Lines changed: 41 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -20,99 +20,81 @@
2020
package signify
2121

2222
import (
23+
"bytes"
24+
"crypto/ed25519"
2325
"encoding/base64"
2426
"errors"
2527
"fmt"
2628
"io/ioutil"
27-
"os"
2829
"strings"
2930
"time"
30-
31-
"crypto/ed25519"
3231
)
3332

3433
var (
35-
errInvalidKeyHeader = errors.New("Incorrect key header")
34+
errInvalidKeyHeader = errors.New("incorrect key header")
3635
errInvalidKeyLength = errors.New("invalid, key length != 104")
3736
)
3837

39-
func parsePrivateKey(key string) (ed25519.PrivateKey, []byte, []byte, error) {
38+
func parsePrivateKey(key string) (k ed25519.PrivateKey, header []byte, keyNum []byte, err error) {
4039
keydata, err := base64.StdEncoding.DecodeString(key)
4140
if err != nil {
4241
return nil, nil, nil, err
4342
}
44-
4543
if len(keydata) != 104 {
4644
return nil, nil, nil, errInvalidKeyLength
4745
}
48-
4946
if string(keydata[:2]) != "Ed" {
5047
return nil, nil, nil, errInvalidKeyHeader
5148
}
52-
5349
return ed25519.PrivateKey(keydata[40:]), keydata[:2], keydata[32:40], nil
5450
}
5551

56-
func commentHasManyLines(comment string) bool {
57-
firstLFIndex := strings.IndexByte(comment, 10)
58-
return (firstLFIndex >= 0 && firstLFIndex < len(comment)-1)
59-
}
60-
61-
// SignifySignFile creates a signature of the input file.
62-
func SignifySignFile(input string, output string, key string, unTrustedComment string, trustedComment string) error {
63-
in, err := os.Open(input)
64-
if err != nil {
65-
return err
52+
// SignFile creates a signature of the input file.
53+
//
54+
// This accepts base64 keys in the format created by the 'signify' tool.
55+
// The signature is written to the 'output' file.
56+
func SignFile(input string, output string, key string, untrustedComment string, trustedComment string) error {
57+
// Pre-check comments and ensure they're set to something.
58+
if strings.IndexByte(untrustedComment, '\n') >= 0 {
59+
return errors.New("untrusted comment must not contain newline")
6660
}
67-
defer in.Close()
68-
69-
out, err := os.Create(output)
70-
if err != nil {
71-
return err
61+
if strings.IndexByte(trustedComment, '\n') >= 0 {
62+
return errors.New("trusted comment must not contain newline")
63+
}
64+
if untrustedComment == "" {
65+
untrustedComment = "verify with " + input + ".pub"
66+
}
67+
if trustedComment == "" {
68+
trustedComment = fmt.Sprintf("timestamp:%d", time.Now().Unix())
7269
}
73-
defer out.Close()
7470

75-
skey, header, keyNum, err := parsePrivateKey(key)
71+
filedata, err := ioutil.ReadFile(input)
7672
if err != nil {
7773
return err
7874
}
79-
80-
filedata, err := ioutil.ReadAll(in)
75+
skey, header, keyNum, err := parsePrivateKey(key)
8176
if err != nil {
8277
return err
8378
}
8479

80+
// Create the main data signature.
8581
rawSig := ed25519.Sign(skey, filedata)
86-
87-
var sigdata []byte
88-
sigdata = append(sigdata, header...)
89-
sigdata = append(sigdata, keyNum...)
90-
sigdata = append(sigdata, rawSig...)
91-
92-
// Check that the trusted comment fits in one line
93-
if commentHasManyLines(unTrustedComment) {
94-
return errors.New("untrusted comment must fit on a single line")
95-
}
96-
97-
if unTrustedComment == "" {
98-
unTrustedComment = "verify with " + input + ".pub"
99-
}
100-
out.WriteString(fmt.Sprintf("untrusted comment: %s\n%s\n", unTrustedComment, base64.StdEncoding.EncodeToString(sigdata)))
101-
102-
// Add the trusted comment if unavailable
103-
if trustedComment == "" {
104-
trustedComment = fmt.Sprintf("timestamp:%d", time.Now().Unix())
105-
}
106-
107-
// Check that the trusted comment fits in one line
108-
if commentHasManyLines(trustedComment) {
109-
return errors.New("trusted comment must fit on a single line")
110-
}
111-
112-
var sigAndComment []byte
113-
sigAndComment = append(sigAndComment, rawSig...)
114-
sigAndComment = append(sigAndComment, []byte(trustedComment)...)
115-
out.WriteString(fmt.Sprintf("trusted comment: %s\n%s\n", trustedComment, base64.StdEncoding.EncodeToString(ed25519.Sign(skey, sigAndComment))))
116-
117-
return nil
82+
var dataSig []byte
83+
dataSig = append(dataSig, header...)
84+
dataSig = append(dataSig, keyNum...)
85+
dataSig = append(dataSig, rawSig...)
86+
87+
// Create the comment signature.
88+
var commentSigInput []byte
89+
commentSigInput = append(commentSigInput, rawSig...)
90+
commentSigInput = append(commentSigInput, []byte(trustedComment)...)
91+
commentSig := ed25519.Sign(skey, commentSigInput)
92+
93+
// Create the output file.
94+
var out = new(bytes.Buffer)
95+
fmt.Fprintln(out, "untrusted comment:", untrustedComment)
96+
fmt.Fprintln(out, base64.StdEncoding.EncodeToString(dataSig))
97+
fmt.Fprintln(out, "trusted comment:", trustedComment)
98+
fmt.Fprintln(out, base64.StdEncoding.EncodeToString(commentSig))
99+
return ioutil.WriteFile(output, out.Bytes(), 0644)
118100
}

crypto/signify/signify_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func TestSignify(t *testing.T) {
5252
t.Fatal(err)
5353
}
5454

55-
err = SignifySignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "clé", "croissants")
55+
err = SignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "clé", "croissants")
5656
if err != nil {
5757
t.Fatal(err)
5858
}
@@ -96,7 +96,7 @@ func TestSignifyTrustedCommentTooManyLines(t *testing.T) {
9696
t.Fatal(err)
9797
}
9898

99-
err = SignifySignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "", "crois\nsants")
99+
err = SignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "", "crois\nsants")
100100
if err == nil || err.Error() == "" {
101101
t.Fatalf("should have errored on a multi-line trusted comment, got %v", err)
102102
}
@@ -121,7 +121,7 @@ func TestSignifyTrustedCommentTooManyLinesLF(t *testing.T) {
121121
t.Fatal(err)
122122
}
123123

124-
err = SignifySignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "crois\rsants", "")
124+
err = SignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "crois\rsants", "")
125125
if err != nil {
126126
t.Fatal(err)
127127
}
@@ -146,7 +146,7 @@ func TestSignifyTrustedCommentEmpty(t *testing.T) {
146146
t.Fatal(err)
147147
}
148148

149-
err = SignifySignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "", "")
149+
err = SignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, "", "")
150150
if err != nil {
151151
t.Fatal(err)
152152
}

0 commit comments

Comments
 (0)