github.com/carter-ya/go-ethereum@v0.0.0-20230628080049-d2309be3983b/cmd/geth/version_check_test.go (about) 1 // Copyright 2020 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "os" 23 "path/filepath" 24 "regexp" 25 "strconv" 26 "strings" 27 "testing" 28 29 "github.com/jedisct1/go-minisign" 30 ) 31 32 func TestVerification(t *testing.T) { 33 // Signatures generated with `minisign` 34 t.Run("minisig", func(t *testing.T) { 35 // For this test, the pubkey is in testdata/minisign.pub 36 // (the privkey is `minisign.sec`, if we want to expand this test. Password 'test' ) 37 pub := "RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp" 38 testVerification(t, pub, "./testdata/vcheck/minisig-sigs/") 39 }) 40 // Signatures generated with `signify-openbsd` 41 t.Run("signify-openbsd", func(t *testing.T) { 42 t.Skip("This currently fails, minisign expects 4 lines of data, signify provides only 2") 43 // For this test, the pubkey is in testdata/signifykey.pub 44 // (the privkey is `signifykey.sec`, if we want to expand this test. Password 'test' ) 45 pub := "RWSKLNhZb0KdATtRT7mZC/bybI3t3+Hv/O2i3ye04Dq9fnT9slpZ1a2/" 46 testVerification(t, pub, "./testdata/vcheck/signify-sigs/") 47 }) 48 } 49 50 func testVerification(t *testing.T, pubkey, sigdir string) { 51 // Data to verify 52 data, err := os.ReadFile("./testdata/vcheck/data.json") 53 if err != nil { 54 t.Fatal(err) 55 } 56 // Signatures, with and without comments, both trusted and untrusted 57 files, err := os.ReadDir(sigdir) 58 if err != nil { 59 t.Fatal(err) 60 } 61 for _, f := range files { 62 sig, err := os.ReadFile(filepath.Join(sigdir, f.Name())) 63 if err != nil { 64 t.Fatal(err) 65 } 66 err = verifySignature([]string{pubkey}, data, sig) 67 if err != nil { 68 t.Fatal(err) 69 } 70 } 71 } 72 73 func versionUint(v string) int { 74 mustInt := func(s string) int { 75 a, err := strconv.Atoi(s) 76 if err != nil { 77 panic(v) 78 } 79 return a 80 } 81 components := strings.Split(strings.TrimPrefix(v, "v"), ".") 82 a := mustInt(components[0]) 83 b := mustInt(components[1]) 84 c := mustInt(components[2]) 85 return a*100*100 + b*100 + c 86 } 87 88 // TestMatching can be used to check that the regexps are correct 89 func TestMatching(t *testing.T) { 90 data, _ := os.ReadFile("./testdata/vcheck/vulnerabilities.json") 91 var vulns []vulnJson 92 if err := json.Unmarshal(data, &vulns); err != nil { 93 t.Fatal(err) 94 } 95 check := func(version string) { 96 vFull := fmt.Sprintf("Geth/%v-unstable-15339cf1-20201204/linux-amd64/go1.15.4", version) 97 for _, vuln := range vulns { 98 r, err := regexp.Compile(vuln.Check) 99 vulnIntro := versionUint(vuln.Introduced) 100 vulnFixed := versionUint(vuln.Fixed) 101 current := versionUint(version) 102 if err != nil { 103 t.Fatal(err) 104 } 105 if vuln.Name == "Denial of service due to Go CVE-2020-28362" { 106 // this one is not tied to geth-versions 107 continue 108 } 109 if vulnIntro <= current && vulnFixed > current { 110 // Should be vulnerable 111 if !r.MatchString(vFull) { 112 t.Errorf("Should be vulnerable, version %v, intro: %v, fixed: %v %v %v", 113 version, vuln.Introduced, vuln.Fixed, vuln.Name, vuln.Check) 114 } 115 } else { 116 if r.MatchString(vFull) { 117 t.Errorf("Should not be flagged vulnerable, version %v, intro: %v, fixed: %v %v %d %d %d", 118 version, vuln.Introduced, vuln.Fixed, vuln.Name, vulnIntro, current, vulnFixed) 119 } 120 } 121 } 122 } 123 for major := 1; major < 2; major++ { 124 for minor := 0; minor < 30; minor++ { 125 for patch := 0; patch < 30; patch++ { 126 vShort := fmt.Sprintf("v%d.%d.%d", major, minor, patch) 127 check(vShort) 128 } 129 } 130 } 131 } 132 133 func TestGethPubKeysParseable(t *testing.T) { 134 for _, pubkey := range gethPubKeys { 135 _, err := minisign.NewPublicKey(pubkey) 136 if err != nil { 137 t.Errorf("Should be parseable") 138 } 139 } 140 } 141 142 func TestKeyID(t *testing.T) { 143 type args struct { 144 id [8]byte 145 } 146 tests := []struct { 147 name string 148 args args 149 want string 150 }{ 151 {"@holiman key", args{id: extractKeyId(gethPubKeys[0])}, "FB1D084D39BAEC24"}, 152 {"second key", args{id: extractKeyId(gethPubKeys[1])}, "138B1CA303E51687"}, 153 {"third key", args{id: extractKeyId(gethPubKeys[2])}, "FD9813B2D2098484"}, 154 } 155 for _, tt := range tests { 156 t.Run(tt.name, func(t *testing.T) { 157 if got := keyID(tt.args.id); got != tt.want { 158 t.Errorf("keyID() = %v, want %v", got, tt.want) 159 } 160 }) 161 } 162 } 163 164 func extractKeyId(pubkey string) [8]byte { 165 p, _ := minisign.NewPublicKey(pubkey) 166 return p.KeyId 167 }