Skip to content

Commit

Permalink
let nonce be provided through proof options
Browse files Browse the repository at this point in the history
  • Loading branch information
reinkrul committed Dec 11, 2023
1 parent a32d1d6 commit 4d796c1
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 8 deletions.
2 changes: 2 additions & 0 deletions auth/services/oauth/relying_party.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,14 @@ func (s *relyingParty) RequestRFC021AccessToken(ctx context.Context, requester d
expires := time.Now().Add(time.Second * 5)
// todo: support multiple wallets
domain := verifier.String()
nonce := nutsCrypto.GenerateNonce()
vp, err := s.wallet.BuildPresentation(ctx, signInstructions[0].VerifiableCredentials, holder.PresentationOptions{
Format: format,
ProofOptions: proof.ProofOptions{
Created: time.Now(),
Expires: &expires,
Domain: &domain,
Nonce: &nonce,
},
}, &requester, false)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions vcr/holder/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,15 @@ func (h wallet) buildJWTPresentation(ctx context.Context, subjectDID did.DID, cr
jwt.IssuerKey: subjectDID.String(),
jwt.SubjectKey: subjectDID.String(),
jwt.JwtIDKey: id.String(),
"nonce": crypto.GenerateNonce(),
"vp": vc.VerifiablePresentation{
Context: append([]ssi.URI{VerifiableCredentialLDContextV1}, options.AdditionalContexts...),
Type: append([]ssi.URI{VerifiablePresentationLDType}, options.AdditionalTypes...),
VerifiableCredential: credentials,
},
}
if options.ProofOptions.Nonce != nil {
claims["nonce"] = *options.ProofOptions.Nonce
}
if options.ProofOptions.Domain != nil {
claims[jwt.AudienceKey] = *options.ProofOptions.Domain
}
Expand Down Expand Up @@ -172,8 +174,6 @@ func (h wallet) buildJSONLDPresentation(ctx context.Context, subjectDID did.DID,
}

ldProof := proof.NewLDProof(options.ProofOptions)
nonce := crypto.GenerateNonce()
ldProof.Nonce = &nonce
signingResult, err := ldProof.
Sign(ctx, document, signature.JSONWebSignature2020{ContextLoader: h.jsonldManager.DocumentLoader(), Signer: h.keyStore}, key)
if err != nil {
Expand Down
14 changes: 11 additions & 3 deletions vcr/holder/wallet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,20 @@ func TestWallet_BuildPresentation(t *testing.T) {
assert.Equal(t, JSONLDPresentationFormat, result.Format())
ldProof, err := credential.ParseLDProof(*result)
require.NoError(t, err)
assert.NotEmpty(t, ldProof.Nonce)
assert.Empty(t, ldProof.Nonce)
})
t.Run("ok - custom options", func(t *testing.T) {
ctrl := gomock.NewController(t)
specialType := ssi.MustParseURI("SpecialPresentation")
domain := "https://example.com"
nonce := "the-nonce"
options := PresentationOptions{
AdditionalContexts: []ssi.URI{credential.NutsV1ContextURI},
AdditionalTypes: []ssi.URI{specialType},
ProofOptions: proof.ProofOptions{
ProofPurpose: "authentication",
Domain: &domain,
Nonce: &nonce,
},
Format: JSONLDPresentationFormat,
}
Expand All @@ -118,10 +120,12 @@ func TestWallet_BuildPresentation(t *testing.T) {
require.NotNil(t, result)
assert.True(t, result.IsType(specialType))
assert.True(t, result.ContainsContext(credential.NutsV1ContextURI))
proofs, _ := result.Proofs()
var proofs []proof.LDProof
require.NoError(t, result.UnmarshalProofValue(&proofs))
require.Len(t, proofs, 1)
assert.Equal(t, "authentication", proofs[0].ProofPurpose)
assert.Equal(t, "https://example.com", *proofs[0].Domain)
assert.Equal(t, nonce, *proofs[0].Nonce)
assert.Equal(t, JSONLDPresentationFormat, result.Format())
})
t.Run("ok - multiple VCs", func(t *testing.T) {
Expand Down Expand Up @@ -159,7 +163,7 @@ func TestWallet_BuildPresentation(t *testing.T) {
assert.Equal(t, JWTPresentationFormat, result.Format())
assert.NotNil(t, result.JWT())
nonce, _ := result.JWT().Get("nonce")
assert.NotEmpty(t, nonce)
assert.Empty(t, nonce)
})
t.Run("ok - multiple VCs", func(t *testing.T) {
ctrl := gomock.NewController(t)
Expand All @@ -180,12 +184,14 @@ func TestWallet_BuildPresentation(t *testing.T) {
t.Run("optional proof options", func(t *testing.T) {
exp := time.Now().Local().Truncate(time.Second)
domain := "https://example.com"
nonce := "the-nonce"
options := PresentationOptions{
Format: JWTPresentationFormat,
ProofOptions: proof.ProofOptions{
Expires: &exp,
Created: exp.Add(-1 * time.Hour),
Domain: &domain,
Nonce: &nonce,
},
}

Expand All @@ -205,6 +211,8 @@ func TestWallet_BuildPresentation(t *testing.T) {
assert.Equal(t, *options.ProofOptions.Expires, result.JWT().Expiration().Local())
assert.Equal(t, options.ProofOptions.Created, result.JWT().NotBefore().Local())
assert.Equal(t, []string{domain}, result.JWT().Audience())
actualNonce, _ := result.JWT().Get("nonce")
assert.Equal(t, nonce, actualNonce)
})
})
t.Run("validation", func(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion vcr/signature/proof/jsonld.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ type ProofOptions struct {
// ProofPurpose contains a specific intent for the proof, the reason why an entity created it.
// Acts as a safeguard to prevent the proof from being misused for a purpose other than the one it was intended for.
ProofPurpose string `json:"proofPurpose"`
// Nonce contains a value that is used to prevent replay attacks
Nonce *string `json:"nonce,omitempty"`
}

// ValidAt checks if the proof is valid at a certain given time.
Expand All @@ -81,7 +83,6 @@ func (o ProofOptions) ValidAt(at time.Time, maxSkew time.Duration) bool {
// LDProof contains the fields of the Proof data model: https://w3c-ccg.github.io/data-integrity-spec/#proofs
type LDProof struct {
ProofOptions
Nonce *string `json:"nonce,omitempty"`
// Type contains the signature type. Its is determined from the key type.
Type ssi.ProofType `json:"type"`
// VerificationMethod is the key identifier for the public/private key pair used to sign this proof
Expand Down
2 changes: 1 addition & 1 deletion vcr/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ func CreateJSONLDPresentation(t *testing.T, subjectDID did.DID, visitor func(pre
ProofOptions: proof.ProofOptions{
Created: time.Now(),
Expires: &exp,
Nonce: &nonce,
},
Nonce: &nonce,
},
},
}
Expand Down

0 comments on commit 4d796c1

Please sign in to comment.