...

Source file src/github.com/theupdateframework/go-tuf/verify/verify_test.go

Documentation: github.com/theupdateframework/go-tuf/verify

     1  package verify
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/ecdsa"
     6  	"crypto/elliptic"
     7  	"crypto/rand"
     8  	"crypto/sha256"
     9  	"encoding/json"
    10  	"errors"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/theupdateframework/go-tuf/data"
    15  	"github.com/theupdateframework/go-tuf/pkg/keys"
    16  	"github.com/theupdateframework/go-tuf/sign"
    17  	"golang.org/x/crypto/ed25519"
    18  
    19  	. "gopkg.in/check.v1"
    20  )
    21  
    22  // Hook up gocheck into the "go test" runner.
    23  func Test(t *testing.T) { TestingT(t) }
    24  
    25  type VerifySuite struct{}
    26  
    27  var _ = Suite(&VerifySuite{})
    28  
    29  type ecdsaSigner struct {
    30  	*ecdsa.PrivateKey
    31  }
    32  
    33  type ecdsaPublic struct {
    34  	PublicKey *keys.PKIXPublicKey `json:"public"`
    35  }
    36  
    37  func (s ecdsaSigner) PublicData() *data.PublicKey {
    38  	keyValBytes, _ := json.Marshal(ecdsaPublic{PublicKey: &keys.PKIXPublicKey{PublicKey: s.Public()}})
    39  	return &data.PublicKey{
    40  		Type:       data.KeyTypeECDSA_SHA2_P256,
    41  		Scheme:     data.KeySchemeECDSA_SHA2_P256,
    42  		Algorithms: data.HashAlgorithms,
    43  		Value:      keyValBytes,
    44  	}
    45  }
    46  
    47  func (s ecdsaSigner) SignMessage(message []byte) ([]byte, error) {
    48  	hash := sha256.Sum256(message)
    49  	return s.PrivateKey.Sign(rand.Reader, hash[:], crypto.SHA256)
    50  }
    51  
    52  func (s ecdsaSigner) ContainsID(id string) bool {
    53  	return s.PublicData().ContainsID(id)
    54  }
    55  
    56  func (ecdsaSigner) MarshalPrivateKey() (*data.PrivateKey, error) {
    57  	return nil, errors.New("not implemented for test")
    58  }
    59  
    60  func (ecdsaSigner) UnmarshalPrivateKey(key *data.PrivateKey) error {
    61  	return errors.New("not implemented for test")
    62  }
    63  
    64  func (VerifySuite) Test(c *C) {
    65  	type test struct {
    66  		name  string
    67  		keys  []*data.PublicKey
    68  		roles map[string]*data.Role
    69  		s     *data.Signed
    70  		ver   int64
    71  		exp   *time.Time
    72  		typ   string
    73  		role  string
    74  		err   error
    75  		mut   func(*test)
    76  	}
    77  
    78  	expiredTime := time.Now().Add(-time.Hour)
    79  	minVer := int64(10)
    80  	tests := []test{
    81  		{
    82  			name: "no signatures",
    83  			mut:  func(t *test) { t.s.Signatures = []data.Signature{} },
    84  			err:  ErrNoSignatures,
    85  		},
    86  		{
    87  			name: "unknown role",
    88  			role: "foo",
    89  			err:  ErrUnknownRole{"foo"},
    90  		},
    91  		{
    92  			// It is impossible to distinguish between an error of an invalid
    93  			// signature and a threshold not achieved. Invalid signatures lead
    94  			// to not achieving the threshold.
    95  			name: "signature wrong length",
    96  			mut:  func(t *test) { t.s.Signatures[0].Signature = []byte{0} },
    97  			err:  ErrRoleThreshold{1, 0},
    98  		},
    99  		{
   100  			name: "key missing from role",
   101  			mut:  func(t *test) { t.roles["root"].KeyIDs = nil },
   102  			err:  ErrRoleThreshold{1, 0},
   103  		},
   104  		{
   105  			name: "invalid signature",
   106  			mut:  func(t *test) { t.s.Signatures[0].Signature = make([]byte, ed25519.SignatureSize) },
   107  			err:  ErrRoleThreshold{1, 0},
   108  		},
   109  		{
   110  			name: "enough signatures with extra invalid signature",
   111  			mut: func(t *test) {
   112  				t.s.Signatures = append(t.s.Signatures, data.Signature{
   113  					KeyID:     t.s.Signatures[0].KeyID,
   114  					Signature: make([]byte, ed25519.SignatureSize)})
   115  			},
   116  		},
   117  		{
   118  			name: "not enough signatures",
   119  			mut:  func(t *test) { t.roles["root"].Threshold = 2 },
   120  			err:  ErrRoleThreshold{2, 1},
   121  		},
   122  		{
   123  			name: "exactly enough signatures",
   124  		},
   125  		{
   126  			name: "more than enough signatures",
   127  			mut: func(t *test) {
   128  				k, _ := keys.GenerateEd25519Key()
   129  				sign.Sign(t.s, k)
   130  				t.keys = append(t.keys, k.PublicData())
   131  				t.roles["root"].KeyIDs = append(t.roles["root"].KeyIDs, k.PublicData().IDs()...)
   132  			},
   133  		},
   134  		{
   135  			name: "duplicate key id",
   136  			mut: func(t *test) {
   137  				t.roles["root"].Threshold = 2
   138  				t.s.Signatures = append(t.s.Signatures, t.s.Signatures[0])
   139  			},
   140  			err: ErrRoleThreshold{2, 1},
   141  		},
   142  		{
   143  			name: "unknown key",
   144  			mut: func(t *test) {
   145  				k, _ := keys.GenerateEd25519Key()
   146  				sign.Sign(t.s, k)
   147  			},
   148  		},
   149  		{
   150  			name: "unknown key below threshold",
   151  			mut: func(t *test) {
   152  				k, _ := keys.GenerateEd25519Key()
   153  				sign.Sign(t.s, k)
   154  				t.roles["root"].Threshold = 2
   155  			},
   156  			err: ErrRoleThreshold{2, 1},
   157  		},
   158  		{
   159  			name: "unknown keys in db",
   160  			mut: func(t *test) {
   161  				k, _ := keys.GenerateEd25519Key()
   162  				sign.Sign(t.s, k)
   163  				t.keys = append(t.keys, k.PublicData())
   164  			},
   165  		},
   166  		{
   167  			name: "unknown keys in db below threshold",
   168  			mut: func(t *test) {
   169  				k, _ := keys.GenerateEd25519Key()
   170  				sign.Sign(t.s, k)
   171  				t.keys = append(t.keys, k.PublicData())
   172  				t.roles["root"].Threshold = 2
   173  			},
   174  			err: ErrRoleThreshold{2, 1},
   175  		},
   176  		{
   177  			name: "wrong type",
   178  			typ:  "bar",
   179  			err:  ErrWrongMetaType,
   180  		},
   181  		{
   182  			name: "low version",
   183  			ver:  minVer - 1,
   184  			err:  ErrLowVersion{minVer - 1, minVer},
   185  		},
   186  		{
   187  			name: "expired",
   188  			exp:  &expiredTime,
   189  			err:  ErrExpired{expiredTime},
   190  		},
   191  		{
   192  			name: "valid ecdsa signature",
   193  			mut: func(t *test) {
   194  				k, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   195  				s := ecdsaSigner{k}
   196  				sign.Sign(t.s, s)
   197  				t.s.Signatures = t.s.Signatures[1:]
   198  				t.keys = []*data.PublicKey{s.PublicData()}
   199  				t.roles["root"].KeyIDs = s.PublicData().IDs()
   200  			},
   201  		},
   202  		{
   203  			// The threshold is still achieved.
   204  			name: "invalid second ecdsa signature",
   205  			mut: func(t *test) {
   206  				k, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   207  				s := ecdsaSigner{k}
   208  				sign.Sign(t.s, s)
   209  				t.s.Signatures[1].Signature[0]++
   210  				t.keys = append(t.keys, s.PublicData())
   211  				t.roles["root"].KeyIDs = append(t.roles["root"].KeyIDs, s.PublicData().IDs()...)
   212  			},
   213  		},
   214  	}
   215  	for _, t := range tests {
   216  		if t.role == "" {
   217  			t.role = "root"
   218  		}
   219  		if t.ver == 0 {
   220  			t.ver = minVer
   221  		}
   222  		if t.exp == nil {
   223  			expires := time.Now().Add(time.Hour)
   224  			t.exp = &expires
   225  		}
   226  		if t.typ == "" {
   227  			t.typ = t.role
   228  		}
   229  		if t.keys == nil && t.s == nil {
   230  			k, _ := keys.GenerateEd25519Key()
   231  			t.s, _ = sign.Marshal(&signedMeta{Type: t.typ, Version: t.ver, Expires: *t.exp}, k)
   232  			t.keys = []*data.PublicKey{k.PublicData()}
   233  		}
   234  		if t.roles == nil {
   235  			t.roles = map[string]*data.Role{
   236  				"root": {
   237  					KeyIDs:    t.keys[0].IDs(),
   238  					Threshold: 1,
   239  				},
   240  			}
   241  		}
   242  		if t.mut != nil {
   243  			t.mut(&t)
   244  		}
   245  
   246  		db := NewDB()
   247  		for _, k := range t.keys {
   248  			for _, id := range k.IDs() {
   249  				err := db.AddKey(id, k)
   250  				c.Assert(err, IsNil)
   251  			}
   252  		}
   253  		for n, r := range t.roles {
   254  			err := db.AddRole(n, r)
   255  			c.Assert(err, IsNil)
   256  		}
   257  
   258  		err := db.Verify(t.s, t.role, minVer)
   259  		if e, ok := t.err.(ErrExpired); ok {
   260  			assertErrExpired(c, err, e)
   261  		} else {
   262  			c.Assert(err, DeepEquals, t.err, Commentf("name = %s", t.name))
   263  		}
   264  	}
   265  }
   266  
   267  func (VerifySuite) TestVerifyIgnoreExpired(c *C) {
   268  	minVer := int64(10)
   269  	role := "root"
   270  	k, _ := keys.GenerateEd25519Key()
   271  	s, _ := sign.Marshal(&signedMeta{Type: role, Version: minVer, Expires: time.Now().Add(-time.Hour)}, k)
   272  	keys := []*data.PublicKey{k.PublicData()}
   273  	roles := map[string]*data.Role{
   274  		"root": {
   275  			KeyIDs:    keys[0].IDs(),
   276  			Threshold: 1,
   277  		},
   278  	}
   279  
   280  	db := NewDB()
   281  	for _, k := range keys {
   282  		for _, id := range k.IDs() {
   283  			err := db.AddKey(id, k)
   284  			c.Assert(err, IsNil)
   285  		}
   286  	}
   287  	for n, r := range roles {
   288  		err := db.AddRole(n, r)
   289  		c.Assert(err, IsNil)
   290  	}
   291  
   292  	err := db.VerifyIgnoreExpiredCheck(s, role, minVer)
   293  	c.Assert(err, IsNil)
   294  }
   295  
   296  func assertErrExpired(c *C, err error, expected ErrExpired) {
   297  	actual, ok := err.(ErrExpired)
   298  	if !ok {
   299  		c.Fatalf("expected err to have type ErrExpired, got %T", err)
   300  	}
   301  	c.Assert(actual.Expired.Unix(), Equals, expected.Expired.Unix())
   302  }
   303  

View as plain text