manual_session_test.go 8.29 KB
Newer Older
1
package sessiontest
2
3

import (
4
	"encoding/json"
Sietse Ringers's avatar
Sietse Ringers committed
5
6
	"testing"

7
8
	"github.com/privacybydesign/gabi"
	"github.com/privacybydesign/gabi/big"
9
	"github.com/privacybydesign/irmago"
Koen van Ingen's avatar
Koen van Ingen committed
10
	"github.com/privacybydesign/irmago/internal/test"
11
	"github.com/privacybydesign/irmago/irmaclient"
12
	"github.com/stretchr/testify/require"
13
14
)

15
// Create a ManualTestHandler for unit tests
16
func createManualSessionHandler(t *testing.T, client *irmaclient.Client) *ManualTestHandler {
17
	return &ManualTestHandler{
18
19
20
21
22
		TestHandler: TestHandler{
			t:      t,
			c:      make(chan *SessionResult),
			client: client,
		},
23
24
25
	}
}

26
func manualSessionHelper(t *testing.T, client *irmaclient.Client, h *ManualTestHandler, request string, verifyAs string, corrupt bool) ([]*irma.DisclosedAttribute, irma.ProofStatus) {
27
	if client == nil {
28
		client = parseStorage(t)
29
		defer test.ClearTestStorage(t)
30
	}
31

32
	client.NewSession(request, h)
33

34
35
36
	result := <-h.c
	if result.Err != nil {
		require.NoError(t, result.Err)
37
38
	}

39
40
41
	switch h.action {
	case irma.ActionDisclosing:
		verifyasRequest := &irma.DisclosureRequest{}
42
43
		err := json.Unmarshal([]byte(verifyAs), verifyasRequest)
		require.NoError(t, err)
44
		list, status, err := result.DisclosureResult.Verify(client.Configuration, verifyasRequest)
45
46
		require.NoError(t, err)
		return list, status
47
48
49
50
51
52
53
54
55
56
57
58
59
	case irma.ActionSigning:
		var verifyasRequest *irma.SignatureRequest
		if verifyAs != "" {
			verifyasRequest = &irma.SignatureRequest{}
			err := json.Unmarshal([]byte(verifyAs), verifyasRequest)
			require.NoError(t, err)
		}

		if corrupt {
			// Interesting: modifying C results in INVALID_CRYPTO; modifying A or an attribute results in INVALID_TIMESTAMP
			i := result.SignatureResult.Signature[0].(*gabi.ProofD).C
			i.Add(i, big.NewInt(16))
		}
60
61
62
		list, status, err := result.SignatureResult.Verify(client.Configuration, verifyasRequest)
		require.NoError(t, err)
		return list, status
63
	default:
64
		return nil, ""
65
	}
66
}
67

68
69
70
func TestManualSession(t *testing.T) {
	request := "{\"nonce\": 42, \"context\": 1337, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.studentID\"]}]}"
	ms := createManualSessionHandler(t, nil)
71

72
73
74
75
76
77
	attrs, status := manualSessionHelper(t, nil, ms, request, request, false)
	require.Equal(t, irma.ProofStatusValid, status)
	require.Equal(t, irma.AttributeProofStatusPresent, attrs[0].Status)
	attrs, status = manualSessionHelper(t, nil, ms, request, "", false)
	require.Equal(t, irma.ProofStatusValid, status)
	require.Equal(t, irma.AttributeProofStatusExtra, attrs[0].Status)
78
79
80
81
}

// Test if proof verification fails with status 'ERROR_CRYPTO' if we verify it with an invalid nonce
func TestManualSessionInvalidNonce(t *testing.T) {
82
83
	request := "{\"nonce\": 0, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.studentID\"]}]}"
	invalidRequest := "{\"nonce\": 1, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.studentID\"]}]}"
84
	ms := createManualSessionHandler(t, nil)
85
	_, status := manualSessionHelper(t, nil, ms, request, invalidRequest, false)
86

87
	require.Equal(t, irma.ProofStatusUnmatchedRequest, status)
88
89
}

90
91
// Test if proof verification fails with status 'MISSING_ATTRIBUTES' if we provide it with a non-matching signature request
func TestManualSessionInvalidRequest(t *testing.T) {
92
93
	request := "{\"nonce\": 0, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.studentID\"]}]}"
	invalidRequest := "{\"nonce\": 0, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.university\"]}]}"
94
	ms := createManualSessionHandler(t, nil)
95
	attrs, status := manualSessionHelper(t, nil, ms, request, invalidRequest, false)
96

97
	require.Equal(t, irma.ProofStatusMissingAttributes, status)
98
	// First attribute result is MISSING, because it is in the request but not disclosed
99
	require.Equal(t, irma.AttributeProofStatusMissing, attrs[0].Status)
100
	// Second attribute result is EXTRA, since it is disclosed, but not matching the sigrequest
101
	require.Equal(t, irma.AttributeProofStatusExtra, attrs[1].Status)
102
103
104
105
}

