Skip to content

Commit a9b2595

Browse files
authored
Fix/pid 3454 verify profile (#93)
* verify if credentialSubjectID equal to ProfileID * refactor * add unit tests * fix formating * more unit tests; do verifyCredentialSubjectID private * change error message
1 parent 9f7320f commit a9b2595

15 files changed

+376
-119
lines changed

circuits.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package circuits
33
import (
44
"bytes"
55
"encoding/json"
6+
"math/big"
67
"reflect"
78
"sync"
89

@@ -358,3 +359,19 @@ func GetCircuit(id CircuitID) (*Data, error) {
358359
}
359360
return &circuit, nil
360361
}
362+
363+
// verifyCredentialSubjectID checks that the credentialSubject ID in the issuerClaim matches the profileID.
364+
func verifyCredentialSubjectID(userID core.ID, issuerClaim core.Claim, nonce *big.Int) error {
365+
profileID, err := core.ProfileID(userID, nonce)
366+
if err != nil {
367+
return errors.Errorf("failed to generate profile ID: %v", err)
368+
}
369+
credentialSubjectID, err := issuerClaim.GetID()
370+
if err != nil {
371+
return errors.Errorf("failed to get credential subject ID: %v", err)
372+
}
373+
if profileID.BigInt().Cmp(credentialSubjectID.BigInt()) != 0 {
374+
return errors.New(ErrorUserProfileMismatch)
375+
}
376+
return nil
377+
}

circuits_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"math/big"
66
"testing"
77

8+
it "github.com/iden3/go-circuits/v2/testing"
89
core "github.com/iden3/go-iden3-core/v2"
910
"github.com/iden3/go-merkletree-sql/v2"
1011
"github.com/stretchr/testify/assert"
@@ -92,3 +93,88 @@ func TestStateJsonMarshallers(t *testing.T) {
9293
require.NoError(t, err)
9394
require.Equal(t, in, out)
9495
}
96+
97+
func TestVerifyCredentialSubjectID(t *testing.T) {
98+
tests := []struct {
99+
name string
100+
user *it.IdentityTest
101+
claim func(t *testing.T) *core.Claim
102+
nonceSubject *big.Int
103+
}{
104+
{
105+
name: "Success. Same profileID with nonce",
106+
user: it.NewIdentity(t, userPK),
107+
nonceSubject: big.NewInt(10),
108+
claim: func(t *testing.T) *core.Claim {
109+
profileID, err := core.ProfileID(it.NewIdentity(t, userPK).ID, big.NewInt(10))
110+
require.NoError(t, err)
111+
return it.DefaultUserClaim(t, profileID)
112+
},
113+
},
114+
{
115+
name: "Success. Same genesis profileID",
116+
user: it.NewIdentity(t, userPK),
117+
nonceSubject: big.NewInt(0),
118+
claim: func(t *testing.T) *core.Claim {
119+
return it.DefaultUserClaim(t, it.NewIdentity(t, userPK).ID)
120+
},
121+
},
122+
}
123+
124+
for _, tt := range tests {
125+
t.Run(tt.name, func(t *testing.T) {
126+
err := verifyCredentialSubjectID(tt.user.ID, *tt.claim(t), tt.nonceSubject)
127+
require.NoError(t, err)
128+
})
129+
}
130+
}
131+
132+
func TestVerifyCredentialSubjectID_Error(t *testing.T) {
133+
tests := []struct {
134+
name string
135+
userID *it.IdentityTest
136+
claim func(t *testing.T) *core.Claim
137+
nonceSubject *big.Int
138+
err string
139+
}{
140+
{
141+
name: "Different userID on the claim",
142+
userID: it.NewIdentity(t, userPK),
143+
claim: func(t *testing.T) *core.Claim {
144+
// put another indentity to claim
145+
return it.DefaultUserClaim(t, it.NewIdentity(t, issuerPK).ID)
146+
},
147+
nonceSubject: big.NewInt(10),
148+
err: ErrorUserProfileMismatch,
149+
},
150+
{
151+
name: "Different nonceSubject on the claim",
152+
userID: it.NewIdentity(t, userPK),
153+
claim: func(t *testing.T) *core.Claim {
154+
profileID, err := core.ProfileID(it.NewIdentity(t, userPK).ID, big.NewInt(11))
155+
require.NoError(t, err)
156+
return it.DefaultUserClaim(t, profileID)
157+
},
158+
nonceSubject: big.NewInt(10),
159+
err: ErrorUserProfileMismatch,
160+
},
161+
{
162+
name: "Different nonceSubject on the claim. Genesis profile",
163+
userID: it.NewIdentity(t, userPK),
164+
claim: func(t *testing.T) *core.Claim {
165+
profileID, err := core.ProfileID(it.NewIdentity(t, userPK).ID, big.NewInt(11))
166+
require.NoError(t, err)
167+
return it.DefaultUserClaim(t, profileID)
168+
},
169+
nonceSubject: big.NewInt(0),
170+
err: ErrorUserProfileMismatch,
171+
},
172+
}
173+
174+
for _, tt := range tests {
175+
t.Run(tt.name, func(t *testing.T) {
176+
err := verifyCredentialSubjectID(tt.userID.ID, *tt.claim(t), tt.nonceSubject)
177+
require.EqualError(t, err, tt.err)
178+
})
179+
}
180+
}

credentialAtomicQueryMTPV2.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ func (a AtomicQueryMTPV2Inputs) Validate() error {
8686
return errors.New(ErrorEmptyRequestID)
8787
}
8888

89+
if err := verifyCredentialSubjectID(
90+
*a.ID, *a.Claim.Claim, a.ClaimSubjectProfileNonce); err != nil {
91+
return err
92+
}
93+
8994
return nil
9095
}
9196

