Skip to content
GitLab
Menu
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
8bac42af
Commit
8bac42af
authored
Mar 28, 2019
by
Sietse Ringers
Browse files
feat: add backwards compatibility with old format session requests
parent
47b28f82
Changes
7
Hide whitespace changes
Inline
Side-by-side
internal/servercore/handle.go
View file @
8bac42af
...
...
@@ -33,7 +33,7 @@ func (session *session) handleGetRequest(min, max *irma.ProtocolVersion) (irma.S
return
nil
,
session
.
fail
(
server
.
ErrorProtocolVersion
,
""
)
}
session
.
conf
.
Logger
.
WithFields
(
logrus
.
Fields
{
"session"
:
session
.
token
,
"version"
:
session
.
version
.
String
()})
.
Debugf
(
"Protocol version negotiated"
)
session
.
request
.
Base
()
.
Version
=
session
.
version
session
.
request
.
Base
()
.
Protocol
Version
=
session
.
version
session
.
setStatus
(
server
.
StatusConnected
)
return
session
.
request
,
nil
...
...
internal/sessiontest/handlers_test.go
View file @
8bac42af
...
...
@@ -112,10 +112,10 @@ func (th TestHandler) RequestVerificationPermission(request *irma.DisclosureRequ
callback
(
true
,
&
choice
)
}
func
(
th
TestHandler
)
RequestIssuancePermission
(
request
*
irma
.
IssuanceRequest
,
candidates
[][][]
*
irma
.
AttributeIdentifier
,
ServerName
irma
.
TranslatedString
,
callback
irmaclient
.
PermissionHandler
)
{
th
.
RequestVerificationPermission
(
request
.
DisclosureRequest
,
candidates
,
ServerName
,
callback
)
th
.
RequestVerificationPermission
(
&
request
.
DisclosureRequest
,
candidates
,
ServerName
,
callback
)
}
func
(
th
TestHandler
)
RequestSignaturePermission
(
request
*
irma
.
SignatureRequest
,
candidates
[][][]
*
irma
.
AttributeIdentifier
,
ServerName
irma
.
TranslatedString
,
callback
irmaclient
.
PermissionHandler
)
{
th
.
RequestVerificationPermission
(
request
.
DisclosureRequest
,
candidates
,
ServerName
,
callback
)
th
.
RequestVerificationPermission
(
&
request
.
DisclosureRequest
,
candidates
,
ServerName
,
callback
)
}
func
(
th
TestHandler
)
RequestSchemeManagerPermission
(
manager
*
irma
.
SchemeManager
,
callback
func
(
proceed
bool
))
{
callback
(
true
)
...
...
@@ -168,7 +168,7 @@ func (th *ManualTestHandler) Success(result string) {
th
.
c
<-
retval
}
func
(
th
*
ManualTestHandler
)
RequestSignaturePermission
(
request
*
irma
.
SignatureRequest
,
candidates
[][][]
*
irma
.
AttributeIdentifier
,
requesterName
irma
.
TranslatedString
,
ph
irmaclient
.
PermissionHandler
)
{
th
.
RequestVerificationPermission
(
request
.
DisclosureRequest
,
candidates
,
requesterName
,
ph
)
th
.
RequestVerificationPermission
(
&
request
.
DisclosureRequest
,
candidates
,
requesterName
,
ph
)
}
func
(
th
*
ManualTestHandler
)
RequestIssuancePermission
(
request
*
irma
.
IssuanceRequest
,
candidates
[][][]
*
irma
.
AttributeIdentifier
,
issuerName
irma
.
TranslatedString
,
ph
irmaclient
.
PermissionHandler
)
{
ph
(
true
,
nil
)
...
...
irmaclient/client.go
View file @
8bac42af
...
...
@@ -764,7 +764,7 @@ func (client *Client) ConstructCredentials(msg []*gabi.IssueSignatureMessage, re
continue
}
sig
:=
msg
[
i
-
offset
]
attrs
,
err
:=
request
.
Credentials
[
i
-
offset
]
.
AttributeList
(
client
.
Configuration
,
irma
.
GetMetadataVersion
(
request
.
Base
()
.
Version
))
attrs
,
err
:=
request
.
Credentials
[
i
-
offset
]
.
AttributeList
(
client
.
Configuration
,
irma
.
GetMetadataVersion
(
request
.
Base
()
.
Protocol
Version
))
if
err
!=
nil
{
return
err
}
...
...
irmaclient/session.go
View file @
8bac42af
...
...
@@ -235,12 +235,12 @@ func (session *session) processSessionInfo() {
}
baserequest
:=
session
.
request
.
Base
()
confirmedProtocolVersion
:=
baserequest
.
Version
confirmedProtocolVersion
:=
baserequest
.
Protocol
Version
if
confirmedProtocolVersion
!=
nil
{
session
.
Version
=
confirmedProtocolVersion
}
else
{
session
.
Version
=
irma
.
NewVersion
(
2
,
0
)
baserequest
.
Version
=
session
.
Version
baserequest
.
Protocol
Version
=
session
.
Version
}
session
.
ServerName
=
serverName
(
session
.
Hostname
,
session
.
request
,
session
.
client
.
Configuration
)
...
...
irmago_test.go
View file @
8bac42af
...
...
@@ -3,6 +3,7 @@ package irma
import
(
"encoding/json"
"path/filepath"
"reflect"
"testing"
"time"
...
...
@@ -248,3 +249,216 @@ func TestAttributeDecoding(t *testing.T) {
oldString
:=
decodeAttribute
(
oldAttribute
,
2
)
require
.
Equal
(
t
,
*
oldString
,
expected
)
}
func
TestSessionRequests
(
t
*
testing
.
T
)
{
attrval
:=
"hello"
sigMessage
:=
"message to be signed"
base
:=
&
DisclosureRequest
{
BaseRequest
:
BaseRequest
{
Type
:
ActionDisclosing
,
Version
:
2
},
Disclose
:
AttributeConDisCon
{
AttributeDisCon
{
AttributeCon
{
NewAttributeRequest
(
"irma-demo.MijnOverheid.ageLimits.over18"
)},
AttributeCon
{
NewAttributeRequest
(
"irma-demo.MijnOverheid.ageLimits.over21"
)},
},
AttributeDisCon
{
AttributeCon
{
AttributeRequest
{
Type
:
NewAttributeTypeIdentifier
(
"irma-demo.MijnOverheid.fullName.firstname"
),
Value
:
&
attrval
}},
},
},
Labels
:
map
[
int
]
TranslatedString
{
0
:
trivialTranslation
(
"Age limit"
),
1
:
trivialTranslation
(
"First name"
)},
}
tests
:=
[]
struct
{
oldJson
,
currentJson
string
old
,
current
,
expected
SessionRequest
}{
{
expected
:
base
,
old
:
&
DisclosureRequest
{},
oldJson
:
`{
"type": "disclosing",
"content": [{
"label": "Age limit",
"attributes": [
"irma-demo.MijnOverheid.ageLimits.over18",
"irma-demo.MijnOverheid.ageLimits.over21"
]
},
{
"label": "First name",
"attributes": {
"irma-demo.MijnOverheid.fullName.firstname": "hello"
}
}]
}`
,
current
:
&
DisclosureRequest
{},
currentJson
:
`{
"type": "disclosing",
"v": 2,
"disclose": [
[
[
"irma-demo.MijnOverheid.ageLimits.over18"
],
[
"irma-demo.MijnOverheid.ageLimits.over21"
]
],
[
{
"irma-demo.MijnOverheid.fullName.firstname": "hello"
}
]
],
"labels": {
"0": {
"en": "Age limit",
"nl": "Age limit"
},
"1": {
"en": "First name",
"nl": "First name"
}
}
}`
,
},
{
expected
:
&
SignatureRequest
{
DisclosureRequest
{
BaseRequest
{
Type
:
ActionSigning
,
Version
:
2
},
base
.
Disclose
,
base
.
Labels
},
sigMessage
,
},
old
:
&
SignatureRequest
{},
oldJson
:
`{
"type": "signing",
"message": "message to be signed",
"content": [{
"label": "Age limit",
"attributes": [
"irma-demo.MijnOverheid.ageLimits.over18",
"irma-demo.MijnOverheid.ageLimits.over21"
]
},
{
"label": "First name",
"attributes": {
"irma-demo.MijnOverheid.fullName.firstname": "hello"
}
}]
}`
,
current
:
&
SignatureRequest
{},
currentJson
:
`{
"type": "signing",
"v": 2,
"disclose": [
[
[
"irma-demo.MijnOverheid.ageLimits.over18"
],
[
"irma-demo.MijnOverheid.ageLimits.over21"
]
],
[
{
"irma-demo.MijnOverheid.fullName.firstname": "hello"
}
]
],
"labels": {
"0": {
"en": "Age limit",
"nl": "Age limit"
},
"1": {
"en": "First name",
"nl": "First name"
}
},
"message": "message to be signed"
}`
,
},
{
expected
:
&
IssuanceRequest
{
DisclosureRequest
:
DisclosureRequest
{
BaseRequest
{
Type
:
ActionIssuing
,
Version
:
2
},
base
.
Disclose
,
base
.
Labels
},
Credentials
:
[]
*
CredentialRequest
{
{
CredentialTypeID
:
NewCredentialTypeIdentifier
(
"irma-demo.MijnOverheid.root"
),
Attributes
:
map
[
string
]
string
{
"BSN"
:
"12345"
},
},
},
},
old
:
&
IssuanceRequest
{},
oldJson
:
`{
"type": "issuing",
"credentials": [{
"credential": "irma-demo.MijnOverheid.root",
"attributes": { "BSN": "12345" }
}],
"disclose": [{
"label": "Age limit",
"attributes": [
"irma-demo.MijnOverheid.ageLimits.over18",
"irma-demo.MijnOverheid.ageLimits.over21"
]
},
{
"label": "First name",
"attributes": {
"irma-demo.MijnOverheid.fullName.firstname": "hello"
}
}]
}`
,
current
:
&
IssuanceRequest
{},
currentJson
:
`{
"type": "issuing",
"v": 2,
"credentials": [
{
"credential": "irma-demo.MijnOverheid.root",
"attributes": {
"BSN": "12345"
}
}
],
"disclose": [
[
[
"irma-demo.MijnOverheid.ageLimits.over18"
],
[
"irma-demo.MijnOverheid.ageLimits.over21"
]
],
[
{
"irma-demo.MijnOverheid.fullName.firstname": "hello"
}
]
],
"labels": {
"0": {
"en": "Age limit",
"nl": "Age limit"
},
"1": {
"en": "First name",
"nl": "First name"
}
}
}`
,
},
}
for
_
,
tst
:=
range
tests
{
require
.
NoError
(
t
,
json
.
Unmarshal
([]
byte
(
tst
.
oldJson
),
tst
.
old
))
require
.
NoError
(
t
,
json
.
Unmarshal
([]
byte
(
tst
.
currentJson
),
tst
.
current
))
require
.
True
(
t
,
reflect
.
DeepEqual
(
tst
.
old
,
tst
.
expected
),
"Legacy %s did not unmarshal to expected value"
,
reflect
.
TypeOf
(
tst
.
old
)
.
String
())
require
.
True
(
t
,
reflect
.
DeepEqual
(
tst
.
current
,
tst
.
expected
),
"%s did not unmarshal to expected value"
,
reflect
.
TypeOf
(
tst
.
old
)
.
String
())
}
}
func
trivialTranslation
(
str
string
)
TranslatedString
{
return
TranslatedString
{
"en"
:
str
,
"nl"
:
str
}
}
legacy.go
0 → 100644
View file @
8bac42af
package
irma
import
(
"encoding/json"
"github.com/go-errors/errors"
)
type
legacyAttributeDisjunction
[]
AttributeRequest
type
attributeDisjunction
struct
{
Label
string
Attributes
legacyAttributeDisjunction
}
type
legacyDisclosureRequest
struct
{
BaseRequest
Content
[]
attributeDisjunction
`json:"content"`
}
func
convertDisjunctions
(
disjunctions
[]
attributeDisjunction
)
(
condiscon
AttributeConDisCon
,
labels
map
[
int
]
TranslatedString
,
)
{
labels
=
make
(
map
[
int
]
TranslatedString
)
condiscon
=
make
(
AttributeConDisCon
,
len
(
disjunctions
))
for
i
,
dis
:=
range
disjunctions
{
condiscon
[
i
]
=
AttributeDisCon
{}
for
_
,
attr
:=
range
dis
.
Attributes
{
condiscon
[
i
]
=
append
(
condiscon
[
i
],
AttributeCon
{{
Type
:
attr
.
Type
,
Value
:
attr
.
Value
}})
}
labels
[
i
]
=
TranslatedString
{
"en"
:
dis
.
Label
,
"nl"
:
dis
.
Label
}
}
return
}
func
parseVersion
(
bts
[]
byte
)
(
int
,
error
)
{
var
v
struct
{
Version
int
`json:"v"`
}
if
err
:=
json
.
Unmarshal
(
bts
,
&
v
);
err
!=
nil
{
return
0
,
err
}
return
v
.
Version
,
nil
}
func
checkType
(
typ
,
expected
Action
)
error
{
if
typ
!=
expected
{
return
errors
.
New
(
"not a "
+
expected
+
" session request"
)
}
return
nil
}
// Reuses AttributeCon.UnmarshalJSON()
func
(
l
*
legacyAttributeDisjunction
)
UnmarshalJSON
(
bts
[]
byte
)
error
{
var
con
AttributeCon
if
err
:=
json
.
Unmarshal
(
bts
,
&
con
);
err
!=
nil
{
return
err
}
*
l
=
legacyAttributeDisjunction
(
con
)
return
nil
}
func
(
dr
*
DisclosureRequest
)
UnmarshalJSON
(
bts
[]
byte
)
(
err
error
)
{
var
version
int
if
version
,
err
=
parseVersion
(
bts
);
err
!=
nil
{
return
err
}
if
version
>=
2
{
type
newDisclosureRequest
DisclosureRequest
// Same type with default JSON unmarshaler
var
req
newDisclosureRequest
if
err
=
json
.
Unmarshal
(
bts
,
&
req
);
err
!=
nil
{
return
err
}
*
dr
=
DisclosureRequest
(
req
)
return
nil
}
var
legacy
legacyDisclosureRequest
if
err
=
json
.
Unmarshal
(
bts
,
&
legacy
);
err
!=
nil
{
return
err
}
dr
.
BaseRequest
=
legacy
.
BaseRequest
dr
.
Version
=
2
dr
.
Disclose
,
dr
.
Labels
=
convertDisjunctions
(
legacy
.
Content
)
return
checkType
(
legacy
.
Type
,
ActionDisclosing
)
}
func
(
sr
*
SignatureRequest
)
UnmarshalJSON
(
bts
[]
byte
)
(
err
error
)
{
var
version
int
if
version
,
err
=
parseVersion
(
bts
);
err
!=
nil
{
return
err
}
if
version
>=
2
{
var
req
struct
{
// Identical type with default JSON unmarshaler
BaseRequest
Disclose
AttributeConDisCon
`json:"disclose"`
Labels
map
[
int
]
TranslatedString
`json:"labels"`
Message
string
`json"string"`
}
if
err
=
json
.
Unmarshal
(
bts
,
&
req
);
err
!=
nil
{
return
err
}
*
sr
=
SignatureRequest
{
DisclosureRequest
{
req
.
BaseRequest
,
req
.
Disclose
,
req
.
Labels
,
},
req
.
Message
,
}
return
nil
}
var
legacy
struct
{
legacyDisclosureRequest
Message
string
`json:"message"`
}
if
err
=
json
.
Unmarshal
(
bts
,
&
legacy
);
err
!=
nil
{
return
err
}
sr
.
BaseRequest
=
legacy
.
BaseRequest
sr
.
Version
=
2
sr
.
Disclose
,
sr
.
Labels
=
convertDisjunctions
(
legacy
.
Content
)
sr
.
Message
=
legacy
.
Message
return
checkType
(
legacy
.
Type
,
ActionSigning
)
}
func
(
ir
*
IssuanceRequest
)
UnmarshalJSON
(
bts
[]
byte
)
(
err
error
)
{
var
version
int
if
version
,
err
=
parseVersion
(
bts
);
err
!=
nil
{
return
err
}
if
version
>=
2
{
var
req
struct
{
// Identical type with default JSON unmarshaler
BaseRequest
Disclose
AttributeConDisCon
`json:"disclose"`
Labels
map
[
int
]
TranslatedString
`json:"labels"`
Credentials
[]
*
CredentialRequest
`json:"credentials"`
}
if
err
=
json
.
Unmarshal
(
bts
,
&
req
);
err
!=
nil
{
return
err
}
*
ir
=
IssuanceRequest
{
DisclosureRequest
:
DisclosureRequest
{
req
.
BaseRequest
,
req
.
Disclose
,
req
.
Labels
},
Credentials
:
req
.
Credentials
,
}
return
nil
}
var
legacy
struct
{
BaseRequest
Credentials
[]
*
CredentialRequest
`json:"credentials"`
Disclose
[]
attributeDisjunction
`json:"disclose"`
}
if
err
=
json
.
Unmarshal
(
bts
,
&
legacy
);
err
!=
nil
{
return
err
}
ir
.
BaseRequest
=
legacy
.
BaseRequest
ir
.
Version
=
2
ir
.
Credentials
=
legacy
.
Credentials
ir
.
Disclose
,
ir
.
Labels
=
convertDisjunctions
(
legacy
.
Disclose
)
return
checkType
(
legacy
.
Type
,
ActionIssuing
)
}
requests.go
View file @
8bac42af
...
...
@@ -19,11 +19,13 @@ import (
type
BaseRequest
struct
{
// Denotes session type, must be "disclosing", "signing" or "issuing"
Type
Action
`json:"type"`
// Message version. Current version is 2.
Version
int
`json:"v"`
// Chosen by the IRMA server during the session
Context
*
big
.
Int
`json:"context,omitempty"`
Nonce
*
big
.
Int
`json:"nonce,omitempty"`
Version
*
ProtocolVersion
`json:"protocolVersion,omitempty"`
Context
*
big
.
Int
`json:"context,omitempty"`
Nonce
*
big
.
Int
`json:"nonce,omitempty"`
Protocol
Version
*
ProtocolVersion
`json:"protocolVersion,omitempty"`
// cache for Identifiers() method
ids
*
IrmaIdentifierSet
...
...
@@ -38,7 +40,8 @@ type AttributeDisCon []AttributeCon
// AttributeConDisCon is only satisfied if all of the containing AttributeDisCon are satisfied.
type
AttributeConDisCon
[]
AttributeDisCon
// A DisclosureRequest is a request to disclose certain attributes.
// A DisclosureRequest is a request to disclose certain attributes. Construct new instances using
// NewDisclosureRequest().
type
DisclosureRequest
struct
{
BaseRequest
...
...
@@ -46,16 +49,18 @@ type DisclosureRequest struct {
Labels
map
[
int
]
TranslatedString
`json:"labels"`
}
// A SignatureRequest is a a request to sign a message with certain attributes.
// A SignatureRequest is a a request to sign a message with certain attributes. Construct new
// instances using NewSignatureRequest().
type
SignatureRequest
struct
{
*
DisclosureRequest
DisclosureRequest
Message
string
`json:"message"`
}
// An IssuanceRequest is a request to issue certain credentials,
// optionally also asking for certain attributes to be simultaneously disclosed.
// optionally also asking for certain attributes to be simultaneously disclosed. Construct new
// instances using NewIssuanceRequest().
type
IssuanceRequest
struct
{
*
DisclosureRequest
DisclosureRequest
Credentials
[]
*
CredentialRequest
`json:"credentials"`
// Derived data
...
...
@@ -221,6 +226,15 @@ func (c *AttributeCon) MarshalJSON() ([]byte, error) {
func
(
c
*
AttributeCon
)
UnmarshalJSON
(
bts
[]
byte
)
error
{
var
err
error
var
l
[]
AttributeTypeIdentifier
if
err
=
json
.
Unmarshal
(
bts
,
&
l
);
err
==
nil
{
for
_
,
id
:=
range
l
{
*
c
=
append
(
*
c
,
AttributeRequest
{
Type
:
id
})
}
return
nil
}
m
:=
map
[
AttributeTypeIdentifier
]
*
string
{}
if
err
=
json
.
Unmarshal
(
bts
,
&
m
);
err
==
nil
{
for
id
,
val
:=
range
m
{
...
...
@@ -229,14 +243,13 @@ func (c *AttributeCon) UnmarshalJSON(bts []byte) error {
return
nil
}
var
l
[]
AttributeTypeIdentifier
if
err
=
json
.
Unmarshal
(
bts
,
&
l
);
err
==
nil
{
for
_
,
id
:=
range
l
{
*
c
=
append
(
*
c
,
AttributeRequest
{
Type
:
id
})
}
var
s
string
if
err
=
json
.
Unmarshal
(
bts
,
&
s
);
err
==
nil
{
*
c
=
append
(
*
c
,
NewAttributeRequest
(
s
))
return
nil
}
return
err
return
err
ors
.
New
(
"Failed to unmarshal attribute conjunction"
)
}
func
(
ar
*
AttributeRequest
)
Satisfy
(
attr
AttributeTypeIdentifier
,
val
*
string
)
bool
{
...
...
@@ -317,7 +330,7 @@ func (dr *DisclosureRequest) AddSingle(attr AttributeTypeIdentifier, value *stri
func
NewDisclosureRequest
(
attrs
...
AttributeTypeIdentifier
)
*
DisclosureRequest
{
request
:=
&
DisclosureRequest
{
BaseRequest
:
BaseRequest
{
Type
:
ActionDisclosing
},
BaseRequest
:
BaseRequest
{
Type
:
ActionDisclosing
,
Version
:
2
},
Labels
:
map
[
int
]
TranslatedString
{},
}
for
_
,
attr
:=
range
attrs
{
...
...
@@ -330,7 +343,7 @@ func NewSignatureRequest(message string, attrs ...AttributeTypeIdentifier) *Sign
dr
:=
NewDisclosureRequest
(
attrs
...
)
dr
.
Type
=
ActionSigning
return
&
SignatureRequest
{
DisclosureRequest
:
dr
,
DisclosureRequest
:
*
dr
,
Message
:
message
,
}
}
...
...
@@ -339,7 +352,7 @@ func NewIssuanceRequest(creds []*CredentialRequest, attrs ...AttributeTypeIdenti
dr
:=
NewDisclosureRequest
(
attrs
...
)
dr
.
Type
=
ActionIssuing
return
&
IssuanceRequest
{
DisclosureRequest
:
dr
,
DisclosureRequest
:
*
dr
,
Credentials
:
creds
,
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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