// Test if proof verification fails with status 'MISSING_ATTRIBUTES' if we provide it with invalid attribute values
func TestManualSessionInvalidAttributeValue(t *testing.T) {
106
107
	request := "{\"nonce\": 0, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":{\"irma-demo.RU.studentCard.studentID\": \"456\"}}]}"
	invalidRequest := "{\"nonce\": 0, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":{\"irma-demo.RU.studentCard.studentID\": \"123\"}}]}"
108
	ms := createManualSessionHandler(t, nil)
109
	attrs, status := manualSessionHelper(t, nil, ms, request, invalidRequest, false)
110

111
112
	require.Equal(t, irma.ProofStatusMissingAttributes, status)
	require.Equal(t, irma.AttributeProofStatusInvalidValue, attrs[0].Status)
113
114
}

115
func TestManualSessionMultiProof(t *testing.T) {
116
	client := parseStorage(t)
117
	defer test.ClearTestStorage(t)
118

119
	// First, we need to issue an extra credential (BSN)
120
	sessionHelper(t, getMultipleIssuanceRequest(), "issue", client)
121
122

	// Request to sign with both BSN and StudentID
123
	request := "{\"nonce\": 0, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.studentID\"]},{\"label\":\"BSN\",\"attributes\":[\"irma-demo.MijnOverheid.root.BSN\"]}]}"
124

125
	ms := createManualSessionHandler(t, client)
126

127
128
129
130
131
132
133
134
	attrs, status := manualSessionHelper(t, client, ms, request, request, false)
	require.Equal(t, irma.ProofStatusValid, status)
	require.Equal(t, irma.AttributeProofStatusPresent, attrs[0].Status)
	require.Equal(t, irma.AttributeProofStatusPresent, attrs[1].Status)
	attrs, status = manualSessionHelper(t, client, ms, request, "", false)
	require.Equal(t, irma.ProofStatusValid, status)
	require.Equal(t, irma.AttributeProofStatusExtra, attrs[0].Status)
	require.Equal(t, irma.AttributeProofStatusExtra, attrs[1].Status)
135
136
}

137
func TestManualSessionInvalidProof(t *testing.T) {
138
	request := "{\"nonce\": 0, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.studentID\"]}]}"
139
	ms := createManualSessionHandler(t, nil)
140
	_, status := manualSessionHelper(t, nil, ms, request, request, true)
141

142
	require.Equal(t, irma.ProofStatusInvalid, status)
143
}
144
145
146
147

func TestManualDisclosureSession(t *testing.T) {
	request := "{\"nonce\": 0, \"context\": 0, \"type\": \"disclosing\", \"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.studentID\"]}]}"
	ms := createManualSessionHandler(t, nil)
148
	attrs, status := manualSessionHelper(t, nil, ms, request, request, false)
149

150
151
152
	require.Equal(t, irma.AttributeProofStatusPresent, attrs[0].Status)
	require.Equal(t, "456", attrs[0].Value["en"])
	require.Equal(t, irma.ProofStatusValid, status)
153
154
155
156
157
158
159
}

// Test if proof verification fails with status 'MISSING_ATTRIBUTES' if we provide it with a non-matching disclosure request
func TestManualDisclosureSessionInvalidRequest(t *testing.T) {
	request := "{\"nonce\": 0, \"context\": 0, \"type\": \"disclosing\", \"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.studentID\"]}]}"
	invalidRequest := "{\"nonce\": 0, \"context\": 0, \"type\": \"disclosing\", \"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.university\"]}]}"
	ms := createManualSessionHandler(t, nil)
160
	attrs, status := manualSessionHelper(t, nil, ms, request, invalidRequest, false)
161

162
	require.Equal(t, irma.ProofStatusMissingAttributes, status)
163
	// First attribute result is MISSING, because it is in the request but not disclosed
164
	require.Equal(t, irma.AttributeProofStatusMissing, attrs[0].Status)
165
	// Second attribute result is EXTRA, since it is disclosed, but not matching the sigrequest
166
	require.Equal(t, irma.AttributeProofStatusExtra, attrs[1].Status)
167
}