github.com/core-coin/go-core/v2@v2.1.9/crypto/signify/signify_fuzz.go (about)

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