Commit d883a3e2 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Use issuer name as server name in (single-issuer) issuance requests

parent ce7ba3d0
......@@ -7,6 +7,7 @@ import (
"github.com/pkg/errors"
"github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/irmaclient"
"github.com/stretchr/testify/require"
)
type TestClientHandler struct {
......@@ -63,6 +64,7 @@ type TestHandler struct {
t *testing.T
c chan *SessionResult
client *irmaclient.Client
expectedServerName irma.TranslatedString
}
func (th TestHandler) KeyshareEnrollmentIncomplete(manager irma.SchemeManagerIdentifier) {
......@@ -109,6 +111,9 @@ func (th TestHandler) RequestVerificationPermission(request irma.DisclosureReque
}
choice.Attributes = append(choice.Attributes, candidates[0])
}
if len(th.expectedServerName) != 0 {
require.Equal(th.t, th.expectedServerName, ServerName)
}
callback(true, choice)
}
func (th TestHandler) RequestIssuancePermission(request irma.IssuanceRequest, ServerName irma.TranslatedString, callback irmaclient.PermissionHandler) {
......
......@@ -6,6 +6,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"reflect"
"testing"
"time"
......@@ -90,12 +91,6 @@ func getIssuanceRequest(defaultValidity bool) *irma.IssuanceRequest {
"studentID": "s1234567",
"level": "42",
},
}, {
Validity: expiry,
CredentialTypeID: irma.NewCredentialTypeIdentifier("irma-demo.MijnOverheid.root"),
Attributes: map[string]string{
"BSN": "299792458",
},
},
},
}
......@@ -136,6 +131,18 @@ func getCombinedIssuanceRequest(id irma.AttributeTypeIdentifier) *irma.IssuanceR
return request
}
func getMultipleIssuanceRequest() *irma.IssuanceRequest {
request := getIssuanceRequest(false)
request.Credentials = append(request.Credentials, &irma.CredentialRequest{
Validity: request.Credentials[0].Validity,
CredentialTypeID: irma.NewCredentialTypeIdentifier("irma-demo.MijnOverheid.root"),
Attributes: map[string]string{
"BSN": "299792458",
},
})
return request
}
var TestType = "irmaserver-jwt"
func startSession(t *testing.T, request irma.SessionRequest, sessiontype string) *irma.Qr {
......@@ -229,7 +236,7 @@ func sessionHelper(t *testing.T, request irma.SessionRequest, sessiontype string
qr := startSession(t, request, sessiontype)
c := make(chan *SessionResult)
h := TestHandler{t, c, client}
h := TestHandler{t, c, client, expectedServerName(t, request, client.Configuration)}
qrjson, err := json.Marshal(qr)
require.NoError(t, err)
client.NewSession(string(qrjson), h)
......@@ -238,3 +245,30 @@ func sessionHelper(t *testing.T, request irma.SessionRequest, sessiontype string
require.NoError(t, result.Err)
}
}
func expectedServerName(t *testing.T, request irma.SessionRequest, conf *irma.Configuration) irma.TranslatedString {
localhost := "localhost"
host := irma.NewTranslatedString(&localhost)
ir, ok := request.(*irma.IssuanceRequest)
if !ok {
return host
}
// In issuance sessions, the server name is expected to be:
// - the name of the issuer, if there is just one issuer
// - the hostname as usual otherwise
var name irma.TranslatedString
for _, credreq := range ir.Credentials {
n := conf.Issuers[credreq.CredentialTypeID.IssuerIdentifier()].Name
if !reflect.DeepEqual(name, n) {
if len(name) != 0 {
return host
}
name = n
}
}
return name
}
......@@ -117,7 +117,7 @@ func TestManualSessionMultiProof(t *testing.T) {
defer test.ClearTestStorage(t)
// First, we need to issue an extra credential (BSN)
sessionHelper(t, getIssuanceRequest(true), "issue", client)
sessionHelper(t, getMultipleIssuanceRequest(), "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\"]}]}"
......
......@@ -25,7 +25,7 @@ func requestorSessionHelper(t *testing.T, request irma.SessionRequest) *server.S
})
require.NoError(t, err)
h := TestHandler{t, clientChan, client}
h := TestHandler{t, clientChan, client, nil}
j, err := json.Marshal(qr)
require.NoError(t, err)
client.NewSession(string(j), h)
......
......@@ -34,6 +34,11 @@ func TestIssuanceSession(t *testing.T) {
sessionHelper(t, request, "issue", nil)
}
func TestMultipleIssuanceSession(t *testing.T) {
request := getMultipleIssuanceRequest()
sessionHelper(t, request, "issue", nil)
}
func TestDefaultCredentialValidity(t *testing.T) {
client := parseStorage(t)
request := getIssuanceRequest(true)
......@@ -74,7 +79,7 @@ func TestIssuanceSingletonCredential(t *testing.T) {
client := parseStorage(t)
defer test.ClearTestStorage(t)
request := getIssuanceRequest(true)
request := getMultipleIssuanceRequest()
credid := irma.NewCredentialTypeIdentifier("irma-demo.MijnOverheid.root")
require.Nil(t, client.Attributes(credid, 0))
......@@ -234,7 +239,7 @@ func TestDownloadSchemeManager(t *testing.T) {
URL: "http://localhost:48681/irma_configuration/irma-demo",
})
require.NoError(t, err)
client.NewSession(string(qr), TestHandler{t, c, client})
client.NewSession(string(qr), TestHandler{t, c, client, nil})
if result := <-c; result != nil {
require.NoError(t, result.Err)
}
......
......@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"net/url"
"reflect"
"strings"
"github.com/go-errors/errors"
......@@ -53,7 +54,7 @@ type session struct {
Action irma.Action
Handler Handler
Version *irma.ProtocolVersion
ServerName string
ServerName irma.TranslatedString
choice *irma.DisclosureChoice
attrIndices irma.DisclosedAttributeIndices
......@@ -66,6 +67,7 @@ type session struct {
builders gabi.ProofBuilderList
// These are empty on manual sessions
Hostname string
ServerURL string
transport *irma.HTTPTransport
}
......@@ -118,7 +120,6 @@ func (client *Client) newManualSession(request irma.SessionRequest, handler Hand
Handler: handler,
client: client,
Version: minVersion,
ServerName: "",
request: request,
}
session.Handler.StatusUpdate(session.Action, irma.StatusManualStarted)
......@@ -146,7 +147,7 @@ func (client *Client) newQrSession(qr *irma.Qr, handler Handler) SessionDismisse
u, _ := url.ParseRequestURI(qr.URL) // Qr validator already checked this for errors
session := &session{
ServerURL: qr.URL,
ServerName: u.Hostname(),
Hostname: u.Hostname(),
transport: irma.NewHTTPTransport(qr.URL),
Action: irma.Action(qr.Type),
Handler: handler,
......@@ -197,6 +198,29 @@ func (session *session) getSessionInfo() {
session.processSessionInfo()
}
func serverName(hostname string, request irma.SessionRequest, conf *irma.Configuration) irma.TranslatedString {
sn := irma.NewTranslatedString(&hostname)
if ir, ok := request.(*irma.IssuanceRequest); ok {
// If there is only one issuer in the current request, use its name as ServerName
var iss irma.TranslatedString
for _, credreq := range ir.Credentials {
credIssuer := conf.Issuers[credreq.CredentialTypeID.IssuerIdentifier()].Name
if !reflect.DeepEqual(credIssuer, iss) { // Can't just test pointer equality: credIssuer != iss
if len(iss) != 0 {
return sn
}
iss = credIssuer
}
}
if len(iss) != 0 {
return iss
}
}
return sn
}
// processSessionInfo continues the session after all session state has been received:
// it checks if the session can be performed and asks the user for consent.
func (session *session) processSessionInfo() {
......@@ -214,6 +238,8 @@ func (session *session) processSessionInfo() {
session.request.SetVersion(session.Version)
}
session.ServerName = serverName(session.Hostname, session.request, session.client.Configuration)
if session.Action == irma.ActionIssuing {
ir := session.request.(*irma.IssuanceRequest)
_, err := ir.GetCredentialInfoList(session.client.Configuration, session.Version)
......@@ -232,10 +258,9 @@ func (session *session) processSessionInfo() {
}
}
serverName := irma.NewTranslatedString(&session.ServerName)
candidates, missing := session.client.CheckSatisfiability(session.request.ToDisclose())
if len(missing) > 0 {
session.Handler.UnsatisfiableRequest(serverName, missing)
session.Handler.UnsatisfiableRequest(session.ServerName, missing)
return
}
session.request.SetCandidates(candidates)
......@@ -250,13 +275,13 @@ func (session *session) processSessionInfo() {
switch session.Action {
case irma.ActionDisclosing:
session.Handler.RequestVerificationPermission(
*session.request.(*irma.DisclosureRequest), serverName, callback)
*session.request.(*irma.DisclosureRequest), session.ServerName, callback)
case irma.ActionSigning:
session.Handler.RequestSignaturePermission(
*session.request.(*irma.SignatureRequest), serverName, callback)
*session.request.(*irma.SignatureRequest), session.ServerName, callback)
case irma.ActionIssuing:
session.Handler.RequestIssuancePermission(
*session.request.(*irma.IssuanceRequest), serverName, callback)
*session.request.(*irma.IssuanceRequest), session.ServerName, callback)
default:
panic("Invalid session type") // does not happen, session.Action has been checked earlier
}
......
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