Commit e3e8f1f8 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Add credential removal functions

parent ef7ce6ee
......@@ -409,3 +409,29 @@ func TestPaillier(t *testing.T) {
teardown(t)
}
func TestCredentialRemoval(t *testing.T) {
manager := parseStorage(t)
id := NewCredentialTypeIdentifier("irma-demo.RU.studentCard")
id2 := NewCredentialTypeIdentifier("test.test.mijnirma")
cred, err := manager.credential(id, 0)
require.NoError(t, err)
require.NotNil(t, cred)
err = manager.RemoveCredentialByHash(cred.AttributeList().hash())
require.NoError(t, err)
cred, err = manager.credential(id, 0)
require.NoError(t, err)
require.Nil(t, cred)
cred, err = manager.credential(id2, 0)
require.NoError(t, err)
require.NotNil(t, cred)
err = manager.RemoveCredential(id2, 0)
require.NoError(t, err)
cred, err = manager.credential(id2, 0)
require.NoError(t, err)
require.Nil(t, cred)
teardown(t)
}
......@@ -2,7 +2,6 @@ package irmago
import (
"encoding/json"
"time"
"github.com/go-errors/errors"
......@@ -26,6 +25,8 @@ type LogEntry struct {
rawResponse json.RawMessage // Unparsed []byte version of response
}
const actionRemoval = Action("removal")
func (session *session) createLogEntry(response interface{}) (*LogEntry, error) {
entry := &LogEntry{
Type: session.Action,
......@@ -96,7 +97,7 @@ func (entry *LogEntry) Jwt() (RequestorJwt, string, error) {
func (entry *LogEntry) GetResponse() (interface{}, error) {
if entry.response == nil {
switch entry.Type {
case Action("removal"):
case actionRemoval:
return nil, nil
case ActionSigning:
fallthrough
......@@ -172,16 +173,24 @@ func (entry *LogEntry) MarshalJSON() ([]byte, error) {
}
}
temp := &jsonLogEntry{
Type: entry.Type,
Time: entry.Time,
Response: entry.rawResponse,
SessionInfo: &logSessionInfo{
var si *logSessionInfo
if entry.SessionInfo != nil {
si = &logSessionInfo{
Jwt: entry.SessionInfo.Jwt,
Nonce: entry.SessionInfo.Nonce,
Context: entry.SessionInfo.Context,
Keys: make(map[string]int),
},
}
// TODO remove on protocol upgrade
for iss, count := range entry.SessionInfo.Keys {
si.Keys[iss.String()] = count
}
}
temp := &jsonLogEntry{
Type: entry.Type,
Time: entry.Time,
Response: entry.rawResponse,
SessionInfo: si,
RemovedCredential: entry.RemovedCredential.String(),
Disclosed: entry.Disclosed,
Received: entry.Received,
......@@ -189,10 +198,5 @@ func (entry *LogEntry) MarshalJSON() ([]byte, error) {
SignedMessageType: entry.SignedMessageType,
}
// TODO remove on protocol upgrade
for iss, count := range entry.SessionInfo.Keys {
temp.SessionInfo.Keys[iss.String()] = count
}
return json.Marshal(temp)
}
......@@ -3,7 +3,9 @@ package irmago
import (
"crypto/rand"
"math/big"
"os"
"sort"
"time"
"github.com/credentials/go-go-gadget-paillier"
"github.com/go-errors/errors"
......@@ -46,6 +48,63 @@ func (cm *CredentialManager) CredentialInfoList() CredentialInfoList {
return list
}
func (cm *CredentialManager) remove(id CredentialTypeIdentifier, index int, storenow bool) error {
// Remove attributes
list, exists := cm.attributes[id]
if !exists || index >= len(list) {
return errors.Errorf("Can't remove credential %s-%d: no such credential", id.String(), index)
}
attrs := list[index]
cm.attributes[id] = append(list[:index], list[index+1:]...)
if storenow {
cm.storeAttributes()
}
// Remove credential
if creds, exists := cm.credentials[id]; exists {
if _, exists := creds[index]; exists {
creds[index] = nil
cm.credentials[id] = creds
}
}
// Remove signature from storage
if err := os.Remove(cm.signatureFilename(attrs)); err != nil {
return err
}
return cm.addLogEntry(&LogEntry{
Type: actionRemoval,
Time: Timestamp(time.Now()),
RemovedCredential: id,
}, storenow)
}
func (cm *CredentialManager) RemoveCredential(id CredentialTypeIdentifier, index int) error {
return cm.remove(id, index, true)
}
func (cm *CredentialManager) RemoveCredentialByHash(hash string) error {
cred, index, err := cm.credentialByHash(hash)
if err != nil {
return err
}
return cm.RemoveCredential(cred.CredentialType().Identifier(), index)
}
func (cm *CredentialManager) RemoveAllCredentials() error {
list := cm.CredentialInfoList()
for _, cred := range list {
if err := cm.remove(NewCredentialTypeIdentifier(cred.ID), cred.Index, false); err != nil {
return err
}
}
if err := cm.storeAttributes(); err != nil {
return err
}
return cm.storeLogs()
}
func (cm *CredentialManager) generateSecretKey() (*secretKey, error) {
key, err := gabi.RandomBigInt(gabi.DefaultSystemParameters[1024].Lm)
if err != nil {
......@@ -83,7 +142,19 @@ func (cm *CredentialManager) Attributes(id CredentialTypeIdentifier, counter int
return list[counter]
}
func (cm *CredentialManager) credentialByID(id CredentialIdentifier) (cred *credential, err error) {
func (cm *CredentialManager) credentialByHash(hash string) (*credential, int, error) {
for _, attrlistlist := range cm.attributes {
for index, attrs := range attrlistlist {
if attrs.hash() == hash {
cred, err := cm.credential(attrs.CredentialType().Identifier(), index)
return cred, index, err
}
}
}
return nil, 0, nil
}
func (cm *CredentialManager) credentialByID(id CredentialIdentifier) (*credential, error) {
return cm.credential(id.Type, id.Index)
}
......@@ -413,9 +484,12 @@ func (cm *CredentialManager) KeyshareRemove(manager SchemeManagerIdentifier) err
return cm.storeKeyshareServers()
}
func (cm *CredentialManager) addLogEntry(entry *LogEntry) error {
func (cm *CredentialManager) addLogEntry(entry *LogEntry, storenow bool) error {
cm.logs = append(cm.logs, entry)
return cm.storeLogs()
if storenow {
return cm.storeLogs()
}
return nil
}
func (cm *CredentialManager) Logs() ([]*LogEntry, error) {
......
......@@ -276,6 +276,6 @@ func (session *session) sendResponse(message interface{}) {
log, err = session.createLogEntry(message) // TODO err
}
session.credManager.addLogEntry(log) // TODO err
session.credManager.addLogEntry(log, true) // TODO err
session.Handler.Success(session.Action)
}
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