From 8431fb78fd8f8bf343d82be6ad9de198f6dc6652 Mon Sep 17 00:00:00 2001 From: Sietse Ringers Date: Wed, 16 Oct 2019 14:51:18 +0200 Subject: [PATCH] test: restructure revocation test for reusability --- internal/servercore/api.go | 9 ++-- internal/sessiontest/requestor_test.go | 46 +++++++++-------- revocation.go | 2 + verify.go | 70 +++++++++++++------------- 4 files changed, 67 insertions(+), 60 deletions(-) diff --git a/internal/servercore/api.go b/internal/servercore/api.go index 312e1d6..b994428 100644 --- a/internal/servercore/api.go +++ b/internal/servercore/api.go @@ -269,6 +269,7 @@ func (s *Server) handleClientMessage( }() // Route to handler + var err error switch len(noun) { case 0: if method == http.MethodDelete { @@ -284,11 +285,11 @@ func (s *Server) handleClientMessage( h := http.Header(headers) min := &irma.ProtocolVersion{} max := &irma.ProtocolVersion{} - if err := json.Unmarshal([]byte(h.Get(irma.MinVersionHeader)), min); err != nil { + if err = json.Unmarshal([]byte(h.Get(irma.MinVersionHeader)), min); err != nil { status, output = server.JsonResponse(nil, session.fail(server.ErrorMalformedInput, err.Error())) return } - if err := json.Unmarshal([]byte(h.Get(irma.MaxVersionHeader)), max); err != nil { + if err = json.Unmarshal([]byte(h.Get(irma.MaxVersionHeader)), max); err != nil { status, output = server.JsonResponse(nil, session.fail(server.ErrorMalformedInput, err.Error())) return } @@ -301,8 +302,8 @@ func (s *Server) handleClientMessage( default: if noun == "statusevents" { - err := server.RemoteError(server.ErrorInvalidRequest, "server sent events not supported by this server") - status, output = server.JsonResponse(nil, err) + rerr := server.RemoteError(server.ErrorInvalidRequest, "server sent events not supported by this server") + status, output = server.JsonResponse(nil, rerr) return } diff --git a/internal/sessiontest/requestor_test.go b/internal/sessiontest/requestor_test.go index 6763656..f52cbdd 100644 --- a/internal/sessiontest/requestor_test.go +++ b/internal/sessiontest/requestor_test.go @@ -349,27 +349,34 @@ func revocationSession(t *testing.T, client *irmaclient.Client, options ...sessi return result } -func TestRevocation(t *testing.T) { - // setup client, constants, and revocation key material - defer test.ClearTestStorage(t) - client, _ := parseStorage(t) - cred := irma.NewCredentialTypeIdentifier("irma-demo.MijnOverheid.root") +// revocationSetup sets up an irmaclient with a revocation-enabled credential, constants, and revocation key material. +func revocationSetup(t *testing.T) *irmaclient.Client { StartRevocationServer(t) - // issue two MijnOverheid.root instances with revocation enabled - request := irma.NewIssuanceRequest([]*irma.CredentialRequest{{ - RevocationKey: "cred0", // once revocation is required for a credential type, this key is required - CredentialTypeID: cred, - Attributes: map[string]string{ - "BSN": "299792458", - }, - }}) - result := requestorSessionHelper(t, request, client) + // issue a MijnOverheid.root instance with revocation enabled + client, _ := parseStorage(t) + result := requestorSessionHelper(t, revocationIssuanceRequest, client) require.Nil(t, result.Err) - // issue second one which overwrites the first one, as our credtype is a singleton + + return client +} + +var revocationIssuanceRequest = irma.NewIssuanceRequest([]*irma.CredentialRequest{{ + RevocationKey: "cred0", // once revocation is required for a credential type, this key is required + CredentialTypeID: irma.NewCredentialTypeIdentifier("irma-demo.MijnOverheid.root"), + Attributes: map[string]string{ + "BSN": "299792458", + }, +}}) + +func TestRevocation(t *testing.T) { + defer test.ClearTestStorage(t) + client := revocationSetup(t) + + // issue second credential which overwrites the first one, as our credtype is a singleton // this is ok, as we use cred0 only to revoke it, to see if cred1 keeps working - request.Credentials[0].RevocationKey = "cred1" - result = requestorSessionHelper(t, request, client) + revocationIssuanceRequest.Credentials[0].RevocationKey = "cred1" + result := requestorSessionHelper(t, revocationIssuanceRequest, client) require.Nil(t, result.Err) // perform disclosure session (of cred1) with nonrevocation proof @@ -377,11 +384,8 @@ func TestRevocation(t *testing.T) { require.Equal(t, irma.ProofStatusValid, result.ProofStatus) require.NotEmpty(t, result.Disclosed) - req := revocationRequest() - require.NoError(t, client.Configuration.RevocationStorage.SetRecords(req.Base())) - require.NoError(t, client.NonrevPreprare(req)) - // revoke cred0 + cred := revocationIssuanceRequest.Credentials[0].CredentialTypeID require.NoError(t, revocationServer.Revoke(cred, "cred0")) // perform another disclosure session with nonrevocation proof to see that cred1 still works diff --git a/revocation.go b/revocation.go index 060427b..b4282b8 100644 --- a/revocation.go +++ b/revocation.go @@ -73,6 +73,7 @@ func (rdb *DB) EnableRevocation(sk *revocation.PrivateKey) error { return err } rdb.Current = *acc + rdb.Updated = time.Now() return nil } @@ -304,6 +305,7 @@ func (rs *RevocationStorage) loadDB(credid CredentialTypeIdentifier) (*DB, error db := &DB{ bolt: b, keystore: keystore, + Updated: time.Unix(0, 0), } if db.Enabled() { if err = db.loadCurrent(); err != nil { diff --git a/verify.go b/verify.go index 6e66093..154a991 100644 --- a/verify.go +++ b/verify.go @@ -69,6 +69,41 @@ func (pl ProofList) ExtractPublicKeys(configuration *Configuration) ([]*gabi.Pub return publicKeys, nil } +// Expired returns true if any of the contained disclosure proofs is specified at the specified time, +// or now, when the specified time is nil. +func (pl ProofList) Expired(configuration *Configuration, t *time.Time) bool { + if t == nil { + temp := time.Now() + t = &temp + } + for _, proof := range pl { + proofd, ok := proof.(*gabi.ProofD) + if !ok { + continue + } + metadata := MetadataFromInt(proofd.ADisclosed[1], configuration) // index 1 is metadata attribute + if metadata.Expiry().Before(*t) { + return true + } + } + return false +} + +func extractAttribute(pl gabi.ProofList, index *DisclosedAttributeIndex, conf *Configuration) (*DisclosedAttribute, *string, error) { + if len(pl) < index.CredentialIndex { + return nil, nil, errors.New("Credential index out of range") + } + proofd, ok := pl[index.CredentialIndex].(*gabi.ProofD) + if !ok { + // If with the index the user told us to look for the required attribute at this specific location, + // and the proof here is not a disclosure proof, then reject + return nil, nil, errors.New("ProofList contained proof of invalid type") + } + + metadata := MetadataFromInt(proofd.ADisclosed[1], conf) // index 1 is metadata attribute + return parseAttribute(index.AttributeIndex, metadata, proofd.ADisclosed[index.AttributeIndex]) +} + // VerifyProofs verifies the proofs cryptographically. func (pl ProofList) VerifyProofs( configuration *Configuration, @@ -158,41 +193,6 @@ func (pl ProofList) VerifyProofs( return true, nil } -// Expired returns true if any of the contained disclosure proofs is specified at the specified time, -// or now, when the specified time is nil. -func (pl ProofList) Expired(configuration *Configuration, t *time.Time) bool { - if t == nil { - temp := time.Now() - t = &temp - } - for _, proof := range pl { - proofd, ok := proof.(*gabi.ProofD) - if !ok { - continue - } - metadata := MetadataFromInt(proofd.ADisclosed[1], configuration) // index 1 is metadata attribute - if metadata.Expiry().Before(*t) { - return true - } - } - return false -} - -func extractAttribute(pl gabi.ProofList, index *DisclosedAttributeIndex, conf *Configuration) (*DisclosedAttribute, *string, error) { - if len(pl) < index.CredentialIndex { - return nil, nil, errors.New("Credential index out of range") - } - proofd, ok := pl[index.CredentialIndex].(*gabi.ProofD) - if !ok { - // If with the index the user told us to look for the required attribute at this specific location, - // and the proof here is not a disclosure proof, then reject - return nil, nil, errors.New("ProofList contained proof of invalid type") - } - - metadata := MetadataFromInt(proofd.ADisclosed[1], conf) // index 1 is metadata attribute - return parseAttribute(index.AttributeIndex, metadata, proofd.ADisclosed[index.AttributeIndex]) -} - func (d *Disclosure) extraIndices(condiscon AttributeConDisCon) []*DisclosedAttributeIndex { disclosed := make([]map[int]struct{}, len(d.Proofs)) for i, proof := range d.Proofs { -- GitLab