diff --git a/doc/swagger.yaml b/doc/swagger.yaml index 9debc12fa..cae44d69c 100644 --- a/doc/swagger.yaml +++ b/doc/swagger.yaml @@ -1,6 +1,8 @@ definitions: credential.CredentialSchema: properties: + digestSRI: + type: string id: type: string type: @@ -214,6 +216,20 @@ definitions: - WebMethod - IONMethod - JWKMethod + did.PublicKeyPurpose: + enum: + - authentication + - assertionMethod + - capabilityInvocation + - capabilityDelegation + - keyAgreement + type: string + x-enum-varnames: + - Authentication + - AssertionMethod + - CapabilityInvocation + - CapabilityDelegation + - KeyAgreement did.VerificationMethod: properties: blockchainAccountId: @@ -896,25 +912,11 @@ definitions: $ref: '#/definitions/jwx.PublicKeyJWK' purposes: items: - $ref: '#/definitions/ion.PublicKeyPurpose' + $ref: '#/definitions/did.PublicKeyPurpose' type: array type: type: string type: object - ion.PublicKeyPurpose: - enum: - - authentication - - assertionMethod - - capabilityInvocation - - capabilityDelegation - - keyAgreement - type: string - x-enum-varnames: - - Authentication - - AssertionMethod - - CapabilityInvocation - - CapabilityDelegation - - KeyAgreement jwx.PublicKeyJWK: properties: alg: diff --git a/go.mod b/go.mod index 3743941bc..ecce3f8c9 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/BurntSushi/toml v1.3.2 - github.com/TBD54566975/ssi-sdk v0.0.4-alpha.0.20230818212001-6e1043316e75 + github.com/TBD54566975/ssi-sdk v0.0.4-alpha.0.20231030185053-d2001a482ff8 github.com/alicebob/miniredis/v2 v2.31.0 github.com/ardanlabs/conf v1.5.0 github.com/benbjohnson/clock v1.3.5 @@ -22,7 +22,7 @@ require ( github.com/google/uuid v1.3.1 github.com/joho/godotenv v1.5.1 github.com/lestrrat-go/jwx v1.2.26 - github.com/lestrrat-go/jwx/v2 v2.0.13 + github.com/lestrrat-go/jwx/v2 v2.0.15 github.com/lib/pq v1.10.9 github.com/magefile/mage v1.15.0 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 @@ -61,12 +61,12 @@ require ( github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aws/aws-sdk-go v1.44.277 // indirect - github.com/bits-and-blooms/bitset v1.8.0 // indirect + github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/cloudflare/circl v1.3.3 // indirect + github.com/cloudflare/circl v1.3.6 // indirect github.com/creasty/defaults v1.7.0 // indirect github.com/cristalhq/jwt/v4 v4.0.2 // indirect github.com/dave/jennifer v1.6.1 // indirect @@ -87,7 +87,7 @@ require ( github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/spec v0.20.9 // indirect github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-playground/validator/v10 v10.15.0 // indirect + github.com/go-playground/validator/v10 v10.15.1 // indirect github.com/golang/glog v1.1.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect @@ -96,7 +96,7 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/gowebpki/jcs v1.0.0 // indirect + github.com/gowebpki/jcs v1.0.1 // indirect github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.4 // indirect diff --git a/go.sum b/go.sum index c511a99a5..3506cdba5 100644 --- a/go.sum +++ b/go.sum @@ -47,8 +47,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= -github.com/TBD54566975/ssi-sdk v0.0.4-alpha.0.20230818212001-6e1043316e75 h1:nUuLKpzXuJBCEzInbsypquopNW8IleHmId+Gh6l6Yu8= -github.com/TBD54566975/ssi-sdk v0.0.4-alpha.0.20230818212001-6e1043316e75/go.mod h1:6HfhtzYPqY/5on4tCFN54iv10td+zKiUJUptAEGHv7U= +github.com/TBD54566975/ssi-sdk v0.0.4-alpha.0.20231030185053-d2001a482ff8 h1:5u8nJAbahMVHtuFpyjXPAa3obai69KRTxEpsdQpeHYA= +github.com/TBD54566975/ssi-sdk v0.0.4-alpha.0.20231030185053-d2001a482ff8/go.mod h1:SSC6mIgP6XqXjeZ5YUZS21S7lbsetkEC0gVh9EPL2vM= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= @@ -64,8 +64,8 @@ github.com/aws/aws-sdk-go v1.44.277 h1:YHmyzBPARTJ7LLYV1fxbfEbQOaUh3kh52hb7nBvX3 github.com/aws/aws-sdk-go v1.44.277/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c= -github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= @@ -94,8 +94,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg= +github.com/cloudflare/circl v1.3.6/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -183,8 +183,8 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.15.0 h1:nDU5XeOKtB3GEa+uB7GNYwhVKsgjAR7VgKoNB6ryXfw= -github.com/go-playground/validator/v10 v10.15.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.15.1 h1:BSe8uhN+xQ4r5guV/ywQI4gO59C2raYcGffYWZEjZzM= +github.com/go-playground/validator/v10 v10.15.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -271,8 +271,8 @@ github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qK github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gowebpki/jcs v1.0.0 h1:0pZtOgGetfH/L7yXb4KWcJqIyZNA43WXFyMd7ftZACw= -github.com/gowebpki/jcs v1.0.0/go.mod h1:CID1cNZ+sHp1CCpAR8mPf6QRtagFBgPJE0FCUQ6+BrI= +github.com/gowebpki/jcs v1.0.1 h1:Qjzg8EOkrOTuWP7DqQ1FbYtcpEbeTzUoTN9bptp8FOU= +github.com/gowebpki/jcs v1.0.1/go.mod h1:CID1cNZ+sHp1CCpAR8mPf6QRtagFBgPJE0FCUQ6+BrI= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= @@ -302,8 +302,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= -github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= +github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= +github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= @@ -350,8 +350,8 @@ github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzlt github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= github.com/lestrrat-go/jwx v1.2.26 h1:4iFo8FPRZGDYe1t19mQP0zTRqA7n8HnJ5lkIiDvJcB0= github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDuIkx8ftpQ= -github.com/lestrrat-go/jwx/v2 v2.0.13 h1:XdxzJbudGaHEoNmyJACAT8aFCB+DmviiaiMoZwuJoUo= -github.com/lestrrat-go/jwx/v2 v2.0.13/go.mod h1:UzXMzcV99p9/xe1JsIb336NJDGXLsleR+Qj3ucEDtfI= +github.com/lestrrat-go/jwx/v2 v2.0.15 h1:XvR2lQdX+mZechmqWxqQb2foU3hgAn5+Rj0ICa0I6sU= +github.com/lestrrat-go/jwx/v2 v2.0.15/go.mod h1:jBHyESp4e7QxfERM0UKkQ80/94paqNIEcdEfiUYz5zE= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= @@ -551,7 +551,6 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -713,7 +712,6 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -722,7 +720,6 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/schema/resolver.go b/internal/schema/resolver.go index 7fe6ef19e..40d255cc9 100644 --- a/internal/schema/resolver.go +++ b/internal/schema/resolver.go @@ -8,5 +8,5 @@ import ( // Resolution is an interface that defines a generic method of resolving a schema type Resolution interface { - Resolve(ctx context.Context, id string) (*schema.JSONSchema, schema.VCJSONSchemaType, error) + Resolve(ctx context.Context, id string) (*schema.JSONSchema, *schema.VCJSONSchema, schema.VCJSONSchemaType, error) } diff --git a/internal/verification/verification.go b/internal/verification/verification.go index 3d8ea82bd..9c7d9954a 100644 --- a/internal/verification/verification.go +++ b/internal/verification/verification.go @@ -3,9 +3,11 @@ package verification import ( "context" "fmt" + "strings" credsdk "github.com/TBD54566975/ssi-sdk/credential" "github.com/TBD54566975/ssi-sdk/credential/integrity" + schemalib "github.com/TBD54566975/ssi-sdk/credential/schema" "github.com/TBD54566975/ssi-sdk/credential/validation" "github.com/TBD54566975/ssi-sdk/crypto" "github.com/TBD54566975/ssi-sdk/crypto/jwx" @@ -14,6 +16,8 @@ import ( sdkutil "github.com/TBD54566975/ssi-sdk/util" "github.com/goccy/go-json" "github.com/pkg/errors" + "github.com/tbd54566975/ssi-service/config" + "github.com/tbd54566975/ssi-service/pkg/service/framework" "github.com/tbd54566975/ssi-service/internal/credential" didint "github.com/tbd54566975/ssi-service/internal/did" @@ -165,16 +169,24 @@ func (v Verifier) staticValidationChecks(ctx context.Context, credential credsdk // if the credential has a schema, resolve it before it is to be used in verification var validationOpts []validation.Option if credential.CredentialSchema != nil { - schemaID := credential.CredentialSchema.ID - resolvedSchema, _, err := v.schemaResolver.Resolve(ctx, schemaID) + schemaID := strings.Replace(credential.CredentialSchema.ID, config.GetServicePath(framework.Schema)+"/", "", 1) + resolvedSchema, resolvedSchemaCred, schemaType, err := v.schemaResolver.Resolve(ctx, schemaID) if err != nil { return errors.Wrapf(err, "for credential<%s> failed to resolve schemas: %s", credential.ID, schemaID) } - schemaBytes, err := json.Marshal(resolvedSchema) - if err != nil { - return errors.Wrapf(err, "for credential<%s> failed to marshal schema: %s", credential.ID, schemaID) + if schemaType == schemalib.JSONSchemaType { + schemaBytes, err := json.Marshal(resolvedSchema) + if err != nil { + return errors.Wrapf(err, "for credential<%s> failed to marshal schema: %s", credential.ID, schemaID) + } + validationOpts = append(validationOpts, validation.WithSchema(string(schemaBytes))) + } else { + schemaCredBytes, err := json.Marshal(resolvedSchemaCred) + if err != nil { + return errors.Wrap(err, "marshalling json schema credential") + } + validationOpts = append(validationOpts, validation.WithSchema(string(schemaCredBytes))) } - validationOpts = append(validationOpts, validation.WithSchema(string(schemaBytes))) } // run the configured static checks on the credential diff --git a/pkg/server/router/credential_test.go b/pkg/server/router/credential_test.go index 6a80dfc33..1642f9025 100644 --- a/pkg/server/router/credential_test.go +++ b/pkg/server/router/credential_test.go @@ -1208,7 +1208,7 @@ func createCredServicePrereqs(tt *testing.T, s storage.ServiceStorage) (issuer, func getEmailSchema() map[string]any { return map[string]any{ - "$schema": "https://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "properties": map[string]any{ "credentialSubject": map[string]any{ diff --git a/pkg/server/router/manifest_test.go b/pkg/server/router/manifest_test.go index db2a505cb..2eca08229 100644 --- a/pkg/server/router/manifest_test.go +++ b/pkg/server/router/manifest_test.go @@ -124,7 +124,7 @@ func TestManifestRouter(t *testing.T) { // create a schema for the creds to be issued against licenseSchema := map[string]any{ - "$schema": "https://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "properties": map[string]any{ "credentialSubject": map[string]any{ diff --git a/pkg/server/router/schema_test.go b/pkg/server/router/schema_test.go index da8d4f887..b94d79dfc 100644 --- a/pkg/server/router/schema_test.go +++ b/pkg/server/router/schema_test.go @@ -175,7 +175,7 @@ func TestSchemaSigning(t *testing.T) { func getSimpleSchema() map[string]any { simpleSchema := map[string]any{ - "$schema": "https://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "properties": map[string]any{ "credentialSubject": map[string]any{ diff --git a/pkg/server/server_credential_test.go b/pkg/server/server_credential_test.go index 5ec18b846..c1fe6cc10 100644 --- a/pkg/server/server_credential_test.go +++ b/pkg/server/server_credential_test.go @@ -428,7 +428,7 @@ func TestCredentialAPI(t *testing.T) { // create a schema simpleSchema := map[string]any{ - "$schema": "https://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "properties": map[string]any{ "credentialSubject": map[string]any{ @@ -613,7 +613,7 @@ func TestCredentialAPI(t *testing.T) { // create a schema simpleSchema := map[string]any{ - "$schema": "https://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "properties": map[string]any{ "credentialSubject": map[string]any{ diff --git a/pkg/server/server_did_test.go b/pkg/server/server_did_test.go index 32c71c23e..fa2717814 100644 --- a/pkg/server/server_did_test.go +++ b/pkg/server/server_did_test.go @@ -312,8 +312,8 @@ func TestDIDAPI(t *testing.T) { X: "tXSKB_rubXS7sCjXqupVJEzTcW3MsjmEvq1YpXn96Zg", Y: "dOicXqbjFxoGJ-K0-GJ1kHYJqic_D_OMuUwkQ7Ol6nk", }, - Purposes: []ion.PublicKeyPurpose{ - ion.Authentication, ion.KeyAgreement, + Purposes: []didsdk.PublicKeyPurpose{ + didsdk.Authentication, didsdk.KeyAgreement, }, }, }, diff --git a/pkg/server/server_issuance_test.go b/pkg/server/server_issuance_test.go index 377c60bea..58e75617c 100644 --- a/pkg/server/server_issuance_test.go +++ b/pkg/server/server_issuance_test.go @@ -412,7 +412,7 @@ func setupAllThings(t *testing.T, s storage.ServiceStorage) (*did.CreateDIDRespo require.NoError(t, err) licenseSchema := map[string]any{ - "$schema": "https://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "properties": map[string]any{ "credentialSubject": map[string]any{ diff --git a/pkg/server/server_manifest_test.go b/pkg/server/server_manifest_test.go index 3e50bc274..5fe24b33b 100644 --- a/pkg/server/server_manifest_test.go +++ b/pkg/server/server_manifest_test.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "net/http/httptest" + "strings" "testing" "time" @@ -462,7 +463,7 @@ func TestManifestAPI(t *testing.T) { } assert.Equal(tt, expectedSubject, vc.CredentialSubject) assert.Equal(tt, time.Date(2022, 10, 31, 0, 0, 0, 0, time.UTC).Format(time.RFC3339), vc.ExpirationDate) - assert.Equal(tt, licenseSchema.ID, vc.CredentialSchema.ID) + assert.True(tt, strings.HasSuffix(vc.CredentialSchema.ID, licenseSchema.ID)) assert.Empty(tt, vc.CredentialStatus) _, _, vc2, err := parsing.ToCredential(appResp.Credentials[1]) @@ -485,7 +486,7 @@ func TestManifestAPI(t *testing.T) { time.Date(2022, 10, 31, 0, 0, 5, 0, time.UTC).Format(time.RFC3339), vc2.ExpirationDate, ) - assert.Equal(tt, licenseSchema.ID, vc2.CredentialSchema.ID) + assert.True(tt, strings.HasSuffix(vc2.CredentialSchema.ID, licenseSchema.ID)) assert.NotEmpty(tt, vc2.CredentialStatus) }) @@ -651,7 +652,7 @@ func TestManifestAPI(t *testing.T) { }, vc.CredentialSubject) assert.Equal(tt, expireAt.Format(time.RFC3339), vc.ExpirationDate) assert.NotEmpty(tt, vc.CredentialStatus) - assert.Equal(tt, licenseSchema.ID, vc.CredentialSchema.ID) + assert.True(tt, strings.HasSuffix(vc.CredentialSchema.ID, licenseSchema.ID)) }) t.Run("Test Denied Application", func(tt *testing.T) { @@ -1175,7 +1176,7 @@ func getValidIssuanceTemplateRequest(m manifest.CredentialManifest, issuerDID *d func getLicenseApplicationSchema() map[string]any { return map[string]any{ - "$schema": "https://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "properties": map[string]any{ "credentialSubject": map[string]any{ @@ -1193,7 +1194,7 @@ func getLicenseApplicationSchema() map[string]any { func getLicenseSchema() map[string]any { return map[string]any{ - "$schema": "https://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "properties": map[string]any{ "credentialSubject": map[string]any{ diff --git a/pkg/server/server_schema_test.go b/pkg/server/server_schema_test.go index 2dd18b4e9..a692cf205 100644 --- a/pkg/server/server_schema_test.go +++ b/pkg/server/server_schema_test.go @@ -299,7 +299,7 @@ func TestSchemaAPI(t *testing.T) { func getTestSchema() schema.JSONSchema { return map[string]any{ "$id": "https://example.com/foo.schema.json", - "$schema": "https://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft-07/schema#", "name": "test schema", "description": "test schema", "type": "object", diff --git a/pkg/service/credential/service.go b/pkg/service/credential/service.go index 3d094181a..8a33833d9 100644 --- a/pkg/service/credential/service.go +++ b/pkg/service/credential/service.go @@ -174,18 +174,23 @@ func (s Service) createCredential(ctx context.Context, request CreateCredentialR } // if a schema value exists, verify we can access it, validate the data against it, then set it - var knownSchema *schemalib.JSONSchema + var knownSchema map[string]any if request.SchemaID != "" { // resolve schema and save it for validation later - gotSchema, schemaType, err := s.schema.Resolve(ctx, request.SchemaID) + gotSchema, gotSchemaCred, schemaType, err := s.schema.Resolve(ctx, request.SchemaID) if err != nil { return nil, sdkutil.LoggingErrorMsgf(err, "failed to create credential; could not get schema: %s", request.SchemaID) } - knownSchema = gotSchema credSchema := credential.CredentialSchema{ - ID: request.SchemaID, Type: schemaType.String(), } + if schemaType == schemalib.JSONSchemaType { + knownSchema = *gotSchema + credSchema.ID = gotSchema.ID() + } else { + knownSchema = *gotSchemaCred + credSchema.ID = (*gotSchemaCred)["id"].(string) + } if err = builder.SetCredentialSchema(credSchema); err != nil { return nil, sdkutil.LoggingErrorMsgf(err, "could not set JSON Schema for credential: %s", request.SchemaID) } @@ -229,7 +234,7 @@ func (s Service) createCredential(ctx context.Context, request CreateCredentialR // verify the built schema complies with the schema we've set if knownSchema != nil { - if err = schemalib.IsCredentialValidForJSONSchema(*cred, *knownSchema); err != nil { + if err = schemalib.IsCredentialValidForJSONSchema(*cred, knownSchema, schemalib.VCJSONSchemaType(cred.CredentialSchema.Type)); err != nil { return nil, sdkutil.LoggingErrorMsgf(err, "credential data does not comply with the provided schema: %s", request.SchemaID) } } diff --git a/pkg/service/credential/storage.go b/pkg/service/credential/storage.go index a35abb1c8..de78fb8cb 100644 --- a/pkg/service/credential/storage.go +++ b/pkg/service/credential/storage.go @@ -13,10 +13,12 @@ import ( "github.com/goccy/go-json" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "github.com/tbd54566975/ssi-service/config" credint "github.com/tbd54566975/ssi-service/internal/credential" "github.com/tbd54566975/ssi-service/internal/keyaccess" "github.com/tbd54566975/ssi-service/internal/util" "github.com/tbd54566975/ssi-service/pkg/service/common" + "github.com/tbd54566975/ssi-service/pkg/service/framework" "github.com/tbd54566975/ssi-service/pkg/storage" "go.einride.tech/aip/filtering" ) @@ -323,7 +325,7 @@ func buildStoredCredential(request StoreCredentialRequest) (*StoredCredential, e // schema is not a required field, so we must do this check schema := "" if cred.CredentialSchema != nil { - schema = cred.CredentialSchema.ID + schema = strings.Replace(cred.CredentialSchema.ID, config.GetServicePath(framework.Schema)+"/", "", 1) } return &StoredCredential{ Key: createPrefixKey(credID, issuer, subject, schema), diff --git a/pkg/service/did/ion.go b/pkg/service/did/ion.go index f919ca8b2..23dbdc29b 100644 --- a/pkg/service/did/ion.go +++ b/pkg/service/did/ion.go @@ -411,7 +411,7 @@ func (h *ionHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (* Type: request.KeyType.String(), PublicKeyJWK: *pubKeyJWK, // TODO(gabe): configurable purposes - Purposes: []ion.PublicKeyPurpose{ion.Authentication, ion.AssertionMethod}, + Purposes: []did.PublicKeyPurpose{did.Authentication, did.AssertionMethod}, }, } pubKeys = append(pubKeys, publicKeysFromJWS...) diff --git a/pkg/service/did/ion_test.go b/pkg/service/did/ion_test.go index f9385748e..11f572897 100644 --- a/pkg/service/did/ion_test.go +++ b/pkg/service/did/ion_test.go @@ -85,7 +85,7 @@ func TestIONHandler(t *testing.T) { ID: "test-id", Type: "JsonWebKey2020", PublicKeyJWK: *jwxJWK, - Purposes: []ion.PublicKeyPurpose{ion.Authentication}, + Purposes: []did.PublicKeyPurpose{did.Authentication}, } ionPublicKeyData, err := json.Marshal(ionPublicKey) require.NoError(tt, err) diff --git a/pkg/service/schema/service.go b/pkg/service/schema/service.go index b188f34c2..f11add208 100644 --- a/pkg/service/schema/service.go +++ b/pkg/service/schema/service.go @@ -120,8 +120,8 @@ func (s Service) CreateSchema(ctx context.Context, request CreateSchemaRequest) // create schema for storage storedSchema := StoredSchema{ID: schemaID} if request.IsCredentialSchemaRequest() { - jsonSchema[schema.JSONSchemaIDProperty] = schemaID - credSchema, err := s.createCredentialSchema(ctx, jsonSchema, schemaURI, request.Issuer, request.FullyQualifiedVerificationMethodID) + jsonSchema[schema.JSONSchemaIDProperty] = schemaURI + credSchema, err := s.createCredentialSchema(ctx, jsonSchema, schemaURI, request.Issuer, request.FullyQualifiedVerificationMethodID, schemaID) if err != nil { return nil, sdkutil.LoggingErrorMsg(err, "could not create credential schema") } @@ -146,7 +146,7 @@ func (s Service) CreateSchema(ctx context.Context, request CreateSchemaRequest) } // createCredentialSchema creates a credential schema, and signs it with the issuer's key and kid -func (s Service) createCredentialSchema(ctx context.Context, jsonSchema schema.JSONSchema, schemaURI, issuer, fullyQualifiedVerificationMethodID string) (*keyaccess.JWT, error) { +func (s Service) createCredentialSchema(ctx context.Context, jsonSchema schema.JSONSchema, schemaURI, issuer, fullyQualifiedVerificationMethodID, schemaID string) (*keyaccess.JWT, error) { builder := credential.NewVerifiableCredentialBuilder() if err := builder.SetID(schemaURI); err != nil { return nil, sdkutil.LoggingErrorMsgf(err, "building credential when setting id: %s", schemaURI) @@ -154,10 +154,18 @@ func (s Service) createCredentialSchema(ctx context.Context, jsonSchema schema.J if err := builder.SetIssuer(issuer); err != nil { return nil, sdkutil.LoggingErrorMsgf(err, "building credential when setting issuer: %s", issuer) } - + if err := builder.SetCredentialSchema(credential.CredentialSchema{ + ID: "https://www.w3.org/2022/credentials/v2/json-schema-credential-schema.json", + Type: "JsonSchema", + DigestSRI: "sha384-S57yQDg1MTzF56Oi9DbSQ14u7jBy0RDdx0YbeV7shwhCS88G8SCXeFq82PafhCrW", + }); err != nil { + return nil, sdkutil.LoggingErrorMsg(err, "building credential when setting credential schema") + } // set subject's jsonSchema value as the schema subject := make(credential.CredentialSubject) subject[credential.VerifiableCredentialJSONSchemaProperty] = jsonSchema + subject[credential.VerifiableCredentialIDProperty] = "urn:uuid:" + schemaID + subject[schema.TypeProperty] = schema.JSONSchemaType if err := builder.SetCredentialSubject(subject); err != nil { return nil, sdkutil.LoggingErrorMsgf(err, "could not set subject: %+v", subject) } @@ -245,33 +253,43 @@ func (s Service) DeleteSchema(ctx context.Context, request DeleteSchemaRequest) } // Resolve wraps our get schema method for exposing schema access to other services -func (s Service) Resolve(ctx context.Context, id string) (*schema.JSONSchema, schema.VCJSONSchemaType, error) { +func (s Service) Resolve(ctx context.Context, id string) (*schema.JSONSchema, *schema.VCJSONSchema, schema.VCJSONSchemaType, error) { gotSchemaResponse, err := s.GetSchema(ctx, GetSchemaRequest{ID: id}) if err != nil { - return nil, "", sdkutil.LoggingErrorMsg(err, "resolving schema") + return nil, nil, "", sdkutil.LoggingErrorMsg(err, "resolving schema") } switch gotSchemaResponse.Type { case schema.JSONSchemaType: - return gotSchemaResponse.Schema, schema.JSONSchemaType, nil + return gotSchemaResponse.Schema, nil, schema.JSONSchemaType, nil case schema.JSONSchemaCredentialType: _, _, cred, err := parsing.ToCredential(gotSchemaResponse.CredentialSchema.String()) if err != nil { - return nil, "", sdkutil.LoggingErrorMsg(err, "converting credential schema from jwt to credential map") + return nil, nil, "", sdkutil.LoggingErrorMsg(err, "converting credential schema from jwt to credential map") } jsonSchema, ok := cred.CredentialSubject[credential.VerifiableCredentialJSONSchemaProperty] if !ok { - return nil, "", sdkutil.LoggingNewErrorf("credential schema does not contain %s property", credential.VerifiableCredentialJSONSchemaProperty) + return nil, nil, "", sdkutil.LoggingNewErrorf("credential schema does not contain %s property", credential.VerifiableCredentialJSONSchemaProperty) } credSubjectJSONSchemaBytes, err := json.Marshal(jsonSchema) if err != nil { - return nil, "", errors.Wrap(err, "marshalling credential subject") + return nil, nil, "", errors.Wrap(err, "marshalling credential subject") } var s schema.JSONSchema if err = json.Unmarshal(credSubjectJSONSchemaBytes, &s); err != nil { - return nil, "", errors.Wrap(err, "unmarshalling credential subject") + return nil, nil, "", errors.Wrap(err, "unmarshalling credential subject") + } + + data, err := json.Marshal(cred) + if err != nil { + return nil, nil, "", sdkutil.LoggingErrorMsg(err, "marshalling credential") + } + + var vcJSONSchema schema.VCJSONSchema + if err := json.Unmarshal(data, &vcJSONSchema); err != nil { + return nil, nil, "", sdkutil.LoggingErrorMsg(err, "umarshalling credential") } - return &s, schema.JSONSchemaCredentialType, nil + return &s, &vcJSONSchema, schema.JSONSchemaCredentialType, nil default: - return nil, "", sdkutil.LoggingNewErrorf("unknown schema type: %s", gotSchemaResponse.Type) + return nil, nil, "", sdkutil.LoggingNewErrorf("unknown schema type: %s", gotSchemaResponse.Type) } }