99 "github.com/TBD54566975/ssi-sdk/did"
1010 "github.com/goccy/go-json"
1111 "github.com/google/uuid"
12+ "github.com/lestrrat-go/jwx/v2/jwa"
1213 "github.com/lestrrat-go/jwx/v2/jws"
1314 "github.com/lestrrat-go/jwx/v2/jwt"
1415 "github.com/pkg/errors"
@@ -81,7 +82,13 @@ func SignVerifiableCredentialJWT(signer jwx.Signer, cred VerifiableCredential) (
8182 return nil , errors .New ("setting credential value" )
8283 }
8384
84- signed , err := jwt .Sign (t , jwt .WithKey (signer .SignatureAlgorithm , signer .Key ))
85+ hdrs := jws .NewHeaders ()
86+ if signer .KID != "" {
87+ if err := hdrs .Set (jws .KeyIDKey , signer .KID ); err != nil {
88+ return nil , errors .Wrap (err , "setting KID protected header" )
89+ }
90+ }
91+ signed , err := jwt .Sign (t , jwt .WithKey (jwa .SignatureAlgorithm (signer .ALG ), signer .PrivateKey , jws .WithProtectedHeaders (hdrs )))
8592 if err != nil {
8693 return nil , errors .Wrap (err , "signing JWT credential" )
8794 }
@@ -179,18 +186,15 @@ func ParseVerifiableCredentialFromToken(token jwt.Token) (*VerifiableCredential,
179186
180187// JWTVVPParameters represents additional parameters needed when constructing a JWT VP as opposed to a VP
181188type JWTVVPParameters struct {
182- // Audience is a required intended audience of the JWT.
183- Audience string `validate:"required"`
189+ // Audience is an optional audience of the JWT.
190+ Audience [] string
184191 // Expiration is an optional expiration time of the JWT using the `exp` property.
185192 Expiration int
186193}
187194
188195// SignVerifiablePresentationJWT transforms a VP into a VP JWT and signs it
189196// According to https://w3c.github.io/vc-jwt/#version-1.1
190197func SignVerifiablePresentationJWT (signer jwx.Signer , parameters JWTVVPParameters , presentation VerifiablePresentation ) ([]byte , error ) {
191- if parameters .Audience == "" {
192- return nil , errors .New ("audience cannot be empty" )
193- }
194198 if presentation .IsEmpty () {
195199 return nil , errors .New ("presentation cannot be empty" )
196200 }
@@ -200,8 +204,14 @@ func SignVerifiablePresentationJWT(signer jwx.Signer, parameters JWTVVPParameter
200204
201205 t := jwt .New ()
202206 // set JWT-VP specific parameters
203- if err := t .Set (jwt .AudienceKey , parameters .Audience ); err != nil {
204- return nil , errors .Wrap (err , "setting audience value" )
207+
208+ // NOTE: according to the JWT encoding rules (https://www.w3.org/TR/vc-data-model/#jwt-encoding) aud is a required
209+ // property; however, aud is not required according to the JWT spec. Requiring audience limits a number of cases
210+ // where JWT-VPs can be used, so we do not enforce this requirement.
211+ if parameters .Audience != nil {
212+ if err := t .Set (jwt .AudienceKey , parameters .Audience ); err != nil {
213+ return nil , errors .Wrap (err , "setting audience value" )
214+ }
205215 }
206216 iatAndNBF := time .Now ().Unix ()
207217 if err := t .Set (jwt .IssuedAtKey , iatAndNBF ); err != nil {
@@ -241,7 +251,13 @@ func SignVerifiablePresentationJWT(signer jwx.Signer, parameters JWTVVPParameter
241251 return nil , errors .Wrap (err , "setting vp value" )
242252 }
243253
244- signed , err := jwt .Sign (t , jwt .WithKey (signer .SignatureAlgorithm , signer .Key ))
254+ hdrs := jws .NewHeaders ()
255+ if signer .KID != "" {
256+ if err := hdrs .Set (jws .KeyIDKey , signer .KID ); err != nil {
257+ return nil , errors .Wrap (err , "setting KID protected header" )
258+ }
259+ }
260+ signed , err := jwt .Sign (t , jwt .WithKey (jwa .SignatureAlgorithm (signer .ALG ), signer .PrivateKey , jws .WithProtectedHeaders (hdrs )))
245261 if err != nil {
246262 return nil , errors .Wrap (err , "signing JWT presentation" )
247263 }
@@ -272,13 +288,13 @@ func VerifyVerifiablePresentationJWT(ctx context.Context, verifier jwx.Verifier,
272288 // make sure the audience matches the verifier
273289 audMatch := false
274290 for _ , aud := range vpToken .Audience () {
275- if aud == verifier .ID || aud == verifier .KeyID () {
291+ if aud == verifier .ID || aud == verifier .KID {
276292 audMatch = true
277293 break
278294 }
279295 }
280296 if ! audMatch {
281- return nil , nil , nil , errors .Errorf ("audience mismatch: expected [%s] or [%s], got %s" , verifier .ID , verifier .KeyID () , vpToken .Audience ())
297+ return nil , nil , nil , errors .Errorf ("audience mismatch: expected [%s] or [%s], got %s" , verifier .ID , verifier .KID , vpToken .Audience ())
282298 }
283299
284300 // verify signature for each credential in the vp
0 commit comments