diff --git a/pkg/server/router/credential_test.go b/pkg/server/router/credential_test.go index b3647237f..018fb34b2 100644 --- a/pkg/server/router/credential_test.go +++ b/pkg/server/router/credential_test.go @@ -261,6 +261,11 @@ func TestCredentialRouter(t *testing.T) { assert.Empty(tt, createdCred) assert.Error(tt, err) assert.ErrorContains(tt, err, "cannot use revoked key") + + // create a schema with the revoked key, it fails + _, err = schemaService.CreateSchema(context.Background(), schema.CreateSchemaRequest{Issuer: controllerDID.DID.ID, Name: "schema (revoked key)", Schema: getEmailSchema(), FullyQualifiedVerificationMethodID: keyID}) + assert.Error(tt, err) + assert.ErrorContains(tt, err, "cannot use revoked key") }) t.Run("Credential Status List Test", func(tt *testing.T) { diff --git a/pkg/server/router/manifest_test.go b/pkg/server/router/manifest_test.go index 2f2f563a0..02861615b 100644 --- a/pkg/server/router/manifest_test.go +++ b/pkg/server/router/manifest_test.go @@ -17,6 +17,9 @@ import ( "github.com/tbd54566975/ssi-service/pkg/service/credential" "github.com/tbd54566975/ssi-service/pkg/service/did" "github.com/tbd54566975/ssi-service/pkg/service/framework" + "github.com/tbd54566975/ssi-service/pkg/service/keystore" + "github.com/tbd54566975/ssi-service/pkg/service/manifest" + "github.com/tbd54566975/ssi-service/pkg/service/manifest/model" "github.com/tbd54566975/ssi-service/pkg/service/operation/storage" presmodel "github.com/tbd54566975/ssi-service/pkg/service/presentation/model" @@ -198,38 +201,51 @@ func TestManifestRouter(t *testing.T) { signed, err := signer.SignJSON(applicationRequest) assert.NoError(ttt, err) - submitApplicationRequest := SubmitApplicationRequest{ApplicationJWT: *signed} - sar, err := submitApplicationRequest.toServiceRequest() - assert.NoError(ttt, err) - createdApplicationResponseOp, err := manifestService.ProcessApplicationSubmission(context.Background(), *sar) - assert.NoError(ttt, err) - assert.False(ttt, createdApplicationResponseOp.Done) - - createdApplicationResponse, err := manifestService.ReviewApplication(context.Background(), model.ReviewApplicationRequest{ - ID: storage.StatusObjectID(createdApplicationResponseOp.ID), - Approved: true, - Reason: "ApprovalMan is here", - CredentialOverrides: map[string]model.CredentialOverride{ - "id1": { - Data: map[string]any{"licenseType": "Class D"}, - }, - "id2": { - Data: map[string]any{"licenseType": "Class D"}, - }, - }, - }) + // submit and review application, the key is valid + createdApplicationResponse, err := submitAndReviewApplication(signed, ttt, manifestService) assert.NoError(ttt, err) assert.NotEmpty(ttt, createdManifest) assert.NotEmpty(ttt, createdApplicationResponse.Response.ID) assert.NotEmpty(ttt, createdApplicationResponse.Response.Fulfillment) assert.Empty(ttt, createdApplicationResponse.Response.Denial) assert.Equal(ttt, len(createManifestRequest.OutputDescriptors), len(createdApplicationResponse.Credentials)) + + // attempt to submit and review application again, this time with the revoked key + err = keyStoreService.RevokeKey(context.Background(), keystore.RevokeKeyRequest{ID: kid}) + assert.NoError(ttt, err) + _, err = submitAndReviewApplication(signed, ttt, manifestService) + assert.Error(tt, err) + assert.ErrorContains(tt, err, "cannot use revoked key") }) }) }) } } +func submitAndReviewApplication(signed *keyaccess.JWT, ttt *testing.T, manifestService *manifest.Service) (*model.SubmitApplicationResponse, error) { + submitApplicationRequest := SubmitApplicationRequest{ApplicationJWT: *signed} + sar, err := submitApplicationRequest.toServiceRequest() + assert.NoError(ttt, err) + createdApplicationResponseOp, err := manifestService.ProcessApplicationSubmission(context.Background(), *sar) + assert.NoError(ttt, err) + assert.False(ttt, createdApplicationResponseOp.Done) + + createdApplicationResponse, err := manifestService.ReviewApplication(context.Background(), model.ReviewApplicationRequest{ + ID: storage.StatusObjectID(createdApplicationResponseOp.ID), + Approved: true, + Reason: "ApprovalMan is here", + CredentialOverrides: map[string]model.CredentialOverride{ + "id1": { + Data: map[string]any{"licenseType": "Class D"}, + }, + "id2": { + Data: map[string]any{"licenseType": "Class D"}, + }, + }, + }) + return createdApplicationResponse, err +} + func getValidManifestRequestRequest(issuerDID *did.CreateDIDResponse, kid string, createdManifest *model.CreateManifestResponse) model.CreateRequestRequest { return model.CreateRequestRequest{ ManifestRequest: model.Request{ diff --git a/pkg/service/keystore/service.go b/pkg/service/keystore/service.go index dacc5b24f..d24f9e031 100644 --- a/pkg/service/keystore/service.go +++ b/pkg/service/keystore/service.go @@ -212,6 +212,9 @@ func (s Service) Sign(ctx context.Context, keyID string, data any) (*keyaccess.J if err != nil { return nil, sdkutil.LoggingErrorMsgf(err, "getting key with keyID<%s>", keyID) } + if gotKey.Revoked { + return nil, sdkutil.LoggingNewErrorf("cannot use revoked key<%s>", gotKey.ID) + } keyAccess, err := keyaccess.NewJWKKeyAccess(gotKey.Controller, gotKey.ID, gotKey.Key) if err != nil { return nil, sdkutil.LoggingErrorMsgf(err, "creating key access for keyID<%s>", keyID) diff --git a/pkg/service/keystore/service_test.go b/pkg/service/keystore/service_test.go index e202e1571..bf2ec2822 100644 --- a/pkg/service/keystore/service_test.go +++ b/pkg/service/keystore/service_test.go @@ -159,6 +159,11 @@ func TestRevokeKey(t *testing.T) { assert.Equal(t, privKey, keyResponse.Key) assert.True(t, keyResponse.Revoked) assert.Equal(t, "2023-06-23T00:00:00Z", keyResponse.RevokedAt) + + // attempt to "Sign()" with the revoked key, ensure it is prohibited + _, err = keyStore.Sign(context.Background(), keyID, "sampleDataAsString") + assert.Error(t, err) + assert.ErrorContains(t, err, "cannot use revoked key") } func createKeyStoreService(t *testing.T) (*Service, error) { diff --git a/pkg/service/manifest/response.go b/pkg/service/manifest/response.go index 982279240..04d5b3815 100644 --- a/pkg/service/manifest/response.go +++ b/pkg/service/manifest/response.go @@ -35,6 +35,9 @@ func (s Service) signCredentialResponse(ctx context.Context, keyStoreID string, if err != nil { return nil, sdkutil.LoggingErrorMsgf(err, "getting key for signing response with key<%s>", keyStoreID) } + if gotKey.Revoked { + return nil, sdkutil.LoggingNewErrorf("cannot use revoked key<%s>", gotKey.ID) + } keyAccess, err := keyaccess.NewJWKKeyAccess(gotKey.Controller, gotKey.ID, gotKey.Key) if err != nil { return nil, sdkutil.LoggingErrorMsgf(err, "creating key access for signing response with key<%s>", gotKey.ID) diff --git a/pkg/service/schema/service.go b/pkg/service/schema/service.go index d41b4d793..4ab277158 100644 --- a/pkg/service/schema/service.go +++ b/pkg/service/schema/service.go @@ -189,6 +189,9 @@ func (s Service) signCredentialSchema(ctx context.Context, cred credential.Verif if gotKey.Controller != issuer { return nil, sdkutil.LoggingNewErrorf("key controller<%s> does not match credential issuer<%s> for key<%s>", gotKey.Controller, issuer, fullyQualifiedVerificationMethodID) } + if gotKey.Revoked { + return nil, sdkutil.LoggingNewErrorf("cannot use revoked key<%s>", gotKey.ID) + } keyAccess, err := keyaccess.NewJWKKeyAccess(fullyQualifiedVerificationMethodID, gotKey.ID, gotKey.Key) if err != nil { return nil, errors.Wrapf(err, "creating key access for signing credential schema with key<%s>", gotKey.ID)