Commit 8491c20a authored by Sietse Ringers's avatar Sietse Ringers

feat: irmaclient no longer suggests revoked credentials as disclosure candidates

parent 14e1e13b
......@@ -42,6 +42,7 @@ type MetadataAttribute struct {
type AttributeList struct {
*MetadataAttribute `json:"-"`
Ints []*big.Int
Revoked bool `json:",omitempty"`
strings []TranslatedString
attrMap map[AttributeTypeIdentifier]TranslatedString
info *CredentialInfo
......@@ -60,6 +61,7 @@ func (al *AttributeList) Info() *CredentialInfo {
if al.info == nil {
al.info = NewCredentialInfo(al.Ints, al.Conf)
}
al.info.Revoked = al.Revoked
return al.info
}
......
......@@ -17,6 +17,7 @@ type CredentialInfo struct {
Expires Timestamp // Unix timestamp
Attributes map[AttributeTypeIdentifier]TranslatedString // Human-readable rendered attributes
Hash string // SHA256 hash over the attributes
Revoked bool // If the credential has been revoked
}
// A CredentialInfoList is a list of credentials (implements sort.Interface).
......
......@@ -13,13 +13,16 @@ import (
)
type TestClientHandler struct {
t *testing.T
c chan error
t *testing.T
c chan error
revoked *irma.CredentialIdentifier
}
func (i *TestClientHandler) UpdateConfiguration(new *irma.IrmaIdentifierSet) {}
func (i *TestClientHandler) UpdateAttributes() {}
func (i *TestClientHandler) Revoked(cred *irma.CredentialIdentifier) {}
func (i *TestClientHandler) Revoked(cred *irma.CredentialIdentifier) {
i.revoked = cred
}
func (i *TestClientHandler) EnrollmentSuccess(manager irma.SchemeManagerIdentifier) {
select {
case i.c <- nil: // nop
......
......@@ -349,15 +349,15 @@ func revocationSession(t *testing.T, client *irmaclient.Client, options ...sessi
}
// revocationSetup sets up an irmaclient with a revocation-enabled credential, constants, and revocation key material.
func revocationSetup(t *testing.T) *irmaclient.Client {
func revocationSetup(t *testing.T) (*irmaclient.Client, irmaclient.ClientHandler) {
StartRevocationServer(t)
// issue a MijnOverheid.root instance with revocation enabled
client, _ := parseStorage(t)
client, handler := parseStorage(t)
result := requestorSessionHelper(t, revocationIssuanceRequest, client)
require.Nil(t, result.Err)
return client
return client, handler
}
var revocationIssuanceRequest = irma.NewIssuanceRequest([]*irma.CredentialRequest{{
......@@ -370,7 +370,7 @@ var revocationIssuanceRequest = irma.NewIssuanceRequest([]*irma.CredentialReques
func TestRevocation(t *testing.T) {
defer test.ClearTestStorage(t)
client := revocationSetup(t)
client, handler := 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
......@@ -403,6 +403,17 @@ func TestRevocation(t *testing.T) {
// try to perform session with revoked credential
// client notices that is credential is revoked and aborts
logger.Info("step 5")
attr := irma.NewAttributeTypeIdentifier("irma-demo.MijnOverheid.root.BSN")
result = revocationSession(t, client, sessionOptionIgnoreClientError)
require.Equal(t, result.Status, server.StatusCancelled)
// client revocation callback was called
require.NotNil(t, handler.(*TestClientHandler).revoked)
require.Equal(t,
attr.CredentialTypeIdentifier(),
handler.(*TestClientHandler).revoked.Type,
)
// credential is no longer suggested as candidates
candidates, missing := client.Candidates(irma.AttributeDisCon{{{Type: attr}}})
require.Empty(t, candidates)
require.NotEmpty(t, missing)
}
......@@ -563,7 +563,7 @@ func (client *Client) credCandidates(con irma.AttributeCon) credCandidateSet {
}
var c []*irma.CredentialIdentifier
for _, cred := range creds {
if !cred.IsValid() {
if !cred.IsValid() || cred.Revoked {
continue
}
c = append(c, &irma.CredentialIdentifier{Type: credtype, Hash: cred.Hash()})
......@@ -784,15 +784,22 @@ func (client *Client) NonrevPreprare(request irma.SessionRequest) error {
if !typ.SupportsRevocation() {
continue
}
for i := 0; i < len(client.attrs(id)); i++ {
attrs := client.attrs(id)
for i := 0; i < len(attrs); i++ {
if cred, err = client.credential(id, i); err != nil {
return err
}
if updated, err = cred.NonrevPrepare(client.Configuration, request); err != nil {
if err == revocation.ErrorRevoked {
attrs[i].Revoked = true
cred.AttributeList().Revoked = true
if serr := client.storage.StoreAttributes(client.attributes); serr != nil {
client.reportError(serr)
return err
}
client.handler.Revoked(&irma.CredentialIdentifier{
Type: cred.CredentialType().Identifier(),
Hash: cred.attrs.Hash(),
Hash: cred.AttributeList().Hash(),
})
}
return err
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment