Commit 78d2cd8a authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Finish removal of Manager and MetaStore singletons

parent eec210bf
......@@ -60,30 +60,22 @@ func (al *AttributeList) UnmarshalJSON(bytes []byte) error {
if err := json.Unmarshal(bytes, &ints); err != nil {
return err
}
list, err := NewAttributeListFromInts(ints)
if err != nil {
return err
}
list := NewAttributeListFromInts(ints, nil)
*al = *list
return nil
}
// NewAttributeListFromInts initializes a new AttributeList from a list of bigints.
func NewAttributeListFromInts(ints []*big.Int, store *ConfigurationStore) (*AttributeList, error) {
meta := MetadataFromInt(ints[0], store)
if ints[0] == nil || meta.CredentialType() == nil {
return nil, errors.New("Encountered credential of unknown type")
}
func NewAttributeListFromInts(ints []*big.Int, store *ConfigurationStore) *AttributeList {
return &AttributeList{
Ints: ints,
MetadataAttribute: meta,
}, nil
MetadataAttribute: MetadataFromInt(ints[0], store),
}
}
func (al *AttributeList) Info() *CredentialInfo {
if al.info == nil {
al.info = NewCredentialInfo(al.Ints)
al.info = NewCredentialInfo(al.Ints, al.store)
}
return al.info
}
......@@ -144,7 +136,7 @@ func (attr *MetadataAttribute) Bytes() []byte {
// and returns this public key.
func (attr *MetadataAttribute) PublicKey() *gabi.PublicKey {
if attr.pk == nil {
attr.pk = MetaStore.PublicKey(attr.CredentialType().IssuerIdentifier(), attr.KeyCounter())
attr.pk = attr.store.PublicKey(attr.CredentialType().IssuerIdentifier(), attr.KeyCounter())
}
return attr.pk
}
......@@ -197,7 +189,7 @@ func (attr *MetadataAttribute) setExpiryDate(timestamp *Timestamp) error {
// CredentialType returns the credential type of the current instance
// using the MetaStore.
func (attr *MetadataAttribute) CredentialType() *CredentialType {
return MetaStore.hashToCredentialType(attr.field(credentialID))
return attr.store.hashToCredentialType(attr.field(credentialID))
}
func (attr *MetadataAttribute) setCredentialTypeIdentifier(id string) {
......@@ -295,7 +287,7 @@ func (disjunction *AttributeDisjunction) Satisfied() bool {
}
// MatchesStore returns true if all attributes contained in the disjunction are
// present in the MetaStore.
// present in the specified configuration store.
func (disjunction *AttributeDisjunction) MatchesStore(store *ConfigurationStore) bool {
for ai := range disjunction.Values {
creddescription, exists := store.Credentials[ai.CredentialTypeIdentifier()]
......
......@@ -20,9 +20,9 @@ type CredentialInfo struct {
ID string // e.g., "irma-demo.RU.studentCard"
SignedOn Timestamp // Unix timestamp
Expires Timestamp // Unix timestamp
Type *CredentialType // Credential information from MetaStore
Issuer *Issuer // Issuer information from MetaStore
SchemeManager *SchemeManager // Scheme manager information from MetaStore
Type *CredentialType // Credential information from ConfigurationStore
Issuer *Issuer // Issuer information from ConfigurationStore
SchemeManager *SchemeManager // Scheme manager information from ConfigurationStore
Attributes []TranslatedString // Human-readable rendered attributes
Logo string // Path to logo on storage
}
......@@ -30,8 +30,8 @@ type CredentialInfo struct {
// A CredentialInfoList is a list of credentials (implements sort.Interface).
type CredentialInfoList []*CredentialInfo
func NewCredentialInfo(ints []*big.Int) *CredentialInfo {
meta := MetadataFromInt(ints[0])
func NewCredentialInfo(ints []*big.Int, store *ConfigurationStore) *CredentialInfo {
meta := MetadataFromInt(ints[0], store)
credtype := meta.CredentialType()
issid := credtype.IssuerIdentifier()
......@@ -46,20 +46,20 @@ func NewCredentialInfo(ints []*big.Int) *CredentialInfo {
SignedOn: Timestamp(meta.SigningDate()),
Expires: Timestamp(meta.Expiry()),
Type: credtype,
Issuer: MetaStore.Issuers[issid],
SchemeManager: MetaStore.SchemeManagers[issid.SchemeManagerIdentifier()],
Issuer: store.Issuers[issid],
SchemeManager: store.SchemeManagers[issid.SchemeManagerIdentifier()],
Attributes: attrs,
Logo: "", // TODO
}
}
func newCredential(gabicred *gabi.Credential) (cred *credential) {
meta := MetadataFromInt(gabicred.Attributes[1])
func newCredential(gabicred *gabi.Credential, store *ConfigurationStore) (cred *credential) {
meta := MetadataFromInt(gabicred.Attributes[1], store)
cred = &credential{
Credential: gabicred,
MetadataAttribute: meta,
}
cred.Pk = MetaStore.PublicKey(meta.CredentialType().IssuerIdentifier(), cred.KeyCounter())
cred.Pk = store.PublicKey(meta.CredentialType().IssuerIdentifier(), cred.KeyCounter())
return
}
......
......@@ -133,8 +133,8 @@ func (sm *SchemeManager) Distributed() bool {
}
// CurrentPublicKey returns the latest known public key of the issuer identified by this instance.
func (id *Issuer) CurrentPublicKey() *gabi.PublicKey {
keys := MetaStore.PublicKeys[id.Identifier()]
func (id *Issuer) CurrentPublicKey(store *ConfigurationStore) *gabi.PublicKey {
keys := store.PublicKeys[id.Identifier()]
if keys == nil || len(keys) == 0 {
return nil
}
......@@ -142,8 +142,8 @@ func (id *Issuer) CurrentPublicKey() *gabi.PublicKey {
}
// PublicKey returns the specified public key of the issuer identified by this instance.
func (id *Issuer) PublicKey(index int) *gabi.PublicKey {
keys := MetaStore.PublicKeys[id.Identifier()]
func (id *Issuer) PublicKey(index int, store *ConfigurationStore) *gabi.PublicKey {
keys := store.PublicKeys[id.Identifier()]
if keys == nil || index >= len(keys) {
return nil
}
......
......@@ -47,9 +47,7 @@ func parseStorage(t *testing.T) *CredentialManager {
}
func teardown(t *testing.T) {
MetaStore = newConfigurationStore()
assert.NoError(t, os.RemoveAll("testdata/storage/test"))
// TODO first RemoveAll?!
}
// A convenience function for initializing big integers from known correct (10
......@@ -124,37 +122,37 @@ func verifyKeyshareIsUnmarshaled(t *testing.T, manager *CredentialManager) {
verifyPaillierKey(t, manager.paillierKeyCache)
}
func verifyStoreIsLoaded(t *testing.T) {
assert.NotNil(t, MetaStore.Issuers[NewIssuerIdentifier("irma-demo.RU")].CurrentPublicKey().N, "irma-demo.RU public key has no modulus")
func verifyStoreIsLoaded(t *testing.T, store *ConfigurationStore) {
assert.NotNil(t, store.Issuers[NewIssuerIdentifier("irma-demo.RU")].CurrentPublicKey(store).N, "irma-demo.RU public key has no modulus")
assert.Equal(t,
"Irma Demo",
MetaStore.SchemeManagers[NewSchemeManagerIdentifier("irma-demo")].Name["en"],
store.SchemeManagers[NewSchemeManagerIdentifier("irma-demo")].Name["en"],
"irma-demo scheme manager has unexpected name")
assert.Equal(t,
"Radboud Universiteit Nijmegen",
MetaStore.Issuers[NewIssuerIdentifier("irma-demo.RU")].Name["en"],
store.Issuers[NewIssuerIdentifier("irma-demo.RU")].Name["en"],
"irma-demo.RU issuer has unexpected name")
assert.Equal(t,
"Student Card",
MetaStore.Credentials[NewCredentialTypeIdentifier("irma-demo.RU.studentCard")].ShortName["en"],
store.Credentials[NewCredentialTypeIdentifier("irma-demo.RU.studentCard")].ShortName["en"],
"irma-demo.RU.studentCard has unexpected name")
assert.Equal(t,
"studentID",
MetaStore.Credentials[NewCredentialTypeIdentifier("irma-demo.RU.studentCard")].Attributes[2].ID,
store.Credentials[NewCredentialTypeIdentifier("irma-demo.RU.studentCard")].Attributes[2].ID,
"irma-demo.RU.studentCard.studentID has unexpected name")
// Hash algorithm pseudocode:
// Base64(SHA256("irma-demo.RU.studentCard")[0:16])
assert.Contains(t, MetaStore.reverseHashes, "1stqlPad5edpfS1Na1U+DA==",
assert.Contains(t, store.reverseHashes, "1stqlPad5edpfS1Na1U+DA==",
"irma-demo.RU.studentCard had improper hash")
assert.Contains(t, MetaStore.reverseHashes, "CLjnADMBYlFcuGOT7Z0xRg==",
assert.Contains(t, store.reverseHashes, "CLjnADMBYlFcuGOT7Z0xRg==",
"irma-demo.MijnOverheid.root had improper hash")
}
func TestAndroidParse(t *testing.T) {
manager := parseStorage(t)
verifyStoreIsLoaded(t)
verifyStoreIsLoaded(t, manager.Store)
parseAndroidStorage(t, manager)
verifyManagerIsUnmarshaled(t, manager)
......
......@@ -139,7 +139,7 @@ func startKeyshareSession(
) {
ksscount := 0
for _, managerID := range session.SchemeManagers() {
if credManager.store.SchemeManagers[managerID].Distributed() {
if credManager.Store.SchemeManagers[managerID].Distributed() {
ksscount++
if _, registered := credManager.keyshareServers[managerID]; !registered {
err := errors.New("Not registered to keyshare server of scheme manager " + managerID.String())
......@@ -166,7 +166,7 @@ func startKeyshareSession(
askPin := false
for _, managerID := range session.SchemeManagers() {
if !ks.credManager.store.SchemeManagers[managerID].Distributed() {
if !ks.credManager.Store.SchemeManagers[managerID].Distributed() {
continue
}
......@@ -234,7 +234,7 @@ func (ks *keyshareSession) VerifyPin(attempts int) {
// If all is ok, success will be true.
func (ks *keyshareSession) verifyPinAttempt(pin string) (success bool, tries int, blocked int, err error) {
for _, managerID := range ks.session.SchemeManagers() {
if !ks.credManager.store.SchemeManagers[managerID].Distributed() {
if !ks.credManager.Store.SchemeManagers[managerID].Distributed() {
continue
}
......@@ -285,7 +285,7 @@ func (ks *keyshareSession) GetCommitments() {
for _, builder := range ks.builders {
pk := builder.PublicKey()
managerID := NewIssuerIdentifier(pk.Issuer).SchemeManagerIdentifier()
if !ks.credManager.store.SchemeManagers[managerID].Distributed() {
if !ks.credManager.Store.SchemeManagers[managerID].Distributed() {
continue
}
if _, contains := pkids[managerID]; !contains {
......@@ -297,7 +297,7 @@ func (ks *keyshareSession) GetCommitments() {
// Now inform each keyshare server of with respect to which public keys
// we want them to send us commitments
for _, managerID := range ks.session.SchemeManagers() {
if !ks.credManager.store.SchemeManagers[managerID].Distributed() {
if !ks.credManager.Store.SchemeManagers[managerID].Distributed() {
continue
}
......@@ -401,7 +401,7 @@ func (ks *keyshareSession) finishDisclosureOrSigning(challenge *big.Int, respons
for i, builder := range ks.builders {
// Parse each received JWT
managerID := NewIssuerIdentifier(builder.PublicKey().Issuer).SchemeManagerIdentifier()
if !ks.credManager.store.SchemeManagers[managerID].Distributed() {
if !ks.credManager.Store.SchemeManagers[managerID].Distributed() {
continue
}
msg := struct {
......
......@@ -21,7 +21,7 @@ type CredentialManager struct {
keyshareServers map[SchemeManagerIdentifier]*keyshareServer
paillierKeyCache *paillierPrivateKey
store *ConfigurationStore
Store *ConfigurationStore
}
// CredentialInfoList returns a list of information of all contained credentials.
......@@ -94,7 +94,7 @@ func (cm *CredentialManager) credential(id CredentialTypeIdentifier, counter int
err = errors.New("signature file not found")
return nil, err
}
meta := MetadataFromInt(ints[1])
meta := MetadataFromInt(ints[1], cm.Store)
pk := meta.PublicKey()
if pk == nil {
return nil, errors.New("unknown public key")
......@@ -103,7 +103,7 @@ func (cm *CredentialManager) credential(id CredentialTypeIdentifier, counter int
Attributes: ints,
Signature: sig,
Pk: pk,
})
}, cm.Store)
cm.credentials[id][counter] = cred
}
......@@ -113,10 +113,7 @@ func (cm *CredentialManager) credential(id CredentialTypeIdentifier, counter int
// addCredential adds the specified credential to the CredentialManager, saving its signature
// imediately, and optionally cm.attributes as well.
func (cm *CredentialManager) addCredential(cred *credential, storeAttributes bool) (err error) {
attrs, err := NewAttributeListFromInts(cred.Attributes[1:])
if err != nil {
return err
}
attrs := NewAttributeListFromInts(cred.Attributes[1:], cm.Store)
id := cred.CredentialType().Identifier()
cm.attributes[id] = append(cm.attrs(id), attrs)
......@@ -142,7 +139,7 @@ func (cm *CredentialManager) Candidates(disjunction *AttributeDisjunction) []*At
for _, attribute := range disjunction.Attributes {
credID := attribute.CredentialTypeIdentifier()
if !cm.store.Contains(credID) {
if !cm.Store.Contains(credID) {
continue
}
creds := cm.credentials[credID]
......@@ -155,8 +152,7 @@ func (cm *CredentialManager) Candidates(disjunction *AttributeDisjunction) []*At
if attribute.IsCredential() {
candidates = append(candidates, id)
} else {
// Ignoring error of unknown credential type, would have happened during initialization
attrs, _ := NewAttributeListFromInts(cred.Attributes[1:])
attrs := NewAttributeListFromInts(cred.Attributes[1:], cm.Store)
val := attrs.Attribute(attribute)
if val == "" { // This won't handle empty attributes correctly
continue
......@@ -203,7 +199,7 @@ func (cm *CredentialManager) groupCredentials(choice *DisclosureChoice) (map[Cre
if identifier.IsCredential() {
continue // In this case we only disclose the metadata attribute, which is already handled
}
index, err := cm.store.Credentials[identifier.CredentialTypeIdentifier()].IndexOf(identifier)
index, err := cm.Store.Credentials[identifier.CredentialTypeIdentifier()].IndexOf(identifier)
if err != nil {
return nil, err
}
......@@ -225,7 +221,7 @@ type IrmaSession interface {
DisjunctionList() AttributeDisjunctionList
DisclosureChoice() *DisclosureChoice
SetDisclosureChoice(choice *DisclosureChoice)
Distributed() bool
Distributed(store *ConfigurationStore) bool
SchemeManagers() []SchemeManagerIdentifier
}
......@@ -267,7 +263,7 @@ func (cm *CredentialManager) IssuanceProofBuilders(request *IssuanceRequest) (ga
proofBuilders := gabi.ProofBuilderList([]gabi.ProofBuilder{})
for _, futurecred := range request.Credentials {
pk := cm.store.PublicKey(futurecred.Credential.IssuerIdentifier(), futurecred.KeyCounter)
pk := cm.Store.PublicKey(futurecred.Credential.IssuerIdentifier(), futurecred.KeyCounter)
credBuilder := gabi.NewCredentialBuilder(pk, request.GetContext(), cm.secretkey, state.nonce2)
request.state.builders = append(request.state.builders, credBuilder)
proofBuilders = append(proofBuilders, credBuilder)
......@@ -303,7 +299,7 @@ func (cm *CredentialManager) ConstructCredentials(msg []*gabi.IssueSignatureMess
// we save none of them to fail the session cleanly
creds := []*gabi.Credential{}
for i, sig := range msg {
attrs, err := request.Credentials[i].AttributeList()
attrs, err := request.Credentials[i].AttributeList(cm.Store)
if err != nil {
return err
}
......@@ -315,7 +311,7 @@ func (cm *CredentialManager) ConstructCredentials(msg []*gabi.IssueSignatureMess
}
for _, cred := range creds {
cm.addCredential(newCredential(cred), true)
cm.addCredential(newCredential(cred, cm.Store), true)
}
return nil
......@@ -342,7 +338,7 @@ func (cm *CredentialManager) paillierKey(wait bool) *paillierPrivateKey {
func (cm *CredentialManager) unenrolledKeyshareServers() []*SchemeManager {
list := []*SchemeManager{}
for name, manager := range cm.store.SchemeManagers {
for name, manager := range cm.Store.SchemeManagers {
if _, contains := cm.keyshareServers[name]; len(manager.KeyshareServer) > 0 && !contains {
list = append(list, manager)
}
......@@ -352,7 +348,7 @@ func (cm *CredentialManager) unenrolledKeyshareServers() []*SchemeManager {
// KeyshareEnroll attempts to register at the keyshare server of the specified scheme manager.
func (cm *CredentialManager) KeyshareEnroll(managerID SchemeManagerIdentifier, email, pin string) error {
manager, ok := cm.store.SchemeManagers[managerID]
manager, ok := cm.Store.SchemeManagers[managerID]
if !ok {
return errors.New("Unknown scheme manager")
}
......
......@@ -111,7 +111,7 @@ type issuanceState struct {
}
// AttributeList returns the list of attributes from this credential request.
func (cr *CredentialRequest) AttributeList() (*AttributeList, error) {
func (cr *CredentialRequest) AttributeList(store *ConfigurationStore) (*AttributeList, error) {
meta := NewMetadataAttribute()
meta.setKeyCounter(cr.KeyCounter)
meta.setCredentialTypeIdentifier(cr.Credential.String())
......@@ -122,7 +122,7 @@ func (cr *CredentialRequest) AttributeList() (*AttributeList, error) {
}
attrs := make([]*big.Int, len(cr.Attributes)+1, len(cr.Attributes)+1)
credtype := MetaStore.Credentials[*cr.Credential]
credtype := store.Credentials[*cr.Credential]
if credtype == nil {
return nil, errors.New("Unknown credential type")
}
......@@ -139,7 +139,7 @@ func (cr *CredentialRequest) AttributeList() (*AttributeList, error) {
}
}
return NewAttributeListFromInts(attrs)
return NewAttributeListFromInts(attrs, store), nil
}
func newIssuanceState() (*issuanceState, error) {
......@@ -154,9 +154,9 @@ func newIssuanceState() (*issuanceState, error) {
}
// Distributed indicates if a keyshare is involved in this session.
func (ir *IssuanceRequest) Distributed() bool {
func (ir *IssuanceRequest) Distributed(store *ConfigurationStore) bool {
for _, manager := range ir.SchemeManagers() {
if MetaStore.SchemeManagers[manager].Distributed() {
if store.SchemeManagers[manager].Distributed() {
return true
}
}
......@@ -193,9 +193,9 @@ func (ir *IssuanceRequest) GetNonce() *big.Int { return ir.Nonce }
func (ir *IssuanceRequest) SetNonce(nonce *big.Int) { ir.Nonce = nonce }
// Distributed indicates if a keyshare is involved in this session.
func (dr *DisclosureRequest) Distributed() bool {
func (dr *DisclosureRequest) Distributed(store *ConfigurationStore) bool {
for _, manager := range dr.SchemeManagers() {
if MetaStore.SchemeManagers[manager].Distributed() {
if store.SchemeManagers[manager].Distributed() {
return true
}
}
......
......@@ -190,7 +190,7 @@ func (session *session) do(proceed bool) {
}
session.Handler.StatusUpdate(session.Action, StatusCommunicating)
if !session.irmaSession.Distributed() {
if !session.irmaSession.Distributed(session.credManager.Store) {
var message interface{}
var err error
switch session.Action {
......
......@@ -51,8 +51,8 @@ func NewCredentialManager(
keyshareServers: make(map[SchemeManagerIdentifier]*keyshareServer),
}
cm.store = newConfigurationStore()
if err = cm.store.ParseFolder(irmaConfigurationPath); err != nil {
cm.Store = newConfigurationStore()
if err = cm.Store.ParseFolder(irmaConfigurationPath); err != nil {
return nil, err
}
......@@ -155,7 +155,7 @@ func (cm *CredentialManager) ParseAndroidStorage() (err error) {
if oldcred.SharedPoints != nil && len(oldcred.SharedPoints) > 0 {
gabicred.Signature.KeyshareP = oldcred.SharedPoints[0]
}
cred := newCredential(gabicred)
cred := newCredential(gabicred, cm.Store)
if cred.CredentialType() == nil {
return errors.New("cannot add unknown credential type")
}
......@@ -361,6 +361,12 @@ func (cm *CredentialManager) loadAttributes() (list map[CredentialTypeIdentifier
return nil, err
}
for _, attrlistlist := range list {
for _, attrlist := range attrlistlist {
attrlist.MetadataAttribute.store = cm.Store
}
}
return list, nil
}
......
......@@ -12,9 +12,6 @@ import (
"github.com/mhe/gabi"
)
// MetaStore is the global instance of ConfigurationStore
var MetaStore = newConfigurationStore()
// ConfigurationStore keeps track of scheme managers, issuers, credential types and public keys.
// Use the global MetaStore instance.
type ConfigurationStore struct {
......
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