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 {
if err := json.Unmarshal(bytes, &ints); err != nil {
return err
}
*al = *NewAttributeListFromInts(ints)
list, err := NewAttributeListFromInts(ints)
if err != nil {
return err
}
*al = *list
return nil
}
// 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])
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})
if ints[0] == nil || meta.CredentialType() == nil {
return nil, errors.New("Encountered credential of unknown type")
}
return &AttributeList{
Ints: ints,
MetadataAttribute: meta,
info: &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
},
}, nil
}
func (al *AttributeList) Info() *Credential {
if al.info == nil {
al.info = NewCredential(al.Ints)
}
return al.info
}
// TODO maybe remove
......
......@@ -3,6 +3,8 @@ package irmago
import (
"strings"
"math/big"
"github.com/mhe/gabi"
)
......@@ -28,6 +30,29 @@ type Credential struct {
// A CredentialList is a list of credentials (implements sort.Interface).
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) {
meta := MetadataFromInt(gabicred.Attributes[1])
cred = &credential{
......
......@@ -31,17 +31,17 @@ type IgnoringKeyshareHandler struct{}
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) {
exists, err := PathExists("testdata/storage/test")
require.NoError(t, err, "pathexists() failed")
if !exists {
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) {
......@@ -62,7 +62,7 @@ func parseAndroidStorage(t *testing.T) {
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)
assert.NoError(t, err, "could not fetch credential")
assert.NotNil(t, cred, "Credential should exist")
......@@ -105,34 +105,7 @@ func verifyKeyshareIsUnmarshaled(t *testing.T) {
verifyPaillierKey(t, Manager.paillierKeyCache)
}
func TestAndroidParse(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)
func verifyStoreIsLoaded(t *testing.T) {
assert.NotNil(t, MetaStore.Issuers[NewIssuerIdentifier("irma-demo.RU")].CurrentPublicKey().N, "irma-demo.RU public key has no modulus")
assert.Equal(t,
"Irma Demo",
......@@ -158,6 +131,29 @@ func TestParseStore(t *testing.T) {
"irma-demo.RU.studentCard had improper hash")
assert.Contains(t, MetaStore.reverseHashes, "CLjnADMBYlFcuGOT7Z0xRg==",
"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)
}
......@@ -179,7 +175,7 @@ func TestMetadataAttribute(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
attr := MetadataFromInt(s2big("49043481832371145193140299771658227036446546573739245068"))
......@@ -241,7 +237,6 @@ func TestAttributeDisjunctionMarshaling(t *testing.T) {
}
func TestCandidates(t *testing.T) {
parseMetaStore(t)
parseStorage(t)
parseAndroidStorage(t)
......@@ -332,7 +327,6 @@ func TestTransport(t *testing.T) {
}
func TestPaillier(t *testing.T) {
parseMetaStore(t)
parseStorage(t)
parseAndroidStorage(t)
......
......@@ -39,7 +39,7 @@ func (cm *CredentialManager) CredentialList() CredentialList {
for _, attrlistlist := range cm.attributes {
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
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()
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 {
cm.credentials[id] = make(map[int]*credential)
}
counter := len(cm.attributes[id]) - 1
cm.credentials[id][counter] = cred
return nil
}
// add adds the specified credential to the CredentialManager.
......@@ -136,11 +141,12 @@ func (cm *CredentialManager) add(cred *credential) (err error) {
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
err = cm.storeSignature(cred, counter)
if err != nil {
if err = cm.storeSignature(cred, counter); err != nil {
return
}
err = cm.storeAttributes()
......@@ -167,7 +173,8 @@ func (cm *CredentialManager) Candidates(disjunction *AttributeDisjunction) []*At
if attribute.IsCredential() {
candidates = append(candidates, id)
} 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)
if val == "" { // This won't handle empty attributes correctly
continue
......
......@@ -139,7 +139,7 @@ func (cr *CredentialRequest) AttributeList() (*AttributeList, error) {
}
}
return NewAttributeListFromInts(attrs), nil
return NewAttributeListFromInts(attrs)
}
func newIssuanceState() (*issuanceState, error) {
......
......@@ -149,7 +149,6 @@ func TestIssuanceSession(t *testing.T) {
func sessionHelper(t *testing.T, jwtcontents interface{}, url string, init bool) {
if init {
parseMetaStore(t)
parseStorage(t)
parseAndroidStorage(t)
}
......@@ -183,7 +182,6 @@ func sessionHelper(t *testing.T, jwtcontents interface{}, url string, init bool)
}
func registerKeyshareServer(t *testing.T) {
parseMetaStore(t)
parseStorage(t)
parseAndroidStorage(t)
......
......@@ -40,28 +40,29 @@ func PathExists(path string) (bool, error) {
}
// Init deserializes the credentials from storage.
func (cm *CredentialManager) Init(path string, keyshareHandler KeyshareHandler) (err error) {
cm.storagePath = path
func (cm *CredentialManager) Init(
storagePath string,
irmaConfigurationPath string,
keyshareHandler KeyshareHandler,
) (err error) {
if err = MetaStore.ParseFolder(irmaConfigurationPath); err != nil {
return
}
err = cm.ensureStorageExists()
if err != nil {
return err
cm.storagePath = storagePath
if err = cm.ensureStorageExists(); err != nil {
return
}
cm.secretkey, err = cm.loadSecretKey()
if err != nil {
if cm.secretkey, err = cm.loadSecretKey(); err != nil {
return
}
cm.attributes, err = cm.loadAttributes()
if err != nil {
if cm.attributes, err = cm.loadAttributes(); err != nil {
return
}
cm.paillierKeyCache, err = cm.loadPaillierKeys()
if err != nil {
if cm.paillierKeyCache, err = cm.loadPaillierKeys(); err != nil {
return
}
cm.keyshareServers, err = cm.loadKeyshareServers()
if err != nil {
if cm.keyshareServers, err = cm.loadKeyshareServers(); err != nil {
return
}
......@@ -301,9 +302,12 @@ func (cm *CredentialManager) storePaillierKeys() (err error) {
func (cm *CredentialManager) loadSignature(id CredentialTypeIdentifier, counter int) (signature *gabi.CLSignature, err error) {
sigpath := cm.signatureFilename(id.String(), counter)
exists, err := PathExists(sigpath)
if err != nil || !exists {
if err != nil {
return
}
if !exists {
return nil, errors.New("Signature file not found")
}
bytes, err := ioutil.ReadFile(sigpath)
if err != nil {
return
......
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