Commit 51703fd6 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Merge branch 'add-keyshare-blocked-message'

parents 917716d1 496920ce
......@@ -688,7 +688,7 @@ func (client *Client) keyshareEnrollWorker(managerID irma.SchemeManagerIdentifie
}
transport := irma.NewHTTPTransport(manager.KeyshareServer)
kss, err := newKeyshareServer(client.paillierKey(true), manager.KeyshareServer, email)
kss, err := newKeyshareServer(managerID, client.paillierKey(true), manager.KeyshareServer, email)
if err != nil {
return err
}
......
......@@ -24,8 +24,10 @@ type KeysharePinRequestor interface {
type keyshareSessionHandler interface {
KeyshareDone(message interface{})
KeyshareCancelled()
KeyshareBlocked(duration int)
KeyshareError(err error)
KeyshareBlocked(manager irma.SchemeManagerIdentifier, duration int)
KeyshareRegistrationIncomplete(manager irma.SchemeManagerIdentifier)
// In errors the manager may be nil, as not all keyshare errors have a clearly associated scheme manager
KeyshareError(manager *irma.SchemeManagerIdentifier, err error)
KeysharePin()
KeysharePinOK()
}
......@@ -43,11 +45,12 @@ type keyshareSession struct {
}
type keyshareServer struct {
URL string `json:"url"`
Username string `json:"username"`
Nonce []byte `json:"nonce"`
PrivateKey *paillierPrivateKey `json:"keyPair"`
token string
URL string `json:"url"`
Username string `json:"username"`
Nonce []byte `json:"nonce"`
PrivateKey *paillierPrivateKey `json:"keyPair"`
SchemeManagerIdentifier irma.SchemeManagerIdentifier
token string
}
type keyshareEnrollment struct {
......@@ -109,12 +112,17 @@ const (
kssPinError = "error"
)
func newKeyshareServer(privatekey *paillierPrivateKey, url, email string) (ks *keyshareServer, err error) {
func newKeyshareServer(
schemeManagerIdentifier irma.SchemeManagerIdentifier,
privatekey *paillierPrivateKey,
url, email string,
) (ks *keyshareServer, err error) {
ks = &keyshareServer{
Nonce: make([]byte, 32),
URL: url,
Username: email,
PrivateKey: privatekey,
Nonce: make([]byte, 32),
URL: url,
Username: email,
PrivateKey: privatekey,
SchemeManagerIdentifier: schemeManagerIdentifier,
}
_, err = rand.Read(ks.Nonce)
return
......@@ -148,14 +156,14 @@ func startKeyshareSession(
ksscount++
if _, enrolled := keyshareServers[managerID]; !enrolled {
err := errors.New("Not enrolled to keyshare server of scheme manager " + managerID.String())
sessionHandler.KeyshareError(err)
sessionHandler.KeyshareError(&managerID, err)
return
}
}
}
if _, issuing := session.(*irma.IssuanceRequest); issuing && ksscount > 1 {
err := errors.New("Issuance session involving more than one keyshare servers are not supported")
sessionHandler.KeyshareError(err)
sessionHandler.KeyshareError(nil, err)
return
}
......@@ -186,7 +194,7 @@ func startKeyshareSession(
authstatus := &keyshareAuthorization{}
err := transport.Post("users/isAuthorized", authstatus, "")
if err != nil {
ks.sessionHandler.KeyshareError(err)
ks.fail(managerID, err)
return
}
switch authstatus.Status {
......@@ -194,7 +202,7 @@ func startKeyshareSession(
case kssTokenExpired:
requestPin = true
default:
ks.sessionHandler.KeyshareError(errors.New("Keyshare server returned unrecognized authorization status"))
ks.sessionHandler.KeyshareError(&managerID, errors.New("Keyshare server returned unrecognized authorization status"))
return
}
}
......@@ -207,6 +215,28 @@ func startKeyshareSession(
}
}
func (ks *keyshareSession) fail(manager irma.SchemeManagerIdentifier, err error) {
serr, ok := err.(*irma.SessionError)
if ok {
if serr.ApiError != nil && len(serr.ApiError.ErrorName) > 0 {
switch serr.ApiError.ErrorName {
case "USER_NOT_REGISTERED":
ks.sessionHandler.KeyshareRegistrationIncomplete(manager)
case "USER_BLOCKED":
duration, err := strconv.Atoi(serr.ApiError.Message)
if err != nil { // Not really clear what to do with duration, but should never happen anyway
duration = -1
}
ks.sessionHandler.KeyshareBlocked(manager, duration)
default:
ks.sessionHandler.KeyshareError(&manager, err)
}
}
} else {
ks.sessionHandler.KeyshareError(&manager, err)
}
}
// Ask for a pin, repeatedly if necessary, and either continue the keyshare protocol
// with authorization, or stop the keyshare protocol and inform of failure.
func (ks *keyshareSession) VerifyPin(attempts int) {
......@@ -215,13 +245,13 @@ func (ks *keyshareSession) VerifyPin(attempts int) {
ks.sessionHandler.KeyshareCancelled()
return
}
success, attemptsRemaining, blocked, err := ks.verifyPinAttempt(pin)
success, attemptsRemaining, blocked, manager, err := ks.verifyPinAttempt(pin)
if err != nil {
ks.sessionHandler.KeyshareError(err)
ks.sessionHandler.KeyshareError(&manager, err)
return
}
if blocked != 0 {
ks.sessionHandler.KeyshareBlocked(blocked)
ks.sessionHandler.KeyshareBlocked(manager, blocked)
return
}
if success {
......@@ -242,14 +272,15 @@ func (ks *keyshareSession) VerifyPin(attempts int) {
// parameter.
// - If this or anything else (specified in err) goes wrong, success will be false.
// If all is ok, success will be true.
func (ks *keyshareSession) verifyPinAttempt(pin string) (success bool, tries int, blocked int, err error) {
for managerID := range ks.session.Identifiers().SchemeManagers {
if !ks.conf.SchemeManagers[managerID].Distributed() {
func (ks *keyshareSession) verifyPinAttempt(pin string) (
success bool, tries int, blocked int, manager irma.SchemeManagerIdentifier, err error) {
for manager = range ks.session.Identifiers().SchemeManagers {
if !ks.conf.SchemeManagers[manager].Distributed() {
continue
}
kss := ks.keyshareServers[managerID]
transport := ks.transports[managerID]
kss := ks.keyshareServers[manager]
transport := ks.transports[manager]
pinmsg := keysharePinMessage{Username: kss.Username, Pin: kss.HashedPin(pin)}
pinresult := &keysharePinStatus{}
err = transport.Post("users/verify/pin", pinresult, pinmsg)
......@@ -263,15 +294,9 @@ func (ks *keyshareSession) verifyPinAttempt(pin string) (success bool, tries int
transport.SetHeader(kssAuthHeader, kss.token)
case kssPinFailure:
tries, err = strconv.Atoi(pinresult.Message)
if err != nil {
return
}
return
case kssPinError:
blocked, err = strconv.Atoi(pinresult.Message)
if err != nil {
return
}
return
default:
err = errors.New("Keyshare server returned unrecognized PIN status")
......@@ -315,7 +340,7 @@ func (ks *keyshareSession) GetCommitments() {
comms := &proofPCommitmentMap{}
err := transport.Post("prove/getCommitments", comms, pkids[managerID])
if err != nil {
ks.sessionHandler.KeyshareError(err)
ks.sessionHandler.KeyshareError(&managerID, err)
return
}
for pki, c := range comms.Commitments {
......@@ -350,7 +375,7 @@ func (ks *keyshareSession) GetProofPs() {
if !issuing {
bytes, err := ks.keyshareServer.PrivateKey.Encrypt(challenge.Bytes())
if err != nil {
ks.sessionHandler.KeyshareError(err)
ks.sessionHandler.KeyshareError(&ks.keyshareServer.SchemeManagerIdentifier, err)
}
kssChallenge = new(big.Int).SetBytes(bytes)
}
......@@ -365,7 +390,7 @@ func (ks *keyshareSession) GetProofPs() {
var jwt string
err := transport.Post("prove/getResponse", &jwt, kssChallenge)
if err != nil {
ks.sessionHandler.KeyshareError(err)
ks.sessionHandler.KeyshareError(&managerID, err)
return
}
responses[managerID] = jwt
......@@ -389,7 +414,7 @@ func (ks *keyshareSession) Finish(challenge *big.Int, responses map[irma.SchemeM
// issuance server to verify
list, err := ks.builders.BuildDistributedProofList(challenge, nil)
if err != nil {
ks.sessionHandler.KeyshareError(err)
ks.sessionHandler.KeyshareError(&ks.keyshareServer.SchemeManagerIdentifier, err)
return
}
message := &gabi.IssueCommitmentMessage{Proofs: list, Nonce2: ks.state.nonce2}
......@@ -418,7 +443,7 @@ func (ks *keyshareSession) finishDisclosureOrSigning(challenge *big.Int, respons
ProofP *gabi.ProofP
}{}
if err := irma.JwtDecode(responses[managerID], &msg); err != nil {
ks.sessionHandler.KeyshareError(err)
ks.sessionHandler.KeyshareError(&managerID, err)
return
}
......@@ -426,7 +451,7 @@ func (ks *keyshareSession) finishDisclosureOrSigning(challenge *big.Int, respons
proofPs[i] = msg.ProofP
bytes, err := ks.keyshareServer.PrivateKey.Decrypt(proofPs[i].SResponse.Bytes())
if err != nil {
ks.sessionHandler.KeyshareError(err)
ks.sessionHandler.KeyshareError(&managerID, err)
return
}
proofPs[i].SResponse = new(big.Int).SetBytes(bytes)
......@@ -435,7 +460,7 @@ func (ks *keyshareSession) finishDisclosureOrSigning(challenge *big.Int, respons
// Create merged proofs and finish protocol
list, err := ks.builders.BuildDistributedProofList(challenge, proofPs)
if err != nil {
ks.sessionHandler.KeyshareError(err)
ks.sessionHandler.KeyshareError(nil, err)
return
}
ks.sessionHandler.KeyshareDone(list)
......
......@@ -2,11 +2,9 @@ package irmaclient
import (
"fmt"
"github.com/go-errors/errors"
"testing"
"github.com/go-errors/errors"
"github.com/privacybydesign/irmago"
)
......@@ -72,21 +70,32 @@ func (sh *ManualSessionHandler) RequestSignaturePermission(request irma.Signatur
// These handlers should not be called, fail test if they are called
func (sh *ManualSessionHandler) Cancelled(irmaAction irma.Action) {
sh.c <- &irma.SessionError{Err: errors.New("Session was cancelled")}
sh.Failure(irma.ActionUnknown, &irma.SessionError{Err: errors.New("Session was cancelled")})
}
func (sh *ManualSessionHandler) MissingKeyshareEnrollment(manager irma.SchemeManagerIdentifier) {
sh.c <- &irma.SessionError{Err: errors.Errorf("Missing keyshare server %s", manager.String())}
sh.Failure(irma.ActionUnknown, &irma.SessionError{Err: errors.Errorf("Missing keyshare server %s", manager.String())})
}
func (sh *ManualSessionHandler) RequestIssuancePermission(request irma.IssuanceRequest, issuerName string, ph PermissionHandler) {
sh.c <- &irma.SessionError{Err: errors.New("Unexpected session type")}
sh.Failure(irma.ActionUnknown, &irma.SessionError{Err: errors.New("Unexpected session type")})
}
func (sh *ManualSessionHandler) RequestSchemeManagerPermission(manager *irma.SchemeManager, callback func(proceed bool)) {
sh.c <- &irma.SessionError{Err: errors.New("Unexpected session type")}
sh.Failure(irma.ActionUnknown, &irma.SessionError{Err: errors.New("Unexpected session type")})
}
func (sh *ManualSessionHandler) RequestVerificationPermission(request irma.DisclosureRequest, verifierName string, ph PermissionHandler) {
sh.c <- &irma.SessionError{Err: errors.New("Unexpected session type")}
sh.Failure(irma.ActionUnknown, &irma.SessionError{Err: errors.New("Unexpected session type")})
}
func (sh *ManualSessionHandler) Failure(irmaAction irma.Action, err *irma.SessionError) {
fmt.Println(err.Err)
sh.c <- err
select {
case sh.c <- err:
// nop
default:
sh.t.Fatal(err)
}
}
func (sh *ManualSessionHandler) KeyshareBlocked(manager irma.SchemeManagerIdentifier, duration int) {
sh.Failure(irma.ActionUnknown, &irma.SessionError{ErrorType: irma.ErrorKeyshareBlocked})
}
func (sh *ManualSessionHandler) KeyshareRegistrationIncomplete(manager irma.SchemeManagerIdentifier) {
sh.Failure(irma.ActionUnknown, &irma.SessionError{Err: errors.New("KeyshareRegistrationIncomplete")})
}
......@@ -31,7 +31,10 @@ type Handler interface {
Cancelled(action irma.Action)
Failure(action irma.Action, err *irma.SessionError)
UnsatisfiableRequest(action irma.Action, ServerName string, missing irma.AttributeDisjunctionList)
MissingKeyshareEnrollment(manager irma.SchemeManagerIdentifier)
KeyshareBlocked(manager irma.SchemeManagerIdentifier, duration int)
KeyshareRegistrationIncomplete(manager irma.SchemeManagerIdentifier)
RequestIssuancePermission(request irma.IssuanceRequest, ServerName string, callback PermissionHandler)
RequestVerificationPermission(request irma.DisclosureRequest, ServerName string, callback PermissionHandler)
......@@ -406,11 +409,15 @@ func (session *session) KeyshareCancelled() {
session.cancel()
}
func (session *session) KeyshareBlocked(duration int) {
session.fail(&irma.SessionError{ErrorType: irma.ErrorKeyshareBlocked, Info: strconv.Itoa(duration)})
func (session *session) KeyshareRegistrationIncomplete(manager irma.SchemeManagerIdentifier) {
session.Handler.KeyshareRegistrationIncomplete(manager)
}
func (session *session) KeyshareBlocked(manager irma.SchemeManagerIdentifier, duration int) {
session.Handler.KeyshareBlocked(manager, duration)
}
func (session *session) KeyshareError(err error) {
func (session *session) KeyshareError(manager *irma.SchemeManagerIdentifier, err error) {
var serr *irma.SessionError
var ok bool
if serr, ok = err.(*irma.SessionError); !ok {
......
......@@ -20,6 +20,14 @@ type TestHandler struct {
client *Client
}
func (th TestHandler) KeyshareRegistrationIncomplete(manager irma.SchemeManagerIdentifier) {
th.Failure(irma.ActionUnknown, &irma.SessionError{Err: errors.New("KeyshareRegistrationIncomplete")})
}
func (th TestHandler) KeyshareBlocked(manager irma.SchemeManagerIdentifier, duration int) {
th.Failure(irma.ActionUnknown, &irma.SessionError{Err: errors.New("KeyshareBlocked")})
}
func (th TestHandler) MissingKeyshareEnrollment(manager irma.SchemeManagerIdentifier) {
th.Failure(irma.ActionUnknown, &irma.SessionError{Err: errors.Errorf("Missing keyshare server %s", manager.String())})
}
......
......@@ -72,6 +72,18 @@ var clientUpdates = []func(client *Client) error{
func(client *Client) (err error) {
return client.Configuration.CopyFromAssets(true)
},
// For each keyshare server, include in its struct the identifier of its scheme manager
func(client *Client) (err error) {
keyshareServers, err := client.storage.LoadKeyshareServers()
if err != nil {
return err
}
for smi, kss := range keyshareServers {
kss.SchemeManagerIdentifier = smi
}
return client.storage.StoreKeyshareServers(keyshareServers)
},
}
// update performs any function from clientUpdates that has not
......
{"test":{"url":"http://localhost:8080/irma_keyshare_server/api/v1","username":"testusername","nonce":"Xb2E0rMzIlLzGRF72zpnIa3OQuQa+PtQf5+Lw6uXFTY=","keyPair":{"N":24428225740399330580333113110902680990277589581067969934949653123683469098494764641155243082249801664112361823434766013151369368511090516353844744830204646148333478565793378429678588341062977096119512869222655526015820538374966936659436617846962895714302754039294374733280764050022433419774087855847938858000332409285415750647466867279610626860664320265681649418469417127726923376741037448704723897078434301858791634189635797437813209386891133527791081093395862543868043852447762291145615589316942332322356214230772589251174590398678888311562947723531989408178115197127709706626583351333795141029721896901485453680319,"G":17948470935821729188106091421709655906001732927602280604374877188502926412173732300250736064220436586121644432565867771993761974358949417374879427109114746839901074083831506941188486018803901725486624170545520797943374384178772090444259028702531962880614697282738685021298955994020851975625300141657255060207178035443078641230729905182801310741253760431199512540950387260880637093634480127770357299622052007681045829349269144636555636560022574641155735732745698662647396619247466755278755885560424714760594726764152680178405250922344992316157163182728147747687910564755889459196648180088397022867342119114131262716803,"NSquared":596738212823908422722684447852557873707091115290261109970619471214678688342663922610410225887969624669528632850269713940927164243946500395632609808709015431150143363018916552402305647705542105198182591241256704640058830256989985731530407093712739321579360275605383025599284152574935758439945013820180868488849586876077265724009673310418503195732728223826931331883694710955296016136427784335719332993384794598188249575083799908524468396099680094784562607747368568764227244378367311828084637807486262977349835646107424857193160577841257746953292275449202680334406981680553910026247464478737898189519886148000530227289008009559577110542216066310896228763339224181840338326046626159368526555117143093509692471618025882574619710623665103358362539924521797298689972262499613191997151181825621274686799114758647167482972918231380049134953711377395205821468850062066750831955543485615342319331993871223164126914743303237376899916098170292785384814958681609873987207017471155787970444329874030299436374891262395778674915034144917802416680050500567825951443996313677157331224391722261090993848466707100532265478585766510876455411260719566093960241080627471763474427127437884993041475493613536790376888114934702629672232540326858573261847941761,"L":12214112870199665290166556555451340495138794790533984967474826561841734549247382320577621541124900832056180911717383006575684684255545258176922372415102323074166739282896689214839294170531488548059756434611327763007910269187483468329718308923481447857151377019647187366640382025011216709887043927923969429000009043691025735700620957989360200766120074560814438642487651452384431551993840116049346685321285785716966985200427756907404837132069368739277146792600578085694607772088567648223321660604893897374788877302677252247276379317622140094627977015392418514260317281875734732187418396525233216445864514276743417185848,"U":19912746068205519364851327179815201082238009565234331045064495080230734476194817479124641743750883796254209246954649623190126403707736555175678388568054172353853041132321654071614367658185715154859106748471838564244810007905965315523998739353754803887245565422499729346591647088945407013226930182535705057075784239580728927331869546685952864393885796413660031420857632579613800450229774588518338215899036306413114356802331906233164336727792565281154474230263297371124137775615041515224573003818467270459709845839627351863248461718283936177402786467332492170107114657485498105659804873302946202504386142981739540069310}}}
\ No newline at end of file
{"test":{"url":"http://localhost:8080/irma_keyshare_server/api/v1","username":"testusername","nonce":"Xb2E0rMzIlLzGRF72zpnIa3OQuQa+PtQf5+Lw6uXFTY=","keyPair":{"N":24428225740399330580333113110902680990277589581067969934949653123683469098494764641155243082249801664112361823434766013151369368511090516353844744830204646148333478565793378429678588341062977096119512869222655526015820538374966936659436617846962895714302754039294374733280764050022433419774087855847938858000332409285415750647466867279610626860664320265681649418469417127726923376741037448704723897078434301858791634189635797437813209386891133527791081093395862543868043852447762291145615589316942332322356214230772589251174590398678888311562947723531989408178115197127709706626583351333795141029721896901485453680319,"G":17948470935821729188106091421709655906001732927602280604374877188502926412173732300250736064220436586121644432565867771993761974358949417374879427109114746839901074083831506941188486018803901725486624170545520797943374384178772090444259028702531962880614697282738685021298955994020851975625300141657255060207178035443078641230729905182801310741253760431199512540950387260880637093634480127770357299622052007681045829349269144636555636560022574641155735732745698662647396619247466755278755885560424714760594726764152680178405250922344992316157163182728147747687910564755889459196648180088397022867342119114131262716803,"NSquared":596738212823908422722684447852557873707091115290261109970619471214678688342663922610410225887969624669528632850269713940927164243946500395632609808709015431150143363018916552402305647705542105198182591241256704640058830256989985731530407093712739321579360275605383025599284152574935758439945013820180868488849586876077265724009673310418503195732728223826931331883694710955296016136427784335719332993384794598188249575083799908524468396099680094784562607747368568764227244378367311828084637807486262977349835646107424857193160577841257746953292275449202680334406981680553910026247464478737898189519886148000530227289008009559577110542216066310896228763339224181840338326046626159368526555117143093509692471618025882574619710623665103358362539924521797298689972262499613191997151181825621274686799114758647167482972918231380049134953711377395205821468850062066750831955543485615342319331993871223164126914743303237376899916098170292785384814958681609873987207017471155787970444329874030299436374891262395778674915034144917802416680050500567825951443996313677157331224391722261090993848466707100532265478585766510876455411260719566093960241080627471763474427127437884993041475493613536790376888114934702629672232540326858573261847941761,"L":12214112870199665290166556555451340495138794790533984967474826561841734549247382320577621541124900832056180911717383006575684684255545258176922372415102323074166739282896689214839294170531488548059756434611327763007910269187483468329718308923481447857151377019647187366640382025011216709887043927923969429000009043691025735700620957989360200766120074560814438642487651452384431551993840116049346685321285785716966985200427756907404837132069368739277146792600578085694607772088567648223321660604893897374788877302677252247276379317622140094627977015392418514260317281875734732187418396525233216445864514276743417185848,"U":19912746068205519364851327179815201082238009565234331045064495080230734476194817479124641743750883796254209246954649623190126403707736555175678388568054172353853041132321654071614367658185715154859106748471838564244810007905965315523998739353754803887245565422499729346591647088945407013226930182535705057075784239580728927331869546685952864393885796413660031420857632579613800450229774588518338215899036306413114356802331906233164336727792565281154474230263297371124137775615041515224573003818467270459709845839627351863248461718283936177402786467332492170107114657485498105659804873302946202504386142981739540069310},"SchemeManagerIdentifier":"test"}}
\ No newline at end of file
[{"When":1517836912,"Number":0,"Success":true,"Error":null},{"When":1517836912,"Number":1,"Success":true,"Error":null},{"When":1517836912,"Number":2,"Success":true,"Error":null}]
\ No newline at end of file
[{"When":1517836912,"Number":0,"Success":true,"Error":null},{"When":1517836912,"Number":1,"Success":true,"Error":null},{"When":1517836912,"Number":2,"Success":true,"Error":null},{"When":1518168705,"Number":3,"Success":true,"Error":null},{"When":1518168712,"Number":4,"Success":true,"Error":null}]
\ No newline at end of file
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