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
8c057616
Commit
8c057616
authored
Sep 23, 2017
by
Sietse Ringers
Browse files
Polish keyshare code
parent
e121d72f
Changes
5
Hide whitespace changes
Inline
Side-by-side
keyshare.go
View file @
8c057616
...
...
@@ -13,9 +13,13 @@ import (
"github.com/mhe/gabi"
)
type
KeyshareSessionHandler
interface
{
AskPin
(
remainingAttempts
int
,
callback
func
(
pin
string
))
type
KeysharePinRequestor
interface
{
AskPin
(
remainingAttempts
int
,
callback
func
(
proceed
bool
,
pin
string
))
}
type
keyshareSessionHandler
interface
{
KeyshareDone
(
message
interface
{})
KeyshareCancelled
()
KeyshareBlocked
(
duration
int
)
KeyshareError
(
err
error
)
}
...
...
@@ -24,7 +28,8 @@ type keyshareSession struct {
session
Session
builders
[]
gabi
.
ProofBuilder
transports
map
[
SchemeManagerIdentifier
]
*
HTTPTransport
sessionHandler
KeyshareSessionHandler
sessionHandler
keyshareSessionHandler
pinRequestor
KeysharePinRequestor
keyshareServer
*
keyshareServer
}
...
...
@@ -108,10 +113,16 @@ func (ks *keyshareServer) HashedPin(pin string) string {
return
base64
.
RawStdEncoding
.
EncodeToString
(
hash
[
:
])
}
func
StartKeyshareSession
(
// startKeyshareSession starts and completes the entire keyshare protocol with all involved keyshare servers
// for the specified session, merging the keyshare proofs into the specified ProofBuilder's.
// The user's pin is retrieved using the KeysharePinRequestor, repeatedly, until either it is correct; or the
// user cancels; or one of the keyshare servers blocks us.
// Error, blocked or success of the keyshare session is reported back to the keyshareSessionHandler.
func
startKeyshareSession
(
session
Session
,
builders
[]
gabi
.
ProofBuilder
,
sessionHandler
KeyshareSessionHandler
,
sessionHandler
keyshareSessionHandler
,
pin
KeysharePinRequestor
,
)
{
ksscount
:=
0
for
_
,
managerId
:=
range
session
.
SchemeManagers
()
{
...
...
@@ -135,6 +146,7 @@ func StartKeyshareSession(
builders
:
builders
,
sessionHandler
:
sessionHandler
,
transports
:
map
[
SchemeManagerIdentifier
]
*
HTTPTransport
{},
pinRequestor
:
pin
,
}
askPin
:=
false
...
...
@@ -174,12 +186,15 @@ func StartKeyshareSession(
// 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
)
{
ks
.
sessionHandle
r
.
AskPin
(
attempts
,
func
(
pin
string
)
{
ks
.
pinRequesto
r
.
AskPin
(
attempts
,
func
(
proceed
bool
,
pin
string
)
{
success
,
attemptsRemaining
,
blocked
,
err
:=
ks
.
verifyPinAttempt
(
pin
)
if
err
!=
nil
{
ks
.
sessionHandler
.
KeyshareError
(
err
)
return
}
if
!
proceed
{
ks
.
sessionHandler
.
KeyshareCancelled
()
}
if
blocked
!=
0
{
ks
.
sessionHandler
.
KeyshareBlocked
(
blocked
)
return
...
...
@@ -194,14 +209,11 @@ func (ks *keyshareSession) VerifyPin(attempts int) {
}
// Verify the specified pin at each of the keyshare servers involved in the specified session.
//
// - If the pin did not verify at one of the keyshare servers but there are attempts remaining,
// the amount of remaining attempts is returned as the second return value.
//
// - If the pin did not verify at one of the keyshare servers and there are no attempts remaining,
// the amount of time for which we are blocked at the keyshare server is returned as the third
// 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
)
{
...
...
@@ -353,7 +365,7 @@ func (ks *keyshareSession) Finish(challenge *big.Int, responses map[SchemeManage
msg
:=
struct
{
ProofP
*
gabi
.
ProofP
}{}
_
,
err
:=
J
wtDecode
(
responses
[
managerId
],
msg
)
_
,
err
:=
j
wtDecode
(
responses
[
managerId
],
msg
)
if
err
!=
nil
{
ks
.
sessionHandler
.
KeyshareError
(
err
)
return
...
...
messages.go
View file @
8c057616
...
...
@@ -107,8 +107,10 @@ const (
// Server rejected our response (second IRMA message)
ErrorRejected
=
ErrorCode
(
"rejectedByServer"
)
// (De)serializing of a message failed
ErrorSerialization
=
ErrorCode
(
"serializationError"
)
ErrorKeyshare
=
ErrorCode
(
"keyshare"
)
ErrorSerialization
=
ErrorCode
(
"serializationError"
)
// Error in keyshare protocol
ErrorKeyshare
=
ErrorCode
(
"keyshare"
)
// Keyshare server has blocked us
ErrorKeyshareBlocked
=
ErrorCode
(
"keyshareBlocked"
)
)
...
...
@@ -119,7 +121,7 @@ func (e *Error) Error() string {
return
string
(
e
.
ErrorCode
)
}
func
J
wtDecode
(
jwt
string
,
body
interface
{})
(
string
,
error
)
{
func
j
wtDecode
(
jwt
string
,
body
interface
{})
(
string
,
error
)
{
jwtparts
:=
strings
.
Split
(
jwt
,
"."
)
if
jwtparts
==
nil
||
len
(
jwtparts
)
<
2
{
return
""
,
errors
.
New
(
"Not a JWT"
)
...
...
session.go
View file @
8c057616
...
...
@@ -25,7 +25,7 @@ type Handler interface {
AskVerificationPermission
(
request
DisclosureRequest
,
ServerName
string
,
callback
PermissionHandler
)
AskSignaturePermission
(
request
SignatureRequest
,
ServerName
string
,
callback
PermissionHandler
)
AskPin
(
remainingAttempts
int
,
callback
func
(
pin
string
))
AskPin
(
remainingAttempts
int
,
callback
func
(
proceed
bool
,
pin
string
))
}
// A session is an IRMA session.
...
...
@@ -141,7 +141,7 @@ func (session *session) start() {
default
:
panic
(
"Invalid session type"
)
// does not happen, session.Action has been checked earlier
}
server
,
err
:=
J
wtDecode
(
info
.
Jwt
,
session
.
jwt
)
server
,
err
:=
j
wtDecode
(
info
.
Jwt
,
session
.
jwt
)
if
err
!=
nil
{
session
.
Handler
.
Failure
(
session
.
Action
,
&
Error
{
ErrorCode
:
ErrorInvalidJWT
,
Err
:
err
})
return
...
...
@@ -219,18 +219,18 @@ func (session *session) do(proceed bool) {
session
.
Handler
.
Failure
(
session
.
Action
,
&
Error
{
ErrorCode
:
ErrorCrypto
,
Err
:
err
})
}
S
tartKeyshareSession
(
session
.
irmaSession
,
builders
,
session
)
s
tartKeyshareSession
(
session
.
irmaSession
,
builders
,
session
,
session
.
Handler
)
}
}
func
(
session
*
session
)
AskPin
(
remainingAttempts
int
,
callback
func
(
pin
string
))
{
session
.
Handler
.
AskPin
(
remainingAttempts
,
callback
)
}
func
(
session
*
session
)
KeyshareDone
(
message
interface
{})
{
session
.
sendResponse
(
message
)
}
func
(
session
*
session
)
KeyshareCancelled
()
{
session
.
Handler
.
Cancelled
(
session
.
Action
)
}
func
(
session
*
session
)
KeyshareBlocked
(
duration
int
)
{
session
.
Handler
.
Failure
(
session
.
Action
,
...
...
session_test.go
View file @
8c057616
...
...
@@ -54,8 +54,8 @@ func (th TestHandler) AskIssuancePermission(request IssuanceRequest, ServerName
func
(
th
TestHandler
)
AskSignaturePermission
(
request
SignatureRequest
,
ServerName
string
,
callback
PermissionHandler
)
{
th
.
AskVerificationPermission
(
request
.
DisclosureRequest
,
ServerName
,
callback
)
}
func
(
th
TestHandler
)
AskPin
(
remainingAttempts
int
,
callback
func
(
pin
string
))
{
callback
(
"12345"
)
func
(
th
TestHandler
)
AskPin
(
remainingAttempts
int
,
callback
func
(
proceed
bool
,
pin
string
))
{
callback
(
true
,
"12345"
)
}
func
getDisclosureJwt
(
name
string
,
id
AttributeTypeIdentifier
)
interface
{}
{
...
...
transport.go
View file @
8c057616
...
...
@@ -18,6 +18,8 @@ type HTTPTransport struct {
headers
map
[
string
]
string
}
const
verbose
=
false
// NewHTTPTransport returns a new HTTPTransport.
func
NewHTTPTransport
(
serverURL
string
)
*
HTTPTransport
{
url
:=
serverURL
...
...
@@ -50,7 +52,9 @@ func (transport *HTTPTransport) request(url string, method string, result interf
if
object
!=
nil
{
var
objstr
string
if
objstr
,
isstr
=
object
.
(
string
);
isstr
{
fmt
.
Printf
(
"GET %s
\n
"
,
url
)
if
verbose
{
fmt
.
Printf
(
"GET %s
\n
"
,
url
)
}
reader
=
bytes
.
NewBuffer
([]
byte
(
objstr
))
}
else
{
marshaled
,
err
:=
json
.
Marshal
(
object
)
...
...
@@ -58,7 +62,9 @@ func (transport *HTTPTransport) request(url string, method string, result interf
return
&
Error
{
Err
:
err
,
ErrorCode
:
ErrorSerialization
}
//return &TransportError{Err: err.Error()}
}
fmt
.
Printf
(
"POST %s: %s
\n
"
,
url
,
string
(
marshaled
))
if
verbose
{
fmt
.
Printf
(
"POST %s: %s
\n
"
,
url
,
string
(
marshaled
))
}
reader
=
bytes
.
NewBuffer
(
marshaled
)
}
}
...
...
@@ -95,11 +101,15 @@ func (transport *HTTPTransport) request(url string, method string, result interf
if
apierr
.
ErrorName
==
""
{
// Not an ApiErrorMessage
return
&
Error
{
ErrorCode
:
ErrorTransport
,
Status
:
res
.
StatusCode
}
}
fmt
.
Printf
(
"ERROR: %+v
\n
"
,
apierr
)
if
verbose
{
fmt
.
Printf
(
"ERROR: %+v
\n
"
,
apierr
)
}
return
&
Error
{
ErrorCode
:
ErrorTransport
,
Status
:
res
.
StatusCode
,
ApiError
:
apierr
}
}
fmt
.
Printf
(
"RESPONSE: %s
\n
"
,
string
(
body
))
if
verbose
{
fmt
.
Printf
(
"RESPONSE: %s
\n
"
,
string
(
body
))
}
err
=
json
.
Unmarshal
(
body
,
result
)
if
err
!=
nil
{
return
&
Error
{
Err
:
err
,
Status
:
res
.
StatusCode
}
...
...
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