Commit 12301e6b authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Renaming, 2: Moving Client to new irmaclient subpackage

parent a2f3c61d
......@@ -40,7 +40,7 @@ type metadataField struct {
type MetadataAttribute struct {
Int *big.Int
pk *gabi.PublicKey
store *ConfigurationStore
Store *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.store)
al.info = NewCredentialInfo(al.Ints, al.Store)
}
return al.info
}
func (al *AttributeList) hash() string {
func (al *AttributeList) Hash() 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) untranslatedAttribute(identifier AttributeTypeIdentifier) string {
func (al *AttributeList) UntranslatedAttribute(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, store: store}
return &MetadataAttribute{Int: i, Store: 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.store.PublicKey(attr.CredentialType().IssuerIdentifier(), attr.KeyCounter())
attr.pk, err = attr.Store.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.store.hashToCredentialType(attr.field(credentialID))
return attr.Store.hashToCredentialType(attr.field(credentialID))
}
func (attr *MetadataAttribute) setCredentialTypeIdentifier(id string) {
......
......@@ -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 = ensureDirectoryExists(store.path); err != nil {
if err = fs.EnsureDirectoryExists(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 := ensureDirectoryExists(store.path); err != nil {
if err := fs.EnsureDirectoryExists(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 := ensureDirectoryExists(store.path + subpath); err != nil {
if err := fs.EnsureDirectoryExists(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 := saveFile(store.path+subpath, bytes); err != nil {
if err := fs.SaveFile(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 := ensureDirectoryExists(fmt.Sprintf("%s/%s", store.path, name)); err != nil {
if err := fs.EnsureDirectoryExists(fmt.Sprintf("%s/%s", store.path, name)); err != nil {
return err
}
b, err := xml.Marshal(manager)
if err != nil {
return err
}
if err := saveFile(fmt.Sprintf("%s/%s/description.xml", store.path, name), b); err != nil {
if err := fs.SaveFile(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 := ensureDirectoryExists(local); err != nil {
if err := fs.EnsureDirectoryExists(local); err != nil {
return nil, err
}
if transport.GetFile(
......
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
}
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)
}
package irmago
package irmaclient
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.hash() == cred.AttributeList().hash() {
if attrs.Hash() == cred.AttributeList().Hash() {
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.hash() == hash {
if attrs.Hash() == 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.hash() == id.Hash {
if attrs.Hash() == 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.hash()}
id := &irmago.AttributeIdentifier{Type: attribute, Hash: attrs.Hash()}
if attribute.IsCredential() {
candidates = append(candidates, id)
} else {
val := attrs.untranslatedAttribute(attribute)
val := attrs.UntranslatedAttribute(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
}
request.state = state
client.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.choice)
disclosures, err := client.ProofBuilders(request.Choice)
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: request.state.nonce2}, nil
return &gabi.IssueCommitmentMessage{Proofs: list, Nonce2: client.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(request.state.builders) {
func (client *Client) ConstructCredentials(msg []*gabi.IssueSignatureMessage, request *irmago.IssuanceRequest) error {
if len(msg) != len(client.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
}