Commit 225dee7d authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Simplify and deduplicode manual session unit tests

parent c837e1dd
......@@ -396,15 +396,15 @@ func TestDownloadSchemeManager(t *testing.T) {
require.NotContains(t, client.Configuration.SchemeManagers, irmademo)
// Do an add-scheme-manager-session
c := make(chan *irma.SessionError)
c := make(chan *SessionResult)
qr, err := json.Marshal(&irma.SchemeManagerRequest{
Type: irma.ActionSchemeManager,
URL: "http://localhost:48681/irma_configuration/irma-demo",
})
require.NoError(t, err)
client.NewSession(string(qr), TestHandler{t, c, client})
if err := <-c; err != nil {
t.Fatal(*err)
if result := <-c; result != nil {
require.NoError(t, result.Err)
}
require.Contains(t, client.Configuration.SchemeManagers, irmademo)
......
......@@ -2,276 +2,140 @@ package irmaclient
import (
"encoding/json"
"fmt"
"math/big"
"testing"
"github.com/mhe/gabi"
"github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/internal/test"
"github.com/stretchr/testify/require"
)
var client *Client
// Issue BSN credential using sessionHelper
func issue(t *testing.T, ms ManualSessionHandler) {
name := "testip"
jwtcontents := getIssuanceJwt(name, true, "")
sessionHandlerHelper(t, jwtcontents, "issue", client, &ms)
}
// Flip one bit in the proof string if invalidate is set to true
var invalidate bool
func corruptAndConvertProofString(proof string) []byte {
proofBytes := []byte(proof)
if invalidate {
// 42 because this is somewhere in a bigint in the json string
proofBytes[42] ^= 0x01
}
return proofBytes
}
// Create a ManualSessionHandler for unit tests
func createManualSessionHandler(request string, invalidRequest string, t *testing.T) ManualSessionHandler {
errorChannel := make(chan *irma.SessionError)
resultChannel := make(chan *irma.SignatureProofResult)
sigRequestJSON := []byte(request)
invalidSigRequestJSON := []byte(invalidRequest)
sigRequest := &irma.SignatureRequest{}
invalidSigRequest := &irma.SignatureRequest{}
json.Unmarshal(sigRequestJSON, sigRequest)
json.Unmarshal(invalidSigRequestJSON, invalidSigRequest)
return ManualSessionHandler{
t: t,
errorChannel: errorChannel,
resultChannel: resultChannel,
sigRequest: sigRequest,
sigVerifyRequest: invalidSigRequest,
func createManualSessionHandler(t *testing.T, client *Client) *ManualSessionHandler {
return &ManualSessionHandler{
TestHandler: TestHandler{
t: t,
c: make(chan *SessionResult),
client: client,
},
}
}
func TestManualSession(t *testing.T) {
invalidate = false
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(request, request, t)
func manualSessionHelper(t *testing.T, client *Client, h *ManualSessionHandler, request string, verifyAs string, corrupt bool) *irma.SignatureProofResult {
init := client == nil
if init {
client = parseStorage(t)
}
client = parseStorage(t)
client.NewSession(request, &ms)
client.NewSession(request, h)
if err := <-ms.errorChannel; err != nil {
test.ClearTestStorage(t)
t.Fatal(*err)
result := <-h.c
if result.Err != nil {
require.NoError(t, result.Err)
}
// No errors, obtain proof result from channel
result := <-ms.resultChannel
if ps := result.ProofStatus; ps != irma.ProofStatusValid {
t.Logf("Invalid proof result: %v Expected: %v", ps, irma.ProofStatusValid)
t.Fatal()
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.Result.Signature[0].(*gabi.ProofD).C
i.Add(i, big.NewInt(16))
}
if attrStatus := result.ToAttributeResultList()[0].AttributeProofStatus; attrStatus != irma.AttributeProofStatusPresent {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.AttributeProofStatusPresent)
t.Fail()
}
test.ClearTestStorage(t)
return result.Result.Verify(client.Configuration, verifyasRequest)
}
// Test if the session fails with unsatisfiable error if we cannot satify the signature request
func TestManualSessionUnsatisfiable(t *testing.T) {
invalidate = false
request := "{\"nonce\": 0, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":{\"irma-demo.RU.studentCard.studentID\": \"123\"}}]}"
ms := createManualSessionHandler(request, request, t)
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)
result := manualSessionHelper(t, nil, ms, request, request, false)
client = parseStorage(t)
client.NewSession(request, &ms)
require.Equal(t, irma.ProofStatusValid, result.ProofStatus)
require.Equal(t, irma.AttributeProofStatusPresent, result.ToAttributeResultList()[0].AttributeProofStatus)
// Fail test if we won't get UnsatisfiableRequest error
if err := <-ms.errorChannel; err.ErrorType != irma.ErrorType("UnsatisfiableRequest") {
test.ClearTestStorage(t)
t.Fatal(*err)
}
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) {
invalidate = false
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\"]}]}"
ms := createManualSessionHandler(t, nil)
result := manualSessionHelper(t, nil, ms, request, invalidRequest, false)
ms := createManualSessionHandler(request, invalidRequest, t)
require.Equal(t, irma.ProofStatusUnmatchedRequest, result.ProofStatus)
client = parseStorage(t)
client.NewSession(request, &ms)
if err := <-ms.errorChannel; err != nil {
test.ClearTestStorage(t)
t.Fatal(*err)
}
// No errors, obtain proof result from channel
if result := <-ms.resultChannel; result.ProofStatus != irma.ProofStatusUnmatchedRequest {
t.Logf("Invalid proof result: %v Expected: %v", result.ProofStatus, irma.ProofStatusUnmatchedRequest)
t.Fail()
}
test.ClearTestStorage(t)
}
// Test if proof verification fails with status 'MISSING_ATTRIBUTES' if we provide it with a non-matching signature request
func TestManualSessionInvalidRequest(t *testing.T) {
invalidate = false
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\"]}]}"
ms := createManualSessionHandler(t, nil)
result := manualSessionHelper(t, nil, ms, request, invalidRequest, false)
list := result.ToAttributeResultList()
ms := createManualSessionHandler(request, invalidRequest, t)
client = parseStorage(t)
client.NewSession(request, &ms)
if err := <-ms.errorChannel; err != nil {
test.ClearTestStorage(t)
t.Fatal(*err)
}
// No errors, obtain proof result from channel
result := <-ms.resultChannel
if ps := result.ProofStatus; ps != irma.ProofStatusMissingAttributes {
t.Logf("Invalid proof result: %v Expected: %v", ps, irma.ProofStatusMissingAttributes)
t.Fail()
}
require.Equal(t, irma.ProofStatusMissingAttributes, result.ProofStatus)
// First attribute result is MISSING, because it is in the request but not disclosed
if attrStatus := result.ToAttributeResultList()[0].AttributeProofStatus; attrStatus != irma.AttributeProofStatusMissing {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.AttributeProofStatusMissing)
t.Fail()
}
require.Equal(t, irma.AttributeProofStatusMissing, list[0].AttributeProofStatus)
// Second attribute result is EXTRA, since it is disclosed, but not matching the sigrequest
if attrStatus := result.ToAttributeResultList()[1].AttributeProofStatus; attrStatus != irma.AttributeProofStatusExtra {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.AttributeProofStatusExtra)
t.Fail()
}
require.Equal(t, irma.AttributeProofStatusExtra, list[1].AttributeProofStatus)
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) {
invalidate = false
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\"}}]}"
ms := createManualSessionHandler(t, nil)
result := manualSessionHelper(t, nil, ms, request, invalidRequest, false)
ms := createManualSessionHandler(request, invalidRequest, t)
client = parseStorage(t)
client.NewSession(request, &ms)
if err := <-ms.errorChannel; err != nil {
test.ClearTestStorage(t)
t.Fatal(*err)
}
require.Equal(t, irma.ProofStatusMissingAttributes, result.ProofStatus)
require.Equal(t, irma.AttributeProofStatusInvalidValue, result.ToAttributeResultList()[0].AttributeProofStatus)
// No errors, obtain proof result from channel
result := <-ms.resultChannel
if ps := result.ProofStatus; ps != irma.ProofStatusMissingAttributes {
t.Logf("Invalid proof result: %v Expected: %v", ps, irma.ProofStatusMissingAttributes)
t.Fail()
}
if attrStatus := result.ToAttributeResultList()[0].AttributeProofStatus; attrStatus != irma.AttributeProofStatusInvalidValue {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.AttributeProofStatusInvalidValue)
t.Fail()
}
test.ClearTestStorage(t)
}
func TestManualKeyShareSession(t *testing.T) {
invalidate = false
request := "{\"nonce\": 0, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"test.test.mijnirma.email\"]}]}"
ms := createManualSessionHandler(t, nil)
result := manualSessionHelper(t, nil, ms, request, request, false)
ms := createManualSessionHandler(request, request, t)
require.Equal(t, irma.ProofStatusValid, result.ProofStatus)
client = parseStorage(t)
client.NewSession(request, &ms)
if err := <-ms.errorChannel; err != nil {
test.ClearTestStorage(t)
t.Fatal(*err)
}
// No errors, obtain proof result from channel
if result := <-ms.resultChannel; result.ProofStatus != irma.ProofStatusValid {
t.Logf("Invalid proof result: %v Expected: %v", result.ProofStatus, irma.ProofStatusValid)
t.Fail()
}
test.ClearTestStorage(t)
}
func TestManualSessionMultiProof(t *testing.T) {
invalidate = false
client = parseStorage(t)
client := parseStorage(t)
// First, we need to issue an extra credential (BSN)
is := ManualSessionHandler{t: t, errorChannel: make(chan *irma.SessionError)}
go issue(t, is)
if err := <-is.errorChannel; err != nil {
fmt.Println("Error during initial issueing!")
t.Fatal(*err)
}
jwtcontents := getIssuanceJwt("testip", true, "")
sessionHelper(t, jwtcontents, "issue", client)
// Request to sign with both BSN and StudentID
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\"]}]}"
ms := createManualSessionHandler(request, request, t)
client.NewSession(request, &ms)
ms := createManualSessionHandler(t, client)
result := manualSessionHelper(t, client, ms, request, request, false)
if err := <-ms.errorChannel; err != nil {
test.ClearTestStorage(t)
t.Fatal(*err)
}
require.Equal(t, irma.ProofStatusValid, result.ProofStatus)
list := result.ToAttributeResultList()
require.Equal(t, irma.AttributeProofStatusPresent, list[0].AttributeProofStatus)
require.Equal(t, irma.AttributeProofStatusPresent, list[1].AttributeProofStatus)
// No errors, obtain proof result from channel
result := <-ms.resultChannel
if ps := result.ProofStatus; ps != irma.ProofStatusValid {
t.Logf("Invalid proof result: %v Expected: %v", result.ProofStatus, irma.ProofStatusValid)
t.Fail()
}
if attrStatus := result.ToAttributeResultList()[0].AttributeProofStatus; attrStatus != irma.AttributeProofStatusPresent {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.AttributeProofStatusPresent)
t.Fail()
}
if attrStatus := result.ToAttributeResultList()[1].AttributeProofStatus; attrStatus != irma.AttributeProofStatusPresent {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.AttributeProofStatusPresent)
t.Fail()
}
test.ClearTestStorage(t)
}
func TestManualSessionInvalidProof(t *testing.T) {
invalidate = true
request := "{\"nonce\": 0, \"context\": 0, \"type\": \"signing\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.studentID\"]}]}"
ms := createManualSessionHandler(request, request, t)
ms := createManualSessionHandler(t, nil)
result := manualSessionHelper(t, nil, ms, request, request, true)
client = parseStorage(t)
client.NewSession(request, &ms)
require.Equal(t, irma.ProofStatusInvalidCrypto, result.ProofStatus)
if err := <-ms.errorChannel; err != nil {
test.ClearTestStorage(t)
t.Fatal(*err)
}
// No errors, obtain proof result from channel
if result := <-ms.resultChannel; result.ProofStatus != irma.ProofStatusInvalidCrypto {
t.Logf("Invalid proof result: %v Expected: %v", result.ProofStatus, irma.ProofStatusInvalidCrypto)
t.Fail()
}
test.ClearTestStorage(t)
}
......@@ -267,14 +267,14 @@ func sessionHandlerHelper(t *testing.T, jwtcontents interface{}, url string, cli
require.NoError(t, transportErr)
qr.URL = url + "/" + qr.URL
c := make(chan *irma.SessionError)
c := make(chan *SessionResult)
if h == nil {
h = TestHandler{t, c, client}
}
client.newQrSession(qr, h)
if err := <-c; err != nil {
t.Fatal(*err)
if result := <-c; result != nil {
require.NoError(t, result.Err)
}
if init {
......
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