diff --git a/watchtower/wtdb/tower_db.go b/watchtower/wtdb/tower_db.go index 2defce213..8610f04d9 100644 --- a/watchtower/wtdb/tower_db.go +++ b/watchtower/wtdb/tower_db.go @@ -46,6 +46,10 @@ var ( // ErrNoSessionHintIndex signals that an active session does not have an // initialized index for tracking its own state updates. ErrNoSessionHintIndex = errors.New("session hint index missing") + + // ErrInvalidBlobSize indicates that the encrypted blob provided by the + // client is not valid according to the blob type of the session. + ErrInvalidBlobSize = errors.New("invalid blob size") ) // TowerDB is single database providing a persistent storage engine for the @@ -233,6 +237,13 @@ func (t *TowerDB) InsertStateUpdate(update *SessionStateUpdate) (uint16, error) return err } + // Assert that the blob is the correct size for the session's + // blob type. + expBlobSize := blob.Size(session.Policy.BlobType) + if len(update.EncryptedBlob) != expBlobSize { + return ErrInvalidBlobSize + } + // Validate the update against the current state of the session. err = session.AcceptUpdateSequence( update.SeqNum, update.LastApplied, diff --git a/watchtower/wtdb/tower_db_test.go b/watchtower/wtdb/tower_db_test.go index a1f75abbe..506f9b17d 100644 --- a/watchtower/wtdb/tower_db_test.go +++ b/watchtower/wtdb/tower_db_test.go @@ -586,6 +586,30 @@ var stateUpdateRevertLastApplied = stateUpdateTest{ }, } +var stateUpdateInvalidBlobSize = stateUpdateTest{ + session: &wtdb.SessionInfo{ + ID: *id(0), + Policy: wtpolicy.Policy{ + TxPolicy: wtpolicy.TxPolicy{ + BlobType: blob.TypeAltruistCommit, + }, + MaxUpdates: 3, + }, + RewardAddress: []byte{}, + }, + updates: []*wtdb.SessionStateUpdate{ + { + ID: *id(0), + SeqNum: 1, + LastApplied: 0, + EncryptedBlob: []byte{0x01, 0x02, 0x03}, // too $hort + }, + }, + updateErrs: []error{ + wtdb.ErrInvalidBlobSize, + }, +} + func TestTowerDB(t *testing.T) { dbs := []struct { name string @@ -703,6 +727,10 @@ func TestTowerDB(t *testing.T) { name: "state update revert last applied", run: runStateUpdateTest(stateUpdateRevertLastApplied), }, + { + name: "invalid blob size", + run: runStateUpdateTest(stateUpdateInvalidBlobSize), + }, { name: "multiple breach matches", run: testMultipleMatches, diff --git a/watchtower/wtmock/tower_db.go b/watchtower/wtmock/tower_db.go index 27cc25f98..1c7b94c9d 100644 --- a/watchtower/wtmock/tower_db.go +++ b/watchtower/wtmock/tower_db.go @@ -37,6 +37,11 @@ func (db *TowerDB) InsertStateUpdate(update *wtdb.SessionStateUpdate) (uint16, e return 0, wtdb.ErrSessionNotFound } + // Assert that the blob is the correct size for the session's blob type. + if len(update.EncryptedBlob) != blob.Size(info.Policy.BlobType) { + return 0, wtdb.ErrInvalidBlobSize + } + err := info.AcceptUpdateSequence(update.SeqNum, update.LastApplied) if err != nil { return info.LastApplied, err