-
Notifications
You must be signed in to change notification settings - Fork 20.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
crypto: signing builds with signify/minisign #21798
Changes from 6 commits
419369d
20331e9
ea463a2
0028e1d
d875837
9fb07a8
c4fee15
5eb3540
80d45d0
3e1f47c
f035c15
80c928c
951d75c
68f8638
6726a72
76886da
3fe9eb6
dfac93a
b2cf7c6
76db596
f92a450
6fa7fc6
40b8b5f
698af71
b22cdb2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// 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 <http://www.gnu.org/licenses/>. | ||
|
||
// 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) | ||
if err != nil { | ||
return err | ||
} | ||
skey, err := readSKey(keydata) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
filedata, err := ioutil.ReadAll(in) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
sigdata := []byte("Ed") | ||
copy(sigdata, keydata[:2]) | ||
gballet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
sigdata = append(sigdata, keydata[32:40]...) | ||
sigdata = append(sigdata, ed25519.Sign(skey, filedata)...) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wow, this looks really funky! At a glance, it looks like you're just happily appending the private key to the Perhaps you can make this more obvious, like
Also, I don't quite understand -- what is sitting on bytes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2-32 it contains data that is indicative of how the key got generated and also a checksum, which is not to be published in the signature. |
||
|
||
out.WriteString(fmt.Sprintf("untrusted comment: verify with geth.pub\n%s\n", base64.StdEncoding.EncodeToString(sigdata))) | ||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// 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 <http://www.gnu.org/licenses/>. | ||
|
||
// 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 ( | ||
"fmt" | ||
"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 { | ||
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) | ||
if 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) | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix those lines up.