...

Source file src/golang.org/x/crypto/internal/wycheproof/wycheproof_test.go

Documentation: golang.org/x/crypto/internal/wycheproof

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package wycheproof runs a set of the Wycheproof tests
     6  // provided by https://github.com/google/wycheproof.
     7  package wycheproof
     8  
     9  import (
    10  	"crypto"
    11  	"crypto/x509"
    12  	"encoding/hex"
    13  	"encoding/json"
    14  	"flag"
    15  	"fmt"
    16  	"log"
    17  	"os"
    18  	"os/exec"
    19  	"path/filepath"
    20  	"testing"
    21  
    22  	_ "crypto/sha1"
    23  	_ "crypto/sha256"
    24  	_ "crypto/sha512"
    25  )
    26  
    27  const wycheproofModVer = "v0.0.0-20191219022705-2196000605e4"
    28  
    29  var wycheproofTestVectorsDir string
    30  
    31  func TestMain(m *testing.M) {
    32  	flag.Parse()
    33  	if flag.Lookup("test.short").Value.(flag.Getter).Get().(bool) {
    34  		log.Println("skipping test that downloads testdata via 'go mod download' in short mode")
    35  		os.Exit(0)
    36  	}
    37  	if _, err := exec.LookPath("go"); err != nil {
    38  		log.Printf("skipping test because 'go' command is unavailable: %v", err)
    39  		os.Exit(0)
    40  	}
    41  	if os.Getenv("GO_BUILDER_FLAKY_NET") != "" {
    42  		log.Printf("skipping test because GO_BUILDER_FLAKY_NET is set")
    43  		os.Exit(0)
    44  	}
    45  
    46  	// Download the JSON test files from github.com/google/wycheproof
    47  	// using `go mod download -json` so the cached source of the testdata
    48  	// can be used in the following tests.
    49  	path := "github.com/google/wycheproof@" + wycheproofModVer
    50  	cmd := exec.Command("go", "mod", "download", "-json", path)
    51  	output, err := cmd.Output()
    52  	if err != nil {
    53  		log.Fatalf("failed to run `go mod download -json %s`, output: %s", path, output)
    54  	}
    55  	var dm struct {
    56  		Dir string // absolute path to cached source root directory
    57  	}
    58  	if err := json.Unmarshal(output, &dm); err != nil {
    59  		log.Fatal(err)
    60  	}
    61  	// Now that the module has been downloaded, use the absolute path of the
    62  	// cached source as the root directory for all tests going forward.
    63  	wycheproofTestVectorsDir = filepath.Join(dm.Dir, "testvectors")
    64  	os.Exit(m.Run())
    65  }
    66  
    67  func readTestVector(t *testing.T, f string, dest interface{}) {
    68  	b, err := os.ReadFile(filepath.Join(wycheproofTestVectorsDir, f))
    69  	if err != nil {
    70  		t.Fatalf("failed to read json file: %v", err)
    71  	}
    72  	if err := json.Unmarshal(b, &dest); err != nil {
    73  		t.Fatalf("failed to unmarshal json file: %v", err)
    74  	}
    75  }
    76  
    77  func decodeHex(s string) []byte {
    78  	b, err := hex.DecodeString(s)
    79  	if err != nil {
    80  		panic(err)
    81  	}
    82  	return b
    83  }
    84  
    85  func decodePublicKey(der string) interface{} {
    86  	d := decodeHex(der)
    87  	pub, err := x509.ParsePKIXPublicKey(d)
    88  	if err != nil {
    89  		panic(fmt.Sprintf("failed to parse DER encoded public key: %v", err))
    90  	}
    91  	return pub
    92  }
    93  
    94  func parseHash(h string) crypto.Hash {
    95  	switch h {
    96  	case "SHA-1":
    97  		return crypto.SHA1
    98  	case "SHA-256":
    99  		return crypto.SHA256
   100  	case "SHA-224":
   101  		return crypto.SHA224
   102  	case "SHA-384":
   103  		return crypto.SHA384
   104  	case "SHA-512":
   105  		return crypto.SHA512
   106  	case "SHA-512/224":
   107  		return crypto.SHA512_224
   108  	case "SHA-512/256":
   109  		return crypto.SHA512_256
   110  	default:
   111  		panic(fmt.Sprintf("could not identify SHA hash algorithm: %q", h))
   112  	}
   113  }
   114  
   115  // shouldPass returns whether or not the test should pass.
   116  // flagsShouldPass is a map associated with whether or not
   117  // a flag for an "acceptable" result should pass.
   118  // Every possible flag value that's associated with an
   119  // "acceptable" result should be explicitly specified,
   120  // otherwise the test will panic.
   121  func shouldPass(result string, flags []string, flagsShouldPass map[string]bool) bool {
   122  	switch result {
   123  	case "valid":
   124  		return true
   125  	case "invalid":
   126  		return false
   127  	case "acceptable":
   128  		for _, flag := range flags {
   129  			pass, ok := flagsShouldPass[flag]
   130  			if !ok {
   131  				panic(fmt.Sprintf("unspecified flag: %q", flag))
   132  			}
   133  			if !pass {
   134  				return false
   135  			}
   136  		}
   137  		return true // There are no flags, or all are meant to pass.
   138  	default:
   139  		panic(fmt.Sprintf("unexpected result: %v", result))
   140  	}
   141  }
   142  

View as plain text