Commit d58c7566 authored by Sietse Ringers's avatar Sietse Ringers

feat: support passing issuance time in revocation command to select a single credential

parent 2723a725
......@@ -139,8 +139,8 @@ func (s *Server) CancelSession(token string) error {
return nil
}
func (s *Server) Revoke(credid irma.CredentialTypeIdentifier, key string) error {
return s.conf.IrmaConfiguration.Revocation.Revoke(credid, key)
func (s *Server) Revoke(credid irma.CredentialTypeIdentifier, key string, issued time.Time) error {
return s.conf.IrmaConfiguration.Revocation.Revoke(credid, key, issued)
}
func ParsePath(path string) (token, noun string, arg []string, err error) {
......
......@@ -59,7 +59,7 @@ func TestRevocationAll(t *testing.T) {
// revoke cred0
logger.Info("step 2")
require.NoError(t, revocationServer.Revoke(revocationTestCred, "cred0"))
require.NoError(t, revocationServer.Revoke(revocationTestCred, "cred0", time.Time{}))
// perform another disclosure session with nonrevocation proof to see that cred1 still works
// client updates its witness to the new accumulator first
......@@ -70,7 +70,7 @@ func TestRevocationAll(t *testing.T) {
// revoke cred1
logger.Info("step 4")
require.NoError(t, revocationServer.Revoke(revocationTestCred, "cred1"))
require.NoError(t, revocationServer.Revoke(revocationTestCred, "cred1", time.Time{}))
// try to perform session with revoked credential
// client notices that his credential is revoked and aborts
......@@ -334,7 +334,7 @@ func TestRevocationAll(t *testing.T) {
ValidUntil: time.Now().Add(-1 * time.Hour).UnixNano(),
}))
// Check existence of insterted record
rec, err := rev.IssuanceRecords(revocationTestCred, "1")
rec, err := rev.IssuanceRecords(revocationTestCred, "1", time.Time{})
require.NoError(t, err)
require.NotEmpty(t, rec)
......@@ -342,7 +342,7 @@ func TestRevocationAll(t *testing.T) {
revocationConfiguration.IrmaConfiguration.Scheduler.RunAll()
// Check that issuance record is gone
rec, err = rev.IssuanceRecords(revocationTestCred, "1")
rec, err = rev.IssuanceRecords(revocationTestCred, "1", time.Time{})
require.Equal(t, gorm.ErrRecordNotFound, err)
})
}
......@@ -395,7 +395,7 @@ func revoke(t *testing.T, key string, conf *irma.RevocationStorage, acc *revocat
Issued: time.Now().UnixNano(),
ValidUntil: time.Now().Add(1 * time.Hour).UnixNano(),
}))
require.NoError(t, conf.Revoke(revocationTestCred, key))
require.NoError(t, conf.Revoke(revocationTestCred, key, time.Time{}))
sacc, err := conf.Accumulator(revocationTestCred, revocationPkCounter)
require.NoError(t, err)
*acc = *sacc.Accumulator
......
......@@ -201,6 +201,7 @@ type RevocationRequest struct {
LDContext string `json:"@context,omitempty"`
CredentialType CredentialTypeIdentifier `json:"type"`
Key string `json:"revocationKey,omitempty"`
Issued int64 `json:"issued,omitempty"`
}
func (r *RevocationRequest) Validate() error {
......
......@@ -304,9 +304,13 @@ func (rs *RevocationStorage) AddIssuanceRecord(r *IssuanceRecord) error {
return rs.sqldb.Insert(r)
}
func (rs *RevocationStorage) IssuanceRecords(typ CredentialTypeIdentifier, key string) ([]*IssuanceRecord, error) {
func (rs *RevocationStorage) IssuanceRecords(typ CredentialTypeIdentifier, key string, issued time.Time) ([]*IssuanceRecord, error) {
where := map[string]interface{}{"cred_type": typ, "revocationkey": key}
if !issued.IsZero() {
where["Issued"] = issued.UnixNano()
}
var r []*IssuanceRecord
err := rs.sqldb.Find(&r, map[string]interface{}{"cred_type": typ, "revocationkey": key})
err := rs.sqldb.Find(&r, where)
if err != nil {
return nil, err
}
......@@ -321,18 +325,18 @@ func (rs *RevocationStorage) IssuanceRecords(typ CredentialTypeIdentifier, key s
// Revoke revokes the credential specified by key if found within the current database,
// by updating its revocation time to now, removing its revocation attribute from the current accumulator,
// and updating the revocation database on disk.
func (rs *RevocationStorage) Revoke(typ CredentialTypeIdentifier, key string) error {
func (rs *RevocationStorage) Revoke(typ CredentialTypeIdentifier, key string, issued time.Time) error {
if rs.getSettings(typ).Mode != RevocationModeServer {
return errors.Errorf("cannot revoke %s", typ)
}
return rs.sqldb.Transaction(func(tx sqlRevStorage) error {
return rs.revoke(tx, typ, key)
return rs.revoke(tx, typ, key, issued)
})
}
func (rs *RevocationStorage) revoke(tx sqlRevStorage, typ CredentialTypeIdentifier, key string) error {
func (rs *RevocationStorage) revoke(tx sqlRevStorage, typ CredentialTypeIdentifier, key string, issued time.Time) error {
var err error
issrecords, err := rs.IssuanceRecords(typ, key)
issrecords, err := rs.IssuanceRecords(typ, key, issued)
if err != nil {
return err
}
......
......@@ -7,6 +7,7 @@ package irmaserver
import (
"io/ioutil"
"net/http"
"time"
"github.com/go-errors/errors"
"github.com/privacybydesign/irmago"
......@@ -99,11 +100,11 @@ func (s *Server) CancelSession(token string) error {
// Revoke revokes the earlier issued credential specified by key. (Can only be used if this server
// is the revocation server for the specified credential type and if the corresponding
// issuer private key is present in the server configuration.)
func Revoke(credid irma.CredentialTypeIdentifier, key string) error {
return s.Revoke(credid, key)
func Revoke(credid irma.CredentialTypeIdentifier, key string, issued time.Time) error {
return s.Revoke(credid, key, issued)
}
func (s *Server) Revoke(credid irma.CredentialTypeIdentifier, key string) error {
return s.Server.Revoke(credid, key)
func (s *Server) Revoke(credid irma.CredentialTypeIdentifier, key string, issued time.Time) error {
return s.Server.Revoke(credid, key, issued)
}
// SubscribeServerSentEvents subscribes the HTTP client to server sent events on status updates
......
......@@ -622,7 +622,11 @@ func (s *Server) revoke(w http.ResponseWriter, requestor string, request *irma.R
server.WriteError(w, server.ErrorUnauthorized, reason)
return
}
if err := s.irmaserv.Revoke(request.CredentialType, request.Key); err != nil {
var issued time.Time
if request.Issued != 0 {
issued = time.Unix(0, request.Issued)
}
if err := s.irmaserv.Revoke(request.CredentialType, request.Key, issued); err != nil {
server.WriteError(w, server.ErrorUnknown, err.Error())
}
server.WriteString(w, "OK")
......
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