credentialAtomicQueryMTPV2OnChain.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ func (a AtomicQueryMTPV2OnChainInputs) Validate() error {
146146
return errors.New(ErrorEmptyChallenge)
147147
}
148148

149+
if err := verifyCredentialSubjectID(
150+
*a.ID, *a.Claim.Claim, a.ClaimSubjectProfileNonce); err != nil {
151+
return err
152+
}
153+
149154
return nil
150155
}
151156

credentialAtomicQueryMTPV2OnChain_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"testing"
88

99
it "github.com/iden3/go-circuits/v2/testing"
10+
core "github.com/iden3/go-iden3-core/v2"
11+
"github.com/iden3/go-iden3-core/v2/w3c"
1012
"github.com/iden3/go-iden3-crypto/poseidon"
1113
"github.com/stretchr/testify/require"
1214
)
@@ -211,3 +213,16 @@ func TestAtomicQueryMTPVOnChain2Outputs_CircuitUnmarshal(t *testing.T) {
211213
require.NoError(t, err)
212214
require.Equal(t, wantStatesInfo, statesInfo, string(j))
213215
}
216+
217+
func TestAttrQueryMTPV2OnChain_ErrorUserProfileMismatch(t *testing.T) {
218+
did, err := w3c.ParseDID("did:iden3:polygon:amoy:x81nCirrkbsh7qZrbnzhZtkwfY76wjUmygcoYztcS")
219+
require.NoError(t, err)
220+
userID, err := core.IDFromDID(*did)
221+
require.NoError(t, err)
222+
223+
inputs := queryMTPV2OnChainInputs(t)
224+
inputs.ID = &userID
225+
226+
err = inputs.Validate()
227+
require.Equal(t, err.Error(), ErrorUserProfileMismatch)
228+
}

credentialAtomicQueryMTPV2_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"testing"
77

88
it "github.com/iden3/go-circuits/v2/testing"
9+
core "github.com/iden3/go-iden3-core/v2"
10+
"github.com/iden3/go-iden3-core/v2/w3c"
911
"github.com/stretchr/testify/require"
1012
)
1113

@@ -221,3 +223,16 @@ func TestAtomicQueryMTPV2Outputs_CircuitUnmarshal(t *testing.T) {
221223
require.NoError(t, err)
222224
require.Equal(t, wantStatesInfo, statesInfo, string(j))
223225
}
226+
227+
func TestAtomicQueryMTPV2Inputs_ErrorUserProfileMismatch(t *testing.T) {
228+
did, err := w3c.ParseDID("did:iden3:polygon:amoy:x81nCirrkbsh7qZrbnzhZtkwfY76wjUmygcoYztcS")
229+
require.NoError(t, err)
230+
userID, err := core.IDFromDID(*did)
231+
require.NoError(t, err)
232+
233+
inputs := queryMTPV2Inputs(t)
234+
inputs.ID = &userID
235+
236+
err = inputs.Validate()
237+
require.Equal(t, err.Error(), ErrorUserProfileMismatch)
238+
}

