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
081c4b1f
Commit
081c4b1f
authored
Jul 24, 2018
by
Sietse Ringers
Browse files
Group similar methods in session.go
parent
38e75746
Changes
1
Hide whitespace changes
Inline
Side-by-side
irmaclient/session.go
View file @
081c4b1f
...
@@ -79,129 +79,7 @@ var supportedVersions = map[int][]int{
...
@@ -79,129 +79,7 @@ var supportedVersions = map[int][]int{
2
:
{
3
,
2
,
1
},
2
:
{
3
,
2
,
1
},
}
}
func
calcVersion
(
qr
*
irma
.
Qr
)
(
*
irma
.
ProtocolVersion
,
error
)
{
// Session constructors
// Iterate supportedVersions in reverse sorted order (i.e. biggest major number first)
keys
:=
make
([]
int
,
0
,
len
(
supportedVersions
))
for
k
:=
range
supportedVersions
{
keys
=
append
(
keys
,
k
)
}
sort
.
Sort
(
sort
.
Reverse
(
sort
.
IntSlice
(
keys
)))
for
_
,
major
:=
range
keys
{
for
_
,
minor
:=
range
supportedVersions
[
major
]
{
aboveMinimum
:=
major
>
qr
.
ProtocolVersion
.
Major
||
(
major
==
qr
.
ProtocolVersion
.
Major
&&
minor
>=
qr
.
ProtocolVersion
.
Minor
)
underMaximum
:=
major
<
qr
.
ProtocolMaxVersion
.
Major
||
(
major
==
qr
.
ProtocolMaxVersion
.
Major
&&
minor
<=
qr
.
ProtocolMaxVersion
.
Minor
)
if
aboveMinimum
&&
underMaximum
{
return
irma
.
NewVersion
(
major
,
minor
),
nil
}
}
}
return
nil
,
fmt
.
Errorf
(
"No supported protocol version between %s and %s"
,
qr
.
ProtocolVersion
.
String
(),
qr
.
ProtocolMaxVersion
.
String
())
}
// IsInteractive returns whether this session uses an API server or not.
func
(
session
*
session
)
IsInteractive
()
bool
{
return
session
.
ServerURL
!=
""
}
// getBuilders computes the builders for disclosure proofs or secretkey-knowledge proof (in case of disclosure/signing
// and issuing respectively).
func
(
session
*
session
)
getBuilders
()
(
gabi
.
ProofBuilderList
,
*
big
.
Int
,
error
)
{
var
builders
gabi
.
ProofBuilderList
var
err
error
var
issuerProofNonce
*
big
.
Int
switch
session
.
Action
{
case
irma
.
ActionSigning
:
builders
,
err
=
session
.
client
.
ProofBuilders
(
session
.
choice
,
session
.
request
,
true
)
case
irma
.
ActionDisclosing
:
builders
,
err
=
session
.
client
.
ProofBuilders
(
session
.
choice
,
session
.
request
,
false
)
case
irma
.
ActionIssuing
:
builders
,
issuerProofNonce
,
err
=
session
.
client
.
IssuanceProofBuilders
(
session
.
request
.
(
*
irma
.
IssuanceRequest
))
}
return
builders
,
issuerProofNonce
,
err
}
// getProofs computes the disclosure proofs or secretkey-knowledge proof (in case of disclosure/signing
// and issuing respectively) to be sent to the server.
func
(
session
*
session
)
getProof
()
(
interface
{},
error
)
{
var
message
interface
{}
var
err
error
switch
session
.
Action
{
case
irma
.
ActionSigning
:
message
,
err
=
session
.
client
.
Proofs
(
session
.
choice
,
session
.
request
,
true
)
case
irma
.
ActionDisclosing
:
message
,
err
=
session
.
client
.
Proofs
(
session
.
choice
,
session
.
request
,
false
)
case
irma
.
ActionIssuing
:
message
,
session
.
builders
,
err
=
session
.
client
.
IssueCommitments
(
session
.
request
.
(
*
irma
.
IssuanceRequest
))
}
return
message
,
err
}
// checkKeyshareEnrollment checks if we are enrolled into all involved keyshare servers,
// and aborts the session if not
func
(
session
*
session
)
checkKeyshareEnrollment
()
bool
{
for
id
:=
range
session
.
request
.
Identifiers
()
.
SchemeManagers
{
manager
,
ok
:=
session
.
client
.
Configuration
.
SchemeManagers
[
id
]
if
!
ok
{
session
.
Handler
.
Failure
(
session
.
Action
,
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorUnknownSchemeManager
,
Info
:
id
.
String
()})
return
false
}
distributed
:=
manager
.
Distributed
()
_
,
enrolled
:=
session
.
client
.
keyshareServers
[
id
]
if
distributed
&&
!
enrolled
{
session
.
Handler
.
KeyshareEnrollmentMissing
(
id
)
return
false
}
}
return
true
}
func
(
session
*
session
)
recoverFromPanic
()
{
if
e
:=
recover
();
e
!=
nil
{
if
session
.
Handler
!=
nil
{
session
.
Handler
.
Failure
(
session
.
Action
,
panicToError
(
e
))
}
}
}
func
(
session
*
session
)
checkAndUpateConfiguration
()
bool
{
for
id
:=
range
session
.
request
.
Identifiers
()
.
SchemeManagers
{
manager
,
contains
:=
session
.
client
.
Configuration
.
SchemeManagers
[
id
]
if
!
contains
{
session
.
fail
(
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorUnknownSchemeManager
,
Info
:
id
.
String
(),
})
return
false
}
if
!
manager
.
Valid
{
session
.
fail
(
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorInvalidSchemeManager
,
Info
:
string
(
manager
.
Status
),
})
return
false
}
}
// Check if we are enrolled into all involved keyshare servers
if
!
session
.
checkKeyshareEnrollment
()
{
return
false
}
// Download missing credential types/issuers/public keys from the scheme manager
downloaded
,
err
:=
session
.
client
.
Configuration
.
Download
(
session
.
request
)
if
err
!=
nil
{
session
.
fail
(
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorConfigurationDownload
,
Err
:
err
})
return
false
}
if
downloaded
!=
nil
&&
!
downloaded
.
Empty
()
{
session
.
client
.
handler
.
UpdateConfiguration
(
downloaded
)
}
return
true
}
// NewManualSession starts a manual session, given a signature request in JSON and a handler to pass messages to
// NewManualSession starts a manual session, given a signature request in JSON and a handler to pass messages to
func
(
client
*
Client
)
NewManualSession
(
sigrequestJSONString
string
,
handler
Handler
)
{
func
(
client
*
Client
)
NewManualSession
(
sigrequestJSONString
string
,
handler
Handler
)
{
...
@@ -287,6 +165,8 @@ func (client *Client) NewSession(qr *irma.Qr, handler Handler) SessionDismisser
...
@@ -287,6 +165,8 @@ func (client *Client) NewSession(qr *irma.Qr, handler Handler) SessionDismisser
return
session
return
session
}
}
// Core session methods
// getSessionInfo retrieves the first message in the IRMA protocol, checks if we can perform
// getSessionInfo retrieves the first message in the IRMA protocol, checks if we can perform
// the request, and informs the user of the outcome.
// the request, and informs the user of the outcome.
func
(
session
*
session
)
getSessionInfo
()
{
func
(
session
*
session
)
getSessionInfo
()
{
...
@@ -407,71 +287,6 @@ func (session *session) doSession(proceed bool) {
...
@@ -407,71 +287,6 @@ func (session *session) doSession(proceed bool) {
}
}
}
}
// Distributed returns whether or not this session involves a keyshare server.
func
(
session
*
session
)
Distributed
()
bool
{
var
smi
irma
.
SchemeManagerIdentifier
if
session
.
Action
==
irma
.
ActionIssuing
{
for
_
,
credreq
:=
range
session
.
request
.
(
*
irma
.
IssuanceRequest
)
.
Credentials
{
smi
=
credreq
.
CredentialTypeID
.
IssuerIdentifier
()
.
SchemeManagerIdentifier
()
if
session
.
client
.
Configuration
.
SchemeManagers
[
smi
]
.
Distributed
()
{
return
true
}
}
}
if
session
.
choice
==
nil
||
session
.
choice
.
Attributes
==
nil
{
return
false
}
for
_
,
ai
:=
range
session
.
choice
.
Attributes
{
smi
=
ai
.
Type
.
CredentialTypeIdentifier
()
.
IssuerIdentifier
()
.
SchemeManagerIdentifier
()
if
session
.
client
.
Configuration
.
SchemeManagers
[
smi
]
.
Distributed
()
{
return
true
}
}
return
false
}
func
(
session
*
session
)
KeyshareDone
(
message
interface
{})
{
session
.
sendResponse
(
message
)
}
func
(
session
*
session
)
KeyshareCancelled
()
{
session
.
cancel
()
}
func
(
session
*
session
)
KeyshareEnrollmentIncomplete
(
manager
irma
.
SchemeManagerIdentifier
)
{
session
.
Handler
.
KeyshareEnrollmentIncomplete
(
manager
)
}
func
(
session
*
session
)
KeyshareEnrollmentDeleted
(
manager
irma
.
SchemeManagerIdentifier
)
{
session
.
Handler
.
KeyshareEnrollmentDeleted
(
manager
)
}
func
(
session
*
session
)
KeyshareBlocked
(
manager
irma
.
SchemeManagerIdentifier
,
duration
int
)
{
session
.
Handler
.
KeyshareBlocked
(
manager
,
duration
)
}
func
(
session
*
session
)
KeyshareError
(
manager
*
irma
.
SchemeManagerIdentifier
,
err
error
)
{
var
serr
*
irma
.
SessionError
var
ok
bool
if
serr
,
ok
=
err
.
(
*
irma
.
SessionError
);
!
ok
{
serr
=
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorKeyshare
,
Err
:
err
}
}
else
{
serr
.
ErrorType
=
irma
.
ErrorKeyshare
}
session
.
fail
(
serr
)
}
func
(
session
*
session
)
KeysharePin
()
{
session
.
Handler
.
StatusUpdate
(
session
.
Action
,
irma
.
StatusConnected
)
}
func
(
session
*
session
)
KeysharePinOK
()
{
session
.
Handler
.
StatusUpdate
(
session
.
Action
,
irma
.
StatusCommunicating
)
}
type
disclosureResponse
string
type
disclosureResponse
string
// sendResponse sends the proofs of knowledge of the hidden attributes and/or the secret key, or the constructed
// sendResponse sends the proofs of knowledge of the hidden attributes and/or the secret key, or the constructed
...
@@ -581,8 +396,162 @@ func (session *session) managerSession() {
...
@@ -581,8 +396,162 @@ func (session *session) managerSession() {
return
return
}
}
// Response calculation methods
// getBuilders computes the builders for disclosure proofs or secretkey-knowledge proof (in case of disclosure/signing
// and issuing respectively).
func
(
session
*
session
)
getBuilders
()
(
gabi
.
ProofBuilderList
,
*
big
.
Int
,
error
)
{
var
builders
gabi
.
ProofBuilderList
var
err
error
var
issuerProofNonce
*
big
.
Int
switch
session
.
Action
{
case
irma
.
ActionSigning
:
builders
,
err
=
session
.
client
.
ProofBuilders
(
session
.
choice
,
session
.
request
,
true
)
case
irma
.
ActionDisclosing
:
builders
,
err
=
session
.
client
.
ProofBuilders
(
session
.
choice
,
session
.
request
,
false
)
case
irma
.
ActionIssuing
:
builders
,
issuerProofNonce
,
err
=
session
.
client
.
IssuanceProofBuilders
(
session
.
request
.
(
*
irma
.
IssuanceRequest
))
}
return
builders
,
issuerProofNonce
,
err
}
// getProofs computes the disclosure proofs or secretkey-knowledge proof (in case of disclosure/signing
// and issuing respectively) to be sent to the server.
func
(
session
*
session
)
getProof
()
(
interface
{},
error
)
{
var
message
interface
{}
var
err
error
switch
session
.
Action
{
case
irma
.
ActionSigning
:
message
,
err
=
session
.
client
.
Proofs
(
session
.
choice
,
session
.
request
,
true
)
case
irma
.
ActionDisclosing
:
message
,
err
=
session
.
client
.
Proofs
(
session
.
choice
,
session
.
request
,
false
)
case
irma
.
ActionIssuing
:
message
,
session
.
builders
,
err
=
session
.
client
.
IssueCommitments
(
session
.
request
.
(
*
irma
.
IssuanceRequest
))
}
return
message
,
err
}
// Helper functions
func
calcVersion
(
qr
*
irma
.
Qr
)
(
*
irma
.
ProtocolVersion
,
error
)
{
// Iterate supportedVersions in reverse sorted order (i.e. biggest major number first)
keys
:=
make
([]
int
,
0
,
len
(
supportedVersions
))
for
k
:=
range
supportedVersions
{
keys
=
append
(
keys
,
k
)
}
sort
.
Sort
(
sort
.
Reverse
(
sort
.
IntSlice
(
keys
)))
for
_
,
major
:=
range
keys
{
for
_
,
minor
:=
range
supportedVersions
[
major
]
{
aboveMinimum
:=
major
>
qr
.
ProtocolVersion
.
Major
||
(
major
==
qr
.
ProtocolVersion
.
Major
&&
minor
>=
qr
.
ProtocolVersion
.
Minor
)
underMaximum
:=
major
<
qr
.
ProtocolMaxVersion
.
Major
||
(
major
==
qr
.
ProtocolMaxVersion
.
Major
&&
minor
<=
qr
.
ProtocolMaxVersion
.
Minor
)
if
aboveMinimum
&&
underMaximum
{
return
irma
.
NewVersion
(
major
,
minor
),
nil
}
}
}
return
nil
,
fmt
.
Errorf
(
"No supported protocol version between %s and %s"
,
qr
.
ProtocolVersion
.
String
(),
qr
.
ProtocolMaxVersion
.
String
())
}
// checkKeyshareEnrollment checks if we are enrolled into all involved keyshare servers,
// and aborts the session if not
func
(
session
*
session
)
checkKeyshareEnrollment
()
bool
{
for
id
:=
range
session
.
request
.
Identifiers
()
.
SchemeManagers
{
manager
,
ok
:=
session
.
client
.
Configuration
.
SchemeManagers
[
id
]
if
!
ok
{
session
.
Handler
.
Failure
(
session
.
Action
,
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorUnknownSchemeManager
,
Info
:
id
.
String
()})
return
false
}
distributed
:=
manager
.
Distributed
()
_
,
enrolled
:=
session
.
client
.
keyshareServers
[
id
]
if
distributed
&&
!
enrolled
{
session
.
Handler
.
KeyshareEnrollmentMissing
(
id
)
return
false
}
}
return
true
}
func
(
session
*
session
)
checkAndUpateConfiguration
()
bool
{
for
id
:=
range
session
.
request
.
Identifiers
()
.
SchemeManagers
{
manager
,
contains
:=
session
.
client
.
Configuration
.
SchemeManagers
[
id
]
if
!
contains
{
session
.
fail
(
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorUnknownSchemeManager
,
Info
:
id
.
String
(),
})
return
false
}
if
!
manager
.
Valid
{
session
.
fail
(
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorInvalidSchemeManager
,
Info
:
string
(
manager
.
Status
),
})
return
false
}
}
// Check if we are enrolled into all involved keyshare servers
if
!
session
.
checkKeyshareEnrollment
()
{
return
false
}
// Download missing credential types/issuers/public keys from the scheme manager
downloaded
,
err
:=
session
.
client
.
Configuration
.
Download
(
session
.
request
)
if
err
!=
nil
{
session
.
fail
(
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorConfigurationDownload
,
Err
:
err
})
return
false
}
if
downloaded
!=
nil
&&
!
downloaded
.
Empty
()
{
session
.
client
.
handler
.
UpdateConfiguration
(
downloaded
)
}
return
true
}
// IsInteractive returns whether this session uses an API server or not.
func
(
session
*
session
)
IsInteractive
()
bool
{
return
session
.
ServerURL
!=
""
}
// Distributed returns whether or not this session involves a keyshare server.
func
(
session
*
session
)
Distributed
()
bool
{
var
smi
irma
.
SchemeManagerIdentifier
if
session
.
Action
==
irma
.
ActionIssuing
{
for
_
,
credreq
:=
range
session
.
request
.
(
*
irma
.
IssuanceRequest
)
.
Credentials
{
smi
=
credreq
.
CredentialTypeID
.
IssuerIdentifier
()
.
SchemeManagerIdentifier
()
if
session
.
client
.
Configuration
.
SchemeManagers
[
smi
]
.
Distributed
()
{
return
true
}
}
}
if
session
.
choice
==
nil
||
session
.
choice
.
Attributes
==
nil
{
return
false
}
for
_
,
ai
:=
range
session
.
choice
.
Attributes
{
smi
=
ai
.
Type
.
CredentialTypeIdentifier
()
.
IssuerIdentifier
()
.
SchemeManagerIdentifier
()
if
session
.
client
.
Configuration
.
SchemeManagers
[
smi
]
.
Distributed
()
{
return
true
}
}
return
false
}
// Session lifetime functions
// Session lifetime functions
func
(
session
*
session
)
recoverFromPanic
()
{
if
e
:=
recover
();
e
!=
nil
{
if
session
.
Handler
!=
nil
{
session
.
Handler
.
Failure
(
session
.
Action
,
panicToError
(
e
))
}
}
}
func
panicToError
(
e
interface
{})
*
irma
.
SessionError
{
func
panicToError
(
e
interface
{})
*
irma
.
SessionError
{
var
info
string
var
info
string
switch
x
:=
e
.
(
type
)
{
switch
x
:=
e
.
(
type
)
{
...
@@ -626,3 +595,44 @@ func (session *session) cancel() {
...
@@ -626,3 +595,44 @@ func (session *session) cancel() {
func
(
session
*
session
)
Dismiss
()
{
func
(
session
*
session
)
Dismiss
()
{
session
.
cancel
()
session
.
cancel
()
}
}
// Keyshare session handler methods
func
(
session
*
session
)
KeyshareDone
(
message
interface
{})
{
session
.
sendResponse
(
message
)
}
func
(
session
*
session
)
KeyshareCancelled
()
{
session
.
cancel
()
}
func
(
session
*
session
)
KeyshareEnrollmentIncomplete
(
manager
irma
.
SchemeManagerIdentifier
)
{
session
.
Handler
.
KeyshareEnrollmentIncomplete
(
manager
)
}
func
(
session
*
session
)
KeyshareEnrollmentDeleted
(
manager
irma
.
SchemeManagerIdentifier
)
{
session
.
Handler
.
KeyshareEnrollmentDeleted
(
manager
)
}
func
(
session
*
session
)
KeyshareBlocked
(
manager
irma
.
SchemeManagerIdentifier
,
duration
int
)
{
session
.
Handler
.
KeyshareBlocked
(
manager
,
duration
)
}
func
(
session
*
session
)
KeyshareError
(
manager
*
irma
.
SchemeManagerIdentifier
,
err
error
)
{
var
serr
*
irma
.
SessionError
var
ok
bool
if
serr
,
ok
=
err
.
(
*
irma
.
SessionError
);
!
ok
{
serr
=
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorKeyshare
,
Err
:
err
}
}
else
{
serr
.
ErrorType
=
irma
.
ErrorKeyshare
}
session
.
fail
(
serr
)
}
func
(
session
*
session
)
KeysharePin
()
{
session
.
Handler
.
StatusUpdate
(
session
.
Action
,
irma
.
StatusConnected
)
}
func
(
session
*
session
)
KeysharePinOK
()
{
session
.
Handler
.
StatusUpdate
(
session
.
Action
,
irma
.
StatusCommunicating
)
}
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