github.com/Unheilbar/quorum@v1.0.0/crypto/signify/signify_fuzz.go (about)

     1  // Copyright 2020 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser 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  // The go-ethereum library 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 Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  //go:build gofuzz
    18  // +build gofuzz
    19  
    20  package signify
    21  
    22  import (
    23  	"bufio"
    24  	"fmt"
    25  	"io/ioutil"
    26  	"log"
    27  	"os"
    28  	"os/exec"
    29  	"runtime"
    30  
    31  	fuzz "github.com/google/gofuzz"
    32  	"github.com/jedisct1/go-minisign"
    33  )
    34  
    35  func Fuzz(data []byte) int {
    36  	if len(data) < 32 {
    37  		return -1
    38  	}
    39  	tmpFile, err := ioutil.TempFile("", "")
    40  	if err != nil {
    41  		panic(err)
    42  	}
    43  	defer os.Remove(tmpFile.Name())
    44  	defer tmpFile.Close()
    45  
    46  	testSecKey, testPubKey := createKeyPair()
    47  	// Create message
    48  	tmpFile.Write(data)
    49  	if err = tmpFile.Close(); err != nil {
    50  		panic(err)
    51  	}
    52  	// Fuzz comments
    53  	var untrustedComment string
    54  	var trustedComment string
    55  	f := fuzz.NewFromGoFuzz(data)
    56  	f.Fuzz(&untrustedComment)
    57  	f.Fuzz(&trustedComment)
    58  	fmt.Printf("untrusted: %v\n", untrustedComment)
    59  	fmt.Printf("trusted: %v\n", trustedComment)
    60  
    61  	err = SignifySignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, untrustedComment, trustedComment)
    62  	if err != nil {
    63  		panic(err)
    64  	}
    65  	defer os.Remove(tmpFile.Name() + ".sig")
    66  
    67  	signify := "signify"
    68  	path := os.Getenv("SIGNIFY")
    69  	if path != "" {
    70  		signify = path
    71  	}
    72  
    73  	_, err := exec.LookPath(signify)
    74  	if err != nil {
    75  		panic(err)
    76  	}
    77  
    78  	// Write the public key into the file to pass it as
    79  	// an argument to signify-openbsd
    80  	pubKeyFile, err := ioutil.TempFile("", "")
    81  	if err != nil {
    82  		panic(err)
    83  	}
    84  	defer os.Remove(pubKeyFile.Name())
    85  	defer pubKeyFile.Close()
    86  	pubKeyFile.WriteString("untrusted comment: signify public key\n")
    87  	pubKeyFile.WriteString(testPubKey)
    88  	pubKeyFile.WriteString("\n")
    89  
    90  	cmd := exec.Command(signify, "-V", "-p", pubKeyFile.Name(), "-x", tmpFile.Name()+".sig", "-m", tmpFile.Name())
    91  	if output, err := cmd.CombinedOutput(); err != nil {
    92  		panic(fmt.Sprintf("could not verify the file: %v, output: \n%s", err, output))
    93  	}
    94  
    95  	// Verify the signature using a golang library
    96  	sig, err := minisign.NewSignatureFromFile(tmpFile.Name() + ".sig")
    97  	if err != nil {
    98  		panic(err)
    99  	}
   100  
   101  	pKey, err := minisign.NewPublicKey(testPubKey)
   102  	if err != nil {
   103  		panic(err)
   104  	}
   105  
   106  	valid, err := pKey.VerifyFromFile(tmpFile.Name(), sig)
   107  	if err != nil {
   108  		panic(err)
   109  	}
   110  	if !valid {
   111  		panic("invalid signature")
   112  	}
   113  	return 1
   114  }
   115  
   116  func getKey(fileS string) (string, error) {
   117  	file, err := os.Open(fileS)
   118  	if err != nil {
   119  		log.Fatal(err)
   120  	}
   121  	defer file.Close()
   122  
   123  	scanner := bufio.NewScanner(file)
   124  	// Discard the first line
   125  	scanner.Scan()
   126  	scanner.Scan()
   127  	return scanner.Text(), scanner.Err()
   128  }
   129  
   130  func createKeyPair() (string, string) {
   131  	// Create key and put it in correct format
   132  	tmpKey, err := ioutil.TempFile("", "")
   133  	if err != nil {
   134  		panic(err)
   135  	}
   136  	defer os.Remove(tmpKey.Name())
   137  	defer os.Remove(tmpKey.Name() + ".pub")
   138  	defer os.Remove(tmpKey.Name() + ".sec")
   139  	cmd := exec.Command("signify", "-G", "-n", "-p", tmpKey.Name()+".pub", "-s", tmpKey.Name()+".sec")
   140  	if output, err := cmd.CombinedOutput(); err != nil {
   141  		panic(fmt.Sprintf("could not verify the file: %v, output: \n%s", err, output))
   142  	}
   143  	secKey, err := getKey(tmpKey.Name() + ".sec")
   144  	if err != nil {
   145  		panic(err)
   146  	}
   147  	pubKey, err := getKey(tmpKey.Name() + ".pub")
   148  	if err != nil {
   149  		panic(err)
   150  	}
   151  	return secKey, pubKey
   152  }