github.com/theQRL/go-zond@v0.1.1/cmd/gzond/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`. Legacy format, not pre-hashed file.
    34  	t.Run("minisig-legacy", func(t *testing.T) {
    35  		// For this test, the pubkey is in testdata/vcheck/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  	t.Run("minisig-new", func(t *testing.T) {
    41  		// For this test, the pubkey is in testdata/vcheck/minisign.pub
    42  		// (the privkey is `minisign.sec`, if we want to expand this test. Password 'test' )
    43  		// `minisign -S -s ./minisign.sec  -m data.json  -x ./minisig-sigs-new/data.json.minisig`
    44  		pub := "RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp"
    45  		testVerification(t, pub, "./testdata/vcheck/minisig-sigs-new/")
    46  	})
    47  	// Signatures generated with `signify-openbsd`
    48  	t.Run("signify-openbsd", func(t *testing.T) {
    49  		t.Skip("This currently fails, minisign expects 4 lines of data, signify provides only 2")
    50  		// For this test, the pubkey is in testdata/vcheck/signifykey.pub
    51  		// (the privkey is `signifykey.sec`, if we want to expand this test. Password 'test' )
    52  		pub := "RWSKLNhZb0KdATtRT7mZC/bybI3t3+Hv/O2i3ye04Dq9fnT9slpZ1a2/"
    53  		testVerification(t, pub, "./testdata/vcheck/signify-sigs/")
    54  	})
    55  }
    56  
    57  func testVerification(t *testing.T, pubkey, sigdir string) {
    58  	// Data to verify
    59  	data, err := os.ReadFile("./testdata/vcheck/data.json")
    60  	if err != nil {
    61  		t.Fatal(err)
    62  	}
    63  	// Signatures, with and without comments, both trusted and untrusted
    64  	files, err := os.ReadDir(sigdir)
    65  	if err != nil {
    66  		t.Fatal(err)
    67  	}
    68  	if len(files) == 0 {
    69  		t.Fatal("Missing tests")
    70  	}
    71  	for _, f := range files {
    72  		sig, err := os.ReadFile(filepath.Join(sigdir, f.Name()))
    73  		if err != nil {
    74  			t.Fatal(err)
    75  		}
    76  		err = verifySignature([]string{pubkey}, data, sig)
    77  		if err != nil {
    78  			t.Fatal(err)
    79  		}
    80  	}
    81  }
    82  
    83  func versionUint(v string) int {
    84  	mustInt := func(s string) int {
    85  		a, err := strconv.Atoi(s)
    86  		if err != nil {
    87  			panic(v)
    88  		}
    89  		return a
    90  	}
    91  	components := strings.Split(strings.TrimPrefix(v, "v"), ".")
    92  	a := mustInt(components[0])
    93  	b := mustInt(components[1])
    94  	c := mustInt(components[2])
    95  	return a*100*100 + b*100 + c
    96  }
    97  
    98  // TestMatching can be used to check that the regexps are correct
    99  func TestMatching(t *testing.T) {
   100  	data, _ := os.ReadFile("./testdata/vcheck/vulnerabilities.json")
   101  	var vulns []vulnJson
   102  	if err := json.Unmarshal(data, &vulns); err != nil {
   103  		t.Fatal(err)
   104  	}
   105  	check := func(version string) {
   106  		vFull := fmt.Sprintf("Gzond/%v-unstable-15339cf1-20201204/linux-amd64/go1.15.4", version)
   107  		for _, vuln := range vulns {
   108  			r, err := regexp.Compile(vuln.Check)
   109  			vulnIntro := versionUint(vuln.Introduced)
   110  			vulnFixed := versionUint(vuln.Fixed)
   111  			current := versionUint(version)
   112  			if err != nil {
   113  				t.Fatal(err)
   114  			}
   115  			if vuln.Name == "Denial of service due to Go CVE-2020-28362" {
   116  				// this one is not tied to geth-versions
   117  				continue
   118  			}
   119  			if vulnIntro <= current && vulnFixed > current {
   120  				// Should be vulnerable
   121  				if !r.MatchString(vFull) {
   122  					t.Errorf("Should be vulnerable, version %v, intro: %v, fixed: %v %v %v",
   123  						version, vuln.Introduced, vuln.Fixed, vuln.Name, vuln.Check)
   124  				}
   125  			} else {
   126  				if r.MatchString(vFull) {
   127  					t.Errorf("Should not be flagged vulnerable, version %v, intro: %v, fixed: %v %v %d %d %d",
   128  						version, vuln.Introduced, vuln.Fixed, vuln.Name, vulnIntro, current, vulnFixed)
   129  				}
   130  			}
   131  		}
   132  	}
   133  	for major := 1; major < 2; major++ {
   134  		for minor := 0; minor < 30; minor++ {
   135  			for patch := 0; patch < 30; patch++ {
   136  				vShort := fmt.Sprintf("v%d.%d.%d", major, minor, patch)
   137  				check(vShort)
   138  			}
   139  		}
   140  	}
   141  }
   142  
   143  func TestGethPubKeysParseable(t *testing.T) {
   144  	for _, pubkey := range gethPubKeys {
   145  		_, err := minisign.NewPublicKey(pubkey)
   146  		if err != nil {
   147  			t.Errorf("Should be parseable")
   148  		}
   149  	}
   150  }
   151  
   152  func TestKeyID(t *testing.T) {
   153  	type args struct {
   154  		id [8]byte
   155  	}
   156  	tests := []struct {
   157  		name string
   158  		args args
   159  		want string
   160  	}{
   161  		{"@holiman key", args{id: extractKeyId(gethPubKeys[0])}, "FB1D084D39BAEC24"},
   162  		{"second key", args{id: extractKeyId(gethPubKeys[1])}, "138B1CA303E51687"},
   163  		{"third key", args{id: extractKeyId(gethPubKeys[2])}, "FD9813B2D2098484"},
   164  	}
   165  	for _, tt := range tests {
   166  		t.Run(tt.name, func(t *testing.T) {
   167  			if got := keyID(tt.args.id); got != tt.want {
   168  				t.Errorf("keyID() = %v, want %v", got, tt.want)
   169  			}
   170  		})
   171  	}
   172  }
   173  
   174  func extractKeyId(pubkey string) [8]byte {
   175  	p, _ := minisign.NewPublicKey(pubkey)
   176  	return p.KeyId
   177  }