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
65876b5f
Commit
65876b5f
authored
Aug 25, 2017
by
Sietse Ringers
Browse files
Improve protocol version negotiation, identifier serialization, HTTP error handling
parent
808ddb58
Changes
4
Hide whitespace changes
Inline
Side-by-side
identifiers.go
View file @
65876b5f
package
irmago
import
"strings"
import
(
"encoding/json"
"strings"
)
type
metaObjectIdentifier
string
...
...
@@ -92,3 +95,11 @@ func (id AttributeTypeIdentifier) IsCredential() bool {
func
(
ai
*
AttributeIdentifier
)
CredentialIdentifier
()
CredentialIdentifier
{
return
CredentialIdentifier
{
Type
:
ai
.
Type
.
CredentialTypeIdentifier
(),
Index
:
ai
.
Index
,
Count
:
ai
.
Count
}
}
func
(
id
AttributeTypeIdentifier
)
MarshalJSON
()
([]
byte
,
error
)
{
return
json
.
Marshal
(
id
.
String
())
}
func
(
id
CredentialTypeIdentifier
)
MarshalJSON
()
([]
byte
,
error
)
{
return
json
.
Marshal
(
id
.
String
())
}
protocol/session.go
View file @
65876b5f
...
...
@@ -4,8 +4,13 @@ import (
"encoding/json"
"errors"
"math/big"
"strconv"
"strings"
"sort"
"fmt"
"github.com/credentials/irmago"
"github.com/mhe/gabi"
)
...
...
@@ -42,15 +47,49 @@ type Session struct {
context
*
big
.
Int
}
// Supported protocol versions. Minor version numbers should be reverse sorted.
var
supportedVersions
=
map
[
int
][]
int
{
2
:
[]
int
{
2
,
1
},
}
func
calcVersion
(
qr
*
Qr
)
(
string
,
error
)
{
// Parse range supported by server
minmajor
,
err
:=
strconv
.
Atoi
(
string
(
qr
.
ProtocolVersion
[
0
]))
minminor
,
err
:=
strconv
.
Atoi
(
string
(
qr
.
ProtocolVersion
[
2
]))
maxmajor
,
err
:=
strconv
.
Atoi
(
string
(
qr
.
ProtocolMaxVersion
[
0
]))
maxminor
,
err
:=
strconv
.
Atoi
(
string
(
qr
.
ProtocolMaxVersion
[
2
]))
if
err
!=
nil
{
return
""
,
err
}
// 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
>
minmajor
||
(
major
==
minmajor
&&
minor
>=
minminor
)
underMaximum
:=
major
<
maxmajor
||
(
major
==
maxmajor
&&
minor
<=
maxminor
)
if
aboveMinimum
&&
underMaximum
{
return
fmt
.
Sprintf
(
"%d.%d"
,
major
,
minor
),
nil
}
}
}
return
""
,
fmt
.
Errorf
(
"No supported protocol version between %s and %s"
,
qr
.
ProtocolVersion
,
qr
.
ProtocolMaxVersion
)
}
// NewSession creates and starts a new IRMA session.
func
NewSession
(
qr
*
Qr
,
handler
Handler
)
*
Session
{
if
qr
.
ProtocolVersion
!=
"2.1"
&&
qr
.
ProtocolVersion
!=
"2.2"
{
// TODO version negotiation
handler
.
Failure
(
ActionUnknown
,
ErrorProtocolVersionNotSupported
,
qr
.
ProtocolVersion
)
version
,
err
:=
calcVersion
(
qr
)
if
err
!=
nil
{
handler
.
Failure
(
ActionUnknown
,
ErrorProtocolVersionNotSupported
,
err
.
Error
())
return
nil
}
session
:=
&
Session
{
Version
:
Version
(
qr
.
ProtocolV
ersion
),
Version
:
Version
(
v
ersion
),
Action
:
Action
(
qr
.
Type
),
ServerURL
:
qr
.
URL
,
Handler
:
handler
,
...
...
protocol/session_test.go
View file @
65876b5f
...
...
@@ -6,6 +6,8 @@ import (
"encoding/base64"
"fmt"
"github.com/credentials/irmago"
"github.com/stretchr/testify/require"
)
...
...
@@ -44,8 +46,8 @@ func (th TestHandler) AskSignaturePermission(request SignatureRequest, ServerNam
}
func
TestSession
(
t
*
testing
.
T
)
{
id
:=
irmago
.
NewAttributeTypeIdentifier
(
"irma-demo.RU.studentCard.student
Number
"
)
url
:=
"https://demo.irmacard.org/tomcat/irma_api_server/api/v2"
id
:=
irmago
.
NewAttributeTypeIdentifier
(
"irma-demo.RU.studentCard.student
ID
"
)
url
:=
"https://demo.irmacard.org/tomcat/irma_api_server/api/v2
/verification
"
name
:=
"testsp"
spRequest
:=
NewServiceProviderJwt
(
name
,
DisclosureRequest
{
...
...
@@ -56,6 +58,7 @@ func TestSession(t *testing.T) {
},
}),
})
fmt
.
Printf
(
"%+v
\n
"
,
spRequest
.
Request
.
Request
.
Content
[
0
])
headerbytes
,
err
:=
json
.
Marshal
(
&
map
[
string
]
string
{
"alg"
:
"none"
,
"typ"
:
"JWT"
})
require
.
NoError
(
t
,
err
)
...
...
@@ -63,8 +66,12 @@ func TestSession(t *testing.T) {
require
.
NoError
(
t
,
err
)
jwt
:=
base64
.
StdEncoding
.
EncodeToString
(
headerbytes
)
+
"."
+
base64
.
StdEncoding
.
EncodeToString
(
bodybytes
)
+
"."
qr
,
err
:=
StartSession
(
jwt
,
url
)
require
.
NoError
(
t
,
err
)
fmt
.
Println
(
jwt
)
qr
,
transportErr
:=
StartSession
(
jwt
,
url
)
if
transportErr
!=
nil
{
fmt
.
Println
(
transportErr
.
(
*
TransportError
)
.
ApiErr
)
}
require
.
NoError
(
t
,
transportErr
)
NewSession
(
qr
,
TestHandler
{
t
})
}
protocol/transport.go
View file @
65876b5f
...
...
@@ -15,6 +15,24 @@ type HTTPTransport struct {
client
*
http
.
Client
}
type
ApiError
struct
{
Status
int
`json:"status"`
ErrorName
string
`json:"error"'`
Description
string
`json:"description"`
Message
string
`json:"message"`
Stacktrace
string
`json:"stacktrace"`
}
type
TransportError
struct
{
Err
string
Status
int
ApiErr
*
ApiError
}
func
(
te
TransportError
)
Error
()
string
{
return
te
.
Err
}
func
NewHTTPTransport
(
serverURL
string
)
*
HTTPTransport
{
url
:=
serverURL
if
!
strings
.
HasSuffix
(
url
,
"/"
)
{
...
...
@@ -40,14 +58,14 @@ func (transport *HTTPTransport) request(url string, method string, result interf
if
object
!=
nil
{
marshaled
,
err
:=
json
.
Marshal
(
object
)
if
err
!=
nil
{
return
err
return
&
TransportError
{
Err
:
err
.
Error
()}
}
reader
=
bytes
.
NewBuffer
(
marshaled
)
}
req
,
err
:=
http
.
NewRequest
(
method
,
transport
.
Server
+
url
,
reader
)
if
err
!=
nil
{
return
err
return
&
TransportError
{
Err
:
err
.
Error
()}
}
req
.
Header
.
Set
(
"User-Agent"
,
"irmago"
)
...
...
@@ -57,17 +75,25 @@ func (transport *HTTPTransport) request(url string, method string, result interf
res
,
err
:=
transport
.
client
.
Do
(
req
)
if
err
!=
nil
{
return
err
return
&
TransportError
{
Err
:
err
.
Error
()}
}
body
,
err
:=
ioutil
.
ReadAll
(
res
.
Body
)
if
err
!=
nil
{
return
err
return
&
TransportError
{
Err
:
err
.
Error
(),
Status
:
res
.
StatusCode
}
}
if
res
.
StatusCode
!=
200
{
apierr
:=
&
ApiError
{}
json
.
Unmarshal
(
body
,
apierr
)
if
apierr
.
ErrorName
==
""
{
// Not an ApiErrorMessage
return
&
TransportError
{
Err
:
err
.
Error
(),
Status
:
res
.
StatusCode
}
}
return
&
TransportError
{
Err
:
apierr
.
ErrorName
,
Status
:
res
.
StatusCode
,
ApiErr
:
apierr
}
}
err
=
json
.
Unmarshal
(
body
,
result
)
if
err
!=
nil
{
return
err
return
&
TransportError
{
Err
:
err
.
Error
(),
Status
:
res
.
StatusCode
}
}
return
nil
...
...
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