Commit 4d97255d authored by David Venhoek's avatar David Venhoek
Browse files

Merge branch 'master' into david-pinchange

parents b02aa5fd 1b853dc0
// Package irmago is work in progress on an IRMA client in Go. // Package irma contains generic IRMA strucs and logic of use to all IRMA participants.
//It will (de)serialize credentials from/to storage, // It parses irma_configuration folders to scheme managers, issuers, credential types and public keys,
// and be the client (like the IRMA Android app, // it contains various messages from the IRMA protocol, and parses IRMA metadata attributes.
// https://github.com/credentials/irma_android_cardemu) in the IRMA protocol (see
// https://credentials.github.io/protocols/irma-protocol).
package irma package irma
...@@ -111,6 +111,9 @@ func (id CredentialTypeIdentifier) IssuerIdentifier() IssuerIdentifier { ...@@ -111,6 +111,9 @@ func (id CredentialTypeIdentifier) IssuerIdentifier() IssuerIdentifier {
// CredentialTypeIdentifier returns the CredentialTypeIdentifier of the attribute identifier. // CredentialTypeIdentifier returns the CredentialTypeIdentifier of the attribute identifier.
func (id AttributeTypeIdentifier) CredentialTypeIdentifier() CredentialTypeIdentifier { func (id AttributeTypeIdentifier) CredentialTypeIdentifier() CredentialTypeIdentifier {
if id.IsCredential() {
return NewCredentialTypeIdentifier(id.String())
}
return NewCredentialTypeIdentifier(id.Parent()) return NewCredentialTypeIdentifier(id.Parent())
} }
......
...@@ -43,7 +43,7 @@ type Client struct { ...@@ -43,7 +43,7 @@ type Client struct {
// Stuff we manage on disk // Stuff we manage on disk
secretkey *secretKey secretkey *secretKey
attributes map[irma.CredentialTypeIdentifier][]*irma.AttributeList attributes map[irma.CredentialTypeIdentifier][]*irma.AttributeList
credentials map[irma.CredentialTypeIdentifier]map[int]*credential credentialsCache map[irma.CredentialTypeIdentifier]map[int]*credential
keyshareServers map[irma.SchemeManagerIdentifier]*keyshareServer keyshareServers map[irma.SchemeManagerIdentifier]*keyshareServer
paillierKeyCache *paillierPrivateKey paillierKeyCache *paillierPrivateKey
logs []*LogEntry logs []*LogEntry
...@@ -53,12 +53,12 @@ type Client struct { ...@@ -53,12 +53,12 @@ type Client struct {
storage storage storage storage
// Other state // Other state
Preferences Preferences Preferences Preferences
Configuration *irma.Configuration Configuration *irma.Configuration
irmaConfigurationPath string irmaConfigurationPath string
androidStoragePath string androidStoragePath string
handler ClientHandler handler ClientHandler
state *issuanceState state *issuanceState
} }
// SentryDSN should be set in the init() function // SentryDSN should be set in the init() function
...@@ -128,7 +128,7 @@ func New( ...@@ -128,7 +128,7 @@ func New(
} }
cm := &Client{ cm := &Client{
credentials: make(map[irma.CredentialTypeIdentifier]map[int]*credential), credentialsCache: make(map[irma.CredentialTypeIdentifier]map[int]*credential),
keyshareServers: make(map[irma.SchemeManagerIdentifier]*keyshareServer), keyshareServers: make(map[irma.SchemeManagerIdentifier]*keyshareServer),
attributes: make(map[irma.CredentialTypeIdentifier][]*irma.AttributeList), attributes: make(map[irma.CredentialTypeIdentifier][]*irma.AttributeList),
irmaConfigurationPath: irmaConfigurationPath, irmaConfigurationPath: irmaConfigurationPath,
...@@ -226,18 +226,18 @@ func (client *Client) addCredential(cred *credential, storeAttributes bool) (err ...@@ -226,18 +226,18 @@ func (client *Client) addCredential(cred *credential, storeAttributes bool) (err
} }
// If this is a singleton credential type, ensure we have at most one by removing any previous instance // If this is a singleton credential type, ensure we have at most one by removing any previous instance
if !id.Empty() && cred.CredentialType().IsSingleton && len(client.creds(id)) > 0 { if !id.Empty() && cred.CredentialType().IsSingleton && len(client.attrs(id)) > 0 {
client.remove(id, 0, false) // Index is 0, because if we're here we have exactly one client.remove(id, 0, false) // Index is 0, because if we're here we have exactly one
} }
// Append the new cred to our attributes and credentials // Append the new cred to our attributes and credentials
client.attributes[id] = append(client.attrs(id), cred.AttributeList()) client.attributes[id] = append(client.attrs(id), cred.AttributeList())
if !id.Empty() { if !id.Empty() {
if _, exists := client.credentials[id]; !exists { if _, exists := client.credentialsCache[id]; !exists {
client.credentials[id] = make(map[int]*credential) client.credentialsCache[id] = make(map[int]*credential)
} }
counter := len(client.attributes[id]) - 1 counter := len(client.attributes[id]) - 1
client.credentials[id][counter] = cred client.credentialsCache[id][counter] = cred
} }
if err = client.storage.StoreSignature(cred); err != nil { if err = client.storage.StoreSignature(cred); err != nil {
...@@ -274,10 +274,10 @@ func (client *Client) remove(id irma.CredentialTypeIdentifier, index int, storen ...@@ -274,10 +274,10 @@ func (client *Client) remove(id irma.CredentialTypeIdentifier, index int, storen
} }
// Remove credential // Remove credential
if creds, exists := client.credentials[id]; exists { if creds, exists := client.credentialsCache[id]; exists {
if _, exists := creds[index]; exists { if _, exists := creds[index]; exists {
delete(creds, index) delete(creds, index)
client.credentials[id] = creds client.credentialsCache[id] = creds
} }
} }
...@@ -354,10 +354,10 @@ func (client *Client) attrs(id irma.CredentialTypeIdentifier) []*irma.AttributeL ...@@ -354,10 +354,10 @@ func (client *Client) attrs(id irma.CredentialTypeIdentifier) []*irma.AttributeL
// creds returns cm.credentials[id], initializing it to an empty map if neccesary // creds returns cm.credentials[id], initializing it to an empty map if neccesary
func (client *Client) creds(id irma.CredentialTypeIdentifier) map[int]*credential { func (client *Client) creds(id irma.CredentialTypeIdentifier) map[int]*credential {
list, exists := client.credentials[id] list, exists := client.credentialsCache[id]
if !exists { if !exists {
list = make(map[int]*credential) list = make(map[int]*credential)
client.credentials[id] = list client.credentialsCache[id] = list
} }
return list return list
} }
...@@ -428,10 +428,10 @@ func (client *Client) credential(id irma.CredentialTypeIdentifier, counter int) ...@@ -428,10 +428,10 @@ func (client *Client) credential(id irma.CredentialTypeIdentifier, counter int)
if err != nil { if err != nil {
return nil, err return nil, err
} }
client.credentials[id][counter] = cred client.credentialsCache[id][counter] = cred
} }
return client.credentials[id][counter], nil return client.credentialsCache[id][counter], nil
} }
// Methods used in the IRMA protocol // Methods used in the IRMA protocol
...@@ -771,8 +771,8 @@ func (client *Client) keyshareChangePinWorker(managerID irma.SchemeManagerIdenti ...@@ -771,8 +771,8 @@ func (client *Client) keyshareChangePinWorker(managerID irma.SchemeManagerIdenti
transport := irma.NewHTTPTransport(kss.URL) transport := irma.NewHTTPTransport(kss.URL)
message := keyshareChangepin{ message := keyshareChangepin{
Username: kss.Username, Username: kss.Username,
OldPin: kss.HashedPin(oldPin), OldPin: kss.HashedPin(oldPin),
NewPin: kss.HashedPin(newPin), NewPin: kss.HashedPin(newPin),
} }
res := &keysharePinStatus{} res := &keysharePinStatus{}
......
// Package irmaclient implements an IRMA client, that can manage and use IRMA attributes.
// It (de)serializes them from/to storage, acts as the client in the IRMA protocol
// (see https://credentials.github.io/protocols/irma-protocol), and also in the IRMA
// keyshare protocol (see http://credentials.github.io/protocols/keyshare-protocol).
package irmaclient
...@@ -2,10 +2,10 @@ package irmaclient ...@@ -2,10 +2,10 @@ package irmaclient
import ( import (
"encoding/json" "encoding/json"
"errors"
"math/big" "math/big"
"os" "os"
"testing" "testing"
"errors"
"github.com/mhe/gabi" "github.com/mhe/gabi"
"github.com/privacybydesign/irmago" "github.com/privacybydesign/irmago"
...@@ -107,9 +107,10 @@ func verifyClientIsUnmarshaled(t *testing.T, client *Client) { ...@@ -107,9 +107,10 @@ func verifyClientIsUnmarshaled(t *testing.T, client *Client) {
func verifyCredentials(t *testing.T, client *Client) { func verifyCredentials(t *testing.T, client *Client) {
var pk *gabi.PublicKey var pk *gabi.PublicKey
var err error for credtype, credsmap := range client.attributes {
for credtype, credsmap := range client.credentials { for index, attrs := range credsmap {
for index, cred := range credsmap { cred, err := client.credential(attrs.CredentialType().Identifier(), index)
require.NoError(t, err)
pk, err = cred.PublicKey() pk, err = cred.PublicKey()
require.NoError(t, err) require.NoError(t, err)
require.True(t, require.True(t,
......
...@@ -8,11 +8,12 @@ import ( ...@@ -8,11 +8,12 @@ import (
"testing" "testing"
"time" "time"
"math/big"
"github.com/go-errors/errors" "github.com/go-errors/errors"
"github.com/privacybydesign/irmago" "github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/internal/test" "github.com/privacybydesign/irmago/internal/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"math/big"
) )
type TestHandler struct { type TestHandler struct {
...@@ -210,6 +211,14 @@ func TestDisclosureSession(t *testing.T) { ...@@ -210,6 +211,14 @@ func TestDisclosureSession(t *testing.T) {
sessionHelper(t, jwtcontents, "verification", nil) sessionHelper(t, jwtcontents, "verification", nil)
} }
func TestNoAttributeDisclosureSession(t *testing.T) {
id := irma.NewAttributeTypeIdentifier("irma-demo.RU.studentCard")
name := "testsp"
jwtcontents := getDisclosureJwt(name, id)
sessionHelper(t, jwtcontents, "verification", nil)
}
func TestIssuanceSession(t *testing.T) { func TestIssuanceSession(t *testing.T) {
id := irma.NewAttributeTypeIdentifier("irma-demo.RU.studentCard.studentID") id := irma.NewAttributeTypeIdentifier("irma-demo.RU.studentCard.studentID")
name := "testip" name := "testip"
...@@ -370,8 +379,8 @@ func keyshareSessions(t *testing.T, client *Client) { ...@@ -370,8 +379,8 @@ func keyshareSessions(t *testing.T, client *Client) {
func TestKeyshareChangePin(t *testing.T) { func TestKeyshareChangePin(t *testing.T) {
client := parseStorage(t) client := parseStorage(t)
require.NoError(t, client.keyshareChangePinWorker(irma.NewSchemeManagerIdentifier("test"), "12345", "54321")); require.NoError(t, client.keyshareChangePinWorker(irma.NewSchemeManagerIdentifier("test"), "12345", "54321"))
require.NoError(t, client.keyshareChangePinWorker(irma.NewSchemeManagerIdentifier("test"), "54321", "12345")); require.NoError(t, client.keyshareChangePinWorker(irma.NewSchemeManagerIdentifier("test"), "54321", "12345"))
test.ClearTestStorage(t) test.ClearTestStorage(t)
} }
......
...@@ -198,7 +198,7 @@ func (client *Client) ParseAndroidStorage() (present bool, err error) { ...@@ -198,7 +198,7 @@ func (client *Client) ParseAndroidStorage() (present bool, err error) {
} }
} }
if len(client.credentials) > 0 { if len(client.credentialsCache) > 0 {
if err = client.storage.StoreAttributes(client.attributes); err != nil { if err = client.storage.StoreAttributes(client.attributes); err != nil {
return return
} }
......
// irmameta parses and prints info about the specified metadata attribute.
package main package main
import ( import (
...@@ -15,7 +16,7 @@ import ( ...@@ -15,7 +16,7 @@ import (
func main() { func main() {
if len(os.Args) != 3 { if len(os.Args) != 3 {
fmt.Println("Usage: irmago metadata_attribute_in_decimal path_to_irma_configuration") fmt.Println("Usage: irmago path_to_irma_configuration metadata_attribute_in_decimal")
} }
metaint, ok := new(big.Int).SetString(os.Args[2], 10) metaint, ok := new(big.Int).SetString(os.Args[2], 10)
......
// schememgr manages signatures on IRMA scheme managers.
// It can generate public-private keypairs for signing their directory structures,
// as well as creating and verifying these signatures.
package main package main
import "github.com/privacybydesign/irmago/schememgr/cmd" import "github.com/privacybydesign/irmago/schememgr/cmd"
......
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