Commit 2fb8b5c2 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Manager.Init() now handles MetaStore initialization

parent e03aeafc
...@@ -59,36 +59,32 @@ func (al *AttributeList) UnmarshalJSON(bytes []byte) error { ...@@ -59,36 +59,32 @@ func (al *AttributeList) UnmarshalJSON(bytes []byte) error {
if err := json.Unmarshal(bytes, &ints); err != nil { if err := json.Unmarshal(bytes, &ints); err != nil {
return err return err
} }
*al = *NewAttributeListFromInts(ints) list, err := NewAttributeListFromInts(ints)
if err != nil {
return err
}
*al = *list
return nil return nil
} }
// NewAttributeListFromInts initializes a new AttributeList from a list of bigints. // NewAttributeListFromInts initializes a new AttributeList from a list of bigints.
func NewAttributeListFromInts(ints []*big.Int) *AttributeList { func NewAttributeListFromInts(ints []*big.Int) (*AttributeList, error) {
meta := MetadataFromInt(ints[0]) meta := MetadataFromInt(ints[0])
credtype := meta.CredentialType() if ints[0] == nil || meta.CredentialType() == nil {
issid := credtype.IssuerIdentifier() return nil, errors.New("Encountered credential of unknown type")
attrs := make([]TranslatedString, len(credtype.Attributes))
for i := range credtype.Attributes {
val := string(ints[i+1].Bytes())
attrs[i] = TranslatedString(map[string]string{"en": val, "nl": val})
} }
return &AttributeList{ return &AttributeList{
Ints: ints, Ints: ints,
MetadataAttribute: meta, MetadataAttribute: meta,
info: &Credential{ }, nil
ID: credtype.Identifier().String(), }
SignedOn: Timestamp(meta.SigningDate()),
Expires: Timestamp(meta.Expiry()), func (al *AttributeList) Info() *Credential {
Type: credtype, if al.info == nil {
Issuer: MetaStore.Issuers[issid], al.info = NewCredential(al.Ints)
SchemeManager: MetaStore.SchemeManagers[issid.SchemeManagerIdentifier()],
Attributes: attrs,
Logo: "", // TODO
},
} }
return al.info
} }
// TODO maybe remove // TODO maybe remove
......
...@@ -3,6 +3,8 @@ package irmago ...@@ -3,6 +3,8 @@ package irmago
import ( import (
"strings" "strings"
"math/big"
"github.com/mhe/gabi" "github.com/mhe/gabi"
) )
...@@ -28,6 +30,29 @@ type Credential struct { ...@@ -28,6 +30,29 @@ type Credential struct {
// A CredentialList is a list of credentials (implements sort.Interface). // A CredentialList is a list of credentials (implements sort.Interface).
type CredentialList []*Credential type CredentialList []*Credential
func NewCredential(ints []*big.Int) *Credential {
meta := MetadataFromInt(ints[0])
credtype := meta.CredentialType()
issid := credtype.IssuerIdentifier()
attrs := make([]TranslatedString, len(credtype.Attributes))
for i := range credtype.Attributes {
val := string(ints[i+1].Bytes())
attrs[i] = TranslatedString(map[string]string{"en": val, "nl": val})
}
return &Credential{
ID: credtype.Identifier().String(),
SignedOn: Timestamp(meta.SigningDate()),
Expires: Timestamp(meta.Expiry()),
Type: credtype,
Issuer: MetaStore.Issuers[issid],
SchemeManager: MetaStore.SchemeManagers[issid.SchemeManagerIdentifier()],
Attributes: attrs,
Logo: "", // TODO
}
}
func newCredential(gabicred *gabi.Credential) (cred *credential) { func newCredential(gabicred *gabi.Credential) (cred *credential) {
meta := MetadataFromInt(gabicred.Attributes[1]) meta := MetadataFromInt(gabicred.Attributes[1])
cred = &credential{ cred = &credential{
......
...@@ -31,17 +31,17 @@ type IgnoringKeyshareHandler struct{} ...@@ -31,17 +31,17 @@ type IgnoringKeyshareHandler struct{}
func (i *IgnoringKeyshareHandler) StartRegistration(m *SchemeManager, callback func(e, p string)) { func (i *IgnoringKeyshareHandler) StartRegistration(m *SchemeManager, callback func(e, p string)) {
} }
func parseMetaStore(t *testing.T) {
require.NoError(t, MetaStore.ParseFolder("testdata/irma_configuration"), "MetaStore.ParseFolder() failed")
}
func parseStorage(t *testing.T) { func parseStorage(t *testing.T) {
exists, err := PathExists("testdata/storage/test") exists, err := PathExists("testdata/storage/test")
require.NoError(t, err, "pathexists() failed") require.NoError(t, err, "pathexists() failed")
if !exists { if !exists {
require.NoError(t, os.Mkdir("testdata/storage/test", 0755), "Could not create test storage") require.NoError(t, os.Mkdir("testdata/storage/test", 0755), "Could not create test storage")
} }
require.NoError(t, Manager.Init("testdata/storage/test", &IgnoringKeyshareHandler{}), "Manager.Init() failed") require.NoError(t, Manager.Init(
"testdata/storage/test",
"testdata/irma_configuration",
&IgnoringKeyshareHandler{},
), "Manager.Init() failed")
} }
func teardown(t *testing.T) { func teardown(t *testing.T) {
...@@ -62,7 +62,7 @@ func parseAndroidStorage(t *testing.T) { ...@@ -62,7 +62,7 @@ func parseAndroidStorage(t *testing.T) {
assert.NoError(t, Manager.ParseAndroidStorage(), "ParseAndroidStorage() failed") assert.NoError(t, Manager.ParseAndroidStorage(), "ParseAndroidStorage() failed")
} }
func verifyStoreIsUnmarshaled(t *testing.T) { func verifyManagerIsUnmarshaled(t *testing.T) {
cred, err := Manager.credential(NewCredentialTypeIdentifier("irma-demo.RU.studentCard"), 0) cred, err := Manager.credential(NewCredentialTypeIdentifier("irma-demo.RU.studentCard"), 0)
assert.NoError(t, err, "could not fetch credential") assert.NoError(t, err, "could not fetch credential")
assert.NotNil(t, cred, "Credential should exist") assert.NotNil(t, cred, "Credential should exist")
...@@ -105,34 +105,7 @@ func verifyKeyshareIsUnmarshaled(t *testing.T) { ...@@ -105,34 +105,7 @@ func verifyKeyshareIsUnmarshaled(t *testing.T) {
verifyPaillierKey(t, Manager.paillierKeyCache) verifyPaillierKey(t, Manager.paillierKeyCache)
} }
func TestAndroidParse(t *testing.T) { func verifyStoreIsLoaded(t *testing.T) {
parseMetaStore(t)
parseStorage(t)
parseAndroidStorage(t)
verifyStoreIsUnmarshaled(t)
verifyKeyshareIsUnmarshaled(t)
teardown(t)
}
func TestUnmarshaling(t *testing.T) {
parseMetaStore(t)
parseStorage(t)
parseAndroidStorage(t)
Manager = newCredentialManager()
err := Manager.Init("testdata/storage/test", nil)
require.NoError(t, err)
verifyStoreIsUnmarshaled(t)
verifyKeyshareIsUnmarshaled(t)
teardown(t)
}
func TestParseStore(t *testing.T) {
parseMetaStore(t)
assert.NotNil(t, MetaStore.Issuers[NewIssuerIdentifier("irma-demo.RU")].CurrentPublicKey().N, "irma-demo.RU public key has no modulus") assert.NotNil(t, MetaStore.Issuers[NewIssuerIdentifier("irma-demo.RU")].CurrentPublicKey().N, "irma-demo.RU public key has no modulus")
assert.Equal(t, assert.Equal(t,
"Irma Demo", "Irma Demo",
...@@ -158,6 +131,29 @@ func TestParseStore(t *testing.T) { ...@@ -158,6 +131,29 @@ func TestParseStore(t *testing.T) {
"irma-demo.RU.studentCard had improper hash") "irma-demo.RU.studentCard had improper hash")
assert.Contains(t, MetaStore.reverseHashes, "CLjnADMBYlFcuGOT7Z0xRg==", assert.Contains(t, MetaStore.reverseHashes, "CLjnADMBYlFcuGOT7Z0xRg==",
"irma-demo.MijnOverheid.root had improper hash") "irma-demo.MijnOverheid.root had improper hash")
}
func TestAndroidParse(t *testing.T) {
parseStorage(t)
verifyStoreIsLoaded(t)
parseAndroidStorage(t)
verifyManagerIsUnmarshaled(t)
verifyKeyshareIsUnmarshaled(t)
teardown(t)
}
func TestUnmarshaling(t *testing.T) {
parseStorage(t)
parseAndroidStorage(t)
Manager = newCredentialManager()
err := Manager.Init("testdata/storage/test", "testdata/irma_configuration", nil)
require.NoError(t, err)
verifyManagerIsUnmarshaled(t)
verifyKeyshareIsUnmarshaled(t)
teardown(t) teardown(t)
} }
...@@ -179,7 +175,7 @@ func TestMetadataAttribute(t *testing.T) { ...@@ -179,7 +175,7 @@ func TestMetadataAttribute(t *testing.T) {
} }
func TestMetadataCompatibility(t *testing.T) { func TestMetadataCompatibility(t *testing.T) {
parseMetaStore(t) require.NoError(t, MetaStore.ParseFolder("testdata/irma_configuration"))
// An actual metadata attribute of an IRMA credential extracted from the IRMA app // An actual metadata attribute of an IRMA credential extracted from the IRMA app
attr := MetadataFromInt(s2big("49043481832371145193140299771658227036446546573739245068")) attr := MetadataFromInt(s2big("49043481832371145193140299771658227036446546573739245068"))
...@@ -241,7 +237,6 @@ func TestAttributeDisjunctionMarshaling(t *testing.T) { ...@@ -241,7 +237,6 @@ func TestAttributeDisjunctionMarshaling(t *testing.T) {
} }
func TestCandidates(t *testing.T) { func TestCandidates(t *testing.T) {
parseMetaStore(t)
parseStorage(t) parseStorage(t)
parseAndroidStorage(t) parseAndroidStorage(t)
...@@ -332,7 +327,6 @@ func TestTransport(t *testing.T) { ...@@ -332,7 +327,6 @@ func TestTransport(t *testing.T) {
} }
func TestPaillier(t *testing.T) { func TestPaillier(t *testing.T) {
parseMetaStore(t)
parseStorage(t) parseStorage(t)
parseAndroidStorage(t) parseAndroidStorage(t)
......
...@@ -39,7 +39,7 @@ func (cm *CredentialManager) CredentialList() CredentialList { ...@@ -39,7 +39,7 @@ func (cm *CredentialManager) CredentialList() CredentialList {
for _, attrlistlist := range cm.attributes { for _, attrlistlist := range cm.attributes {
for _, attrlist := range attrlistlist { for _, attrlist := range attrlistlist {
list = append(list, attrlist.info) list = append(list, attrlist.Info())
} }
} }
...@@ -119,15 +119,20 @@ func (cm *CredentialManager) credential(id CredentialTypeIdentifier, counter int ...@@ -119,15 +119,20 @@ func (cm *CredentialManager) credential(id CredentialTypeIdentifier, counter int
return cm.credentials[id][counter], nil return cm.credentials[id][counter], nil
} }
func (cm *CredentialManager) addCredential(cred *credential) { func (cm *CredentialManager) addCredential(cred *credential) error {
attrs, err := NewAttributeListFromInts(cred.Attributes[1:])
if err != nil {
return err
}
id := cred.CredentialType().Identifier() id := cred.CredentialType().Identifier()
cm.attributes[id] = append(cm.attrs(id), NewAttributeListFromInts(cred.Attributes[1:])) cm.attributes[id] = append(cm.attrs(id), attrs)
if _, exists := cm.credentials[id]; !exists { if _, exists := cm.credentials[id]; !exists {
cm.credentials[id] = make(map[int]*credential) cm.credentials[id] = make(map[int]*credential)
} }
counter := len(cm.attributes[id]) - 1 counter := len(cm.attributes[id]) - 1
cm.credentials[id][counter] = cred cm.credentials[id][counter] = cred
return nil
} }
// add adds the specified credential to the CredentialManager. // add adds the specified credential to the CredentialManager.
...@@ -136,11 +141,12 @@ func (cm *CredentialManager) add(cred *credential) (err error) { ...@@ -136,11 +141,12 @@ func (cm *CredentialManager) add(cred *credential) (err error) {
return errors.New("cannot add unknown credential type") return errors.New("cannot add unknown credential type")
} }
cm.addCredential(cred) if err = cm.addCredential(cred); err != nil {
return
}
counter := len(cm.credentials[cred.CredentialType().Identifier()]) - 1 counter := len(cm.credentials[cred.CredentialType().Identifier()]) - 1
err = cm.storeSignature(cred, counter) if err = cm.storeSignature(cred, counter); err != nil {
if err != nil {
return return
} }
err = cm.storeAttributes() err = cm.storeAttributes()
...@@ -167,7 +173,8 @@ func (cm *CredentialManager) Candidates(disjunction *AttributeDisjunction) []*At ...@@ -167,7 +173,8 @@ func (cm *CredentialManager) Candidates(disjunction *AttributeDisjunction) []*At
if attribute.IsCredential() { if attribute.IsCredential() {
candidates = append(candidates, id) candidates = append(candidates, id)
} else { } else {
attrs := NewAttributeListFromInts(cred.Attributes[1:]) // Ignoring error of unknown credential type, would have happened during initialization
attrs, _ := NewAttributeListFromInts(cred.Attributes[1:])
val := attrs.Attribute(attribute) val := attrs.Attribute(attribute)
if val == "" { // This won't handle empty attributes correctly if val == "" { // This won't handle empty attributes correctly
continue continue
......
...@@ -139,7 +139,7 @@ func (cr *CredentialRequest) AttributeList() (*AttributeList, error) { ...@@ -139,7 +139,7 @@ func (cr *CredentialRequest) AttributeList() (*AttributeList, error) {
} }
} }
return NewAttributeListFromInts(attrs), nil return NewAttributeListFromInts(attrs)
} }
func newIssuanceState() (*issuanceState, error) { func newIssuanceState() (*issuanceState, error) {
......
...@@ -149,7 +149,6 @@ func TestIssuanceSession(t *testing.T) { ...@@ -149,7 +149,6 @@ func TestIssuanceSession(t *testing.T) {
func sessionHelper(t *testing.T, jwtcontents interface{}, url string, init bool) { func sessionHelper(t *testing.T, jwtcontents interface{}, url string, init bool) {
if init { if init {
parseMetaStore(t)
parseStorage(t) parseStorage(t)
parseAndroidStorage(t) parseAndroidStorage(t)
} }
...@@ -183,7 +182,6 @@ func sessionHelper(t *testing.T, jwtcontents interface{}, url string, init bool) ...@@ -183,7 +182,6 @@ func sessionHelper(t *testing.T, jwtcontents interface{}, url string, init bool)
} }
func registerKeyshareServer(t *testing.T) { func registerKeyshareServer(t *testing.T) {
parseMetaStore(t)
parseStorage(t) parseStorage(t)
parseAndroidStorage(t) parseAndroidStorage(t)
......
...@@ -40,28 +40,29 @@ func PathExists(path string) (bool, error) { ...@@ -40,28 +40,29 @@ func PathExists(path string) (bool, error) {
} }
// Init deserializes the credentials from storage. // Init deserializes the credentials from storage.
func (cm *CredentialManager) Init(path string, keyshareHandler KeyshareHandler) (err error) { func (cm *CredentialManager) Init(
cm.storagePath = path storagePath string,
irmaConfigurationPath string,
keyshareHandler KeyshareHandler,
) (err error) {
if err = MetaStore.ParseFolder(irmaConfigurationPath); err != nil {
return
}
err = cm.ensureStorageExists() cm.storagePath = storagePath
if err != nil { if err = cm.ensureStorageExists(); err != nil {
return err return
} }
cm.secretkey, err = cm.loadSecretKey() if cm.secretkey, err = cm.loadSecretKey(); err != nil {
if err != nil {
return return
} }
cm.attributes, err = cm.loadAttributes() if cm.attributes, err = cm.loadAttributes(); err != nil {
if err != nil {
return return
} }
cm.paillierKeyCache, err = cm.loadPaillierKeys() if cm.paillierKeyCache, err = cm.loadPaillierKeys(); err != nil {
if err != nil {
return return
} }
if cm.keyshareServers, err = cm.loadKeyshareServers(); err != nil {
cm.keyshareServers, err = cm.loadKeyshareServers()
if err != nil {
return return
} }
...@@ -301,9 +302,12 @@ func (cm *CredentialManager) storePaillierKeys() (err error) { ...@@ -301,9 +302,12 @@ func (cm *CredentialManager) storePaillierKeys() (err error) {
func (cm *CredentialManager) loadSignature(id CredentialTypeIdentifier, counter int) (signature *gabi.CLSignature, err error) { func (cm *CredentialManager) loadSignature(id CredentialTypeIdentifier, counter int) (signature *gabi.CLSignature, err error) {
sigpath := cm.signatureFilename(id.String(), counter) sigpath := cm.signatureFilename(id.String(), counter)
exists, err := PathExists(sigpath) exists, err := PathExists(sigpath)
if err != nil || !exists { if err != nil {
return return
} }
if !exists {
return nil, errors.New("Signature file not found")
}
bytes, err := ioutil.ReadFile(sigpath) bytes, err := ioutil.ReadFile(sigpath)
if err != nil { if err != nil {
return return
......
Supports Markdown
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