Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
IRMA
Github mirrors
irmago
Commits
12301e6b
Commit
12301e6b
authored
Oct 24, 2017
by
Sietse Ringers
Browse files
Renaming, 2: Moving Client to new irmaclient subpackage
parent
a2f3c61d
Changes
17
Hide whitespace changes
Inline
Side-by-side
attributes.go
View file @
12301e6b
...
...
@@ -40,7 +40,7 @@ type metadataField struct {
type
MetadataAttribute
struct
{
Int
*
big
.
Int
pk
*
gabi
.
PublicKey
s
tore
*
ConfigurationStore
S
tore
*
ConfigurationStore
}
// AttributeList contains attributes, excluding the secret key,
...
...
@@ -63,12 +63,12 @@ func NewAttributeListFromInts(ints []*big.Int, store *ConfigurationStore) *Attri
func
(
al
*
AttributeList
)
Info
()
*
CredentialInfo
{
if
al
.
info
==
nil
{
al
.
info
=
NewCredentialInfo
(
al
.
Ints
,
al
.
s
tore
)
al
.
info
=
NewCredentialInfo
(
al
.
Ints
,
al
.
S
tore
)
}
return
al
.
info
}
func
(
al
*
AttributeList
)
h
ash
()
string
{
func
(
al
*
AttributeList
)
H
ash
()
string
{
if
al
.
h
==
""
{
bytes
:=
[]
byte
{}
for
_
,
i
:=
range
al
.
Ints
{
...
...
@@ -91,7 +91,7 @@ func (al *AttributeList) Strings() []TranslatedString {
return
al
.
strings
}
func
(
al
*
AttributeList
)
u
ntranslatedAttribute
(
identifier
AttributeTypeIdentifier
)
string
{
func
(
al
*
AttributeList
)
U
ntranslatedAttribute
(
identifier
AttributeTypeIdentifier
)
string
{
if
al
.
CredentialType
()
.
Identifier
()
!=
identifier
.
CredentialTypeIdentifier
()
{
return
""
}
...
...
@@ -118,7 +118,7 @@ func (al *AttributeList) Attribute(identifier AttributeTypeIdentifier) Translate
// MetadataFromInt wraps the given Int
func
MetadataFromInt
(
i
*
big
.
Int
,
store
*
ConfigurationStore
)
*
MetadataAttribute
{
return
&
MetadataAttribute
{
Int
:
i
,
s
tore
:
store
}
return
&
MetadataAttribute
{
Int
:
i
,
S
tore
:
store
}
}
// NewMetadataAttribute constructs a new instance containing the default values:
...
...
@@ -149,7 +149,7 @@ func (attr *MetadataAttribute) Bytes() []byte {
func
(
attr
*
MetadataAttribute
)
PublicKey
()
(
*
gabi
.
PublicKey
,
error
)
{
if
attr
.
pk
==
nil
{
var
err
error
attr
.
pk
,
err
=
attr
.
s
tore
.
PublicKey
(
attr
.
CredentialType
()
.
IssuerIdentifier
(),
attr
.
KeyCounter
())
attr
.
pk
,
err
=
attr
.
S
tore
.
PublicKey
(
attr
.
CredentialType
()
.
IssuerIdentifier
(),
attr
.
KeyCounter
())
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -206,7 +206,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
attr
.
s
tore
.
hashToCredentialType
(
attr
.
field
(
credentialID
))
return
attr
.
S
tore
.
hashToCredentialType
(
attr
.
field
(
credentialID
))
}
func
(
attr
*
MetadataAttribute
)
setCredentialTypeIdentifier
(
id
string
)
{
...
...
configstore.go
View file @
12301e6b
...
...
@@ -14,6 +14,7 @@ import (
"strings"
"github.com/credentials/irmago/internal/fs"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
)
...
...
@@ -38,7 +39,7 @@ func NewConfigurationStore(path string, assets string) (store *ConfigurationStor
path
:
path
,
}
if
err
=
e
nsureDirectoryExists
(
store
.
path
);
err
!=
nil
{
if
err
=
fs
.
E
nsureDirectoryExists
(
store
.
path
);
err
!=
nil
{
return
nil
,
err
}
if
assets
!=
""
{
...
...
@@ -226,7 +227,7 @@ func (store *ConfigurationStore) Contains(cred CredentialTypeIdentifier) bool {
}
func
(
store
*
ConfigurationStore
)
Copy
(
source
string
,
parse
bool
)
error
{
if
err
:=
e
nsureDirectoryExists
(
store
.
path
);
err
!=
nil
{
if
err
:=
fs
.
E
nsureDirectoryExists
(
store
.
path
);
err
!=
nil
{
return
err
}
...
...
@@ -237,7 +238,7 @@ func (store *ConfigurationStore) Copy(source string, parse bool) error {
}
subpath
:=
path
[
len
(
source
)
:
]
if
info
.
IsDir
()
{
if
err
:=
e
nsureDirectoryExists
(
store
.
path
+
subpath
);
err
!=
nil
{
if
err
:=
fs
.
E
nsureDirectoryExists
(
store
.
path
+
subpath
);
err
!=
nil
{
return
err
}
}
else
{
...
...
@@ -250,7 +251,7 @@ func (store *ConfigurationStore) Copy(source string, parse bool) error {
if
err
!=
nil
{
return
err
}
if
err
:=
s
aveFile
(
store
.
path
+
subpath
,
bytes
);
err
!=
nil
{
if
err
:=
fs
.
S
aveFile
(
store
.
path
+
subpath
,
bytes
);
err
!=
nil
{
return
err
}
}
...
...
@@ -314,14 +315,14 @@ func (store *ConfigurationStore) RemoveSchemeManager(id SchemeManagerIdentifier)
func
(
store
*
ConfigurationStore
)
AddSchemeManager
(
manager
*
SchemeManager
)
error
{
name
:=
manager
.
ID
if
err
:=
e
nsureDirectoryExists
(
fmt
.
Sprintf
(
"%s/%s"
,
store
.
path
,
name
));
err
!=
nil
{
if
err
:=
fs
.
E
nsureDirectoryExists
(
fmt
.
Sprintf
(
"%s/%s"
,
store
.
path
,
name
));
err
!=
nil
{
return
err
}
b
,
err
:=
xml
.
Marshal
(
manager
)
if
err
!=
nil
{
return
err
}
if
err
:=
s
aveFile
(
fmt
.
Sprintf
(
"%s/%s/description.xml"
,
store
.
path
,
name
),
b
);
err
!=
nil
{
if
err
:=
fs
.
S
aveFile
(
fmt
.
Sprintf
(
"%s/%s/description.xml"
,
store
.
path
,
name
),
b
);
err
!=
nil
{
return
err
}
store
.
SchemeManagers
[
NewSchemeManagerIdentifier
(
name
)]
=
manager
...
...
@@ -378,7 +379,7 @@ func (store *ConfigurationStore) Download(set *IrmaIdentifierSet) (*IrmaIdentifi
issuer
:=
credid
.
IssuerIdentifier
()
manager
:=
issuer
.
SchemeManagerIdentifier
()
local
:=
fmt
.
Sprintf
(
"%s/%s/%s/Issues"
,
store
.
path
,
manager
.
Name
(),
issuer
.
Name
())
if
err
:=
e
nsureDirectoryExists
(
local
);
err
!=
nil
{
if
err
:=
fs
.
E
nsureDirectoryExists
(
local
);
err
!=
nil
{
return
nil
,
err
}
if
transport
.
GetFile
(
...
...
cred
ential
.go
→
cred
info
.go
View file @
12301e6b
package
irmago
import
(
"strings"
"math/big"
"fmt"
"math/big"
"strings"
"github.com/
mhe/gabi
"
"github.com/
credentials/irmago/internal/fs
"
)
// credential represents an IRMA credential, whose zeroth attribute
// is always the secret key and the first attribute the metadata attribute.
type
credential
struct
{
*
gabi
.
Credential
*
MetadataAttribute
attrs
*
AttributeList
}
// CredentialInfo contains all information of an IRMA credential.
type
CredentialInfo
struct
{
CredentialTypeID
string
// e.g., "irma-demo.RU.studentCard"
...
...
@@ -46,7 +36,7 @@ func NewCredentialInfo(ints []*big.Int, store *ConfigurationStore) *CredentialIn
}
path
:=
fmt
.
Sprintf
(
"%s/%s/%s/Issues/%s/logo.png"
,
store
.
path
,
credtype
.
SchemeManagerID
,
credtype
.
IssuerID
,
credtype
.
ID
)
exists
,
err
:=
PathExists
(
path
)
exists
,
err
:=
fs
.
PathExists
(
path
)
if
err
!=
nil
{
return
nil
}
...
...
@@ -64,29 +54,8 @@ func NewCredentialInfo(ints []*big.Int, store *ConfigurationStore) *CredentialIn
Expires
:
Timestamp
(
meta
.
Expiry
()),
Attributes
:
attrs
,
Logo
:
path
,
Hash
:
NewAttributeListFromInts
(
ints
,
store
)
.
hash
(),
}
}
func
newCredential
(
gabicred
*
gabi
.
Credential
,
store
*
ConfigurationStore
)
(
*
credential
,
error
)
{
meta
:=
MetadataFromInt
(
gabicred
.
Attributes
[
1
],
store
)
cred
:=
&
credential
{
Credential
:
gabicred
,
MetadataAttribute
:
meta
,
}
var
err
error
cred
.
Pk
,
err
=
store
.
PublicKey
(
meta
.
CredentialType
()
.
IssuerIdentifier
(),
cred
.
KeyCounter
())
if
err
!=
nil
{
return
nil
,
err
}
return
cred
,
nil
}
func
(
cred
*
credential
)
AttributeList
()
*
AttributeList
{
if
cred
.
attrs
==
nil
{
cred
.
attrs
=
NewAttributeListFromInts
(
cred
.
Credential
.
Attributes
[
1
:
],
cred
.
MetadataAttribute
.
store
)
Hash
:
NewAttributeListFromInts
(
ints
,
store
)
.
Hash
(),
}
return
cred
.
attrs
}
// Len implements sort.Interface.
...
...
@@ -101,6 +70,6 @@ func (cl CredentialInfoList) Swap(i, j int) {
// Less implements sort.Interface.
func
(
cl
CredentialInfoList
)
Less
(
i
,
j
int
)
bool
{
// TODO Decide on sorting, and if it depends on a TranslatedString, allow language choosing
// TODO Decide on sorting, and if it depends on a
irmago.
TranslatedString, allow language choosing
return
strings
.
Compare
(
cl
[
i
]
.
Name
,
cl
[
j
]
.
Name
)
>
0
}
internal/fs/fs.go
0 → 100644
View file @
12301e6b
package
fs
import
(
"crypto/rand"
"encoding/hex"
"io/ioutil"
"os"
"path"
"github.com/pkg/errors"
)
// AssertPathExists returns nil only if it has been successfully
// verified that the specified path exists.
func
AssertPathExists
(
path
string
)
error
{
exist
,
err
:=
PathExists
(
path
)
if
err
!=
nil
{
return
err
}
if
!
exist
{
return
errors
.
Errorf
(
"Path %s does not exist"
,
path
)
}
return
nil
}
// PathExists checks if the specified path exists.
func
PathExists
(
path
string
)
(
bool
,
error
)
{
_
,
err
:=
os
.
Stat
(
path
)
if
err
==
nil
{
return
true
,
nil
}
if
os
.
IsNotExist
(
err
)
{
return
false
,
nil
}
return
true
,
err
}
func
EnsureDirectoryExists
(
path
string
)
error
{
exists
,
err
:=
PathExists
(
path
)
if
err
!=
nil
{
return
err
}
if
exists
{
return
nil
}
return
os
.
Mkdir
(
path
,
0700
)
}
// Save the filecontents at the specified path atomically:
// - first save the content in a temp file with a random filename in the same dir
// - then rename the temp file to the specified filepath, overwriting the old file
func
SaveFile
(
filepath
string
,
content
[]
byte
)
(
err
error
)
{
dir
:=
path
.
Dir
(
filepath
)
// Read random data for filename and convert to hex
randBytes
:=
make
([]
byte
,
16
)
_
,
err
=
rand
.
Read
(
randBytes
)
if
err
!=
nil
{
return
}
tempfilename
:=
hex
.
EncodeToString
(
randBytes
)
// Create temp file
err
=
ioutil
.
WriteFile
(
dir
+
"/"
+
tempfilename
,
content
,
0600
)
if
err
!=
nil
{
return
}
// Rename, overwriting old file
return
os
.
Rename
(
dir
+
"/"
+
tempfilename
,
filepath
)
}
client.go
→
irmaclient/
client.go
View file @
12301e6b
package
irma
go
package
irma
client
import
(
"crypto/rand"
...
...
@@ -7,6 +7,8 @@ import (
"time"
"github.com/credentials/go-go-gadget-paillier"
"github.com/credentials/irmago"
"github.com/credentials/irmago/internal/fs"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
)
...
...
@@ -35,9 +37,9 @@ import (
type
Client
struct
{
// Stuff we manage on disk
secretkey
*
secretKey
attributes
map
[
CredentialTypeIdentifier
][]
*
AttributeList
credentials
map
[
CredentialTypeIdentifier
]
map
[
int
]
*
credential
keyshareServers
map
[
SchemeManagerIdentifier
]
*
keyshareServer
attributes
map
[
irmago
.
CredentialTypeIdentifier
][]
*
irmago
.
AttributeList
credentials
map
[
irmago
.
CredentialTypeIdentifier
]
map
[
int
]
*
credential
keyshareServers
map
[
irmago
.
SchemeManagerIdentifier
]
*
keyshareServer
paillierKeyCache
*
paillierPrivateKey
logs
[]
*
LogEntry
updates
[]
update
...
...
@@ -46,24 +48,25 @@ type Client struct {
storage
storage
// Other state
ConfigurationStore
*
ConfigurationStore
UnenrolledSchemeManagers
[]
SchemeManagerIdentifier
ConfigurationStore
*
irmago
.
ConfigurationStore
UnenrolledSchemeManagers
[]
irmago
.
SchemeManagerIdentifier
irmaConfigurationPath
string
androidStoragePath
string
handler
ClientHandler
state
*
issuanceState
}
// KeyshareHandler is used for asking the user for his email address and PIN,
// for enrolling at a keyshare server.
type
KeyshareHandler
interface
{
EnrollmentError
(
manager
SchemeManagerIdentifier
,
err
error
)
EnrollmentSuccess
(
manager
SchemeManagerIdentifier
)
EnrollmentError
(
manager
irmago
.
SchemeManagerIdentifier
,
err
error
)
EnrollmentSuccess
(
manager
irmago
.
SchemeManagerIdentifier
)
}
type
ClientHandler
interface
{
KeyshareHandler
UpdateConfigurationStore
(
new
*
IrmaIdentifierSet
)
UpdateConfigurationStore
(
new
*
irmago
.
IrmaIdentifierSet
)
UpdateAttributes
()
}
...
...
@@ -90,23 +93,23 @@ func NewClient(
handler
ClientHandler
,
)
(
*
Client
,
error
)
{
var
err
error
if
err
=
AssertPathExists
(
storagePath
);
err
!=
nil
{
if
err
=
fs
.
AssertPathExists
(
storagePath
);
err
!=
nil
{
return
nil
,
err
}
if
err
=
AssertPathExists
(
irmaConfigurationPath
);
err
!=
nil
{
if
err
=
fs
.
AssertPathExists
(
irmaConfigurationPath
);
err
!=
nil
{
return
nil
,
err
}
cm
:=
&
Client
{
credentials
:
make
(
map
[
CredentialTypeIdentifier
]
map
[
int
]
*
credential
),
keyshareServers
:
make
(
map
[
SchemeManagerIdentifier
]
*
keyshareServer
),
attributes
:
make
(
map
[
CredentialTypeIdentifier
][]
*
AttributeList
),
credentials
:
make
(
map
[
irmago
.
CredentialTypeIdentifier
]
map
[
int
]
*
credential
),
keyshareServers
:
make
(
map
[
irmago
.
SchemeManagerIdentifier
]
*
keyshareServer
),
attributes
:
make
(
map
[
irmago
.
CredentialTypeIdentifier
][]
*
irmago
.
AttributeList
),
irmaConfigurationPath
:
irmaConfigurationPath
,
androidStoragePath
:
androidStoragePath
,
handler
:
handler
,
}
cm
.
ConfigurationStore
,
err
=
NewConfigurationStore
(
storagePath
+
"/irma_configuration"
,
irmaConfigurationPath
)
cm
.
ConfigurationStore
,
err
=
irmago
.
NewConfigurationStore
(
storagePath
+
"/irma_configuration"
,
irmaConfigurationPath
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -151,8 +154,8 @@ func NewClient(
}
// CredentialInfoList returns a list of information of all contained credentials.
func
(
client
*
Client
)
CredentialInfoList
()
CredentialInfoList
{
list
:=
CredentialInfoList
([]
*
CredentialInfo
{})
func
(
client
*
Client
)
CredentialInfoList
()
irmago
.
CredentialInfoList
{
list
:=
irmago
.
CredentialInfoList
([]
*
irmago
.
CredentialInfo
{})
for
_
,
attrlistlist
:=
range
client
.
attributes
{
for
index
,
attrlist
:=
range
attrlistlist
{
...
...
@@ -174,7 +177,7 @@ func (client *Client) addCredential(cred *credential, storeAttributes bool) (err
// Don't add duplicate creds
for
_
,
attrlistlist
:=
range
client
.
attributes
{
for
_
,
attrs
:=
range
attrlistlist
{
if
attrs
.
h
ash
()
==
cred
.
AttributeList
()
.
h
ash
()
{
if
attrs
.
H
ash
()
==
cred
.
AttributeList
()
.
H
ash
()
{
return
nil
}
}
...
...
@@ -212,7 +215,7 @@ func generateSecretKey() (*secretKey, error) {
// Removal methods
func
(
client
*
Client
)
remove
(
id
CredentialTypeIdentifier
,
index
int
,
storenow
bool
)
error
{
func
(
client
*
Client
)
remove
(
id
irmago
.
CredentialTypeIdentifier
,
index
int
,
storenow
bool
)
error
{
// Remove attributes
list
,
exists
:=
client
.
attributes
[
id
]
if
!
exists
||
index
>=
len
(
list
)
{
...
...
@@ -239,20 +242,20 @@ func (client *Client) remove(id CredentialTypeIdentifier, index int, storenow bo
return
err
}
removed
:=
map
[
CredentialTypeIdentifier
][]
TranslatedString
{}
removed
:=
map
[
irmago
.
CredentialTypeIdentifier
][]
irmago
.
TranslatedString
{}
removed
[
id
]
=
attrs
.
Strings
()
if
storenow
{
return
client
.
addLogEntry
(
&
LogEntry
{
Type
:
actionRemoval
,
Time
:
Timestamp
(
time
.
Now
()),
Time
:
irmago
.
Timestamp
(
time
.
Now
()),
Removed
:
removed
,
})
}
return
nil
}
func
(
client
*
Client
)
RemoveCredential
(
id
CredentialTypeIdentifier
,
index
int
)
error
{
func
(
client
*
Client
)
RemoveCredential
(
id
irmago
.
CredentialTypeIdentifier
,
index
int
)
error
{
return
client
.
remove
(
id
,
index
,
true
)
}
...
...
@@ -265,7 +268,7 @@ func (client *Client) RemoveCredentialByHash(hash string) error {
}
func
(
client
*
Client
)
RemoveAllCredentials
()
error
{
removed
:=
map
[
CredentialTypeIdentifier
][]
TranslatedString
{}
removed
:=
map
[
irmago
.
CredentialTypeIdentifier
][]
irmago
.
TranslatedString
{}
for
_
,
attrlistlist
:=
range
client
.
attributes
{
for
_
,
attrs
:=
range
attrlistlist
{
if
attrs
.
CredentialType
()
!=
nil
{
...
...
@@ -274,14 +277,14 @@ func (client *Client) RemoveAllCredentials() error {
client
.
storage
.
DeleteSignature
(
attrs
)
}
}
client
.
attributes
=
map
[
CredentialTypeIdentifier
][]
*
AttributeList
{}
client
.
attributes
=
map
[
irmago
.
CredentialTypeIdentifier
][]
*
irmago
.
AttributeList
{}
if
err
:=
client
.
storage
.
StoreAttributes
(
client
.
attributes
);
err
!=
nil
{
return
err
}
logentry
:=
&
LogEntry
{
Type
:
actionRemoval
,
Time
:
Timestamp
(
time
.
Now
()),
Time
:
irmago
.
Timestamp
(
time
.
Now
()),
Removed
:
removed
,
}
if
err
:=
client
.
addLogEntry
(
logentry
);
err
!=
nil
{
...
...
@@ -293,17 +296,17 @@ func (client *Client) RemoveAllCredentials() error {
// Attribute and credential getter methods
// attrs returns cm.attributes[id], initializing it to an empty slice if neccesary
func
(
client
*
Client
)
attrs
(
id
CredentialTypeIdentifier
)
[]
*
AttributeList
{
func
(
client
*
Client
)
attrs
(
id
irmago
.
CredentialTypeIdentifier
)
[]
*
irmago
.
AttributeList
{
list
,
exists
:=
client
.
attributes
[
id
]
if
!
exists
{
list
=
make
([]
*
AttributeList
,
0
,
1
)
list
=
make
([]
*
irmago
.
AttributeList
,
0
,
1
)
client
.
attributes
[
id
]
=
list
}
return
list
}
// creds returns cm.credentials[id], initializing it to an empty map if neccesary
func
(
client
*
Client
)
creds
(
id
CredentialTypeIdentifier
)
map
[
int
]
*
credential
{
func
(
client
*
Client
)
creds
(
id
irmago
.
CredentialTypeIdentifier
)
map
[
int
]
*
credential
{
list
,
exists
:=
client
.
credentials
[
id
]
if
!
exists
{
list
=
make
(
map
[
int
]
*
credential
)
...
...
@@ -313,7 +316,7 @@ func (client *Client) creds(id CredentialTypeIdentifier) map[int]*credential {
}
// Attributes returns the attribute list of the requested credential, or nil if we do not have it.
func
(
client
*
Client
)
Attributes
(
id
CredentialTypeIdentifier
,
counter
int
)
(
attributes
*
AttributeList
)
{
func
(
client
*
Client
)
Attributes
(
id
irmago
.
CredentialTypeIdentifier
,
counter
int
)
(
attributes
*
irmago
.
AttributeList
)
{
list
:=
client
.
attrs
(
id
)
if
len
(
list
)
<=
counter
{
return
...
...
@@ -324,7 +327,7 @@ func (client *Client) Attributes(id CredentialTypeIdentifier, counter int) (attr
func
(
client
*
Client
)
credentialByHash
(
hash
string
)
(
*
credential
,
int
,
error
)
{
for
_
,
attrlistlist
:=
range
client
.
attributes
{
for
index
,
attrs
:=
range
attrlistlist
{
if
attrs
.
h
ash
()
==
hash
{
if
attrs
.
H
ash
()
==
hash
{
cred
,
err
:=
client
.
credential
(
attrs
.
CredentialType
()
.
Identifier
(),
index
)
return
cred
,
index
,
err
}
...
...
@@ -333,12 +336,12 @@ func (client *Client) credentialByHash(hash string) (*credential, int, error) {
return
nil
,
0
,
nil
}
func
(
client
*
Client
)
credentialByID
(
id
CredentialIdentifier
)
(
*
credential
,
error
)
{
func
(
client
*
Client
)
credentialByID
(
id
irmago
.
CredentialIdentifier
)
(
*
credential
,
error
)
{
if
_
,
exists
:=
client
.
attributes
[
id
.
Type
];
!
exists
{
return
nil
,
nil
}
for
index
,
attrs
:=
range
client
.
attributes
[
id
.
Type
]
{
if
attrs
.
h
ash
()
==
id
.
Hash
{
if
attrs
.
H
ash
()
==
id
.
Hash
{
return
client
.
credential
(
attrs
.
CredentialType
()
.
Identifier
(),
index
)
}
}
...
...
@@ -346,7 +349,7 @@ func (client *Client) credentialByID(id CredentialIdentifier) (*credential, erro
}
// credential returns the requested credential, or nil if we do not have it.
func
(
client
*
Client
)
credential
(
id
CredentialTypeIdentifier
,
counter
int
)
(
cred
*
credential
,
err
error
)
{
func
(
client
*
Client
)
credential
(
id
irmago
.
CredentialTypeIdentifier
,
counter
int
)
(
cred
*
credential
,
err
error
)
{
// If the requested credential is not in credential map, we check if its attributes were
// deserialized during NewClient(). If so, there should be a corresponding signature file,
// so we read that, construct the credential, and add it to the credential map
...
...
@@ -388,8 +391,8 @@ func (client *Client) credential(id CredentialTypeIdentifier, counter int) (cred
// Candidates returns a list of attributes present in this client
// that satisfy the specified attribute disjunction.
func
(
client
*
Client
)
Candidates
(
disjunction
*
AttributeDisjunction
)
[]
*
AttributeIdentifier
{
candidates
:=
make
([]
*
AttributeIdentifier
,
0
,
10
)
func
(
client
*
Client
)
Candidates
(
disjunction
*
irmago
.
AttributeDisjunction
)
[]
*
irmago
.
AttributeIdentifier
{
candidates
:=
make
([]
*
irmago
.
AttributeIdentifier
,
0
,
10
)
for
_
,
attribute
:=
range
disjunction
.
Attributes
{
credID
:=
attribute
.
CredentialTypeIdentifier
()
...
...
@@ -402,11 +405,11 @@ func (client *Client) Candidates(disjunction *AttributeDisjunction) []*Attribute
continue
}
for
_
,
attrs
:=
range
creds
{
id
:=
&
AttributeIdentifier
{
Type
:
attribute
,
Hash
:
attrs
.
h
ash
()}
id
:=
&
irmago
.
AttributeIdentifier
{
Type
:
attribute
,
Hash
:
attrs
.
H
ash
()}
if
attribute
.
IsCredential
()
{
candidates
=
append
(
candidates
,
id
)
}
else
{
val
:=
attrs
.
u
ntranslatedAttribute
(
attribute
)
val
:=
attrs
.
U
ntranslatedAttribute
(
attribute
)
if
val
==
""
{
// This won't handle empty attributes correctly
continue
}
...
...
@@ -424,12 +427,12 @@ func (client *Client) Candidates(disjunction *AttributeDisjunction) []*Attribute
// to satisfy the specifed disjunction list. If not, the unsatisfiable disjunctions
// are returned.
func
(
client
*
Client
)
CheckSatisfiability
(
disjunctions
AttributeDisjunctionList
,
)
([][]
*
AttributeIdentifier
,
AttributeDisjunctionList
)
{
candidates
:=
[][]
*
AttributeIdentifier
{}
missing
:=
AttributeDisjunctionList
{}
disjunctions
irmago
.
AttributeDisjunctionList
,
)
([][]
*
irmago
.
AttributeIdentifier
,
irmago
.
AttributeDisjunctionList
)
{
candidates
:=
[][]
*
irmago
.
AttributeIdentifier
{}
missing
:=
irmago
.
AttributeDisjunctionList
{}
for
i
,
disjunction
:=
range
disjunctions
{
candidates
=
append
(
candidates
,
[]
*
AttributeIdentifier
{})
candidates
=
append
(
candidates
,
[]
*
irmago
.
AttributeIdentifier
{})
candidates
[
i
]
=
client
.
Candidates
(
disjunction
)
if
len
(
candidates
[
i
])
==
0
{
missing
=
append
(
missing
,
disjunction
)
...
...
@@ -438,8 +441,8 @@ func (client *Client) CheckSatisfiability(
return
candidates
,
missing
}
func
(
client
*
Client
)
groupCredentials
(
choice
*
DisclosureChoice
)
(
map
[
CredentialIdentifier
][]
int
,
error
)
{
grouped
:=
make
(
map
[
CredentialIdentifier
][]
int
)
func
(
client
*
Client
)
groupCredentials
(
choice
*
irmago
.
DisclosureChoice
)
(
map
[
irmago
.
CredentialIdentifier
][]
int
,
error
)
{
grouped
:=
make
(
map
[
irmago
.
CredentialIdentifier
][]
int
)
if
choice
==
nil
||
choice
.
Attributes
==
nil
{
return
grouped
,
nil
}
...
...
@@ -473,7 +476,7 @@ func (client *Client) groupCredentials(choice *DisclosureChoice) (map[Credential
}
// ProofBuilders constructs a list of proof builders for the specified attribute choice.
func
(
client
*
Client
)
ProofBuilders
(
choice
*
DisclosureChoice
)
(
gabi
.
ProofBuilderList
,
error
)
{
func
(
client
*
Client
)
ProofBuilders
(
choice
*
irmago
.
DisclosureChoice
)
(
gabi
.
ProofBuilderList
,
error
)
{
todisclose
,
err
:=
client
.
groupCredentials
(
choice
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -491,7 +494,7 @@ func (client *Client) ProofBuilders(choice *DisclosureChoice) (gabi.ProofBuilder
}
// Proofs computes disclosure proofs containing the attributes specified by choice.
func
(
client
*
Client
)
Proofs
(
choice
*
DisclosureChoice
,
request
IrmaSession
,
issig
bool
)
(
gabi
.
ProofList
,
error
)
{
func
(
client
*
Client
)
Proofs
(
choice
*
irmago
.
DisclosureChoice
,
request
irmago
.
IrmaSession
,
issig
bool
)
(
gabi
.
ProofList
,
error
)
{
builders
,
err
:=
client
.
ProofBuilders
(
choice
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -501,12 +504,12 @@ func (client *Client) Proofs(choice *DisclosureChoice, request IrmaSession, issi
// IssuanceProofBuilders constructs a list of proof builders in the issuance protocol
// for the future credentials as well as possibly any disclosed attributes.
func
(
client
*
Client
)
IssuanceProofBuilders
(
request
*
IssuanceRequest
)
(
gabi
.
ProofBuilderList
,
error
)
{
func
(
client
*
Client
)
IssuanceProofBuilders
(
request
*
irmago
.
IssuanceRequest
)
(
gabi
.
ProofBuilderList
,
error
)
{
state
,
err
:=
newIssuanceState
()
if
err
!=
nil
{
return
nil
,
err
}
reques
t
.
state
=
state
clien
t
.
state
=
state
proofBuilders
:=
gabi
.
ProofBuilderList
([]
gabi
.
ProofBuilder
{})
for
_
,
futurecred
:=
range
request
.
Credentials
{
...
...
@@ -517,11 +520,11 @@ func (client *Client) IssuanceProofBuilders(request *IssuanceRequest) (gabi.Proo
}
credBuilder
:=
gabi
.
NewCredentialBuilder
(
pk
,
request
.
GetContext
(),
client
.
secretkey
.
Key
,
state
.
nonce2
)
request
.
state
.
builders
=
append
(
request
.
state
.
builders
,
credBuilder
)
state
.
builders
=
append
(
state
.
builders
,
credBuilder
)
proofBuilders
=
append
(
proofBuilders
,
credBuilder
)
}
disclosures
,
err
:=
client
.
ProofBuilders
(
request
.
c
hoice
)
disclosures
,
err
:=
client
.
ProofBuilders
(
request
.
C
hoice
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -531,19 +534,19 @@ func (client *Client) IssuanceProofBuilders(request *IssuanceRequest) (gabi.Proo
// IssueCommitments computes issuance commitments, along with disclosure proofs
// specified by choice.
func
(
client
*
Client
)
IssueCommitments
(
request
*
IssuanceRequest
)
(
*
gabi
.
IssueCommitmentMessage
,
error
)
{
func
(
client
*
Client
)
IssueCommitments
(
request
*
irmago
.
IssuanceRequest
)
(
*
gabi
.
IssueCommitmentMessage
,
error
)
{
proofBuilders
,
err
:=
client
.
IssuanceProofBuilders
(
request
)
if
err
!=
nil
{
return
nil
,
err
}
list
:=
proofBuilders
.
BuildProofList
(
request
.
GetContext
(),
request
.
GetNonce
(),
false
)
return
&
gabi
.
IssueCommitmentMessage
{
Proofs
:
list
,
Nonce2
:
reques
t
.
state
.
nonce2
},
nil
return
&
gabi
.
IssueCommitmentMessage
{
Proofs
:
list
,
Nonce2
:
clien
t
.
state
.
nonce2
},
nil
}
// ConstructCredentials constructs and saves new credentials
// using the specified issuance signature messages.
func
(
client
*
Client
)
ConstructCredentials
(
msg
[]
*
gabi
.
IssueSignatureMessage
,
request
*
IssuanceRequest
)
error
{
if
len
(
msg
)
!=
len
(
reques
t
.
state
.
builders
)
{
func
(
client
*
Client
)
ConstructCredentials
(
msg
[]
*
gabi
.
IssueSignatureMessage
,
request
*
irmago
.
IssuanceRequest
)
error
{
if
len
(
msg
)
!=
len
(
clien
t
.
state
.
builders
)
{
return
errors
.
New
(
"Received unexpected amount of signatures"
)
}
...
...
@@ -555,7 +558,7 @@ func (client *Client) ConstructCredentials(msg []*gabi.IssueSignatureMessage, re
if
err
!=
nil
{
return
err
}
cred
,
err
:=
reques
t
.
state
.
builders
[
i
]
.
ConstructCredential
(
sig
,
attrs
.
Ints
)