Skip to content

Commit af71c19

Browse files
committed
remove custom minisign implementation
This commit removes the custom (partial) minisign implementation and instead relies on `github.com/aead/minisign`. This commit should not cause any behavior or API changes. Signed-off-by: Andreas Auernhammer <[email protected]>
1 parent 5d1eb19 commit af71c19

File tree

3 files changed

+41
-128
lines changed

3 files changed

+41
-128
lines changed

go.mod

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ module github.com/minio/selfupdate
22

33
go 1.14
44

5-
require golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b
5+
require (
6+
aead.dev/minisign v0.2.0
7+
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b // indirect
8+
)

go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
1+
aead.dev/minisign v0.2.0 h1:kAWrq/hBRu4AARY6AlciO83xhNnW9UaC8YipS2uhLPk=
2+
aead.dev/minisign v0.2.0/go.mod h1:zdq6LdSd9TbuSxchxwhpA9zEb9YXcVGoE8JakuiGaIQ=
3+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
4+
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
15
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b h1:QAqMVf3pSa6eeTsuklijukjXBlj7Es2QQplab+/RbQ4=
26
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
7+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
38
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
9+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
10+
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
411
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
12+
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
513
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
614
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
715
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
16+
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
817
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
18+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
919
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
1020
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

minisign.go

Lines changed: 27 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,61 @@
11
package selfupdate
22

3-
// Borrowed code directly from https://github.com/jedisct1/go-minisign
4-
// however modified to support reading signatures from remote URLs,
5-
// local file etc.
63
import (
7-
"encoding/base64"
84
"errors"
9-
"io/ioutil"
5+
"io"
106
"net/http"
11-
"strings"
127

13-
"golang.org/x/crypto/blake2b"
14-
"golang.org/x/crypto/ed25519"
8+
"aead.dev/minisign"
159
)
1610

1711
type Verifier struct {
18-
publicKey publicKey
19-
signature signature
12+
publicKey minisign.PublicKey
13+
signature minisign.Signature
2014
}
2115

