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
bfcb58de
Commit
bfcb58de
authored
Feb 25, 2018
by
Sietse Ringers
Browse files
Add auto-issuance of keyshare login attribute to keyshare server enrolling
parent
f4262fdf
Changes
5
Hide whitespace changes
Inline
Side-by-side
irmaclient/client.go
View file @
bfcb58de
...
...
@@ -668,14 +668,10 @@ func (client *Client) KeyshareEnroll(manager irma.SchemeManagerIdentifier, email
}()
err
:=
client
.
keyshareEnrollWorker
(
manager
,
email
,
pin
)
client
.
UnenrolledSchemeManagers
=
client
.
unenrolledSchemeManagers
()
if
err
!=
nil
{
client
.
handler
.
EnrollmentError
(
manager
,
err
)
}
else
{
client
.
handler
.
EnrollmentSuccess
(
manager
)
}
}()
}
func
(
client
*
Client
)
keyshareEnrollWorker
(
managerID
irma
.
SchemeManagerIdentifier
,
email
,
pin
string
)
error
{
...
...
@@ -696,19 +692,30 @@ func (client *Client) keyshareEnrollWorker(managerID irma.SchemeManagerIdentifie
return
err
}
message
:=
keyshareEnrollment
{
Username
:
email
,
Email
:
email
,
Pin
:
kss
.
HashedPin
(
pin
),
PublicKey
:
(
*
paillierPublicKey
)(
&
kss
.
PrivateKey
.
PublicKey
),
}
result
:=
&
struct
{}
{}
err
=
transport
.
Post
(
"
web/users/selfenroll"
,
result
,
message
)
qr
:=
&
irma
.
Qr
{}
err
=
transport
.
Post
(
"
client/register"
,
qr
,
message
)
if
err
!=
nil
{
return
err
}
// We add the new keyshare server to the client here, without saving it to disk,
// and start the issuance session for the keyshare server login attribute -
// keyshare.go needs the relevant keyshare server to be present in the client.
// If the session succeeds or fails, the keyshare server is stored to disk or
// removed from the client by the keyshareEnrollmentHandler.
client
.
keyshareServers
[
managerID
]
=
kss
return
client
.
storage
.
StoreKeyshareServers
(
client
.
keyshareServers
)
client
.
NewSession
(
qr
,
&
keyshareEnrollmentHandler
{
client
:
client
,
pin
:
pin
,
kss
:
kss
,
})
return
nil
}
// KeyshareRemove unenrolls the keyshare server of the specified scheme manager.
...
...
irmaclient/handlers.go
0 → 100644
View file @
bfcb58de
package
irmaclient
import
(
"github.com/go-errors/errors"
"github.com/privacybydesign/irmago"
)
// keyshareEnrollmentHandler handles the keyshare attribute issuance session
// after registering to a new keyshare server.
type
keyshareEnrollmentHandler
struct
{
pin
string
client
*
Client
kss
*
keyshareServer
}
// Force keyshareEnrollmentHandler to implement the Handler interface
var
_
Handler
=
(
*
keyshareEnrollmentHandler
)(
nil
)
// Session handlers in the order they are called
func
(
h
*
keyshareEnrollmentHandler
)
RequestIssuancePermission
(
request
irma
.
IssuanceRequest
,
ServerName
string
,
callback
PermissionHandler
)
{
h
.
kss
.
Username
=
request
.
Credentials
[
0
]
.
Attributes
[
"email"
]
// TODO magic string
h
.
client
.
storage
.
StoreKeyshareServers
(
h
.
client
.
keyshareServers
)
callback
(
true
,
nil
)
}
func
(
h
*
keyshareEnrollmentHandler
)
RequestPin
(
remainingAttempts
int
,
callback
PinHandler
)
{
if
remainingAttempts
==
-
1
{
// -1 signifies that this is the first attempt
callback
(
true
,
h
.
pin
)
}
else
{
h
.
fail
(
errors
.
New
(
"PIN incorrect"
))
}
}
func
(
h
*
keyshareEnrollmentHandler
)
Success
(
action
irma
.
Action
,
result
string
)
{
_
=
h
.
client
.
storage
.
StoreKeyshareServers
(
h
.
client
.
keyshareServers
)
// TODO handle err?
h
.
client
.
UnenrolledSchemeManagers
=
h
.
client
.
unenrolledSchemeManagers
()
h
.
client
.
handler
.
EnrollmentSuccess
(
h
.
kss
.
SchemeManagerIdentifier
)
}
func
(
h
*
keyshareEnrollmentHandler
)
Failure
(
action
irma
.
Action
,
err
*
irma
.
SessionError
)
{
h
.
fail
(
err
)
}
// fail is a helper to ensure the kss is removed from the client in case of any problem
func
(
h
*
keyshareEnrollmentHandler
)
fail
(
err
error
)
{
delete
(
h
.
client
.
keyshareServers
,
h
.
kss
.
SchemeManagerIdentifier
)
h
.
client
.
handler
.
EnrollmentError
(
h
.
kss
.
SchemeManagerIdentifier
,
err
)
}
// Not interested, ingore
func
(
h
*
keyshareEnrollmentHandler
)
StatusUpdate
(
action
irma
.
Action
,
status
irma
.
Status
)
{}
// The methods below should never be called, so we let each of them fail the session
func
(
h
*
keyshareEnrollmentHandler
)
RequestVerificationPermission
(
request
irma
.
DisclosureRequest
,
ServerName
string
,
callback
PermissionHandler
)
{
callback
(
false
,
nil
)
}
func
(
h
*
keyshareEnrollmentHandler
)
RequestSignaturePermission
(
request
irma
.
SignatureRequest
,
ServerName
string
,
callback
PermissionHandler
)
{
callback
(
false
,
nil
)
}
func
(
h
*
keyshareEnrollmentHandler
)
RequestSchemeManagerPermission
(
manager
*
irma
.
SchemeManager
,
callback
func
(
proceed
bool
))
{
callback
(
false
)
}
func
(
h
*
keyshareEnrollmentHandler
)
Cancelled
(
action
irma
.
Action
)
{
h
.
fail
(
errors
.
New
(
"Keyshare enrollment session unexpectedly cancelled"
))
}
func
(
h
*
keyshareEnrollmentHandler
)
KeyshareBlocked
(
manager
irma
.
SchemeManagerIdentifier
,
duration
int
)
{
h
.
fail
(
errors
.
New
(
"Keyshare enrollment failed: blocked"
))
}
func
(
h
*
keyshareEnrollmentHandler
)
KeyshareEnrollmentIncomplete
(
manager
irma
.
SchemeManagerIdentifier
)
{
h
.
fail
(
errors
.
New
(
"Keyshare enrollment failed: registration incomplete"
))
}
func
(
h
*
keyshareEnrollmentHandler
)
KeyshareEnrollmentMissing
(
manager
irma
.
SchemeManagerIdentifier
)
{
h
.
fail
(
errors
.
New
(
"Keyshare enrollment failed: unenrolled"
))
}
func
(
h
*
keyshareEnrollmentHandler
)
UnsatisfiableRequest
(
action
irma
.
Action
,
ServerName
string
,
missing
irma
.
AttributeDisjunctionList
)
{
h
.
fail
(
errors
.
New
(
"Keyshare enrollment failed: unsatisfiable"
))
}
irmaclient/irmaclient_test.go
View file @
bfcb58de
...
...
@@ -20,12 +20,26 @@ func TestMain(m *testing.M) {
os
.
Exit
(
retCode
)
}
type
IgnoringClientHandler
struct
{}
type
TestClientHandler
struct
{
t
*
testing
.
T
c
chan
error
}
func
(
i
*
IgnoringClientHandler
)
UpdateConfiguration
(
new
*
irma
.
IrmaIdentifierSet
)
{}
func
(
i
*
IgnoringClientHandler
)
UpdateAttributes
()
{}
func
(
i
*
IgnoringClientHandler
)
EnrollmentError
(
manager
irma
.
SchemeManagerIdentifier
,
err
error
)
{}
func
(
i
*
IgnoringClientHandler
)
EnrollmentSuccess
(
manager
irma
.
SchemeManagerIdentifier
)
{}
func
(
i
*
TestClientHandler
)
UpdateConfiguration
(
new
*
irma
.
IrmaIdentifierSet
)
{}
func
(
i
*
TestClientHandler
)
UpdateAttributes
()
{}
func
(
i
*
TestClientHandler
)
EnrollmentSuccess
(
manager
irma
.
SchemeManagerIdentifier
)
{
select
{
case
i
.
c
<-
nil
:
// nop
default
:
// nop
}
}
func
(
i
*
TestClientHandler
)
EnrollmentError
(
manager
irma
.
SchemeManagerIdentifier
,
err
error
)
{
select
{
case
i
.
c
<-
err
:
// nop
default
:
i
.
t
.
Fatal
(
err
)
}
}
func
parseStorage
(
t
*
testing
.
T
)
*
Client
{
require
.
NoError
(
t
,
fs
.
CopyDirectory
(
"../testdata/teststorage"
,
"../testdata/storage/test"
))
...
...
@@ -33,7 +47,7 @@ func parseStorage(t *testing.T) *Client {
"../testdata/storage/test"
,
"../testdata/irma_configuration"
,
""
,
&
Ignoring
ClientHandler
{},
&
Test
ClientHandler
{
t
:
t
},
)
require
.
NoError
(
t
,
err
)
return
manager
...
...
irmaclient/keyshare.go
View file @
bfcb58de
...
...
@@ -57,6 +57,7 @@ type keyshareEnrollment struct {
Username
string
`json:"username"`
Pin
string
`json:"pin"`
PublicKey
*
paillierPublicKey
`json:"publicKey"`
Email
string
`json:"email"`
}
type
keyshareAuthorization
struct
{
...
...
irmaclient/session_test.go
View file @
bfcb58de
...
...
@@ -249,24 +249,7 @@ func sessionHandlerHelper(t *testing.T, jwtcontents interface{}, url string, cli
}
}
func
enrollKeyshareServer
(
t
*
testing
.
T
,
client
*
Client
)
{
bytes
:=
make
([]
byte
,
8
,
8
)
rand
.
Read
(
bytes
)
email
:=
fmt
.
Sprintf
(
"%s@example.com"
,
hex
.
EncodeToString
(
bytes
))
require
.
NoError
(
t
,
client
.
keyshareEnrollWorker
(
irma
.
NewSchemeManagerIdentifier
(
"test"
),
email
,
"12345"
))
}
// Enroll at a keyshare server and do an issuance, disclosure,
// and issuance session, also using irma-demo credentials deserialized from Android storage
func
TestKeyshareEnrollmentAndSessions
(
t
*
testing
.
T
)
{
client
:=
parseStorage
(
t
)
require
.
NoError
(
t
,
client
.
RemoveCredentialByHash
(
client
.
Attributes
(
irma
.
NewCredentialTypeIdentifier
(
"test.test.mijnirma"
),
0
)
.
Hash
(),
))
require
.
NoError
(
t
,
client
.
KeyshareRemove
(
irma
.
NewSchemeManagerIdentifier
(
"test"
)))
enrollKeyshareServer
(
t
,
client
)
func
keyshareSessions
(
t
*
testing
.
T
,
client
*
Client
)
{
id
:=
irma
.
NewAttributeTypeIdentifier
(
"irma-demo.RU.studentCard.studentID"
)
expiry
:=
irma
.
Timestamp
(
irma
.
NewMetadataAttribute
()
.
Expiry
())
credid
:=
irma
.
NewCredentialTypeIdentifier
(
"test.test.mijnirma"
)
...
...
@@ -300,6 +283,34 @@ func TestKeyshareEnrollmentAndSessions(t *testing.T) {
},
)
sessionHelper
(
t
,
jwt
,
"signature"
,
client
)
}
// Enroll at a keyshare server and do an issuance, disclosure,
// and issuance session, also using irma-demo credentials deserialized from Android storage
func
TestKeyshareEnrollmentAndSessions
(
t
*
testing
.
T
)
{
client
:=
parseStorage
(
t
)
credtype
:=
irma
.
NewCredentialTypeIdentifier
(
"test.test.mijnirma"
)
// Remove existing registration at test keyshare server
require
.
NoError
(
t
,
client
.
RemoveCredentialByHash
(
client
.
Attributes
(
credtype
,
0
)
.
Hash
(),
))
require
.
NoError
(
t
,
client
.
KeyshareRemove
(
irma
.
NewSchemeManagerIdentifier
(
"test"
)))
// Do a new registration session
c
:=
make
(
chan
error
)
// channel for TestClientHandler to inform us of result
client
.
handler
.
(
*
TestClientHandler
)
.
c
=
c
bytes
:=
make
([]
byte
,
8
,
8
)
rand
.
Read
(
bytes
)
email
:=
fmt
.
Sprintf
(
"%s@example.com"
,
hex
.
EncodeToString
(
bytes
))
require
.
NoError
(
t
,
client
.
keyshareEnrollWorker
(
irma
.
NewSchemeManagerIdentifier
(
"test"
),
email
,
"12345"
))
if
err
:=
<-
c
;
err
!=
nil
{
t
.
Fatal
(
err
)
}
require
.
NotNil
(
t
,
client
.
Attributes
(
credtype
,
0
))
keyshareSessions
(
t
,
client
)
test
.
ClearTestStorage
(
t
)
}
...
...
@@ -309,40 +320,8 @@ func TestKeyshareEnrollmentAndSessions(t *testing.T) {
// Use keyshareuser.sql to enroll the user at the keyshare server.
func
TestKeyshareSessions
(
t
*
testing
.
T
)
{
client
:=
parseStorage
(
t
)
id
:=
irma
.
NewAttributeTypeIdentifier
(
"irma-demo.RU.studentCard.studentID"
)
expiry
:=
irma
.
Timestamp
(
irma
.
NewMetadataAttribute
()
.
Expiry
())
credid
:=
irma
.
NewCredentialTypeIdentifier
(
"test.test.mijnirma"
)
jwt
:=
getCombinedJwt
(
"testip"
,
id
)
jwt
.
(
*
irma
.
IdentityProviderJwt
)
.
Request
.
Request
.
Credentials
=
append
(
jwt
.
(
*
irma
.
IdentityProviderJwt
)
.
Request
.
Request
.
Credentials
,
&
irma
.
CredentialRequest
{
Validity
:
&
expiry
,
CredentialTypeID
:
&
credid
,
Attributes
:
map
[
string
]
string
{
"email"
:
"example@example.com"
},
},
)
sessionHelper
(
t
,
jwt
,
"issue"
,
client
)
jwt
=
getDisclosureJwt
(
"testsp"
,
id
)
jwt
.
(
*
irma
.
ServiceProviderJwt
)
.
Request
.
Request
.
Content
=
append
(
jwt
.
(
*
irma
.
ServiceProviderJwt
)
.
Request
.
Request
.
Content
,
//[]*AttributeDisjunction{},
&
irma
.
AttributeDisjunction
{
Label
:
"foo"
,
Attributes
:
[]
irma
.
AttributeTypeIdentifier
{
irma
.
NewAttributeTypeIdentifier
(
"test.test.mijnirma.email"
)},
},
)
sessionHelper
(
t
,
jwt
,
"verification"
,
client
)
jwt
=
getSigningJwt
(
"testsigclient"
,
id
)
jwt
.
(
*
irma
.
SignatureRequestorJwt
)
.
Request
.
Request
.
Content
=
append
(
jwt
.
(
*
irma
.
SignatureRequestorJwt
)
.
Request
.
Request
.
Content
,
//[]*AttributeDisjunction{},
&
irma
.
AttributeDisjunction
{
Label
:
"foo"
,
Attributes
:
[]
irma
.
AttributeTypeIdentifier
{
irma
.
NewAttributeTypeIdentifier
(
"test.test.mijnirma.email"
)},
},
)
sessionHelper
(
t
,
jwt
,
"signature"
,
client
)
keyshareSessions
(
t
,
client
)
test
.
ClearTestStorage
(
t
)
}
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