-
Notifications
You must be signed in to change notification settings - Fork 20.5k
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
Merged
Merged
Changes from 20 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
419369d
internal/build: implement signify's signing func
gballet 20331e9
Add signify to the ci utility
gballet ea463a2
fix output file format
gballet 0028e1d
Add unit test for signify
gballet d875837
holiman's + travis' feedback
gballet 9fb07a8
internal/build: verify signify's output
gballet c4fee15
crypto: move signify to common dir
gballet 5eb3540
use go-minisign to verify binaries
gballet 80d45d0
more holiman feedback
gballet 3e1f47c
crypto, ci: support minisign output
gballet f035c15
only accept one-line trusted comments
gballet 80c928c
configurable untrusted comments
gballet 951d75c
code cleanup in tests
gballet 68f8638
revert to use ed25519 from the stdlib
gballet 6726a72
bug: fix for empty untrusted comments
gballet 76886da
write timestamp as comment if trusted comment isn't present
gballet 3fe9eb6
rename line checker to commentHasManyLines
gballet dfac93a
crypto: added signify fuzzer (#6)
MariusVanDerWijden b2cf7c6
extract key data inside a single function
gballet 76db596
don't treat \r as a newline
gballet f92a450
travis: fix signing command line
gballet 6fa7fc6
do not use an external binary in tests
gballet 40b8b5f
crypto: move signify to crypto/signify
gballet 698af71
travis: fix formatting issue
gballet b22cdb2
ci: fix linter build after package move
gballet File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// 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 crypto | ||
|
||
import ( | ||
"encoding/base64" | ||
"errors" | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"strings" | ||
"time" | ||
|
||
"crypto/ed25519" | ||
) | ||
|
||
var ( | ||
errInvalidKeyHeader = errors.New("Incorrect key header") | ||
errInvalidKeyLength = errors.New("invalid, key length != 104") | ||
) | ||
|
||
func parsePrivateKey(key string) (ed25519.PrivateKey, []byte, []byte, error) { | ||
keydata, err := base64.StdEncoding.DecodeString(key) | ||
if err != nil { | ||
return nil, nil, nil, err | ||
} | ||
|
||
if len(keydata) != 104 { | ||
return nil, nil, nil, errInvalidKeyLength | ||
} | ||
|
||
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 { | ||
firstLFIndex := strings.IndexByte(comment, 10) | ||
return (firstLFIndex >= 0 && firstLFIndex < len(comment)-1) | ||
} | ||
|
||
// SignifySignFile creates a signature of the input file. | ||
func SignifySignFile(input string, output string, key string, unTrustedComment string, trustedComment 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() | ||
|
||
skey, header, keyNum, err := parsePrivateKey(key) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
filedata, err := ioutil.ReadAll(in) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
rawSig := ed25519.Sign(skey, filedata) | ||
|
||
var sigdata []byte | ||
sigdata = append(sigdata, header...) | ||
sigdata = append(sigdata, keyNum...) | ||
sigdata = append(sigdata, rawSig...) | ||
|
||
// Check that the trusted comment fits in one line | ||
if commentHasManyLines(unTrustedComment) { | ||
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 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 | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.