github.com/benorgera/go-ethereum@v1.10.18-0.20220401011646-b3f57b1a73ba/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  	"io/ioutil"
    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 := ioutil.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 := ioutil.ReadDir(sigdir)
    58  	if err != nil {
    59  		t.Fatal(err)
    60  	}
    61  	for _, f := range files {
    62  		sig, err := ioutil.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, _ := ioutil.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  	}
   124  	for major := 1; major < 2; major++ {
   125  		for minor := 0; minor < 30; minor++ {
   126  			for patch := 0; patch < 30; patch++ {
   127  				vShort := fmt.Sprintf("v%d.%d.%d", major, minor, patch)
   128  				check(vShort)
   129  			}
   130  		}
   131  	}
   132  }
   133  
   134  func TestGethPubKeysParseable(t *testing.T) {
   135  	for _, pubkey := range gethPubKeys {
   136  		_, err := minisign.NewPublicKey(pubkey)
   137  		if err != nil {
   138  			t.Errorf("Should be parseable")
   139  		}
   140  	}
   141  }
   142  
   143  func TestKeyID(t *testing.T) {
   144  	type args struct {
   145  		id [8]byte
   146  	}
   147  	tests := []struct {
   148  		name string
   149  		args args
   150  		want string
   151  	}{
   152  		{"@holiman key", args{id: extractKeyId(gethPubKeys[0])}, "FB1D084D39BAEC24"},
   153  		{"second key", args{id: extractKeyId(gethPubKeys[1])}, "138B1CA303E51687"},
   154  		{"third key", args{id: extractKeyId(gethPubKeys[2])}, "FD9813B2D2098484"},
   155  	}
   156  	for _, tt := range tests {
   157  		t.Run(tt.name, func(t *testing.T) {
   158  			if got := keyID(tt.args.id); got != tt.want {
   159  				t.Errorf("keyID() = %v, want %v", got, tt.want)
   160  			}
   161  		})
   162  	}
   163  }
   164  
   165  func extractKeyId(pubkey string) [8]byte {
   166  	p, _ := minisign.NewPublicKey(pubkey)
   167  	return p.KeyId
   168  }