// 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 }
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 }
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 }
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 }
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 }
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 }
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)) } } }
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) } } }