Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
IRMA
Github mirrors
irmago
Commits
f81d74b1
Commit
f81d74b1
authored
Feb 03, 2018
by
Sietse Ringers
Browse files
Add new KeyshareBlocked message to session handler interface
parent
e4d97606
Changes
6
Hide whitespace changes
Inline
Side-by-side
irmaclient/client.go
View file @
f81d74b1
...
...
@@ -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
}
...
...
irmaclient/keyshare.go
View file @
f81d74b1
...
...
@@ -7,9 +7,9 @@ import (
"math/big"
"strconv"
"github.com/privacybydesign/irmago"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
"github.com/privacybydesign/irmago"
)
// This file contains an implementation of the client side of the keyshare protocol,
...
...
@@ -24,8 +24,9 @@ type KeysharePinRequestor interface {
type
keyshareSessionHandler
interface
{
KeyshareDone
(
message
interface
{})
KeyshareCancelled
()
KeyshareBlocked
(
duration
int
)
KeyshareError
(
err
error
)
KeyshareBlocked
(
manager
irma
.
SchemeManagerIdentifier
,
duration
int
)
// 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 +44,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 +111,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 +155,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 +193,7 @@ func startKeyshareSession(
authstatus
:=
&
keyshareAuthorization
{}
err
:=
transport
.
Post
(
"users/isAuthorized"
,
authstatus
,
""
)
if
err
!=
nil
{
ks
.
sessionHandler
.
KeyshareError
(
err
)
ks
.
sessionHandler
.
KeyshareError
(
&
managerID
,
err
)
return
}
switch
authstatus
.
Status
{
...
...
@@ -194,7 +201,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
}
}
...
...
@@ -215,13 +222,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 +249,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
[
manager
ID
]
transport
:=
ks
.
transports
[
manager
ID
]
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 +271,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 +317,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 +352,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 +367,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 +391,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 +420,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 +428,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 +437,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
)
...
...
irmaclient/manual_session_test.go
View file @
f81d74b1
...
...
@@ -2,8 +2,9 @@ package irmaclient
import
(
"fmt"
"github.com/privacybydesign/irmago"
"testing"
"github.com/privacybydesign/irmago"
)
type
ManualSessionHandler
struct
{
...
...
@@ -86,3 +87,6 @@ func (sh *ManualSessionHandler) Failure(irmaAction irma.Action, err *irma.Sessio
fmt
.
Println
(
err
.
Err
)
sh
.
t
.
Fail
()
}
func
(
sh
*
ManualSessionHandler
)
KeyshareBlocked
(
manager
irma
.
SchemeManagerIdentifier
,
duration
int
)
{
sh
.
Failure
(
irma
.
ActionUnknown
,
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorKeyshareBlocked
})
}
irmaclient/session.go
View file @
f81d74b1
...
...
@@ -9,9 +9,9 @@ import (
"math/big"
"github.com/privacybydesign/irmago"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
"github.com/privacybydesign/irmago"
)
// This file contains the client side of the IRMA protocol, as well as the Handler interface
...
...
@@ -31,7 +31,9 @@ type Handler interface {
Cancelled
(
action
irma
.
Action
)
Failure
(
action
irma
.
Action
,
err
*
irma
.
SessionError
)
UnsatisfiableRequest
(
action
irma
.
Action
,
missing
irma
.
AttributeDisjunctionList
)
MissingKeyshareEnrollment
(
manager
irma
.
SchemeManagerIdentifier
)
KeyshareBlocked
(
manager
irma
.
SchemeManagerIdentifier
,
duration
int
)
RequestIssuancePermission
(
request
irma
.
IssuanceRequest
,
ServerName
string
,
callback
PermissionHandler
)
RequestVerificationPermission
(
request
irma
.
DisclosureRequest
,
ServerName
string
,
callback
PermissionHandler
)
...
...
@@ -65,7 +67,7 @@ type session struct {
irmaSession
irma
.
IrmaSession
}
//
We
implement baseSessi
no for a sessi
on
//
session
implement
s
baseSession
var
_
baseSession
=
(
*
session
)(
nil
)
// A interactiveSession is an interactive IRMA session
...
...
@@ -458,15 +460,21 @@ func (session *manualSession) KeyshareCancelled() {
session
.
Handler
.
Cancelled
(
session
.
Action
)
}
func
(
session
*
interactiveSession
)
KeyshareBlocked
(
duration
int
)
{
session
.
fail
(
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorKeyshareBlocked
,
Info
:
strconv
.
Itoa
(
duration
)})
func
(
session
*
interactiveSession
)
KeyshareBlocked
(
manager
irma
.
SchemeManagerIdentifier
,
duration
int
)
{
if
session
.
delete
()
{
if
session
.
downloaded
!=
nil
&&
!
session
.
downloaded
.
Empty
()
{
session
.
client
.
handler
.
UpdateConfiguration
(
session
.
downloaded
)
}
}
session
.
Handler
.
KeyshareBlocked
(
manager
,
duration
)
}
func
(
session
*
manualSession
)
KeyshareBlocked
(
duration
int
)
{
session
.
Handler
.
Failure
(
session
.
Action
,
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorKeyshareBlocked
,
Info
:
strconv
.
Itoa
(
duration
)})
func
(
session
*
manualSession
)
KeyshareBlocked
(
manager
irma
.
SchemeManagerIdentifier
,
duration
int
)
{
// TODO: fire UpdateConfiguration()?
session
.
Handler
.
KeyshareBlocked
(
manager
,
duration
)
}
func
(
session
*
interactiveSession
)
KeyshareError
(
err
error
)
{
func
(
session
*
interactiveSession
)
KeyshareError
(
manager
*
irma
.
SchemeManagerIdentifier
,
err
error
)
{
var
serr
*
irma
.
SessionError
var
ok
bool
if
serr
,
ok
=
err
.
(
*
irma
.
SessionError
);
!
ok
{
...
...
@@ -477,7 +485,7 @@ func (session *interactiveSession) KeyshareError(err error) {
session
.
fail
(
serr
)
}
func
(
session
*
manualSession
)
KeyshareError
(
err
error
)
{
func
(
session
*
manualSession
)
KeyshareError
(
manager
*
irma
.
SchemeManagerIdentifier
,
err
error
)
{
var
serr
*
irma
.
SessionError
var
ok
bool
if
serr
,
ok
=
err
.
(
*
irma
.
SessionError
);
!
ok
{
...
...
irmaclient/session_test.go
View file @
f81d74b1
package
irmaclient
// TODO +build integration
import
(
"crypto/rand"
"encoding/base64"
...
...
@@ -10,8 +8,8 @@ import (
"fmt"
"testing"
"github.com/privacybydesign/irmago"
"github.com/go-errors/errors"
"github.com/privacybydesign/irmago"
"github.com/stretchr/testify/require"
)
...
...
@@ -21,6 +19,10 @@ type TestHandler struct {
client
*
Client
}
func
(
th
TestHandler
)
KeyshareBlocked
(
manager
irma
.
SchemeManagerIdentifier
,
duration
int
)
{
th
.
Failure
(
irma
.
ActionUnknown
,
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorKeyshareBlocked
})
}
func
(
th
TestHandler
)
MissingKeyshareEnrollment
(
manager
irma
.
SchemeManagerIdentifier
)
{
th
.
Failure
(
irma
.
ActionUnknown
,
&
irma
.
SessionError
{
Err
:
errors
.
Errorf
(
"Missing keyshare server %s"
,
manager
.
String
())})
}
...
...
irmaclient/updates.go
View file @
f81d74b1
...
...
@@ -25,14 +25,16 @@ type update struct {
}
var
clientUpdates
=
[]
func
(
client
*
Client
)
error
{
// Convert old cardemu.xml Android storage to our own storage format
func
(
client
*
Client
)
error
{
_
,
err
:=
client
.
ParseAndroidStorage
()
return
err
},
// Adding scheme manager index, signature and public key
// Check the signatures of all scheme managers, if any is not ok,
// copy the entire irma_configuration folder from assets
func
(
client
*
Client
)
error
{
// Adding scheme manager index, signature and public key
// Check the signatures of all scheme managers, if any is not ok,
// copy the entire irma_configuration folder from assets
conf
:=
client
.
Configuration
if
len
(
conf
.
DisabledSchemeManagers
)
>
0
{
return
conf
.
CopyFromAssets
(
true
)
...
...
@@ -45,6 +47,8 @@ var clientUpdates = []func(client *Client) error{
}
return
nil
},
// Rename config -> preferences
func
(
client
*
Client
)
(
err
error
)
{
exists
,
err
:=
fs
.
PathExists
(
client
.
storage
.
path
(
"config"
))
if
!
exists
||
err
!=
nil
{
...
...
@@ -63,6 +67,14 @@ var clientUpdates = []func(client *Client) error{
}
return
client
.
storage
.
StorePreferences
(
client
.
Preferences
)
},
// For each keyshare server, include in its struct the identifier of its scheme manager
func
(
client
*
Client
)
(
err
error
)
{
for
smi
,
kss
:=
range
client
.
keyshareServers
{
kss
.
SchemeManagerIdentifier
=
smi
}
return
client
.
storage
.
StoreKeyshareServers
(
client
.
keyshareServers
)
},
}
// update performs any function from clientUpdates that has not
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment