identifiers.go 6.3 KB
Newer Older
1
package irma
2

3
import "strings"
4

Sietse Ringers's avatar
Sietse Ringers committed
5
type metaObjectIdentifier string
6
7
8

// SchemeManagerIdentifier identifies a scheme manager. Equal to its ID. For example "irma-demo".
type SchemeManagerIdentifier struct {
Sietse Ringers's avatar
Sietse Ringers committed
9
	metaObjectIdentifier
10
11
}

Sietse Ringers's avatar
Sietse Ringers committed
12
// IssuerIdentifier identifies an issuer. For example "irma-demo.RU".
13
type IssuerIdentifier struct {
Sietse Ringers's avatar
Sietse Ringers committed
14
	metaObjectIdentifier
15
16
}

17
18
// CredentialTypeIdentifier identifies a credentialtype. For example "irma-demo.RU.studentCard".
type CredentialTypeIdentifier struct {
Sietse Ringers's avatar
Sietse Ringers committed
19
	metaObjectIdentifier
20
21
}

22
23
// AttributeTypeIdentifier identifies an attribute. For example "irma-demo.RU.studentCard.studentID".
type AttributeTypeIdentifier struct {
Sietse Ringers's avatar
Sietse Ringers committed
24
	metaObjectIdentifier
25
26
}

Sietse Ringers's avatar
Sietse Ringers committed
27
// CredentialIdentifier identifies a credential instance.
28
type CredentialIdentifier struct {
29
30
	Type CredentialTypeIdentifier
	Hash string
31
32
}

Sietse Ringers's avatar
Sietse Ringers committed
33
// AttributeIdentifier identifies an attribute instance.
34
type AttributeIdentifier struct {
35
36
	Type           AttributeTypeIdentifier
	CredentialHash string
37
38
}

39
40
41
42
43
44
45
46
47
// IrmaIdentifierSet contains a set (ensured by using map[...]struct{}) of all scheme managers,
// all issuers, all credential types and all public keys that are involved in an IRMA session.
type IrmaIdentifierSet struct {
	SchemeManagers  map[SchemeManagerIdentifier]struct{}
	Issuers         map[IssuerIdentifier]struct{}
	CredentialTypes map[CredentialTypeIdentifier]struct{}
	PublicKeys      map[IssuerIdentifier][]int
}

Sietse Ringers's avatar
Sietse Ringers committed
48
// Parent returns the parent object of this identifier.
Sietse Ringers's avatar
Sietse Ringers committed
49
func (oi metaObjectIdentifier) Parent() string {
50
	str := string(oi)
Sietse Ringers's avatar
Sietse Ringers committed
51
52
53
54
55
	if i := strings.LastIndex(str, "."); i != -1 {
		return str[:i]
	} else {
		return str
	}
56
57
}

Sietse Ringers's avatar
Sietse Ringers committed
58
// Name returns the last part of this identifier.
Sietse Ringers's avatar
Sietse Ringers committed
59
func (oi metaObjectIdentifier) Name() string {
60
	str := string(oi)
Sietse Ringers's avatar
Sietse Ringers committed
61
	return str[strings.LastIndex(str, ".")+1:]
62
63
}

Sietse Ringers's avatar
Sietse Ringers committed
64
// String returns this identifier as a string.
Sietse Ringers's avatar
Sietse Ringers committed
65
func (oi metaObjectIdentifier) String() string {
66
67
68
	return string(oi)
}

69
70
71
72
func (oi metaObjectIdentifier) Empty() bool {
	return len(oi) == 0
}

Sietse Ringers's avatar
Sietse Ringers committed
73
74
75
76
77
78
79
80
81
func (oi metaObjectIdentifier) Root() string {
	str := string(oi)
	if i := strings.Index(str, "."); i != -1 {
		return str[:i]
	} else {
		return str
	}
}

82
83
// NewSchemeManagerIdentifier converts the specified identifier to a SchemeManagerIdentifier.
func NewSchemeManagerIdentifier(id string) SchemeManagerIdentifier {
Sietse Ringers's avatar
Sietse Ringers committed
84
	return SchemeManagerIdentifier{metaObjectIdentifier(id)}
85
86
87
88
}

// NewIssuerIdentifier converts the specified identifier to a IssuerIdentifier.
func NewIssuerIdentifier(id string) IssuerIdentifier {
Sietse Ringers's avatar
Sietse Ringers committed
89
	return IssuerIdentifier{metaObjectIdentifier(id)}
90
91
}

92
93
// NewCredentialTypeIdentifier converts the specified identifier to a CredentialTypeIdentifier.
func NewCredentialTypeIdentifier(id string) CredentialTypeIdentifier {
Sietse Ringers's avatar
Sietse Ringers committed
94
	return CredentialTypeIdentifier{metaObjectIdentifier(id)}
95
96
}

97
98
// NewAttributeTypeIdentifier converts the specified identifier to a AttributeTypeIdentifier.
func NewAttributeTypeIdentifier(id string) AttributeTypeIdentifier {
Sietse Ringers's avatar
Sietse Ringers committed
99
	return AttributeTypeIdentifier{metaObjectIdentifier(id)}
100
101
102
103
104
105
106
107
}

// SchemeManagerIdentifier returns the scheme manager identifer of the issuer.
func (id IssuerIdentifier) SchemeManagerIdentifier() SchemeManagerIdentifier {
	return NewSchemeManagerIdentifier(id.Parent())
}

// IssuerIdentifier returns the IssuerIdentifier of the credential identifier.
108
func (id CredentialTypeIdentifier) IssuerIdentifier() IssuerIdentifier {
109
110
111
	return NewIssuerIdentifier(id.Parent())
}

112
// CredentialTypeIdentifier returns the CredentialTypeIdentifier of the attribute identifier.
113
func (id AttributeTypeIdentifier) CredentialTypeIdentifier() CredentialTypeIdentifier {
114
115
116
	if id.IsCredential() {
		return NewCredentialTypeIdentifier(id.String())
	}
117
	return NewCredentialTypeIdentifier(id.Parent())
118
}
119

Sietse Ringers's avatar
Sietse Ringers committed
120
121
// IsCredential returns true if this attribute refers to its containing credential
// (i.e., it consists of only 3 parts).
122
123
124
func (id AttributeTypeIdentifier) IsCredential() bool {
	return strings.Count(id.String(), ".") == 2
}
125

Sietse Ringers's avatar
Sietse Ringers committed
126
// CredentialIdentifier returns the credential identifier of this attribute.
127
func (ai *AttributeIdentifier) CredentialIdentifier() CredentialIdentifier {
128
	return CredentialIdentifier{Type: ai.Type.CredentialTypeIdentifier(), Hash: ai.CredentialHash}
129
}
130

131
132
133
// MarshalText implements encoding.TextMarshaler.
func (id SchemeManagerIdentifier) MarshalText() ([]byte, error) {
	return []byte(id.String()), nil
134
135
}

136
137
138
139
140
141
// UnmarshalText implements encoding.TextUnmarshaler.
func (id *SchemeManagerIdentifier) UnmarshalText(text []byte) error {
	*id = NewSchemeManagerIdentifier(string(text))
	return nil
}

Sietse Ringers's avatar
Sietse Ringers committed
142
143
144
145
146
// MarshalText implements encoding.TextMarshaler.
func (id IssuerIdentifier) MarshalText() ([]byte, error) {
	return []byte(id.String()), nil
}

Tomas's avatar
Tomas committed
147
148
149
150
151
// UnmarshalText implements encoding.TextUnmarshaler.
func (id *IssuerIdentifier) UnmarshalText(text []byte) error {
	*id = NewIssuerIdentifier(string(text))
	return nil
}
152

153
154
155
156
157
158
159
160
// MarshalText implements encoding.TextMarshaler.
func (id CredentialTypeIdentifier) MarshalText() ([]byte, error) {
	return []byte(id.String()), nil
}

// UnmarshalText implements encoding.TextUnmarshaler.
func (id *CredentialTypeIdentifier) UnmarshalText(text []byte) error {
	*id = NewCredentialTypeIdentifier(string(text))
161
162
	return nil
}
Sietse Ringers's avatar
Sietse Ringers committed
163

164
165
166
167
168
169
170
171
// MarshalText implements encoding.TextMarshaler.
func (id AttributeTypeIdentifier) MarshalText() ([]byte, error) {
	return []byte(id.String()), nil
}

// UnmarshalText implements encoding.TextUnmarshaler.
func (id *AttributeTypeIdentifier) UnmarshalText(text []byte) error {
	*id = NewAttributeTypeIdentifier(string(text))
Sietse Ringers's avatar
Sietse Ringers committed
172
173
	return nil
}
174

175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
func (set *IrmaIdentifierSet) join(other *IrmaIdentifierSet) {
	for scheme := range other.SchemeManagers {
		set.SchemeManagers[scheme] = struct{}{}
	}
	for issuer := range other.Issuers {
		set.Issuers[issuer] = struct{}{}
	}
	for ct := range other.CredentialTypes {
		set.CredentialTypes[ct] = struct{}{}
	}
	for issuer := range other.PublicKeys {
		if len(set.PublicKeys[issuer]) == 0 {
			set.PublicKeys[issuer] = make([]int, 0, len(other.PublicKeys[issuer]))
		}
		set.PublicKeys[issuer] = append(set.PublicKeys[issuer], other.PublicKeys[issuer]...)
	}
}

193
func (set *IrmaIdentifierSet) Distributed(conf *Configuration) bool {
194
	for id := range set.SchemeManagers {
195
		if conf.SchemeManagers[id].Distributed() {
196
197
198
199
200
			return true
		}
	}
	return false
}
201
202
203
204

func (set *IrmaIdentifierSet) Empty() bool {
	return len(set.SchemeManagers) == 0 && len(set.Issuers) == 0 && len(set.CredentialTypes) == 0 && len(set.PublicKeys) == 0
}