credential.go 2.64 KB
Newer Older
1
2
package irmago

Sietse Ringers's avatar
Sietse Ringers committed
3
4
5
import (
	"strings"

6
7
	"math/big"

Sietse Ringers's avatar
Sietse Ringers committed
8
9
	"github.com/mhe/gabi"
)
10

Sietse Ringers's avatar
Sietse Ringers committed
11
// credential represents an IRMA credential, whose zeroth attribute
12
// is always the secret key and the first attribute the metadata attribute.
Sietse Ringers's avatar
Sietse Ringers committed
13
type credential struct {
14
15
	*gabi.Credential
	*MetadataAttribute
Sietse Ringers's avatar
Sietse Ringers committed
16
17
}

18
19
// CredentialInfo contains all information of an IRMA credential.
type CredentialInfo struct {
Sietse Ringers's avatar
Sietse Ringers committed
20
21
22
	ID            string             // e.g., "irma-demo.RU.studentCard"
	SignedOn      Timestamp          // Unix timestamp
	Expires       Timestamp          // Unix timestamp
23
24
25
	Type          *CredentialType    // Credential information from ConfigurationStore
	Issuer        *Issuer            // Issuer information from ConfigurationStore
	SchemeManager *SchemeManager     // Scheme manager information from ConfigurationStore
Sietse Ringers's avatar
Sietse Ringers committed
26
27
	Attributes    []TranslatedString // Human-readable rendered attributes
	Logo          string             // Path to logo on storage
28
29
}

30
31
// A CredentialInfoList is a list of credentials (implements sort.Interface).
type CredentialInfoList []*CredentialInfo
Sietse Ringers's avatar
Sietse Ringers committed
32

33
34
func NewCredentialInfo(ints []*big.Int, store *ConfigurationStore) *CredentialInfo {
	meta := MetadataFromInt(ints[0], store)
35
36
37
38
39
40
41
42
43
	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})
	}

44
	return &CredentialInfo{
45
46
47
48
		ID:            credtype.Identifier().String(),
		SignedOn:      Timestamp(meta.SigningDate()),
		Expires:       Timestamp(meta.Expiry()),
		Type:          credtype,
49
50
		Issuer:        store.Issuers[issid],
		SchemeManager: store.SchemeManagers[issid.SchemeManagerIdentifier()],
51
52
53
54
55
		Attributes:    attrs,
		Logo:          "", // TODO
	}
}

56
func newCredential(gabicred *gabi.Credential, store *ConfigurationStore) (*credential, error) {
57
	meta := MetadataFromInt(gabicred.Attributes[1], store)
58
	cred := &credential{
Sietse Ringers's avatar
Sietse Ringers committed
59
60
61
		Credential:        gabicred,
		MetadataAttribute: meta,
	}
62
63
64
65
66
67
	var err error
	cred.Pk, err = store.PublicKey(meta.CredentialType().IssuerIdentifier(), cred.KeyCounter())
	if err != nil {
		return nil, err
	}
	return cred, nil
68
}
Sietse Ringers's avatar
Sietse Ringers committed
69
70

// Len implements sort.Interface.
71
func (cl CredentialInfoList) Len() int {
Sietse Ringers's avatar
Sietse Ringers committed
72
73
74
75
	return len(cl)
}

// Swap implements sort.Interface.
76
func (cl CredentialInfoList) Swap(i, j int) {
Sietse Ringers's avatar
Sietse Ringers committed
77
78
79
80
	cl[i], cl[j] = cl[j], cl[i]
}

// Less implements sort.Interface.
81
func (cl CredentialInfoList) Less(i, j int) bool {
Sietse Ringers's avatar
Sietse Ringers committed
82
83
84
	// TODO Decide on sorting, and if it depends on a TranslatedString, allow language choosing
	return strings.Compare(cl[i].Type.Name["en"], cl[j].Type.Name["en"]) > 0
}