credentialAtomicQuerySigV2.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ func (a AtomicQuerySigV2Inputs) Validate() error {
107107
if a.Query.Values == nil {
108108
return errors.New(ErrorEmptyQueryValue)
109109
}
110+
111+
if err := verifyCredentialSubjectID(
112+
*a.ID, *a.Claim.Claim, a.ClaimSubjectProfileNonce); err != nil {
113+
return err
114+
}
115+
110116
return nil
111117
}
112118

credentialAtomicQuerySigV2OnChain.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,12 @@ func (a AtomicQuerySigV2OnChainInputs) Validate() error {
168168
if a.Challenge == nil {
169169
return errors.New(ErrorEmptyChallenge)
170170
}
171+
172+
if err := verifyCredentialSubjectID(
173+
*a.ID, *a.Claim.Claim, a.ClaimSubjectProfileNonce); err != nil {
174+
return err
175+
}
176+
171177
return nil
172178
}
173179

@@ -345,7 +351,6 @@ func (a AtomicQuerySigV2OnChainInputs) GetPublicStatesInfo() (StatesInfo, error)
345351
return statesInfo, nil
346352
}
347353

348-
349354
// AtomicQuerySigV2OnChainPubSignals public inputs
350355
type AtomicQuerySigV2OnChainPubSignals struct {
351356
BaseConfig

credentialAtomicQuerySigV2OnChain_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"testing"
88

99
it "github.com/iden3/go-circuits/v2/testing"
10+
core "github.com/iden3/go-iden3-core/v2"
11+
"github.com/iden3/go-iden3-core/v2/w3c"
1012
"github.com/iden3/go-iden3-crypto/poseidon"
1113
"github.com/stretchr/testify/require"
1214
)
@@ -219,3 +221,16 @@ func TestAtomicQuerySigV2OnChainOutputs_CircuitUnmarshal(t *testing.T) {
219221
require.NoError(t, err)
220222
require.Equal(t, wantStatesInfo, statesInfo, string(j))
221223
}
224+
225+
func TestAttrQuerySigV2OnChain_ErrorUserProfileMismatch(t *testing.T) {
226+
did, err := w3c.ParseDID("did:iden3:polygon:amoy:x81nCirrkbsh7qZrbnzhZtkwfY76wjUmygcoYztcS")
227+
require.NoError(t, err)
228+
userID, err := core.IDFromDID(*did)
229+
require.NoError(t, err)
230+
231+
inputs := querySigV2OnChainInputs(t)
232+
inputs.ID = &userID
233+
234+
err = inputs.Validate()
235+
require.Equal(t, err.Error(), ErrorUserProfileMismatch)
236+
}

credentialAtomicQuerySigV2_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
it "github.com/iden3/go-circuits/v2/testing"
1111
core "github.com/iden3/go-iden3-core/v2"
12+
"github.com/iden3/go-iden3-core/v2/w3c"
1213
"github.com/iden3/go-merkletree-sql/v2"
1314
"github.com/stretchr/testify/require"
1415
)
@@ -282,3 +283,16 @@ func hashPtrFromInt(i *big.Int) *merkletree.Hash {
282283
}
283284
return h
284285
}
286+
287+
func TestAttrQuerySigV2_ErrorUserProfileMismatch(t *testing.T) {
288+
did, err := w3c.ParseDID("did:iden3:polygon:amoy:x81nCirrkbsh7qZrbnzhZtkwfY76wjUmygcoYztcS")
289+
require.NoError(t, err)
290+
userID, err := core.IDFromDID(*did)
291+
require.NoError(t, err)
292+
293+
inputs := querySigV2Inputs(t)
294+
inputs.ID = &userID
295+
296+
err = inputs.Validate()
297+
require.Equal(t, err.Error(), ErrorUserProfileMismatch)
298+
}

0 commit comments

Comments
 (0)