manual_session_test.go 8.82 KB
Newer Older
1
2
3
package irmaclient

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

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

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

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

31
	client.NewSession(request, h)
32

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

38
39
40
	switch h.action {
	case irma.ActionDisclosing:
		verifyasRequest := &irma.DisclosureRequest{}
41
42
		err := json.Unmarshal([]byte(verifyAs), verifyasRequest)
		require.NoError(t, err)
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
		return irma.ProofList(result.VerificationResult).Verify(client.Configuration, verifyasRequest)
	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))
		}
		return result.SignatureResult.Verify(client.Configuration, verifyasRequest)
	default:
59
		return nil, ""
60
	}
61
}
62

63
64
65
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)
66

67
68
69
70
71
72
	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)
73
74
75
76
77
78

	test.ClearTestStorage(t)
}

// Test if proof verification fails with status 'ERROR_CRYPTO' if we verify it with an invalid nonce
func TestManualSessionInvalidNonce(t *testing.T) {
79
80
	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\"]}]}"
81
	ms := createManualSessionHandler(t, nil)
82
	_, status := manualSessionHelper(t, nil, ms, request, invalidRequest, false)
83

84
	require.Equal(t, irma.ProofStatusUnmatchedRequest, status)
85

86
	test.ClearTestStorage(t)
87
88
}

89
90
// Test if proof verification fails with status 'MISSING_ATTRIBUTES' if we provide it with a non-matching signature request
func TestManualSessionInvalidRequest(t *testing.T) {
91
92
	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\"]}]}"
93
	ms := createManualSessionHandler(t, nil)
94
	attrs, status := manualSessionHelper(t, nil, ms, request, invalidRequest, false)
95

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

102
103
104
105
106
	test.ClearTestStorage(t)
}

// Test if proof verification fails with status 'MISSING_ATTRIBUTES' if we provide it with invalid attribute values
func TestManualSessionInvalidAttributeValue(t *testing.T) {
107
108
	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\"}}]}"
109
	ms := createManualSessionHandler(t, nil)
110
	attrs, status := manualSessionHelper(t, nil, ms, request, invalidRequest, false)
111

112
113
	require.Equal(t, irma.ProofStatusMissingAttributes, status)
	require.Equal(t, irma.AttributeProofStatusInvalidValue, attrs[0].Status)
114
115
116
117
118

	test.ClearTestStorage(t)
}

func TestManualKeyShareSession(t *testing.T) {
119
	request := "{\"nonce\": 0, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"test.test.mijnirma.email\"]}]}"
120
	ms := createManualSessionHandler(t, nil)
121

122
123
124
125
	_, status := manualSessionHelper(t, nil, ms, request, request, false)
	require.Equal(t, irma.ProofStatusValid, status)
	_, status = manualSessionHelper(t, nil, ms, request, "", false)
	require.Equal(t, irma.ProofStatusValid, status)
126

127
	test.ClearTestStorage(t)
128
129
130
}

func TestManualSessionMultiProof(t *testing.T) {
131
	client := parseStorage(t)
132

133
	// First, we need to issue an extra credential (BSN)
134
135
	jwtcontents := getIssuanceJwt("testip", true, "")
	sessionHelper(t, jwtcontents, "issue", client)
136
137

	// Request to sign with both BSN and StudentID
138
	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\"]}]}"
139

140
	ms := createManualSessionHandler(t, client)
141

142
143
144
145
146
147
148
149
	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)
150

151
	test.ClearTestStorage(t)
152
153
}

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

159
	require.Equal(t, irma.ProofStatusInvalid, status)
160

161
	test.ClearTestStorage(t)
162
}
163
164
165
166

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)
167
	attrs, status := manualSessionHelper(t, nil, ms, request, request, false)
168

169
170
171
	require.Equal(t, irma.AttributeProofStatusPresent, attrs[0].Status)
	require.Equal(t, "456", attrs[0].Value["en"])
	require.Equal(t, irma.ProofStatusValid, status)
172
173
174
175
176
177
178
179
180

	test.ClearTestStorage(t)
}

// 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)
181
	attrs, status := manualSessionHelper(t, nil, ms, request, invalidRequest, false)
182

183
	require.Equal(t, irma.ProofStatusMissingAttributes, status)
184
	// First attribute result is MISSING, because it is in the request but not disclosed
185
	require.Equal(t, irma.AttributeProofStatusMissing, attrs[0].Status)
186
	// Second attribute result is EXTRA, since it is disclosed, but not matching the sigrequest
187
	require.Equal(t, irma.AttributeProofStatusExtra, attrs[1].Status)
188
189
190

	test.ClearTestStorage(t)
}