Commit 709972d2 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

feat: irmaclient now stores nonrevocation witness after updates

parent 2e38ffc5
......@@ -711,10 +711,15 @@ func (client *Client) ProofBuilders(choice *irma.DisclosureChoice, request irma.
if err != nil {
return nil, nil, nil, err
}
nonrev, err := cred.PrepareNonrevocation(client.Configuration, request)
nonrev, updated, err := cred.prepareNonrevocation(client.Configuration, request)
if err != nil {
return nil, nil, nil, err
}
if updated {
if err = client.storage.StoreSignature(cred); err != nil {
return nil, nil, nil, err
}
}
builder, err = cred.CreateDisclosureProofBuilder(grp.attrs, nonrev)
if err != nil {
return nil, nil, nil, err
......
......@@ -2,6 +2,7 @@ package irmaclient
import (
"github.com/privacybydesign/gabi"
"github.com/privacybydesign/gabi/revocation"
"github.com/privacybydesign/irmago"
)
......@@ -40,34 +41,57 @@ func (cred *credential) AttributeList() *irma.AttributeList {
return cred.attrs
}
func (cred *credential) PrepareNonrevocation(conf *irma.Configuration, request irma.SessionRequest) (bool, error) {
// prepareNonrevocation attempts to update the credential's nonrevocation witness from
// 1) the session request, and then 2) the revocation server if our witness is too far out of date.
// Returns whether or not a nonrevocation proof should be included for this credential, and whether
// or not the credential's nonrevocation state was updated. If so the caller should persist the
// updated credential to storage.
func (cred *credential) prepareNonrevocation(conf *irma.Configuration, request irma.SessionRequest) (bool, bool, error) {
// If the requestor wants us to include a nonrevocation proof,
// it will have sent us the latest revocation update messages
m := request.Base().RevocationUpdates
credtype := cred.CredentialType().Identifier()
if len(m) == 0 || len(m[credtype]) == 0 {
return false, nil
return false, false, nil
}
revupdates := m[credtype]
nonrev := len(revupdates) > 0
if updated, err := conf.RevocationStorage.UpdateWitness(cred.NonRevocationWitness, revupdates, credtype.IssuerIdentifier()); err != nil {
return false, err
updated, err := cred.updateNonrevWitness(revupdates, conf.RevocationStorage)
if err != nil {
return false, updated, err
} else if updated {
cred.DiscardRevocationCache()
}
// TODO (in both branches): attach our newer updates to response
if nonrev && cred.NonRevocationWitness.Index >= revupdates[len(revupdates)-1].EndIndex {
return nonrev, nil
return nonrev, updated, nil
}
// nonrevocation witness is still out of date after applying the updates from the request,
// i.e. we were too far behind. Update from revocation server.
revupdates, err := conf.RevocationStorage.GetUpdates(credtype, cred.NonRevocationWitness.Index+1)
revupdates, err = conf.RevocationStorage.GetUpdates(credtype, cred.NonRevocationWitness.Index+1)
if err != nil {
return nonrev, err
return nonrev, updated, err
}
updated, err = cred.updateNonrevWitness(revupdates, conf.RevocationStorage)
return nonrev, updated, err
}
// updateNonrevWitness updates the credential's nonrevocation witness using the specified messages,
// if they all verify and if their indices are ahead and adjacent to that of our witness.
func (cred *credential) updateNonrevWitness(messages []*irma.RevocationRecord, rs *irma.RevocationStorage) (bool, error) {
var err error
var pk *revocation.PublicKey
oldindex := cred.NonRevocationWitness.Index
for _, msg := range messages {
if pk, err = rs.PublicKey(cred.CredentialType().IssuerIdentifier(), msg.PublicKeyIndex); err != nil {
return false, err
}
if err = cred.NonRevocationWitness.Update(pk, msg.Message); err != nil {
return false, err
}
}
_, err = conf.RevocationStorage.UpdateWitness(cred.NonRevocationWitness, revupdates, credtype.IssuerIdentifier())
return nonrev, err
return cred.NonRevocationWitness.Index == oldindex, err
}
......@@ -329,21 +329,6 @@ func (rs *RevocationStorage) PublicKey(issid IssuerIdentifier, counter uint) (*r
return revpk, nil
}
func (rs *RevocationStorage) UpdateWitness(w *revocation.Witness, msgs []*RevocationRecord, issid IssuerIdentifier) (bool, error) {
var err error
var pk *revocation.PublicKey
oldindex := w.Index
for _, msg := range msgs {
if pk, err = rs.PublicKey(issid, msg.PublicKeyIndex); err != nil {
return false, err
}
if err = w.Update(pk, msg.Message); err != nil {
return false, err
}
}
return w.Index == oldindex, nil
}
func (rs *RevocationStorage) GetUpdates(credid CredentialTypeIdentifier, index uint64) ([]*RevocationRecord, error) {
var records []*RevocationRecord
err := NewHTTPTransport(rs.conf.CredentialTypes[credid].RevocationServer).
......
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