Example #1
0
// CreateTimestamp creates a new timestamp. If a prev timestamp is provided, it
// is assumed this is the immediately previous one, and the new one will have a
// version number one higher than prev. The store is used to lookup the current
// snapshot, this function does not save the newly generated timestamp.
func CreateTimestamp(gun string, prev *data.SignedTimestamp, snapshot []byte, store storage.MetaStore, cryptoService signed.CryptoService) (*data.Signed, int, error) {
	algorithm, public, err := store.GetTimestampKey(gun)
	if err != nil {
		// owner of gun must have generated a timestamp key otherwise
		// we won't proceed with generating everything.
		return nil, 0, err
	}
	key := data.NewPublicKey(algorithm, public)
	sn := &data.Signed{}
	err = json.Unmarshal(snapshot, sn)
	if err != nil {
		// couldn't parse snapshot
		return nil, 0, err
	}
	ts, err := data.NewTimestamp(sn)
	if err != nil {
		return nil, 0, err
	}
	if prev != nil {
		ts.Signed.Version = prev.Signed.Version + 1
	}
	sgndTs, err := cjson.Marshal(ts.Signed)
	if err != nil {
		return nil, 0, err
	}
	out := &data.Signed{
		Signatures: ts.Signatures,
		Signed:     sgndTs,
	}
	err = signed.Sign(cryptoService, out, key)
	if err != nil {
		return nil, 0, err
	}
	return out, ts.Signed.Version, nil
}
Example #2
0
func (k *Key) ID() string {
	k.idOnce.Do(func() {
		data, _ := cjson.Marshal(k)
		digest := sha256.Sum256(data)
		k.id = hex.EncodeToString(digest[:])
	})
	return k.id
}
Example #3
0
func (k *TUFKey) ID() string {
	if k.id == "" {
		pubK := NewPublicKey(k.Algorithm(), k.Public())
		data, err := cjson.Marshal(&pubK)
		if err != nil {
			logrus.Error("Error generating key ID:", err)
		}
		digest := sha256.Sum256(data)
		k.id = hex.EncodeToString(digest[:])
	}
	return k.id
}
Example #4
0
func (k *TUFKey) ID() string {
	logrus.Debug("Generating Key ID")
	if k.id == "" {
		logrus.Debug("Generating Key ID")
		pubK := NewTUFKey(k.Cipher(), k.Public(), nil)
		data, err := cjson.Marshal(&pubK)
		if err != nil {
			logrus.Error("Error generating key ID:", err)
		}
		digest := sha256.Sum256(data)
		k.id = hex.EncodeToString(digest[:])
	}
	return k.id
}
Example #5
0
func (ts SignedTimestamp) ToSigned() (*Signed, error) {
	s, err := cjson.Marshal(ts.Signed)
	if err != nil {
		return nil, err
	}
	signed := json.RawMessage{}
	err = signed.UnmarshalJSON(s)
	if err != nil {
		return nil, err
	}
	sigs := make([]Signature, len(ts.Signatures))
	copy(sigs, ts.Signatures)
	return &Signed{
		Signatures: sigs,
		Signed:     signed,
	}, nil
}
Example #6
0
func (sp SignedSnapshot) ToSigned() (*Signed, error) {
	s, err := cjson.Marshal(sp.Signed)
	if err != nil {
		return nil, err
	}
	signed := json.RawMessage{}
	err = signed.UnmarshalJSON(s)
	if err != nil {
		return nil, err
	}
	sigs := make([]Signature, len(sp.Signatures))
	copy(sigs, sp.Signatures)
	return &Signed{
		Signatures: sigs,
		Signed:     signed,
	}, nil
}
Example #7
0
func (VerifySuite) Test(c *C) {
	trust := NewEd25519()
	type test struct {
		name  string
		keys  []*data.PublicKey
		roles map[string]*data.Role
		s     *data.Signed
		ver   int
		exp   *time.Time
		typ   string
		role  string
		err   error
		mut   func(*test)
	}

	expiredTime := time.Now().Add(-time.Hour)
	minVer := 10
	tests := []test{
		{
			name: "no signatures",
			mut:  func(t *test) { t.s.Signatures = []data.Signature{} },
			err:  ErrNoSignatures,
		},
		{
			name: "unknown role",
			role: "foo",
			err:  ErrUnknownRole,
		},
		//{
		//	name: "wrong signature method",
		//	mut:  func(t *test) { t.s.Signatures[0].Method = "foo" },
		//	err:  ErrWrongMethod,
		//},
		//	{
		//		name: "signature wrong length",
		//		mut:  func(t *test) { t.s.Signatures[0].Signature = []byte{0} },
		//		err:  ErrInvalid,
		//	},
		{
			name: "key missing from role",
			mut:  func(t *test) { t.roles["root"].KeyIDs = nil },
			err:  ErrRoleThreshold,
		},
		//	{
		//		name: "invalid signature",
		//		mut:  func(t *test) { t.s.Signatures[0].Signature = make([]byte, ed25519.SignatureSize) },
		//		err:  ErrInvalid,
		//	},
		{
			name: "not enough signatures",
			mut:  func(t *test) { t.roles["root"].Threshold = 2 },
			err:  ErrRoleThreshold,
		},
		{
			name: "exactly enough signatures",
		},
		{
			name: "more than enough signatures",
			mut: func(t *test) {
				k, _ := trust.Create("root", data.ED25519Key)
				Sign(trust, t.s, k)
				t.keys = append(t.keys, k)
				t.roles["root"].KeyIDs = append(t.roles["root"].KeyIDs, k.ID())
			},
		},
		{
			name: "duplicate key id",
			mut: func(t *test) {
				t.roles["root"].Threshold = 2
				t.s.Signatures = append(t.s.Signatures, t.s.Signatures[0])
			},
			err: ErrRoleThreshold,
		},
		{
			name: "unknown key",
			mut: func(t *test) {
				k, _ := trust.Create("root", data.ED25519Key)
				Sign(trust, t.s, k)
			},
		},
		{
			name: "unknown key below threshold",
			mut: func(t *test) {
				k, _ := trust.Create("root", data.ED25519Key)
				Sign(trust, t.s, k)
				t.roles["root"].Threshold = 2
			},
			err: ErrRoleThreshold,
		},
		{
			name: "unknown keys in db",
			mut: func(t *test) {
				k, _ := trust.Create("root", data.ED25519Key)
				Sign(trust, t.s, k)
				t.keys = append(t.keys, k)
			},
		},
		{
			name: "unknown keys in db below threshold",
			mut: func(t *test) {
				k, _ := trust.Create("root", data.ED25519Key)
				Sign(trust, t.s, k)
				t.keys = append(t.keys, k)
				t.roles["root"].Threshold = 2
			},
			err: ErrRoleThreshold,
		},
		{
			name: "wrong type",
			typ:  "bar",
			err:  ErrWrongType,
		},
		{
			name: "low version",
			ver:  minVer - 1,
			err:  ErrLowVersion{minVer - 1, minVer},
		},
		{
			name: "expired",
			exp:  &expiredTime,
			err:  ErrExpired{expiredTime.Format("2006-01-02 15:04:05 MST")},
		},
	}
	for _, t := range tests {
		if t.role == "" {
			t.role = "root"
		}
		if t.ver == 0 {
			t.ver = minVer
		}
		if t.exp == nil {
			expires := time.Now().Add(time.Hour)
			t.exp = &expires
		}
		if t.typ == "" {
			t.typ = data.TUFTypes[t.role]
		}
		if t.keys == nil && t.s == nil {
			k, _ := trust.Create("root", data.ED25519Key)
			meta := &signedMeta{Type: t.typ, Version: t.ver, Expires: t.exp.Format("2006-01-02 15:04:05 MST")}

			b, err := cjson.Marshal(meta)
			c.Assert(err, IsNil)
			s := &data.Signed{Signed: b}
			Sign(trust, s, k)
			t.s = s
			t.keys = []*data.PublicKey{k}
		}
		if t.roles == nil {
			t.roles = map[string]*data.Role{
				"root": &data.Role{
					RootRole: data.RootRole{
						KeyIDs:    []string{t.keys[0].ID()},
						Threshold: 1,
					},
					Name: "root",
				},
			}
		}
		if t.mut != nil {
			t.mut(&t)
		}

		db := keys.NewDB()
		for _, k := range t.keys {
			db.AddKey(k)
		}
		for _, r := range t.roles {
			err := db.AddRole(r)
			c.Assert(err, IsNil)
		}

		err := Verify(t.s, t.role, minVer, db)
		if e, ok := t.err.(ErrExpired); ok {
			assertErrExpired(c, err, e)
		} else {
			c.Assert(err, DeepEquals, t.err, Commentf("name = %s", t.name))
		}
	}
}
Example #8
0
func Test(t *testing.T) {
	cryptoService := NewEd25519()
	type test struct {
		name  string
		keys  []data.PublicKey
		roles map[string]*data.Role
		s     *data.Signed
		ver   int
		exp   *time.Time
		typ   string
		role  string
		err   error
		mut   func(*test)
	}

	expiredTime := time.Now().Add(-time.Hour)
	minVer := 10
	tests := []test{
		{
			name: "no signatures",
			mut:  func(t *test) { t.s.Signatures = []data.Signature{} },
			err:  ErrNoSignatures,
		},
		{
			name: "unknown role",
			role: "foo",
			err:  ErrUnknownRole,
		},
		//{
		//	name: "wrong signature method",
		//	mut:  func(t *test) { t.s.Signatures[0].Method = "foo" },
		//	err:  ErrWrongMethod,
		//},
		//	{
		//		name: "signature wrong length",
		//		mut:  func(t *test) { t.s.Signatures[0].Signature = []byte{0} },
		//		err:  ErrInvalid,
		//	},
		{
			name: "key missing from role",
			mut:  func(t *test) { t.roles["root"].KeyIDs = nil },
			err:  ErrRoleThreshold{},
		},
		//	{
		//		name: "invalid signature",
		//		mut:  func(t *test) { t.s.Signatures[0].Signature = make([]byte, ed25519.SignatureSize) },
		//		err:  ErrInvalid,
		//	},
		{
			name: "not enough signatures",
			mut:  func(t *test) { t.roles["root"].Threshold = 2 },
			err:  ErrRoleThreshold{},
		},
		{
			name: "exactly enough signatures",
		},
		{
			name: "more than enough signatures",
			mut: func(t *test) {
				k, _ := cryptoService.Create("root", data.ED25519Key)
				Sign(cryptoService, t.s, k)
				t.keys = append(t.keys, k)
				t.roles["root"].KeyIDs = append(t.roles["root"].KeyIDs, k.ID())
			},
		},
		{
			name: "duplicate key id",
			mut: func(t *test) {
				t.roles["root"].Threshold = 2
				t.s.Signatures = append(t.s.Signatures, t.s.Signatures[0])
			},
			err: ErrRoleThreshold{},
		},
		{
			name: "unknown key",
			mut: func(t *test) {
				k, _ := cryptoService.Create("root", data.ED25519Key)
				Sign(cryptoService, t.s, k)
			},
		},
		{
			name: "unknown key below threshold",
			mut: func(t *test) {
				k, _ := cryptoService.Create("root", data.ED25519Key)
				Sign(cryptoService, t.s, k)
				t.roles["root"].Threshold = 2
			},
			err: ErrRoleThreshold{},
		},
		{
			name: "unknown keys in db",
			mut: func(t *test) {
				k, _ := cryptoService.Create("root", data.ED25519Key)
				Sign(cryptoService, t.s, k)
				t.keys = append(t.keys, k)
			},
		},
		{
			name: "unknown keys in db below threshold",
			mut: func(t *test) {
				k, _ := cryptoService.Create("root", data.ED25519Key)
				Sign(cryptoService, t.s, k)
				t.keys = append(t.keys, k)
				t.roles["root"].Threshold = 2
			},
			err: ErrRoleThreshold{},
		},
		{
			name: "wrong type",
			typ:  "bar",
			err:  ErrWrongType,
		},
		{
			name: "low version",
			ver:  minVer - 1,
			err:  ErrLowVersion{minVer - 1, minVer},
		},
		{
			role: "root",
			name: "expired",
			exp:  &expiredTime,
			err:  ErrExpired{"root", expiredTime.Format("Mon Jan 2 15:04:05 MST 2006")},
		},
	}
	for _, run := range tests {
		if run.role == "" {
			run.role = "root"
		}
		if run.ver == 0 {
			run.ver = minVer
		}
		if run.exp == nil {
			expires := time.Now().Add(time.Hour)
			run.exp = &expires
		}
		if run.typ == "" {
			run.typ = data.TUFTypes[run.role]
		}
		if run.keys == nil && run.s == nil {
			k, _ := cryptoService.Create("root", data.ED25519Key)
			meta := &data.SignedCommon{Type: run.typ, Version: run.ver, Expires: *run.exp}

			b, err := cjson.Marshal(meta)
			assert.NoError(t, err)
			s := &data.Signed{Signed: b}
			Sign(cryptoService, s, k)
			run.s = s
			run.keys = []data.PublicKey{k}
		}
		if run.roles == nil {
			run.roles = map[string]*data.Role{
				"root": &data.Role{
					RootRole: data.RootRole{
						KeyIDs:    []string{run.keys[0].ID()},
						Threshold: 1,
					},
					Name: "root",
				},
			}
		}
		if run.mut != nil {
			run.mut(&run)
		}

		db := keys.NewDB()
		for _, k := range run.keys {
			db.AddKey(k)
		}
		for _, r := range run.roles {
			err := db.AddRole(r)
			assert.NoError(t, err)
		}

		err := Verify(run.s, run.role, minVer, db)
		if e, ok := run.err.(ErrExpired); ok {
			assertErrExpired(t, err, e)
		} else {
			assert.Equal(t, run.err, err)
		}
	}
}