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
8f545870
Commit
8f545870
authored
Nov 20, 2019
by
Sietse Ringers
Browse files
feat: split irma server revocation command HTTP endpoints to /revocation
parent
d79a6207
Changes
2
Hide whitespace changes
Inline
Side-by-side
irma/cmd/revocation-revoke.go
View file @
8f545870
...
...
@@ -55,10 +55,10 @@ func postRevocation(request *irma.RevocationRequest, url, schemespath, authmetho
switch
authmethod
{
case
"none"
:
err
=
transport
.
Post
(
"
sess
ion"
,
nil
,
request
)
err
=
transport
.
Post
(
"
revocat
ion"
,
nil
,
request
)
case
"token"
:
transport
.
SetHeader
(
"Authorization"
,
key
)
err
=
transport
.
Post
(
"
sess
ion"
,
nil
,
request
)
err
=
transport
.
Post
(
"
revocat
ion"
,
nil
,
request
)
case
"hmac"
,
"rsa"
:
sk
,
jwtalg
,
err
:=
configureJWTKey
(
authmethod
,
key
)
j
:=
irma
.
RevocationJwt
{
...
...
@@ -72,7 +72,7 @@ func postRevocation(request *irma.RevocationRequest, url, schemespath, authmetho
if
err
!=
nil
{
die
(
"failed to sign JWT"
,
err
)
}
err
=
transport
.
Post
(
"
sess
ion"
,
nil
,
jwtstr
)
err
=
transport
.
Post
(
"
revocat
ion"
,
nil
,
jwtstr
)
default
:
die
(
"Invalid authentication method (must be none, token, hmac or rsa)"
,
nil
)
}
...
...
server/requestorserver/server.go
View file @
8f545870
...
...
@@ -204,7 +204,7 @@ func (s *Server) Handler() http.Handler {
}
// Server routes
r
.
Post
(
"/session"
,
s
.
handleCreate
)
r
.
Post
(
"/session"
,
s
.
handleCreate
Session
)
r
.
Delete
(
"/session/{token}"
,
s
.
handleDelete
)
r
.
Get
(
"/session/{token}/status"
,
s
.
handleStatus
)
r
.
Get
(
"/session/{token}/statusevents"
,
s
.
handleStatusEvents
)
...
...
@@ -217,6 +217,14 @@ func (s *Server) Handler() http.Handler {
r
.
Get
(
"/publickey"
,
s
.
handlePublicKey
)
})
router
.
Group
(
func
(
r
chi
.
Router
)
{
r
.
Use
(
cors
.
New
(
corsOptions
)
.
Handler
)
if
s
.
conf
.
Verbose
>=
2
{
r
.
Use
(
s
.
logHandler
(
"revocation"
,
true
,
true
,
true
))
}
r
.
Post
(
"/revocation"
,
s
.
handleRevocation
)
})
return
router
}
...
...
@@ -281,7 +289,7 @@ func (s *Server) StaticFilesHandler() http.Handler {
)
}
func
(
s
*
Server
)
handleCreate
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
(
s
*
Server
)
handleCreate
Session
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
body
,
err
:=
ioutil
.
ReadAll
(
r
.
Body
)
if
err
!=
nil
{
s
.
conf
.
Logger
.
Error
(
"Could not read session request HTTP POST body"
)
...
...
@@ -295,7 +303,6 @@ func (s *Server) handleCreate(w http.ResponseWriter, r *http.Request) {
// one of them is applicable and able to authenticate the request.
var
(
rrequest
irma
.
RequestorRequest
revreq
*
irma
.
RevocationRequest
requestor
string
rerr
*
irma
.
RemoteError
applies
bool
...
...
@@ -305,75 +312,12 @@ func (s *Server) handleCreate(w http.ResponseWriter, r *http.Request) {
if
applies
||
rerr
!=
nil
{
break
}
applies
,
revreq
,
requestor
,
rerr
=
authenticator
.
AuthenticateRevocation
(
r
.
Header
,
body
)
if
applies
||
rerr
!=
nil
{
break
}
}
if
rerr
!=
nil
{
_
=
server
.
LogError
(
rerr
)
server
.
WriteResponse
(
w
,
nil
,
rerr
)
return
}
if
!
applies
{
var
ctype
=
r
.
Header
.
Get
(
"Content-Type"
)
if
ctype
!=
"application/json"
&&
ctype
!=
"text/plain"
{
s
.
conf
.
Logger
.
Warnf
(
"Session request uses unsupported Content-Type: %s"
,
ctype
)
server
.
WriteError
(
w
,
server
.
ErrorInvalidRequest
,
"Unsupported Content-Type: "
+
ctype
)
return
}
s
.
conf
.
Logger
.
Warnf
(
"Session request uses unknown authentication method, HTTP headers: %s, HTTP POST body: %s"
,
server
.
ToJson
(
r
.
Header
),
string
(
body
))
server
.
WriteError
(
w
,
server
.
ErrorInvalidRequest
,
"Request could not be authenticated"
)
return
}
if
rrequest
!=
nil
{
s
.
handleCreateSession
(
w
,
requestor
,
rrequest
)
}
else
{
s
.
handleRevoke
(
w
,
requestor
,
revreq
)
}
}
func
(
s
*
Server
)
handleCreateSession
(
w
http
.
ResponseWriter
,
requestor
string
,
rrequest
irma
.
RequestorRequest
)
{
// Authorize request: check if the requestor is allowed to verify or issue
// the requested attributes or credentials
request
:=
rrequest
.
SessionRequest
()
if
request
.
Action
()
==
irma
.
ActionIssuing
{
allowed
,
reason
:=
s
.
conf
.
CanIssue
(
requestor
,
request
.
(
*
irma
.
IssuanceRequest
)
.
Credentials
)
if
!
allowed
{
s
.
conf
.
Logger
.
WithFields
(
logrus
.
Fields
{
"requestor"
:
requestor
,
"id"
:
reason
})
.
Warn
(
"Requestor not authorized to issue credential; full request: "
,
server
.
ToJson
(
request
))
server
.
WriteError
(
w
,
server
.
ErrorUnauthorized
,
reason
)
return
}
}
condiscon
:=
request
.
Disclosure
()
.
Disclose
if
len
(
condiscon
)
>
0
{
allowed
,
reason
:=
s
.
conf
.
CanVerifyOrSign
(
requestor
,
request
.
Action
(),
condiscon
)
if
!
allowed
{
s
.
conf
.
Logger
.
WithFields
(
logrus
.
Fields
{
"requestor"
:
requestor
,
"id"
:
reason
})
.
Warn
(
"Requestor not authorized to verify attribute; full request: "
,
server
.
ToJson
(
request
))
server
.
WriteError
(
w
,
server
.
ErrorUnauthorized
,
reason
)
return
}
}
if
rrequest
.
Base
()
.
CallbackURL
!=
""
&&
s
.
conf
.
jwtPrivateKey
==
nil
{
s
.
conf
.
Logger
.
WithFields
(
logrus
.
Fields
{
"requestor"
:
requestor
})
.
Warn
(
"Requestor provided callbackUrl but no JWT private key is installed"
)
server
.
WriteError
(
w
,
server
.
ErrorUnsupported
,
""
)
if
ok
:=
s
.
checkAuth
(
w
,
r
,
rerr
,
applies
,
body
);
!
ok
{
return
}
// Everything is authenticated and parsed, we're good to go!
qr
,
token
,
err
:=
s
.
irmaserv
.
StartSession
(
rrequest
,
s
.
doResultCallback
)
if
err
!=
nil
{
server
.
WriteError
(
w
,
server
.
ErrorInvalidRequest
,
err
.
Error
())
return
}
server
.
WriteJson
(
w
,
server
.
SessionPackage
{
SessionPtr
:
qr
,
Token
:
token
,
})
s
.
createSession
(
w
,
requestor
,
rrequest
)
}
func
(
s
*
Server
)
handleCreateStatic
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
...
...
@@ -391,18 +335,32 @@ func (s *Server) handleCreateStatic(w http.ResponseWriter, r *http.Request) {
server
.
WriteJson
(
w
,
qr
)
}
func
(
s
*
Server
)
handleRevo
ke
(
w
http
.
ResponseWriter
,
r
equestor
string
,
request
*
irma
.
Revocation
Request
)
{
allowed
,
reason
:=
s
.
conf
.
CanRevoke
(
requestor
,
request
.
CredentialType
)
if
!
allowed
{
s
.
conf
.
Logger
.
WithFields
(
logrus
.
Fields
{
"requestor"
:
requestor
,
"message"
:
reason
})
.
Warn
(
"Requestor not authorized to revoke credential; full request: "
,
server
.
ToJson
(
request
)
)
server
.
WriteError
(
w
,
server
.
Error
Unauthorized
,
reason
)
func
(
s
*
Server
)
handleRevo
cation
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
body
,
err
:=
ioutil
.
ReadAll
(
r
.
Body
)
if
err
!=
nil
{
s
.
conf
.
Logger
.
Error
(
"Could not read revocation request HTTP POST body"
)
_
=
server
.
LogError
(
err
)
server
.
WriteError
(
w
,
server
.
Error
InvalidRequest
,
err
.
Error
()
)
return
}
if
err
:=
s
.
irmaserv
.
Revoke
(
request
.
CredentialType
,
request
.
Key
);
err
!=
nil
{
server
.
WriteError
(
w
,
server
.
ErrorUnknown
,
err
.
Error
())
var
(
revreq
*
irma
.
RevocationRequest
requestor
string
rerr
*
irma
.
RemoteError
applies
bool
)
for
_
,
authenticator
:=
range
authenticators
{
applies
,
revreq
,
requestor
,
rerr
=
authenticator
.
AuthenticateRevocation
(
r
.
Header
,
body
)
if
applies
||
rerr
!=
nil
{
break
}
}
server
.
WriteString
(
w
,
"OK"
)
if
ok
:=
s
.
checkAuth
(
w
,
r
,
rerr
,
applies
,
body
);
!
ok
{
return
}
s
.
revoke
(
w
,
requestor
,
revreq
)
}
func
(
s
*
Server
)
handleStatus
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
...
...
@@ -613,3 +571,79 @@ func (s *Server) doResultCallback(result *server.SessionResult) {
logger
.
Warn
(
errors
.
WrapPrefix
(
err
,
"Failed to POST session result to callback URL"
,
0
))
}
}
func
(
s
*
Server
)
createSession
(
w
http
.
ResponseWriter
,
requestor
string
,
rrequest
irma
.
RequestorRequest
)
{
// Authorize request: check if the requestor is allowed to verify or issue
// the requested attributes or credentials
request
:=
rrequest
.
SessionRequest
()
if
request
.
Action
()
==
irma
.
ActionIssuing
{
allowed
,
reason
:=
s
.
conf
.
CanIssue
(
requestor
,
request
.
(
*
irma
.
IssuanceRequest
)
.
Credentials
)
if
!
allowed
{
s
.
conf
.
Logger
.
WithFields
(
logrus
.
Fields
{
"requestor"
:
requestor
,
"id"
:
reason
})
.
Warn
(
"Requestor not authorized to issue credential; full request: "
,
server
.
ToJson
(
request
))
server
.
WriteError
(
w
,
server
.
ErrorUnauthorized
,
reason
)
return
}
}
condiscon
:=
request
.
Disclosure
()
.
Disclose
if
len
(
condiscon
)
>
0
{
allowed
,
reason
:=
s
.
conf
.
CanVerifyOrSign
(
requestor
,
request
.
Action
(),
condiscon
)
if
!
allowed
{
s
.
conf
.
Logger
.
WithFields
(
logrus
.
Fields
{
"requestor"
:
requestor
,
"id"
:
reason
})
.
Warn
(
"Requestor not authorized to verify attribute; full request: "
,
server
.
ToJson
(
request
))
server
.
WriteError
(
w
,
server
.
ErrorUnauthorized
,
reason
)
return
}
}
if
rrequest
.
Base
()
.
CallbackURL
!=
""
&&
s
.
conf
.
jwtPrivateKey
==
nil
{
s
.
conf
.
Logger
.
WithFields
(
logrus
.
Fields
{
"requestor"
:
requestor
})
.
Warn
(
"Requestor provided callbackUrl but no JWT private key is installed"
)
server
.
WriteError
(
w
,
server
.
ErrorUnsupported
,
""
)
return
}
// Everything is authenticated and parsed, we're good to go!
qr
,
token
,
err
:=
s
.
irmaserv
.
StartSession
(
rrequest
,
s
.
doResultCallback
)
if
err
!=
nil
{
server
.
WriteError
(
w
,
server
.
ErrorInvalidRequest
,
err
.
Error
())
return
}
server
.
WriteJson
(
w
,
server
.
SessionPackage
{
SessionPtr
:
qr
,
Token
:
token
,
})
}
func
(
s
*
Server
)
revoke
(
w
http
.
ResponseWriter
,
requestor
string
,
request
*
irma
.
RevocationRequest
)
{
allowed
,
reason
:=
s
.
conf
.
CanRevoke
(
requestor
,
request
.
CredentialType
)
if
!
allowed
{
s
.
conf
.
Logger
.
WithFields
(
logrus
.
Fields
{
"requestor"
:
requestor
,
"message"
:
reason
})
.
Warn
(
"Requestor not authorized to revoke credential; full request: "
,
server
.
ToJson
(
request
))
server
.
WriteError
(
w
,
server
.
ErrorUnauthorized
,
reason
)
return
}
if
err
:=
s
.
irmaserv
.
Revoke
(
request
.
CredentialType
,
request
.
Key
);
err
!=
nil
{
server
.
WriteError
(
w
,
server
.
ErrorUnknown
,
err
.
Error
())
}
server
.
WriteString
(
w
,
"OK"
)
}
func
(
s
*
Server
)
checkAuth
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
rerr
*
irma
.
RemoteError
,
applies
bool
,
body
[]
byte
)
bool
{
if
rerr
!=
nil
{
_
=
server
.
LogError
(
rerr
)
server
.
WriteResponse
(
w
,
nil
,
rerr
)
return
false
}
if
!
applies
{
var
ctype
=
r
.
Header
.
Get
(
"Content-Type"
)
if
ctype
!=
"application/json"
&&
ctype
!=
"text/plain"
{
s
.
conf
.
Logger
.
Warnf
(
"Session request uses unsupported Content-Type: %s"
,
ctype
)
server
.
WriteError
(
w
,
server
.
ErrorInvalidRequest
,
"Unsupported Content-Type: "
+
ctype
)
return
false
}
s
.
conf
.
Logger
.
Warnf
(
"Session request uses unknown authentication method, HTTP headers: %s, HTTP POST body: %s"
,
server
.
ToJson
(
r
.
Header
),
string
(
body
))
server
.
WriteError
(
w
,
server
.
ErrorInvalidRequest
,
"Request could not be authenticated"
)
return
false
}
return
true
}
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