22-
type publicKey struct {
23-
SignatureAlgorithm [2]byte
24-
KeyID [8]byte
25-
Key [32]byte
26-
}
27-
28-
type signature struct {
29-
UntrustedComment string
30-
SignatureAlgorithm [2]byte
31-
KeyID [8]byte
32-
Signature [64]byte
33-
TrustedComment string
34-
GlobalSignature [64]byte
35-
}
36-
37-
func parsePublicKey(publicKeyStr string) (publicKey, error) {
38-
var pkey publicKey
39-
bin, err := base64.StdEncoding.DecodeString(publicKeyStr)
40-
if err != nil || len(bin) != 42 {
41-
return pkey, errors.New("Invalid encoded public key")
42-
}
43-
copy(pkey.SignatureAlgorithm[:], bin[0:2])
44-
copy(pkey.KeyID[:], bin[2:10])
45-
copy(pkey.Key[:], bin[10:42])
46-
return pkey, nil
47-
}
48-
49-
func trimCarriageReturn(input string) string {
50-
return strings.TrimRight(input, "\r")
51-
}
52-
53-
func decodeSignature(in string) (signature, error) {
54-
var sign signature
55-
lines := strings.SplitN(in, "\n", 4)
56-
if len(lines) < 4 {
57-
return sign, errors.New("Incomplete encoded signature")
58-
}
59-
sign.UntrustedComment = trimCarriageReturn(lines[0])
60-
bin1, err := base64.StdEncoding.DecodeString(lines[1])
61-
if err != nil || len(bin1) != 74 {
62-
return sign, errors.New("Invalid encoded signature")
63-
}
64-
sign.TrustedComment = trimCarriageReturn(lines[2])
65-
bin2, err := base64.StdEncoding.DecodeString(lines[3])
66-
if err != nil || len(bin2) != 64 {
67-
return sign, errors.New("Invalid encoded signature")
16+
func (v *Verifier) LoadFromURL(signatureURL string, passphrase string, transport http.RoundTripper) error {
17+
var publicKey minisign.PublicKey
18+
if err := publicKey.UnmarshalText([]byte(passphrase)); err != nil {
19+
return err
6820
}
69-
copy(sign.SignatureAlgorithm[:], bin1[0:2])
70-
copy(sign.KeyID[:], bin1[2:10])
71-
copy(sign.Signature[:], bin1[10:74])
72-
copy(sign.GlobalSignature[:], bin2)
73-
return sign, nil
74-
}
7521

76-
func parseSignatureFromURL(url string, transport http.RoundTripper) (signature, error) {
77-
var sign signature
78-
req, err := http.NewRequest(http.MethodGet, url, nil)
22+
client := &http.Client{Transport: transport}
23+
req, err := http.NewRequest(http.MethodGet, signatureURL, nil)
7924
if err != nil {
80-
return sign, err
25+
return err
8126
}
82-
client := &http.Client{Transport: transport}
8327
resp, err := client.Do(req)
8428
if err != nil {
85-
return sign, err
29+
return err
8630
}
8731
defer resp.Body.Close()
8832
if resp.StatusCode != http.StatusOK {
89-
return sign, errors.New(resp.Status)
90-
}
91-
bin, err := ioutil.ReadAll(resp.Body)
92-
if err != nil {
93-
return sign, err
33+
return errors.New(resp.Status)
9434
}
95-
return decodeSignature(string(bin))
96-
}
97-
98-
func parseSignatureFromFile(file string) (signature, error) {
99-
bin, err := ioutil.ReadFile(file)
100-
if err != nil {
101-
return signature{}, err
102-
}
103-
return decodeSignature(string(bin))
104-
}
10535

106-
func (v *Verifier) LoadFromURL(signatureURL string, passphrase string, transport http.RoundTripper) error {
107-
pkey, err := parsePublicKey(passphrase)
36+
const MaxSize = 1 << 20
37+
b, err := io.ReadAll(io.LimitReader(resp.Body, MaxSize))
10838
if err != nil {
10939
return err
11040
}
111-
v.publicKey = pkey
112-
113-
sign, err := parseSignatureFromURL(signatureURL, transport)
114-
if err != nil {
41+
var signature minisign.Signature
42+
if err = signature.UnmarshalText(b); err != nil {
11543
return err
11644
}
117-
118-
v.signature = sign
45+
v.publicKey, v.signature = publicKey, signature
11946
return nil
12047
}
12148

12249
func (v *Verifier) LoadFromFile(signaturePath string, passphrase string) error {
123-
pkey, err := parsePublicKey(passphrase)
124-
if err != nil {
50+
var publicKey minisign.PublicKey
51+
if err := publicKey.UnmarshalText([]byte(passphrase)); err != nil {
12552
return err
12653
}
127-
v.publicKey = pkey
128-
129-
sign, err := parseSignatureFromFile(signaturePath)
54+
signature, err := minisign.SignatureFromFile(signaturePath)
13055
if err != nil {
13156
return err
13257
}
133-
134-
v.signature = sign
58+
v.publicKey, v.signature = publicKey, signature
13559
return nil
13660
}
13761

@@ -140,36 +64,12 @@ func NewVerifier() *Verifier {
14064
}
14165

14266
func (v *Verifier) Verify(bin []byte) error {
143-
if v.publicKey.SignatureAlgorithm != [2]byte{'E', 'd'} {
144-
return errors.New("Incompatible signature algorithm")
145-
}
146-
prehashed := false
147-
if v.signature.SignatureAlgorithm[0] == 0x45 && v.signature.SignatureAlgorithm[1] == 0x64 {
148-
prehashed = false
149-
} else if v.signature.SignatureAlgorithm[0] == 0x45 && v.signature.SignatureAlgorithm[1] == 0x44 {
150-
prehashed = true
151-
} else {
152-
return errors.New("Unsupported signature algorithm")
153-
}
154-
if v.publicKey.KeyID != v.signature.KeyID {
155-
return errors.New("Incompatible key identifiers")
156-
}
157-
if !strings.HasPrefix(v.signature.TrustedComment, "trusted comment: ") {
158-
return errors.New("Unexpected format for the trusted comment")
159-
}
160-
if prehashed {
161-
h, _ := blake2b.New512(nil)
162-
h.Write(bin)
163-
bin = h.Sum(nil)
164-
}
165-
if !ed25519.Verify(ed25519.PublicKey(v.publicKey.Key[:]), bin, v.signature.Signature[:]) {
166-
return errors.New("Invalid signature")
67+
signature, err := v.signature.MarshalText()
68+
if err != nil {
69+
return err
16770
}
168-
if !ed25519.Verify(ed25519.PublicKey(v.publicKey.Key[:]),
169-
append(v.signature.Signature[:],
170-
[]byte(v.signature.TrustedComment)[17:]...),
171-
v.signature.GlobalSignature[:]) {
172-
return errors.New("Invalid global signature")
71+
if !minisign.Verify(v.publicKey, bin, signature) {
72+
return errors.New("selfupdate: signature verification failed")
17373
}
17474
return nil
17575
}

0 commit comments

Comments
 (0)